e2f331afafdb8589fff6822afc1b4383745f0be2
[blender.git] / source / blender / render / intern / source / rendercore.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributors: Hos, Robert Wenzlaff.
24  * Contributors: 2004/2005/2006 Blender Foundation, full recode
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /* system includes */
30 #include <stdio.h>
31 #include <math.h>
32 #include <string.h>
33
34 /* External modules: */
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_arithb.h"
38 #include "BLI_blenlib.h"
39 #include "BLI_jitter.h"
40 #include "BLI_rand.h"
41 #include "BLI_threads.h"
42
43 #include "BKE_utildefines.h"
44
45 #include "DNA_image_types.h"
46 #include "DNA_lamp_types.h"
47 #include "DNA_material_types.h"
48 #include "DNA_meshdata_types.h"
49
50 #include "BKE_global.h"
51 #include "BKE_image.h"
52 #include "BKE_main.h"
53 #include "BKE_node.h"
54 #include "BKE_texture.h"
55
56 #include "IMB_imbuf_types.h"
57 #include "IMB_imbuf.h"
58
59 /* local include */
60 #include "renderpipeline.h"
61 #include "render_types.h"
62 #include "renderdatabase.h"
63 #include "pixelblending.h"
64 #include "pixelshading.h"
65 #include "shadbuf.h"
66 #include "shading.h"
67 #include "sss.h"
68 #include "zbuf.h"
69 #include "RE_raytrace.h"
70
71 #include "PIL_time.h"
72
73 /* own include */
74 #include "rendercore.h"
75
76
77 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
78 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
79 /* only to be used here in this file, it's for speed */
80 extern struct Render R;
81 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
82
83 /* x and y are current pixels in rect to be rendered */
84 /* do not normalize! */
85 void calc_view_vector(float *view, float x, float y)
86 {
87
88         view[2]= -ABS(R.clipsta);
89         
90         if(R.r.mode & R_ORTHO) {
91                 view[0]= view[1]= 0.0f;
92         }
93         else {
94                 
95                 if(R.r.mode & R_PANORAMA)
96                         x-= R.panodxp;
97                 
98                 /* move x and y to real viewplane coords */
99                 x= (x/(float)R.winx);
100                 view[0]= R.viewplane.xmin + x*(R.viewplane.xmax - R.viewplane.xmin);
101                 
102                 y= (y/(float)R.winy);
103                 view[1]= R.viewplane.ymin + y*(R.viewplane.ymax - R.viewplane.ymin);
104                 
105 //              if(R.flag & R_SEC_FIELD) {
106 //                      if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
107 //                      else view[1]= (y+R.ystart+1.0)*R.ycor;
108 //              }
109 //              else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
110         
111                 if(R.r.mode & R_PANORAMA) {
112                         float u= view[0] + R.panodxv; float v= view[2];
113                         view[0]= R.panoco*u + R.panosi*v;
114                         view[2]= -R.panosi*u + R.panoco*v;
115                 }
116         }
117 }
118
119 void calc_renderco_ortho(float *co, float x, float y, int z)
120 {
121         /* x and y 3d coordinate can be derived from pixel coord and winmat */
122         float fx= 2.0f/(R.winx*R.winmat[0][0]);
123         float fy= 2.0f/(R.winy*R.winmat[1][1]);
124         float zco;
125         
126         co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
127         co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
128         
129         zco= ((float)z)/2147483647.0f;
130         co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
131 }
132
133 void calc_renderco_zbuf(float *co, float *view, int z)
134 {
135         float fac, zco;
136         
137         /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
138         zco= ((float)z)/2147483647.0f;
139         co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
140
141         fac= co[2]/view[2];
142         co[0]= fac*view[0];
143         co[1]= fac*view[1];
144 }
145
146 /* also used in zbuf.c and shadbuf.c */
147 int count_mask(unsigned short mask)
148 {
149         if(R.samples)
150                 return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]);
151         return 0;
152 }
153
154 static int calchalo_z(HaloRen *har, int zz)
155 {
156         
157         if(har->type & HA_ONLYSKY) {
158                 if(zz!=0x7FFFFFFF) zz= - 0x7FFFFF;
159         }
160         else {
161                 zz= (zz>>8);
162         }
163         return zz;
164 }
165
166 static void halo_pixelstruct(HaloRen *har, float *rb, float dist, float xn, float yn, PixStr *ps)
167 {
168         float col[4], accol[4];
169         int amount, amountm, zz, flarec;
170         
171         amount= 0;
172         accol[0]=accol[1]=accol[2]=accol[3]= 0.0f;
173         flarec= har->flarec;
174         
175         while(ps) {
176                 amountm= count_mask(ps->mask);
177                 amount+= amountm;
178                 
179                 zz= calchalo_z(har, ps->z);
180                 if(zz> har->zs) {
181                         float fac;
182                         
183                         shadeHaloFloat(har, col, zz, dist, xn, yn, flarec);
184                         fac= ((float)amountm)/(float)R.osa;
185                         accol[0]+= fac*col[0];
186                         accol[1]+= fac*col[1];
187                         accol[2]+= fac*col[2];
188                         accol[3]+= fac*col[3];
189                         flarec= 0;
190                 }
191                 
192                 ps= ps->next;
193         }
194         /* now do the sky sub-pixels */
195         amount= R.osa-amount;
196         if(amount) {
197                 float fac;
198
199                 shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec);
200                 fac= ((float)amount)/(float)R.osa;
201                 accol[0]+= fac*col[0];
202                 accol[1]+= fac*col[1];
203                 accol[2]+= fac*col[2];
204                 accol[3]+= fac*col[3];
205         }
206         col[0]= accol[0];
207         col[1]= accol[1];
208         col[2]= accol[2];
209         col[3]= accol[3];
210         
211         addalphaAddfacFloat(rb, col, har->add);
212         
213 }
214
215 static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
216 {
217         HaloRen *har;
218         rcti disprect= pa->disprect, testrect= pa->disprect;
219         float dist, xsq, ysq, xn, yn, *rb;
220         float col[4];
221         long *rd= NULL;
222         int a, *rz, zz, y;
223         short minx, maxx, miny, maxy, x;
224
225         /* we don't render halos in the cropped area, gives errors in flare counter */
226         if(pa->crop) {
227                 testrect.xmin+= pa->crop;
228                 testrect.xmax-= pa->crop;
229                 testrect.ymin+= pa->crop;
230                 testrect.ymax-= pa->crop;
231         }
232         
233         for(a=0; a<R.tothalo; a++) {
234                 har= R.sortedhalos[a];
235
236                 /* layer test, clip halo with y */
237                 if((har->lay & lay)==0);
238                 else if(testrect.ymin > har->maxy);
239                 else if(testrect.ymax < har->miny);
240                 else {
241                         
242                         minx= floor(har->xs-har->rad);
243                         maxx= ceil(har->xs+har->rad);
244                         
245                         if(testrect.xmin > maxx);
246                         else if(testrect.xmax < minx);
247                         else {
248                                 
249                                 minx= MAX2(minx, testrect.xmin);
250                                 maxx= MIN2(maxx, testrect.xmax);
251                         
252                                 miny= MAX2(har->miny, testrect.ymin);
253                                 maxy= MIN2(har->maxy, testrect.ymax);
254                         
255                                 for(y=miny; y<maxy; y++) {
256                                         int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
257                                         rb= pass + 4*rectofs;
258                                         rz= pa->rectz + rectofs;
259                                         
260                                         if(pa->rectdaps)
261                                                 rd= pa->rectdaps + rectofs;
262                                         
263                                         yn= (y-har->ys)*R.ycor;
264                                         ysq= yn*yn;
265                                         
266                                         for(x=minx; x<maxx; x++, rb+=4, rz++) {
267                                                 xn= x- har->xs;
268                                                 xsq= xn*xn;
269                                                 dist= xsq+ysq;
270                                                 if(dist<har->radsq) {
271                                                         if(rd && *rd) {
272                                                                 halo_pixelstruct(har, rb, dist, xn, yn, (PixStr *)*rd);
273                                                         }
274                                                         else {
275                                                                 zz= calchalo_z(har, *rz);
276                                                                 if(zz> har->zs) {
277                                                                         shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec);
278                                                                         addalphaAddfacFloat(rb, col, har->add);
279                                                                 }
280                                                         }
281                                                 }
282                                                 if(rd) rd++;
283                                         }
284                                 }
285                         }
286                 }
287                 if(R.test_break() ) break; 
288         }
289 }
290
291 static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
292 {
293         ShadeInput shi;
294         float *pass= rl->rectf;
295         float fac;
296         long *rd= pa->rectdaps;
297         int x, y, *rz= pa->rectz;
298         
299         shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */
300         
301         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
302                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, pass+=4) {
303                         
304                         calc_view_vector(shi.view, x, y);
305                         
306                         if(rd && *rd) {
307                                 PixStr *ps= (PixStr *)*rd;
308                                 int samp, totsamp= 0;
309                                 
310                                 while(ps) {
311                                         if(R.r.mode & R_ORTHO)
312                                                 calc_renderco_ortho(shi.co, (float)x, (float)y, ps->z);
313                                         else
314                                                 calc_renderco_zbuf(shi.co, shi.view, ps->z);
315                                         
316                                         totsamp+= samp= count_mask(ps->mask);
317                                         fac= ((float)samp)/(float)R.osa;
318                                         renderspothalo(&shi, pass, fac);
319                                         ps= ps->next;
320                                 }
321                                 if(totsamp<R.osa) {
322                                         fac= ((float)R.osa-totsamp)/(float)R.osa;
323                                         shi.co[2]= 0.0f;
324                                         renderspothalo(&shi, pass, fac);
325                                 }
326                         }
327                         else {
328                                 if(R.r.mode & R_ORTHO)
329                                         calc_renderco_ortho(shi.co, (float)x, (float)y, *rz);
330                                 else
331                                         calc_renderco_zbuf(shi.co, shi.view, *rz);
332                                 
333                                 renderspothalo(&shi, pass, 1.0f);
334                         }
335                         
336                         if(rd) rd++;
337                 }
338                 if(y&1)
339                         if(R.test_break()) break; 
340         }
341 }                               
342
343
344 /* ********************* MAINLOOPS ******************** */
345
346 /* osa version */
347 static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr)
348 {
349         RenderPass *rpass;
350         
351         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
352                 float *fp, *col= NULL;
353                 int pixsize= 3;
354                 
355                 switch(rpass->passtype) {
356                         case SCE_PASS_RGBA:
357                                 col= shr->col;
358                                 pixsize= 4;
359                                 break;
360                         case SCE_PASS_DIFFUSE:
361                                 col= shr->diff;
362                                 break;
363                         case SCE_PASS_SPEC:
364                                 col= shr->spec;
365                                 break;
366                         case SCE_PASS_SHADOW:
367                                 col= shr->shad;
368                                 break;
369                         case SCE_PASS_AO:
370                                 col= shr->ao;
371                                 break;
372                         case SCE_PASS_REFLECT:
373                                 col= shr->refl;
374                                 break;
375                         case SCE_PASS_REFRACT:
376                                 col= shr->refr;
377                                 break;
378                         case SCE_PASS_RADIO:
379                                 col= shr->rad;
380                                 break;
381                         case SCE_PASS_NORMAL:
382                                 col= shr->nor;
383                                 break;
384                         case SCE_PASS_UV:
385                                 /* box filter only, gauss will screwup UV too much */
386                                 if(shi->totuv) {
387                                         float mult= (float)count_mask(curmask)/(float)R.osa;
388                                         fp= rpass->rect + 3*offset;
389                                         fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
390                                         fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
391                                         fp[2]+= mult;
392                                 }
393                                 break;
394                         case SCE_PASS_INDEXOB:
395                                 /* no filter */
396                                 if(shi->vlr) {
397                                         fp= rpass->rect + offset;
398                                         if(*fp==0.0f)
399                                                 *fp= (float)shi->obr->ob->index;
400                                 }
401                                 break;
402                         case SCE_PASS_VECTOR:
403                         {
404                                 /* add minimum speed in pixel, no filter */
405                                 fp= rpass->rect + 4*offset;
406                                 if( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
407                                         fp[0]= shr->winspeed[0];
408                                         fp[1]= shr->winspeed[1];
409                                 }
410                                 if( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
411                                         fp[2]= shr->winspeed[2];
412                                         fp[3]= shr->winspeed[3];
413                                 }
414                         }
415                                 break;
416                 }
417                 if(col) {
418                         fp= rpass->rect + pixsize*offset;
419                         add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
420                 }
421         }
422 }
423
424 /* non-osa version */
425 static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr)
426 {
427         RenderPass *rpass;
428         
429         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
430                 float *fp, *col= NULL, uvcol[3];
431                 int a, pixsize= 3;
432                 
433                 switch(rpass->passtype) {
434                         case SCE_PASS_RGBA:
435                                 col= shr->col;
436                                 pixsize= 4;
437                                 break;
438                         case SCE_PASS_DIFFUSE:
439                                 col= shr->diff;
440                                 break;
441                         case SCE_PASS_SPEC:
442                                 col= shr->spec;
443                                 break;
444                         case SCE_PASS_SHADOW:
445                                 col= shr->shad;
446                                 break;
447                         case SCE_PASS_AO:
448                                 col= shr->ao;
449                                 break;
450                         case SCE_PASS_REFLECT:
451                                 col= shr->refl;
452                                 break;
453                         case SCE_PASS_REFRACT:
454                                 col= shr->refr;
455                                 break;
456                         case SCE_PASS_RADIO:
457                                 col= shr->rad;
458                                 break;
459                         case SCE_PASS_NORMAL:
460                                 col= shr->nor;
461                                 break;
462                         case SCE_PASS_UV:
463                                 if(shi->totuv) {
464                                         uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
465                                         uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
466                                         uvcol[2]= 1.0f;
467                                         col= uvcol;
468                                 }
469                                 break;
470                         case SCE_PASS_VECTOR:
471                                 col= shr->winspeed;
472                                 pixsize= 4;
473                                 break;
474                         case SCE_PASS_INDEXOB:
475                                 if(shi->vlr) {
476                                         fp= rpass->rect + offset;
477                                         *fp= (float)shi->obr->ob->index;
478                                 }
479                                 break;
480                 }
481                 if(col) {
482                         fp= rpass->rect + pixsize*offset;
483                         for(a=0; a<pixsize; a++)
484                                 fp[a]= col[a];
485                 }
486         }
487 }
488
489 /* only do sky, is default in the solid layer (shade_tile) btw */
490 static void sky_tile(RenderPart *pa, float *pass)
491 {
492         float col[4];
493         int x, y;
494         
495         if(R.r.alphamode!=R_ADDSKY)
496                 return;
497         
498         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
499                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, pass+=4) {
500                         if(pass[3]<1.0f) {
501                                 if(pass[3]==0.0f)
502                                         shadeSkyPixel(pass, x, y);
503                                 else {
504                                         shadeSkyPixel(col, x, y);
505                                         addAlphaOverFloat(col, pass);
506                                         QUATCOPY(pass, col);
507                                 }
508                         }
509                 }
510                 
511                 if(y&1)
512                         if(R.test_break()) break; 
513         }
514 }
515
516 static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
517 {
518         RenderResult *rr= pa->result;
519         ShadeSample ssamp;
520         float *fcol, *rf, *rectf= rl->rectf;
521         long *rd, *rectdaps= pa->rectdaps;
522         int samp;
523         int x, y, seed, crop=0, offs=0, od, addpassflag;
524         
525         if(R.test_break()) return; 
526         
527         /* irregular shadowb buffer creation */
528         if(R.r.mode & R_SHADOW)
529                 ISB_create(pa, NULL);
530         
531         /* we set per pixel a fixed seed, for random AO and shadow samples */
532         seed= pa->rectx*pa->disprect.ymin;
533         
534         /* general shader info, passes */
535         shade_sample_initialize(&ssamp, pa, rl);
536         addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
537                                 
538         /* filtered render, for now we assume only 1 filter size */
539         if(pa->crop) {
540                 crop= 1;
541                 rectf+= 4*(pa->rectx + 1);
542                 rectdaps+= pa->rectx + 1;
543                 offs= pa->rectx + 1;
544         }
545         
546         /* scanline updates have to be 2 lines behind */
547         rr->renrect.ymin= 0;
548         rr->renrect.ymax= -2*crop;
549         rr->renlay= rl;
550                                 
551         for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
552                 rf= rectf;
553                 rd= rectdaps;
554                 od= offs;
555                 
556                 for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, rf+=4, od++) {
557                         BLI_thread_srandom(pa->thread, seed++);
558                         
559                         if(*rd) {
560                                 if(shade_samples(&ssamp, (PixStr *)(*rd), x, y)) {
561                                         for(samp=0; samp<ssamp.tot; samp++) {
562                                                 
563                                                 fcol= ssamp.shr[samp].combined;
564                                                 add_filt_fmask(ssamp.shi[samp].mask, fcol, rf, pa->rectx);
565                                                 
566                                                 if(addpassflag)
567                                                         add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]);
568                                         }
569                                 }
570                         }
571                 }
572                 
573                 rectf+= 4*pa->rectx;
574                 rectdaps+= pa->rectx;
575                 offs+= pa->rectx;
576                 
577                 if(y&1) if(R.test_break()) break; 
578         }
579         
580         /* disable scanline updating */
581         rr->renlay= NULL;
582         
583         if(R.r.mode & R_SHADOW)
584                 ISB_free(pa);
585 }
586
587 /* ************* pixel struct ******** */
588
589
590 static PixStrMain *addpsmain(ListBase *lb)
591 {
592         PixStrMain *psm;
593         
594         psm= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain),"pixstrMain");
595         BLI_addtail(lb, psm);
596         
597         psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr),"pixstr");
598         psm->counter= 0;
599         
600         return psm;
601 }
602
603 static void freeps(ListBase *lb)
604 {
605         PixStrMain *psm, *psmnext;
606         
607         for(psm= lb->first; psm; psm= psmnext) {
608                 psmnext= psm->next;
609                 if(psm->ps)
610                         MEM_freeN(psm->ps);
611                 MEM_freeN(psm);
612         }
613         lb->first= lb->last= NULL;
614 }
615
616 static void addps(ListBase *lb, long *rd, int obi, int facenr, int z, unsigned short mask)
617 {
618         PixStrMain *psm;
619         PixStr *ps, *last= NULL;
620         
621         if(*rd) {       
622                 ps= (PixStr *)(*rd);
623                 
624                 while(ps) {
625                         if( ps->obi == obi && ps->facenr == facenr ) {
626                                 ps->mask |= mask;
627                                 return;
628                         }
629                         last= ps;
630                         ps= ps->next;
631                 }
632         }
633         
634         /* make new PS (pixel struct) */
635         psm= lb->last;
636         
637         if(psm->counter==4095)
638                 psm= addpsmain(lb);
639         
640         ps= psm->ps + psm->counter++;
641         
642         if(last) last->next= ps;
643         else *rd= (long)ps;
644         
645         ps->next= NULL;
646         ps->obi= obi;
647         ps->facenr= facenr;
648         ps->z= z;
649         ps->mask = mask;
650         ps->shadfac= 0;
651 }
652
653 static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
654 {
655         float addcol[4];
656         int pix;
657         
658         if(arect==NULL)
659                 return;
660         
661         for(pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
662                 if(*arect != 0.0f) {
663                         addcol[0]= *arect * R.r.edgeR;
664                         addcol[1]= *arect * R.r.edgeG;
665                         addcol[2]= *arect * R.r.edgeB;
666                         addcol[3]= *arect;
667                         addAlphaOverFloat(rectf, addcol);
668                 }
669         }
670 }
671
672
673 static void convert_to_key_alpha(RenderPart *pa, float *rectf)
674 {
675         int y;
676         
677         for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
678                 if(rectf[3] >= 1.0f);
679                 else if(rectf[3] > 0.0f) {
680                         rectf[0] /= rectf[3];
681                         rectf[1] /= rectf[3];
682                         rectf[2] /= rectf[3];
683                 }
684         }
685 }
686
687 /* adds only alpha values */
688 void edge_enhance_tile(RenderPart *pa, float *rectf)    
689 {
690         /* use zbuffer to define edges, add it to the image */
691         int y, x, col, *rz, *rz1, *rz2, *rz3;
692         int zval1, zval2, zval3;
693         float *rf;
694         
695         /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */
696         rz= pa->rectz;
697         if(rz==NULL) return;
698         
699         for(y=0; y<pa->recty; y++)
700                 for(x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
701         
702         rz1= pa->rectz;
703         rz2= rz1+pa->rectx;
704         rz3= rz2+pa->rectx;
705         
706         rf= rectf+pa->rectx+1;
707         
708         for(y=0; y<pa->recty-2; y++) {
709                 for(x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
710                         
711                         /* prevent overflow with sky z values */
712                         zval1=   rz1[0] + 2*rz1[1] +   rz1[2];
713                         zval2=  2*rz2[0]           + 2*rz2[2];
714                         zval3=   rz3[0] + 2*rz3[1] +   rz3[2];
715                         
716                         col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 );
717                         if(col<0) col= -col;
718                         
719                         col >>= 5;
720                         if(col > (1<<16)) col= (1<<16);
721                         else col= (R.r.edgeint*col)>>8;
722                         
723                         if(col>0) {
724                                 float fcol;
725                                 
726                                 if(col>255) fcol= 1.0f;
727                                 else fcol= (float)col/255.0f;
728                                 
729                                 if(R.osa)
730                                         *rf+= fcol/(float)R.osa;
731                                 else
732                                         *rf= fcol;
733                         }
734                 }
735                 rz1+= 2;
736                 rz2+= 2;
737                 rz3+= 2;
738                 rf+= 2;
739         }
740         
741         /* shift back zbuf values, we might need it still */
742         rz= pa->rectz;
743         for(y=0; y<pa->recty; y++)
744                 for(x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4;
745         
746 }
747
748 static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
749 {
750         /* for all pixels with max speed, set to zero */
751         float *fp;
752         int a;
753         
754         fp= RE_RenderLayerGetPass(rl, SCE_PASS_VECTOR);
755         if(fp==NULL) return;
756         
757         for(a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
758                 if(fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f;
759 }
760
761
762 static unsigned short *make_solid_mask(RenderPart *pa)
763
764         long *rd= pa->rectdaps;
765         unsigned short *solidmask, *sp;
766         int x;
767         
768         if(rd==NULL) return NULL;
769         
770         sp=solidmask= MEM_mallocN(sizeof(short)*pa->rectx*pa->recty, "solidmask");
771         
772         for(x=pa->rectx*pa->recty; x>0; x--, rd++, sp++) {
773                 if(*rd) {
774                         PixStr *ps= (PixStr *)*rd;
775                         
776                         *sp= ps->mask;
777                         for(ps= ps->next; ps; ps= ps->next)
778                                 *sp |= ps->mask;
779                 }
780                 else
781                         *sp= 0;
782         }
783                         
784         return solidmask;
785 }
786
787 static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask)
788 {
789         unsigned short shared= dmask & smask;
790         float mul= 1.0 - source[3];
791         
792         if(shared) {    /* overlapping masks */
793                 
794                 /* masks differ, we make a mixture of 'add' and 'over' */
795                 if(shared!=dmask) {
796                         float shared_bits= (float)count_mask(shared);           /* alpha over */
797                         float tot_bits= (float)count_mask(smask|dmask);         /* alpha add */
798                         
799                         float add= (tot_bits - shared_bits)/tot_bits;           /* add level */
800                         mul= add + (1.0f-add)*mul;
801                 }
802         }
803         else if(dmask && smask) {
804                 /* works for premul only, of course */
805                 dest[0]+= source[0];
806                 dest[1]+= source[1];
807                 dest[2]+= source[2];
808                 dest[3]+= source[3];
809                 
810                 return;
811         }
812
813         dest[0]= (mul*dest[0]) + source[0];
814         dest[1]= (mul*dest[1]) + source[1];
815         dest[2]= (mul*dest[2]) + source[2];
816         dest[3]= (mul*dest[3]) + source[3];
817 }
818
819 typedef struct ZbufSolidData {
820         RenderLayer *rl;
821         ListBase *psmlist;
822         float *edgerect;
823 } ZbufSolidData;
824
825 void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
826 {
827         ZbufSolidData *sdata= (ZbufSolidData*)data;
828         ListBase *lb= sdata->psmlist;
829         long *rd= pa->rectdaps;
830         int *ro= zspan->recto;
831         int *rp= zspan->rectp;
832         int *rz= zspan->rectz;
833         int x, y;
834         int mask= 1<<sample;
835
836         for(y=0; y<pa->recty; y++) {
837                 for(x=0; x<pa->rectx; x++, rd++, rp++, ro++) {
838                         if(*rp) {
839                                 addps(lb, rd, *ro, *rp, *(rz+x), mask);
840                         }
841                 }
842                 rz+= pa->rectx;
843         }
844
845         if(sdata->rl->layflag & SCE_LAY_EDGE) 
846                 if(R.r.mode & R_EDGE) 
847                         edge_enhance_tile(pa, sdata->edgerect);
848 }
849
850 /* main call for shading Delta Accum, for OSA */
851 /* supposed to be fully threadable! */
852 void zbufshadeDA_tile(RenderPart *pa)
853 {
854         RenderResult *rr= pa->result;
855         RenderLayer *rl;
856         ListBase psmlist= {NULL, NULL};
857         float *edgerect= NULL;
858         
859         /* allocate the necessary buffers */
860                                 /* zbuffer inits these rects */
861         pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
862         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
863         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
864         
865         for(rl= rr->layers.first; rl; rl= rl->next) {
866
867                 /* initialize pixelstructs and edge buffer */
868                 addpsmain(&psmlist);
869                 pa->rectdaps= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd");
870                 
871                 if(rl->layflag & SCE_LAY_EDGE) 
872                         if(R.r.mode & R_EDGE) 
873                                 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
874                 
875                 /* always fill visibility */
876                 for(pa->sample=0; pa->sample<R.osa; pa->sample+=4) {
877                         ZbufSolidData sdata;
878
879                         sdata.rl= rl;
880                         sdata.psmlist= &psmlist;
881                         sdata.edgerect= edgerect;
882                         zbuffer_solid(pa, rl->lay, rl->layflag, make_pixelstructs, &sdata);
883                         if(R.test_break()) break; 
884                 }
885                 
886                 /* shades solid */
887                 if(rl->layflag & SCE_LAY_SOLID) 
888                         shadeDA_tile(pa, rl);
889                 
890                 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
891                 if(R.flag & R_LAMPHALO)
892                         if(rl->layflag & SCE_LAY_HALO)
893                                 lamphalo_tile(pa, rl);
894                 
895                 /* halo before ztra, because ztra fills in zbuffer now */
896                 if(R.flag & R_HALO)
897                         if(rl->layflag & SCE_LAY_HALO)
898                                 halo_tile(pa, rl->rectf, rl->lay);
899
900                 /* transp layer */
901                 if(R.flag & R_ZTRA) {
902                         if(rl->layflag & SCE_LAY_ZTRA) {
903                                 unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
904                                 
905                                 /* allocate, but not free here, for asynchronous display of this rect in main thread */
906                                 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
907                                 
908                                 /* swap for live updates, and it is used in zbuf.c!!! */
909                                 SWAP(float *, rl->acolrect, rl->rectf);
910                                 ztramask= zbuffer_transp_shade(pa, rl, rl->rectf);
911                                 SWAP(float *, rl->acolrect, rl->rectf);
912                                 
913                                 /* zbuffer transp only returns ztramask if there's solid rendered */
914                                 if(ztramask)
915                                         solidmask= make_solid_mask(pa);
916
917                                 if(ztramask && solidmask) {
918                                         unsigned short *sps= solidmask, *spz= ztramask;
919                                         unsigned short fullmask= (1<<R.osa)-1;
920                                         float *fcol= rl->rectf; float *acol= rl->acolrect;
921                                         int x;
922                                         
923                                         for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
924                                                 if(*sps == fullmask)
925                                                         addAlphaOverFloat(fcol, acol);
926                                                 else
927                                                         addAlphaOverFloatMask(fcol, acol, *sps, *spz);
928                                         }
929                                 }
930                                 else {
931                                         float *fcol= rl->rectf; float *acol= rl->acolrect;
932                                         int x;
933                                         for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
934                                                 addAlphaOverFloat(fcol, acol);
935                                         }
936                                 }
937                                 if(solidmask) MEM_freeN(solidmask);
938                                 if(ztramask) MEM_freeN(ztramask);
939                         }
940                 }
941
942                 /* strand rendering */
943                 if((rl->layflag & SCE_LAY_STRAND) && R.totstrand) {
944                         float *fcol, *scol;
945                         unsigned short *strandmask, *solidmask= NULL; /* 16 bits, MAX_OSA */
946                         int x;
947                         
948                         /* allocate, but not free here, for asynchronous display of this rect in main thread */
949                         rl->scolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "strand layer");
950
951                         /* swap for live updates, and it is used in zbuf.c!!! */
952                         SWAP(float*, rl->scolrect, rl->rectf);
953                         strandmask= zbuffer_strands_shade(&R, pa, rl, rl->rectf);
954                         SWAP(float*, rl->scolrect, rl->rectf);
955
956                         /* zbuffer strands only returns strandmask if there's solid rendered */
957                         if(strandmask)
958                                 solidmask= make_solid_mask(pa);
959                         
960                         if(strandmask && solidmask) {
961                                 unsigned short *sps= solidmask, *spz= strandmask;
962                                 unsigned short fullmask= (1<<R.osa)-1;
963
964                                 fcol= rl->rectf; scol= rl->scolrect;
965                                 for(x=pa->rectx*pa->recty; x>0; x--, scol+=4, fcol+=4, sps++, spz++) {
966                                         if(*sps == fullmask)
967                                                 addAlphaOverFloat(fcol, scol);
968                                         else
969                                                 addAlphaOverFloatMask(fcol, scol, *sps, *spz);
970                                 }
971                         }
972                         else {
973                                 fcol= rl->rectf; scol= rl->scolrect;
974                                 for(x=pa->rectx*pa->recty; x>0; x--, scol+=4, fcol+=4)
975                                         addAlphaOverFloat(fcol, scol);
976                         }
977
978                         if(solidmask) MEM_freeN(solidmask);
979                         if(strandmask) MEM_freeN(strandmask);
980                 }
981
982                 /* sky before edge */
983                 if(rl->layflag & SCE_LAY_SKY)
984                         sky_tile(pa, rl->rectf);
985
986                 /* extra layers */
987                 if(rl->layflag & SCE_LAY_EDGE) 
988                         if(R.r.mode & R_EDGE) 
989                                 edge_enhance_add(pa, rl->rectf, edgerect);
990                 
991                 if(rl->passflag & SCE_PASS_Z)
992                         convert_zbuf_to_distbuf(pa, rl);
993                 
994                 if(rl->passflag & SCE_PASS_VECTOR)
995                         reset_sky_speed(pa, rl);
996                 
997                 /* de-premul alpha */
998                 if(R.r.alphamode & R_ALPHAKEY)
999                         convert_to_key_alpha(pa, rl->rectf);
1000                 
1001                 /* free stuff within loop! */
1002                 MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
1003                 freeps(&psmlist);
1004                 
1005                 if(edgerect) MEM_freeN(edgerect);
1006                 edgerect= NULL;
1007         }
1008         
1009         /* free all */
1010         MEM_freeN(pa->recto); pa->recto= NULL;
1011         MEM_freeN(pa->rectp); pa->rectp= NULL;
1012         MEM_freeN(pa->rectz); pa->rectz= NULL;
1013         
1014         /* display active layer */
1015         rr->renrect.ymin=rr->renrect.ymax= 0;
1016         rr->renlay= render_get_active_layer(&R, rr);
1017 }
1018
1019
1020 /* ------------------------------------------------------------------------ */
1021
1022 /* non OSA case, full tile render */
1023 /* supposed to be fully threadable! */
1024 void zbufshade_tile(RenderPart *pa)
1025 {
1026         ShadeSample ssamp;
1027         RenderResult *rr= pa->result;
1028         RenderLayer *rl;
1029         PixStr ps;
1030         float *edgerect= NULL;
1031         int addpassflag;
1032         
1033         /* fake pixel struct, to comply to osa render */
1034         ps.next= NULL;
1035         ps.mask= 0xFFFF;
1036         
1037         /* zbuffer code clears/inits rects */
1038         pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1039         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1040         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1041
1042         for(rl= rr->layers.first; rl; rl= rl->next) {
1043                 
1044                 /* general shader info, passes */
1045                 shade_sample_initialize(&ssamp, pa, rl);
1046                 addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
1047                 
1048                 zbuffer_solid(pa, rl->lay, rl->layflag, NULL, NULL);
1049                 
1050                 if(!R.test_break()) {   /* NOTE: this if() is not consistant */
1051                         
1052                         /* edges only for solid part, ztransp doesn't support it yet anti-aliased */
1053                         if(rl->layflag & SCE_LAY_EDGE) {
1054                                 if(R.r.mode & R_EDGE) {
1055                                         edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
1056                                         edge_enhance_tile(pa, edgerect);
1057                                 }
1058                         }
1059                         
1060                         /* initialize scanline updates for main thread */
1061                         rr->renrect.ymin= 0;
1062                         rr->renlay= rl;
1063                         
1064                         if(rl->layflag & SCE_LAY_SOLID) {
1065                                 float *fcol= rl->rectf;
1066                                 int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
1067                                 int x, y, offs=0, seed;
1068                                 
1069                                 /* we set per pixel a fixed seed, for random AO and shadow samples */
1070                                 seed= pa->rectx*pa->disprect.ymin;
1071                                 
1072                                 /* irregular shadowb buffer creation */
1073                                 if(R.r.mode & R_SHADOW)
1074                                         ISB_create(pa, NULL);
1075                                 
1076                                 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1077                                         for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) {
1078                                                 /* per pixel fixed seed */
1079                                                 BLI_thread_srandom(pa->thread, seed++);
1080                                                 
1081                                                 if(*rp) {
1082                                                         ps.obi= *ro;
1083                                                         ps.facenr= *rp;
1084                                                         ps.z= *rz;
1085                                                         if(shade_samples(&ssamp, &ps, x, y)) {
1086                                                                 QUATCOPY(fcol, ssamp.shr[0].combined);
1087
1088                                                                 if(!(fcol[0] == fcol[0]))
1089                                                                         printvecf("fudgecol", fcol);
1090                                                                 
1091                                                                 /* passes */
1092                                                                 if(addpassflag)
1093                                                                         add_passes(rl, offs, ssamp.shi, ssamp.shr);
1094                                                         }
1095                                                 }
1096                                         }
1097                                         if(y&1)
1098                                                 if(R.test_break()) break; 
1099                                 }
1100                                 
1101                                 if(R.r.mode & R_SHADOW)
1102                                         ISB_free(pa);
1103                         }
1104                         
1105                         /* disable scanline updating */
1106                         rr->renlay= NULL;
1107                 }
1108                 
1109                 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1110                 if(R.flag & R_LAMPHALO)
1111                         if(rl->layflag & SCE_LAY_HALO)
1112                                 lamphalo_tile(pa, rl);
1113                 
1114                 /* halo before ztra, because ztra fills in zbuffer now */
1115                 if(R.flag & R_HALO)
1116                         if(rl->layflag & SCE_LAY_HALO)
1117                                 halo_tile(pa, rl->rectf, rl->lay);
1118                 
1119                 if(R.flag & R_ZTRA) {
1120                         if(rl->layflag & SCE_LAY_ZTRA) {
1121                                 float *fcol, *acol;
1122                                 int x;
1123                                 
1124                                 /* allocate, but not free here, for asynchronous display of this rect in main thread */
1125                                 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1126                                 
1127                                 /* swap for live updates */
1128                                 SWAP(float *, rl->acolrect, rl->rectf);
1129                                 zbuffer_transp_shade(pa, rl, rl->rectf);
1130                                 SWAP(float *, rl->acolrect, rl->rectf);
1131                                 
1132                                 fcol= rl->rectf; acol= rl->acolrect;
1133                                 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1134                                         addAlphaOverFloat(fcol, acol);
1135                                 }
1136                         }
1137                 }
1138
1139                 /* strand rendering */
1140                 if((rl->layflag & SCE_LAY_STRAND) && R.totstrand) {
1141                         float *fcol, *scol;
1142                         int x;
1143                         
1144                         /* allocate, but not free here, for asynchronous display of this rect in main thread */
1145                         rl->scolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "strand layer");
1146
1147                         /* swap for live updates */
1148                         SWAP(float*, rl->scolrect, rl->rectf);
1149                         zbuffer_strands_shade(&R, pa, rl, rl->rectf);
1150                         SWAP(float*, rl->scolrect, rl->rectf);
1151
1152                         fcol= rl->rectf; scol= rl->scolrect;
1153                         for(x=pa->rectx*pa->recty; x>0; x--, scol+=4, fcol+=4)
1154                                 addAlphaOverFloat(fcol, scol);
1155                 }
1156                 
1157                 /* sky before edge */
1158                 if(rl->layflag & SCE_LAY_SKY)
1159                         sky_tile(pa, rl->rectf);
1160                 
1161                 if(!R.test_break()) {
1162                         if(rl->layflag & SCE_LAY_EDGE) 
1163                                 if(R.r.mode & R_EDGE)
1164                                         edge_enhance_add(pa, rl->rectf, edgerect);
1165                 }
1166                 
1167                 if(rl->passflag & SCE_PASS_Z)
1168                         convert_zbuf_to_distbuf(pa, rl);
1169                 
1170                 if(rl->passflag & SCE_PASS_VECTOR)
1171                         reset_sky_speed(pa, rl);
1172                 
1173                 /* de-premul alpha */
1174                 if(R.r.alphamode & R_ALPHAKEY)
1175                         convert_to_key_alpha(pa, rl->rectf);
1176                 
1177                 if(edgerect) MEM_freeN(edgerect);
1178                 edgerect= NULL;
1179         }
1180
1181         /* display active layer */
1182         rr->renrect.ymin=rr->renrect.ymax= 0;
1183         rr->renlay= render_get_active_layer(&R, rr);
1184         
1185         MEM_freeN(pa->recto); pa->recto= NULL;
1186         MEM_freeN(pa->rectp); pa->rectp= NULL;
1187         MEM_freeN(pa->rectz); pa->rectz= NULL;
1188 }
1189
1190 /* SSS preprocess tile render, fully threadable */
1191 typedef struct ZBufSSSHandle {
1192         RenderPart *pa;
1193         ListBase psmlist;
1194         int totps;
1195 } ZBufSSSHandle;
1196
1197 static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z)
1198 {
1199         ZBufSSSHandle *handle = cb_handle;
1200         RenderPart *pa= handle->pa;
1201
1202         /* extra border for filter gives double samples on part edges,
1203            don't use those */
1204         if(x<pa->crop || x>=pa->rectx-pa->crop)
1205                 return;
1206         if(y<pa->crop || y>=pa->recty-pa->crop)
1207                 return;
1208         
1209         if(pa->rectall) {
1210                 long *rs= pa->rectall + pa->rectx*y + x;
1211
1212                 addps(&handle->psmlist, rs, obi, facenr, z, 0);
1213                 handle->totps++;
1214         }
1215         if(pa->rectz) {
1216                 int *rz= pa->rectz + pa->rectx*y + x;
1217                 int *rp= pa->rectp + pa->rectx*y + x;
1218                 int *ro= pa->recto + pa->rectx*y + x;
1219
1220                 if(z < *rz) {
1221                         if(*rp == 0)
1222                                 handle->totps++;
1223                         *rz= z;
1224                         *rp= facenr;
1225                         *ro= obi;
1226                 }
1227         }
1228         if(pa->rectbackz) {
1229                 int *rz= pa->rectbackz + pa->rectx*y + x;
1230                 int *rp= pa->rectbackp + pa->rectx*y + x;
1231                 int *ro= pa->rectbacko + pa->rectx*y + x;
1232
1233                 if(z >= *rz) {
1234                         if(*rp == 0)
1235                                 handle->totps++;
1236                         *rz= z;
1237                         *rp= facenr;
1238                         *ro= obi;
1239                 }
1240         }
1241 }
1242
1243 static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRen *obi, VlakRen *vlr, int quad, float x, float y, float z, float *co, float *color, float *area)
1244 {
1245         ShadeInput *shi= ssamp->shi;
1246         ShadeResult shr;
1247         float texfac, orthoarea, nor[3];
1248
1249         /* cache for shadow */
1250         shi->samplenr++;
1251         
1252         if(quad) 
1253                 shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
1254         else
1255                 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
1256
1257         /* center pixel */
1258         x += 0.5f;
1259         y += 0.5f;
1260
1261         /* we estimate the area here using shi->dxco and shi->dyco. we need to
1262            enabled shi->osatex these are filled. we compute two areas, one with
1263            the normal pointed at the camera and one with the original normal, and
1264            then clamp to avoid a too large contribution from a single pixel */
1265         shi->osatex= 1;
1266
1267         VECCOPY(nor, shi->facenor);
1268         calc_view_vector(shi->facenor, x, y);
1269         Normalize(shi->facenor);
1270         shade_input_set_viewco(shi, x, y, z);
1271         orthoarea= VecLength(shi->dxco)*VecLength(shi->dyco);
1272
1273         VECCOPY(shi->facenor, nor);
1274         shade_input_set_viewco(shi, x, y, z);
1275         *area= VecLength(shi->dxco)*VecLength(shi->dyco);
1276         *area= MIN2(*area, 2.0f*orthoarea);
1277
1278         shade_input_set_uv(shi);
1279         shade_input_set_normals(shi);
1280
1281         /* we don't want flipped normals, they screw up back scattering */
1282         if(shi->flippednor)
1283                 shade_input_flip_normals(shi);
1284
1285         /* not a pretty solution, but fixes common cases */
1286         if(shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
1287                 VecMulf(shi->vn, -1.0f);
1288                 VecMulf(shi->vno, -1.0f);
1289         }
1290
1291         /* if nodetree, use the material that we are currently preprocessing
1292            instead of the node material */
1293         if(shi->mat->nodetree && shi->mat->use_nodes)
1294                 shi->mat= mat;
1295
1296         /* init material vars */
1297         // note, keep this synced with render_types.h
1298         memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
1299         shi->har= shi->mat->har;
1300         
1301         /* render */
1302         shade_input_set_shade_texco(shi);
1303         
1304         shade_samples_do_AO(ssamp);
1305         shade_material_loop(shi, &shr);
1306         
1307         VECCOPY(co, shi->co);
1308         VECCOPY(color, shr.combined);
1309
1310         /* texture blending */
1311         texfac= shi->mat->sss_texfac;
1312
1313         if(texfac == 0.0f) {
1314                 if(shr.col[0]!=0.0f) color[0] /= shr.col[0];
1315                 if(shr.col[1]!=0.0f) color[1] /= shr.col[1];
1316                 if(shr.col[2]!=0.0f) color[2] /= shr.col[2];
1317         }
1318         else if(texfac != 1.0f) {
1319                 if(shr.col[0]!=0.0f) color[0] *= pow(shr.col[0], texfac)/shr.col[0];
1320                 if(shr.col[1]!=0.0f) color[1] *= pow(shr.col[1], texfac)/shr.col[1];
1321                 if(shr.col[2]!=0.0f) color[2] *= pow(shr.col[2], texfac)/shr.col[2];
1322         }
1323 }
1324
1325 static void zbufshade_sss_free(RenderPart *pa)
1326 {
1327 #if 0
1328         MEM_freeN(pa->rectall); pa->rectall= NULL;
1329         freeps(&handle.psmlist);
1330 #else
1331         MEM_freeN(pa->rectz); pa->rectz= NULL;
1332         MEM_freeN(pa->rectp); pa->rectp= NULL;
1333         MEM_freeN(pa->recto); pa->recto= NULL;
1334         MEM_freeN(pa->rectbackz); pa->rectbackz= NULL;
1335         MEM_freeN(pa->rectbackp); pa->rectbackp= NULL;
1336         MEM_freeN(pa->rectbacko); pa->rectbacko= NULL;
1337 #endif
1338 }
1339
1340 void zbufshade_sss_tile(RenderPart *pa)
1341 {
1342         Render *re= &R;
1343         ShadeSample ssamp;
1344         ZBufSSSHandle handle;
1345         RenderResult *rr= pa->result;
1346         RenderLayer *rl= rr->layers.first;
1347         VlakRen *vlr;
1348         Material *mat= re->sss_mat;
1349         float (*co)[3], (*color)[3], *area, *fcol= rl->rectf;
1350         int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS);
1351         int *ro, *rz, *rp, *rbo, *rbz, *rbp;
1352 #if 0
1353         PixStr *ps;
1354         long *rs;
1355         int z;
1356 #endif
1357
1358         /* setup pixelstr list and buffer for zbuffering */
1359         handle.pa= pa;
1360         handle.totps= 0;
1361
1362 #if 0
1363         handle.psmlist.first= handle.psmlist.last= NULL;
1364         addpsmain(&handle.psmlist);
1365
1366         pa->rectall= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "rectall");
1367 #else
1368         pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1369         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1370         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1371         pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko");
1372         pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp");
1373         pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
1374 #endif
1375
1376         /* create the pixelstrs to be used later */
1377         zbuffer_sss(pa, rl->lay, &handle, addps_sss);
1378
1379         if(handle.totps==0) {
1380                 zbufshade_sss_free(pa);
1381                 return;
1382         }
1383
1384         co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
1385         color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
1386         area= MEM_mallocN(sizeof(float)*handle.totps, "SSSArea");
1387
1388 #if 0
1389         /* create ISB (does not work currently!) */
1390         if(re->r.mode & R_SHADOW)
1391                 ISB_create(pa, NULL);
1392 #endif
1393
1394         /* setup shade sample with correct passes */
1395         memset(&ssamp, 0, sizeof(ssamp));
1396         shade_sample_initialize(&ssamp, pa, rl);
1397         ssamp.shi[0].passflag= SCE_PASS_DIFFUSE|SCE_PASS_AO|SCE_PASS_RADIO;
1398         ssamp.shi[0].passflag |= SCE_PASS_RGBA;
1399         ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
1400         ssamp.tot= 1;
1401
1402         if(display) {
1403                 /* initialize scanline updates for main thread */
1404                 rr->renrect.ymin= 0;
1405                 rr->renlay= rl;
1406         }
1407         
1408         seed= pa->rectx*pa->disprect.ymin;
1409 #if 0
1410         rs= pa->rectall;
1411 #else
1412         rz= pa->rectz;
1413         rp= pa->rectp;
1414         ro= pa->recto;
1415         rbz= pa->rectbackz;
1416         rbp= pa->rectbackp;
1417         rbo= pa->rectbacko;
1418 #endif
1419         totpoint= 0;
1420
1421         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1422                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, fcol+=4) {
1423                         /* per pixel fixed seed */
1424                         BLI_thread_srandom(pa->thread, seed++);
1425                         
1426 #if 0
1427                         if(rs) {
1428                                 /* for each sample in this pixel, shade it */
1429                                 for(ps=(PixStr*)*rs; ps; ps=ps->next) {
1430                                         ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
1431                                         ObjectRen *obr= obi->obr;
1432                                         vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
1433                                         quad= (ps->facenr & RE_QUAD_OFFS);
1434                                         z= ps->z;
1435
1436                                         shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z,
1437                                                 co[totpoint], color[totpoint], &area[totpoint]);
1438
1439                                         totpoint++;
1440
1441                                         VECADD(fcol, fcol, color);
1442                                         fcol[3]= 1.0f;
1443                                 }
1444
1445                                 rs++;
1446                         }
1447 #else
1448                         if(rp) {
1449                                 if(*rp != 0) {
1450                                         ObjectInstanceRen *obi= &re->objectinstance[*ro];
1451                                         ObjectRen *obr= obi->obr;
1452
1453                                         /* shade front */
1454                                         vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK);
1455                                         quad= ((*rp) & RE_QUAD_OFFS);
1456
1457                                         shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz,
1458                                                 co[totpoint], color[totpoint], &area[totpoint]);
1459                                         
1460                                         VECADD(fcol, fcol, color[totpoint]);
1461                                         fcol[3]= 1.0f;
1462                                         totpoint++;
1463                                 }
1464
1465                                 rp++; rz++; ro++;
1466                         }
1467
1468                         if(rbp) {
1469                                 if(*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) {
1470                                         ObjectInstanceRen *obi= &re->objectinstance[*rbo];
1471                                         ObjectRen *obr= obi->obr;
1472
1473                                         /* shade back */
1474                                         vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK);
1475                                         quad= ((*rbp) & RE_QUAD_OFFS);
1476
1477                                         shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz,
1478                                                 co[totpoint], color[totpoint], &area[totpoint]);
1479                                         
1480                                         /* to indicate this is a back sample */
1481                                         area[totpoint]= -area[totpoint];
1482
1483                                         VECADD(fcol, fcol, color[totpoint]);
1484                                         fcol[3]= 1.0f;
1485                                         totpoint++;
1486                                 }
1487
1488                                 rbz++; rbp++; rbo++;
1489                         }
1490 #endif
1491                 }
1492
1493                 if(y&1)
1494                         if(re->test_break()) break; 
1495         }
1496
1497         /* note: after adding we do not free these arrays, sss keeps them */
1498         if(totpoint > 0) {
1499                 sss_add_points(re, co, color, area, totpoint);
1500         }
1501         else {
1502                 MEM_freeN(co);
1503                 MEM_freeN(color);
1504                 MEM_freeN(area);
1505         }
1506         
1507 #if 0
1508         if(re->r.mode & R_SHADOW)
1509                 ISB_free(pa);
1510 #endif
1511                 
1512         if(display) {
1513                 /* display active layer */
1514                 rr->renrect.ymin=rr->renrect.ymax= 0;
1515                 rr->renlay= render_get_active_layer(&R, rr);
1516         }
1517         
1518         zbufshade_sss_free(pa);
1519 }
1520
1521 /* ------------------------------------------------------------------------ */
1522
1523 static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har)       /* postprocess version */
1524 {
1525         float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf;
1526         float haloxs, haloys;
1527         int minx, maxx, miny, maxy, x, y;
1528
1529         /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */
1530         haloxs= har->xs - R.disprect.xmin;
1531         haloys= har->ys - R.disprect.ymin;
1532         
1533         har->miny= miny= haloys - har->rad/R.ycor;
1534         har->maxy= maxy= haloys + har->rad/R.ycor;
1535         
1536         if(maxy<0);
1537         else if(rr->recty<miny);
1538         else {
1539                 minx= floor(haloxs-har->rad);
1540                 maxx= ceil(haloxs+har->rad);
1541                         
1542                 if(maxx<0);
1543                 else if(rr->rectx<minx);
1544                 else {
1545                 
1546                         if(minx<0) minx= 0;
1547                         if(maxx>=rr->rectx) maxx= rr->rectx-1;
1548                         if(miny<0) miny= 0;
1549                         if(maxy>rr->recty) maxy= rr->recty;
1550         
1551                         rectft= rectf+ 4*rr->rectx*miny;
1552
1553                         for(y=miny; y<maxy; y++) {
1554         
1555                                 rtf= rectft+4*minx;
1556                                 
1557                                 yn= (y - haloys)*R.ycor;
1558                                 ysq= yn*yn;
1559                                 
1560                                 for(x=minx; x<=maxx; x++) {
1561                                         xn= x - haloxs;
1562                                         xsq= xn*xn;
1563                                         dist= xsq+ysq;
1564                                         if(dist<har->radsq) {
1565                                                 
1566                                                 shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec);
1567                                                 addalphaAddfacFloat(rtf, colf, har->add);
1568                                         }
1569                                         rtf+=4;
1570                                 }
1571         
1572                                 rectft+= 4*rr->rectx;
1573                                 
1574                                 if(R.test_break()) break; 
1575                         }
1576                 }
1577         }
1578
1579 /* ------------------------------------------------------------------------ */
1580
1581 static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
1582 {
1583         extern float hashvectf[];
1584         HaloRen fla;
1585         Material *ma;
1586         float *rc, rad, alfa, visifac, vec[3];
1587         int b, type;
1588         
1589         fla= *har;
1590         fla.linec= fla.ringc= fla.flarec= 0;
1591         
1592         rad= har->rad;
1593         alfa= har->alfa;
1594         
1595         visifac= R.ycor*(har->pixels);
1596         /* all radials added / r^3  == 1.0f! */
1597         visifac /= (har->rad*har->rad*har->rad);
1598         visifac*= visifac;
1599
1600         ma= har->mat;
1601         
1602         /* first halo: just do */
1603         
1604         har->rad= rad*ma->flaresize*visifac;
1605         har->radsq= har->rad*har->rad;
1606         har->zs= fla.zs= 0;
1607         
1608         har->alfa= alfa*visifac;
1609
1610         renderhalo_post(rr, rectf, har);
1611         
1612         /* next halo's: the flares */
1613         rc= hashvectf + ma->seed2;
1614         
1615         for(b=1; b<har->flarec; b++) {
1616                 
1617                 fla.r= fabs(rc[0]);
1618                 fla.g= fabs(rc[1]);
1619                 fla.b= fabs(rc[2]);
1620                 fla.alfa= ma->flareboost*fabs(alfa*visifac*rc[3]);
1621                 fla.hard= 20.0f + fabs(70*rc[7]);
1622                 fla.tex= 0;
1623                 
1624                 type= (int)(fabs(3.9*rc[6]));
1625
1626                 fla.rad= ma->subsize*sqrt(fabs(2.0f*har->rad*rc[4]));
1627                 
1628                 if(type==3) {
1629                         fla.rad*= 3.0f;
1630                         fla.rad+= R.rectx/10;
1631                 }
1632                 
1633                 fla.radsq= fla.rad*fla.rad;
1634                 
1635                 vec[0]= 1.4*rc[5]*(har->xs-R.winx/2);
1636                 vec[1]= 1.4*rc[5]*(har->ys-R.winy/2);
1637                 vec[2]= 32.0f*sqrt(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f);
1638                 
1639                 fla.xs= R.winx/2 + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2];
1640                 fla.ys= R.winy/2 + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2];
1641
1642                 if(R.flag & R_SEC_FIELD) {
1643                         if(R.r.mode & R_ODDFIELD) fla.ys += 0.5;
1644                         else fla.ys -= 0.5;
1645                 }
1646                 if(type & 1) fla.type= HA_FLARECIRC;
1647                 else fla.type= 0;
1648                 renderhalo_post(rr, rectf, &fla);
1649
1650                 fla.alfa*= 0.5;
1651                 if(type & 2) fla.type= HA_FLARECIRC;
1652                 else fla.type= 0;
1653                 renderhalo_post(rr, rectf, &fla);
1654                 
1655                 rc+= 7;
1656         }
1657 }
1658
1659 /* needs recode... integrate this better! */
1660 void add_halo_flare(Render *re)
1661 {
1662         RenderResult *rr= re->result;
1663         RenderLayer *rl;
1664         HaloRen *har;
1665         int a, mode, do_draw=0;
1666         
1667         /* for now, we get the first renderlayer in list with halos set */
1668         for(rl= rr->layers.first; rl; rl= rl->next)
1669                 if(rl->layflag & SCE_LAY_HALO)
1670                         break;
1671
1672         if(rl==NULL || rl->rectf==NULL)
1673                 return;
1674         
1675         mode= R.r.mode;
1676         R.r.mode &= ~R_PANORAMA;
1677         
1678         project_renderdata(&R, projectverto, 0, 0, 0);
1679         
1680         for(a=0; a<R.tothalo; a++) {
1681                 har= R.sortedhalos[a];
1682                 
1683                 if(har->flarec) {
1684                         do_draw= 1;
1685                         renderflare(rr, rl->rectf, har);
1686                 }
1687         }
1688
1689         if(do_draw) {
1690                 /* weak... the display callback wants an active renderlayer pointer... */
1691                 rr->renlay= rl;
1692                 re->display_draw(rr, NULL);
1693         }
1694         
1695         R.r.mode= mode; 
1696 }
1697
1698 /* ************************* used for shaded view ************************ */
1699
1700 /* if *re, then initialize, otherwise execute */
1701 void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
1702 {
1703         static VlakRen vlr;
1704         
1705         /* init */
1706         if(re) {
1707                 R= *re;
1708                 
1709                 /* fake render face */
1710                 memset(&vlr, 0, sizeof(VlakRen));
1711                 vlr.lay= -1;
1712                 
1713                 return;
1714         }
1715         shi->vlr= &vlr;
1716         
1717         if(shi->mat->nodetree && shi->mat->use_nodes)
1718                 ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
1719         else {
1720                 /* copy all relevant material vars, note, keep this synced with render_types.h */
1721                 memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
1722                 shi->har= shi->mat->har;
1723                 
1724                 shade_material_loop(shi, shr);
1725         }
1726 }
1727
1728 /* ************************* bake ************************ */
1729
1730 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
1731
1732 typedef struct BakeShade {
1733         ShadeSample ssamp;
1734         ObjectInstanceRen *obi;
1735         VlakRen *vlr;
1736         
1737         ZSpan *zspan;
1738         Image *ima;
1739         ImBuf *ibuf;
1740         
1741         int rectx, recty, quad, type, vdone, ready;
1742
1743         float dir[3];
1744         Object *actob;
1745         
1746         unsigned int *rect;
1747         float *rect_float;
1748 } BakeShade;
1749
1750 static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v)
1751 {
1752         if(isect) {
1753                 /* raytrace intersection with different u,v than scanconvert */
1754                 if(vlr->v4) {
1755                         if(quad)
1756                                 shade_input_set_triangle_i(shi, obi, vlr, 2, 1, 3);
1757                         else
1758                                 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 3);
1759                 }
1760                 else
1761                         shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
1762         }
1763         else {
1764                 /* regular scanconvert */
1765                 if(quad) 
1766                         shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
1767                 else
1768                         shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
1769         }
1770                 
1771         /* set up view vector */
1772         VECCOPY(shi->view, shi->co);
1773         Normalize(shi->view);
1774         
1775         /* cache for shadow */
1776         shi->samplenr++;
1777         
1778         shi->u= -u;
1779         shi->v= -v;
1780         shi->xs= x;
1781         shi->ys= y;
1782         
1783         shade_input_set_normals(shi);
1784
1785         /* no normal flip */
1786         if(shi->flippednor)
1787                 shade_input_flip_normals(shi);
1788 }
1789
1790 static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int x, int y, float u, float v, float *tvn, float *ttang)
1791 {
1792         BakeShade *bs= handle;
1793         ShadeSample *ssamp= &bs->ssamp;
1794         ShadeResult shr;
1795         VlakRen *vlr= shi->vlr;
1796         
1797         /* init material vars */
1798         memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));        // note, keep this synced with render_types.h
1799         shi->har= shi->mat->har;
1800         
1801         if(bs->type==RE_BAKE_AO) {
1802                 ambient_occlusion(shi);
1803                 ambient_occlusion_to_diffuse(shi, shr.combined);
1804         }
1805         else {
1806                 shade_input_set_shade_texco(shi);
1807                 
1808                 shade_samples_do_AO(ssamp);
1809                 
1810                 if(shi->mat->nodetree && shi->mat->use_nodes) {
1811                         ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
1812                         shi->mat= vlr->mat;             /* shi->mat is being set in nodetree */
1813                 }
1814                 else
1815                         shade_material_loop(shi, &shr);
1816                 
1817                 if(bs->type==RE_BAKE_NORMALS) {
1818                         float nor[3];
1819
1820                         VECCOPY(nor, shi->vn);
1821
1822                         if(R.r.bake_normal_space == R_BAKE_SPACE_CAMERA);
1823                         else if(R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
1824                                 float mat[3][3], imat[3][3];
1825
1826                                 /* bitangent */
1827                                 if(tvn && ttang) {
1828                                         VECCOPY(mat[0], ttang);
1829                                         Crossf(mat[1], tvn, ttang);
1830                                         VECCOPY(mat[2], tvn);
1831                                 }
1832                                 else {
1833                                         VECCOPY(mat[0], shi->tang);
1834                                         Crossf(mat[1], shi->vn, shi->tang);
1835                                         VECCOPY(mat[2], shi->vn);
1836                                 }
1837
1838                                 Mat3Inv(imat, mat);
1839                                 Mat3MulVecfl(imat, nor);
1840                         }
1841                         else if(R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
1842                                 Mat4Mul3Vecfl(ob->imat, nor); /* ob->imat includes viewinv! */
1843                         else if(R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
1844                                 Mat4Mul3Vecfl(R.viewinv, nor);
1845
1846                         Normalize(nor); /* in case object has scaling */
1847
1848                         shr.combined[0]= nor[0]/2.0f + 0.5f;
1849                         shr.combined[1]= 0.5f - nor[1]/2.0f;
1850                         shr.combined[2]= nor[2]/2.0f + 0.5f;
1851                 }
1852                 else if(bs->type==RE_BAKE_TEXTURE) {
1853                         shr.combined[0]= shi->r;
1854                         shr.combined[1]= shi->g;
1855                         shr.combined[2]= shi->b;
1856                 }
1857         }
1858         
1859         if(bs->rect) {
1860                 char *col= (char *)(bs->rect + bs->rectx*y + x);
1861                 col[0]= FTOCHAR(shr.combined[0]);
1862                 col[1]= FTOCHAR(shr.combined[1]);
1863                 col[2]= FTOCHAR(shr.combined[2]);
1864                 col[3]= 255;
1865         }
1866         else {
1867                 float *col= bs->rect_float + 4*(bs->rectx*y + x);
1868                 VECCOPY(col, shr.combined);
1869                 col[3]= 1.0f;
1870         }
1871 }
1872
1873 static void bake_displacement(void *handle, ShadeInput *shi, Isect *isec, int dir, int x, int y)
1874 {
1875         BakeShade *bs= handle;
1876         float disp;
1877         
1878         disp = 0.5 + (isec->labda*VecLength(isec->vec) * -dir);
1879         
1880         if(bs->rect_float) {
1881                 float *col= bs->rect_float + 4*(bs->rectx*y + x);
1882                 col[0] = col[1] = col[2] = disp;
1883                 col[3]= 1.0f;
1884         } else {        
1885                 char *col= (char *)(bs->rect + bs->rectx*y + x);
1886                 col[0]= FTOCHAR(disp);
1887                 col[1]= FTOCHAR(disp);
1888                 col[2]= FTOCHAR(disp);
1889                 col[3]= 255;
1890         }
1891 }
1892
1893 static int bake_check_intersect(Isect *is, RayFace *face)
1894 {
1895         VlakRen *vlr = (VlakRen*)face;
1896         BakeShade *bs = (BakeShade*)is->userdata;
1897         
1898         /* no direction checking for now, doesn't always improve the result
1899          * (INPR(shi->facenor, bs->dir) > 0.0f); */
1900
1901         return (vlr->obr->ob != bs->actob);
1902 }
1903
1904 static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *dir, float sign, float *hitco)
1905 {
1906         float maxdist;
1907         int hit;
1908
1909         /* might be useful to make a user setting for maxsize*/
1910         if(R.r.bake_maxdist > 0.0f)
1911                 maxdist= R.r.bake_maxdist;
1912         else
1913                 maxdist= RE_ray_tree_max_size(R.raytree);
1914
1915         isect->end[0] = isect->start[0] + dir[0]*maxdist*sign;
1916         isect->end[1] = isect->start[1] + dir[1]*maxdist*sign;
1917         isect->end[2] = isect->start[2] + dir[2]*maxdist*sign;
1918
1919         hit = RE_ray_tree_intersect_check(R.raytree, isect, bake_check_intersect);
1920         if(hit) {
1921                 hitco[0] = isect->start[0] + isect->labda*isect->vec[0];
1922                 hitco[1] = isect->start[1] + isect->labda*isect->vec[1];
1923                 hitco[2] = isect->start[2] + isect->labda*isect->vec[2];
1924         }
1925
1926         return hit;
1927 }
1928
1929 static void do_bake_shade(void *handle, int x, int y, float u, float v)
1930 {
1931         BakeShade *bs= handle;
1932         VlakRen *vlr= bs->vlr;
1933         ObjectInstanceRen *obi= bs->obi;
1934         Object *ob= obi->obr->ob;
1935         float l, *v1, *v2, *v3, tvn[3], ttang[3];
1936         int quad;
1937         ShadeSample *ssamp= &bs->ssamp;
1938         ShadeInput *shi= ssamp->shi;
1939         
1940         /* fast threadsafe break test */
1941         if(R.test_break())
1942                 return;
1943         
1944         /* setup render coordinates */
1945         if(bs->quad) {
1946                 v1= vlr->v1->co;
1947                 v2= vlr->v3->co;
1948                 v3= vlr->v4->co;
1949         }
1950         else {
1951                 v1= vlr->v1->co;
1952                 v2= vlr->v2->co;
1953                 v3= vlr->v3->co;
1954         }
1955         
1956         /* renderco */
1957         l= 1.0f-u-v;
1958         
1959         shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
1960         shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
1961         shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
1962         
1963         if(obi->flag & R_TRANSFORMED)
1964                 Mat4MulVecfl(obi->mat, shi->co);
1965         
1966         quad= bs->quad;
1967         bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
1968
1969         if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) {
1970                 shade_input_set_shade_texco(shi);
1971                 VECCOPY(tvn, shi->vn);
1972                 VECCOPY(ttang, shi->tang);
1973         }
1974
1975         /* if we are doing selected to active baking, find point on other face */
1976         if(bs->actob) {
1977                 Isect isec, minisec;
1978                 float co[3], minco[3];
1979                 int hit, sign, dir=1;
1980                 
1981                 /* intersect with ray going forward and backward*/
1982                 hit= 0;
1983                 memset(&minisec, 0, sizeof(minisec));
1984                 minco[0]= minco[1]= minco[2]= 0.0f;
1985                 
1986                 VECCOPY(bs->dir, shi->vn);
1987                 
1988                 for(sign=-1; sign<=1; sign+=2) {
1989                         memset(&isec, 0, sizeof(isec));
1990                         VECCOPY(isec.start, shi->co);
1991                         isec.mode= RE_RAY_MIRROR;
1992                         isec.faceorig= (RayFace*)vlr;
1993                         isec.oborig= RAY_OBJECT_SET(&R, obi);
1994                         isec.userdata= bs;
1995                         
1996                         if(bake_intersect_tree(R.raytree, &isec, shi->vn, sign, co)) {
1997                                 if(!hit || VecLenf(shi->co, co) < VecLenf(shi->co, minco)) {
1998                                         minisec= isec;
1999                                         VECCOPY(minco, co);
2000                                         hit= 1;
2001                                         dir = sign;
2002                                 }
2003                         }
2004                 }
2005
2006                 if (hit && bs->type==RE_BAKE_DISPLACEMENT) {;
2007                         bake_displacement(handle, shi, &minisec, dir, x, y);
2008                         return;
2009                 }
2010
2011                 /* if hit, we shade from the new point, otherwise from point one starting face */
2012                 if(hit) {
2013                         vlr= (VlakRen*)minisec.face;
2014                         obi= RAY_OBJECT_GET(&R, minisec.ob);
2015                         quad= (minisec.isect == 2);
2016                         VECCOPY(shi->co, minco);
2017                         
2018                         u= -minisec.u;
2019                         v= -minisec.v;
2020                         bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
2021                 }
2022         }
2023
2024         if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT)
2025                 bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
2026         else
2027                 bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
2028 }
2029
2030 static int get_next_bake_face(BakeShade *bs)
2031 {
2032         ObjectRen *obr;
2033         VlakRen *vlr;
2034         MTFace *tface;
2035         static int v= 0, vdone= 0;
2036         static ObjectInstanceRen *obi= NULL;
2037         
2038         if(bs==NULL) {
2039                 vlr= NULL;
2040                 v= vdone= 0;
2041                 obi= R.instancetable.first;
2042                 return 0;
2043         }
2044         
2045         BLI_lock_thread(LOCK_CUSTOM1);  
2046
2047         for(; obi; obi=obi->next, v=0) {
2048                 obr= obi->obr;
2049
2050                 for(; v<obr->totvlak; v++) {
2051                         vlr= RE_findOrAddVlak(obr, v);
2052
2053                         if((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
2054                                 tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
2055
2056                                 if(tface && tface->tpage) {
2057                                         Image *ima= tface->tpage;
2058                                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2059                                         float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
2060                                         
2061                                         if(ibuf==NULL)
2062                                                 continue;
2063                                         
2064                                         if(ibuf->rect==NULL && ibuf->rect_float==NULL)
2065                                                 continue;
2066                                         
2067                                         if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
2068                                                 continue;
2069                                         
2070                                         /* find the image for the first time? */
2071                                         if(ima->id.flag & LIB_DOIT) {
2072                                                 ima->id.flag &= ~LIB_DOIT;
2073                                                 
2074                                                 /* we either fill in float or char, this ensures things go fine */
2075                                                 if(ibuf->rect_float)
2076                                                         imb_freerectImBuf(ibuf);
2077                                                 /* clear image */
2078                                                 if(R.r.bake_flag & R_BAKE_CLEAR)
2079                                                         IMB_rectfill(ibuf, vec);
2080                                         
2081                                                 /* might be read by UI to set active image for display */
2082                                                 R.bakebuf= ima;
2083                                         }                               
2084                                         
2085                                         bs->obi= obi;
2086                                         bs->vlr= vlr;
2087                                         
2088                                         bs->vdone++;    /* only for error message if nothing was rendered */
2089                                         v++;
2090                                         
2091                                         BLI_unlock_thread(LOCK_CUSTOM1);
2092                                         return 1;
2093                                 }
2094                         }
2095                 }
2096         }
2097         
2098         BLI_unlock_thread(LOCK_CUSTOM1);
2099         return 0;
2100 }
2101
2102 /* already have tested for tface and ima and zspan */
2103 static void shade_tface(BakeShade *bs)
2104 {
2105         VlakRen *vlr= bs->vlr;
2106         ObjectInstanceRen *obi= bs->obi;
2107         ObjectRen *obr= obi->obr;
2108         MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
2109         Image *ima= tface->tpage;
2110         float vec[4][2];
2111         int a, i1, i2, i3;
2112         
2113         /* check valid zspan */
2114         if(ima!=bs->ima) {
2115                 bs->ima= ima;
2116                 bs->ibuf= BKE_image_get_ibuf(ima, NULL);
2117                 /* note, these calls only free/fill contents of zspan struct, not zspan itself */
2118                 zbuf_free_span(bs->zspan);
2119                 zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
2120         }                               
2121         
2122         bs->rectx= bs->ibuf->x;
2123         bs->recty= bs->ibuf->y;
2124         bs->rect= bs->ibuf->rect;
2125         bs->rect_float= bs->ibuf->rect_float;
2126         bs->quad= 0;
2127         
2128         /* get pixel level vertex coordinates */
2129         for(a=0; a<4; a++) {
2130                 vec[a][0]= tface->uv[a][0]*(float)bs->rectx - 0.5f;
2131                 vec[a][1]= tface->uv[a][1]*(float)bs->recty - 0.5f;
2132         }
2133         
2134         /* UV indices have to be corrected for possible quad->tria splits */
2135         i1= 0; i2= 1; i3= 2;
2136         vlr_set_uv_indices(vlr, &i1, &i2, &i3);
2137         zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
2138         
2139         if(vlr->v4) {
2140                 bs->quad= 1;
2141                 zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
2142         }
2143 }
2144
2145 static void *do_bake_thread(void *bs_v)
2146 {
2147         BakeShade *bs= bs_v;
2148         
2149         while(get_next_bake_face(bs)) {
2150                 shade_tface(bs);
2151                 
2152                 /* fast threadsafe break test */
2153                 if(R.test_break())
2154                         break;
2155         }
2156         bs->ready= 1;
2157         
2158         return NULL;
2159 }
2160
2161 /* using object selection tags, the faces with UV maps get baked */
2162 /* render should have been setup */
2163 /* returns 0 if nothing was handled */
2164 int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
2165 {
2166         BakeShade handles[BLENDER_MAX_THREADS];
2167         ListBase threads;
2168         Image *ima;
2169         int a, vdone=0;
2170
2171         /* initialize render global */
2172         R= *re;
2173         R.bakebuf= NULL;
2174         
2175         /* initialize static vars */
2176         get_next_bake_face(NULL);
2177         
2178         /* baker uses this flag to detect if image was initialized */
2179         for(ima= G.main->image.first; ima; ima= ima->id.next)
2180                 ima->id.flag |= LIB_DOIT;
2181         
2182         BLI_init_threads(&threads, do_bake_thread, re->r.threads);
2183
2184         /* get the threads running */
2185         for(a=0; a<re->r.threads; a++) {
2186                 /* set defaults in handles */
2187                 memset(&handles[a], 0, sizeof(BakeShade));
2188                 
2189                 handles[a].ssamp.shi[0].lay= re->scene->lay;
2190                 handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED;
2191                 handles[a].ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
2192                 handles[a].ssamp.shi[0].thread= a;
2193                 handles[a].ssamp.tot= 1;
2194                 
2195                 handles[a].type= type;
2196                 handles[a].actob= actob;
2197                 handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
2198                 
2199                 BLI_insert_thread(&threads, &handles[a]);
2200         }
2201         
2202         /* wait for everything to be done */
2203         a= 0;
2204         while(a!=re->r.threads) {
2205                 
2206                 PIL_sleep_ms(50);
2207
2208                 for(a=0; a<re->r.threads; a++)
2209                         if(handles[a].ready==0)
2210                                 break;
2211         }
2212         
2213         /* filter and refresh images */
2214         for(ima= G.main->image.first; ima; ima= ima->id.next) {
2215                 if((ima->id.flag & LIB_DOIT)==0) {
2216                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2217                         for(a=0; a<re->r.bake_filter; a++)
2218                                 IMB_filter_extend(ibuf);
2219                         ibuf->userflags |= IB_BITMAPDIRTY;
2220                         
2221                         if (ibuf->rect_float) IMB_rect_from_float(ibuf);
2222                 }
2223         }
2224         
2225         /* calculate return value */
2226         for(a=0; a<re->r.threads; a++) {
2227                 vdone+= handles[a].vdone;
2228                 
2229                 zbuf_free_span(handles[a].zspan);
2230                 MEM_freeN(handles[a].zspan);
2231         }
2232         
2233         BLI_end_threads(&threads);
2234         return vdone;
2235 }
2236
2237 struct Image *RE_bake_shade_get_image(void)
2238 {
2239         return R.bakebuf;
2240 }
2241