The aim of the Haskell Scene Graph project is to provide a solid basis for the development of 3D applications. Other work which has 3D content has focused on an application or a research topic. Whilst these projects have a scene graph and/or 3D component, it is not easy to extract a useful library. The project's aim is to provide such a library.
This page is a broad brush description of the design of the library. Feel free to add comments on the talk page.
Current Status: Initial 0.1 version is under development.
It draws inspiration from the following Haskell projects:
and from the following non-Haskell work:
2 Scene Node
The graph will be built using FGL. So it remains to define a scene node to get things started:
data SceneNode = SGroup | SMaterial Phong | SGeode Geometry | SSwitch Int | STransform Matrix | SLight | SCamera | SCompiled (Maybe DisplayList) | SPrimitive (IO ())
SGroup - Supports grouping of nodes. Since the Graph will provide the links to children we don't need to have anything more.
SMaterial - Sets the material for the tree starting at this node. Currently just Phong is shown.
SGeode - Is where geometries shapes are specified. In theory these nodes should not have children. Geometries can be basic shapes (provided in GLUT.Objects) or meshes of some form.
SSWitch - Provides the ability to choose the sub-tree based on the integer value. Some implementations suggest using a bit map across all the children.
STransform - Introduces a transform (translate, scale or rotate).
SLight - Specifies a light at the origin with various properties.
SCamera - Specifies a camera .
SCompiled - Indicates that the tree with this node as parent can be compiled into a display list. Even on parts of the graph that ungo change it might be advantageous to use the display list. For instance, when the user is roating the view, using a display list improves performance greatly. This indicates that a multi-valued flag would be required for example CompileAlways, DontCompile, CompileForUserInteraction.
SPrimitive - Provides the means to supply a drawing function.
Note that the scene is defined as a graph but drawn as a tree. There may well be restrictions on some of the ways the graph can be built using the above nodes used.
3 Scene Graph Monad
Wrapping in Monad enables us to define a simple DSL for building Scene Graphs:
type OSGT m = (StateT OSGState m) -- Append the two graphs parented at the supplied nodes (<+>) :: Monad m => OSGT m SceneNode -> OSGT m SceneNode -> OSGT m SceneNode -- Translate a node (and child graph) -- Rotate, scale and colour can be defined in similar ways translate :: Monad m => OSGT m SceneNode -> Vector3 Float -> OSGT m SceneNode -- Example ferris :: Float -> OSG SceneNode ferris theta = do let ring = torus 0.5 `colour` White --Blue axial1 = cube 0.5 `scale` v1x 40 `colour` Green axial2 = cube 0.5 `scale` v1z 40 `colour` Green axial = axial1 <+> axial2 root <- (ring `translate` vy 2 <+> ring `translate` vy (-2) <+> axial `translate` vy (-2) <+> axial `translate` vy 2 <+> crossbeams) `rotate` (theta , (vector3 0 1 0 )) return root
The Monad can be run to extract the actual scene graph and then sent off for viewing...
Include view with basic navigation mechanisms. Use can switch between them; example interaction models are:
- Flight Simulator.
- FPS (First Person Shooter) - i.e. use the keys AWDX to move relative to mouse direction.
(Inspired by Open Scene Graph)
A simple viewer has a camera and light, grouped and then transformed. This transform is modified by user actions as per the 'interaction model'.
Can either have multiple viewports, one per camera and/or press number keys to get different camera.
Including viewports in the scene graph allows the possibility for users to define artifects on the viewport such as a mini-map or buttons to control aspects of the scene.
The library will include the ability to provide callbacks for nodes on the graph to respond to user actions such as mouse clicks and drags and key presses. Thoughts are along the lines of using Reactive in some way.
COLLADA is the format embedded in Google Earth 6.0 KML files. Google Sketch-Up can save to these and their are numerous models on the Google Sketchup site.