From 5bdb855e7143d13b05ac836978dd8e67017482df Mon Sep 17 00:00:00 2001 From: Marc Sunet Date: Sat, 1 Sep 2012 11:20:12 +0200 Subject: Replaced Rotation for an arbitrary axis --- Spear.lkshs | 6 ++-- Spear.lkshw | 4 +-- Spear/Math/MatrixUtils.hs | 26 ++++++--------- Spear/Scene/GameObject.hs | 81 +++++++++++++++++++++++------------------------ Spear/Scene/Loader.hs | 17 +++------- 5 files changed, 59 insertions(+), 75 deletions(-) diff --git a/Spear.lkshs b/Spear.lkshs index 4b0d469..3e07004 100644 --- a/Spear.lkshs +++ b/Spear.lkshs @@ -1,14 +1,14 @@ Version of session file format: 1 Time of storage: - "Fri Aug 31 22:25:44 CEST 2012" -Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 1, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [("Browser",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 302) 217),("Debug",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 1, detachedId = Nothing, detachedSize = Nothing}) 256)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 663) 954 + "Sat Sep 1 10:54:22 CEST 2012" +Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 1, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [("Browser",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 327) 235),("Debug",HorizontalP (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 1, detachedId = Nothing, detachedSize = Nothing}) 277)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 714) 954 Population: [(Just (BreakpointsSt BreakpointsState),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP BottomP]),(Just (ErrorsSt ErrorsState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Factory.hs" 1205)),[SplitP LeftP]),(Just (FilesSt FilesState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Scene/GameObject.hs" 3114)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject.hs" 1432)),[SplitP LeftP]),(Just (InfoSt (InfoState Nothing)),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Scene/Loader.hs" 17178)),[SplitP LeftP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Math/MatrixUtils.hs" 1235)),[SplitP LeftP]),(Just (ModulesSt (ModulesState 328 (PackageScope False,False) (Nothing,Nothing) (ExpanderState {packageExp = ([],[]), packageExpNoBlack = ([[0]],[]), packageDExp = ([],[]), packageDExpNoBlack = ([],[]), workspaceExp = ([],[]), workspaceExpNoBlack = ([],[]), workspaceDExp = ([],[]), workspaceDExpNoBlack = ([],[]), systemExp = ([],[]), systemExpNoBlack = ([],[])}))),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Player.hs" 2249)),[SplitP LeftP]),(Just (SearchSt (SearchState {searchString = "putStrLn", searchScope = PackageScope False, searchMode = Prefix {caseSense = False}})),[SplitP RightP,SplitP TopP]),(Just (TraceSt TraceState),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Utils.hs" 587)),[SplitP LeftP]),(Just (VariablesSt VariablesState),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP BottomP]),(Just (WorkspaceSt WorkspaceState),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP TopP]),(Just (BufferSt (BufferStateTrans "_Eval.hs" "\n" 0)),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP TopP])] Window size: (1820,944) Completion size: (750,399) Workspace: Just "/home/jeanne/programming/haskell/Spear/Spear.lkshw" -Active pane: Just "GameObject.hs" +Active pane: Just "Modules" Toolbar visible: True FindbarState: (False,FindState {entryStr = "986", entryHist = ["986","drawElements","56","drawArray","drawVA","f","SV","VAO","'VAO'","\170","\\","^"], replaceStr = "V3.", replaceHist = [], caseSensitive = True, entireWord = False, wrapAround = False, regex = False, lineNr = 1}) diff --git a/Spear.lkshw b/Spear.lkshw index 79c18ef..ff27127 100644 --- a/Spear.lkshw +++ b/Spear.lkshw @@ -1,10 +1,10 @@ Version of workspace file format: 1 Time of storage: - "Fri Aug 31 20:53:49 CEST 2012" + "Sat Sep 1 11:10:35 CEST 2012" Name of the workspace: "Spear" File paths of contained packages: ["demos/simple-scene/simple-scene.cabal","Spear.cabal"] Maybe file path of an active package: - Just "demos/simple-scene/simple-scene.cabal" \ No newline at end of file + Just "Spear.cabal" \ No newline at end of file diff --git a/Spear/Math/MatrixUtils.hs b/Spear/Math/MatrixUtils.hs index 2c1d083..dcc1965 100644 --- a/Spear/Math/MatrixUtils.hs +++ b/Spear/Math/MatrixUtils.hs @@ -1,7 +1,6 @@ module Spear.Math.MatrixUtils ( - Rotation(..) -, fastNormalMatrix + fastNormalMatrix , rpgTransform , pltTransform , rpgInverse @@ -16,9 +15,6 @@ import Spear.Math.Vector2 as V2 import Spear.Math.Vector3 as V3 -data Rotation = Yaw | Pitch | Roll deriving Eq - - -- | Compute the normal matrix of the given matrix. fastNormalMatrix :: Matrix4 -> Matrix3 fastNormalMatrix m = @@ -31,21 +27,17 @@ fastNormalMatrix m = -- | Maps the given 2D transformation matrix to a 3D transformation matrix. rpgTransform - :: Float -- ^ The height above the ground. - -> Float -- ^ Angle of rotation. - -> Rotation -- ^ How the 2D rotation should be interpreted in 3D. + :: Float -- ^ The height above the ground + -> Float -- ^ Angle of rotation + -> Vector3 -- ^ Axis of rotation -> Matrix3 -> Matrix4 -rpgTransform h a rtype mat = +rpgTransform h a axis mat = {-let r = let r' = M3.right mat in vec3 (V2.x r') (V2.y r') 0 u = V3.unity f = let f' = M3.forward mat in vec3 (V2.x f') 0 (V2.y f') t = (vec3 0 h 0) + let t' = M3.position mat in vec3 (V2.x t') 0 (V2.y t')-} - let rot = case rtype of - Yaw -> rotY - Pitch -> rotX - Roll -> rotZ - mat' = rot a + let mat' = axisAngle axis a r = M4.right mat' u = M4.up mat' f = M4.forward mat' @@ -79,9 +71,9 @@ pltTransform mat = -- -- Use this in games such as RPGs and RTSs. rpgInverse - :: Float -- ^ The height above the ground. - -> Float -- ^ Angle of rotation. - -> Rotation -- ^ How the 2D rotation should be interpreted in 3D. + :: Float -- ^ The height above the ground + -> Float -- ^ Angle of rotation + -> Vector3 -- ^ Axis of rotation -> Matrix3 -> Matrix4 rpgInverse h a rot = M4.inverseTransform . rpgTransform h a rot diff --git a/Spear/Scene/GameObject.hs b/Spear/Scene/GameObject.hs index f29ee09..d3b4e9e 100644 --- a/Spear/Scene/GameObject.hs +++ b/Spear/Scene/GameObject.hs @@ -3,7 +3,6 @@ module Spear.Scene.GameObject GameObject , GameStyle(..) , AM.AnimationSpeed -, Rotation(..) -- * Construction , goNew -- * Accessors @@ -54,10 +53,10 @@ data GameStyle -- | An object in the game scene. data GameObject = GameObject { gameStyle :: !GameStyle - , rotation :: !Rotation , renderer :: !(Either StaticModelRenderer AM.AnimatedModelRenderer) , collisioners :: ![Collisioner] , transform :: !M3.Matrix3 + , axis :: Vector3 , angle :: Float } @@ -136,17 +135,17 @@ instance S2.Spatial2 GameObject where -- | Create a new game object. goNew :: GameStyle - -> Rotation -> Either StaticModelResource AM.AnimatedModelResource -> [Collisioner] - -> M3.Matrix3 + -> M3.Matrix3 -- ^ Transform + -> Vector3 -- ^ Axis of rotation -> GameObject -goNew style rtype (Left smr) cols transf = - GameObject style rtype (Left $ SM.staticModelRenderer smr) cols transf 0 +goNew style (Left smr) cols transf axis = + GameObject style (Left $ SM.staticModelRenderer smr) cols transf axis 0 -goNew style rtype (Right amr) cols transf = - GameObject style rtype (Right $ AM.animatedModelRenderer 1 amr) cols transf 0 +goNew style (Right amr) cols transf axis = + GameObject style (Right $ AM.animatedModelRenderer 1 amr) cols transf axis 0 goUpdate :: Float -> GameObject -> GameObject @@ -160,6 +159,25 @@ goUpdate dt go = } +-- | Get the game object's ith bounding box. +goAABB :: Int -> GameObject -> AABB +goAABB i go = goAABB' $ (collisioners go) !! i + +goAABB' col = case col of + (AABBCol box) -> box + (CircleCol circle) -> aabbFromCircle circle + + +-- | Get the game object's bounding boxes. +goAABBs :: GameObject -> [AABB] +goAABBs = fmap goAABB' . collisioners + + +-- | Get the game object's 3D transform. +go3Dtransform :: GameObject -> M4.Matrix4 +go3Dtransform go = rpgTransform 0 (angle go) (axis go) . S2.transform $ go + + -- | Get the game object's current animation. currentAnimation :: Enum a => GameObject -> a currentAnimation go = case renderer go of @@ -167,6 +185,11 @@ currentAnimation go = case renderer go of Right amr -> AM.currentAnimation amr +-- | Return the game object's number of collisioners. +numCollisioners :: GameObject -> Int +numCollisioners = length . collisioners + + -- | Set the game object's current animation. setAnimation :: Enum a => a -> GameObject -> GameObject setAnimation a go = case renderer go of @@ -181,38 +204,14 @@ setAnimationSpeed s go = case renderer go of Right amr -> go { renderer = Right $ AM.setAnimationSpeed s amr } --- | Return the game object's number of collisioners. -numCollisioners :: GameObject -> Int -numCollisioners = length . collisioners - - --- | Manipulate the game object's collisioners. -withCollisioners :: GameObject -> ([Collisioner] -> [Collisioner]) -> GameObject -withCollisioners go f = go { collisioners = f $ collisioners go } - - -- | Set the game object's collisioners. setCollisioners :: GameObject -> [Collisioner] -> GameObject setCollisioners go cols = go { collisioners = cols } --- | Get the game object's ith bounding box. -goAABB :: Int -> GameObject -> AABB -goAABB i go = goAABB' $ (collisioners go) !! i - -goAABB' col = case col of - (AABBCol box) -> box - (CircleCol circle) -> aabbFromCircle circle - - --- | Get the game object's bounding boxes. -goAABBs :: GameObject -> [AABB] -goAABBs = fmap goAABB' . collisioners - - --- | Get the game object's 3D transform. -go3Dtransform :: GameObject -> M4.Matrix4 -go3Dtransform go = rpgTransform 0 (angle go) (rotation go) . S2.transform $ go +-- | Manipulate the game object's collisioners. +withCollisioners :: GameObject -> ([Collisioner] -> [Collisioner]) -> GameObject +withCollisioners go f = go { collisioners = f $ collisioners go } -- | Render the game object. @@ -222,13 +221,13 @@ goRender sprog aprog cam go = apu = animatedProgramUniforms aprog mat = S2.transform go style = gameStyle go - rtype = rotation go + axis' = axis go a = angle go in case renderer go of Left smr -> - goRender' style a rtype sprog spu mat cam (SM.bind spu smr) (SM.render spu smr) + goRender' style a axis' sprog spu mat cam (SM.bind spu smr) (SM.render spu smr) Right amr -> - goRender' style a rtype aprog apu mat cam (AM.bind apu amr) (AM.render apu amr) + goRender' style a axis' aprog apu mat cam (AM.bind apu amr) (AM.render apu amr) type Bind = IO () @@ -239,7 +238,7 @@ type Render = IO () goRender' :: (ProgramUniforms u, Program p) => GameStyle -> Float - -> Rotation + -> Vector3 -> p -> u -> M3.Matrix3 @@ -247,10 +246,10 @@ goRender' :: (ProgramUniforms u, Program p) -> Bind -> Render -> IO () -goRender' style a rtype prog uniforms model cam bindRenderer render = +goRender' style a axis prog uniforms model cam bindRenderer render = let view = M4.inverseTransform $ Cam.transform cam modelview = case style of - RPG -> view * rpgTransform 0 a rtype model + RPG -> view * rpgTransform 0 a axis model PLT -> view * pltTransform model normalmat = fastNormalMatrix modelview in do diff --git a/Spear/Scene/Loader.hs b/Spear/Scene/Loader.hs index ea08385..f5d06a6 100644 --- a/Spear/Scene/Loader.hs +++ b/Spear/Scene/Loader.hs @@ -31,7 +31,7 @@ import Spear.Render.AnimatedModel as AM import Spear.Render.Material import Spear.Render.Program import Spear.Render.StaticModel as SM -import qualified Spear.Scene.GameObject as GO +import Spear.Scene.GameObject as GO import Spear.Scene.Graph import Spear.Scene.Light import Spear.Scene.SceneResources @@ -342,18 +342,18 @@ newLight _ = return () -- Object Loading -- -------------------- -loadGO :: GO.GameStyle -> SceneResources -> [Property] -> Matrix3 -> Setup GO.GameObject +loadGO :: GameStyle -> SceneResources -> [Property] -> Matrix3 -> Setup GameObject loadGO style sceneRes props transf = do modelName <- asString . mandatory "model" $ props - rtype <- asGORotation . mandatory "rotation" $ props + axis <- asVec3 . mandatory "axis" $ props let animSpeed = asFloat . value "animation-speed" $ props go <- case getAnimatedModel sceneRes modelName of Just model -> - return $ GO.goNew style rtype (Right model) [] transf + return $ goNew style (Right model) [] transf axis Nothing -> case getStaticModel sceneRes modelName of Just model -> - return $ GO.goNew style rtype (Left model) [] transf + return $ goNew style (Left model) [] transf axis Nothing -> setupError $ "model " ++ modelName ++ " not found" return $ case animSpeed of @@ -467,13 +467,6 @@ asRotation val = fmap parseRotation val where parseRotation (ax:ay:az:order:_) = Rotation (read ax) (read ay) (read az) (readOrder order) -asGORotation :: Functor f => f [String] -> f GO.Rotation -asGORotation val = fmap parseRotation val - where parseRotation ["yaw"] = GO.Yaw - parseRotation ["pitch"] = GO.Pitch - parseRotation ["roll"] = GO.Roll - - data Rotation = Rotation { ax :: Float , ay :: Float -- cgit v1.2.3