handa-opengl-0.1.6.1: src/Graphics/Rendering/Handa/Face.hs
{-|
Module : Graphics.Rendering.Handa.Face
Copyright : (c) 2015 Brian W Bush
License : MIT
Maintainer : Brian W Bush <consult@brianwbush.info>
Stability : Stable
Portability : Portable
Functions and types for managing objects represented as collections of faces.
-}
module Graphics.Rendering.Handa.Face (
-- * Types
Face
, Edges
, faceToEdges
-- * Rendering
, drawFaces
, drawFrame
-- * Particular Objects
, coneFaces
, brickFaces
) where
import Graphics.Rendering.Handa.Util (cosd, sind, vertex3)
import Graphics.Rendering.OpenGL.GL (PrimitiveMode(..), VertexComponent, renderPrimitive)
-- | Edges are paired series of triple of vertex components.
type Edges a = [(a, a, a)]
-- | A face is a collections of the vertices on its boundary.
type Face a = [(a, a, a)]
-- | Convert a face to a
faceToEdges :: Face a -> Edges a
faceToEdges face = concat $ zipWith ((. return) . (:)) (init face) (tail face)
-- | Draw faces.
drawFaces :: (Num a, VertexComponent a)
=> [Face a] -- ^ The faces.
-> IO () -- ^ An action to draw the faces.
drawFaces = renderPrimitive Quads . mapM_ vertex3 . concat
-- | Draw the frame around faces.
drawFrame :: (Num a, VertexComponent a)
=> [Face a] -- ^ The faces.
-> IO () -- ^ An action to draw the frame of the faces' edges.
drawFrame = renderPrimitive Lines . mapM_ vertex3 . concatMap faceToEdges
-- | The faces of a truncated cone that has its tip at the origin and points towards the negative z axis.
coneFaces :: (Enum a, Floating a, VertexComponent a)
=> Int -- ^ The number of faces around the cone.
-> a -- ^ The height of the cone.
-> a -- ^ The radius of the cone.
-> [Face a] -- ^ Faces representing the cone.
coneFaces n height radius =
let
point = (0, 0, 0)
center = (0, 0, height)
rim = [(radius * cosd x, radius * sind x, height) | x <- [0,(360 / fromIntegral n)..360]]
in
[
[p0, p1, p2]
|
(p1, p2) <- zip (tail rim) (init rim)
, p0 <- [point, center]
]
-- | The faces of a brick that has one corner at the origin.
brickFaces :: Num a
=> a -- ^ The x (width) dimension of the brick.
-> a -- ^ The y (height) dimension of the brick.
-> a -- ^ The z (depth) dimension of the brick.
-> [Face a] -- ^ Faces representing the brick.
brickFaces w h d =
[[(0, 0, z), (w, 0, z), (w, h, z), (0, h, z)] | z <- [0, d]]
++
[[(0, y, 0), (w, y, 0), (w, y, d), (0, y, d)] | y <- [0, h]]
++
[[(x, 0, 0), (x, h, 0), (x, h, d), (x, 0, d)] | x <- [0, w]]