[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