Revision: 27141
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27141
Author:   blendix
Date:     2010-02-25 21:21:09 +0100 (Thu, 25 Feb 2010)

Log Message:
-----------
Render Branch: fix for lowres raytracing of instanced objects, and some
cache test code that's still disabled.

Modified Paths:
--------------
    branches/render25/source/blender/render/intern/include/cache.h
    branches/render25/source/blender/render/intern/include/render_types.h
    branches/render25/source/blender/render/intern/source/cache.c
    branches/render25/source/blender/render/intern/source/convertblender.c
    branches/render25/source/blender/render/intern/source/rayshade.c

Modified: branches/render25/source/blender/render/intern/include/cache.h
===================================================================
--- branches/render25/source/blender/render/intern/include/cache.h      
2010-02-25 16:08:32 UTC (rev 27140)
+++ branches/render25/source/blender/render/intern/include/cache.h      
2010-02-25 20:21:09 UTC (rev 27141)
@@ -92,5 +92,12 @@
        IrrCache *cache, float *ao, float env[3], float indirect[3],
        float P[3], float dPdu[3], float dPdv[3], float N[3], int do_sample);
 
+/* Radiosity Cache */
+
+void radio_cache_create(struct Render *re, int thread);
+void radio_cache_free(struct RenderDB *rdb, int thread);
+int radio_cache_lookup(struct Render *re, struct ShadeInput *shi, float 
color[3], float raylength);
+void radio_cache_add(struct Render *re, struct ShadeInput *shi, float 
color[3]);
+
 #endif /* __RENDER_CACHE_H__ */
 

Modified: branches/render25/source/blender/render/intern/include/render_types.h
===================================================================
--- branches/render25/source/blender/render/intern/include/render_types.h       
2010-02-25 16:08:32 UTC (rev 27140)
+++ branches/render25/source/blender/render/intern/include/render_types.h       
2010-02-25 20:21:09 UTC (rev 27141)
@@ -47,6 +47,7 @@
 struct MemArena;
 struct Object;
 struct ObjectInstanceRen;
+struct RadioCache;
 struct RayFace;
 struct RayObject;
 struct VlakPrimitive;
@@ -110,6 +111,7 @@
 
        /* irradiance cache for AO/env/indirect */
        struct IrrCache *irrcache[BLENDER_MAX_THREADS];
+       struct RadioCache *radiocache[BLENDER_MAX_THREADS];
 } RenderDB;
 
 typedef struct RenderSampleData {

Modified: branches/render25/source/blender/render/intern/source/cache.c
===================================================================
--- branches/render25/source/blender/render/intern/source/cache.c       
2010-02-25 16:08:32 UTC (rev 27140)
+++ branches/render25/source/blender/render/intern/source/cache.c       
2010-02-25 20:21:09 UTC (rev 27141)
@@ -408,8 +408,6 @@
 #define MAX_ERROR_K                            1.0f
 #define WEIGHT_NORMAL_DENOM            65.823047821929777f             /* 1/(1 
- cos(10°)) */
 #define SINGULAR_VALUE_EPSILON 1e-4f
-#define LSQ_RECONSTRUCTION
-#define NEIGHBOUR_CLAMP
 
 /* Data Structures */
 
@@ -442,10 +440,15 @@
        MemArena *arena;                        /* memory arena for nodes and 
samples */
        int thread;                                     /* thread owning the 
cache */
 
-       /* test: a stable global coordinate system may help */
        int totsample;
        int totlookup;
        int totpost;
+
+       /* options */
+       int neighbour_clamp;
+       int lsq_reconstruction;
+
+       /* test: a stable global coordinate system may help */
 };
 
 typedef struct Lsq4DFit {
@@ -526,6 +529,10 @@
        cache->stacksize= 10;
        cache->stack= MEM_mallocN(sizeof(IrrCacheNode*)*cache->stacksize*8, 
"IrrCache stack");
 
+       /* options */
+       cache->lsq_reconstruction= 1;
+       cache->neighbour_clamp= 1;
+
        return cache;
 }
 
@@ -575,7 +582,6 @@
        if(indirect) copy_v3_v3(indirect, C+4);
 }
 
-#ifdef NEIGHBOUR_CLAMP
 /* Neighbour Clamping [Křivánek 2006] */
 
 static void irr_cache_clamp_sample(IrrCache *cache, IrrCacheSample *nsample)
@@ -615,7 +621,6 @@
                }
        }
 }
-#endif
 
 /* Add a Sample */
 
@@ -642,11 +647,11 @@
                sample->dP= Rmean;
                irr_sample_set(sample->C, ao, env, indirect);
 
-#ifdef NEIGHBOUR_CLAMP
-               /* neighbour clamping trick */
-               irr_cache_clamp_sample(cache, sample);
-               Rmean= sample->dP; /* copy dP back so we get the right place in 
the octree */
-#endif
+               if(cache->neighbour_clamp) {
+                       /* neighbour clamping trick */
+                       irr_cache_clamp_sample(cache, sample);
+                       Rmean= sample->dP; /* copy dP back so we get the right 
place in the octree */
+               }
 
                /* error multiplier */
                Rmean /= MAX_ERROR_K;
@@ -695,10 +700,8 @@
        IrrCacheNode *node, **stack, **stacknode;
        float accum[CACHE_DIMENSION], P[3], N[3], totw;
        float discard_weight, maxdist, distfac;
-       int i, added= 0, totfound= 0;
-#ifdef LSQ_RECONSTRUCTION
+       int i, added= 0, totfound= 0, use_lsq;
        Lsq4DFit lsq;
-#endif
 
        /* XXX check how often this is called! */
        /* XXX can identical samples end up in the cache now? */
@@ -718,12 +721,13 @@
        stacknode= stack;
        *stacknode++= &cache->root;
 
-#ifdef LSQ_RECONSTRUCTION
-       memset(&lsq, 0, sizeof(lsq));
-#else
-       memset(accum, 0, sizeof(accum));
-#endif
+       use_lsq= cache->lsq_reconstruction;
 
+       if(use_lsq)
+               memset(&lsq, 0, sizeof(lsq));
+       else
+               memset(accum, 0, sizeof(accum));
+
        /* the motivation for this factor is that in preprocess we only require
           one sample for lookup not to fail, whereas for least squares
           reconstruction we need more samples for a proper reconstruction. it's
@@ -776,14 +780,14 @@
 
                        if(w > BLI_thread_frand(cache->thread)*discard_weight) {
                                if(!preprocess) {
-#ifdef LSQ_RECONSTRUCTION
-                                       float a[4]= {D[0], D[1], D[2], 1.0f};
-
-                                       lsq_4D_add(&lsq, a, sample->C, w);
-#else
-                                       for(i=0; i<CACHE_DIMENSION; i++)
-                                               accum[i] += w*sample->C[i];
-#endif
+                                       if(use_lsq) {
+                                               float a[4]= {D[0], D[1], D[2], 
1.0f};
+                                               lsq_4D_add(&lsq, a, sample->C, 
w);
+                                       }
+                                       else {
+                                               for(i=0; i<CACHE_DIMENSION; i++)
+                                                       accum[i] += 
w*sample->C[i];
+                                       }
                                }
 
                                totw += w;
@@ -803,14 +807,15 @@
        /* do we have anything ? */
        if(totw > EPSILON && totfound >= 1) {
                if(!preprocess) {
-#ifdef LSQ_RECONSTRUCTION
-                       lsq_4D_solve(&lsq, accum);
-#else
-                       float invw= 1.0/totw;
+                       if(use_lsq) {
+                               lsq_4D_solve(&lsq, accum);
+                       }
+                       else {
+                               float invw= 1.0/totw;
 
-                       for(i=0; i<CACHE_DIMENSION; i++)
-                               accum[i] *= invw;
-#endif
+                               for(i=0; i<CACHE_DIMENSION; i++)
+                                       accum[i] *= invw;
+                       }
 
                        irr_sample_get(accum, ao, env, indirect);
                }
@@ -842,6 +847,8 @@
        if(!((re->db.wrld.aomode & WO_AOCACHE) && (re->db.wrld.mode & 
(WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT))))
                return;
 
+       //radio_cache_create(re, pa->thread);
+
        cache= irr_cache_new(re, pa->thread);
        re->db.irrcache[pa->thread]= cache;
 
@@ -897,9 +904,9 @@
                                                }
                                        }
                                }
+
+                               if(re->cb.test_break(re->cb.tbh)) break;
                        }
-
-                       if(re->cb.test_break(re->cb.tbh)) break;
                }
 
                step /= 2;
@@ -916,5 +923,313 @@
                irr_cache_delete(cache);
                re->db.irrcache[pa->thread]= NULL;
        }
+
+       radio_cache_free(&re->db, pa->thread);
 }
 
+/****************************** Radiosity Cache ******************************/
+
+#if 0
+#define RADIO_CACHE_MAX_CHILD  8
+
+/* Data Structures */
+
+typedef struct RadioCacheSample {
+       /* cache sample in a node */
+       struct RadioCacheSample *next;
+
+       float P[3];
+       float C[3];
+} RadioCacheSample;
+
+typedef struct RadioCacheNode {
+       /* node in the cache tree */
+       float center[3];                                        /* center of 
node */
+       float side;                                                     /* max 
side length */
+       RadioCacheSample *samples;                      /* samples in the node 
*/
+       struct RadioCacheNode *children[8];     /* child nodes */
+       int totsample;
+} RadioCacheNode;
+
+typedef struct RadioCache {
+       /* radioadiance cache */
+       RadioCacheNode root;                    /* root node of the tree */
+       int maxdepth;                           /* maximum tree dist */
+
+       RadioCacheNode **stack;         /* stack for traversal */
+       int stacksize;                          /* stack size */
+
+       MemArena *arena;                        /* memory arena for nodes and 
samples */
+       int thread;                                     /* thread owning the 
cache */
+
+       int totsample;
+       int totlookup;
+} RadioCache;
+
+/* Create and Free */
+
+void radio_cache_create(Render *re, int thread)
+{
+       RadioCache *cache;
+       float bb[2][3];
+
+       cache= MEM_callocN(sizeof(RadioCache), "RadioCache");
+       cache->thread= thread;
+       cache->maxdepth= 1;
+
+       cache->arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+       BLI_memarena_use_calloc(cache->arena);
+
+       /* initialize root node with bounds */
+       render_instances_bound(&re->db, bb);
+       mid_v3_v3v3(cache->root.center, bb[0], bb[1]);
+       cache->root.side= MAX3(bb[1][0]-bb[0][0], bb[1][1]-bb[0][1], 
bb[1][2]-bb[0][2]);
+
+       /* allocate stack */
+       cache->stacksize= 10;
+       cache->stack= MEM_mallocN(sizeof(RadioCacheNode*)*cache->stacksize*8, 
"RadioCache stack");
+
+       re->db.radiocache[thread]= cache;
+}
+
+void radio_cache_free(RenderDB *rdb, int thread)
+{
+       RadioCache *cache= rdb->radiocache[thread];
+
+       if(cache) {
+               printf("radio cache %d/%d, efficiency %f\n", cache->totsample, 
cache->totlookup, (float)cache->totsample/(float)cache->totlookup);
+
+               BLI_memarena_free(cache->arena);
+               MEM_freeN(cache->stack);
+               MEM_freeN(cache);
+               
+               rdb->radiocache[thread]= NULL;
+       }
+}
+
+void radio_cache_check_stack(RadioCache *cache)
+{
+       /* increase stack size as more nodes are added */
+       if(cache->maxdepth > cache->stacksize) {
+               cache->stacksize= cache->maxdepth + 5;
+               MEM_freeN(cache->stack);
+               cache->stack= 
MEM_mallocN(sizeof(RadioCacheNode*)*cache->stacksize*8, "RadioCache stack");
+       }
+}
+
+static int radio_cache_node_point_inside(RadioCacheNode *node, float scale, 
float add, float P[3])
+{
+       float side= node->side*scale + add;
+
+       return (((node->center[0] + side) > P[0]) &&
+               ((node->center[1] + side) > P[1]) &&
+               ((node->center[2] + side) > P[2]) &&
+               ((node->center[0] - side) < P[0]) &&
+               ((node->center[1] - side) < P[1]) &&
+               ((node->center[2] - side) < P[2]));
+}
+
+void radio_cache_add(Render *re, ShadeInput *shi, float C[3])
+{
+       RadioCache *cache= re->db.radiocache[shi->shading.thread];
+       RadioCacheSample *sample;
+       RadioCacheNode *node;
+       float P[3];
+       int i, j, depth;
+
+       if(!cache)
+               return;
+
+       sample= BLI_memarena_alloc(cache->arena, sizeof(RadioCacheSample));
+
+       /* record the data */
+       copy_v3_v3(P, shi->geometry.co);
+       copy_v3_v3(sample->P, P);
+       copy_v3_v3(sample->C, C);
+
+       /* insert the new sample into the cache */
+       node= &cache->root;
+       depth= 0;
+       while(node->totsample > RADIO_CACHE_MAX_CHILD) {
+               depth++;
+
+               j= 0;
+               for(i=0; i<3; i++)
+                       if(P[i] > node->center[i])
+                               j |= 1 << i;
+
+               if(node->children[j] == NULL) {
+                       RadioCacheNode *nnode= BLI_memarena_alloc(cache->arena, 
sizeof(RadioCacheNode));
+
+                       for(i=0; i<3; i++) {
+                               float fac= (P[i] > node->center[i])? 0.25f: 
-0.25f;
+                               nnode->center[i]= node->center[i] + 
fac*node->side;
+                       }
+
+                       nnode->side= node->side*0.5f;
+                       node->children[j]= nnode;
+               }
+
+               node= node->children[j];
+       }
+
+       sample->next= node->samples;
+       node->samples= sample;
+       node->totsample++;
+
+       cache->maxdepth= MAX2(depth, cache->maxdepth);
+       radio_cache_check_stack(cache);
+
+       cache->totsample++;
+}
+
+/* Lookup */
+
+int radio_cache_lookup(Render *re, ShadeInput *shi, float C[3], float 
raylength)
+{
+       RadioCache *cache= re->db.radiocache[shi->shading.thread];
+       RadioCacheSample *sample;
+       RadioCacheNode *node, **stack, **stacknode;
+       float P[3], accum[3], totw, maxdist;
+       int i, totfound= 0;
+
+       if(!cache)
+               return 0;
+
+       cache->totlookup++;
+

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