From fa3e0779521777b94aa1649b81222693150b5299 Mon Sep 17 00:00:00 2001 From: Marc Sunet Date: Mon, 3 Sep 2012 12:42:45 +0200 Subject: 2d virtual = view --- Spear.lkshs | 10 ++++----- Spear.lkshw | 2 +- Spear/Math/MatrixUtils.hs | 50 +++++++++++++++++++----------------------- Spear/Scene/GameObject.hs | 56 +++++++++++++++++++++++++++++------------------ 4 files changed, 64 insertions(+), 54 deletions(-) diff --git a/Spear.lkshs b/Spear.lkshs index 646bfd8..9d57ffa 100644 --- a/Spear.lkshs +++ b/Spear.lkshs @@ -1,9 +1,9 @@ Version of session file format: 1 Time of storage: - "Sun Sep 2 11:03:47 CEST 2012" -Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 9, 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}) 310) 222),("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}) 264)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 682) 954 -Population: [(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/AnimatedGO.hs" 451)),[SplitP LeftP]),(Just (BreakpointsSt BreakpointsState),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Collision.hs" 5042)),[SplitP LeftP]),(Just (ErrorsSt ErrorsState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Factory.hs" 1371)),[SplitP LeftP]),(Just (FilesSt FilesState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Scene/GameObject.hs" 3988)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject.hs" 797)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameState.hs" 891)),[SplitP LeftP]),(Just (InfoSt (InfoState Nothing)),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP BottomP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Math/MatrixUtils.hs" 0)),[SplitP LeftP]),(Just (ModulesSt (ModulesState 328 (PackageScope False,False) (Nothing,Nothing) (ExpanderState {packageExp = ([],[]), packageExpNoBlack = ([],[]), 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" 741)),[SplitP LeftP]),(Just (SearchSt (SearchState {searchString = "putStrLn", searchScope = PackageScope False, searchMode = Prefix {caseSense = False}})),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/StaticGO.hs" 434)),[SplitP LeftP]),(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" 629)),[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]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.hs" 4434)),[SplitP LeftP])] + "Mon Sep 3 00:01:24 CEST 2012" +Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 4, 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}) 346) 184),("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}) 265)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 688) 954 +Population: [(Just (BreakpointsSt BreakpointsState),[SplitP RightP,SplitP TopP,GroupP "Debug",SplitP BottomP]),(Just (ErrorsSt ErrorsState),[SplitP RightP,SplitP TopP]),(Just (FilesSt FilesState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Scene/GameObject.hs" 217)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject.hs" 2615)),[SplitP LeftP]),(Just (InfoSt (InfoState Nothing)),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP BottomP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Math/MatrixUtils.hs" 1873)),[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" 858)),[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" 471)),[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]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.hs" 4657)),[SplitP LeftP])] Window size: (1820,944) Completion size: (750,399) @@ -11,8 +11,8 @@ Workspace: Just "/home/jeanne/programming/haskell/Spear/Spear.lkshw" Active pane: Just "Utils.hs" 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}) +FindbarState: (False,FindState {entryStr = "asdad", entryHist = ["asdad","m[15]","m[14]","m[1]","m[13]","m[12]","m[11]","m[10]","m[9]","m[8]","m[7]","m[6]"], replaceStr = "a01", replaceHist = [], caseSensitive = True, entireWord = False, wrapAround = False, regex = False, lineNr = 1}) Recently opened files: - ["/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Utils.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/StaticGO.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/AnimatedGO.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Player.hs","/home/jeanne/programming/haskell/Spear/Spear/Math/Matrix4.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameState.hs","/home/jeanne/programming/haskell/Spear/Spear/Math/AABB.hs","/home/jeanne/programming/haskell/Spear/Spear/Collision.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Factory.hs","/home/jeanne/programming/haskell/Spear/Spear/Scene/Scene.hs","/home/jeanne/programming/haskell/Spear/Spear/Math/Entity.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/Program/Box.hs"] + ["/home/jeanne/programming/haskell/Spear/Spear/Math/Camera.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Factory.hs","/home/jeanne/programming/haskell/Spear/Spear/Math/Matrix3.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/Program/Box.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/Program/Line.hs","/home/jeanne/programming/haskell/Spear/Spear/Math/MatrixUtils.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Utils.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/StaticGO.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/AnimatedGO.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Player.hs","/home/jeanne/programming/haskell/Spear/Spear/Math/Matrix4.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameState.hs"] Recently opened workspaces: ["/home/jeanne/programming/haskell/hagen/hagen.lkshw","/home/jeanne/programming/haskell/foo/foo.lkshw","/home/jeanne/programming/haskell/Spear/Spear.lkshw","/home/jeanne/programming/haskell/nexus/nexus.lkshw","/home/jeanne/leksah.lkshw"] \ No newline at end of file diff --git a/Spear.lkshw b/Spear.lkshw index a54198c..fce08ab 100644 --- a/Spear.lkshw +++ b/Spear.lkshw @@ -1,7 +1,7 @@ Version of workspace file format: 1 Time of storage: - "Sun Sep 2 15:36:42 CEST 2012" + "Mon Sep 3 11:26:24 CEST 2012" Name of the workspace: "Spear" File paths of contained packages: diff --git a/Spear/Math/MatrixUtils.hs b/Spear/Math/MatrixUtils.hs index 44af2c0..87d84e5 100644 --- a/Spear/Math/MatrixUtils.hs +++ b/Spear/Math/MatrixUtils.hs @@ -5,7 +5,7 @@ module Spear.Math.MatrixUtils , pltTransform , rpgInverse , pltInverse -, toClip +, objToClip ) where @@ -27,31 +27,28 @@ fastNormalMatrix m = (M4.m02 m') (M4.m12 m') (M4.m22 m') --- | Maps the given 2D transformation matrix to a 3D transformation matrix. +-- | Map an object's transform in view space to world space. rpgTransform - :: Float -- ^ The height above the ground - -> Float -- ^ Angle of rotation - -> Vector3 -- ^ Axis of rotation - -> Vector2 -- ^ Object's position. + :: Float -- ^ The height above the ground + -> Float -- ^ Angle of rotation + -> Vector3 -- ^ Axis of rotation + -> Vector2 -- ^ Object's position. + -> Matrix4 -- ^ Inverse view matrix. -> Matrix4 -rpgTransform h a axis pos = - {-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')-} +rpgTransform h a axis pos viewInverse = let mat' = axisAngle axis a r = M4.right mat' u = M4.up mat' f = M4.forward mat' t = vec3 0 h 0 + vec3 (V2.x pos) 0 (-V2.y pos) in mat4 - (V3.x r) (V3.x u) (V3.x f) (V3.x t) - (V3.y r) (V3.y u) (V3.y f) (V3.y t) - (V3.z r) (V3.z u) (V3.z f) (V3.z t) - 0 0 0 1 + (V3.x r) (V3.x u) (V3.x f) (V3.x t) + (V3.y r) (V3.y u) (V3.y f) (V3.y t) + (V3.z r) (V3.z u) (V3.z f) (V3.z t) + 0 0 0 1 --- | Maps the given 2D transformation matrix to a 3D transformation matrix. +-- | Map an object's transform in view space to world space. pltTransform :: Matrix3 -> Matrix4 pltTransform mat = let r = let r' = M3.right mat in vec3 (V2.x r') (V2.y r') 0 @@ -65,23 +62,22 @@ pltTransform mat = 0 0 0 1 --- | Compute the inverse transform of the given transformation matrix. --- --- This function maps an object's transform in 2D to the object's inverse in 3D. +-- | Map an object's transform in world space to view space. -- -- The XY plane in 2D translates to the X(-Z) plane in 3D. -- -- Use this in games such as RPGs and RTSs. rpgInverse - :: Float -- ^ The height above the ground - -> Float -- ^ Angle of rotation - -> Vector3 -- ^ Axis of rotation - -> Vector2 + :: Float -- ^ The height above the ground + -> Float -- ^ Angle of rotation + -> Vector3 -- ^ Axis of rotation + -> Vector2 -- ^ Object's position. + -> Matrix4 -- ^ Inverse view matrix. -> Matrix4 -rpgInverse h a rot pos = M4.inverseTransform $ rpgTransform h a rot pos +rpgInverse h a rot pos viewInv = M4.inverseTransform $ rpgTransform h a rot pos viewInv --- | Compute the inverse transform of the given transformation matrix. +-- | Map an object's transform in world space to view space. -- -- This function maps an object's transform in 2D to the object's inverse in 3D. -- @@ -93,8 +89,8 @@ pltInverse = M4.inverseTransform . pltTransform -- | Transform an object from object to clip space coordinates. -toClip :: Camera -> Matrix4 -> Vector3 -> Vector2 -toClip cam model p = +objToClip :: Camera -> Matrix4 -> Vector3 -> Vector2 +objToClip cam model p = let view = M4.inverseTransform $ Cam.transform cam proj = Cam.projection cam diff --git a/Spear/Scene/GameObject.hs b/Spear/Scene/GameObject.hs index fc35c2b..a109a35 100644 --- a/Spear/Scene/GameObject.hs +++ b/Spear/Scene/GameObject.hs @@ -9,7 +9,8 @@ module Spear.Scene.GameObject , currentAnimation , goAABB , goAABBs -, go3Dtransform +, collisioners +, goRPGtransform , numCollisioners , renderer -- * Manipulation @@ -18,6 +19,7 @@ module Spear.Scene.GameObject , setAnimationSpeed , withCollisioners , setCollisioners +, setViewInverse -- * Rendering , goRender -- * Collision @@ -58,6 +60,7 @@ data GameObject = GameObject , transform :: !M3.Matrix3 , axis :: Vector3 , angle :: Float + , viewInv :: !M4.Matrix4 } @@ -148,10 +151,10 @@ goNew :: GameStyle -> GameObject goNew style (Left smr) cols transf axis = - GameObject style (Left $ SM.staticModelRenderer smr) cols transf axis 0 + GameObject style (Left $ SM.staticModelRenderer smr) cols transf axis 0 M4.id goNew style (Right amr) cols transf axis = - GameObject style (Right $ AM.animatedModelRenderer 1 amr) cols transf axis 0 + GameObject style (Right $ AM.animatedModelRenderer 1 amr) cols transf axis 0 M4.id goUpdate :: Float -> GameObject -> GameObject @@ -176,8 +179,8 @@ goAABBs = fmap getAABB . collisioners -- | Get the game object's 3D transform. -go3Dtransform :: GameObject -> M4.Matrix4 -go3Dtransform go = rpgTransform 0 (angle go) (axis go) (S2.pos go) +goRPGtransform :: GameObject -> M4.Matrix4 +goRPGtransform go = rpgTransform 0 (angle go) (axis go) (S2.pos go) (viewInv go) -- | Get the game object's current animation. @@ -211,6 +214,11 @@ setCollisioners :: GameObject -> [Collisioner] -> GameObject setCollisioners go cols = go { collisioners = cols } +-- | Set the game object's view inverse matrix. +setViewInverse :: M4.Matrix4 -> GameObject -> GameObject +setViewInverse mat go = go { viewInv = mat } + + -- | Manipulate the game object's collisioners. withCollisioners :: GameObject -> ([Collisioner] -> [Collisioner]) -> GameObject withCollisioners go f = go { collisioners = f $ collisioners go } @@ -221,15 +229,24 @@ goRender :: StaticProgram -> AnimatedProgram -> Cam.Camera -> GameObject -> IO ( goRender sprog aprog cam go = let spu = staticProgramUniforms sprog apu = animatedProgramUniforms aprog - mat = S2.transform go - style = gameStyle go - axis' = axis go - a = angle go + style = gameStyle go + axis' = axis go + a = angle go + viewI = viewInv go + proj = Cam.projection cam + view = M4.inverseTransform $ Cam.transform cam + transf = S2.transform go + normal = fastNormalMatrix modelview + modelview = case style of + RPG -> view * rpgTransform 0 a axis' (M3.position transf) viewI + PLT -> view * pltTransform transf in case renderer go of Left smr -> - goRender' style a axis' sprog spu mat cam (SM.bind spu smr) (SM.render spu smr) + goRender' style a axis' sprog spu modelview proj normal + (SM.bind spu smr) (SM.render spu smr) Right amr -> - goRender' style a axis' aprog apu mat cam (AM.bind apu amr) (AM.render apu amr) + goRender' style a axis' aprog apu modelview proj normal + (AM.bind apu amr) (AM.render apu amr) type Bind = IO () @@ -243,22 +260,19 @@ goRender' :: (ProgramUniforms u, Program p) -> Vector3 -> p -> u - -> M3.Matrix3 - -> Cam.Camera + -> M4.Matrix4 -- Modelview + -> M4.Matrix4 -- Projection + -> M3.Matrix3 -- Normal matrix -> Bind -> Render -> IO () -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 axis (M3.position model) - PLT -> view * pltTransform model - normalmat = fastNormalMatrix modelview +goRender' style a axis prog uniforms modelview proj normal bindRenderer render = + let in do useProgram . program $ prog - uniformMat4 (projLoc uniforms) $ Cam.projection cam + uniformMat4 (projLoc uniforms) proj uniformMat4 (modelviewLoc uniforms) modelview - uniformMat3 (normalmatLoc uniforms) normalmat + uniformMat3 (normalmatLoc uniforms) normal bindRenderer render -- cgit v1.2.3