[Bf-blender-cvs] [43fa4a3f706] hair_guides_grooming: Set shape parameters per region and use them as per-guide attributes.

Lukas Tönne noreply at git.blender.org
Tue Jun 12 09:46:14 CEST 2018


Commit: 43fa4a3f7065939455fe598caa48ccd44f9b9eac
Author: Lukas Tönne
Date:   Tue Jun 12 08:45:04 2018 +0100
Branches: hair_guides_grooming
https://developer.blender.org/rB43fa4a3f7065939455fe598caa48ccd44f9b9eac

Set shape parameters per region and use them as per-guide attributes.

Eventually should also support scalp textures/vgroups as factors for
fine-grained control.

===================================================================

M	release/scripts/startup/bl_ui/properties_data_groom.py
M	source/blender/blenkernel/BKE_hair.h
M	source/blender/blenkernel/intern/groom.c
M	source/blender/blenkernel/intern/hair.c
M	source/blender/blenkernel/intern/hair_draw.c
M	source/blender/draw/modes/shaders/common_hair_guides_lib.glsl
M	source/blender/makesdna/DNA_groom_types.h
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/makesrna/intern/rna_groom.c
M	source/blender/makesrna/intern/rna_modifier.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_groom.py b/release/scripts/startup/bl_ui/properties_data_groom.py
index 5cd1f68bf35..7899ff96494 100644
--- a/release/scripts/startup/bl_ui/properties_data_groom.py
+++ b/release/scripts/startup/bl_ui/properties_data_groom.py
@@ -113,6 +113,10 @@ class DATA_PT_groom_regions(DataButtonsPanel, Panel):
 
             col.prop(region.bundle, "guides_count")
 
+            sub = col.column(align=True)
+            sub.prop(region, "taper_length")
+            sub.prop(region, "taper_thickness")
+
 
 class DATA_PT_groom_hair(DataButtonsPanel, Panel):
     bl_label = "Hair"
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index cad25348e43..73f8e3d9c12 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -65,7 +65,8 @@ void BKE_hair_guide_curves_begin(struct HairSystem *hsys, int totcurves);
  * \param mesh_sample Origin of the guide curve on the scalp mesh.
  * \param numverts Number of vertices in this guide curve
  */
-void BKE_hair_set_guide_curve(struct HairSystem *hsys, int index, const struct MeshSample *mesh_sample, int numverts);
+void BKE_hair_set_guide_curve(struct HairSystem *hsys, int index, const struct MeshSample *mesh_sample, int numverts,
+                              float taper_length, float taper_thickness);
 
 /* Finalize guide curve update */
 void BKE_hair_guide_curves_end(struct HairSystem *hsys);
@@ -130,13 +131,17 @@ void BKE_hair_draw_settings_free(struct HairDrawSettings *draw_settings);
 /* Intermediate data for export */
 typedef struct HairExportCache
 {
+	/* Per guide curve data */
 	int totguidecurves;
-	int totguideverts;
 	struct HairGuideCurve *guide_curves;
+	
+	/* Per guide vertex data */
+	int totguideverts;
 	struct HairGuideVertex *guide_verts;
 	float (*guide_tangents)[3];             /* Tangent vectors on guide curves */
 	float (*guide_normals)[3];              /* Normal vectors on guide curves */
 	
+	/* Per fiber data */
 	int totfibercurves;
 	int totfiberverts;
 	int *fiber_numverts;                    /* Number of vertices in each fiber */
diff --git a/source/blender/blenkernel/intern/groom.c b/source/blender/blenkernel/intern/groom.c
index f3e1f1263fa..bb992304581 100644
--- a/source/blender/blenkernel/intern/groom.c
+++ b/source/blender/blenkernel/intern/groom.c
@@ -880,7 +880,12 @@ void BKE_groom_hair_update_guide_curves(const Depsgraph *depsgraph, Groom *groom
 		const int curvesize = bundle->curvesize;
 		for (int i = 0; i < bundle->totguides; ++i)
 		{
-			BKE_hair_set_guide_curve(hsys, i, &bundle->guides[i].root, curvesize);
+			/* TODO implement optional factors using scalp textures/vgroups */
+			float taper_length = region->taper_length;
+			float taper_thickness = region->taper_thickness;
+			
+			BKE_hair_set_guide_curve(hsys, i, &bundle->guides[i].root, curvesize,
+			                         taper_length, taper_thickness);
 		}
 	}
 	BKE_hair_guide_curves_end(hsys);
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index cca003142da..70ae53b58c8 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -228,13 +228,16 @@ void BKE_hair_guide_curves_begin(HairSystem *hsys, int totcurves)
 	}
 }
 
-void BKE_hair_set_guide_curve(HairSystem *hsys, int index, const MeshSample *mesh_sample, int numverts)
+void BKE_hair_set_guide_curve(HairSystem *hsys, int index, const MeshSample *mesh_sample, int numverts,
+                              float taper_length, float taper_thickness)
 {
 	BLI_assert(index <= hsys->guides.totcurves);
 	
 	HairGuideCurve *curve = &hsys->guides.curves[index];
 	memcpy(&curve->mesh_sample, mesh_sample, sizeof(MeshSample));
 	curve->numverts = numverts;
+	curve->taper_length = taper_length;
+	curve->taper_thickness = taper_thickness;
 	
 	hsys->flag |= HAIR_SYSTEM_UPDATE_FOLLICLE_BINDING;
 	BKE_hair_batch_cache_dirty(hsys, BKE_HAIR_BATCH_DIRTY_ALL);
@@ -672,7 +675,7 @@ int BKE_hair_export_cache_update(HairExportCache *cache, const HairSystem *hsys,
 			const HairGuideCurve *curve_orig = &hsys->guides.curves[i];
 			HairGuideCurve *curve = &cache->guide_curves[i];
 			
-			memcpy(&curve->mesh_sample, &curve_orig->mesh_sample, sizeof(MeshSample));
+			memcpy(curve, curve_orig, sizeof(HairGuideCurve));
 			curve->numverts = hair_get_strand_subdiv_length(curve_orig->numverts, subdiv);
 			curve->vertstart = totguideverts;
 			
diff --git a/source/blender/blenkernel/intern/hair_draw.c b/source/blender/blenkernel/intern/hair_draw.c
index 5e0cc4f882a..5b7e6e7cb67 100644
--- a/source/blender/blenkernel/intern/hair_draw.c
+++ b/source/blender/blenkernel/intern/hair_draw.c
@@ -91,6 +91,10 @@ BLI_STATIC_ASSERT_ALIGN(HairStrandVertexTextureBuffer, 8)
 typedef struct HairStrandMapTextureBuffer {
 	unsigned int vertex_start;
 	unsigned int vertex_count;
+	
+	/* Shape attributes */
+	float taper_length;         /* Distance at which final thickness is reached */
+	float taper_thickness;      /* Relative thickness of the strand */
 } HairStrandMapTextureBuffer;
 BLI_STATIC_ASSERT_ALIGN(HairStrandMapTextureBuffer, 8)
 
@@ -109,6 +113,8 @@ static void hair_get_strand_buffer(
 		
 		smap->vertex_start = curve->vertstart;
 		smap->vertex_count = curve->numverts;
+		smap->taper_length = curve->taper_length;
+		smap->taper_thickness = curve->taper_thickness;
 		
 		for (int j = 0; j < curve->numverts; ++j)
 		{
diff --git a/source/blender/draw/modes/shaders/common_hair_guides_lib.glsl b/source/blender/draw/modes/shaders/common_hair_guides_lib.glsl
index e9b7e90b497..e737048bd31 100644
--- a/source/blender/draw/modes/shaders/common_hair_guides_lib.glsl
+++ b/source/blender/draw/modes/shaders/common_hair_guides_lib.glsl
@@ -57,44 +57,27 @@ mat4 rotateZ(float angle)
  * https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch42.html
  */
 
-/* Hairs tend to stick together and run in parallel.
- * The effect increases with distance from the root,
- * as the stresses pulling fibers apart decrease.
- */
-struct ClumpParams
+struct DeformParams
 {
+	/* Length where strand reaches final thickness */
+	float taper_length;
 	/* Relative strand thickness at the tip.
 	 * (0.0, 1.0]
 	 * 0.0 : Strand clumps into a single line
 	 * 1.0 : Strand does not clump at all
 	 * (> 1.0 is possible but not recommended)
 	 */
-	float thickness;
-};
+	float taper_thickness;
 
-/* Hairs often don't have a circular cross section, but are somewhat flattened.
- * This creates the local bending which results in the typical curly hair geometry.
- */ 
-struct CurlParams
-{
 	/* Radius of the curls.
 	 * >= 0.0
 	 */
-	float radius;
+	float curl_radius;
 	/* Steepness of curls
 	 * < 0.0 : Clockwise curls
 	 * > 0.0 : Anti-clockwise curls
 	 */
-	float angle;
-};
-
-struct DeformParams
-{
-	/* Length where strand reaches final thickness */
-	float taper_length;
-
-	ClumpParams clump;
-	CurlParams curl;
+	float curl_angle;
 };
 
 void deform_taper(DeformParams params, float t, out float taper, out float dtaper)
@@ -111,14 +94,18 @@ void deform_taper(DeformParams params, float t, out float taper, out float dtape
 	dtaper = 1.5 * x * (2.0 - x) * dx;
 }
 
+/* Hairs tend to stick together and run in parallel.
+ * The effect increases with distance from the root,
+ * as the stresses pulling fibers apart decrease.
+ */
 void deform_clump(DeformParams params,
                   float t, float tscale, mat4 target_matrix,
                   inout vec3 co, inout vec3 tang)
 {
 	float taper, dtaper;
 	deform_taper(params, t, taper, dtaper);
-	float factor = (1.0 - params.clump.thickness) * taper;
-	float dfactor = (1.0 - params.clump.thickness) * dtaper;
+	float factor = (1.0 - params.taper_thickness) * taper;
+	float dfactor = (1.0 - params.taper_thickness) * dtaper;
 	
 	vec3 target_co = target_matrix[3].xyz;
 	vec3 target_tang = target_matrix[0].xyz;
@@ -129,14 +116,17 @@ void deform_clump(DeformParams params,
 	tang = ntang;
 }
 
+/* Hairs often don't have a circular cross section, but are somewhat flattened.
+ * This creates the local bending which results in the typical curly hair geometry.
+ */
 void deform_curl(DeformParams params,
                  float t, float tscale,
                  inout mat4 target_matrix)
 {
-	float pitch = 2.0*M_PI * params.curl.radius * tan(params.curl.angle);
-	float turns = tscale / (params.curl.radius * tan(params.curl.angle));
+	float pitch = 2.0*M_PI * params.curl_radius * tan(params.curl_angle);
+	float turns = tscale / (params.curl_radius * tan(params.curl_angle));
 	float angle = t * turns;
-	mat4 local_mat = rotateX(angle) * translate(vec3(0.0, params.curl.radius, 0.0)) * rotateY(params.curl.angle);
+	mat4 local_mat = rotateX(angle) * translate(vec3(0.0, params.curl_radius, 0.0)) * rotateY(params.curl_angle);
 	target_matrix = target_matrix * local_mat;
 }
 
@@ -172,13 +162,19 @@ mat4 mat4_from_vectors(vec3 nor, vec3 tang, vec3 co)
 	return mat4(vec4(tang, 0.0), vec4(xnor, 0.0), vec4(cross(tang, xnor), 0.0), vec4(co, 1.0));
 }
 
-void get_strand_data(int index, out int start, out int count)
+void get_strand_data(int index, out int start, out int count, out DeformParams deform_params)
 {
 	int offset = strand_map_start + index;
 	vec2 a = read_texdata(offset);
+	vec2 b = read_texdata(offset + 1);
 
 	start = floatBitsToInt(a.r);
 	count = floatBitsToInt(a.g);
+
+	deform_params.taper_length = b.r;
+	deform_params.taper_thickness = b.g;
+	deform_params.curl_radius = 0.1;
+	deform_params.curl_angle = 0.2;
 }
 
 void get_strand_vertex(int index, out vec3 co, out vec3 nor, out vec3 tang)
@@ -219,10 +215,10 @@ void get_fiber_data(int fiber_index, out ivec4 parent_index, out vec4 parent_wei
 	pos = vec3(e.rg, f.r);
 }
 
-void interpolate_parent_curve(int index, float curve_param, out vec3 co, out vec3 nor, out vec3 tang, out vec3 rootco)
+void interpolate_parent_curve(int index, float curve_param, out vec3 co, out vec3 nor, out vec3 tang, out vec3 rootco, out DeformParams deform_params)
 {
 	int start, count;
-	get_strand_data(index, start, count);
+	get_strand_data(index, start, count, deform_params);
 	
 	get_strand_root(start, rootco);
 	
@@ -250,7 +246,7 @@ void interpo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list