[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33894] trunk/blender/source/blender/ render/intern: Bugfix #24966

Ton Roosendaal ton at blender.org
Sun Dec 26 18:47:17 CET 2010


Revision: 33894
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33894
Author:   ton
Date:     2010-12-26 18:47:17 +0100 (Sun, 26 Dec 2010)

Log Message:
-----------
Bugfix #24966

Hair render: using strand "Blender Unit" size didn't correctly
clip for larger/wider strands. Now code clips strands based
on the maximum width.

Also found bad code for using clipping flags, which was mixed up,
and probably caused hair strands to be missing in cases.

Modified Paths:
--------------
    trunk/blender/source/blender/render/intern/include/render_types.h
    trunk/blender/source/blender/render/intern/include/strand.h
    trunk/blender/source/blender/render/intern/source/convertblender.c
    trunk/blender/source/blender/render/intern/source/renderdatabase.c
    trunk/blender/source/blender/render/intern/source/strand.c
    trunk/blender/source/blender/render/intern/source/zbuf.c

Modified: trunk/blender/source/blender/render/intern/include/render_types.h
===================================================================
--- trunk/blender/source/blender/render/intern/include/render_types.h	2010-12-26 13:01:02 UTC (rev 33893)
+++ trunk/blender/source/blender/render/intern/include/render_types.h	2010-12-26 17:47:17 UTC (rev 33894)
@@ -433,7 +433,9 @@
 	int overrideuv;
 	int flag, maxdepth;
 	float adaptcos, minwidth, widthfade;
-
+	
+	float maxwidth;	/* for cliptest of strands in blender unit */
+	
 	float winmat[4][4];
 	int winx, winy;
 } StrandBuffer;

Modified: trunk/blender/source/blender/render/intern/include/strand.h
===================================================================
--- trunk/blender/source/blender/render/intern/include/strand.h	2010-12-26 13:01:02 UTC (rev 33893)
+++ trunk/blender/source/blender/render/intern/include/strand.h	2010-12-26 17:47:17 UTC (rev 33894)
@@ -90,7 +90,7 @@
 
 void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
 void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
-void strand_minmax(struct StrandRen *strand, float *min, float *max);
+void strand_minmax(struct StrandRen *strand, float *min, float *max, float width);
 
 struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset);
 void free_strand_surface(struct Render *re);

Modified: trunk/blender/source/blender/render/intern/source/convertblender.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/convertblender.c	2010-12-26 13:01:02 UTC (rev 33893)
+++ trunk/blender/source/blender/render/intern/source/convertblender.c	2010-12-26 17:47:17 UTC (rev 33894)
@@ -4176,13 +4176,23 @@
 			}
 
 			if(obr->strandbuf) {
+				float width;
+				
+				/* compute average bounding box of strandpoint itself (width) */
+				if(obr->strandbuf->flag & R_STRAND_B_UNITS)
+					obr->strandbuf->maxwidth= MAX2(obr->strandbuf->ma->strand_sta, obr->strandbuf->ma->strand_end);
+				else
+					obr->strandbuf->maxwidth= 0.0f;
+				
+				width= obr->strandbuf->maxwidth;
 				sbound= obr->strandbuf->bound;
 				for(b=0; b<obr->strandbuf->totbound; b++, sbound++) {
+					
 					INIT_MINMAX(smin, smax);
 
 					for(a=sbound->start; a<sbound->end; a++) {
 						strand= RE_findOrAddStrand(obr, a);
-						strand_minmax(strand, smin, smax);
+						strand_minmax(strand, smin, smax, width);
 					}
 
 					VECCOPY(sbound->boundbox[0], smin);

Modified: trunk/blender/source/blender/render/intern/source/renderdatabase.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/renderdatabase.c	2010-12-26 13:01:02 UTC (rev 33893)
+++ trunk/blender/source/blender/render/intern/source/renderdatabase.c	2010-12-26 17:47:17 UTC (rev 33894)
@@ -1398,19 +1398,21 @@
 
 		fl= 0;
 		if(bounds) {
-			if(vec[0] > bounds[1]*vec[3]) fl |= 1;
-			if(vec[0]< bounds[0]*vec[3]) fl |= 2;
+			if(vec[0] < bounds[0]*vec[3]) fl |= 1;
+			else if(vec[0] > bounds[1]*vec[3]) fl |= 2;
+			
 			if(vec[1] > bounds[3]*vec[3]) fl |= 4;
-			if(vec[1]< bounds[2]*vec[3]) fl |= 8;
+			else if(vec[1]< bounds[2]*vec[3]) fl |= 8;
 		}
 		else {
 			if(vec[0] < -vec[3]) fl |= 1;
-			if(vec[0] > vec[3]) fl |= 2;
-			if(vec[1] < -vec[3]) fl |= 4;
-			if(vec[1] > vec[3]) fl |= 8;
+			else if(vec[0] > vec[3]) fl |= 2;
+			
+			if(vec[1] > vec[3]) fl |= 4;
+			else if(vec[1] < -vec[3]) fl |= 8;
 		}
 		if(vec[2] < -vec[3]) fl |= 16;
-		if(vec[2] > vec[3]) fl |= 32;
+		else if(vec[2] > vec[3]) fl |= 32;
 
 		flag &= fl;
 		if(flag==0) return 0;

Modified: trunk/blender/source/blender/render/intern/source/strand.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/strand.c	2010-12-26 13:01:02 UTC (rev 33893)
+++ trunk/blender/source/blender/render/intern/source/strand.c	2010-12-26 17:47:17 UTC (rev 33894)
@@ -578,7 +578,8 @@
 	}
 }
 
-static int strand_test_clip(float winmat[][4], ZSpan *zspan, float *bounds, float *co, float *zcomp)
+/* width is calculated in hoco space, to ensure strands are visible */
+static int strand_test_clip(float winmat[][4], ZSpan *zspan, float *bounds, float *co, float *zcomp, float widthx, float widthy)
 {
 	float hoco[4];
 	int clipflag= 0;
@@ -588,10 +589,11 @@
 	/* we compare z without perspective division for segment sorting */
 	*zcomp= hoco[2];
 
-	if(hoco[0] > bounds[1]*hoco[3]) clipflag |= 1;
-	else if(hoco[0]< bounds[0]*hoco[3]) clipflag |= 2;
-	else if(hoco[1] > bounds[3]*hoco[3]) clipflag |= 4;
-	else if(hoco[1]< bounds[2]*hoco[3]) clipflag |= 8;
+	if(hoco[0]+widthx < bounds[0]*hoco[3]) clipflag |= 1;
+	else if(hoco[0]-widthx > bounds[1]*hoco[3]) clipflag |= 2;
+	
+	if(hoco[1]-widthy > bounds[3]*hoco[3]) clipflag |= 4;
+	else if(hoco[1]+widthy < bounds[2]*hoco[3]) clipflag |= 8;
 
 	clipflag |= testclip(hoco);
 
@@ -826,6 +828,7 @@
 	/* for all object instances */
 	for(obi=re->instancetable.first, i=0; obi; obi=obi->next, i++) {
 		Material *ma;
+		float widthx, widthy;
 
 		obr= obi->obr;
 
@@ -848,6 +851,9 @@
 
 		if(clip_render_object(obi->obr->boundbox, bounds, winmat))
 			continue;
+		
+		widthx= obr->strandbuf->maxwidth*obwinmat[0][0];
+		widthy= obr->strandbuf->maxwidth*obwinmat[1][1];
 
 		/* for each bounding box containing a number of strands */
 		sbound= obr->strandbuf->bound;
@@ -861,14 +867,14 @@
 				svert= strand->vert;
 
 				/* keep clipping and z depth for 4 control points */
-				clip[1]= strand_test_clip(obwinmat, &zspan, bounds, svert->co, &z[1]);
-				clip[2]= strand_test_clip(obwinmat, &zspan, bounds, (svert+1)->co, &z[2]);
+				clip[1]= strand_test_clip(obwinmat, &zspan, bounds, svert->co, &z[1], widthx, widthy);
+				clip[2]= strand_test_clip(obwinmat, &zspan, bounds, (svert+1)->co, &z[2], widthx, widthy);
 				clip[0]= clip[1]; z[0]= z[1];
 
 				for(b=0; b<strand->totvert-1; b++, svert++) {
 					/* compute 4th point clipping and z depth */
 					if(b < strand->totvert-2) {
-						clip[3]= strand_test_clip(obwinmat, &zspan, bounds, (svert+2)->co, &z[3]);
+						clip[3]= strand_test_clip(obwinmat, &zspan, bounds, (svert+2)->co, &z[3], widthx, widthy);
 					}
 					else {
 						clip[3]= clip[2]; z[3]= z[2];
@@ -1025,12 +1031,22 @@
 	BLI_freelistN(&re->strandsurface);
 }
 
-void strand_minmax(StrandRen *strand, float *min, float *max)
+void strand_minmax(StrandRen *strand, float *min, float *max, float width)
 {
 	StrandVert *svert;
+	float vec[3], width2= 2.0f*width;
 	int a;
 
-	for(a=0, svert=strand->vert; a<strand->totvert; a++, svert++)
-		DO_MINMAX(svert->co, min, max)
+	for(a=0, svert=strand->vert; a<strand->totvert; a++, svert++) {
+		VECCOPY(vec, svert->co);
+		DO_MINMAX(vec, min, max);
+		
+		if(width!=0.0f) {
+			vec[0]+= width; vec[1]+= width; vec[2]+= width;
+			DO_MINMAX(vec, min, max);
+			vec[0]-= width2; vec[1]-= width2; vec[2]-= width2;
+			DO_MINMAX(vec, min, max);
+		}
+	}
 }
 

Modified: trunk/blender/source/blender/render/intern/source/zbuf.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/zbuf.c	2010-12-26 13:01:02 UTC (rev 33893)
+++ trunk/blender/source/blender/render/intern/source/zbuf.c	2010-12-26 17:47:17 UTC (rev 33894)
@@ -243,14 +243,14 @@
 	   prevents issues with vertices lying exact on borders */
 	abs4= fabs(v[3]) + FLT_EPSILON;
 	
-	if(v[2]< -abs4) c=16;			/* this used to be " if(v[2]<0) ", see clippz() */
-	else if(v[2]> abs4) c+= 32;
+	if( v[0] < -abs4) c+=1;
+	else if( v[0] > abs4) c+=2;
 	
-	if( v[0]>abs4) c+=2;
-	else if( v[0]< -abs4) c+=1;
+	if( v[1] > abs4) c+=4;
+	else if( v[1] < -abs4) c+=8;
 	
-	if( v[1]>abs4) c+=4;
-	else if( v[1]< -abs4) c+=8;
+	if(v[2] < -abs4) c+=16;			/* this used to be " if(v[2]<0) ", see clippz() */
+	else if(v[2]> abs4) c+= 32;
 	
 	return c;
 }
@@ -1782,10 +1782,10 @@
 		projectvert(co, winmat, ho);
 
 		wco= ho[3];
-		if(ho[0] > bounds[1]*wco) clipflag |= 1;
-		else if(ho[0]< bounds[0]*wco) clipflag |= 2;
+		if(ho[0] < bounds[0]*wco) clipflag |= 1;
+		else if(ho[0] > bounds[1]*wco) clipflag |= 2;
 		if(ho[1] > bounds[3]*wco) clipflag |= 4;
-		else if(ho[1]< bounds[2]*wco) clipflag |= 8;
+		else if(ho[1] < bounds[2]*wco) clipflag |= 8;
 
 		QUATCOPY(cache[cindex].ho, ho);
 		cache[cindex].clip= clipflag;





More information about the Bf-blender-cvs mailing list