diff options
author | Joe Crayne <joe@jerkface.net> | 2019-06-13 19:41:27 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-06-13 19:41:27 -0400 |
commit | 7c9abb1082b36bf1d1e596dc6f3a5a44134a5e53 (patch) | |
tree | 2700d90e428a1230b9c5bda0291e3e685351bf47 | |
parent | 03b4ed79972046dc1397430ac7d96493eb9c2c3e (diff) |
crayne parser: usemap support
-rw-r--r-- | src/Wavefront.hs | 29 |
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 | ||
332 | substVar :: ObjConfig -> L.ByteString -> L.ByteString | ||
333 | substVar _ mtl | L.take 1 mtl/="$" = mtl | ||
334 | substVar (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 | |||
330 | parseOBJ :: Monad m => ObjBuilder m -> ObjConfig -> L.ByteString -> m () | 341 | parseOBJ :: Monad m => ObjBuilder m -> ObjConfig -> L.ByteString -> m () |
331 | parseOBJ builder args bs0 | 342 | parseOBJ 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 |