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