[Bf-blender-cvs] [383c6bc1724] hair_guides: Also cache guide tangents and normals and fiber root positions in export data.
Lukas Tönne
noreply at git.blender.org
Sat May 12 11:42:40 CEST 2018
Commit: 383c6bc1724e24fc5a977b49fc12e5e255b3d188
Author: Lukas Tönne
Date: Sat May 12 10:42:16 2018 +0100
Branches: hair_guides
https://developer.blender.org/rB383c6bc1724e24fc5a977b49fc12e5e255b3d188
Also cache guide tangents and normals and fiber root positions in export data.
===================================================================
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
===================================================================
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index b2034cd4507..de3c69bb7b0 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -117,17 +117,20 @@ typedef struct HairExportCache
{
int totguidecurves;
int totguideverts;
-
+ struct HairGuideCurve *guide_curves;
+ struct HairGuideVertex *guide_verts;
+ float (*guide_tangents)[3]; /* Tangent vectors on guide curves */
+ float (*guide_normals)[3]; /* Normal vectors on guide curves */
+
int totfibercurves;
int totfiberverts;
- int *fiber_numverts; /* Number of vertices in each fiber */
-
+ int *fiber_numverts; /* Number of vertices in each fiber */
+ float (*fiber_root_position)[3]; /* Root position of each fiber */
+
const struct HairFollicle *follicles;
- struct HairGuideCurve *guide_curves;
- struct HairGuideVertex *guide_verts;
} HairExportCache;
-struct HairExportCache* BKE_hair_export_cache_new(const struct HairSystem *hsys, int subdiv);
+struct HairExportCache* BKE_hair_export_cache_new(const struct HairSystem *hsys, int subdiv, struct DerivedMesh *scalp);
void BKE_hair_export_cache_free(struct HairExportCache *cache);
/* === Draw Cache === */
@@ -148,7 +151,6 @@ void BKE_hair_get_texture_buffer_size(
int *r_fiber_start);
void BKE_hair_get_texture_buffer(
const struct HairExportCache *cache,
- struct DerivedMesh *scalp,
void *texbuffer);
/* === Render API === */
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index f9e89a5e132..d6e84ed6d2e 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -421,17 +421,20 @@ void BKE_hair_bind_follicles(HairSystem *hsys, DerivedMesh *scalp)
/* === Export === */
-BLI_INLINE int hair_get_strand_subdiv_numverts(int numstrands, int numverts, int subdiv)
+/* Returns number of vertices in a curve after subdivision */
+BLI_INLINE int hair_get_strand_subdiv_length(int orig_length, int subdiv)
{
- return ((numverts - numstrands) << subdiv) + numstrands;
+ return ((orig_length - 1) << subdiv) + 1;
}
-BLI_INLINE int hair_get_strand_subdiv_length(int orig_length, int subdiv)
+/* Returns total number of vertices after subdivision */
+BLI_INLINE int hair_get_strand_subdiv_numverts(int numstrands, int numverts, int subdiv)
{
- return ((orig_length - 1) << subdiv) + 1;
+ return ((numverts - numstrands) << subdiv) + numstrands;
}
-static int hair_strand_subdivide(const HairGuideCurve* curve, const HairGuideVertex* verts, int subdiv, HairGuideVertex *r_verts)
+/* Subdivide a curve */
+static int hair_guide_subdivide(const HairGuideCurve* curve, const HairGuideVertex* verts, int subdiv, HairGuideVertex *r_verts)
{
{
/* Move vertex positions from the dense array to their initial configuration for subdivision. */
@@ -472,7 +475,55 @@ static int hair_strand_subdivide(const HairGuideCurve* curve, const HairGuideVer
return num_verts;
}
-HairExportCache* BKE_hair_export_cache_new(const HairSystem *hsys, int subdiv)
+/* Calculate tangent and normal vector changes from one segment to the next */
+static void hair_guide_transport_frame(const float co1[3], const float co2[3],
+ float prev_tang[3], float prev_nor[3],
+ float r_tang[3], float r_nor[3])
+{
+ /* segment direction */
+ sub_v3_v3v3(r_tang, co2, co1);
+ normalize_v3(r_tang);
+
+ /* rotate the frame */
+ float rot[3][3];
+ rotation_between_vecs_to_mat3(rot, prev_tang, r_tang);
+ mul_v3_m3v3(r_nor, rot, prev_nor);
+
+ copy_v3_v3(prev_tang, r_tang);
+ copy_v3_v3(prev_nor, r_nor);
+}
+
+/* Calculate tangent and normal vectors for all vertices on a curve */
+static void hair_guide_calc_vectors(const HairGuideVertex* verts, int numverts, float rootmat[3][3],
+ float (*r_tangents)[3], float (*r_normals)[3])
+{
+ BLI_assert(numverts >= 2);
+
+ float prev_tang[3], prev_nor[3];
+
+ copy_v3_v3(prev_tang, rootmat[2]);
+ copy_v3_v3(prev_nor, rootmat[0]);
+
+ hair_guide_transport_frame(
+ verts[0].co, verts[1].co,
+ prev_tang, prev_nor,
+ r_tangents[0], r_normals[0]);
+
+ for (int i = 1; i < numverts - 1; ++i)
+ {
+ hair_guide_transport_frame(
+ verts[i-1].co, verts[i+1].co,
+ prev_tang, prev_nor,
+ r_tangents[i], r_normals[i]);
+ }
+
+ hair_guide_transport_frame(
+ verts[numverts-2].co, verts[numverts-1].co,
+ prev_tang, prev_nor,
+ r_tangents[numverts-1], r_normals[numverts-1]);
+}
+
+HairExportCache* BKE_hair_export_cache_new(const HairSystem *hsys, int subdiv, DerivedMesh *scalp)
{
HairExportCache *cache = MEM_callocN(sizeof(HairExportCache), "hair export cache");
@@ -494,14 +545,28 @@ HairExportCache* BKE_hair_export_cache_new(const HairSystem *hsys, int subdiv)
cache->totguideverts = totguideverts;
cache->guide_verts = MEM_mallocN(sizeof(HairGuideVertex) * totguideverts, "hair export guide verts");
+ cache->guide_tangents = MEM_mallocN(sizeof(float[3]) * totguideverts, "hair export guide tangents");
+ cache->guide_normals = MEM_mallocN(sizeof(float[3]) * totguideverts, "hair export guide normals");
for (int i = 0; i < totguidecurves; ++i) {
const HairGuideCurve *curve_orig = &hsys->guides.curves[i];
const HairGuideVertex *verts_orig = &hsys->guides.verts[curve_orig->vertstart];
const HairGuideCurve *curve = &cache->guide_curves[i];
HairGuideVertex *verts = &cache->guide_verts[curve->vertstart];
+ float (*tangents)[3] = &cache->guide_tangents[curve->vertstart];
+ float (*normals)[3] = &cache->guide_normals[curve->vertstart];
- hair_strand_subdivide(curve_orig, verts_orig, subdiv, verts);
+ hair_guide_subdivide(curve_orig, verts_orig, subdiv, verts);
+
+ {
+ /* Root matrix for defining the initial normal direction */
+ float rootpos[3];
+ float rootmat[3][3];
+ BKE_mesh_sample_eval(scalp, &curve->mesh_sample, rootpos, rootmat[2], rootmat[0]);
+ cross_v3_v3v3(rootmat[1], rootmat[2], rootmat[0]);
+
+ hair_guide_calc_vectors(verts, curve->numverts, rootmat, tangents, normals);
+ }
}
if (hsys->pattern)
@@ -511,10 +576,11 @@ HairExportCache* BKE_hair_export_cache_new(const HairSystem *hsys, int subdiv)
cache->follicles = hsys->pattern->follicles;
cache->fiber_numverts = MEM_mallocN(sizeof(int) * totfibercurves, "fiber numverts");
+ cache->fiber_root_position = MEM_mallocN(sizeof(float[3]) * totfibercurves, "fiber root position");
// Calculate the length of the fiber from the weighted average of its guide strands
cache->totfiberverts = 0;
- HairFollicle *follicle = hsys->pattern->follicles;
+ const HairFollicle *follicle = hsys->pattern->follicles;
for (int i = 0; i < totfibercurves; ++i, ++follicle) {
float fiblen = 0.0f;
@@ -529,10 +595,16 @@ HairExportCache* BKE_hair_export_cache_new(const HairSystem *hsys, int subdiv)
fiblen += (float)cache->guide_curves[si].numverts * sw;
}
- // Use rounded number of segments
+ /* Use rounded number of segments */
const int numverts = (int)(fiblen + 0.5f);
cache->fiber_numverts[i] = numverts;
cache->totfiberverts += numverts;
+
+ /* Cache fiber root position */
+ {
+ float nor[3], tang[3];
+ BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, cache->fiber_root_position[i], nor, tang);
+ }
}
}
@@ -553,5 +625,17 @@ void BKE_hair_export_cache_free(HairExportCache *cache)
{
MEM_freeN(cache->guide_verts);
}
+ if (cache->guide_tangents)
+ {
+ MEM_freeN(cache->guide_tangents);
+ }
+ if (cache->guide_normals)
+ {
+ MEM_freeN(cache->guide_normals);
+ }
+ if (cache->fiber_root_position)
+ {
+ MEM_freeN(cache->fiber_root_position);
+ }
MEM_freeN(cache);
}
diff --git a/source/blender/blenkernel/intern/hair_draw.c b/source/blender/blenkernel/intern/hair_draw.c
index a17522b0aef..bdb115ff589 100644
--- a/source/blender/blenkernel/intern/hair_draw.c
+++ b/source/blender/blenkernel/intern/hair_draw.c
@@ -89,90 +89,40 @@ typedef struct HairStrandMapTextureBuffer {
} HairStrandMapTextureBuffer;
BLI_STATIC_ASSERT_ALIGN(HairStrandMapTextureBuffer, 8)
-static void hair_strand_transport_frame(const float co1[3], const float co2[3],
- float prev_tang[3], float prev_nor[3],
- float r_tang[3], float r_nor[3])
-{
- /* segment direction */
- sub_v3_v3v3(r_tang, co2, co1);
- normalize_v3(r_tang);
-
- /* rotate the frame */
- float rot[3][3];
- rotation_between_vecs_to_mat3(rot, prev_tang, r_tang);
- mul_v3_m3v3(r_nor, rot, prev_nor);
-
- copy_v3_v3(prev_tang, r_tang);
- copy_v3_v3(prev_nor, r_nor);
-}
-
-static void hair_strand_calc_vectors(const HairGuideVertex* verts, int num_verts, float rootmat[3][3],
- HairStrandVertexTextureBuffer *strand)
-{
- for (int i = 0; i < num_verts; ++i) {
- copy_v3_v3(strand[i].co, verts[i].co);
- }
-
- // Calculate tangent and normal vectors
- {
- BLI_assert(num_verts >= 2);
-
- float prev_tang[3], prev_nor[3];
-
- copy_v3_v3(prev_tang, rootmat[2]);
- copy_v3_v3(prev_nor, rootmat[0]);
-
- hair_strand_transport_frame(strand[0].co, strand[1].co,
- prev_tang, prev_nor,
- strand[0].tang, strand[0].nor);
-
- for (int i = 1; i < num_verts - 1; ++i)
- {
- hair_strand_transport_frame(strand[i-1].co, strand[i+1].co,
- prev_tang, prev_nor,
- strand[i].tang, strand[i].nor);
- }
-
- hair_strand_transport_frame(strand[num_verts-2].co, strand[num_verts-1].co,
- prev_tang, prev_nor,
- strand[num_verts-1].tang, strand[num_verts-1].nor);
- }
-}
-
static void hair_get_strand_buffer(
const HairExportCache *cache,
- DerivedMesh *scalp,
HairStrandMapTextureBuffer *strand_map_buffer,
HairStrandVertexTextureBuffer *strand_vertex_buffer)
{
for (int i = 0; i < cache->totguidecurves; ++i) {
const HairGuideCurve *curve = &cache->guide_curves[i];
const HairGuideVertex *verts = &cache->guide_verts[curve->vertstart];
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list