summaryrefslogtreecommitdiff
path: root/src/Graphics/Formats/Collada/Transformations.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Graphics/Formats/Collada/Transformations.hs')
-rw-r--r--src/Graphics/Formats/Collada/Transformations.hs97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/Graphics/Formats/Collada/Transformations.hs b/src/Graphics/Formats/Collada/Transformations.hs
new file mode 100644
index 0000000..9efa801
--- /dev/null
+++ b/src/Graphics/Formats/Collada/Transformations.hs
@@ -0,0 +1,97 @@
1module Graphics.Formats.Collada.Transformations where
2import Graphics.Formats.Collada.ColladaTypes
3import Graphics.Formats.Collada.GenerateObjects
4import Graphics.Formats.Collada.Vector2D3D
5import Data.Vector (Vector)
6import qualified Data.Vector as V
7import Data.Tuple.Select
8
9translate :: V3 -> Geometry -> Geometry
10translate v (Geometry name prims (Vertices vname ps ns)) = Geometry name prims (Vertices vname (V.map (+ v) ps) ns)
11
12-- |extrude a 2d polygon to 3d, the same points are added again with extrusion direction v
13extrude :: V3 -> Geometry -> Geometry
14extrude v (Geometry name prims (Vertices vname ps _)) = Geometry name
15 (map addIndices prims)
16 (Vertices vname (addNewPoints ps)
17 (fourN ns) )
18 where
19 addNewPoints :: Vector V3 -> Vector V3
20 addNewPoints vs | V.null vs = V.empty
21 | otherwise = V.cons (V.head vs) $ V.cons ((V.head vs)+v) (addNewPoints (V.tail vs))
22
23 fourN :: Vector V3 -> Vector V3
24 fourN vs | V.null vs = V.empty
25 | otherwise = V.cons (V.head vs) $
26 V.cons (V.head vs) $
27 V.cons (V.head vs) $ V.cons (V.head vs) (fourN (V.tail vs))
28
29 addIndices (LP (LinePrimitive points normals tex color)) = PL (LinePrimitive (p points) (p points) tex color)
30
31 ns = V.map (normalsFrom v) (cycleNeighbours ps)
32 p :: Vector (Vector Int) -> Vector (Vector Int)
33 p several_outlines = V.foldr (V.++) V.empty (V.map extr_outline several_outlines)
34
35extr_outline :: Vector Int -> Vector (Vector Int)
36extr_outline points = V.map quads (cycleNeighbours points)
37 where
38 quads xs = V.cons ((V.head xs)*2) $ -- [x*2,y*2,x*2+1,y*2+1]
39 V.cons ((V.head (V.tail xs))*2) $
40 V.cons ((V.head (V.tail xs))*2+1) $
41 V.singleton ((V.head xs)*2+1)
42
43normalsFrom (V3 x0 y0 z0) xs = crosspr (v1x-x0,v1y-y0,v1z-z0) (v1x-v2x,v1y-v2y,v1z-v2z)
44 where (V3 v1x v1y v1z ,V3 v2x v2y v2z) = (V.head xs, V.head (V.tail xs)) :: (V3,V3)
45 crosspr (v0,v1,v2) (w0,w1,w2) = (V3 (v1*w2-v2*w1) (v2*w0-v0*w2) (v0*w1-v1*w0))
46
47-- |return a list containing lists of every element with its neighbour
48-- i.e. [e1,e2,e3] -> [ [e1,e2], [e2,e3], [e3, e1] ]
49cycleNeighbours :: Vector a -> Vector (Vector a)
50cycleNeighbours xs | V.null xs = V.empty
51 | otherwise = cycleN (V.head xs) xs
52
53cycleN :: a -> Vector a -> Vector (Vector a)
54cycleN f xs | V.length xs >= 2 = V.cons (V.fromList [V.head xs, V.head (V.tail xs)]) (cycleN f (V.tail xs))
55 | otherwise = V.singleton (V.fromList [V.head xs, f ]) -- if the upper doesn't match close cycle
56
57
58atop :: Geometry -> Geometry -> Geometry
59atop (Geometry name0 prims0 (Vertices vname0 ps0 ns0))
60 (Geometry name1 prims1 (Vertices vname1 ps1 ns1)) = Geometry name0
61 ( prims0 ++ (map (changeIndices l) prims1) )
62 ( Vertices vname0 (ps0 V.++ ps1) (ns0 V.++ ns1) )
63 where changeIndices l (LP (LinePrimitive points normals texCoord mat)) =
64 LP (LinePrimitive (V.map (V.map (l+)) points) (V.map (V.map (l+)) normals) texCoord mat)
65 changeIndices l (LS (LinePrimitive points normals texCoord mat)) =
66 LS (LinePrimitive (V.map (V.map (l+)) points) (V.map (V.map (l+)) normals) texCoord mat)
67 changeIndices l (PL (LinePrimitive points normals texCoord mat)) =
68 PL (LinePrimitive (V.map (V.map (l+)) points) (V.map (V.map (l+)) normals) texCoord mat)
69 changeIndices l (Tr (LinePrimitive points normals texCoord mat)) =
70 Tr (LinePrimitive (V.map (V.map (l+)) points) (V.map (V.map (l+)) normals) texCoord mat)
71 l = V.length ps0
72
73
74changeDiffuseColor :: String -> V4 -> Geometry -> Geometry
75changeDiffuseColor str color (Geometry name prims
76 (Vertices vname ps ns)) = (Geometry name (map (c color) prims) (Vertices vname ps ns))
77 where c col (LP (LinePrimitive ps ns texCoord mat)) =
78 LP (LinePrimitive ps ns texCoord (map (diffuse col str) mat))
79 c col (LS (LinePrimitive ps ns texCoord mat)) =
80 LS (LinePrimitive ps ns texCoord (map (diffuse col str) mat))
81 c col (PL (LinePrimitive ps ns texCoord mat)) =
82 PL (LinePrimitive ps ns texCoord (map (diffuse col str) mat))
83 c col (Tr (LinePrimitive ps ns texCoord mat)) =
84 Tr (LinePrimitive ps ns texCoord (map (diffuse col str) mat))
85
86changeAmbientColor :: String -> V4 -> Geometry -> Geometry
87changeAmbientColor str color (Geometry name prims
88 (Vertices vname ps ns)) = (Geometry name (map (c color) prims) (Vertices vname ps ns))
89 where c col (LP (LinePrimitive ps ns texCoord mat)) =
90 LP (LinePrimitive ps ns texCoord (map (ambient col str) mat) )
91 c col (LS (LinePrimitive ps ns texCoord mat)) =
92 LS (LinePrimitive ps ns texCoord (map (ambient col str) mat) )
93 c col (PL (LinePrimitive ps ns texCoord mat)) =
94 PL (LinePrimitive ps ns texCoord (map (ambient col str) mat) )
95 c col (Tr (LinePrimitive ps ns texCoord mat)) =
96 Tr (LinePrimitive ps ns texCoord (map (ambient col str) mat) )
97