ply-loader-0.1.0.0: src/PLY/Conf.hs
{-# LANGUAGE OverloadedStrings #-}
-- |Parse Stanford 3D Scanning Repository ".conf" files that place
-- individual PLY models into a consistent coordinate frame.
module PLY.Conf (parseConf, Transformation, Conf(..)) where
import Control.Applicative
import Data.Attoparsec.Char8
import Data.ByteString (ByteString)
import Linear.V3
import Linear.Quaternion
import PLY.Internal.Parsers (line, word)
-- | A 3D transformation represented as a translation vector and a
-- rotation.
type Transformation a = (V3 a, Quaternion a)
-- |A @.conf@ file includes a base transformation matrix, and a
-- list of meshes identified by their file name and a 'Transformation'
-- to place geometry in a consistent coordinate frame.
data Conf = Conf { camera :: Transformation Double
, meshes :: [(ByteString, Transformation Double)] }
deriving Show
-- |Parse a 3D translation vector followed by a quaternion.
transformation :: Parser (V3 Double, Quaternion Double)
transformation = (,) <$> vec <*> rotation
where vec = (\[x,y,z] -> V3 x y z) <$> count 3 (skipSpace *> double)
rotation = Quaternion <$> (skipSpace *> double) <*> vec
-- |Parse a mesh file specification.
mesh :: Parser (ByteString, Transformation Double)
mesh = (,) <$> ("bmesh " .*> word) <*> transformation
-- |Parser for a Stanford .conf file.
conf :: Parser Conf
conf = Conf <$> ("camera " .*> transformation <* skipSpace)
<*> (skipSpace *> cybmesh *> many1 (skipSpace *> mesh))
where cybmesh = skipMany ("mesh " .*> line) -- Not a PLY file!
-- |Parse a Stanford .conf file.
parseConf :: ByteString -> Either String Conf
parseConf = parseOnly conf