[Bf-blender-cvs] [1ddbde24fff] hair_guides: Add fields for curve storage in hair systems and use it in draw code.
Lukas Tönne
noreply at git.blender.org
Sat Nov 11 15:14:34 CET 2017
Commit: 1ddbde24fff0e2ed2b39b135026c64238a9dda43
Author: Lukas Tönne
Date: Sat Nov 11 14:13:47 2017 +0000
Branches: hair_guides
https://developer.blender.org/rB1ddbde24fff0e2ed2b39b135026c64238a9dda43
Add fields for curve storage in hair systems and use it in draw code.
===================================================================
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/blenloader/intern/readfile.c
M source/blender/blenloader/intern/writefile.c
M source/blender/makesdna/DNA_hair_types.h
M source/blender/modifiers/intern/MOD_hair.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 10eb7020206..986cbc3a71b 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -41,6 +41,7 @@ struct HairPattern;
struct HairSystem;
struct DerivedMesh;
struct EvaluationContext;
+struct MeshSample;
struct Scene;
struct HairSystem* BKE_hair_new(void);
@@ -51,13 +52,12 @@ void BKE_hair_generate_follicles(struct HairSystem* hsys, unsigned int seed);
/* === Guide Strands === */
+void BKE_hair_guide_curves_begin(struct HairSystem *hsys, int totcurves, int totverts);
+void BKE_hair_set_guide_curve(struct HairSystem *hsys, int index, const struct MeshSample *mesh_sample, int numverts);
+void BKE_hair_set_guide_vertex(struct HairSystem *hsys, int index, int flag, const float co[3]);
+void BKE_hair_guide_curves_end(struct HairSystem *hsys);
+
struct DerivedMesh* BKE_hair_get_scalp(const struct HairSystem *hsys, struct Scene *scene, const struct EvaluationContext *eval_ctx);
-int BKE_hair_get_num_strands(const struct HairSystem *hsys);
-int BKE_hair_get_num_strands_verts(const struct HairSystem *hsys);
-void BKE_hair_get_strand_lengths(const struct HairSystem *hsys, int *r_lengths);
-void BKE_hair_get_strand_roots(const struct HairSystem *hsys, struct MeshSample *r_roots);
-void BKE_hair_get_strand_vertices(const struct HairSystem *hsys, float (*r_positions)[3]);
-void BKE_hair_get_follicle_weights(const struct HairSystem *hsys, unsigned int (*r_parents)[4], float (*r_weights)[4]);
/* === Draw Cache === */
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index a268803fe25..49c72cd9f8d 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -311,6 +311,56 @@ HairFiber* BKE_hair_fibers_create(const HairDrawDataInterface *hairdata,
/* ================================= */
+void BKE_hair_guide_curves_begin(HairSystem *hsys, int totcurves, int totverts)
+{
+ if (totcurves != hsys->totcurves)
+ {
+ hsys->curves = MEM_reallocN(hsys->curves, sizeof(HairGuideCurve) * totcurves);
+ hsys->flag |= HAIR_GUIDE_CURVES_DIRTY;
+ }
+ if (totverts != hsys->totverts)
+ {
+ hsys->verts = MEM_reallocN(hsys->curves, sizeof(HairGuideCurve) * totverts);
+ hsys->flag |= HAIR_GUIDE_VERTS_DIRTY;
+ }
+}
+
+void BKE_hair_set_guide_curve(HairSystem *hsys, int index, const MeshSample *mesh_sample, int numverts)
+{
+ BLI_assert(index <= hsys->totcurves);
+
+ HairGuideCurve *curve = &hsys->curves[index];
+ memcpy(&curve->mesh_sample, mesh_sample, sizeof(MeshSample));
+ curve->numverts = numverts;
+
+ hsys->flag |= HAIR_GUIDE_CURVES_DIRTY;
+}
+
+void BKE_hair_set_guide_vertex(HairSystem *hsys, int index, int flag, const float co[3])
+{
+ BLI_assert(index <= hsys->totverts);
+
+ HairGuideVertex *vertex = &hsys->verts[index];
+ vertex->flag = flag;
+ copy_v3_v3(vertex->co, co);
+
+ hsys->flag |= HAIR_GUIDE_VERTS_DIRTY;
+}
+
+void BKE_hair_guide_curves_end(HairSystem *hsys)
+{
+ /* Recalculate vertex offsets */
+ if (hsys->flag & HAIR_GUIDE_CURVES_DIRTY)
+ {
+ int vertstart = 0;
+ for (int i = 0; i < hsys->totcurves; ++i)
+ {
+ hsys->curves[i].vertstart = vertstart;
+ vertstart += hsys->curves[i].numverts;
+ }
+ }
+}
+
DerivedMesh* BKE_hair_get_scalp(const HairSystem *hsys, struct Scene *scene, const struct EvaluationContext *eval_ctx)
{
Object *ob = hsys->guide_object;
diff --git a/source/blender/blenkernel/intern/hair_draw.c b/source/blender/blenkernel/intern/hair_draw.c
index 0b21612d539..0da2f1b3849 100644
--- a/source/blender/blenkernel/intern/hair_draw.c
+++ b/source/blender/blenkernel/intern/hair_draw.c
@@ -53,13 +53,6 @@ BLI_INLINE int hair_get_strand_subdiv_length(int orig_length, int subdiv)
return ((orig_length - 1) << subdiv) + 1;
}
-static void hair_get_strand_subdiv_lengths(int *lengths, const int *orig_lengths, int num_strands, int subdiv)
-{
- for (int i = 0; i < num_strands; ++i) {
- lengths[i] = hair_get_strand_subdiv_length(orig_lengths[i], subdiv);
- }
-}
-
int* BKE_hair_get_fiber_lengths(const HairSystem *hsys, int subdiv)
{
if (!hsys->pattern) {
@@ -69,10 +62,12 @@ int* BKE_hair_get_fiber_lengths(const HairSystem *hsys, int subdiv)
const int totfibers = hsys->pattern->num_follicles;
int *fiber_length = MEM_mallocN(sizeof(int) * totfibers, "fiber length");
- const int num_strands = BKE_hair_get_num_strands(hsys);
+ const int num_strands = hsys->totcurves;
+ /* Cache subdivided lengths for repeated lookup */
int *lengths = MEM_mallocN(sizeof(int) * num_strands, "strand length");
- BKE_hair_get_strand_lengths(hsys, lengths);
- hair_get_strand_subdiv_lengths(lengths, lengths, num_strands, subdiv);
+ for (int i = 0; i < hsys->totcurves; ++i) {
+ lengths[i] = hair_get_strand_subdiv_length(hsys->curves[i].numverts, subdiv);
+ }
// Calculate the length of the fiber from the weighted average of its guide strands
unsigned int (*parent_indices)[4] = MEM_mallocN(sizeof(unsigned int) * 4 * totfibers, "parent index");
@@ -187,24 +182,21 @@ static void hair_strand_calc_vectors(const float (*positions)[3], int num_verts,
}
}
-static int hair_strand_subdivide(float (*verts)[3], const float (*verts_orig)[3], int numverts_orig, int subdiv)
+static int hair_strand_subdivide(const HairSystem *hsys, const HairGuideCurve* curve, int subdiv, float (*verts)[3])
{
{
/* Move vertex positions from the dense array to their initial configuration for subdivision. */
const int step = (1 << subdiv);
- const float (*src)[3] = verts_orig;
float (*dst)[3] = verts;
- for (int i = 0; i < numverts_orig; ++i) {
- copy_v3_v3(*dst, *src);
-
- ++src;
+ for (int i = curve->vertstart; i < curve->numverts; ++i) {
+ copy_v3_v3(*dst, hsys->verts[i].co);
dst += step;
}
}
/* Subdivide */
for (int d = 0; d < subdiv; ++d) {
- const int num_edges = (numverts_orig - 1) << d;
+ const int num_edges = (curve->numverts - 1) << d;
const int hstep = 1 << (subdiv - d - 1);
const int step = 1 << (subdiv - d);
@@ -227,64 +219,47 @@ static int hair_strand_subdivide(float (*verts)[3], const float (*verts_orig)[3]
}
}
- const int num_verts = ((numverts_orig - 1) << subdiv) + 1;
+ const int num_verts = ((curve->numverts - 1) << subdiv) + 1;
return num_verts;
}
-static void hair_get_strand_buffer(DerivedMesh *scalp, int numstrands, int numverts_orig, int subdiv,
- const int *lengths_orig, const float (*vertco_orig)[3], const MeshSample *roots,
- HairStrandMapTextureBuffer *strand_map_buffer,
- HairStrandVertexTextureBuffer *strand_vertex_buffer)
+static void hair_get_strand_buffer(
+ const HairSystem *hsys,
+ DerivedMesh *scalp,
+ int subdiv,
+ HairStrandMapTextureBuffer *strand_map_buffer,
+ HairStrandVertexTextureBuffer *strand_vertex_buffer)
{
- const int numverts = hair_get_strand_subdiv_numverts(numstrands, numverts_orig, subdiv);
+ const int numverts = hair_get_strand_subdiv_numverts(hsys->totcurves, hsys->totverts, subdiv);
- const int *lengths;
- const float (*vertco)[3];
- int *lengths_subdiv = NULL;
- float (*vertco_subdiv)[3] = NULL;
- if (subdiv > 0) {
- lengths = lengths_subdiv = MEM_mallocN(sizeof(int) * numstrands, "strand lengths subdivided");
- hair_get_strand_subdiv_lengths(lengths_subdiv, lengths_orig, numstrands, subdiv);
-
- vertco = vertco_subdiv = MEM_mallocN(sizeof(float[3]) * numverts, "strand vertex positions subdivided");
- }
- else {
- lengths = lengths_orig;
- vertco = vertco_orig;
- }
+ float (*vertco)[3] = MEM_mallocN(sizeof(float[3]) * numverts, "strand vertex positions subdivided");
HairStrandMapTextureBuffer *smap = strand_map_buffer;
HairStrandVertexTextureBuffer *svert = strand_vertex_buffer;
- int vertex_orig_start = 0;
int vertex_start = 0;
- for (int i = 0; i < numstrands; ++i) {
- const int len_orig = lengths_orig[i];
- const int len = lengths[i];
+ for (int i = 0; i < hsys->totcurves; ++i) {
+ const HairGuideCurve *curve = &hsys->curves[i];
+ const int len_orig = curve->numverts;
+ const int len = hair_get_strand_subdiv_length(len_orig, subdiv);
smap->vertex_start = vertex_start;
smap->vertex_count = len;
if (subdiv > 0) {
- hair_strand_subdivide(vertco_subdiv + vertex_start, vertco_orig + vertex_orig_start, len_orig, subdiv);
+ hair_strand_subdivide(hsys, curve, subdiv, vertco + vertex_start);
}
{
float pos[3];
float matrix[3][3];
- BKE_mesh_sample_eval(scalp, &roots[i], pos, matrix[2], matrix[0]);
+ BKE_mesh_sample_eval(scalp, &hsys->curves[i].mesh_sample, pos, matrix[2], matrix[0]);
cross_v3_v3v3(matrix[1], matrix[2], matrix[0]);
hair_strand_calc_vectors(vertco + vertex_start, len, matrix, svert);
}
- vertex_orig_start += len_orig;
vertex_start += len;
++smap;
svert += len;
}
-
- if (subdiv > 0) {
- MEM_freeN(lengths_subdiv);
- MEM_freeN(vertco_subdiv);
- }
}
static void hair_get_fiber_buffer(const HairSystem* hsys, DerivedMesh *scalp,
@@ -310,9 +285,7 @@ void BKE_hair_get_texture_buffer_size(
int *r_strand_vertex_start,
int *r_fiber_start)
{
- const int totstrands = BKE_hair_get_num_strands(hsys);
- const int totverts_orig = BKE_hair_get_num_strands_verts(hsys);
- hair_get_texture_buffer_size(totstrands, totverts_orig, subdiv, hsys->pattern->num_follicles,
+ hair_get_texture_buffer_size(hsys->totcurves, hsys->totverts, subdiv, hsys->pattern->num_follicles,
r_size, r_strand_map_start, r_strand_vertex_start, r_fiber_start);
}
@@ -325,10 +298,8 @@ void BKE_hair_get_texture_buffer(
{
HairPattern* pattern = hsys->pattern;
DerivedMesh *scalp = BKE_hair_get_scalp(hsys, scene, eval_ctx);
- const int totstrands = BKE_hair_get_num_strands(hsys);
- const int totverts_orig = BKE_hair_get_num_strands_verts(hsys);
int size, strand_map_start, strand_vertex_start, fiber_start;
- hair_get_texture_buffer_size(totstrands, totverts_orig, subdiv, pattern->num_follicles,
+ hair_get_texture_buffer_size(hsys->totcurves, hsys->totverts, subdiv, pattern->num_follicle
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list