Commit: 63f023111db02ec958dcdf562e0f501432c4bb5b Author: Luca Rood Date: Thu Jan 12 19:13:33 2017 -0200 Branches: cloth-improvements https://developer.blender.org/rB63f023111db02ec958dcdf562e0f501432c4bb5b
Apply collision responce on state before pre-collision solve (breaks selfcol) This uses the pre-collision solve result only to find the collisions and calculate the responce impulses, but rolls back to before the pre-collision solve when it is time to actually apply the responce. This prevents the cloth from undergoing a double solve per time-step, which essentially made colliding clothes move much faster than non-colliding clothes. =================================================================== M source/blender/blenkernel/BKE_cloth.h M source/blender/blenkernel/intern/collision.c M source/blender/physics/intern/BPH_mass_spring.cpp M source/blender/physics/intern/implicit.h M source/blender/physics/intern/implicit_blender.c =================================================================== diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 52c8e9a472..c505e5fcbd 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -116,6 +116,7 @@ typedef struct ClothVertex { float goal; /* goal, from SB */ float impulse[3]; /* used in collision.c */ float xrest[3]; /* rest position of the vertex */ + float dcvel[3]; /* delta velocities to be applied by collision responce */ unsigned int impulse_count; /* same as above */ float avg_spring_len; /* average length of connected springs */ float struct_stiff; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index a4dfd334d6..445881b394 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -662,6 +662,7 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision if (verts[i].impulse_count) { // VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count ); VECADD ( verts[i].tv, verts[i].tv, verts[i].impulse); + VECADD ( verts[i].dcvel, verts[i].dcvel, verts[i].impulse); zero_v3(verts[i].impulse); verts[i].impulse_count = 0; diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp index 90c5819a43..6077dc9e04 100644 --- a/source/blender/physics/intern/BPH_mass_spring.cpp +++ b/source/blender/physics/intern/BPH_mass_spring.cpp @@ -952,6 +952,7 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold); copy_v3_v3(verts[i].v, verts[i].tv); + zero_v3(verts[i].dcvel); } #if 0 /* unused */ @@ -964,47 +965,52 @@ static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, Lis // TODO: check if "step" or "step+dt" is correct - dg do_extra_solve = cloth_bvh_objcollision(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); - } - if (do_extra_solve) { + ImplicitSolverResult result; // cloth_calc_helper_forces(ob, clmd, initial_cos, 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)) 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); + + /* Update position, based on old position, only applying delta caused by collision responce */ + add_v3_v3v3(verts[i].tx, verts[i].txold, verts[i].dcvel); + BPH_mass_spring_set_position(id, i, verts[i].tx); + + /* Update velocity, based on old velocity, only applying delta caused by collision responce */ + BPH_mass_spring_get_velocity(id, i, verts[i].tv); + madd_v3_v3fl(verts[i].tv, verts[i].dcvel, spf); + BPH_mass_spring_set_velocity(id, i, verts[i].tv); } - } - - if (do_extra_solve) { - ImplicitSolverResult result; - - // X = Xnew; - BPH_mass_spring_apply_result(id); /* initialize forces to zero */ BPH_mass_spring_clear_forces(id); - // calculate forces + /* calculate forces */ cloth_calc_force(clmd, frame, effectors, step, true); - // calculate new velocity and position + /* solve new velocities */ 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! */ + + for (i = 0; i < mvert_num; i++) { + float prex[3]; + + /* Get position calculated in pre-collision solve */ + BPH_mass_spring_get_new_position(id, i, prex); + + /* Solve new possition from old position and velocity solved after collision responce */ + BPH_mass_spring_get_position(id, i, verts[i].tx); + BPH_mass_spring_get_new_velocity(id, i, verts[i].tv); + madd_v3_v3fl(verts[i].tx, verts[i].tv, dt); + + /* Apply the average position between pre-collision and post-collision solves, + * this is by no means a physically based operation, but it make resting contacts much more stable + * than if the post-collision positions were fully applied. + * Note that the velocities are nonetheless fully post-collision solved (done above). */ + mid_v3_v3v3(verts[i].tx, prex, verts[i].tx); + BPH_mass_spring_set_new_position(id, i, verts[i].tx); + } } } diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h index 64df10aee1..207316287e 100644 --- a/source/blender/physics/intern/implicit.h +++ b/source/blender/physics/intern/implicit.h @@ -81,6 +81,7 @@ void BPH_mass_spring_set_position(struct Implicit_Data *data, int index, const f void BPH_mass_spring_set_velocity(struct Implicit_Data *data, int index, const float v[3]); void BPH_mass_spring_get_motion_state(struct Implicit_Data *data, int index, float x[3], float v[3]); void BPH_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3]); +void BPH_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3]); /* access to modified motion state during solver step */ void BPH_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3]); diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c index 4bfe82d7a4..0f17ed67ee 100644 --- a/source/blender/physics/intern/implicit_blender.c +++ b/source/blender/physics/intern/implicit_blender.c @@ -1204,6 +1204,11 @@ void BPH_mass_spring_set_new_position(struct Implicit_Data *data, int index, con world_to_root_v3(data, index, data->Xnew[index], x); } +void BPH_mass_spring_get_velocity(struct Implicit_Data *data, int index, float v[3]) +{ + root_to_world_v3(data, index, v, data->V[index]); +} + void BPH_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3]) { root_to_world_v3(data, index, v, data->Vnew[index]); _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs