summaryrefslogtreecommitdiff
path: root/src/Graphics/Formats/Collada/GenerateObjects.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Graphics/Formats/Collada/GenerateObjects.hs')
-rw-r--r--src/Graphics/Formats/Collada/GenerateObjects.hs285
1 files changed, 285 insertions, 0 deletions
diff --git a/src/Graphics/Formats/Collada/GenerateObjects.hs b/src/Graphics/Formats/Collada/GenerateObjects.hs
new file mode 100644
index 0000000..c1dcae7
--- /dev/null
+++ b/src/Graphics/Formats/Collada/GenerateObjects.hs
@@ -0,0 +1,285 @@
1module Graphics.Formats.Collada.GenerateObjects
2where
3
4import Data.Enumerable
5import Data.Tree
6import Data.Tuple.Enum
7import Data.Word
8import qualified Data.Vector as V
9import Data.Vector (Vector)
10import Graphics.Formats.Collada.ColladaTypes
11import Graphics.Formats.Collada.Vector2D3D
12
13-- type Scene = Tree SceneNode
14n x = Node x []
15makeScene sid sceneNodes = Node (SceneNode sid NOTYPE [] tranrot [] [] [] []) (map n sceneNodes)
16
17-- | An animated cube
18animatedCube :: (Scene, [Animation])
19animatedCube = (aScene, animation)
20
21-- | Example scene with a cube
22aScene :: Scene
23aScene = makeScene "aCube" (cameraAndLight ++ [aCube])
24
25lightedGeometry :: [Geometry] -> Scene
26lightedGeometry g = makeScene "g" (cameraAndLight ++ (map ge g))
27
28lightedSceneNode :: SceneNode -> Scene
29lightedSceneNode node = makeScene "node" (cameraAndLight ++ [node])
30
31lightedScene :: Scene -> Scene
32lightedScene node = Node EmptyRoot ((map n cameraAndLight) ++ [node])
33
34-- | Every scene needs a camera and light
35cameraAndLight = [ aCamera,
36 pointLight "pointLight" 3 4 10,
37 pointLight "pointL" (-500) 1000 400 ]
38
39rot x y z = Rotate (V3 1 0 0) x
40 (V3 0 1 0) y
41 (V3 0 0 1) z
42
43tranrot = [ ("tran", Translate (V3 0 0 0)), ("rot", rot 0 0 0) ] -- there have to be values for an animation channel to access
44
45aCamera = SceneNode "camera0" NOTYPE []
46 [("tran", Translate (V3 1000 2000 2500)),
47 ("rot", rot (-22) 13 0)]
48 -- [("lookat", LookAt (1000,1000,2500) (0,0,0) (0,1,0))]
49 [(Perspective "Persp" (ViewSizeXY (37,37)) (Z 10 1000) )]
50 [] [] []
51
52pointLight str x y z = SceneNode str NOTYPE []
53 [("tran", Translate (V3 x y z)),
54 ("rot", rot 0 0 0)]
55 [] [] []
56 [(Point "point" (RGB 1 1 1) (Attenuation 1 0 0) )]
57
58ambientLight = SceneNode "ambientLight" NOTYPE []
59 [("tran", Translate (V3 (-500) 1000 400)),
60 ("rot", rot 0 0 0)]
61 [] [] []
62 [(Ambient "ambient" (RGB 1 1 1) )]
63
64aCube :: SceneNode
65aCube = SceneNode "cube_geometry" NOTYPE [] tranrot [] [] [cube] []
66
67obj :: String -> [Geometry] -> V3 -> SceneNode
68obj name c tr = SceneNode name NOTYPE []
69 [("tran", Translate tr),
70 ("rot", rot 0 0 0)]
71 [] []
72 c -- geometries
73 []
74
75-- | Example animation of the cube
76animation :: [Animation]
77animation = [Node ("cube_rotate", anim_channel) []]
78
79anim_channel = AnimChannel ("input", [0, 1, 2, 3], [[("name","TIME"), ("type","Float")]] )
80 ("output",[0, 50, 100, 150], [[("name","ANGLE"), ("type","Float")]] )
81 [ Bezier [-0.333333, 0] [2.5, 0], -- intangent outtangent
82 Bezier [5,0] [7.916667, 0],
83 Bezier [8.333333, 56] [9.166667, 56],
84 Bezier [9.583333, 18.666666] [10.333333, -14.933331] ]
85 [("cube_geometry/rotateY","ANGLE")]
86
87fl = V.fromList
88
89-- | A blue/textured cube
90cube :: Geometry
91cube = Geometry "cube"
92 [PL (LinePrimitive
93 (fl [fl [0,2,3,1], fl [0,1,5,4], fl [6,7,3,2], fl [0,4,6,2], fl [3,7,5,1], fl [5,7,6,4]]) -- indices to vertices
94 (fl [fl [0,0,0,0], fl [1,1,1,1], fl [2,2,2,2], fl [3,3,3,3], fl [4,4,4,4], fl [5,5,5,5]]) -- indices to normals
95 (fl [fl [0,1,2,3], fl [0,1,2,3], fl [0,1,2,3], fl [0,1,2,3], fl [0,1,2,3], fl [0,1,2,3]]) -- indices to texture coordinates, use an empty list when no texture
96 [logo]
97 -- [blue]
98 )]
99 (Vertices "cube_vertices"
100 (fl [(V3 (-10) 10 10), (V3 10 10 10), (V3 (-10) (-10) 10), (V3 10 (-10) 10), -- vertices
101 (V3 (-10) 10 (-10)),(V3 10 10 (-10)),(V3 (-10) (-10) (-10)),(V3 10 (-10) (-10))])
102 (fl [(V3 0 0 1), (V3 0 1 0), (V3 0 (-1) 0), (V3 (-1) 0 0), (V3 1 0 0), (V3 0 0 (-1))]) -- normals
103 )
104
105blue = ("blue", COMMON "" NoParam
106 (PhongCol [CEmission (Color (V4 0 0 0 1)),
107 CAmbient (Color (V4 0 0 0 1)),
108 CDiffuse(Color (V4 0.137255 0.403922 0.870588 1)),
109 CSpecular(Color (V4 0.5 0.5 0.5 1)),
110 CShininess 16,
111 CReflective (Color (V4 0 0 0 1)),
112 CReflectivity 0.5,
113 CTransparent (Color (V4 0 0 0 1)),
114 CTransparency 1,
115 CIndex_of_refraction 0]
116 )
117 ""
118 )
119
120diffuse c str (a, COMMON asset NoParam (PhongCol cs) s) = ("color_" ++ str, COMMON asset NoParam (PhongCol (map (replaceDiff c) cs)) s)
121
122replaceDiff c (CDiffuse _) = CDiffuse (Color c)
123replaceDiff _ c = c
124
125ambient c str (a, COMMON asset NoParam (PhongCol cs) s) = ("color_" ++ str, COMMON asset NoParam (PhongCol (map (replaceAmb c) cs)) s)
126
127replaceAmb c (CAmbient _) = CAmbient (Color c)
128replaceAmb _ c = c
129
130
131getDiffuseColor ( CDiffuse (Color c) ) = Just c
132getDiffuseColor _ = Nothing
133
134getAmbientColor ( CAmbient (Color c) ) = Just c
135getAmbientColor _ = Nothing
136
137logo = ("haskell-logo", COMMON "" NoParam
138 (PhongTex [(TDiffuse tex)]
139 [[0,0,1,0,1,1,0,1]] -- [u0,v0,u1,v1,..] -coordinates (Floats between 0 and 1) that point into the texture
140 )
141 ""
142 )
143
144tex = Texture "logo" "Haskell-Logo-Variation.png" Nothing
145
146polys :: Vector V3 -> Vector V3 -> Vector (Vector Int) -> Vector (Vector Int) -> [Geometry]
147polys p n pi ni = [Geometry "polygons"
148 [PL (LinePrimitive pi -- indices to vertices
149 ni -- indices to normals
150 V.empty -- no texure
151 [blue]
152 )]
153 (Vertices "polygons_vertices" p n)]
154
155
156lines :: Vector V3 -> Vector V3 -> Vector (Vector Int) -> Vector (Vector Int) -> [Geometry]
157lines p n pi ni = [Geometry "lines"
158 [LS (LinePrimitive pi -- indices to vertices
159 ni -- indices to normals
160 V.empty -- no texure
161 [blue]
162 )]
163 (Vertices "lines_vertices" p n)]
164
165
166trifans :: Vector V3 -> Vector V3 -> Vector (Vector Int)-> Vector (Vector Int) -> [Geometry]
167trifans p n pi ni = [Geometry "trifans"
168 [Trf (LinePrimitive pi -- indices to vertices
169 ni -- indices to normals
170 V.empty -- no texure
171 [blue]
172 )]
173 (Vertices "trifans_vertices" p n)]
174
175
176tristrips :: Vector V3 -> Vector V3 -> Vector (Vector Int) -> Vector (Vector Int) -> [Geometry]
177tristrips p n pi ni = [Geometry "tristrips"
178 [Trs (LinePrimitive pi -- indices to vertices
179 ni -- indices to normals
180 V.empty -- no texure
181 [blue]
182 )]
183 (Vertices "trifans_vertices" p n)]
184
185
186ge :: Geometry -> SceneNode
187ge (Geometry name p v) = obj name [Geometry name p v] (V3 0 0 0)
188-- ------------------
189-- a bigger example
190-- ------------------
191animatedCubes = (scene2, animation2)
192animatedCubes2 = [(scene2, animation2)]
193
194scene2 :: Scene
195scene2 = Node EmptyRoot $ [ n aCamera, n (pointLight "pl" (-500) 1000 400) ] ++ (map n test_objs)
196
197-- | Animation of several cubes
198animation2 :: [Animation]
199animation2 = [Node ("cube_rotate", new_channels anim_channel test_objs) []]
200
201emptyAnimation :: [[Animation]]
202emptyAnimation = []
203
204emptyAnim :: [Animation]
205emptyAnim = []
206
207-- | generate an animation that points to the cubes
208new_channels :: AnimChannel -> [SceneNode] -> AnimChannel
209new_channels (AnimChannel i o interp _) nodes =
210 AnimChannel i o interp $ map (\obj -> ((obj_name obj) ++ "/rotateY","ANGLE")) nodes
211
212obj_name (SceneNode n _ _ _ _ _ _ _) = n
213
214-- | a helper function for xyz_grid
215tran :: SceneNode -> V3 -> String -> SceneNode
216tran (SceneNode _ typ layer tr cam contr geo light) v3 str =
217 (SceneNode str typ layer [("tr", Translate v3)] cam contr geo light)
218
219test_objs :: [SceneNode]
220test_objs = xyz_grid 10 10 10 150 aCube
221
222-- | Generate a 3 dimensional grid where an object (stored in a SceneNode) is repeated in along the grid
223xyz_grid :: Int -> Int -> Int -> Float -> SceneNode -> [SceneNode]
224xyz_grid x y z d obj = zipWith (tran obj)
225 (concat (concat (x_line x (map (map (\(V3 a b c) -> (V3 (a+d) b c)))) $
226 x_line y (map (\(V3 a b c) -> (V3 a (b+d) c))) $
227 x_line z (\(V3 a b c) -> (V3 a b (c+d))) (V3 0 0 0)) ))
228 (enum_obj obj [1..(x*y*z)])
229
230enum_obj obj (i:is) = ((obj_name obj) ++ (show i)) : (enum_obj obj is)
231
232x_line 0 change value = []
233x_line n change value = value : ( x_line (n-1) change (change value) )
234
235-------------------------------------------------------------------
236-- visualizing a stream of positions with copies of a base object
237-------------------------------------------------------------------
238
239positions = map (\(x, y, z) -> (x*100, y*100, z*100) ) $
240 -- map (\(x,y,z) -> (fromIntegral x, fromIntegral y, fromIntegral z))
241 en
242
243en :: [(Float,Float,Float)]
244-- en :: [(Word8,Word8,Word8)]
245-- en = take 100 enumerate
246-- en = take 100 all3s
247
248en = map (\(V x y)->(x*20,y*20,0)) []
249
250base_objects = map (rename aCube) (map show [1..(length positions)])
251
252rename :: SceneNode -> String -> SceneNode
253rename (SceneNode str typ layer tr cam contr geo light) s =
254 (SceneNode (str ++ s) typ layer tr cam contr geo light)
255
256getName (SceneNode str _ _ _ _ _ _ _) = str
257get_name (Geometry str _ _) = str
258
259animatedStream = (streamScene base_objects, streamAnimation positions base_objects)
260
261streamScene :: [SceneNode] -> Scene
262streamScene objects = Node EmptyRoot $ [ n aCamera,
263 n (pointLight "pl" (-500) 1000 400) ] ++
264 (map n $ objects)
265
266streamAnimation :: [(Float,Float,Float)] -> [SceneNode] -> [Animation]
267streamAnimation ps base_objects =
268 [Node ("cube_stream", EmptyAnim) (map n $ concat $
269 zipWith (\ind bo -> [tr_channel ind ((show ind) ++ "1") bo (length ps) s1 "X"] ++
270 [tr_channel ind ((show ind) ++ "2") bo (length ps) s2 "Y"] ++
271 [tr_channel ind ((show ind) ++ "3") bo (length ps) s3 "Z"])
272 [1..(length ps)] (map getName base_objects) )
273 ]
274 where
275 s1 = map (\(a,b,c) -> a) ps
276 s2 = map (\(a,b,c) -> b) ps
277 s3 = map (\(a,b,c) -> c) ps
278
279tr_channel ind name bname lps s c = ( "anim" ++ name,
280 AnimChannel ("input", map (*0.3) (map fromIntegral [0..(lps-1)]), [[("name","TIME"), ("type","Float")]] )
281 ("output", (take ind s) ++ (take (lps-ind) (repeat (head (drop ind s)))),
282 [[("name",c), ("type","Float")]] )
283 (take lps (repeat Linear))
284 [(bname ++ "/tran",c)]
285 )