diff options
author | Marc Sunet <jeannekamikaze@gmail.com> | 2012-08-30 19:32:58 +0200 |
---|---|---|
committer | Marc Sunet <jeannekamikaze@gmail.com> | 2012-08-30 19:32:58 +0200 |
commit | a502bf0a62c38a789c1325d6f1082d5ff2af612c (patch) | |
tree | 172f49eebad0af0b92598419ec3b99fd62939efc | |
parent | 83876d723d598111741c83e570db74139cc0d22d (diff) |
Simplified collision interface
-rw-r--r-- | Spear.cabal | 12 | ||||
-rw-r--r-- | Spear.lkshs | 10 | ||||
-rw-r--r-- | Spear/Collision.hs | 159 | ||||
-rw-r--r-- | Spear/Collision/Collision.hs | 80 | ||||
-rw-r--r-- | Spear/Collision/Collisioner.hs | 82 | ||||
-rw-r--r-- | Spear/Collision/Types.hs | 6 | ||||
-rw-r--r-- | Spear/Math/QuadTree.hs | 2 | ||||
-rw-r--r-- | Spear/Scene/GameObject.hs | 3 | ||||
-rw-r--r-- | Spear/Scene/Loader.hs | 2 | ||||
-rw-r--r-- | Spear/Scene/Scene.hs | 4 |
10 files changed, 170 insertions, 190 deletions
diff --git a/Spear.cabal b/Spear.cabal index bc9f429..a893ce3 100644 --- a/Spear.cabal +++ b/Spear.cabal | |||
@@ -19,13 +19,11 @@ library | |||
19 | exposed-modules: Spear.Scene.GameObject Spear.Math.QuadTree | 19 | exposed-modules: Spear.Scene.GameObject Spear.Math.QuadTree |
20 | Spear.Physics.Types Spear.App Spear.App.Application Spear.App.Input | 20 | Spear.Physics.Types Spear.App Spear.App.Application Spear.App.Input |
21 | Spear.Assets.Image Spear.Assets.Model Spear.Collision | 21 | Spear.Assets.Image Spear.Assets.Model Spear.Collision |
22 | Spear.Math.AABB Spear.Collision.Collision | 22 | Spear.Math.AABB Spear.Math.Circle Spear.Math.Triangle Spear.Game |
23 | Spear.Collision.Collisioner Spear.Math.Circle Spear.Math.Triangle | 23 | Spear.GLSL Spear.Math.Camera Spear.Math.Entity Spear.Math.Matrix3 |
24 | Spear.Collision.Types Spear.Game Spear.GLSL Spear.Math.Camera | 24 | Spear.Math.Matrix4 Spear.Math.MatrixUtils Spear.Math.Plane |
25 | Spear.Math.Entity Spear.Math.Matrix3 Spear.Math.Matrix4 | 25 | Spear.Math.Quaternion Spear.Math.Vector3 Spear.Math.Vector4 |
26 | Spear.Math.MatrixUtils Spear.Math.Plane Spear.Math.Quaternion | 26 | Spear.Physics Spear.Physics.Rigid Spear.Render.AnimatedModel |
27 | Spear.Math.Vector3 Spear.Math.Vector4 Spear.Physics | ||
28 | Spear.Physics.Rigid Spear.Render.AnimatedModel | ||
29 | Spear.Render.Material Spear.Render.Model Spear.Render.Program | 27 | Spear.Render.Material Spear.Render.Model Spear.Render.Program |
30 | Spear.Render.StaticModel Spear.Render.Texture Spear.Scene.Graph | 28 | Spear.Render.StaticModel Spear.Render.Texture Spear.Scene.Graph |
31 | Spear.Scene.Light Spear.Scene.Loader Spear.Scene.Scene | 29 | Spear.Scene.Light Spear.Scene.Loader Spear.Scene.Scene |
diff --git a/Spear.lkshs b/Spear.lkshs index 38c6f2c..1f6f16e 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 | "Thu Aug 30 19:22:08 CEST 2012" | 4 | "Thu Aug 30 19:32:45 CEST 2012" |
5 | Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 2, 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}) 357) 139)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 653) 954 | 5 | Layout: VerticalP (TerminalP {paneGroups = fromList [], paneTabs = Just TopP, currentPage = 0, 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}) 353) 140)], paneTabs = Just BottomP, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) (TerminalP {paneGroups = fromList [], paneTabs = Nothing, currentPage = 0, detachedId = Nothing, detachedSize = Nothing}) 653) 954 |
6 | Population: [(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" 447)),[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" 0)),[SplitP LeftP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(Just (ModulesSt (ModulesState 328 (PackageScope False,False) (Just (ModuleName ["Spear","Render","Renderable"]),Nothing) (ExpanderState {packageExp = ([],[]), packageExpNoBlack = ([[0,6],[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/Spear/Render/Program.hs" 248)),[SplitP LeftP]),(Just (WorkspaceSt WorkspaceState),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP TopP])] | 6 | Population: [(Just (BufferSt (BufferState "/home/jeanne/programming/haskell/Spear/Spear/Collision.hs" 3278)),[SplitP LeftP]),(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" 402)),[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" 296)),[SplitP LeftP]),(Just (LogSt LogState),[SplitP RightP,SplitP BottomP]),(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/Spear/Render/Program.hs" 248)),[SplitP LeftP]),(Just (WorkspaceSt WorkspaceState),[SplitP RightP,SplitP TopP,GroupP "Browser",SplitP TopP])] |
7 | Window size: (1820,939) | 7 | Window size: (1820,939) |
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 "Modules" | 11 | Active pane: Just "Collision.hs" |
12 | Toolbar visible: | 12 | Toolbar visible: |
13 | True | 13 | True |
14 | FindbarState: (False,FindState {entryStr = "", entryHist = ["VAO","'VAO'","\170","\\","^","scale","Vector4.","asdad","translv","Vector3.","Vector.","copy_tr"], replaceStr = "V3.", replaceHist = [], caseSensitive = True, entireWord = False, wrapAround = False, regex = False, lineNr = 1}) | 14 | FindbarState: (False,FindState {entryStr = "", entryHist = ["VAO","'VAO'","\170","\\","^","scale","Vector4.","asdad","translv","Vector3.","Vector.","copy_tr"], 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/Spear/Updatable.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.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/demos/simple-scene/Game/GameObject/Player.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL/VAO.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL/Uniform.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL/Texture.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL/Management.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL/Buffer.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL/Error.hs"] | 16 | ["/home/jeanne/programming/haskell/Spear/Spear/Math/QuadTree.hs","/home/jeanne/programming/haskell/Spear/Spear/Scene/Scene.hs","/home/jeanne/programming/haskell/Spear/Spear/Collision/Types.hs","/home/jeanne/programming/haskell/Spear/Spear/Collision/Collisioner.hs","/home/jeanne/programming/haskell/Spear/Spear/Collision/Collision.hs","/home/jeanne/programming/haskell/Spear/Spear/Updatable.hs","/home/jeanne/programming/haskell/Spear/demos/simple-scene/main.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/demos/simple-scene/Game/GameObject/Player.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL.hs","/home/jeanne/programming/haskell/Spear/Spear/GLSL/VAO.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/Collision.hs b/Spear/Collision.hs index 975f3cf..0dbebdb 100644 --- a/Spear/Collision.hs +++ b/Spear/Collision.hs | |||
@@ -1,10 +1,161 @@ | |||
1 | module Spear.Collision | 1 | module Spear.Collision |
2 | ( | 2 | ( |
3 | module Spear.Collision.Collision | 3 | -- * Collision tests |
4 | , module Spear.Collision.Types | 4 | CollisionType(..) |
5 | , Collisionable(..) | ||
6 | -- * Collisioners | ||
7 | , Collisioner(..) | ||
8 | -- ** Construction | ||
9 | , aabbCollisioner | ||
10 | , sphereCollisioner | ||
11 | , buildAABB | ||
12 | -- ** Collision test | ||
13 | , collide | ||
14 | -- ** Manipulation | ||
15 | , move | ||
16 | -- * Helpers | ||
17 | , aabbFromCircle | ||
5 | ) | 18 | ) |
6 | where | 19 | where |
7 | 20 | ||
8 | 21 | ||
9 | import Spear.Collision.Collision | 22 | import Spear.Math.AABB |
10 | import Spear.Collision.Types | 23 | import Spear.Math.Circle |
24 | import Spear.Math.Plane | ||
25 | import Spear.Math.Vector2 | ||
26 | |||
27 | |||
28 | -- | Encodes several collision situations. | ||
29 | data CollisionType = NoCollision | Collision | FullyContains | FullyContainedBy | ||
30 | deriving (Eq, Show) | ||
31 | |||
32 | |||
33 | class Collisionable a where | ||
34 | collideBox :: AABB -> a -> CollisionType | ||
35 | collideSphere :: Circle -> a -> CollisionType | ||
36 | |||
37 | |||
38 | instance Collisionable AABB where | ||
39 | |||
40 | collideBox box1@(AABB min1 max1) box2@(AABB min2 max2) | ||
41 | | min1 > max2 = NoCollision | ||
42 | | max1 < min2 = NoCollision | ||
43 | | box1 `aabbpt` min2 && box1 `aabbpt` max2 = FullyContains | ||
44 | | box2 `aabbpt` min1 && box2 `aabbpt` max1 = FullyContainedBy | ||
45 | | (x max1) < (x min2) = NoCollision | ||
46 | | (x min1) > (x max2) = NoCollision | ||
47 | | (y max1) < (y min2) = NoCollision | ||
48 | | (y min1) > (y max2) = NoCollision | ||
49 | | otherwise = Collision | ||
50 | |||
51 | collideSphere sphere@(Circle c r) aabb@(AABB min max) | ||
52 | | test == FullyContains || test == FullyContainedBy = test | ||
53 | | normSq (c - boxC) > (l + r)^2 = NoCollision | ||
54 | | otherwise = Collision | ||
55 | where | ||
56 | test = aabb `collideBox` aabbFromCircle sphere | ||
57 | boxC = min + (max-min)/2 | ||
58 | l = norm $ min + (vec2 (x boxC) (y min)) - min | ||
59 | |||
60 | |||
61 | |||
62 | instance Collisionable Circle where | ||
63 | |||
64 | collideBox box sphere = case collideSphere sphere box of | ||
65 | FullyContains -> FullyContainedBy | ||
66 | FullyContainedBy -> FullyContains | ||
67 | x -> x | ||
68 | |||
69 | collideSphere s1@(Circle c1 r1) s2@(Circle c2 r2) | ||
70 | | distance_centers <= sub_radii = if (r1 > r2) then FullyContains else FullyContainedBy | ||
71 | | distance_centers <= sum_radii = Collision | ||
72 | | otherwise = NoCollision | ||
73 | where | ||
74 | distance_centers = normSq $ c1 - c2 | ||
75 | sum_radii = (r1 + r2)^2 | ||
76 | sub_radii = (r1 - r2)^2 | ||
77 | |||
78 | |||
79 | aabbPoints :: AABB -> [Vector2] | ||
80 | aabbPoints (AABB min max) = [p1,p2,p3,p4,p5,p6,p7,p8] | ||
81 | where | ||
82 | p1 = vec2 (x min) (y min) | ||
83 | p2 = vec2 (x min) (y min) | ||
84 | p3 = vec2 (x min) (y max) | ||
85 | p4 = vec2 (x min) (y max) | ||
86 | p5 = vec2 (x max) (y min) | ||
87 | p6 = vec2 (x max) (y min) | ||
88 | p7 = vec2 (x max) (y max) | ||
89 | p8 = vec2 (x max) (y max) | ||
90 | |||
91 | |||
92 | -- | A collisioner component. | ||
93 | data Collisioner | ||
94 | -- | An axis-aligned bounding box. | ||
95 | = AABBCol { getBox :: {-# UNPACK #-} !AABB } | ||
96 | -- | A bounding sphere. | ||
97 | | CircleCol { getCircle :: {-# UNPACK #-} !Circle } | ||
98 | |||
99 | |||
100 | -- | Create a collisioner from the specified box. | ||
101 | aabbCollisioner :: AABB -> Collisioner | ||
102 | aabbCollisioner = AABBCol | ||
103 | |||
104 | |||
105 | -- | Create a collisioner from the specified circle. | ||
106 | sphereCollisioner :: Circle -> Collisioner | ||
107 | sphereCollisioner = CircleCol | ||
108 | |||
109 | |||
110 | -- | Create the minimal AABB fully containing the specified collisioners. | ||
111 | buildAABB :: [Collisioner] -> AABB | ||
112 | buildAABB cols = aabb $ generatePoints cols | ||
113 | |||
114 | |||
115 | -- | Create the minimal AABB collisioner fully containing the specified circle. | ||
116 | boxFromSphere :: Circle -> Collisioner | ||
117 | boxFromSphere = AABBCol . aabbFromCircle | ||
118 | |||
119 | |||
120 | generatePoints :: [Collisioner] -> [Vector2] | ||
121 | generatePoints = foldr generate [] | ||
122 | where | ||
123 | generate (AABBCol (AABB min max)) acc = p1:p2:p3:p4:p5:p6:p7:p8:acc | ||
124 | where | ||
125 | p1 = vec2 (x min) (y min) | ||
126 | p2 = vec2 (x min) (y min) | ||
127 | p3 = vec2 (x min) (y max) | ||
128 | p4 = vec2 (x min) (y max) | ||
129 | p5 = vec2 (x max) (y min) | ||
130 | p6 = vec2 (x max) (y min) | ||
131 | p7 = vec2 (x max) (y max) | ||
132 | p8 = vec2 (x max) (y max) | ||
133 | |||
134 | generate (CircleCol (Circle c r)) acc = p1:p2:p3:p4:acc | ||
135 | where | ||
136 | p1 = c + unitx * (vec2 r r) | ||
137 | p2 = c - unitx * (vec2 r r) | ||
138 | p3 = c + unity * (vec2 r r) | ||
139 | p4 = c - unity * (vec2 r r) | ||
140 | |||
141 | |||
142 | -- | Collide the given collisioners. | ||
143 | collide :: Collisioner -> Collisioner -> CollisionType | ||
144 | collide (AABBCol box1) (AABBCol box2) = collideBox box1 box2 | ||
145 | collide (CircleCol s1) (CircleCol s2) = collideSphere s1 s2 | ||
146 | collide (AABBCol box) (CircleCol sphere) = collideBox box sphere | ||
147 | collide (CircleCol sphere) (AABBCol box) = collideSphere sphere box | ||
148 | |||
149 | |||
150 | -- | Move the collisioner. | ||
151 | move :: Vector2 -> Collisioner -> Collisioner | ||
152 | move v (AABBCol (AABB min max)) = AABBCol (AABB (min+v) (max+v)) | ||
153 | move v (CircleCol (Circle c r)) = CircleCol (Circle (c+v) r) | ||
154 | |||
155 | |||
156 | -- | Create the minimal box fully containing the specified circle. | ||
157 | aabbFromCircle :: Circle -> AABB | ||
158 | aabbFromCircle (Circle c r) = AABB bot top | ||
159 | where | ||
160 | bot = c - (vec2 r r) | ||
161 | top = c + (vec2 r r) | ||
diff --git a/Spear/Collision/Collision.hs b/Spear/Collision/Collision.hs deleted file mode 100644 index 60c2f03..0000000 --- a/Spear/Collision/Collision.hs +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | module Spear.Collision.Collision | ||
2 | ( | ||
3 | Collisionable(..) | ||
4 | , aabbFromCircle | ||
5 | ) | ||
6 | where | ||
7 | |||
8 | |||
9 | import Spear.Collision.Types | ||
10 | import Spear.Math.AABB | ||
11 | import Spear.Math.Circle | ||
12 | import Spear.Math.Plane | ||
13 | import Spear.Math.Vector2 | ||
14 | |||
15 | |||
16 | class Collisionable a where | ||
17 | collideBox :: AABB -> a -> CollisionType | ||
18 | collideSphere :: Circle -> a -> CollisionType | ||
19 | |||
20 | |||
21 | instance Collisionable AABB where | ||
22 | |||
23 | collideBox box1@(AABB min1 max1) box2@(AABB min2 max2) | ||
24 | | min1 > max2 = NoCollision | ||
25 | | max1 < min2 = NoCollision | ||
26 | | box1 `aabbpt` min2 && box1 `aabbpt` max2 = FullyContains | ||
27 | | box2 `aabbpt` min1 && box2 `aabbpt` max1 = FullyContainedBy | ||
28 | | (x max1) < (x min2) = NoCollision | ||
29 | | (x min1) > (x max2) = NoCollision | ||
30 | | (y max1) < (y min2) = NoCollision | ||
31 | | (y min1) > (y max2) = NoCollision | ||
32 | | otherwise = Collision | ||
33 | |||
34 | collideSphere sphere@(Circle c r) aabb@(AABB min max) | ||
35 | | test == FullyContains || test == FullyContainedBy = test | ||
36 | | normSq (c - boxC) > (l + r)^2 = NoCollision | ||
37 | | otherwise = Collision | ||
38 | where | ||
39 | test = aabb `collideBox` aabbFromCircle sphere | ||
40 | boxC = min + (max-min)/2 | ||
41 | l = norm $ min + (vec2 (x boxC) (y min)) - min | ||
42 | |||
43 | |||
44 | |||
45 | instance Collisionable Circle where | ||
46 | |||
47 | collideBox box sphere = case collideSphere sphere box of | ||
48 | FullyContains -> FullyContainedBy | ||
49 | FullyContainedBy -> FullyContains | ||
50 | x -> x | ||
51 | |||
52 | collideSphere s1@(Circle c1 r1) s2@(Circle c2 r2) | ||
53 | | distance_centers <= sub_radii = if (r1 > r2) then FullyContains else FullyContainedBy | ||
54 | | distance_centers <= sum_radii = Collision | ||
55 | | otherwise = NoCollision | ||
56 | where | ||
57 | distance_centers = normSq $ c1 - c2 | ||
58 | sum_radii = (r1 + r2)^2 | ||
59 | sub_radii = (r1 - r2)^2 | ||
60 | |||
61 | |||
62 | aabbPoints :: AABB -> [Vector2] | ||
63 | aabbPoints (AABB min max) = [p1,p2,p3,p4,p5,p6,p7,p8] | ||
64 | where | ||
65 | p1 = vec2 (x min) (y min) | ||
66 | p2 = vec2 (x min) (y min) | ||
67 | p3 = vec2 (x min) (y max) | ||
68 | p4 = vec2 (x min) (y max) | ||
69 | p5 = vec2 (x max) (y min) | ||
70 | p6 = vec2 (x max) (y min) | ||
71 | p7 = vec2 (x max) (y max) | ||
72 | p8 = vec2 (x max) (y max) | ||
73 | |||
74 | |||
75 | -- | Create the minimal box fully containing the specified circle. | ||
76 | aabbFromCircle :: Circle -> AABB | ||
77 | aabbFromCircle (Circle c r) = AABB bot top | ||
78 | where | ||
79 | bot = c - (vec2 r r) | ||
80 | top = c + (vec2 r r) | ||
diff --git a/Spear/Collision/Collisioner.hs b/Spear/Collision/Collisioner.hs deleted file mode 100644 index dd41d61..0000000 --- a/Spear/Collision/Collisioner.hs +++ /dev/null | |||
@@ -1,82 +0,0 @@ | |||
1 | module Spear.Collision.Collisioner | ||
2 | ( | ||
3 | Collisioner(..) | ||
4 | , CollisionType(..) | ||
5 | , aabbCollisioner | ||
6 | , sphereCollisioner | ||
7 | , buildAABB | ||
8 | , collide | ||
9 | , move | ||
10 | ) | ||
11 | where | ||
12 | |||
13 | |||
14 | import Spear.Collision.Collision as C | ||
15 | import Spear.Collision.Types | ||
16 | import Spear.Math.AABB | ||
17 | import Spear.Math.Circle | ||
18 | import Spear.Math.Vector2 | ||
19 | |||
20 | |||
21 | -- | A collisioner component. | ||
22 | data Collisioner | ||
23 | -- | An axis-aligned bounding box. | ||
24 | = AABBCol { getBox :: {-# UNPACK #-} !AABB } | ||
25 | -- | A bounding sphere. | ||
26 | | CircleCol { getCircle :: {-# UNPACK #-} !Circle } | ||
27 | |||
28 | |||
29 | -- | Create a 'Collisioner' from the specified box. | ||
30 | aabbCollisioner :: AABB -> Collisioner | ||
31 | aabbCollisioner = AABBCol | ||
32 | |||
33 | |||
34 | -- | Create a 'Collisioner' from the specified circle. | ||
35 | sphereCollisioner :: Circle -> Collisioner | ||
36 | sphereCollisioner = CircleCol | ||
37 | |||
38 | |||
39 | -- | Create the minimal 'AABB' fully containing the specified collisioners. | ||
40 | buildAABB :: [Collisioner] -> AABB | ||
41 | buildAABB cols = aabb $ generatePoints cols | ||
42 | |||
43 | |||
44 | -- | Create the minimal 'AABB' collisioner fully containing the specified circle. | ||
45 | boxFromSphere :: Circle -> Collisioner | ||
46 | boxFromSphere = AABBCol . aabbFromCircle | ||
47 | |||
48 | |||
49 | generatePoints :: [Collisioner] -> [Vector2] | ||
50 | generatePoints = foldr generate [] | ||
51 | where | ||
52 | generate (AABBCol (AABB min max)) acc = p1:p2:p3:p4:p5:p6:p7:p8:acc | ||
53 | where | ||
54 | p1 = vec2 (x min) (y min) | ||
55 | p2 = vec2 (x min) (y min) | ||
56 | p3 = vec2 (x min) (y max) | ||
57 | p4 = vec2 (x min) (y max) | ||
58 | p5 = vec2 (x max) (y min) | ||
59 | p6 = vec2 (x max) (y min) | ||
60 | p7 = vec2 (x max) (y max) | ||
61 | p8 = vec2 (x max) (y max) | ||
62 | |||
63 | generate (CircleCol (Circle c r)) acc = p1:p2:p3:p4:acc | ||
64 | where | ||
65 | p1 = c + unitx * (vec2 r r) | ||
66 | p2 = c - unitx * (vec2 r r) | ||
67 | p3 = c + unity * (vec2 r r) | ||
68 | p4 = c - unity * (vec2 r r) | ||
69 | |||
70 | |||
71 | -- | Collide the given collisioners. | ||
72 | collide :: Collisioner -> Collisioner -> CollisionType | ||
73 | collide (AABBCol box1) (AABBCol box2) = collideBox box1 box2 | ||
74 | collide (CircleCol s1) (CircleCol s2) = collideSphere s1 s2 | ||
75 | collide (AABBCol box) (CircleCol sphere) = collideBox box sphere | ||
76 | collide (CircleCol sphere) (AABBCol box) = collideSphere sphere box | ||
77 | |||
78 | |||
79 | -- | Move the collisioner. | ||
80 | move :: Vector2 -> Collisioner -> Collisioner | ||
81 | move v (AABBCol (AABB min max)) = AABBCol (AABB (min+v) (max+v)) | ||
82 | move v (CircleCol (Circle c r)) = CircleCol (Circle (c+v) r) | ||
diff --git a/Spear/Collision/Types.hs b/Spear/Collision/Types.hs deleted file mode 100644 index 61b224f..0000000 --- a/Spear/Collision/Types.hs +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | module Spear.Collision.Types | ||
2 | where | ||
3 | |||
4 | -- | Encodes several collision situations. | ||
5 | data CollisionType = NoCollision | Collision | FullyContains | FullyContainedBy | ||
6 | deriving (Eq, Show) | ||
diff --git a/Spear/Math/QuadTree.hs b/Spear/Math/QuadTree.hs index 2e92265..e553c88 100644 --- a/Spear/Math/QuadTree.hs +++ b/Spear/Math/QuadTree.hs | |||
@@ -9,7 +9,7 @@ module Spear.Math.QuadTree | |||
9 | ) | 9 | ) |
10 | where | 10 | where |
11 | 11 | ||
12 | import Spear.Collision.Types | 12 | import Spear.Collision |
13 | import Spear.Math.AABB | 13 | import Spear.Math.AABB |
14 | import Spear.Math.Vector2 | 14 | import Spear.Math.Vector2 |
15 | 15 | ||
diff --git a/Spear/Scene/GameObject.hs b/Spear/Scene/GameObject.hs index cfc825d..9886f35 100644 --- a/Spear/Scene/GameObject.hs +++ b/Spear/Scene/GameObject.hs | |||
@@ -23,8 +23,7 @@ module Spear.Scene.GameObject | |||
23 | where | 23 | where |
24 | 24 | ||
25 | 25 | ||
26 | import Spear.Collision.Collision | 26 | import Spear.Collision as Col |
27 | import Spear.Collision.Collisioner as Col | ||
28 | import Spear.GLSL | 27 | import Spear.GLSL |
29 | import Spear.Math.AABB | 28 | import Spear.Math.AABB |
30 | import qualified Spear.Math.Camera as Cam | 29 | import qualified Spear.Math.Camera as Cam |
diff --git a/Spear/Scene/Loader.hs b/Spear/Scene/Loader.hs index 081b927..820ad51 100644 --- a/Spear/Scene/Loader.hs +++ b/Spear/Scene/Loader.hs | |||
@@ -19,7 +19,7 @@ where | |||
19 | 19 | ||
20 | 20 | ||
21 | import Spear.Assets.Model as Model | 21 | import Spear.Assets.Model as Model |
22 | import Spear.Collision.Collisioner | 22 | import Spear.Collision |
23 | import qualified Spear.GLSL as GLSL | 23 | import qualified Spear.GLSL as GLSL |
24 | import Spear.Math.Matrix3 as M3 | 24 | import Spear.Math.Matrix3 as M3 |
25 | import Spear.Math.Matrix4 as M4 | 25 | import Spear.Math.Matrix4 as M4 |
diff --git a/Spear/Scene/Scene.hs b/Spear/Scene/Scene.hs index 0dfa459..b8366f3 100644 --- a/Spear/Scene/Scene.hs +++ b/Spear/Scene/Scene.hs | |||
@@ -13,14 +13,14 @@ module Spear.Scene.Scene | |||
13 | -- * Update and render | 13 | -- * Update and render |
14 | , update | 14 | , update |
15 | , updateM | 15 | , updateM |
16 | , collide | 16 | , Spear.Scene.Scene.collide |
17 | , collideM | 17 | , collideM |
18 | , render | 18 | , render |
19 | ) | 19 | ) |
20 | where | 20 | where |
21 | 21 | ||
22 | 22 | ||
23 | import Spear.Collision.Types | 23 | import Spear.Collision |
24 | import Spear.Game (Game) | 24 | import Spear.Game (Game) |
25 | import Spear.Math.AABB | 25 | import Spear.Math.AABB |
26 | import Spear.Math.QuadTree as QT | 26 | import Spear.Math.QuadTree as QT |