Mercurial > projects > openmelee
annotate render/render.d @ 18:7f74e064dad5
refactored code
author | zzzzrrr <mason.green@gmail.com> |
---|---|
date | Wed, 25 Mar 2009 11:28:25 -0400 |
parents | render.d@82efafc87d54 |
children | 4fce5596d1f6 |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright (c) 2009, Mason Green (zzzzrrr) | |
3 * Based on Box2D by Erin Catto, http://www.box2d.org | |
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 */ | |
18 | 31 module openmelee.render.render; |
32 | |
33 import tango.math.Math : PI; | |
0 | 34 |
35 import xf.dog.Dog; | |
36 import xf.omg.core.LinearAlgebra; | |
37 import xf.hybrid.Event; | |
38 import xf.hybrid.Font; | |
39 | |
18 | 40 import blaze.bzWorld : bzWorld; |
41 import blaze.dynamics.bzBody : bzBody; | |
42 import blaze.collision.shapes.bzShape : bzShape; | |
43 import blaze.collision.shapes.bzShapeType; | |
44 import blaze.collision.shapes.bzCircle : bzCircle; | |
45 import blaze.collision.shapes.bzPolygon : bzPolygon; | |
46 import blaze.collision.shapes.bzEdge : bzEdge; | |
47 import blaze.collision.nbody.bzBroadPhase : bzBroadPhase, bzProxy; | |
48 import blaze.collision.bzCollision : bzAABB; | |
49 import blaze.common.bzMath : bzXForm, bzVec2, bzMul, bzClamp; | |
50 import blaze.common.bzConstants : k_toiSlop,k_maxProxies; | |
0 | 51 |
18 | 52 import openmelee.ships.ship : Ship; |
53 import openmelee.melee.melee : Settings; | |
54 | |
55 // Cursor scale factor | |
56 const CURSORSIZE = 0.05f; | |
57 const INIT_SPAWN_SIZE = 0.5f; | |
58 // Dragging stuffs | |
59 const BUNGEE_K = 1.5f; | |
60 // Damping factor for dragging | |
61 const DRAGDAMP = 20.0f; | |
62 // Size of hinges | |
63 const HINGE_RADIUS = 0.05f; | |
64 // Smallest allowed dimension | |
65 const MIN_DIMENSION = 0.1; | |
7
2217fd1fe384
added angular and linear velocity limit
zzzzrrr <mason.green@gmail.com>
parents:
6
diff
changeset
|
66 const MAX_CIRCLE_RES = 32; |
2217fd1fe384
added angular and linear velocity limit
zzzzrrr <mason.green@gmail.com>
parents:
6
diff
changeset
|
67 |
0 | 68 /// Color for drawing. Each value has the range [0,1]. |
69 struct Color { | |
70 static Color opCall(float r, float g, float b) | |
71 { | |
72 Color u; | |
73 u.r = r; | |
74 u.g = g; | |
75 u.b = b; | |
76 return u; | |
77 } | |
78 | |
79 float r = 0; | |
80 float g = 0; | |
81 float b = 0; | |
82 } | |
83 | |
18 | 84 class Render |
0 | 85 { |
86 | |
18 | 87 float zoom = 40; |
88 vec2 viewCenter; | |
89 bzWorld world; | |
90 vec2i screenSize; | |
91 bool scaling = false; | |
92 bool full = false; | |
93 Settings settings; | |
94 Ship ship1, ship2; | |
95 | |
96 this(bzWorld world, Ship s1, Ship s2, Settings settings) { | |
97 this.settings = settings; | |
98 ship1 = s1; | |
99 ship2 = s2; | |
100 this.world = world; | |
101 viewCenter = vec2(10, 10); | |
102 screenSize = vec2i.zero; | |
103 } | |
0 | 104 |
18 | 105 void drawCircle(GL gl, vec2 center, float radius, bool water = false, float theta = float.nan) |
106 { | |
107 int segs = cast(int)(radius) + 20; | |
108 if (segs > MAX_CIRCLE_RES) segs = MAX_CIRCLE_RES; | |
109 double coef = 2.0 * PI / segs; | |
0 | 110 |
18 | 111 auto realTheta = (theta <>= 0 ? theta : 0); |
112 if (water) { | |
113 gl.immediate(GL_TRIANGLE_FAN, | |
114 { | |
115 gl.Vertex2fv(center.ptr); | |
116 for (int n = 0; n <= segs; n++) { | |
117 double rads = n * coef; | |
118 gl.Vertex2f(radius * cos(rads + realTheta) + center.x, radius * sin(rads + realTheta) + center.y); | |
119 } | |
120 }); | |
121 } | |
122 | |
123 gl.immediate(GL_LINE_STRIP, | |
0 | 124 { |
125 for (int n = 0; n <= segs; n++) { | |
126 double rads = n * coef; | |
127 gl.Vertex2f(radius * cos(rads + realTheta) + center.x, radius * sin(rads + realTheta) + center.y); | |
128 } | |
18 | 129 if (theta <>= 0) |
130 gl.Vertex2fv(center.ptr); | |
131 }); | |
132 } | |
133 | |
134 void drawSolidCircle(GL gl, vec2 center, float radius, vec2 axis, Color color) | |
135 { | |
136 const k_segments = 25.0f; | |
137 const k_increment = 2.0f * PI / k_segments; | |
138 float theta = 0.0f; | |
139 gl.Enable(GL_BLEND); | |
140 gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
141 gl.Color4f(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 0.5f); | |
142 gl.Begin(GL_TRIANGLE_FAN); | |
143 for (int i = 0; i < k_segments; ++i) { | |
144 vec2 v = center + radius * vec2(cos(theta), sin(theta)); | |
145 gl.Vertex2f(v.x, v.y); | |
146 theta += k_increment; | |
147 } | |
148 gl.End(); | |
149 gl.Disable(GL_BLEND); | |
150 | |
151 theta = 0.0f; | |
152 gl.Color4f(color.r, color.g, color.b, 1.0f); | |
153 gl.Begin(GL_LINE_LOOP); | |
154 for (int i = 0; i < k_segments; ++i) { | |
155 vec2 v = center + radius * vec2(cos(theta), sin(theta)); | |
156 gl.Vertex2f(v.x, v.y); | |
157 theta += k_increment; | |
158 } | |
159 gl.End(); | |
160 | |
161 vec2 p = center + radius * axis; | |
162 gl.Begin(GL_LINES); | |
163 gl.Vertex2f(center.x, center.y); | |
164 gl.Vertex2f(p.x, p.y); | |
165 gl.End(); | |
166 } | |
167 | |
168 void drawPolygon(GL gl, vec2[] glVerts, Color color) | |
169 { | |
170 gl.Color3f(color.r, color.g, color.b); | |
171 gl.immediate(GL_LINE_LOOP, | |
172 { | |
173 foreach (v; glVerts) | |
174 gl.Vertex2fv(v.ptr); | |
175 }); | |
176 } | |
177 | |
178 void drawSolidPolygon(GL gl, vec2[] vertices, Color color) | |
179 { | |
180 gl.Enable(GL_BLEND); | |
181 gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
182 gl.Color4f(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 0.5f); | |
183 gl.Begin(GL_TRIANGLE_FAN); | |
184 for (int i = 0; i < vertices.length; ++i) { | |
185 gl.Vertex2f(vertices[i].x, vertices[i].y); | |
186 } | |
187 gl.End(); | |
188 gl.Disable(GL_BLEND); | |
189 | |
190 gl.Color4f(color.r, color.g, color.b, 1.0f); | |
191 gl.Begin(GL_LINE_LOOP); | |
192 for (int i = 0; i < vertices.length; ++i) { | |
193 gl.Vertex2f(vertices[i].x, vertices[i].y); | |
194 } | |
195 gl.End(); | |
196 } | |
197 | |
198 | |
199 void drawPoint(GL gl, vec2 p, float size, Color color) | |
200 { | |
201 gl.Color3f(color.r, color.g, color.b); | |
202 gl.PointSize(size); | |
203 gl.Begin(GL_POINTS); | |
204 gl.Vertex2f(p.x, p.y); | |
205 gl.End(); | |
206 gl.PointSize(1.0f); | |
207 } | |
208 | |
209 void drawSegment(GL gl, vec2 begin, vec2 end, Color color) | |
210 { | |
211 gl.Color3f(color.r, color.g, color.b); | |
212 gl.immediate(GL_LINES, | |
213 { | |
214 gl.Vertex2fv(begin.ptr); | |
215 gl.Vertex2fv(end.ptr); | |
216 }); | |
217 } | |
218 | |
219 // TODO: handle inequal radii correctly | |
220 void connectCircles(GL gl, vec2 center1, float radius1, vec2 center2, float radius2) | |
221 { | |
222 auto d = center2 - center1; | |
223 if (!d.length) | |
224 return; | |
225 d *= (d.length - radius1) / d.length; | |
226 center1 += d; | |
227 center2 -= d; | |
228 gl.immediate(GL_LINES, | |
229 { | |
230 gl.Vertex2fv(center1.ptr); | |
231 gl.Vertex2fv(center2.ptr); | |
232 }); | |
233 } | |
234 | |
235 void drawXForm(GL gl, bzXForm xf) | |
236 { | |
237 bzVec2 p1 = xf.position, p2; | |
238 const k_axisScale = 0.4f; | |
239 | |
240 gl.Begin(GL_LINES); | |
241 { | |
242 gl.Color3f(1.0f, 0.0f, 0.0f); | |
243 gl.Vertex2f(p1.x, p1.y); | |
244 p2 = p1 + k_axisScale * xf.R.col1; | |
245 gl.Vertex2f(p2.x, p2.y); | |
246 | |
247 gl.Color3f(0.0f, 1.0f, 0.0f); | |
248 gl.Vertex2f(p1.x, p1.y); | |
249 p2 = p1 + k_axisScale * xf.R.col2; | |
250 gl.Vertex2f(p2.x, p2.y); | |
251 } | |
252 gl.End(); | |
253 } | |
254 | |
255 void drawSpring(GL gl, vec2 a, vec2 b, uint zigs) | |
256 { | |
257 zigs++; | |
258 | |
259 // Portion of length dedicated to connectors | |
260 const float connPart = 0.2; | |
261 | |
262 vec2 inc = (b - a) / (zigs); | |
263 // One step from a to b | |
264 vec2 zigLen = inc * (1 - connPart); | |
265 // Length of a connector | |
266 vec2 connLen = inc * (connPart / 2) * zigs; | |
267 // Width of a zig | |
268 vec2 zigWidth = (b - a).rotatedHalfPi.normalized; | |
269 gl.immediate(GL_LINE_STRIP, | |
270 { | |
271 gl.Vertex2fv(a.ptr); | |
272 | |
273 a += connLen; | |
274 gl.Vertex2fv(a.ptr); | |
275 | |
276 bool dir = true; | |
277 a += zigWidth / 2 + zigLen / 2; | |
278 for (int i = 0; i < zigs; i++) { | |
279 gl.Vertex2fv(a.ptr); | |
280 a += zigLen; | |
281 if (dir) { | |
282 a -= zigWidth; | |
283 }else { | |
284 a += zigWidth; | |
285 } | |
286 dir = !dir; | |
287 } | |
288 | |
289 gl.Vertex2fv((b - connLen).ptr); | |
290 gl.Vertex2fv(b.ptr); | |
0 | 291 }); |
292 } | |
293 | |
18 | 294 void drawShape(GL gl, bzShape shape, bzXForm xf, Color color, bool core) |
0 | 295 { |
18 | 296 Color coreColor = Color(0.9f, 0.6f, 0.6f); |
0 | 297 |
18 | 298 switch (shape.type) { |
299 case bzShapeType.CIRCLE: | |
300 auto circle = cast(bzCircle)shape; | |
0 | 301 |
18 | 302 vec2 center = vec2.from(bzMul(xf, circle.localPosition)); |
303 float radius = circle.radius; | |
304 vec2 axis = vec2.from(xf.R.col1); | |
305 | |
306 gl.drawSolidCircle(center, radius, axis, color); | |
0 | 307 |
18 | 308 if (core) { |
309 gl.Color3f(coreColor.r, coreColor.g, coreColor.b); | |
310 gl.drawCircle(center, radius - k_toiSlop); | |
311 } | |
312 break; | |
313 case bzShapeType.POLYGON: | |
314 { | |
315 bzPolygon poly = cast(bzPolygon)shape; | |
316 bzVec2[] vertices = poly.worldVertices; | |
317 vec2[] verts; | |
318 verts.length = vertices.length; | |
319 foreach (int i, v; vertices) { | |
320 verts[i] = vec2.from(v); | |
321 } | |
0 | 322 |
18 | 323 gl.drawSolidPolygon(verts, color); |
0 | 324 |
18 | 325 if (core) { |
326 bzVec2[] localCoreVertices = poly.coreVertices; | |
327 verts.length = localCoreVertices.length; | |
328 for (int i = 0; i < localCoreVertices.length; ++i) { | |
329 verts[i] = vec2.from(bzMul(xf, localCoreVertices[i])); | |
330 } | |
331 gl.drawPolygon(verts, coreColor); | |
332 } | |
333 } | |
334 break; | |
0 | 335 |
18 | 336 case bzShapeType.EDGE: |
337 { | |
338 bzEdge edge = cast(bzEdge)shape; | |
0 | 339 |
18 | 340 vec2 p1 = vec2.from(bzMul(xf, edge.vertex1)); |
341 vec2 p2 = vec2.from(bzMul(xf, edge.vertex2)); | |
342 gl.drawSegment(p1, p2, color); | |
0 | 343 |
18 | 344 if (core) { |
345 p1 = vec2.from(bzMul(xf, edge.coreVertex1)); | |
346 p2 = vec2.from(bzMul(xf, edge.coreVertex2)); | |
347 gl.drawSegment(p1, p2, coreColor); | |
348 } | |
349 } | |
350 break; | |
351 } | |
352 } | |
0 | 353 |
18 | 354 void draw(vec2i screenSize, GL gl) |
0 | 355 { |
18 | 356 |
357 vec2 point1 = vec2.from(ship1.rBody.position); | |
358 vec2 point2 = vec2.from(ship2.rBody.position); | |
359 vec2 range = point1 - point2; | |
360 zoom = bzClamp(1000/range.length, 2, 60); | |
361 viewCenter = point1 - (range * 0.5f); | |
362 | |
363 this.screenSize = screenSize; | |
0 | 364 |
18 | 365 gl.LoadIdentity(); |
366 gl.MatrixMode(GL_PROJECTION); | |
367 gl.LoadIdentity(); | |
368 | |
369 float left = -screenSize.x / zoom; | |
370 float right = screenSize.x / zoom; | |
371 float bottom = -screenSize.y / zoom; | |
372 float top = screenSize.y / zoom; | |
0 | 373 |
18 | 374 gl.gluOrtho2D(left, right, bottom, top); |
375 gl.Translatef(-viewCenter.x, -viewCenter.y, 0); | |
376 gl.MatrixMode(GL_MODELVIEW); | |
377 gl.Disable(GL_DEPTH_TEST); | |
378 gl.LoadIdentity(); | |
379 gl.Clear(GL_COLOR_BUFFER_BIT); | |
0 | 380 |
18 | 381 vec2 pp1 = vec2.from(ship2.rBody.position); |
382 vec2 pp2 = vec2.from(ship2.state.target); | |
383 | |
384 //gl.drawSegment(pp1, pp2, Color(0, 1, 0)); | |
385 | |
386 // Draw dynamic bodies | |
387 if (settings.drawShapes) { | |
388 for (bzBody b = world.bodyList; b; b = b.next) { | |
389 for (bzShape shape = b.shapeList; shape; shape = shape.next) { | |
390 | |
391 bzShape s = shape; | |
392 bzXForm xf = b.xf; | |
0 | 393 |
18 | 394 if (b.isStatic) { |
395 gl.drawShape(s, xf, Color(0.5f, 0.9f, 0.5f), settings.drawCoreShapes); | |
396 }else if (b.isSleeping) { | |
397 gl.drawShape(s, xf, Color(0.5f, 0.5f, 0.9f), settings.drawCoreShapes); | |
398 }else { | |
399 gl.drawShape(s, xf, Color(0.9f, 0.9f, 0.9f), settings.drawCoreShapes); | |
400 } | |
0 | 401 |
18 | 402 gl.LoadIdentity(); |
403 gl.Flush(); | |
404 } | |
405 } | |
0 | 406 } |
407 | |
18 | 408 // Draw joints |
409 /* | |
410 if (settings.drawJoints) { | |
411 Color color = Color(0, 0, 1); | |
412 gl.Color3f(0, 0, 1); | |
0 | 413 |
18 | 414 gl.LineWidth(1); |
415 for (bzJoint joint = world.jointList; joint; joint = joint.next) { | |
416 auto distance = cast(bzDistanceJoint)joint; | |
417 auto pulley = cast(bzPulleyJoint)joint; | |
418 auto revolute = cast(bzRevoluteJoint)joint; | |
419 auto prismatic = cast(bzPrismaticJoint)joint; | |
420 auto line = cast(bzLineJoint)joint; | |
421 if (distance) { | |
422 color = Color(.5, .5, 0); | |
423 // Endpoints | |
424 vec2 a = vec2.from(distance.anchor1); | |
425 vec2 b = vec2.from(distance.anchor2); | |
426 // Circles | |
427 gl.drawCircle(a, HINGE_RADIUS); | |
428 gl.drawCircle(b, HINGE_RADIUS); | |
429 // Connecting line | |
430 gl.connectCircles(a, HINGE_RADIUS, b, HINGE_RADIUS); | |
431 }else if (pulley) { | |
432 auto a = vec2.from(pulley.anchor1); | |
433 auto b = vec2.from(pulley.groundAnchor1); | |
434 auto c = vec2.from(pulley.groundAnchor2); | |
435 auto d = vec2.from(pulley.anchor2); | |
436 gl.drawCircle(a, HINGE_RADIUS); | |
437 gl.drawCircle(b, HINGE_RADIUS); | |
438 gl.connectCircles(a, HINGE_RADIUS, b, HINGE_RADIUS); | |
439 gl.drawSegment(b, c, color); | |
440 gl.drawCircle(c, HINGE_RADIUS); | |
441 gl.drawCircle(d, HINGE_RADIUS); | |
442 gl.connectCircles(c, HINGE_RADIUS, d, HINGE_RADIUS); | |
443 }else if (revolute) { | |
444 auto a = vec2.from(revolute.rBody1.position); | |
445 auto b = vec2.from(revolute.anchor1); | |
446 auto c = vec2.from(revolute.rBody2.position); | |
447 gl.drawCircle(a, HINGE_RADIUS); | |
448 gl.drawCircle(b, HINGE_RADIUS); | |
449 gl.connectCircles(a, HINGE_RADIUS, b, HINGE_RADIUS); | |
450 gl.drawCircle(c, HINGE_RADIUS); | |
451 gl.connectCircles(b, HINGE_RADIUS, c, HINGE_RADIUS); | |
452 }else if (prismatic) { | |
453 auto a = vec2.from(prismatic.rBody1.position); | |
454 auto b = vec2.from(prismatic.anchor1); | |
455 auto c = vec2.from(prismatic.rBody2.position); | |
456 gl.drawCircle(a, HINGE_RADIUS); | |
457 gl.drawCircle(b, HINGE_RADIUS); | |
458 gl.connectCircles(a, HINGE_RADIUS, b, HINGE_RADIUS); | |
459 gl.drawCircle(c, HINGE_RADIUS); | |
460 gl.connectCircles(b, HINGE_RADIUS, c, HINGE_RADIUS); | |
461 }else if (line) { | |
462 auto a = vec2.from(line.rBody1.position); | |
463 auto b = vec2.from(line.anchor1); | |
464 auto c = vec2.from(line.rBody2.position); | |
465 gl.drawCircle(a, HINGE_RADIUS); | |
466 gl.drawCircle(b, HINGE_RADIUS); | |
467 gl.connectCircles(a, HINGE_RADIUS, b, HINGE_RADIUS); | |
468 gl.drawCircle(c, HINGE_RADIUS); | |
469 gl.connectCircles(b, HINGE_RADIUS, c, HINGE_RADIUS); | |
470 } | |
471 } | |
472 | |
0 | 473 |
18 | 474 if (settings.drawControllers) { |
475 bzForceGenerator[] forces = world.forces; | |
476 foreach (f; forces) { | |
477 auto spring1 = cast(bzSpring1) f; | |
478 auto spring2 = cast(bzSpring2) f; | |
479 auto buoyancy = cast(bzBuoyancy) f; | |
0 | 480 |
18 | 481 if (spring1) { |
482 auto bungee1 = cast(bzBungee1)spring1; | |
483 if (bungee1) { | |
484 gl.Color3f(.5, .5, 0); | |
485 // Endpoints | |
486 vec2 a = vec2.from(bungee1.rBody.position); | |
487 vec2 b = vec2.from(bungee1.anchor); | |
488 // Circles | |
489 gl.drawCircle(a, HINGE_RADIUS); | |
490 gl.drawCircle(b, HINGE_RADIUS); | |
491 // Connecting line | |
492 gl.connectCircles(a, HINGE_RADIUS, b, HINGE_RADIUS); | |
493 }else { | |
494 uint zigs = 10; | |
495 auto anchor1 = vec2.from(spring1.anchor); | |
496 auto anchor2 = vec2.from(spring1.rBody.position); | |
497 gl.drawSpring(anchor1, anchor2, zigs); | |
498 } | |
499 } | |
2 | 500 |
18 | 501 if (spring2) { |
502 auto bungee2 = cast(bzBungee2)spring2; | |
503 if (bungee2) { | |
504 gl.Color3f(.5, .5, 0); | |
505 // Endpoints | |
506 vec2 a = vec2.from(bungee2.rBody.position); | |
507 vec2 b = vec2.from(bungee2.otherBody.position); | |
508 // Circles | |
509 gl.drawCircle(a, HINGE_RADIUS); | |
510 gl.drawCircle(b, HINGE_RADIUS); | |
511 // Connecting line | |
512 gl.connectCircles(a, HINGE_RADIUS, b, HINGE_RADIUS); | |
513 }else { | |
514 uint zigs = 10; | |
515 auto anchor1 = vec2.from(spring2.otherBody.position); | |
516 auto anchor2 = vec2.from(spring2.rBody.position); | |
517 gl.drawSpring(anchor1, anchor2, zigs); | |
518 } | |
519 } | |
0 | 520 |
18 | 521 if(buoyancy) { |
522 float plane = buoyancy.planeOffset; | |
523 vec2 p1 = vec2(-50, plane); | |
524 vec2 p2 = vec2(50, plane); | |
525 gl.drawSegment(p1, p2, color); | |
0 | 526 } |
18 | 527 } |
528 } | |
529 } | |
530 */ | |
531 | |
532 // Draw the world bounds | |
533 bzBroadPhase bp = world.broadPhase; | |
534 bzVec2 worldLower = bp.m_worldAABB.lowerBound; | |
535 bzVec2 worldUpper = bp.m_worldAABB.upperBound; | |
536 Color color = Color(0.3f, 0.9f, 0.9f); | |
537 vec2 vs[4]; | |
538 vs[0] = vec2(worldLower.x, worldLower.y); | |
539 vs[1] = vec2(worldUpper.x, worldLower.y); | |
540 vs[2] = vec2(worldUpper.x, worldUpper.y); | |
541 vs[3] = vec2(worldLower.x, worldUpper.y); | |
542 drawPolygon(gl, vs, color); | |
543 | |
544 // Draw axis aligned bounding boxes (bzAABB) | |
545 if (settings.drawAABBs) { | |
546 bzVec2 invQ; | |
547 invQ.set(1.0f / bp.m_quantizationFactor.x, 1.0f / bp.m_quantizationFactor.y); | |
548 color = Color(1.0f, 1.0f, 1.0f); | |
549 | |
550 for (int i = 0; i < k_maxProxies; ++i) { | |
551 bzProxy p = bp.m_proxyPool[i]; | |
552 if (!p.isValid) { | |
553 continue; | |
0 | 554 } |
555 | |
18 | 556 bzAABB b; |
557 b.lowerBound.x = worldLower.x + invQ.x * bp.m_bounds[0][p.lowerBounds[0]].value; | |
558 b.lowerBound.y = worldLower.y + invQ.y * bp.m_bounds[1][p.lowerBounds[1]].value; | |
559 b.upperBound.x = worldLower.x + invQ.x * bp.m_bounds[0][p.upperBounds[0]].value; | |
560 b.upperBound.y = worldLower.y + invQ.y * bp.m_bounds[1][p.upperBounds[1]].value; | |
561 | |
562 vs[0] = vec2(b.lowerBound.x, b.lowerBound.y); | |
563 vs[1] = vec2(b.upperBound.x, b.lowerBound.y); | |
564 vs[2] = vec2(b.upperBound.x, b.upperBound.y); | |
565 vs[3] = vec2(b.lowerBound.x, b.upperBound.y); | |
566 | |
567 drawPolygon(gl, vs, color); | |
0 | 568 } |
569 } | |
570 } | |
571 } |