[Bf-blender-cvs] [63f023111d] cloth-improvements: Apply collision responce on state before pre-collision solve (breaks selfcol)
Luca Rood
noreply at git.blender.org
Sat Jan 14 06:19:14 CET 2017
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]);
More information about the Bf-blender-cvs
mailing list