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