Recreating my GSoC branch.
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 <float.h>
33 #include <string.h>
34 #include <assert.h>
35
36 /* External modules: */
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_math.h"
40 #include "BLI_blenlib.h"
41 #include "BLI_jitter.h"
42 #include "BLI_rand.h"
43 #include "BLI_threads.h"
44
45 #include "BKE_utildefines.h"
46
47 #include "DNA_image_types.h"
48 #include "DNA_lamp_types.h"
49 #include "DNA_material_types.h"
50 #include "DNA_meshdata_types.h"
51 #include "DNA_group_types.h"
52
53 #include "BKE_global.h"
54 #include "BKE_image.h"
55 #include "BKE_main.h"
56 #include "BKE_node.h"
57 #include "BKE_texture.h"
58
59 #include "IMB_imbuf_types.h"
60 #include "IMB_imbuf.h"
61
62 /* local include */
63 #include "renderpipeline.h"
64 #include "render_types.h"
65 #include "renderdatabase.h"
66 #include "occlusion.h"
67 #include "pixelblending.h"
68 #include "pixelshading.h"
69 #include "shadbuf.h"
70 #include "shading.h"
71 #include "sss.h"
72 #include "zbuf.h"
73 #include "RE_raytrace.h"
74
75 #include "PIL_time.h"
76
77 /* own include */
78 #include "rendercore.h"
79
80
81 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
82 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
83 /* only to be used here in this file, it's for speed */
84 extern struct Render R;
85 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
86
87 /* x and y are current pixels in rect to be rendered */
88 /* do not normalize! */
89 void calc_view_vector(float *view, float x, float y)
90 {
91
92         view[2]= -ABS(R.clipsta);
93         
94         if(R.r.mode & R_ORTHO) {
95                 view[0]= view[1]= 0.0f;
96         }
97         else {
98                 
99                 if(R.r.mode & R_PANORAMA)
100                         x-= R.panodxp;
101                 
102                 /* move x and y to real viewplane coords */
103                 x= (x/(float)R.winx);
104                 view[0]= R.viewplane.xmin + x*(R.viewplane.xmax - R.viewplane.xmin);
105                 
106                 y= (y/(float)R.winy);
107                 view[1]= R.viewplane.ymin + y*(R.viewplane.ymax - R.viewplane.ymin);
108                 
109 //              if(R.flag & R_SEC_FIELD) {
110 //                      if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
111 //                      else view[1]= (y+R.ystart+1.0)*R.ycor;
112 //              }
113 //              else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
114         
115                 if(R.r.mode & R_PANORAMA) {
116                         float u= view[0] + R.panodxv; float v= view[2];
117                         view[0]= R.panoco*u + R.panosi*v;
118                         view[2]= -R.panosi*u + R.panoco*v;
119                 }
120         }
121 }
122
123 void calc_renderco_ortho(float *co, float x, float y, int z)
124 {
125         /* x and y 3d coordinate can be derived from pixel coord and winmat */
126         float fx= 2.0f/(R.winx*R.winmat[0][0]);
127         float fy= 2.0f/(R.winy*R.winmat[1][1]);
128         float zco;
129         
130         co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
131         co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
132         
133         zco= ((float)z)/2147483647.0f;
134         co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
135 }
136
137 void calc_renderco_zbuf(float *co, float *view, int z)
138 {
139         float fac, zco;
140         
141         /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
142         zco= ((float)z)/2147483647.0f;
143         co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
144
145         fac= co[2]/view[2];
146         co[0]= fac*view[0];
147         co[1]= fac*view[1];
148 }
149
150 /* also used in zbuf.c and shadbuf.c */
151 int count_mask(unsigned short mask)
152 {
153         if(R.samples)
154                 return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]);
155         return 0;
156 }
157
158 static int calchalo_z(HaloRen *har, int zz)
159 {
160         
161         if(har->type & HA_ONLYSKY) {
162                 if(zz < 0x7FFFFFF0) zz= - 0x7FFFFF;     /* edge render messes zvalues */
163         }
164         else {
165                 zz= (zz>>8);
166         }
167         return zz;
168 }
169
170
171
172 static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps)
173 {
174         float col[4], accol[4], fac;
175         int amount, amountm, zz, flarec, sample, fullsample, mask=0;
176         
177         fullsample= (totsample > 1);
178         amount= 0;
179         accol[0]=accol[1]=accol[2]=accol[3]= 0.0f;
180         flarec= har->flarec;
181         
182         while(ps) {
183                 amountm= count_mask(ps->mask);
184                 amount+= amountm;
185                 
186                 zz= calchalo_z(har, ps->z);
187                 if((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
188                         if(shadeHaloFloat(har, col, zz, dist, xn, yn, flarec)) {
189                                 flarec= 0;
190
191                                 if(fullsample) {
192                                         for(sample=0; sample<totsample; sample++)
193                                                 if(ps->mask & (1 << sample))
194                                                         addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
195                                 }
196                                 else {
197                                         fac= ((float)amountm)/(float)R.osa;
198                                         accol[0]+= fac*col[0];
199                                         accol[1]+= fac*col[1];
200                                         accol[2]+= fac*col[2];
201                                         accol[3]+= fac*col[3];
202                                 }
203                         }
204                 }
205                 
206                 mask |= ps->mask;
207                 ps= ps->next;
208         }
209
210         /* now do the sky sub-pixels */
211         amount= R.osa-amount;
212         if(amount) {
213                 if(shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec)) {
214                         if(!fullsample) {
215                                 fac= ((float)amount)/(float)R.osa;
216                                 accol[0]+= fac*col[0];
217                                 accol[1]+= fac*col[1];
218                                 accol[2]+= fac*col[2];
219                                 accol[3]+= fac*col[3];
220                         }
221                 }
222         }
223
224         if(fullsample) {
225                 for(sample=0; sample<totsample; sample++)
226                         if(!(mask & (1 << sample)))
227                                 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
228         }
229         else {
230                 col[0]= accol[0];
231                 col[1]= accol[1];
232                 col[2]= accol[2];
233                 col[3]= accol[3];
234                 
235                 for(sample=0; sample<totsample; sample++)
236                         addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
237         }
238 }
239
240 static void halo_tile(RenderPart *pa, RenderLayer *rl)
241 {
242         RenderLayer *rlpp[RE_MAX_OSA];
243         HaloRen *har;
244         rcti disprect= pa->disprect, testrect= pa->disprect;
245         float dist, xsq, ysq, xn, yn;
246         float col[4];
247         intptr_t *rd= NULL;
248         int a, *rz, zz, y, sample, totsample, od;
249         short minx, maxx, miny, maxy, x;
250         unsigned int lay= rl->lay;
251
252         /* we don't render halos in the cropped area, gives errors in flare counter */
253         if(pa->crop) {
254                 testrect.xmin+= pa->crop;
255                 testrect.xmax-= pa->crop;
256                 testrect.ymin+= pa->crop;
257                 testrect.ymax-= pa->crop;
258         }
259         
260         totsample= get_sample_layers(pa, rl, rlpp);
261
262         for(a=0; a<R.tothalo; a++) {
263                 har= R.sortedhalos[a];
264
265                 /* layer test, clip halo with y */
266                 if((har->lay & lay)==0);
267                 else if(testrect.ymin > har->maxy);
268                 else if(testrect.ymax < har->miny);
269                 else {
270                         
271                         minx= floor(har->xs-har->rad);
272                         maxx= ceil(har->xs+har->rad);
273                         
274                         if(testrect.xmin > maxx);
275                         else if(testrect.xmax < minx);
276                         else {
277                                 
278                                 minx= MAX2(minx, testrect.xmin);
279                                 maxx= MIN2(maxx, testrect.xmax);
280                         
281                                 miny= MAX2(har->miny, testrect.ymin);
282                                 maxy= MIN2(har->maxy, testrect.ymax);
283                         
284                                 for(y=miny; y<maxy; y++) {
285                                         int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
286                                         rz= pa->rectz + rectofs;
287                                         od= rectofs;
288                                         
289                                         if(pa->rectdaps)
290                                                 rd= pa->rectdaps + rectofs;
291                                         
292                                         yn= (y-har->ys)*R.ycor;
293                                         ysq= yn*yn;
294                                         
295                                         for(x=minx; x<maxx; x++, rz++, od++) {
296                                                 xn= x- har->xs;
297                                                 xsq= xn*xn;
298                                                 dist= xsq+ysq;
299                                                 if(dist<har->radsq) {
300                                                         if(rd && *rd) {
301                                                                 halo_pixelstruct(har, rlpp, totsample, od, dist, xn, yn, (PixStr *)*rd);
302                                                         }
303                                                         else {
304                                                                 zz= calchalo_z(har, *rz);
305                                                                 if((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
306                                                                         if(shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) {
307                                                                                 for(sample=0; sample<totsample; sample++)
308                                                                                         addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
309                                                                         }
310                                                                 }
311                                                         }
312                                                 }
313                                                 if(rd) rd++;
314                                         }
315                                 }
316                         }
317                 }
318                 if(R.test_break(R.tbh) ) break; 
319         }
320 }
321
322 static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
323 {
324         RenderLayer *rlpp[RE_MAX_OSA];
325         ShadeInput shi;
326         float *pass;
327         float fac, col[4];
328         intptr_t *rd= pa->rectdaps;
329         int *rz= pa->rectz;
330         int x, y, sample, totsample, fullsample, od;
331         
332         totsample= get_sample_layers(pa, rl, rlpp);
333         fullsample= (totsample > 1);
334
335         shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */
336         
337         for(od=0, y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
338                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, od++) {
339                         
340                         calc_view_vector(shi.view, x, y);
341                         
342                         if(rd && *rd) {
343                                 PixStr *ps= (PixStr *)*rd;
344                                 int count, totsamp= 0, mask= 0;
345                                 
346                                 while(ps) {
347                                         if(R.r.mode & R_ORTHO)
348                                                 calc_renderco_ortho(shi.co, (float)x, (float)y, ps->z);
349                                         else
350                                                 calc_renderco_zbuf(shi.co, shi.view, ps->z);
351                                         
352                                         totsamp+= count= count_mask(ps->mask);
353                                         mask |= ps->mask;
354
355                                         col[0]= col[1]= col[2]= col[3]= 0.0f;
356                                         renderspothalo(&shi, col, 1.0f);
357
358                                         if(fullsample) {
359                                                 for(sample=0; sample<totsample; sample++) {
360                                                         if(ps->mask & (1 << sample)) {
361                                                                 pass= rlpp[sample]->rectf + od*4;
362                                                                 pass[0]+= col[0];
363                                                                 pass[1]+= col[1];
364                                                                 pass[2]+= col[2];
365                                                                 pass[3]+= col[3];
366                                                                 if(pass[3]>1.0f) pass[3]= 1.0f;
367                                                         }
368                                                 }
369                                         }
370                                         else {
371                                                 fac= ((float)count)/(float)R.osa;
372                                                 pass= rl->rectf + od*4;
373                                                 pass[0]+= fac*col[0];
374                                                 pass[1]+= fac*col[1];
375                                                 pass[2]+= fac*col[2];
376                                                 pass[3]+= fac*col[3];
377                                                 if(pass[3]>1.0f) pass[3]= 1.0f;
378                                         }
379
380                                         ps= ps->next;
381                                 }
382
383                                 if(totsamp<R.osa) {
384                                         shi.co[2]= 0.0f;
385
386                                         col[0]= col[1]= col[2]= col[3]= 0.0f;
387                                         renderspothalo(&shi, col, 1.0f);
388
389                                         if(fullsample) {
390                                                 for(sample=0; sample<totsample; sample++) {
391                                                         if(!(mask & (1 << sample))) {
392                                                                 pass= rlpp[sample]->rectf + od*4;
393                                                                 pass[0]+= col[0];
394                                                                 pass[1]+= col[1];
395                                                                 pass[2]+= col[2];
396                                                                 pass[3]+= col[3];
397                                                                 if(pass[3]>1.0f) pass[3]= 1.0f;
398                                                         }
399                                                 }
400                                         }
401                                         else {
402                                                 fac= ((float)R.osa-totsamp)/(float)R.osa;
403                                                 pass= rl->rectf + od*4;
404                                                 pass[0]+= fac*col[0];
405                                                 pass[1]+= fac*col[1];
406                                                 pass[2]+= fac*col[2];
407                                                 pass[3]+= fac*col[3];
408                                                 if(pass[3]>1.0f) pass[3]= 1.0f;
409                                         }
410                                 }
411                         }
412                         else {
413                                 if(R.r.mode & R_ORTHO)
414                                         calc_renderco_ortho(shi.co, (float)x, (float)y, *rz);
415                                 else
416                                         calc_renderco_zbuf(shi.co, shi.view, *rz);
417                                 
418                                 col[0]= col[1]= col[2]= col[3]= 0.0f;
419                                 renderspothalo(&shi, col, 1.0f);
420
421                                 for(sample=0; sample<totsample; sample++) {
422                                         pass= rlpp[sample]->rectf + od*4;
423                                         pass[0]+= col[0];
424                                         pass[1]+= col[1];
425                                         pass[2]+= col[2];
426                                         pass[3]+= col[3];
427                                         if(pass[3]>1.0f) pass[3]= 1.0f;
428                                 }
429                         }
430                         
431                         if(rd) rd++;
432                 }
433                 if(y&1)
434                         if(R.test_break(R.tbh)) break; 
435         }
436 }                               
437
438
439 /* ********************* MAINLOOPS ******************** */
440
441 /* osa version */
442 static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr)
443 {
444         RenderPass *rpass;
445
446         /* combined rgb */
447         add_filt_fmask(curmask, shr->combined, rl->rectf + 4*offset, rectx);
448         
449         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
450                 float *fp, *col= NULL;
451                 int pixsize= 3;
452                 
453                 switch(rpass->passtype) {
454                         case SCE_PASS_Z:
455                                 fp= rpass->rect + offset;
456                                 *fp= shr->z;
457                                 break;
458                         case SCE_PASS_RGBA:
459                                 col= shr->col;
460                                 pixsize= 4;
461                                 break;
462                         case SCE_PASS_EMIT:
463                                 col= shr->emit;
464                                 break;
465                         case SCE_PASS_DIFFUSE:
466                                 col= shr->diff;
467                                 break;
468                         case SCE_PASS_SPEC:
469                                 col= shr->spec;
470                                 break;
471                         case SCE_PASS_SHADOW:
472                                 col= shr->shad;
473                                 break;
474                         case SCE_PASS_AO:
475                                 col= shr->ao;
476                                 break;
477                         case SCE_PASS_ENVIRONMENT:
478                                 col= shr->env;
479                                 break;
480                         case SCE_PASS_INDIRECT:
481                                 col= shr->indirect;
482                                 break;
483                         case SCE_PASS_REFLECT:
484                                 col= shr->refl;
485                                 break;
486                         case SCE_PASS_REFRACT:
487                                 col= shr->refr;
488                                 break;
489                         case SCE_PASS_NORMAL:
490                                 col= shr->nor;
491                                 break;
492                         case SCE_PASS_UV:
493                                 /* box filter only, gauss will screwup UV too much */
494                                 if(shi->totuv) {
495                                         float mult= (float)count_mask(curmask)/(float)R.osa;
496                                         fp= rpass->rect + 3*offset;
497                                         fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
498                                         fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
499                                         fp[2]+= mult;
500                                 }
501                                 break;
502                         case SCE_PASS_INDEXOB:
503                                 /* no filter */
504                                 if(shi->vlr) {
505                                         fp= rpass->rect + offset;
506                                         if(*fp==0.0f)
507                                                 *fp= (float)shi->obr->ob->index;
508                                 }
509                                 break;
510                         case SCE_PASS_MIST:
511                                 /*  */
512                                 col= &shr->mist;
513                                 pixsize= 1;
514                                 break;
515                         
516                         case SCE_PASS_VECTOR:
517                         {
518                                 /* add minimum speed in pixel, no filter */
519                                 fp= rpass->rect + 4*offset;
520                                 if( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
521                                         fp[0]= shr->winspeed[0];
522                                         fp[1]= shr->winspeed[1];
523                                 }
524                                 if( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
525                                         fp[2]= shr->winspeed[2];
526                                         fp[3]= shr->winspeed[3];
527                                 }
528                         }
529                                 break;
530
531                         case SCE_PASS_RAYHITS:
532                                 /*  */
533                                 col= shr->rayhits;
534                                 pixsize= 4;
535                                 break;
536                 }
537                 if(col) {
538                         fp= rpass->rect + pixsize*offset;
539                         add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
540                 }
541         }
542 }
543
544 /* non-osa version */
545 static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr)
546 {
547         RenderPass *rpass;
548         float *fp;
549         
550         fp= rl->rectf + 4*offset;
551         QUATCOPY(fp, shr->combined);
552         
553         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
554                 float *col= NULL, uvcol[3];
555                 int a, pixsize= 3;
556                 
557                 switch(rpass->passtype) {
558                         case SCE_PASS_Z:
559                                 fp= rpass->rect + offset;
560                                 *fp= shr->z;
561                                 break;
562                         case SCE_PASS_RGBA:
563                                 col= shr->col;
564                                 pixsize= 4;
565                                 break;
566                         case SCE_PASS_EMIT:
567                                 col= shr->emit;
568                                 break;
569                         case SCE_PASS_DIFFUSE:
570                                 col= shr->diff;
571                                 break;
572                         case SCE_PASS_SPEC:
573                                 col= shr->spec;
574                                 break;
575                         case SCE_PASS_SHADOW:
576                                 col= shr->shad;
577                                 break;
578                         case SCE_PASS_AO:
579                                 col= shr->ao;
580                                 break;
581                         case SCE_PASS_ENVIRONMENT:
582                                 col= shr->env;
583                                 break;
584                         case SCE_PASS_INDIRECT:
585                                 col= shr->indirect;
586                                 break;
587                         case SCE_PASS_REFLECT:
588                                 col= shr->refl;
589                                 break;
590                         case SCE_PASS_REFRACT:
591                                 col= shr->refr;
592                                 break;
593                         case SCE_PASS_NORMAL:
594                                 col= shr->nor;
595                                 break;
596                         case SCE_PASS_UV:
597                                 if(shi->totuv) {
598                                         uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
599                                         uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
600                                         uvcol[2]= 1.0f;
601                                         col= uvcol;
602                                 }
603                                 break;
604                         case SCE_PASS_VECTOR:
605                                 col= shr->winspeed;
606                                 pixsize= 4;
607                                 break;
608                         case SCE_PASS_INDEXOB:
609                                 if(shi->vlr) {
610                                         fp= rpass->rect + offset;
611                                         *fp= (float)shi->obr->ob->index;
612                                 }
613                                 break;
614                         case SCE_PASS_MIST:
615                                 fp= rpass->rect + offset;
616                                 *fp= shr->mist;
617                                 break;
618                         case SCE_PASS_RAYHITS:
619                                 col= shr->rayhits;
620                                 pixsize= 4;
621                                 break;
622                 }
623                 if(col) {
624                         fp= rpass->rect + pixsize*offset;
625                         for(a=0; a<pixsize; a++)
626                                 fp[a]= col[a];
627                 }
628         }
629 }
630
631 int get_sample_layers(RenderPart *pa, RenderLayer *rl, RenderLayer **rlpp)
632 {
633         
634         if(pa->fullresult.first) {
635                 int sample, nr= BLI_findindex(&pa->result->layers, rl);
636                 
637                 for(sample=0; sample<R.osa; sample++) {
638                         RenderResult *rr= BLI_findlink(&pa->fullresult, sample);
639                 
640                         rlpp[sample]= BLI_findlink(&rr->layers, nr);
641                 }               
642                 return R.osa;
643         }
644         else {
645                 rlpp[0]= rl;
646                 return 1;
647         }
648 }
649
650
651 /* only do sky, is default in the solid layer (shade_tile) btw */
652 static void sky_tile(RenderPart *pa, RenderLayer *rl)
653 {
654         RenderLayer *rlpp[RE_MAX_OSA];
655         int x, y, od=0, totsample;
656         
657         if(R.r.alphamode!=R_ADDSKY)
658                 return;
659         
660         totsample= get_sample_layers(pa, rl, rlpp);
661         
662         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
663                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) {
664                         float col[4];
665                         int sample, done= 0;
666                         
667                         for(sample= 0; sample<totsample; sample++) {
668                                 float *pass= rlpp[sample]->rectf + od;
669                                 
670                                 if(pass[3]<1.0f) {
671                                         
672                                         if(done==0) {
673                                                 shadeSkyPixel(col, x, y, pa->thread);
674                                                 done= 1;
675                                         }
676                                         
677                                         if(pass[3]==0.0f) {
678                                                 QUATCOPY(pass, col);
679                                         }
680                                         else {
681                                                 addAlphaUnderFloat(pass, col);
682                                         }
683                                 }
684                         }                       
685                 }
686                 
687                 if(y&1)
688                         if(R.test_break(R.tbh)) break; 
689         }
690 }
691
692 static void atm_tile(RenderPart *pa, RenderLayer *rl)
693 {
694         RenderPass *zpass;
695         GroupObject *go;
696         LampRen *lar;
697         RenderLayer *rlpp[RE_MAX_OSA];
698         int totsample;
699         int x, y, od= 0;
700         
701         totsample= get_sample_layers(pa, rl, rlpp);
702
703         /* check that z pass is enabled */
704         if(pa->rectz==NULL) return;
705         for(zpass= rl->passes.first; zpass; zpass= zpass->next)
706                 if(zpass->passtype==SCE_PASS_Z)
707                         break;
708         
709         if(zpass==NULL) return;
710
711         /* check for at least one sun lamp that its atmosphere flag is is enabled */
712         for(go=R.lights.first; go; go= go->next) {
713                 lar= go->lampren;
714                 if(lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_AP))
715                         break;
716         }
717         /* do nothign and return if there is no sun lamp */
718         if(go==NULL)
719                 return;
720         
721         /* for each x,y and each sample, and each sun lamp*/
722         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
723                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od++) {
724                         int sample;
725                         
726                         for(sample=0; sample<totsample; sample++) {
727                                 float *zrect= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_Z) + od;
728                                 float *rgbrect = rlpp[sample]->rectf + 4*od;
729                                 float rgb[3] = {0};
730                                 int done= 0;
731                                 
732                                 for(go=R.lights.first; go; go= go->next) {
733                                 
734                                         
735                                         lar= go->lampren;
736                                         if(lar->type==LA_SUN && lar->sunsky) {
737                                                 
738                                                 /* if it's sky continue and don't apply atmosphere effect on it */
739                                                 if(*zrect >= 9.9e10 || rgbrect[3]==0.0f) {
740                                                         continue;
741                                                 }
742                                                                                                 
743                                                 if((lar->sunsky->effect_type & LA_SUN_EFFECT_AP)) {     
744                                                         float tmp_rgb[3];
745                                                         
746                                                         /* skip if worldspace lamp vector is below horizon */
747                                                         if(go->ob->obmat[2][2] < 0.f) {
748                                                                 continue;
749                                                         }
750                                                         
751                                                         VECCOPY(tmp_rgb, rgbrect);
752                                                         if(rgbrect[3]!=1.0f) {  /* de-premul */
753                                                                 float div= 1.0f/rgbrect[3];
754                                                                 VECMUL(tmp_rgb, div);
755                                                         }
756                                                         shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
757                                                         if(rgbrect[3]!=1.0f) {  /* premul */
758                                                                 VECMUL(tmp_rgb, rgbrect[3]);
759                                                         }
760                                                         
761                                                         if(done==0) {
762                                                                 VECCOPY(rgb, tmp_rgb);
763                                                                 done = 1;                                               
764                                                         }
765                                                         else{
766                                                                 rgb[0] = 0.5f*rgb[0] + 0.5f*tmp_rgb[0];
767                                                                 rgb[1] = 0.5f*rgb[1] + 0.5f*tmp_rgb[1];
768                                                                 rgb[2] = 0.5f*rgb[2] + 0.5f*tmp_rgb[2];
769                                                         }
770                                                 }
771                                         }
772                                 }
773
774                                 /* if at least for one sun lamp aerial perspective was applied*/
775                                 if(done) {
776                                         VECCOPY(rgbrect, rgb);
777                                 }
778                         }
779                 }
780         }
781 }
782
783 static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
784 {
785         RenderResult *rr= pa->result;
786         ShadeSample ssamp;
787         intptr_t *rd, *rectdaps= pa->rectdaps;
788         int samp;
789         int x, y, seed, crop=0, offs=0, od;
790         
791         if(R.test_break(R.tbh)) return; 
792         
793         /* irregular shadowb buffer creation */
794         if(R.r.mode & R_SHADOW)
795                 ISB_create(pa, NULL);
796         
797         /* we set per pixel a fixed seed, for random AO and shadow samples */
798         seed= pa->rectx*pa->disprect.ymin;
799         
800         /* general shader info, passes */
801         shade_sample_initialize(&ssamp, pa, rl);
802
803         /* occlusion caching */
804         if(R.occlusiontree)
805                 cache_occ_samples(&R, pa, &ssamp);
806                 
807         /* filtered render, for now we assume only 1 filter size */
808         if(pa->crop) {
809                 crop= 1;
810                 rectdaps+= pa->rectx + 1;
811                 offs= pa->rectx + 1;
812         }
813         
814         /* scanline updates have to be 2 lines behind */
815         rr->renrect.ymin= 0;
816         rr->renrect.ymax= -2*crop;
817         rr->renlay= rl;
818                                 
819         for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
820                 rd= rectdaps;
821                 od= offs;
822                 
823                 for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, od++) {
824                         BLI_thread_srandom(pa->thread, seed++);
825                         
826                         if(*rd) {
827                                 if(shade_samples(&ssamp, (PixStr *)(*rd), x, y)) {
828                                         
829                                         /* multisample buffers or filtered mask filling? */
830                                         if(pa->fullresult.first) {
831                                                 int a;
832                                                 for(samp=0; samp<ssamp.tot; samp++) {
833                                                         int smask= ssamp.shi[samp].mask;
834                                                         for(a=0; a<R.osa; a++) {
835                                                                 int mask= 1<<a;
836                                                                 if(smask & mask)
837                                                                         add_passes(ssamp.rlpp[a], od, &ssamp.shi[samp], &ssamp.shr[samp]);
838                                                         }
839                                                 }
840                                         }
841                                         else {
842                                                 for(samp=0; samp<ssamp.tot; samp++)
843                                                         add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]);
844                                         }
845                                 }
846                         }
847                 }
848                 
849                 rectdaps+= pa->rectx;
850                 offs+= pa->rectx;
851                 
852                 if(y&1) if(R.test_break(R.tbh)) break; 
853         }
854         
855         /* disable scanline updating */
856         rr->renlay= NULL;
857         
858         if(R.r.mode & R_SHADOW)
859                 ISB_free(pa);
860
861         if(R.occlusiontree)
862                 free_occ_samples(&R, pa);
863 }
864
865 /* ************* pixel struct ******** */
866
867
868 static PixStrMain *addpsmain(ListBase *lb)
869 {
870         PixStrMain *psm;
871         
872         psm= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain),"pixstrMain");
873         BLI_addtail(lb, psm);
874         
875         psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr),"pixstr");
876         psm->counter= 0;
877         
878         return psm;
879 }
880
881 static void freeps(ListBase *lb)
882 {
883         PixStrMain *psm, *psmnext;
884         
885         for(psm= lb->first; psm; psm= psmnext) {
886                 psmnext= psm->next;
887                 if(psm->ps)
888                         MEM_freeN(psm->ps);
889                 MEM_freeN(psm);
890         }
891         lb->first= lb->last= NULL;
892 }
893
894 static void addps(ListBase *lb, intptr_t *rd, int obi, int facenr, int z, int maskz, unsigned short mask)
895 {
896         PixStrMain *psm;
897         PixStr *ps, *last= NULL;
898         
899         if(*rd) {       
900                 ps= (PixStr *)(*rd);
901                 
902                 while(ps) {
903                         if( ps->obi == obi && ps->facenr == facenr ) {
904                                 ps->mask |= mask;
905                                 return;
906                         }
907                         last= ps;
908                         ps= ps->next;
909                 }
910         }
911         
912         /* make new PS (pixel struct) */
913         psm= lb->last;
914         
915         if(psm->counter==4095)
916                 psm= addpsmain(lb);
917         
918         ps= psm->ps + psm->counter++;
919         
920         if(last) last->next= ps;
921         else *rd= (intptr_t)ps;
922         
923         ps->next= NULL;
924         ps->obi= obi;
925         ps->facenr= facenr;
926         ps->z= z;
927         ps->maskz= maskz;
928         ps->mask = mask;
929         ps->shadfac= 0;
930 }
931
932 static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
933 {
934         float addcol[4];
935         int pix;
936         
937         if(arect==NULL)
938                 return;
939         
940         for(pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
941                 if(*arect != 0.0f) {
942                         addcol[0]= *arect * R.r.edgeR;
943                         addcol[1]= *arect * R.r.edgeG;
944                         addcol[2]= *arect * R.r.edgeB;
945                         addcol[3]= *arect;
946                         addAlphaOverFloat(rectf, addcol);
947                 }
948         }
949 }
950
951 static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl)
952 {
953         RenderLayer *rlpp[RE_MAX_OSA];
954         int y, sample, totsample;
955         
956         totsample= get_sample_layers(pa, rl, rlpp);
957         
958         for(sample= 0; sample<totsample; sample++) {
959                 float *rectf= rlpp[sample]->rectf;
960                 
961                 for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
962                         if(rectf[3] >= 1.0f);
963                         else if(rectf[3] > 0.0f) {
964                                 rectf[0] /= rectf[3];
965                                 rectf[1] /= rectf[3];
966                                 rectf[2] /= rectf[3];
967                         }
968                 }
969         }
970 }
971
972 /* adds only alpha values */
973 void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz)
974 {
975         /* use zbuffer to define edges, add it to the image */
976         int y, x, col, *rz, *rz1, *rz2, *rz3;
977         int zval1, zval2, zval3;
978         float *rf;
979         
980         /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */
981         rz= rectz;
982         if(rz==NULL) return;
983         
984         for(y=0; y<pa->recty; y++)
985                 for(x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
986         
987         rz1= rectz;
988         rz2= rz1+pa->rectx;
989         rz3= rz2+pa->rectx;
990         
991         rf= rectf+pa->rectx+1;
992         
993         for(y=0; y<pa->recty-2; y++) {
994                 for(x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
995                         
996                         /* prevent overflow with sky z values */
997                         zval1=   rz1[0] + 2*rz1[1] +   rz1[2];
998                         zval2=  2*rz2[0]           + 2*rz2[2];
999                         zval3=   rz3[0] + 2*rz3[1] +   rz3[2];
1000                         
1001                         col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 );
1002                         if(col<0) col= -col;
1003                         
1004                         col >>= 5;
1005                         if(col > (1<<16)) col= (1<<16);
1006                         else col= (R.r.edgeint*col)>>8;
1007                         
1008                         if(col>0) {
1009                                 float fcol;
1010                                 
1011                                 if(col>255) fcol= 1.0f;
1012                                 else fcol= (float)col/255.0f;
1013                                 
1014                                 if(R.osa)
1015                                         *rf+= fcol/(float)R.osa;
1016                                 else
1017                                         *rf= fcol;
1018                         }
1019                 }
1020                 rz1+= 2;
1021                 rz2+= 2;
1022                 rz3+= 2;
1023                 rf+= 2;
1024         }
1025         
1026         /* shift back zbuf values, we might need it still */
1027         rz= rectz;
1028         for(y=0; y<pa->recty; y++)
1029                 for(x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4;
1030         
1031 }
1032
1033 static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
1034 {
1035         /* for all pixels with max speed, set to zero */
1036         RenderLayer *rlpp[RE_MAX_OSA];
1037         float *fp;
1038         int a, sample, totsample;
1039         
1040         totsample= get_sample_layers(pa, rl, rlpp);
1041
1042         for(sample= 0; sample<totsample; sample++) {
1043                 fp= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_VECTOR);
1044                 if(fp==NULL) break;
1045
1046                 for(a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
1047                         if(fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f;
1048         }
1049 }
1050
1051 static unsigned short *make_solid_mask(RenderPart *pa)
1052
1053          intptr_t *rd= pa->rectdaps;
1054          unsigned short *solidmask, *sp;
1055          int x;
1056         
1057         if(rd==NULL) return NULL;
1058         
1059         sp=solidmask= MEM_mallocN(sizeof(short)*pa->rectx*pa->recty, "solidmask");
1060         
1061         for(x=pa->rectx*pa->recty; x>0; x--, rd++, sp++) {
1062                 if(*rd) {
1063                         PixStr *ps= (PixStr *)*rd;
1064                         
1065                         *sp= ps->mask;
1066                         for(ps= ps->next; ps; ps= ps->next)
1067                                 *sp |= ps->mask;
1068                 }
1069                 else
1070                         *sp= 0;
1071         }
1072                         
1073         return solidmask;
1074 }
1075
1076 static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask)
1077 {
1078         unsigned short shared= dmask & smask;
1079         float mul= 1.0 - source[3];
1080         
1081         if(shared) {    /* overlapping masks */
1082                 
1083                 /* masks differ, we make a mixture of 'add' and 'over' */
1084                 if(shared!=dmask) {
1085                         float shared_bits= (float)count_mask(shared);           /* alpha over */
1086                         float tot_bits= (float)count_mask(smask|dmask);         /* alpha add */
1087                         
1088                         float add= (tot_bits - shared_bits)/tot_bits;           /* add level */
1089                         mul= add + (1.0f-add)*mul;
1090                 }
1091         }
1092         else if(dmask && smask) {
1093                 /* works for premul only, of course */
1094                 dest[0]+= source[0];
1095                 dest[1]+= source[1];
1096                 dest[2]+= source[2];
1097                 dest[3]+= source[3];
1098                 
1099                 return;
1100          }
1101
1102         dest[0]= (mul*dest[0]) + source[0];
1103         dest[1]= (mul*dest[1]) + source[1];
1104         dest[2]= (mul*dest[2]) + source[2];
1105         dest[3]= (mul*dest[3]) + source[3];
1106 }
1107
1108 typedef struct ZbufSolidData {
1109         RenderLayer *rl;
1110         ListBase *psmlist;
1111         float *edgerect;
1112 } ZbufSolidData;
1113
1114 void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
1115 {
1116         ZbufSolidData *sdata= (ZbufSolidData*)data;
1117         ListBase *lb= sdata->psmlist;
1118         intptr_t *rd= pa->rectdaps;
1119         int *ro= zspan->recto;
1120         int *rp= zspan->rectp;
1121         int *rz= zspan->rectz;
1122         int *rm= zspan->rectmask;
1123         int x, y;
1124         int mask= 1<<sample;
1125
1126         for(y=0; y<pa->recty; y++) {
1127                 for(x=0; x<pa->rectx; x++, rd++, rp++, ro++, rz++, rm++) {
1128                         if(*rp) {
1129                                 addps(lb, rd, *ro, *rp, *rz, (zspan->rectmask)? *rm: 0, mask);
1130                         }
1131                 }
1132         }
1133
1134         if(sdata->rl->layflag & SCE_LAY_EDGE) 
1135                 if(R.r.mode & R_EDGE) 
1136                         edge_enhance_tile(pa, sdata->edgerect, zspan->rectz);
1137 }
1138
1139 /* main call for shading Delta Accum, for OSA */
1140 /* supposed to be fully threadable! */
1141 void zbufshadeDA_tile(RenderPart *pa)
1142 {
1143         RenderResult *rr= pa->result;
1144         RenderLayer *rl;
1145         ListBase psmlist= {NULL, NULL};
1146         float *edgerect= NULL;
1147         
1148         /* allocate the necessary buffers */
1149                                 /* zbuffer inits these rects */
1150         pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1151         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1152         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1153         for(rl= rr->layers.first; rl; rl= rl->next) {
1154                 if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
1155                         pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
1156         
1157                 /* initialize pixelstructs and edge buffer */
1158                 addpsmain(&psmlist);
1159                 pa->rectdaps= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "zbufDArectd");
1160                 
1161                 if(rl->layflag & SCE_LAY_EDGE) 
1162                         if(R.r.mode & R_EDGE) 
1163                                 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
1164                 
1165                 /* always fill visibility */
1166                 for(pa->sample=0; pa->sample<R.osa; pa->sample+=4) {
1167                         ZbufSolidData sdata;
1168
1169                         sdata.rl= rl;
1170                         sdata.psmlist= &psmlist;
1171                         sdata.edgerect= edgerect;
1172                         zbuffer_solid(pa, rl, make_pixelstructs, &sdata);
1173                         if(R.test_break(R.tbh)) break; 
1174                 }
1175                 
1176                 /* shades solid */
1177                 if(rl->layflag & SCE_LAY_SOLID) 
1178                         shadeDA_tile(pa, rl);
1179                 
1180                 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1181                 if(R.flag & R_LAMPHALO)
1182                         if(rl->layflag & SCE_LAY_HALO)
1183                                 lamphalo_tile(pa, rl);
1184                 
1185                 /* halo before ztra, because ztra fills in zbuffer now */
1186                 if(R.flag & R_HALO)
1187                         if(rl->layflag & SCE_LAY_HALO)
1188                                 halo_tile(pa, rl);
1189
1190                 /* transp layer */
1191                 if(R.flag & R_ZTRA || R.totstrand) {
1192                         if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
1193                                 if(pa->fullresult.first) {
1194                                         zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
1195                                 }
1196                                 else {
1197                                         unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
1198                                         
1199                                         /* allocate, but not free here, for asynchronous display of this rect in main thread */
1200                                         rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1201                                         
1202                                         /* swap for live updates, and it is used in zbuf.c!!! */
1203                                         SWAP(float *, rl->acolrect, rl->rectf);
1204                                         ztramask= zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
1205                                         SWAP(float *, rl->acolrect, rl->rectf);
1206                                         
1207                                         /* zbuffer transp only returns ztramask if there's solid rendered */
1208                                         if(ztramask)
1209                                                 solidmask= make_solid_mask(pa);
1210
1211                                         if(ztramask && solidmask) {
1212                                                 unsigned short *sps= solidmask, *spz= ztramask;
1213                                                 unsigned short fullmask= (1<<R.osa)-1;
1214                                                 float *fcol= rl->rectf; float *acol= rl->acolrect;
1215                                                 int x;
1216                                                 
1217                                                 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
1218                                                         if(*sps == fullmask)
1219                                                                 addAlphaOverFloat(fcol, acol);
1220                                                         else
1221                                                                 addAlphaOverFloatMask(fcol, acol, *sps, *spz);
1222                                                 }
1223                                         }
1224                                         else {
1225                                                 float *fcol= rl->rectf; float *acol= rl->acolrect;
1226                                                 int x;
1227                                                 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1228                                                         addAlphaOverFloat(fcol, acol);
1229                                                 }
1230                                         }
1231                                         if(solidmask) MEM_freeN(solidmask);
1232                                         if(ztramask) MEM_freeN(ztramask);
1233                                 }
1234                         }
1235                 }
1236
1237                 /* sun/sky */
1238                 if(rl->layflag & SCE_LAY_SKY)
1239                         atm_tile(pa, rl);
1240                 
1241                 /* sky before edge */
1242                 if(rl->layflag & SCE_LAY_SKY)
1243                         sky_tile(pa, rl);
1244
1245                 /* extra layers */
1246                 if(rl->layflag & SCE_LAY_EDGE) 
1247                         if(R.r.mode & R_EDGE) 
1248                                 edge_enhance_add(pa, rl->rectf, edgerect);
1249                 
1250                 if(rl->passflag & SCE_PASS_VECTOR)
1251                         reset_sky_speed(pa, rl);
1252                 
1253                 /* de-premul alpha */
1254                 if(R.r.alphamode & R_ALPHAKEY)
1255                         convert_to_key_alpha(pa, rl);
1256                 
1257                 /* free stuff within loop! */
1258                 MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
1259                 freeps(&psmlist);
1260                 
1261                 if(edgerect) MEM_freeN(edgerect);
1262                 edgerect= NULL;
1263
1264                 if(pa->rectmask) {
1265                         MEM_freeN(pa->rectmask);
1266                         pa->rectmask= NULL;
1267                 }
1268         }
1269         
1270         /* free all */
1271         MEM_freeN(pa->recto); pa->recto= NULL;
1272         MEM_freeN(pa->rectp); pa->rectp= NULL;
1273         MEM_freeN(pa->rectz); pa->rectz= NULL;
1274         
1275         /* display active layer */
1276         rr->renrect.ymin=rr->renrect.ymax= 0;
1277         rr->renlay= render_get_active_layer(&R, rr);
1278 }
1279
1280
1281 /* ------------------------------------------------------------------------ */
1282
1283 /* non OSA case, full tile render */
1284 /* supposed to be fully threadable! */
1285 void zbufshade_tile(RenderPart *pa)
1286 {
1287         ShadeSample ssamp;
1288         RenderResult *rr= pa->result;
1289         RenderLayer *rl;
1290         PixStr ps;
1291         float *edgerect= NULL;
1292         
1293         /* fake pixel struct, to comply to osa render */
1294         ps.next= NULL;
1295         ps.mask= 0xFFFF;
1296         
1297         /* zbuffer code clears/inits rects */
1298         pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1299         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1300         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1301
1302         for(rl= rr->layers.first; rl; rl= rl->next) {
1303                 if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
1304                         pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
1305
1306                 /* general shader info, passes */
1307                 shade_sample_initialize(&ssamp, pa, rl);
1308                 
1309                 zbuffer_solid(pa, rl, NULL, NULL);
1310                 
1311                 if(!R.test_break(R.tbh)) {      /* NOTE: this if() is not consistent */
1312                         
1313                         /* edges only for solid part, ztransp doesn't support it yet anti-aliased */
1314                         if(rl->layflag & SCE_LAY_EDGE) {
1315                                 if(R.r.mode & R_EDGE) {
1316                                         edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
1317                                         edge_enhance_tile(pa, edgerect, pa->rectz);
1318                                 }
1319                         }
1320                         
1321                         /* initialize scanline updates for main thread */
1322                         rr->renrect.ymin= 0;
1323                         rr->renlay= rl;
1324                         
1325                         if(rl->layflag & SCE_LAY_SOLID) {
1326                                 float *fcol= rl->rectf;
1327                                 int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
1328                                 int x, y, offs=0, seed;
1329                                 
1330                                 /* we set per pixel a fixed seed, for random AO and shadow samples */
1331                                 seed= pa->rectx*pa->disprect.ymin;
1332                                 
1333                                 /* irregular shadowb buffer creation */
1334                                 if(R.r.mode & R_SHADOW)
1335                                         ISB_create(pa, NULL);
1336
1337                                 if(R.occlusiontree)
1338                                         cache_occ_samples(&R, pa, &ssamp);
1339                                 
1340                                 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1341                                         for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) {
1342                                                 /* per pixel fixed seed */
1343                                                 BLI_thread_srandom(pa->thread, seed++);
1344                                                 
1345                                                 if(*rp) {
1346                                                         ps.obi= *ro;
1347                                                         ps.facenr= *rp;
1348                                                         ps.z= *rz;
1349                                                         if(shade_samples(&ssamp, &ps, x, y)) {
1350                                                                 /* combined and passes */
1351                                                                 add_passes(rl, offs, ssamp.shi, ssamp.shr);
1352                                                         }
1353                                                 }
1354                                         }
1355                                         if(y&1)
1356                                                 if(R.test_break(R.tbh)) break; 
1357                                 }
1358                                 
1359                                 if(R.occlusiontree)
1360                                         free_occ_samples(&R, pa);
1361                                 
1362                                 if(R.r.mode & R_SHADOW)
1363                                         ISB_free(pa);
1364                         }
1365                         
1366                         /* disable scanline updating */
1367                         rr->renlay= NULL;
1368                 }
1369                 
1370                 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1371                 if(R.flag & R_LAMPHALO)
1372                         if(rl->layflag & SCE_LAY_HALO)
1373                                 lamphalo_tile(pa, rl);
1374                 
1375                 /* halo before ztra, because ztra fills in zbuffer now */
1376                 if(R.flag & R_HALO)
1377                         if(rl->layflag & SCE_LAY_HALO)
1378                                 halo_tile(pa, rl);
1379                 
1380                 if(R.flag & R_ZTRA || R.totstrand) {
1381                         if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
1382                                 float *fcol, *acol;
1383                                 int x;
1384                                 
1385                                 /* allocate, but not free here, for asynchronous display of this rect in main thread */
1386                                 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1387                                 
1388                                 /* swap for live updates */
1389                                 SWAP(float *, rl->acolrect, rl->rectf);
1390                                 zbuffer_transp_shade(pa, rl, rl->rectf, NULL);
1391                                 SWAP(float *, rl->acolrect, rl->rectf);
1392                                 
1393                                 fcol= rl->rectf; acol= rl->acolrect;
1394                                 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1395                                         addAlphaOverFloat(fcol, acol);
1396                                 }
1397                         }
1398                 }
1399                 
1400                 /* sun/sky */
1401                 if(rl->layflag & SCE_LAY_SKY)
1402                         atm_tile(pa, rl);
1403                 
1404                 /* sky before edge */
1405                 if(rl->layflag & SCE_LAY_SKY)
1406                         sky_tile(pa, rl);
1407                 
1408                 if(!R.test_break(R.tbh)) {
1409                         if(rl->layflag & SCE_LAY_EDGE) 
1410                                 if(R.r.mode & R_EDGE)
1411                                         edge_enhance_add(pa, rl->rectf, edgerect);
1412                 }
1413                 
1414                 if(rl->passflag & SCE_PASS_VECTOR)
1415                         reset_sky_speed(pa, rl);
1416                 
1417                 /* de-premul alpha */
1418                 if(R.r.alphamode & R_ALPHAKEY)
1419                         convert_to_key_alpha(pa, rl);
1420                 
1421                 if(edgerect) MEM_freeN(edgerect);
1422                 edgerect= NULL;
1423
1424                 if(pa->rectmask) {
1425                         MEM_freeN(pa->rectmask);
1426                         pa->rectmask= NULL;
1427                 }
1428         }
1429
1430         /* display active layer */
1431         rr->renrect.ymin=rr->renrect.ymax= 0;
1432         rr->renlay= render_get_active_layer(&R, rr);
1433         
1434         MEM_freeN(pa->recto); pa->recto= NULL;
1435         MEM_freeN(pa->rectp); pa->rectp= NULL;
1436         MEM_freeN(pa->rectz); pa->rectz= NULL;
1437 }
1438
1439 /* SSS preprocess tile render, fully threadable */
1440 typedef struct ZBufSSSHandle {
1441         RenderPart *pa;
1442         ListBase psmlist;
1443         int totps;
1444 } ZBufSSSHandle;
1445
1446 static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z)
1447 {
1448         ZBufSSSHandle *handle = cb_handle;
1449         RenderPart *pa= handle->pa;
1450
1451         /* extra border for filter gives double samples on part edges,
1452            don't use those */
1453         if(x<pa->crop || x>=pa->rectx-pa->crop)
1454                 return;
1455         if(y<pa->crop || y>=pa->recty-pa->crop)
1456                 return;
1457         
1458         if(pa->rectall) {
1459                 intptr_t *rs= pa->rectall + pa->rectx*y + x;
1460
1461                 addps(&handle->psmlist, rs, obi, facenr, z, 0, 0);
1462                 handle->totps++;
1463         }
1464         if(pa->rectz) {
1465                 int *rz= pa->rectz + pa->rectx*y + x;
1466                 int *rp= pa->rectp + pa->rectx*y + x;
1467                 int *ro= pa->recto + pa->rectx*y + x;
1468
1469                 if(z < *rz) {
1470                         if(*rp == 0)
1471                                 handle->totps++;
1472                         *rz= z;
1473                         *rp= facenr;
1474                         *ro= obi;
1475                 }
1476         }
1477         if(pa->rectbackz) {
1478                 int *rz= pa->rectbackz + pa->rectx*y + x;
1479                 int *rp= pa->rectbackp + pa->rectx*y + x;
1480                 int *ro= pa->rectbacko + pa->rectx*y + x;
1481
1482                 if(z >= *rz) {
1483                         if(*rp == 0)
1484                                 handle->totps++;
1485                         *rz= z;
1486                         *rp= facenr;
1487                         *ro= obi;
1488                 }
1489         }
1490 }
1491
1492 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)
1493 {
1494         ShadeInput *shi= ssamp->shi;
1495         ShadeResult shr;
1496         float texfac, orthoarea, nor[3], alpha, sx, sy;
1497
1498         /* cache for shadow */
1499         shi->samplenr= R.shadowsamplenr[shi->thread]++;
1500         
1501         if(quad) 
1502                 shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
1503         else
1504                 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
1505
1506         /* center pixel */
1507         sx = x + 0.5f;
1508         sy = y + 0.5f;
1509
1510         /* we estimate the area here using shi->dxco and shi->dyco. we need to
1511            enabled shi->osatex these are filled. we compute two areas, one with
1512            the normal pointed at the camera and one with the original normal, and
1513            then clamp to avoid a too large contribution from a single pixel */
1514         shi->osatex= 1;
1515
1516         VECCOPY(nor, shi->facenor);
1517         calc_view_vector(shi->facenor, sx, sy);
1518         normalize_v3(shi->facenor);
1519         shade_input_set_viewco(shi, x, y, sx, sy, z);
1520         orthoarea= len_v3(shi->dxco)*len_v3(shi->dyco);
1521
1522         VECCOPY(shi->facenor, nor);
1523         shade_input_set_viewco(shi, x, y, sx, sy, z);
1524         *area= len_v3(shi->dxco)*len_v3(shi->dyco);
1525         *area= MIN2(*area, 2.0f*orthoarea);
1526
1527         shade_input_set_uv(shi);
1528         shade_input_set_normals(shi);
1529
1530         /* we don't want flipped normals, they screw up back scattering */
1531         if(shi->flippednor)
1532                 shade_input_flip_normals(shi);
1533
1534         /* not a pretty solution, but fixes common cases */
1535         if(shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
1536                 negate_v3(shi->vn);
1537                 negate_v3(shi->vno);
1538         }
1539
1540         /* if nodetree, use the material that we are currently preprocessing
1541            instead of the node material */
1542         if(shi->mat->nodetree && shi->mat->use_nodes)
1543                 shi->mat= mat;
1544
1545         /* init material vars */
1546         shade_input_init_material(shi);
1547         
1548         /* render */
1549         shade_input_set_shade_texco(shi);
1550         
1551         shade_samples_do_AO(ssamp);
1552         shade_material_loop(shi, &shr);
1553         
1554         VECCOPY(co, shi->co);
1555         VECCOPY(color, shr.combined);
1556
1557         /* texture blending */
1558         texfac= shi->mat->sss_texfac;
1559
1560         alpha= shr.combined[3];
1561         *area *= alpha;
1562 }
1563
1564 static void zbufshade_sss_free(RenderPart *pa)
1565 {
1566 #if 0
1567         MEM_freeN(pa->rectall); pa->rectall= NULL;
1568         freeps(&handle.psmlist);
1569 #else
1570         MEM_freeN(pa->rectz); pa->rectz= NULL;
1571         MEM_freeN(pa->rectp); pa->rectp= NULL;
1572         MEM_freeN(pa->recto); pa->recto= NULL;
1573         MEM_freeN(pa->rectbackz); pa->rectbackz= NULL;
1574         MEM_freeN(pa->rectbackp); pa->rectbackp= NULL;
1575         MEM_freeN(pa->rectbacko); pa->rectbacko= NULL;
1576 #endif
1577 }
1578
1579 void zbufshade_sss_tile(RenderPart *pa)
1580 {
1581         Render *re= &R;
1582         ShadeSample ssamp;
1583         ZBufSSSHandle handle;
1584         RenderResult *rr= pa->result;
1585         RenderLayer *rl;
1586         VlakRen *vlr;
1587         Material *mat= re->sss_mat;
1588         float (*co)[3], (*color)[3], *area, *fcol;
1589         int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS);
1590         int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay;
1591 #if 0
1592         PixStr *ps;
1593         intptr_t *rs;
1594         int z;
1595 #endif
1596
1597         /* setup pixelstr list and buffer for zbuffering */
1598         handle.pa= pa;
1599         handle.totps= 0;
1600
1601 #if 0
1602         handle.psmlist.first= handle.psmlist.last= NULL;
1603         addpsmain(&handle.psmlist);
1604
1605         pa->rectall= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "rectall");
1606 #else
1607         pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1608         pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1609         pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1610         pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko");
1611         pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp");
1612         pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
1613 #endif
1614
1615         /* setup shade sample with correct passes */
1616         memset(&ssamp, 0, sizeof(ssamp));
1617         shade_sample_initialize(&ssamp, pa, rr->layers.first);
1618         ssamp.tot= 1;
1619         
1620         for(rl=rr->layers.first; rl; rl=rl->next) {
1621                 ssamp.shi[0].lay |= rl->lay;
1622                 ssamp.shi[0].layflag |= rl->layflag;
1623                 ssamp.shi[0].passflag |= rl->passflag;
1624                 ssamp.shi[0].combinedflag |= ~rl->pass_xor;
1625         }
1626
1627         rl= rr->layers.first;
1628         ssamp.shi[0].passflag |= SCE_PASS_RGBA|SCE_PASS_COMBINED;
1629         ssamp.shi[0].combinedflag &= ~(SCE_PASS_SPEC);
1630         ssamp.shi[0].mat_override= NULL;
1631         ssamp.shi[0].light_override= NULL;
1632         lay= ssamp.shi[0].lay;
1633
1634         /* create the pixelstrs to be used later */
1635         zbuffer_sss(pa, lay, &handle, addps_sss);
1636
1637         if(handle.totps==0) {
1638                 zbufshade_sss_free(pa);
1639                 return;
1640         }
1641         
1642         fcol= rl->rectf;
1643
1644         co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
1645         color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
1646         area= MEM_mallocN(sizeof(float)*handle.totps, "SSSArea");
1647
1648 #if 0
1649         /* create ISB (does not work currently!) */
1650         if(re->r.mode & R_SHADOW)
1651                 ISB_create(pa, NULL);
1652 #endif
1653
1654         if(display) {
1655                 /* initialize scanline updates for main thread */
1656                 rr->renrect.ymin= 0;
1657                 rr->renlay= rl;
1658         }
1659         
1660         seed= pa->rectx*pa->disprect.ymin;
1661 #if 0
1662         rs= pa->rectall;
1663 #else
1664         rz= pa->rectz;
1665         rp= pa->rectp;
1666         ro= pa->recto;
1667         rbz= pa->rectbackz;
1668         rbp= pa->rectbackp;
1669         rbo= pa->rectbacko;
1670 #endif
1671         totpoint= 0;
1672
1673         for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1674                 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, fcol+=4) {
1675                         /* per pixel fixed seed */
1676                         BLI_thread_srandom(pa->thread, seed++);
1677                         
1678 #if 0
1679                         if(rs) {
1680                                 /* for each sample in this pixel, shade it */
1681                                 for(ps=(PixStr*)*rs; ps; ps=ps->next) {
1682                                         ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
1683                                         ObjectRen *obr= obi->obr;
1684                                         vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
1685                                         quad= (ps->facenr & RE_QUAD_OFFS);
1686                                         z= ps->z;
1687
1688                                         shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z,
1689                                                 co[totpoint], color[totpoint], &area[totpoint]);
1690
1691                                         totpoint++;
1692
1693                                         VECADD(fcol, fcol, color);
1694                                         fcol[3]= 1.0f;
1695                                 }
1696
1697                                 rs++;
1698                         }
1699 #else
1700                         if(rp) {
1701                                 if(*rp != 0) {
1702                                         ObjectInstanceRen *obi= &re->objectinstance[*ro];
1703                                         ObjectRen *obr= obi->obr;
1704
1705                                         /* shade front */
1706                                         vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK);
1707                                         quad= ((*rp) & RE_QUAD_OFFS);
1708
1709                                         shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz,
1710                                                 co[totpoint], color[totpoint], &area[totpoint]);
1711                                         
1712                                         VECADD(fcol, fcol, color[totpoint]);
1713                                         fcol[3]= 1.0f;
1714                                         totpoint++;
1715                                 }
1716
1717                                 rp++; rz++; ro++;
1718                         }
1719
1720                         if(rbp) {
1721                                 if(*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) {
1722                                         ObjectInstanceRen *obi= &re->objectinstance[*rbo];
1723                                         ObjectRen *obr= obi->obr;
1724
1725                                         /* shade back */
1726                                         vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK);
1727                                         quad= ((*rbp) & RE_QUAD_OFFS);
1728
1729                                         shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz,
1730                                                 co[totpoint], color[totpoint], &area[totpoint]);
1731                                         
1732                                         /* to indicate this is a back sample */
1733                                         area[totpoint]= -area[totpoint];
1734
1735                                         VECADD(fcol, fcol, color[totpoint]);
1736                                         fcol[3]= 1.0f;
1737                                         totpoint++;
1738                                 }
1739
1740                                 rbz++; rbp++; rbo++;
1741                         }
1742 #endif
1743                 }
1744
1745                 if(y&1)
1746                         if(re->test_break(re->tbh)) break; 
1747         }
1748
1749         /* note: after adding we do not free these arrays, sss keeps them */
1750         if(totpoint > 0) {
1751                 sss_add_points(re, co, color, area, totpoint);
1752         }
1753         else {
1754                 MEM_freeN(co);
1755                 MEM_freeN(color);
1756                 MEM_freeN(area);
1757         }
1758         
1759 #if 0
1760         if(re->r.mode & R_SHADOW)
1761                 ISB_free(pa);
1762 #endif
1763                 
1764         if(display) {
1765                 /* display active layer */
1766                 rr->renrect.ymin=rr->renrect.ymax= 0;
1767                 rr->renlay= render_get_active_layer(&R, rr);
1768         }
1769         
1770         zbufshade_sss_free(pa);
1771 }
1772
1773 /* ------------------------------------------------------------------------ */
1774
1775 static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har)       /* postprocess version */
1776 {
1777         float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf;
1778         float haloxs, haloys;
1779         int minx, maxx, miny, maxy, x, y;
1780
1781         /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */
1782         haloxs= har->xs - R.disprect.xmin;
1783         haloys= har->ys - R.disprect.ymin;
1784         
1785         har->miny= miny= haloys - har->rad/R.ycor;
1786         har->maxy= maxy= haloys + har->rad/R.ycor;
1787         
1788         if(maxy<0);
1789         else if(rr->recty<miny);
1790         else {
1791                 minx= floor(haloxs-har->rad);
1792                 maxx= ceil(haloxs+har->rad);
1793                         
1794                 if(maxx<0);
1795                 else if(rr->rectx<minx);
1796                 else {
1797                 
1798                         if(minx<0) minx= 0;
1799                         if(maxx>=rr->rectx) maxx= rr->rectx-1;
1800                         if(miny<0) miny= 0;
1801                         if(maxy>rr->recty) maxy= rr->recty;
1802         
1803                         rectft= rectf+ 4*rr->rectx*miny;
1804
1805                         for(y=miny; y<maxy; y++) {
1806         
1807                                 rtf= rectft+4*minx;
1808                                 
1809                                 yn= (y - haloys)*R.ycor;
1810                                 ysq= yn*yn;
1811                                 
1812                                 for(x=minx; x<=maxx; x++) {
1813                                         xn= x - haloxs;
1814                                         xsq= xn*xn;
1815                                         dist= xsq+ysq;
1816                                         if(dist<har->radsq) {
1817                                                 
1818                                                 if(shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec))
1819                                                         addalphaAddfacFloat(rtf, colf, har->add);
1820                                         }
1821                                         rtf+=4;
1822                                 }
1823         
1824                                 rectft+= 4*rr->rectx;
1825                                 
1826                                 if(R.test_break(R.tbh)) break; 
1827                         }
1828                 }
1829         }
1830
1831 /* ------------------------------------------------------------------------ */
1832
1833 static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
1834 {
1835         extern float hashvectf[];
1836         HaloRen fla;
1837         Material *ma;
1838         float *rc, rad, alfa, visifac, vec[3];
1839         int b, type;
1840         
1841         fla= *har;
1842         fla.linec= fla.ringc= fla.flarec= 0;
1843         
1844         rad= har->rad;
1845         alfa= har->alfa;
1846         
1847         visifac= R.ycor*(har->pixels);
1848         /* all radials added / r^3  == 1.0f! */
1849         visifac /= (har->rad*har->rad*har->rad);
1850         visifac*= visifac;
1851
1852         ma= har->mat;
1853         
1854         /* first halo: just do */
1855         
1856         har->rad= rad*ma->flaresize*visifac;
1857         har->radsq= har->rad*har->rad;
1858         har->zs= fla.zs= 0;
1859         
1860         har->alfa= alfa*visifac;
1861
1862         renderhalo_post(rr, rectf, har);
1863         
1864         /* next halo's: the flares */
1865         rc= hashvectf + ma->seed2;
1866         
1867         for(b=1; b<har->flarec; b++) {
1868                 
1869                 fla.r= fabs(rc[0]);
1870                 fla.g= fabs(rc[1]);
1871                 fla.b= fabs(rc[2]);
1872                 fla.alfa= ma->flareboost*fabs(alfa*visifac*rc[3]);
1873                 fla.hard= 20.0f + fabs(70*rc[7]);
1874                 fla.tex= 0;
1875                 
1876                 type= (int)(fabs(3.9*rc[6]));
1877
1878                 fla.rad= ma->subsize*sqrt(fabs(2.0f*har->rad*rc[4]));
1879                 
1880                 if(type==3) {
1881                         fla.rad*= 3.0f;
1882                         fla.rad+= R.rectx/10;
1883                 }
1884                 
1885                 fla.radsq= fla.rad*fla.rad;
1886                 
1887                 vec[0]= 1.4*rc[5]*(har->xs-R.winx/2);
1888                 vec[1]= 1.4*rc[5]*(har->ys-R.winy/2);
1889                 vec[2]= 32.0f*sqrt(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f);
1890                 
1891                 fla.xs= R.winx/2 + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2];
1892                 fla.ys= R.winy/2 + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2];
1893
1894                 if(R.flag & R_SEC_FIELD) {
1895                         if(R.r.mode & R_ODDFIELD) fla.ys += 0.5;
1896                         else fla.ys -= 0.5;
1897                 }
1898                 if(type & 1) fla.type= HA_FLARECIRC;
1899                 else fla.type= 0;
1900                 renderhalo_post(rr, rectf, &fla);
1901
1902                 fla.alfa*= 0.5;
1903                 if(type & 2) fla.type= HA_FLARECIRC;
1904                 else fla.type= 0;
1905                 renderhalo_post(rr, rectf, &fla);
1906                 
1907                 rc+= 7;
1908         }
1909 }
1910
1911 /* needs recode... integrate this better! */
1912 void add_halo_flare(Render *re)
1913 {
1914         RenderResult *rr= re->result;
1915         RenderLayer *rl;
1916         HaloRen *har;
1917         int a, mode, do_draw=0;
1918         
1919         /* for now, we get the first renderlayer in list with halos set */
1920         for(rl= rr->layers.first; rl; rl= rl->next)
1921                 if(rl->layflag & SCE_LAY_HALO)
1922                         break;
1923
1924         if(rl==NULL || rl->rectf==NULL)
1925                 return;
1926         
1927         mode= R.r.mode;
1928         R.r.mode &= ~R_PANORAMA;
1929         
1930         project_renderdata(&R, projectverto, 0, 0, 0);
1931         
1932         for(a=0; a<R.tothalo; a++) {
1933                 har= R.sortedhalos[a];
1934                 
1935                 if(har->flarec) {
1936                         do_draw= 1;
1937                         renderflare(rr, rl->rectf, har);
1938                 }
1939         }
1940
1941         if(do_draw) {
1942                 /* weak... the display callback wants an active renderlayer pointer... */
1943                 rr->renlay= rl;
1944                 re->display_draw(re->ddh, rr, NULL);
1945         }
1946         
1947         R.r.mode= mode; 
1948 }
1949
1950 /* ************************* used for shaded view ************************ */
1951
1952 /* if *re, then initialize, otherwise execute */
1953 void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
1954 {
1955         static VlakRen vlr;
1956         static ObjectRen obr;
1957         static ObjectInstanceRen obi;
1958         
1959         /* init */
1960         if(re) {
1961                 R= *re;
1962                 
1963                 /* fake render face */
1964                 memset(&vlr, 0, sizeof(VlakRen));
1965                 memset(&obr, 0, sizeof(ObjectRen));
1966                 memset(&obi, 0, sizeof(ObjectInstanceRen));
1967                 obr.lay= -1;
1968                 obi.obr= &obr;
1969                 
1970                 return;
1971         }
1972         shi->vlr= &vlr;
1973         shi->obr= &obr;
1974         shi->obi= &obi;
1975         
1976         if(shi->mat->nodetree && shi->mat->use_nodes)
1977                 ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
1978         else {
1979                 shade_input_init_material(shi);
1980                 shade_material_loop(shi, shr);
1981         }
1982 }
1983
1984 /* ************************* bake ************************ */
1985
1986
1987 typedef struct BakeShade {
1988         ShadeSample ssamp;
1989         ObjectInstanceRen *obi;
1990         VlakRen *vlr;
1991         
1992         ZSpan *zspan;
1993         Image *ima;
1994         ImBuf *ibuf;
1995         
1996         int rectx, recty, quad, type, vdone, ready;
1997
1998         float dir[3];
1999         Object *actob;
2000         
2001         unsigned int *rect;
2002         float *rect_float;
2003         
2004         int usemask;
2005         char *rect_mask; /* bake pixel mask */
2006
2007         float dxco[3], dyco[3];
2008
2009         short *do_update;
2010 } BakeShade;
2011
2012 /* bake uses a char mask to know what has been baked */
2013 #define BAKE_MASK_NULL          0
2014 #define BAKE_MASK_MARGIN        1
2015 #define BAKE_MASK_BAKED         2
2016 static void bake_mask_filter_extend( char *mask, int width, int height )
2017 {
2018         char *row1, *row2, *row3;
2019         int rowlen, x, y;
2020         char *temprect;
2021         
2022         rowlen= width;
2023         
2024         /* make a copy, to prevent flooding */
2025         temprect= MEM_dupallocN(mask);
2026         
2027         for(y=1; y<=height; y++) {
2028                 /* setup rows */
2029                 row1= (char *)(temprect + (y-2)*rowlen);
2030                 row2= row1 + rowlen;
2031                 row3= row2 + rowlen;
2032                 if(y==1)
2033                         row1= row2;
2034                 else if(y==height)
2035                         row3= row2;
2036                 
2037                 for(x=0; x<rowlen; x++) {
2038                         if (mask[((y-1)*rowlen)+x]==0) {
2039                                 if (*row1 || *row2 || *row3 || *(row1+1) || *(row3+1) ) {
2040                                         mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
2041                                 } else if((x!=rowlen-1) && (*(row1+2) || *(row2+2) || *(row3+2)) ) {
2042                                         mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
2043                                 }
2044                         }
2045                         
2046                         if(x!=0) {
2047                                 row1++; row2++; row3++;
2048                         }
2049                 }
2050         }
2051         MEM_freeN(temprect);
2052 }
2053
2054 static void bake_mask_clear( ImBuf *ibuf, char *mask, char val )
2055 {
2056         int x,y;
2057         if (ibuf->rect_float) {
2058                 for(x=0; x<ibuf->x; x++) {
2059                         for(y=0; y<ibuf->y; y++) {
2060                                 if (mask[ibuf->x*y + x] == val) {
2061                                         float *col= ibuf->rect_float + 4*(ibuf->x*y + x);
2062                                         col[0] = col[1] = col[2] = col[3] = 0.0f;
2063                                 }
2064                         }
2065                 }
2066                 
2067         } else {
2068                 /* char buffer */
2069                 for(x=0; x<ibuf->x; x++) {
2070                         for(y=0; y<ibuf->y; y++) {
2071                                 if (mask[ibuf->x*y + x] == val) {
2072                                         char *col= (char *)(ibuf->rect + ibuf->x*y + x);
2073                                         col[0] = col[1] = col[2] = col[3] = 0;
2074                                 }
2075                         }
2076                 }
2077         }
2078 }
2079
2080 static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v)
2081 {
2082         if(isect) {
2083                 /* raytrace intersection with different u,v than scanconvert */
2084                 if(vlr->v4) {
2085                         if(quad)
2086                                 shade_input_set_triangle_i(shi, obi, vlr, 2, 1, 3);
2087                         else
2088                                 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 3);
2089                 }
2090                 else
2091                         shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
2092         }
2093         else {
2094                 /* regular scanconvert */
2095                 if(quad) 
2096                         shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
2097                 else
2098                         shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
2099         }
2100                 
2101         /* cache for shadow */
2102         shi->samplenr= R.shadowsamplenr[shi->thread]++;
2103
2104         shi->mask= 0xFFFF; /* all samples */
2105         
2106         shi->u= -u;
2107         shi->v= -v;
2108         shi->xs= x;
2109         shi->ys= y;
2110         
2111         shade_input_set_uv(shi);
2112         shade_input_set_normals(shi);
2113
2114         /* no normal flip */
2115         if(shi->flippednor)
2116                 shade_input_flip_normals(shi);
2117
2118         /* set up view vector to look right at the surface (note that the normal
2119          * is negated in the renderer so it does not need to be done here) */
2120         shi->view[0]= shi->vn[0];
2121         shi->view[1]= shi->vn[1];
2122         shi->view[2]= shi->vn[2];
2123 }
2124
2125 static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int x, int y, float u, float v, float *tvn, float *ttang)
2126 {
2127         BakeShade *bs= handle;
2128         ShadeSample *ssamp= &bs->ssamp;
2129         ShadeResult shr;
2130         VlakRen *vlr= shi->vlr;
2131         
2132         shade_input_init_material(shi);
2133         
2134         if(bs->type==RE_BAKE_AO) {
2135                 ambient_occlusion(shi);
2136
2137                 if(R.r.bake_flag & R_BAKE_NORMALIZE) {
2138                         copy_v3_v3(shr.combined, shi->ao);
2139                 }
2140                 else {
2141                         zero_v3(shr.combined);
2142                         environment_lighting_apply(shi, &shr);
2143                 }
2144         }
2145         else {
2146                 if (bs->type==RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */
2147                         shi->r = shi->g = shi->b = 1.0f;
2148         
2149                 shade_input_set_shade_texco(shi);
2150                 
2151                 if(!ELEM3(bs->type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_SHADOW))
2152                         shade_samples_do_AO(ssamp);
2153                 
2154                 if(shi->mat->nodetree && shi->mat->use_nodes) {
2155                         ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
2156                         shi->mat= vlr->mat;             /* shi->mat is being set in nodetree */
2157                 }
2158                 else
2159                         shade_material_loop(shi, &shr);
2160                 
2161                 if(bs->type==RE_BAKE_NORMALS) {
2162                         float nor[3];
2163
2164                         VECCOPY(nor, shi->vn);
2165
2166                         if(R.r.bake_normal_space == R_BAKE_SPACE_CAMERA);
2167                         else if(R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
2168                                 float mat[3][3], imat[3][3];
2169
2170                                 /* bitangent */
2171                                 if(tvn && ttang) {
2172                                         VECCOPY(mat[0], ttang);
2173                                         cross_v3_v3v3(mat[1], tvn, ttang);
2174                                         VECCOPY(mat[2], tvn);
2175                                 }
2176                                 else {
2177                                         VECCOPY(mat[0], shi->nmaptang);
2178                                         cross_v3_v3v3(mat[1], shi->vn, shi->nmaptang);
2179                                         VECCOPY(mat[2], shi->vn);
2180                                 }
2181
2182                                 invert_m3_m3(imat, mat);
2183                                 mul_m3_v3(imat, nor);
2184                         }
2185                         else if(R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
2186                                 mul_mat3_m4_v3(ob->imat, nor); /* ob->imat includes viewinv! */
2187                         else if(R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
2188                                 mul_mat3_m4_v3(R.viewinv, nor);
2189
2190                         normalize_v3(nor); /* in case object has scaling */
2191
2192                         shr.combined[0]= nor[0]/2.0f + 0.5f;
2193                         shr.combined[1]= 0.5f - nor[1]/2.0f;
2194                         shr.combined[2]= nor[2]/2.0f + 0.5f;
2195                 }
2196                 else if(bs->type==RE_BAKE_TEXTURE) {
2197                         shr.combined[0]= shi->r;
2198                         shr.combined[1]= shi->g;
2199                         shr.combined[2]= shi->b;
2200                         shr.alpha = shi->alpha;
2201                 }
2202                 else if(bs->type==RE_BAKE_SHADOW) {
2203                         VECCOPY(shr.combined, shr.shad);
2204                         shr.alpha = shi->alpha;
2205                 }
2206         }
2207         
2208         if(bs->rect_float) {
2209                 float *col= bs->rect_float + 4*(bs->rectx*y + x);
2210                 VECCOPY(col, shr.combined);
2211                 if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
2212                         col[3]= shr.alpha;
2213                 } else {
2214                         col[3]= 1.0;
2215                 }
2216         }
2217         else {
2218                 char *col= (char *)(bs->rect + bs->rectx*y + x);
2219
2220                 if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE) &&     (R.r.color_mgt_flag & R_COLOR_MANAGEMENT)) {
2221                         float srgb[3];
2222                         srgb[0]= linearrgb_to_srgb(shr.combined[0]);
2223                         srgb[1]= linearrgb_to_srgb(shr.combined[1]);
2224                         srgb[2]= linearrgb_to_srgb(shr.combined[2]);
2225                         
2226                         col[0]= FTOCHAR(srgb[0]);
2227                         col[1]= FTOCHAR(srgb[1]);
2228                         col[2]= FTOCHAR(srgb[2]);
2229                 } else {
2230                         col[0]= FTOCHAR(shr.combined[0]);
2231                         col[1]= FTOCHAR(shr.combined[1]);
2232                         col[2]= FTOCHAR(shr.combined[2]);
2233                 }
2234                 
2235                 if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
2236                         col[3]= FTOCHAR(shr.alpha);
2237                 } else {
2238                         col[3]= 255;
2239                 }
2240         }
2241         
2242         if (bs->rect_mask) {
2243                 bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
2244         }
2245 }
2246
2247 static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x, int y)
2248 {
2249         BakeShade *bs= handle;
2250         float disp;
2251         
2252         if(R.r.bake_flag & R_BAKE_NORMALIZE && R.r.bake_maxdist) {
2253                 disp = (dist+R.r.bake_maxdist) / (R.r.bake_maxdist*2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
2254         } else {
2255                 disp = 0.5 + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
2256         }
2257         
2258         if(bs->rect_float) {
2259                 float *col= bs->rect_float + 4*(bs->rectx*y + x);
2260                 col[0] = col[1] = col[2] = disp;
2261                 col[3]= 1.0f;
2262         } else {        
2263                 char *col= (char *)(bs->rect + bs->rectx*y + x);
2264                 col[0]= FTOCHAR(disp);
2265                 col[1]= FTOCHAR(disp);
2266                 col[2]= FTOCHAR(disp);
2267                 col[3]= 255;
2268         }
2269         if (bs->rect_mask) {
2270                 bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
2271         }
2272 }
2273
2274 static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist)
2275 {
2276         float maxdist;
2277         int hit;
2278
2279         /* might be useful to make a user setting for maxsize*/
2280         if(R.r.bake_maxdist > 0.0f)
2281                 maxdist= R.r.bake_maxdist;
2282         else
2283                 maxdist= RE_RAYTRACE_MAXDIST + R.r.bake_biasdist;
2284         
2285         /* 'dir' is always normalized */
2286         VECADDFAC(isect->start, start, dir, -R.r.bake_biasdist);                                        
2287
2288         isect->vec[0] = dir[0]*maxdist*sign;
2289         isect->vec[1] = dir[1]*maxdist*sign;
2290         isect->vec[2] = dir[2]*maxdist*sign;
2291
2292         isect->labda = maxdist;
2293
2294         hit = RE_rayobject_raycast(raytree, isect);
2295         if(hit) {
2296                 hitco[0] = isect->start[0] + isect->labda*isect->vec[0];
2297                 hitco[1] = isect->start[1] + isect->labda*isect->vec[1];
2298                 hitco[2] = isect->start[2] + isect->labda*isect->vec[2];
2299
2300                 *dist= len_v3v3(start, hitco);
2301         }
2302
2303         return hit;
2304 }
2305
2306 static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3)
2307 {
2308         VlakRen *vlr= bs->vlr;
2309         float A, d1, d2, d3, *v1, *v2, *v3;
2310
2311         if(bs->quad) {
2312                 v1= vlr->v1->co;
2313                 v2= vlr->v3->co;
2314                 v3= vlr->v4->co;
2315         }
2316         else {
2317                 v1= vlr->v1->co;
2318                 v2= vlr->v2->co;
2319                 v3= vlr->v3->co;
2320         }
2321
2322         /* formula derived from barycentric coordinates:
2323          * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea
2324          * then taking u and v partial derivatives to get dxco and dyco */
2325         A= (uv2[0] - uv1[0])*(uv3[1] - uv1[1]) - (uv3[0] - uv1[0])*(uv2[1] - uv1[1]);
2326
2327         if(fabs(A) > FLT_EPSILON) {
2328                 A= 0.5f/A;
2329
2330                 d1= uv2[1] - uv3[1];
2331                 d2= uv3[1] - uv1[1];
2332                 d3= uv1[1] - uv2[1];
2333                 bs->dxco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
2334                 bs->dxco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
2335                 bs->dxco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
2336
2337                 d1= uv3[0] - uv2[0];
2338                 d2= uv1[0] - uv3[0];
2339                 d3= uv2[0] - uv1[0];
2340                 bs->dyco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
2341                 bs->dyco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
2342                 bs->dyco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
2343         }
2344         else {
2345                 bs->dxco[0]= bs->dxco[1]= bs->dxco[2]= 0.0f;
2346                 bs->dyco[0]= bs->dyco[1]= bs->dyco[2]= 0.0f;
2347         }
2348
2349         if(bs->obi->flag & R_TRANSFORMED) {
2350                 mul_m3_v3(bs->obi->nmat, bs->dxco);
2351                 mul_m3_v3(bs->obi->nmat, bs->dyco);
2352         }
2353 }
2354
2355 static void do_bake_shade(void *handle, int x, int y, float u, float v)
2356 {
2357         BakeShade *bs= handle;
2358         VlakRen *vlr= bs->vlr;
2359         ObjectInstanceRen *obi= bs->obi;
2360         Object *ob= obi->obr->ob;
2361         float l, *v1, *v2, *v3, tvn[3], ttang[3];
2362         int quad;
2363         ShadeSample *ssamp= &bs->ssamp;
2364         ShadeInput *shi= ssamp->shi;
2365         
2366         /* fast threadsafe break test */
2367         if(R.test_break(R.tbh))
2368                 return;
2369         
2370         /* setup render coordinates */
2371         if(bs->quad) {
2372                 v1= vlr->v1->co;
2373                 v2= vlr->v3->co;
2374                 v3= vlr->v4->co;
2375         }
2376         else {
2377                 v1= vlr->v1->co;
2378                 v2= vlr->v2->co;
2379                 v3= vlr->v3->co;
2380         }
2381         
2382         /* renderco */
2383         l= 1.0f-u-v;
2384         
2385         shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
2386         shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
2387         shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
2388         
2389         if(obi->flag & R_TRANSFORMED)
2390                 mul_m4_v3(obi->mat, shi->co);
2391         
2392         VECCOPY(shi->dxco, bs->dxco);
2393         VECCOPY(shi->dyco, bs->dyco);
2394
2395         quad= bs->quad;
2396         bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
2397
2398         if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) {
2399                 shade_input_set_shade_texco(shi);
2400                 VECCOPY(tvn, shi->vn);
2401                 VECCOPY(ttang, shi->nmaptang);
2402         }
2403
2404         /* if we are doing selected to active baking, find point on other face */
2405         if(bs->actob) {
2406                 Isect isec, minisec;
2407                 float co[3], minco[3], dist, mindist=0.0f;
2408                 int hit, sign, dir=1;
2409                 
2410                 /* intersect with ray going forward and backward*/
2411                 hit= 0;
2412                 memset(&minisec, 0, sizeof(minisec));
2413                 minco[0]= minco[1]= minco[2]= 0.0f;
2414                 
2415                 VECCOPY(bs->dir, shi->vn);
2416                 
2417                 for(sign=-1; sign<=1; sign+=2) {
2418                         memset(&isec, 0, sizeof(isec));
2419                         isec.mode= RE_RAY_MIRROR;
2420
2421                         isec.orig.ob   = obi;
2422                         isec.orig.face = vlr;
2423                         isec.userdata= bs->actob;
2424                         isec.skip = RE_SKIP_VLR_NEIGHBOUR|RE_SKIP_VLR_BAKE_CHECK;
2425                         
2426                         if(bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) {
2427                                 if(!hit || len_v3v3(shi->co, co) < len_v3v3(shi->co, minco)) {
2428                                         minisec= isec;
2429                                         mindist= dist;
2430                                         VECCOPY(minco, co);
2431                                         hit= 1;
2432                                         dir = sign;
2433                                 }
2434                         }
2435                 }
2436
2437                 if (bs->type==RE_BAKE_DISPLACEMENT) {
2438                         if(hit)
2439                                 bake_displacement(handle, shi, (dir==-1)? mindist:-mindist, x, y);
2440                         else
2441                                 bake_displacement(handle, shi, 0.0f, x, y);
2442                         return;
2443                 }
2444
2445                 /* if hit, we shade from the new point, otherwise from point one starting face */
2446                 if(hit) {
2447                         obi= (ObjectInstanceRen*)minisec.hit.ob;
2448                         vlr= (VlakRen*)minisec.hit.face;
2449                         quad= (minisec.isect == 2);
2450                         VECCOPY(shi->co, minco);
2451                         
2452                         u= -minisec.u;
2453                         v= -minisec.v;
2454                         bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
2455                 }
2456         }
2457
2458         if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT)
2459                 bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
2460         else
2461                 bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
2462 }
2463
2464 static int get_next_bake_face(BakeShade *bs)
2465 {
2466         ObjectRen *obr;
2467         VlakRen *vlr;
2468         MTFace *tface;
2469         static int v= 0, vdone= 0;
2470         static ObjectInstanceRen *obi= NULL;
2471         
2472         if(bs==NULL) {
2473                 vlr= NULL;
2474                 v= vdone= 0;
2475                 obi= R.instancetable.first;
2476                 return 0;
2477         }
2478         
2479         BLI_lock_thread(LOCK_CUSTOM1);  
2480
2481         for(; obi; obi=obi->next, v=0) {
2482                 obr= obi->obr;
2483
2484                 for(; v<obr->totvlak; v++) {
2485                         vlr= RE_findOrAddVlak(obr, v);
2486
2487                         if((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
2488                                 tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
2489
2490                                 if(tface && tface->tpage) {
2491                                         Image *ima= tface->tpage;
2492                                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2493                                         float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
2494                                         
2495                                         if(ibuf==NULL)
2496                                                 continue;
2497                                         
2498                                         if(ibuf->rect==NULL && ibuf->rect_float==NULL)
2499                                                 continue;
2500                                         
2501                                         if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
2502                                                 continue;
2503                                         
2504                                         /* find the image for the first time? */
2505                                         if(ima->id.flag & LIB_DOIT) {
2506                                                 ima->id.flag &= ~LIB_DOIT;
2507                                                 
2508                                                 /* we either fill in float or char, this ensures things go fine */
2509                                                 if(ibuf->rect_float)
2510                                                         imb_freerectImBuf(ibuf);
2511                                                 /* clear image */
2512                                                 if(R.r.bake_flag & R_BAKE_CLEAR)
2513                                                         IMB_rectfill(ibuf, vec);
2514                                         
2515                                                 /* might be read by UI to set active image for display */
2516                                                 R.bakebuf= ima;
2517                                         }                               
2518                                         
2519                                         bs->obi= obi;
2520                                         bs->vlr= vlr;
2521                                         
2522                                         bs->vdone++;    /* only for error message if nothing was rendered */
2523                                         v++;
2524                                         
2525                                         BLI_unlock_thread(LOCK_CUSTOM1);
2526                                         return 1;
2527                                 }
2528                         }
2529                 }
2530         }
2531         
2532         BLI_unlock_thread(LOCK_CUSTOM1);
2533         return 0;
2534 }
2535
2536 /* already have tested for tface and ima and zspan */
2537 static void shade_tface(BakeShade *bs)
2538 {
2539         VlakRen *vlr= bs->vlr;
2540         ObjectInstanceRen *obi= bs->obi;
2541         ObjectRen *obr= obi->obr;
2542         MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
2543         Image *ima= tface->tpage;
2544         float vec[4][2];
2545         int a, i1, i2, i3;
2546         
2547         /* check valid zspan */
2548         if(ima!=bs->ima) {
2549                 bs->ima= ima;
2550                 bs->ibuf= BKE_image_get_ibuf(ima, NULL);
2551                 /* note, these calls only free/fill contents of zspan struct, not zspan itself */
2552                 zbuf_free_span(bs->zspan);
2553                 zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
2554         }                               
2555         
2556         bs->rectx= bs->ibuf->x;
2557         bs->recty= bs->ibuf->y;
2558         bs->rect= bs->ibuf->rect;
2559         bs->rect_float= bs->ibuf->rect_float;
2560         bs->quad= 0;
2561         
2562         if (bs->usemask) {
2563                 if (bs->ibuf->userdata==NULL) {
2564                         BLI_lock_thread(LOCK_CUSTOM1);
2565                         if (bs->ibuf->userdata==NULL) { /* since the thread was locked, its possible another thread alloced the value */
2566                                 bs->ibuf->userdata = (void *)MEM_callocN(sizeof(char)*bs->rectx*bs->recty, "BakeMask");
2567                                 bs->rect_mask= (char *)bs->ibuf->userdata;
2568                         }
2569                         BLI_unlock_thread(LOCK_CUSTOM1);
2570                 } else {
2571                         bs->rect_mask= (char *)bs->ibuf->userdata;
2572                 }
2573         }
2574         
2575         /* get pixel level vertex coordinates */
2576         for(a=0; a<4; a++) {
2577                 /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests
2578                  * where a pixel gets inbetween 2 faces or the middle of a quad,
2579                  * camera aligned quads also have this problem but they are less common.
2580                  * Add a small offset to the UVs, fixes bug #18685 - Campbell */
2581                 vec[a][0]= tface->uv[a][0]*(float)bs->rectx - (0.5f + 0.001);
2582                 vec[a][1]= tface->uv[a][1]*(float)bs->recty - (0.5f + 0.002);
2583         }
2584         
2585         /* UV indices have to be corrected for possible quad->tria splits */
2586         i1= 0; i2= 1; i3= 2;
2587         vlr_set_uv_indices(vlr, &i1, &i2, &i3);
2588         bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]);
2589         zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
2590         
2591         if(vlr->v4) {
2592                 bs->quad= 1;
2593                 bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]);
2594                 zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
2595         }
2596 }
2597
2598 static void *do_bake_thread(void *bs_v)
2599 {
2600         BakeShade *bs= bs_v;
2601         
2602         while(get_next_bake_face(bs)) {
2603                 shade_tface(bs);
2604                 
2605                 /* fast threadsafe break test */
2606                 if(R.test_break(R.tbh))
2607                         break;
2608
2609                 /* access is not threadsafe but since its just true/false probably ok
2610                  * only used for interactive baking */
2611                 if(bs->do_update)
2612                         *bs->do_update= TRUE;
2613         }
2614         bs->ready= 1;
2615         
2616         return NULL;
2617 }
2618
2619 /* using object selection tags, the faces with UV maps get baked */
2620 /* render should have been setup */
2621 /* returns 0 if nothing was handled */
2622 int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update, float *progress)
2623 {
2624         BakeShade *handles;
2625         ListBase threads;
2626         Image *ima;
2627         int a, vdone=0, usemask=0;
2628         
2629         /* initialize render global */
2630         R= *re;
2631         R.bakebuf= NULL;
2632         
2633         /* initialize static vars */
2634         get_next_bake_face(NULL);
2635         
2636         /* do we need a mask? */
2637         if (re->r.bake_filter)
2638                 usemask = 1;
2639         
2640         /* baker uses this flag to detect if image was initialized */
2641         for(ima= G.main->image.first; ima; ima= ima->id.next) {
2642                 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2643                 ima->id.flag |= LIB_DOIT;
2644                 if(ibuf) {
2645                         ibuf->userdata = NULL; /* use for masking if needed */
2646                         if(ibuf->rect_float)
2647                                 ibuf->profile = IB_PROFILE_LINEAR_RGB;
2648                 }
2649         }
2650         
2651         BLI_init_threads(&threads, do_bake_thread, re->r.threads);
2652
2653         handles= MEM_callocN(sizeof(BakeShade)*re->r.threads, "BakeShade");
2654
2655         /* get the threads running */
2656         for(a=0; a<re->r.threads; a++) {
2657                 /* set defaults in handles */
2658                 handles[a].ssamp.shi[0].lay= re->lay;
2659                 
2660                 if (type==RE_BAKE_SHADOW) {
2661                         handles[a].ssamp.shi[0].passflag= SCE_PASS_SHADOW;
2662                 } else {
2663                         handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED;
2664                 }
2665                 handles[a].ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
2666                 handles[a].ssamp.shi[0].thread= a;
2667                 handles[a].ssamp.tot= 1;
2668                 
2669                 handles[a].type= type;
2670                 handles[a].actob= actob;
2671                 handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
2672                 
2673                 handles[a].usemask = usemask;
2674
2675                 handles[a].do_update = do_update; /* use to tell the view to update */
2676                 
2677                 BLI_insert_thread(&threads, &handles[a]);
2678         }
2679         
2680         /* wait for everything to be done */
2681         a= 0;
2682         while(a!=re->r.threads) {
2683                 PIL_sleep_ms(50);
2684
2685                 /* calculate progress */
2686                 for(vdone=0, a=0; a<re->r.threads; a++)
2687                         vdone+= handles[a].vdone;
2688                 if (progress)
2689                         *progress = (float)(vdone / (float)re->totvlak);
2690                 
2691                 for(a=0; a<re->r.threads; a++) {
2692                         if(handles[a].ready==0)
2693                                 break;
2694                 }
2695         }
2696         
2697         /* filter and refresh images */
2698         for(ima= G.main->image.first; ima; ima= ima->id.next) {
2699                 if((ima->id.flag & LIB_DOIT)==0) {
2700                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2701
2702                         if(!ibuf)
2703                                 continue;
2704
2705                         if(re->r.bake_filter) {
2706                                 if (usemask) {
2707                                         /* extend the mask +2 pixels from the image,
2708                                          * this is so colors dont blend in from outside */
2709                                         char *temprect;
2710                                         
2711                                         for(a=0; a<re->r.bake_filter; a++)
2712                                                 bake_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y);
2713                                         
2714                                         temprect = MEM_dupallocN(ibuf->userdata);
2715                                         
2716                                         /* expand twice to clear this many pixels, so they blend back in */
2717                                         bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
2718                                         bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
2719                                         
2720                                         /* clear all pixels in the margin*/
2721                                         bake_mask_clear(ibuf, temprect, BAKE_MASK_MARGIN);
2722                                         MEM_freeN(temprect);
2723                                 }
2724                                 
2725                                 for(a=0; a<re->r.bake_filter; a++) {
2726                                         /*the mask, ibuf->userdata - can be null, in this case only zero alpha is used */
2727                                         IMB_filter_extend(ibuf, (char *)ibuf->userdata);
2728                                 }
2729                                 
2730                                 if (ibuf->userdata) {
2731                                         MEM_freeN(ibuf->userdata);
2732                                         ibuf->userdata= NULL;
2733                                 }
2734                         }
2735
2736                         ibuf->userflags |= IB_BITMAPDIRTY;
2737                         if (ibuf->rect_float) IMB_rect_from_float(ibuf);
2738                 }
2739         }
2740         
2741         /* calculate return value */
2742         for(a=0; a<re->r.threads; a++) {
2743                 zbuf_free_span(handles[a].zspan);
2744                 MEM_freeN(handles[a].zspan);
2745         }
2746
2747         MEM_freeN(handles);
2748         
2749         BLI_end_threads(&threads);
2750
2751         return vdone;
2752 }
2753
2754 struct Image *RE_bake_shade_get_image(void)
2755 {
2756         return R.bakebuf;
2757 }
2758