Blender  V2.59
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 #if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__hppa__) || defined (__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.5;
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                         mul_m4_m4m4(obviewmat, obi->mat, viewmat);
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                                 VECCOPY(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.0);
00778         
00779         perspective_m4( shb->winmat,-wsize, wsize, -wsize, wsize, shb->d, shb->clipend);
00780         mul_m4_m4m4(shb->persmat, shb->viewmat, shb->winmat);
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.0 - temp*temp;
01098                         
01099         }
01100 }
01101 
01102 static void shadowbuf_project_co(float *x, float *y, float *z, ShadBuf *shb, 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, float *co, float *dxco, float *dyco, 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.0 - temp*temp;
01291 }
01292 
01293 
01294 float shadow_halo(LampRen *lar, float *p1, float *p2)
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.5*(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.0+co[0]/co[3]);
01314         yf1= siz*(1.0+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.0+co[0]/co[3]);
01324         yf2= siz*(1.0+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.0) {
01334                         labdax= (xf1-xs1-1.0)/(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.0) {
01351                         labday= (yf1-ys1-1.0)/(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.0) break;
01393                 
01394                 zf= zf1 + labda*(zf2-zf1);
01395                 count+= (float)shb->totbuf;
01396 
01397                 if(zf<= -1.0) lightcount += 1.0;        /* close to the spot */
01398                 else {
01399                 
01400                         /* make sure, behind the clipend we extend halolines. */
01401                         if(zf>=1.0) 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.0) return (lightcount/count);
01411         return 0.0;
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, float *v1)
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, float *v1)
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 static float VecLen2f( float *v1, float *v2)
01643 {
01644         float x= v1[0]-v2[0];
01645         float y= v1[1]-v2[1];
01646         return (float)sqrt(x*x+y*y);
01647 }
01648 
01649 /* initialize vars in face, for optimal point-in-face test */
01650 static void bspface_init_strand(BSPFace *face) 
01651 {
01652         
01653         face->radline= 0.5f*VecLen2f(face->v1, face->v2);
01654         
01655         mid_v3_v3v3(face->vec1, face->v1, face->v2);
01656         if(face->v4)
01657                 mid_v3_v3v3(face->vec2, face->v3, face->v4);
01658         else
01659                 VECCOPY(face->vec2, face->v3);
01660         
01661         face->rc[0]= face->vec2[0]-face->vec1[0];
01662         face->rc[1]= face->vec2[1]-face->vec1[1];
01663         face->rc[2]= face->vec2[2]-face->vec1[2];
01664         
01665         face->len= face->rc[0]*face->rc[0]+ face->rc[1]*face->rc[1];
01666         
01667         if(face->len!=0.0f) {
01668                 face->radline_end= face->radline/sqrt(face->len);
01669                 face->len= 1.0f/face->len;
01670         }
01671 }
01672 
01673 /* brought back to a simple 2d case */
01674 static int point_behind_strand(float *p, BSPFace *face)
01675 {
01676         /* v1 - v2 is radius, v1 - v3 length */
01677         float dist, rc[2], pt[2];
01678         
01679         /* using code from dist_to_line_segment_v2(), distance vec to line-piece */
01680 
01681         if(face->len==0.0f) {
01682                 rc[0]= p[0]-face->vec1[0];
01683                 rc[1]= p[1]-face->vec1[1];
01684                 dist= (float)(sqrt(rc[0]*rc[0]+ rc[1]*rc[1]));
01685                 
01686                 if(dist < face->radline)
01687                         return 1;
01688         }
01689         else {
01690                 float labda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len;
01691                 
01692                 if(labda > -face->radline_end && labda < 1.0f+face->radline_end) { 
01693                         /* hesse for dist: */
01694                         //dist= (float)(fabs( (p[0]-vec2[0])*rc[1] + (p[1]-vec2[1])*rc[0])/len);
01695                         
01696                         pt[0]= labda*face->rc[0]+face->vec1[0];
01697                         pt[1]= labda*face->rc[1]+face->vec1[1];
01698                         
01699                         rc[0]= pt[0]-p[0];
01700                         rc[1]= pt[1]-p[1];
01701                         dist= (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]);
01702                         
01703                         if(dist < face->radline) {
01704                                 float zval= face->vec1[2] + labda*face->rc[2];
01705                                 if(p[2] > zval)
01706                                         return 1;
01707                         }
01708                 }
01709         }
01710         return 0;
01711 }
01712 
01713 
01714 /* return 1 if inside. code derived from src/parametrizer.c */
01715 static int point_behind_tria2d(float *p, float *v1, float *v2, float *v3)
01716 {
01717         float a[2], c[2], h[2], div;
01718         float u, v;
01719         
01720         a[0] = v2[0] - v1[0];
01721         a[1] = v2[1] - v1[1];
01722         c[0] = v3[0] - v1[0];
01723         c[1] = v3[1] - v1[1];
01724         
01725         div = a[0]*c[1] - a[1]*c[0];
01726         if(div==0.0f)
01727                 return 0;
01728         
01729         h[0] = p[0] - v1[0];
01730         h[1] = p[1] - v1[1];
01731         
01732         div = 1.0f/div;
01733         
01734         u = (h[0]*c[1] - h[1]*c[0])*div;
01735         if(u >= 0.0f) {
01736                 v = (a[0]*h[1] - a[1]*h[0])*div;
01737                 if(v >= 0.0f) {
01738                         if( u + v <= 1.0f) {
01739                                 /* inside, now check if point p is behind */
01740                                 float z=  (1.0f-u-v)*v1[2] + u*v2[2] + v*v3[2];
01741                                 if(z <= p[2])
01742                                         return 1;
01743                         }
01744                 }
01745         }
01746         
01747         return 0;
01748 }
01749 
01750 #if 0
01751 /* tested these calls, but it gives inaccuracy, 'side' cannot be found reliably using v3 */
01752 
01753 /* check if line v1-v2 has all rect points on other side of point v3 */
01754 static int rect_outside_line(rctf *rect, float *v1, float *v2, float *v3)
01755 {
01756         float a, b, c;
01757         int side;
01758         
01759         /* line formula for v1-v2 */
01760         a= v2[1]-v1[1];
01761         b= v1[0]-v2[0];
01762         c= -a*v1[0] - b*v1[1];
01763         side= a*v3[0] + b*v3[1] + c < 0.0f;
01764         
01765         /* the four quad points */
01766         if( side==(rect->xmin*a + rect->ymin*b + c >= 0.0f) )
01767                 if( side==(rect->xmax*a + rect->ymin*b + c >= 0.0f) )
01768                         if( side==(rect->xmax*a + rect->ymax*b + c >= 0.0f) )
01769                                 if( side==(rect->xmin*a + rect->ymax*b + c >= 0.0f) )
01770                                         return 1;
01771         return 0;
01772 }
01773 
01774 /* check if one of the triangle edges separates all rect points on 1 side */
01775 static int rect_isect_tria(rctf *rect, float *v1, float *v2, float *v3)
01776 {
01777         if(rect_outside_line(rect, v1, v2, v3))
01778                 return 0;
01779         if(rect_outside_line(rect, v2, v3, v1))
01780                 return 0;
01781         if(rect_outside_line(rect, v3, v1, v2))
01782                 return 0;
01783         return 1;
01784 }
01785 #endif
01786 
01787 /* if face overlaps a branch, it executes func. recursive */
01788 static void isb_bsp_face_inside(ISBBranch *bspn, BSPFace *face)
01789 {
01790         
01791         /* are we descending? */
01792         if(bspn->left) {
01793                 /* hrmf, the box struct cannot be addressed with index */
01794                 if(bspn->index==0) {
01795                         if(face->box.xmin <= bspn->divider[0])
01796                                 isb_bsp_face_inside(bspn->left, face);
01797                         if(face->box.xmax > bspn->divider[0])
01798                                 isb_bsp_face_inside(bspn->right, face);
01799                 }
01800                 else {
01801                         if(face->box.ymin <= bspn->divider[1])
01802                                 isb_bsp_face_inside(bspn->left, face);
01803                         if(face->box.ymax > bspn->divider[1])
01804                                 isb_bsp_face_inside(bspn->right, face);
01805                 }
01806         }
01807         else {
01808                 /* else: end branch reached */
01809                 int a;
01810                 
01811                 if(bspn->totsamp==0) return;
01812                 
01813                 /* check for nodes entirely in shadow, can be skipped */
01814                 if(bspn->totsamp==bspn->full)
01815                         return;
01816                 
01817                 /* if bsp node is entirely in front of face, give up */
01818                 if(bspn->box.zmax < face->box.zmin)
01819                         return;
01820                 
01821                 /* if face boundbox is outside of branch rect, give up */
01822                 if(0==BLI_isect_rctf((rctf *)&face->box, (rctf *)&bspn->box, NULL))
01823                         return;
01824                 
01825                 /* test all points inside branch */
01826                 for(a=bspn->totsamp-1; a>=0; a--) {
01827                         ISBSample *samp= bspn->samples[a];
01828                         
01829                         if((samp->facenr!=face->facenr || samp->obi!=face->obi) && samp->shadfac) {
01830                                 if(face->box.zmin < samp->zco[2]) {
01831                                         if(BLI_in_rctf((rctf *)&face->box, samp->zco[0], samp->zco[1])) {
01832                                                 int inshadow= 0;
01833                                                 
01834                                                 if(face->type) {
01835                                                         if(point_behind_strand(samp->zco, face)) 
01836                                                                 inshadow= 1;
01837                                                 }
01838                                                 else if( point_behind_tria2d(samp->zco, face->v1, face->v2, face->v3))
01839                                                         inshadow= 1;
01840                                                 else if(face->v4 && point_behind_tria2d(samp->zco, face->v1, face->v3, face->v4))
01841                                                         inshadow= 1;
01842 
01843                                                 if(inshadow) {
01844                                                         *(samp->shadfac) += face->shad_alpha;
01845                                                         /* optimize; is_full means shad_alpha==4096 */
01846                                                         if(*(samp->shadfac) >= 4096 || face->is_full) {
01847                                                                 bspn->full++;
01848                                                                 samp->shadfac= NULL;
01849                                                         }
01850                                                 }
01851                                         }
01852                                 }
01853                         }
01854                 }
01855         }
01856 }
01857 
01858 /* based on available samples, recalculate the bounding box for bsp nodes, recursive */
01859 static void isb_bsp_recalc_box(ISBBranch *root)
01860 {
01861         if(root->left) {
01862                 isb_bsp_recalc_box(root->left);
01863                 isb_bsp_recalc_box(root->right);
01864         }
01865         else if(root->totsamp) {
01866                 int a;
01867                 
01868                 init_box(&root->box);
01869                 for(a=root->totsamp-1; a>=0; a--)
01870                         bound_boxf(&root->box, root->samples[a]->zco);
01871         }       
01872 }
01873 
01874 /* callback function for zbuf clip */
01875 static void isb_bsp_test_strand(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
01876 {
01877         BSPFace face;
01878         
01879         face.v1= v1;
01880         face.v2= v2;
01881         face.v3= v3;
01882         face.v4= v4;
01883         face.obi= obi;
01884         face.facenr= zvlnr & ~RE_QUAD_OFFS;
01885         face.type= R_STRAND;
01886         if(R.osa)
01887                 face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha/(float)R.osa);
01888         else
01889                 face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha);
01890         
01891         face.is_full= (zspan->shad_alpha==1.0f);
01892         
01893         /* setup boundbox */
01894         init_box(&face.box);
01895         bound_boxf(&face.box, v1);
01896         bound_boxf(&face.box, v2);
01897         bound_boxf(&face.box, v3);
01898         if(v4)
01899                 bound_boxf(&face.box, v4);
01900         
01901         /* optimize values */
01902         bspface_init_strand(&face);
01903         
01904         isb_bsp_face_inside((ISBBranch *)zspan->rectz, &face);
01905         
01906 }
01907 
01908 /* callback function for zbuf clip */
01909 static void isb_bsp_test_face(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4) 
01910 {
01911         BSPFace face;
01912         
01913         face.v1= v1;
01914         face.v2= v2;
01915         face.v3= v3;
01916         face.v4= v4;
01917         face.obi= obi;
01918         face.facenr= zvlnr & ~RE_QUAD_OFFS;
01919         face.type= 0;
01920         if(R.osa)
01921                 face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha/(float)R.osa);
01922         else
01923                 face.shad_alpha= (short)ceil(4096.0f*zspan->shad_alpha);
01924         
01925         face.is_full= (zspan->shad_alpha==1.0f);
01926         
01927         /* setup boundbox */
01928         init_box(&face.box);
01929         bound_boxf(&face.box, v1);
01930         bound_boxf(&face.box, v2);
01931         bound_boxf(&face.box, v3);
01932         if(v4)
01933                 bound_boxf(&face.box, v4);
01934 
01935         isb_bsp_face_inside((ISBBranch *)zspan->rectz, &face);
01936 }
01937 
01938 static int testclip_minmax(float *ho, float *minmax)
01939 {
01940         float wco= ho[3];
01941         int flag= 0;
01942         
01943         if( ho[0] > minmax[1]*wco) flag = 1;
01944         else if( ho[0]< minmax[0]*wco) flag = 2;
01945         
01946         if( ho[1] > minmax[3]*wco) flag |= 4;
01947         else if( ho[1]< minmax[2]*wco) flag |= 8;
01948         
01949         return flag;
01950 }
01951 
01952 /* main loop going over all faces and check in bsp overlaps, fill in shadfac values */
01953 static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
01954 {
01955         ObjectInstanceRen *obi;
01956         ObjectRen *obr;
01957         ShadBuf *shb= lar->shb;
01958         ZSpan zspan, zspanstrand;
01959         VlakRen *vlr= NULL;
01960         Material *ma= NULL;
01961         float minmaxf[4], winmat[4][4];
01962         int size= shb->size;
01963         int i, a, ok=1, lay= -1;
01964         
01965         /* further optimize, also sets minz maxz */
01966         isb_bsp_recalc_box(root);
01967         
01968         /* extra clipping for minmax */
01969         minmaxf[0]= (2.0f*root->box.xmin - size-2.0f)/size;
01970         minmaxf[1]= (2.0f*root->box.xmax - size+2.0f)/size;
01971         minmaxf[2]= (2.0f*root->box.ymin - size-2.0f)/size;
01972         minmaxf[3]= (2.0f*root->box.ymax - size+2.0f)/size;
01973         
01974         if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay;
01975         
01976         /* (ab)use zspan, since we use zbuffer clipping code */
01977         zbuf_alloc_span(&zspan, size, size, re->clipcrop);
01978         
01979         zspan.zmulx=  ((float)size)/2.0f;
01980         zspan.zmuly=  ((float)size)/2.0f;
01981         zspan.zofsx= -0.5f;
01982         zspan.zofsy= -0.5f;
01983         
01984         /* pass on bsp root to zspan */
01985         zspan.rectz= (int *)root;
01986         
01987         /* filling methods */
01988         zspanstrand= zspan;
01989         //      zspan.zbuflinefunc= zbufline_onlyZ;
01990         zspan.zbuffunc= isb_bsp_test_face;
01991         zspanstrand.zbuffunc= isb_bsp_test_strand;
01992         
01993         for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
01994                 obr= obi->obr;
01995 
01996                 if(obi->flag & R_TRANSFORMED)
01997                         mul_m4_m4m4(winmat, obi->mat, shb->persmat);
01998                 else
01999                         copy_m4_m4(winmat, shb->persmat);
02000 
02001                 for(a=0; a<obr->totvlak; a++) {
02002                         
02003                         if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
02004                         else vlr++;
02005                         
02006                         /* note, these conditions are copied in shadowbuf_autoclip() */
02007                         if(vlr->mat!= ma) {
02008                                 ma= vlr->mat;
02009                                 ok= 1;
02010                                 if((ma->mode & MA_SHADBUF)==0) ok= 0;
02011                                 if(ma->material_type == MA_TYPE_WIRE) ok= 0;
02012                                 zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
02013                         }
02014                         
02015                         if(ok && (obi->lay & lay)) {
02016                                 float hoco[4][4];
02017                                 int c1, c2, c3, c4=0;
02018                                 int d1, d2, d3, d4=0;
02019                                 int partclip;
02020                                 
02021                                 /* create hocos per face, it is while render */
02022                                 projectvert(vlr->v1->co, winmat, hoco[0]); d1= testclip_minmax(hoco[0], minmaxf);
02023                                 projectvert(vlr->v2->co, winmat, hoco[1]); d2= testclip_minmax(hoco[1], minmaxf);
02024                                 projectvert(vlr->v3->co, winmat, hoco[2]); d3= testclip_minmax(hoco[2], minmaxf);
02025                                 if(vlr->v4) {
02026                                         projectvert(vlr->v4->co, winmat, hoco[3]); d4= testclip_minmax(hoco[3], minmaxf);
02027                                 }
02028 
02029                                 /* minmax clipping */
02030                                 if(vlr->v4) partclip= d1 & d2 & d3 & d4;
02031                                 else partclip= d1 & d2 & d3;
02032                                 
02033                                 if(partclip==0) {
02034                                         
02035                                         /* window clipping */
02036                                         c1= testclip(hoco[0]); 
02037                                         c2= testclip(hoco[1]); 
02038                                         c3= testclip(hoco[2]); 
02039                                         if(vlr->v4)
02040                                                 c4= testclip(hoco[3]); 
02041                                         
02042                                         /* ***** NO WIRE YET */                 
02043                                         if(ma->material_type == MA_TYPE_WIRE) {
02044                                                 if(vlr->v4)
02045                                                         zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
02046                                                 else
02047                                                         zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], 0, c1, c2, c3, 0);
02048                                         }
02049                                         else if(vlr->v4) {
02050                                                 if(vlr->flag & R_STRAND)
02051                                                         zbufclip4(&zspanstrand, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
02052                                                 else
02053                                                         zbufclip4(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
02054                                         }
02055                                         else
02056                                                 zbufclip(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], c1, c2, c3);
02057                                         
02058                                 }
02059                         }
02060                 }
02061         }
02062         
02063         zbuf_free_span(&zspan);
02064 }
02065 
02066 /* returns 1 when the viewpixel is visible in lampbuffer */
02067 static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *vlr, float x, float y, float *co)
02068 {
02069         float hoco[4], v1[3], nor[3];
02070         float dface, fac, siz;
02071         
02072         RE_vlakren_get_normal(&R, obi, vlr, nor);
02073         VECCOPY(v1, vlr->v1->co);
02074         if(obi->flag & R_TRANSFORMED)
02075                 mul_m4_v3(obi->mat, v1);
02076 
02077         /* from shadepixel() */
02078         dface= v1[0]*nor[0] + v1[1]*nor[1] + v1[2]*nor[2];
02079         hoco[3]= 1.0f;
02080         
02081         /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */
02082         if(R.r.mode & R_ORTHO) {
02083                 /* x and y 3d coordinate can be derived from pixel coord and winmat */
02084                 float fx= 2.0/(R.winx*R.winmat[0][0]);
02085                 float fy= 2.0/(R.winy*R.winmat[1][1]);
02086                 
02087                 hoco[0]= (x - 0.5*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
02088                 hoco[1]= (y - 0.5*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
02089                 
02090                 /* using a*x + b*y + c*z = d equation, (a b c) is normal */
02091                 if(nor[2]!=0.0f)
02092                         hoco[2]= (dface - nor[0]*hoco[0] - nor[1]*hoco[1])/nor[2];
02093                 else
02094                         hoco[2]= 0.0f;
02095         }
02096         else {
02097                 float div, view[3];
02098                 
02099                 calc_view_vector(view, x, y);
02100                 
02101                 div= nor[0]*view[0] + nor[1]*view[1] + nor[2]*view[2];
02102                 if (div==0.0f) 
02103                         return 0;
02104                 
02105                 fac= dface/div;
02106                 
02107                 hoco[0]= fac*view[0];
02108                 hoco[1]= fac*view[1];
02109                 hoco[2]= fac*view[2];
02110         }
02111         
02112         /* move 3d vector to lampbuf */
02113         mul_m4_v4(shb->persmat, hoco);  /* rational hom co */
02114         
02115         /* clip We can test for -1.0/1.0 because of the properties of the
02116          * coordinate transformations. */
02117         fac= fabs(hoco[3]);
02118         if(hoco[0]<-fac || hoco[0]>fac)
02119                 return 0;
02120         if(hoco[1]<-fac || hoco[1]>fac)
02121                 return 0;
02122         if(hoco[2]<-fac || hoco[2]>fac)
02123                 return 0;
02124         
02125         siz= 0.5f*(float)shb->size;
02126         co[0]= siz*(1.0f+hoco[0]/hoco[3]) -0.5f;
02127         co[1]= siz*(1.0f+hoco[1]/hoco[3]) -0.5f;
02128         co[2]= ((float)0x7FFFFFFF)*(hoco[2]/hoco[3]);
02129         
02130         /* XXXX bias, much less than normal shadbuf, or do we need a constant? */
02131         co[2] -= 0.05f*shb->bias;
02132         
02133         return 1;
02134 }
02135 
02136 /* storage of shadow results, solid osa and transp case */
02137 static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int obi, int facenr, short shadfac, short samples)
02138 {
02139         ISBShadfacA *new;
02140         float shadfacf;
02141         
02142         /* in osa case, the samples were filled in with factor 1.0/R.osa. if fewer samples we have to correct */
02143         if(R.osa)
02144                 shadfacf= ((float)shadfac*R.osa)/(4096.0*samples);
02145         else
02146                 shadfacf= ((float)shadfac)/(4096.0);
02147         
02148         new= BLI_memarena_alloc(mem, sizeof(ISBShadfacA));
02149         new->obi= obi;
02150         new->facenr= facenr & ~RE_QUAD_OFFS;
02151         new->shadfac= shadfacf;
02152         if(*isbsapp)
02153                 new->next= (*isbsapp);
02154         else
02155                 new->next= NULL;
02156         
02157         *isbsapp= new;
02158 }
02159 
02160 /* adding samples, solid case */
02161 static int isb_add_samples(RenderPart *pa, ISBBranch *root, MemArena *memarena, ISBSample **samplebuf)
02162 {
02163         int xi, yi, *xcos, *ycos;
02164         int sample, bsp_err= 0;
02165         
02166         /* bsp split doesn't like to handle regular sequenes */
02167         xcos= MEM_mallocN( pa->rectx*sizeof(int), "xcos");
02168         ycos= MEM_mallocN( pa->recty*sizeof(int), "ycos");
02169         for(xi=0; xi<pa->rectx; xi++)
02170                 xcos[xi]= xi;
02171         for(yi=0; yi<pa->recty; yi++)
02172                 ycos[yi]= yi;
02173         BLI_array_randomize(xcos, sizeof(int), pa->rectx, 12345);
02174         BLI_array_randomize(ycos, sizeof(int), pa->recty, 54321);
02175         
02176         for(sample=0; sample<(R.osa?R.osa:1); sample++) {
02177                 ISBSample *samp= samplebuf[sample], *samp1;
02178                 
02179                 for(yi=0; yi<pa->recty; yi++) {
02180                         int y= ycos[yi];
02181                         for(xi=0; xi<pa->rectx; xi++) {
02182                                 int x= xcos[xi];
02183                                 samp1= samp + y*pa->rectx + x;
02184                                 if(samp1->facenr)
02185                                         bsp_err |= isb_bsp_insert(root, memarena, samp1);
02186                         }
02187                         if(bsp_err) break;
02188                 }
02189         }       
02190         
02191         MEM_freeN(xcos);
02192         MEM_freeN(ycos);
02193 
02194         return bsp_err;
02195 }
02196 
02197 /* solid version */
02198 /* lar->shb, pa->rectz and pa->rectp should exist */
02199 static void isb_make_buffer(RenderPart *pa, LampRen *lar)
02200 {
02201         ShadBuf *shb= lar->shb;
02202         ISBData *isbdata;
02203         ISBSample *samp, *samplebuf[16];        /* should be RE_MAX_OSA */
02204         ISBBranch root;
02205         MemArena *memarena;
02206         intptr_t *rd;
02207         int *recto, *rectp, x, y, sindex, sample, bsp_err=0;
02208         
02209         /* storage for shadow, per thread */
02210         isbdata= shb->isb_result[pa->thread];
02211         
02212         /* to map the shi->xs and ys coordinate */
02213         isbdata->minx= pa->disprect.xmin;
02214         isbdata->miny= pa->disprect.ymin;
02215         isbdata->rectx= pa->rectx;
02216         isbdata->recty= pa->recty;
02217         
02218         /* branches are added using memarena (32k branches) */
02219         memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena");
02220         BLI_memarena_use_calloc(memarena);
02221         
02222         /* samplebuf is in camera view space (pixels) */
02223         for(sample=0; sample<(R.osa?R.osa:1); sample++)
02224                 samplebuf[sample]= MEM_callocN(sizeof(ISBSample)*pa->rectx*pa->recty, "isb samplebuf");
02225         
02226         /* for end result, ISBSamples point to this in non OSA case, otherwise to pixstruct->shadfac */
02227         if(R.osa==0)
02228                 isbdata->shadfacs= MEM_callocN(pa->rectx*pa->recty*sizeof(short), "isb shadfacs");
02229         
02230         /* setup bsp root */
02231         memset(&root, 0, sizeof(ISBBranch));
02232         root.box.xmin= (float)shb->size;
02233         root.box.ymin= (float)shb->size;
02234         
02235         /* create the sample buffers */
02236         for(sindex=0, y=0; y<pa->recty; y++) {
02237                 for(x=0; x<pa->rectx; x++, sindex++) {
02238                         
02239                         /* this makes it a long function, but splitting it out would mean 10+ arguments */
02240                         /* first check OSA case */
02241                         if(R.osa) {
02242                                 rd= pa->rectdaps + sindex;
02243                                 if(*rd) {
02244                                         float xs= (float)(x + pa->disprect.xmin);
02245                                         float ys= (float)(y + pa->disprect.ymin);
02246                                         
02247                                         for(sample=0; sample<R.osa; sample++) {
02248                                                 PixStr *ps= (PixStr *)(*rd);
02249                                                 int mask= (1<<sample);
02250                                                 
02251                                                 while(ps) {
02252                                                         if(ps->mask & mask)
02253                                                                 break;
02254                                                         ps= ps->next;
02255                                                 }
02256                                                 if(ps && ps->facenr>0) {
02257                                                         ObjectInstanceRen *obi= &R.objectinstance[ps->obi];
02258                                                         ObjectRen *obr= obi->obr;
02259                                                         VlakRen *vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
02260                                                         
02261                                                         samp= samplebuf[sample] + sindex;
02262                                                         /* convert image plane pixel location to lamp buffer space */
02263                                                         if(viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], samp->zco)) {
02264                                                                 samp->obi= ps->obi;
02265                                                                 samp->facenr= ps->facenr & ~RE_QUAD_OFFS;
02266                                                                 ps->shadfac= 0;
02267                                                                 samp->shadfac= &ps->shadfac;
02268                                                                 bound_rectf((rctf *)&root.box, samp->zco);
02269                                                         }
02270                                                 }
02271                                         }
02272                                 }
02273                         }
02274                         else {
02275                                 rectp= pa->rectp + sindex;
02276                                 recto= pa->recto + sindex;
02277                                 if(*rectp>0) {
02278                                         ObjectInstanceRen *obi= &R.objectinstance[*recto];
02279                                         ObjectRen *obr= obi->obr;
02280                                         VlakRen *vlr= RE_findOrAddVlak(obr, (*rectp-1) & RE_QUAD_MASK);
02281                                         float xs= (float)(x + pa->disprect.xmin);
02282                                         float ys= (float)(y + pa->disprect.ymin);
02283                                         
02284                                         samp= samplebuf[0] + sindex;
02285                                         /* convert image plane pixel location to lamp buffer space */
02286                                         if(viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, samp->zco)) {
02287                                                 samp->obi= *recto;
02288                                                 samp->facenr= *rectp & ~RE_QUAD_OFFS;
02289                                                 samp->shadfac= isbdata->shadfacs + sindex;
02290                                                 bound_rectf((rctf *)&root.box, samp->zco);
02291                                         }
02292                                 }
02293                         }
02294                 }
02295         }
02296         
02297         /* simple method to see if we have samples */
02298         if(root.box.xmin != (float)shb->size) {
02299                 /* now create a regular split, root.box has the initial bounding box of all pixels */
02300                 /* split bsp 8 levels deep, in regular grid (16 x 16) */
02301                 isb_bsp_split_init(&root, memarena, 8);
02302                 
02303                 /* insert all samples in BSP now */
02304                 bsp_err= isb_add_samples(pa, &root, memarena, samplebuf);
02305                         
02306                 if(bsp_err==0) {
02307                         /* go over all faces and fill in shadow values */
02308                         
02309                         isb_bsp_fillfaces(&R, lar, &root);      /* shb->persmat should have been calculated */
02310                         
02311                         /* copy shadow samples to persistant buffer, reduce memory overhead */
02312                         if(R.osa) {
02313                                 ISBShadfacA **isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs");
02314                                 
02315                                 isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena");
02316                                 BLI_memarena_use_calloc(isbdata->memarena);
02317 
02318                                 for(rd= pa->rectdaps, x=pa->rectx*pa->recty; x>0; x--, rd++, isbsa++) {
02319                                         
02320                                         if(*rd) {
02321                                                 PixStr *ps= (PixStr *)(*rd);
02322                                                 while(ps) {
02323                                                         if(ps->shadfac)
02324                                                                 isb_add_shadfac(isbsa, isbdata->memarena, ps->obi, ps->facenr, ps->shadfac, count_mask(ps->mask));
02325                                                         ps= ps->next;
02326                                                 }
02327                                         }
02328                                 }
02329                         }
02330                 }
02331         }
02332         else {
02333                 if(isbdata->shadfacs) {
02334                         MEM_freeN(isbdata->shadfacs);
02335                         isbdata->shadfacs= NULL;
02336                 }
02337         }
02338 
02339         /* free BSP */
02340         BLI_memarena_free(memarena);
02341         
02342         /* free samples */
02343         for(x=0; x<(R.osa?R.osa:1); x++)
02344                 MEM_freeN(samplebuf[x]);
02345         
02346         if(bsp_err) printf("error in filling bsp\n");
02347 }
02348 
02349 /* add sample to buffer, isbsa is the root sample in a buffer */
02350 static ISBSampleA *isb_alloc_sample_transp(ISBSampleA **isbsa, MemArena *mem)
02351 {
02352         ISBSampleA *new;
02353         
02354         new= BLI_memarena_alloc(mem, sizeof(ISBSampleA));
02355         if(*isbsa)
02356                 new->next= (*isbsa);
02357         else
02358                 new->next= NULL;
02359         
02360         *isbsa= new;
02361         return new;
02362 }
02363 
02364 /* adding samples in BSP, transparent case */
02365 static int isb_add_samples_transp(RenderPart *pa, ISBBranch *root, MemArena *memarena, ISBSampleA ***samplebuf)
02366 {
02367         int xi, yi, *xcos, *ycos;
02368         int sample, bsp_err= 0;
02369         
02370         /* bsp split doesn't like to handle regular sequenes */
02371         xcos= MEM_mallocN( pa->rectx*sizeof(int), "xcos");
02372         ycos= MEM_mallocN( pa->recty*sizeof(int), "ycos");
02373         for(xi=0; xi<pa->rectx; xi++)
02374                 xcos[xi]= xi;
02375         for(yi=0; yi<pa->recty; yi++)
02376                 ycos[yi]= yi;
02377         BLI_array_randomize(xcos, sizeof(int), pa->rectx, 12345);
02378         BLI_array_randomize(ycos, sizeof(int), pa->recty, 54321);
02379         
02380         for(sample=0; sample<(R.osa?R.osa:1); sample++) {
02381                 ISBSampleA **samp= samplebuf[sample], *samp1;
02382                 
02383                 for(yi=0; yi<pa->recty; yi++) {
02384                         int y= ycos[yi];
02385                         for(xi=0; xi<pa->rectx; xi++) {
02386                                 int x= xcos[xi];
02387                                 
02388                                 samp1= *(samp + y*pa->rectx + x);
02389                                 while(samp1) {
02390                                         bsp_err |= isb_bsp_insert(root, memarena, (ISBSample *)samp1);
02391                                         samp1= samp1->next;
02392                                 }
02393                         }
02394                         if(bsp_err) break;
02395                 }
02396         }       
02397         
02398         MEM_freeN(xcos);
02399         MEM_freeN(ycos);
02400         
02401         return bsp_err;
02402 }
02403 
02404 
02405 /* Ztransp version */
02406 /* lar->shb, pa->rectz and pa->rectp should exist */
02407 static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *lar)
02408 {
02409         ShadBuf *shb= lar->shb;
02410         ISBData *isbdata;
02411         ISBSampleA *samp, **samplebuf[16];      /* MAX_OSA */
02412         ISBBranch root;
02413         MemArena *memarena;
02414         APixstr *ap;
02415         int x, y, sindex, sample, bsp_err=0;
02416         
02417         /* storage for shadow, per thread */
02418         isbdata= shb->isb_result[pa->thread];
02419         
02420         /* to map the shi->xs and ys coordinate */
02421         isbdata->minx= pa->disprect.xmin;
02422         isbdata->miny= pa->disprect.ymin;
02423         isbdata->rectx= pa->rectx;
02424         isbdata->recty= pa->recty;
02425         
02426         /* branches are added using memarena (32k branches) */
02427         memarena = BLI_memarena_new(0x8000 * sizeof(ISBBranch), "isb arena");
02428         BLI_memarena_use_calloc(memarena);
02429         
02430         /* samplebuf is in camera view space (pixels) */
02431         for(sample=0; sample<(R.osa?R.osa:1); sample++)
02432                 samplebuf[sample]= MEM_callocN(sizeof(void *)*pa->rectx*pa->recty, "isb alpha samplebuf");
02433         
02434         /* setup bsp root */
02435         memset(&root, 0, sizeof(ISBBranch));
02436         root.box.xmin= (float)shb->size;
02437         root.box.ymin= (float)shb->size;
02438 
02439         /* create the sample buffers */
02440         for(ap= apixbuf, sindex=0, y=0; y<pa->recty; y++) {
02441                 for(x=0; x<pa->rectx; x++, sindex++, ap++) {
02442                         
02443                         if(ap->p[0]) {
02444                                 APixstr *apn;
02445                                 float xs= (float)(x + pa->disprect.xmin);
02446                                 float ys= (float)(y + pa->disprect.ymin);
02447                                 
02448                                 for(apn=ap; apn; apn= apn->next) {
02449                                         int a;
02450                                         for(a=0; a<4; a++) {
02451                                                 if(apn->p[a]) {
02452                                                         ObjectInstanceRen *obi= &R.objectinstance[apn->obi[a]];
02453                                                         ObjectRen *obr= obi->obr;
02454                                                         VlakRen *vlr= RE_findOrAddVlak(obr, (apn->p[a]-1) & RE_QUAD_MASK);
02455                                                         float zco[3];
02456                                                         
02457                                                         /* here we store shadfac, easier to create the end storage buffer. needs zero'ed, multiple shadowbufs use it */
02458                                                         apn->shadfac[a]= 0;
02459                                                         
02460                                                         if(R.osa) {
02461                                                                 for(sample=0; sample<R.osa; sample++) {
02462                                                                         int mask= (1<<sample);
02463                                                                         
02464                                                                         if(apn->mask[a] & mask) {
02465                                                                                 
02466                                                                                 /* convert image plane pixel location to lamp buffer space */
02467                                                                                 if(viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], zco)) {
02468                                                                                         samp= isb_alloc_sample_transp(samplebuf[sample] + sindex, memarena);
02469                                                                                         samp->obi= apn->obi[a];
02470                                                                                         samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
02471                                                                                         samp->shadfac= &apn->shadfac[a];
02472                                                                                         
02473                                                                                         VECCOPY(samp->zco, zco);
02474                                                                                         bound_rectf((rctf *)&root.box, samp->zco);
02475                                                                                 }
02476                                                                         }
02477                                                                 }
02478                                                         }
02479                                                         else {
02480                                                                 
02481                                                                 /* convert image plane pixel location to lamp buffer space */
02482                                                                 if(viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, zco)) {
02483                                                                         
02484                                                                         samp= isb_alloc_sample_transp(samplebuf[0] + sindex, memarena);
02485                                                                         samp->obi= apn->obi[a];
02486                                                                         samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
02487                                                                         samp->shadfac= &apn->shadfac[a];
02488                                                                         
02489                                                                         VECCOPY(samp->zco, zco);
02490                                                                         bound_rectf((rctf *)&root.box, samp->zco);
02491                                                                 }
02492                                                         }
02493                                                 }
02494                                         }
02495                                 }
02496                         }
02497                 }
02498         }
02499         
02500         /* simple method to see if we have samples */
02501         if(root.box.xmin != (float)shb->size) {
02502                 /* now create a regular split, root.box has the initial bounding box of all pixels */
02503                 /* split bsp 8 levels deep, in regular grid (16 x 16) */
02504                 isb_bsp_split_init(&root, memarena, 8);
02505                 
02506                 /* insert all samples in BSP now */
02507                 bsp_err= isb_add_samples_transp(pa, &root, memarena, samplebuf);
02508                 
02509                 if(bsp_err==0) {
02510                         ISBShadfacA **isbsa;
02511                         
02512                         /* go over all faces and fill in shadow values */
02513                         isb_bsp_fillfaces(&R, lar, &root);      /* shb->persmat should have been calculated */
02514                         
02515                         /* copy shadow samples to persistant buffer, reduce memory overhead */
02516                         isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs");
02517                         
02518                         isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena");
02519                         
02520                         for(ap= apixbuf, x=pa->rectx*pa->recty; x>0; x--, ap++, isbsa++) {
02521                                         
02522                                 if(ap->p[0]) {
02523                                         APixstr *apn;
02524                                         for(apn=ap; apn; apn= apn->next) {
02525                                                 int a;
02526                                                 for(a=0; a<4; a++) {
02527                                                         if(apn->p[a] && apn->shadfac[a]) {
02528                                                                 if(R.osa)
02529                                                                         isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], count_mask(apn->mask[a]));
02530                                                                 else
02531                                                                         isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], 0);
02532                                                         }
02533                                                 }
02534                                         }
02535                                 }
02536                         }
02537                 }
02538         }
02539 
02540         /* free BSP */
02541         BLI_memarena_free(memarena);
02542 
02543         /* free samples */
02544         for(x=0; x<(R.osa?R.osa:1); x++)
02545                 MEM_freeN(samplebuf[x]);
02546 
02547         if(bsp_err) printf("error in filling bsp\n");
02548 }
02549 
02550 
02551 
02552 /* exported */
02553 
02554 /* returns amount of light (1.0 = no shadow) */
02555 /* note, shadepixel() rounds the coordinate, not the real sample info */
02556 float ISB_getshadow(ShadeInput *shi, ShadBuf *shb)
02557 {
02558         /* if raytracing, we can't accept irregular shadow */
02559         if(shi->depth==0) {
02560                 ISBData *isbdata= shb->isb_result[shi->thread];
02561                 
02562                 if(isbdata) {
02563                         if(isbdata->shadfacs || isbdata->shadfaca) {
02564                                 int x= shi->xs - isbdata->minx;
02565                                 
02566                                 if(x >= 0 && x < isbdata->rectx) {
02567                                         int y= shi->ys - isbdata->miny;
02568                         
02569                                         if(y >= 0 && y < isbdata->recty) {
02570                                                 if(isbdata->shadfacs) {
02571                                                         short *sp= isbdata->shadfacs + y*isbdata->rectx + x;
02572                                                         return *sp>=4096?0.0f:1.0f - ((float)*sp)/4096.0f;
02573                                                 }
02574                                                 else {
02575                                                         int sindex= y*isbdata->rectx + x;
02576                                                         int obi= shi->obi - R.objectinstance;
02577                                                         ISBShadfacA *isbsa= *(isbdata->shadfaca + sindex);
02578                                                         
02579                                                         while(isbsa) {
02580                                                                 if(isbsa->facenr==shi->facenr+1 && isbsa->obi==obi)
02581                                                                         return isbsa->shadfac>=1.0f?0.0f:1.0f - isbsa->shadfac;
02582                                                                 isbsa= isbsa->next;
02583                                                         }
02584                                                 }
02585                                         }
02586                                 }
02587                         }
02588                 }
02589         }
02590         return 1.0f;
02591 }
02592 
02593 /* part is supposed to be solid zbuffered (apixbuf==NULL) or transparent zbuffered */
02594 void ISB_create(RenderPart *pa, APixstr *apixbuf)
02595 {
02596         GroupObject *go;
02597         
02598         /* go over all lamps, and make the irregular buffers */
02599         for(go=R.lights.first; go; go= go->next) {
02600                 LampRen *lar= go->lampren;
02601                 
02602                 if(lar->type==LA_SPOT && lar->shb && lar->buftype==LA_SHADBUF_IRREGULAR) {
02603                         
02604                         /* create storage for shadow, per thread */
02605                         lar->shb->isb_result[pa->thread]= MEM_callocN(sizeof(ISBData), "isb data");
02606                         
02607                         if(apixbuf)
02608                                 isb_make_buffer_transp(pa, apixbuf, lar);
02609                         else
02610                                 isb_make_buffer(pa, lar);
02611                 }
02612         }
02613 }
02614 
02615 
02616 /* end of part rendering, free stored shadow data for this thread from all lamps */
02617 void ISB_free(RenderPart *pa)
02618 {
02619         GroupObject *go;
02620         
02621         /* go over all lamps, and free the irregular buffers */
02622         for(go=R.lights.first; go; go= go->next) {
02623                 LampRen *lar= go->lampren;
02624                 
02625                 if(lar->type==LA_SPOT && lar->shb && lar->buftype==LA_SHADBUF_IRREGULAR) {
02626                         ISBData *isbdata= lar->shb->isb_result[pa->thread];
02627 
02628                         if(isbdata) {
02629                                 if(isbdata->shadfacs)
02630                                         MEM_freeN(isbdata->shadfacs);
02631                                 if(isbdata->shadfaca)
02632                                         MEM_freeN(isbdata->shadfaca);
02633                                 
02634                                 if(isbdata->memarena)
02635                                         BLI_memarena_free(isbdata->memarena);
02636                                 
02637                                 MEM_freeN(isbdata);
02638                                 lar->shb->isb_result[pa->thread]= NULL;
02639                         }
02640                 }
02641         }
02642 }
02643