summaryrefslogtreecommitdiff
path: root/LoadMesh.hs
diff options
context:
space:
mode:
Diffstat (limited to 'LoadMesh.hs')
-rw-r--r--LoadMesh.hs60
1 files changed, 50 insertions, 10 deletions
diff --git a/LoadMesh.hs b/LoadMesh.hs
index aaf0e06..cd7a8ad 100644
--- a/LoadMesh.hs
+++ b/LoadMesh.hs
@@ -18,6 +18,7 @@ import Data.Maybe
18import Data.Map (Map) 18import Data.Map (Map)
19import qualified Data.Map as Map 19import qualified Data.Map as Map
20import qualified Data.Vector as V 20import qualified Data.Vector as V
21import qualified Data.Vector.Storable as StorableV
21import qualified Data.ByteString as SB 22import qualified Data.ByteString as SB
22import qualified Data.ByteString.Lazy.Char8 as L 23import qualified Data.ByteString.Lazy.Char8 as L
23import Data.Text (unpack,Text,pack) 24import Data.Text (unpack,Text,pack)
@@ -37,10 +38,19 @@ data MaterialMesh m = MaterialMesh
37 , materialMasks :: Map Text Mask 38 , materialMasks :: Map Text Mask
38 } 39 }
39 40
40type MeshData = ( [MaterialMesh Mesh] -- List of uniform-material meshes (and the name of the material). 41data CurveData = CurveData
41 , ( V.Vector MtlLib -- Material definitions. 42 { curves :: [Curve]
42 , FilePath ) -- Path to wavefront obj file. 43 , curvePt :: Int -> Location
43 ) 44 , curveMax :: Int
45 }
46
47
48data MeshData = MeshData
49 { matMeshes :: [MaterialMesh Mesh] -- List of uniform-material meshes (and the name of the material).
50 , matLib :: ( V.Vector MtlLib -- Material definitions.
51 , FilePath ) -- Path to wavefront obj file.
52 , matCurves :: CurveData
53 }
44 54
45relativeFrom :: FilePath -> FilePath -> FilePath 55relativeFrom :: FilePath -> FilePath -> FilePath
46relativeFrom path file | isAbsolute file = file 56relativeFrom path file | isAbsolute file = file
@@ -51,7 +61,12 @@ loadOBJ fname = L.readFile fname >>= \bs -> do
51 let obj@OBJ{..} = Wavefront.parse bs 61 let obj@OBJ{..} = Wavefront.parse bs
52 -- load materials 62 -- load materials
53 mtlLib <- mapM (readMtlWithFallback . relativeFrom fname . unpack) objMtlLibs 63 mtlLib <- mapM (readMtlWithFallback . relativeFrom fname . unpack) objMtlLibs
54 return $ Right (objToMesh obj,(mtlLib,fname)) 64 return $ Right MeshData
65 { matMeshes = objToMesh obj
66 , matLib = (mtlLib,fname)
67 , matCurves = objToCurveData obj
68 }
69
55 70
56 71
57data BoundingBox = BoundingBox 72data BoundingBox = BoundingBox
@@ -122,22 +137,37 @@ transformMesh t m = m
122 { mAttributes = Map.adjust (tranformAttribute t) "position" (mAttributes m) 137 { mAttributes = Map.adjust (tranformAttribute t) "position" (mAttributes m)
123 } 138 }
124 139
125uploadOBJToGPU :: Maybe BoundingBox -> MeshData -> IO ([MaterialMesh GPUMesh],Matrix Float) 140transformLocation :: Matrix Float -> Location -> Location
126uploadOBJToGPU scalebb (subModels,(mtlLib,objpath)) = do 141transformLocation t (Location x y z w) = Location xx yy zz ww
127 let meshbb = foldMap (attribBoundingBox . mAttributes . materialMesh) subModels :: BoundingBox 142 where
143 [xx,yy,zz,ww] = toList $ t #> fromList [x,y,z,w]
144
145locationBoundingBox :: Location -> BoundingBox
146locationBoundingBox (Location x y z w) = BoundingBox x x y y z z
147
148uploadOBJToGPU :: Maybe BoundingBox -> MeshData -> IO (([MaterialMesh GPUMesh],CurveData),Matrix Float)
149uploadOBJToGPU scalebb (MeshData subModels (mtlLib,objpath) curveData) = do
150 let meshbb = foldMap (attribBoundingBox . mAttributes . materialMesh) subModels
151 <> foldMap (foldMap (locationBoundingBox . curvePt curveData) . curvePoints)
152 (curves curveData)
128 m = maybe (ident 4) (scaleWithin meshbb) scalebb 153 m = maybe (ident 4) (scaleWithin meshbb) scalebb
154 curveData' = case scalebb of
155 Just _ -> curveData { curvePt = transformLocation m . curvePt curveData }
156 Nothing -> curveData
129 putStrLn $ show meshbb 157 putStrLn $ show meshbb
130 gpuSubModels <- forM subModels $ \matmesh -> do 158 gpuSubModels <- forM subModels $ \matmesh -> do
131 a <- LambdaCubeGL.uploadMeshToGPU (transformMesh m (materialMesh matmesh)) 159 a <- LambdaCubeGL.uploadMeshToGPU (transformMesh m (materialMesh matmesh))
132 return matmesh { materialMesh = a } 160 return matmesh { materialMesh = a }
133 return (gpuSubModels,m) 161 return ((gpuSubModels,curveData'),m)
134 162
135uploadMtlLib :: (V.Vector MtlLib,FilePath) -> IO (V.Vector (Map Text (ObjMaterial,TextureData))) 163uploadMtlLib :: (V.Vector MtlLib,FilePath) -> IO (V.Vector (Map Text (ObjMaterial,TextureData)))
136uploadMtlLib (mtlLib,objpath) = do 164uploadMtlLib (mtlLib,objpath) = do
137 -- collect used textures 165 -- collect used textures
138 let usedTextures = nub . concatMap (maybeToList . mtl_map_Kd) $ concatMap Map.elems $ V.toList mtlLib 166 let usedTextures = nub . concatMap (maybeToList . mtl_map_Kd) $ concatMap Map.elems $ V.toList mtlLib
139 whiteImage = Juicy.ImageRGB8 $ Juicy.generateImage (\_ _ -> Juicy.PixelRGB8 255 255 255) 1 1 167 whiteImage = Juicy.ImageRGB8 $ Juicy.generateImage (\_ _ -> Juicy.PixelRGB8 255 255 255) 1 1
140 checkerImage = Juicy.ImageRGB8 $ Juicy.generateImage (\x y -> if mod (x + y) 2 == 0 then Juicy.PixelRGB8 0 0 0 else Juicy.PixelRGB8 255 255 0) 2 2 168 checkerImage = Juicy.ImageRGB8 $ Juicy.generateImage mkchecker 2 2
169 where mkchecker x y = if mod (x + y) 2 == 0 then Juicy.PixelRGB8 0 0 0
170 else Juicy.PixelRGB8 255 255 0
141 checkerTex <- LC.uploadTexture2DToGPU checkerImage 171 checkerTex <- LC.uploadTexture2DToGPU checkerImage
142 -- load images and upload to gpu 172 -- load images and upload to gpu
143 textureLib <- forM (Map.fromList $ zip usedTextures usedTextures) $ \fname -> Juicy.readImage (relativeFrom objpath fname) >>= \case 173 textureLib <- forM (Map.fromList $ zip usedTextures usedTextures) $ \fname -> Juicy.readImage (relativeFrom objpath fname) >>= \case
@@ -147,6 +177,16 @@ uploadMtlLib (mtlLib,objpath) = do
147 -- pair textures and materials 177 -- pair textures and materials
148 return $ fmap (\a -> (a, maybe whiteTex (fromMaybe checkerTex . flip Map.lookup textureLib) . mtl_map_Kd $ a)) <$> mtlLib 178 return $ fmap (\a -> (a, maybe whiteTex (fromMaybe checkerTex . flip Map.lookup textureLib) . mtl_map_Kd $ a)) <$> mtlLib
149 179
180vecLocation :: Location -> StorableV.Vector Float
181vecLocation (Location x y z w) = StorableV.fromList [x,y,z,w]
182
183objToCurveData :: WavefrontOBJ -> CurveData
184objToCurveData OBJ{..} = CurveData
185 { curves = map elValue $ V.toList $ objCurves
186 , curvePt = (objLocations V.!)
187 , curveMax = V.length objLocations
188 }
189
150objToMesh :: WavefrontOBJ -> [MaterialMesh Mesh] 190objToMesh :: WavefrontOBJ -> [MaterialMesh Mesh]
151objToMesh OBJ{..} = [ toMesh faceGroup | faceGroup <- faces ] 191objToMesh OBJ{..} = [ toMesh faceGroup | faceGroup <- faces ]
152 where 192 where