This is shade.c in view mode; [Download] [Up]
#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;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.