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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to