/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 1997 by Ton Roosendaal, Frank van Beek and Joeri Kassenaar. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ /* * effect.c 1992 * * d.o.f. jan 93 * edge_enhance jan 93 * spothalo jan/maart 94 * * */ #include #include #include #include #include #include "/usr/people/include/Trace.h" #include /* rand */ struct VV *effvv; extern void VecMulf(float *v1, float f); float spglob[3], dxt[3], dyt[3]; short test= 0; /* ********************* LAMP HALO ******************* */ void spothalo(struct LampRen *lar, float *view, float *intens) { float t0, t1, t2, t3, a, b, c, disc, Normalise(), VecLenf(); float *npos, nray[3], p1[3], p2[3], p3[3], ladist, maxz, maxy; int snijp, doclip=1, use_yco=0; int ok1=0, ok2=0, ok3=0; *intens= 0.0; npos= lar->sh_invcampos; /* in initlamp berekend */ /* view roteren */ VECCOPY(nray, view); Mat3MulVecfl(lar->imat, nray); /* maxz roteren */ if(R.co[2]==0) doclip= 0; else { p1[0]= R.co[0]-lar->co[0]; p1[1]= R.co[1]-lar->co[1]; p1[2]= R.co[2]-lar->co[2]; maxz= lar->imat[0][2]*p1[0]+lar->imat[1][2]*p1[1]+lar->imat[2][2]*p1[2]; maxz*= lar->sh_zfac; maxy= lar->imat[0][1]*p1[0]+lar->imat[1][1]*p1[1]+lar->imat[2][1]*p1[2]; if( fabs(nray[2]) <0.000001 ) use_yco= 1; } /* z scalen zodat het volume genormaliseerd is */ nray[2]*= lar->sh_zfac; /* nray hoeft niet genormaliseerd */ ladist= lar->sh_zfac*lar->dist; /* oplossen */ a = nray[0] * nray[0] + nray[1] * nray[1] - nray[2]*nray[2]; b = nray[0] * npos[0] + nray[1] * npos[1] - nray[2]*npos[2]; c = npos[0] * npos[0] + npos[1] * npos[1] - npos[2]*npos[2]; snijp= 0; if (fabs(a) < 0.000001) { /* * Only one intersection point... */ return; } else { disc = b*b - a*c; if (disc >= 0.0) { disc = fsqrt(disc); t1 = (-b + disc) / a; t2 = (-b - disc) / a; snijp= 2; } } if(snijp) { /* sorteren */ if(t1>t2) { a= t1; t1= t2; t2= a; } /* z van snijpunten met diabolo */ p1[2]= npos[2] + t1*nray[2]; p2[2]= npos[2] + t2*nray[2]; /* beide punten evalueren */ if(p1[2]<=0.0) ok1= 1; if(p2[2]<=0.0 && t1!=t2) ok2= 1; /* minstens 1 punt met negatieve z */ if(ok1==0 && ok2==0) return; /* snijpunt met -ladist, de bodem van de kegel */ if(use_yco==0) { t3= (-ladist-npos[2])/nray[2]; /* moet 1 van de snijpunten worden vervangen? */ if(ok1) { if(p1[2]<-ladist) t1= t3; } else { ok1= 1; t1= t3; } if(ok2) { if(p2[2]<-ladist) t2= t3; } else { ok2= 1; t2= t3; } } else if(ok1==0 || ok2==0) return; /* minstens 1 zichtbaar snijpunt */ if(t1<0.0 && t2<0.0) return; if(t1<0.0) t1= 0.0; if(t2<0.0) t2= 0.0; if(t1==t2) return; /* voor zekerheid nog eens sorteren */ if(t1>t2) { a= t1; t1= t2; t2= a; } /* t0 berekenen: is de maximale zichtbare z (als halo door vlak doorsneden wordt) */ if(doclip) { if(use_yco==0) t0= (maxz-npos[2])/nray[2]; else t0= (maxy-npos[1])/nray[1]; if(t0ibuf= mbuf; makemipmap(ima); /* bereken welke twee ibufs nodig zjn */ /* maxd = relatieve afmeting samplegebied */ if(mbuf->x > mbuf->y) maxd= fac/mbuf->x; else maxd= fac/mbuf->y; if(maxd>0.5) maxd= 0.5; pixsize = 2.0 / (float) MAX2(mbuf->x, mbuf->y); mm= ima->mipmap; previbuf= ibuf= ima->ibuf; while(mm) { if(maxd <= pixsize) break; previbuf= ibuf; ibuf= mm->ibuf; pixsize= 2.0 / (float)MAX2(ibuf->x, ibuf->y); mm= mm->next; } buf1fac= 2.0*(pixsize-maxd)/pixsize; buf2fac= 1.0-buf1fac; trect= mallocN(4*mbuf->x*mbuf->y, "doblur1"); rt= (char *)trect; rm= (char *)mbuf->rect; for(y=0; yy; y++) { /* float coordinaat */ dx= 1.0/(float)(mbuf->x); fx= 0.5*dx; fy= (((float)y)+.5) /(float)(mbuf->y); maxx= fx+0.5*maxd; minx= fx-0.5*maxd;; maxy= fy+0.5*maxd; miny= fy-0.5*maxd;; for(x=0; xx; x++, rt+= 4, rm+= 4) { boxsample(ibuf, minx, miny, maxx, maxy, &colr, &colg, &colb, &cola); if(previbuf!=ibuf) { /* interpoleren */ boxsample(previbuf, minx, miny, maxx, maxy, &fac1, &fac2, &fac3, &fac4); if(buf1fac>=1.0) { cola= fac4; colb= fac3; colg= fac2; colr= fac1; } else { colb= buf2fac*colb+ buf1fac*fac3; colg= buf2fac*colg+ buf1fac*fac2; colr= buf2fac*colr+ buf1fac*fac1; cola= buf2fac*cola+ buf1fac*fac4; } } rt[0]= 255.0*cola; rt[1]= 255.0*colb; rt[2]= 255.0*colg; rt[3]= 255.0*colr; minx+= dx; maxx+= dx; } } /* vrijgeven */ mm= ima->mipmap; while(mm) { mmn= mm->next; freeImBuf(mm->ibuf); freeN(mm); mm= mmn; } freeN(ima); freeN(mbuf->rect); mbuf->rect= trect; } void blurbuf(struct ImBuf *ibuf, int nr) { /* nr = aantal keer verkleinen en vergroten */ /* vervangt de rect van ibuf */ struct ImBuf *tbuf, *ttbuf; int i, x4; tbuf= dupImBuf(ibuf); x4= ibuf->x/4; /* verkleinen */ for(i=0; ix<4 || tbuf->y<4) break; } /* vergroten */ for(i=0; ix > x4) { scaleImBuf(tbuf, ibuf->x, ibuf->y); break; } } freeN(ibuf->rect); ibuf->rect= tbuf->rect; freeN(tbuf); } void doblur(struct ImBuf *mbuf, float fac) { /* maak mipmap structuur aan * fac is aantal pixels */ struct ImBuf *ibuf, *pbuf; float ifac, pfac; int n, b1, b2; char *irect, *prect, *mrect; /* welke twee buffers zijn nodig? */ if(fac>7.0) fac= 7.0; if(fac<=1.0) return; pfac= 2.0; pbuf= dupImBuf(mbuf); n= 1; while(pfac < fac) { blurbuf(pbuf, n); blurbuf(pbuf, n); n++; pfac+= 1.0; } ifac= pfac; pfac-= 1.0; ibuf= dupImBuf(pbuf); blurbuf(ibuf, n); blurbuf(ibuf, n); fac= 255.0*(fac-pfac)/(ifac-pfac); b1= fac; if(b1>255) b1= 255; b2= 255-b1; if(b1==255) { freeN(mbuf->rect); mbuf->rect= ibuf->rect; freeN(ibuf); freeImBuf(pbuf); } else if(b1==0) { freeN(mbuf->rect); mbuf->rect= pbuf->rect; freeN(pbuf); freeImBuf(ibuf); } else { /* interpoleren */ n= ibuf->x*ibuf->y; irect= (char *)ibuf->rect; prect= (char *)pbuf->rect; mrect= (char *)mbuf->rect; while(n--) { mrect[0]= (irect[0]*b1+ prect[0]*b2)>>8; mrect[1]= (irect[1]*b1+ prect[1]*b2)>>8; mrect[2]= (irect[2]*b1+ prect[2]*b2)>>8; mrect[3]= (irect[3]*b1+ prect[3]*b2)>>8; mrect+= 4; irect+= 4; prect+= 4; } freeImBuf(ibuf); freeImBuf(pbuf); } } void bufblend(rt, ri, b1, b2) char *rt, *ri; int b1, b2; { rt[1]= (rt[1]*b1+ ri[1]*b2)>>8; rt[2]= (rt[2]*b1+ ri[2]*b2)>>8; rt[3]= (rt[3]*b1+ ri[3]*b2)>>8; } void bufadd(rt, ri, b1, b2) char *rt, *ri; long b1, b2; { long c; c= rt[1]+ ((ri[1]*b2)>>8); if(c>255) rt[1]= 255; else rt[1]= c; c= rt[2]+ ((ri[2]*b2)>>8); if(c>255) rt[2]= 255; else rt[2]= c; c= rt[3]+ ((ri[3]*b2)>>8); if(c>255) rt[3]= 255; else rt[3]= c; } void bufsub(rt, ri, b1, b2) char *rt, *ri; long b1, b2; { long c; c= rt[1]- ((ri[1]*b2)>>8); if(c<0) rt[1]= 0; else rt[1]= c; c= rt[2]- ((ri[2]*b2)>>8); if(c<0) rt[2]= 0; else rt[2]= c; c= rt[3]- ((ri[3]*b2)>>8); if(c<0) rt[3]= 0; else rt[3]= c; } void onlyinblack(rt, ri, b1, b2) ulong *rt, *ri; long b1, b2; { long c; if(*rt==0) *rt= *ri; } void addalphaOverNA(rt, ri, b1, b2) /* Normal Alpha */ char *rt, *ri; long b1, b2; { long c; /* premullen */ ri[0]= (b2*ri[0])>>8; c= ri[0]; ri[1]= (c*ri[1])>>8; ri[2]= (c*ri[2])>>8; ri[3]= (c*ri[3])>>8; addalphaOver(rt, ri); } void addalphaUnderNA(rt, ri, b1, b2) /* Normal Alpha */ char *rt, *ri; long b1, b2; { long c; ri[0]= (b2*ri[0])>>8; ri[1]= (b2*ri[1])>>8; ri[2]= (b2*ri[2])>>8; ri[3]= (b2*ri[3])>>8; addalphaUnderGamma(rt, ri, b1, b2); } void dobufscript() { extern void rectcpy(), rectfill(); void (*blendfunc)(); struct ImBuf *ibuf, *ibuf2; FILE *fp; float x1,x2,fac,ease(); ulong *rt, *ri; long cfra,sf,ef, ofs,b1,b2, x, y; short end=1,scr,ipo; char *strp, str[100], ipostr[20]; strcpy(str,G.bufscr); convertstringcode(str); fp=fopen(str,"r"); if(fp==NULL) { error("Can't open script"); return; } while(end>0) { cfra= G.cfra; /* cfra= G.framelen*G.cfra; OOK HIERONDER NOG EEN KEER */ if(cfra<1) cfra= 1; end=fscanf(fp,"%s",str); if(end<=0) break; scr=0; /* operators op R.rectot */ if( strcmp(str, "LOAD")==0) scr=1; else if( strcmp(str, "BLEND")==0) scr=2; else if( strcmp(str, "ADDALPHAOVER")==0) scr=3; else if( strcmp(str, "ADDALPHAUNDER")==0) scr=4; else if( strcmp(str, "ONLYINBLACK")==0) scr=5; else if( strcmp(str, "LOADCROP")==0) scr=6; /* LET OP: begin-eind waarde is x-y ofset */ else if( strcmp(str, "DOUBLECROSS")==0) scr=7; /* LET OP: eerst plaatje laden met LOAD */ else if( strcmp(str, "ADD")==0) scr=10; else if( strcmp(str, "SUB")==0) scr=11; else if( strcmp(str, "BLUR_LOAD")==0) scr=101; /* else if( strcmp(str, "BLUR_BLEND")==0) scr=102; */ /* else if( strcmp(str, "BLUR_ADDALPHAOVER")==0) scr=103; */ else if( strcmp(str,"END")==0 ) { end= -1234; break; } if(scr) { end= fscanf(fp,"%s",str); if(end<0) break; if( str[strlen(str)-1]=='/' ) { end= fscanf(fp, "%d", &ofs); if(end<=0) break; /* ofs= G.framelen*(G.cfra+ofs); afgeschakeld!! */ ofs= (G.cfra+ofs); if(ofs<1) ofs= 1; makepicstring2(str, ofs); } end= fscanf(fp,"%d %d",&sf,&ef); if(end<=0) break; end= fscanf(fp,"%f %f",&x1,&x2); if(end<=0) break; end= fscanf(fp,"%s",ipostr); if(end<=0) break; ipo=0; if(ipostr[0]=='i') ipo=1; else if(ipostr[0]=='c') ipo=2; if(ipo) strp= ipostr+1; else strp= ipostr; if( strcmp(strp,"EASE")==0 ) { end=fscanf(fp,"%d %d",&b1,&b2); if(end<=0) break; } else b1=b2=0; if( (cfra>=sf && cfra<=ef) || (ef==0 && sf==0) ) { fac=ef-sf; if(fac==0) fac=1; else { if(b1!=0 || b2!=0) { fac=ease((float)cfra-sf,(float)ef-sf,(float)b1,(float)b2); } else { fac=(cfra-sf)/fac; if(fac<0) fac=0; else if(fac>1) fac=1; } } } else if(ipo==1) fac= -1; else if(cfra=0) { ibuf= loadiffname(str,LI_rect); if(ibuf) { if(R.rectx!=ibuf->x || R.recty!=ibuf->y) { if(scr==6) { ibuf2= allocImBuf(R.rectx, R.recty, 32, 1, 0); rectoptot(ibuf2, 0, rectfill, 0); x= (R.rectx-ibuf->x)/2 +x1; y= (R.recty-ibuf->y)/2 +x2; if(y & 1) y--; rectop(ibuf2, ibuf, x, y, 0, 0, 32767, 32767, rectcpy); freeImBuf(ibuf); ibuf= ibuf2; scr= 1; } else scalefastImBuf(ibuf, R.rectx, R.recty); } if(scr>100) { doblur(ibuf, (1-fac)*x1+fac*x2); scr-= 100; } if(scr==1) { memcpy(R.rectot, ibuf->rect, 4*R.rectx*R.recty); } else { if(scr==2) blendfunc= bufblend; else if(scr==3) blendfunc= addalphaOverNA; else if(scr==4) blendfunc= addalphaUnderNA; else if(scr==5) blendfunc= onlyinblack; else if(scr==7) blendfunc= bufblend; else if(scr==10) blendfunc= bufadd; else if(scr==11) blendfunc= bufsub; fac= (1-fac)*x1+fac*x2; b2= (long)fac; if(b2>255) b2= 255; b1= 255- b2; if(scr==7) { /* doublecross */ /* x1= ((float)b1)/255.0; */ /* x2= ((float)b2)/255.0; */ /* b1= 255.0*(3*x1*x1-2*x1*x1*x1); */ /* b2= 255.0*(3*x2*x2-2*x2*x2*x2); */ b1= (b1*b1)>>8; b2= (b2*b2)>>8; } rt= R.rectot; ri= ibuf->rect; for(y=0;y0) { end=fscanf(fp,"%s",str); if(end<=0) break; scr=0; if( strcmp(str,"BYTE")==0 ) scr=1; else if( strcmp(str,"WORD")==0 ) scr=2; else if( strcmp(str,"LONG")==0 ) scr=3; else if( strcmp(str,"FLOAT")==0 ) scr=4; else if( strcmp(str,"DOUBLE")==0 ) scr=5; else if( strcmp(str,"STRING")==0 ) scr=6; else if( strcmp(str,"TEXT")==0 ) scr=7; else if( strcmp(str,"LOAD")==0 ) scr=10; else if( strcmp(str,"REND")==0 ) scr=11; else if( strcmp(str,"ANIM")==0 ) scr=12; else if( strcmp(str,"PATCH")==0 ) scr=13; else if( strcmp(str,"PATCH2")==0 ) scr=14; else if( strcmp(str,"END")==0 ) { end= -1234; break; } if(scr>=1 && scr<=7) { nnr= 0; end=fscanf(fp,"%s %d",naam,&nnr); if(end<0) break; end=fscanf(fp,"%s %d",data,&ofs); if(end<=0) break; end=fscanf(fp,"%d %d",&sf,&ef); if(end<=0) break; if (scr <= 5) { end=fscanf(fp,"%f %f",&x1,&x2); } else { end=fscanf(fp," %256[^#]# %256[^#]# ", string1, string2); } if(end<=0) break; end=fscanf(fp,"%s",ipostr); if(end<=0) break; ipo=0; if(ipostr[0]=='i') ipo=1; else if(ipostr[0]=='c') ipo=2; else if(ipostr[0]=='p') ipo=3; if(ipo) strp= ipostr+1; else strp= ipostr; if( strcmp(strp,"EASE")==0 ) { end=fscanf(fp,"%d %d",&b1,&b2); if(end<=0) break; } else b1=b2=0; /* dit stuk (tot aan do ) moet hier staan, als meerdere bases * worden veranderd, wordt dit maar 1 x uitgerekend. */ cfra= G.framelen*G.cfra; if(cfra<1) cfra= 1; /* cyclic */ if(ipo==2 || ipo==3) { delta= abs(ef-sf+1); while(cfra>ef) cfra-= delta; while(cfrastr,14)==0 ) { if(nnr== -1) ok= 1; else if(nnr==base->nnr) ok= 1; } if(ok) { adr=0; if(strcmp(data,"BASE")==0) adr= (char *)base; if(strcmp(data,"BADA")==0) adr= (char *)base->d; if(strcmp(data,"VIEW")==0) { adr= (char *)&view0; viewchanged= 1; } if(strcmp(data,"WRLD")==0) adr= (char *)&wrld; if(strncmp(data,"TEX", 3)==0) { tbl= atol( data+3 ); if(tbl>0 && tbl<=G.totex) adr= (char *)G.adrtex[tbl]; } if(adr==0) { end=EOF; break; } adr+=ofs; if( (cfra>=sf && cfra<=ef) || (ef==0 && sf==0) ) { fac=ef-sf; if(fac==0) fac=1; else { if(b1!=0 || b2!=0) { fac=ease((float)cfra-sf,(float)ef-sf,(float)b1,(float)b2); } else { fac=(cfra-sf)/fac; if(fac<0) fac=0; else if(fac>1) fac=1; } } } else if(ipo==1) fac= -1; else if(cfra=0) { if (scr==4) { *(float *)adr= (1-fac)*x1+fac*x2; } else if (scr == 6) { strcpy(adr, string1); } else if (scr == 7) { adr = (char *) (((struct ObData *) adr)->fo); if (adr) { adr = (char *) (((struct FontData *) adr)->str); if (adr) { long len1, len2, i; float f1, f2; len1 = strlen(string1); len2 = strlen(string2); if (len1 != len2) { if (len1 > len2) strcpy(stringn, string1); else strcpy(stringn, string2); len1 = len1 + 0.5 + fac * (len2 - len1); stringn[len1] = 0; } else { for (i = 0; i < len1; i++) { f1 = string1[i]; f2 = string2[i]; stringn[i] = f1 + 0.5 + fac * (f2 - f1); } stringn[len1] = 0; } strcpy(adr, stringn); makepolytext(base); extrudepoly(base); } } } else { nr= ffloor( (1-fac)*x1+fac*x2+.1 ); if(scr==1) *adr= nr; else if(scr==2) *((short *)adr)= nr; else if(scr==3) *((long *)adr)= nr; } } } if(base==0) { if(naam[0]!='~') base= G.firstbase; } else base= base->next; } while(base); } else if(scr==10) { /* load */ end=fscanf(fp,"%s",str); if(end<0) break; leesscene(str,0); if(G.winar[0]) projektie(); } else if(scr==11) { /* rend */ end=fscanf(fp,"%d",&b1); if(end<0) break; G.cfra= b1; initrender(0); } else if(scr==12) { /* anim */ initrender(R.anim); } else if(scr==13) { /* patch */ G.genlock = 0; } else if(scr==14) { /* patch */ G.genlock = 1; } if(G.afbreek) { if(getbutton(LEFTSHIFTKEY)) break; } } /*if(G.afbreek==0 && end!= -1234) error("Syntax error");*/ fclose(fp); if(viewchanged && !G.background) { SetButs(111, 125); } } void doscript(long field) { float ipo(), frametotime(); struct Base *base; FILE *fp; float x1,x2,fac,ease(); long nnr,tsf,tef,b1,b2,ofs,nr, tbl, delta; float cfra, sf, ef; short end=1,scr,ipo1,ok, viewchanged= 0; char str[100],naam[40],data[40],ipostr[40], string1[256], string2[256], stringn[256],*strp,*adr; float add = 0.0; long debug = FALSE; data[0]= 0; if(G.background==0 && G.localview) return; strcpy(str,G.scr); convertstringcode(str); fp=fopen(str,"r"); if(fp==NULL) { error("Can't open script"); return; } while(end>0) { end=fscanf(fp,"%s",str); if(end<=0) { if (debug) printf("end: %d\n", end); break; } scr=0; if( strcmp(str,"BYTE")==0 ) scr=1; else if( strcmp(str,"WORD")==0 ) scr=2; else if( strcmp(str,"LONG")==0 ) scr=3; else if( strcmp(str,"FLOAT")==0 ) scr=4; else if( strcmp(str,"DOUBLE")==0 ) scr=5; else if( strcmp(str,"STRING")==0 ) scr=6; else if( strcmp(str,"TEXT")==0 ) scr=7; else if( strcmp(str,"LOAD")==0 ) scr=10; else if( strcmp(str,"REND")==0 ) scr=11; else if( strcmp(str,"ANIM")==0 ) scr=12; else if( strcmp(str,"CAMERA")==0 ) scr=13; else if( strcmp(str,"DEBUG")==0 ) {debug = TRUE; scr = -1; printf("debug on\n");} else if( strcmp(str,"+0.0")==0 ) add = 0.0; else if( strcmp(str,"+0.5")==0 ) add = 0.5; else if( strcmp(str,"+1.0")==0 ) add = 1.0; else if( strcmp(str,"END")==0 ) { end= -1234; break; } if (scr == 0 && debug) printf("skipping: %s\n", str); if(scr>=1 && scr<=7) { nnr= 0; end=fscanf(fp,"%s %d",naam,&nnr); if(end<0) break; end=fscanf(fp,"%s %d",data,&ofs); if(end<=0) break; end=fscanf(fp,"%d %d",&tsf,&tef); if(end<=0) break; sf = tsf; ef = tef + add; if (scr <= 5) { end=fscanf(fp,"%f %f",&x1,&x2); } else { end=fscanf(fp," %256[^#]# %256[^#]# ", string1, string2); } if(end<=0) break; end=fscanf(fp,"%s",ipostr); if(end<=0) break; ipo1=0; if(ipostr[0]=='i') ipo1=1; else if(ipostr[0]=='c') ipo1=2; else if(ipostr[0]=='p') ipo1=3; if(ipo1) strp= ipostr+1; else strp= ipostr; if( strcmp(strp,"EASE")==0 ) { end=fscanf(fp,"%d %d",&b1,&b2); if(end<=0) break; } else b1=b2=0; /* dit stuk (tot aan do ) moet hier staan, als meerdere bases * worden veranderd, wordt dit maar 1 x uitgerekend. */ cfra= frametotime(G.cfra); if(cfra < 1.0) cfra= 1.0; /* cyclic */ if(ipo1==2 || ipo1==3) { delta= abs(ef-sf+1); while(cfra>ef) cfra-= delta; while(cfrastr,14)==0 ) { if(nnr== -1) ok= 1; else if(nnr==base->nnr) ok= 1; } if(ok) { adr=0; if(strcmp(data,"BASE")==0) adr= (char *)base; if(strcmp(data,"BADA")==0) adr= (char *)base->d; if(strcmp(data,"VIEW")==0) { adr= (char *)&view0; if(ofs==80) viewchanged= 1; } if(strcmp(data,"WRLD")==0) adr= (char *)&wrld; if(strncmp(data,"TEX", 3)==0) { tbl= atol( data+3 ); if(tbl>0 && tbl<=G.totex) adr= (char *)G.adrtex[tbl]; } if(adr==0) { end=EOF; break; } adr+=ofs; if( (cfra>=sf && cfra<=ef) || (ef==0 && sf==0) ) { fac=ef-sf; if(fac==0) fac=1; else { if(b1!=0 || b2!=0) { fac=ease((float)cfra-sf,(float)ef-sf,(float)b1,(float)b2); } else { fac=(cfra-sf)/fac; if(fac<0) fac=0; else if(fac>1) fac=1; } } } else if(ipo1==1) fac= -1; else if(cfra=0) { if (scr==4) { *(float *)adr= (1-fac)*x1+fac*x2; } else if (scr == 6) { strcpy(adr, string1); } else if (scr == 7) { adr = (char *) (((struct ObData *) adr)->fo); if (adr) { adr = (char *) (((struct FontData *) adr)->str); if (adr) { long len1, len2, i; float f1, f2; len1 = strlen(string1); len2 = strlen(string2); if (len1 != len2) { if (len1 > len2) strcpy(stringn, string1); else strcpy(stringn, string2); len1 = len1 + 0.5 + fac * (len2 - len1); stringn[len1] = 0; } else { for (i = 0; i < len1; i++) { f1 = string1[i]; f2 = string2[i]; stringn[i] = f1 + 0.5 + fac * (f2 - f1); } stringn[len1] = 0; } strcpy(adr, stringn); makepolytext(base); extrudepoly(base); } } } else { nr= ffloor( (1.0-fac)*x1+fac*x2+.5 ); if(scr==1) *adr= nr; else if(scr==2) *((short *)adr)= nr; else if(scr==3) *((long *)adr)= nr; } } } if(base==0) { if(naam[0]!='~') base= G.firstbase; } else base= base->next; } while(base); } else if(scr==10) { /* load */ end=fscanf(fp,"%s",str); if(end<0) break; leesscene(str,0); if(G.winar[0]) projektie(); } else if(scr==11) { /* rend */ end=fscanf(fp,"%d",&b1); if(end<0) break; G.cfra= b1; initrender(0); } else if(scr==12) { /* anim */ initrender(R.anim); } else if(scr==13) { /* camera */ end=fscanf(fp,"%s %d",naam, &nnr); if(end<0) break; end=fscanf(fp,"%d %d",&tsf,&tef); if(end<0) break; cfra= frametotime(G.cfra); if( tsf<=cfra && tef>=cfra) { /* op zoek naar de camera met deze naam */ base= G.firstbase; while(base) { if(base->nnr==nnr && strncmp(naam, base->str, 14)==0) { view0.cambase= base; } base= base->next; } } } if(G.afbreek) { if(getbutton(LEFTSHIFTKEY)) break; } } /*if(G.afbreek==0 && end!= -1234) error("Syntax error");*/ fclose(fp); if(viewchanged && !G.background) { SetButs(111, 125); } } void speedtest1() { float fx, fy, minx, maxx, miny, maxy; spglob[0]= R.co[0]; spglob[1]= R.co[1]; spglob[2]= R.co[2]; VECCOPY(dxt, spglob); VECCOPY(dyt, spglob); switch(test) { case 0: fx = (spglob[0] + 32768.0) / 65536.0; fy = (spglob[1] + 32768.0) / 65536.0; dxt[0]/=65536.0; dxt[1]/=65536.0; dyt[0]/=65536.0; dyt[1]/=65536.0; break; case 1: break; } if(fx<0.0) fx= 0.0; else if(fx>1.0) fx= 1.0; if(fy<0.0) fy= 0.0; else if(fy>1.0) fy= 1.0; /* pixel coordinaten */ minx= MIN3(dxt[0],dyt[0],dxt[0]+dyt[0] ); maxx= MAX3(dxt[0],dyt[0],dxt[0]+dyt[0] ); miny= MIN3(dxt[1],dyt[1],dxt[1]+dyt[1] ); maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] ); } void speedtest() { long a; for(a=0; a<20; a++) { speedtest1(); } } void initeffects() { /* initspeakerdata(); */ } void bgneffect(vv) struct VV *vv; { long len; len= sizeof(struct VV)+vv->vert*sizeof(struct VertOb)+vv->vlak*sizeof(struct VlakOb); effvv= (struct VV *)mallocN(len,"bgneffect"); memcpy(effvv,vv,len); } void endeffect(vv) struct VV *vv; { long len; len= sizeof(struct VV)+vv->vert*sizeof(struct VertOb)+vv->vlak*sizeof(struct VlakOb); memcpy(vv,effvv,len); freeN(effvv); effvv= 0; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ short build(cur,tot,base, len) /* nog primitief */ short cur,tot; struct Base *base; short len; { short cfra, grens; cfra= G.cfra-(base->sf-1); if(cfra<0) return 0; if( cfra >= base->len ) return 1; if( cfra==G.sfra) return 0; grens= (cfra*tot)/base->len; if(cur>=grens) return 0; if(cur< grens-len) return 0; return 1; } int build_schiphol(base, tot) /* geeft aantal vlakken terug op current frame */ struct Base *base; int tot; { float frametofloat(); float fac; fac= frametofloat( (float)G.cfra, base->sf, base->len, base->f2 & 1); fac*= tot; return ( (int)fac ); } /* VLAKLAMP */ float calcStokefactor(lar, nor) struct LampRen *lar; float *nor; { float tvec[3], cent[3], fac; float vec[4][3]; /* vectoren van shootcent naar vertices rp */ float cross[4][3]; /* uitprodukten hiervan */ float rad[4]; /* hoeken tussen vecs */ /* vlak: lar->face[4][3] bestaat niet meer! Include veranderen! * cent: R.co * norm: nor */ VECCOPY(cent, R.co); /* test op richting */ /* VecSubf(tvec, shoot->cent, rp->cent); */ /* if( tvec[0]*shoot->norm[0]+ tvec[1]*shoot->norm[1]+ tvec[2]*shoot->norm[2]>0.0) */ /* return 0.0; */ /* hoekvectors */ /* VecSubf(vec[0], cent, lar->face[0]); */ /* VecSubf(vec[1], cent, lar->face[1]); */ /* VecSubf(vec[2], cent, lar->face[2]); */ /* VecSubf(vec[3], cent, lar->face[3]); */ Normalise(vec[0]); Normalise(vec[1]); Normalise(vec[2]); Normalise(vec[3]); /* uitprod */ Crossf(cross[0], vec[0], vec[1]); Crossf(cross[1], vec[1], vec[2]); Crossf(cross[2], vec[2], vec[3]); Crossf(cross[3], vec[3], vec[0]); Normalise(cross[0]); Normalise(cross[1]); Normalise(cross[2]); Normalise(cross[3]); /* hoeken */ rad[0]= vec[0][0]*vec[1][0]+ vec[0][1]*vec[1][1]+ vec[0][2]*vec[1][2]; rad[1]= vec[1][0]*vec[2][0]+ vec[1][1]*vec[2][1]+ vec[1][2]*vec[2][2]; rad[2]= vec[2][0]*vec[3][0]+ vec[2][1]*vec[3][1]+ vec[2][2]*vec[3][2]; rad[3]= vec[3][0]*vec[0][0]+ vec[3][1]*vec[0][1]+ vec[3][2]*vec[0][2]; rad[0]= facos(rad[0]); rad[1]= facos(rad[1]); rad[2]= facos(rad[2]); rad[3]= facos(rad[3]); /* Stoke formule */ VecMulf(cross[0], rad[0]); VecMulf(cross[1], rad[1]); VecMulf(cross[2], rad[2]); VecMulf(cross[3], rad[3]); fac= nor[0]*cross[0][0]+ nor[1]*cross[0][1]+ nor[2]*cross[0][2]; fac+= nor[0]*cross[1][0]+ nor[1]*cross[1][1]+ nor[2]*cross[1][2]; fac+= nor[0]*cross[2][0]+ nor[1]*cross[2][1]+ nor[2]*cross[2][2]; fac+= nor[0]*cross[3][0]+ nor[1]*cross[3][1]+ nor[2]*cross[3][2]; return (-fac); } /* ***************** EDGE ENHANCE ****************************** */ void subtractcol(c1, c2) char *c1, *c2; { long val; val= c1[1]-c2[1]; if(val<0) c1[1]= 0; else c1[1]= val; val= c1[2]-c2[2]; if(val<0) c1[2]= 0; else c1[2]= val; val= c1[3]-c2[3]; if(val<0) c1[3]= 0; else c1[3]= val; } void edge_enhance(osa) long osa; { /* maak van zbuffer eerste afgeleide */ float fval; long val, y, x, col, *rz, *rnew, *rz1, *rz2, *rz3; char *cp; /* alle getallen in zbuffer 3 naar rechts shiften */ rz= (long *)R.rectz; if(rz==0) return; for(y=0; y>= 3; } } /* eerste order: val= abs(rz1[0]-rz2[1])+ 2*abs(rz1[1]-rz2[1])+ abs(rz1[2]-rz2[1]); val+= 2*abs(rz2[0]-rz2[1])+ 2*abs(rz1[2]-rz2[1]); val+= abs(rz3[0]-rz2[1])+ 2*abs(rz3[1]-rz2[1])+ abs(rz3[2]-rz2[1]); *rz= val; */ rz1= (long *)R.rectz; rz2= rz1+R.rectx; rz3= rz2+R.rectx; rz= (long *)R.rectot+R.rectx; if(G.ali) { cp= (char *)(R.rectaccu+R.rectx); } else { cp= (char *)(R.rectot+R.rectx); } for(y=0; y>14; if(col>255) col= 255; if(col) { if(G.ali) { col/= G.osa; val= cp[0]+col; if(val>255) cp[0]= 255; else cp[0]= val; if(R.f & 16) { /* transp!! */ val= cp[1]- col; if(val<0) cp[1]= 0; else cp[1]= val; val= cp[2]- col; if(val<0) cp[2]= 0; else cp[2]= val; val= cp[3]- col; if(val<0) cp[3]= 0; else cp[3]= val; } } else { val= cp[1]- col; if(val<0) cp[1]= 0; else cp[1]= val; val= cp[2]- col; if(val<0) cp[2]= 0; else cp[2]= val; val= cp[3]- col; if(val<0) cp[3]= 0; else cp[3]= val; } } } rz++; rz1+= 2; rz2+= 2; rz3+= 2; cp+= 8; } } /* ***************** D.O.F. ****************************** */ struct zxysort { long z; short x, y; }; long vergzval(x1,x2) struct zxysort *x1,*x2; { if( x1->z > x2->z ) return -1; else if( x1->z < x2->z) return 1; return 0; } void setzvalues_dof() { struct PixStr *ps; ulong *rd; long *rz, z, x, y, aantal, tot; rz= (long *)R.rectz; rd= R.rectdaps; for(y=0; y (long)(ps->z) ) *rz= (long)(ps->z); ps= ps->next; } } } } } float *disttab, *dofbuf; void addtodofbufo(xc, yc, z, col, rad, buf, minz, maxz, distz) long xc, yc, z; char *col; float rad, *buf; long minz, maxz, distz; { float *db, *dtab, weight, dist, r, g, b; long x, y, mul, *rz, ofs, temp, xmin, xmax, ymin, ymax; temp= xc+0.5; xmin= ffloor(temp-rad); xmax= ffloor(temp+rad); temp= yc+0.5; ymin= ffloor(temp-rad); ymax= ffloor(temp+rad); if(xmin<0) xmin= 0; if(ymin<0) ymin= 0; if(xmax>R.rectx-1) xmax= R.rectx-1; if(ymax>R.recty-1) ymax= R.recty-1; /* threshold */ z-= 1000; r= col[3]; g= col[2]; b= col[1]; mul= wrld.dofi+1; /* if(rad>1.0) { if(rad>4.0) {r= 255; g= 0; b= 0;} else if(rad>3.0) {g= 255; r= 0; b= 0;} else if(rad>2.0) {b= 255; g= 0; r= 0;} else {r= 255; g= 255; b= 0;} } */ for(y= ymin; y<=ymax; y++) { ofs= (y*R.rectx+xmin); db= buf+4*ofs; rz= (long *)(R.rectz+ofs); dtab= disttab+ mul*abs(y-yc) ; for(x= xmin; x<=xmax; x++, db+=4, rz++) { if(*rz>minz) { /* afstand centrum - centrum */ dist= *(dtab+abs(x-xc)); if(dist==0.0) weight= 1.0; else if(dist < rad-0.5) weight= 1.0; else if(dist>rad+0.5) weight= 0.0; else { weight= rad+0.5-dist; } if(weight!=0.0) { weight/= 6.3*rad*rad; if(*rz>maxz || *rz>z) { db[0]+= weight; db[1]+= weight*b; db[2]+= weight*g; db[3]+= weight*r; } else { dist= *rz-minz; dist/= ((float)(z-minz)); weight*= fsqrt(fsqrt(dist)); db[0]+= weight; db[1]+= weight*b; db[2]+= weight*g; db[3]+= weight*r; } } } } } } float calcz_dof(vec) float *vec; { float hoco[4]; projectverto(vec, hoco); if(hoco[2]>hoco[3] || hoco[2]<0.0) return 0.0; else { return (float)0x7FFFFFFF *(hoco[2]/hoco[3]); } } void dofo() { /* alleen als geen parts */ float size, filtsize, *dofbuf, *db, vec[3], hoco[4]; ulong *rz; ulong minz, maxz, staz, endz, distz; long x, y, min; char *rt; db= disttab= mallocN(4*(wrld.dofi+1)*(wrld.dofi+1), "dof"); for(y=0; y<=wrld.dofi; y++) { for(x=0; x<=wrld.dofi; x++, db++) { *db= fsqrt( (float)(x*x+y*y) ); } } rt= (char *)R.rectot; rz= R.rectz; db= dofbuf= callocN(4*4*R.rectx*R.recty, "dof1"); /* near= 0 en far= 0x7FFFFFFF */ vec[0]= vec[1]= 0.0; vec[2]= -R.near- 1000*wrld.dofmin; minz= calcz_dof(vec); vec[2]= -R.near- 1000*wrld.dofmax; maxz= calcz_dof(vec); vec[2]= -R.near- 1000*wrld.dofsta; staz= calcz_dof(vec); vec[2]= -R.near- 1000*wrld.dofend; endz= calcz_dof(vec); distz= maxz-minz; filtsize= wrld.dofi; for(y=0; ymaxz || distz==0) size= filtsize; else { size= *rz-minz; size/= ((float)distz); size*= filtsize; } addtodofbufo(x, y, *rz, rt, size, dofbuf, minz, maxz, distz); } } if(G.afbreek) break; } rt= (char *)R.rectot; db= dofbuf; for(y=0; yR.rectx-1) xmax= R.rectx-1; if(ymax>R.recty-1) ymax= R.recty-1; col= (char *)(R.rectot+yc*R.rectx+xc); r= col[3]; g= col[2]; b= col[1]; mul= wrld.dofi+1; /* if(rad>1.0) { */ /* if(rad>4.0) {r= 255; g= 0; b= 0;} */ /* else if(rad>3.0) {g= 255; r= 0; b= 0;} */ /* else if(rad>2.0) {b= 255; g= 0; r= 0;} */ /* else {r= 255; g= 255; b= 0;} */ /* } */ for(y= ymin; y<=ymax; y++) { ofs= (y*R.rectx+xmin); db= dofbuf+4*ofs; dtab= disttab+ mul*abs(y-yc) ; for(x= xmin; x<=xmax; x++, db+=4) { /* afstand centrum - centrum */ dist= *(dtab+abs(x-xc)); if(dist==0.0) weight= 1.0; else if(dist < rad-0.5) weight= 1.0; else if(dist>rad+0.5) weight= 0.0; else { weight= rad+0.5-dist; } if(weight!=0.0) { weight/= 6.3*rad*rad; db[0]+= weight; db[1]+= weight*b; db[2]+= weight*g; db[3]+= weight*r; } } } } void dof() { /* alleen als geen parts */ struct zxysort *sb, *sortbuf; float size, filtsize, *db, vec[3], distz1, distz2; ulong *rz; ulong minz, maxz, staz, endz; long x, y, ofs; char *rt; ofs= 0; /* error */ if(wrld.dofmin>=wrld.dofsta) ofs= 1; if(wrld.dofsta>=wrld.dofend) ofs= 1; if(wrld.dofend>=wrld.dofmax) ofs= 1; if(ofs) { error("DOF: minz= *rz; sb->x= x; sb->y= y; } } qsort(sortbuf, R.rectx*R.recty, sizeof(struct zxysort), vergzval); /* accumuleren in dofbuf, is (voorlopig) float */ db= dofbuf= callocN(4*4*R.rectx*R.recty, "dof1"); sb= sortbuf; for(y=0; yz>=staz && sb->z<=endz) { ofs= sb->y*R.rectx + sb->x; rt= (char *)(R.rectot+ofs); db= dofbuf+4*ofs; db[0]+= 1.0; db[1]+= rt[1]; db[2]+= rt[2]; db[3]+= rt[3]; } else { /* afmeting filtercirkel */ if(sb->z<=minz || sb->z>=maxz) { size= 1.0; } else if(sb->zz; size= size/distz1; } else { size= sb->z-endz; size= size/distz2; } size*= filtsize; if(size>0.5) { addtodofbuf(sb->x, sb->y, size); } else { ofs= sb->y*R.rectx + sb->x; rt= (char *)(R.rectot+ofs); db= dofbuf+4*ofs; db[0]+= 1.0; db[1]+= rt[1]; db[2]+= rt[2]; db[3]+= rt[3]; } } } if(G.afbreek) break; } rt= (char *)R.rectot; db= dofbuf; for(y=0; yvert); for(a=0;avlak;a++) { if(c==0) { v1= adrve2+ adrvl1->v1; v2= adrve2+ adrvl1->v2; } else if(c==1) { v1= adrve2+ adrvl1->v2; v2= adrve2+ adrvl1->v3; } else { v1= adrve2+ adrvl1->v3; v2= adrve2+ adrvl1->v1; } dis1= abs(v1->c[0]-v2->c[0]); dis1+= abs(v1->c[1]-v2->c[1]); dis1+= abs(v1->c[2]-v2->c[2]); if(c==0) { v1= adrve1+ adrvl1->v1; v2= adrve1+ adrvl1->v2; } else if(c==1) { v1= adrve1+ adrvl1->v2; v2= adrve1+ adrvl1->v3; } else { v1= adrve1+ adrvl1->v3; v2= adrve1+ adrvl1->v1; } dx= (v1->c[0]-v2->c[0]); dis2= abs(dx); dy= (v1->c[1]-v2->c[1]); dis2+= abs(dy); dz= (v1->c[2]-v2->c[2]); dis2+= abs(dz); if(dis1!=dis2) { fac= 0.5- .2*((float)(dis2))/((float)(dis1)); if(fac>.9) fac= .9; if(fac<.1) fac= .1; dx*=fac; dy*=fac; dz*=fac; cx= (v1->c[0]+v2->c[0])/2; cy= (v1->c[1]+v2->c[1])/2; cz= (v1->c[2]+v2->c[2])/2; v1->c[0]= cx+dx; v2->c[0]= cx-dx; v1->c[1]= cy+dy; v2->c[1]= cy-dy; v1->c[2]= cz+dz; v2->c[2]= cz-dz; } adrvl1++; } } } void vlag(base) struct Base *base; { struct ObData *ob; struct VV *vv; struct VertOb *adrve; float hoek,si,co,fac,frametofloat(),x,y,z; long a; ob= (struct ObData *)base->d; vv= ob->vv; fac= frametofloat( (float)G.cfra, base->sf, base->len, base->f2 & 1); fac*= 2*PI; hoek= 15*PI/180.0; si= fsin(hoek); co= fcos(hoek); adrve= (struct VertOb *)(vv+1); for(a=0;avert;a++) { x= adrve->c[0]; x= co*x; x/= (10767.0/PI); z= 0.12*(32767+adrve->c[0])*(fsin(x-fac)); adrve->c[2]= z; adrve++; } } void vlagdiag(base) struct Base *base; { struct ObData *ob; struct VV *vv; struct VertOb *adrve; float hoek,si,co,fac,frametofloat(),x,y,z; long a; ob= (struct ObData *)base->d; vv= ob->vv; fac= frametofloat( (float)G.cfra,base->sf,base->len,base->f2 & 1); fac*= 2*PI; hoek= 15*PI/180.0; si= fsin(hoek); co= fcos(hoek); adrve= (struct VertOb *)(vv+1); for(a=0;avert;a++) { x= adrve->c[0]; y= adrve->c[1]; z= adrve->c[2]; x= co*x+ si*y; y= -si*adrve->c[0]+ co*y; x/= (16767.0/PI); y/= (16767.0/PI); z/= (16767.0/PI); x+= fsin(x)/2.0; z= 0.2*(32767+adrve->c[0])*(fsin(x-fac)); adrve->c[2]= z; adrve++; } } void vlago(base) struct Base *base; { struct ObData *ob; struct VV *vv; struct VertOb *adrve; float hoek,si,co,fac,fac2,frametofloat(),x,y,z; long a; ob= (struct ObData *)base->d; vv= ob->vv; hoek= 15*PI/180.0; si= fsin(hoek); co= fcos(hoek); fac= frametofloat( (float)G.cfra,base->sf,base->len,base->f2 & 1); fac*= 2*PI; adrve= (struct VertOb *)(vv+1); for(a=0;avert;a++) { x= adrve->c[0]; y= adrve->c[1]; z= adrve->c[2]; x= co*x+ si*y; y= -si*x+ co*y; x/= (32767.0/PI); fac2= (32767.0+ (float)adrve->c[0])/32767.0; x+= fcos(x)/2; z= fac2*6000.0*(fsin(-2.5*x+fac)); adrve->c[0]= (fac2-1)*30200+ fac2*z/26; adrve->c[1]+= fac2*(z/16); adrve->c[2]= z; adrve++; } } void flexa() { float fac1,fac2,fac3,breedkw,*data,*vec; ulong *rect,*rd; short absx,absy,cx,cy,dx,dy,a,x,y,mval[2]; short breed,breeddy; Device mdev[2]; ortho2(-.49,R.rectx-.5,-.49,R.recty-.5); /* voor zekerheid */ mdev[0] = MOUSEX; mdev[1] = MOUSEY; breed=25; breedkw= breed*breed; breeddy= 2*(2*breed+1); getdev(2, mdev, mval); cx= mval[0]-R.xof; cy=mval[1]-R.yof; if((cx-breed<0) || (cx+breed>R.rectx) || (cy-breed<0) || (cy+breed>R.recty)) { return; } rect=(ulong *)mallocN(4*(2*breed)*(2*breed)+breed, "rt"); data=(float *)mallocN(8*(2*breed+1)*(2*breed+1)+breed, "rt"); lrectread(cx-breed,cy-breed,cx+breed-1,cy+breed-1,rect); while(getbutton(LEFTMOUSE)) { /* bereken dx en dy */ getdev(2, mdev, mval); dx= -cx+mval[0]-R.xof; dy= -cy+mval[1]-R.yof; if(dx<-breed) dx= -breed; else if(dx>breed) dx=breed; if(dy<-breed) dy= -breed; else if(dy>breed) dy=breed; /* init vertexdata */ vec= data; for(y= -breed;y<=breed;y++) { for(x= -breed;x<=breed;x++) { absx= abs(x); absy= abs(y); if(absx==breed || absy==breed) { vec[0]= cx+x; vec[1]= cy+y; } else { /* afstand tot centrum kwadraat */ fac1= x*x+y*y; fac1= 1.0-fac1/breedkw; fac2= 1.0- absx/(float)breed; fac3= 1.0- absy/(float)breed; fac2= fsqrt(fac2); fac3= fsqrt(fac3); fac1=fac2*fac3; vec[0]= cx+x+ (fac1)*dx; vec[1]= cy+y+ (fac1)*dy; } vec+=2; } } /* tekenpolys */ vec= data; rd= rect; for(y= -breed;y 0 ; y--){ rect = recto; rect += (ofsy >> 16) * oldx; ofsy += stepy; ofsx = 32768; for (x = newx ; x>0 ; x--){ *newrect++ = rect[ofsx >> 16]; ofsx += stepx; } } } void zoomwin() { static float zoom=3.0; ulong *rz,*rect; long q_event; short x,y,cx,cy,cxo=12000,cyo=0,lus=1,val,mval[2]; Device mdev[2]; mdev[0] = MOUSEX; mdev[1] = MOUSEY; if(R.rectot==0) return; zbuffer(0); zdraw(1); lrectwrite(0,0,R.rectx-1,R.recty-1,R.rectot); zdraw(0); rectzoom(zoom,zoom); while(lus) { getdev(2, mdev, mval); cx= mval[0]-R.xof; cy=mval[1]-R.yof; x= R.rectx/(2*zoom)+1; y= R.recty/(2*zoom)+1; if(cxR.rectx-x) cx=R.rectx-x; if(cy>R.recty-y) cy=R.recty-y; if(cx==cxo && cy==cyo); else { cxo=cx; cyo=cy; readsource(SRC_ZBUFFER); rectcopy(cx-x,cy-y,cx+x,cy+y,0,0); readsource(SRC_AUTO); finish(); /* wachten tot GLpipe klaar is */ } while(qtest()!=0 && lus==1) { q_event=traces_qread(&val); if(val) { if(q_event==ESCKEY) lus=0; else if(q_event==INPUTCHANGE) { lus=0; qenter(q_event,val); } else if(q_event==PADMINUS) { zoom-=1.0; cxo= 0; if(zoom<2.0) zoom=2.0; else rectzoom(zoom,zoom); } else if(q_event==PADPLUSKEY) { zoom+=1.0; if(zoom>15.0) zoom=15.0; else rectzoom(zoom,zoom); cxo=0; } else if(q_event==JKEY) { if(R.rectspare==0) R.rectspare= (ulong *)callocN(4*R.rectx*R.recty, "rectot"); SWAP(ulong *, R.rectspare, R.rectot); /* naar zbuf schrijven */ rectzoom(1.0, 1.0); zbuffer(0); zdraw(1); lrectwrite(0, 0, R.rectx-1, R.recty-1, R.rectot); zdraw(0); rectzoom(zoom, zoom); cxo= 12000; /* redraw */ } } } sginap(1); } rectzoom(1.0,1.0); readsource(SRC_ZBUFFER); rectcopy(0,0,R.rectx-1,R.recty-1,0,0); readsource(SRC_AUTO); /* lrectwrite(0,0,R.rectx-1,R.recty-1,R.rectot); */ } void husselverts_o() { struct VV *vv; struct VertOb *adrve,*adrven,*ve; struct VlakOb *adrvl; float mult; long ra; short a,new,oud,*hash,*h; if(G.ebase!=0 || G.basact==0 || G.basact->soort!= 1) return; if(okee("Hash vertices")==0) return; vv= ((struct ObData *)G.basact->d)->vv; /* array maken van husselgetallen */ h= hash= (short *)mallocN(2*vv->vert,"husselverts"); for(a=0;avert;a++) { *(h++)=a; } srandom(1); mult= ((float)vv->vert)/32768.0; h= hash; for(a=0;avert;a++) { new= (short) (mult*( (float)(random() & 32767) )); if(new>=0 && newvert) { oud= *h; *h= hash[new]; hash[new]= oud; } h++; } /* nieuw temp vertexblock */ adrven= (struct VertOb *)mallocN(vv->vert*sizeof(struct VertOb),"temphussel"); ve= adrve= (struct VertOb *)(vv+1); h= hash; for(a=0;avert;a++) { memcpy((adrven+ *h),ve,sizeof(struct VertOb)); h++; ve++; } /* nieuw naar oud moven */ memcpy(adrve,adrven,vv->vert*sizeof(struct VertOb)); /* vlakpointers goedzetten */ adrvl= (struct VlakOb *)(adrve+vv->vert); for(a=0;avlak;a++) { adrvl->v1= hash[adrvl->v1]; adrvl->v2= hash[adrvl->v2]; adrvl->v3= hash[adrvl->v3]; adrvl++; } freeN(hash); freeN(adrven); } struct VertOb *verg_vert; int verg_hoogste_zco(x1, x2) struct VlakOb *x1,*x2; { int z1, z2; struct VertOb *v1, *v2, *v3; v1= verg_vert+x1->v1; v2= verg_vert+x1->v2; v3= verg_vert+x1->v3; z1= MAX3(v1->c[2], v2->c[2], v3->c[2]); v1= verg_vert+x2->v1; v2= verg_vert+x2->v2; v3= verg_vert+x2->v3; z2= MAX3(v1->c[2], v2->c[2], v3->c[2]); if( z1 > z2 ) return 1; else if( z1 < z2) return -1; return 0; } void sortfaces() { int a; struct VV *vv; struct VertOb *adrve; struct VlakOb *adrvl; if(G.ebase!=0 || G.basact==0 || G.basact->soort!= 1) return; if(okee("Sort faces")==0) return; vv= ((struct ObData *)G.basact->d)->vv; adrve= verg_vert= (struct VertOb *)(vv+1); adrvl= (struct VlakOb *)(adrve+vv->vert); qsort(adrvl, vv->vlak, sizeof(struct VlakOb), verg_hoogste_zco); } int vergbaseco(x1,x2) struct Base **x1,**x2; { if( (*x1)->sy > (*x2)->sy ) return 1; else if( (*x1)->sy < (*x2)->sy) return -1; else if( (*x1)->sx > (*x2)->sx ) return 1; else if( (*x1)->sx < (*x2)->sx ) return -1; return 0; } void renamebase() { struct Base *base,**basesort,**bs; short start, tot=0, a, delta = -1; if(G.basact==0) return; if(G.qual & 3) { delta= 1; if(okee("Automatic startframes")==0) return; start= G.basact->sf; if(button(&start,1,1000,"Start")==0) return; if(button(&delta,0,100,"Step")==0) return; } else { if(okee("Rename & number bases")==0) return; start= G.basact->nnr; } /* maak lijst van alle bases, xco yco (scherm) */ base= G.firstbase; while(base) { if(TESTBASE(base)) { tot++; } base= base->next; } bs= basesort= (struct Base **)mallocN(4*tot,"renamebase"); base= G.firstbase; while(base) { if(TESTBASE(base)) { *bs= base; bs++; } base= base->next; } qsort(basesort,tot,4,vergbaseco); bs= basesort; for(a=0; asf= start; start+= delta; } else { if(*bs!=G.basact) strcpy((*bs)->str,G.basact->str); (*bs)->nnr= start++; } bs++; } freeN(basesort); projektie(); } void golf(base) struct Base *base; { struct ObData *ob; struct VV *vv; struct VertOb *a1; float f1, cfra, div1, div2; short a,b,c,size,*mem,*point,val1,val2,val3; if(base->soort!=1) return; ob= (struct ObData *)base->d; vv= ob->vv; size = sqrt(vv->vert); mem=(short *) mallocN(2*vv->vert,"golfmem"); if (mem==0) return; /* random grid */ srand(1); point=mem; cfra= G.cfra; if(G.f & 64) cfra+= .5; f1= ((float)base->len)/80.0; div1= 11.0*f1; div2= 13.0*f1; for(a=0; avert; a++) { f1 = rand()*sin( cfra/div1 + rand()/1000.0 )/60.0; f1 += rand()*sin( cfra/div2 + rand()/1000.0 )/60.0; *(point++) = f1; } /* filteren: */ for(c=2;c>0;c--){ for(a=0;a0;b--){ val3 = point[size]; *point = (val1 + (val2<<1) + val3) >> 2; val1 = val2; val2 = val3; point += size; } *point = (val2 + 3*val3) >> 2; } point = mem; for(a=0;a0;b--){ val3 = point[1]; *point = (val1 + (val2<<1) + val3) >> 2; val1 = val2; val2 = val3; point += 1; } *(point++) = (val2 + 3*val3) >> 2; } } /* in z waardes vertices schrijven */ a1=(struct VertOb *)(vv+1); point=mem; for(a=0;avert;a++) { a1->c[2] = *(point++); a1++; } freeN(mem); } void vertexTex(struct ObData *ob) { struct Tex *rtex; struct VertOb *ve; float b2,t[3],vec[3],hnoise(),ofs; int tot, nr; if(ob->ef!=3) return; nr= ob->elen; if(G.totexvar[1]; ve= (struct VertOb *)((ob->vv)+1); tot= ob->vv->vert; while(tot--) { VECCOPY(t, ve->c); if(rtex->soort!=8) { externtex(nr, t, &b2); vec[0]= 0.0; vec[1]= 0.0; vec[2]= b2; } else { b2= hnoise(rtex->var[0],t[0],t[1],t[2]); if(rtex->type > 1) ofs*=(b2*b2); vec[0]= b2-hnoise(rtex->var[0],t[0]+ofs,t[1],t[2]); vec[1]= b2-hnoise(rtex->var[0],t[0],t[1]+ofs,t[2]); vec[2]= b2-hnoise(rtex->var[0],t[0],t[1],t[2]+ofs); } t[0]+= 4000*vec[0]; if(t[0]<-32767) t[0]= -32767; if(t[0]>32767) t[0]= 32767; t[1]+= 4000*vec[1]; if(t[1]<-32767) t[1]= -32767; if(t[1]>32767) t[1]= 32767; t[2]+= 4000*vec[2]; if(t[2]<-32767) t[2]= -32767; if(t[2]>32767) t[2]= 32767; if(view0.grid==777) { if(ve->c[2]>0) VECCOPY(ve->c, t); } else VECCOPY(ve->c, t); ve++; } } extern unsigned char hash[512]; /* - er moet een 'vast' aantal sterren gegenereerd worden tussen near en far. * - alle sterren moeten bij voorkeur op de far liggen en uitsluitend in * helderheid / kleur verschillen. * - */ void make_stars(wire) long wire; { float vec[4], fx, fy, fz; long x, y, z, sx, sy, sz, ex, ey, ez, done = 0; float minx, maxx, miny, maxy, minz, maxz, fac, starmindist; double dblrand, hlfrand; ushort seed[3]; float mat[4][4]; struct HaloRen *har; extern struct HaloRen *initstar(); float stargrid = 1000 * wrld.rt5[0]; /* om de hoeveel een ster ? */ float maxrand = 2.0; /* hoeveel mag een ster verschuiven (uitgedrukt in grid eenheden) */ int maxjit = 2 * wrld.rt5[1]; /* hoeveel mag een kleur veranderen */ float force = 100.0 * wrld.rt5[2]; /* hoe sterk zijn de sterren */ float far = 1000.0 * view0.far; float near = view0.near; /* schermafmeting sterren */ force= ( (float)wrld.rt5[2] )/20.0; force*= ( (float)R.xsch )/640.0; /* minimale vrije ruimte */ starmindist= 1000.0*wrld.starmindist; if (wrld.rt5[0] <= 10) return; if (wire == 0) R.f |= 1; else stargrid*= 2.0; /* tekent er minder */ minx = miny = minz = HUGE; maxx = maxy = maxz = -HUGE; Mat4Invert(mat, G.viewmat); /* BOUNDINGBOX BEREKENING * bbox loopt van z = near | far, * x = -z | +z, * y = -z | +z */ for (z = 0; z <= 1; z++) { if (z) fz = - far; else fz = - near; for (y = -1; y <= 1; y += 2){ for (x = -1; x <= 1; x += 2){ vec[0] = x * fz; vec[1] = y * fz; vec[2] = fz; vec[3] = 1.0; /*printf("%.2f %.2f %.2f ", vec[0], vec[1], vec[2]);*/ Mat4MulVecfl(mat, vec); /*printf("%.2f %.2f %.2f\n", vec[0], vec[1], vec[2]);*/ if (vec[0] < minx) minx = vec[0]; if (vec[0] > maxx) maxx = vec[0]; if (vec[1] < miny) miny = vec[1]; if (vec[1] > maxy) maxy = vec[1]; if (vec[2] < minz) minz = vec[2]; if (vec[2] > maxz) maxz = vec[2]; } } } /* printf("x: %.2f %.2f %.0f\n", minx, maxx, (maxx - minx) / stargrid); printf("y: %.2f %.2f %.0f\n", miny, maxy, (maxy - miny) / stargrid); printf("z: %.2f %.2f %.0f\n", minz, maxz, (maxz - minz) / stargrid); */ /* omzetten naar grid coordinaten */ sx = (minx / stargrid) - maxrand; sy = (miny / stargrid) - maxrand; sz = (minz / stargrid) - maxrand; ex = (maxx / stargrid) + maxrand; ey = (maxy / stargrid) + maxrand; ez = (maxz / stargrid) + maxrand; dblrand = maxrand * stargrid; hlfrand = 2.0 * dblrand / RAND_MAX; /*hlfrand = 2.0 * dblrand / 1.0;*/ if (wire) { cpack(-1); bgnpoint(); } for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) { for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += stargrid) { for (z = sz, fz = sz * stargrid; z <= ez; z++, fz += stargrid) { if( fabs(fx)+fabs(fy)+fabs(fz) >starmindist ) { srand((hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8)); vec[0] = fx + (hlfrand * rand()) - dblrand; vec[1] = fy + (hlfrand * rand()) - dblrand; vec[2] = fz + (hlfrand * rand()) - dblrand; vec[3] = 1.0; if (wire) { v3f(vec); done++; } else { Mat4MulVecfl(G.viewmat, vec); if (vec[2] <= -near) { minx = (far + vec[2]) / (far - near); if (minx < 0.0) minx = 0.0; if (minx > 1.0) minx = 1.0; if(minx>0.0) { minx= fsqrt(fsqrt(minx)); fac= force * rand(); fac/= RAND_MAX; har = initstar(vec, fac); if (har) { har->alfa = 255.0 * minx; har->r = har->g = har->b = 255; if (maxjit) { har->r += ((maxjit * rand()) / RAND_MAX) - maxjit; har->g += ((maxjit * rand()) / RAND_MAX) - maxjit; har->b += ((maxjit * rand()) / RAND_MAX) - maxjit; } har->type = 32; /* even getal, geen 'ster' */ har->f= 2; /* only in sky */ done++; } } } } } } if(G.afbreek) break; } if(G.afbreek) break; } if (wire) endpoint(); /*printf("done: %d\n", done);*/ } /* ************************* SCHUIFPUZZEL **************** */ float schuifset[4][4][2]; /* coordinaten stukjes */ int sch_x, sch_y; /* huidige gat */ int sch_lastframe= 0; #define SCH_GRIDX 1600; #define SCH_GRIDY 900; void sch_moveto(int newx, int newy, float fac) { int a, b, c, deltax, deltay; float start, end, delta; if(newx<0 || newy<0 || newx>3 || newy>3) { printf("error in schuifscript: moveto %d %d\n", newx, newy); return; } deltax= newx-sch_x; deltay= newy-sch_y; /* alle stukjes in interval moeten verplaatst */ /* gat wordt: */ schuifset[3][0][0]= newx; schuifset[3][0][1]= newy; if(deltax) { if(deltax>0) { start= sch_x+1; end= newx; delta= -fac; } else { start= newx; end= sch_x-1; delta= fac; } for(a=0; a<4; a++) { for(b=0; b<4; b++) { if( ffloor(schuifset[a][b][1]+0.5) == (float)newy ) { if( ffloor(schuifset[a][b][0]+0.5) >= start && ffloor(schuifset[a][b][0]+0.5) <= end ) { schuifset[a][b][0] += delta; } } } } } else if(deltay) { if(deltay>0) { start= sch_y+1; end= newy; delta= -fac; } else { start= newy; end= sch_y-1; delta= fac; } for(a=0; a<4; a++) { for(b=0; b<4; b++) { if( ( (int)ffloor(schuifset[a][b][0]+0.5)) == newx ) { if( ffloor(schuifset[a][b][1]+0.5) >= start && ffloor(schuifset[a][b][1]+0.5) <= end ) { schuifset[a][b][1] += delta; } } } } } sch_x= newx; sch_y= newy; } void schuifpuzzel_set() { FILE *fp; float frametotime(); float cfra, fac; int a, b, newx, newy, sf, ef, end=1, delta; char str[80]; /* SYNTAX SCRIPT: * * START x * x is startframe * * DELTA x * x is delta, startframe wordt iedere moveto opgehoogd, ef= sf+delta * * MOVETO x y * x en y coordinaat gat */ strcpy(str, "//schuifscript"); convertstringcode(str); fp= fopen(str, "r"); if(fp==NULL) { printf("can't read schuifscript\n"); return; } /* initialiseren */ for(b=0; b<4; b++) { for(a=0; a<4; a++) { schuifset[a][b][0]= a; schuifset[a][b][1]= b; } } sch_x= 3; sch_y= 0; /* waar dus [3][0] staat is het gat! */ cfra= frametotime(G.cfra); while(end>0) { end= fscanf(fp, "%s ", str); if(end<0) break; if(strncmp(str, "START", 5)==0) { end= fscanf(fp, "%d", &sf); } else if(strncmp(str, "DELTA", 5)==0) { end= fscanf(fp, "%d", &delta); } else if(strncmp(str, "MOVETO", 6)==0) { end= fscanf(fp, "%d %d", &newx, &newy, &sf, &ef); if(end<0) break; ef= sf+delta; if( ((float)sf) > cfra ) break; if( cfra < ((float)ef) ) { fac= (cfra -sf); fac/= (float)delta; fac= 3.0*fac*fac-2.0*fac*fac*fac; } else fac= 1.0; sch_moveto(newx, newy, fac); sf+= delta; } } fclose(fp); } void schuifpuzzel_base(struct Base *base) /* leest schuifset en schrijft locatie in base */ { int a, b; float xfac, yfac; if( sch_lastframe != G.cfra ) { schuifpuzzel_set(); sch_lastframe= G.cfra; } switch( base->nnr ) { case 0: a= 0; b= 3; break; case 1: a= 1; b= 3; break; case 2: a= 2; b= 3; break; case 3: a= 3; b= 3; break; case 4: a= 0; b= 2; break; case 5: a= 1; b= 2; break; case 6: a= 2; b= 2; break; case 7: a= 3; b= 2; break; case 8: a= 0; b= 1; break; case 9: a= 1; b= 1; break; case 10: a= 2; b= 1; break; case 11: a= 3; b= 1; break; case 12: a= 0; b= 0; break; case 13: a= 1; b= 0; break; case 14: a= 2; b= 0; break; default: a=0; b=0; } xfac= schuifset[a][b][0]-1.5; yfac= schuifset[a][b][1]-1.5; base->o[0]= xfac*SCH_GRIDX; base->o[1]= yfac*SCH_GRIDY; }