| University of California, Berkeley EECS Dept, CS Division | ||
| Jordan Smith | SLIDE: Scene Language for Interactive Dynamic Environments | Prof. Carlo H. Séquin | 
| Home | Goals | Publications | People | Gallery | Assignments | Distributions | 
 
 
 
The file diamonds.slf contains the description of a 2D dynamic scene made up almost entirely of diamonds. The diagrams below show two frames from the diamonds' animation. The diamonds are all blue. The static bounding boxes appear in white, and the dynamic bounding boxes appear in red. The upper left hand corner contains a static group of two diamonds. The upper right hand corner contains another static instance of the group of two diamonds with another diamond surrounding them which is statically rotated and is scaling in a pulsating manner. The bottom left hand corner contains a morphing diamond which has a dynamic point. The bottom right hand corner contains the same morphing diamond rotated 90 degrees. The left hand diagram shows the dynamic objects at their minimal extent, and the right hand diagram shows them at their maximal extent.
|   |   | 
 The objectives of Preprocess are: to initialize any
dynamic TCL values, mark any objects which have any dynamic fields as
dynamic, and to mark all the bounding boxes in the object
and group nodes of the scene graph as invalid.  In the
Preprocess phase of execution, the
CSLIDEWorld object calls the Preprocess
method flatly on each object of all types (
CSLIDESurfaces, CSLIDEPoints,
CSLIDEFaces, CSLIDETransforms,
CSLIDEInstances, CSLIDEObjects and
CSLIDEGroups and CSLIDECameras and
CSLIDELights, CSLIDEViewports, and
CSLIDERenders ) exactly once.  The
CSLIDEWorld's dynamics list is not used or modified while
preprocessing. 
 The objects initialize any dynamic values by executing the TCL
statement which is stored as a string.  DynVector,
DynPoint, and DynFloat type variables
execute any TCL commands associated with them when their respective
Update method is invoked.  
 An object can tell if its fields are dynamic by calling their
GetDynamic() boolean method.  This method returns true if
any of the data values are controlled by a TCL statement.  The dynamic
objects are colored red in the diagram below. 
 Bounding boxes are invalidated in this flat pass over the data
structure to optimize the traversal of the scene graph in the
PreprocessGraph phase of execution.  The bounding box
valid flag can be used to check whether a node has already been
processed in the depth first traversal of the scene graph DAG which is
executed by the PreprocessGraph function.
 The diagram below shows the state of the scene graph DAG, of the
diamonds.slf example, after Preprocess has
been executed.  The red nodes in the graph correspond to objects which
have been marked dynamic because one or more of their fields are
dynamic.  Note that CSLIDEInstances consider their
CSLIDETransforms as fields, but CSLIDEGroups
do not consider their CSLIDEInstances as fields.
CSLIDEInstances are considered as arcs in the scene graph
instead.  The CSLIDEWorld's list of dynamic object is
empty.  ( Note: There is a spurious arrow head pointing from the
camera to the dynamics list.  And the rotation transform, "R," in the
iPulsate instance is not dynamic, but the scale, "S," is dynamic. )
CSLIDEWorld::Preprocess(): flatly for each (
CSLIDESurfaces, CSLIDEPoints,
CSLIDEFaces, CSLIDETransforms,
CSLIDEInstances, CSLIDEObjects and
CSLIDEGroups and CSLIDECameras and
CSLIDELights, CSLIDEViewports, and
CSLIDERenders ) call the Preprocess method:
   
For a cleaner view of the graph view the postscript version: preprocess.ps.
 The objectives of the PreprocessGraph phase of
execution are: to initialize the bounding boxes of the nodes of the
scene graph and mark any object or group
nodes whose bounding boxes could change dynamic as having a dynamic
bounding box.  In the PreprocessGraph phase of execution,
the CSLIDEWorld object calls the
PreprocessGraph method on each of its
CSLIDERender objects.  Each CSLIDERender
object initiates a depth first traversal of its scene graph by
recursively calling the PreprocessGraph method of its
root node.  At the end of the PreprocessGraph traversal
of the scene graphs, the CSLIDEWorld object flatly runs
through all of the its objects and places any objects with dynamic
fields or dynamic bounds on its dynamics list.  
 Bounding boxes are calculated for every CSLIDEObject
and CSLIDEGroup in the scene graph hierarchy.  These
bounding boxes are created recursively, so a CSLIDEGroup
creates its bounding box by first having its children create their
bounding boxes and then transforming their bounding boxes to create
the local bounding box.  It should only be necessary to calculate a
bounding box exactly one time in this depth first traversal.  This is
acheived by marking the bound valid flag true after the bounding box
is created, and by only calculating bounding boxes for nodes who's
bounding boxes are invalid.  The green arrows in the diagram below
demonstrate how the depth first traversal avoids doing redundant
work. 
A node of the scene graph hierarchy should be marked as having a dynamic bounding box if one of its children has a dynamic bounding box or if one of instances is dynamic and the node pointed to by that instance actually has a bounding box. All real geometry nodes have bounding boxes. Cameras and lights do not contain any real geometry, so they do not have a boundary. Following from this fact, any subtree of the graph which only contains camera or light leaves has no boundary. The nodes with dynamic bounding boxes are colored purple in the diagram below. It is possible for a group to have dynamic fields, but not have a dynamic bounding box. For example, it could have a dynamic surface properties which do not alter its geometric extent.
 After PreprocessGraph is done
CSLIDEWorld::CreatDynamicsList() is called.  In this
procedure, the CSLIDEWorld runs through its
CSLIDESurfaces, CSLIDEPoints,
CSLIDEFaces, CSLIDETransforms,
CSLIDEInstances, CSLIDEObjects and
CSLIDEGroups and CSLIDECameras and
CSLIDELights, CSLIDEViewports, and
CSLIDERenders in this order.  It adds any object which is
dynamic or has a dynamic bounding box to the dynamics list,
maintaining the order in which they are checked.  Objects will be
updated in the order which they appear in the dynamics list.  An
example of why this order might be important is transforms and instances.
If transforms are updated before instances, then instances can
premultiply their transforms into a single matrix which can then be
used in the graph update. 
 In the diagram below, notice that the dynamic transforms appear
before the instances which reference them.  Also notice that the
static rotation from the iPulsate instance does not
appear in the dynamics list. 
CSLIDEWorld::PreprocessGraph(): for each
CSLIDERender object call the PreprocessGraph method:
  PreprocessGraph on all children
     
For a cleaner view of the graph view the postscript version: preprocessgraph.ps.
 The objectives of Update are: to update any dynamic
TCL values and mark all the bounding boxes invalid for the objects on
the dynamics list.  The CSLIDEWorld object is awaken by a
timer event which invokes its Update method.  The
CSLIDEWorld object only touches the objects on the
dynamics list which is illustrated by the green arrows traversing the
dynamics list in the diagram below.  After the flat
Update is executed CSLIDEWorld object then
calls the recursive UpdateGraph method. 
CSLIDEWorld::Update(): flatly for each object in
  the dynamics list call the Update method:
   
For a cleaner view of the graph view the postscript version: update.ps.
 The objective of the UpdateGraph phase of execution
is to update the bounding boxes of the dynamic nodes of the scene
graph.  In the UpdateGraph phase of execution, the
CSLIDEWorld object calls the UpdateGraph
method on each of its CSLIDERender objects.  Each
CSLIDERender object initiates a depth first traversal of
its scene graph by recursively calling the UpdateGraph
method of its root node.  At the end of the UpdateGraph
traversal of the scene graphs, the world geometry data base is
consistent and ready to be rendered.  The CSLIDEWorld
sends redisplay events to all of the SLIDE windows, so that they will
update their renderings of the world.  
The green arrows in the diagram below demonstrate how the depth first traversal avoids doing redundant work. Redunandant works includes recomputing bounding boxes of static nodes as well as recomputing bounding boxes of dynamic nodes more than once.
CSLIDEWorld::UpdateGraph(): for each
CSLIDERender object call the UpdateGraph method:
  UpdateGraph on all children
     
For a cleaner view of the graph view the postscript version: updategraph.ps.
 Each CWindow will call its rendering pass when it
receives a redisplay event.  The diagram below shows what the
rendering pass looks like for the full SLIDE rendering pipeline. 
 
For a cleaner view of the graph view the postscript version: render.ps.
This page was originally built by Jordan Smith.
Last modified: Saturday, 08-May-1999 17:03:10 PDT