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

Reply via email to