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.