summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-06-19 23:10:17 -0400
committerJoe Crayne <joe@jerkface.net>2019-06-19 23:10:17 -0400
commitbf3001c4c4577cf5c65e05a21a3e9502dbe0b834 (patch)
treeda07a05559203ecb5f4723f536e3e131f35fd669
parent018f8847fe987abe3f036ff8739468f164429e7d (diff)
Maskable groups.
-rw-r--r--LoadMesh.hs63
1 files changed, 42 insertions, 21 deletions
diff --git a/LoadMesh.hs b/LoadMesh.hs
index bfc5070..b970f3e 100644
--- a/LoadMesh.hs
+++ b/LoadMesh.hs
@@ -1,6 +1,8 @@
1{-# LANGUAGE LambdaCase #-} 1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE RecordWildCards #-} 2{-# LANGUAGE LambdaCase #-}
3{-# LANGUAGE FlexibleContexts #-} 3{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE RecordWildCards #-}
5{-# LANGUAGE TupleSections #-}
4module LoadMesh where 6module LoadMesh where
5 7
6import LambdaCube.GL as LC -- renderer 8import LambdaCube.GL as LC -- renderer
@@ -8,8 +10,10 @@ import LambdaCube.GL.Mesh as LambdaCubeGL
8import LambdaCube.GL.Type as LC 10import LambdaCube.GL.Type as LC
9import MtlParser 11import MtlParser
10 12
13import Control.Arrow
11import Control.Monad 14import Control.Monad
12import Data.Int 15import Data.Int
16import Data.List as List
13import Data.Maybe 17import Data.Maybe
14import Data.Map (Map) 18import Data.Map (Map)
15import qualified Data.Map as Map 19import qualified Data.Map as Map
@@ -139,32 +143,48 @@ uploadMtlLib (mtlLib,objpath) = do
139 return $ (\a -> (a, maybe whiteTex (fromMaybe checkerTex . flip Map.lookup textureLib) . mtl_map_Kd $ a)) <$> mtlLib 143 return $ (\a -> (a, maybe whiteTex (fromMaybe checkerTex . flip Map.lookup textureLib) . mtl_map_Kd $ a)) <$> mtlLib
140 144
141objToMesh :: WavefrontOBJ -> [MaterialMesh Mesh] 145objToMesh :: WavefrontOBJ -> [MaterialMesh Mesh]
142objToMesh OBJ{..} = [ MaterialMesh (toMesh faceGroup) 146objToMesh OBJ{..} = [ toMesh faceGroup | faceGroup <- faces ]
143 (elMtl . head $ faceGroup)
144 Map.empty {- TODO -}
145 | faceGroup <- faces ]
146 where 147 where
147 faces = groupBy (\a b -> elMtl a == elMtl b) (V.toList objFaces) 148 faces = groupBy (\a b -> elMtl a == elMtl b) (V.toList objFaces)
148 toMesh l = Mesh 149 toMesh l = MaterialMesh mesh mtl gs
149 { mAttributes = Map.fromList 150 where
150 [ ("position", A_V4F position) 151 mtl = elMtl $ head l
151 , ("normal", A_V3F normal) 152 mesh = Mesh { mAttributes = Map.fromList
152 , ("uvw", A_V3F texcoord) 153 [ ("position", A_V4F position)
153 ] 154 , ("normal", A_V3F normal)
154 , mPrimitive = P_Triangles 155 , ("uvw", A_V3F texcoord)
155 } where 156 ]
156 triangulate (Triangle a b c) = [a,b,c] 157 , mPrimitive = P_Triangles
157 triangulate (Quad a b c d) = [a,b,c, c,d,a] 158 }
158 triangulate (Face a b c l) = a : b : c : concatMap (\(x,y) -> [a,x,y]) (zip (c:l) l) -- should work for convex polygons without holes
159 defaultPosition = Location 0 0 0 0 159 defaultPosition = Location 0 0 0 0
160 defaultNormal = Normal 0 0 0 160 defaultNormal = Normal 0 1 0
161 defaultTexCoord = TexCoord 0 0 0 161 defaultTexCoord = TexCoord 0 0 0
162 v !- i = v V.!? i 162 v !- i = v V.!? i
163 toVertex FaceIndex{..} = ( let Location x y z w = fromMaybe defaultPosition (objLocations !- faceLocIndex) in V4 x y z w 163 toVertex FaceIndex{..} = ( let Location x y z w = fromMaybe defaultPosition (objLocations !- faceLocIndex) in V4 x y z w
164 , let Normal x y z = fromMaybe defaultNormal ((objNormals !-) =<< faceNorIndex) in V3 x y z 164 , let Normal x y z = fromMaybe defaultNormal ((objNormals !-) =<< faceNorIndex) in V3 x y z
165 , let TexCoord x y z = fromMaybe defaultTexCoord ((objTexCoords !-) =<< faceTexCoordIndex) in V3 x y z 165 , let TexCoord x y z = fromMaybe defaultTexCoord ((objTexCoords !-) =<< faceTexCoordIndex) in V3 x y z
166 ) 166 )
167 (position,normal,texcoord) = V.unzip3 . V.concat . map (V.fromList . map toVertex . triangulate . elValue) $ l 167 (gs,fs) = elementIndices l
168 (positions,normals,texcoords) = unzip3 $ map toVertex fs
169 position = V.fromList positions
170 normal = V.fromList normals
171 texcoord = V.fromList texcoords
172
173triangulate :: Face -> [FaceIndex]
174triangulate (Triangle a b c) = [a,b,c]
175triangulate (Quad a b c d) = [a,b,c, c,d,a]
176triangulate (Face a b c l) = a : b : c : concatMap (\(x,y) -> [a,x,y]) (zip (c:l) l) -- should work for convex polygons without holes
177
178elementIndices :: [Element Face] -> (Map Text Mask, [FaceIndex])
179elementIndices els = (spans,concatMap snd ts)
180 where
181 ts = map ((elGroups &&& elValue) . fmap triangulate) els
182 rs = List.scanl' go ((0,0),[]) ts -- scanl :: (b -> a -> b) -> b -> [a] -> [b]
183 go ((start,len),_) (gs,vs) = ((start+len,length vs),gs)
184 spans = fmap (Mask . map (fromIntegral***fromIntegral))
185 $ foldr (Map.unionWith (++)) Map.empty $ map singletonSpan rs
186 singletonSpan (span,gnames) = Map.fromList $ map (, [span]) gnames
187
168 188
169data MaskableObject = MaskableObject 189data MaskableObject = MaskableObject
170 { maskableObject :: LC.Object 190 { maskableObject :: LC.Object
@@ -188,4 +208,5 @@ addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \matmesh ->
188 Just (ObjMaterial{..},t) -> LC.updateObjectUniforms obj $ do 208 Just (ObjMaterial{..},t) -> LC.updateObjectUniforms obj $ do
189 "diffuseTexture" @= return t -- set model's diffuse texture 209 "diffuseTexture" @= return t -- set model's diffuse texture
190 "diffuseColor" @= let (r,g,b) = mtl_Kd in return (V4 r g b mtl_Tr) 210 "diffuseColor" @= let (r,g,b) = mtl_Kd in return (V4 r g b mtl_Tr)
191 return $ MaskableObject obj $ maybe Map.empty (`Map.singleton` objSpan obj) (materialName matmesh) 211 let matmask = maybe Map.empty (`Map.singleton` objSpan obj) (fmap ("m:" <>) $ materialName matmesh)
212 return $ MaskableObject obj (matmask `Map.union` materialMasks matmesh)