From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id D8F54BDE9 for ; Fri, 2 Sep 2005 18:37:32 +0200 (CEST) Received: from pih-relay04.plus.net (pih-relay04.plus.net [212.159.14.131]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id j82E8c7T006539 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 2 Sep 2005 16:08:38 +0200 Received: from [80.229.56.224] (helo=chetara) by pih-relay04.plus.net with esmtp (Exim) id 1EBBs2-000364-Pe for caml-list@yquem.inria.fr; Fri, 02 Sep 2005 14:46:18 +0100 From: Jon Harrop Organization: Flying Frog Consultancy Ltd. To: caml-list@yquem.inria.fr Subject: Polymorphic variants and scene graphs Date: Fri, 2 Sep 2005 14:43:22 +0100 User-Agent: KMail/1.7.2 MIME-Version: 1.0 Content-Disposition: inline Message-Id: <200509021443.22943.jon@ffconsultancy.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Miltered: at nez-perce with ID 43185CE6.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; variants:01 reuse:01 variants:01 iter:01 rec:01 iter:01 rec:01 combinator:01 recursion:01 dispatching:01 naming:01 hbox:01 vbox:01 ocaml:01 frog:98 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.3 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