home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsv / ch5_5 / global.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-04  |  33.3 KB  |  915 lines

  1. #include <math.h>
  2. #include <stdlib.h>
  3.  
  4. //      NUMERIC CONSTANTS AND RELATED THINGS
  5.  
  6. const double Pi=3.1415926535;
  7. inline double RAD(double r) {return Pi*r/180.;}     // DEG-TO-RAD CONVERSION
  8. const double EPS=1e-4;                              // VERY SMALL NUMBER
  9.  
  10. //      LIST TEMPLATE
  11.  
  12. template <class T> struct listelem {
  13.         T o;                                            // OBJECT
  14.         listelem<T> *n;                                 // NEXT ELEMENT
  15.         listelem(T o) {this->o=o; n=(listelem<T>*)0;}
  16. };
  17.  
  18. template <class T> class list {
  19.         listelem<T> *h, *t, *a;                         // HEAD, TAIL, ACTUAL
  20. public:
  21.         list() {h=t=(listelem<T>*)0;}
  22.         ~list() {for(;h;h=a) {a=h->n; delete h;}}
  23.         void operator+=(T o) {                          // INSERT INTO LIST
  24.                 listelem<T> *e=new listelem<T>(o);
  25.                 if(t) {t->n=e; t=e;} else {h=e; t=e;}
  26.         }
  27.         T first() {a=h; return a?a->o:(T)0;}
  28.         T next() {a=a->n; return a?a->o:(T)0;}
  29.         int operator[](T o) {                                   // o ON LIST?
  30.                 for(listelem<T>*e=h;e;e=e->n) if(e->o==o) return 1;
  31.                 return 0;
  32.         }
  33. };
  34.  
  35. //      DECLARATION TEMPLATE (SIMILAR TO LIST BUT MAY BE ENHANCED)
  36.  
  37. template <class T> struct declaration {
  38.         char *i;                                                // IDENTIFIER
  39.         T *p;                                                   // OBJECT
  40.         declaration<T> *n;                                      // NEXT
  41.         declaration(char* i, T* p) {this->i=i; this->p=p;}
  42.         ~declaration() {delete i; delete p;}
  43. };
  44.  
  45. template <class T> class declarations {
  46.         declaration<T> *h;                                      // HEAD
  47. public:
  48.         declarations() {h=(declaration<T>*)0;}
  49.         ~declarations() {
  50.                 for(declaration<T>* a; h; h=a) {a=h->n; delete h;}
  51.         }
  52.         void operator+=(declaration<T>* d) {d->n=h; h=d;}       // INSERT
  53.         T* operator[](char* i) {                                // GET
  54.                 for(declaration<T>* d=h; d; d=d->n)
  55.                         if(strcmp(d->i,i)==0)
  56.                                 return d->p;
  57.                 cout<<"identifier "<<i<<" not found\n";
  58.                 exit(1);
  59.                 return (T*)0;
  60.         }
  61. };
  62.  
  63. //      VECTORS AND MATRICES
  64.  
  65. class xform;
  66.  
  67. class vector {
  68.         friend ostream& operator<<(ostream& o, vector& v);
  69.         friend vector operator-(vector& v);
  70.         friend class xform;
  71.         double x, y, z;
  72. public:
  73.         vector() {x=0.; y=0.; z=0.;}
  74.         vector(double x, double y, double z) {
  75.                 this->x=x; this->y=y; this->z=z;
  76.         }
  77.         vector operator+(vector& v) {return vector(x+v.x,y+v.y,z+v.z);}
  78.         vector operator-(vector& v) {return vector(x-v.x,y-v.y,z-v.z);}
  79.         vector operator*(vector& v) {return vector(x*v.x,y*v.y,z*v.z);}
  80.         vector operator/(vector& v) {return vector(x/v.x,y/v.y,z/v.z);}
  81.         vector operator+(double d) {return vector(x+d,y+d,z+d);}
  82.         vector operator-(double d) {return vector(x-d,y-d,z-d);}
  83.         vector operator*(double d) {return vector(x*d,y*d,z*d);}
  84.         vector operator/(double d) {return vector(x/d,y/d,z/d);}
  85.         double operator%(vector& v) {return x*v.x+y*v.y+z*v.z;}
  86.         operator double() {return y;}
  87.         double operator[](int i) {return i==0?this->x:i==1?this->y:this->z;}
  88.         double get_x() { return this->x;}
  89.         double get_y() { return this->y;}
  90.         double get_z() { return this->z;}
  91. };
  92.  
  93. extern vector norm(vector& v);
  94.  
  95. struct matrix {
  96.         double m11, m12, m13;                                   // 1ST ROW
  97.         double m21, m22, m23;                                   // 2ND ROW
  98.         double m31, m32, m33;                                   // 3RD ROW
  99.         matrix(double m11=1., double m12=0., double m13=0.,
  100.                double m21=0., double m22=1., double m23=0.,
  101.                double m31=0., double m32=0., double m33=1.) {
  102.                 this->m11=m11; this->m12=m12; this->m13=m13;
  103.                 this->m21=m21; this->m22=m22; this->m23=m23;
  104.                 this->m31=m31; this->m32=m32; this->m33=m33;
  105.         }
  106.         matrix operator*(matrix& m) {
  107.                 return matrix(
  108.                         m11*m.m11+m12*m.m21+m13*m.m31,
  109.                         m11*m.m12+m12*m.m22+m13*m.m32,
  110.                         m11*m.m13+m12*m.m23+m13*m.m33,
  111.  
  112.                         m21*m.m11+m22*m.m21+m23*m.m31,
  113.                         m21*m.m12+m22*m.m22+m23*m.m32,
  114.                         m21*m.m13+m22*m.m23+m23*m.m33,
  115.  
  116.                         m31*m.m11+m32*m.m21+m33*m.m31,
  117.                         m31*m.m12+m32*m.m22+m33*m.m32,
  118.                         m31*m.m13+m32*m.m23+m33*m.m33
  119.                 );
  120.         }
  121.         vector operator*(vector& v) {
  122.                 return vector(
  123.                         vector(m11,m12,m13)%v,
  124.                         vector(m21,m22,m23)%v,
  125.                         vector(m31,m32,m33)%v
  126.                 );
  127.         }
  128.         vector operator/(vector& v) {                     // INVERSE
  129.                 return vector(
  130.                         v%vector(m11,m21,m31),
  131.                         v%vector(m12,m22,m32),
  132.                         v%vector(m13,m23,m33)
  133.                 );
  134.         }
  135. };
  136.  
  137. //      RAYS AND INTERSECTIONS
  138.  
  139. struct ray {
  140.         vector o;                                               // ORIGIN
  141.         vector d;                                               // DIRECTION
  142.         int l;                                                  // LEVEL
  143.         int c;                                                  // CODE
  144.         ray(vector& o, vector& d, int l, int c)
  145.                 {this->o=o; this->d=d; this->l=l; this->c=c;}
  146. };
  147.  
  148. class object;
  149.  
  150. struct intersect {
  151.         double t;                                       // RAY PARAMETER
  152.         vector p;                                       // SURFACE POINT
  153.         vector n;                                       // SURFACE NORMAL
  154.         object *o;                                      // OBJECT SURFACE
  155.         intersect() {o=(object*)0;}
  156.         intersect(double t, vector& p, vector& n, object *o) {
  157.                 this->t=t; this->p=p; this->n=n; this->o=o;
  158.         }
  159. };
  160.  
  161. //      HALF-SPACES
  162.  
  163. struct halfspace {
  164.         vector n;                                       // NORMAL
  165.         double d;                                       // DISTANCE FROM ORIGIN
  166.         halfspace()                                     // DEFAULT CONSTRUCTOR
  167.                 {this->n=vector(0.,0.,1.); this->d=0.;}
  168.         halfspace(vector& n, double d)                  // USUAL DEFINITION
  169.                 {this->n=norm(n); this->d=d;}
  170.         halfspace(vector& u, vector& v)     // BISECTOR PLANE
  171.                 {n=norm(v-u); d=((u+v)/2.)%n;}
  172.         int operator&(vector& p) {return n%p<=d;} // IF CONTAINS POINT p
  173. };
  174.  
  175. //      GEOMETRIC TRANSFORMATIONS (RIGID MOTIONS)
  176.  
  177. class xform {
  178.         friend ostream& operator<<(ostream& o, xform& T);
  179.         matrix A;                               // ORTHONORMAL ORIENTATION
  180.         vector s;                               // DIAGONAL SCALE
  181.         vector t;                               // TRANSLATION VECTOR
  182. public:
  183.         xform() {s=vector(1.,1.,1.); t=vector(0.,0.,0.);}
  184.         void operator+=(vector& t) {this->t=this->t+t;}   // TRANSLATE
  185.         void operator*=(vector& s) {                      // SCALE
  186.                 this->s=this->s*s; this->t=s*this->t;
  187.         }
  188.         void operator<<=(vector& r) {                     // ROTATE
  189.                 double sa=sin(RAD(r.x)), ca=cos(RAD(r.x));
  190.                 double sb=sin(RAD(r.y)), cb=cos(RAD(r.y));
  191.                 double sc=sin(RAD(r.z)), cc=cos(RAD(r.z));
  192.                 matrix Ap=matrix(cc,-sc,0., sc,cc,0., 0.,0.,1.)*
  193.                          (matrix(cb,0.,sb, 0.,1.,0., -sb,0.,cb)*
  194.                           matrix(1.,0.,0., 0.,ca,-sa, 0.,sa,ca));
  195.                 matrix B(
  196.                         s.x*Ap.m11, s.y*Ap.m12, s.z*Ap.m13,
  197.                         s.x*Ap.m21, s.y*Ap.m22, s.z*Ap.m23,
  198.                         s.x*Ap.m31, s.y*Ap.m32, s.z*Ap.m33
  199.                 );
  200.                 s=vector(
  201.                         sqrt(B.m11*B.m11+B.m12*B.m12+B.m13*B.m13),
  202.                         sqrt(B.m21*B.m21+B.m22*B.m22+B.m23*B.m23),
  203.                         sqrt(B.m31*B.m31+B.m32*B.m32+B.m33*B.m33)
  204.                 );
  205.                 A=matrix(
  206.                         B.m11/s.x, B.m12/s.x, B.m13/s.x,
  207.                         B.m21/s.y, B.m22/s.y, B.m23/s.y,
  208.                         B.m31/s.z, B.m32/s.z, B.m33/s.z
  209.                 );
  210.                 t=Ap*t;
  211.         }
  212.         vector operator*(vector& v) {return s*(A*v)+t;}         // TRANSFORM
  213.         vector operator/(vector& v) {return (A/(v-t))/s;}       // INVERSE
  214.         vector operator<<(vector& v) {return s*(A*v);}          // ROTATE
  215.         vector operator>>(vector& v) {return (A/v)/s;}          // INVERSE
  216.         ray operator*(ray& r)
  217.                 {return ray((*this)*r.o,(*this)<<r.d,r.l,r.c);}
  218.         ray operator/(ray& r)
  219.                 {return ray((*this)/r.o,(*this)>>r.d,r.l,r.c);}
  220.         intersect operator*(intersect& i)
  221.                 {return intersect(i.t,(*this)*i.p,norm((*this)<<i.n),i.o);}
  222.         list<intersect*> *operator*(list<intersect*> *l) {
  223.                 for(intersect* i=l->first(); i; i=l->next())
  224.                         *i=(*this)*(*i);
  225.                 return l;
  226.         }
  227.         halfspace operator*(halfspace& h) {
  228.                 vector p=(*this)*(h.n*h.d); vector n=(*this)<<h.n;
  229.                 return halfspace(n,p%n);
  230.         }
  231.         halfspace operator/(halfspace& h) {
  232.                 vector p=(*this)/(h.n*h.d); vector n=(*this)>>h.n;
  233.                 return halfspace(n,p%n);
  234.         }
  235. };
  236.  
  237. //      CAMERA MODEL
  238.  
  239. class camera {
  240.         friend ostream& operator<<(ostream& o, camera& c);
  241.         vector l;                                       // LOCATION
  242.         vector s;                                       // SKY
  243.         vector d;                                       // DIRECTION
  244.         vector u;                                       // UP
  245.         vector r;                                       // RIGHT
  246.         vector a;                                       // LOOK_AT
  247.         xform T;                                        // TRANSFORMATION
  248. public:
  249.         camera() {
  250.                 l=vector(0.,0.,0.); s=vector(0.,1.,0.); d=vector(0.,0.,1.);
  251.                 u=vector(0.,1.,0.); r=vector(1.33,0.,0.); a=vector(0.,0.,1.);
  252.         }
  253.         void setl(vector& v) {l=v;}
  254.         void sets(vector& v) {s=v;}
  255.         void setd(vector& v) {d=v;}
  256.         void setu(vector& v) {u=v;}
  257.         void setr(vector& v) {r=v;}
  258.         void seta(vector& v) {a=v;}
  259.         void traT(vector& v) {T+=v;}
  260.         void rotT(vector& v) {T<<=v;}
  261.         void scaT(vector& v) {T*=v;}
  262.         ray getray(double x, double y) {
  263.                 return this->T*ray(l,norm((r*x)+(u*y)+d),0,0);
  264.         }
  265. };
  266.  
  267. //      TEXTURES - I. PIGMENT
  268.  
  269. class icolor {
  270.         unsigned char r, g, b;                          // RED, GREEN, BLUE
  271. public:
  272.         icolor(unsigned char r=0, unsigned char g=0, unsigned char b=0) {
  273.                 this->r=r; this->g=g; this->b=b;
  274.         }
  275. };
  276.  
  277. class color;
  278.  
  279. class intensity {
  280.         friend ostream& operator<<(ostream& o, intensity& i);
  281.         friend class color;
  282.         double r, g, b;                                 // RED, GREEN, BLUE
  283. public:
  284.         intensity(double r=0., double g=0., double b=0.) {
  285.                 this->r=r; this->g=g; this->b=b;
  286.         }
  287.         intensity operator*(double d) {return intensity(r*d,g*d,b*d);}
  288.         intensity operator+(intensity& i)
  289.                 {return intensity(r+i.r,g+i.g,b+i.b);}
  290.         void operator+=(intensity& i) {r+=i.r; g+=i.g; b+=i.b;}
  291.         operator icolor() {
  292.                 unsigned char ir=r<1.?(unsigned char)(r*255.):255;
  293.                 unsigned char ig=g<1.?(unsigned char)(g*255.):255;
  294.                 unsigned char ib=b<1.?(unsigned char)(b*255.):255;
  295.                 return icolor(ir, ig, ib);
  296.         }
  297. };
  298.  
  299. class color {
  300.         friend ostream& operator<<(ostream& o, color& c);
  301.         double r, g, b;                                 // RED, GREEN, BLUE
  302.         double f;                                       // FILTER
  303. public:
  304.         color(double r=0., double g=0., double b=0., double f=0.) {
  305.                 this->r=r; this->g=g; this->b=b; this->f=f;
  306.         }
  307.         void setr(double d) {r=d;}
  308.         void setg(double d) {g=d;}
  309.         void setb(double d) {b=d;}
  310.         void setf(double d) {f=d;}
  311.         double filter() {return f;}
  312.         color operator*(color& c){return color(r*c.r,g*c.g,b*c.b,f*c.f);}
  313.         operator intensity() {return intensity(r,g,b);}
  314.         intensity operator*(intensity& i)
  315.                 {return intensity(r*i.r,g*i.g,b*i.b);}
  316. };
  317.  
  318. class finish;
  319.  
  320. class fog {
  321. };
  322.  
  323. class pigment {
  324.         friend ostream& operator<<(ostream& o, pigment& p);
  325. protected:
  326.         color q;                                        // QUICK COLOR
  327.         vector t;                                       // TURBULENCE
  328.         int o;                                          // OCTAVES
  329.         double m;                                       // OMEGA
  330.         double l;                                       // LAMBDA
  331.         double f, p;                                    // FREQUENCY, PHASE
  332.         xform T;                                        // TRANSFORMATION
  333. public:
  334.         virtual void out(ostream& o) {}
  335.         pigment() {t=vector(0.,0.,0.); o=6; m=.5; l=2.; f=1.; p=0.;}
  336.         virtual ~pigment() {}
  337.         void operator|=(pigment& p) {
  338.                 t=p.t; o=p.o; m=p.m; l=p.l; f=p.f; this->p=p.p; T=p.T;
  339.         }
  340.         void setq(color& q) {this->q=q;}
  341.         void sett(vector& t) {this->t=t;}
  342.         void seto(int o) {this->o=o;}
  343.         void setm(double m) {this->m=m;}
  344.         void setl(double l) {this->l=l;}
  345.         void setf(double f) {this->f=f;}
  346.         void setp(double p) {this->p=p;}
  347.         void traT(vector& v) {T+=v;}
  348.         void rotT(vector& v) {T<<=v;}
  349.         void scaT(vector& v) {T*=v;}
  350.         virtual pigment* copy() {pigment *p=new pigment; *p=*this; return p;}
  351.         virtual color paint(vector& p) {return q;}
  352.         color surfcolor(vector& p) {return paint(T/p);}
  353. };
  354.  
  355. class solid : public pigment {
  356.         color c;
  357. public:
  358.         solid() {c=color(1.,1.,1.); setq(c);}
  359.         solid(color& c) {this->c=c; setq(c);}
  360.         void out(ostream& o) {o<<"color "<<c<<"\n";}
  361.         pigment* copy() {solid *p=new solid; *p=*this; return p;}
  362.         color paint(vector& p) {return c;}
  363. };
  364.  
  365. class checker : public pigment {
  366.         color c1, c2;
  367. public:
  368.         checker() {c1=color(0.,0.,1.,0.); c2=color(0.,1.,0.,0.);}
  369.         checker(color& c1) {this->c1=c1; c2=color(0.,1.,0.,0.);}
  370.         checker(color& c1, color& c2) {this->c1=c1; this->c2=c2;}
  371.         void out(ostream& o) {o<<"checker color "<<c1<<" color "<<c2<<"\n";}
  372.         pigment* copy() {checker *p=new checker; *p=*this; return p;}
  373.         color paint(vector& p)
  374.                 {return (((int)p[0]+(int)p[1]+(int)p[2])%2)?c2:c1;}
  375. };
  376.  
  377. class hexagon : public pigment {
  378.         color c1, c2, c3;
  379. public:
  380.         hexagon() {
  381.                 c1=color(0.,0.,1.,0.); c2=color(0.,1.,0.,0.);
  382.                 c3=color(1.,0.,0.,0.);
  383.         }
  384.         hexagon(color& c1)
  385.                 {this->c1=c1; c2=color(0.,1.,0.,0.); c3=color(1.,0.,0.,0.);}
  386.         hexagon(color& c1, color& c2)
  387.                 {this->c1=c1; this->c2=c2; c3=color(1.,0.,0.,0.);}
  388.         hexagon(color& c1, color& c2, color& c3)
  389.                 {this->c1=c1; this->c2=c2; this->c3=c3;}
  390.         pigment* copy() {hexagon *p=new hexagon; *p=*this; return p;}
  391.         color paint(vector& p) {return c1;}
  392. };
  393.  
  394. struct colormapitem {
  395.         double b, e;                                    // BEGIN, END VALUES
  396.         color cb, ce;                                   // BEGIN, END COLORS
  397.         colormapitem() {b=0.; e=1.; cb=color(0.,0.,0.); ce=color(1.,1.,1.);}
  398.         colormapitem(double b, double e, color& cb, color& ce)
  399.                 {this->b=b; this->e=e; this->cb=cb; this->ce=ce;}
  400. };
  401.  
  402. class colormap {
  403.         friend ostream& operator<<(ostream& o, colormap& m);
  404.         friend class colormapped;
  405.         colormapitem *I;
  406.         int nI;
  407. public:
  408.         colormap() {I=new colormapitem; nI=1;}
  409.         virtual ~colormap() {delete I;}
  410.         colormap& operator=(colormap& m) {
  411.                 delete I; I=new colormapitem[m.nI];
  412.                 for(register int i=0; i<m.nI; i++) I[i]=m.I[i]; nI=m.nI;
  413.                 return *this;
  414.         }
  415.         void operator+=(colormapitem& J) {
  416.                 colormapitem *K=new colormapitem[nI+1];
  417.                 for(register int i=0; i<nI; i++) K[i]=I[i];
  418.                 K[nI]=J; delete I; I=K; nI=nI+1; 
  419.         }
  420.         colormap* copy() {colormap*p=new colormap; *p=*this; return p;}
  421. };
  422.  
  423. class colormapped : public pigment {
  424.         friend ostream& operator<<(ostream& o, colormapped& m);
  425. public:
  426.         colormap cm;
  427.         colormapped() {}
  428.         virtual ~colormapped() {}
  429.         pigment* copy() {colormapped*p=new colormapped; *p=*this; return p;}
  430. };
  431.  
  432. class gradient : public colormapped {
  433. };
  434.  
  435. class marble : public colormapped {
  436. };
  437.  
  438. class wood : public colormapped {
  439. };
  440.  
  441. class onion : public colormapped {
  442. };
  443.  
  444. class leopard : public colormapped {
  445. };
  446.  
  447. class granite : public colormapped {
  448. };
  449.  
  450. class bozo : public colormapped {
  451. };
  452.  
  453. class spotted : public colormapped {
  454. };
  455.  
  456. class agate : public colormapped {
  457. };
  458.  
  459. class mandel : public colormapped {
  460. };
  461.  
  462. class radial : public colormapped {
  463. };
  464.  
  465. //      TEXTURES - II. NORMAL
  466.  
  467. class normal {
  468.         friend ostream& operator<<(ostream& o, normal& n);
  469.         vector t;                                       // TURBULENCE
  470.         double f, p;                                    // FREQUENCY, PHASE
  471.         xform T;                                        // TRANSFORMATION
  472. public:
  473.         virtual void out(ostream& o) {}
  474.         normal() {t=vector(0.,0.,0.); f=1.; p=0.;}
  475.         virtual ~normal() {}
  476.         void operator|=(normal& n) {
  477.                 t=n.t; f=n.f; p=n.p; T=n.T;
  478.         }
  479.         void sett(vector& t) {this->t=t;}
  480.         void setf(double f) {this->f=f;}
  481.         void setp(double p) {this->p=p;}
  482.         void traT(vector& v) {T+=v;}
  483.         void rotT(vector& v) {T<<=v;}
  484.         void scaT(vector& v) {T*=v;}
  485.         virtual normal* copy() {normal *n=new normal; *n=*this; return n;}
  486.         virtual vector perturbate(vector& n,vector& p) {return n;}
  487.         vector surfnormal(vector& n,vector& p) {
  488.                 return norm(T<<perturbate(norm(T>>n),T*p));
  489.         }
  490. };
  491.  
  492. class bumps : public normal {
  493.         double p;                                       // PERTURBATION
  494. public:
  495.         void out(ostream& o) {o<<"bumps "<<p<<"\n";}
  496.         bumps() {p=.4;}
  497.         bumps(double d) {p=d;}
  498.         normal* copy() {bumps *n=new bumps; *n=*this; return n;}
  499.         vector perturbate(vector& n,vector& p) {
  500.                 double theta,phi,nx,ny,nz;
  501.                 theta=acos(n.get_z())+RAD((double)rand()*this->p);
  502.                 phi=atan(n.get_y()/n.get_x())+RAD((double)rand()*this->p);
  503.                 /*double k=RAD(p%p);
  504.                 theta=acos(n.get_z())+RAD(sin(k)*this->p);
  505.                 phi=atan(n.get_y()/n.get_x())+RAD(cos(k)*this->p);*/
  506.                 nz=cos(theta);
  507.                 nx=sqrt((1-nz*nz)/(1+tan(phi)*tan(phi)));
  508.                 ny=nx*tan(phi);
  509.                 n=vector(nx,ny,nz);
  510.                 return n;
  511.                 }
  512. };
  513.  
  514. class dents : public normal {
  515.         double d;                                               // DENTING
  516. public:
  517.         void out(ostream& o) {o<<"dents "<<d<<"\n";}
  518.         dents() {d=.4;}
  519.         dents(double d) {this->d=d;}
  520.         normal* copy() {dents *n=new dents; *n=*this; return n;}
  521.         vector perturbate(vector& n,vector& p) {return n;}
  522. };
  523.  
  524. class ripples : public normal {
  525. };
  526.  
  527. class waves : public normal {
  528. };
  529.  
  530. class wrinkles : public normal {
  531. };
  532.  
  533. class bumpmap : public normal {
  534. };
  535.  
  536. //      TEXTURES - III. FINISH
  537.  
  538. class finish {
  539.         friend ostream& operator<<(ostream& o, finish& f);
  540.         double kd, kb, kc;                      // DIFFUSE, BRILLIANCE, CRAND
  541.         double ka;                              // AMBIENT
  542.         double kr;                              // REFLECTION
  543.         double ks, kp, kh, kg;                  // PHONG, SPECULAR HIGHLIGHTS
  544.         int km;                                 // METALLIC
  545.         double kt, ki;                          // REFRACTION, INDEX OF REFR.
  546. public:
  547.         finish() {
  548.                 kd=.6; kb=0.; kc=0.; ka=.1; kr=0.; ks=0.; kp=40.; 
  549.                 kh=0.; kg=.05; km=0; kt=0.; ki=1.;
  550.         }
  551.         void setkd(double d) {kd=d;}
  552.         void setkb(double d) {kb=d;}
  553.         void setkc(double d) {kc=d;}
  554.         void setka(double d) {ka=d;}
  555.         void setkr(double d) {kr=d;}
  556.         void setks(double d) {ks=d;}
  557.         void setkp(double d) {kp=d;}
  558.         void setkh(double d) {kh=d;}
  559.         void setkg(double d) {kg=d;}
  560.         void setkm(int i) {km=i;}
  561.         void setkt(double d) {kt=d;}
  562.         void setki(double d) {ki=d;}
  563.         finish* copy() {finish *f=new finish; *f=*this; return f;}
  564.         intensity surfoptics(color& c, vector& n, ray& r, intersect& i);
  565. };
  566.  
  567. //      TEXTURES - IV. TOP LEVEL
  568.  
  569. class texture {
  570.         friend ostream& operator<<(ostream& o, texture& t);
  571.         pigment *p;
  572.         normal *n;
  573.         finish *f;
  574. protected:
  575.         list<texture*> *l;
  576.         xform T;
  577. public:
  578.         texture() {p=new solid;n=new normal;f=new finish;l=new list<texture*>;}
  579.         virtual ~texture() {
  580.                 delete p; delete n; delete f;
  581.                 for(texture* t=l->first(); t; t=l->next()) delete t;
  582.                 delete l;
  583.         }
  584.         texture& operator=(texture& t) {
  585.                 delete p; p=t.p->copy();
  586.                 delete n; n=t.n->copy();
  587.                 delete f; f=t.f->copy();
  588.                 for(texture* x=l->first(); x; x=l->next()) delete x;
  589.                 delete l; l=new list<texture*>;
  590.                 for(texture* p=t.l->first(); p; p=t.l->next()) *l+=p->copy();
  591.                 return *this;
  592.         }
  593.         void operator+=(texture* t) {*l+=t;}
  594.         virtual void out(ostream& o) {
  595.                 o<<"texture {\n";
  596.                 o<<*p; o<<*n; o<<*f;
  597.                 o<<T<<"}\n";
  598.                 for(texture* x=l->first(); x; x=l->next()) o<<*x;
  599.         }
  600.         void setp(pigment& p) {delete this->p; this->p=p.copy();}
  601.         void setn(normal& n) {delete this->n; this->n=n.copy();}
  602.         void setf(finish& f) {delete this->f; this->f=f.copy();}
  603.         void traT(vector& v) {T+=v;}
  604.         void rotT(vector& v) {T<<=v;}
  605.         void scaT(vector& v) {T*=v;}
  606.         pigment* copyp() {return p->copy();}
  607.         normal* copyn() {return n->copy();}
  608.         finish* copyf() {return f->copy();}
  609.         virtual texture* copy() {texture* t=new texture; *t=*this; return t;}
  610.         virtual intensity shade(ray& r, intersect& i) {
  611.                 i.p=T/i.p;
  612.                 color c=p->surfcolor(i.p);
  613.                 vector v=n->surfnormal(i.n, i.p);
  614.                 return f->surfoptics(c, v, r, i);
  615.         }
  616. };
  617.  
  618. class tiles : public texture {
  619. public:
  620.         void out(ostream& o) {
  621.                 o<<"texture {\n";
  622.                 o<<"tiles\n"<<*(texture*)this<<"tile2\n"<<*(l->first());
  623.                 o<<T<<"}\n";
  624.         }
  625.         texture* copy() {tiles* t=new tiles; *t=*this; return t;}
  626.         intensity shade(ray& r, intersect& i)
  627.                 {return texture::shade(r,i);}
  628. };
  629.  
  630. class materialmap : public texture {
  631. };
  632.  
  633. //      OBJECTS IN GENERAL
  634.  
  635. class object {
  636. protected:
  637.         friend ostream& operator<<(ostream& o, object& p);
  638.         texture t;                                      // TEXTURE
  639.         xform T;                                        // TRANSFORMATION
  640.         virtual list<intersect*> *shape(ray& r)   // RAY INTERSECTION
  641.                 {return new list<intersect*>;}
  642. public:
  643.         void outopt(ostream& o) {o<<t<<T;}
  644.         virtual void out(ostream& o) {o<<"undefined {\n";outopt(o);o<<"}\n";}
  645.         virtual ~object() {}
  646.         void sett(texture& t) {this->t=t;}
  647.         void setp(pigment& p) {t.setp(p);}
  648.         void setn(normal& n) {t.setn(n);}
  649.         void setf(finish& f) {t.setf(f);}
  650.         void traT(vector& v) {T+=v;}
  651.         void rotT(vector& v) {T<<=v;}
  652.         void scaT(vector& v) {T*=v;}
  653.         virtual object* copy() {object* o=new object; *o=*this; return o;}
  654.         list<intersect*> *test(ray& r) {return T*shape(T/r);}
  655.         intensity shade(ray& r, intersect& i) {return t.shade(r,i);}
  656.         virtual list<vector*> *particles() {
  657.                 vector *v=new vector; *v=(this->T)*vector(0.,0.,0.);
  658.                 list<vector*> *l=new list<vector*>; *l+=v;
  659.                 return l;
  660.         }
  661.         virtual int operator&(halfspace& h) {return 1;}   // INTERSECTS h
  662. };
  663.  
  664. //      INTERSECTION ACCELERATION TECHNIQUES
  665.  
  666. class method {
  667.         list<object*> *lo;                              // SCENE OBJECTS
  668.         virtual list<object*> *firstlist(ray& r)
  669.                 {return lo;}                            // BRUTE-FORCE METHOD
  670.         virtual list<object*> *nextlist()
  671.                 {return (list<object*>*)0;}             // BRUTE-FORCE METHOD
  672. public:
  673.         method() {lo=new list<object*>;}
  674.         virtual void preprocess(list<object*> *l)
  675.                 {delete lo; lo=l;}                      // NO PREPROCESSING
  676.         intersect operator()(ray& r) {                  // GENERAL SCHEME
  677.                 intersect imin, *i;
  678.                 for(list<object*>*lo=firstlist(r); lo; lo=nextlist()) {
  679.                         for(object *o=lo->first(); o; o=lo->next()) {
  680.                                 list<intersect*> *li=o->test(r);
  681.                                 if(i=li->first()) {
  682.                                         if(!imin.o || i->t<imin.t )
  683.                                                 imin=*i;
  684.                                 }
  685.                                 for(i=li->first(); i; i=li->next())
  686.                                         delete i;
  687.                                 delete li;
  688.                         }
  689.                 }
  690.                 return imin;
  691.         }
  692. };
  693.  
  694. extern method* query;                                   // IN FILE main
  695.  
  696. //      OBJECTS SPECIFIED -  I. SOLID FINITE PRIMITIVES
  697.  
  698. class sphere : public object {
  699.         vector c;                                       // CENTER
  700.         double r;                                       // RADIUS
  701.         list<intersect*> *shape(ray& r);
  702. public:
  703.         void out(ostream& o) {
  704.                 o<<"sphere {\n"<<c<<"\n"<<r<<"\n"; outopt(o); o<<"}\n";
  705.         }
  706.         friend ostream& operator<<(ostream& o, sphere& s);
  707.         sphere() {c=vector(0.,0.,0.); r=1.;}
  708.         sphere(vector& c, double r) {this->c=c;this->r=r;}
  709.         object* copy() {sphere* o=new sphere; *o=*this; return o;}
  710.         list<vector*> *particles() {
  711.                 vector *v=new vector; *v=T*c;
  712.                 list<vector*> *l=new list<vector*>; *l+=v;
  713.                 return l;
  714.         }
  715.         int operator&(halfspace& h)
  716.                 {halfspace H=T/h; return (c-H.n*(r+H.d))*H.n<=EPS;}
  717. };
  718.  
  719. class box : public object {
  720. };
  721.  
  722. class cone : public object {
  723. };
  724.  
  725. class cylinder : public object {
  726. };
  727.  
  728. class torus : public object {
  729. };
  730.  
  731. class blob : public object {
  732. };
  733.  
  734. //      OBJECTS SPECIFIED -  II. FINITE PATCH PRIMITIVES
  735.  
  736.  
  737. //      OBJECTS SPECIFIED -  III. INFINITE SOLID PRIMITIVES
  738.  
  739. class plane : public object, public halfspace {
  740. };
  741.  
  742. class quadric : public object {
  743. };
  744.  
  745.  
  746. //      OBJECTS SPECIFIED -  IV. CONSTRUCTIVE SOLID GEOMETRY (CSG)
  747.  
  748. class csg : public object {
  749.         friend ostream& operator<<(ostream& o, csg& c);
  750. protected:
  751.         list<object*> *l;
  752. public:
  753.         csg(list<object*>*ol=(list<object*>*)0) {l=ol?ol:new list<object*>;}
  754.         ~csg() {for(object* o=l->first();o;o=l->next()) delete o; delete l;}
  755.         void outobj(ostream& o) {
  756.                 for(object *p=l->first();p;p=l->next()) o<<*p;
  757.         }
  758.         csg& operator=(csg& c) {
  759.                 object* o;
  760.                 for(o=l->first(); o; o=l->next()) delete o;
  761.                 delete l; l=new list<object*>;
  762.                 for(o=c.l->first(); o; o=c.l->next()) *l+=o->copy();
  763.                 return *this;
  764.         }
  765.         virtual object* copy() {csg* o=new csg; *o=*this; return o;}
  766.         list<vector*> *particles() {
  767.                 list<vector*> *L=new list<vector*>;
  768.                 for(object*o=l->first();o;o=l->next()) {
  769.                         list<vector*> *M=o->particles();
  770.                         for(vector*v=M->first();v;v=M->next())
  771.                                 {*v=T*(*v); *L+=v;}
  772.                         delete M;
  773.                 }
  774.                 return L;
  775.         }
  776.         int operator&(halfspace& h) {
  777.                 halfspace H=T/h;
  778.                 for(object*o=l->first();o;o=l->next()) if(*o&H) return 1;
  779.                 return 0;
  780.         }
  781. };
  782.  
  783. class csguni : public csg {
  784.         friend ostream& operator<<(ostream& o, csguni& c);
  785. public:
  786.         csguni(list<object*>*ol=(list<object*>*)0) : csg(ol) {}
  787.         ~csguni() {}
  788.         void out(ostream& o) {
  789.                 o<<"union {\n"; outobj(o); outopt(o); o<<"}\n";
  790.         }
  791.         object* copy() {csguni* o=new csguni; *o=*this; return o;}
  792. };
  793.  
  794. class csgmer : public csg {
  795.         friend ostream& operator<<(ostream& o, csgmer& c);
  796. public:
  797.         csgmer(list<object*>*ol=(list<object*>*)0) : csg(ol) {}
  798.         ~csgmer() {}
  799.         void out(ostream& o) {
  800.                 o<<"merge {\n"; outobj(o); outopt(o); o<<"}\n";
  801.         }
  802.         object* copy() {csgmer* o=new csgmer; *o=*this; return o;}
  803. };
  804.  
  805. class csgint : public csg {
  806.         friend ostream& operator<<(ostream& o, csgint& c);
  807. public:
  808.         csgint(list<object*>*ol=(list<object*>*)0) : csg(ol) {}
  809.         ~csgint() {}
  810.         void out(ostream& o) {
  811.                 o<<"intersection {\n";outobj(o);outopt(o);o<<"}\n";
  812.         }
  813.         object* copy() {csgint* o=new csgint; *o=*this; return o;}
  814. };
  815.  
  816. class csgdif : public csg {
  817.         friend ostream& operator<<(ostream& o, csgdif& c);
  818. public:
  819.         csgdif(list<object*>*ol=(list<object*>*)0) : csg(ol) {}
  820.         ~csgdif() {}
  821.         void out(ostream& o) {
  822.                 o<<"difference {\n";outobj(o);outopt(o);o<<"}\n";
  823.         }
  824.         object* copy() {csgdif* o=new csgdif; *o=*this; return o;}
  825. };
  826.  
  827.  
  828. //      OBJECTS SPECIFIED -  V. LIGHT SOURCES
  829.  
  830. struct light {
  831.         intensity i;
  832.         vector v;
  833.         light(intensity& i, vector& v) {this->i=i; this->v=v;}
  834. };
  835.  
  836. class lightsource : public object {
  837.         friend ostream& operator<<(ostream& o, lightsource& l);
  838. protected:
  839.         vector p;                                       // POSITION
  840.         color c;                                        // COLOR
  841. public:
  842.         virtual void out(ostream& o) {
  843.                 o<<"light_source {\n"<<p<<"\n"<<c<<"\n"; o<<T; o<<"}\n";
  844.         }
  845.         lightsource() {p=vector(0.,0.,0.); c=color(1.,1.,1.);}
  846.         void setp(vector& p) {this->p=p;}
  847.         void setc(color& c)  {this->c=c;}
  848.         object* copy() {lightsource* o=new lightsource; *o=*this; return o;}
  849.         list<intersect*> *shape(ray& r) {return new list<intersect*>;}
  850.         virtual list<light*>* illum(intersect& i) {
  851.                 list<light*> *L=new list<light*>;
  852.                 if((*query)(ray(this->p,norm(i.p-this->p),0,-1)).o!=i.o)
  853.                         return L;
  854.                 light *l=new light((intensity)c,norm(this->p-i.p));
  855.                 *L+=l;
  856.                 return L;
  857.         }
  858.         list<vector*> *particles() {
  859.                 vector *v=new vector; *v=T*p;
  860.                 list<vector*> *l=new list<vector*>; *l+=v;
  861.                 return l;
  862.         }
  863. };
  864.  
  865. class spotlight : public lightsource {
  866.         friend ostream& operator<<(ostream& o, spotlight& l);
  867.         vector a;                                               // POINT AT
  868.         double r;                                               // RADIUS
  869.         double f;                                               // FALLOFF
  870.         double t;                                               // TIGHTNESS
  871. public:
  872.         virtual void out(ostream& o) {
  873.                 o<<"light_source {\n"<<p<<"\n"<<c<<"\n";
  874.                 o<<"spotlight\npoint_at "<<a<<"\nradius "<<r<<"\n";
  875.                 o<<"falloff "<<f<<"\ntightness "<<t<<"\n";
  876.                 o<<T;
  877.                 o<<"}\n";
  878.         }
  879.         spotlight() {a=vector(0.,0.,0.); r=0.; f=0., t=10;}
  880.         spotlight(vector a, double r, double f, double t)
  881.                 {this->a=a; this->r=r; this->f=f; this->t=t;}
  882.         void seta(vector& a) {this->a=a;}
  883.         void setr(double r) {this->r=r;}
  884.         void setf(double f) {this->f=f;}
  885.         void sett(double t) {this->t=t;}
  886.         object* copy() {spotlight* o=new spotlight; *o=*this; return o;}
  887. };
  888.  
  889. //      ACCELERATION TECHNIQUES - I. VIA VORONOI-DIAGRAM
  890.  
  891. struct cell;                                    // DECLARED IN voronoi.cxx
  892.  
  893. class voronoi : public method {
  894.         cell *C;                                // CELL CLOSEST TO CENTROID
  895.         cell **s;                               // ARRAY OF STARTING CELLS
  896.         long traverse;                          // TRAVERSE CODE (disperse)
  897.         void disperse(object *o, cell*C);
  898.         cell* a; ray* r; double t;              // USED BY step()
  899.         void step();                            // USED BY first-,nextlist()
  900.         list<object*> *firstlist(ray& r);
  901.         list<object*> *nextlist();
  902. public:
  903.         void preprocess(list<object*> *lo);
  904. };
  905.  
  906. //      GLOBAL OBJECTS
  907.  
  908. extern int lmax;                                // MAXIMAL LEVEL OF RECURSION
  909. extern int verbose;                             // PRINTOUTS
  910. extern list<object*> objects;                   // SCENE OBJECTS
  911. extern list<lightsource*> lightsources;         // LIGHTSOURCES
  912. extern camera actcamera;                        // CAMERA
  913. extern intensity trace(ray& r);                 // RECURSIVE RAY TRACING
  914. extern fog actfog;                              // FOG
  915.