Difference between revisions of "SceneGraph"

From HaskellWiki
Jump to navigation Jump to search
m
(Initial version release to Hackage)
Line 5: Line 5:
 
component, it is not easy to extract a useful library. The project's aim is to provide such a library.
 
component, it is not easy to extract a useful library. The project's aim is to provide such a library.
   
  +
Current Status: Initial 0.1 version is available on [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/scenegraph Hackage]
This page is a broad brush description of the design of the library. Feel free to add comments on the talk page.
 
   
  +
The library draws inspiration from the following Haskell projects:
Current Status: Initial 0.1 version is under development.
 
 
It draws inspiration from the following Haskell projects:
 
   
 
* [[PolyFunViz]]
 
* [[PolyFunViz]]
Line 21: Line 19:
 
* [http://en.wikipedia.org/wiki/COLLADA COLLADA]
 
* [http://en.wikipedia.org/wiki/COLLADA COLLADA]
   
== Scene Node ==
+
== Getting Started ==
  +
The graph will be built using [http://web.engr.oregonstate.edu/~erwig/fgl/haskell FGL]. So it remains to define a scene node to get things started:
 
  +
A scene is constructed using a set of combinators. The following creates a green cube
   
 
<code><pre>
 
<code><pre>
  +
cube 0.5 `colour` Green
data SceneNode =
 
SGroup
 
| SMaterial Phong
 
| SGeode Geometry
 
| SSwitch Int
 
| STransform Matrix
 
| SLight
 
| SCamera
 
| SCompiled (Maybe DisplayList)
 
| SPrimitive (IO ())
 
 
</pre></code>
 
</pre></code>
   
  +
To scale the cube we use the 'scale' function. This takes a vector indicating by how much to scale in X,Y and Z directions:
'''SGroup''' - Supports grouping of nodes. Since the Graph will provide the links to children we don't need to have anything more.
 
   
  +
<code><pre>
'''SMaterial''' - Sets the material for the tree starting at this node. Currently just Phong is shown.
 
  +
cube 0.5 `colour` Green `scale` v1x 40
  +
</pre></code>
   
  +
v1x is a function that given a number n, returns the vector (n,1,1). This contributes to a concise specification of the scene.So here the cube is scale by 40 in the X direction.
'''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.
 
   
  +
To translate the scene we use a similar function to scale:
'''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.
 
   
  +
<code><pre>
'''STransform''' - Introduces a transform (translate, scale or rotate).
 
  +
cube 0.5 `colour` Green `scale` v1x 40 `translate` vy 2
  +
</pre></code>
   
  +
Finally our scene requires a camera and light to be specified:
'''SLight''' - Specifies a light at the origin with various properties.
 
   
  +
<code><pre>
'''SCamera''' - Specifies a camera .
 
  +
cube 0.5 `colour` Green `scale` v1x 40 `translate` vy 2 <+> camera `translate` vy (-10) <+> light `translate` vz 10
  +
</pre></code>
  +
  +
In order to run the scene we use runScene. As the above scene has been constructed in a monad, we need to run the monad, to extract the actual Scene data structure.
  +
  +
<code><pre>
  +
runScene $ osgt $ cube 0.5 `colour` Green `scale` v1x 40 `translate` vy 2 <+> camera `translate` vy (-10) <+> light `translate` vz 10
  +
</pre></code>
  +
  +
To navigate the scene use the following:
  +
  +
* W - Move forward
  +
* S - Move back
  +
* A - Move left
  +
* D - Move right
  +
* Z - Move down
  +
* X - Move up
  +
* ESC - Exit
  +
  +
== Reactive Scenes ==
  +
  +
The module Graphics.SceneGraph.Reactive uses [[Reactive]] to enliven a scene. ExampleReactive.hs provides an example of this.This uses a calculator defined independantly of the GUI and is made tangible by SceneGraph.
  +
  +
<code><pre>
  +
calc = runSceneReactive calculator sceneButtonReactive
  +
</pre></code>
  +
  +
calculator is the Scene representing the calculator. The button and display objects are labelled to allow event hanlders to be applied during a second pass.
  +
  +
sceneButtonReactive is where the second pass is performed and this wires up the calculator.
  +
  +
== Internals ==
  +
The Scene Graph is built using [http://web.engr.oregonstate.edu/~erwig/fgl/haskell FGL]. So it remains to define a scene node to get things started:
  +
  +
<code><pre>
  +
data SceneData = Group
  +
| Geode Geometry
  +
| LOD
  +
| MatrixTransform (MatrixD)
  +
| Switch Int
  +
| Material Phong
  +
| Handler (Maybe (ClickHandler, Sink ())) (Maybe (DragHandler, Sink GLdouble))
  +
| Light
  +
| Camera
  +
| Texture String
  +
| Text String
  +
</pre></code>
  +
  +
'''Group''' - Supports grouping of nodes. Since the Graph will provide the links to children we don't need to have anything more.
  +
  +
'''Geode''' - 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.
  +
  +
'''LOD''' - Level of detail. Children of this would be representations of the same sub-scene at different level of detail. Choice of which child which depend on current viewing scale. (Currently not implemented).
  +
  +
'''MatrixTransform''' - Transform node.
  +
  +
'''Switch''' - Provides the ability to choose the sub-tree based on the integer value. One application of this is to provide a representation to be drawn when the object is selected. Some implementations suggest using a bit map across all the children.
  +
  +
'''Material''' - Sets the material for the tree starting at this node. Currently just Phong is shown.
  +
  +
'''Handler''' - Some form of event handler can be specified at this node. Two types are available - ClickHandler to handle mouse clicks on the object, and DragHandler to handle drag events on the object.
  +
  +
'''Light''' - Specifies a light at the origin.
  +
  +
'''Camera''' - Specifies a camera at the origin.
   
  +
'''Texture'''- Named texture is applied to the sub-tree.
'''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.
 
   
  +
'''Text''' - Text object.
'''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.
+
Note that the scene is defined as a graph but when the monad is run a tree is created.
   
 
== Scene Graph Monad ==
 
== Scene Graph Monad ==
Line 82: Line 141:
 
</pre></code>
 
</pre></code>
   
The Monad can be run to extract the actual scene graph and then sent off for viewing...
+
The Monad can be run to extract the actual scene graph and then sent off for viewing.
 
== Viewer ==
 
Include view with basic navigation mechanisms. Use can switch between them; example interaction models are:
 
 
* Orbital.
 
* 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'.
 
   
  +
== Limitations ==
Can either have multiple viewports, one per camera and/or press number keys to get different camera.
 
   
  +
Currently, system is very fickle about light and camera. These need to be specified and need to be translated immediately.
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.
 
   
== Events ==
+
== Further Work ==
  +
Build an extended example that uses the library. A puzzle game of some sort.
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.
 
   
  +
Texture loading requires program to be run in root directory of package.
== COLLADA ==
 
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.
 

Revision as of 00:55, 1 June 2008

Introduction

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.

Current Status: Initial 0.1 version is available on Hackage

The library draws inspiration from the following Haskell projects:

and from the following non-Haskell work:

Getting Started

A scene is constructed using a set of combinators. The following creates a green cube

cube 0.5 `colour` Green

To scale the cube we use the 'scale' function. This takes a vector indicating by how much to scale in X,Y and Z directions:

cube 0.5 `colour` Green `scale` v1x 40

v1x is a function that given a number n, returns the vector (n,1,1). This contributes to a concise specification of the scene.So here the cube is scale by 40 in the X direction.

To translate the scene we use a similar function to scale:

cube 0.5 `colour` Green `scale` v1x 40 `translate` vy 2

Finally our scene requires a camera and light to be specified:

cube 0.5 `colour` Green `scale` v1x 40 `translate` vy 2 <+> camera `translate` vy (-10) <+> light `translate` vz 10

In order to run the scene we use runScene. As the above scene has been constructed in a monad, we need to run the monad, to extract the actual Scene data structure.

runScene $ osgt $ cube 0.5 `colour` Green `scale` v1x 40 `translate` vy 2 <+> camera `translate` vy (-10) <+> light `translate` vz 10 

To navigate the scene use the following:

  • W - Move forward
  • S - Move back
  • A - Move left
  • D - Move right
  • Z - Move down
  • X - Move up
  • ESC - Exit

Reactive Scenes

The module Graphics.SceneGraph.Reactive uses Reactive to enliven a scene. ExampleReactive.hs provides an example of this.This uses a calculator defined independantly of the GUI and is made tangible by SceneGraph.

calc = runSceneReactive calculator sceneButtonReactive

calculator is the Scene representing the calculator. The button and display objects are labelled to allow event hanlders to be applied during a second pass.

sceneButtonReactive is where the second pass is performed and this wires up the calculator.

Internals

The Scene Graph is built using FGL. So it remains to define a scene node to get things started:

data SceneData  = Group 
                | Geode Geometry 
                | LOD 
                | MatrixTransform (MatrixD)
                | Switch Int
                | Material Phong
                | Handler (Maybe (ClickHandler, Sink ())) (Maybe (DragHandler, Sink GLdouble))
                | Light
                | Camera
                | Texture String
                | Text String

Group - Supports grouping of nodes. Since the Graph will provide the links to children we don't need to have anything more.

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

LOD - Level of detail. Children of this would be representations of the same sub-scene at different level of detail. Choice of which child which depend on current viewing scale. (Currently not implemented).

MatrixTransform - Transform node.

Switch - Provides the ability to choose the sub-tree based on the integer value. One application of this is to provide a representation to be drawn when the object is selected. Some implementations suggest using a bit map across all the children.

Material - Sets the material for the tree starting at this node. Currently just Phong is shown.

Handler - Some form of event handler can be specified at this node. Two types are available - ClickHandler to handle mouse clicks on the object, and DragHandler to handle drag events on the object.

Light - Specifies a light at the origin.

Camera - Specifies a camera at the origin.

Texture- Named texture is applied to the sub-tree.

Text - Text object.

Note that the scene is defined as a graph but when the monad is run a tree is created.

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.

Limitations

Currently, system is very fickle about light and camera. These need to be specified and need to be translated immediately.

Further Work

Build an extended example that uses the library. A puzzle game of some sort.

Texture loading requires program to be run in root directory of package.