summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-06-13 20:18:15 -0400
committerJoe Crayne <joe@jerkface.net>2019-06-13 20:18:15 -0400
commitf41806fb911f17e5102be3ef20a74d0b033fa2a9 (patch)
tree46506d269ef85448ee0de9f7e04b0e792f99e244
parent7c9abb1082b36bf1d1e596dc6f3a5a44134a5e53 (diff)
crayne parser: maplib,c_interp,d_interp keywords
-rw-r--r--src/Wavefront.hs47
1 files changed, 42 insertions, 5 deletions
diff --git a/src/Wavefront.hs b/src/Wavefront.hs
index 84edd6d..208e5bf 100644
--- a/src/Wavefront.hs
+++ b/src/Wavefront.hs
@@ -43,6 +43,9 @@ data ObjBuilder m = ObjBuilder
43 , step :: [Int] -> m () 43 , step :: [Int] -> m ()
44 , points :: [Int] -> m () 44 , points :: [Int] -> m ()
45 , usemap :: Maybe S.ByteString -> m () 45 , usemap :: Maybe S.ByteString -> m ()
46 , maplib :: [S.ByteString] -> m ()
47 , c_interp :: Bool -> m ()
48 , d_interp :: Bool -> m ()
46 , badToken :: L.ByteString -> m () 49 , badToken :: L.ByteString -> m ()
47 } 50 }
48 51
@@ -79,6 +82,9 @@ nullBuilder = ObjBuilder
79 , step = \is -> pure () 82 , step = \is -> pure ()
80 , points = \is -> pure () 83 , points = \is -> pure ()
81 , usemap = \map -> pure () 84 , usemap = \map -> pure ()
85 , maplib = \fns -> pure ()
86 , c_interp = \b -> pure ()
87 , d_interp = \b -> pure ()
82 , badToken = \bs -> pure () 88 , badToken = \bs -> pure ()
83 } 89 }
84 90
@@ -173,7 +179,7 @@ findNewLine ps o@(ObjConfig args) bs = case L.break (\c -> c=='\n' || c=='\\' ||
173 5 x call 179 5 x call
174 6 cdc 180 6 cdc
175 7 x cdp 181 7 x cdp
176 8 x c_interp 182 8 c_interp
177 9 con 183 9 con
178 10 x csh -- for all except these, 184 10 x csh -- for all except these,
179 11 cstype -- Two chars suffice to distinguish 185 11 cstype -- Two chars suffice to distinguish
@@ -181,13 +187,13 @@ findNewLine ps o@(ObjConfig args) bs = case L.break (\c -> c=='\n' || c=='\\' ||
181 13 curv2 -- for all except these, 187 13 curv2 -- for all except these,
182 14 curv -- Two chars suffice to distinguish 188 14 curv -- Two chars suffice to distinguish
183 15 deg 189 15 deg
184 16 x d_interp 190 16 d_interp
185 17 end 191 17 end
186 18 f 192 18 f
187 19 g 193 19 g
188 20 hole 194 20 hole
189 21 x lod 195 21 x lod
190 22 x maplib 196 22 maplib
191 23 mg 197 23 mg
192 24 mtllib 198 24 mtllib
193 25 o 199 25 o
@@ -210,7 +216,6 @@ findNewLine ps o@(ObjConfig args) bs = case L.break (\c -> c=='\n' || c=='\\' ||
210 42 vp 216 42 vp
211 43 vt 217 43 vt
212 218
213
214-} 219-}
215 220
216nextToken :: (L.ByteString -> L.ByteString) -> L.ByteString -> L.ByteString 221nextToken :: (L.ByteString -> L.ByteString) -> L.ByteString -> L.ByteString
@@ -419,7 +424,23 @@ parseOBJ builder args bs0
419 let u0:v0:_ = vs ++ repeat 0.0 424 let u0:v0:_ = vs ++ repeat 0.0
420 curv builder u0 v0 is 425 curv builder u0 v0 is
421 parseOBJ builder args bs'' 426 parseOBJ builder args bs''
427 "c_" -> -- c_interp
428 let tok = findToken args (next 2 bs)
429 in if lengthLessThan 2 tok
430 then bad tok
431 else let flag = case L.index tok 1 of
432 'f' -> c_interp builder False -- off
433 _ -> c_interp builder True -- on
434 in parseOBJ builder args (next 2 tok)
422 "de" -> parseI deg 3 435 "de" -> parseI deg 3
436 "d_" -> -- d_interp
437 let tok = findToken args (next 2 bs)
438 in if lengthLessThan 2 tok
439 then bad tok
440 else let flag = case L.index tok 1 of
441 'f' -> d_interp builder False -- off
442 _ -> d_interp builder True -- on
443 in parseOBJ builder args (next 2 tok)
423 "en" -> do endFreeForm builder 444 "en" -> do endFreeForm builder
424 parseOBJ builder args (next 2 bs) 445 parseOBJ builder args (next 2 bs)
425 "ho" -> -- hole 446 "ho" -> -- hole
@@ -499,6 +520,22 @@ parseOBJ builder args bs0
499 else Just (L.toStrict mtl) 520 else Just (L.toStrict mtl)
500 _ -> usemtl builder (L.toStrict mtl) 521 _ -> usemtl builder (L.toStrict mtl)
501 parseOBJ builder args bs' 522 parseOBJ builder args bs'
523 "ma" -> -- maplib
524 case findNewLine [] args $ next 2 bs of
525 (fnn,bs') -> do
526 let slurp fnn = case L.break (=='.') fnn of
527 (fn,ext) | L.null (L.drop 1 ext) -> if L.null fn then []
528 else [fn]
529 | ext <- L.take 4 ext
530 -- XXX What is the map library extension?
531 , ext `elem` [".map",".mtl",".obj"] ->
532 if L.all isSpace (L.take 1 $ L.drop 4 ext)
533 then (fn <> ext) : slurp (findToken args $ L.drop 4 ext)
534 else let f:fs = slurp (L.drop 3 ext) in (fn <> L.take 3 ext <> f) : fs
535 | otherwise -> let (f:fs) = slurp (L.drop 1 ext)
536 in (fn <> L.take 1 ext <> f) : fs
537 maplib builder (map L.toStrict $ slurp fnn)
538 parseOBJ builder args bs'
502 "mt" -> -- mtllib 539 "mt" -> -- mtllib
503 case findNewLine [] args $ next 2 bs of 540 case findNewLine [] args $ next 2 bs of
504 (fnn,bs') -> do 541 (fnn,bs') -> do
@@ -513,7 +550,7 @@ parseOBJ builder args bs0
513 in (fn <> L.take 1 ext <> f) : fs 550 in (fn <> L.take 1 ext <> f) : fs
514 mtllib builder (map L.toStrict $ slurp fnn) 551 mtllib builder (map L.toStrict $ slurp fnn)
515 parseOBJ builder args bs' 552 parseOBJ builder args bs'
516 -- TODO: call,csh,c_interp,d_interp,lod,shadow_obj,trace_obj,bevel 553 -- TODO: call,csh,lod,shadow_obj,trace_obj,bevel
517 _ -> bad bs 554 _ -> bad bs
518 where 555 where
519 bs = findToken args bs0 556 bs = findToken args bs0