[Bf-blender-cvs] [3134a7c] hair_system: Added back child hair rendering and random offsets.

Lukas Tönne noreply at git.blender.org
Wed Aug 13 10:43:53 CEST 2014


Commit: 3134a7c3d3f3b5c022d97981d14915375d920d0d
Author: Lukas Tönne
Date:   Wed Aug 13 10:13:58 2014 +0200
Branches: hair_system
https://developer.blender.org/rB3134a7c3d3f3b5c022d97981d14915375d920d0d

Added back child hair rendering and random offsets.

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

M	source/blender/blenkernel/BKE_hair.h
M	source/blender/blenkernel/intern/hair.c
M	source/blender/editors/space_view3d/drawhair.c

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

diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 2e859bf..c1cbbd3 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -57,7 +57,7 @@ void BKE_hair_debug_data_free(struct HairDebugData *debug_data);
 
 /* cached per-hair data */
 typedef struct HairPointRenderCache {
-	float frame[3][3];
+	float nor[3], tan[3], cotan[3];
 } HairPointRenderCache;
 
 typedef struct HairRenderChildData {
@@ -67,7 +67,7 @@ typedef struct HairRenderChildData {
 typedef struct HairRenderIterator {
 	struct HairSystem *hsys;
 	struct HairPointRenderCache *hair_cache; /* array of maxpoints elements to avoid recalculating per child hair */
-	int maxpoints;
+	int maxsteps;
 	int steps_per_point;
 	
 	HairRenderChildData *child_data;
@@ -77,6 +77,9 @@ typedef struct HairRenderIterator {
 	struct HairCurve *hair;
 	int i;
 	
+	/* child instance */
+	int child, totchildren;
+	
 	/* hair point data */
 	struct HairPoint *point;
 	int k;
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 2ce76cf..7b337f3 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -299,10 +299,24 @@ static void hair_precalc_cache(HairRenderIterator *iter)
 	for (HAIR_frame_iter_init(frame_iter, iter->hair, iter->hair->avg_rest_length, iter->hsys->params.curl_smoothing, initial_frame);
 	     HAIR_frame_iter_valid(frame_iter);
 	     HAIR_frame_iter_next(frame_iter)) {
+		int k = HAIR_frame_iter_index(frame_iter);
 		
-		HAIR_frame_iter_get(frame_iter, cache->frame[0], cache->frame[1], cache->frame[2]);
-		/* matrix is stored row-major, needs to be transposed */
-		transpose_m3(cache->frame);
+		HAIR_frame_iter_get(frame_iter, cache->nor, cache->tan, cache->cotan);
+		
+		/* for rendering, rotate frames half-way to the next segment */
+		if (k > 0) {
+			add_v3_v3((cache-1)->nor, cache->nor);
+			mul_v3_fl((cache-1)->nor, 0.5f);
+			normalize_v3((cache-1)->nor);
+			
+			add_v3_v3((cache-1)->tan, cache->tan);
+			mul_v3_fl((cache-1)->tan, 0.5f);
+			normalize_v3((cache-1)->tan);
+			
+			add_v3_v3((cache-1)->cotan, cache->cotan);
+			mul_v3_fl((cache-1)->cotan, 0.5f);
+			normalize_v3((cache-1)->cotan);
+		}
 		
 		++cache;
 	}
@@ -310,16 +324,20 @@ static void hair_precalc_cache(HairRenderIterator *iter)
 
 void BKE_hair_render_iter_init(HairRenderIterator *iter, HairSystem *hsys)
 {
+	int maxpoints = hair_maxpoints(hsys);
+	
 	iter->hsys = hsys;
-	iter->maxpoints = hair_maxpoints(hsys);
-	iter->hair_cache = MEM_mallocN(sizeof(HairPointRenderCache) * iter->maxpoints, "hair render cache data");
 	iter->steps_per_point = 1; // XXX TODO!
+	iter->maxsteps = (maxpoints - 1) * iter->steps_per_point + 1;
+	iter->hair_cache = MEM_mallocN(sizeof(HairPointRenderCache) * maxpoints, "hair render cache data");
 	
 	iter->maxchildren = hsys->params.num_render_hairs;
 	iter->child_data = hair_gen_child_data(&hsys->params, 12345); /* TODO handle seeds properly here ... */
 	
 	iter->hair = hsys->curves;
 	iter->i = 0;
+	iter->totchildren = hsys->params.num_render_hairs;
+	iter->child = 0;
 }
 
 void BKE_hair_render_iter_init_hair(HairRenderIterator *iter)
@@ -327,11 +345,17 @@ void BKE_hair_render_iter_init_hair(HairRenderIterator *iter)
 	iter->point = iter->hair->points;
 	iter->k = 0;
 	
-	iter->step = 0;
 	iter->totsteps = (iter->hair->totpoints - 1) * iter->steps_per_point + 1;
+	iter->step = 0;
 	
-	/* fill the hair cache to avoid redundant per-child calculations */
-	hair_precalc_cache(iter);
+	/* actual new hair or just next child? */
+	if (iter->child >= iter->totchildren) {
+		iter->totchildren = iter->hsys->params.num_render_hairs; /* XXX in principle could differ per hair */
+		iter->child = 0;
+		
+		/* fill the hair cache to avoid redundant per-child calculations */
+		hair_precalc_cache(iter);
+	}
 }
 
 void BKE_hair_render_iter_end(HairRenderIterator *iter)
@@ -358,8 +382,12 @@ void BKE_hair_render_iter_next(HairRenderIterator *iter)
 	++iter->step;
 	
 	if (iter->step >= iter->totsteps) {
-		++iter->hair;
-		++iter->i;
+		++iter->child;
+		
+		if (iter->child >= iter->totchildren) {
+			++iter->hair;
+			++iter->i;
+		}
 	}
 	else if (iter->step % iter->steps_per_point == 0) {
 		++iter->point;
@@ -367,21 +395,40 @@ void BKE_hair_render_iter_next(HairRenderIterator *iter)
 	}
 }
 
-void BKE_hair_render_iter_get(HairRenderIterator *iter, float co[3], float *radius)
+void BKE_hair_render_iter_get(HairRenderIterator *iter, float r_co[3], float *r_radius)
 {
+	HairPoint *pt0 = iter->point;
+	float tan[3], cotan[3];
+	float co[3];
+	float radius;
+	
+	copy_v3_v3(co, pt0->co);
+	radius = pt0->radius;
+	
+	copy_v3_v3(tan, iter->hair_cache[iter->k].tan);
+	copy_v3_v3(cotan, iter->hair_cache[iter->k].cotan);
+	
 	if (iter->step < iter->totsteps - 1) {
+		HairPoint *pt1 = pt0 + 1;
 		int i = iter->step % iter->steps_per_point;
 		float t = (float)i / (float)iter->steps_per_point;
 		float mt = 1.0f - t;
-		HairPoint *pt0 = iter->point, *pt1 = pt0 + 1;
 		
-		interp_v3_v3v3(co, pt0->co, pt1->co, t);
-		*radius = pt0->radius * mt + pt1->radius * t;
+		interp_v3_v3v3(co, co, pt1->co, t);
+		radius = radius * mt + pt1->radius * t;
+		
+		interp_v3_v3v3(tan, tan, iter->hair_cache[iter->k + 1].tan, t);
+		interp_v3_v3v3(cotan, cotan, iter->hair_cache[iter->k + 1].cotan, t);
 	}
-	else {
-		HairPoint *pt0 = iter->point;
+	
+	/* child offset */
+	{
+		HairRenderChildData *child_data = iter->child_data + iter->child;
 		
-		copy_v3_v3(co, pt0->co);
-		*radius = pt0->radius;
+		madd_v3_v3fl(co, tan, child_data->u * radius);
+		madd_v3_v3fl(co, cotan, child_data->v * radius);
 	}
+	
+	if (r_co) copy_v3_v3(r_co, co);
+	if (r_radius) *r_radius = radius;
 }
diff --git a/source/blender/editors/space_view3d/drawhair.c b/source/blender/editors/space_view3d/drawhair.c
index e6041d6..a215220 100644
--- a/source/blender/editors/space_view3d/drawhair.c
+++ b/source/blender/editors/space_view3d/drawhair.c
@@ -95,7 +95,7 @@ static void draw_hair_render(HairSystem *hsys)
 	static unsigned int vertex_glbuf = 0;
 	static unsigned int elem_glbuf = 0;
 	
-	int maxsteps, maxverts, maxelems;
+	int maxverts, maxelems;
 	
 	float (*vertex_data)[3];
 	unsigned int *elem_data;
@@ -103,9 +103,8 @@ static void draw_hair_render(HairSystem *hsys)
 	HairRenderIterator iter;
 	
 	BKE_hair_render_iter_init(&iter, hsys);
-	maxsteps = iter.maxpoints * iter.steps_per_point;
-	maxverts = maxsteps;
-	maxelems = 2 * (maxsteps - 1);
+	maxverts = iter.maxsteps;
+	maxelems = 2 * (iter.maxsteps - 1);
 	if (maxelems < 1) {
 		BKE_hair_render_iter_end(&iter);
 		return;




More information about the Bf-blender-cvs mailing list