Skip to content

Commit e455f57

Browse files
committed
RayCast example
1 parent de5620f commit e455f57

1 file changed

Lines changed: 308 additions & 0 deletions

File tree

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
/**
2+
*
3+
* LiquidFunProcessing | Copyright 2017 Thomas Diewald - www.thomasdiewald.com
4+
*
5+
* https://github.com/diwi/LiquidFunProcessing.git
6+
*
7+
* Box2d / LiquidFun Library for Processing.
8+
* MIT License: https://opensource.org/licenses/MIT
9+
*
10+
*/
11+
12+
13+
14+
package box2d_EdgeShapes;
15+
16+
17+
import com.thomasdiewald.liquidfun.java.DwWorld;
18+
19+
import org.jbox2d.callbacks.RayCastCallback;
20+
import org.jbox2d.collision.shapes.CircleShape;
21+
import org.jbox2d.collision.shapes.EdgeShape;
22+
import org.jbox2d.collision.shapes.PolygonShape;
23+
import org.jbox2d.common.Color3f;
24+
import org.jbox2d.common.MathUtils;
25+
import org.jbox2d.common.Vec2;
26+
import org.jbox2d.dynamics.Body;
27+
import org.jbox2d.dynamics.BodyDef;
28+
import org.jbox2d.dynamics.BodyType;
29+
import org.jbox2d.dynamics.Fixture;
30+
import org.jbox2d.dynamics.FixtureDef;
31+
import processing.core.*;
32+
import processing.opengl.PGraphics2D;
33+
34+
35+
public class box2d_EdgeShapes extends PApplet {
36+
37+
// Example to demonstrate how to use the RayCastCallback
38+
39+
int viewport_w = 1280;
40+
int viewport_h = 720;
41+
int viewport_x = 230;
42+
int viewport_y = 0;
43+
44+
boolean UPDATE_PHYSICS = true;
45+
boolean USE_DEBUG_DRAW = false;
46+
47+
DwWorld world;
48+
49+
public void settings(){
50+
size(viewport_w, viewport_h, P2D);
51+
smooth(8);
52+
}
53+
54+
55+
public void setup(){
56+
surface.setLocation(viewport_x, viewport_y);
57+
reset();
58+
frameRate(120);
59+
}
60+
61+
62+
public void release(){
63+
if(world != null) world.release(); world = null;
64+
}
65+
66+
67+
public void reset(){
68+
// release old resources
69+
release();
70+
71+
world = new DwWorld(this, 25);
72+
world.transform.setCamera(0, 10, 25);
73+
// create scene: rigid bodies, particles, etc ...
74+
initScene();
75+
}
76+
77+
78+
int id = 0;
79+
public void draw(){
80+
81+
// create a new body every second
82+
if((frameCount%120) == 0){
83+
Create(id++%5);
84+
}
85+
86+
if(UPDATE_PHYSICS){
87+
world.update();
88+
}
89+
90+
PGraphics2D canvas = (PGraphics2D) this.g;
91+
canvas.background(32);
92+
canvas.pushMatrix();
93+
world.applyTransform(canvas);
94+
world.drawBulletSpawnTrack(canvas);
95+
if(USE_DEBUG_DRAW){
96+
world.displayDebugDraw(canvas);
97+
// DwDebugDraw.display(canvas, world);
98+
} else {
99+
world.display(canvas);
100+
}
101+
step();
102+
canvas.popMatrix();
103+
104+
// info
105+
int num_bodies = world.getBodyCount();
106+
int num_particles = world.getParticleCount();
107+
String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
108+
surface.setTitle(txt_fps);
109+
}
110+
111+
112+
113+
//////////////////////////////////////////////////////////////////////////////
114+
// User Interaction
115+
//////////////////////////////////////////////////////////////////////////////
116+
public void keyReleased(){
117+
if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
118+
if(key == 'r') reset();
119+
if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
120+
if(key >= '1' && key <= '5') Create(key-'1');
121+
}
122+
123+
124+
125+
//////////////////////////////////////////////////////////////////////////////
126+
// Scene Setup
127+
//////////////////////////////////////////////////////////////////////////////
128+
129+
130+
131+
int e_maxBodies = 256;
132+
int m_bodyIndex;
133+
Body m_bodies[] = new Body[e_maxBodies];
134+
PolygonShape m_polygons[] = new PolygonShape[4];
135+
CircleShape m_circle;
136+
137+
float m_angle;
138+
139+
// https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/EdgeShapes.java
140+
public void initScene() {
141+
for (int i = 0; i < m_bodies.length; i++) {
142+
m_bodies[i] = null;
143+
}
144+
// Ground body
145+
{
146+
BodyDef bd = new BodyDef();
147+
Body ground = world.createBody(bd);
148+
149+
float x1 = -20.0f;
150+
float y1 = 2.0f * MathUtils.cos(x1 / 10.0f * MathUtils.PI);
151+
for (int i = 0; i < 80; ++i) {
152+
float x2 = x1 + 0.5f;
153+
float y2 = 2.0f * MathUtils.cos(x2 / 10.0f * MathUtils.PI);
154+
155+
EdgeShape shape = new EdgeShape();
156+
shape.set(new Vec2(x1, y1), new Vec2(x2, y2));
157+
ground.createFixture(shape, 0.0f);
158+
159+
x1 = x2;
160+
y1 = y2;
161+
}
162+
world.bodies.add(ground, false, color(0), true, color(255,255,0), 1f);
163+
}
164+
165+
{
166+
Vec2 vertices[] = new Vec2[3];
167+
vertices[0] = new Vec2(-0.5f, 0.0f);
168+
vertices[1] = new Vec2(0.5f, 0.0f);
169+
vertices[2] = new Vec2(0.0f, 1.5f);
170+
m_polygons[0] = new PolygonShape();
171+
m_polygons[0].set(vertices, 3);
172+
}
173+
174+
{
175+
Vec2 vertices[] = new Vec2[3];
176+
vertices[0] = new Vec2(-0.1f, 0.0f);
177+
vertices[1] = new Vec2(0.1f, 0.0f);
178+
vertices[2] = new Vec2(0.0f, 1.5f);
179+
m_polygons[1] = new PolygonShape();
180+
m_polygons[1].set(vertices, 3);
181+
}
182+
183+
{
184+
float w = 1.0f;
185+
float b = w / (2.0f + MathUtils.sqrt(2.0f));
186+
float s = MathUtils.sqrt(2.0f) * b;
187+
188+
Vec2 vertices[] = new Vec2[8];
189+
vertices[0] = new Vec2(0.5f * s, 0.0f);
190+
vertices[1] = new Vec2(0.5f * w, b);
191+
vertices[2] = new Vec2(0.5f * w, b + s);
192+
vertices[3] = new Vec2(0.5f * s, w);
193+
vertices[4] = new Vec2(-0.5f * s, w);
194+
vertices[5] = new Vec2(-0.5f * w, b + s);
195+
vertices[6] = new Vec2(-0.5f * w, b);
196+
vertices[7] = new Vec2(-0.5f * s, 0.0f);
197+
198+
m_polygons[2] = new PolygonShape();
199+
m_polygons[2].set(vertices, 8);
200+
}
201+
202+
{
203+
m_polygons[3] = new PolygonShape();
204+
m_polygons[3].setAsBox(0.5f, 0.5f);
205+
}
206+
207+
{
208+
m_circle = new CircleShape();
209+
m_circle.m_radius = 0.5f;
210+
}
211+
212+
m_bodyIndex = 0;
213+
m_angle = 0.0f;
214+
}
215+
216+
217+
218+
219+
220+
void Create(int index) {
221+
if (m_bodies[m_bodyIndex] != null) {
222+
world.destroyBody(m_bodies[m_bodyIndex]);
223+
m_bodies[m_bodyIndex] = null;
224+
}
225+
226+
BodyDef bd = new BodyDef();
227+
228+
float x = MathUtils.randomFloat(-10.0f, 10.0f);
229+
float y = MathUtils.randomFloat(10.0f, 20.0f);
230+
bd.position.set(x, y);
231+
bd.angle = MathUtils.randomFloat(-MathUtils.PI, MathUtils.PI);
232+
bd.type = BodyType.DYNAMIC;
233+
234+
if (index == 4) {
235+
bd.angularDamping = 0.02f;
236+
}
237+
238+
m_bodies[m_bodyIndex] = world.createBody(bd);
239+
240+
if (index < 4) {
241+
FixtureDef fd = new FixtureDef();
242+
fd.shape = m_polygons[index];
243+
fd.friction = 0.3f;
244+
fd.density = 20.0f;
245+
m_bodies[m_bodyIndex].createFixture(fd);
246+
} else {
247+
FixtureDef fd = new FixtureDef();
248+
fd.shape = m_circle;
249+
fd.friction = 0.3f;
250+
fd.density = 20.0f;
251+
m_bodies[m_bodyIndex].createFixture(fd);
252+
}
253+
254+
world.bodies.add(m_bodies[m_bodyIndex], true, color(255,0,0), true, color(0), 1f);
255+
256+
m_bodyIndex = (m_bodyIndex + 1) % e_maxBodies;
257+
}
258+
259+
260+
261+
262+
EdgeShapesCallback callback = new EdgeShapesCallback();
263+
264+
265+
public void step(){
266+
267+
m_angle += 0.25f * PI / 180.0f;
268+
269+
float radius = 25.0f;
270+
Vec2 point1 = new Vec2(0.0f, 10.0f);
271+
Vec2 p1p2 = new Vec2(radius * cos(m_angle), -radius * abs(sin(m_angle)));
272+
Vec2 point2 = point1.add(p1p2);
273+
274+
callback.m_fixture = null;
275+
world.raycast(callback, point1, point2);
276+
277+
if (callback.m_fixture != null) {
278+
world.debug_draw.drawPoint(callback.m_point, 5.0f/world.transform.screen_scale, new Color3f(0.4f, 0.9f, 0.4f));
279+
world.debug_draw.drawSegment(point1, callback.m_point, new Color3f(0.8f, 0.8f, 0.8f));
280+
Vec2 head = callback.m_normal.mul(.5f).addLocal(callback.m_point);
281+
world.debug_draw.drawSegment(callback.m_point, head, new Color3f(0.9f, 0.9f, 0.4f));
282+
} else {
283+
world.debug_draw.drawSegment(point1, point2, new Color3f(0.8f, 0.8f, 0.8f));
284+
}
285+
286+
}
287+
288+
289+
static class EdgeShapesCallback implements RayCastCallback {
290+
291+
Fixture m_fixture = null;
292+
Vec2 m_point;
293+
Vec2 m_normal;
294+
295+
public float reportFixture(Fixture fixture, final Vec2 point, final Vec2 normal, float fraction) {
296+
m_fixture = fixture;
297+
m_point = point;
298+
m_normal = normal;
299+
return fraction;
300+
}
301+
}
302+
303+
304+
public static void main(String args[]) {
305+
PApplet.main(new String[] { box2d_EdgeShapes.class.getName() });
306+
}
307+
308+
}

0 commit comments

Comments
 (0)