############################################################################
#
# Funs - a simple SLIDE example
#
# This example shows how to do the following:
# 1) Comment Code
# 2) Specify Geometry
# 3) Add Color
# 4) Create Sliders with Tcl/Tk

############################################################################
# 1) Comment Code
#
#    "#" - comments out a single line, like "//" in C++
(*   "(*  text  *)" - comments out all text in between, like "/*  */" in C++   *)


############################################################################
# 2) Specify Geometry 
#
# 2a) First specify the primitive objects (spheres, cones, etc) and their parameters.
#     The complete SLIDE syntax is http://www.cs.berkeley.edu/~ug/slide/docs/slide/spec/

sphere mySphere
  radius 0.5
endsphere

group mySpheres
  instance mySphere
    shading SLF_PHONG
  endinstance
  instance myCones
    shading SLF_FLAT
    scale (0.5 0.5 0.5)
    surface sYellow
    translate ( 1 0 0 )
    rotate ( 0 0 1 ) ( {expr 30.0*$SLF_TIME*$fun_sped*2} ) 
  endinstance
endgroup

cylinder myCylinder
  radius 1.0
#  zmin 0.0
   zmax 2.0
  thetaslices 16
endcylinder

group myCylinders
  shading SLF_GOURAUD
  instance myCylinder
  endinstance
  instance myDisk
    rotate ( 1 0 0 ) ( 180 ) 
  endinstance
  instance myDisk
    translate ( 0 0 2 )
  endinstance
endgroup

torus myTorus
endtorus

group myTori
  instance myTorus
  endinstance
  instance mySpheres
    surface sBlue
    translate ( 1 0 0 )
    rotate ( 0 1 0 ) ( {expr 30.0*$SLF_TIME*$fun_sped} ) 
    translate ( 1 0 0 )
  endinstance
endgroup

cone myCone
endcone

cone myDisk
  height 0
  thetaslices 16
endcone

group myCones
  instance myCone
  endinstance
  instance myCone
    rotate ( 1 0 0 ) ( 180 ) 
  endinstance
endgroup    

group gFuns
  instance myTorus
    shading SLF_GOURAUD
    scale ( 0.5 0.5 0.5 )
	scale ( {expr cos($SLF_TIME)+1.5} {expr sin($SLF_TIME)+1.5} 1 )
  endinstance
  instance mySphere
    scale ( {expr $fun_size }{expr $fun_size } {expr $fun_size })
    surface sBlue
    translate ( 0 0 {expr $fun_higt} )
    rotate ( 1 0 0 ) ( {expr 30.0*$SLF_TIME*$fun_sped} ) 
  endinstance
  instance myCylinders
    surface sRed
    scale ( 0.5 0.5 0.5)
    rotate ( 0 1 0 ) ( {expr 30.0*$SLF_TIME*$fun_sped} ) 
    translate ( {expr $fun_higt} 0 0 )
    rotate ( 0 0 1 ) ( {expr 30.0*$SLF_TIME*$fun_sped} ) 
  endinstance
  instance myTori
    surface sGreen
    shading SLF_WIRE
    rotate ( 1 0 0 ) ( 90 )
    translate ( 0 0 {expr $fun_higt} )
    rotate ( 0 1 0 ) ( {expr 30.0*$SLF_TIME*$fun_sped} ) 
  endinstance
endgroup


# 2c) Finally we need to add the funs to the World.

group World
  instance gFuns
    scale ( 0.1 0.1 0.1 )
  endinstance
endgroup


############################################################################
# 3) Add Color
#
#    In the Fun group we specified the surface color of each instance.
#    Now we need to define these surfaces.

surface sRed
  color (1.0 0.0 0.0)
endsurface

surface sGreen
  color (0.0 1.0 0.0)
endsurface

surface sBlue
  color (0.0 0.0 1.0)
endsurface

surface sYellow
  color (1.0 1.0 0.0)
endsurface

############################################################################
# 4) Create Sliders with Tcl/Tk
#
#  The following Tcl/Tk code shows how to create the sliders and variables
#  that we referenced above.


#  Make a Tcl initialization block

tclinit {
  set winName .slfWINDOW

  ### include some tcl libraries
  source SLIDEUI.tcl
  source MATH.tcl


  ### This defines a procedure called CreateSliders
  proc CreateSliders { parent name } {

    ### Don't worry about this stuff ...
    set subname "slf_[subst $name]"

    if { $parent == {} } {
	set root .$subname
    } elseif { $parent == "." } {
	set root .$subname
    } else {
	set root $parent.$subname
    }

    toplevel $root


    ### This is where the sliders are actually created ! ! !

    ### variable name       variable name    slider text
    ###  |                             |     |
    ###  V                             V     V       

   set higt [CreateScale $name $root higt "Height" 3  0.1 4 0.1 1 horizontal]
   set size [CreateScale $name $root size "Size"   1  0.5 5 0.1 1 horizontal]
   set sped [CreateScale $name $root sped "Speed"  3  1   5 0.1 1 horizontal]

    ###                                            ^  ^   ^  ^
    ###                                            |  |   |  |
    ###                     initial slider value---'  |   |  |
    ###                     minimum slider value------'   |  |
    ###                     maximum slider value----------'  `- slider step value



    ### This line is important too.  This tells the window to display the sliders.

    pack $higt $size $sped -side top -fill x
  }

  ### This calls the procedure that creates the sliders
  CreateSliders $winName fun
}


########################################################################################
# The code below this line specifies the camera, lighting, and rendering.
# Don't worry too much about this for now.


#################### 
# CAMERA
#################### 

camera cam
  projection SLF_PERSPECTIVE
  frustum ( -0.5 -0.5 -2 ) ( 0.5 0.5 -0.2 )
endcamera

group gCamera
  instance cam
    id instCam
    translate ( 0.0 0.0 1.0 )
  endinstance
endgroup

#################### 
# LIGHTS
#################### 

light lAmbient
  type SLF_AMBIENT
  color ( 0.2 0.2 0.2 )
endlight

light lTop
  type SLF_DIRECTIONAL
  color ( 1.0 1.0 1.0 )
endlight

group gLight
  instance lTop
    id iTop
    lookat
      eye ( 0 0 0 )
      target ( -1 -1 -1 )
      up ( 0 1 0 )
    endlookat
    translate ( 1 1 1 )
  endinstance
endgroup

####################
# RENDER
####################

window WINDOW
#  background ( 0.25 0.60 1.0 )
endwindow

viewport VIEWPORT WINDOW
endviewport

render VIEWPORT gCamera.instCam.cam World
  light lAmbient
  light gLight.iTop.lTop
endrender