[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17466] branches/sim_physics/source/ blender/render/intern: cleaned some code and split volume precaching into a new file

Matt Ebb matt at mke3.net
Sat Nov 15 05:16:49 CET 2008


Revision: 17466
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17466
Author:   broken
Date:     2008-11-15 05:16:46 +0100 (Sat, 15 Nov 2008)

Log Message:
-----------
cleaned some code and split volume precaching into a new file

Modified Paths:
--------------
    branches/sim_physics/source/blender/render/intern/include/volumetric.h
    branches/sim_physics/source/blender/render/intern/source/volumetric.c

Added Paths:
-----------
    branches/sim_physics/source/blender/render/intern/include/volume_precache.h
    branches/sim_physics/source/blender/render/intern/source/volume_precache.c

Added: branches/sim_physics/source/blender/render/intern/include/volume_precache.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/volume_precache.h	                        (rev 0)
+++ branches/sim_physics/source/blender/render/intern/include/volume_precache.h	2008-11-15 04:16:46 UTC (rev 17466)
@@ -0,0 +1,30 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Matt Ebb.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+ 
+void volume_precache(Render *re);
+void free_volume_precache(Render *re);
\ No newline at end of file

Modified: branches/sim_physics/source/blender/render/intern/include/volumetric.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/volumetric.h	2008-11-15 02:58:47 UTC (rev 17465)
+++ branches/sim_physics/source/blender/render/intern/include/volumetric.h	2008-11-15 04:16:46 UTC (rev 17466)
@@ -21,12 +21,23 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): Farsthary (Raul FHernandez), Matt Ebb.
+ * Contributor(s): Matt Ebb.
  *
  * ***** END GPL LICENSE BLOCK *****
  */
 
+float vol_get_stepsize(struct ShadeInput *shi, int context);
+float vol_get_density(struct ShadeInput *shi, float *co);
+void vol_get_scattering(ShadeInput *shi, float *scatter, float *co, float stepsize, float density);
+
 void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr);
 void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is);
-void volume_precache(Render *re);
-void free_volume_precache(Render *re);
\ No newline at end of file
+
+#define STEPSIZE_VIEW	0
+#define STEPSIZE_SHADE	1
+
+#define VOL_IS_BACKFACE			1
+#define VOL_IS_SAMEMATERIAL		2
+
+#define VOL_BOUNDS_DEPTH	0
+#define VOL_BOUNDS_SS		1
\ No newline at end of file

Added: branches/sim_physics/source/blender/render/intern/source/volume_precache.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/volume_precache.c	                        (rev 0)
+++ branches/sim_physics/source/blender/render/intern/source/volume_precache.c	2008-11-15 04:16:46 UTC (rev 17466)
@@ -0,0 +1,356 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Matt Ebb.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "PIL_time.h"
+
+#include "RE_shader_ext.h"
+#include "RE_raytrace.h"
+
+#include "DNA_material_types.h"
+
+#include "render_types.h"
+#include "renderdatabase.h"
+#include "volumetric.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+
+/* Recursive test for intersections, from a point inside the mesh, to outside
+ * Number of intersections (depth) determine if a point is inside or outside the mesh */
+int intersect_outside_volume(RayTree *tree, Isect *isect, float *offset, int limit, int depth)
+{
+	if (limit == 0) return depth;
+	
+	if (RE_ray_tree_intersect(tree, isect)) {
+		float hitco[3];
+		
+		hitco[0] = isect->start[0] + isect->labda*isect->vec[0];
+		hitco[1] = isect->start[1] + isect->labda*isect->vec[1];
+		hitco[2] = isect->start[2] + isect->labda*isect->vec[2];
+		VecAddf(isect->start, hitco, offset);
+
+		return intersect_outside_volume(tree, isect, offset, limit-1, depth+1);
+	} else {
+		return depth;
+	}
+}
+
+/* Uses ray tracing to check if a point is inside or outside an ObjectInstanceRen */
+int point_inside_obi(RayTree *tree, ObjectInstanceRen *obi, float *co)
+{
+	float maxsize = RE_ray_tree_max_size(tree);
+	Isect isect;
+	float vec[3] = {0.0f,0.0f,1.0f};
+	int final_depth=0, depth=0, limit=20;
+	
+	/* set up the isect */
+	memset(&isect, 0, sizeof(isect));
+	VECCOPY(isect.start, co);
+	isect.end[0] = co[0] + vec[0] * maxsize;
+	isect.end[1] = co[1] + vec[1] * maxsize;
+	isect.end[2] = co[2] + vec[2] * maxsize;
+	
+	/* and give it a little offset to prevent self-intersections */
+	VecMulf(vec, 1e-5);
+	VecAddf(isect.start, isect.start, vec);
+	
+	isect.mode= RE_RAY_MIRROR;
+	isect.face_last= NULL;
+	isect.lay= -1;
+	
+	final_depth = intersect_outside_volume(tree, &isect, vec, limit, depth);
+	
+	/* even number of intersections: point is outside
+	 * odd number: point is inside */
+	if (final_depth % 2 == 0) return 0;
+	else return 1;
+}
+
+static int inside_check_func(Isect *is, int ob, RayFace *face)
+{
+	return 1;
+}
+static void vlr_face_coords(RayFace *face, float **v1, float **v2, float **v3, float **v4)
+{
+	VlakRen *vlr= (VlakRen*)face;
+
+	*v1 = (vlr->v1)? vlr->v1->co: NULL;
+	*v2 = (vlr->v2)? vlr->v2->co: NULL;
+	*v3 = (vlr->v3)? vlr->v3->co: NULL;
+	*v4 = (vlr->v4)? vlr->v4->co: NULL;
+}
+
+RayTree *create_raytree_obi(ObjectInstanceRen *obi, float *bbmin, float *bbmax)
+{
+	int v;
+	VlakRen *vlr= NULL;
+	
+	/* create empty raytree */
+	RayTree *tree = RE_ray_tree_create(64, obi->obr->totvlak, bbmin, bbmax,
+		vlr_face_coords, inside_check_func, NULL, NULL);
+	
+	/* fill it with faces */
+	for(v=0; v<obi->obr->totvlak; v++) {
+		if((v & 255)==0)
+			vlr= obi->obr->vlaknodes[v>>8].vlak;
+		else
+			vlr++;
+	
+		RE_ray_tree_add_face(tree, 0, vlr);
+	}
+	
+	RE_ray_tree_done(tree);
+	
+	return tree;
+}
+
+static float get_avg_surrounds(float *cache, int res, int res_2, int res_3, int rgb, int xx, int yy, int zz)
+{
+	int x, y, z, x_, y_, z_;
+	int added=0;
+	float tot=0.0f;
+	int i;
+	
+	for (x=-1; x <= 1; x++) {
+		x_ = xx+x;
+		if (x_ >= 0 && x_ <= res-1) {
+		
+			for (y=-1; y <= 1; y++) {
+				y_ = yy+y;
+				if (y_ >= 0 && y_ <= res-1) {
+				
+					for (z=-1; z <= 1; z++) {
+						z_ = zz+z;
+						if (z_ >= 0 && z_ <= res-1) {
+						
+							i = rgb*res_3 + x_*res_2 + y_*res + z_;
+							if (cache[i] > 0.0f) {
+								tot += cache[i];
+								added++;
+							}
+							
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	tot /= added;
+	
+	return ((added>0)?tot:0.0f);
+}
+
+/* function to filter the edges of the light cache, where there was no volume originally.
+ * For each voxel which was originally external to the mesh, it finds the average values of
+ * the surrounding internal voxels and sets the original external voxel to that average amount.
+ * Works almost a bit like a 'dilate' filter */
+static void lightcache_filter(float *cache, int res)
+{
+	int x, y, z, rgb;
+	int res_2, res_3;
+	int i;
+	
+	res_2 = res*res;
+	res_3 = res*res*res;
+
+	for (x=0; x < res; x++) {
+		for (y=0; y < res; y++) {
+			for (z=0; z < res; z++) {
+				for (rgb=0; rgb < 3; rgb++) {
+					i = rgb*res_3 + x*res_2 + y*res + z;
+
+					/* trigger for outside mesh */
+					if (cache[i] < 0.5f) cache[i] = get_avg_surrounds(cache, res, res_2, res_3, rgb, x, y, z);
+				}
+			}
+		}
+	}
+}
+
+/* Precache a volume into a 3D voxel grid.
+ * The voxel grid is stored in the ObjectInstanceRen, 
+ * in camera space, aligned with the ObjectRen's bounding box.
+ * Resolution is defined by the user.
+ */
+void vol_precache_objectinstance(Render *re, ObjectInstanceRen *obi, Material *ma, float *bbmin, float *bbmax)
+{
+	int x, y, z;
+
+	float co[3], voxel[3], scatter_col[3];
+	ShadeInput shi;
+	float view[3] = {0.0,0.0,-1.0};
+	float density;
+	float stepsize;
+	
+	float resf, res_3f;
+	int res_2, res_3;
+	
+	float i = 1.0f;
+	double time, lasttime= PIL_check_seconds_timer();
+	const int res = ma->vol_precache_resolution;
+	RayTree *tree;
+	
+	R = *re;
+
+	/* create a raytree with just the faces of the instanced ObjectRen, 
+	 * used for checking if the cached point is inside or outside. */
+	tree = create_raytree_obi(obi, bbmin, bbmax);
+	if (!tree) return;
+
+	/* Need a shadeinput to calculate scattering */
+	memset(&shi, 0, sizeof(ShadeInput)); 
+	shi.depth= 1;
+	shi.mask= 1;
+	shi.mat = ma;
+	shi.vlr = NULL;
+	memcpy(&shi.r, &shi.mat->r, 23*sizeof(float));	// note, keep this synced with render_types.h
+	shi.har= shi.mat->har;
+	shi.obi= obi;
+	shi.obr= obi->obr;
+	shi.lay = re->scene->lay;
+	VECCOPY(shi.view, view);
+	
+	stepsize = vol_get_stepsize(&shi, STEPSIZE_VIEW);
+
+	resf = (float)res;
+	res_2 = res*res;
+	res_3 = res*res*res;
+	res_3f = (float)res_3;
+	
+	VecSubf(voxel, bbmax, bbmin);
+	if ((voxel[0] < FLT_EPSILON) || (voxel[1] < FLT_EPSILON) || (voxel[2] < FLT_EPSILON))
+		return;
+	VecMulf(voxel, 1.0f/res);
+	
+	obi->volume_precache = MEM_callocN(sizeof(float)*res_3*3, "volume light cache");
+	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list