summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-06-13 19:41:27 -0400
committerJoe Crayne <joe@jerkface.net>2019-06-13 19:41:27 -0400
commit7c9abb1082b36bf1d1e596dc6f3a5a44134a5e53 (patch)
tree2700d90e428a1230b9c5bda0291e3e685351bf47
parent03b4ed79972046dc1397430ac7d96493eb9c2c3e (diff)
crayne parser: usemap support
-rw-r--r--src/Wavefront.hs29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/Wavefront.hs b/src/Wavefront.hs
index ca4b497..84edd6d 100644
--- a/src/Wavefront.hs
+++ b/src/Wavefront.hs
@@ -42,6 +42,7 @@ data ObjBuilder m = ObjBuilder
42 , bmat :: ParamSpec -> [Double] -> m () 42 , bmat :: ParamSpec -> [Double] -> m ()
43 , step :: [Int] -> m () 43 , step :: [Int] -> m ()
44 , points :: [Int] -> m () 44 , points :: [Int] -> m ()
45 , usemap :: Maybe S.ByteString -> m ()
45 , badToken :: L.ByteString -> m () 46 , badToken :: L.ByteString -> m ()
46 } 47 }
47 48
@@ -77,6 +78,7 @@ nullBuilder = ObjBuilder
77 , bmat = \uv fs -> pure () 78 , bmat = \uv fs -> pure ()
78 , step = \is -> pure () 79 , step = \is -> pure ()
79 , points = \is -> pure () 80 , points = \is -> pure ()
81 , usemap = \map -> pure ()
80 , badToken = \bs -> pure () 82 , badToken = \bs -> pure ()
81 } 83 }
82 84
@@ -201,7 +203,7 @@ findNewLine ps o@(ObjConfig args) bs = case L.break (\c -> c=='\n' || c=='\\' ||
201 35 surf 203 35 surf
202 36 x trace_obj -- for all except these, 204 36 x trace_obj -- for all except these,
203 37 trim -- Two chars suffice to distinguish 205 37 trim -- Two chars suffice to distinguish
204 38 x usemap -- for all except these, 206 38 usemap -- for all except these,
205 39 usemtl -- Two chars suffice to distinguish 207 39 usemtl -- Two chars suffice to distinguish
206 40 v 208 40 v
207 41 vn 209 41 vn
@@ -327,6 +329,15 @@ lengthLessThan n bs =
327 (L.toChunks bs) 329 (L.toChunks bs)
328 n 330 n
329 331
332substVar :: ObjConfig -> L.ByteString -> L.ByteString
333substVar _ mtl | L.take 1 mtl/="$" = mtl
334substVar (ObjConfig args) mtl = case I.readDecimal (L.toStrict $ L.drop 1 mtl) of
335 Just (i,_) -> case IntMap.lookup i args of
336 Just val -> val
337 Nothing -> mtl
338 Nothing -> mtl
339
340
330parseOBJ :: Monad m => ObjBuilder m -> ObjConfig -> L.ByteString -> m () 341parseOBJ :: Monad m => ObjBuilder m -> ObjConfig -> L.ByteString -> m ()
331parseOBJ builder args bs0 342parseOBJ builder args bs0
332 | lengthLessThan 2 bs = return () 343 | lengthLessThan 2 bs = return ()
@@ -477,11 +488,17 @@ parseOBJ builder args bs0
477 parseCurveSpecs (findToken args) (next 2 bs) $ \ss bs' -> do 488 parseCurveSpecs (findToken args) (next 2 bs) $ \ss bs' -> do
478 trim builder ss 489 trim builder ss
479 parseOBJ builder args bs' 490 parseOBJ builder args bs'
480 "us" -> -- usemtl 491 "us" -> -- usemtl or usemap
481 case L.break isSpace $ next 2 bs of 492 if lengthLessThan 5 bs
482 (mtl,bs') -> do 493 then bad bs
483 usemtl builder (L.toStrict mtl) 494 else case L.break isSpace $ next 2 bs of
484 parseOBJ builder args bs' 495 (mtl0,bs') -> do
496 let mtl = substVar args mtl0
497 case L.index bs 4 of
498 'a' -> usemap builder $ if mtl == "off" then Nothing
499 else Just (L.toStrict mtl)
500 _ -> usemtl builder (L.toStrict mtl)
501 parseOBJ builder args bs'
485 "mt" -> -- mtllib 502 "mt" -> -- mtllib
486 case findNewLine [] args $ next 2 bs of 503 case findNewLine [] args $ next 2 bs of
487 (fnn,bs') -> do 504 (fnn,bs') -> do