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 Complete SLIDE Software Graphics Pipeline

  1. Viewer Outline
  2. Dynamic Diamonds Example
  3. Preprocess
  4. PreprocessGraph
  5. Update
  6. UpdateGraph
  7. Render


Viewer Outline

Load a SLIDE File

Update the World

Render a Window


Dynamic Diamonds Example

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.


Preprocess

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. )

Preprocess Summary

  1. CSLIDEWorld::Preprocess(): flatly for each ( CSLIDESurfaces, CSLIDEPoints, CSLIDEFaces, CSLIDETransforms, CSLIDEInstances, CSLIDEObjects and CSLIDEGroups and CSLIDECameras and CSLIDELights, CSLIDEViewports, and CSLIDERenders ) call the Preprocess method:
    1. Initialize any dynamic values, including smashing matrices in instances
    2. Mark as dynamic if it has any dynamic fields
    3. Invalidate bounding box

For a cleaner view of the graph view the postscript version: preprocess.ps.


Preprocess Graph

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.

PreprocessGraph Summary

  1. CSLIDEWorld::PreprocessGraph(): for each CSLIDERender object call the PreprocessGraph method:
    1. if bounding box valid return
    2. Call PreprocessGraph on all children
    3. Calculate bounding box
    4. Mark as having a dynamic bound box if appropriate
    5. Set bounding box valid

For a cleaner view of the graph view the postscript version: preprocessgraph.ps.


Update

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.

Update Summary

  1. CSLIDEWorld::Update(): flatly for each object in the dynamics list call the Update method:
    1. Update any dynamic values, including smashing matrices in instances
    2. Invalidate bounding box

For a cleaner view of the graph view the postscript version: update.ps.


Update Graph

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.

UpdateGraph Summary

  1. CSLIDEWorld::UpdateGraph(): for each CSLIDERender object call the UpdateGraph method:
    1. if bounding box valid return
    2. Call UpdateGraph on all children
    3. Calculate bounding box
    4. Set bounding box valid

For a cleaner view of the graph view the postscript version: updategraph.ps.


Render

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