Revision: 17152 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17152 Author: unclezeiv Date: 2008-10-21 22:21:48 +0200 (Tue, 21 Oct 2008)
Log Message: ----------- Minor improvement: implemented a new function to provide bounding cones for clusters of oriented lights. This should lead to tighter bounds and, ultimately, to better light trees, according to the paper "Fast Agglomerative Clustering" (http://www.graphics.cornell.edu/~bjw/papers.html). Also added yet another check for nan values in VPLs. Modified Paths: -------------- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c Modified: branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c =================================================================== --- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 2008-10-21 17:59:56 UTC (rev 17151) +++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 2008-10-21 20:21:48 UTC (rev 17152) @@ -147,6 +147,8 @@ /* cone_* variables only for oriented lights */ float cone_dir[3]; /* store normalized */ float cone_angle; + float cone_min[3]; /* for auxiliary bounding box */ + float cone_max[3]; float luminance; short falloff_type, sphere; float falloff_dist; @@ -275,9 +277,40 @@ static void add_virtual_point_light(Render * re, LightcutsData *lcd, LampRen *orig, float *col, short lev, float weight); -/* XXX: this function looks really slow! */ -static float get_bounding_cone(LightcutsCluster * one, LightcutsCluster * two, float *vec) +static float get_bounding_cone_cos(LightcutsCluster * dest, LightcutsCluster * one, LightcutsCluster * two) { + float diag[3], center[3], dist, rad_sq; + float cone_min[3], cone_max[3]; + + /* update auxiliary bounding box */ + VECCOPY(cone_min, one->cone_min); + VECCOPY(cone_max, one->cone_max); + DO_MINMAX(two->cone_min, cone_min, cone_max); + DO_MINMAX(two->cone_max, cone_min, cone_max); + + VECSUB(diag, cone_max, cone_min); + VECADDFAC(center, cone_min, diag, 0.5f); + + if (dest) { + VECCOPY(dest->cone_dir, center); + Normalize(dest->cone_dir); + VECCOPY(dest->cone_min, cone_min); + VECCOPY(dest->cone_max, cone_max); + } + + dist= sqrt(VEC_LEN_SQ(center)); + rad_sq= VEC_LEN_SQ(diag) * 0.25f; + + /* center and radius of circle in intersection */ + if (sqrt(rad_sq) > dist + 1.0f) + return -1; + + return 0.5f * ((1.0f - rad_sq) / dist + dist); +} + +#if 0 +static float get_bounding_cone_old(LightcutsCluster * dest, LightcutsCluster * one, LightcutsCluster * two) +{ float angle, angle_new; angle= NormalizedVecAngle2(one->cone_dir, two->cone_dir); @@ -286,18 +319,19 @@ if (angle > angle_new) angle_new= (angle + angle_new) * 0.5f; - if (vec) { + if (dest) { float axis[3]; float mat[3][3]; - VECCOPY(vec, one->cone_dir); + VECCOPY(dest->cone_dir, one->cone_dir); Crossf(axis, one->cone_dir, two->cone_dir); /* TODO: XXX: check signs */ VecRotToMat3(axis, angle_new, mat); - Mat3MulVecfl(mat, vec); + Mat3MulVecfl(mat, dest->cone_dir); } return angle_new; } +#endif static float lightcuts_compute_metric(float csq, LightcutsCluster * one, LightcutsCluster * two) { @@ -312,7 +346,7 @@ VECSUB(diff, max, min); if (one->type == CLUSTER_SPOT) { - float cos_a= cosf(get_bounding_cone(one, two, NULL)); + float cos_a= get_bounding_cone_cos(NULL, one, two); float term = (1 - cos_a) * (1 - cos_a); return (one->luminance + two->luminance) * (VEC_LEN_SQ(diff) + csq * term); } @@ -365,7 +399,7 @@ /* if LA_SPOT, compute new bounding cone */ if (one->type == CLUSTER_SPOT) - dest->cone_angle= get_bounding_cone(one, two, dest->cone_dir); + dest->cone_angle= acosf(get_bounding_cone_cos(dest, one, two)); /* worst case falloff type/dist for conservative error estimation */ dest->falloff_type= falloff_merge[one->falloff_type][two->falloff_type]; @@ -438,7 +472,7 @@ } if (!found) - printf("BUG: no representative selected for %d: tot_lum %f\n", one->id, tot_lum); + printf("BUG: no representative selected for %d (%d + %d): tot_lum %f\n", dest->id, one->id, two->id, tot_lum); } /* sort list and allocate list */ @@ -595,6 +629,8 @@ VECCOPY(clus->min, lar->co); VECCOPY(clus->max, lar->co); VECCOPY(clus->cone_dir, lar->vec); + VECCOPY(clus->cone_min, lar->vec); + VECCOPY(clus->cone_max, lar->vec); clus->cone_angle= 0.0f; break; } @@ -1565,6 +1601,11 @@ } // #endif + if (isnan(fac)) { + lcd->stat_discard_nan++; + return; + } + lar= MEM_callocN(sizeof(LampRen), "lampren"); lamp_init(re, lar); lar->dist= lcd->indir_dist; _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs