diff options
-rw-r--r-- | Spear.lkshs | 10 | ||||
-rw-r--r-- | Spear.lkshw | 2 | ||||
-rw-r--r-- | Spear/Math/MatrixUtils.hs | 59 | ||||
-rw-r--r-- | Spear/Scene/GameObject.hs | 53 | ||||
-rw-r--r-- | Spear/Scene/Loader.hs | 18 |
5 files changed, 92 insertions, 50 deletions
diff --git a/Spear.lkshs b/Spear.lkshs index 5ee07cf..4b0d469 100644 --- a/Spear.lkshs +++ b/Spear.lkshs | |||
@@ -1,18 +1,18 @@ | |||
1 | Version of session file format: | 1 | Version of session file format: |
2 | 1 | 2 | 1 |
3 | Time of storage: | 3 | Time of storage: |
4 | "Fri Aug 31 16:57:11 CEST 2012" | 4 | "Fri Aug 31 22:25:44 CEST 2012" |
5 | 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}) 290) 209),("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}) 246)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 639) 954 | 5 | 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 |
6 | Population: [(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/Program/Box.hs" 1712)),[SplitP LeftP]),(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" 1309)),[SplitP LeftP]),(Just (FilesSt FilesState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/GLSL.hs" 13235)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Scene/GameObject.hs" 4522)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject.hs" 1652)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameState.hs" 584)),[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/Assets/Model.hsc" 15715)),[SplitP LeftP]),(Just (ModulesSt (ModulesState 328 (PackageScope False,False) (Just (ModuleName ["Game","GameState"]),Nothing) (ExpanderState {packageExp = ([],[]), packageExpNoBlack = ([[0]],[]), packageDExp = ([],[]), packageDExpNoBlack = ([],[]), workspaceExp = ([],[]), workspaceExpNoBlack = ([],[]), workspaceDExp = ([],[]), workspaceDExpNoBlack = ([],[]), systemExp = ([],[]), systemExpNoBlack = ([],[])}))),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP TopP]),(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" 726)),[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" 2287)),[SplitP LeftP])] | 6 | 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])] |
7 | Window size: (1820,944) | 7 | Window size: (1820,944) |
8 | Completion size: | 8 | Completion size: |
9 | (750,399) | 9 | (750,399) |
10 | Workspace: Just "/home/jeanne/programming/haskell/Spear/Spear.lkshw" | 10 | Workspace: Just "/home/jeanne/programming/haskell/Spear/Spear.lkshw" |
11 | Active pane: Just "GameObject.hs(1)" | 11 | Active pane: Just "GameObject.hs" |
12 | Toolbar visible: | 12 | Toolbar visible: |
13 | True | 13 | True |
14 | 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}) | 14 | 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}) |
15 | Recently opened files: | 15 | Recently opened files: |
16 | ["/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/Program/Box.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameState.hs","/home/jeanne/programming/haskell/Spear/Spear/Setup.hs","/home/jeanne/programming/haskell/Spear/Spear/Scene/SceneResources.hs","/home/jeanne/programming/haskell/Spear/Spear/Scene/Loader.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameObject/Utils.hs","/home/jeanne/programming/haskell/Spear/Spear/Render/Texture.hs","/home/jeanne/programming/haskell/Spear/Spear/Render/AnimatedModel.hs","/home/jeanne/programming/haskell/Spear/Spear/Render/StaticModel.hs","/home/jeanne/programming/haskell/Spear/Spear/Render/Program.hs"] | 16 | ["/home/jeanne/programming/haskell/Spear/Spear/Math/Spatial2.hs","/home/jeanne/programming/haskell/Spear/Spear/Math/Matrix4.hs","/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/Model.c","/home/jeanne/programming/haskell/Spear/Spear/Assets/Model.hsc","/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/Model.h","/home/jeanne/programming/haskell/Spear/Spear/Assets/Model/OBJ/OBJ_load.c","/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/Program/Box.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/Game/GameState.hs","/home/jeanne/programming/haskell/Spear/Spear/Setup.hs","/home/jeanne/programming/haskell/Spear/Spear/Scene/SceneResources.hs","/home/jeanne/programming/haskell/Spear/Spear/Scene/Loader.hs"] |
17 | Recently opened workspaces: | 17 | Recently opened workspaces: |
18 | ["/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 | 18 | ["/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 9220bd8..79c18ef 100644 --- a/Spear.lkshw +++ b/Spear.lkshw | |||
@@ -1,7 +1,7 @@ | |||
1 | Version of workspace file format: | 1 | Version of workspace file format: |
2 | 1 | 2 | 1 |
3 | Time of storage: | 3 | Time of storage: |
4 | "Fri Aug 31 18:36:39 CEST 2012" | 4 | "Fri Aug 31 20:53:49 CEST 2012" |
5 | Name of the workspace: | 5 | Name of the workspace: |
6 | "Spear" | 6 | "Spear" |
7 | File paths of contained packages: | 7 | File paths of contained packages: |
diff --git a/Spear/Math/MatrixUtils.hs b/Spear/Math/MatrixUtils.hs index 68ad6cd..2c1d083 100644 --- a/Spear/Math/MatrixUtils.hs +++ b/Spear/Math/MatrixUtils.hs | |||
@@ -1,6 +1,7 @@ | |||
1 | module Spear.Math.MatrixUtils | 1 | module Spear.Math.MatrixUtils |
2 | ( | 2 | ( |
3 | fastNormalMatrix | 3 | Rotation(..) |
4 | , fastNormalMatrix | ||
4 | , rpgTransform | 5 | , rpgTransform |
5 | , pltTransform | 6 | , pltTransform |
6 | , rpgInverse | 7 | , rpgInverse |
@@ -15,6 +16,9 @@ import Spear.Math.Vector2 as V2 | |||
15 | import Spear.Math.Vector3 as V3 | 16 | import Spear.Math.Vector3 as V3 |
16 | 17 | ||
17 | 18 | ||
19 | data Rotation = Yaw | Pitch | Roll deriving Eq | ||
20 | |||
21 | |||
18 | -- | Compute the normal matrix of the given matrix. | 22 | -- | Compute the normal matrix of the given matrix. |
19 | fastNormalMatrix :: Matrix4 -> Matrix3 | 23 | fastNormalMatrix :: Matrix4 -> Matrix3 |
20 | fastNormalMatrix m = | 24 | fastNormalMatrix m = |
@@ -26,13 +30,26 @@ fastNormalMatrix m = | |||
26 | 30 | ||
27 | 31 | ||
28 | -- | Maps the given 2D transformation matrix to a 3D transformation matrix. | 32 | -- | Maps the given 2D transformation matrix to a 3D transformation matrix. |
29 | rpgTransform :: Float -- ^ The height above the ground. | 33 | rpgTransform |
30 | -> Matrix3 -> Matrix4 | 34 | :: Float -- ^ The height above the ground. |
31 | rpgTransform h mat = | 35 | -> Float -- ^ Angle of rotation. |
32 | let r = let r' = M3.right mat in vec3 (V2.x r') (V2.y r') 0 | 36 | -> Rotation -- ^ How the 2D rotation should be interpreted in 3D. |
37 | -> Matrix3 | ||
38 | -> Matrix4 | ||
39 | rpgTransform h a rtype mat = | ||
40 | {-let r = let r' = M3.right mat in vec3 (V2.x r') (V2.y r') 0 | ||
33 | u = V3.unity | 41 | u = V3.unity |
34 | f = let f' = M3.forward mat in vec3 (V2.x f') 0 (V2.y f') | 42 | f = let f' = M3.forward mat in vec3 (V2.x f') 0 (V2.y f') |
35 | t = (vec3 0 h 0) + let t' = M3.position mat in vec3 (V2.x t') 0 (V2.y t') | 43 | t = (vec3 0 h 0) + let t' = M3.position mat in vec3 (V2.x t') 0 (V2.y t')-} |
44 | let rot = case rtype of | ||
45 | Yaw -> rotY | ||
46 | Pitch -> rotX | ||
47 | Roll -> rotZ | ||
48 | mat' = rot a | ||
49 | r = M4.right mat' | ||
50 | u = M4.up mat' | ||
51 | f = M4.forward mat' | ||
52 | t = vec3 0 h 0 + let t' = M3.position mat in vec3 (V2.x t') 0 (V2.y t') | ||
36 | in mat4 | 53 | in mat4 |
37 | (V3.x r) (V3.x u) (V3.x f) (V3.x t) | 54 | (V3.x r) (V3.x u) (V3.x f) (V3.x t) |
38 | (V3.y r) (V3.y u) (V3.y f) (V3.y t) | 55 | (V3.y r) (V3.y u) (V3.y f) (V3.y t) |
@@ -61,18 +78,13 @@ pltTransform mat = | |||
61 | -- The XY plane in 2D translates to the X(-Z) plane in 3D. | 78 | -- The XY plane in 2D translates to the X(-Z) plane in 3D. |
62 | -- | 79 | -- |
63 | -- Use this in games such as RPGs and RTSs. | 80 | -- Use this in games such as RPGs and RTSs. |
64 | rpgInverse :: Float -- ^ Height above the ground. | 81 | rpgInverse |
65 | -> Matrix3 -> Matrix4 | 82 | :: Float -- ^ The height above the ground. |
66 | rpgInverse h mat = | 83 | -> Float -- ^ Angle of rotation. |
67 | let r = let r' = M3.right mat in vec3 (V2.x r') (V2.y r') 0 | 84 | -> Rotation -- ^ How the 2D rotation should be interpreted in 3D. |
68 | u = V3.unity | 85 | -> Matrix3 |
69 | f = let f' = M3.forward mat in vec3 (V2.x f') 0 (-V2.y f') | 86 | -> Matrix4 |
70 | t = (vec3 0 h 0) + let t' = M3.position mat in -(vec3 (V2.x t') 0 (-V2.y t')) | 87 | rpgInverse h a rot = M4.inverseTransform . rpgTransform h a rot |
71 | in mat4 | ||
72 | (V3.x r) (V3.y r) (V3.z r) (t `V3.dot` r) | ||
73 | (V3.x u) (V3.y u) (V3.z u) (t `V3.dot` u) | ||
74 | (V3.x f) (V3.y f) (V3.z f) (t `V3.dot` f) | ||
75 | 0 0 0 1 | ||
76 | 88 | ||
77 | 89 | ||
78 | -- | Compute the inverse transform of the given transformation matrix. | 90 | -- | Compute the inverse transform of the given transformation matrix. |
@@ -83,13 +95,4 @@ rpgInverse h mat = | |||
83 | -- | 95 | -- |
84 | -- Use this in games like platformers and space invaders style games. | 96 | -- Use this in games like platformers and space invaders style games. |
85 | pltInverse :: Matrix3 -> Matrix4 | 97 | pltInverse :: Matrix3 -> Matrix4 |
86 | pltInverse mat = | 98 | pltInverse = M4.inverseTransform . pltTransform |
87 | let r = let r' = M3.right mat in vec3 (V2.x r') (V2.y r') 0 | ||
88 | u = let u' = M3.up mat in vec3 (V2.x u') (V2.y u') 0 | ||
89 | f = V3.unitz | ||
90 | t = let t' = M3.position mat in vec3 (V2.x t') (V2.y t') 0 | ||
91 | in mat4 | ||
92 | (V3.x r) (V3.y r) (V3.z r) (t `V3.dot` r) | ||
93 | (V3.x u) (V3.y u) (V3.z u) (t `V3.dot` u) | ||
94 | (V3.x f) (V3.y f) (V3.z f) (t `V3.dot` f) | ||
95 | 0 0 0 1 | ||
diff --git a/Spear/Scene/GameObject.hs b/Spear/Scene/GameObject.hs index e012122..f29ee09 100644 --- a/Spear/Scene/GameObject.hs +++ b/Spear/Scene/GameObject.hs | |||
@@ -3,14 +3,16 @@ module Spear.Scene.GameObject | |||
3 | GameObject | 3 | GameObject |
4 | , GameStyle(..) | 4 | , GameStyle(..) |
5 | , AM.AnimationSpeed | 5 | , AM.AnimationSpeed |
6 | , Rotation(..) | ||
6 | -- * Construction | 7 | -- * Construction |
7 | , goNew | 8 | , goNew |
8 | -- * Accessors | 9 | -- * Accessors |
9 | , renderer | ||
10 | , currentAnimation | 10 | , currentAnimation |
11 | , numCollisioners | ||
12 | , goAABB | 11 | , goAABB |
13 | , goAABBs | 12 | , goAABBs |
13 | , go3Dtransform | ||
14 | , numCollisioners | ||
15 | , renderer | ||
14 | -- * Manipulation | 16 | -- * Manipulation |
15 | , goUpdate | 17 | , goUpdate |
16 | , setAnimation | 18 | , setAnimation |
@@ -39,6 +41,7 @@ import qualified Spear.Render.AnimatedModel as AM | |||
39 | import Spear.Render.Program | 41 | import Spear.Render.Program |
40 | import Spear.Render.StaticModel as SM | 42 | import Spear.Render.StaticModel as SM |
41 | 43 | ||
44 | import Data.Fixed (mod') | ||
42 | import Data.List (foldl') | 45 | import Data.List (foldl') |
43 | 46 | ||
44 | 47 | ||
@@ -51,9 +54,11 @@ data GameStyle | |||
51 | -- | An object in the game scene. | 54 | -- | An object in the game scene. |
52 | data GameObject = GameObject | 55 | data GameObject = GameObject |
53 | { gameStyle :: !GameStyle | 56 | { gameStyle :: !GameStyle |
57 | , rotation :: !Rotation | ||
54 | , renderer :: !(Either StaticModelRenderer AM.AnimatedModelRenderer) | 58 | , renderer :: !(Either StaticModelRenderer AM.AnimatedModelRenderer) |
55 | , collisioners :: ![Collisioner] | 59 | , collisioners :: ![Collisioner] |
56 | , transform :: !M3.Matrix3 | 60 | , transform :: !M3.Matrix3 |
61 | , angle :: Float | ||
57 | } | 62 | } |
58 | 63 | ||
59 | 64 | ||
@@ -96,7 +101,11 @@ instance S2.Spatial2 GameObject where | |||
96 | , transform = M3.translv v * m | 101 | , transform = M3.translv v * m |
97 | } | 102 | } |
98 | 103 | ||
99 | rotate angle go = go { transform = transform go * M3.rot angle } | 104 | rotate a go = |
105 | go | ||
106 | { transform = transform go * M3.rot a | ||
107 | , angle = (angle go + a) `mod'` 360 | ||
108 | } | ||
100 | 109 | ||
101 | pos go = M3.position . transform $ go | 110 | pos go = M3.position . transform $ go |
102 | 111 | ||
@@ -113,20 +122,31 @@ instance S2.Spatial2 GameObject where | |||
113 | setPos pos go = | 122 | setPos pos go = |
114 | let m = transform go | 123 | let m = transform go |
115 | in go { transform = M3.transform (M3.right m) (M3.forward m) pos } | 124 | in go { transform = M3.transform (M3.right m) (M3.forward m) pos } |
125 | |||
126 | lookAt p go = | ||
127 | let position = S2.pos go | ||
128 | fwd = V2.normalise $ p - position | ||
129 | r = perp fwd | ||
130 | in | ||
131 | go | ||
132 | { transform = M3.transform r fwd position | ||
133 | , angle = acos $ r `V2.dot` V2.unitx | ||
134 | } | ||
116 | 135 | ||
117 | 136 | ||
118 | -- | Create a new game object. | 137 | -- | Create a new game object. |
119 | goNew :: GameStyle | 138 | goNew :: GameStyle |
139 | -> Rotation | ||
120 | -> Either StaticModelResource AM.AnimatedModelResource | 140 | -> Either StaticModelResource AM.AnimatedModelResource |
121 | -> [Collisioner] | 141 | -> [Collisioner] |
122 | -> M3.Matrix3 | 142 | -> M3.Matrix3 |
123 | -> GameObject | 143 | -> GameObject |
124 | 144 | ||
125 | goNew style (Left smr) cols transf = | 145 | goNew style rtype (Left smr) cols transf = |
126 | GameObject style (Left $ SM.staticModelRenderer smr) cols transf | 146 | GameObject style rtype (Left $ SM.staticModelRenderer smr) cols transf 0 |
127 | 147 | ||
128 | goNew style (Right amr) cols transf = | 148 | goNew style rtype (Right amr) cols transf = |
129 | GameObject style (Right $ AM.animatedModelRenderer 1 amr) cols transf | 149 | GameObject style rtype (Right $ AM.animatedModelRenderer 1 amr) cols transf 0 |
130 | 150 | ||
131 | 151 | ||
132 | goUpdate :: Float -> GameObject -> GameObject | 152 | goUpdate :: Float -> GameObject -> GameObject |
@@ -190,6 +210,11 @@ goAABBs :: GameObject -> [AABB] | |||
190 | goAABBs = fmap goAABB' . collisioners | 210 | goAABBs = fmap goAABB' . collisioners |
191 | 211 | ||
192 | 212 | ||
213 | -- | Get the game object's 3D transform. | ||
214 | go3Dtransform :: GameObject -> M4.Matrix4 | ||
215 | go3Dtransform go = rpgTransform 0 (angle go) (rotation go) . S2.transform $ go | ||
216 | |||
217 | |||
193 | -- | Render the game object. | 218 | -- | Render the game object. |
194 | goRender :: StaticProgram -> AnimatedProgram -> Cam.Camera -> GameObject -> IO () | 219 | goRender :: StaticProgram -> AnimatedProgram -> Cam.Camera -> GameObject -> IO () |
195 | goRender sprog aprog cam go = | 220 | goRender sprog aprog cam go = |
@@ -197,9 +222,13 @@ goRender sprog aprog cam go = | |||
197 | apu = animatedProgramUniforms aprog | 222 | apu = animatedProgramUniforms aprog |
198 | mat = S2.transform go | 223 | mat = S2.transform go |
199 | style = gameStyle go | 224 | style = gameStyle go |
225 | rtype = rotation go | ||
226 | a = angle go | ||
200 | in case renderer go of | 227 | in case renderer go of |
201 | Left smr -> goRender' style sprog spu mat cam (SM.bind spu smr) (SM.render spu smr) | 228 | Left smr -> |
202 | Right amr -> goRender' style aprog apu mat cam (AM.bind apu amr) (AM.render apu amr) | 229 | goRender' style a rtype sprog spu mat cam (SM.bind spu smr) (SM.render spu smr) |
230 | Right amr -> | ||
231 | goRender' style a rtype aprog apu mat cam (AM.bind apu amr) (AM.render apu amr) | ||
203 | 232 | ||
204 | 233 | ||
205 | type Bind = IO () | 234 | type Bind = IO () |
@@ -209,6 +238,8 @@ type Render = IO () | |||
209 | 238 | ||
210 | goRender' :: (ProgramUniforms u, Program p) | 239 | goRender' :: (ProgramUniforms u, Program p) |
211 | => GameStyle | 240 | => GameStyle |
241 | -> Float | ||
242 | -> Rotation | ||
212 | -> p | 243 | -> p |
213 | -> u | 244 | -> u |
214 | -> M3.Matrix3 | 245 | -> M3.Matrix3 |
@@ -216,10 +247,10 @@ goRender' :: (ProgramUniforms u, Program p) | |||
216 | -> Bind | 247 | -> Bind |
217 | -> Render | 248 | -> Render |
218 | -> IO () | 249 | -> IO () |
219 | goRender' style prog uniforms model cam bindRenderer render = | 250 | goRender' style a rtype prog uniforms model cam bindRenderer render = |
220 | let view = M4.inverseTransform $ Cam.transform cam | 251 | let view = M4.inverseTransform $ Cam.transform cam |
221 | modelview = case style of | 252 | modelview = case style of |
222 | RPG -> view * rpgTransform 0 model | 253 | RPG -> view * rpgTransform 0 a rtype model |
223 | PLT -> view * pltTransform model | 254 | PLT -> view * pltTransform model |
224 | normalmat = fastNormalMatrix modelview | 255 | normalmat = fastNormalMatrix modelview |
225 | in do | 256 | in do |
diff --git a/Spear/Scene/Loader.hs b/Spear/Scene/Loader.hs index e3b9546..ea08385 100644 --- a/Spear/Scene/Loader.hs +++ b/Spear/Scene/Loader.hs | |||
@@ -31,7 +31,7 @@ import Spear.Render.AnimatedModel as AM | |||
31 | import Spear.Render.Material | 31 | import Spear.Render.Material |
32 | import Spear.Render.Program | 32 | import Spear.Render.Program |
33 | import Spear.Render.StaticModel as SM | 33 | import Spear.Render.StaticModel as SM |
34 | import Spear.Scene.GameObject as GO | 34 | import qualified Spear.Scene.GameObject as GO |
35 | import Spear.Scene.Graph | 35 | import Spear.Scene.Graph |
36 | import Spear.Scene.Light | 36 | import Spear.Scene.Light |
37 | import Spear.Scene.SceneResources | 37 | import Spear.Scene.SceneResources |
@@ -342,17 +342,18 @@ newLight _ = return () | |||
342 | -- Object Loading -- | 342 | -- Object Loading -- |
343 | -------------------- | 343 | -------------------- |
344 | 344 | ||
345 | loadGO :: GameStyle -> SceneResources -> [Property] -> Matrix3 -> Setup GameObject | 345 | loadGO :: GO.GameStyle -> SceneResources -> [Property] -> Matrix3 -> Setup GO.GameObject |
346 | loadGO style sceneRes props transf = do | 346 | loadGO style sceneRes props transf = do |
347 | modelName <- asString . mandatory "model" $ props | 347 | modelName <- asString . mandatory "model" $ props |
348 | rtype <- asGORotation . mandatory "rotation" $ props | ||
348 | let animSpeed = asFloat . value "animation-speed" $ props | 349 | let animSpeed = asFloat . value "animation-speed" $ props |
349 | go <- case getAnimatedModel sceneRes modelName of | 350 | go <- case getAnimatedModel sceneRes modelName of |
350 | Just model -> | 351 | Just model -> |
351 | return $ goNew style (Right model) [] transf | 352 | return $ GO.goNew style rtype (Right model) [] transf |
352 | Nothing -> | 353 | Nothing -> |
353 | case getStaticModel sceneRes modelName of | 354 | case getStaticModel sceneRes modelName of |
354 | Just model -> | 355 | Just model -> |
355 | return $ goNew style (Left model) [] transf | 356 | return $ GO.goNew style rtype (Left model) [] transf |
356 | Nothing -> | 357 | Nothing -> |
357 | setupError $ "model " ++ modelName ++ " not found" | 358 | setupError $ "model " ++ modelName ++ " not found" |
358 | return $ case animSpeed of | 359 | return $ case animSpeed of |
@@ -466,6 +467,13 @@ asRotation val = fmap parseRotation val | |||
466 | where parseRotation (ax:ay:az:order:_) = Rotation (read ax) (read ay) (read az) (readOrder order) | 467 | where parseRotation (ax:ay:az:order:_) = Rotation (read ax) (read ay) (read az) (readOrder order) |
467 | 468 | ||
468 | 469 | ||
470 | asGORotation :: Functor f => f [String] -> f GO.Rotation | ||
471 | asGORotation val = fmap parseRotation val | ||
472 | where parseRotation ["yaw"] = GO.Yaw | ||
473 | parseRotation ["pitch"] = GO.Pitch | ||
474 | parseRotation ["roll"] = GO.Roll | ||
475 | |||
476 | |||
469 | data Rotation = Rotation | 477 | data Rotation = Rotation |
470 | { ax :: Float | 478 | { ax :: Float |
471 | , ay :: Float | 479 | , ay :: Float |