Skip to content

Instantly share code, notes, and snippets.

@scan
Created July 13, 2012 18:02
Show Gist options
  • Save scan/3106343 to your computer and use it in GitHub Desktop.
Save scan/3106343 to your computer and use it in GitHub Desktop.
{-# LANGUAGE TemplateHaskell, QuasiQuotes, OverloadedStrings #-}
module Loader.Obj where
import Control.Applicative ((<$>), (<*>))
import Data.Vect.Float
import System.IO (readFile)
import Text.Parsec
import qualified Text.Parsec.Token as P
import Text.Parsec.Language (haskellDef)
data Vertex = Vertex !Vec3 !Vec3
deriving (Show)
data Face = Tri !Int !Int !Int
| Quad !Int !Int !Int !Int
deriving (Show)
data Mesh = Mesh [Face] [Vertex]
deriving (Show)
test = do
cnt <- readFile "data/tst.obj"
parseTest pMesh cnt
loadFile f = do
cnt <- readFile f
return cnt
pMesh = do
vecs <- pVecs
normals <- pNormals
faces <- pFaces
return $ Mesh faces $ zipWith Vertex vecs normals
lexer = P.makeTokenParser haskellDef
float = P.float lexer
lexeme = P.lexeme lexer
natural = P.natural lexer
float' = do s <- sign; s <$> float
negative = char '-' >> return negate
sign = try negative <|> return id
pVecs = sepBy pVec newline
pNormals = sepBy pNormal newline
pFaces = sepBy pFace newline
pVec = do
lexeme $ char 'v'
x <- lexeme float'
y <- lexeme float'
z <- lexeme float'
return $ Vec3 (realToFrac x) (realToFrac y) (realToFrac z)
pNormal = do
lexeme $ string "vn"
x <- lexeme float'
y <- lexeme float'
z <- lexeme float'
return $ Vec3 (realToFrac x) (realToFrac y) (realToFrac z)
pIndex = do
spaces
i <- natural
string "//"
j <- natural
return $ fromIntegral i
pFace = (try pTri) <|> pQuad
pTri = do
char 'f'
spaces
Tri <$> pIndex <*> pIndex <*> pIndex
pQuad = do
char 'f'
spaces
Quad <$> pIndex <*> pIndex <*> pIndex <*> pIndex
@jfischoff
Copy link

data Index = Index Int Int

data Face2 = Tri Index Index Index

pIndex = do
spaces
i <- natural
string '//'
j <- natural
return $ Index i j

pFaces = do
char 'f'
spaces
Face2 <$> pIndex <> pIndex <> pIndex

@jfischoff
Copy link

Just got back from lunch, saw your message. You probably need a 'spaces' somewhere

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment