Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/render/intern/source/shadbuf.c')
-rw-r--r--source/blender/render/intern/source/shadbuf.c771
1 files changed, 771 insertions, 0 deletions
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
new file mode 100644
index 00000000000..bd0a844a354
--- /dev/null
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -0,0 +1,771 @@
+/* shadbuf.c RENDER
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * april 95
+ *
+ * $Id$
+ *
+ * 27-Jun-2001 switched the shadow buffer for UR to the object-shadow
+ * buffers, and removed all references and fixes for UR rendering from
+ * this one.
+ * */
+
+#include <math.h>
+#include <string.h>
+
+#include "MTC_matrixops.h"
+#include "MEM_guardedalloc.h"
+#include "BLI_arithb.h"
+
+#include "DNA_lamp_types.h"
+
+#include "render.h"
+#include "render_intern.h"
+
+#include "shadbuf.h"
+#include "renderHelp.h"
+#include "jitter.h"
+#include "zbuf.h"
+
+/* if defined: objects don't cast shadows anymore */
+/* #define RE_NO_SHADOWS */
+
+/* unused? */
+static int bias= 0x00500000;
+/* crud */
+#define MIN2(x,y) ( (x)<(y) ? (x) : (y) )
+
+/* ------------------------------------------------------------------------- */
+
+void lrectreadRectz(int x1, int y1, int x2, int y2, char *r1);
+int sizeoflampbuf(struct ShadBuf *shb);
+int firstreadshadbuf(struct ShadBuf *shb, int xs, int ys, int nr);
+float readshadowbuf(struct ShadBuf *shb, int xs, int ys, int zs);
+float readshadowbuf_halo(struct ShadBuf *shb, int xs, int ys, int zs);
+float *give_jitter_tab(int samp);
+/* ------------------------------------------------------------------------- */
+
+
+void initshadowbuf(LampRen *lar, float mat[][4])
+{
+ struct ShadBuf *shb;
+ float hoek, temp, viewinv[4][4];
+
+ /* if(la->spsi<16) return; */
+
+ /* geheugen reserveren */
+ shb= (struct ShadBuf *)MEM_callocN( sizeof(struct ShadBuf),"initshadbuf");
+ lar->shb= shb;
+
+ if(shb==0) return;
+
+ VECCOPY(shb->co, lar->co);
+
+ /* percentage: min en max in de gaten houden */
+ shb->size= (lar->bufsize*R.r.size)/100;
+ if(shb->size<512) shb->size= 512;
+ else if(shb->size > lar->bufsize) shb->size= lar->bufsize;
+
+ shb->samp= lar->samp;
+ shb->soft= lar->soft;
+ shb->shadhalostep= lar->shadhalostep;
+
+ shb->zbuf= (unsigned long *)MEM_mallocN( sizeof(unsigned long)*(shb->size*shb->size)/256, "initshadbuf2");
+ shb->cbuf= (char *)MEM_callocN( (shb->size*shb->size)/256, "initshadbuf3");
+
+ if(shb->zbuf==0 || shb->cbuf==0) {
+ if(shb->zbuf) MEM_freeN(shb->zbuf);
+ MEM_freeN(lar->shb);
+ lar->shb= 0;
+ return;
+ }
+
+ MTC_Mat4Ortho(mat);
+ MTC_Mat4Invert(shb->winmat, mat); /* winmat is hier temp */
+
+ /* matrix: combinatie van inverse view en lampmat */
+ /* opnieuw berekenen: de ortho-render heeft geen correcte viewinv */
+ MTC_Mat4Invert(viewinv, R.viewmat);
+ MTC_Mat4MulMat4(shb->viewmat, viewinv, shb->winmat);
+
+ /* projektie */
+ hoek= saacos(lar->spotsi);
+ temp= 0.5*shb->size*cos(hoek)/sin(hoek);
+ shb->d= lar->clipsta;
+
+ shb->pixsize= (shb->d)/temp;
+
+ shb->far= lar->clipend;
+ /* bias is percentage, 2x groter gemaakt ivm invalshoek correctie */
+ shb->bias= (0.02*lar->bias)*0x7FFFFFFF;
+ shb->bias= shb->bias*(100/R.r.size);
+
+}
+/* ------------------------------------------------------------------------- */
+
+
+void lrectreadRectz(int x1, int y1, int x2, int y2, char *r1) /* leest deel uit rectz in r1 */
+{
+ unsigned int len4, *rz;
+
+ if(x1>=R.rectx || x2>=R.rectx || y1>=R.recty || y2>=R.recty) return;
+ if(x1>x2 || y1>y2) return;
+
+ len4= 4*(x2- x1+1);
+ rz= R.rectz+R.rectx*y1+x1;
+ for(;y1<=y2;y1++) {
+ memcpy(r1,rz,len4);
+ rz+= R.rectx;
+ r1+= len4;
+ }
+}
+
+
+int sizeoflampbuf(struct ShadBuf *shb)
+{
+ int num,count=0;
+ char *cp;
+
+ cp= shb->cbuf;
+ num= (shb->size*shb->size)/256;
+
+ while(num--) count+= *(cp++);
+
+ return 256*count;
+}
+
+float *give_jitter_tab(int samp)
+{
+ /* these are all possible jitter tables, takes up some
+ * 12k, not really bad!
+ * For soft shadows, it saves memory and render time
+ */
+ static int tab[17]={1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256};
+ static float jit[1496][2];
+ static char ctab[17]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ int a, offset=0;
+
+ if(samp<2) samp= 2;
+ else if(samp>16) samp= 16;
+
+ for(a=0; a<samp-1; a++) offset+= tab[a];
+
+ if(ctab[samp]==0) {
+ initjit(jit[offset], samp*samp);
+ ctab[samp]= 1;
+ }
+
+ return jit[offset];
+
+}
+
+void makeshadowbuf(LampRen *lar)
+{
+ struct ShadBuf *shb= lar->shb;
+ float panophi;
+ float temp, wsize, dist;
+ int *rz, *rz1, verg, verg1;
+ unsigned long *ztile;
+ int a, x, y, minx, miny, byt1, byt2;
+ short temprx,tempry, square;
+ char *rc, *rcline, *ctile, *zt;
+
+ panophi = getPanoPhi();
+
+ /* viewvars onthouden */
+ temprx= R.rectx; tempry= R.recty;
+ R.rectx= R.recty= shb->size;
+
+ shb->jit= give_jitter_tab(shb->samp);
+
+ /* matrices en window: in R.winmat komt transformatie
+ van obsview naar lampview, inclusief lampwinmat */
+
+ wsize= shb->pixsize*(shb->size/2.0);
+
+ i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->far, shb->winmat);
+
+ MTC_Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat);
+
+ /* temp, will be restored */
+ MTC_Mat4SwapMat4(shb->persmat, R.winmat);
+
+ /* zbufferen */
+ if(R.rectz) MEM_freeN(R.rectz);
+ R.rectz= (unsigned int *)MEM_mallocN(sizeof(int)*shb->size*shb->size,"makeshadbuf");
+ rcline= MEM_mallocN(256*4+sizeof(int),"makeshadbuf2");
+
+ /* onthouden: panorama rot */
+ temp= panophi;
+ panophi= 0.0;
+ pushTempPanoPhi(0.0);
+
+ /* pano interference here? */
+ setzbufvlaggen(projectvert);
+
+ popTempPanoPhi();
+ panophi= temp;
+
+ zbuffershad(lar);
+
+ /* alle pixels 1 x ingevuld verwijderen (oneven) */
+ /* probleem hierbij kan geven dat er abrupte overgangen van zacht gebied
+ * naar geen zacht gebied is: bijv als eronder een klein vlakje zit
+ * DAAROM ER WEER UIT
+ * ook vanwege shadowhalo!
+ *
+ a= shb->size*shb->size;
+ rz= R.rectz;
+ while(a--) {
+ if(*rz & 1) *rz= 0x7FFFFFFF;
+ rz++;
+ }
+ */
+
+ square= lar->mode & LA_SQUARE;
+
+ /* Z tiles aanmaken: dit systeem is 24 bits!!! */
+
+ ztile= shb->zbuf;
+ ctile= shb->cbuf;
+ for(y=0; y<shb->size; y+=16) {
+ if(y< shb->size/2) miny= y+15-shb->size/2;
+ else miny= y-shb->size/2;
+
+ for(x=0; x<shb->size; x+=16) {
+
+ /* ligt rechthoek binnen spotbundel? */
+ a= shb->size/2;
+ if(x< a) minx= x+15-a;
+ else minx= x-a;
+
+ dist= sqrt( (float)(minx*minx+miny*miny) );
+
+ if(square==0 && dist>(float)(a+12)) { /* 12, tested with a onlyshadow lamp */
+ a= 256; verg= 0; /* 0x80000000; */ /* 0x7FFFFFFF; */
+ rz1= (&verg)+1;
+ }
+ else {
+ lrectreadRectz(x, y, MIN2(shb->size-1,x+15), MIN2(shb->size-1,y+15), rcline);
+ rz1= (int *)rcline;
+
+ verg= (*rz1 & 0xFFFFFF00);
+
+ for(a=0;a<256;a++,rz1++) {
+ if( (*rz1 & 0xFFFFFF00) !=verg) break;
+ }
+ }
+ if(a==256) { /* compleet leeg vakje */
+ *ctile= 0;
+ *ztile= *(rz1-1);
+ }
+ else {
+
+ /* ACOMP enz. zijn defined L/B endian */
+
+ rc= rcline;
+ rz1= (int *)rcline;
+ verg= rc[ACOMP];
+ verg1= rc[BCOMP];
+ rc+= 4;
+ byt1= 1; byt2= 1;
+ for(a=1;a<256;a++,rc+=4) {
+ byt1 &= (verg==rc[ACOMP]);
+ byt2 &= (verg1==rc[BCOMP]);
+
+ if(byt1==0) break;
+ }
+ if(byt1 && byt2) { /* alleen byte opslaan */
+ *ctile= 1;
+ *ztile= (unsigned long)MEM_mallocN(256+4, "tile1");
+ rz= (int *)*ztile;
+ *rz= *rz1;
+
+ zt= (char *)(rz+1);
+ rc= rcline;
+ for(a=0; a<256; a++, zt++, rc+=4) *zt= rc[GCOMP];
+ }
+ else if(byt1) { /* short opslaan */
+ *ctile= 2;
+ *ztile= (unsigned long)MEM_mallocN(2*256+4,"Tile2");
+ rz= (int *)*ztile;
+ *rz= *rz1;
+
+ zt= (char *)(rz+1);
+ rc= rcline;
+ for(a=0; a<256; a++, zt+=2, rc+=4) {
+ zt[0]= rc[BCOMP];
+ zt[1]= rc[GCOMP];
+ }
+ }
+ else { /* triple opslaan */
+ *ctile= 3;
+ *ztile= (unsigned long)MEM_mallocN(3*256,"Tile3");
+
+ zt= (char *)*ztile;
+ rc= rcline;
+ for(a=0; a<256; a++, zt+=3, rc+=4) {
+ zt[0]= rc[ACOMP];
+ zt[1]= rc[BCOMP];
+ zt[2]= rc[GCOMP];
+ }
+ }
+ }
+ ztile++;
+ ctile++;
+ }
+ }
+
+ MEM_freeN(rcline);
+ MEM_freeN(R.rectz); R.rectz= 0;
+
+ R.rectx= temprx; R.recty= tempry;
+ MTC_Mat4SwapMat4(shb->persmat, R.winmat);
+
+ /* printf("lampbuf %d\n", sizeoflampbuf(shb)); */
+}
+
+int firstreadshadbuf(struct ShadBuf *shb, int xs, int ys, int nr)
+{
+ /* return 1 als volledig gecomprimeerde shadbuftile && z==const */
+ static int *rz;
+ int ofs;
+ char *ct;
+
+ /* always test borders of shadowbuffer */
+ if(xs<0) xs= 0; else if(xs>=shb->size) xs= shb->size-1;
+ if(ys<0) ys= 0; else if(ys>=shb->size) ys= shb->size-1;
+
+ /* z berekenen */
+ ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
+ ct= shb->cbuf+ofs;
+ if(*ct==0) {
+ if(nr==0) {
+ rz= *( (int **)(shb->zbuf+ofs) );
+ return 1;
+ }
+ else if(rz!= *( (int **)(shb->zbuf+ofs) )) return 0;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+float readshadowbuf(struct ShadBuf *shb, int xs, int ys, int zs) /* return 1.0 : volledig licht */
+{
+ float temp;
+ int *rz, ofs;
+ int zsamp;
+ char *ct, *cz;
+
+ /* simpleclip */
+ /* if(xs<0 || ys<0) return 1.0; */
+ /* if(xs>=shb->size || ys>=shb->size) return 1.0; */
+
+ /* always test borders of shadowbuffer */
+ if(xs<0) xs= 0; else if(xs>=shb->size) xs= shb->size-1;
+ if(ys<0) ys= 0; else if(ys>=shb->size) ys= shb->size-1;
+
+ /* z berekenen */
+ ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
+ ct= shb->cbuf+ofs;
+ rz= *( (int **)(shb->zbuf+ofs) );
+
+ if(*ct==3) {
+ ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15);
+ cz= (char *)&zsamp;
+ cz[ACOMP]= ct[0];
+ cz[BCOMP]= ct[1];
+ cz[GCOMP]= ct[2];
+ }
+ else if(*ct==2) {
+ ct= ((char *)rz);
+ ct+= 4+2*16*(ys & 15)+2*(xs & 15);
+ zsamp= *rz;
+
+ cz= (char *)&zsamp;
+ cz[BCOMP]= ct[0];
+ cz[GCOMP]= ct[1];
+ }
+ else if(*ct==1) {
+ ct= ((char *)rz);
+ ct+= 4+16*(ys & 15)+(xs & 15);
+ zsamp= *rz;
+
+ cz= (char *)&zsamp;
+ cz[GCOMP]= ct[0];
+
+ }
+ else {
+ /* got warning on this from alpha .... */
+ /* but it's working code! (ton) */
+ zsamp= (int) rz;
+ }
+
+ /* if(zsamp >= 0x7FFFFE00) return 1.0; */ /* geen schaduw als op oneindig wordt gesampeld*/
+
+ if(zsamp > zs) return 1.0; /* absoluut geen schaduw */
+ else if( zsamp < zs-bias) return 0.0 ; /* absoluut wel schaduw */
+ else { /* zacht gebied */
+
+ temp= ( (float)(zs- zsamp) )/(float)bias;
+ return 1.0 - temp*temp;
+
+ }
+}
+
+
+float testshadowbuf(struct ShadBuf *shb, float inp) /* return 1.0: geen schaduw */
+{
+ float fac, co[4], dx[3], dy[3], aantal=0;
+ float xs1,ys1, siz, *j, xres, yres;
+ int xs,ys, zs;
+ short a,num;
+
+#ifdef RE_NO_SHADOWS
+ return 1.0;
+#endif
+
+ /* if(inp <= 0.0) return 1.0; */
+
+ /* renderco en osaco roteren */
+ siz= 0.5*(float)shb->size;
+ VECCOPY(co, R.co);
+ co[3]= 1.0;
+
+ MTC_Mat4MulVec4fl(shb->persmat, co); /* rationele hom co */
+
+ xs1= siz*(1.0+co[0]/co[3]);
+ ys1= siz*(1.0+co[1]/co[3]);
+
+ /* Clip for z: near and far clip values of the shadow buffer. We
+ * can test for -1.0/1.0 because of the properties of the
+ * coordinate transformations. */
+ fac= (co[2]/co[3]);
+
+ if(fac>=1.0) {
+ return 0.0;
+ } else if(fac<= -1.0) {
+ return 1.0;
+ }
+
+ zs= ((float)0x7FFFFFFF)*fac;
+
+ /* num*num samples nemen, gebied met fac vergroten */
+ num= shb->samp*shb->samp;
+ fac= shb->soft;
+
+
+ bias= (1.1-inp*inp)*shb->bias;
+
+ if(num==1) {
+ return readshadowbuf(shb,(int)xs1, (int)ys1, zs);
+ }
+
+ co[0]= R.co[0]+O.dxco[0];
+ co[1]= R.co[1]+O.dxco[1];
+ co[2]= R.co[2]+O.dxco[2];
+ co[3]= 1.0;
+ MTC_Mat4MulVec4fl(shb->persmat,co); /* rationele hom co */
+ dx[0]= xs1- siz*(1.0+co[0]/co[3]);
+ dx[1]= ys1- siz*(1.0+co[1]/co[3]);
+
+ co[0]= R.co[0]+O.dyco[0];
+ co[1]= R.co[1]+O.dyco[1];
+ co[2]= R.co[2]+O.dyco[2];
+ co[3]= 1.0;
+ MTC_Mat4MulVec4fl(shb->persmat,co); /* rationele hom co */
+ dy[0]= xs1- siz*(1.0+co[0]/co[3]);
+ dy[1]= ys1- siz*(1.0+co[1]/co[3]);
+
+ xres= fac*( fabs(dx[0])+fabs(dy[0]) );
+ yres= fac*( fabs(dx[1])+fabs(dy[1]) );
+
+ if(xres<fac) xres= fac;
+ if(yres<fac) yres= fac;
+
+ xs1-= (xres)/2;
+ ys1-= (yres)/2;
+
+ j= shb->jit;
+
+ if(xres<16.0 && yres<16.0) {
+ if(firstreadshadbuf(shb, (int)xs1, (int)ys1, 0)) {
+ if(firstreadshadbuf(shb, (int)(xs1+xres), (int)ys1, 1)) {
+ if(firstreadshadbuf(shb, (int)xs1, (int)(ys1+yres), 1)) {
+ if(firstreadshadbuf(shb, (int)(xs1+xres), (int)(ys1+yres), 1)) {
+ return readshadowbuf(shb,(int)xs1, (int)ys1, zs);
+ }
+ }
+ }
+ }
+ }
+
+ for(a=num;a>0;a--) {
+ /* i.p.v. jit ook met random geprobeerd: lelijk! */
+ xs= xs1 + xres*j[0];
+ ys= ys1 + yres*j[1];
+ j+=2;
+
+ aantal+= readshadowbuf(shb, xs, ys, zs);
+ }
+
+ /* Renormalizes for the sample number: */
+ return aantal/( (float)(num) );
+}
+
+/* different function... sampling behind clipend can be LIGHT, bias is negative! */
+/* return: light */
+float readshadowbuf_halo(struct ShadBuf *shb, int xs, int ys, int zs)
+{
+ float temp;
+ int *rz, ofs;
+ int zbias, zsamp;
+ char *ct, *cz;
+
+ /* simpleclip */
+ if(xs<0 || ys<0) return 0.0;
+ if(xs>=shb->size || ys>=shb->size) return 0.0;
+
+ /* z berekenen */
+ ofs= (ys>>4)*(shb->size>>4) + (xs>>4);
+ ct= shb->cbuf+ofs;
+ rz= *( (int **)(shb->zbuf+ofs) );
+
+ if(*ct==3) {
+ ct= ((char *)rz)+3*16*(ys & 15)+3*(xs & 15);
+ cz= (char *)&zsamp;
+ zsamp= 0;
+ cz[ACOMP]= ct[0];
+ cz[BCOMP]= ct[1];
+ cz[GCOMP]= ct[2];
+ }
+ else if(*ct==2) {
+ ct= ((char *)rz);
+ ct+= 4+2*16*(ys & 15)+2*(xs & 15);
+ zsamp= *rz;
+
+ cz= (char *)&zsamp;
+ cz[BCOMP]= ct[0];
+ cz[GCOMP]= ct[1];
+ }
+ else if(*ct==1) {
+ ct= ((char *)rz);
+ ct+= 4+16*(ys & 15)+(xs & 15);
+ zsamp= *rz;
+
+ cz= (char *)&zsamp;
+ cz[GCOMP]= ct[0];
+
+ }
+ else {
+ /* same as before */
+ /* still working code! (ton) */
+ zsamp= (int) rz;
+ }
+
+ /* geen schaduw als op oneindig wordt gesampeld*/
+
+ if(zsamp >= 0x7FFFFE00) return 1.0;
+
+ if(zsamp > zs) return 1.0; /* absoluut geen schaduw */
+ else {
+ /* bias is negative, so the (zs-bias) can be beyond 0x7fffffff */
+ zbias= 0x7fffffff - zs;
+ if(zbias > -bias) {
+ if( zsamp < zs-bias) return 0.0 ; /* absoluut wel schaduw */
+ }
+ else return 0.0 ; /* absoluut wel schaduw */
+ }
+
+ /* zacht gebied */
+
+ temp= ( (float)(zs- zsamp) )/(float)bias;
+ return 1.0 - temp*temp;
+}
+
+
+float shadow_halo(LampRen *lar, float *p1, float *p2)
+{
+ /* p1 p2 already are rotated in spot-space */
+ ShadBuf *shb= lar->shb;
+ float co[4], siz;
+ float labda, labdao, labdax, labday, ldx, ldy;
+ float zf, xf1, yf1, zf1, xf2, yf2, zf2;
+ float count, lightcount;
+ int x, y, z, xs1, ys1;
+ int dx = 0, dy = 0;
+
+ siz= 0.5*(float)shb->size;
+ /* negative! The other side is more important */
+ bias= -shb->bias;
+
+ co[0]= p1[0];
+ co[1]= p1[1];
+ co[2]= p1[2]/lar->sh_zfac;
+ co[3]= 1.0;
+ MTC_Mat4MulVec4fl(shb->winmat, co); /* rationele hom co */
+ xf1= siz*(1.0+co[0]/co[3]);
+ yf1= siz*(1.0+co[1]/co[3]);
+ zf1= (co[2]/co[3]);
+
+
+ co[0]= p2[0];
+ co[1]= p2[1];
+ co[2]= p2[2]/lar->sh_zfac;
+ co[3]= 1.0;
+ MTC_Mat4MulVec4fl(shb->winmat, co); /* rationele hom co */
+ xf2= siz*(1.0+co[0]/co[3]);
+ yf2= siz*(1.0+co[1]/co[3]);
+ zf2= (co[2]/co[3]);
+
+ /* de 2dda */
+
+ xs1= (int)xf1;
+ ys1= (int)yf1;
+
+ if(xf1 != xf2) {
+ if(xf2-xf1 > 0.0) {
+ labdax= (xf1-xs1-1.0)/(xf1-xf2);
+ ldx= -shb->shadhalostep/(xf1-xf2);
+ dx= shb->shadhalostep;
+ }
+ else {
+ labdax= (xf1-xs1)/(xf1-xf2);
+ ldx= shb->shadhalostep/(xf1-xf2);
+ dx= -shb->shadhalostep;
+ }
+ }
+ else {
+ labdax= 1.0;
+ ldx= 0.0;
+ }
+
+ if(yf1 != yf2) {
+ if(yf2-yf1 > 0.0) {
+ labday= (yf1-ys1-1.0)/(yf1-yf2);
+ ldy= -shb->shadhalostep/(yf1-yf2);
+ dy= shb->shadhalostep;
+ }
+ else {
+ labday= (yf1-ys1)/(yf1-yf2);
+ ldy= shb->shadhalostep/(yf1-yf2);
+ dy= -shb->shadhalostep;
+ }
+ }
+ else {
+ labday= 1.0;
+ ldy= 0.0;
+ }
+
+ x= xs1;
+ y= ys1;
+ labda= count= lightcount= 0.0;
+
+/* printf("start %x %x \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */
+
+ while(1) {
+ labdao= labda;
+
+ if(labdax==labday) {
+ labdax+= ldx;
+ x+= dx;
+ labday+= ldy;
+ y+= dy;
+ }
+ else {
+ if(labdax<labday) {
+ labdax+= ldx;
+ x+= dx;
+ } else {
+ labday+= ldy;
+ y+= dy;
+ }
+ }
+
+ labda= MIN2(labdax, labday);
+ if(labda==labdao || labda>=1.0) break;
+
+ zf= zf1 + labda*(zf2-zf1);
+ count+= 1.0;
+
+ if(zf<= 0.0) lightcount += 1.0; /* close to the spot */
+ else {
+
+ /* make sure, behind the clipend we extend halolines. */
+ if(zf>=1.0) z= 0x7FFFF000;
+ else z= (int)(0x7FFFF000*zf);
+
+ lightcount+= readshadowbuf_halo(shb, x, y, z);
+
+ }
+ }
+
+ if(count!=0.0) return (lightcount/count);
+ return 0.0;
+
+}
+
+
+
+
+/* sampelen met filter
+ xstart= xs-1;
+ ystart= ys-1;
+ if(xstart<0) xstart= 0;
+ if(ystart<0) ystart= 0;
+ xend= xstart+2;
+ yend= ystart+2;
+ if(xend>=shb->size) { xstart= shb->size-3; xend= shb->size-1;}
+ if(yend>=shb->size) { ystart= shb->size-3; yend= shb->size-1;}
+
+ fid= filt3;
+ for(ys=ystart;ys<=yend;ys++) {
+ rz= shb->buf+ ys*shb->size+ xstart;
+ for(xs= xstart;xs<=xend;xs++,rz++) {
+ if( *rz+0x100000<zs) aantal+= *fid;
+ fid++;
+ }
+ }
+
+
+ return 1.0-((float)aantal)/16.0;
+*/
+
+
+
+
+
+
+
+
+
+