Version française
Home     About     Download     Resources     Contact us    
Browse thread
Polymorphic variants and scene graphs
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jon Harrop <jon@f...>
Subject: Polymorphic variants and scene graphs

Here's my first attempt at using the technique described in Jacques' paper 
"Code reuse using polymorphic variants" to make an extensible scene graph. 
This could be useful for GUI code because users could easily add their own 
widgets.

First, we define functions to render a polygon or a group (list of scene 
graphs):

  type polygon = [ `Polygon of vec2 list ]
    
  let render_polygon (`Polygon rs) =
    GlDraw.begins `polygon;
    List.iter vertex rs;
    GlDraw.ends ()

  type 'a group = [ `Group of 'a list ]

  let rec render_group render (`Group l) =
    List.iter (render_group render) l

  type 'a t =
      [ `Polygon of vec2 list 
      |`Group of 'a list ]

  let rec render1 self = function
    | #polygon as polygon -> render_polygon polygon
    | #group as group -> render_group (render1 self) group

This "render1" function needs a Y combinator to implement recursion:

  let rec render1' t = render1 render1' t

That "render1'" function can now be used to render scene graphs containing 
polygons and groups.

Next, we define a function to render an axis-aligned rectangle (e.g. for a 
button):

  type rectangle = [ `Rectangle of vec2 * vec2 ]

  let render_rectangle (`Rectangle (l, u)) =
    render_polygon (`Polygon [vec2 l.x l.y; vec2 u.x l.y;
			      vec2 u.x u.y; vec2 l.x u.y])

  let render2 self = function
    | #rectangle as rectangle -> render_rectangle rectangle
    | #t as t -> render1 self t

By dispatching over type "t", this render function can now render rectangles 
as well as polygons and groups. Here's the final "render2'" function:

  let rec render2' t = render2 render2' t

Do polymorphic variants look like the way to go for scene graphs? They are 
slower than ordinary variants but performance is not so important in scene 
graph code and, particularly, not in GUI code.

Now, we want to add:

1. GL naming to identify which GUI element has been clicked on.

2. A "get_bound" function.

3. Layout functions, e.g. "hbox" and "vbox".

4. GL picking to search for the first GUI element under a mouse click.

5. Rendering of text.

and, finally, a selection of widgets.

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists