############################################################################
#
# Barbell - 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/


# This is a sphere named Weight with radius=2

sphere Weight
#  radius 2
endsphere


# This is a cylinder named Bar with radius=0.5,
# which extends from zmin to zmax.  zmin and zmax
# have been set to two dynamic Tcl/Tk variables, which
# will be controlled by sliders (defined later in this file).

cylinder Bar
  radius 0.5
  zmin {expr $barbell_zmin}
  zmax {expr $barbell_zmax}
endcylinder



# 2b) Now we need to group the Weight and Bar together to make the Barbell.
#     Groups are created by instancing (referencing) primitive objects or other groups.
#     So to make a Barbell we need to 1 Bar and 2 Weights. The Weights need to
#     be placed at the ends of the Bar, so we'll add translations to these instances
#     so that they correspond to the ends of the Bar (zmin and zmax).  We will also
#     make a slider to control the size of the first Weight by scaling it.

group Barbell
  instance Bar
    surface sRed
  endinstance

  instance Weight
    scale     ( {expr $barbell_size} {expr $barbell_size} {expr $barbell_size} )
    translate ( 0 0 {expr $barbell_zmin} )
    surface sBlue
  endinstance

  instance Weight
    translate ( 0 0 {expr $barbell_zmax} )
    surface sBlue
  endinstance
endgroup


# 2c) Finally we need to add the Barbell to the World.
#     Since the Barbell is vertical we need rotate it.

group World
  instance Barbell
    rotate (0 1 0) (90)
  endinstance
endgroup


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

surface sBlue
  color (0.0 0.0 1.0)
endsurface

surface sRed
  color (1.0 0.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 zmin [CreateScale $name $root zmin "zmin" -4 -1 -10 0.5 1 horizontal]
    set zmax [CreateScale $name $root zmax "zmax"  4  1  10 0.5 1 horizontal]	
    set size [CreateScale $name $root size "size"  1  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 $zmin $zmax $size  -side top -fill x
  }

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


########################################################################################
# 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_PARALLEL
  frustum ( -10 -10 -100 ) ( 10 10 100 )
endcamera

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

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

light lite
  type SLF_DIRECTIONAL
endlight

group gLight
  instance lite
    id instLite
    lookat
      eye ( 1.0 1.0 1.0 )
      target ( 0.0 0.0 0.0 )
      up ( 0.0 1.0 0.0 )
    endlookat
  endinstance
endgroup

light lite2
  type SLF_AMBIENT
  color (0.5 0.5 0.5)
endlight

group gLight2
  instance lite2
    id instLite2
  endinstance
endgroup

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

window WINDOW
endwindow

viewport VIEWPORT WINDOW
  origin ( 0.0 0.0 )
  size ( 1.0 1.0 )
endviewport

render VIEWPORT gCamera.instCam.cam World
  light gLight.instLite.lite
  light gLight2.instLite2.lite2
endrender