{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances, FunctionalDependencies #-}
module Main
where
import Control.Monad (when)
import qualified Graphics.UI.SDL as SDL
import Graphics.Ogre.Ogre
import Common
robotTemplate :: String -> Vector3 -> Entity
robotTemplate swname pos = Entity swname pos (StdMesh "robot.mesh" (YPR halfPI 0.0 0.0)) True (Vector3 0.2 0.2 0.2)
initGame :: IO ()
initGame = do
let set = OgreSettings "resources.cfg" False "Hogre Example 03" (Color 0.9 0.9 0.9) StencilModulative [ExteriorClose]
let cam = Camera (Vector3 242.0 120.0 580) 0 (Vector3 241 120 580)
let (wid, hei) = (1024, 768)
let sce = OgreScene cam [] []
_ <- SDL.setVideoMode wid hei 16 [SDL.OpenGL, SDL.HWAccel]
SDL.wasInit [SDL.InitEverything] >>= print
initOgre set
addScene sce
setSkyDome (Just ("Examples/CloudySky", 5))
setWorldGeometry "terrain.cfg"
main :: IO ()
main = runWithSDL initGame (0, EventCallback query, FrameCallback (\v -> return v))
getLMB :: IO (Maybe (Int, Int))
getLMB = do
(xpos, ypos, btns) <- SDL.getMouseState
return $ case SDL.ButtonLeft `elem` btns of
True -> Just (xpos, ypos)
False -> Nothing
getLMBPressed :: [SDL.Event] -> Maybe (Int, Int)
getLMBPressed [] = Nothing
getLMBPressed (e:es) = case e of
(SDL.MouseButtonDown xp yp SDL.ButtonLeft) -> Just ((fromIntegral xp), (fromIntegral yp))
_ -> getLMBPressed es
query :: Int -> [SDL.Event] -> IO Int
query counter events = do
cameraAboveGround
putObject counter events
cameraAboveGround :: IO ()
cameraAboveGround = do
(Vector3 camx camy camz) <- getCameraPosition
mres <- raySceneQuerySimple (Vector3 camx 5000 camz) negUnitY
case mres of
Nothing -> return ()
Just res -> when ((y res) + 10 > camy) $ setCameraPosition (Vector3 camx ((y res) + 10) camz)
putObject :: Int -> [SDL.Event] -> IO Int
putObject counter events = do
let mp = getLMBPressed events
case mp of
Nothing -> return counter
Just (xpos, ypos) -> do
scr <- SDL.getVideoSurface
let wid = SDL.surfaceGetWidth scr
let hei = SDL.surfaceGetHeight scr
print (xpos, ypos, wid, hei)
let wabs = (fromIntegral xpos) / (fromIntegral wid)
let habs = (fromIntegral ypos) / (fromIntegral hei)
pres <- raySceneQueryMouseSimple wabs habs
case pres of
Nothing -> return counter
Just (Vector3 resx resy resz) -> do
let swname = "robot" ++ (show counter)
let pos = Vector3 resx (resy + 10) resz
addEntity (robotTemplate swname pos)
print swname
return (counter + 1)