!====================================================================
!!
!! Room with a table and other stuff...
!!
!! 1.0 = 1"
!!
!====================================================================


? "\n\n*** Table top with stuff on it **\n",
  "\n";

integer FULLMODEL = 1;  ! Set to zero for "quickie" rendering...
integer GLAZING   = 1;  ! Set to one for glass in windows...
integer NORMALVIEW = 1;  ! 0 = east (into room), 1 = west, (out window)
integer TEXTURED_FLOOR = 1; ! Individual boards or "painted" floor...
integer HILL_LEVEL = 6;  ! 0 = no hills, 6 = 4096 poly`s, 7 = 16k poly's

!====================================================================
!!
!! Camera setup...
!!
!====================================================================
if (NORMALVIEW) {
  CAMERA'POS     = [179, -40, 60];
  CAMERA'TARGET  = [30,  10, 50];
}
else {
  CAMERA'POS     = [-120, -48, 60];
  CAMERA'TARGET  = [180,  60, 50];
}

!====================================================================
!!
!! Surface colors...
!!
!====================================================================
WHITE   : COLOR( RGB, [1.0, 1.0, 1.0] );
PALEGRN : COLOR( RGB, [0.8, 0.9, 0.8] );
GRAY    : COLOR( RGB, [0.5, 0.5, 0.5] );
BLACK   : COLOR( RGB, [0.0, 0.0, 0.0] );
RED     : COLOR( RGB, [0.9, 0.0, 0.0] );
BLUE    : COLOR( RGB, [0.0, 0.0, 0.8] );

DKGREEN      : COLOR( RGB, [0.10, 0.40, 0.10] );
CANDLECOLOR  : COLOR( RGB, [1.00, 0.90, 0.90] );
PEWTERCOLOR  : COLOR( RGB, [0.70, 0.70, 0.80] );
BRASSCOLOR   : COLOR( RGB, [1.00, 0.70, 0.10] );
BRONZECOLOR  : COLOR( RGB, [0.80, 0.30, 0.10] );
FLAMECOLOR   : COLOR( RGB, [1.00, 0.80, 0.20]*10 );
WICKCOLOR    : COLOR( RGB, [0.10, 0.10, 0.10] );
TABLECOLOR   : COLOR( RGB, [0.60, 0.30, 0.20] );
BUREAUCOLOR  : COLOR( RGB, [0.60, 0.30, 0.20] );
LSHADECOLOR  : COLOR( RGB, [0.80, 0.60, 0.40] );
HILLCOLOR    : COLOR( RGB, [0.20, 0.35, 0.05] );
CORKCOLOR    : COLOR( RGB, [0.70, 0.70, 0.20] );
FLOORCOLOR   : COLOR( RGB, [0.40, 0.20, 0.10] );
PLATECOLOR   : COLOR( RGB, [0.90, 1.00, 0.90] );
WALLCOLOR    : COLOR( RGB, [1.00, 0.80, 0.80] );
RWOODCOLOR   : COLOR( RGB, [0.60, 0.40, 0.20] );
CURTAINCOLOR : COLOR( RGB, [0.20, 0.70, 0.90] );
RODCOLOR     : COLOR( RGB, [0.90, 0.90, 0.90] );
CHROMECOLOR  : COLOR( RGB, [0.90, 0.90, 1.00] );
BBCOLOR      : COLOR( RGB, [0.60, 0.30, 0.20] );
TRIMCOLOR    : COLOR( RGB, [1.00, 1.00, 1.00] );

FLOOR_TEXTURE : texturemap( "floorboards.ilbm" );
HILLS         : texturemap( "hills.ilbm" );  ! Painting on wall
OXPISS        : texturemap( "oxpiss.ilbm" );
MARBLE1       : texturemap( "marble3.ilbm" );


!====================================================================
!!
!! Surface coefficients...
!!                           ka   kd   ks    n    km   kr   ri   kb
!====================================================================
GLASS       : SURFACE( PHONG, 0.00,0.0, 0.0,  0.0, 0.2, 0.75,0.99,0.0, TRANSPARENT );
DULL        : SURFACE( PHONG, 1.0, 1.0, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, 0 );

CANDLESURF  : SURFACE( PHONG, 0.8, 1.0, 0.4,  9.0, 0.0, 0.0, 0.0, 0.0, 0 );
PEWTERSURF  : SURFACE( PHONG, 0.7, 0.7, 0.6, 20.0, 0.4, 0.0, 0.0, 0.001, 0 );
BRASSSURF   : SURFACE( PHONG, 0.7, 0.8, 0.8, 32.0, 0.4, 0.0, 0.0, 0.0, 0 );
BRONZESURF  : SURFACE( PHONG, 0.7, 0.8, 0.8,  8.0, 0.0, 0.0, 0.0, 0.0, 0 );
FLAMESURF   : SURFACE( PHONG, 1.0, 1.0, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, TRANSLUCENT );
WICKSURF    : SURFACE( PHONG, 1.0, 1.0, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, 0 );
TABLESURF   : SURFACE( PHONG, 0.7, 0.8, 0.1,  8.0, 0.0, 0.0, 0.0, 0.0, 0 );
BUREAUSURF  : SURFACE( PHONG, 0.7, 0.8, 0.1,  8.0, 0.0, 0.0, 0.0, 0.0, 0 );
LSHADESURF  : SURFACE( PHONG, 0.0, 1.0, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, TRANSLUCENT );
FLOORSURF   : SURFACE( PHONG, 1.0, 0.8, 0.0,  0.0, 0.3, 0.0, 0.0, 0.05, SILVER );
PLATESURF   : SURFACE( PHONG, 0.7, 0.8, 0.3, 32.0, 0.3, 0.0, 0.0, 0.0, 0 );
WALLSURF    : SURFACE( PHONG, 1.0, 1.0, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, 0 );
BOTTLESURF  : SURFACE( PHONG, 0.1, 0.5, 0.5, 32.0, 0.5, 0.0, 0.9, 0.0, 0 );
HILLSURF    : SURFACE( PHONG, 0.4, 0.8, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, 0 );
RWOODSURF   : SURFACE( PHONG, 1.0, 0.9, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, 0 );
CURTAINSURF : SURFACE( PHONG, 1.0, 1.0, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, TRANSLUCENT );
RODSURF     : SURFACE( PHONG, 0.7, 0.8, 0.4, 16.0, 0.3, 0.0, 0.0, 0.0, 0 );
CHROMESURF  : SURFACE( PHONG, 0.4, 0.8, 0.8, 32.0, 0.4, 0.0, 0.0, 0.001, 0 );
PICTURESURF : SURFACE( PHONG, 1.0, 1.0, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, 0 );
BBSURF      : SURFACE( PHONG, 0.8, 0.9, 0.0,  0.0, 0.0, 0.0, 0.0, 0.0, 0 );
TRIMSURF    : SURFACE( PHONG, 0.8, 1.0, 0.7, 16.0, 0.1, 0.0, 0.0, 0.01, 0 );
VASESURF    : SURFACE( PHONG, 1.0, 1.0, 0.9,  8.0, 0.0, 0.0, 0.0, 0.0, 0 );
CHEESESURF  : SURFACE( PHONG, 0.6, 1.0, 0.5, 10.0, 0.0, 0.0, 0.0, 0.0, 0 );

!====================================================================
!!
!! General variables...
!!
!!===================================================================

real  LIGHTNESS = 1.0;

vector CANDLEFLAME = [ 2, 1.5, 0.5 ] * 30 * LIGHTNESS,
       WATT        = [ 3, 2.7, 2.7 ] * LIGHTNESS,
       BULB100     = WATT * 100,
       SKYZEN      = [0.05, 0.05, 0.30] * LIGHTNESS,
       SKYHOR      = [0.40, 0.55, 0.80] * LIGHTNESS,

! Window corners...
       W1a = [-120,110,12],
       W1b = [-120,14,12],
       W1c = [-120,14,80],
       W1d = [-120,110,80],

! Door corners...
       D1a = [-120,-20,0],
       D1b = [-120,-56,0],
       D1c = [-120,-56,80],
       D1d = [-120,-20,80];



!====================================================================
!!
!! Our scene's backdrop is a landscape panel of rolling hills...
!! LANDSCAPE( <seed>, <level>, <factor>, <pos0>, <pos1>, <pos2>,
!!            <color>, <surface>, <flags> );
!!
!====================================================================
proc SCENERY()

   if (FULLMODEL && HILL_LEVEL > 0) {
     LS : LANDSCAPE( 13, HILL_LEVEL, 0.07,
       [200,-120,-50], [-100000,-30000,-50], [0,50000,-50],
       HILLCOLOR, HILLSURF, PHONG );   }
endproc


!====================================================================
!!
!! A drinking goblet...
!!
!====================================================================
proc GOBLET( vector POS, real SCALE )
  SCALE = SCALE * 0.02;
  boundary

    lathe( ([0,0,0], [0,0,80], [5,0,85], [10,0,80],[20,0,40],[40,0,10],
          [100,0,10], [120,0,40], [140,0,80],[160,0,100],[200,0,100],
          [200,0,95], [160,0,95], [ 140,0,60], [120,0,20], [115,0,0]),
      20, 360, 0, [SCALE,SCALE,SCALE], POS, [0,-90,0], WHITE, GLASS, PHONG );

  endboundary
endproc


!====================================================================
!!
!! A plate...
!!
!====================================================================
proc CHEESE( vector POS, vector SCALE )

  boundary

! The cheese
    lathe( ([0,0,0], [0,0,1], [0.1,0,1.6], [0.4,0,1.9],
            [0.8,0,2], [1.2,0,1.9], [1.3,0,1.6], [1.4,0,1], [1.4,0,0] ),
      16, 360, 0, SCALE, POS, [0,-90,0], RED, CHEESESURF, PHONG );

  endboundary
endproc


!====================================================================
!!
!! A plate...
!!
!====================================================================
proc PLATE( vector POS, vector SCALE, integer SEGMENTS )

  boundary

! The plate
    lathe( ([0,0,0], [0,0,3], [0.2,0,3.4], [0.4,0,3.6],
            [0.5,0,3.65], [0.6,0,3.6], [0.58,0,3.5],
            [0.4,0,3.2], [0.2,0,0] ),
      SEGMENTS, 360, 0, SCALE, POS, [0,-90,0], PLATECOLOR, PLATESURF, PHONG );

  endboundary
endproc


!====================================================================
!!
!! Bureau leg.  Smaller at bottom than top.  Height 6".
!!
!====================================================================
proc BUREAULEG( vector POS )
  boundary

    lathe( ( [0,0,1], [6,0,1.3] ),
      8, 360, 0, [1,1,1], POS, [0,-90,0], BUREAUCOLOR, BUREAUSURF, OPEN );

  endboundary
endproc


!====================================================================
!!
!! Bureau edge boards...
!!
!!===================================================================
proc BUREAUEDGE( vector POS, vector ROTS, real LENGTH, real DEPTH )
  boundary

    extrude( ( [0,0,0], [0,DEPTH,0], [1,0.5,0], [0.5,0,0] ),
     3, [0,0,LENGTH], [1,1,1], POS, ROTS, BUREAUCOLOR, BUREAUSURF, 0 );

  endboundary
endproc


!====================================================================
!!
!! Bureau drawer knobs...
!!
!!===================================================================
proc BUREAUKNOB( vector POS, vector ROTS )
  boundary

    lathe( ( [0.1,0,0], [0,0,0.4], [0,0,0.5], [0.1,0,0.6], [0.2,0,0.6],
             [0.4,0,0.2], [0.6,0,0.2], [0.6,0,0] ),
      8, 360, 0, [1,1,1], POS, ROTS, BRASSCOLOR, BRASSSURF, PHONG );

  endboundary
endproc


!====================================================================
!!
!! Bureau drawers...
!!
!!===================================================================
proc BUREAUDRAWER( vector POS, real WIDTH, real HEIGHT, real BVL )
  boundary

    extrude( ( [0,0,0], [0,0,HEIGHT], [WIDTH,0,HEIGHT], [WIDTH,0,0] ),
      BVL, [0,6,0], [1,1,1], POS, [0,0,0], BUREAUCOLOR, BUREAUSURF, BEVEL );

    BUREAUKNOB( POS+[WIDTH*0.25,-0.6,HEIGHT*0.5], [0,0,90] );
    BUREAUKNOB( POS+[WIDTH*0.75,-0.6,HEIGHT*0.5], [0,0,90] );

  endboundary
endproc


!====================================================================
!!
!! The bureau itself...
!!
!!===================================================================
proc BUREAU( vector POS )
  real Y;

  boundary


    BUREAULEG( POS+[2,2,0] );
    BUREAULEG( POS+[2,22,0] );
    BUREAULEG( POS+[46,22,0] );
    BUREAULEG( POS+[46,2,0] );

    BUREAUEDGE( POS+[0,0,6], [0,0,0], 36.0, 24.0 );
    BUREAUEDGE( POS+[0,0,42], [0,90,0], 48.0, 24.0 );
    BUREAUEDGE( POS+[48,0,42], [0,180,0], 36.0, 24.0 );
    BUREAUEDGE( POS+[48,0,6], [0,270,0], 48.0, 24.0 );

    boundary
      BUREAUDRAWER( POS+[1,0,7], 46.0, 9.0, 1.0 );
      BUREAUDRAWER( POS+[1,0,16], 46.0, 9.0, 1.0 );
      BUREAUDRAWER( POS+[1,0,25], 46.0, 8.0, 1.0 );
      BUREAUDRAWER( POS+[1,0,33], 46.0, 8.0, 1.0 );
    endboundary

    lathe( ( [1,0,7.9], [3,0,8.9], [7,0,9.9], [11,0,9.9],
             [14,0,8.9], [18,0,6.9], [19,0,7.9], [20,0,7.9], [20,0,7.95],
             [20,0,8], [19,0,8], [18,0,7], [14,0,9], [11,0,10], [7,0,10],
             [3,0,9], [1,0,8], [0,0,7] ),
      20, -360, 0, [0.3,0.3,0.5], POS+[8,13,42], [0,-90,0], MARBLE1(1,1), VASESURF , OPEN|PHONG );

    PLATE( POS+[25,16,42], [2,2,1.5], 24 );
    GOBLET( POS+[25,16,42.5], 1.5 );

  endboundary
endproc


!====================================================================
!!
!! A floor lamp...
!!
!====================================================================
proc FLOORLAMP( vector POS )
  boundary

! The lamp base
    lathe( ( [0,0,0], [0,0,6], [0.2,0,6], [0.8,0,6],
             [1.0,0,5.8], [2.0,0,3], [3.0,0,2], [3.5,0,0.75] ),
      20, 360, 0, [1,1,1], POS, [0,-90,0], BRASSCOLOR, BRASSSURF, PHONG );

! The lamp column
    lathe( ( [0,0,0], [0,0,0.7], [55,0,0.6], [60,0,0] ),
      6, 360, 0, [1,1,1], POS+[0,0,3.5], [0,-90,0], BRONZECOLOR, BRONZESURF, 0 );

! The lamp shade
    lathe( ( [0,0,10], [14,0,8] ),
      64, 360, 0, [1,1,1], POS+[0,0,55+3.5], [0,-90,0],
      LSHADECOLOR, LSHADESURF, PHONG|OPEN );

! The light bulb
    if (FULLMODEL) {
      lamp1( POS+[0,0,65], BULB100, 2, 20 );
    }

  endboundary
endproc


!====================================================================
!!
!! A bottle of wine...
!!
!====================================================================
proc WINE( vector POS )
  boundary

! The bottle
    lathe( ([0,0,0], [0,0,1.4], [0.1,0,1.45], [0.2,0,1.5], [0.3,0,1.5],
            [6.4,0,1.5], [6.5,0,1.5], [6.8,0,1.45], [7.2,0,1.12],
            [7.8,0,0.65], [8,0,0.54], [8.4,0,0.5], [9.5,0,0.5],
            [9.6,0,0.53], [9.7,0,0.53], [9.9,0,0.53], [10,0,0.5],
            [10,0,0.48], [9.9,0,0.4], [9,0,0.4], [9,0,0] ),
      24, 360, 0, [1,1,1], POS, [0,-90,0], DKGREEN, BOTTLESURF, PHONG );

! The cork
    lathe( ([0,0,0], [0,0,0.4], [1.8,0,0.4], [1.8,0,0] ),
      12, 360, 0, [1,1,1], POS+[0,0,9.0], [0,-90,0], CORKCOLOR, DULL, PHONG );

! The label
    lathe( ( [3,-1.51,0], [0,-1.51,0] ),
      8, -120, 0, [1,1,1], POS+[0,0,1.5], [0,-90,0], OXPISS(1,1), DULL, OPEN|PHONG );

  endboundary
endproc


!====================================================================
!!
!! A candle, wick, and flame.  A small point light source on tip of
!! flame...
!!
!====================================================================
proc CANDLE( vector POS )
  boundary

! The candle proper
    lathe( ([0,0,0.4], [8,0,0.38], [8.1,0,0.37], [8.0,0,0.35] ),
      12, 360, 0, [1,1,1], POS, [0,-90,0], CANDLECOLOR, CANDLESURF, OPEN|PHONG );

! The wick
    lathe( ([0,0,0], [0,0,0.05], [0.5,0,0.05], [0.5,0,0] ),
      5, 360, 0, [1,1,1], POS+[0,0,8], [0,-90,0], WICKCOLOR, WICKSURF, 0 );

! The flame
    lathe( ([0,0,0], [0.2,0,0.21], [0.4,0,0.2], [0.6,0,0.15],
            [0.8,0,0.06], [1,0,0] ),
      8, 360, 0, [1,1,1], POS+[0,0,8.3], [0,-90,0], FLAMECOLOR, FLAMESURF, PHONG );

! The flame's lamp
    lamp1( POS+[0,0,10.4], CANDLEFLAME, 0.001, 30 );

  endboundary
endproc


!====================================================================
!!
!! A candlestick...
!!
!====================================================================
proc CANDLESTICK( vector POS )
  boundary

! Candlestick proper...
    lathe( ([0,0,0], [0,0,2], [0.02,0,2], [0.2,0,1.9],
            [0.4,0,1.6], [0.6,0,1], [0.8,0,0.8], [1.2,0,0.65],
            [1.59,0,0.6], [1.6,0,0.6], [2.7,0,0.6], [2.8,0,0.62],
            [3.0,0,0.82], [3.08,0,1], [3.10,0,1.05], [3.12,0,1.0],
            [3.07,0,0.6], [3.0,0,0.4], [2.0,0,0] ),
      20, 360, 0, [1,1,1], POS, [0,-90,0], PEWTERCOLOR, PEWTERSURF, PHONG );

! Filligree...
    lathe( ([0,0,0], [0,0,0.6], [0.08,0,0.7], [0.12,0,0.7],
            [0.18,0,0.6], [0.22,0,0.6], [0.28,0,0.69], [0.32,0,0.69],
            [0.38,0,0.6], [0.42,0,0.6], [0.48,0,0.68], [0.52,0,0.68],
            [0.58,0,0.6], [0.62,0,0.6], [0.68,0,0.67], [0.72,0,0.67],
            [0.78,0,0.6], [0.8,0,0.6], [0.8,0,0] ),
      12, 360, 0, [1,1,1], POS+[0,0,1.6], [0,-90,0], PEWTERCOLOR, PEWTERSURF, PHONG );

     CANDLE( POS+[0,0,3] );

  endboundary
endproc


!====================================================================
!!
!! Table leg.  2" on a side at the top, 1.5" on a side at the bottom
!!
!====================================================================
proc TABLELEG( vector POS )
  boundary

    lathe( ( [0,0,1.2], [30,0,1.42] ),

      8, 360, 0, [1,1,1], POS, [0,-90,0], TABLECOLOR, TABLESURF, OPEN );

  endboundary
endproc


!====================================================================
!!
!! Table top boards...
!!
!!===================================================================
proc TABLETOPBOARD( vector POS, real WIDTH, real LENGTH )
  boundary

    extrude( ( [0,0.2,0], [0,0,0.2], [0,0,1.3], [0,0.2,1.5],

               [0,WIDTH-0.2,1.5], [0,WIDTH,1.3],

               [0,WIDTH,0.2], [0,WIDTH-0.2,0] ),

     0.2, [LENGTH,0,0], [1,1,1], POS, [0,0,0], TABLECOLOR, TABLESURF, BEVEL );

  endboundary
endproc


!====================================================================
!!
!! Table supports...
!!
!!===================================================================
proc TABLETOPSUPPORTS( vector POS )
  boundary

    extrude( ( [-0.5,0,0], [-0.5,0,2], [0.5,0,2], [0.5,0,0] ),

      0, [0,34,0], [1,1,1], POS+[7,7,0], [0,0,0], TABLECOLOR, TABLESURF, 0 );

    extrude( ( [-0.5,0,0], [-0.5,0,2], [0.5,0,2], [0.5,0,0] ),
      0, [0,34,0], [1,1,1], POS+[57,7,0], [0,0,0], TABLECOLOR, TABLESURF, 0 );

    extrude( ( [-0.5,0,0], [-0.5,0,2], [0.5,0,2], [0.5,0,0] ),
      0, [0,50,0], [1,1,1], POS+[7,7,0], [0,0,-90], TABLECOLOR, TABLESURF, 0 );

    extrude( ( [-0.5,0,0], [-0.5,0,2], [0.5,0,2], [0.5,0,0] ),
      0, [0,50,0], [1,1,1], POS+[7,41,0], [0,0,-90], TABLECOLOR, TABLESURF, 0 );

  endboundary
endproc


!====================================================================
!!
!! The table itself...
!!
!!===================================================================
proc TABLE( vector POS )
  real Y;

  boundary


    TABLELEG( POS+[7,7,0] );
    TABLELEG( POS+[57,7,0] );
    TABLELEG( POS+[7,41,0] );
    TABLELEG( POS+[57,41,0] );

    boundary
      do {
        TABLETOPBOARD( POS+[0,Y,30], 7.9, 64.0 );
        Y = Y + 8;
      } while (Y<48);
    endboundary

    TABLETOPSUPPORTS( POS+[0,0,28] );

  endboundary
endproc


!====================================================================
!!
!! The table assembly...
!!
!!===================================================================
proc TABLEASM( vector POS )
  boundary

    boundary
      CANDLESTICK( POS+[16,24,31.5] );
      CANDLESTICK( POS+[48,29,31.5] );
      GOBLET( POS+[21,18,31.5], 1.0 );
      GOBLET( POS+[50,32,31.5], 1.0 );
      WINE( POS+[41,36,31.5] );
      WINE( POS+[14,15,31.5] );
      PLATE( POS+[40,16,31.5], [2,1,1.5], 24 );
      PLATE( POS+[22,32,31.5], [1,1,1], 20 );
      CHEESE( POS+[22,32,32], [1,1,1] );
    endboundary

    TABLE( POS );

  endboundary
endproc


!====================================================================
!!
!! FLoor boards...
!!
!!===================================================================
proc FLOORBOARD( vector POS, real WIDTH, real LENGTH )
  boundary

    extrude( ( [0,0.2,0], [0,0,0.2], [0,0,1.3], [0,0.2,1.5],

               [0,WIDTH-0.2,1.5], [0,WIDTH,1.3],

               [0,WIDTH,0.2], [0,WIDTH-0.2,0] ),

     3, [LENGTH,0,0], [1,1,1], POS, [0,0,0], FLOORCOLOR, FLOORSURF, 0 );

  endboundary
endproc


proc FLOORBOARDS( vector FBPOS )
  real  Y;

  Y = -120;
  boundary
    do {
      FLOORBOARD( FBPOS+[-120,Y,-1.5], 9.9, 300.0 );
      Y = Y + 10;
    } while (Y<120);

  endboundary
endproc


!====================================================================
!!
!! The room...   Floor, walls, ceiling....
!!
!!===================================================================
proc ROOM( vector RPOS )

  boundary

! Floor boards
    if (TEXTURED_FLOOR) {
      polygon( @[-120,120,0]+RPOS, @[180,120,0]+RPOS,
               @[180,-120,0]+RPOS, @[-120,-120,0]+RPOS,
               FLOOR_TEXTURE(2,8,SMOOTH5), FLOORSURF, 0 );
    }
    else {
      FLOORBOARDS( RPOS );
    }

! North wall
    polygon( @[-120,120,0]+RPOS, @[-120,120,96]+RPOS,
      @[180,120,96]+RPOS, @[180,120,0]+RPOS,
      WALLCOLOR, WALLSURF, 0 );

! East wall
    polygon( @[180,120,0]+RPOS, @[180,120,96]+RPOS,
      @[180,-120,96]+RPOS, @[180,-120,0]+RPOS,
      WALLCOLOR, WALLSURF, 0 );

! South wall
    polygon( @[-120,-120,0]+RPOS, @[-120,-120,96]+RPOS,
      @[180,-120,96]+RPOS, @[180,-120,0]+RPOS,
      WALLCOLOR, WALLSURF, 0 );

! West wall
    WINDOW : hole( POLYGON, @W1a+RPOS, @W1b+RPOS,
      @W1c+RPOS, @W1d+RPOS );

    DOOR   : hole( POLYGON, @D1a+RPOS, @D1b+RPOS,
      @D1c+RPOS, @D1d+RPOS );

    polygon( @[-120,-120,-10]+RPOS, @[-120,-120,96]+RPOS,
      @[-120,120,96]+RPOS, @[-120,120,-10]+RPOS,
      WALLCOLOR, WALLSURF, 0, WINDOW, DOOR );

    boundary

! Window sill
      extrude( ( [1,0,0], [1.5,0,0.75], [-6,0,0.75], [-6,0,0] ),
       3, [0,-96,0], [1,1,1], W1a, [0,0,0], TRIMCOLOR, TRIMSURF, 0 );

! Window sides & top
      polygon( @W1a+RPOS, @W1a+RPOS+[-6,0,0],
        @W1d+RPOS+[-6,0,0], @W1d+RPOS,
        WALLCOLOR, WALLSURF, 0 );

      polygon( @W1b+RPOS, @W1b+RPOS+[-6,0,0],
        @W1c+RPOS+[-6,0,0], @W1c+RPOS,
        WALLCOLOR, WALLSURF, 0 );

      polygon( @W1c+RPOS, @W1c+RPOS+[-6,0,0],
        @W1d+RPOS+[-6,0,0], @W1d+RPOS,
        WALLCOLOR, WALLSURF, 0 );

! Window glass
      if (GLAZING) {
        polygon( @W1a+RPOS+[-5,0,0], @W1d+RPOS+[-5,0,0],
          @W1c+RPOS+[-5,0,0], @W1b+RPOS+[-5,0,0],
          WHITE, GLASS, 0 );
      }

! Curtains
      extrude( ( [-50,0,0], [-41,4,0], [-39,4,0], [-31,-4,0], [-29,-4,0],
                 [-21,4,0], [-19,4,0], [-11,-4,0],[-9,-4,0], [-1,4,0],
                 [1,4,0], [9,-4,0], [11,-4,0], [19,4,0],[21,4,0],
                 [29,-4,0],[31,-4,0],[39,4,0],[41,4,0],[50,0,0] ),
        0, [0,0,87], [0.4,0.2,1], W1a+[3,-5,-11]+RPOS, [0,0,-90],
        CURTAINCOLOR, CURTAINSURF, OPEN|NOENDS|PHONG );

      extrude( ( [-50,0,0], [-41,4,0], [-39,4,0], [-31,-4,0], [-29,-4,0],
                 [-21,4,0], [-19,4,0], [-11,-4,0],[-9,-4,0], [-1,4,0],
                 [1,4,0], [9,-4,0], [11,-4,0], [19,4,0],[21,4,0],
                 [29,-4,0],[31,-4,0],[39,4,0],[41,4,0],[50,0,0] ),
        0, [0,0,87], [0.4,0.2,1], W1b+[3,5,-11]+RPOS, [0,0,-90],
        CURTAINCOLOR, CURTAINSURF, OPEN|NOENDS|PHONG );

! Curtain rod
      extrude( ( [-0.1,0,-0.3], [-0.1,0,0.3], [0.1,0,0.3], [0.1,0,-0.3] ),
        0, W1a-W1b, [1,1,1], W1b+[1,0,86-12], [0,0,0],
        RODCOLOR, RODSURF, 0 );

    endboundary

! Door sides & top
    boundary
      polygon( @D1a+RPOS, @D1a+RPOS+[-6,0,0],
        @D1d+RPOS+[-6,0,0], @D1d+RPOS,
        TRIMCOLOR, TRIMSURF, 0 );

      polygon( @D1b+RPOS, @D1b+RPOS+[-6,0,0],
        @D1c+RPOS+[-6,0,0], @D1c+RPOS,
        TRIMCOLOR, TRIMSURF, 0 );

      polygon( @D1c+RPOS, @D1c+RPOS+[-6,0,0],
        @D1d+RPOS+[-6,0,0], @D1d+RPOS,
        TRIMCOLOR, TRIMSURF, 0 );

! Door trim
      extrude( ( [0,0,0], [0.1,0,0], [0.5,2,0], [0,2,0] ),
        0, D1d-D1a+[0,0,2], [1,1,1], D1a, [0,0,0],
        TRIMCOLOR, TRIMSURF, OPEN|NOENDS );

      extrude( ( [0,0,0], [0.1,0,0], [0.5,0,2], [0,0,2] ),
        0, D1d-D1c+[0,4,0], [1,1,1], D1c-[0,2,0], [0,0,0],
        TRIMCOLOR, TRIMSURF, OPEN|NOENDS );

      extrude( ( [0,0,0], [0.1,0,0], [0.5,-2,0], [0,-2,0] ),
        0, D1c-D1b+[0,0,2], [1,1,1], D1b, [0,0,0],
        TRIMCOLOR, TRIMSURF, OPEN|NOENDS );

! Light switch
      extrude( ( [0,-1.5,-2.5], [0,-1.5,2.5], [0,1.5,2.5], [0,1.5,-2.5] ),
        0.1, [-1,0,0], [1,1,1], ((W1b+D1a)/2)+[0.1,0,40], [0,0,0],
        TRIMCOLOR, TRIMSURF, BEVEL );

      extrude( ( [0,-0.15,-0.2], [0,-0.15,0.2], [0,0.15,0.2], [0,0.15,-0.2] ),
        0, [0.4,0,0], [1,1,1], ((W1b+D1a)/2)+[0,0,40], [0,30,0],
        TRIMCOLOR, TRIMSURF, 0 );

    endboundary

! Baseboard
    extrude( ( [0,0,0], [0.3,0,0], [0.3,0,1.5], [0,0,1.5] ),
      0, [-120,118,0]-D1a, [1,1,1], D1a+[0,2,0], [0,0,0],
      BBCOLOR, BBSURF, 0 );

    extrude( ( [0,0,0], [0,-0.3,0], [0,-0.3,1.5], [0,0,1.5] ),
      0, [300,0,0], [1,1,1], [-120,120,0], [0,0,0],
      BBCOLOR, BBSURF, 0 );

! Ceiling
    polygon( @[-120,-120,96], @[-120,120,96], @[180,120,96], @[180,-120,96],
      WHITE, DULL, 0 );

  endboundary
endproc


!====================================================================
!!
!! Veranda flooring...
!!
!!===================================================================
proc VERANDABOARD( vector POS, real WIDTH, real LENGTH )
  boundary

    extrude( ( [0,0.2,0], [0,0,0.2], [0,0,1.3], [0,0.2,1.5],
               [0,WIDTH-0.2,1.5], [0,WIDTH,1.3],
               [0,WIDTH,0.2], [0,WIDTH-0.2,0] ),
     3, [LENGTH,0,0], [1,1,1], POS, [0,0,0], RWOODCOLOR, RWOODSURF, 0 );

  endboundary
endproc


!====================================================================
!!
!! Veranda stanchion...
!!
!!===================================================================
proc VERANDASTANCHION( vector POS )
  boundary

    extrude( ( [-2,-2,0], [-2,2,0], [2,2,0], [2,-2,0] ),
     0, [0,0,30], [1,1,1], POS, [0,0,0], RWOODCOLOR, RWOODSURF, 0 );

  endboundary
endproc


!====================================================================
!!
!! Veranda railing...
!!
!!===================================================================
proc VERANDARAILING( vector RSTART, vector REND, real WIDTH)
  real WID = WIDTH / 2;

  boundary

    extrude( ( [-WID,0,0], [-WID,0,1.5], [WID,0,1.5], [WID,0,0] ),
     0, REND-RSTART, [1,1,1], RSTART, [0,0,0], RWOODCOLOR, RWOODSURF, 0 );

  endboundary
endproc


!====================================================================
!!
!! The veranda, floor and railing...
!!
!!===================================================================
proc VERANDA( vector POS )
  real  Y;

  boundary

! Veranda floor boards
    Y = -120;
    boundary
      do {
        VERANDABOARD( POS+[-96,Y,-1.5], 5.75, 96.0 );
        Y = Y + 6;
      } while (Y<160);
    endboundary

! Veranda railing assembly...
    Y = 158;
    boundary
      do {
        VERANDASTANCHION( POS+[-94,Y,0] );
        Y = Y - 36;
      } while (Y>-120);

      VERANDARAILING( POS+[-96,-120,30], POS+[-96,160,30], 3.0 );
      VERANDARAILING( POS+[-96,-120,15], POS+[-96,160,15], 1.7 );
    endboundary

  endboundary
endproc


!====================================================================
!!
!! Picture on the wall...
!!
!!===================================================================
proc PICTURE1( vector POS, vector ROTS )
  matrix  MAT1 = xform(ROTS);

  boundary

! The picture itself
    polygon( @(POS+[-24,-0.6,18])#MAT1, @(POS+[24,-0.6,18])#MAT1,
             @(POS+[24,-0.6,-18])#MAT1, @(POS+[-24,-0.6,-18])#MAT1,
             HILLS(1,1), PICTURESURF, 0 );

! The picture frame front
    ph1 : hole (polygon, @(POS+[-23.5,-0.7,17.5])#MAT1, @(POS+[23.5,-0.7,17.5])#MAT1,
             @(POS+[23.5,-0.7,-17.5])#MAT1, @(POS+[-23.5,-0.7,-17.5])#MAT1 );

    polygon( @(POS+[-24.5,-0.7,18.5])#MAT1, @(POS+[24.5,-0.7,18.5])#MAT1,
             @(POS+[24.5,-0.7,-18.5])#MAT1, @(POS+[-24.5,-0.7,-18.5])#MAT1,
             CHROMECOLOR, CHROMESURF, 0, ph1 );

! The frame edges
    polygon( @(POS+[-24.5,-0.7,18.5])#MAT1, @(POS+[24.5,-0.7,18.5])#MAT1,
             @(POS+[24.5,0.0,18.5])#MAT1, @(POS+[-24.5,0.0,18.5])#MAT1,
             CHROMECOLOR, CHROMESURF, 0 );

    polygon( @(POS+[24.5,-0.7,18.5])#MAT1, @(POS+[24.5,-0.7,-18.5])#MAT1,
             @(POS+[24.5,0.0,-18.5])#MAT1, @(POS+[24.5,0.0,18.5])#MAT1,
             CHROMECOLOR, CHROMESURF, 0 );

    polygon( @(POS+[24.5,-0.7,-18.5])#MAT1, @(POS+[-24.5,-0.7,-18.5])#MAT1,
             @(POS+[-24.5,0.0,-18.5])#MAT1, @(POS+[24.5,0.0,-18.5])#MAT1,
             CHROMECOLOR, CHROMESURF, 0 );

    polygon( @(POS+[-24.5,-0.7,-18.5])#MAT1, @(POS+[-24.5,-0.7,18.5])#MAT1,
             @(POS+[-24.5,0.0,18.5])#MAT1, @(POS+[-24.5,0.0,-18.5])#MAT1,
             CHROMECOLOR, CHROMESURF, 0 );

  endboundary
endproc


!====================================================================
!!
!! Define the scene.......
!!
!!===================================================================

frameloop
  clearscene;

  star   ( [30000,-40000,80000], [1.5, 1.5, 1.5 ], 6000 );
  ambient( [0,0,0], [0.7,0.7,0.7], UNIT([1,0.5,0.2]), 0.9, 0.10 );

  background( SKY, SKYHOR, SKYZEN );

  boundary
    SCENERY();
    ROOM( [0,0,0] );
    TABLEASM( [-10,0,0] );
    FLOORLAMP( [10,100,0] );
    VERANDA( [-120,0,0] );
    BUREAU( [-100,95,0] );
    PICTURE1( [24-100,120,66], [0,0,0] );
  endboundary

  render;
nextframe

end
