{-# LANGUAGE GADTs, KindSignatures, DataKinds, ScopedTypeVariables, TypeOperators, FlexibleContexts #-} module Graphics.Rendering.Ombra.Geometry ( Geometry, Vertex(..), Triangle(..), mkGeometry, mapVertices, removeAttribute, decompose, -- * Geometry builder Attributes, AttrVertex, GeometryBuilder, GeometryBuilderT, vertex, triangle, buildGeometry, buildGeometryT, -- * 2D and 3D geometries D2.Geometry2D, D3.Geometry3D, mkGeometry2D, mkGeometry3D, mkGeometry2D', mkGeometry3D', vertex2D, vertex3D ) where import Control.Monad import Control.Monad.ST import Data.Foldable (foldrM) import Data.Hashable import Data.Proxy import Data.Word (Word16) import qualified Data.HashTable.ST.Basic as H import Graphics.Rendering.Ombra.Backend (GLES) import Graphics.Rendering.Ombra.Internal.TList (Append) import Graphics.Rendering.Ombra.Geometry.Internal import Graphics.Rendering.Ombra.Geometry.Types import Graphics.Rendering.Ombra.Shader.CPU import Graphics.Rendering.Ombra.Shader.Default2D (Position2) import Graphics.Rendering.Ombra.Shader.Default3D (Position3, Normal3) import qualified Graphics.Rendering.Ombra.Shader.Default2D as D2 import qualified Graphics.Rendering.Ombra.Shader.Default3D as D3 import Graphics.Rendering.Ombra.Vector -- | Create a 3D 'Geometry'. mkGeometry3D :: GLES => [Triangle (Vec3, Vec2, Vec3)] -- ^ (Position, UV, Normal) -> Geometry D3.Geometry3D mkGeometry3D = mkGeometry . map (fmap $ \(v, u, n) -> mkVertex3D v u n) -- | Create an extended 3D 'Geometry'. mkGeometry3D' :: (GLES, Attributes (Append (i ': is) D3.Geometry3D)) => [Triangle (Vertex (i ': is), Vec3, Vec2, Vec3)] -> Geometry (Append (i ': is) D3.Geometry3D) mkGeometry3D' = mkGeometry . map (fmap $ \(e, v, u, n) -> extend e $ mkVertex3D v u n) -- | Create a 2D 'Geometry'. mkGeometry2D :: GLES => [Triangle (Vec2, Vec2)] -- ^ (Position, Texture UV coordinates) -> Geometry D2.Geometry2D mkGeometry2D = mkGeometry . map (fmap $ \(v, u) -> mkVertex2D v u) -- | Create an extended 2D 'Geometry'. mkGeometry2D' :: (GLES, Attributes (Append (i ': is) D2.Geometry2D)) => [Triangle (Vertex (i ': is), Vec2, Vec2)] -> Geometry (Append (i ': is) D2.Geometry2D) mkGeometry2D' = mkGeometry . map (fmap $ \(e, v, u) -> extend e $ mkVertex2D v u) -- | Create a new 2D vertex. vertex2D :: (GLES, Monad m) => Vec2 -> Vec2 -> GeometryBuilderT D2.Geometry2D m (AttrVertex D2.Geometry2D) vertex2D p u = vertex $ mkVertex2D p u -- | Create a new 3D vertex. vertex3D :: (GLES, Monad m) => Vec3 -> Vec2 -> Vec3 -> GeometryBuilderT D3.Geometry3D m (AttrVertex D3.Geometry3D) vertex3D p u n = vertex $ mkVertex3D p u n mkVertex3D :: GLES => Vec3 -> Vec2 -> Vec3 -> Vertex D3.Geometry3D mkVertex3D p u n = Attr D3.Position3 p :~ Attr D3.UV u :~ Attr D3.Normal3 n mkVertex2D :: GLES => Vec2 -> Vec2 -> Vertex D2.Geometry2D mkVertex2D p u = Attr D2.Position2 p :~ Attr D2.UV u extend :: Vertex is -> Vertex is' -> Vertex (Append is is') extend (Attr c x) v = Attr c x :~ v extend (Attr c x :~ v') v = Attr c x :~ extend v' v