|
Blender
V2.59
|
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