diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,11 @@
+Copyright (c) 2010, Tillmann Vogt
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+The names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+import Distribution.Simple
+main = defaultMain
diff --git a/collada-types.cabal b/collada-types.cabal
new file mode 100644
--- /dev/null
+++ b/collada-types.cabal
@@ -0,0 +1,23 @@
+Name:               collada-types
+Version:            0.1
+Synopsis:           data exchange between graphic applications
+Description:        Collada is the standard graphics format for data exchange between 3d Tools. As well as the file format also its represenation as an algebraic data type could be used to make libraries more composable. Please propose changes.
+category:           graphics
+License:            BSD3
+License-file:       LICENSE
+Author:             Tillmann Vogt
+Maintainer:         Tillmann.Vogt@rwth-aachen.de
+Build-Type:         Simple
+Cabal-Version:    >=1.6
+
+Library
+    hs-source-dirs: src
+    build-depends:
+        base ==4.*,
+        containers == 0.4.*,
+        enumerable,
+        tuple-gen
+    exposed-modules:
+        Graphics.Formats.Collada.ColladaTypes
+        Graphics.Formats.Collada.GenerateObjects
+        Graphics.Formats.Collada.Transformations
diff --git a/src/Graphics/Formats/Collada/ColladaTypes.hs b/src/Graphics/Formats/Collada/ColladaTypes.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Formats/Collada/ColladaTypes.hs
@@ -0,0 +1,282 @@
+-- some of the Types are from http://hackage.haskell.org/package/GPipe-Collada
+-- adopted for possible future combination
+
+module Graphics.Formats.Collada.ColladaTypes
+(
+    Scene,
+    SceneNode(..), NodeType(..),
+    Transform(..),
+    Camera(..),
+    ViewSize(..),
+    Z(..),
+    
+    Light(..),
+    Attenuation(..),
+    Controller(..),
+    
+    Geometry(..),
+    Mesh(..),
+    Vertices(..),
+    LinePrimitive(..), Polygon(..),
+	-- Polylist(..), Spline(..), TriangleMesh(..), TriFan(..), TriStrip(..),
+    AnimChannel(..),
+    ID, SID,
+    Semantic,
+    Profile(..), NewParam(..), TechniqueCommon(..), Material, Effect,
+    C(..), Color(..),
+    Animation(..),
+    Fx_common_color_type(..), Fx_common_texture_type(..), Texture(..),
+	Interpolation(..)
+)
+where
+
+import Data.Tree
+type Vec3 = (Float,Float,Float)
+type Mat44 = ((Float,Float,Float,Float),
+              (Float,Float,Float,Float),
+			  (Float,Float,Float,Float),
+			  (Float,Float,Float,Float))
+
+type Scene = Tree SceneNode
+
+data SceneNode = SceneNode {
+                nodeId :: ID,
+                nodeType :: NodeType,
+                nodeLayers :: [String],
+                nodeTransformations :: [(SID, Transform)],
+                nodeCameras :: [Camera],
+                nodeController :: [Controller],
+                nodeGeometries :: [Geometry],
+                nodeLights :: [Light]
+              } | EmptyRoot
+              deriving (Show, Eq)
+
+
+data NodeType = JOINT | NODE | NOTYPE deriving (Show, Eq)
+
+data Transform = LookAt {
+                    lookAtEye:: Vec3,
+                    lookAtInterest :: Vec3,
+                    lookAtUp :: Vec3
+                 }
+               | Matrix Mat44
+               | Rotate Vec3 Float Vec3 Float Vec3 Float
+               | Scale Vec3
+               | Skew {
+                    skewAngle :: Float,
+                    skewRotation :: Vec3,
+                    skewTranslation :: Vec3
+                 }
+               | Translate Vec3
+               deriving (Show, Eq)
+
+data Camera = Perspective {
+                perspectiveID :: ID,
+                perspectiveFov :: ViewSize,
+                perspectiveZ :: Z
+              }
+            | Orthographic {
+                orthographicID :: ID,
+                orthographicViewSize :: ViewSize,
+                orthographicZ :: Z
+              }
+              deriving (Show, Eq)
+
+data ViewSize = ViewSizeX Float
+              | ViewSizeY Float
+              | ViewSizeXY (Float,Float)
+              deriving (Show, Eq)
+
+data Z = Z { 
+            zNear :: Float, 
+            zFar :: Float
+           }
+           deriving (Show, Eq)
+
+data Light = Ambient {
+                ambientID :: ID,
+                ambientColor :: Color
+             }
+           | Directional {
+                directionalID :: ID,
+                directionalColor :: Color
+             }
+           | Point {
+                pointID :: ID,
+                pointColor :: Color,
+                pointAttenuation :: Attenuation
+             }
+           | Spot {
+                spotID :: ID,
+                spotColor :: Color,
+                spotAttenuation :: Attenuation,
+                spotFallOffAngle :: Float,
+                spotFallOffExponent :: Float
+             }
+              deriving (Show, Eq)
+
+data Attenuation = Attenuation {
+                attenuationConstant :: Float,
+                attenuationLinear :: Float,
+                attenuationQuadratic :: Float
+            }
+              deriving (Show, Eq)
+
+data Controller = Controller {
+                contrId :: ID,
+                skin :: [Skin],
+                morph :: [Morph]
+            }
+              deriving (Show, Eq)
+
+data Skin = Skin {
+                bindShapeMatrix :: [Mat44],
+                source :: [String],
+                joint :: [Joint],
+                vertexWeights :: String
+            }
+              deriving (Show, Eq)
+
+data Morph = Morph {
+                geometrySource :: String,
+                method :: MorphMethod,
+                morphSource :: String,
+                morphTargets :: [Input]
+            }
+              deriving (Show, Eq)
+
+data MorphMethod = Normalized | Relative deriving (Show, Eq)
+
+data Joint = Joint {
+                jointID :: String,
+                prismatic :: Prismatic,
+                revolute :: Revolute
+            }
+              deriving (Show, Eq)
+
+type Prismatic = String
+type Revolute = String
+
+data Input = Input {
+                offset :: Int,
+                semantic :: Semantic,
+                inputSource :: String,
+                set :: Int
+            }
+              deriving (Show, Eq)
+
+data Semantic = BINORMAL | COLOR | CONTINUITY | IMAGE | INPUT | IN_TANGENT | INTERPOLATION |
+                INV_BIND_MATRIX | ISJOINT | LINEAR_STEPS | MORPH_TARGET | MORPH_WEIGHT |
+                NORMAL | OUTPUT | OUT_TANGENT | POSITION | TANGENT | TEXBINORMAL |
+                TEXCOORD | TEXTANGENT | UV | VERTEX | WEIGHT
+                deriving (Show, Eq)
+
+data Geometry = Geometry {
+                meshID :: ID,
+                mesh :: [Mesh],
+                vertices :: Vertices
+--                convexMesh :: [Mesh],
+--                splines :: [Spline],
+--                breps :: [Brep]
+            }
+            deriving (Show)
+
+instance Eq Geometry where
+  (Geometry mid1 _ _) == (Geometry mid2 _ _) = mid1 == mid2
+
+data Mesh = LP LinePrimitive | -- ^Lines
+            LS LinePrimitive | -- ^LineStrips
+            P Polygon | -- ^Polygon: Contains polygon primitives which may contain holes.
+            PL LinePrimitive | -- ^PolyList: Contains polygon primitives that cannot contain holes.
+            Tr LinePrimitive | -- ^Triangles
+            Trf LinePrimitive | -- ^TriFans
+            Trs LinePrimitive | -- ^TriStrips
+            S LinePrimitive -- ^Splines
+            deriving (Show, Eq)
+
+data Vertices = Vertices {
+                  name :: ID,
+                  verts :: [(Float,Float,Float)],
+                  normals :: [(Float,Float,Float)]
+            }
+            deriving (Show, Eq)
+
+data LinePrimitive = LinePrimitive {
+                lineP :: [[Int]], -- point indices
+                lineN :: [[Int]], -- normal indices
+                lineT :: [[Int]], -- texture indices
+                ms :: [Material]
+            }
+            deriving (Show, Eq)
+
+data Polygon = Polygon {
+                poylgonP :: [[Int]],
+                poylgonN :: [[Int]],
+                polygonPh :: ([Int],[Int]), -- (indices, indices of a hole)
+                polygonMs :: [Material]
+            }
+            deriving (Show, Eq)
+
+type Material = (SID,Effect)
+
+type Effect = Profile
+
+type Animation = Tree (SID, AnimChannel)
+
+data AnimChannel = AnimChannel {
+                     input :: (ID,[Float],Accessor) , -- Accessor: i.e. "TIME"
+                     output :: (ID,[Float],Accessor),
+                     interp :: [Interpolation],
+                     -- target channels in Collada
+                     targets :: [(TargetID,AccessorName)] -- transfer values to several objects
+                   } | EmptyAnim
+                   deriving (Show, Eq)
+
+data Interpolation = Step | Linear | Bezier [Float] [Float] deriving (Show, Eq)
+
+type TargetID = String
+type Accessor = [[(AccessorName, AccessorType)]]
+type AccessorName = String
+type AccessorType = String
+
+data Profile = BRIDGE Asset Extra |
+               CG Asset Code Include NewParam TechniqueCG Extra |
+               COMMON Asset NewParam TechniqueCommon String |
+               GLES Asset NewParam TechniqueCG Extra |
+               GLES2 Asset Code Include NewParam TechniqueCG Extra |
+               GLSL Asset Code Include NewParam TechniqueCG Extra
+			   deriving (Show, Eq)
+
+type Asset = String
+type Code = String
+type Include = String
+data NewParam = Annotat | Semantic | Modifier | NoParam deriving (Show, Eq)
+data TechniqueCommon = Constant | LambertCol [Fx_common_color_type]
+                                | LambertTex [Fx_common_texture_type] [[Float]]
+                                | PhongCol [Fx_common_color_type]
+                                | PhongTex [Fx_common_texture_type] [[Float]]
+                                | Blinn
+                                deriving (Show, Eq)
+data TechniqueCG = IsAsset | IsAnnotate | Pass | Extra deriving (Show, Eq)
+data Extra = String deriving (Show, Eq) -- Asset | Technique
+data Technique = Profile deriving (Show, Eq) -- XML -- | Xmlns Schema
+data Fx_common_color_type = CEmission C | CAmbient C | CDiffuse C | CSpecular C |
+                            CShininess Float | CReflective C | CReflectivity Float |
+                            CTransparent C | CTransparency Float | CIndex_of_refraction Float
+                            deriving (Show, Eq)
+data Fx_common_texture_type = TEmission Texture | TAmbient Texture | TDiffuse Texture | TSpecular Texture |
+                              TShininess Float | TReflective Texture | TReflectivity Float |
+                              TTransparent Texture | TTransparency Float | TIndex_of_refraction Float
+                              deriving (Show, Eq)
+data C = Color (Float, Float, Float, Float) deriving (Show, Eq)
+
+data Texture = Texture {
+                   imageSID :: ID,
+                   path :: String -- ToDo: better type, embedded images
+            }
+            deriving (Show, Eq)
+
+type ID = String
+type SID = String -- Maybe
+
+data Color = RGB Float Float Float deriving (Eq, Show)
diff --git a/src/Graphics/Formats/Collada/GenerateObjects.hs b/src/Graphics/Formats/Collada/GenerateObjects.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Formats/Collada/GenerateObjects.hs
@@ -0,0 +1,260 @@
+module Graphics.Formats.Collada.GenerateObjects
+where
+
+import Graphics.Formats.Collada.ColladaTypes
+import Data.Tree
+import Data.Tuple.Gen
+import Data.Enumerable
+import Data.Word
+
+animatedCube = (aScene, animation)
+
+-- | Example scene with a camera, lights and a cube
+aScene :: Scene
+aScene = Node EmptyRoot [ n aCamera,
+                          n (pointLight "pointLight" 3 4 10),
+                          n (pointLight "pointL" (-500) 1000 400),
+                          n aCube ]
+
+-- type Scene = Tree SceneNode
+
+n x = Node x []
+
+aCamera = SceneNode "camera0" NOTYPE []
+                       [("tran", Translate (1000,1000,2500)),
+                         ("rot", Rotate (1,0,0) (-22)
+                                        (0,1,0) 13
+                                        (0,0,1) 0)]
+                       -- [("lookat", LookAt (1000,1000,2500) (0,0,0) (0,1,0))]
+                       [(Perspective "Persp" (ViewSizeXY (37,37)) (Z 10 1000) )]
+                       [] [] []
+
+pointLight str x y z = SceneNode str NOTYPE []
+                         [("tran", Translate (x,y,z)),
+                          ("rot", Rotate (1,0,0) 0
+                                         (0,1,0) 0
+                                         (0,0,1) 0)]
+                         [] [] []
+                         [(Point "point" (RGB 1 1 1) (Attenuation 1 0 0) )]
+
+ambientLight = SceneNode "ambientLight" NOTYPE []
+                         [("tran", Translate ((-500),1000,400)),
+                          ("rot", Rotate (1,0,0) 0
+                                         (0,1,0) 0
+                                         (0,0,1) 0)]
+                         [] [] []
+                         [(Ambient "ambient" (RGB 1 1 1) )]
+
+aCube :: SceneNode
+aCube = SceneNode "cube_geometry" NOTYPE []
+                         [("tran", Translate (0,0,0)),
+                          ("rot", Rotate (1,0,0) 0
+                                         (0,1,0) 0
+                                         (0,0,1) 0) ]
+                         [] []
+                         [cube] -- geometries
+                         []
+
+obj :: String -> [Geometry] -> SceneNode
+obj name c = SceneNode name NOTYPE []
+                         [("tran", Translate (0,0,0)),
+                          ("rot", Rotate (1,0,0) 0
+                                         (0,1,0) 0
+                                         (0,0,1) 0)]
+                         [] []
+                         c -- geometries
+                         []
+
+-- | Example animation of the cube
+animation :: [Animation]
+animation = [Node ("cube_rotate", anim_channel) []]
+
+anim_channel = AnimChannel ("input", [0, 1, 2, 3], [[("name","TIME"), ("type","Float")]] )
+                           ("output",[0, 50, 100, 150], [[("name","ANGLE"), ("type","Float")]] )
+                           [ Bezier [-0.333333, 0] [2.5, 0], -- intangent outtangent
+                             Bezier [5,0] [7.916667, 0],
+                             Bezier [8.333333, 56] [9.166667, 56],
+                             Bezier [9.583333, 18.666666] [10.333333, -14.933331] ]
+                           [("cube_geometry/rotateY","ANGLE")]
+
+-- | A blue/textured cube
+cube :: Geometry
+cube = Geometry "cube"
+       [PL (LinePrimitive
+         [[0,2,3,1],[0,1,5,4],[6,7,3,2],[0,4,6,2],[3,7,5,1],[5,7,6,4]] -- indices to vertices
+         [[0,0,0,0],[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4],[5,5,5,5]] -- indices to normals
+         [] -- [[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3]] -- indices to texture coordinates, use an empty list when no texture
+         -- [logo]
+         [blue]
+       )]
+       (Vertices "cube_vertices"
+         [(-50,50,50), (50,50,50), (-50,-50,50), (50,-50,50), -- vertices
+          (-50,50,-50),(50,50,-50),(-50,-50,-50),(50,-50,-50)]
+         [(0,0,1), (0,1,0), (0,-1,0), (-1,0,0), (1,0,0), (0,0,-1)] -- normals
+       )
+
+blue = ("blue", COMMON "" NoParam
+               (PhongCol [(CEmission (Color (0,0,0,1))),
+                          (CAmbient  (Color (0,0,0,1))),
+                          (CDiffuse(Color (0.137255,0.403922,0.870588,1))),
+                          (CSpecular(Color (0.5,0.5,0.5,1))),
+                          (CShininess 16), 
+                          (CReflective (Color (0,0,0,1))),
+                          (CReflectivity 0.5),
+                          (CTransparent (Color (0,0,0,1))),
+                          (CTransparency 1),
+                          (CIndex_of_refraction 0)]
+               )
+               ""
+       )
+
+logo = ("haskell-logo", COMMON "" NoParam
+               (PhongTex [(TDiffuse tex)]
+			             [[0,0,1,0,1,1,0,1]] -- [u0,v0,u1,v1,..] -coordinates (Floats between 0 and 1) that point into the texture
+               )
+               ""
+       )
+
+tex = Texture "logo" "Haskell-Logo-Variation.png"
+
+polys :: [(Float,Float,Float)] -> [(Float,Float,Float)] -> [[Int]] -> [[Int]] -> [Geometry]
+polys p n pi ni = [Geometry "polygons"
+  [PL (LinePrimitive pi -- indices to vertices
+                     ni -- indices to normals
+                     [] -- no texure
+              [blue]
+         )]
+ (Vertices "polygons_vertices" p n)]
+
+
+lines :: [(Float,Float,Float)] -> [(Float,Float,Float)] -> [[Int]] -> [[Int]] -> [Geometry]
+lines p n pi ni = [Geometry "lines"
+  [LS (LinePrimitive pi -- indices to vertices
+                     ni -- indices to normals
+                     [] -- no texure
+              [blue]
+         )]
+ (Vertices "lines_vertices" p n)]
+
+
+trifans :: [(Float,Float,Float)] -> [(Float,Float,Float)] -> [[Int]] -> [[Int]] -> [Geometry]
+trifans p n pi ni = [Geometry "trifans"
+  [Trf (LinePrimitive pi -- indices to vertices
+                      ni -- indices to normals
+                      [] -- no texure
+              [blue]
+         )]
+ (Vertices "trifans_vertices" p n)]
+
+
+tristrips :: [(Float,Float,Float)] -> [(Float,Float,Float)] -> [[Int]] -> [[Int]] -> [Geometry]
+tristrips p n pi ni = [Geometry "tristrips"
+  [Trs (LinePrimitive pi -- indices to vertices
+                      ni -- indices to normals
+                      [] -- no texure
+              [blue]
+         )]
+ (Vertices "trifans_vertices" p n)]
+
+
+lightedScene :: [Geometry] -> Scene
+lightedScene g = Node EmptyRoot ( [ n aCamera,
+                                    n (pointLight "pointLight" 3 4 10),
+                                    n (pointLight "pointL" (-500) 1000 400)] ++
+                                      (map n (map ge g)) )
+
+ge :: Geometry -> SceneNode
+ge (Geometry name p v) = obj name [Geometry name p v]
+-- ------------------
+-- a bigger example
+-- ------------------
+animatedCubes = (scene2, animation2)
+animatedCubes2 = [(scene2, animation2)]
+
+scene2 :: Scene
+scene2 = Node EmptyRoot $ [ n aCamera, n (pointLight "pl" (-500) 1000 400) ] ++ (map n test_objs)
+
+-- | Animation of several cubes
+animation2 :: [Animation]
+animation2 = [Node ("cube_rotate", new_channels anim_channel test_objs) []]
+
+emptyAnimation :: [[Animation]]
+emptyAnimation = []
+
+emptyAnim :: [Animation]
+emptyAnim = []
+
+-- | generate an animation that points to the cubes
+new_channels :: AnimChannel -> [SceneNode] -> AnimChannel
+new_channels (AnimChannel i o interp _) nodes =
+              AnimChannel i o interp $ map (\obj -> ((obj_name obj) ++ "/rotateY","ANGLE")) nodes
+
+obj_name (SceneNode n _ _ _ _ _ _ _) = n
+
+-- | a helper function for xyz_grid
+tran :: SceneNode -> (Float,Float,Float) -> String -> SceneNode
+tran (SceneNode _   typ layer tr                             cam contr geo light) (tx, ty, tz) str =
+     (SceneNode str typ	layer [("tr", Translate (tx,ty,tz))] cam contr geo light)
+
+test_objs :: [SceneNode]
+test_objs = xyz_grid 10 10 10 150 aCube
+
+-- | Generate a 3 dimensional grid where an object (stored in a SceneNode) is repeated in along the grid
+xyz_grid :: Int -> Int -> Int -> Float -> SceneNode -> [SceneNode]
+xyz_grid x y z d obj = zipWith (tran obj)
+                       (concat (concat (x_line x (map (map (\(a,b,c) -> (a+d,b,c)))) $
+                                        x_line y (map (\(a,b,c) -> (a,b+d,c))) $
+                                        x_line z (\(a,b,c) -> (a,b,c+d))        (0,0,0)) ))
+                       (enum_obj obj [1..(x*y*z)])
+
+enum_obj obj (i:is) = ((obj_name obj) ++ (show i)) : (enum_obj obj is)
+
+x_line 0 change value = []
+x_line n change value = value : ( x_line (n-1) change (change value) )
+
+-------------------------------------------------------------------
+-- visualizing a stream of positions with copies of a base object
+-------------------------------------------------------------------
+
+positions = take 50 $ map (\(x, y, z) -> (x*100, y*100, z*100) ) $
+ map (\(x,y,z) -> (fromIntegral x, fromIntegral y, fromIntegral z)) en
+
+en :: [(Word8,Word8,Word8)]
+en = enumerate
+-- en = all3s
+
+base_objects = map (rename aCube) (map show [1..(length positions)])
+
+rename :: SceneNode -> String -> SceneNode
+rename (SceneNode str        typ layer tr cam contr geo light) s =
+       (SceneNode (str ++ s) typ layer tr cam contr geo light)
+
+getName (SceneNode str _ _ _ _ _ _ _) = str
+
+animatedStream = (streamScene base_objects, streamAnimation positions base_objects)
+
+streamScene :: [SceneNode] -> Scene
+streamScene objects = Node EmptyRoot $ [ n aCamera,
+                                         n (pointLight "pl" (-500) 1000 400) ] ++
+                                         (map n $ objects)
+
+streamAnimation :: [(Float,Float,Float)] -> [SceneNode] -> [Animation]
+streamAnimation ps base_objects =
+       [Node ("cube_stream", EmptyAnim) (map n $ concat $
+             zipWith (\ind bo -> [tr_channel ind ((show ind) ++ "1") bo (length ps) s1 "X"] ++
+                                 [tr_channel ind ((show ind) ++ "2") bo (length ps) s2 "Y"] ++
+                                 [tr_channel ind ((show ind) ++ "3") bo (length ps) s3 "Z"])
+            [1..(length ps)] (map getName base_objects) )
+       ]
+  where
+    s1 = map (\(a,b,c) -> a) ps
+    s2 = map (\(a,b,c) -> b) ps
+    s3 = map (\(a,b,c) -> c) ps
+
+tr_channel ind name bname lps s c = ( "anim" ++ name,
+                           AnimChannel ("input", map (*0.3) (map fromIntegral [0..(lps-1)]), [[("name","TIME"), ("type","Float")]] )
+                                       ("output", (take ind s) ++ (take (lps-ind) (repeat (head (drop ind s)))),
+                                         [[("name",c), ("type","Float")]] )
+                                       (take lps (repeat Linear))
+                                       [(bname ++ "/tran",c)]
+                                  )
diff --git a/src/Graphics/Formats/Collada/Transformations.hs b/src/Graphics/Formats/Collada/Transformations.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Formats/Collada/Transformations.hs
@@ -0,0 +1,29 @@
+module Graphics.Formats.Collada.Transformations where
+import Graphics.Formats.Collada.ColladaTypes
+type V = (Float,Float,Float)
+-- |extrude a 2d polygon to 3d, the same points are added again with extrusion direction v
+extrude :: V -> Geometry -> Geometry
+extrude v (Geometry name prims (Vertices vname ps _)) = Geometry name
+                                                         (map addIndices prims)
+                                                         (Vertices vname (concat (map addPoints lines))
+                                                                         (concat (map (\x -> [x,x,x,x]) ns)) )
+  where
+  addIndices (LP (LinePrimitive points normals tex color)) = PL (LinePrimitive (p points) (p points) tex color)
+  lines = cycleNeighbours ps
+  addPoints points = points ++ ( map (add v) (reverse points) )
+  add (x0,y0,z0) (x1,y1,z1) = (x0+x1, y0+y1, z0+z1)
+  ns = map (normals v) lines
+  normals (vx0,vy0,vz0) [(vx1,vy1,vz1),(vx2,vy2,vz2)] = crosspr (vx1-vx0,vy1-vy0,vz1-vz0)
+                                                                (vx1-vx2,vy1-vy2,vz1-vz2)
+  crosspr (v0,v1,v2) (w0,w1,w2) = (v1*w2-v2*w1, v2*w0-v0*w2, v0*w1-v1*w0)
+  p points = concat $ map (map (\x -> [x*4, x*4+1, x*4+2, x*4+3])) points
+
+-- |return a list containing lists of every element with its neighbour
+-- i.e. [e1,e2,e3] -> [ [e1,e2], [e2,e3], [e3, e1] ]
+cycleNeighbours :: [a] -> [[a]]
+cycleNeighbours [] = []
+cycleNeighbours xs = cycleN (head xs) xs
+
+cycleN :: a -> [a] -> [[a]]
+cycleN f (x:y:xs) = [x,y] : (cycleN f (y:xs))
+cycleN f e = [[head e, f ]] -- if the upper doesn't match close cycle
