# FieldTrip

### From HaskellWiki

m (→FieldTrip meets Reactive: making the torus animation) |
m (→Basic types: formatting) |
||

(24 intermediate revisions by 10 users not shown) | |||

Line 1: | Line 1: | ||

− | [[Category:Graphics]] |
+ | [[Category:Graphics]] |

+ | [[Category:3D]] |
||

[[Category:Packages]] |
[[Category:Packages]] |
||

== Abstract == |
== Abstract == |
||

− | [[Image:Torus-pair-d-shadowed.png|right|thumb|300px|Torus pair modeled and rendered in FieldTrip]] |
||

− | '''FieldTrip''' is a library for functional 3D graphics, intended for building static, animated, and interactive 3D geometry, efficient enough for real-time synthesis and display. |
+ | [[Image:Torus-pair-d-shadowed.png|right|thumb|300px|Torus pair modeled and rendered in FieldTrip]] |

+ | '''FieldTrip''' is a library for functional 3D graphics, intended for building static, animated, and interactive 3D geometry, efficient |
||

+ | enough for real-time synthesis and display. |
||

Our first renderer uses OpenGL, with the usual visual limitations. |
Our first renderer uses OpenGL, with the usual visual limitations. |
||

Since FieldTrip is functional, it is about ''being'' rather than ''doing''. |
Since FieldTrip is functional, it is about ''being'' rather than ''doing''. |
||

One describes what models are, not how to render them. |
One describes what models are, not how to render them. |
||

+ | |||

+ | FieldTrip is work-in-progress. |
||

+ | It's being released to show what's going on and see who's interested in collaborating on developing it further. |
||

Besides this wiki page, here are more ways to find out about and get involved with FieldTrip: |
Besides this wiki page, here are more ways to find out about and get involved with FieldTrip: |
||

* Join the [http://www.haskell.org/mailman/listinfo/FieldTrip FieldTrip mailing list]. |
* Join the [http://www.haskell.org/mailman/listinfo/FieldTrip FieldTrip mailing list]. |
||

− | * Peruse [http://code.haskell.org/FieldTrip/doc/html/ the library documentation]. |
+ | * Visit the [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/FieldTrip Hackage page] for library documentation and to download & install. |

− | * Install [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/FieldTrip from Hackage]. |
+ | * Or install with <tt>cabal install FieldTrip</tt>. See [[#Installation dependencies|Installation dependencies]] below. |

− | * Download the code repository: '''<tt>darcs get http://code.haskell.org/FieldTrip</tt>'''. Patches welcome. |
+ | * Get the code repository: <tt>darcs get http://code.haskell.org/FieldTrip</tt> |

− | * Report bugs and request features on [http://trac.haskell.org/fieldtrip/ the tracker]. |
+ | <!-- * See the [[FieldTrip/Versions| version history]]. --> |

− | * Examine the [[FieldTrip/Versions| version history]]. |
+ | * Report bugs and request features on [http://trac.haskell.org/FieldTrip/ the tracker]. |

== Basic types == |
== Basic types == |
||

− | The basic purpose of the core FieldTrip library is to allow a user build 3D geometry, from individual simple shapes to full 3D scenes. The principal types are as follows. |
+ | The basic purpose of the core FieldTrip library is to allow a user build 3D geometry, from individual simple shapes to full 3D scenes. |

+ | The principal types are as follows. |
||

; <hask>Geometry3</hask> |
; <hask>Geometry3</hask> |
||

Line 26: | Line 28: | ||

; <hask>Surf a = (a,a) -> (a,a,a)</hask> |
; <hask>Surf a = (a,a) -> (a,a,a)</hask> |
||

− | : Parametric surfaces, i.e., mappings from 2D to 3D. Normals are constructed automatically and exactly via derivatives, thanks to the [[vector-space]] library. These normals are used for shading. For simplicity and composability, ''surfaces are curved'', not faceted. Surface ''rendering'' tessellates adaptively, caching tessellations in an efficient, infinite data structure for reuse. The mechanism for choosing tessellation is a very primitive placeholder. FieldTrip provides some basic shapes of surfaces (spheres, torus, cubes, etc) and many functions for manipulating surfaces, colors, etc. |
+ | : Parametric surfaces, i.e., mappings from 2D to 3D. Normals are constructed automatically and exactly via derivatives, thanks to the [[vector-space]] library. These normals are used for shading. For simplicity and composability, ''surfaces are curved'', not faceted. |

+ | : Surface ''rendering'' tessellates adaptively, caching tessellations in an efficient, infinite data structure for reuse. The mechanism for choosing tessellation is a very primitive placeholder. FieldTrip provides some basic shapes of surfaces (spheres, torus, cubes, etc) and many functions for manipulating surfaces, colors, etc. |
||

; <hask>Geometry2</hask> |
; <hask>Geometry2</hask> |
||

Line 32: | Line 34: | ||

; <hask>Image o = (R,R) -> o</hask> |
; <hask>Image o = (R,R) -> o</hask> |
||

− | : A primitive placeholder for functional imagery in the spirit of [http://conal.net/Pan Pan]. The intention is to use this type or something like it for texture mapping. Much design and implementation work to be done. |
+ | : A primitive placeholder for functional imagery in the spirit of [http://conal.net/Pan Pan]. The intention is to use this type or |

+ | something like it for texture mapping. Much design and implementation work to be done. |
||

− | == FieldTrip meets Reactive == |
+ | == Example == |

− | FieldTrip contains no support for animation, because we intend it to be used with the [[Reactive]] functional reactive programming ([[FRP]]) library (and possibly other animation frameworks). |
+ | The code for the static torus pair shown above: |

− | By design, FieldTrip is completely orthogonal to any formulation or implementation of FRP. |
||

− | |||

− | The [[reactive-fieldtrip]] project connects [[Reactive]] and FieldTrip. |
||

− | To picture above comes from an animation in [[reactive-fieldtrip]]. |
||

− | Load src/Test.hs into ghci, and type |
||

− | <haskell> |
||

− | anim3 (spinningG torusPair) |
||

− | </haskell> |
||

− | |||

− | The code for the static torus pair: |
||

<haskell> |
<haskell> |
||

torusPair :: Geometry3 |
torusPair :: Geometry3 |
||

Line 43: | Line 45: | ||

tor = torus 1 (2/5) |
tor = torus 1 (2/5) |
||

f :: Col -> R -> Geometry3 |
f :: Col -> R -> Geometry3 |
||

− | f col dx = plasmat col (move3X dx tor) |
+ | f col dx = materialG (plastic col) (move3X dx tor) |

</haskell> |
</haskell> |
||

− | where <hask>pivot3X</hask> and <hask>move3X</hask> are simple helper functions for 3D transformation, and <hask>plasmat</hask> applies a color with a plastic look (defined in <code>Test.hs</code>. |
+ | where <hask>pivot3X</hask> and <hask>move3X</hask> are simple helper short-hands for 3D transformation. |

+ | |||

+ | The <code>[http://hackage.haskell.org/packages/archive/FieldTrip/0.2.2/doc/html/Graphics-FieldTrip-Geometry3.html#v%3Atorus torus]</code> function used here is a |
||

+ | simple wrapper around a parametric surface defined as follows: |
||

+ | <haskell> |
||

+ | -- | Torus, given radius of sweep circle and cross section |
||

+ | torus :: (Floating s, VectorSpace s, Scalar s ~ s) => s -> s -> Surf s |
||

+ | torus sr cr = revolve (const (sr,0) ^+^ cr *^ circle) |
||

+ | </haskell> |
||

+ | where <hask>revolve</hask> and <hask>circle</hask> are defined in |
||

+ | [http://hackage.haskell.org/packages/archive/FieldTrip/latest/doc/html/Graphics-FieldTrip-ParamSurf.html Graphics.FieldTrip.ParamSurf], along with other tools for shape generation. |
||

+ | |||

+ | The trick to turning this polymorphic <hask>torus</hask> function into a <hask>Geometry3</hask> is to use a derivative tower (from |
||

+ | [[vector-space]]) for the type parameter <hask>s</hask>. |
||

+ | <haskell> |
||

+ | surfG :: Surf (Vector2 R :> R) -> Geometry3 |
||

+ | |||

+ | torus :: R -> R -> Geometry3 |
||

+ | torus sr cr = surfG (P.torus (pureD sr) (pureD cr)) |
||

+ | </haskell> |
||

+ | |||

+ | ''[fill in more examples]'' |
||

+ | |||

+ | == FieldTrip meets Reactive == |
||

+ | |||

+ | FieldTrip contains no support for animation, because we intend it to be used with the [[Reactive]] functional reactive programming |
||

+ | ([[FRP]]) library (and possibly other animation frameworks). |
||

+ | By design, FieldTrip is completely orthogonal to any formulation or implementation of FRP. |
||

+ | |||

+ | The [[reactive-fieldtrip]] project connects [[Reactive]] and FieldTrip. |
||

+ | |||

+ | The picture above comes from an animation in [[reactive-fieldtrip]]. |
||

+ | Load <code>src/Test.hs</code>, as follows: |
||

+ | <pre> |
||

+ | ~/Haskell$ cd reactive-fieldtrip/src |
||

+ | ~/Haskell/reactive-fieldtrip/src$ ghci |
||

+ | GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help |
||

+ | Loading package ghc-prim ... linking ... done. |
||

+ | Loading package integer ... linking ... done. |
||

+ | Loading package base ... linking ... done. |
||

+ | Prelude> :l Test |
||

+ | :l Test |
||

+ | [1 of 2] Compiling FRP.Reactive.FieldTrip.Adapter ( FRP/Reactive/FieldTrip/Adapter.hs, interpreted ) |
||

+ | [2 of 2] Compiling Test ( Test.hs, interpreted ) |
||

+ | Ok, modules loaded: FRP.Reactive.FieldTrip.Adapter, Test. |
||

+ | </pre> |
||

+ | Then run the example: |
||

+ | <pre> |
||

+ | *Test> anim3 (const (spinningG torusPair)) |
||

+ | Loading package OpenGL-2.2.1.1 ... linking ... done. |
||

+ | Loading package syb ... linking ... done. |
||

+ | Loading package base-3.0.3.0 ... linking ... done. |
||

+ | [...] |
||

+ | Loading package reactive-0.9.0 ... linking ... done. |
||

+ | Loading package FieldTrip-0.2.2 ... linking ... done. |
||

+ | Loading package reactive-glut-0.0.5 ... linking ... done. |
||

+ | </pre> |
||

+ | |||

+ | == Some videos == |
||

+ | |||

+ | * [http://www.youtube.com/watch?v=ulPsJzUCQi8 Texture-mapped Earth.] |
||

+ | * [http://www.youtube.com/watch?v=WNB5V9Z7Obc The torus demo running in GHCi.] |
||

+ | |||

+ | == Problems and solutions == |
||

+ | |||

+ | === Installation dependencies === |
||

+ | |||

+ | ==== Haskell packages ==== |
||

+ | |||

+ | You'll need the OpenGL and GLUT packages. If you are using synaptics/apt-get, those are called libghc6-opengl-dev and libghc6-glut-dev. If you're using cabal-install, it will take care of the dependencies for you (see "Non-Haskell libraries" below though). |
||

+ | |||

+ | ==== Non-Haskell libraries ==== |
||

+ | |||

+ | Make sure that you have the opengl-dev and glut-dev libraries installed. If you don't have them, there are two ways to fail: Either on the installation of the corresponding Haskell libraries, like this: |
||

+ | |||

+ | <pre> |
||

+ | configure: error: no GLUT header found, so this package cannot be built |
||

+ | See `config.log' for more details. |
||

+ | cabal: Error: some packages failed to install: |
||

+ | GLUT-2.1.1.2 failed during the configure step. The exception was: |
||

+ | exit: ExitFailure 1 |
||

+ | </pre> |
||

+ | |||

+ | Or, if you do have the Haskell packages and C libraries, but accidentally removed the opengl-dev and glut-dev libraries, you can end up with FieldTrip just producing black windows. |
||

+ | |||

+ | ===== Linking problems on Debian Lenny ===== |
||

+ | |||

+ | You may experience linker problems on Debian Lenny. Running: |
||

+ | |||

+ | > ghc --make -main-is Test Test.hs |
||

+ | |||

+ | can give you: |
||

+ | |||

+ | <pre> |
||

+ | Linking Test ... |
||

+ | /home/ghc/.cabal/lib/reactive-glut-0.1.6/ghc-6.10.1/libHSreactive-glut-0.1.6.a(SimpleGL.o): In function `s5SW_info': |
||

+ | (.text+0x1654): undefined reference to `glutInitDisplayMode' |
||

+ | /home/ghc/.cabal/lib/reactive-glut-0.1.6/ghc-6.10.1/libHSreactive-glut-0.1.6.a(SimpleGL.o): In function `s5SW_info': |
||

+ | (.text+0x1668): undefined reference to `glutInitWindowSize' |
||

+ | ... |
||

+ | </pre> |
||

+ | |||

+ | This is a HOpenGL problem and has already been [http://www.haskell.org/pipermail/haskell-cafe/2008-September/047357.html reported here] and a [http://www.haskell.org/pipermail/haskell-cafe/2008-September/047815.html solution here]. To make a long story short, you need to explicitly link with glut when compiling: |
||

+ | |||

+ | > ghc --make -lglut -main-is Test Test.hs |

## Latest revision as of 19:45, 3 July 2009

## Contents |

## [edit] 1 Abstract

**FieldTrip** is a library for functional 3D graphics, intended for building static, animated, and interactive 3D geometry, efficient
enough for real-time synthesis and display.
Our first renderer uses OpenGL, with the usual visual limitations.
Since FieldTrip is functional, it is about *being* rather than *doing*.
One describes what models are, not how to render them.

FieldTrip is work-in-progress. It's being released to show what's going on and see who's interested in collaborating on developing it further.

Besides this wiki page, here are more ways to find out about and get involved with FieldTrip:

- Join the FieldTrip mailing list.
- Visit the Hackage page for library documentation and to download & install.
- Or install with
`cabal install FieldTrip`. See Installation dependencies below. - Get the code repository:
`darcs get http://code.haskell.org/FieldTrip` - Report bugs and request features on the tracker.

## [edit] 2 Basic types

The basic purpose of the core FieldTrip library is to allow a user build 3D geometry, from individual simple shapes to full 3D scenes. The principal types are as follows.

- Geometry3
- 3D geometry. These values can be spatially transformed in space (affinely: scale, rotate, translate) and combined (union).

- Surf a = (a,a) -> (a,a,a)
- Parametric surfaces, i.e., mappings from 2D to 3D. Normals are constructed automatically and exactly via derivatives, thanks to the vector-space library. These normals are used for shading. For simplicity and composability,
*surfaces are curved*, not faceted. - Surface
*rendering*tessellates adaptively, caching tessellations in an efficient, infinite data structure for reuse. The mechanism for choosing tessellation is a very primitive placeholder. FieldTrip provides some basic shapes of surfaces (spheres, torus, cubes, etc) and many functions for manipulating surfaces, colors, etc.

- Geometry2
- 2D geometry. There's a function () to embed 2D into 3D.flatG

- Image o = (R,R) -> o
- A primitive placeholder for functional imagery in the spirit of Pan. The intention is to use this type or

something like it for texture mapping. Much design and implementation work to be done.

## [edit] 3 Example

The code for the static torus pair shown above:

torusPair :: Geometry3 torusPair = f red (1/2) `mappend` pivot3X (f green (-1/2)) where tor = torus 1 (2/5) f :: Col -> R -> Geometry3 f col dx = materialG (plastic col) (move3X dx tor)

The `torus`

function used here is a
simple wrapper around a parametric surface defined as follows:

-- | Torus, given radius of sweep circle and cross section torus :: (Floating s, VectorSpace s, Scalar s ~ s) => s -> s -> Surf s torus sr cr = revolve (const (sr,0) ^+^ cr *^ circle)

Graphics.FieldTrip.ParamSurf, along with other tools for shape generation.

The trick to turning this polymorphicsurfG :: Surf (Vector2 R :> R) -> Geometry3 torus :: R -> R -> Geometry3 torus sr cr = surfG (P.torus (pureD sr) (pureD cr))

*[fill in more examples]*

## [edit] 4 FieldTrip meets Reactive

FieldTrip contains no support for animation, because we intend it to be used with the Reactive functional reactive programming (FRP) library (and possibly other animation frameworks). By design, FieldTrip is completely orthogonal to any formulation or implementation of FRP.

The reactive-fieldtrip project connects Reactive and FieldTrip.

The picture above comes from an animation in reactive-fieldtrip.
Load `src/Test.hs`

, as follows:

~/Haskell$ cd reactive-fieldtrip/src ~/Haskell/reactive-fieldtrip/src$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> :l Test :l Test [1 of 2] Compiling FRP.Reactive.FieldTrip.Adapter ( FRP/Reactive/FieldTrip/Adapter.hs, interpreted ) [2 of 2] Compiling Test ( Test.hs, interpreted ) Ok, modules loaded: FRP.Reactive.FieldTrip.Adapter, Test.

Then run the example:

*Test> anim3 (const (spinningG torusPair)) Loading package OpenGL-2.2.1.1 ... linking ... done. Loading package syb ... linking ... done. Loading package base-3.0.3.0 ... linking ... done. [...] Loading package reactive-0.9.0 ... linking ... done. Loading package FieldTrip-0.2.2 ... linking ... done. Loading package reactive-glut-0.0.5 ... linking ... done.

## [edit] 5 Some videos

## [edit] 6 Problems and solutions

### [edit] 6.1 Installation dependencies

#### [edit] 6.1.1 Haskell packages

You'll need the OpenGL and GLUT packages. If you are using synaptics/apt-get, those are called libghc6-opengl-dev and libghc6-glut-dev. If you're using cabal-install, it will take care of the dependencies for you (see "Non-Haskell libraries" below though).

#### [edit] 6.1.2 Non-Haskell libraries

Make sure that you have the opengl-dev and glut-dev libraries installed. If you don't have them, there are two ways to fail: Either on the installation of the corresponding Haskell libraries, like this:

configure: error: no GLUT header found, so this package cannot be built See `config.log' for more details. cabal: Error: some packages failed to install: GLUT-2.1.1.2 failed during the configure step. The exception was: exit: ExitFailure 1

Or, if you do have the Haskell packages and C libraries, but accidentally removed the opengl-dev and glut-dev libraries, you can end up with FieldTrip just producing black windows.

##### [edit] 6.1.2.1 Linking problems on Debian Lenny

You may experience linker problems on Debian Lenny. Running:

> ghc --make -main-is Test Test.hs

can give you:

Linking Test ... /home/ghc/.cabal/lib/reactive-glut-0.1.6/ghc-6.10.1/libHSreactive-glut-0.1.6.a(SimpleGL.o): In function `s5SW_info': (.text+0x1654): undefined reference to `glutInitDisplayMode' /home/ghc/.cabal/lib/reactive-glut-0.1.6/ghc-6.10.1/libHSreactive-glut-0.1.6.a(SimpleGL.o): In function `s5SW_info': (.text+0x1668): undefined reference to `glutInitWindowSize' ...

This is a HOpenGL problem and has already been reported here and a solution here. To make a long story short, you need to explicitly link with glut when compiling:

> ghc --make -lglut -main-is Test Test.hs