aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Spear.lkshs8
-rw-r--r--Spear/Physics/World.hs99
2 files changed, 28 insertions, 79 deletions
diff --git a/Spear.lkshs b/Spear.lkshs
index 3f28583..afbce39 100644
--- a/Spear.lkshs
+++ b/Spear.lkshs
@@ -1,14 +1,14 @@
1Version of session file format: 1Version of session file format:
2 1 2 1
3Time of storage: 3Time of storage:
4 "Thu Aug 9 11:37:44 CEST 2012" 4 "Thu Aug 9 13:31:29 CEST 2012"
5Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 5, 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}) 279) 208)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 732) 954 5Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 6, 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}) 266) 197)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 702) 954
6Population: [(Just (ErrorsSt ErrorsState),[SplitP RightP,SplitP TopP]),(Just (FilesSt FilesState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/GameObject.hs" 259)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/GameState.hs" 670)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Sys/Store/ID.hs" 96)),[SplitP LeftP]),(Just (InfoSt (InfoState Nothing)),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP BottomP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(Just (ModulesSt (ModulesState 328 (PackageScope False,False) (Nothing,Nothing) (ExpanderState {packageExp = ([],[]), packageExpNoBlack = ([],[]), packageDExp = ([],[]), packageDExpNoBlack = ([],[]), workspaceExp = ([],[]), workspaceExpNoBlack = ([[5]],[]), workspaceDExp = ([],[]), workspaceDExpNoBlack = ([],[]), systemExp = ([],[]), systemExpNoBlack = ([],[])}))),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Physics.hs" 207)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Physics/Rigid.hs" 2175)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Sys/Store.hs" 2183)),[SplitP LeftP]),(Just (WorkspaceSt WorkspaceState),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Physics/World.hs" 1269)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.hs" 204)),[SplitP LeftP])] 6Population: [(Just (ErrorsSt ErrorsState),[SplitP RightP,SplitP TopP]),(Just (FilesSt FilesState),[SplitP RightP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/GameObject.hs" 259)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/GameState.hs" 670)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Sys/Store/ID.hs" 96)),[SplitP LeftP]),(Just (InfoSt (InfoState (Just (Real (RealDescr {dscName' = "storeFree", dscMbTypeStr' = Just "storeFree :: Index -> Store a -> Store a", dscMbModu' = Just (PM {pack = PackageIdentifier {pkgName = PackageName "Spear", pkgVersion = Version {versionBranch = [0,1], versionTags = []}}, modu = ModuleName ["Spear","Sys","Store"]}), dscMbLocation' = Just (Location {locationSLine = 101, locationSCol = 1, locationELine = 108, locationECol = 32}), dscMbComment' = Just " Free the given slot.", dscTypeHint' = VariableDescr, dscExported' = True}))))),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP BottomP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(Just (ModulesSt (ModulesState 328 (PackageScope False,False) (Just (ModuleName ["Spear","Sys","Store"]),Just "storeFree") (ExpanderState {packageExp = ([],[]), packageExpNoBlack = ([[0,9],[0]],[]), packageDExp = ([],[]), packageDExpNoBlack = ([],[]), workspaceExp = ([],[]), workspaceExpNoBlack = ([[5]],[]), workspaceDExp = ([],[]), workspaceDExpNoBlack = ([],[]), systemExp = ([],[]), systemExpNoBlack = ([],[])}))),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP BottomP,SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Physics.hs" 207)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Physics/Rigid.hs" 2175)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Sys/Store.hs" 4136)),[SplitP LeftP]),(Just (WorkspaceSt WorkspaceState),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP TopP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Physics/World.hs" 287)),[SplitP LeftP]),(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.hs" 204)),[SplitP LeftP])]
7Window size: (1841,964) 7Window size: (1841,964)
8Completion size: 8Completion size:
9 (750,400) 9 (750,400)
10Workspace: Just "/home/jeanne/programming/haskell/Spear/Spear.lkshw" 10Workspace: Just "/home/jeanne/programming/haskell/Spear/Spear.lkshw"
11Active pane: Just "Store.hs" 11Active pane: Just "World.hs"
12Toolbar visible: 12Toolbar visible:
13 True 13 True
14FindbarState: (False,FindState {entryStr = "asda", entryHist = ["assigned","Triangle","transforma","gravity","asdad","rotSpeed","azimuth","mandatory","mandao","col","forward","MouseButton"], replaceStr = "objects", replaceHist = [], caseSensitive = True, entireWord = False, wrapAround = False, regex = False, lineNr = 1}) 14FindbarState: (False,FindState {entryStr = "asda", entryHist = ["assigned","Triangle","transforma","gravity","asdad","rotSpeed","azimuth","mandatory","mandao","col","forward","MouseButton"], replaceStr = "objects", replaceHist = [], caseSensitive = True, entireWord = False, wrapAround = False, regex = False, lineNr = 1})
diff --git a/Spear/Physics/World.hs b/Spear/Physics/World.hs
index e0996e6..b4e6176 100644
--- a/Spear/Physics/World.hs
+++ b/Spear/Physics/World.hs
@@ -12,9 +12,8 @@ module Spear.Physics.World
12 -- * Object operations 12 -- * Object operations
13, newObject 13, newObject
14, deleteObject 14, deleteObject
15, modifyObject 15, withBody
16, objectTransform 16, objectTransform
17, objectForces
18, setForces 17, setForces
19) 18)
20where 19where
@@ -28,10 +27,9 @@ import Spear.Math.Spatial
28import Spear.Math.Vector3 27import Spear.Math.Vector3
29import Spear.Physics.Rigid as Rigid 28import Spear.Physics.Rigid as Rigid
30import Spear.Physics.Types 29import Spear.Physics.Types
30import Spear.Sys.Store
31
31 32
32import Control.Monad.ST
33import Data.Array as A
34import Data.Array.ST
35import Data.Maybe (fromJust) 33import Data.Maybe (fromJust)
36 34
37 35
@@ -48,90 +46,47 @@ data Object = Object
48 46
49-- | The world where physical bodies are simulated. 47-- | The world where physical bodies are simulated.
50data World = World 48data World = World
51 { bodies :: Array Int (Maybe Object) -- ^ Collection of objects. 49 { bodies :: Store Object -- ^ Collection of objects.
52 , gravity :: Vector3 -- ^ World gravity. 50 , gravity :: Vector3 -- ^ World gravity.
53 } 51 }
54 52
55 53
56-- | Create an empty 'World'. 54-- | Create an empty world.
57emptyWorld :: World 55emptyWorld :: World
58emptyWorld = World emptyArray defaultGravity 56emptyWorld = World emptyStore $ vec3 0 (-9.8) 0
59 where
60 defaultGravity = vec3 0 (-9.8) 0
61 emptyArray = listArray (0,0) []
62 57
63 58
64-- | Create a new object. 59-- | Create a new object.
65newObject :: RigidBody -> Collisioner -> World -> (World, ObjectID) 60newObject :: RigidBody -> Collisioner -> World -> (ObjectID, World)
66newObject body collisioner world = 61newObject body collisioner world =
67 let obj = (Object body collisioner []) 62 let (index, bodies') = store (Object body collisioner []) $ bodies world
68 in case emptySlot world of 63 in (ObjectID index, world { bodies = bodies' })
69 Just i -> (insert i obj world, ObjectID i)
70 Nothing -> append obj world
71
72
73-- | Search for an empty slot in the given 'World'.
74emptySlot :: World -> Maybe Int
75emptySlot world = Nothing
76
77
78-- | Insert the given 'Object' in the given 'World' at the given position.
79insert :: Int -> Object -> World -> World
80insert i obj world = world { bodies = bodies' }
81 where
82 bodies' = runSTArray $ do
83 bs <- thaw $ bodies world
84 writeArray bs i $ Just obj
85 return bs
86 64
87 65
88-- | Append the given object to the given 'World'. 66-- | Remove the object specified by the given object ID.
89--
90-- The world's vectors are doubled in size to make future insertions faster.
91append :: Object -> World -> (World, ObjectID)
92append obj world = (world, ObjectID 0)
93
94
95-- | Remove the object specified by the given 'ObjectID' from the given 'World'.
96deleteObject :: ObjectID -> World -> World 67deleteObject :: ObjectID -> World -> World
97deleteObject (ObjectID i) world = world { bodies = bodies' } 68deleteObject (ObjectID i) world = world { bodies = bodies' }
98 where 69 where
99 bodies' = runSTArray $ do 70 bodies' = storeFree i $ bodies world
100 bs <- thaw $ bodies world
101 writeArray bs i Nothing
102 return bs
103 71
104 72
105-- | Modify the object identified by the given 'ObjectID' in the given 'World'. 73-- | Modify the object identified by the given object ID.
106modifyObject :: (RigidBody -> RigidBody) -> ObjectID -> World -> World 74withBody :: ObjectID -> World -> (RigidBody -> RigidBody) -> World
107modifyObject f (ObjectID i) world = world { bodies = bodies' } 75withBody (ObjectID index) world f = world { bodies = bodies' }
108 where 76 where
109 bodies' = runSTArray $ do 77 bodies' = withElement index (bodies world) $ \obj -> obj { body = f $ body obj }
110 bs <- thaw $ bodies world
111 obj <- readArray bs i
112 writeArray bs i $ fmap (\obj -> obj { body = f $ body obj }) obj
113 return bs
114 78
115 79
116-- | Get the transform of the object identified by the given 'ObjectID'. 80-- | Get the transform of the object identified by the given object ID.
117objectTransform :: World -> ObjectID -> Matrix4 81objectTransform :: World -> ObjectID -> Matrix4
118objectTransform world (ObjectID i) = transform . body . fromJust $ bodies world ! i 82objectTransform world (ObjectID i) = transform . body . fromJust $ (element i $ bodies world)
119 83
120 84
121-- | Get the forces acting on the object identified by the given 'ObjectID'. 85-- | Add the given force to the forces acting on the object identified by the given object ID.
122objectForces :: World -> ObjectID -> [Force]
123objectForces world (ObjectID i) = forces . fromJust $ bodies world ! i
124
125
126-- | Add the given force to the forces acting on the object identified by the given 'ObjectID'.
127setForces :: [Force] -> ObjectID -> World -> World 86setForces :: [Force] -> ObjectID -> World -> World
128setForces fs (ObjectID i) world = world { bodies = bodies' } 87setForces fs (ObjectID i) world = world { bodies = bodies' }
129 where 88 where
130 bodies' = runSTArray $ do 89 bodies' = withElement i (bodies world) $ \obj -> obj { forces = fs }
131 bs <- thaw $ bodies world
132 obj <- readArray bs i
133 writeArray bs i $ fmap (\obj -> obj { forces = fs }) obj
134 return bs
135 90
136 91
137-- | Set the world's gravity. 92-- | Set the world's gravity.
@@ -139,17 +94,11 @@ setGravity :: Vector3 -> World -> World
139setGravity g world = world { gravity = g } 94setGravity g world = world { gravity = g }
140 95
141 96
142-- | Update the 'World'. 97-- | Update the world.
143updateWorld :: Dt -> World -> World 98updateWorld :: Dt -> World -> World
144updateWorld dt world = world { bodies = bodies' } 99updateWorld dt world = world { bodies = fmap updateObject $ bodies world }
145 where 100 where
146 bodies' = runSTArray $ do 101 updateObject (Object body collisioner forces) = Object body' collisioner' forces
147 bs <- thaw $ bodies world
148 mapArray updateObject bs
149 return bs
150
151 updateObject = fmap updateObject'
152 updateObject' (Object body collisioner forces) = Object body' collisioner' forces
153 where 102 where
154 -- Forces acting on the body. 103 -- Forces acting on the body.
155 forces' = scale (mass body) (gravity world) : forces 104 forces' = scale (mass body) (gravity world) : forces
@@ -170,7 +119,7 @@ updateWorld dt world = world { bodies = bodies' }
170 aabbCollisioner $ AABB min' max' 119 aabbCollisioner $ AABB min' max'
171 120
172 121
173{--- | Test for potential collisions in the given 'World'. 122{--- | Test for potential collisions.
174-- 123--
175-- Returns a new world and a list of colliding pairs of objects. 124-- Returns a new world and a list of colliding pairs of objects.
176--testCollisions :: World -> (World, [(ObjectID, ObjectID)])-} 125--testCollisions :: World -> (World, [(ObjectID, ObjectID)])-}