summaryrefslogtreecommitdiff
path: root/src/Graphics/WaveFront/Load.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Graphics/WaveFront/Load.hs')
-rw-r--r--src/Graphics/WaveFront/Load.hs108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/Graphics/WaveFront/Load.hs b/src/Graphics/WaveFront/Load.hs
new file mode 100644
index 0000000..6d65693
--- /dev/null
+++ b/src/Graphics/WaveFront/Load.hs
@@ -0,0 +1,108 @@
1-- |
2-- Module : Graphics.WaveFront.Load
3-- Description : Loading (and perhaps writing) OBJ and MTL files
4-- Copyright : (c) Jonatan H Sundqvist, 2015
5-- License : MIT
6-- Maintainer : Jonatan H Sundqvist
7-- Stability : experimental|stable
8-- Portability : POSIX (not sure)
9--
10
11-- Created July 26 2015
12
13-- TODO | - Logging
14-- -
15
16-- SPEC | -
17-- -
18
19
20
21--------------------------------------------------------------------------------------------------------------------------------------------
22-- GHC Extensions
23--------------------------------------------------------------------------------------------------------------------------------------------
24{-# LANGUAGE UnicodeSyntax #-}
25-- {-# LANGUAGE TupleSections #-}
26
27
28
29--------------------------------------------------------------------------------------------------------------------------------------------
30-- API
31--------------------------------------------------------------------------------------------------------------------------------------------
32-- TODO | - Decide on an API
33module Graphics.WaveFront.Load (
34 obj, mtl, materials, model
35) where
36
37
38
39--------------------------------------------------------------------------------------------------------------------------------------------
40-- We'll need these
41--------------------------------------------------------------------------------------------------------------------------------------------
42import System.FilePath (splitFileName, takeDirectory, (</>))
43
44import Data.Text (Text)
45import qualified Data.Text as T
46import qualified Data.Text.IO as T
47import Data.Vector (Vector)
48
49import Control.Applicative ((<$>))
50import Control.Monad.Trans.Except
51import Control.Monad.Trans.Class (lift)
52
53import qualified Data.Attoparsec.Text as Atto
54
55import Graphics.WaveFront.Types
56import qualified Graphics.WaveFront.Parse as Parse
57import qualified Graphics.WaveFront.Parse.Common as Parse
58import Graphics.WaveFront.Model (createMTLTable, createModel)
59
60
61
62--------------------------------------------------------------------------------------------------------------------------------------------
63-- Functions (IO)
64--------------------------------------------------------------------------------------------------------------------------------------------
65
66-- Loading data ----------------------------------------------------------------------------------------------------------------------------
67
68-- |
69-- TODO | - Use bytestrings (?)
70-- - Deal with IO and parsing errors
71obj :: (Fractional f, Integral i) => String -> IO (Either String (OBJ f Text i []))
72obj fn = runExceptT $ do
73 lift $ putStrLn $ "Loading obj file: " ++ fn
74 ExceptT $ Atto.parseOnly (Parse.wholeFile Parse.obj) <$> T.readFile fn
75
76
77-- |
78-- TODO | - Use bytestrings (?)
79-- - Merge OBJ and MTL parsers (and plug in format-specific code as needed) (?)
80-- - Deal with IO and parsing errors
81mtl :: (Fractional f) => String -> IO (Either String (MTL f Text []))
82mtl fn = do
83 putStrLn $ "Loading mtl file: " ++ fn
84 Atto.parseOnly (Parse.wholeFile Parse.mtl) <$> T.readFile fn
85
86
87-- |
88-- TODO | - Better names (than 'mtls' and 'fns') (?)
89-- - Refactor, simplify
90-- - Improve path handling (cf. '</>')
91-- - Graceful error handling
92materials :: (Fractional f) => [FilePath] -> IO (Either String (MTLTable f Text))
93materials fns = runExceptT $ do
94 tokens <- mapM (ExceptT . mtl) fns
95 ExceptT . return $ createTableFromMTLs tokens
96 where
97 createTableFromMTLs :: [[MTLToken f Text]] -> Either String (MTLTable f Text)
98 createTableFromMTLs = createMTLTable . zip (map (T.pack . snd . splitFileName) fns)
99
100
101-- | Loads an OBJ model from file, including associated materials
102-- TODO | - Graceful error handling
103model :: (Fractional f, Integral i) => FilePath -> IO (Either String (Model f Text i Vector))
104model fn = runExceptT $ do
105 obj <- ExceptT $ obj fn
106 materials <- ExceptT $ materials [ fst (splitFileName fn) </> T.unpack name | LibMTL name <- obj ]
107 ExceptT . return $ createModel obj materials (Just $ takeDirectory fn)
108 -- where loadWithName name = mtl name >>= return . (name,)