/* taken from Listing 2.8 : A complex rib generating file  */
#include <ri.h>
#include <math.h>

#define ROOTFILENAME "hard"
#define RECURSION    1          /* Recursion level for fractal       */
#define NFRAMES      3          /* Number of frames in the animation */
#define WINDOWX      100       /* Width of the window               */
#define WINDOWY      100        /* Height of the window              */

#define PI         3.14159256 /* PI */

main()
{
  RtInt frame;
  RtPoint from, to;
  RtFloat intensity, fov, fraction, yAngle, xAngle;
  char filename[20];
  
  RiBegin(RI_NULL);    /* Start the renderer */
  
  for (frame = 0; frame < NFRAMES; frame++) {
    fraction = (float) frame / (float) NFRAMES;

    sprintf(filename, "%s%d.tif", ROOTFILENAME, frame );
    RiFrameBegin(frame);

    from[0] =  1.0; to[0] = 0.0;
    from[1] =  1.0; to[1] = 0.0;
    from[2] = -2.0; to[2] = 0.0;

    intensity = 1.5;

    RiLightSource("distantlight", "intensity", &intensity, "from", from, "to", to,RI_NULL);  
    
    /*** Viewing transformation ***/
    fov = 50; /* measured in degrees of the field of view */
    RiProjection("perspective", RI_FOV, (RtPointer) &fov, RI_NULL);
    RiTranslate(0.0, 0.0, 2.0);
    
    /*** Display information ***/
    RiDisplay(filename, RI_FILE, RI_RGB, RI_NULL);
    RiFormat((RtInt) WINDOWX, (RtInt) WINDOWY, -1.0); 
    RiShadingRate(1.0);

    /*** Geometry Begin ***/
    RiWorldBegin();
    
    RiSides((RtInt) 1);  /* Tells whether to render back-face polys */
    
    xAngle = 30.0;
    yAngle = 30.0 * (1.0 - fraction) + fraction * 60.0;
    RiRotate(yAngle, 0.0, 1.0, 0.0); 
    RiRotate(-xAngle, cos(yAngle * PI/180.0), 0.0, sin(yAngle * PI/180.0));

    /*** Surface information ***/
    PlainMaple(fraction);   

    /*** Geometry information ***/
    SC(RECURSION);

    RiWorldEnd();
    RiFrameEnd();
  }
  
  RiEnd();

  return 0;
}


SC(n)
  int n;
{
  if (n == 0) {
    UnitCube();
  } else {
    RiTransformBegin();
       RiScale(1.0/3.0, 1.0/3.0, 1.0/3.0);
       SC_Square(n);
       RiTranslate(0.0,0.0,-1.0);
       SC_Square(n);
       RiTranslate(0.0,0.0,2.0);
       SC_Square(n);
       RiTranslate(0.0,0.0,-1.0);
       RiRotate(-90.0,0.0,1.0,0.0);
       SC_Square(n);
       RiRotate(90.0,1.0,0.0,0.0);
       SC_Square(n);
    RiTransformEnd();
  }
}

SC_Square(n)
int n;
{
  RiTransformBegin();
    RiTranslate(1.0,1.0,0.0);
    SC(n-1);
    RiTranslate(-2.0,0.0,0.0);
    SC(n-1);
    RiTranslate(0.0,-2.0,0.0);
    SC(n-1);
    RiTranslate(2.0,0.0,0.0);
    SC(n-1);
  RiTransformEnd();
}


PlainMaple(fraction) 
RtFloat fraction;
{
  RtColor stain, dark, light;
  RtFloat lookScale;
  
  RiDeclare("darkcolor", "color");
  RiDeclare("lightcolor", "color");
  RiDeclare("StainColor", "color");
  
  RiTransformBegin(); 
  
  lookScale = 3.0;
  RiScale(lookScale,lookScale,lookScale); 
  
  stain[0] = stain[1] = stain[2] = 1;
  dark[0] = 0.657883 * (1.0 - fraction) + fraction * 0.0;
  dark[1] = 0.27327 * (1.0 - fraction) + fraction * 0.0;
  dark[2] = 1.52588e-05 * (1.0 - fraction) + fraction * 1.0;
  light[0] = 0.999969;
  light[1] = 0.944061;
  light[2] = 0.69519;
  
  RiSurface("_VFX_MStarter|Wood|Maple|pxs00012",
	    "darkcolor", dark,
	    "lightcolor", light,
	    "StainColor", stain,
	    RI_NULL); 
  
  RiTransformEnd(); 
}