home *** CD-ROM | disk | FTP | other *** search
- #include <math.h>
-
- #include "ray.h"
-
- void initdiffuse(),initspecular(),initmirror(),initglass();
- struct color diffuse(),specular(),mirror(),glass();
-
- double phong();
-
- initshade()
- { nshadetab=4;
- shadetab=nalloc(struct shadetab,nshadetab);
- shadetab[0].shadeinitfunc=initdiffuse;
- shadetab[0].shadefunc=diffuse;
- shadetab[0].nparams=6;
- shadetab[1].shadeinitfunc=initspecular;
- shadetab[1].shadefunc=specular;
- shadetab[1].nparams=10;
- shadetab[2].shadeinitfunc=initmirror;
- shadetab[2].shadefunc=mirror;
- shadetab[2].nparams=13;
- shadetab[3].shadeinitfunc=initglass;
- shadetab[3].shadefunc=glass;
- shadetab[3].nparams=17;
- }
-
- shadow(o,r)
- int o;
- struct ray r;
- {struct intersect i;
- shadowcount++;
- i=intersect(r);
- return i.obj!=o;
- }
-
- double phong(n,e,li,g)
- struct vector n,e,li;
- double g;
- {struct vector h;
- double l,c,t;
- h.x=e.x+li.x;
- h.y=e.y+li.y;
- h.z=e.z+li.z;
- l= -(h.x*n.x+h.y*n.y+h.z*n.z);
- if(l<0)
- return 0.0;
- c=l*l/(h.x*h.x+h.y*h.y+h.z*h.z);
- t=(1-c)/c;
- if(t>10*g)
- return 0;
- return exp(-t/g);
- }
-
- struct vector nilvect={0.0,0.0,0.0};
-
- struct vector reflect(n,u)
- struct vector n,u;
- {struct vector v;
- double p;
- p=2*(n.x*u.x+n.y*u.y+n.z*u.z);
- v.x=u.x-p*n.x;
- v.y=u.y-p*n.y;
- v.z=u.z-p*n.z;
- return v;
- }
-
- struct vector refract(n,u,ni)
- struct vector n,u;
- double ni;
- {struct vector v;
- double p,t;
- p=n.x*u.x+n.y*u.y+n.z*u.z;
- if(p<0)
- { t=1-(1-p*p)/(ni*ni);
- if(t<=0)
- return nilvect;
- t= -p/ni-sqrt(t);
- }
- else
- { ni=1/ni;
- t=1-(1-p*p)/(ni*ni);
- if(t<=0)
- return nilvect;
- t= -p/ni+sqrt(t);
- }
- v.x=u.x/ni+t*n.x;
- v.y=u.y/ni+t*n.y;
- v.z=u.z/ni+t*n.z;
- return v;
- }
-
- void initdiffuse(o)
- struct object *o;
- {
- #ifdef lint
- o=o;
- #endif
- }
-
- void initspecular(o)
- struct object *o;
- {
- #ifdef lint
- o=o;
- #endif
- }
-
- void initmirror(o)
- struct object *o;
- { o->flags|=REFLECT;
- }
-
- void initglass(o)
- struct object *o;
- { o->flags|=REFLECT|REFRACT|SELF;
- }
-
- struct color diffuse(n,r,i)
- int n;
- struct ray r;
- struct intersect i;
- {int j;
- struct color c;
- double l,vx,vy,vz;
- struct ray r2;
- double *sdparams;
- #ifdef lint
- n=n;
- #endif
- sdparams=objects[i.obj].sdparams;
- c.r=sdparams[0];
- c.g=sdparams[1];
- c.b=sdparams[2];
- for(j=1;j<lights+1;j++)
- { r2.a=objects[j].center;
- vx=r.a.x+i.t*r.l.x-r2.a.x;
- vy=r.a.y+i.t*r.l.y-r2.a.y;
- vz=r.a.z+i.t*r.l.z-r2.a.z;
- l=1/sqrt(vx*vx+vy*vy+vz*vz);
- vx*=l;
- vy*=l;
- vz*=l;
- r2.obj=j;
- r2.l.x=vx;
- r2.l.y=vy;
- r2.l.z=vz;
- l= -(i.n.x*vx+i.n.y*vy+i.n.z*vz);
- if(l>0&&!shadow(i.obj,r2))
- { c.r+=l*sdparams[3];
- c.g+=l*sdparams[4];
- c.b+=l*sdparams[5];
- }
- }
- return c;
- }
-
- struct color specular(n,r,i)
- int n;
- struct ray r;
- struct intersect i;
- {int j;
- struct color c;
- double l,x,y,z,sp;
- struct ray r2;
- struct vector e,li;
- double *sdparams;
- #ifdef lint
- n=n;
- #endif
- sdparams=objects[i.obj].sdparams;
- c.r=sdparams[0];
- c.g=sdparams[1];
- c.b=sdparams[2];
- x=r.a.x+i.t*r.l.x;
- y=r.a.y+i.t*r.l.y;
- z=r.a.z+i.t*r.l.z;
- e.x=x-objects[0].center.x;
- e.y=y-objects[0].center.y;
- e.z=z-objects[0].center.z;
- l=1/sqrt(e.x*e.x+e.y*e.y+e.z*e.z);
- e.x*=l;
- e.y*=l;
- e.z*=l;
- for(j=1;j<lights+1;j++)
- { r2.a=objects[j].center;
- li.x=x-r2.a.x;
- li.y=y-r2.a.y;
- li.z=z-r2.a.z;
- l=1/sqrt(li.x*li.x+li.y*li.y+li.z*li.z);
- li.x*=l;
- li.y*=l;
- li.z*=l;
- r2.obj=j;
- r2.l=li;
- l= -(i.n.x*li.x+i.n.y*li.y+i.n.z*li.z);
- if(l>0&&!shadow(i.obj,r2))
- { c.r+=l*sdparams[3];
- c.g+=l*sdparams[4];
- c.b+=l*sdparams[5];
- sp=phong(i.n,e,li,sdparams[9]);
- c.r+=sp*sdparams[6];
- c.g+=sp*sdparams[7];
- c.b+=sp*sdparams[8];
- }
- }
- return c;
- }
-
- struct color mirror(n,r,i)
- int n;
- struct ray r;
- struct intersect i;
- {int j;
- struct color c,rc;
- double l,x,y,z,sp;
- struct ray r2;
- struct vector e,li;
- double *sdparams;
- sdparams=objects[i.obj].sdparams;
- c.r=sdparams[0];
- c.g=sdparams[1];
- c.b=sdparams[2];
- x=r.a.x+i.t*r.l.x;
- y=r.a.y+i.t*r.l.y;
- z=r.a.z+i.t*r.l.z;
- e.x=x-objects[0].center.x;
- e.y=y-objects[0].center.y;
- e.z=z-objects[0].center.z;
- l=1/sqrt(e.x*e.x+e.y*e.y+e.z*e.z);
- e.x*=l;
- e.y*=l;
- e.z*=l;
- for(j=1;j<lights+1;j++)
- { r2.a=objects[j].center;
- li.x=x-r2.a.x;
- li.y=y-r2.a.y;
- li.z=z-r2.a.z;
- l=1/sqrt(li.x*li.x+li.y*li.y+li.z*li.z);
- li.x*=l;
- li.y*=l;
- li.z*=l;
- r2.obj=j;
- r2.l=li;
- l= -(i.n.x*li.x+i.n.y*li.y+i.n.z*li.z);
- if(l>0&&!shadow(i.obj,r2))
- { c.r+=l*sdparams[3];
- c.g+=l*sdparams[4];
- c.b+=l*sdparams[5];
- sp=phong(i.n,e,li,sdparams[9]);
- c.r+=sp*sdparams[6];
- c.g+=sp*sdparams[7];
- c.b+=sp*sdparams[8];
- }
- }
- r2.obj=i.obj;
- r2.a.x=x;
- r2.a.y=y;
- r2.a.z=z;
- r2.l=reflect(i.n,r.l);
- rc=trace(n+1,r2);
- c.r+=rc.r*sdparams[10];
- c.g+=rc.g*sdparams[11];
- c.b+=rc.b*sdparams[12];
- return c;
- }
-
- struct color glass(n,r,i)
- int n;
- struct ray r;
- struct intersect i;
- {int j;
- struct color c,rc;
- double l,x,y,z,sp;
- struct ray r2;
- struct vector e,li;
- double *sdparams;
- sdparams=objects[i.obj].sdparams;
- c.r=sdparams[0];
- c.g=sdparams[1];
- c.b=sdparams[2];
- x=r.a.x+i.t*r.l.x;
- y=r.a.y+i.t*r.l.y;
- z=r.a.z+i.t*r.l.z;
- e.x=x-objects[0].center.x;
- e.y=y-objects[0].center.y;
- e.z=z-objects[0].center.z;
- l=1/sqrt(e.x*e.x+e.y*e.y+e.z*e.z);
- e.x*=l;
- e.y*=l;
- e.z*=l;
- for(j=1;j<lights+1;j++)
- { r2.a=objects[j].center;
- li.x=x-r2.a.x;
- li.y=y-r2.a.y;
- li.z=z-r2.a.z;
- l=1/sqrt(li.x*li.x+li.y*li.y+li.z*li.z);
- li.x*=l;
- li.y*=l;
- li.z*=l;
- r2.obj=j;
- r2.l=li;
- l= -(i.n.x*li.x+i.n.y*li.y+i.n.z*li.z);
- if(l>0&&!shadow(i.obj,r2))
- { c.r+=l*sdparams[3];
- c.g+=l*sdparams[4];
- c.b+=l*sdparams[5];
- sp=phong(i.n,e,li,sdparams[9]);
- c.r+=sp*sdparams[6];
- c.g+=sp*sdparams[7];
- c.b+=sp*sdparams[8];
- }
- }
- r2.obj=i.obj;
- r2.a.x=x;
- r2.a.y=y;
- r2.a.z=z;
- r2.l=reflect(i.n,r.l);
- rc=trace(n+1,r2);
- c.r+=rc.r*sdparams[10];
- c.g+=rc.g*sdparams[11];
- c.b+=rc.b*sdparams[12];
- r2.l=refract(i.n,r.l,sdparams[16]);
- if(r2.l.x==0&&r2.l.y==0&&r2.l.z==0)
- return c;
- rc=trace(n+1,r2);
- c.r+=rc.r*sdparams[13];
- c.g+=rc.g*sdparams[14];
- c.b+=rc.b*sdparams[15];
- return c;
- }
-