Merge branch 'hair_immediate_fixes' into gooseberry
authorLukas Tönne <lukas.toenne@gmail.com>
Sun, 9 Nov 2014 12:11:05 +0000 (13:11 +0100)
committerLukas Tönne <lukas.toenne@gmail.com>
Tue, 20 Jan 2015 08:30:07 +0000 (09:30 +0100)
Conflicts:
source/blender/physics/intern/BPH_mass_spring.cpp

source/blender/blenloader/intern/versioning_270.c
source/blender/physics/intern/BPH_mass_spring.cpp
source/blender/physics/intern/implicit_blender.c

index dcdf51f3dd6337e12018b4a2c0ba9b1d3ce7e416..2261f311a237c13f519350c15e5656698b06642c 100644 (file)
@@ -472,25 +472,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
                        }
                }
        }
-
-       if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "int", "voxel_res")) {
-               Object *ob;
-               ModifierData *md;
-               for (ob = main->object.first; ob; ob = ob->id.next) {
-                       for (md = ob->modifiers.first; md; md = md->next) {
-                               if (md->type == eModifierType_Cloth) {
-                                       ClothModifierData *clmd = (ClothModifierData*) md;
-                                       clmd->sim_parms->voxel_res = 32;
-                               }
-                               else if (md->type == eModifierType_ParticleSystem) {
-                                       ParticleSystemModifierData *pmd = (ParticleSystemModifierData*) md;
-                                       if (pmd->psys->clmd) {
-                                               pmd->psys->clmd->sim_parms->voxel_res = 32;
-                                       }
-                               }
-                       }
-               }
-       }
        
        if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "float", "bending_damping")) {
                Object *ob;
index fbb1cb7cf2ca5356ff8780057b69de93c9e7f830..a20f1617505caf2d6949d41700c71bc3681bee37 100644 (file)
@@ -526,6 +526,261 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
        }\r
 }\r
 \r
+#if 0\r
+#endif\r
+/* returns active vertexes' motion state, or original location the vertex is disabled */\r
+BLI_INLINE bool cloth_get_grid_location(Implicit_Data *data, float cell_scale, const float cell_offset[3],\r
+                                        ClothVertex *vert, int index, float x[3], float v[3])\r
+{\r
+       bool is_motion_state;\r
+       BPH_mass_spring_get_position(data, index, x);\r
+       BPH_mass_spring_get_new_velocity(data, index, v);\r
+       is_motion_state = true;\r
+       \r
+       mul_v3_fl(x, cell_scale);\r
+       add_v3_v3(x, cell_offset);\r
+       \r
+       return is_motion_state;\r
+}\r
+\r
+/* returns next spring forming a continous hair sequence */\r
+BLI_INLINE LinkNode *hair_spring_next(LinkNode *spring_link)\r
+{\r
+       ClothSpring *spring = (ClothSpring *)spring_link->link;\r
+       LinkNode *next = spring_link->next;\r
+       if (next) {\r
+               ClothSpring *next_spring = (ClothSpring *)next->link;\r
+               if (next_spring->type == CLOTH_SPRING_TYPE_STRUCTURAL && next_spring->kl == spring->ij)\r
+                       return next;\r
+       }\r
+       return NULL;\r
+}\r
+\r
+/* XXX this is nasty: cloth meshes do not explicitly store\r
+ * the order of hair segments!\r
+ * We have to rely on the spring build function for now,\r
+ * which adds structural springs in reverse order:\r
+ *   (3,4), (2,3), (1,2)\r
+ * This is currently the only way to figure out hair geometry inside this code ...\r
+ */\r
+static LinkNode *cloth_continuum_add_hair_segments(HairGrid *grid, const float cell_scale, const float cell_offset[3], Cloth *cloth, LinkNode *spring_link)\r
+{\r
+       Implicit_Data *data = cloth->implicit;\r
+       LinkNode *next_spring_link = NULL; /* return value */\r
+       ClothSpring *spring1, *spring2, *spring3;\r
+       ClothVertex *verts = cloth->verts;\r
+       ClothVertex *vert3, *vert4;\r
+       float x1[3], v1[3], x2[3], v2[3], x3[3], v3[3], x4[3], v4[3];\r
+       float dir1[3], dir2[3], dir3[3];\r
+       \r
+       spring1 = NULL;\r
+       spring2 = NULL;\r
+       spring3 = (ClothSpring *)spring_link->link;\r
+       \r
+       zero_v3(x1); zero_v3(v1);\r
+       zero_v3(dir1);\r
+       zero_v3(x2); zero_v3(v2);\r
+       zero_v3(dir2);\r
+       \r
+       vert3 = &verts[spring3->kl];\r
+       cloth_get_grid_location(data, cell_scale, cell_offset, vert3, spring3->kl, x3, v3);\r
+       vert4 = &verts[spring3->ij];\r
+       cloth_get_grid_location(data, cell_scale, cell_offset, vert4, spring3->ij, x4, v4);\r
+       sub_v3_v3v3(dir3, x4, x3);\r
+       normalize_v3(dir3);\r
+       \r
+       while (spring_link) {\r
+               /* move on */\r
+               spring1 = spring2;\r
+               spring2 = spring3;\r
+               \r
+               vert3 = vert4;\r
+               \r
+               copy_v3_v3(x1, x2); copy_v3_v3(v1, v2);\r
+               copy_v3_v3(x2, x3); copy_v3_v3(v2, v3);\r
+               copy_v3_v3(x3, x4); copy_v3_v3(v3, v4);\r
+               \r
+               copy_v3_v3(dir1, dir2);\r
+               copy_v3_v3(dir2, dir3);\r
+               \r
+               /* read next segment */\r
+               next_spring_link = spring_link->next;\r
+               spring_link = hair_spring_next(spring_link);\r
+               \r
+               if (spring_link) {\r
+                       spring3 = (ClothSpring *)spring_link->link;\r
+                       vert4 = &verts[spring3->ij];\r
+                       cloth_get_grid_location(data, cell_scale, cell_offset, vert4, spring3->ij, x4, v4);\r
+                       sub_v3_v3v3(dir3, x4, x3);\r
+                       normalize_v3(dir3);\r
+               }\r
+               else {\r
+                       spring3 = NULL;\r
+                       vert4 = NULL;\r
+                       zero_v3(x4); zero_v3(v4);\r
+                       zero_v3(dir3);\r
+               }\r
+               \r
+               BPH_hair_volume_add_segment(grid, x1, v1, x2, v2, x3, v3, x4, v4,\r
+                                           spring1 ? dir1 : NULL,\r
+                                           dir2,\r
+                                           spring3 ? dir3 : NULL);\r
+       }\r
+       \r
+       /* last segment */\r
+       spring1 = spring2;\r
+       spring2 = spring3;\r
+       spring3 = NULL;\r
+       \r
+       vert3 = vert4;\r
+       vert4 = NULL;\r
+       \r
+       copy_v3_v3(x1, x2); copy_v3_v3(v1, v2);\r
+       copy_v3_v3(x2, x3); copy_v3_v3(v2, v3);\r
+       copy_v3_v3(x3, x4); copy_v3_v3(v3, v4);\r
+       zero_v3(x4);        zero_v3(v4);\r
+       \r
+       copy_v3_v3(dir1, dir2);\r
+       copy_v3_v3(dir2, dir3);\r
+       zero_v3(dir3);\r
+       \r
+       BPH_hair_volume_add_segment(grid, x1, v1, x2, v2, x3, v3, x4, v4,\r
+                                   spring1 ? dir1 : NULL,\r
+                                   dir2,\r
+                                   NULL);\r
+       \r
+       return next_spring_link;\r
+}\r
+\r
+static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)\r
+{\r
+#if 0\r
+       Implicit_Data *data = cloth->implicit;\r
+       int numverts = cloth->numverts;\r
+       ClothVertex *vert;\r
+       int i;\r
+       \r
+       for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {\r
+               float x[3], v[3];\r
+               \r
+               cloth_get_vertex_motion_state(data, vert, x, v);\r
+               BPH_hair_volume_add_vertex(grid, x, v);\r
+       }\r
+#else\r
+       LinkNode *link;\r
+       float cellsize, gmin[3], cell_scale, cell_offset[3];\r
+       \r
+       /* scale and offset for transforming vertex locations into grid space\r
+        * (cell size is 0..1, gmin becomes origin)\r
+        */\r
+       BPH_hair_volume_grid_geometry(grid, &cellsize, NULL, gmin, NULL);\r
+       cell_scale = cellsize > 0.0f ? 1.0f / cellsize : 0.0f;\r
+       mul_v3_v3fl(cell_offset, gmin, cell_scale);\r
+       negate_v3(cell_offset);\r
+       \r
+       link = cloth->springs;\r
+       while (link) {\r
+               ClothSpring *spring = (ClothSpring *)link->link;\r
+               if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL)\r
+                       link = cloth_continuum_add_hair_segments(grid, cell_scale, cell_offset, cloth, link);\r
+               else\r
+                       link = link->next;\r
+       }\r
+#endif\r
+       BPH_hair_volume_normalize_vertex_grid(grid);\r
+}\r
+\r
+static void cloth_continuum_step(ClothModifierData *clmd, float dt)\r
+{\r
+       ClothSimSettings *parms = clmd->sim_parms;\r
+       Cloth *cloth = clmd->clothObject;\r
+       Implicit_Data *data = cloth->implicit;\r
+       int numverts = cloth->numverts;\r
+       ClothVertex *vert;\r
+       \r
+       const float fluid_factor = 0.95f; /* blend between PIC and FLIP methods */\r
+       float smoothfac = parms->velocity_smooth;\r
+       float pressfac = parms->pressure;\r
+       float minpress = parms->pressure_threshold;\r
+       float gmin[3], gmax[3];\r
+       int i;\r
+       \r
+       /* clear grid info */\r
+       zero_v3_int(clmd->hair_grid_res);\r
+       zero_v3(clmd->hair_grid_min);\r
+       zero_v3(clmd->hair_grid_max);\r
+       \r
+       hair_get_boundbox(clmd, gmin, gmax);\r
+       \r
+       /* gather velocities & density */\r
+       if (smoothfac > 0.0f || pressfac > 0.0f) {\r
+               HairGrid *grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_cell_size, gmin, gmax);\r
+               BPH_hair_volume_set_debug_data(grid, clmd->debug_data);\r
+               \r
+               cloth_continuum_fill_grid(grid, cloth);\r
+               \r
+               /* main hair continuum solver */\r
+               BPH_hair_volume_solve_divergence(grid, dt);\r
+               \r
+               for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {\r
+                       float x[3], v[3], nv[3];\r
+                       \r
+                       /* calculate volumetric velocity influence */\r
+                       BPH_mass_spring_get_position(data, i, x);\r
+                       BPH_mass_spring_get_new_velocity(data, i, v);\r
+                       \r
+                       BPH_hair_volume_grid_velocity(grid, x, v, fluid_factor, nv);\r
+                       \r
+                       interp_v3_v3v3(nv, v, nv, smoothfac);\r
+                       \r
+                       /* apply on hair data */\r
+                       BPH_mass_spring_set_new_velocity(data, i, nv);\r
+               }\r
+               \r
+               /* store basic grid info in the modifier data */\r
+               BPH_hair_volume_grid_geometry(grid, NULL, clmd->hair_grid_res, clmd->hair_grid_min, clmd->hair_grid_max);\r
+               \r
+#if 0 /* DEBUG hair velocity vector field */\r
+               {\r
+                       const int size = 64;\r
+                       int i, j;\r
+                       float offset[3], a[3], b[3];\r
+                       const int axis = 0;\r
+                       const float shift = 0.45f;\r
+                       \r
+                       copy_v3_v3(offset, clmd->hair_grid_min);\r
+                       zero_v3(a);\r
+                       zero_v3(b);\r
+                       \r
+                       offset[axis] = interpf(clmd->hair_grid_max[axis], clmd->hair_grid_min[axis], shift);\r
+                       a[(axis+1) % 3] = clmd->hair_grid_max[(axis+1) % 3] - clmd->hair_grid_min[(axis+1) % 3];\r
+                       b[(axis+2) % 3] = clmd->hair_grid_max[(axis+2) % 3] - clmd->hair_grid_min[(axis+2) % 3];\r
+                       \r
+                       BKE_sim_debug_data_clear_category(clmd->debug_data, "grid velocity");\r
+                       for (j = 0; j < size; ++j) {\r
+                               for (i = 0; i < size; ++i) {\r
+                                       float x[3], v[3], gvel[3], gvel_smooth[3], gdensity;\r
+                                       \r
+                                       madd_v3_v3v3fl(x, offset, a, (float)i / (float)(size-1));\r
+                                       madd_v3_v3fl(x, b, (float)j / (float)(size-1));\r
+                                       zero_v3(v);\r
+                                       \r
+                                       BPH_hair_volume_grid_interpolate(grid, x, &gdensity, gvel, gvel_smooth, NULL, NULL);\r
+                                       \r
+//                                     BKE_sim_debug_data_add_circle(clmd->debug_data, x, gdensity, 0.7, 0.3, 1, "grid density", hash_int_2d(hash_int_2d(i, j), 3111));\r
+                                       if (!is_zero_v3(gvel) || !is_zero_v3(gvel_smooth)) {\r
+                                               BKE_sim_debug_data_add_vector(clmd->debug_data, x, gvel, 0.4, 0, 1, "grid velocity", hash_int_2d(hash_int_2d(i, j), 3112));\r
+                                               BKE_sim_debug_data_add_vector(clmd->debug_data, x, gvel_smooth, 0.6, 4, 1, "grid velocity", hash_int_2d(hash_int_2d(i, j), 3113));\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+#endif\r
+               \r
+               BPH_hair_volume_free_vertex_grid(grid);\r
+       }\r
+}\r
+\r
 #if 0\r
 static void cloth_calc_volume_force(ClothModifierData *clmd)\r
 {\r
@@ -585,12 +840,19 @@ static void cloth_calc_volume_force(ClothModifierData *clmd)
 \r
 /* returns active vertexes' motion state, or original location the vertex is disabled */\r
 BLI_INLINE bool cloth_get_grid_location(Implicit_Data *data, float cell_scale, const float cell_offset[3],\r
-                                        ClothVertex *vert, int index, float x[3], float v[3])\r
+                                        ClothVertex *vert, float x[3], float v[3])\r
 {\r
        bool is_motion_state;\r
-       BPH_mass_spring_get_position(data, index, x);\r
-       BPH_mass_spring_get_new_velocity(data, index, v);\r
-       is_motion_state = true;\r
+       if (vert->solver_index < 0) {\r
+               copy_v3_v3(x, vert->x);\r
+               copy_v3_v3(v, vert->v);\r
+               is_motion_state = false;\r
+       }\r
+       else {\r
+               BPH_mass_spring_get_position(data, vert->solver_index, x);\r
+               BPH_mass_spring_get_new_velocity(data, vert->solver_index, v);\r
+               is_motion_state = true;\r
+       }\r
        \r
        mul_v3_fl(x, cell_scale);\r
        add_v3_v3(x, cell_offset);\r
@@ -638,9 +900,9 @@ static LinkNode *cloth_continuum_add_hair_segments(HairGrid *grid, const float c
        zero_v3(dir2);\r
        \r
        vert3 = &verts[spring3->kl];\r
-       cloth_get_grid_location(data, cell_scale, cell_offset, vert3, spring3->kl, x3, v3);\r
+       cloth_get_grid_location(data, cell_scale, cell_offset, vert3, x3, v3);\r
        vert4 = &verts[spring3->ij];\r
-       cloth_get_grid_location(data, cell_scale, cell_offset, vert4, spring3->ij, x4, v4);\r
+       cloth_get_grid_location(data, cell_scale, cell_offset, vert4, x4, v4);\r
        sub_v3_v3v3(dir3, x4, x3);\r
        normalize_v3(dir3);\r
        \r
@@ -665,7 +927,7 @@ static LinkNode *cloth_continuum_add_hair_segments(HairGrid *grid, const float c
                if (spring_link) {\r
                        spring3 = (ClothSpring *)spring_link->link;\r
                        vert4 = &verts[spring3->ij];\r
-                       cloth_get_grid_location(data, cell_scale, cell_offset, vert4, spring3->ij, x4, v4);\r
+                       cloth_get_grid_location(data, cell_scale, cell_offset, vert4, x4, v4);\r
                        sub_v3_v3v3(dir3, x4, x3);\r
                        normalize_v3(dir3);\r
                }\r
@@ -780,16 +1042,19 @@ static void cloth_continuum_step(ClothModifierData *clmd, float dt)
                for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {\r
                        float x[3], v[3], nv[3];\r
                        \r
+                       if (vert->solver_index < 0)\r
+                               continue;\r
+                       \r
                        /* calculate volumetric velocity influence */\r
-                       BPH_mass_spring_get_position(data, i, x);\r
-                       BPH_mass_spring_get_new_velocity(data, i, v);\r
+                       BPH_mass_spring_get_position(data, vert->solver_index, x);\r
+                       BPH_mass_spring_get_new_velocity(data, vert->solver_index, v);\r
                        \r
                        BPH_hair_volume_grid_velocity(grid, x, v, fluid_factor, nv);\r
                        \r
                        interp_v3_v3v3(nv, v, nv, smoothfac);\r
                        \r
                        /* apply on hair data */\r
-                       BPH_mass_spring_set_new_velocity(data, i, nv);\r
+                       BPH_mass_spring_set_new_velocity(data, vert->solver_index, nv);\r
                }\r
                \r
                /* store basic grid info in the modifier data */\r
@@ -1019,3 +1284,24 @@ bool BPH_cloth_solver_get_texture_data(Object *UNUSED(ob), ClothModifierData *cl
        \r
        return true;\r
 }\r
+\r
+bool BPH_cloth_solver_get_texture_data(Object *UNUSED(ob), ClothModifierData *clmd, VoxelData *vd)\r
+{\r
+       Cloth *cloth = clmd->clothObject;\r
+       HairGrid *grid;\r
+       float gmin[3], gmax[3];\r
+       \r
+       if (!clmd->clothObject || !clmd->clothObject->implicit)\r
+               return false;\r
+       \r
+       hair_get_boundbox(clmd, gmin, gmax);\r
+       \r
+       grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_cell_size, gmin, gmax);\r
+       cloth_continuum_fill_grid(grid, cloth);\r
+       \r
+       BPH_hair_volume_get_texture_data(grid, vd);\r
+       \r
+       BPH_hair_volume_free_vertex_grid(grid);\r
+       \r
+       return true;\r
+}\r
index 865f100e7e69d6f426c7566b7e1ea6338ac8f03b..cb115a2c10a7ba1784f2bdae3ead4613ce6c8db5 100644 (file)
@@ -324,6 +324,7 @@ static void print_sparse_matrix(fmatrix3x3 *m)
                }
        }
 }
+#endif
 
 static void print_lvector(lfVector *v, int numverts)
 {
@@ -380,7 +381,6 @@ static void print_bfmatrix(fmatrix3x3 *m)
        
        MEM_freeN(t);
 }
-#endif
 
 /* copy 3x3 matrix */
 DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3])