module Main where import Control.Monad import Graphics.Ogre.HOgre import Graphics.Ogre.Types import Common -- based on intermediate tutorial 1 from Ogre Wiki. -- http://www.ogre3d.org/tikiwiki/Intermediate+Tutorial+1&structure=Tutorials main :: IO () main = do _ <- generalSetup $ \root -> do smgr <- root_getSceneManager root "Scene Manager" cam <- sceneManager_getCamera smgr "PlayerCam" -- set ambient light colourValue_with 1 1 1 1 $ sceneManager_setAmbientLight smgr (robotEntity, robotNode) <- addEntity smgr "robot.mesh" let (initx, initz) = initPos node_translate_NodePfloatfloatfloatNodeTransformSpace (toNode robotNode) initx 0 initz TS_WORLD anim <- entity_getAnimationState robotEntity "Walk" animationState_setLoop anim True animationState_setEnabled anim True addKnot smgr 0 (-10) 25 addKnot smgr 550 (-10) 50 addKnot smgr (-100) (-10) (-200) camera_setPosition_CameraPfloatfloatfloat cam 90 280 535 -- camera_lookAt cam 0 0 30 radian_with_float (-0.52359) $ camera_pitch cam radian_with_float (-0.26179) $ camera_yaw cam window <- root_getAutoCreatedWindow root render window root (initState robotEntity robotNode) handler return () type OgreState = (Entity, SceneNode, (Float, Float), [(Float, Float)]) initPos :: (Float, Float) initPos = (0, 25) initState :: Entity -> SceneNode -> OgreState initState e n = (e, n, initPos, cycle [(550, 50), (-100, -200), (0, 25)]) handler :: Root -> Float -> OgreState -> IO (OgreState, Bool) handler _ delta (ent, node, (locx, locz), wl) = do let (wx, wz) = head wl dist <- vector3_with_floatfloatfloat locx 0 locz $ \locv -> vector3_with_floatfloatfloat wx 0 wz $ vector3_distance locv let wl' = if dist <= 30 then tail wl else wl (tgtx, tgtz) = head wl' ang = atan2 (locz - tgtz) (locx - tgtx) locx' = locx - 35 * delta * cos ang locz' = locz - 35 * delta * sin ang when (dist > 150) $ vector3_with_floatfloatfloat tgtx 0 tgtz $ \v1 -> vector3_with_floatfloatfloat 1 0 0 $ \v -> sceneNode_lookAt node v1 TS_WORLD v node_setPosition (toNode node) locx' 0 locz' anim <- entity_getAnimationState ent "Walk" animationState_addTime anim delta return ((ent, node, (locx', locz'), wl'), True) addKnot :: SceneManager -> Float -> Float -> Float -> IO () addKnot smgr v1 v2 v3 = do (_, knot) <- addEntity smgr "knot.mesh" node_translate_NodePfloatfloatfloatNodeTransformSpace (toNode knot) v1 v2 v3 TS_WORLD node_setScale (toNode knot) 0.1 0.1 0.1