Commit: d0337e00981c40bbda55e21d78fcd45887e31f20
Author: Lukas Tönne
Date:   Sun Sep 14 17:36:53 2014 +0200
Branches: hair_immediate_fixes
https://developer.blender.org/rBd0337e00981c40bbda55e21d78fcd45887e31f20

Moved most of the main cloth solver function out of implicit code core.

Force calculation is disabled, will follow shortly.

===================================================================

M       source/blender/physics/intern/BPH_mass_spring.cpp
M       source/blender/physics/intern/implicit.h
M       source/blender/physics/intern/implicit_blender.c
M       source/blender/physics/intern/implicit_eigen.cpp

===================================================================

diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp 
b/source/blender/physics/intern/BPH_mass_spring.cpp
index d9b3fe9..ae68525 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -29,6 +29,8 @@
  *  \ingroup bph
  */
 
+extern "C" {
+#include "DNA_cloth_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_object_types.h"
 #include "DNA_meshdata_types.h"
@@ -39,6 +41,9 @@
 #include "BLI_utildefines.h"
 
 #include "BKE_cloth.h"
+#include "BKE_collision.h"
+#include "BKE_effect.h"
+}
 
 #include "BPH_mass_spring.h"
 #include "implicit.h"
@@ -98,3 +103,242 @@ void BKE_cloth_solver_set_positions(ClothModifierData 
*clmd)
                BPH_mass_spring_set_motion_state(id, i, verts[i].x, verts[i].v);
        }
 }
+
+static bool collision_response(ClothModifierData *clmd, CollisionModifierData 
*collmd, CollPair *collpair, float restitution, float r_impulse[3])
+{
+       Cloth *cloth = clmd->clothObject;
+       int index = collpair->ap1;
+       bool result = false;
+       
+       float v1[3], v2_old[3], v2_new[3], v_rel_old[3], v_rel_new[3];
+       float epsilon2 = BLI_bvhtree_getepsilon(collmd->bvhtree);
+
+       float margin_distance = collpair->distance - epsilon2;
+       float mag_v_rel;
+       
+       zero_v3(r_impulse);
+       
+       if (margin_distance > 0.0f)
+               return false; /* XXX tested before already? */
+       
+       /* only handle static collisions here */
+       if ( collpair->flag & COLLISION_IN_FUTURE )
+               return false;
+       
+       /* velocity */
+       copy_v3_v3(v1, cloth->verts[index].v);
+       collision_get_collider_velocity(v2_old, v2_new, collmd, collpair);
+       /* relative velocity = velocity of the cloth point relative to the 
collider */
+       sub_v3_v3v3(v_rel_old, v1, v2_old);
+       sub_v3_v3v3(v_rel_new, v1, v2_new);
+       /* normal component of the relative velocity */
+       mag_v_rel = dot_v3v3(v_rel_old, collpair->normal);
+       
+       /* only valid when moving toward the collider */
+       if (mag_v_rel < -ALMOST_ZERO) {
+               float v_nor_old, v_nor_new;
+               float v_tan_old[3], v_tan_new[3];
+               float bounce, repulse;
+               
+               /* Collision response based on
+                * "Simulating Complex Hair with Robust Collision Handling" 
(Choe, Choi, Ko, ACM SIGGRAPH 2005)
+                * 
http://graphics.snu.ac.kr/publications/2005-choe-HairSim/Choe_2005_SCA.pdf
+                */
+               
+               v_nor_old = mag_v_rel;
+               v_nor_new = dot_v3v3(v_rel_new, collpair->normal);
+               
+               madd_v3_v3v3fl(v_tan_old, v_rel_old, collpair->normal, 
-v_nor_old);
+               madd_v3_v3v3fl(v_tan_new, v_rel_new, collpair->normal, 
-v_nor_new);
+               
+               /* TODO repulsion forces can easily destabilize the system,
+                * have to clamp them or construct a linear spring instead
+                */
+//             repulse = -margin_distance / dt + dot_v3v3(v1, 
collpair->normal);
+               repulse = 0.0f;
+               
+               if (margin_distance < -epsilon2) {
+                       bounce = -(v_nor_new + v_nor_old * restitution);
+                       mul_v3_v3fl(r_impulse, collpair->normal, 
max_ff(repulse, bounce));
+               }
+               else {
+                       bounce = 0.0f;
+                       mul_v3_v3fl(r_impulse, collpair->normal, repulse);
+               }
+               
+               result = true;
+       }
+       
+       return result;
+}
+
+/* Init constraint matrix
+ * This is part of the modified CG method suggested by Baraff/Witkin in
+ * "Large Steps in Cloth Simulation" (Siggraph 1998)
+ */
+static void cloth_setup_constraints(ClothModifierData *clmd, ColliderContacts 
*contacts, int totcolliders, float dt)
+{
+       Cloth *cloth = clmd->clothObject;
+       Implicit_Data *data = cloth->implicit;
+       ClothVertex *verts = cloth->verts;
+       int numverts = cloth->numverts;
+       int i, j, v;
+       
+       const float ZERO[3] = {0.0f, 0.0f, 0.0f};
+       
+       BPH_mass_spring_clear_constraints(data);
+       
+       for (v = 0; v < numverts; v++) {
+               if (verts[v].flags & CLOTH_VERT_FLAG_PINNED) {
+                       /* pinned vertex constraints */
+                       BPH_mass_spring_add_constraint_ndof0(data, v, ZERO); /* 
velocity is defined externally */
+               }
+               
+               verts[v].impulse_count = 0;
+       }
+
+       for (i = 0; i < totcolliders; ++i) {
+               ColliderContacts *ct = &contacts[i];
+               for (j = 0; j < ct->totcollisions; ++j) {
+                       CollPair *collpair = &ct->collisions[j];
+//                     float restitution = (1.0f - clmd->coll_parms->damping) 
* (1.0f - ct->ob->pd->pdef_sbdamp);
+                       float restitution = 0.0f;
+                       int v = collpair->face1;
+                       float impulse[3];
+                       
+                       /* pinned verts handled separately */
+                       if (verts[v].flags & CLOTH_VERT_FLAG_PINNED)
+                               continue;
+                       
+                       /* XXX cheap way of avoiding instability from multiple 
collisions in the same step
+                        * this should eventually be supported ...
+                        */
+                       if (verts[v].impulse_count > 0)
+                               continue;
+                       
+                       /* calculate collision response */
+                       if (!collision_response(clmd, ct->collmd, collpair, 
restitution, impulse))
+                               continue;
+                       
+                       BPH_mass_spring_add_constraint_ndof2(data, v, 
collpair->normal, impulse);
+                       ++verts[v].impulse_count;
+                       
+                       BKE_sim_debug_data_add_dot(clmd->debug_data, 
collpair->pa, 0, 1, 0, "collision", hash_collpair(936, collpair));
+                       BKE_sim_debug_data_add_dot(clmd->debug_data, 
collpair->pb, 1, 0, 0, "collision", hash_collpair(937, collpair));
+                       BKE_sim_debug_data_add_line(clmd->debug_data, 
collpair->pa, collpair->pb, 0.7, 0.7, 0.7, "collision", hash_collpair(938, 
collpair));
+                       
+                       { /* DEBUG */
+//                             float nor[3];
+//                             mul_v3_v3fl(nor, collpair->normal, 
collpair->distance);
+//                             BKE_sim_debug_data_add_vector(clmd->debug_data, 
collpair->pb, nor, 1, 1, 0, "collision", hash_collpair(939, collpair));
+                               BKE_sim_debug_data_add_vector(clmd->debug_data, 
collpair->pb, impulse, 1, 1, 0, "collision", hash_collpair(940, collpair));
+//                             BKE_sim_debug_data_add_vector(clmd->debug_data, 
collpair->pb, collpair->normal, 1, 1, 0, "collision", hash_collpair(941, 
collpair));
+                       }
+               }
+       }
+}
+
+int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase 
*effectors)
+{
+       unsigned int i=0;
+       float step=0.0f, tf=clmd->sim_parms->timescale;
+       Cloth *cloth = clmd->clothObject;
+       ClothVertex *verts = cloth->verts/*, *cv*/;
+       unsigned int numverts = cloth->numverts;
+       float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
+       Implicit_Data *id = cloth->implicit;
+       ColliderContacts *contacts = NULL;
+       int totcolliders = 0;
+       
+       BKE_sim_debug_data_clear_category(clmd->debug_data, "collision");
+       
+       if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { /* do goal 
stuff */
+               for (i = 0; i < numverts; i++) {
+                       // update velocities with constrained velocities from 
pinned verts
+                       if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) {
+                               float v[3];
+                               sub_v3_v3v3(v, verts[i].xconst, verts[i].xold);
+                               // mul_v3_fl(v, clmd->sim_parms->stepsPerFrame);
+                               BPH_mass_spring_set_velocity(id, i, v);
+                       }
+               }
+       }
+       
+       if (clmd->debug_data) {
+               for (i = 0; i < numverts; i++) {
+                       BKE_sim_debug_data_add_dot(clmd->debug_data, 
verts[i].x, 1.0f, 0.1f, 1.0f, "points", hash_vertex(583, i));
+               }
+       }
+       
+       while (step < tf) {
+               
+               /* copy velocities for collision */
+               for (i = 0; i < numverts; i++) {
+                       BPH_mass_spring_get_motion_state(id, i, NULL, 
verts[i].tv);
+                       copy_v3_v3(verts[i].v, verts[i].tv);
+               }
+               
+               /* determine contact points */
+               if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) {
+                       if (clmd->coll_parms->flags & 
CLOTH_COLLSETTINGS_FLAG_POINTS) {
+                               cloth_find_point_contacts(ob, clmd, 0.0f, tf, 
&contacts, &totcolliders);
+                       }
+               }
+               
+               /* setup vertex constraints for pinned vertices and contacts */
+               cloth_setup_constraints(clmd, contacts, totcolliders, dt);
+               
+               // damping velocity for artistic reasons
+               // this is a bad way to do it, should be removed imo - lukas_t
+               if (clmd->sim_parms->vel_damping != 1.0f) {
+                       for (i = 0; i < numverts; i++) {
+                               float v[3];
+                               BPH_mass_spring_get_motion_state(id, i, NULL, 
v);
+                               mul_v3_fl(v, clmd->sim_parms->vel_damping);
+                               BPH_mass_spring_set_velocity(id, i, v);
+                       }
+               }
+               
+               // calculate forces
+//             cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, 
id->dFdX, effectors, step, id->M);
+               
+               // calculate new velocity and position
+               BPH_mass_spring_solve(id, dt);
+               
+               BPH_mass_spring_apply_result(id);
+               
+               /* move pinned verts to correct position */
+               for (i = 0; i < numverts; i++) {
+                       if (clmd->sim_parms->flags & 
CLOTH_SIMSETTINGS_FLAG_GOAL) {
+                               if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
+                                       float x[3];
+                                       interp_v3_v3v3(x, verts[i].xold, 
verts[i].xconst, step + dt);
+                                       BPH_mass_spring_set_position(id, i, x);
+                               }
+                       }
+                       
+                       BPH_mass_spring_get_motion_state(id, i, verts[i].txold, 
NULL);
+                       
+//                     if (!(verts[i].flags & CLOTH_VERT_FLAG_PINNED) && i > 
0) {
+//                             BKE_sim_debug_data_add_line(clmd->debug_data, 
id->X[i], id->X[i-1], 0.6, 0.3, 0.3, "hair", hash_vertex(4892, i));
+//                             BKE_sim_debug_data_add_line(clmd->debug_data, 
id->Xnew[i], id->Xnew[i-1], 1, 0.5, 0.5, "hair", hash_vertex(4893, i));
+//                     }
+//                     BKE_sim_debug_data_add_vector(clmd->debug_data, 
id->X[i], id->V[i], 0, 0, 1, "velocity", hash_vertex(3158, i));
+               }
+               
+               /* free contact points */
+               if (contacts) {
+                       cloth_free_contacts(contacts, totcolliders);
+               }
+               
+               step += dt;
+       }
+       
+       /* copy results back to cloth data */
+       for (i = 0; i < numverts; i++) {
+               BPH_mass_spring_get_motion_state(id, i, verts[i].x, verts[i].v);
+               copy_v3_v3(verts[i].txold, verts[i].x);
+       }
+       
+       return 1;
+}
diff --git a/source/blender/physics/intern/implicit.h 
b/source/blender/physics/intern/implicit.h
index c674b49..d203671 100644
--- a/source/blender/physics/intern/implicit.h
+++ b/source/blender/physics/intern/implicit.h
@@ -34,6 +34,8 @@
 
 #include "stdio.h"
 
+#include "BKE_collision.h"
+
 #include "BLI_utildefines.h"
 
 #ifdef __cplusplus
@@ -63,11 +65,59 @@ BLI_INLINE void implicit_print_matrix_elem(float v)
     printf("%-8.3f", v);
 }
 
+/* ==== hash functions for debugging ==== */
+BLI_INLINE unsigned int hash_int_2d(unsigned int kx, unsigned int ky)
+{
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+       unsigned int a, b, c;
+
+       a = b = c = 0xdeadbeef + (2 << 2) + 13;
+       a += kx;
+       b += ky;
+
+       c ^= b; c -= rot(b,14);
+       a ^= c; a -= rot(c,11);
+       b ^= a; b -= rot(a,25);
+       c ^= b; c -= rot(b,16);
+       a ^= c; a -= rot(c,4);
+       b ^= a; b -= rot(a,14);
+       c ^= b; c -= rot(b,24);
+
+       return c;
+
+#undef rot
+}
+
+BLI_INLINE int hash_vertex(int type, int vertex)
+{
+       return hash_int_2d((unsigned int)type, (unsigned int)vertex)

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to