Commit: aa85cbee0050156c57aad021f45e124d3716d318 Author: Lukas Tönne Date: Sat Jun 30 08:02:15 2018 +0100 Branches: tmp_hair_curves https://developer.blender.org/rBaa85cbee0050156c57aad021f45e124d3716d318
Replace parent indices and weights with single curve index. Curves can be shared between follicles, but there will only be one curve per follicle for defining the shape. =================================================================== M source/blender/blenkernel/BKE_hair.h M source/blender/blenkernel/intern/hair.c M source/blender/blenkernel/intern/hair_draw.c M source/blender/draw/intern/draw_cache_impl_hair.c M source/blender/makesdna/DNA_hair_types.h =================================================================== diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h index af4af4fb53a..afc1fefbcb9 100644 --- a/source/blender/blenkernel/BKE_hair.h +++ b/source/blender/blenkernel/BKE_hair.h @@ -34,7 +34,7 @@ #include "BLI_utildefines.h" -static const unsigned int HAIR_STRAND_INDEX_NONE = 0xFFFFFFFF; +static const unsigned int HAIR_CURVE_INDEX_NONE = 0xFFFFFFFF; struct HairFollicle; struct HairPattern; @@ -141,12 +141,9 @@ typedef struct HairExportCache float (*fiber_tangents)[3]; /* Tangent vectors on fiber curves */ float (*fiber_normals)[3]; /* Normal vectors on fiber curves */ - /* Per fiber data */ - int totfibercurves; - int totfiberverts; - int *fiber_numverts; /* Number of vertices in each fiber */ - float (*fiber_root_position)[3]; /* Root position of each fiber */ - + /* Per follicle data */ + int totfollicles; + float (*follicle_root_position)[3]; /* Root position of each follicle */ const struct HairFollicle *follicles; } HairExportCache; @@ -154,19 +151,16 @@ typedef struct HairExportCache typedef enum eHairExportCacheUpdateFlags { /* Follicle placement on the scalp mesh */ - HAIR_EXPORT_FIBER_ROOT_POSITIONS = (1 << 0), - /* Fiber vertex counts */ - HAIR_EXPORT_FIBER_VERTEX_COUNTS = (1 << 1), - /* Follicle parent indices and weights */ - HAIR_EXPORT_FOLLICLE_BINDING = (1 << 2), + HAIR_EXPORT_FOLLICLE_ROOT_POSITIONS = (1 << 0), + /* Follicle curve index */ + HAIR_EXPORT_FOLLICLE_BINDING = (1 << 1), /* Fiber vertex positions (deform only) */ - HAIR_EXPORT_FIBER_VERTICES = (1 << 3), + HAIR_EXPORT_FIBER_VERTICES = (1 << 2), /* Fiber curve number and vertex counts (topology changes) */ - HAIR_EXPORT_FIBER_CURVES = (1 << 4), + HAIR_EXPORT_FIBER_CURVES = (1 << 3), HAIR_EXPORT_ALL = - HAIR_EXPORT_FIBER_ROOT_POSITIONS | - HAIR_EXPORT_FIBER_VERTEX_COUNTS | + HAIR_EXPORT_FOLLICLE_ROOT_POSITIONS | HAIR_EXPORT_FOLLICLE_BINDING | HAIR_EXPORT_FIBER_VERTICES | HAIR_EXPORT_FIBER_CURVES, @@ -174,8 +168,7 @@ typedef enum eHairExportCacheUpdateFlags HAIR_EXPORT_FIBER_VERTICES | HAIR_EXPORT_FIBER_CURVES, HAIR_EXPORT_FOLLICLES = - HAIR_EXPORT_FIBER_ROOT_POSITIONS | - HAIR_EXPORT_FIBER_VERTEX_COUNTS | + HAIR_EXPORT_FOLLICLE_ROOT_POSITIONS | HAIR_EXPORT_FOLLICLE_BINDING, } eHairExportCacheUpdateFlags; @@ -227,6 +220,7 @@ void BKE_hair_get_texture_buffer( /* Calculate required size for render buffers. */ void BKE_hair_render_get_buffer_size( const struct HairExportCache* cache, + int subdiv, int *r_totcurves, int *r_totverts); @@ -235,6 +229,7 @@ void BKE_hair_render_get_buffer_size( */ void BKE_hair_render_fill_buffers( const struct HairExportCache* cache, + int subdiv, int vertco_stride, int *r_curvestart, int *r_curvelen, diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c index 2db345dc65b..de52bddb4d9 100644 --- a/source/blender/blenkernel/intern/hair.c +++ b/source/blender/blenkernel/intern/hair.c @@ -330,90 +330,6 @@ void BKE_hair_clear_fiber_curves(HairSystem *hsys) /* ================================= */ -BLI_INLINE void hair_fiber_verify_weights(HairFollicle *follicle) -{ - const float *w = follicle->parent_weight; - - BLI_assert(w[0] >= 0.0f && w[1] >= 0.0f && w[2] >= 0.0f && w[3] >= 0.0f); - float sum = w[0] + w[1] + w[2] + w[3]; - float epsilon = 1.0e-2; - BLI_assert(sum > 1.0f - epsilon && sum < 1.0f + epsilon); - UNUSED_VARS(sum, epsilon); - - BLI_assert(w[0] >= w[1] && w[1] >= w[2] && w[2] >= w[3]); -} - -static void hair_fiber_sort_weights(HairFollicle *follicle) -{ - unsigned int *idx = follicle->parent_index; - float *w = follicle->parent_weight; - -#define FIBERSWAP(a, b) \ - SWAP(unsigned int, idx[a], idx[b]); \ - SWAP(float, w[a], w[b]); - - for (int k = 0; k < 3; ++k) { - int maxi = k; - float maxw = w[k]; - for (int i = k+1; i < 4; ++i) { - if (w[i] > maxw) { - maxi = i; - maxw = w[i]; - } - } - if (maxi != k) - FIBERSWAP(k, maxi); - } - -#undef FIBERSWAP -} - -static void hair_fiber_find_closest_strand( - HairFollicle *follicle, - const float loc[3], - const KDTree *tree, - const float (*strandloc)[3]) -{ - /* Use the 3 closest strands for interpolation. - * Note that we have up to 4 possible weights, but we - * only look for a triangle with this method. - */ - KDTreeNearest nearest[3]; - const float *sloc[3] = {NULL}; - int k, found = BLI_kdtree_find_nearest_n(tree, loc, nearest, 3); - for (k = 0; k < found; ++k) { - follicle->parent_index[k] = (unsigned int)nearest[k].index; - sloc[k] = strandloc[nearest[k].index]; - } - for (; k < 4; ++k) { - follicle->parent_index[k] = HAIR_STRAND_INDEX_NONE; - follicle->parent_weight[k] = 0.0f; - } - - /* calculate barycentric interpolation weights */ - if (found == 3) { - float closest[3]; - closest_on_tri_to_point_v3(closest, loc, sloc[0], sloc[1], sloc[2]); - - float w[3]; - interp_weights_tri_v3(w, sloc[0], sloc[1], sloc[2], closest); - copy_v3_v3(follicle->parent_weight, w); - /* float precisions issues can cause slightly negative weights */ - CLAMP3(follicle->parent_weight, 0.0f, 1.0f); - } - else if (found == 2) { - follicle->parent_weight[1] = line_point_factor_v3(loc, sloc[0], sloc[1]); - follicle->parent_weight[0] = 1.0f - follicle->parent_weight[1]; - /* float precisions issues can cause slightly negative weights */ - CLAMP2(follicle->parent_weight, 0.0f, 1.0f); - } - else if (found == 1) { - follicle->parent_weight[0] = 1.0f; - } - - hair_fiber_sort_weights(follicle); -} - bool BKE_hair_bind_follicles(HairSystem *hsys, const Mesh *scalp) { if (!(hsys->flag & HAIR_SYSTEM_UPDATE_FOLLICLE_BINDING)) @@ -437,8 +353,7 @@ bool BKE_hair_bind_follicles(HairSystem *hsys, const Mesh *scalp) { for (int k = 0; k < 4; ++k) { - follicle->parent_index[k] = HAIR_STRAND_INDEX_NONE; - follicle->parent_weight[k] = 0.0f; + follicle->curve = HAIR_CURVE_INDEX_NONE; } } return false; @@ -470,8 +385,7 @@ bool BKE_hair_bind_follicles(HairSystem *hsys, const Mesh *scalp) float loc[3], nor[3], tang[3]; if (BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, loc, nor, tang)) { - hair_fiber_find_closest_strand(follicle, loc, tree, strandloc); - hair_fiber_verify_weights(follicle); + follicle->curve = BLI_kdtree_find_nearest(tree, loc, NULL); } } } @@ -621,13 +535,9 @@ static int hair_export_cache_get_required_updates(const HairExportCache *cache) { data |= HAIR_EXPORT_FOLLICLE_BINDING; } - if (!cache->fiber_root_position) - { - data |= HAIR_EXPORT_FIBER_ROOT_POSITIONS; - } - if (!cache->fiber_numverts) + if (!cache->follicle_root_position) { - data |= HAIR_EXPORT_FIBER_VERTEX_COUNTS; + data |= HAIR_EXPORT_FOLLICLE_ROOT_POSITIONS; } return data; } @@ -642,7 +552,7 @@ static int hair_export_cache_get_dependencies(int data) data |= HAIR_EXPORT_FIBER_VERTICES | HAIR_EXPORT_FOLLICLE_BINDING; if (data & HAIR_EXPORT_FOLLICLE_BINDING) - data |= HAIR_EXPORT_FIBER_ROOT_POSITIONS | HAIR_EXPORT_FIBER_VERTEX_COUNTS; + data |= HAIR_EXPORT_FOLLICLE_ROOT_POSITIONS; return data; } @@ -717,67 +627,31 @@ int BKE_hair_export_cache_update(HairExportCache *cache, const HairSystem *hsys, if (data & HAIR_EXPORT_FOLLICLE_BINDING) { cache->follicles = hsys->pattern->follicles; - cache->totfibercurves = hsys->pattern->num_follicles; + cache->totfollicles = hsys->pattern->num_follicles; } - if (data & HAIR_EXPORT_FIBER_VERTEX_COUNTS) + if (data & HAIR_EXPORT_FOLLICLE_ROOT_POSITIONS) { - /* Calculate the length of each fiber from the weighted average of its parents */ - const int totcurves = cache->totcurves; - const int totfibercurves = cache->totfibercurves; - - cache->fiber_numverts = MEM_reallocN_id(cache->fiber_numverts, sizeof(int) * totfibercurves, "fiber numverts"); - cache->totfiberverts = 0; + const int totfibercurves = cache->totfollicles; - const HairFollicle *follicle = hsys->pattern->follicles; - for (int i = 0; i < totfibercurves; ++i, ++follicle) { - float fiblen = 0.0f; - - for (int k = 0; k < 4; ++k) { - const int si = follicle->parent_index[k]; - const float sw = follicle->parent_weight[k]; - if (si == HAIR_STRAND_INDEX_NONE || sw == 0.0f) { - break; - } - BLI_assert(si < totcurves); - - fiblen += (float)cache->fiber_curves[si].numverts * sw; - } - - /* Use rounded number of segments */ - const int numverts = (int)(fiblen + 0.5f); - cache->fiber_numverts[i] = numverts; - cache->totfiberverts += numverts; - } - } - - if (data & HAIR_EXPORT_FIBER_ROOT_POSITIONS) - { - const int totfibercurves = cache->totfibercurves; - - cache->fiber_root_position = MEM_reallocN_id(cache->fiber_root_position, sizeof(float[3]) * totfibercurves, "fiber root position"); + cache->follicle_root_position = MEM_reallocN_id(cache->follicle_root_position, sizeof(float[3]) * totfibercurves, "fiber root position"); const HairFollicle *follicle = hsys->pattern->follicles; for (int i = 0; i < totfibercurves; ++i, ++follicle) { /* Cache fiber root position */ float nor[3], tang[3]; - BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, cache->fiber_root_position[i], nor, tang); + BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, cache->follicle_root_position[i], nor, tang); } } } else { cache->follicles = NULL; - cache->totfibercurves = 0; + cache->totfollicles = 0; - if (cache->fiber_numverts) - { - MEM_freeN(cache->fiber_numverts); - cache->fiber_numverts = NULL; - } - if (cache->fiber_root_position) + if (cache->follicle_root_position) { - MEM_freeN(cache->fiber_root_position); - cache->fiber_root_position = NULL; + MEM_freeN(cache->follicle_root_position); + cache->follicle_root_position = NULL; } } @@ -788,10 +662,6 @@ int BKE_hair_export_cache_update(HairExportCache *cache, const Hai @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs