Mercurial > projects > openmelee
annotate melee.d @ 8:4ee9e4a0c03b
changed license header
author | zzzzrrr <mason.green@gmail.com> |
---|---|
date | Sat, 21 Mar 2009 19:44:19 -0400 |
parents | 2217fd1fe384 |
children | d998bf1b0654 |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright (c) 2009, Mason Green (zzzzrrr) | |
8 | 3 * http://www.dsource.org/projects/openmelee |
0 | 4 * |
5 * All rights reserved. | |
6 * | |
7 * Redistribution and use in source and binary forms, with or without modification, | |
8 * are permitted provided that the following conditions are met: | |
9 * | |
10 * * Redistributions of source code must retain the above copyright notice, | |
11 * this list of conditions and the following disclaimer. | |
12 * * Redistributions in binary form must reproduce the above copyright notice, | |
13 * this list of conditions and the following disclaimer in the documentation | |
14 * and/or other materials provided with the distribution. | |
15 * * Neither the name of the polygonal nor the names of its contributors may be | |
16 * used to endorse or promote products derived from this software without specific | |
17 * prior written permission. | |
18 * | |
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
30 */ | |
2 | 31 module openmelee.melee; |
0 | 32 |
5 | 33 import tango.io.Stdout: Stdout; |
34 | |
0 | 35 import Integer = tango.text.convert.Integer; |
36 import tango.math.Math; | |
37 import tango.math.random.Kiss; | |
38 | |
39 import xf.hybrid.Event; | |
40 import xf.input.KeySym; | |
41 import xf.omg.core.LinearAlgebra; | |
42 | |
43 public import blaze.all; | |
44 | |
2 | 45 import openmelee.boundaryListener; |
46 import openmelee.contactListener; | |
47 import openmelee.ship; | |
48 import openmelee.urQuan; | |
49 import openmelee.orz; | |
6 | 50 import openmelee.planet; |
0 | 51 |
52 // Cursor scale factor | |
53 const CURSORSIZE = 0.05f; | |
54 | |
55 const INIT_SPAWN_SIZE = 0.5f; | |
56 | |
57 // Dragging stuffs | |
58 const BUNGEE_K = 1.5f; | |
59 // Damping factor for dragging | |
60 const DRAGDAMP = 20.0f; | |
61 | |
62 // Size of hinges | |
63 const HINGE_RADIUS = 0.05f; | |
64 | |
65 // Smallest allowed dimension | |
66 const MIN_DIMENSION = 0.1; | |
67 | |
68 const k_maxContactPoints = 2048; | |
69 | |
70 enum ContactState { | |
71 e_contactAdded, | |
72 e_contactPersisted, | |
73 e_contactRemoved | |
74 } | |
75 | |
76 struct ContactPoint { | |
77 bzShape shape1; | |
78 bzShape shape2; | |
79 bzVec2 normal; | |
80 bzVec2 position; | |
81 bzVec2 velocity; | |
82 bzContactID id; | |
83 ContactState state; | |
84 } | |
85 | |
86 // Melee settings. Some can be controlled in the GUI. | |
87 struct Settings { | |
7
2217fd1fe384
added angular and linear velocity limit
zzzzrrr <mason.green@gmail.com>
parents:
6
diff
changeset
|
88 float hz = 30; |
2217fd1fe384
added angular and linear velocity limit
zzzzrrr <mason.green@gmail.com>
parents:
6
diff
changeset
|
89 int velocityIterations = 5; |
2217fd1fe384
added angular and linear velocity limit
zzzzrrr <mason.green@gmail.com>
parents:
6
diff
changeset
|
90 int positionIterations = 1; |
0 | 91 bool drawShapes = true; |
92 bool drawJoints = true; | |
93 bool drawControllers; | |
94 bool drawCoreShapes; | |
5 | 95 bool drawAABBs; |
0 | 96 bool drawOBBs; |
97 bool drawPairs; | |
98 bool drawContactPoints; | |
99 bool drawContactNormals; | |
100 bool drawContactForces; | |
101 bool drawFrictionForces; | |
102 bool drawCOMs; | |
103 bool drawStats; | |
104 bool enableWarmStarting; | |
105 bool enableTOI; | |
106 } | |
107 | |
108 // Dirty, dirty hack for communicating config changes to Main | |
109 // TODO: Harass h3 to add .changed to hybrid so this isn't necessary | |
110 struct ConfigChange (T) | |
111 { | |
112 protected | |
113 { | |
114 bool _pending = false; | |
115 T _value; | |
116 } | |
117 | |
118 T value() | |
119 { | |
120 _pending = false; | |
121 return _value; | |
122 } | |
123 | |
124 void value(T change) | |
125 { | |
126 _value = change; | |
127 _pending = true; | |
128 } | |
129 | |
130 bool pending() | |
131 { | |
132 return _pending; | |
133 } | |
134 | |
135 T opAssign(T change) | |
136 { | |
137 value(change); | |
138 return _value; | |
139 } | |
140 | |
141 bool opEquals(T other) | |
142 { | |
143 return _value == other; | |
144 } | |
145 } | |
146 | |
147 T randomRange(T = int) (T min, T max) | |
148 { | |
149 return min + Kiss.instance.natural() % (max + 1 - min); | |
150 } | |
151 | |
152 class Melee | |
153 { | |
154 | |
155 this(Settings *settings) | |
156 { | |
157 this.settings = settings; | |
158 spawnRect = vec2(INIT_SPAWN_SIZE, INIT_SPAWN_SIZE); | |
159 // bzWorld boundary callback | |
160 m_boundaryListener = new BoundaryListener(this); | |
161 // bzContact callback | |
162 m_contactListener = new ContactListener(this); | |
5 | 163 init(); |
0 | 164 } |
165 | |
166 void init() { | |
167 // Define world boundaries | |
7
2217fd1fe384
added angular and linear velocity limit
zzzzrrr <mason.green@gmail.com>
parents:
6
diff
changeset
|
168 worldAABB.lowerBound.set(-200.0f, -200.0f); |
2217fd1fe384
added angular and linear velocity limit
zzzzrrr <mason.green@gmail.com>
parents:
6
diff
changeset
|
169 worldAABB.upperBound.set(200.0f, 200.0f); |
0 | 170 world = new bzWorld(worldAABB, gravity, allowSleep); |
171 world.boundaryListener = m_boundaryListener; | |
172 world.contactListener = m_contactListener; | |
173 viewCenter = vec2(10, 10); | |
174 ship1 = new Orz(world); | |
175 ship2 = new UrQuan(world); | |
6 | 176 auto planet = new Planet(world); |
0 | 177 } |
178 | |
179 void drag() | |
180 { | |
181 | |
182 } | |
183 | |
184 EventHandling onClick(MouseButtonEvent e) | |
185 { | |
186 return EventHandling.Stop; | |
187 } | |
188 | |
189 EventHandling onKey(KeyboardEvent e) | |
190 { | |
5 | 191 // Key pressed |
0 | 192 if (e.down) { |
193 switch (e.keySym) { | |
5 | 194 case KeySym.space: |
195 settings.drawAABBs = !settings.drawAABBs; | |
196 break; | |
0 | 197 case KeySym.Escape: |
198 quit = true; | |
199 break; | |
5 | 200 case KeySym.Up: |
201 thrust = true; | |
202 break; | |
203 case KeySym.Left: | |
204 ship1.turnLeft(); | |
205 break; | |
206 case KeySym.Right: | |
207 ship1.turnRight(); | |
208 break; | |
209 case KeySym.Down: | |
210 break; | |
0 | 211 default: |
212 break; | |
213 } | |
214 // Key released | |
215 } else { | |
5 | 216 if(e.keySym == KeySym.Up) { |
0 | 217 thrust = false; |
5 | 218 } else if (e.keySym == KeySym.Left || e.keySym == KeySym.Right) { |
0 | 219 ship1.rBody.angularVelocity = 0.0f; |
220 } | |
221 } | |
222 return EventHandling.Stop; | |
223 } | |
224 | |
225 // Mouse move | |
226 EventHandling onMove(MouseMoveEvent e) | |
227 { | |
228 return EventHandling.Stop; | |
229 } | |
230 | |
231 EventHandling onDT(TimeUpdateEvent e) | |
232 { | |
233 return EventHandling.Continue; | |
234 } | |
235 | |
236 EventHandling onMouseEnter(MouseEnterEvent e) | |
237 { | |
238 return EventHandling.Continue; | |
239 } | |
240 | |
241 EventHandling onMouseLeave(MouseLeaveEvent e) | |
242 { | |
243 return EventHandling.Continue; | |
244 } | |
245 | |
246 protected | |
247 { | |
248 const bzVec2 gravity = bzVec2(0.0f, 0.0f); | |
249 bool allowSleep = false; | |
250 | |
251 vec2 spawnRect; | |
252 | |
253 vec2[] drawing; | |
254 | |
255 vec2i screenSize = vec2i.zero; | |
256 vec2 mousePos = vec2.zero; | |
257 | |
258 bool scaling = false; | |
259 bool full = false; | |
260 | |
261 vec2 spawnStart; | |
262 | |
263 bool preserveBullet = false; | |
264 | |
265 float waterDelta = 0; | |
266 } | |
267 | |
268 void boundaryViolated(bzBody rBody) | |
269 { | |
5 | 270 float x,y; |
271 | |
272 if(rBody.position.x > worldAABB.upperBound.x) { | |
273 x = worldAABB.lowerBound.x + 5; | |
274 rBody.position = bzVec2(x, rBody.position.y); | |
275 } else if (rBody.position.x < worldAABB.lowerBound.x) { | |
276 x = worldAABB.upperBound.x - 5; | |
277 rBody.position = bzVec2(x, rBody.position.y); | |
278 } else if (rBody.position.y > worldAABB.upperBound.y) { | |
279 y = worldAABB.lowerBound.y + 5; | |
280 rBody.position = bzVec2(rBody.position.x, y); | |
281 } else if(rBody.position.y < worldAABB.lowerBound.y) { | |
282 y = worldAABB.upperBound.y - 5; | |
283 rBody.position = bzVec2(rBody.position.x, y); | |
284 } | |
0 | 285 } |
286 | |
287 bool quit; | |
288 | |
289 // Ortho view zoom | |
290 float zoom = 40; | |
291 int pointCount; | |
292 vec2 viewCenter; | |
293 | |
294 bzWorld world; | |
295 Settings *settings; | |
296 | |
297 // bzWorld boundary listener. Destroy bodies that leave world bzAABB | |
298 bzBoundaryListener m_boundaryListener; | |
299 bzContactListener m_contactListener; | |
300 ContactPoint[k_maxContactPoints] points; | |
301 | |
302 ConfigChange!(vec2) editChange; | |
303 bool thrust; | |
2 | 304 bzAABB worldAABB; |
305 | |
0 | 306 Ship ship1; |
307 Ship ship2; | |
308 } | |
309 | |
310 // Utility functions | |
311 bzVec2 toBlaze(vec2 vec) | |
312 { | |
313 auto ret = bzVec2(vec.x, vec.y); | |
314 return ret; | |
315 } | |
316 | |
317 vec2 rotate(vec2 point, float rad) | |
318 { | |
319 return vec2(cos(rad) * point.x - sin(rad) * point.y, sin(rad) * point.x + cos(rad) * point.y); | |
320 } | |
321 | |
322 class Select | |
323 { | |
324 bool select; | |
325 } |