Blender V2.61 - r43446

shadbuf.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * Contributor(s): 2004-2006, Blender Foundation
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00031 #include <math.h>
00032 #include <string.h>
00033 
00034 
00035 #include "MEM_guardedalloc.h"
00036 
00037 #include "DNA_group_types.h"
00038 #include "DNA_lamp_types.h"
00039 #include "DNA_material_types.h"
00040 
00041 #include "BKE_global.h"
00042 #include "BKE_scene.h"
00043 
00044 
00045 #include "BLI_math.h"
00046 #include "BLI_blenlib.h"
00047 #include "BLI_jitter.h"
00048 #include "BLI_memarena.h"
00049 #include "BLI_rand.h"
00050 #include "BLI_utildefines.h"
00051 
00052 #include "PIL_time.h"
00053 
00054 #include "renderpipeline.h"
00055 #include "render_types.h"
00056 #include "renderdatabase.h"
00057 #include "rendercore.h"
00058 #include "shadbuf.h"
00059 #include "shading.h"
00060 #include "zbuf.h"
00061 
00062 /* XXX, could be better implemented... this is for endian issues
00063 */
00064 #ifdef __BIG_ENDIAN__
00065 #  define RCOMP 3
00066 #  define GCOMP 2
00067 #  define BCOMP 1
00068 #  define ACOMP 0
00069 #else
00070 #  define RCOMP 0
00071 #  define GCOMP 1
00072 #  define BCOMP 2
00073 #  define ACOMP 3
00074 #endif
00075 
00076 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
00077 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
00078 /* only to be used here in this file, it's for speed */
00079 extern struct Render R;
00080 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
00081 
00082 /* ------------------------------------------------------------------------- */
00083 
00084 /* initshadowbuf() in convertBlenderScene.c */
00085 
00086 /* ------------------------------------------------------------------------- */
00087 
00088 static void copy_to_ztile(int *rectz, int size, int x1, int y1, int tile, char *r1)
00089 {
00090     int len4, *rz;  
00091     int x2, y2;
00092     
00093     x2= x1+tile;
00094     y2= y1+tile;
00095     if(x2>=size) x2= size-1;
00096     if(y2>=size) y2= size-1;
00097 
00098     if(x1>=x2 || y1>=y2) return;
00099 
00100     len4= 4*(x2- x1);
00101     rz= rectz + size*y1 + x1;
00102     for(; y1<y2; y1++) {
00103         memcpy(r1, rz, len4);
00104         rz+= size;
00105         r1+= len4;
00106     }
00107 }
00108 
00109 #if 0
00110 static int sizeoflampbuf(ShadBuf *shb)
00111 {
00112     int num,count=0;
00113     char *cp;
00114     
00115     cp= shb->cbuf;
00116     num= (shb->size*shb->size)/256;
00117 
00118     while(num--) count+= *(cp++);
00119     
00120     return 256*count;
00121 }
00122 #endif
00123 
00124 /* not threadsafe... */
00125 static float *give_jitter_tab(int samp)
00126 {
00127     /* these are all possible jitter tables, takes up some
00128      * 12k, not really bad!
00129      * For soft shadows, it saves memory and render time
00130      */
00131     static int tab[17]={1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256};
00132     static float jit[1496][2];
00133     static char ctab[17]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00134     int a, offset=0;
00135     
00136     if(samp<2) samp= 2;
00137     else if(samp>16) samp= 16;
00138 
00139     for(a=0; a<samp-1; a++) offset+= tab[a];
00140 
00141     if(ctab[samp]==0) {
00142         ctab[samp]= 1;
00143         BLI_initjit(jit[offset], samp*samp);
00144     }
00145         
00146     return jit[offset];
00147     
00148 }
00149 
00150 static void make_jitter_weight_tab(Render *re, ShadBuf *shb, short filtertype) 
00151 {
00152     float *jit, totw= 0.0f;
00153     int samp= get_render_shadow_samples(&re->r, shb->samp);
00154     int a, tot=samp*samp;
00155     
00156     shb->weight= MEM_mallocN(sizeof(float)*tot, "weight tab lamp");
00157     
00158     for(jit= shb->jit, a=0; a<tot; a++, jit+=2) {
00159         if(filtertype==LA_SHADBUF_TENT) 
00160             shb->weight[a]= 0.71f - sqrt(jit[0]*jit[0] + jit[1]*jit[1]);
00161         else if(filtertype==LA_SHADBUF_GAUSS) 
00162             shb->weight[a]= RE_filter_value(R_FILTER_GAUSS, 1.8f*sqrt(jit[0]*jit[0] + jit[1]*jit[1]));
00163         else
00164             shb->weight[a]= 1.0f;
00165         
00166         totw+= shb->weight[a];
00167     }
00168     
00169     totw= 1.0f/totw;
00170     for(a=0; a<tot; a++) {
00171         shb->weight[a]*= totw;
00172     }
00173 }
00174 
00175 static int verg_deepsample(const void *poin1, const void *poin2)
00176 {
00177     const DeepSample *ds1= (const DeepSample*)poin1;
00178     const DeepSample *ds2= (const DeepSample*)poin2;
00179 
00180     if(ds1->z < ds2->z) return -1;
00181     else if(ds1->z == ds2->z) return 0;
00182     else return 1;
00183 }
00184 
00185 static int compress_deepsamples(DeepSample *dsample, int tot, float epsilon)
00186 {
00187     /* uses doubles to avoid overflows and other numerical issues,
00188        could be improved */
00189     DeepSample *ds, *newds;
00190     float v;
00191     double slope, slopemin, slopemax, min, max, div, newmin, newmax;
00192     int a, first, z, newtot= 0;
00193 
00194     /*if(print) {
00195         for(a=0, ds=dsample; a<tot; a++, ds++)
00196             printf("%lf,%f ", ds->z/(double)0x7FFFFFFF, ds->v);
00197         printf("\n");
00198     }*/
00199 
00200     /* read from and write into same array */
00201     ds= dsample;
00202     newds= dsample;
00203     a= 0;
00204 
00205     /* as long as we are not at the end of the array */
00206     for(a++, ds++; a<tot; a++, ds++) {
00207         slopemin= 0.0f;
00208         slopemax= 0.0f;
00209         first= 1;
00210 
00211         for(; a<tot; a++, ds++) {
00212             //dz= ds->z - newds->z;
00213             if(ds->z == newds->z) {
00214                 /* still in same z position, simply check
00215                    visibility difference against epsilon */
00216                 if(!(fabs(newds->v - ds->v) <= epsilon)) {
00217                     break;
00218                 }
00219             }
00220             else {
00221                 /* compute slopes */
00222                 div= (double)0x7FFFFFFF/((double)ds->z - (double)newds->z);
00223                 min= ((ds->v - epsilon) - newds->v)*div;
00224                 max= ((ds->v + epsilon) - newds->v)*div;
00225 
00226                 /* adapt existing slopes */
00227                 if(first) {
00228                     newmin= min;
00229                     newmax= max;
00230                     first= 0;
00231                 }
00232                 else {
00233                     newmin= MAX2(slopemin, min);
00234                     newmax= MIN2(slopemax, max);
00235 
00236                     /* verify if there is still space between the slopes */
00237                     if(newmin > newmax) {
00238                         ds--;
00239                         a--;
00240                         break;
00241                     }
00242                 }
00243 
00244                 slopemin= newmin;
00245                 slopemax= newmax;
00246             }
00247         }
00248 
00249         if(a == tot) {
00250             ds--;
00251             a--;
00252         }
00253 
00254         /* always previous z */
00255         z= ds->z;
00256 
00257         if(first || a==tot-1) {
00258             /* if slopes were not initialized, use last visibility */
00259             v= ds->v;
00260         }
00261         else {
00262             /* compute visibility at center between slopes at z */
00263             slope= (slopemin+slopemax)*0.5f;
00264             v= newds->v + slope*((z - newds->z)/(double)0x7FFFFFFF);
00265         }
00266 
00267         newds++;
00268         newtot++;
00269 
00270         newds->z= z;
00271         newds->v= v;
00272     }
00273 
00274     if(newtot == 0 || (newds->v != (newds-1)->v))
00275         newtot++;
00276 
00277     /*if(print) {
00278         for(a=0, ds=dsample; a<newtot; a++, ds++)
00279             printf("%lf,%f ", ds->z/(double)0x7FFFFFFF, ds->v);
00280         printf("\n");
00281     }*/
00282 
00283     return newtot;
00284 }
00285 
00286 static float deep_alpha(Render *re, int obinr, int facenr, int strand)
00287 {
00288     ObjectInstanceRen *obi= &re->objectinstance[obinr];
00289     Material *ma;
00290 
00291     if(strand) {
00292         StrandRen *strand= RE_findOrAddStrand(obi->obr, facenr-1);
00293         ma= strand->buffer->ma;
00294     }
00295     else {
00296         VlakRen *vlr= RE_findOrAddVlak(obi->obr, (facenr-1) & RE_QUAD_MASK);
00297         ma= vlr->mat;
00298     }
00299 
00300     return ma->shad_alpha;
00301 }
00302 
00303 static void compress_deepshadowbuf(Render *re, ShadBuf *shb, APixstr *apixbuf, APixstrand *apixbufstrand)
00304 {
00305     ShadSampleBuf *shsample;
00306     DeepSample *ds[RE_MAX_OSA], *sampleds[RE_MAX_OSA], *dsb, *newbuf;
00307     APixstr *ap, *apn;
00308     APixstrand *aps, *apns;
00309     float visibility;
00310 
00311     const int totbuf= shb->totbuf;
00312     const float totbuf_f= (float)shb->totbuf;
00313     const float totbuf_f_inv= 1.0f/totbuf_f;
00314     const int size= shb->size;
00315 
00316     int a, b, c, tot, minz, found, prevtot, newtot;
00317     int sampletot[RE_MAX_OSA], totsample = 0, totsamplec = 0;
00318     
00319     shsample= MEM_callocN( sizeof(ShadSampleBuf), "shad sample buf");
00320     BLI_addtail(&shb->buffers, shsample);
00321 
00322     shsample->totbuf= MEM_callocN(sizeof(int)*size*size, "deeptotbuf");
00323     shsample->deepbuf= MEM_callocN(sizeof(DeepSample*)*size*size, "deepbuf");
00324 
00325     ap= apixbuf;
00326     aps= apixbufstrand;
00327     for(a=0; a<size*size; a++, ap++, aps++) {
00328         /* count number of samples */
00329         for(c=0; c<totbuf; c++)
00330             sampletot[c]= 0;
00331 
00332         tot= 0;
00333         for(apn=ap; apn; apn=apn->next)
00334             for(b=0; b<4; b++)
00335                 if(apn->p[b])
00336                     for(c=0; c<totbuf; c++)
00337                         if(apn->mask[b] & (1<<c))
00338                             sampletot[c]++;
00339 
00340         if(apixbufstrand) {
00341             for(apns=aps; apns; apns=apns->next)
00342                 for(b=0; b<4; b++)
00343                     if(apns->p[b])
00344                         for(c=0; c<totbuf; c++)
00345                             if(apns->mask[b] & (1<<c))
00346                                 sampletot[c]++;
00347         }
00348 
00349         for(c=0; c<totbuf; c++)
00350             tot += sampletot[c];
00351 
00352         if(tot == 0) {
00353             shsample->deepbuf[a]= NULL;
00354             shsample->totbuf[a]= 0;
00355             continue;
00356         }
00357 
00358         /* fill samples */
00359         ds[0]= sampleds[0]= MEM_callocN(sizeof(DeepSample)*tot*2, "deepsample");
00360         for(c=1; c<totbuf; c++)
00361             ds[c]= sampleds[c]= sampleds[c-1] + sampletot[c-1]*2;
00362 
00363         for(apn=ap; apn; apn=apn->next) {
00364             for(b=0; b<4; b++) {
00365                 if(apn->p[b]) {
00366                     for(c=0; c<totbuf; c++) {
00367                         if(apn->mask[b] & (1<<c)) {
00368                             /* two entries to create step profile */
00369                             ds[c]->z= apn->z[b];
00370                             ds[c]->v= 1.0f; /* not used */
00371                             ds[c]++;
00372                             ds[c]->z= apn->z[b];
00373                             ds[c]->v= deep_alpha(re, apn->obi[b], apn->p[b], 0);
00374                             ds[c]++;
00375                         }
00376                     }
00377                 }
00378             }
00379         }
00380 
00381         if(apixbufstrand) {
00382             for(apns=aps; apns; apns=apns->next) {
00383                 for(b=0; b<4; b++) {
00384                     if(apns->p[b]) {
00385                         for(c=0; c<totbuf; c++) {
00386                             if(apns->mask[b] & (1<<c)) {
00387                                 /* two entries to create step profile */
00388                                 ds[c]->z= apns->z[b];
00389                                 ds[c]->v= 1.0f; /* not used */
00390                                 ds[c]++;
00391                                 ds[c]->z= apns->z[b];
00392                                 ds[c]->v= deep_alpha(re, apns->obi[b], apns->p[b], 1);
00393                                 ds[c]++;
00394                             }
00395                         }
00396                     }
00397                 }
00398             }
00399         }
00400 
00401         for(c=0; c<totbuf; c++) {
00402             /* sort by increasing z */
00403             qsort(sampleds[c], sampletot[c], sizeof(DeepSample)*2, verg_deepsample);
00404 
00405             /* sum visibility, replacing alpha values */
00406             visibility= 1.0f;
00407             ds[c]= sampleds[c];
00408 
00409             for(b=0; b<sampletot[c]; b++) {
00410                 /* two entries creating step profile */
00411                 ds[c]->v= visibility;
00412                 ds[c]++;
00413 
00414                 visibility *= 1.0f-ds[c]->v;
00415                 ds[c]->v= visibility;
00416                 ds[c]++;
00417             }
00418 
00419             /* halfway trick, probably won't work well for volumes? */
00420             ds[c]= sampleds[c];
00421             for(b=0; b<sampletot[c]; b++) {
00422                 if(b+1 < sampletot[c]) {
00423                     ds[c]->z= (ds[c]->z>>1) + ((ds[c]+2)->z>>1);
00424                     ds[c]++;
00425                     ds[c]->z= (ds[c]->z>>1) + ((ds[c]+2)->z>>1);
00426                     ds[c]++;
00427                 }
00428                 else {
00429                     ds[c]->z= (ds[c]->z>>1) + (0x7FFFFFFF>>1);
00430                     ds[c]++;
00431                     ds[c]->z= (ds[c]->z>>1) + (0x7FFFFFFF>>1);
00432                     ds[c]++;
00433                 }
00434             }
00435 
00436             /* init for merge loop */
00437             ds[c]= sampleds[c];
00438             sampletot[c] *= 2;
00439         }
00440 
00441         shsample->deepbuf[a]= MEM_callocN(sizeof(DeepSample)*tot*2, "deepsample");
00442         shsample->totbuf[a]= 0;
00443 
00444         /* merge buffers */
00445         dsb= shsample->deepbuf[a];
00446         while(1) {
00447             minz= 0;
00448             found= 0;
00449 
00450             for(c=0; c<totbuf; c++) {
00451                 if(sampletot[c] && (!found || ds[c]->z < minz)) {
00452                     minz= ds[c]->z;
00453                     found= 1;
00454                 }
00455             }
00456 
00457             if(!found)
00458                 break;
00459 
00460             dsb->z= minz;
00461             dsb->v= 0.0f;
00462 
00463             visibility= 0.0f;
00464             for(c=0; c<totbuf; c++) {
00465                 if(sampletot[c] && ds[c]->z == minz) {
00466                     ds[c]++;
00467                     sampletot[c]--;
00468                 }
00469 
00470                 if(sampleds[c] == ds[c])
00471                     visibility += totbuf_f_inv;
00472                 else
00473                     visibility += (ds[c]-1)->v / totbuf_f;
00474             }
00475 
00476             dsb->v= visibility;
00477             dsb++;
00478             shsample->totbuf[a]++;
00479         }
00480 
00481         prevtot= shsample->totbuf[a];
00482         totsample += prevtot;
00483 
00484         newtot= compress_deepsamples(shsample->deepbuf[a], prevtot, shb->compressthresh);
00485         shsample->totbuf[a]= newtot;
00486         totsamplec += newtot;
00487 
00488         if(newtot < prevtot) {
00489             newbuf= MEM_mallocN(sizeof(DeepSample)*newtot, "cdeepsample");
00490             memcpy(newbuf, shsample->deepbuf[a], sizeof(DeepSample)*newtot);
00491             MEM_freeN(shsample->deepbuf[a]);
00492             shsample->deepbuf[a]= newbuf;
00493         }
00494 
00495         MEM_freeN(sampleds[0]);
00496     }
00497 
00498     //printf("%d -> %d, ratio %f\n", totsample, totsamplec, (float)totsamplec/(float)totsample);
00499 }
00500 
00501 /* create Z tiles (for compression): this system is 24 bits!!! */
00502 static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
00503 {
00504     ShadSampleBuf *shsample;
00505     float dist;
00506     uintptr_t *ztile;
00507     int *rz, *rz1, verg, verg1, size= shb->size;
00508     int a, x, y, minx, miny, byt1, byt2;
00509     char *rc, *rcline, *ctile, *zt;
00510     
00511     shsample= MEM_callocN( sizeof(ShadSampleBuf), "shad sample buf");
00512     BLI_addtail(&shb->buffers, shsample);
00513     
00514     shsample->zbuf= MEM_mallocN( sizeof(uintptr_t)*(size*size)/256, "initshadbuf2");
00515     shsample->cbuf= MEM_callocN( (size*size)/256, "initshadbuf3");
00516     
00517     ztile= (uintptr_t *)shsample->zbuf;
00518     ctile= shsample->cbuf;
00519     
00520     /* help buffer */
00521     rcline= MEM_mallocN(256*4+sizeof(int), "makeshadbuf2");
00522     
00523     for(y=0; y<size; y+=16) {
00524         if(y< size/2) miny= y+15-size/2;
00525         else miny= y-size/2;    
00526         
00527         for(x=0; x<size; x+=16) {
00528             
00529             /* is tile within spotbundle? */
00530             a= size/2;
00531             if(x< a) minx= x+15-a;
00532             else minx= x-a; 
00533             
00534             dist= sqrt( (float)(minx*minx+miny*miny) );
00535             
00536             if(square==0 && dist>(float)(a+12)) {   /* 12, tested with a onlyshadow lamp */
00537                 a= 256; verg= 0; /* 0x80000000; */ /* 0x7FFFFFFF; */
00538                 rz1= (&verg)+1;
00539             } 
00540             else {
00541                 copy_to_ztile(rectz, size, x, y, 16, rcline);
00542                 rz1= (int *)rcline;
00543                 
00544                 verg= (*rz1 & 0xFFFFFF00);
00545                 
00546                 for(a=0;a<256;a++,rz1++) {
00547                     if( (*rz1 & 0xFFFFFF00) !=verg) break;
00548                 }
00549             }
00550             if(a==256) { /* complete empty tile */
00551                 *ctile= 0;
00552                 *ztile= *(rz1-1);
00553             }
00554             else {
00555                 
00556                 /* ACOMP etc. are defined to work L/B endian */
00557                 
00558                 rc= rcline;
00559                 rz1= (int *)rcline;
00560                 verg=  rc[ACOMP];
00561                 verg1= rc[BCOMP];
00562                 rc+= 4;
00563                 byt1= 1; byt2= 1;
00564                 for(a=1;a<256;a++,rc+=4) {
00565                     byt1 &= (verg==rc[ACOMP]);
00566                     byt2 &= (verg1==rc[BCOMP]);
00567                     
00568                     if(byt1==0) break;
00569                 }
00570                 if(byt1 && byt2) {  /* only store byte */
00571                     *ctile= 1;
00572                     *ztile= (uintptr_t)MEM_mallocN(256+4, "tile1");
00573                     rz= (int *)*ztile;
00574                     *rz= *rz1;
00575                     
00576                     zt= (char *)(rz+1);
00577                     rc= rcline;
00578                     for(a=0; a<256; a++, zt++, rc+=4) *zt= rc[GCOMP];   
00579                 }
00580                 else if(byt1) {     /* only store short */
00581                     *ctile= 2;
00582                     *ztile= (uintptr_t)MEM_mallocN(2*256+4,"Tile2");
00583                     rz= (int *)*ztile;
00584                     *rz= *rz1;
00585                     
00586                     zt= (char *)(rz+1);
00587                     rc= rcline;
00588                     for(a=0; a<256; a++, zt+=2, rc+=4) {
00589                         zt[0]= rc[BCOMP];
00590                         zt[1]= rc[GCOMP];
00591                     }
00592                 }
00593                 else {          /* store triple */
00594                     *ctile= 3;
00595                     *ztile= (uintptr_t)MEM_mallocN(3*256,"Tile3");
00596 
00597                     zt= (char *)*ztile;
00598                     rc= rcline;
00599                     for(a=0; a<256; a++, zt+=3, rc+=4) {
00600                         zt[0]= rc[ACOMP];
00601                         zt[1]= rc[BCOMP];
00602                         zt[2]= rc[GCOMP];
00603                     }
00604                 }
00605             }
00606             ztile++;
00607             ctile++;
00608         }
00609     }
00610 
00611     MEM_freeN(rcline);
00612 }
00613 
00614 /* sets start/end clipping. lar->shb should be initialized */
00615 static void shadowbuf_autoclip(Render *re, LampRen *lar)
00616 {
00617     ObjectInstanceRen *obi;
00618     ObjectRen *obr;
00619     VlakRen *vlr= NULL;
00620     VertRen *ver= NULL;
00621     Material *ma= NULL;
00622     float minz, maxz, vec[3], viewmat[4][4], obviewmat[4][4];
00623     unsigned int lay = -1;
00624     int i, a, maxtotvert, ok= 1;
00625     char *clipflag;
00626     
00627     minz= 1.0e30f; maxz= -1.0e30f;
00628     copy_m4_m4(viewmat, lar->shb->viewmat);
00629     
00630     if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay;
00631 
00632     maxtotvert= 0;
00633     for(obr=re->objecttable.first; obr; obr=obr->next)
00634         maxtotvert= MAX2(obr->totvert, maxtotvert);
00635 
00636     clipflag= MEM_callocN(sizeof(char)*maxtotvert, "autoclipflag");
00637 
00638     /* set clip in vertices when face visible */
00639     for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
00640         obr= obi->obr;
00641 
00642         if(obi->flag & R_TRANSFORMED)
00643             mult_m4_m4m4(obviewmat, viewmat, obi->mat);
00644         else
00645             copy_m4_m4(obviewmat, viewmat);
00646 
00647         memset(clipflag, 0, sizeof(char)*obr->totvert);
00648 
00649         /* clear clip, is being set if face is visible (clip is calculated for real later) */
00650         for(a=0; a<obr->totvlak; a++) {
00651             if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
00652             else vlr++;
00653             
00654             /* note; these conditions are copied from zbuffer_shadow() */
00655             if(vlr->mat!= ma) {
00656                 ma= vlr->mat;
00657                 ok= 1;
00658                 if((ma->mode & MA_SHADBUF)==0) ok= 0;
00659             }
00660             
00661             if(ok && (obi->lay & lay)) {
00662                 clipflag[vlr->v1->index]= 1;
00663                 clipflag[vlr->v2->index]= 1;
00664                 clipflag[vlr->v3->index]= 1;
00665                 if(vlr->v4) clipflag[vlr->v4->index]= 1;
00666             }               
00667         }       
00668         
00669         /* calculate min and max */
00670         for(a=0; a< obr->totvert;a++) {
00671             if((a & 255)==0) ver= RE_findOrAddVert(obr, a);
00672             else ver++;
00673             
00674             if(clipflag[a]) {
00675                 copy_v3_v3(vec, ver->co);
00676                 mul_m4_v3(obviewmat, vec);
00677                 /* Z on visible side of lamp space */
00678                 if(vec[2] < 0.0f) {
00679                     float inpr, z= -vec[2];
00680                     
00681                     /* since vec is rotated in lampspace, this is how to get the cosine of angle */
00682                     /* precision is set 20% larger */
00683                     vec[2]*= 1.2f;
00684                     normalize_v3(vec);
00685                     inpr= - vec[2];
00686 
00687                     if(inpr>=lar->spotsi) {
00688                         if(z<minz) minz= z;
00689                         if(z>maxz) maxz= z;
00690                     }
00691                 }
00692             }
00693         }
00694     }
00695 
00696     MEM_freeN(clipflag);
00697     
00698     /* set clipping min and max */
00699     if(minz < maxz) {
00700         float delta= (maxz - minz); /* threshold to prevent precision issues */
00701         
00702         //printf("minz %f maxz %f delta %f\n", minz, maxz, delta);
00703         if(lar->bufflag & LA_SHADBUF_AUTO_START)
00704             lar->shb->d= minz - delta*0.02f;    /* 0.02 is arbitrary... needs more thinking! */
00705         if(lar->bufflag & LA_SHADBUF_AUTO_END)
00706             lar->shb->clipend= maxz + delta*0.1f;
00707         
00708         /* bias was calculated as percentage, we scale it to prevent animation issues */
00709         delta= (lar->clipend-lar->clipsta)/(lar->shb->clipend-lar->shb->d);
00710         //printf("bias delta %f\n", delta);
00711         lar->shb->bias= (int) (delta*(float)lar->shb->bias);
00712     }
00713 }
00714 
00715 static void makeflatshadowbuf(Render *re, LampRen *lar, float *jitbuf)
00716 {
00717     ShadBuf *shb= lar->shb;
00718     int *rectz, samples;
00719 
00720     /* zbuffering */
00721     rectz= MEM_mapallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf");
00722     
00723     for(samples=0; samples<shb->totbuf; samples++) {
00724         zbuffer_shadow(re, shb->persmat, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]);
00725         /* create Z tiles (for compression): this system is 24 bits!!! */
00726         compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE);
00727 
00728         if(re->test_break(re->tbh))
00729             break;
00730     }
00731     
00732     MEM_freeN(rectz);
00733 }
00734 
00735 static void makedeepshadowbuf(Render *re, LampRen *lar, float *jitbuf)
00736 {
00737     ShadBuf *shb= lar->shb;
00738     APixstr *apixbuf;
00739     APixstrand *apixbufstrand= NULL;
00740     ListBase apsmbase= {NULL, NULL};
00741 
00742     /* zbuffering */
00743     apixbuf= MEM_callocN(sizeof(APixstr)*shb->size*shb->size, "APixbuf");
00744     if(re->totstrand)
00745         apixbufstrand= MEM_callocN(sizeof(APixstrand)*shb->size*shb->size, "APixbufstrand");
00746 
00747     zbuffer_abuf_shadow(re, lar, shb->persmat, apixbuf, apixbufstrand, &apsmbase, shb->size,
00748         shb->totbuf, (float(*)[2])jitbuf);
00749 
00750     /* create Z tiles (for compression): this system is 24 bits!!! */
00751     compress_deepshadowbuf(re, shb, apixbuf, apixbufstrand);
00752     
00753     MEM_freeN(apixbuf);
00754     if(apixbufstrand)
00755         MEM_freeN(apixbufstrand);
00756     freepsA(&apsmbase);
00757 }
00758 
00759 void makeshadowbuf(Render *re, LampRen *lar)
00760 {
00761     ShadBuf *shb= lar->shb;
00762     float wsize, *jitbuf, twozero[2]= {0.0f, 0.0f}, angle, temp;
00763     
00764     if(lar->bufflag & (LA_SHADBUF_AUTO_START|LA_SHADBUF_AUTO_END))
00765         shadowbuf_autoclip(re, lar);
00766     
00767     /* just to enforce identical behaviour of all irregular buffers */
00768     if(lar->buftype==LA_SHADBUF_IRREGULAR)
00769         shb->size= 1024;
00770     
00771     /* matrices and window: in winmat the transformation is being put,
00772         transforming from observer view to lamp view, including lamp window matrix */
00773     
00774     angle= saacos(lar->spotsi);
00775     temp= 0.5f*shb->size*cos(angle)/sin(angle);
00776     shb->pixsize= (shb->d)/temp;
00777     wsize= shb->pixsize*(shb->size/2.0f);
00778     
00779     perspective_m4( shb->winmat,-wsize, wsize, -wsize, wsize, shb->d, shb->clipend);
00780     mult_m4_m4m4(shb->persmat, shb->winmat, shb->viewmat);
00781 
00782     if(ELEM3(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP)) {
00783         shb->totbuf= lar->buffers;
00784 
00785         /* jitter, weights - not threadsafe! */
00786         BLI_lock_thread(LOCK_CUSTOM1);
00787         shb->jit= give_jitter_tab(get_render_shadow_samples(&re->r, shb->samp));
00788         make_jitter_weight_tab(re, shb, lar->filtertype);
00789         BLI_unlock_thread(LOCK_CUSTOM1);
00790         
00791         if(shb->totbuf==4) jitbuf= give_jitter_tab(2);
00792         else if(shb->totbuf==9) jitbuf= give_jitter_tab(3);
00793         else jitbuf= twozero;
00794         
00795         /* zbuffering */
00796         if(lar->buftype == LA_SHADBUF_DEEP) {
00797             makedeepshadowbuf(re, lar, jitbuf);
00798             shb->totbuf= 1;
00799         }
00800         else
00801             makeflatshadowbuf(re, lar, jitbuf);
00802 
00803         /* printf("lampbuf %d\n", sizeoflampbuf(shb)); */
00804     }
00805 }
00806 
00807 static void *do_shadow_thread(void *re_v)
00808 {
00809     Render *re= (Render*)re_v;
00810     LampRen *lar;
00811 
00812     do {
00813         BLI_lock_thread(LOCK_CUSTOM1);
00814         for(lar=re->lampren.first; lar; lar=lar->next) {
00815             if(lar->shb && !lar->thread_assigned) {
00816                 lar->thread_assigned= 1;
00817                 break;
00818             }
00819         }
00820         BLI_unlock_thread(LOCK_CUSTOM1);
00821 
00822         /* if type is irregular, this only sets the perspective matrix and autoclips */
00823         if(lar) {
00824             makeshadowbuf(re, lar);
00825             BLI_lock_thread(LOCK_CUSTOM1);
00826             lar->thread_ready= 1;
00827             BLI_unlock_thread(LOCK_CUSTOM1);
00828         }
00829     } while(lar && !re->test_break(re->tbh));
00830 
00831     return NULL;
00832 }
00833 
00834 static volatile int g_break= 0;
00835 static int thread_break(void *UNUSED(arg))
00836 {
00837     return g_break;
00838 }
00839 
00840 void threaded_makeshadowbufs(Render *re)
00841 {
00842     ListBase threads;
00843     LampRen *lar;
00844     int a, totthread= 0;
00845     int (*test_break)(void *);
00846 
00847     /* count number of threads to use */
00848     if(G.rendering) {
00849         for(lar=re->lampren.first; lar; lar= lar->next)
00850             if(lar->shb)
00851                 totthread++;
00852         
00853         totthread= MIN2(totthread, re->r.threads);
00854     }
00855     else
00856         totthread= 1; /* preview render */
00857 
00858     if(totthread <= 1) {
00859         for(lar=re->lampren.first; lar; lar= lar->next) {
00860             if(re->test_break(re->tbh)) break;
00861             if(lar->shb) {
00862                 /* if type is irregular, this only sets the perspective matrix and autoclips */
00863                 makeshadowbuf(re, lar);
00864             }
00865         }
00866     }
00867     else {
00868         /* swap test break function */
00869         test_break= re->test_break;
00870         re->test_break= thread_break;
00871 
00872         for(lar=re->lampren.first; lar; lar= lar->next) {
00873             lar->thread_assigned= 0;
00874             lar->thread_ready= 0;
00875         }
00876 
00877         BLI_init_threads(&threads, do_shadow_thread, totthread);
00878         
00879         for(a=0; a<totthread; a++)
00880             BLI_insert_thread(&threads, re);
00881 
00882         /* keep rendering as long as there are shadow buffers not ready */
00883         do {
00884             if((g_break=test_break(re->tbh)))
00885                 break;
00886 
00887             PIL_sleep_ms(50);
00888 
00889             BLI_lock_thread(LOCK_CUSTOM1);
00890             for(lar=re->lampren.first; lar; lar= lar->next)
00891                 if(lar->shb && !lar->thread_ready)
00892                     break;
00893             BLI_unlock_thread(LOCK_CUSTOM1);
00894         } while(lar);
00895     
00896         BLI_end_threads(&threads);
00897 
00898         /* unset threadsafety */
00899         re->test_break= test_break;
00900         g_break= 0;
00901     }
00902 }
00903 
00904 void freeshadowbuf(LampRen *lar)
00905 {
00906     if(lar->shb) {
00907         ShadBuf *shb= lar->shb;
00908         ShadSampleBuf *shsample;
00909         int b, v;
00910         
00911         for(shsample= shb->buffers.first; shsample; shsample= shsample->next) {
00912             if(shsample->deepbuf) {
00913                 v= shb->size*shb->size;
00914                 for(b=0; b<v; b++)
00915                     if(shsample->deepbuf[b])
00916                         MEM_freeN(shsample->deepbuf[b]);
00917                     
00918                 MEM_freeN(shsample->deepbuf);
00919                 MEM_freeN(shsample->totbuf);
00920             }
00921             else {
00922                 intptr_t *ztile= shsample->zbuf;
00923                 char *ctile= shsample->cbuf;
00924                 
00925                 v= (shb->size*shb->size)/256;
00926                 for(b=0; b<v; b++, ztile++, ctile++)
00927                     if(*ctile) MEM_freeN((void *) *ztile);
00928                 
00929                 MEM_freeN(shsample->zbuf);
00930                 MEM_freeN(shsample->cbuf);
00931             }
00932         }
00933         BLI_freelistN(&shb->buffers);
00934         
00935         if(shb->weight) MEM_freeN(shb->weight);
00936         MEM_freeN(lar->shb);
00937         
00938         lar->shb= NULL;
00939     }
00940 }
00941 
00942 
00943 static int firstreadshadbuf(ShadBuf *shb, ShadSampleBuf *shsample, int **rz, int xs, int ys, int nr)
00944 {
00945     /* return a 1 if fully compressed shadbuf-tile && z==const */
00946     int ofs;
00947     char *ct;
00948 
00949     if(shsample->deepbuf)
00950         return 0;
00951 
00952     /* always test borders of shadowbuffer */
00953     if(xs<0) xs= 0; else if(xs>=shb->size) xs= shb->size-1;
00954     if(ys<0) ys= 0; else if(ys>=shb->size) ys= shb->size-1;
00955 
00956     /* calc z */
00957     ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
00958     ct= shsample->cbuf+ofs;
00959     if(*ct==0) {
00960         if(nr==0) {
00961             *rz= *( (int **)(shsample->zbuf+ofs) );
00962             return 1;
00963         }
00964         else if(*rz!= *( (int **)(shsample->zbuf+ofs) )) return 0;
00965         
00966         return 1;
00967     }
00968     
00969     return 0;
00970 }
00971 
00972 static float readdeepvisibility(DeepSample *dsample, int tot, int z, int bias, float *biast)
00973 {
00974     DeepSample *ds, *prevds;
00975     float t;
00976     int a;
00977 
00978     /* tricky stuff here; we use ints which can overflow easily with bias values */
00979 
00980     ds= dsample;
00981     for(a=0; a<tot && (z-bias > ds->z); a++, ds++)
00982         ;
00983 
00984     if(a == tot) {
00985         if(biast)
00986             *biast= 0.0f;
00987         return (ds-1)->v; /* completely behind all samples */
00988     }
00989     
00990     /* check if this read needs bias blending */
00991     if(biast) {
00992         if(z > ds->z)
00993             *biast= (float)(z - ds->z)/(float)bias;
00994         else
00995             *biast= 0.0f;
00996     }
00997 
00998     if(a == 0)
00999         return 1.0f; /* completely in front of all samples */
01000 
01001     /* converting to float early here because ds->z - prevds->z can overflow */
01002     prevds= ds-1;
01003     t= ((float)(z-bias) - (float)prevds->z)/((float)ds->z - (float)prevds->z);
01004     return t*ds->v + (1.0f-t)*prevds->v;
01005 }
01006 
01007 static float readdeepshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int xs, int ys, int zs)
01008 {
01009     float v, biasv, biast;
01010     int ofs, tot;
01011 
01012     if(zs < - 0x7FFFFE00 + bias)
01013         return 1.0; /* extreme close to clipstart */
01014 
01015     /* calc z */
01016     ofs= ys*shb->size + xs;
01017     tot= shsample->totbuf[ofs];
01018     if(tot == 0)
01019         return 1.0f;
01020 
01021     v= readdeepvisibility(shsample->deepbuf[ofs], tot, zs, bias, &biast);
01022 
01023     if(biast != 0.0f) {
01024         /* in soft bias area */
01025         biasv= readdeepvisibility(shsample->deepbuf[ofs], tot, zs, 0, 0);
01026 
01027         biast= biast*biast;
01028         return (1.0f-biast)*v + biast*biasv;
01029     }
01030 
01031     return v;
01032 }
01033 
01034 /* return 1.0 : fully in light */
01035 static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int xs, int ys, int zs) 
01036 {
01037     float temp;
01038     int *rz, ofs;
01039     int zsamp=0;
01040     char *ct, *cz;
01041 
01042     /* simpleclip */
01043     /* if(xs<0 || ys<0) return 1.0; */
01044     /* if(xs>=shb->size || ys>=shb->size) return 1.0; */
01045     
01046     /* always test borders of shadowbuffer */
01047     if(xs<0) xs= 0; else if(xs>=shb->size) xs= shb->size-1;
01048     if(ys<0) ys= 0; else if(ys>=shb->size) ys= shb->size-1;
01049 
01050     if(shsample->deepbuf)
01051         return readdeepshadowbuf(shb, shsample, bias, xs, ys, zs);
01052 
01053     /* calc z */
01054     ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
01055     ct= shsample->cbuf+ofs;
01056     rz= *( (int **)(shsample->zbuf+ofs) );
01057 
01058     if(*ct==3) {
01059         ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15);
01060         cz= (char *)&zsamp;
01061         cz[ACOMP]= ct[0];
01062         cz[BCOMP]= ct[1];
01063         cz[GCOMP]= ct[2];
01064     }
01065     else if(*ct==2) {
01066         ct= ((char *)rz);
01067         ct+= 4+2*16*(ys & 15)+2*(xs & 15);
01068         zsamp= *rz;
01069     
01070         cz= (char *)&zsamp;
01071         cz[BCOMP]= ct[0];
01072         cz[GCOMP]= ct[1];
01073     }
01074     else if(*ct==1) {
01075         ct= ((char *)rz);
01076         ct+= 4+16*(ys & 15)+(xs & 15);
01077         zsamp= *rz;
01078 
01079         cz= (char *)&zsamp;
01080         cz[GCOMP]= ct[0];
01081 
01082     }
01083     else {
01084         /* got warning on this for 64 bits.... */
01085         /* but it's working code! in this case rz is not a pointer but zvalue (ton) */
01086         zsamp= GET_INT_FROM_POINTER(rz);
01087     }
01088 
01089     /* tricky stuff here; we use ints which can overflow easily with bias values */
01090     
01091     if(zsamp > zs) return 1.0;      /* absolute no shadow */
01092     else if(zs < - 0x7FFFFE00 + bias) return 1.0;   /* extreme close to clipstart */
01093     else if(zsamp < zs-bias) return 0.0 ;   /* absolute in shadow */
01094     else {                  /* soft area */
01095         
01096         temp=  ( (float)(zs- zsamp) )/(float)bias;
01097         return 1.0f - temp*temp;
01098             
01099     }
01100 }
01101 
01102 static void shadowbuf_project_co(float *x, float *y, float *z, ShadBuf *shb, const float co[3])
01103 {
01104     float hco[4], size= 0.5f*(float)shb->size;
01105 
01106     copy_v3_v3(hco, co);
01107     hco[3]= 1.0f;
01108 
01109     mul_m4_v4(shb->persmat, hco);
01110 
01111     *x= size*(1.0f+hco[0]/hco[3]);
01112     *y= size*(1.0f+hco[1]/hco[3]);
01113     if(z) *z= (hco[2]/hco[3]);
01114 }
01115 
01116 /* the externally called shadow testing (reading) function */
01117 /* return 1.0: no shadow at all */
01118 float testshadowbuf(Render *re, ShadBuf *shb, const float co[3], const float dxco[3], const float dyco[3], float inp, float mat_bias)
01119 {
01120     ShadSampleBuf *shsample;
01121     float fac, dco[3], dx[3], dy[3], shadfac=0.0f;
01122     float xs1, ys1, zs1, *jit, *weight, xres, yres, biasf;
01123     int xs, ys, zs, bias, *rz;
01124     short a, num;
01125     
01126     /* crash preventer */
01127     if(shb->buffers.first==NULL)
01128         return 1.0f;
01129     
01130     /* when facing away, assume fully in shadow */
01131     if(inp <= 0.0f)
01132         return 0.0f;
01133 
01134     /* project coordinate to pixel space */
01135     shadowbuf_project_co(&xs1, &ys1, &zs1, shb, co);
01136 
01137     /* clip z coordinate, z is projected so that (-1.0, 1.0) matches
01138        (clipstart, clipend), so we can do this simple test */
01139     if(zs1>=1.0f)
01140         return 0.0f;
01141     else if(zs1<= -1.0f)
01142         return 1.0f;
01143 
01144     zs= ((float)0x7FFFFFFF)*zs1;
01145 
01146     /* take num*num samples, increase area with fac */
01147     num= get_render_shadow_samples(&re->r, shb->samp);
01148     num= num*num;
01149     fac= shb->soft;
01150     
01151     /* compute z bias */
01152     if(mat_bias!=0.0f) biasf= shb->bias*mat_bias;
01153     else biasf= shb->bias;
01154     /* with inp==1.0, bias is half the size. correction value was 1.1, giving errors 
01155        on cube edges, with one side being almost frontal lighted (ton)  */
01156     bias= (1.5f-inp*inp)*biasf;
01157     
01158     /* in case of no filtering we can do things simpler */
01159     if(num==1) {
01160         for(shsample= shb->buffers.first; shsample; shsample= shsample->next)
01161             shadfac += readshadowbuf(shb, shsample, bias, (int)xs1, (int)ys1, zs);
01162         
01163         return shadfac/(float)shb->totbuf;
01164     }
01165 
01166     /* calculate filter size */
01167     add_v3_v3v3(dco, co, dxco);
01168     shadowbuf_project_co(&dx[0], &dx[1], NULL, shb, dco);
01169     dx[0]= xs1 - dx[0];
01170     dx[1]= ys1 - dx[1];
01171 
01172     add_v3_v3v3(dco, co, dyco);
01173     shadowbuf_project_co(&dy[0], &dy[1], NULL, shb, dco);
01174     dy[0]= xs1 - dy[0];
01175     dy[1]= ys1 - dy[1];
01176     
01177     xres= fac*(fabs(dx[0]) + fabs(dy[0]));
01178     yres= fac*(fabs(dx[1]) + fabs(dy[1]));
01179     if(xres<1.0f) xres= 1.0f;
01180     if(yres<1.0f) yres= 1.0f;
01181     
01182     /* make xs1/xs1 corner of sample area */
01183     xs1 -= xres*0.5f;
01184     ys1 -= yres*0.5f;
01185 
01186     /* in case we have a constant value in a tile, we can do quicker lookup */
01187     if(xres<16.0f && yres<16.0f) {
01188         shsample= shb->buffers.first;
01189         if(firstreadshadbuf(shb, shsample, &rz, (int)xs1, (int)ys1, 0)) {
01190             if(firstreadshadbuf(shb, shsample, &rz, (int)(xs1+xres), (int)ys1, 1)) {
01191                 if(firstreadshadbuf(shb, shsample, &rz, (int)xs1, (int)(ys1+yres), 1)) {
01192                     if(firstreadshadbuf(shb, shsample, &rz, (int)(xs1+xres), (int)(ys1+yres), 1)) {
01193                         return readshadowbuf(shb, shsample, bias,(int)xs1, (int)ys1, zs);
01194                     }
01195                 }
01196             }
01197         }
01198     }
01199     
01200     /* full jittered shadow buffer lookup */
01201     for(shsample= shb->buffers.first; shsample; shsample= shsample->next) {
01202         jit= shb->jit;
01203         weight= shb->weight;
01204         
01205         for(a=num; a>0; a--, jit+=2, weight++) {
01206             /* instead of jit i tried random: ugly! */
01207             /* note: the plus 0.5 gives best sampling results, jit goes from -0.5 to 0.5 */
01208             /* xs1 and ys1 are already corrected to be corner of sample area */
01209             xs= xs1 + xres*(jit[0] + 0.5f);
01210             ys= ys1 + yres*(jit[1] + 0.5f);
01211             
01212             shadfac+= *weight * readshadowbuf(shb, shsample, bias, xs, ys, zs);
01213         }
01214     }
01215 
01216     /* Renormalizes for the sample number: */
01217     return shadfac/(float)shb->totbuf;
01218 }
01219 
01220 /* different function... sampling behind clipend can be LIGHT, bias is negative! */
01221 /* return: light */
01222 static float readshadowbuf_halo(ShadBuf *shb, ShadSampleBuf *shsample, int xs, int ys, int zs)
01223 {
01224     float temp;
01225     int *rz, ofs;
01226     int bias, zbias, zsamp;
01227     char *ct, *cz;
01228 
01229     /* negative! The other side is more important */
01230     bias= -shb->bias;
01231     
01232     /* simpleclip */
01233     if(xs<0 || ys<0) return 0.0;
01234     if(xs>=shb->size || ys>=shb->size) return 0.0;
01235 
01236     /* calc z */
01237     ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
01238     ct= shsample->cbuf+ofs;
01239     rz= *( (int **)(shsample->zbuf+ofs) );
01240 
01241     if(*ct==3) {
01242         ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15);
01243         cz= (char *)&zsamp;
01244         zsamp= 0;
01245         cz[ACOMP]= ct[0];
01246         cz[BCOMP]= ct[1];
01247         cz[GCOMP]= ct[2];
01248     }
01249     else if(*ct==2) {
01250         ct= ((char *)rz);
01251         ct+= 4+2*16*(ys & 15)+2*(xs & 15);
01252         zsamp= *rz;
01253     
01254         cz= (char *)&zsamp;
01255         cz[BCOMP]= ct[0];
01256         cz[GCOMP]= ct[1];
01257     }
01258     else if(*ct==1) {
01259         ct= ((char *)rz);
01260         ct+= 4+16*(ys & 15)+(xs & 15);
01261         zsamp= *rz;
01262 
01263         cz= (char *)&zsamp;
01264         cz[GCOMP]= ct[0];
01265 
01266     }
01267     else {
01268         /* same as before */
01269         /* still working code! (ton) */
01270         zsamp= GET_INT_FROM_POINTER(rz);
01271     }
01272 
01273     /* NO schadow when sampled at 'eternal' distance */
01274 
01275     if(zsamp >= 0x7FFFFE00) return 1.0; 
01276 
01277     if(zsamp > zs) return 1.0;      /* absolute no shadww */
01278     else {
01279         /* bias is negative, so the (zs-bias) can be beyond 0x7fffffff */
01280         zbias= 0x7fffffff - zs;
01281         if(zbias > -bias) {
01282             if( zsamp < zs-bias) return 0.0 ;   /* absolute in shadow */
01283         }
01284         else return 0.0 ;   /* absolute shadow */
01285     }
01286 
01287     /* soft area */
01288     
01289     temp=  ( (float)(zs- zsamp) )/(float)bias;
01290     return 1.0f - temp*temp;
01291 }
01292 
01293 
01294 float shadow_halo(LampRen *lar, const float p1[3], const float p2[3])
01295 {
01296     /* p1 p2 already are rotated in spot-space */
01297     ShadBuf *shb= lar->shb;
01298     ShadSampleBuf *shsample;
01299     float co[4], siz;
01300     float labda, labdao, labdax, labday, ldx, ldy;
01301     float zf, xf1, yf1, zf1, xf2, yf2, zf2;
01302     float count, lightcount;
01303     int x, y, z, xs1, ys1;
01304     int dx = 0, dy = 0;
01305     
01306     siz= 0.5f*(float)shb->size;
01307     
01308     co[0]= p1[0];
01309     co[1]= p1[1];
01310     co[2]= p1[2]/lar->sh_zfac;
01311     co[3]= 1.0;
01312     mul_m4_v4(shb->winmat, co); /* rational hom co */
01313     xf1= siz*(1.0f+co[0]/co[3]);
01314     yf1= siz*(1.0f+co[1]/co[3]);
01315     zf1= (co[2]/co[3]);
01316 
01317 
01318     co[0]= p2[0];
01319     co[1]= p2[1];
01320     co[2]= p2[2]/lar->sh_zfac;
01321     co[3]= 1.0;
01322     mul_m4_v4(shb->winmat, co); /* rational hom co */
01323     xf2= siz*(1.0f+co[0]/co[3]);
01324     yf2= siz*(1.0f+co[1]/co[3]);
01325     zf2= (co[2]/co[3]);
01326 
01327     /* the 2dda (a pixel line formula) */
01328 
01329     xs1= (int)xf1;
01330     ys1= (int)yf1;
01331 
01332     if(xf1 != xf2) {
01333         if(xf2-xf1 > 0.0f) {
01334             labdax= (xf1-xs1-1.0f)/(xf1-xf2);
01335             ldx= -shb->shadhalostep/(xf1-xf2);
01336             dx= shb->shadhalostep;
01337         }
01338         else {
01339             labdax= (xf1-xs1)/(xf1-xf2);
01340             ldx= shb->shadhalostep/(xf1-xf2);
01341             dx= -shb->shadhalostep;
01342         }
01343     }
01344     else {
01345         labdax= 1.0;
01346         ldx= 0.0;
01347     }
01348 
01349     if(yf1 != yf2) {
01350         if(yf2-yf1 > 0.0f) {
01351             labday= (yf1-ys1-1.0f)/(yf1-yf2);
01352             ldy= -shb->shadhalostep/(yf1-yf2);
01353             dy= shb->shadhalostep;
01354         }
01355         else {
01356             labday= (yf1-ys1)/(yf1-yf2);
01357             ldy= shb->shadhalostep/(yf1-yf2);
01358             dy= -shb->shadhalostep;
01359         }
01360     }
01361     else {
01362         labday= 1.0;
01363         ldy= 0.0;
01364     }
01365     
01366     x= xs1;
01367     y= ys1;
01368     labda= count= lightcount= 0.0;
01369 
01370 /* printf("start %x %x  \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */
01371 
01372     while(1) {
01373         labdao= labda;
01374         
01375         if(labdax==labday) {
01376             labdax+= ldx;
01377             x+= dx;
01378             labday+= ldy;
01379             y+= dy;
01380         }
01381         else {
01382             if(labdax<labday) {
01383                 labdax+= ldx;
01384                 x+= dx;
01385             } else {
01386                 labday+= ldy;
01387                 y+= dy;
01388             }
01389         }
01390         
01391         labda= MIN2(labdax, labday);
01392         if(labda==labdao || labda>=1.0f) break;
01393         
01394         zf= zf1 + labda*(zf2-zf1);
01395         count+= (float)shb->totbuf;
01396 
01397         if(zf<= -1.0f) lightcount += 1.0f;  /* close to the spot */
01398         else {
01399         
01400             /* make sure, behind the clipend we extend halolines. */
01401             if(zf>=1.0f) z= 0x7FFFF000;
01402             else z= (int)(0x7FFFF000*zf);
01403             
01404             for(shsample= shb->buffers.first; shsample; shsample= shsample->next)
01405                 lightcount+= readshadowbuf_halo(shb, shsample, x, y, z);
01406             
01407         }
01408     }
01409     
01410     if(count!=0.0f) return (lightcount/count);
01411     return 0.0f;
01412     
01413 }
01414 
01415 
01416 /* ********************* Irregular Shadow Buffer (ISB) ************* */
01417 /* ********** storage of all view samples in a raster of lists ***** */
01418 
01419 /* based on several articles describing this method, like:
01420 The Irregular Z-Buffer and its Application to Shadow Mapping
01421 Gregory S. Johnson - William R. Mark - Christopher A. Burns 
01422 and
01423 Alias-Free Shadow Maps
01424 Timo Aila and Samuli Laine
01425 */
01426 
01427 /* bsp structure (actually kd tree) */
01428 
01429 #define BSPMAX_SAMPLE   128
01430 #define BSPMAX_DEPTH    32
01431 
01432 /* aligned with struct rctf */
01433 typedef struct Boxf {
01434     float xmin, xmax;
01435     float ymin, ymax;
01436     float zmin, zmax;
01437 } Boxf;
01438 
01439 typedef struct ISBBranch {
01440     struct ISBBranch *left, *right;
01441     float divider[2];
01442     Boxf box;
01443     short totsamp, index, full, unused;
01444     ISBSample **samples;
01445 } ISBBranch;
01446 
01447 typedef struct BSPFace {
01448     Boxf box;
01449     float *v1, *v2, *v3, *v4;
01450     int obi;        /* object for face lookup */
01451     int facenr;     /* index to retrieve VlakRen */
01452     int type;       /* only for strand now */
01453     short shad_alpha, is_full;
01454     
01455     /* strand caching data, optimize for point_behind_strand() */
01456     float radline, radline_end, len;
01457     float vec1[3], vec2[3], rc[3];
01458 } BSPFace;
01459 
01460 /* boxes are in lamp projection */
01461 static void init_box(Boxf *box)
01462 {
01463     box->xmin= 1000000.0f;
01464     box->xmax= 0;
01465     box->ymin= 1000000.0f;
01466     box->ymax= 0;
01467     box->zmin= 0x7FFFFFFF;
01468     box->zmax= - 0x7FFFFFFF;
01469 }
01470 
01471 /* use v1 to calculate boundbox */
01472 static void bound_boxf(Boxf *box, const float v1[3])
01473 {
01474     if(v1[0] < box->xmin) box->xmin= v1[0];
01475     if(v1[0] > box->xmax) box->xmax= v1[0];
01476     if(v1[1] < box->ymin) box->ymin= v1[1];
01477     if(v1[1] > box->ymax) box->ymax= v1[1];
01478     if(v1[2] < box->zmin) box->zmin= v1[2];
01479     if(v1[2] > box->zmax) box->zmax= v1[2];
01480 }
01481 
01482 /* use v1 to calculate boundbox */
01483 static void bound_rectf(rctf *box, const float v1[2])
01484 {
01485     if(v1[0] < box->xmin) box->xmin= v1[0];
01486     if(v1[0] > box->xmax) box->xmax= v1[0];
01487     if(v1[1] < box->ymin) box->ymin= v1[1];
01488     if(v1[1] > box->ymax) box->ymax= v1[1];
01489 }
01490 
01491 
01492 /* halfway splitting, for initializing a more regular tree */
01493 static void isb_bsp_split_init(ISBBranch *root, MemArena *mem, int level)
01494 {
01495     
01496     /* if level > 0 we create new branches and go deeper*/
01497     if(level > 0) {
01498         ISBBranch *left, *right;
01499         int i;
01500         
01501         /* splitpoint */
01502         root->divider[0]= 0.5f*(root->box.xmin+root->box.xmax);
01503         root->divider[1]= 0.5f*(root->box.ymin+root->box.ymax);
01504         
01505         /* find best splitpoint */
01506         if(root->box.xmax-root->box.xmin > root->box.ymax-root->box.ymin)
01507             i= root->index= 0;
01508         else
01509             i= root->index= 1;
01510         
01511         left= root->left= BLI_memarena_alloc(mem, sizeof(ISBBranch));
01512         right= root->right= BLI_memarena_alloc(mem, sizeof(ISBBranch));
01513         
01514         /* box info */
01515         left->box= root->box;
01516         right->box= root->box;
01517         if(i==0) {
01518             left->box.xmax= root->divider[0];
01519             right->box.xmin= root->divider[0];
01520         }
01521         else {
01522             left->box.ymax= root->divider[1];
01523             right->box.ymin= root->divider[1];
01524         }
01525         isb_bsp_split_init(left, mem, level-1);
01526         isb_bsp_split_init(right, mem, level-1);
01527     }
01528     else {
01529         /* we add sample array */
01530         root->samples= BLI_memarena_alloc(mem, BSPMAX_SAMPLE*sizeof(void *));
01531     }
01532 }
01533 
01534 /* note; if all samples on same location we just spread them over 2 new branches */
01535 static void isb_bsp_split(ISBBranch *root, MemArena *mem)
01536 {
01537     ISBBranch *left, *right;
01538     ISBSample *samples[BSPMAX_SAMPLE];
01539     int a, i;
01540 
01541     /* splitpoint */
01542     root->divider[0]= root->divider[1]= 0.0f;
01543     for(a=BSPMAX_SAMPLE-1; a>=0; a--) {
01544         root->divider[0]+= root->samples[a]->zco[0];
01545         root->divider[1]+= root->samples[a]->zco[1];
01546     }
01547     root->divider[0]/= BSPMAX_SAMPLE;
01548     root->divider[1]/= BSPMAX_SAMPLE;
01549     
01550     /* find best splitpoint */
01551     if(root->box.xmax-root->box.xmin > root->box.ymax-root->box.ymin)
01552         i= root->index= 0;
01553     else
01554         i= root->index= 1;
01555     
01556     /* new branches */
01557     left= root->left= BLI_memarena_alloc(mem, sizeof(ISBBranch));
01558     right= root->right= BLI_memarena_alloc(mem, sizeof(ISBBranch));
01559 
01560     /* new sample array */
01561     left->samples= BLI_memarena_alloc(mem, BSPMAX_SAMPLE*sizeof(void *));
01562     right->samples= samples; // tmp
01563     
01564     /* split samples */
01565     for(a=BSPMAX_SAMPLE-1; a>=0; a--) {
01566         int comp= 0;
01567         /* this prevents adding samples all to 1 branch when divider is equal to samples */
01568         if(root->samples[a]->zco[i] == root->divider[i])
01569             comp= a & 1;
01570         else if(root->samples[a]->zco[i] < root->divider[i])
01571             comp= 1;
01572         
01573         if(comp==1) {
01574             left->samples[left->totsamp]= root->samples[a];
01575             left->totsamp++;
01576         }
01577         else {
01578             right->samples[right->totsamp]= root->samples[a];
01579             right->totsamp++;
01580         }
01581     }
01582     
01583     /* copy samples from tmp */
01584     memcpy(root->samples, samples, right->totsamp*(sizeof(void *)));
01585     right->samples= root->samples;
01586     root->samples= NULL;
01587     
01588     /* box info */
01589     left->box= root->box;
01590     right->box= root->box;
01591     if(i==0) {
01592         left->box.xmax= root->divider[0];
01593         right->box.xmin= root->divider[0];
01594     }
01595     else {
01596         left->box.ymax= root->divider[1];
01597         right->box.ymin= root->divider[1];
01598     }
01599 }
01600 
01601 /* inserts sample in main tree, also splits on threshold */
01602 /* returns 1 if error */
01603 static int isb_bsp_insert(ISBBranch *root, MemArena *memarena, ISBSample *sample)
01604 {
01605     ISBBranch *bspn= root;
01606     float *zco= sample->zco;
01607     int i= 0;
01608     
01609     /* debug counter, also used to check if something was filled in ever */
01610     root->totsamp++;
01611     
01612     /* going over branches until last one found */
01613     while(bspn->left) {
01614         if(zco[bspn->index] <= bspn->divider[bspn->index])
01615             bspn= bspn->left;
01616         else
01617             bspn= bspn->right;
01618         i++;
01619     }
01620     /* bspn now is the last branch */
01621     
01622     if(bspn->totsamp==BSPMAX_SAMPLE) {
01623         printf("error in bsp branch\n");    /* only for debug, cannot happen */
01624         return 1;
01625     }
01626     
01627     /* insert */
01628     bspn->samples[bspn->totsamp]= sample;
01629     bspn->totsamp++;
01630 
01631     /* split if allowed and needed */
01632     if(bspn->totsamp==BSPMAX_SAMPLE) {
01633         if(i==BSPMAX_DEPTH) {
01634             bspn->totsamp--;    /* stop filling in... will give errors */
01635             return 1;
01636         }
01637         isb_bsp_split(bspn, memarena);
01638     }
01639     return 0;
01640 }
01641 
01642 /* initialize vars in face, for optimal point-in-face test */
01643 static void bspface_init_strand(BSPFace *face) 
01644 {
01645     
01646     face->radline= 0.5f* len_v2v2(face->v1, face->v2);
01647     
01648     mid_v3_v3v3(face->vec1, face->v1, face->v2);
01649     if(face->v4)
01650         mid_v3_v3v3(face->vec2, face->v3, face->v4);
01651     else
01652         copy_v3_v3(face->vec2, face->v3);
01653     
01654     face->rc[0]= face->vec2[0]-face->vec1[0];
01655     face->rc[1]= face->vec2[1]-face->vec1[1];
01656     face->rc[2]= face->vec2[2]-face->vec1[2];
01657     
01658     face->len= face->rc[0]*face->rc[0]+ face->rc[1]*face->rc[1];
01659     
01660     if(face->len!=0.0f) {
01661         face->radline_end= face->radline/sqrt(face->len);
01662         face->len= 1.0f/face->len;
01663     }
01664 }
01665 
01666 /* brought back to a simple 2d case */
01667 static int point_behind_strand(const float p[3], BSPFace *face)
01668 {
01669     /* v1 - v2 is radius, v1 - v3 length */
01670     float dist, rc[2], pt[2];
01671     
01672     /* using code from dist_to_line_segment_v2(), distance vec to line-piece */
01673 
01674     if(face->len==0.0f) {
01675         rc[0]= p[0]-face->vec1[0];
01676         rc[1]= p[1]-face->vec1[1];
01677         dist= (float)(sqrt(rc[0]*rc[0]+ rc[1]*rc[1]));
01678         
01679         if(dist < face->radline)
01680             return 1;
01681     }
01682     else {
01683         float labda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len;
01684         
01685         if(labda > -face->radline_end && labda < 1.0f+face->radline_end) { 
01686             /* hesse for dist: */
01687             //dist= (float)(fabs( (p[0]-vec2[0])*rc[1] + (p[1]-vec2[1])*rc[0])/len);
01688             
01689             pt[0]= labda*face->rc[0]+face->vec1[0];
01690             pt[1]= labda*face->rc[1]+face->vec1[1];
01691             
01692             rc[0]= pt[0]-p[0];
01693             rc[1]= pt[1]-p[1];
01694             dist= (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]);
01695             
01696             if(dist < face->radline) {
01697                 float zval= face->vec1[2] + labda*face->rc[2];
01698                 if(p[2] > zval)
01699                     return 1;
01700             }
01701         }
01702     }
01703     return 0;
01704 }
01705 
01706 
01707 /* return 1 if inside. code derived from src/parametrizer.c */
01708 static int point_behind_tria2d(const float p[3], const float v1[3], const float v2[3], const float v3[3])
01709 {
01710     float a[2], c[2], h[2], div;
01711     float u, v;
01712     
01713     a[0] = v2[0] - v1[0];
01714     a[1] = v2[1] - v1[1];
01715     c[0] = v3[0] - v1[0];
01716     c[1] = v3[1] - v1[1];
01717     
01718     div = a[0]*c[1] - a[1]*c[0];
01719     if(div==0.0f)
01720         return 0;
01721     
01722     h[0] = p[0] - v1[0];
01723     h[1] = p[1] - v1[1];
01724     
01725     div = 1.0f/div;
01726     
01727     u = (h[0]*c[1] - h[1]*c[0])*div;
01728     if(u >= 0.0f) {
01729         v = (a[0]*h[1] - a[1]*h[0])*div;
01730         if(v >= 0.0f) {
01731             if( u + v <= 1.0f) {
01732                 /* inside, now check if point p is behind */
01733                 float z=  (1.0f-u-v)*v1[2] + u*v2[2] + v*v3[2];
01734                 if(z <= p[2])
01735                     return 1;
01736             }
01737         }
01738     }
01739     
01740     return 0;
01741 }
01742 
01743 #if 0
01744 /* tested these calls, but it gives inaccuracy, 'side' cannot be found reliably using v3 */
01745 
01746 /* check if line v1-v2 has all rect points on other side of point v3 */
01747 static int rect_outside_line(rctf *rect, const float v1[3], const float v2[3], const float v3[3])
01748 {
01749     float a, b, c;
01750     int side;
01751     
01752     /* line formula for v1-v2 */
01753     a= v2[1]-v1[1];
01754     b= v1[0]-v2[0];
01755     c= -a*v1[0] - b*v1[1];
01756     side= a*v3[0] + b*v3[1] + c < 0.0f;
01757     
01758     /* the four quad points */
01759     if( side==(rect->xmin*a + rect->ymin*b + c >= 0.0f) )
01760         if( side==(rect->xmax*a + rect->ymin*b + c >= 0.0f) )
01761             if( side==(rect->xmax*a + rect->ymax*b + c >= 0.0f) )
01762                 if( side==(rect->xmin*a + rect->ymax*b + c >= 0.0f) )
01763                     return 1;
01764     return 0;
01765 }
01766 
01767 /* check if one of the triangle edges separates all rect points on 1 side */
01768 static int rect_isect_tria(rctf *rect, const float v1[3], const float v2[3], const float v3[3])
01769 {
01770     if(rect_outside_line(rect, v1, v2, v3))
01771         return 0;
01772     if(rect_outside_line(rect, v2, v3, v1))
01773         return 0;
01774     if(rect_outside_line(rect, v3, v1, v2))
01775         return 0;
01776     return 1;
01777 }
01778 #endif
01779 
01780 /* if face overlaps a branch, it executes func. recursive */
01781 static void isb_bsp_face_inside(ISBBranch *bspn, BSPFace *face)
01782 {
01783     
01784     /* are we descending? */
01785     if(bspn->left) {
01786         /* hrmf, the box struct cannot be addressed with index */
01787         if(bspn->index==0) {
01788             if(face->box.xmin <= bspn->divider[0])
01789                 isb_bsp_face_inside(bspn->left, face);
01790             if(face->box.xmax > bspn->divider[0])
01791                 isb_bsp_face_inside(bspn->right, face);
01792         }
01793         else {
01794             if(face->box.ymin <= bspn->divider[1])
01795                 isb_bsp_face_inside(bspn->left, face);
01796             if(face->box.ymax > bspn->divider[1])
01797                 isb_bsp_face_inside(bspn->right, face);
01798         }
01799     }
01800     else {
01801         /* else: end branch reached */
01802         int a;
01803         
01804         if(bspn->totsamp==0) return;
01805         
01806         /* check for nodes entirely in shadow, can be skipped */
01807         if(bspn->totsamp==bspn->full)
01808             return;
01809         
01810         /* if bsp node is entirely in front of face, give up */
01811         if(bspn->box.zmax < face->box.zmin)
01812             return;
01813         
01814         /* if face boundbox is outside of branch rect, give up */
01815         if(0==BLI_isect_rctf((rctf *)&face->box, (rctf *)&bspn->box, NULL))
01816             return;
01817         
01818         /* test all points inside branch */
01819         for(a=bspn->totsamp-1; a>=0; a--) {
01820             ISBSample *samp= bspn->samples[a];
01821             
01822             if((samp->facenr!=face->facenr || samp->obi!=face->obi) && samp->shadfac) {
01823                 if(face->box.zmin < samp->zco[2]) {
01824                     if(BLI_in_rctf((rctf *)&face->box, samp->zco[0], samp->zco[1])) {
01825                         int inshadow= 0;
01826                         
01827                         if(face->type) {
01828                             if(point_behind_strand(samp->zco, face)) 
01829                                 inshadow= 1;
01830                         }
01831                         else if( point_behind_tria2d(samp->zco, face->v1, face->v2, face->v3))
01832                             inshadow= 1;
01833                         else if(face->v4 && point_behind_tria2d(samp->zco, face->v1, face->v3, face->v4))
01834                             inshadow= 1;
01835 
01836                         if(inshadow) {
01837                             *(samp->shadfac) += face->shad_alpha;
01838                             /* optimize; is_full means shad_alpha==4096 */
01839                             if(*(samp->shadfac) >= 4096 || face->is_full) {
01840                                 bspn->full++;
01841                                 samp->shadfac= NULL;
01842                             }
01843                         }
01844                     }
01845                 }
01846             }
01847         }
01848     }
01849 }
01850 
01851 /* based on available samples, recalculate the bounding box for bsp nodes, recursive */
01852 static void isb_bsp_recalc_box(ISBBranch *root)
01853 {
01854     if(root->left) {
01855         isb_bsp_recalc_box(root->left);
01856         isb_bsp_recalc_box(root->right);
01857     }
01858     else if(root->totsamp) {
01859         int a;
01860         
01861         init_box(&root->box);
01862         for(a=root->totsamp-1; a>=0; a--)
01863             bound_boxf(&root->box, root->samples[a]->zco);
01864     }   
01865 }
01866 
01867 /* callback function for zbuf clip */
01868 static void isb_bsp_test_strand(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
01869 {
01870     BSPFace face;
01871     
01872     face.v1= v1;
01873     face.v2= v2;
01874     face.v3= v3;
01875     face.v4= v4;
01876     face.obi= obi;
01877     face.facenr= zvlnr & ~RE_QUAD_OFFS;
01878     face.type= R_STRAND;
01879     if(R.osa)
01880         face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha/(float)R.osa);
01881     else
01882         face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha);
01883     
01884     face.is_full= (zspan->shad_alpha==1.0f);
01885     
01886     /* setup boundbox */
01887     init_box(&face.box);
01888     bound_boxf(&face.box, v1);
01889     bound_boxf(&face.box, v2);
01890     bound_boxf(&face.box, v3);
01891     if(v4)
01892         bound_boxf(&face.box, v4);
01893     
01894     /* optimize values */
01895     bspface_init_strand(&face);
01896     
01897     isb_bsp_face_inside((ISBBranch *)zspan->rectz, &face);
01898     
01899 }
01900 
01901 /* callback function for zbuf clip */
01902 static void isb_bsp_test_face(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4) 
01903 {
01904     BSPFace face;
01905     
01906     face.v1= v1;
01907     face.v2= v2;
01908     face.v3= v3;
01909     face.v4= v4;
01910     face.obi= obi;
01911     face.facenr= zvlnr & ~RE_QUAD_OFFS;
01912     face.type= 0;
01913     if(R.osa)
01914         face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha/(float)R.osa);
01915     else
01916         face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha);
01917     
01918     face.is_full= (zspan->shad_alpha==1.0f);
01919     
01920     /* setup boundbox */
01921     init_box(&face.box);
01922     bound_boxf(&face.box, v1);
01923     bound_boxf(&face.box, v2);
01924     bound_boxf(&face.box, v3);
01925     if(v4)
01926         bound_boxf(&face.box, v4);
01927 
01928     isb_bsp_face_inside((ISBBranch *)zspan->rectz, &face);
01929 }
01930 
01931 static int testclip_minmax(const float ho[4], const float minmax[4])
01932 {
01933     float wco= ho[3];
01934     int flag= 0;
01935     
01936     if( ho[0] > minmax[1]*wco) flag = 1;
01937     else if( ho[0]< minmax[0]*wco) flag = 2;
01938     
01939     if( ho[1] > minmax[3]*wco) flag |= 4;
01940     else if( ho[1]< minmax[2]*wco) flag |= 8;
01941     
01942     return flag;
01943 }
01944 
01945 /* main loop going over all faces and check in bsp overlaps, fill in shadfac values */
01946 static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
01947 {
01948     ObjectInstanceRen *obi;
01949     ObjectRen *obr;
01950     ShadBuf *shb= lar->shb;
01951     ZSpan zspan, zspanstrand;
01952     VlakRen *vlr= NULL;
01953     Material *ma= NULL;
01954     float minmaxf[4], winmat[4][4];
01955     int size= shb->size;
01956     int i, a, ok=1, lay= -1;
01957     
01958     /* further optimize, also sets minz maxz */
01959     isb_bsp_recalc_box(root);
01960     
01961     /* extra clipping for minmax */
01962     minmaxf[0]= (2.0f*root->box.xmin - size-2.0f)/size;
01963     minmaxf[1]= (2.0f*root->box.xmax - size+2.0f)/size;
01964     minmaxf[2]= (2.0f*root->box.ymin - size-2.0f)/size;
01965     minmaxf[3]= (2.0f*root->box.ymax - size+2.0f)/size;
01966     
01967     if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay;
01968     
01969     /* (ab)use zspan, since we use zbuffer clipping code */
01970     zbuf_alloc_span(&zspan, size, size, re->clipcrop);
01971     
01972     zspan.zmulx=  ((float)size)/2.0f;
01973     zspan.zmuly=  ((float)size)/2.0f;
01974     zspan.zofsx= -0.5f;
01975     zspan.zofsy= -0.5f;
01976     
01977     /* pass on bsp root to zspan */
01978     zspan.rectz= (int *)root;
01979     
01980     /* filling methods */
01981     zspanstrand= zspan;
01982     //  zspan.zbuflinefunc= zbufline_onlyZ;
01983     zspan.zbuffunc= isb_bsp_test_face;
01984     zspanstrand.zbuffunc= isb_bsp_test_strand;
01985     
01986     for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
01987         obr= obi->obr;
01988 
01989         if(obi->flag & R_TRANSFORMED)
01990             mult_m4_m4m4(winmat, shb->persmat, obi->mat);
01991         else
01992             copy_m4_m4(winmat, shb->persmat);
01993 
01994         for(a=0; a<obr->totvlak; a++) {
01995             
01996             if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
01997             else vlr++;
01998             
01999             /* note, these conditions are copied in shadowbuf_autoclip() */
02000             if(vlr->mat!= ma) {
02001                 ma= vlr->mat;
02002                 ok= 1;
02003                 if((ma->mode & MA_SHADBUF)==0) ok= 0;
02004                 if(ma->material_type == MA_TYPE_WIRE) ok= 0;
02005                 zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
02006             }
02007             
02008             if(ok && (obi->lay & lay)) {
02009                 float hoco[4][4];
02010                 int c1, c2, c3, c4=0;
02011                 int d1, d2, d3, d4=0;
02012                 int partclip;
02013                 
02014                 /* create hocos per face, it is while render */
02015                 projectvert(vlr->v1->co, winmat, hoco[0]); d1= testclip_minmax(hoco[0], minmaxf);
02016                 projectvert(vlr->v2->co, winmat, hoco[1]); d2= testclip_minmax(hoco[1], minmaxf);
02017                 projectvert(vlr->v3->co, winmat, hoco[2]); d3= testclip_minmax(hoco[2], minmaxf);
02018                 if(vlr->v4) {
02019                     projectvert(vlr->v4->co, winmat, hoco[3]); d4= testclip_minmax(hoco[3], minmaxf);
02020                 }
02021 
02022                 /* minmax clipping */
02023                 if(vlr->v4) partclip= d1 & d2 & d3 & d4;
02024                 else partclip= d1 & d2 & d3;
02025                 
02026                 if(partclip==0) {
02027                     
02028                     /* window clipping */
02029                     c1= testclip(hoco[0]); 
02030                     c2= testclip(hoco[1]); 
02031                     c3= testclip(hoco[2]); 
02032                     if(vlr->v4)
02033                         c4= testclip(hoco[3]); 
02034                     
02035                     /* ***** NO WIRE YET */         
02036                     if(ma->material_type == MA_TYPE_WIRE) {
02037                         if(vlr->v4)
02038                             zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
02039                         else
02040                             zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], 0, c1, c2, c3, 0);
02041                     }
02042                     else if(vlr->v4) {
02043                         if(vlr->flag & R_STRAND)
02044                             zbufclip4(&zspanstrand, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
02045                         else
02046                             zbufclip4(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
02047                     }
02048                     else
02049                         zbufclip(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], c1, c2, c3);
02050                     
02051                 }
02052             }
02053         }
02054     }
02055     
02056     zbuf_free_span(&zspan);
02057 }
02058 
02059 /* returns 1 when the viewpixel is visible in lampbuffer */
02060 static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *vlr, float x, float y, float co_r[3])
02061 {
02062     float hoco[4], v1[3], nor[3];
02063     float dface, fac, siz;
02064     
02065     RE_vlakren_get_normal(&R, obi, vlr, nor);
02066     copy_v3_v3(v1, vlr->v1->co);
02067     if(obi->flag & R_TRANSFORMED)
02068         mul_m4_v3(obi->mat, v1);
02069 
02070     /* from shadepixel() */
02071     dface= v1[0]*nor[0] + v1[1]*nor[1] + v1[2]*nor[2];
02072     hoco[3]= 1.0f;
02073     
02074     /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */
02075     if(R.r.mode & R_ORTHO) {
02076         /* x and y 3d coordinate can be derived from pixel coord and winmat */
02077         float fx= 2.0f/(R.winx*R.winmat[0][0]);
02078         float fy= 2.0f/(R.winy*R.winmat[1][1]);
02079         
02080         hoco[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
02081         hoco[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
02082         
02083         /* using a*x + b*y + c*z = d equation, (a b c) is normal */
02084         if(nor[2]!=0.0f)
02085             hoco[2]= (dface - nor[0]*hoco[0] - nor[1]*hoco[1])/nor[2];
02086         else
02087             hoco[2]= 0.0f;
02088     }
02089     else {
02090         float div, view[3];
02091         
02092         calc_view_vector(view, x, y);
02093         
02094         div= nor[0]*view[0] + nor[1]*view[1] + nor[2]*view[2];
02095         if (div==0.0f) 
02096             return 0;
02097         
02098         fac= dface/div;
02099         
02100         hoco[0]= fac*view[0];
02101         hoco[1]= fac*view[1];
02102         hoco[2]= fac*view[2];
02103     }
02104     
02105     /* move 3d vector to lampbuf */
02106     mul_m4_v4(shb->persmat, hoco);  /* rational hom co */
02107     
02108     /* clip We can test for -1.0/1.0 because of the properties of the
02109      * coordinate transformations. */
02110     fac= fabs(hoco[3]);
02111     if(hoco[0]<-fac || hoco[0]>fac)
02112         return 0;
02113     if(hoco[1]<-fac || hoco[1]>fac)
02114         return 0;
02115     if(hoco[2]<-fac || hoco[2]>fac)
02116         return 0;
02117     
02118     siz= 0.5f*(float)shb->size;
02119     co_r[0]= siz*(1.0f+hoco[0]/hoco[3]) -0.5f;
02120     co_r[1]= siz*(1.0f+hoco[1]/hoco[3]) -0.5f;
02121     co_r[2]= ((float)0x7FFFFFFF)*(hoco[2]/hoco[3]);
02122     
02123     /* XXXX bias, much less than normal shadbuf, or do we need a constant? */
02124     co_r[2] -= 0.05f*shb->bias;
02125     
02126     return 1;
02127 }
02128 
02129 /* storage of shadow results, solid osa and transp case */
02130 static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int obi, int facenr, short shadfac, short samples)
02131 {
02132     ISBShadfacA *new;
02133     float shadfacf;
02134     
02135     /* in osa case, the samples were filled in with factor 1.0/R.osa. if fewer samples we have to correct */
02136     if(R.osa)
02137         shadfacf= ((float)shadfac*R.osa)/(4096.0f*samples);
02138     else
02139         shadfacf= ((float)shadfac)/(4096.0f);
02140     
02141     new= BLI_memarena_alloc(mem, sizeof(ISBShadfacA));
02142     new->obi= obi;
02143     new->facenr= facenr & ~RE_QUAD_OFFS;
02144     new->shadfac= shadfacf;
02145     if(*isbsapp)
02146         new->next= (*isbsapp);
02147     else
02148         new->next= NULL;
02149     
02150     *isbsapp= new;
02151 }
02152 
02153 /* adding samples, solid case */
02154 static int isb_add_samples(RenderPart *pa, ISBBranch *root, MemArena *memarena, ISBSample **samplebuf)
02155 {
02156     int xi, yi, *xcos, *ycos;
02157     int sample, bsp_err= 0;
02158     
02159     /* bsp split doesn't like to handle regular sequences */
02160     xcos= MEM_mallocN( pa->rectx*sizeof(int), "xcos");
02161     ycos= MEM_mallocN( pa->recty*sizeof(int), "ycos");
02162     for(xi=0; xi<pa->rectx; xi++)
02163         xcos[xi]= xi;
02164     for(yi=0; yi<pa->recty; yi++)
02165         ycos[yi]= yi;
02166     BLI_array_randomize(xcos, sizeof(int), pa->rectx, 12345);
02167     BLI_array_randomize(ycos, sizeof(int), pa->recty, 54321);
02168     
02169     for(sample=0; sample<(R.osa?R.osa:1); sample++) {
02170         ISBSample *samp= samplebuf[sample], *samp1;
02171         
02172         for(yi=0; yi<pa->recty; yi++) {
02173             int y= ycos[yi];
02174             for(xi=0; xi<pa->rectx; xi++) {
02175                 int x= xcos[xi];
02176                 samp1= samp + y*pa->rectx + x;
02177                 if(samp1->facenr)
02178                     bsp_err |= isb_bsp_insert(root, memarena, samp1);
02179             }
02180             if(bsp_err) break;
02181         }
02182     }   
02183     
02184     MEM_freeN(xcos);
02185     MEM_freeN(ycos);
02186 
02187     return bsp_err;
02188 }
02189 
02190 /* solid version */
02191 /* lar->shb, pa->rectz and pa->rectp should exist */
02192 static void isb_make_buffer(RenderPart *pa, LampRen *lar)
02193 {
02194     ShadBuf *shb= lar->shb;
02195     ISBData *isbdata;
02196     ISBSample *samp, *samplebuf[16];    /* should be RE_MAX_OSA */
02197     ISBBranch root;
02198     MemArena *memarena;
02199     intptr_t *rd;
02200     int *recto, *rectp, x, y, sindex, sample, bsp_err=0;
02201     
02202     /* storage for shadow, per thread */
02203     isbdata= shb->isb_result[pa->thread];
02204     
02205     /* to map the shi->xs and ys coordinate */
02206     isbdata->minx= pa->disprect.xmin;
02207     isbdata->miny= pa->disprect.ymin;
02208     isbdata->rectx= pa->rectx;
02209     isbdata->recty= pa->recty;
02210     
02211     /* branches are added using memarena (32k branches) */
02212     memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena");
02213     BLI_memarena_use_calloc(memarena);
02214     
02215     /* samplebuf is in camera view space (pixels) */
02216     for(sample=0; sample<(R.osa?R.osa:1); sample++)
02217         samplebuf[sample]= MEM_callocN(sizeof(ISBSample)*pa->rectx*pa->recty, "isb samplebuf");
02218     
02219     /* for end result, ISBSamples point to this in non OSA case, otherwise to pixstruct->shadfac */
02220     if(R.osa==0)
02221         isbdata->shadfacs= MEM_callocN(pa->rectx*pa->recty*sizeof(short), "isb shadfacs");
02222     
02223     /* setup bsp root */
02224     memset(&root, 0, sizeof(ISBBranch));
02225     root.box.xmin= (float)shb->size;
02226     root.box.ymin= (float)shb->size;
02227     
02228     /* create the sample buffers */
02229     for(sindex=0, y=0; y<pa->recty; y++) {
02230         for(x=0; x<pa->rectx; x++, sindex++) {
02231             
02232             /* this makes it a long function, but splitting it out would mean 10+ arguments */
02233             /* first check OSA case */
02234             if(R.osa) {
02235                 rd= pa->rectdaps + sindex;
02236                 if(*rd) {
02237                     float xs= (float)(x + pa->disprect.xmin);
02238                     float ys= (float)(y + pa->disprect.ymin);
02239                     
02240                     for(sample=0; sample<R.osa; sample++) {
02241                         PixStr *ps= (PixStr *)(*rd);
02242                         int mask= (1<<sample);
02243                         
02244                         while(ps) {
02245                             if(ps->mask & mask)
02246                                 break;
02247                             ps= ps->next;
02248                         }
02249                         if(ps && ps->facenr>0) {
02250                             ObjectInstanceRen *obi= &R.objectinstance[ps->obi];
02251                             ObjectRen *obr= obi->obr;
02252                             VlakRen *vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
02253                             
02254                             samp= samplebuf[sample] + sindex;
02255                             /* convert image plane pixel location to lamp buffer space */
02256                             if(viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], samp->zco)) {
02257                                 samp->obi= ps->obi;
02258                                 samp->facenr= ps->facenr & ~RE_QUAD_OFFS;
02259                                 ps->shadfac= 0;
02260                                 samp->shadfac= &ps->shadfac;
02261                                 bound_rectf((rctf *)&root.box, samp->zco);
02262                             }
02263                         }
02264                     }
02265                 }
02266             }
02267             else {
02268                 rectp= pa->rectp + sindex;
02269                 recto= pa->recto + sindex;
02270                 if(*rectp>0) {
02271                     ObjectInstanceRen *obi= &R.objectinstance[*recto];
02272                     ObjectRen *obr= obi->obr;
02273                     VlakRen *vlr= RE_findOrAddVlak(obr, (*rectp-1) & RE_QUAD_MASK);
02274                     float xs= (float)(x + pa->disprect.xmin);
02275                     float ys= (float)(y + pa->disprect.ymin);
02276                     
02277                     samp= samplebuf[0] + sindex;
02278                     /* convert image plane pixel location to lamp buffer space */
02279                     if(viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, samp->zco)) {
02280                         samp->obi= *recto;
02281                         samp->facenr= *rectp & ~RE_QUAD_OFFS;
02282                         samp->shadfac= isbdata->shadfacs + sindex;
02283                         bound_rectf((rctf *)&root.box, samp->zco);
02284                     }
02285                 }
02286             }
02287         }
02288     }
02289     
02290     /* simple method to see if we have samples */
02291     if(root.box.xmin != (float)shb->size) {
02292         /* now create a regular split, root.box has the initial bounding box of all pixels */
02293         /* split bsp 8 levels deep, in regular grid (16 x 16) */
02294         isb_bsp_split_init(&root, memarena, 8);
02295         
02296         /* insert all samples in BSP now */
02297         bsp_err= isb_add_samples(pa, &root, memarena, samplebuf);
02298             
02299         if(bsp_err==0) {
02300             /* go over all faces and fill in shadow values */
02301             
02302             isb_bsp_fillfaces(&R, lar, &root);  /* shb->persmat should have been calculated */
02303             
02304             /* copy shadow samples to persistent buffer, reduce memory overhead */
02305             if(R.osa) {
02306                 ISBShadfacA **isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs");
02307                 
02308                 isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena");
02309                 BLI_memarena_use_calloc(isbdata->memarena);
02310 
02311                 for(rd= pa->rectdaps, x=pa->rectx*pa->recty; x>0; x--, rd++, isbsa++) {
02312                     
02313                     if(*rd) {
02314                         PixStr *ps= (PixStr *)(*rd);
02315                         while(ps) {
02316                             if(ps->shadfac)
02317                                 isb_add_shadfac(isbsa, isbdata->memarena, ps->obi, ps->facenr, ps->shadfac, count_mask(ps->mask));
02318                             ps= ps->next;
02319                         }
02320                     }
02321                 }
02322             }
02323         }
02324     }
02325     else {
02326         if(isbdata->shadfacs) {
02327             MEM_freeN(isbdata->shadfacs);
02328             isbdata->shadfacs= NULL;
02329         }
02330     }
02331 
02332     /* free BSP */
02333     BLI_memarena_free(memarena);
02334     
02335     /* free samples */
02336     for(x=0; x<(R.osa?R.osa:1); x++)
02337         MEM_freeN(samplebuf[x]);
02338     
02339     if(bsp_err) printf("error in filling bsp\n");
02340 }
02341 
02342 /* add sample to buffer, isbsa is the root sample in a buffer */
02343 static ISBSampleA *isb_alloc_sample_transp(ISBSampleA **isbsa, MemArena *mem)
02344 {
02345     ISBSampleA *new;
02346     
02347     new= BLI_memarena_alloc(mem, sizeof(ISBSampleA));
02348     if(*isbsa)
02349         new->next= (*isbsa);
02350     else
02351         new->next= NULL;
02352     
02353     *isbsa= new;
02354     return new;
02355 }
02356 
02357 /* adding samples in BSP, transparent case */
02358 static int isb_add_samples_transp(RenderPart *pa, ISBBranch *root, MemArena *memarena, ISBSampleA ***samplebuf)
02359 {
02360     int xi, yi, *xcos, *ycos;
02361     int sample, bsp_err= 0;
02362     
02363     /* bsp split doesn't like to handle regular sequences */
02364     xcos= MEM_mallocN( pa->rectx*sizeof(int), "xcos");
02365     ycos= MEM_mallocN( pa->recty*sizeof(int), "ycos");
02366     for(xi=0; xi<pa->rectx; xi++)
02367         xcos[xi]= xi;
02368     for(yi=0; yi<pa->recty; yi++)
02369         ycos[yi]= yi;
02370     BLI_array_randomize(xcos, sizeof(int), pa->rectx, 12345);
02371     BLI_array_randomize(ycos, sizeof(int), pa->recty, 54321);
02372     
02373     for(sample=0; sample<(R.osa?R.osa:1); sample++) {
02374         ISBSampleA **samp= samplebuf[sample], *samp1;
02375         
02376         for(yi=0; yi<pa->recty; yi++) {
02377             int y= ycos[yi];
02378             for(xi=0; xi<pa->rectx; xi++) {
02379                 int x= xcos[xi];
02380                 
02381                 samp1= *(samp + y*pa->rectx + x);
02382                 while(samp1) {
02383                     bsp_err |= isb_bsp_insert(root, memarena, (ISBSample *)samp1);
02384                     samp1= samp1->next;
02385                 }
02386             }
02387             if(bsp_err) break;
02388         }
02389     }   
02390     
02391     MEM_freeN(xcos);
02392     MEM_freeN(ycos);
02393     
02394     return bsp_err;
02395 }
02396 
02397 
02398 /* Ztransp version */
02399 /* lar->shb, pa->rectz and pa->rectp should exist */
02400 static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *lar)
02401 {
02402     ShadBuf *shb= lar->shb;
02403     ISBData *isbdata;
02404     ISBSampleA *samp, **samplebuf[16];  /* MAX_OSA */
02405     ISBBranch root;
02406     MemArena *memarena;
02407     APixstr *ap;
02408     int x, y, sindex, sample, bsp_err=0;
02409     
02410     /* storage for shadow, per thread */
02411     isbdata= shb->isb_result[pa->thread];
02412     
02413     /* to map the shi->xs and ys coordinate */
02414     isbdata->minx= pa->disprect.xmin;
02415     isbdata->miny= pa->disprect.ymin;
02416     isbdata->rectx= pa->rectx;
02417     isbdata->recty= pa->recty;
02418     
02419     /* branches are added using memarena (32k branches) */
02420     memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena");
02421     BLI_memarena_use_calloc(memarena);
02422     
02423     /* samplebuf is in camera view space (pixels) */
02424     for(sample=0; sample<(R.osa?R.osa:1); sample++)
02425         samplebuf[sample]= MEM_callocN(sizeof(void *)*pa->rectx*pa->recty, "isb alpha samplebuf");
02426     
02427     /* setup bsp root */
02428     memset(&root, 0, sizeof(ISBBranch));
02429     root.box.xmin= (float)shb->size;
02430     root.box.ymin= (float)shb->size;
02431 
02432     /* create the sample buffers */
02433     for(ap= apixbuf, sindex=0, y=0; y<pa->recty; y++) {
02434         for(x=0; x<pa->rectx; x++, sindex++, ap++) {
02435             
02436             if(ap->p[0]) {
02437                 APixstr *apn;
02438                 float xs= (float)(x + pa->disprect.xmin);
02439                 float ys= (float)(y + pa->disprect.ymin);
02440                 
02441                 for(apn=ap; apn; apn= apn->next) {
02442                     int a;
02443                     for(a=0; a<4; a++) {
02444                         if(apn->p[a]) {
02445                             ObjectInstanceRen *obi= &R.objectinstance[apn->obi[a]];
02446                             ObjectRen *obr= obi->obr;
02447                             VlakRen *vlr= RE_findOrAddVlak(obr, (apn->p[a]-1) & RE_QUAD_MASK);
02448                             float zco[3];
02449                             
02450                             /* here we store shadfac, easier to create the end storage buffer. needs zero'ed, multiple shadowbufs use it */
02451                             apn->shadfac[a]= 0;
02452                             
02453                             if(R.osa) {
02454                                 for(sample=0; sample<R.osa; sample++) {
02455                                     int mask= (1<<sample);
02456                                     
02457                                     if(apn->mask[a] & mask) {
02458                                         
02459                                         /* convert image plane pixel location to lamp buffer space */
02460                                         if(viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], zco)) {
02461                                             samp= isb_alloc_sample_transp(samplebuf[sample] + sindex, memarena);
02462                                             samp->obi= apn->obi[a];
02463                                             samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
02464                                             samp->shadfac= &apn->shadfac[a];
02465                                             
02466                                             copy_v3_v3(samp->zco, zco);
02467                                             bound_rectf((rctf *)&root.box, samp->zco);
02468                                         }
02469                                     }
02470                                 }
02471                             }
02472                             else {
02473                                 
02474                                 /* convert image plane pixel location to lamp buffer space */
02475                                 if(viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, zco)) {
02476                                     
02477                                     samp= isb_alloc_sample_transp(samplebuf[0] + sindex, memarena);
02478                                     samp->obi= apn->obi[a];
02479                                     samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
02480                                     samp->shadfac= &apn->shadfac[a];
02481                                     
02482                                     copy_v3_v3(samp->zco, zco);
02483                                     bound_rectf((rctf *)&root.box, samp->zco);
02484                                 }
02485                             }
02486                         }
02487                     }
02488                 }
02489             }
02490         }
02491     }
02492     
02493     /* simple method to see if we have samples */
02494     if(root.box.xmin != (float)shb->size) {
02495         /* now create a regular split, root.box has the initial bounding box of all pixels */
02496         /* split bsp 8 levels deep, in regular grid (16 x 16) */
02497         isb_bsp_split_init(&root, memarena, 8);
02498         
02499         /* insert all samples in BSP now */
02500         bsp_err= isb_add_samples_transp(pa, &root, memarena, samplebuf);
02501         
02502         if(bsp_err==0) {
02503             ISBShadfacA **isbsa;
02504             
02505             /* go over all faces and fill in shadow values */
02506             isb_bsp_fillfaces(&R, lar, &root);  /* shb->persmat should have been calculated */
02507             
02508             /* copy shadow samples to persistent buffer, reduce memory overhead */
02509             isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs");
02510             
02511             isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena");
02512             
02513             for(ap= apixbuf, x=pa->rectx*pa->recty; x>0; x--, ap++, isbsa++) {
02514                     
02515                 if(ap->p[0]) {
02516                     APixstr *apn;
02517                     for(apn=ap; apn; apn= apn->next) {
02518                         int a;
02519                         for(a=0; a<4; a++) {
02520                             if(apn->p[a] && apn->shadfac[a]) {
02521                                 if(R.osa)
02522                                     isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], count_mask(apn->mask[a]));
02523                                 else
02524                                     isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], 0);
02525                             }
02526                         }
02527                     }
02528                 }
02529             }
02530         }
02531     }
02532 
02533     /* free BSP */
02534     BLI_memarena_free(memarena);
02535 
02536     /* free samples */
02537     for(x=0; x<(R.osa?R.osa:1); x++)
02538         MEM_freeN(samplebuf[x]);
02539 
02540     if(bsp_err) printf("error in filling bsp\n");
02541 }
02542 
02543 
02544 
02545 /* exported */
02546 
02547 /* returns amount of light (1.0 = no shadow) */
02548 /* note, shadepixel() rounds the coordinate, not the real sample info */
02549 float ISB_getshadow(ShadeInput *shi, ShadBuf *shb)
02550 {
02551     /* if raytracing, we can't accept irregular shadow */
02552     if(shi->depth==0) {
02553         ISBData *isbdata= shb->isb_result[shi->thread];
02554         
02555         if(isbdata) {
02556             if(isbdata->shadfacs || isbdata->shadfaca) {
02557                 int x= shi->xs - isbdata->minx;
02558                 
02559                 if(x >= 0 && x < isbdata->rectx) {
02560                     int y= shi->ys - isbdata->miny;
02561             
02562                     if(y >= 0 && y < isbdata->recty) {
02563                         if(isbdata->shadfacs) {
02564                             short *sp= isbdata->shadfacs + y*isbdata->rectx + x;
02565                             return *sp>=4096?0.0f:1.0f - ((float)*sp)/4096.0f;
02566                         }
02567                         else {
02568                             int sindex= y*isbdata->rectx + x;
02569                             int obi= shi->obi - R.objectinstance;
02570                             ISBShadfacA *isbsa= *(isbdata->shadfaca + sindex);
02571                             
02572                             while(isbsa) {
02573                                 if(isbsa->facenr==shi->facenr+1 && isbsa->obi==obi)
02574                                     return isbsa->shadfac>=1.0f?0.0f:1.0f - isbsa->shadfac;
02575                                 isbsa= isbsa->next;
02576                             }
02577                         }
02578                     }
02579                 }
02580             }
02581         }
02582     }
02583     return 1.0f;
02584 }
02585 
02586 /* part is supposed to be solid zbuffered (apixbuf==NULL) or transparent zbuffered */
02587 void ISB_create(RenderPart *pa, APixstr *apixbuf)
02588 {
02589     GroupObject *go;
02590     
02591     /* go over all lamps, and make the irregular buffers */
02592     for(go=R.lights.first; go; go= go->next) {
02593         LampRen *lar= go->lampren;
02594         
02595         if(lar->type==LA_SPOT && lar->shb && lar->buftype==LA_SHADBUF_IRREGULAR) {
02596             
02597             /* create storage for shadow, per thread */
02598             lar->shb->isb_result[pa->thread]= MEM_callocN(sizeof(ISBData), "isb data");
02599             
02600             if(apixbuf)
02601                 isb_make_buffer_transp(pa, apixbuf, lar);
02602             else
02603                 isb_make_buffer(pa, lar);
02604         }
02605     }
02606 }
02607 
02608 
02609 /* end of part rendering, free stored shadow data for this thread from all lamps */
02610 void ISB_free(RenderPart *pa)
02611 {
02612     GroupObject *go;
02613     
02614     /* go over all lamps, and free the irregular buffers */
02615     for(go=R.lights.first; go; go= go->next) {
02616         LampRen *lar= go->lampren;
02617         
02618         if(lar->type==LA_SPOT && lar->shb && lar->buftype==LA_SHADBUF_IRREGULAR) {
02619             ISBData *isbdata= lar->shb->isb_result[pa->thread];
02620 
02621             if(isbdata) {
02622                 if(isbdata->shadfacs)
02623                     MEM_freeN(isbdata->shadfacs);
02624                 if(isbdata->shadfaca)
02625                     MEM_freeN(isbdata->shadfaca);
02626                 
02627                 if(isbdata->memarena)
02628                     BLI_memarena_free(isbdata->memarena);
02629                 
02630                 MEM_freeN(isbdata);
02631                 lar->shb->isb_result[pa->thread]= NULL;
02632             }
02633         }
02634     }
02635 }