2014-04-22 01:27:01 +02:00
|
|
|
{-# LANGUAGE RankNTypes #-}
|
|
|
|
module Render.Types (createFlatCam, createSphereCam, Camera, GLCamera(..)) where
|
|
|
|
|
|
|
|
import Linear
|
|
|
|
import Foreign.C (CFloat)
|
|
|
|
import Render.Misc (lookAt)
|
2014-05-15 15:10:10 +02:00
|
|
|
import Map.Map (giveMapHeight)
|
|
|
|
import Map.Types (PlayMap)
|
|
|
|
import GHC.Float
|
|
|
|
import qualified Debug.Trace as D
|
2014-04-22 01:27:01 +02:00
|
|
|
|
|
|
|
type Distance = Double
|
|
|
|
type Pitch = Double
|
|
|
|
type Yaw = Double
|
|
|
|
|
|
|
|
class GLCamera a where
|
|
|
|
getCam :: a -> Distance -> Pitch -> Yaw -> M44 CFloat
|
2014-05-15 15:10:10 +02:00
|
|
|
moveBy :: a -> (Position -> Position) -> PlayMap -> a
|
|
|
|
move :: a -> Position -> PlayMap -> a
|
2014-04-22 01:27:01 +02:00
|
|
|
|
|
|
|
type Position = (Double, Double)
|
|
|
|
|
|
|
|
type Radius = Double
|
|
|
|
|
2014-05-15 15:10:10 +02:00
|
|
|
type Height = Double
|
|
|
|
|
|
|
|
data Camera = Flat Position Height
|
2014-04-22 01:27:01 +02:00
|
|
|
| Sphere Position Radius
|
|
|
|
|
|
|
|
-- | create a Flatcam-Camera starting at given x/z-Coordinates
|
2014-05-15 15:10:10 +02:00
|
|
|
createFlatCam :: Double -> Double -> PlayMap -> Camera
|
2014-05-16 17:26:40 +02:00
|
|
|
createFlatCam x z map' = Flat (x,z) (giveMapHeight map' (x, z))
|
2014-04-22 01:27:01 +02:00
|
|
|
|
|
|
|
-- | create a Flatcam-Camera starting at given pitch/azimuth/radius
|
|
|
|
createSphereCam :: Double -> Double -> Double -> Camera
|
2014-05-15 15:10:10 +02:00
|
|
|
createSphereCam p a = Sphere (p,a)
|
2014-04-22 01:27:01 +02:00
|
|
|
|
|
|
|
|
|
|
|
instance GLCamera Camera where
|
2014-05-15 15:10:10 +02:00
|
|
|
getCam (Flat (x',z') y') dist' xa' ya' =
|
2014-04-22 01:27:01 +02:00
|
|
|
lookAt (cpos ^+^ at') at' up
|
|
|
|
where
|
2014-05-16 19:06:05 +02:00
|
|
|
at' = V3 x (y+2) z
|
2014-04-22 01:27:01 +02:00
|
|
|
cpos = crot !* (V3 0 0 (-dist))
|
|
|
|
crot = (
|
|
|
|
(fromQuaternion $ axisAngle upmap (xa::CFloat))
|
|
|
|
!*!
|
|
|
|
(fromQuaternion $ axisAngle (V3 0 1 0) (ya::CFloat))
|
|
|
|
) ::M33 CFloat
|
|
|
|
upmap = ((fromQuaternion $ axisAngle (V3 0 1 0) (ya::CFloat)) :: M33 CFloat)
|
|
|
|
!* (V3 1 0 0)
|
|
|
|
x = realToFrac x'
|
2014-05-15 15:10:10 +02:00
|
|
|
y = realToFrac y'
|
2014-04-22 01:27:01 +02:00
|
|
|
z = realToFrac z'
|
|
|
|
dist = realToFrac dist'
|
|
|
|
xa = realToFrac xa'
|
|
|
|
ya = realToFrac ya'
|
|
|
|
up = V3 0 1 0
|
|
|
|
getCam (Sphere (inc',az') r') dist' xa' ya' = --inclination (pitch), azimuth (yaw)
|
|
|
|
lookAt (cpos ^+^ at') at' up
|
|
|
|
where
|
|
|
|
at' = sphereToCart r inc az
|
|
|
|
cpos = crot !* (V3 0 0 (-dist))
|
|
|
|
crot = (
|
|
|
|
(fromQuaternion $ axisAngle upmap (xa::CFloat))
|
|
|
|
!*!
|
|
|
|
(fromQuaternion $ axisAngle (V3 0 1 0) (ya::CFloat))
|
|
|
|
) ::M33 CFloat
|
|
|
|
upmap = ((fromQuaternion $ axisAngle (V3 0 1 0) (ya::CFloat)) :: M33 CFloat)
|
|
|
|
!* (V3 1 0 0)
|
|
|
|
up = (sphereToCart (r+1) inc az) ^-^ at'
|
|
|
|
r = realToFrac r'
|
|
|
|
inc = realToFrac inc'
|
|
|
|
az = realToFrac az'
|
|
|
|
dist = realToFrac dist'
|
|
|
|
xa = realToFrac xa'
|
|
|
|
ya = realToFrac ya'
|
2014-05-15 15:10:10 +02:00
|
|
|
moveBy (Sphere (inc, az) r) f map = undefined
|
2014-05-16 17:26:40 +02:00
|
|
|
moveBy (Flat (x', z') y) f map = Flat (x,z) y
|
2014-05-15 15:10:10 +02:00
|
|
|
where
|
|
|
|
(x,z) = f (x', z')
|
2014-05-16 17:26:40 +02:00
|
|
|
y = giveMapHeight map (x,z)
|
2014-05-15 15:10:10 +02:00
|
|
|
move c (x', z') map = moveBy c (\(x,z) -> (x+x',z+z')) map
|
2014-04-22 01:27:01 +02:00
|
|
|
|
|
|
|
sphereToCart :: (Floating a) => a -> a -> a -> V3 a
|
|
|
|
sphereToCart r inc az = V3
|
|
|
|
(r * (sin inc) * (cos az))
|
|
|
|
(r * (sin inc) * (sin az))
|
2014-05-15 15:10:10 +02:00
|
|
|
(r * (cos inc))
|