Long waited feature: Render Baking
[blender.git] / source / blender / render / intern / source / zbuf.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, RPW
24  *               2004-2006 Blender Foundation, full recode
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29
30 /*---------------------------------------------------------------------------*/
31 /* Common includes                                                           */
32 /*---------------------------------------------------------------------------*/
33
34 #include <math.h>
35 #include <float.h>
36 #include <stdlib.h>
37 #include <limits.h>
38 #include <string.h>
39
40 #include "BLI_arithb.h"
41 #include "BLI_blenlib.h"
42 #include "BLI_threads.h"
43 #include "BLI_jitter.h"
44
45 #include "MTC_matrixops.h"
46 #include "MEM_guardedalloc.h"
47
48 #include "DNA_lamp_types.h"
49 #include "DNA_mesh_types.h"
50 #include "DNA_node_types.h"
51 #include "DNA_meshdata_types.h"
52
53 #include "BKE_global.h"
54 #include "BKE_utildefines.h"
55
56 #include "radio_types.h"
57 #include "radio.h"  /* needs RG, some root data for radiosity */
58
59 #include "RE_render_ext.h"
60
61 /* local includes */
62 #include "gammaCorrectionTables.h"
63 #include "pixelblending.h"
64 #include "render_types.h"
65 #include "renderpipeline.h"
66 #include "renderdatabase.h"
67 #include "rendercore.h"
68 #include "shadbuf.h"
69
70 /* own includes */
71 #include "zbuf.h"
72
73 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
74 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
75 /* only to be used here in this file, it's for speed */
76 extern struct Render R;
77 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
78
79
80 /* ****************** Spans ******************************* */
81
82 /* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */
83 void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty)
84 {
85         memset(zspan, 0, sizeof(ZSpan));
86         
87         zspan->rectx= rectx;
88         zspan->recty= recty;
89         
90         zspan->span1= MEM_mallocN(recty*sizeof(float), "zspan");
91         zspan->span2= MEM_mallocN(recty*sizeof(float), "zspan");
92 }
93
94 void zbuf_free_span(ZSpan *zspan)
95 {
96         if(zspan) {
97                 if(zspan->span1) MEM_freeN(zspan->span1);
98                 if(zspan->span2) MEM_freeN(zspan->span2);
99                 zspan->span1= zspan->span2= NULL;
100         }
101 }
102
103 /* reset range for clipping */
104 static void zbuf_init_span(ZSpan *zspan)
105 {
106         zspan->miny1= zspan->miny2= zspan->recty+1;
107         zspan->maxy1= zspan->maxy2= -1;
108         zspan->minp1= zspan->maxp1= zspan->minp2= zspan->maxp2= NULL;
109 }
110
111 static void zbuf_add_to_span(ZSpan *zspan, float *v1, float *v2)
112 {
113         float *minv, *maxv, *span;
114         float xx1, dx0, xs0;
115         int y, my0, my2;
116         
117         if(v1[1]<v2[1]) {
118                 minv= v1; maxv= v2;
119         }
120         else {
121                 minv= v2; maxv= v1;
122         }
123         
124         my0= ceil(minv[1]);
125         my2= floor(maxv[1]);
126         
127         if(my2<0 || my0>= zspan->recty) return;
128         
129         /* clip top */
130         if(my2>=zspan->recty) my2= zspan->recty-1;
131         /* clip bottom */
132         if(my0<0) my0= 0;
133         
134         if(my0>my2) return;
135         /* if(my0>my2) should still fill in, that way we get spans that skip nicely */
136         
137         xx1= maxv[1]-minv[1];
138         if(xx1>FLT_EPSILON) {
139                 dx0= (minv[0]-maxv[0])/xx1;
140                 xs0= dx0*(minv[1]-my2) + minv[0];
141         }
142         else {
143                 dx0= 0.0f;
144                 xs0= MIN2(minv[0],maxv[0]);
145         }
146         
147         /* empty span */
148         if(zspan->maxp1 == NULL) {
149                 span= zspan->span1;
150         }
151         else {  /* does it complete left span? */
152                 if( maxv == zspan->minp1 || minv==zspan->maxp1) {
153                         span= zspan->span1;
154                 }
155                 else {
156                         span= zspan->span2;
157                 }
158         }
159
160         if(span==zspan->span1) {
161 //              printf("left span my0 %d my2 %d\n", my0, my2);
162                 if(zspan->minp1==NULL || zspan->minp1[1] > minv[1] ) {
163                         zspan->minp1= minv;
164                 }
165                 if(zspan->maxp1==NULL || zspan->maxp1[1] < maxv[1] ) {
166                         zspan->maxp1= maxv;
167                 }
168                 if(my0<zspan->miny1) zspan->miny1= my0;
169                 if(my2>zspan->maxy1) zspan->maxy1= my2;
170         }
171         else {
172 //              printf("right span my0 %d my2 %d\n", my0, my2);
173                 if(zspan->minp2==NULL || zspan->minp2[1] > minv[1] ) {
174                         zspan->minp2= minv;
175                 }
176                 if(zspan->maxp2==NULL || zspan->maxp2[1] < maxv[1] ) {
177                         zspan->maxp2= maxv;
178                 }
179                 if(my0<zspan->miny2) zspan->miny2= my0;
180                 if(my2>zspan->maxy2) zspan->maxy2= my2;
181         }
182
183         for(y=my2; y>=my0; y--, xs0+= dx0) {
184                 /* xs0 is the xcoord! */
185                 span[y]= xs0;
186         }
187 }
188
189 /*-----------------------------------------------------------*/ 
190 /* Functions                                                 */
191 /*-----------------------------------------------------------*/ 
192
193
194 void fillrect(int *rect, int x, int y, int val)
195 {
196         int len, *drect;
197
198         len= x*y;
199         drect= rect;
200         while(len>0) {
201                 len--;
202                 *drect= val;
203                 drect++;
204         }
205 }
206
207 /* based on Liang&Barsky, for clipping of pyramidical volume */
208 static short cliptestf(float p, float q, float *u1, float *u2)
209 {
210         float r;
211         
212         if(p<0.0) {
213                 if(q<p) return 0;
214                 else if(q<0.0) {
215                         r= q/p;
216                         if(r>*u2) return 0;
217                         else if(r>*u1) *u1=r;
218                 }
219         }
220         else {
221                 if(p>0.0) {
222                         if(q<0.0) return 0;
223                         else if(q<p) {
224                                 r= q/p;
225                                 if(r<*u1) return 0;
226                                 else if(r<*u2) *u2=r;
227                         }
228                 }
229                 else if(q<0.0) return 0;
230         }
231         return 1;
232 }
233
234 int testclip(float *v)
235 {
236         float abs4;     /* WATCH IT: this function should do the same as cliptestf, otherwise troubles in zbufclip()*/
237         short c=0;
238         
239         /* if we set clip flags, the clipping should be at least larger than epsilon. 
240            prevents issues with vertices lying exact on borders */
241         abs4= fabs(v[3]) + FLT_EPSILON;
242         
243         if(v[2]< -abs4) c=16;                   /* this used to be " if(v[2]<0) ", see clippz() */
244         else if(v[2]> abs4) c+= 32;
245         
246         if( v[0]>abs4) c+=2;
247         else if( v[0]< -abs4) c+=1;
248         
249         if( v[1]>abs4) c+=4;
250         else if( v[1]< -abs4) c+=8;
251         
252         return c;
253 }
254
255
256
257 /* *************  ACCUMULATION ZBUF ************ */
258
259
260 static APixstr *addpsmainA(ListBase *lb)
261 {
262         APixstrMain *psm;
263
264         psm= MEM_mallocN(sizeof(APixstrMain), "addpsmainA");
265         BLI_addtail(lb, psm);
266         psm->ps= MEM_callocN(4096*sizeof(APixstr),"pixstr");
267
268         return psm->ps;
269 }
270
271 static void freepsA(ListBase *lb)
272 {
273         APixstrMain *psm, *psmnext;
274
275         for(psm= lb->first; psm; psm= psmnext) {
276                 psmnext= psm->next;
277                 if(psm->ps)
278                         MEM_freeN(psm->ps);
279                 MEM_freeN(psm);
280         }
281 }
282
283 static APixstr *addpsA(ZSpan *zspan)
284 {
285         /* make new PS */
286         if(zspan->apsmcounter==0) {
287                 zspan->curpstr= addpsmainA(zspan->apsmbase);
288                 zspan->apsmcounter= 4095;
289         }
290         else {
291                 zspan->curpstr++;
292                 zspan->apsmcounter--;
293         }
294         return zspan->curpstr;
295 }
296
297 static void zbuffillAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
298 {
299         APixstr *ap, *apofs, *apn;
300         double zxd, zyd, zy0, zverg;
301         float x0,y0,z0;
302         float x1,y1,z1,x2,y2,z2,xx1;
303         float *span1, *span2;
304         int *rz, x, y;
305         int sn1, sn2, rectx, *rectzofs, my0, my2, mask;
306         
307         /* init */
308         zbuf_init_span(zspan);
309         
310         /* set spans */
311         zbuf_add_to_span(zspan, v1, v2);
312         zbuf_add_to_span(zspan, v2, v3);
313         if(v4) {
314                 zbuf_add_to_span(zspan, v3, v4);
315                 zbuf_add_to_span(zspan, v4, v1);
316         }
317         else
318                 zbuf_add_to_span(zspan, v3, v1);
319         
320         /* clipped */
321         if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
322
323         if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
324         if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
325         
326         if(my2<my0) return;
327         
328         /* ZBUF DX DY, in floats still */
329         x1= v1[0]- v2[0];
330         x2= v2[0]- v3[0];
331         y1= v1[1]- v2[1];
332         y2= v2[1]- v3[1];
333         z1= v1[2]- v2[2];
334         z2= v2[2]- v3[2];
335         x0= y1*z2-z1*y2;
336         y0= z1*x2-x1*z2;
337         z0= x1*y2-y1*x2;
338         
339         if(z0==0.0) return;
340         
341         xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
342         
343         zxd= -(double)x0/(double)z0;
344         zyd= -(double)y0/(double)z0;
345         zy0= ((double)my2)*zyd + (double)xx1;
346         
347         /* start-offset in rect */
348         rectx= zspan->rectx;
349         rectzofs= (int *)(zspan->arectz+rectx*(my2));
350         apofs= (zspan->apixbuf+ rectx*(my2));
351         mask= zspan->mask;
352
353         /* correct span */
354         sn1= (my0 + my2)/2;
355         if(zspan->span1[sn1] < zspan->span2[sn1]) {
356                 span1= zspan->span1+my2;
357                 span2= zspan->span2+my2;
358         }
359         else {
360                 span1= zspan->span2+my2;
361                 span2= zspan->span1+my2;
362         }
363         
364         for(y=my2; y>=my0; y--, span1--, span2--) {
365                 
366                 sn1= floor(*span1);
367                 sn2= floor(*span2);
368                 sn1++; 
369                 
370                 if(sn2>=rectx) sn2= rectx-1;
371                 if(sn1<0) sn1= 0;
372                 
373                 if(sn2>=sn1) {
374                         zverg= (double)sn1*zxd + zy0;
375                         rz= rectzofs+sn1;
376                         ap= apofs+sn1;
377                         x= sn2-sn1;
378                         
379                         zverg-= zspan->polygon_offset;
380                         
381                         while(x>=0) {
382                                 if( (int)zverg < *rz) {
383 //                                      int i= zvlnr & 3;
384                                         
385                                         apn= ap;
386                                         while(apn) {
387                                                 if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; }
388                                                 if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; }
389                                                 if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; }
390                                                 if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; }
391                                                 if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; }
392                                                 if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
393                                                 if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; }
394                                                 if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
395 //                                              if(apn->p[i]==0) {apn->p[i]= zvlnr; apn->z[i]= zverg; apn->mask[i]= mask; break; }
396 //                                              if(apn->p[i]==zvlnr) {apn->mask[i]|= mask; break; }
397                                                 if(apn->next==NULL) apn->next= addpsA(zspan);
398                                                 apn= apn->next;
399                                         }                               
400                                 }
401                                 zverg+= zxd;
402                                 rz++; 
403                                 ap++; 
404                                 x--;
405                         }
406                 }
407                 
408                 zy0-=zyd;
409                 rectzofs-= rectx;
410                 apofs-= rectx;
411         }
412 }
413
414
415
416 static void zbuflineAc(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
417 {
418         APixstr *ap, *apn;
419         int *rectz;
420         int start, end, x, y, oldx, oldy, ofs;
421         int dz, vergz, mask, maxtest=0;
422         float dx, dy;
423         float v1[3], v2[3];
424         
425         dx= vec2[0]-vec1[0];
426         dy= vec2[1]-vec1[1];
427         
428         mask= zspan->mask;
429         
430         if(fabs(dx) > fabs(dy)) {
431
432                 /* all lines from left to right */
433                 if(vec1[0]<vec2[0]) {
434                         VECCOPY(v1, vec1);
435                         VECCOPY(v2, vec2);
436                 }
437                 else {
438                         VECCOPY(v2, vec1);
439                         VECCOPY(v1, vec2);
440                         dx= -dx; dy= -dy;
441                 }
442
443                 start= floor(v1[0]);
444                 end= start+floor(dx);
445                 if(end>=zspan->rectx) end= zspan->rectx-1;
446                 
447                 oldy= floor(v1[1]);
448                 dy/= dx;
449                 
450                 vergz= v1[2];
451                 vergz-= zspan->polygon_offset;
452                 dz= (v2[2]-v1[2])/dx;
453                 if(vergz>0x50000000 && dz>0) maxtest= 1;                // prevent overflow
454                 
455                 rectz= (int *)(zspan->arectz+zspan->rectx*(oldy) +start);
456                 ap= (zspan->apixbuf+ zspan->rectx*(oldy) +start);
457
458                 if(dy<0) ofs= -zspan->rectx;
459                 else ofs= zspan->rectx;
460                 
461                 for(x= start; x<=end; x++, rectz++, ap++) {
462                         
463                         y= floor(v1[1]);
464                         if(y!=oldy) {
465                                 oldy= y;
466                                 rectz+= ofs;
467                                 ap+= ofs;
468                         }
469                         
470                         if(x>=0 && y>=0 && y<zspan->recty) {
471                                 if(vergz<*rectz) {
472                                 
473                                         apn= ap;
474                                         while(apn) {    /* loop unrolled */
475                                                 if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; }
476                                                 if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; }
477                                                 if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; }
478                                                 if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; }
479                                                 if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; }
480                                                 if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
481                                                 if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
482                                                 if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
483                                                 if(apn->next==0) apn->next= addpsA(zspan);
484                                                 apn= apn->next;
485                                         }                               
486                                         
487                                 }
488                         }
489                         
490                         v1[1]+= dy;
491                         if(maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0;
492                         else vergz+= dz;
493                 }
494         }
495         else {
496         
497                 /* all lines from top to bottom */
498                 if(vec1[1]<vec2[1]) {
499                         VECCOPY(v1, vec1);
500                         VECCOPY(v2, vec2);
501                 }
502                 else {
503                         VECCOPY(v2, vec1);
504                         VECCOPY(v1, vec2);
505                         dx= -dx; dy= -dy;
506                 }
507
508                 start= floor(v1[1]);
509                 end= start+floor(dy);
510                 
511                 if(start>=zspan->recty || end<0) return;
512                 
513                 if(end>=zspan->recty) end= zspan->recty-1;
514                 
515                 oldx= floor(v1[0]);
516                 dx/= dy;
517                 
518                 vergz= v1[2];
519                 vergz-= zspan->polygon_offset;
520                 dz= (v2[2]-v1[2])/dy;
521                 if(vergz>0x50000000 && dz>0) maxtest= 1;                // prevent overflow
522
523                 rectz= (int *)( zspan->arectz+ (start)*zspan->rectx+ oldx );
524                 ap= (zspan->apixbuf+ zspan->rectx*(start) +oldx);
525                                 
526                 if(dx<0) ofs= -1;
527                 else ofs= 1;
528
529                 for(y= start; y<=end; y++, rectz+=zspan->rectx, ap+=zspan->rectx) {
530                         
531                         x= floor(v1[0]);
532                         if(x!=oldx) {
533                                 oldx= x;
534                                 rectz+= ofs;
535                                 ap+= ofs;
536                         }
537                         
538                         if(x>=0 && y>=0 && x<zspan->rectx) {
539                                 if(vergz<*rectz) {
540                                         
541                                         apn= ap;
542                                         while(apn) {    /* loop unrolled */
543                                                 if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; }
544                                                 if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; }
545                                                 if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; }
546                                                 if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; }
547                                                 if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; }
548                                                 if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
549                                                 if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
550                                                 if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
551                                                 if(apn->next==0) apn->next= addpsA(zspan);
552                                                 apn= apn->next;
553                                         }       
554                                         
555                                 }
556                         }
557                         
558                         v1[0]+= dx;
559                         if(maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0;
560                         else vergz+= dz;
561                 }
562         }
563 }
564
565 /* *************  NORMAL ZBUFFER ************ */
566
567 static void zbufline(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
568 {
569         int *rectz, *rectp;
570         int start, end, x, y, oldx, oldy, ofs;
571         int dz, vergz, maxtest= 0;
572         float dx, dy;
573         float v1[3], v2[3];
574         
575         dx= vec2[0]-vec1[0];
576         dy= vec2[1]-vec1[1];
577         
578         if(fabs(dx) > fabs(dy)) {
579
580                 /* all lines from left to right */
581                 if(vec1[0]<vec2[0]) {
582                         VECCOPY(v1, vec1);
583                         VECCOPY(v2, vec2);
584                 }
585                 else {
586                         VECCOPY(v2, vec1);
587                         VECCOPY(v1, vec2);
588                         dx= -dx; dy= -dy;
589                 }
590
591                 start= floor(v1[0]);
592                 end= start+floor(dx);
593                 if(end>=zspan->rectx) end= zspan->rectx-1;
594                 
595                 oldy= floor(v1[1]);
596                 dy/= dx;
597                 
598                 vergz= floor(v1[2]);
599                 dz= floor((v2[2]-v1[2])/dx);
600                 if(vergz>0x50000000 && dz>0) maxtest= 1;                // prevent overflow
601                 
602                 rectz= zspan->rectz + oldy*zspan->rectx+ start;
603                 rectp= zspan->rectp + oldy*zspan->rectx+ start;
604                 
605                 if(dy<0) ofs= -zspan->rectx;
606                 else ofs= zspan->rectx;
607                 
608                 for(x= start; x<=end; x++, rectz++, rectp++) {
609                         
610                         y= floor(v1[1]);
611                         if(y!=oldy) {
612                                 oldy= y;
613                                 rectz+= ofs;
614                                 rectp+= ofs;
615                         }
616                         
617                         if(x>=0 && y>=0 && y<zspan->recty) {
618                                 if(vergz<*rectz) {
619                                         *rectz= vergz;
620                                         *rectp= zvlnr;
621                                 }
622                         }
623                         
624                         v1[1]+= dy;
625                         
626                         if(maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0;
627                         else vergz+= dz;
628                 }
629         }
630         else {
631                 /* all lines from top to bottom */
632                 if(vec1[1]<vec2[1]) {
633                         VECCOPY(v1, vec1);
634                         VECCOPY(v2, vec2);
635                 }
636                 else {
637                         VECCOPY(v2, vec1);
638                         VECCOPY(v1, vec2);
639                         dx= -dx; dy= -dy;
640                 }
641
642                 start= floor(v1[1]);
643                 end= start+floor(dy);
644                 
645                 if(end>=zspan->recty) end= zspan->recty-1;
646                 
647                 oldx= floor(v1[0]);
648                 dx/= dy;
649                 
650                 vergz= floor(v1[2]);
651                 dz= floor((v2[2]-v1[2])/dy);
652                 if(vergz>0x50000000 && dz>0) maxtest= 1;                // prevent overflow
653                 
654                 rectz= zspan->rectz + start*zspan->rectx+ oldx;
655                 rectp= zspan->rectp + start*zspan->rectx+ oldx;
656                 
657                 if(dx<0) ofs= -1;
658                 else ofs= 1;
659
660                 for(y= start; y<=end; y++, rectz+=zspan->rectx, rectp+=zspan->rectx) {
661                         
662                         x= floor(v1[0]);
663                         if(x!=oldx) {
664                                 oldx= x;
665                                 rectz+= ofs;
666                                 rectp+= ofs;
667                         }
668                         
669                         if(x>=0 && y>=0 && x<zspan->rectx) {
670                                 if(vergz<*rectz) {
671                                         *rectz= vergz;
672                                         *rectp= zvlnr;
673                                 }
674                         }
675                         
676                         v1[0]+= dx;
677                         if(maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0;
678                         else vergz+= dz;
679                 }
680         }
681 }
682
683 static void zbufline_onlyZ(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
684 {
685         int *rectz, *rectz1= NULL;
686         int start, end, x, y, oldx, oldy, ofs;
687         int dz, vergz, maxtest= 0;
688         float dx, dy;
689         float v1[3], v2[3];
690         
691         dx= vec2[0]-vec1[0];
692         dy= vec2[1]-vec1[1];
693         
694         if(fabs(dx) > fabs(dy)) {
695                 
696                 /* all lines from left to right */
697                 if(vec1[0]<vec2[0]) {
698                         VECCOPY(v1, vec1);
699                         VECCOPY(v2, vec2);
700                 }
701                 else {
702                         VECCOPY(v2, vec1);
703                         VECCOPY(v1, vec2);
704                         dx= -dx; dy= -dy;
705                 }
706                 
707                 start= floor(v1[0]);
708                 end= start+floor(dx);
709                 if(end>=zspan->rectx) end= zspan->rectx-1;
710                 
711                 oldy= floor(v1[1]);
712                 dy/= dx;
713                 
714                 vergz= floor(v1[2]);
715                 dz= floor((v2[2]-v1[2])/dx);
716                 if(vergz>0x50000000 && dz>0) maxtest= 1;                // prevent overflow
717                 
718                 rectz= zspan->rectz + oldy*zspan->rectx+ start;
719                 if(zspan->rectz1)
720                         rectz1= zspan->rectz1 + oldy*zspan->rectx+ start;
721                 
722                 if(dy<0) ofs= -zspan->rectx;
723                 else ofs= zspan->rectx;
724                 
725                 for(x= start; x<=end; x++, rectz++) {
726                         
727                         y= floor(v1[1]);
728                         if(y!=oldy) {
729                                 oldy= y;
730                                 rectz+= ofs;
731                                 if(rectz1) rectz1+= ofs;
732                         }
733                         
734                         if(x>=0 && y>=0 && y<zspan->recty) {
735                                 if(vergz < *rectz) {
736                                         if(rectz1) *rectz1= *rectz;
737                                         *rectz= vergz;
738                                 }
739                                 else if(rectz1 && vergz < *rectz1)
740                                         *rectz1= vergz;
741                         }
742                         
743                         v1[1]+= dy;
744                         
745                         if(maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0;
746                         else vergz+= dz;
747                         
748                         if(rectz1) rectz1++;
749                 }
750         }
751         else {
752                 /* all lines from top to bottom */
753                 if(vec1[1]<vec2[1]) {
754                         VECCOPY(v1, vec1);
755                         VECCOPY(v2, vec2);
756                 }
757                 else {
758                         VECCOPY(v2, vec1);
759                         VECCOPY(v1, vec2);
760                         dx= -dx; dy= -dy;
761                 }
762                 
763                 start= floor(v1[1]);
764                 end= start+floor(dy);
765                 
766                 if(end>=zspan->recty) end= zspan->recty-1;
767                 
768                 oldx= floor(v1[0]);
769                 dx/= dy;
770                 
771                 vergz= floor(v1[2]);
772                 dz= floor((v2[2]-v1[2])/dy);
773                 if(vergz>0x50000000 && dz>0) maxtest= 1;                // prevent overflow
774                 
775                 rectz= zspan->rectz + start*zspan->rectx+ oldx;
776                 if(zspan->rectz1)
777                         rectz1= zspan->rectz1 + start*zspan->rectx+ oldx;
778                 
779                 if(dx<0) ofs= -1;
780                 else ofs= 1;
781                 
782                 for(y= start; y<=end; y++, rectz+=zspan->rectx) {
783                         
784                         x= floor(v1[0]);
785                         if(x!=oldx) {
786                                 oldx= x;
787                                 rectz+= ofs;
788                                 if(rectz1) rectz1+= ofs;
789                         }
790                         
791                         if(x>=0 && y>=0 && x<zspan->rectx) {
792                                 if(vergz < *rectz) {
793                                         if(rectz1) *rectz1= *rectz;
794                                         *rectz= vergz;
795                                 }
796                                 else if(rectz1 && vergz < *rectz1)
797                                         *rectz1= vergz;
798                         }
799                         
800                         v1[0]+= dx;
801                         if(maxtest && (vergz > 0x7FFFFFF0 - dz)) vergz= 0x7FFFFFF0;
802                         else vergz+= dz;
803                         
804                         if(rectz1)
805                                 rectz1+=zspan->rectx;
806                 }
807         }
808 }
809
810
811 static int clipline(float *v1, float *v2)       /* return 0: do not draw */
812 {
813         float dz,dw, u1=0.0, u2=1.0;
814         float dx, dy, v13;
815         
816         dz= v2[2]-v1[2];
817         dw= v2[3]-v1[3];
818         
819         /* this 1.01 is for clipping x and y just a tinsy larger. that way it is
820                 filled in with zbufwire correctly when rendering in parts. otherwise
821                 you see line endings at edges... */
822         
823         if(cliptestf(-dz-dw, v1[3]+v1[2], &u1,&u2)) {
824                 if(cliptestf(dz-dw, v1[3]-v1[2], &u1,&u2)) {
825                         
826                         dx= v2[0]-v1[0];
827                         dz= 1.01*(v2[3]-v1[3]);
828                         v13= 1.01*v1[3];
829                         
830                         if(cliptestf(-dx-dz, v1[0]+v13, &u1,&u2)) {
831                                 if(cliptestf(dx-dz, v13-v1[0], &u1,&u2)) {
832                                         
833                                         dy= v2[1]-v1[1];
834                                         
835                                         if(cliptestf(-dy-dz, v1[1]+v13, &u1,&u2)) {
836                                                 if(cliptestf(dy-dz, v13-v1[1], &u1,&u2)) {
837                                                         
838                                                         if(u2<1.0) {
839                                                                 v2[0]= v1[0]+u2*dx;
840                                                                 v2[1]= v1[1]+u2*dy;
841                                                                 v2[2]= v1[2]+u2*dz;
842                                                                 v2[3]= v1[3]+u2*dw;
843                                                         }
844                                                         if(u1>0.0) {
845                                                                 v1[0]= v1[0]+u1*dx;
846                                                                 v1[1]= v1[1]+u1*dy;
847                                                                 v1[2]= v1[2]+u1*dz;
848                                                                 v1[3]= v1[3]+u1*dw;
849                                                         }
850                                                         return 1;
851                                                 }
852                                         }
853                                 }
854                         }
855                 }
856         }
857         
858         return 0;
859 }
860
861 static void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco)
862 {
863         float div;
864         
865         div= 1.0f/hoco[3];
866         zco[0]= zspan->zmulx*(1.0+hoco[0]*div) + zspan->zofsx;
867         zco[1]= zspan->zmuly*(1.0+hoco[1]*div) + zspan->zofsy;
868         zco[2]= 0x7FFFFFFF *(hoco[2]*div);
869 }
870
871 void zbufclipwire(ZSpan *zspan, int zvlnr, VlakRen *vlr)
872 {
873         float vez[20], *f1, *f2, *f3, *f4= 0;
874         int c1, c2, c3, c4, ec, and, or;
875
876         /* edgecode: 1= draw */
877         ec = vlr->ec;
878         if(ec==0) return;
879
880         c1= vlr->v1->clip;
881         c2= vlr->v2->clip;
882         c3= vlr->v3->clip;
883         f1= vlr->v1->ho;
884         f2= vlr->v2->ho;
885         f3= vlr->v3->ho;
886         
887         if(vlr->v4) {
888                 f4= vlr->v4->ho;
889                 c4= vlr->v4->clip;
890                 
891                 and= (c1 & c2 & c3 & c4);
892                 or= (c1 | c2 | c3 | c4);
893         }
894         else {
895                 and= (c1 & c2 & c3);
896                 or= (c1 | c2 | c3);
897         }
898         
899         if(or) {        /* not in the middle */
900                 if(and) {       /* out completely */
901                         return;
902                 }
903                 else {  /* clipping */
904
905                         if(ec & ME_V1V2) {
906                                 QUATCOPY(vez, f1);
907                                 QUATCOPY(vez+4, f2);
908                                 if( clipline(vez, vez+4)) {
909                                         hoco_to_zco(zspan, vez, vez);
910                                         hoco_to_zco(zspan, vez+4, vez+4);
911                                         zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
912                                 }
913                         }
914                         if(ec & ME_V2V3) {
915                                 QUATCOPY(vez, f2);
916                                 QUATCOPY(vez+4, f3);
917                                 if( clipline(vez, vez+4)) {
918                                         hoco_to_zco(zspan, vez, vez);
919                                         hoco_to_zco(zspan, vez+4, vez+4);
920                                         zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
921                                 }
922                         }
923                         if(vlr->v4) {
924                                 if(ec & ME_V3V4) {
925                                         QUATCOPY(vez, f3);
926                                         QUATCOPY(vez+4, f4);
927                                         if( clipline(vez, vez+4)) {
928                                                 hoco_to_zco(zspan, vez, vez);
929                                                 hoco_to_zco(zspan, vez+4, vez+4);
930                                                 zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
931                                         }
932                                 }
933                                 if(ec & ME_V4V1) {
934                                         QUATCOPY(vez, f4);
935                                         QUATCOPY(vez+4, f1);
936                                         if( clipline(vez, vez+4)) {
937                                                 hoco_to_zco(zspan, vez, vez);
938                                                 hoco_to_zco(zspan, vez+4, vez+4);
939                                                 zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
940                                         }
941                                 }
942                         }
943                         else {
944                                 if(ec & ME_V3V1) {
945                                         QUATCOPY(vez, f3);
946                                         QUATCOPY(vez+4, f1);
947                                         if( clipline(vez, vez+4)) {
948                                                 hoco_to_zco(zspan, vez, vez);
949                                                 hoco_to_zco(zspan, vez+4, vez+4);
950                                                 zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
951                                         }
952                                 }
953                         }
954                         
955                         return;
956                 }
957         }
958
959         hoco_to_zco(zspan, vez, f1);
960         hoco_to_zco(zspan, vez+4, f2);
961         hoco_to_zco(zspan, vez+8, f3);
962         if(vlr->v4) {
963                 hoco_to_zco(zspan, vez+12, f4);
964
965                 if(ec & ME_V3V4)  zspan->zbuflinefunc(zspan, zvlnr, vez+8, vez+12);
966                 if(ec & ME_V4V1)  zspan->zbuflinefunc(zspan, zvlnr, vez+12, vez);
967         }
968         else {
969                 if(ec & ME_V3V1)  zspan->zbuflinefunc(zspan, zvlnr, vez+8, vez);
970         }
971
972         if(ec & ME_V1V2)  zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
973         if(ec & ME_V2V3)  zspan->zbuflinefunc(zspan, zvlnr, vez+4, vez+8);
974
975 }
976
977 /**
978  * Fill the z buffer, but invert z order, and add the face index to
979  * the corresponing face buffer.
980  *
981  * This is one of the z buffer fill functions called in zbufclip() and
982  * zbufwireclip(). 
983  *
984  * @param v1 [4 floats, world coordinates] first vertex
985  * @param v2 [4 floats, world coordinates] second vertex
986  * @param v3 [4 floats, world coordinates] third vertex
987  */
988 static void zbuffillGLinv4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4) 
989 {
990         double zxd, zyd, zy0, zverg;
991         float x0,y0,z0;
992         float x1,y1,z1,x2,y2,z2,xx1;
993         float *span1, *span2;
994         int *rectpofs, *rp;
995         int *rz, x, y;
996         int sn1, sn2, rectx, *rectzofs, my0, my2;
997         
998         /* init */
999         zbuf_init_span(zspan);
1000         
1001         /* set spans */
1002         zbuf_add_to_span(zspan, v1, v2);
1003         zbuf_add_to_span(zspan, v2, v3);
1004         if(v4) {
1005                 zbuf_add_to_span(zspan, v3, v4);
1006                 zbuf_add_to_span(zspan, v4, v1);
1007         }
1008         else 
1009                 zbuf_add_to_span(zspan, v3, v1);
1010         
1011         /* clipped */
1012         if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
1013         
1014         if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
1015         if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
1016         
1017         //      printf("my %d %d\n", my0, my2);
1018         if(my2<my0) return;
1019         
1020         
1021         /* ZBUF DX DY, in floats still */
1022         x1= v1[0]- v2[0];
1023         x2= v2[0]- v3[0];
1024         y1= v1[1]- v2[1];
1025         y2= v2[1]- v3[1];
1026         z1= v1[2]- v2[2];
1027         z2= v2[2]- v3[2];
1028         x0= y1*z2-z1*y2;
1029         y0= z1*x2-x1*z2;
1030         z0= x1*y2-y1*x2;
1031         
1032         if(z0==0.0) return;
1033         
1034         xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
1035         
1036         zxd= -(double)x0/(double)z0;
1037         zyd= -(double)y0/(double)z0;
1038         zy0= ((double)my2)*zyd + (double)xx1;
1039         
1040         /* start-offset in rect */
1041         rectx= zspan->rectx;
1042         rectzofs= (zspan->rectz+rectx*my2);
1043         rectpofs= (zspan->rectp+rectx*my2);
1044         
1045         /* correct span */
1046         sn1= (my0 + my2)/2;
1047         if(zspan->span1[sn1] < zspan->span2[sn1]) {
1048                 span1= zspan->span1+my2;
1049                 span2= zspan->span2+my2;
1050         }
1051         else {
1052                 span1= zspan->span2+my2;
1053                 span2= zspan->span1+my2;
1054         }
1055         
1056         for(y=my2; y>=my0; y--, span1--, span2--) {
1057                 
1058                 sn1= floor(*span1);
1059                 sn2= floor(*span2);
1060                 sn1++; 
1061                 
1062                 if(sn2>=rectx) sn2= rectx-1;
1063                 if(sn1<0) sn1= 0;
1064                 
1065                 if(sn2>=sn1) {
1066                         zverg= (double)sn1*zxd + zy0;
1067                         rz= rectzofs+sn1;
1068                         rp= rectpofs+sn1;
1069                         x= sn2-sn1;
1070                         
1071                         while(x>=0) {
1072                                 if( (int)zverg > *rz || *rz==0x7FFFFFFF) {
1073                                         *rz= (int)zverg;
1074                                         *rp= zvlnr;
1075                                 }
1076                                 zverg+= zxd;
1077                                 rz++; 
1078                                 rp++; 
1079                                 x--;
1080                         }
1081                 }
1082                 
1083                 zy0-=zyd;
1084                 rectzofs-= rectx;
1085                 rectpofs-= rectx;
1086         }
1087 }
1088
1089 /* uses spanbuffers */
1090
1091 static void zbuffillGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
1092 {
1093         double zxd, zyd, zy0, zverg;
1094         float x0,y0,z0;
1095         float x1,y1,z1,x2,y2,z2,xx1;
1096         float *span1, *span2;
1097         int *rectpofs, *rp;
1098         int *rz, x, y;
1099         int sn1, sn2, rectx, *rectzofs, my0, my2;
1100         
1101         /* init */
1102         zbuf_init_span(zspan);
1103         
1104         /* set spans */
1105         zbuf_add_to_span(zspan, v1, v2);
1106         zbuf_add_to_span(zspan, v2, v3);
1107         if(v4) {
1108                 zbuf_add_to_span(zspan, v3, v4);
1109                 zbuf_add_to_span(zspan, v4, v1);
1110         }
1111         else 
1112                 zbuf_add_to_span(zspan, v3, v1);
1113                 
1114         /* clipped */
1115         if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
1116         
1117         if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
1118         if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
1119         
1120 //      printf("my %d %d\n", my0, my2);
1121         if(my2<my0) return;
1122         
1123         
1124         /* ZBUF DX DY, in floats still */
1125         x1= v1[0]- v2[0];
1126         x2= v2[0]- v3[0];
1127         y1= v1[1]- v2[1];
1128         y2= v2[1]- v3[1];
1129         z1= v1[2]- v2[2];
1130         z2= v2[2]- v3[2];
1131         x0= y1*z2-z1*y2;
1132         y0= z1*x2-x1*z2;
1133         z0= x1*y2-y1*x2;
1134         
1135         if(z0==0.0) return;
1136
1137         xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
1138
1139         zxd= -(double)x0/(double)z0;
1140         zyd= -(double)y0/(double)z0;
1141         zy0= ((double)my2)*zyd + (double)xx1;
1142
1143         /* start-offset in rect */
1144         rectx= zspan->rectx;
1145         rectzofs= (zspan->rectz+rectx*my2);
1146         rectpofs= (zspan->rectp+rectx*my2);
1147
1148         /* correct span */
1149         sn1= (my0 + my2)/2;
1150         if(zspan->span1[sn1] < zspan->span2[sn1]) {
1151                 span1= zspan->span1+my2;
1152                 span2= zspan->span2+my2;
1153         }
1154         else {
1155                 span1= zspan->span2+my2;
1156                 span2= zspan->span1+my2;
1157         }
1158         
1159         for(y=my2; y>=my0; y--, span1--, span2--) {
1160                 
1161                 sn1= floor(*span1);
1162                 sn2= floor(*span2);
1163                 sn1++; 
1164                 
1165                 if(sn2>=rectx) sn2= rectx-1;
1166                 if(sn1<0) sn1= 0;
1167                 
1168                 if(sn2>=sn1) {
1169                         zverg= (double)sn1*zxd + zy0;
1170                         rz= rectzofs+sn1;
1171                         rp= rectpofs+sn1;
1172                         x= sn2-sn1;
1173                         
1174                         while(x>=0) {
1175                                 if( (int)zverg < *rz) {
1176                                         *rz= (int)zverg;
1177                                         *rp= zvlnr;
1178                                 }
1179                                 zverg+= zxd;
1180                                 rz++; 
1181                                 rp++; 
1182                                 x--;
1183                         }
1184                 }
1185                 
1186                 zy0-=zyd;
1187                 rectzofs-= rectx;
1188                 rectpofs-= rectx;
1189         }
1190 }
1191
1192 /**
1193  * Fill the z buffer. The face buffer is not operated on!
1194  *
1195  * This is one of the z buffer fill functions called in zbufclip() and
1196  * zbufwireclip(). 
1197  *
1198  * @param v1 [4 floats, world coordinates] first vertex
1199  * @param v2 [4 floats, world coordinates] second vertex
1200  * @param v3 [4 floats, world coordinates] third vertex
1201  */
1202
1203 /* now: filling two Z values, the closest and 2nd closest */
1204 static void zbuffillGL_onlyZ(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4) 
1205 {
1206         double zxd, zyd, zy0, zverg;
1207         float x0,y0,z0;
1208         float x1,y1,z1,x2,y2,z2,xx1;
1209         float *span1, *span2;
1210         int *rz, *rz1, x, y;
1211         int sn1, sn2, rectx, *rectzofs, *rectzofs1= NULL, my0, my2;
1212         
1213         /* init */
1214         zbuf_init_span(zspan);
1215         
1216         /* set spans */
1217         zbuf_add_to_span(zspan, v1, v2);
1218         zbuf_add_to_span(zspan, v2, v3);
1219         if(v4) {
1220                 zbuf_add_to_span(zspan, v3, v4);
1221                 zbuf_add_to_span(zspan, v4, v1);
1222         }
1223         else 
1224                 zbuf_add_to_span(zspan, v3, v1);
1225         
1226         /* clipped */
1227         if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
1228         
1229         if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
1230         if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
1231         
1232         //      printf("my %d %d\n", my0, my2);
1233         if(my2<my0) return;
1234         
1235         
1236         /* ZBUF DX DY, in floats still */
1237         x1= v1[0]- v2[0];
1238         x2= v2[0]- v3[0];
1239         y1= v1[1]- v2[1];
1240         y2= v2[1]- v3[1];
1241         z1= v1[2]- v2[2];
1242         z2= v2[2]- v3[2];
1243         x0= y1*z2-z1*y2;
1244         y0= z1*x2-x1*z2;
1245         z0= x1*y2-y1*x2;
1246         
1247         if(z0==0.0) return;
1248         
1249         xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
1250         
1251         zxd= -(double)x0/(double)z0;
1252         zyd= -(double)y0/(double)z0;
1253         zy0= ((double)my2)*zyd + (double)xx1;
1254         
1255         /* start-offset in rect */
1256         rectx= zspan->rectx;
1257         rectzofs= (zspan->rectz+rectx*my2);
1258         if(zspan->rectz1)
1259                 rectzofs1= (zspan->rectz1+rectx*my2);
1260         
1261         /* correct span */
1262         sn1= (my0 + my2)/2;
1263         if(zspan->span1[sn1] < zspan->span2[sn1]) {
1264                 span1= zspan->span1+my2;
1265                 span2= zspan->span2+my2;
1266         }
1267         else {
1268                 span1= zspan->span2+my2;
1269                 span2= zspan->span1+my2;
1270         }
1271         
1272         for(y=my2; y>=my0; y--, span1--, span2--) {
1273                 
1274                 sn1= floor(*span1);
1275                 sn2= floor(*span2);
1276                 sn1++; 
1277                 
1278                 if(sn2>=rectx) sn2= rectx-1;
1279                 if(sn1<0) sn1= 0;
1280                 
1281                 if(sn2>=sn1) {
1282                         zverg= (double)sn1*zxd + zy0;
1283                         rz= rectzofs+sn1;
1284                         rz1= rectzofs1+sn1;
1285                         x= sn2-sn1;
1286                         
1287                         while(x>=0) {
1288                                 int zvergi= (int)zverg;
1289                                 /* option: maintain two depth values, closest and 2nd closest */
1290                                 if(zvergi < *rz) {
1291                                         if(rectzofs1) *rz1= *rz;
1292                                         *rz= zvergi;
1293                                 }
1294                                 else if(rectzofs1 && zvergi < *rz1)
1295                                         *rz1= zvergi;
1296
1297                                 zverg+= zxd;
1298                                 
1299                                 rz++; 
1300                                 rz1++;
1301                                 x--;
1302                         }
1303                 }
1304                 
1305                 zy0-=zyd;
1306                 rectzofs-= rectx;
1307                 if(rectzofs1) rectzofs1-= rectx;
1308         }
1309 }
1310
1311 /* 2d scanconvert for tria, calls func for each x,y coordinate and gives UV barycentrics */
1312 /* zspan should be initialized, has rect size and span buffers */
1313
1314 void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float) )
1315 {
1316         float x0, y0, x1, y1, x2, y2, z0, z1, z2;
1317         float u, v, uxd, uyd, vxd, vyd, uy0, vy0, xx1;
1318         float *span1, *span2;
1319         int x, y, sn1, sn2, rectx= zspan->rectx, my0, my2;
1320         
1321         /* init */
1322         zbuf_init_span(zspan);
1323         
1324         /* set spans */
1325         zbuf_add_to_span(zspan, v1, v2);
1326         zbuf_add_to_span(zspan, v2, v3);
1327         zbuf_add_to_span(zspan, v3, v1);
1328         
1329         /* clipped */
1330         if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
1331         
1332         if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
1333         if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
1334         
1335         //      printf("my %d %d\n", my0, my2);
1336         if(my2<my0) return;
1337         
1338         /* ZBUF DX DY, in floats still */
1339         x1= v1[0]- v2[0];
1340         x2= v2[0]- v3[0];
1341         y1= v1[1]- v2[1];
1342         y2= v2[1]- v3[1];
1343         
1344         z1= 1.0f; // (u1 - u2)
1345         z2= 0.0f; // (u2 - u3)
1346         
1347         x0= y1*z2-z1*y2;
1348         y0= z1*x2-x1*z2;
1349         z0= x1*y2-y1*x2;
1350         
1351         if(z0==0.0f) return;
1352         
1353         xx1= (x0*v1[0] + y0*v1[1])/z0 + 1.0f;   
1354         uxd= -(double)x0/(double)z0;
1355         uyd= -(double)y0/(double)z0;
1356         uy0= ((double)my2)*uyd + (double)xx1;
1357
1358         z1= -1.0f; // (v1 - v2)
1359         z2= 1.0f;  // (v2 - v3)
1360         
1361         x0= y1*z2-z1*y2;
1362         y0= z1*x2-x1*z2;
1363         
1364         xx1= (x0*v1[0] + y0*v1[1])/z0;
1365         vxd= -(double)x0/(double)z0;
1366         vyd= -(double)y0/(double)z0;
1367         vy0= ((double)my2)*vyd + (double)xx1;
1368         
1369         /* correct span */
1370         sn1= (my0 + my2)/2;
1371         if(zspan->span1[sn1] < zspan->span2[sn1]) {
1372                 span1= zspan->span1+my2;
1373                 span2= zspan->span2+my2;
1374         }
1375         else {
1376                 span1= zspan->span2+my2;
1377                 span2= zspan->span1+my2;
1378         }
1379         
1380         for(y=my2; y>=my0; y--, span1--, span2--) {
1381                 
1382                 sn1= floor(*span1);
1383                 sn2= floor(*span2);
1384                 sn1++; 
1385                 
1386                 if(sn2>=rectx) sn2= rectx-1;
1387                 if(sn1<0) sn1= 0;
1388                 
1389                 u= (double)sn1*uxd + uy0;
1390                 v= (double)sn1*vxd + vy0;
1391                 
1392                 for(x= sn1; x<=sn2; x++, u+=uxd, v+=vxd)
1393                         func(handle, x, y, u, v);
1394                 
1395                 uy0 -= uyd;
1396                 vy0 -= vyd;
1397         }
1398 }
1399
1400
1401
1402 /**
1403  * (clip pyramid)
1404  * Sets labda: flag, and parametrize the clipping of vertices in
1405  * viewspace coordinates. labda = -1 means no clipping, labda in [0,
1406          * 1] means a clipping.
1407  * Note: uses globals.
1408  * @param v1 start coordinate s
1409  * @param v2 target coordinate t
1410  * @param b1 
1411  * @param b2 
1412  * @param b3
1413  * @param a index for coordinate (x, y, or z)
1414  */
1415
1416 static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a)
1417 {
1418         float da,dw,u1=0.0,u2=1.0;
1419         float v13;
1420         
1421         labda[0]= -1.0;
1422         labda[1]= -1.0;
1423
1424         da= v2[a]-v1[a];
1425         /* prob; we clip slightly larger, osa renders add 2 pixels on edges, should become variable? */
1426         /* or better; increase r.winx/y size, but thats quite a complex one. do it later */
1427         if(a==2) {
1428                 dw= (v2[3]-v1[3]);
1429                 v13= v1[3];
1430         }
1431         else {
1432                 /* XXXXX EVIL! this is a R global, whilst this function can be called for shadow, before R was set */
1433                 dw= R.clipcrop*(v2[3]-v1[3]);
1434                 v13= R.clipcrop*v1[3];
1435         }       
1436         /* according the original article by Liang&Barsky, for clipping of
1437          * homogenous coordinates with viewplane, the value of "0" is used instead of "-w" .
1438          * This differs from the other clipping cases (like left or top) and I considered
1439          * it to be not so 'homogenic'. But later it has proven to be an error,
1440          * who would have thought that of L&B!
1441          */
1442
1443         if(cliptestf(-da-dw, v13+v1[a], &u1,&u2)) {
1444                 if(cliptestf(da-dw, v13-v1[a], &u1,&u2)) {
1445                         *b3=1;
1446                         if(u2<1.0) {
1447                                 labda[1]= u2;
1448                                 *b2=1;
1449                         }
1450                         else labda[1]=1.0;  /* u2 */
1451                         if(u1>0.0) {
1452                                 labda[0]= u1;
1453                                 *b2=1;
1454                         } else labda[0]=0.0;
1455                 }
1456         }
1457 }
1458
1459 /**
1460  * (make vertex pyramide clip)
1461  * Checks labda and uses this to make decision about clipping the line
1462  * segment from v1 to v2. labda is the factor by which the vector is
1463  * cut. ( calculate s + l * ( t - s )). The result is appended to the
1464  * vertex list of this face.
1465  * 
1466  * 
1467  * @param v1 start coordinate s
1468  * @param v2 target coordinate t
1469  * @param b1 
1470  * @param b2 
1471  * @param clve vertex vector.
1472  */
1473
1474 static void makevertpyra(float *vez, float *labda, float **trias, float *v1, float *v2, int *b1, int *clve)
1475 {
1476         float l1, l2, *adr;
1477
1478         l1= labda[0];
1479         l2= labda[1];
1480
1481         if(l1!= -1.0) {
1482                 if(l1!= 0.0) {
1483                         adr= vez+4*(*clve);
1484                         trias[*b1]=adr;
1485                         (*clve)++;
1486                         adr[0]= v1[0]+l1*(v2[0]-v1[0]);
1487                         adr[1]= v1[1]+l1*(v2[1]-v1[1]);
1488                         adr[2]= v1[2]+l1*(v2[2]-v1[2]);
1489                         adr[3]= v1[3]+l1*(v2[3]-v1[3]);
1490                 } 
1491                 else trias[*b1]= v1;
1492                 
1493                 (*b1)++;
1494         }
1495         if(l2!= -1.0) {
1496                 if(l2!= 1.0) {
1497                         adr= vez+4*(*clve);
1498                         trias[*b1]=adr;
1499                         (*clve)++;
1500                         adr[0]= v1[0]+l2*(v2[0]-v1[0]);
1501                         adr[1]= v1[1]+l2*(v2[1]-v1[1]);
1502                         adr[2]= v1[2]+l2*(v2[2]-v1[2]);
1503                         adr[3]= v1[3]+l2*(v2[3]-v1[3]);
1504                         (*b1)++;
1505                 }
1506         }
1507 }
1508
1509 /* ------------------------------------------------------------------------- */
1510
1511 void projectverto(float *v1, float winmat[][4], float *adr)
1512 {
1513         /* calcs homogenic coord of vertex v1 */
1514         float x,y,z;
1515
1516         x= v1[0]; 
1517         y= v1[1]; 
1518         z= v1[2];
1519         adr[0]= x*winmat[0][0]                          +       z*winmat[2][0] + winmat[3][0];
1520         adr[1]=                       y*winmat[1][1]    +       z*winmat[2][1] + winmat[3][1];
1521         adr[2]=                                                                         z*winmat[2][2] + winmat[3][2];
1522         adr[3]=                                                                         z*winmat[2][3] + winmat[3][3];
1523
1524         //printf("hoco %f %f %f %f\n", adr[0], adr[1], adr[2], adr[3]);
1525 }
1526
1527 /* ------------------------------------------------------------------------- */
1528
1529 void projectvert(float *v1, float winmat[][4], float *adr)
1530 {
1531         /* calcs homogenic coord of vertex v1 */
1532         float x,y,z;
1533
1534         x= v1[0]; 
1535         y= v1[1]; 
1536         z= v1[2];
1537         adr[0]= x*winmat[0][0]+ y*winmat[1][0]+ z*winmat[2][0]+ winmat[3][0];
1538         adr[1]= x*winmat[0][1]+ y*winmat[1][1]+ z*winmat[2][1]+ winmat[3][1];
1539         adr[2]= x*winmat[0][2]+ y*winmat[1][2]+ z*winmat[2][2]+ winmat[3][2];
1540         adr[3]= x*winmat[0][3]+ y*winmat[1][3]+ z*winmat[2][3]+ winmat[3][3];
1541 }
1542
1543 /* do zbuffering and clip, f1 f2 f3 are hocos, c1 c2 c3 are clipping flags */
1544
1545 void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3)
1546 {
1547         float *vlzp[32][3], labda[3][2];
1548         float vez[400], *trias[40];
1549         
1550         if(c1 | c2 | c3) {      /* not in middle */
1551                 if(c1 & c2 & c3) {      /* completely out */
1552                         return;
1553                 } else {        /* clipping */
1554                         int arg, v, b, clipflag[3], b1, b2, b3, c4, clve=3, clvlo, clvl=1;
1555
1556                         vez[0]= f1[0]; vez[1]= f1[1]; vez[2]= f1[2]; vez[3]= f1[3];
1557                         vez[4]= f2[0]; vez[5]= f2[1]; vez[6]= f2[2]; vez[7]= f2[3];
1558                         vez[8]= f3[0]; vez[9]= f3[1]; vez[10]= f3[2];vez[11]= f3[3];
1559
1560                         vlzp[0][0]= vez;
1561                         vlzp[0][1]= vez+4;
1562                         vlzp[0][2]= vez+8;
1563
1564                         clipflag[0]= ( (c1 & 48) | (c2 & 48) | (c3 & 48) );
1565                         if(clipflag[0]==0) {    /* othwerwise it needs to be calculated again, after the first (z) clip */
1566                                 clipflag[1]= ( (c1 & 3) | (c2 & 3) | (c3 & 3) );
1567                                 clipflag[2]= ( (c1 & 12) | (c2 & 12) | (c3 & 12) );
1568                         }
1569                         else clipflag[1]=clipflag[2]= 0;
1570                         
1571                         for(b=0;b<3;b++) {
1572                                 
1573                                 if(clipflag[b]) {
1574                                 
1575                                         clvlo= clvl;
1576                                         
1577                                         for(v=0; v<clvlo; v++) {
1578                                         
1579                                                 if(vlzp[v][0]!=NULL) {  /* face is still there */
1580                                                         b2= b3 =0;      /* clip flags */
1581
1582                                                         if(b==0) arg= 2;
1583                                                         else if (b==1) arg= 0;
1584                                                         else arg= 1;
1585                                                         
1586                                                         clippyra(labda[0], vlzp[v][0],vlzp[v][1], &b2,&b3, arg);
1587                                                         clippyra(labda[1], vlzp[v][1],vlzp[v][2], &b2,&b3, arg);
1588                                                         clippyra(labda[2], vlzp[v][2],vlzp[v][0], &b2,&b3, arg);
1589
1590                                                         if(b2==0 && b3==1) {
1591                                                                 /* completely 'in', but we copy because of last for() loop in this section */;
1592                                                                 vlzp[clvl][0]= vlzp[v][0];
1593                                                                 vlzp[clvl][1]= vlzp[v][1];
1594                                                                 vlzp[clvl][2]= vlzp[v][2];
1595                                                                 vlzp[v][0]= NULL;
1596                                                                 clvl++;
1597                                                         } else if(b3==0) {
1598                                                                 vlzp[v][0]= NULL;
1599                                                                 /* completely 'out' */;
1600                                                         } else {
1601                                                                 b1=0;
1602                                                                 makevertpyra(vez, labda[0], trias, vlzp[v][0],vlzp[v][1], &b1,&clve);
1603                                                                 makevertpyra(vez, labda[1], trias, vlzp[v][1],vlzp[v][2], &b1,&clve);
1604                                                                 makevertpyra(vez, labda[2], trias, vlzp[v][2],vlzp[v][0], &b1,&clve);
1605
1606                                                                 /* after front clip done: now set clip flags */
1607                                                                 if(b==0) {
1608                                                                         clipflag[1]= clipflag[2]= 0;
1609                                                                         f1= vez;
1610                                                                         for(b3=0; b3<clve; b3++) {
1611                                                                                 c4= testclip(f1);
1612                                                                                 clipflag[1] |= (c4 & 3);
1613                                                                                 clipflag[2] |= (c4 & 12);
1614                                                                                 f1+= 4;
1615                                                                         }
1616                                                                 }
1617                                                                 
1618                                                                 vlzp[v][0]= NULL;
1619                                                                 if(b1>2) {
1620                                                                         for(b3=3; b3<=b1; b3++) {
1621                                                                                 vlzp[clvl][0]= trias[0];
1622                                                                                 vlzp[clvl][1]= trias[b3-2];
1623                                                                                 vlzp[clvl][2]= trias[b3-1];
1624                                                                                 clvl++;
1625                                                                         }
1626                                                                 }
1627                                                         }
1628                                                 }
1629                                         }
1630                                 }
1631                         }
1632
1633             /* warning, this should never happen! */
1634                         if(clve>38 || clvl>31) printf("clip overflow: clve clvl %d %d\n",clve,clvl);
1635
1636             /* perspective division */
1637                         f1=vez;
1638                         for(c1=0;c1<clve;c1++) {
1639                                 hoco_to_zco(zspan, f1, f1);
1640                                 f1+=4;
1641                         }
1642                         for(b=1;b<clvl;b++) {
1643                                 if(vlzp[b][0]) {
1644                                         zspan->zbuffunc(zspan, zvlnr, vlzp[b][0],vlzp[b][1],vlzp[b][2], NULL);
1645                                 }
1646                         }
1647                         return;
1648                 }
1649         }
1650
1651         /* perspective division: HCS to ZCS */
1652         hoco_to_zco(zspan, vez, f1);
1653         hoco_to_zco(zspan, vez+4, f2);
1654         hoco_to_zco(zspan, vez+8, f3);
1655         zspan->zbuffunc(zspan, zvlnr, vez,vez+4,vez+8, NULL);
1656 }
1657
1658 void zbufclip4(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4)
1659 {
1660         float vez[16];
1661         
1662         if(c1 | c2 | c3 | c4) { /* not in middle */
1663                 if(c1 & c2 & c3 & c4) { /* completely out */
1664                         return;
1665                 } else {        /* clipping */
1666                         zbufclip(zspan, zvlnr, f1, f2, f3, c1, c2, c3);
1667                         zbufclip(zspan, zvlnr, f1, f3, f4, c1, c3, c4);
1668                 }
1669                 return;
1670         }
1671
1672         /* perspective division: HCS to ZCS */
1673         hoco_to_zco(zspan, vez, f1);
1674         hoco_to_zco(zspan, vez+4, f2);
1675         hoco_to_zco(zspan, vez+8, f3);
1676         hoco_to_zco(zspan, vez+12, f4);
1677
1678         zspan->zbuffunc(zspan, zvlnr, vez, vez+4, vez+8, vez+12);
1679 }
1680
1681
1682 /* ***************** ZBUFFER MAIN ROUTINES **************** */
1683
1684 void set_part_zbuf_clipflag(RenderPart *pa)
1685 {
1686         VertRen *ver=NULL;
1687         float minx, miny, maxx, maxy, wco;
1688         unsigned short clipclear;
1689         int v;
1690
1691         minx= (2*pa->disprect.xmin - R.winx-1)/(float)R.winx;
1692         maxx= (2*pa->disprect.xmax - R.winx+1)/(float)R.winx;
1693         miny= (2*pa->disprect.ymin - R.winy-1)/(float)R.winy;
1694         maxy= (2*pa->disprect.ymax - R.winy+1)/(float)R.winy;
1695         
1696         /* supports up to 4 threads this way */
1697         clipclear= ~(15 << 4*(pa->thread & 3));
1698         
1699         /* extra security to prevent access to same data */
1700         BLI_lock_thread(LOCK_CUSTOM1);
1701         
1702         for(v=0; v<R.totvert; v++) {
1703                 if((v & 255)==0)
1704                         ver= RE_findOrAddVert(&R, v);
1705                 else ver++;
1706                 
1707                 wco= ver->ho[3];
1708                 ver->flag &= clipclear;
1709                 
1710                 switch(pa->thread & 3) {
1711                         case 0:
1712                                 if( ver->ho[0] > maxx*wco) ver->flag |= 1;
1713                                 else if( ver->ho[0]< minx*wco) ver->flag |= 2;
1714                                 if( ver->ho[1] > maxy*wco) ver->flag |= 4;
1715                                 else if( ver->ho[1]< miny*wco) ver->flag |= 8;
1716                                 break;
1717                         case 1:
1718                                 if( ver->ho[0] > maxx*wco) ver->flag |= 16;
1719                                 else if( ver->ho[0]< minx*wco) ver->flag |= 32;
1720                                 if( ver->ho[1] > maxy*wco) ver->flag |= 64;
1721                                 else if( ver->ho[1]< miny*wco) ver->flag |= 128;
1722                                 break;
1723                         case 2:
1724                                 if( ver->ho[0] > maxx*wco) ver->flag |= 256;
1725                                 else if( ver->ho[0]< minx*wco) ver->flag |= 512;
1726                                 if( ver->ho[1] > maxy*wco) ver->flag |= 1024;
1727                                 else if( ver->ho[1]< miny*wco) ver->flag |= 2048;
1728                                 break;
1729                         case 3:
1730                                 if( ver->ho[0] > maxx*wco) ver->flag |= 4096;
1731                                 else if( ver->ho[0]< minx*wco) ver->flag |= 8192;
1732                                 if( ver->ho[1] > maxy*wco) ver->flag |= 16384;
1733                                 else if( ver->ho[1]< miny*wco) ver->flag |= 32768;
1734                                 break;
1735                 }
1736         }
1737         
1738         BLI_unlock_thread(LOCK_CUSTOM1);
1739 }
1740
1741 void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag)
1742 {
1743         ZSpan zspan;
1744         VlakRen *vlr= NULL;
1745         Material *ma=0;
1746         int v, zvlnr;
1747         unsigned short clipmask;
1748         short nofill=0, env=0, wire=0, all_z= layflag & SCE_LAY_ALL_Z;
1749
1750         zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
1751         
1752         /* needed for transform from hoco to zbuffer co */
1753         zspan.zmulx=  ((float)R.winx)/2.0;
1754         zspan.zmuly=  ((float)R.winy)/2.0;
1755         
1756         if(R.osa) {
1757                 zspan.zofsx= -pa->disprect.xmin - R.jit[pa->sample][0];
1758                 zspan.zofsy= -pa->disprect.ymin - R.jit[pa->sample][1];
1759         }
1760         else if(R.i.curblur) {
1761                 zspan.zofsx= -pa->disprect.xmin - R.jit[R.i.curblur-1][0];
1762                 zspan.zofsy= -pa->disprect.ymin - R.jit[R.i.curblur-1][1];
1763         }
1764         else {
1765                 zspan.zofsx= -pa->disprect.xmin;
1766                 zspan.zofsy= -pa->disprect.ymin;
1767         }
1768         /* to centre the sample position */
1769         zspan.zofsx -= 0.5f;
1770         zspan.zofsy -= 0.5f;
1771         
1772         /* the buffers */
1773         zspan.rectz= pa->rectz;
1774         zspan.rectp= pa->rectp;
1775         fillrect(pa->rectp, pa->rectx, pa->recty, 0);
1776         fillrect(pa->rectz, pa->rectx, pa->recty, 0x7FFFFFFF);
1777         
1778         /* filling methods */
1779         zspan.zbuffunc= zbuffillGL4;
1780         zspan.zbuflinefunc= zbufline;
1781
1782         /* part clipflag, threaded */
1783         clipmask= (15 << 4*(pa->thread & 3));
1784
1785         for(v=0; v<R.totvlak; v++) {
1786
1787                 if((v & 255)==0) vlr= R.blovl[v>>8];
1788                 else vlr++;
1789                 
1790                 if((vlr->flag & R_VISIBLE)) {
1791                         /* three cases, visible for render, only z values and nothing */
1792                         if(vlr->lay & lay) {
1793                                 if(vlr->mat!=ma) {
1794                                         ma= vlr->mat;
1795                                         nofill= ma->mode & (MA_ZTRA|MA_ONLYCAST);
1796                                         env= (ma->mode & MA_ENV);
1797                                         wire= (ma->mode & MA_WIRE);
1798                                         
1799                                         if(ma->mode & MA_ZINV) zspan.zbuffunc= zbuffillGLinv4;
1800                                         else zspan.zbuffunc= zbuffillGL4;
1801                                 }
1802                         }
1803                         else if(all_z) {
1804                                 env= 1;
1805                                 nofill= 0;
1806                                 ma= NULL; 
1807                         }
1808                         else {
1809                                 nofill= 1;
1810                                 ma= NULL;       /* otherwise nofill can hang */
1811                         }
1812                         
1813                         if(nofill==0) {
1814                                 unsigned short partclip;
1815                                 
1816                                 /* partclipping doesn't need viewplane clipping */
1817                                 if(vlr->v4) partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag;
1818                                 else partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag;
1819                                 
1820                                 if((partclip & clipmask)==0) {
1821                                         
1822                                         if(env) zvlnr= -1;
1823                                         else zvlnr= v+1;
1824                                         
1825                                         if(wire) zbufclipwire(&zspan, zvlnr, vlr);
1826                                         else {
1827                                                 /* strands allow to be filled in as quad */
1828                                                 if(vlr->v4 && (vlr->flag & R_STRAND)) {
1829                                                         zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
1830                                                 }
1831                                                 else {
1832                                                         zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
1833                                                         if(vlr->v4) {
1834                                                                 if(zvlnr>0) zvlnr+= RE_QUAD_OFFS;
1835                                                                 zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
1836                                                         }
1837                                                 }
1838                                         }
1839                                 }
1840                         }
1841                 }
1842         }
1843         
1844         zbuf_free_span(&zspan);
1845 }
1846
1847 typedef struct {
1848         float *vert;
1849         float hoco[4];
1850         int clip;
1851 } VertBucket;
1852
1853 /* warning, not threaded! */
1854 static int hashlist_projectvert(float *v1, float winmat[][4], float *hoco)
1855 {
1856         static VertBucket bucket[256], *buck;
1857         
1858         /* init static bucket */
1859         if(v1==NULL) {
1860                 memset(bucket, 0, 256*sizeof(VertBucket));
1861                 return 0;
1862         }
1863         
1864         buck= &bucket[ (((long)v1)/16) & 255 ];
1865         if(buck->vert==v1) {
1866                 QUATCOPY(hoco, buck->hoco);
1867                 return buck->clip;
1868         }
1869         
1870         projectvert(v1, winmat, hoco);
1871         buck->clip = testclip(hoco);
1872         buck->vert= v1;
1873         QUATCOPY(buck->hoco, hoco);
1874         return buck->clip;
1875 }
1876
1877 /* used for booth radio 'tool' as during render */
1878 void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Render *re)
1879 {
1880         ZSpan zspan;
1881         float hoco[4][4], winmat[4][4];
1882         int a, zvlnr;
1883         int c1, c2, c3, c4= 0;
1884
1885         if(rg_totelem==0) return;
1886
1887         hashlist_projectvert(NULL, winmat, NULL);
1888         
1889         /* needed for projectvert */
1890         MTC_Mat4MulMat4(winmat, vw->viewmat, vw->winmat);
1891
1892         /* for clipping... bad stuff actually */
1893         R.clipcrop= 1.0f;
1894         
1895         zbuf_alloc_span(&zspan, vw->rectx, vw->recty);
1896         zspan.zmulx=  ((float)vw->rectx)/2.0;
1897         zspan.zmuly=  ((float)vw->recty)/2.0;
1898         zspan.zofsx= -0.5f;
1899         zspan.zofsy= -0.5f;
1900         
1901         /* the buffers */
1902         zspan.rectz= vw->rectz;
1903         zspan.rectp= vw->rect;
1904         fillrect(zspan.rectz, vw->rectx, vw->recty, 0x7FFFFFFF);
1905         fillrect(zspan.rectp, vw->rectx, vw->recty, 0xFFFFFF);
1906         
1907         /* filling methods */
1908         zspan.zbuffunc= zbuffillGL4;
1909         
1910         if(rg_elem) {   /* radio tool */
1911                 RNode **re, *rn;
1912
1913                 re= rg_elem;
1914                 re+= (rg_totelem-1);
1915                 for(a= rg_totelem-1; a>=0; a--, re--) {
1916                         rn= *re;
1917                         if( (rn->f & RAD_SHOOT)==0 ) {    /* no shootelement */
1918                                 
1919                                 if( rn->f & RAD_TWOSIDED) zvlnr= a;
1920                                 else if( rn->f & RAD_BACKFACE) zvlnr= 0xFFFFFF; 
1921                                 else zvlnr= a;
1922                                 
1923                                 c1= hashlist_projectvert(rn->v1, winmat, hoco[0]);
1924                                 c2= hashlist_projectvert(rn->v2, winmat, hoco[1]);
1925                                 c3= hashlist_projectvert(rn->v3, winmat, hoco[2]);
1926                                 
1927                                 if(rn->v4) {
1928                                         c4= hashlist_projectvert(rn->v4, winmat, hoco[3]);
1929                                 }
1930         
1931                                 if(rn->v4)
1932                                         zbufclip4(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
1933                                 else
1934                                         zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
1935                         }
1936                 }
1937         }
1938         else {  /* radio render */
1939                 VlakRen *vlr=NULL;
1940                 RadFace *rf;
1941                 int totface=0;
1942                 
1943                 for(a=0; a<re->totvlak; a++) {
1944                         if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++;
1945                 
1946                         if(vlr->radface) {
1947                                 rf= vlr->radface;
1948                                 if( (rf->flag & RAD_SHOOT)==0 ) {    /* no shootelement */
1949                                         
1950                                         if( rf->flag & RAD_TWOSIDED) zvlnr= totface;
1951                                         else if( rf->flag & RAD_BACKFACE) zvlnr= 0xFFFFFF;      /* receives no energy, but is zbuffered */
1952                                         else zvlnr= totface;
1953                                         
1954                                         c1= hashlist_projectvert(vlr->v1->co, winmat, hoco[0]);
1955                                         c2= hashlist_projectvert(vlr->v2->co, winmat, hoco[1]);
1956                                         c3= hashlist_projectvert(vlr->v3->co, winmat, hoco[2]);
1957                                         
1958                                         if(vlr->v4) {
1959                                                 c4= hashlist_projectvert(vlr->v4->co, winmat, hoco[3]);
1960                                         }
1961                 
1962                                         if(vlr->v4)
1963                                                 zbufclip4(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
1964                                         else
1965                                                 zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
1966                                 }
1967                                 totface++;
1968                         }
1969                 }
1970         }
1971
1972         zbuf_free_span(&zspan);
1973 }
1974
1975 void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size, float jitx, float jity)
1976 {
1977         ZSpan zspan;
1978         VlakRen *vlr= NULL;
1979         Material *ma= NULL;
1980         int a, ok=1, lay= -1;
1981
1982         if(lar->mode & LA_LAYER) lay= lar->lay;
1983
1984         zbuf_alloc_span(&zspan, size, size);
1985         zspan.zmulx=  ((float)size)/2.0;
1986         zspan.zmuly=  ((float)size)/2.0;
1987         zspan.zofsx= jitx;
1988         zspan.zofsy= jity;
1989         
1990         /* the buffers */
1991         zspan.rectz= rectz;
1992         fillrect(rectz, size, size, 0x7FFFFFFE);
1993         if(lar->buftype==LA_SHADBUF_HALFWAY) {
1994                 zspan.rectz1= MEM_mallocN(size*size*sizeof(int), "seconday z buffer");
1995                 fillrect(zspan.rectz1, size, size, 0x7FFFFFFE);
1996         }
1997         
1998         /* filling methods */
1999         zspan.zbuflinefunc= zbufline_onlyZ;
2000         zspan.zbuffunc= zbuffillGL_onlyZ;
2001
2002         for(a=0; a<re->totvlak; a++) {
2003
2004                 if((a & 255)==0) vlr= re->blovl[a>>8];
2005                 else vlr++;
2006
2007                 /* note, these conditions are copied in shadowbuf_autoclip() */
2008                 if(vlr->mat!= ma) {
2009                         ma= vlr->mat;
2010                         ok= 1;
2011                         if((ma->mode & MA_SHADBUF)==0) ok= 0;
2012                 }
2013                 
2014                 if(ok && (vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {
2015                         if(ma->mode & MA_WIRE) zbufclipwire(&zspan, a+1, vlr);
2016                         else if(vlr->flag & R_STRAND) zbufclipwire(&zspan, a+1, vlr);
2017                         else {
2018                                 if(vlr->v4) 
2019                                         zbufclip4(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
2020                                 else
2021                                         zbufclip(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
2022                         }
2023                 }
2024         }
2025         
2026         /* merge buffers */
2027         if(lar->buftype==LA_SHADBUF_HALFWAY) {
2028                 for(a=size*size -1; a>=0; a--)
2029                         rectz[a]= (rectz[a]>>1) + (zspan.rectz1[a]>>1);
2030                 
2031                 MEM_freeN(zspan.rectz1);
2032         }
2033         
2034         zbuf_free_span(&zspan);
2035 }
2036
2037 /* ******************** VECBLUR ACCUM BUF ************************* */
2038
2039 typedef struct DrawBufPixel {
2040         float *colpoin;
2041         float alpha;
2042 } DrawBufPixel;
2043
2044
2045 static void zbuf_fill_in_rgba(ZSpan *zspan, DrawBufPixel *col, float *v1, float *v2, float *v3, float *v4)
2046 {
2047         DrawBufPixel *rectpofs, *rp;
2048         double zxd, zyd, zy0, zverg;
2049         float x0,y0,z0;
2050         float x1,y1,z1,x2,y2,z2,xx1;
2051         float *span1, *span2;
2052         float *rectzofs, *rz;
2053         int x, y;
2054         int sn1, sn2, rectx, my0, my2;
2055         
2056         /* init */
2057         zbuf_init_span(zspan);
2058         
2059         /* set spans */
2060         zbuf_add_to_span(zspan, v1, v2);
2061         zbuf_add_to_span(zspan, v2, v3);
2062         zbuf_add_to_span(zspan, v3, v4);
2063         zbuf_add_to_span(zspan, v4, v1);
2064         
2065         /* clipped */
2066         if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
2067         
2068         if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
2069         if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
2070         
2071         //      printf("my %d %d\n", my0, my2);
2072         if(my2<my0) return;
2073         
2074         /* ZBUF DX DY, in floats still */
2075         x1= v1[0]- v2[0];
2076         x2= v2[0]- v3[0];
2077         y1= v1[1]- v2[1];
2078         y2= v2[1]- v3[1];
2079         z1= v1[2]- v2[2];
2080         z2= v2[2]- v3[2];
2081         x0= y1*z2-z1*y2;
2082         y0= z1*x2-x1*z2;
2083         z0= x1*y2-y1*x2;
2084         
2085         if(z0==0.0) return;
2086         
2087         xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
2088         
2089         zxd= -(double)x0/(double)z0;
2090         zyd= -(double)y0/(double)z0;
2091         zy0= ((double)my2)*zyd + (double)xx1;
2092         
2093         /* start-offset in rect */
2094         rectx= zspan->rectx;
2095         rectzofs= (float *)(zspan->rectz + rectx*my2);
2096         rectpofs= ((DrawBufPixel *)zspan->rectp) + rectx*my2;
2097         
2098         /* correct span */
2099         sn1= (my0 + my2)/2;
2100         if(zspan->span1[sn1] < zspan->span2[sn1]) {
2101                 span1= zspan->span1+my2;
2102                 span2= zspan->span2+my2;
2103         }
2104         else {
2105                 span1= zspan->span2+my2;
2106                 span2= zspan->span1+my2;
2107         }
2108         
2109         for(y=my2; y>=my0; y--, span1--, span2--) {
2110                 
2111                 sn1= floor(*span1);
2112                 sn2= floor(*span2);
2113                 sn1++; 
2114                 
2115                 if(sn2>=rectx) sn2= rectx-1;
2116                 if(sn1<0) sn1= 0;
2117                 
2118                 if(sn2>=sn1) {
2119                         zverg= (double)sn1*zxd + zy0;
2120                         rz= rectzofs+sn1;
2121                         rp= rectpofs+sn1;
2122                         x= sn2-sn1;
2123                         
2124                         while(x>=0) {
2125                                 if( zverg < *rz) {
2126                                         *rz= zverg;
2127                                         *rp= *col;
2128                                 }
2129                                 zverg+= zxd;
2130                                 rz++; 
2131                                 rp++; 
2132                                 x--;
2133                         }
2134                 }
2135                 
2136                 zy0-=zyd;
2137                 rectzofs-= rectx;
2138                 rectpofs-= rectx;
2139         }
2140 }
2141
2142 static void antialias_tagbuf(int xsize, int ysize, char *rectmove)
2143 {
2144         char *row1, *row2, *row3;
2145         char prev, next;
2146         int a, x, y, step;
2147         
2148         /* 1: tag pixels to be candidate for AA */
2149         for(y=2; y<ysize; y++) {
2150                 /* setup rows */
2151                 row1= rectmove + (y-2)*xsize;
2152                 row2= row1 + xsize;
2153                 row3= row2 + xsize;
2154                 for(x=2; x<xsize; x++, row1++, row2++, row3++) {
2155                         if(row2[1]) {
2156                                 if(row2[0]==0 || row2[2]==0 || row1[1]==0 || row3[1]==0)
2157                                         row2[1]= 128;
2158                         }
2159                 }
2160         }
2161         /* 2: evaluate horizontal scanlines and calculate alphas */
2162         row1= rectmove;
2163         for(y=0; y<ysize; y++) {
2164                 row1++;
2165                 for(x=1; x<xsize; x++, row1++) {
2166                         if(row1[0]==128 && row1[1]==128) {
2167                                 /* find previous color and next color and amount of steps to blend */
2168                                 prev= row1[-1];
2169                                 step= 1;
2170                                 while(x+step<xsize && row1[step]==128)
2171                                         step++;
2172                                 
2173                                 if(x+step!=xsize) {
2174                                         /* now we can blend values */
2175                                         next= row1[step];
2176                                         if(prev!=next) {
2177                                                 for(a=0; a<step; a++) {
2178                                                         int fac, mfac;
2179                                                         
2180                                                         fac= ((a+1)<<8)/(step+1);
2181                                                         mfac= 255-fac;
2182                                                         
2183                                                         row1[a]= (prev*mfac + next*fac)>>8; 
2184                                                 }
2185                                         }
2186                                 }
2187                         }
2188                 }
2189         }
2190         /* 2: evaluate vertical scanlines and calculate alphas */
2191         for(x=0; x<xsize; x++) {
2192                 row1= rectmove + x+xsize;
2193                 
2194                 for(y=1; y<ysize; y++, row1+=xsize) {
2195                         if(row1[0]==128 && row1[xsize]==128) {
2196                                 /* find previous color and next color and amount of steps to blend */
2197                                 prev= row1[-xsize];
2198                                 step= 1;
2199                                 while(y+step<ysize && row1[step*xsize]==128)
2200                                         step++;
2201                                 
2202                                 if(y+step!=ysize) {
2203                                         /* now we can blend values */
2204                                         next= row1[step*xsize];
2205                                         if(prev!=next) {
2206                                                 for(a=0; a<step; a++) {
2207                                                         int fac, mfac;
2208                                                         
2209                                                         fac= ((a+1)<<8)/(step+1);
2210                                                         mfac= 255-fac;
2211                                                         
2212                                                         row1[a*xsize]= (prev*mfac + next*fac)>>8; 
2213                                                 }
2214                                         }
2215                                 }
2216                         }
2217                 }
2218         }
2219         
2220         
2221         /* last: pixels with 0 we fill in zbuffer, with 1 we skip for mask */
2222         for(y=2; y<ysize; y++) {
2223                 /* setup rows */
2224                 row1= rectmove + (y-2)*xsize;
2225                 row2= row1 + xsize;
2226                 row3= row2 + xsize;
2227                 for(x=2; x<xsize; x++, row1++, row2++, row3++) {
2228                         if(row2[1]==0) {
2229                                 if(row2[0]>1 || row2[2]>1 || row1[1]>1 || row3[1]>1)
2230                                         row2[1]= 1;
2231                         }
2232                 }
2233         }
2234 }
2235
2236 void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *newrect, float *imgrect, float *vecbufrect, float *zbufrect)
2237 {
2238         ZSpan zspan;
2239         DrawBufPixel *rectdraw, *dr;
2240         float jit[16][2];
2241         float v1[3], v2[3], v3[3], v4[3], fx, fy;
2242         float *rectvz, *dvz, *dimg, *dvec1, *dvec2, *dz1, *dz2, *rectz, *minvecbufrect= NULL;
2243         float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed;
2244         int y, x, step, maxspeed=nbd->maxspeed, samples= nbd->samples;
2245         int tsktsk= 0;
2246         char *rectmove, *dm;
2247         
2248         zbuf_alloc_span(&zspan, xsize, ysize);
2249         zspan.zmulx=  ((float)xsize)/2.0;
2250         zspan.zmuly=  ((float)ysize)/2.0;
2251         zspan.zofsx= 0.0f;
2252         zspan.zofsy= 0.0f;
2253         
2254         /* the buffers */
2255         rectz= MEM_mapallocN(sizeof(float)*xsize*ysize, "zbuf accum");
2256         zspan.rectz= (int *)rectz;
2257         
2258         rectmove= MEM_mapallocN(xsize*ysize, "rectmove");
2259         rectdraw= MEM_mapallocN(sizeof(DrawBufPixel)*xsize*ysize, "rect draw");
2260         zspan.rectp= (int *)rectdraw;
2261         
2262         /* debug... check if PASS_VECTOR_MAX still is in buffers */
2263         dvec1= vecbufrect;
2264         for(x= 4*xsize*ysize; x>0; x--, dvec1++) {
2265                 if(dvec1[0]==PASS_VECTOR_MAX) {
2266                         dvec1[0]= 0.0f;
2267                         tsktsk= 1;
2268                 }
2269         }
2270         if(tsktsk) printf("tsk tsk! PASS_VECTOR_MAX left in buffer...\n");
2271         
2272         /* min speed? then copy speedbuffer to recalculate speed vectors */
2273         if(nbd->minspeed) {
2274                 float minspeed= (float)nbd->minspeed;
2275                 float minspeedsq= minspeed*minspeed;
2276                 
2277                 minvecbufrect= MEM_mapallocN(4*sizeof(float)*xsize*ysize, "minspeed buf");
2278                 
2279                 dvec1= vecbufrect;
2280                 dvec2= minvecbufrect;
2281                 for(x= 2*xsize*ysize; x>0; x--, dvec1+=2, dvec2+=2) {
2282                         if(dvec1[0]==0.0f && dvec1[1]==0.0f) {
2283                                 dvec2[0]= dvec1[0];
2284                                 dvec2[1]= dvec1[1];
2285                         }
2286                         else {
2287                                 float speedsq= dvec1[0]*dvec1[0] + dvec1[1]*dvec1[1];
2288                                 if(speedsq <= minspeedsq) {
2289                                         dvec2[0]= 0.0f;
2290                                         dvec2[1]= 0.0f;
2291                                 }
2292                                 else {
2293                                         speedsq= 1.0f - minspeed/sqrt(speedsq);
2294                                         dvec2[0]= speedsq*dvec1[0];
2295                                         dvec2[1]= speedsq*dvec1[1];
2296                                 }
2297                         }
2298                 }
2299                 SWAP(float *, minvecbufrect, vecbufrect);
2300         }
2301         
2302         /* make vertex buffer with averaged speed and zvalues */
2303         rectvz= MEM_mapallocN(5*sizeof(float)*(xsize+1)*(ysize+1), "vertices");
2304         dvz= rectvz;
2305         for(y=0; y<=ysize; y++) {
2306                 
2307                 if(y==0) {
2308                         dvec1= vecbufrect + 4*y*xsize;
2309                         dz1= zbufrect + y*xsize;
2310                 }
2311                 else {
2312                         dvec1= vecbufrect + 4*(y-1)*xsize;
2313                         dz1= zbufrect + (y-1)*xsize;
2314                 }
2315                 
2316                 if(y==ysize) {
2317                         dvec2= vecbufrect + 4*(y-1)*xsize;
2318                         dz2= zbufrect + (y-1)*xsize;
2319                 }
2320                 else {
2321                         dvec2= vecbufrect + 4*y*xsize;
2322                         dz2= zbufrect + y*xsize;
2323                 }
2324                 
2325                 for(x=0; x<=xsize; x++, dz1++, dz2++) {
2326                         
2327                         /* two vectors, so a step loop */
2328                         for(step=0; step<2; step++, dvec1+=2, dvec2+=2, dvz+=2) {
2329                                 /* average on minimal speed */
2330                                 int div= 0;
2331                                 
2332                                 if(x!=0) {
2333                                         if(dvec1[-4]!=0.0f || dvec1[-3]!=0.0f) {
2334                                                 dvz[0]= dvec1[-4];
2335                                                 dvz[1]= dvec1[-3];
2336                                                 div++;
2337                                         }
2338                                         if(dvec2[-4]!=0.0f || dvec2[-3]!=0.0f) {
2339                                                 if(div==0) {
2340                                                         dvz[0]= dvec2[-4];
2341                                                         dvz[1]= dvec2[-3];
2342                                                         div++;
2343                                                 }
2344                                                 else if( (ABS(dvec2[-4]) + ABS(dvec2[-3]))< (ABS(dvz[0]) + ABS(dvz[1])) ) {
2345                                                         dvz[0]= dvec2[-4];
2346                                                         dvz[1]= dvec2[-3];
2347                                                 }
2348                                         }
2349                                 }
2350
2351                                 if(x!=xsize) {
2352                                         if(dvec1[0]!=0.0f || dvec1[1]!=0.0f) {
2353                                                 if(div==0) {
2354                                                         dvz[0]= dvec1[0];
2355                                                         dvz[1]= dvec1[1];
2356                                                         div++;
2357                                                 }
2358                                                 else if( (ABS(dvec1[0]) + ABS(dvec1[1]))< (ABS(dvz[0]) + ABS(dvz[1])) ) {
2359                                                         dvz[0]= dvec1[0];
2360                                                         dvz[1]= dvec1[1];
2361                                                 }
2362                                         }
2363                                         if(dvec2[0]!=0.0f || dvec2[1]!=0.0f) {
2364                                                 if(div==0) {
2365                                                         dvz[0]= dvec2[0];
2366                                                         dvz[1]= dvec2[1];
2367                                                 }
2368                                                 else if( (ABS(dvec2[0]) + ABS(dvec2[1]))< (ABS(dvz[0]) + ABS(dvz[1])) ) {
2369                                                         dvz[0]= dvec2[0];
2370                                                         dvz[1]= dvec2[1];
2371                                                 }
2372                                         }
2373                                 }
2374                                 if(maxspeed) {
2375                                         float speedsq= dvz[0]*dvz[0] + dvz[1]*dvz[1];
2376                                         if(speedsq > maxspeedsq) {
2377                                                 speedsq= (float)maxspeed/sqrt(speedsq);
2378                                                 dvz[0]*= speedsq;
2379                                                 dvz[1]*= speedsq;
2380                                         }
2381                                 }
2382                         }
2383                         /* the z coordinate */
2384                         if(x!=0) {
2385                                 if(x!=xsize)
2386                                         dvz[0]= 0.25f*(dz1[-1] + dz2[-1] + dz1[0] + dz2[0]);
2387                                 else dvz[0]= 0.5f*(dz1[0] + dz2[0]);
2388                         }
2389                         else dvz[0]= 0.5f*(dz1[-1] + dz2[-1]);
2390                         
2391                         dvz++;
2392                 }
2393         }
2394         
2395         /* set border speeds to keep border speeds on border */
2396         dz1= rectvz;
2397         dz2= rectvz+5*(ysize)*(xsize+1);
2398         for(x=0; x<=xsize; x++, dz1+=5, dz2+=5) {
2399                 dz1[1]= 0.0f;
2400                 dz2[1]= 0.0f;
2401                 dz1[3]= 0.0f;
2402                 dz2[3]= 0.0f;
2403         }
2404         dz1= rectvz;
2405         dz2= rectvz+5*(xsize);
2406         for(y=0; y<=ysize; y++, dz1+=5*(xsize+1), dz2+=5*(xsize+1)) {
2407                 dz1[0]= 0.0f;
2408                 dz2[0]= 0.0f;
2409                 dz1[2]= 0.0f;
2410                 dz2[2]= 0.0f;
2411         }
2412         
2413         /* tag moving pixels, only these faces we draw */
2414         dm= rectmove;
2415         dvec1= vecbufrect;
2416         for(x=xsize*ysize; x>0; x--, dm++, dvec1+=4) {
2417                 if(dvec1[0]!=0.0f || dvec1[1]!=0.0f || dvec1[2]!=0.0f || dvec1[3]!=0.0f)
2418                         *dm= 255;
2419         }
2420         
2421         antialias_tagbuf(xsize, ysize, rectmove);
2422         
2423         BLI_initjit(jit[0], 16);
2424         
2425         
2426         /* accumulate */
2427         samples/= 2;
2428         for(step= 1; step<=samples; step++) {
2429                 float speedfac= 0.5f*nbd->fac*(float)step/(float)(samples+1);
2430                 float blendfac= 1.0f/(ABS(step)+1);
2431                 int side, z= 4;
2432                 
2433                 for(side=0; side<2; side++) {
2434                         
2435                         /* clear zbuf, if we draw future we fill in not moving pixels */
2436                         if(0)
2437                                 for(x= xsize*ysize-1; x>=0; x--) rectz[x]= 10e16;
2438                         else 
2439                                 for(x= xsize*ysize-1; x>=0; x--) {
2440                                         if(rectmove[x]==0)
2441                                                 rectz[x]= zbufrect[x];
2442                                         else
2443                                                 rectz[x]= 10e16;
2444                                 }
2445                         
2446                         /* clear drawing buffer */
2447                         for(x= xsize*ysize-1; x>=0; x--) rectdraw[x].colpoin= NULL;
2448                         
2449                         dimg= imgrect;
2450                         dm= rectmove;
2451                         dz1= rectvz;
2452                         dz2= rectvz + 5*(xsize + 1);
2453                         
2454                         if(side) {
2455                                 dz1+= 2;
2456                                 dz2+= 2;
2457                                 z= 2;
2458                                 speedfac= -speedfac;
2459                         }
2460
2461                         for(fy= -0.5f+jit[step & 15][0], y=0; y<ysize; y++, fy+=1.0f) {
2462                                 for(fx= -0.5f+jit[step & 15][1], x=0; x<xsize; x++, fx+=1.0f, dimg+=4, dz1+=5, dz2+=5, dm++) {
2463                                         if(*dm>1) {
2464                                                 DrawBufPixel col;
2465                                                 
2466                                                 /* make vertices */
2467                                                 v1[0]= speedfac*dz1[0]+fx;                      v1[1]= speedfac*dz1[1]+fy;                      v1[2]= dz1[z];
2468                                                 v2[0]= speedfac*dz1[5]+fx+1.0f;         v2[1]= speedfac*dz1[6]+fy;                      v2[2]= dz1[z+5];
2469                                                 v3[0]= speedfac*dz2[5]+fx+1.0f;         v3[1]= speedfac*dz2[6]+fy+1.0f;         v3[2]= dz2[z+5];
2470                                                 v4[0]= speedfac*dz2[0]+fx;                      v4[1]= speedfac*dz2[1]+fy+1.0f;         v4[2]= dz2[z];
2471                                                 
2472                                                 if(*dm==255) col.alpha= 1.0f;
2473                                                 else if(*dm<2) col.alpha= 0.0f;
2474                                                 else col.alpha= ((float)*dm)/255.0f;
2475                                                 col.colpoin= dimg;
2476                                                 
2477                                                 zbuf_fill_in_rgba(&zspan, &col, v1, v2, v3, v4);
2478                                         }
2479                                 }
2480                                 dz1+=5;
2481                                 dz2+=5;
2482                         }
2483                         
2484                         /* accum */
2485                         for(dr= rectdraw, dz2=newrect, x= xsize*ysize-1; x>=0; x--, dr++, dz2+=4) {
2486                                 if(dr->colpoin) {
2487                                         float bfac= dr->alpha*blendfac;
2488                                         float mf= 1.0f - bfac;
2489                                         
2490                                         dz2[0]= mf*dz2[0] + bfac*dr->colpoin[0];
2491                                         dz2[1]= mf*dz2[1] + bfac*dr->colpoin[1];
2492                                         dz2[2]= mf*dz2[2] + bfac*dr->colpoin[2];
2493                                         dz2[3]= mf*dz2[3] + bfac*dr->colpoin[3];
2494                                 }
2495                         }
2496                 }
2497         }
2498         
2499         MEM_freeN(rectz);
2500         MEM_freeN(rectmove);
2501         MEM_freeN(rectdraw);
2502         MEM_freeN(rectvz);
2503         if(minvecbufrect) MEM_freeN(vecbufrect);  /* rects were swapped! */
2504         zbuf_free_span(&zspan);
2505 }
2506
2507 /* ******************** ABUF ************************* */
2508
2509 /**
2510  * Copy results from the solid face z buffering to the transparent
2511  * buffer.
2512  */
2513 static void copyto_abufz(RenderPart *pa, int *arectz, int sample)
2514 {
2515         PixStr *ps;
2516         int x, y, *rza;
2517         long *rd;
2518         
2519         if(R.osa==0) {
2520                 memcpy(arectz, pa->rectz, 4*pa->rectx*pa->recty);
2521                 return;
2522         }
2523         
2524         rza= arectz;
2525         rd= pa->rectdaps;
2526
2527         sample= (1<<sample);
2528         
2529         for(y=0; y<pa->recty; y++) {
2530                 for(x=0; x<pa->rectx; x++) {
2531                         
2532                         *rza= 0x7FFFFFFF;
2533                         if(*rd) {       
2534                                 /* when there's a sky pixstruct, fill in sky-Z, otherwise solid Z */
2535                                 for(ps= (PixStr *)(*rd); ps; ps= ps->next) {
2536                                         if(sample & ps->mask) {
2537                                                 *rza= ps->z;
2538                                                 break;
2539                                         }
2540                                 }
2541                         }
2542                         
2543                         rd++; rza++;
2544                 }
2545         }
2546 }
2547
2548
2549 /* ------------------------------------------------------------------------ */
2550
2551 /**
2552  * Do accumulation z buffering.
2553  */
2554
2555 static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay)
2556 {
2557         ZSpan zspan;
2558         Material *ma=NULL;
2559         VlakRen *vlr=NULL;
2560         float vec[3], hoco[4], mul, zval, fval;
2561         int v, zvlnr, zsample, dofill= 0;
2562         unsigned short clipmask;
2563         
2564         zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
2565         
2566         /* needed for transform from hoco to zbuffer co */
2567         zspan.zmulx=  ((float)R.winx)/2.0;
2568         zspan.zmuly=  ((float)R.winy)/2.0;
2569         
2570         /* the buffers */
2571         zspan.arectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectz");
2572         zspan.apixbuf= APixbuf;
2573         zspan.apsmbase= apsmbase;
2574         
2575         /* filling methods */
2576         zspan.zbuffunc= zbuffillAc4;
2577         zspan.zbuflinefunc= zbuflineAc;
2578         
2579         /* part clipflag, 4 threads */
2580         clipmask= (15 << 4*(pa->thread & 3));
2581         
2582         for(zsample=0; zsample<R.osa || R.osa==0; zsample++) {
2583                 
2584                 copyto_abufz(pa, zspan.arectz, zsample);        /* init zbuffer */
2585                 zspan.mask= 1<<zsample;
2586                 
2587                 if(R.osa) {
2588                         zspan.zofsx= -pa->disprect.xmin - R.jit[zsample][0];
2589                         zspan.zofsy= -pa->disprect.ymin - R.jit[zsample][1];
2590                 }
2591                 else if(R.i.curblur) {
2592                         zspan.zofsx= -pa->disprect.xmin - R.jit[R.i.curblur-1][0];
2593                         zspan.zofsy= -pa->disprect.ymin - R.jit[R.i.curblur-1][1];
2594                 }
2595                 else {
2596                         zspan.zofsx= -pa->disprect.xmin;
2597                         zspan.zofsy= -pa->disprect.ymin;
2598                 }
2599                 /* to centre the sample position */
2600                 zspan.zofsx -= 0.5f;
2601                 zspan.zofsy -= 0.5f;
2602                 
2603                 for(v=0; v<R.totvlak; v++) {
2604                         if((v & 255)==0)
2605                                 vlr= R.blovl[v>>8];
2606                         else vlr++;
2607                         
2608                         if(vlr->mat!=ma) {
2609                                 ma= vlr->mat;
2610                                 dofill= (ma->mode & MA_ZTRA) && !(ma->mode & MA_ONLYCAST);
2611                         }
2612                         
2613                         if(dofill) {
2614                                 if((vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {
2615                                         unsigned short partclip;
2616                                         
2617                                         /* partclipping doesn't need viewplane clipping */
2618                                         if(vlr->v4) partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag;
2619                                         else partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag;
2620                                         
2621                                         if((partclip & clipmask)==0) {
2622                                                 /* a little advantage for transp rendering (a z offset) */
2623                                                 if( ma->zoffs != 0.0) {
2624                                                         mul= 0x7FFFFFFF;
2625                                                         zval= mul*(1.0+vlr->v1->ho[2]/vlr->v1->ho[3]);
2626
2627                                                         VECCOPY(vec, vlr->v1->co);
2628                                                         /* z is negative, otherwise its being clipped */ 
2629                                                         vec[2]-= ma->zoffs;
2630                                                         projectverto(vec, R.winmat, hoco);
2631                                                         fval= mul*(1.0+hoco[2]/hoco[3]);
2632
2633                                                         zspan.polygon_offset= (int) fabs(zval - fval );
2634                                                 }
2635                                                 else zspan.polygon_offset= 0;
2636                                                 
2637                                                 zvlnr= v+1;
2638                         
2639                                                 if(ma->mode & (MA_WIRE)) zbufclipwire(&zspan, zvlnr, vlr);
2640                                                 else {
2641                                                         if(vlr->v4 && (vlr->flag & R_STRAND)) {
2642                                                                 zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
2643                                                         }
2644                                                         else {
2645                                                                 zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
2646                                                                 if(vlr->v4) {
2647                                                                         zvlnr+= RE_QUAD_OFFS;
2648                                                                         zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
2649                                                                 }
2650                                                         }
2651                                                 }
2652                                         }
2653                                 }
2654                                 if( (v & 255)==255) 
2655                                         if(R.test_break()) 
2656                                                 break; 
2657                         }
2658                 }
2659                 
2660                 if(R.osa==0) break;
2661                 if(R.test_break()) break;
2662         }
2663         
2664         MEM_freeN(zspan.arectz);
2665         zbuf_free_span(&zspan);
2666
2667 }
2668
2669 /* different rules for speed in transparent pass...  */
2670 /* speed pointer NULL = sky, we clear */
2671 /* else if either alpha is full or no solid was filled in: copy speed */
2672 /* else fill in minimum speed */
2673 static void add_transp_speed(RenderLayer *rl, int offset, float *speed, float alpha, long *rdrect)
2674 {
2675         RenderPass *rpass;
2676         
2677         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
2678                 if(rpass->passtype==SCE_PASS_VECTOR) {
2679                         float *fp= rpass->rect + 4*offset;
2680                         
2681                         if(speed==NULL) {
2682                                 /* clear */
2683                                 if(fp[0]==PASS_VECTOR_MAX) fp[0]= 0.0f;
2684                                 if(fp[1]==PASS_VECTOR_MAX) fp[1]= 0.0f;
2685                                 if(fp[2]==PASS_VECTOR_MAX) fp[2]= 0.0f;
2686                                 if(fp[3]==PASS_VECTOR_MAX) fp[3]= 0.0f;
2687                         }
2688                         else if(rdrect==NULL || rdrect[offset]==0 || alpha>0.95f) {
2689                                 QUATCOPY(fp, speed);
2690                         }
2691                         else {
2692                                 /* add minimum speed in pixel */
2693                                 if( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
2694                                         fp[0]= speed[0];
2695                                         fp[1]= speed[1];
2696                                 }
2697                                 if( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
2698                                         fp[2]= speed[2];
2699                                         fp[3]= speed[3];
2700                                 }
2701                                 
2702                         }
2703                 }
2704         }
2705 }
2706
2707 static void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, float weight)
2708 {
2709         RenderPass *rpass;
2710         
2711         for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
2712                 float *fp, *col= NULL;
2713                 int a, pixsize= 3;
2714                 
2715                 switch(rpass->passtype) {
2716                         case SCE_PASS_RGBA:
2717                                 if(shr) col= shr->col;
2718                                 pixsize= 4;
2719                                 break;
2720                         case SCE_PASS_DIFFUSE:
2721                                 if(shr) col= shr->diff;
2722                                 break;
2723                         case SCE_PASS_SPEC:
2724                                 if(shr) col= shr->spec;
2725                                 break;
2726                         case SCE_PASS_SHADOW:
2727                                 if(shr) col= shr->shad;
2728                                 break;
2729                         case SCE_PASS_AO:
2730                                 if(shr) col= shr->ao;
2731                                 break;
2732                         case SCE_PASS_RAY:
2733                                 if(shr) col= shr->ray;
2734                                 break;
2735                         case SCE_PASS_NORMAL:
2736                                 if(shr) col= shr->nor;
2737                                 break;
2738                 }
2739                 if(col) {
2740                         fp= rpass->rect + pixsize*offset;
2741                         for(a=0; a<pixsize; a++)
2742                                 fp[a]+= weight*col[a];
2743                 }
2744         }
2745 }
2746
2747
2748 static int vergzvlak(const void *a1, const void *a2)
2749 {
2750         const int *x1=a1, *x2=a2;
2751
2752         if( x1[0] < x2[0] ) return 1;
2753         else if( x1[0] > x2[0]) return -1;
2754         return 0;
2755 }
2756
2757 /**
2758 * Shade this face at this location in SCS.
2759  */
2760 static void shadetrapixel(ShadePixelInfo *shpi, float x, float y, int z, int facenr, int mask)
2761 {
2762         float rco[3];
2763         
2764         if(facenr<0)
2765                 return;
2766         else if( (facenr & RE_QUAD_MASK) > R.totvlak) {
2767                 printf("error in shadetrapixel nr: %d\n", (facenr & RE_QUAD_MASK));
2768                 return;
2769         }
2770         /* correction back for zbuffer filling in */
2771         x+= 0.5f;
2772         y+= 0.5f;
2773         
2774         if(R.osa) {
2775                 VlakRen *vlr= RE_findOrAddVlak(&R, (facenr-1) & RE_QUAD_MASK);
2776                 float accumcol[4]={0,0,0,0}, tot=0.0;
2777                 int a;
2778                 
2779                 if(vlr->flag & R_FULL_OSA) {
2780                         for(a=0; a<R.osa; a++) {
2781                                 if(mask & (1<<a)) {
2782                                         shadepixel(shpi, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, rco);
2783                                         accumcol[0]+= shpi->shr.combined[0];
2784                                         accumcol[1]+= shpi->shr.combined[1];
2785                                         accumcol[2]+= shpi->shr.combined[2];
2786                                         accumcol[3]+= shpi->shr.combined[3];
2787                                         tot+= 1.0;
2788                                 }
2789                         }
2790                         tot= 1.0/tot;
2791                         shpi->shr.combined[0]= accumcol[0]*tot;
2792                         shpi->shr.combined[1]= accumcol[1]*tot;
2793                         shpi->shr.combined[2]= accumcol[2]*tot;
2794                         shpi->shr.combined[3]= accumcol[3]*tot;
2795                 }
2796                 else {
2797                         int b= R.samples->centmask[mask];
2798                         x= x+R.samples->centLut[b & 15];
2799                         y= y+R.samples->centLut[b>>4];
2800                         shadepixel(shpi, x, y, z, facenr, mask, rco);
2801                 }
2802         }
2803         else {
2804                 shadepixel(shpi, x, y, z, facenr, mask, rco);
2805         }
2806 }
2807
2808 static int addtosamp_shr(ShadeResult *samp_shr, ShadeResult *shr, int mask, int addpassflag)
2809 {
2810         int a, retval = R.osa;
2811         
2812         for(a=0; a < R.osa; a++) {
2813                 if(mask & (1<<a)) {
2814                         addAlphaUnderFloat(samp_shr->combined, shr->combined);
2815                         
2816                         if(addpassflag & SCE_PASS_VECTOR) {
2817                                 QUATCOPY(samp_shr->winspeed, shr->winspeed);
2818                         }
2819                         else if(addpassflag & SCE_PASS_NORMAL) {
2820                                 VECCOPY(samp_shr->nor, shr->nor);
2821                         }
2822                 }
2823                 
2824                 if(samp_shr->combined[3]>0.999) retval--;
2825                 samp_shr++;
2826         }
2827         return retval;
2828 }
2829
2830 #define MAX_ZROW        2000
2831 /* main render call to fill in pass the full transparent layer */
2832
2833 void zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass)
2834 {
2835         RenderResult *rr= pa->result;
2836         ShadePixelInfo shpi;
2837         APixstr *APixbuf;      /* Zbuffer: linked list of face samples */
2838         APixstr *ap, *aprect, *apn;
2839         ListBase apsmbase={NULL, NULL};
2840         ShadeResult samp_shr[16];
2841         float fac, sampalpha, *passrect= pass;
2842         long *rdrect;
2843         int x, y, crop=0, a, zrow[MAX_ZROW][3], totface;
2844         int sval, addpassflag, offs= 0, od, addzbuf;
2845
2846         /* looks nicer for calling code */
2847         if(R.test_break())
2848                 return;
2849         
2850         APixbuf= MEM_callocN(pa->rectx*pa->recty*sizeof(APixstr), "APixbuf");
2851         
2852         if(R.osa>16) {
2853                 printf("abufsetrow: osa too large\n");
2854                 G.afbreek= 1;
2855                 return;
2856         }
2857         
2858         /* fill shadepixel info struct */
2859         shpi.thread= pa->thread;
2860         shpi.lay= rl->lay;
2861         shpi.layflag= rl->layflag;
2862         shpi.passflag= 0;
2863         
2864         if(rl->passflag & ~(SCE_PASS_Z|SCE_PASS_NORMAL|SCE_PASS_VECTOR|SCE_PASS_COMBINED))
2865                 shpi.passflag= rl->passflag;
2866         addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
2867         addzbuf= rl->passflag & SCE_PASS_Z;
2868         
2869         if(R.osa)
2870                 sampalpha= 1.0f/(float)R.osa;
2871         else
2872                 sampalpha= 1.0f;
2873         
2874         /* fill the Apixbuf */
2875         zbuffer_abuf(pa, APixbuf, &apsmbase, rl->lay);
2876         aprect= APixbuf;
2877         rdrect= pa->rectdaps;
2878         
2879         /* irregular shadowb buffer creation */
2880         if(R.r.mode & R_SHADOW)
2881                 ISB_create(pa, APixbuf);
2882         
2883         /* filtered render, for now we assume only 1 filter size */
2884         if(pa->crop) {
2885                 crop= 1;
2886                 offs= pa->rectx + 1;
2887                 passrect+= 4*offs;
2888                 aprect+= offs;
2889         }
2890         
2891         /* init scanline updates */
2892         rr->renrect.ymin= 0;
2893         rr->renrect.ymax= -pa->crop;
2894         rr->renlay= rl;
2895                                 
2896         /* render the tile */
2897         for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
2898                 pass= passrect;
2899                 ap= aprect;
2900                 od= offs;
2901                 
2902                 if(R.test_break())
2903                         break;
2904                 
2905                 for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, ap++, pass+=4, od++) {
2906                         
2907                         if(ap->p[0]==0) {
2908                                 if(addpassflag & SCE_PASS_VECTOR) 
2909                                         add_transp_speed(rl, od, NULL, 0.0f, rdrect);
2910                         }
2911                         else {
2912                                 /* sort in z */
2913                                 totface= 0;
2914                                 apn= ap;
2915                                 while(apn) {
2916                                         for(a=0; a<4; a++) {
2917                                                 if(apn->p[a]) {
2918                                                         zrow[totface][0]= apn->z[a];
2919                                                         zrow[totface][1]= apn->p[a];
2920                                                         zrow[totface][2]= apn->mask[a];
2921                                                         totface++;
2922                                                         if(totface>=MAX_ZROW) totface=&nbs