[Bf-blender-cvs] [aa85cbee005] tmp_hair_curves: Replace parent indices and weights with single curve index.
Lukas Tönne
noreply at git.blender.org
Sat Jun 30 10:45:19 CEST 2018
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. @@
More information about the Bf-blender-cvs
mailing list