├── LICENSE
├── README.md
├── examples
├── Basic_Tutorial
│ └── Basic_Tutorial.java
├── box2d_BlobJoint
│ └── box2d_BlobJoint.java
├── box2d_BlobJoint_LiquidFx
│ └── box2d_BlobJoint_LiquidFx.java
├── box2d_Breakable
│ └── box2d_Breakable.java
├── box2d_BrickWall
│ └── box2d_BrickWall.java
├── box2d_Bullet
│ └── box2d_Bullet.java
├── box2d_Cantilever_WeldJoint
│ └── box2d_Cantilever_WeldJoint.java
├── box2d_Car
│ └── box2d_Car.java
├── box2d_Chain_RevoluteJoint
│ └── box2d_Chain_RevoluteJoint.java
├── box2d_CircleStressTest
│ └── box2d_CircleStressTest.java
├── box2d_Collisions
│ └── box2d_Collisions.java
├── box2d_Collisions_SensorTest
│ └── box2d_Collisions_SensorTest.java
├── box2d_Collisions_SensorTestCallback
│ └── box2d_Collisions_SensorTestCallback.java
├── box2d_CompoundShapes
│ └── box2d_CompoundShapes.java
├── box2d_DominoTower
│ └── box2d_DominoTower.java
├── box2d_Dominos
│ └── box2d_Dominos.java
├── box2d_MobileBalanced
│ └── box2d_MobileBalanced.java
├── box2d_PistonStressTest
│ └── box2d_PistonStressTest.java
├── box2d_PulleyJoint
│ └── box2d_PulleyJoint.java
├── box2d_RainingBodies
│ └── box2d_RainingBodies.java
├── box2d_RayCastEdgeShapes
│ └── box2d_RayCastEdgeShapes.java
├── box2d_RopeJoint
│ └── box2d_RopeJoint.java
├── box2d_TheoJansenWalker
│ └── box2d_TheoJansenWalker.java
├── box2d_Tumbler
│ └── box2d_Tumbler.java
├── box2d_TumblerMod
│ └── box2d_TumblerMod.java
├── box2d_VaryingFriction
│ └── box2d_VaryingFriction.java
├── box2d_VaryingRestitution
│ └── box2d_VaryingRestitution.java
├── liquidfun_Chain_DistanceJoints_LiquidFx
│ └── liquidfun_Chain_DistanceJoints_LiquidFx.java
├── liquidfun_DamBreak
│ └── liquidfun_DamBreak.java
├── liquidfun_DamBreak_LiquidFx
│ └── liquidfun_DamBreak_LiquidFx.java
├── liquidfun_DamBreak_PShapeParticles
│ └── liquidfun_DamBreak_PShapeParticles.java
├── liquidfun_DrawingParticles
│ └── liquidfun_DrawingParticles.java
├── liquidfun_DrawingParticles_LiquidFx
│ └── liquidfun_DrawingParticles_LiquidFx.java
├── liquidfun_LiquidTimer
│ └── liquidfun_LiquidTimer.java
├── liquidfun_ParticleColors_LiquidFx
│ └── liquidfun_ParticleColors_LiquidFx.java
├── liquidfun_ParticleEmitter_LiquidFx
│ └── liquidfun_ParticleEmitter_LiquidFx.java
├── liquidfun_ParticleRenderGroups_LiquidFx
│ └── liquidfun_ParticleRenderGroups_LiquidFx.java
├── liquidfun_ParticleRenderGroups_LiquidFxDark
│ └── liquidfun_ParticleRenderGroups_LiquidFxDark.java
├── liquidfun_ParticleTypes
│ └── liquidfun_ParticleTypes.java
├── liquidfun_ParticleTypes_LiquidFx
│ └── liquidfun_ParticleTypes_LiquidFx.java
├── liquidfun_WaveMachine
│ └── liquidfun_WaveMachine.java
└── liquidfun_WaveMachine_LiquidFx
│ └── liquidfun_WaveMachine_LiquidFx.java
├── screenshots
├── LiquidFunProcessing_DebugDraw1.png
├── LiquidFunProcessing_Draw.png
├── LiquidFunProcessing_Orange.png
├── LiquidFunProcessing_Timer.png
├── LiquidFunProcessing_Wavemaschine.png
├── examples
│ ├── diewald_LiquidFunProcessing_BalancedTree.jpg
│ ├── diewald_LiquidFunProcessing_BlobJoints.jpg
│ ├── diewald_LiquidFunProcessing_Chains.jpg
│ ├── diewald_LiquidFunProcessing_CircleStress.jpg
│ ├── diewald_LiquidFunProcessing_Collisions.jpg
│ ├── diewald_LiquidFunProcessing_DamBreak.jpg
│ ├── diewald_LiquidFunProcessing_DominoPyramid.jpg
│ ├── diewald_LiquidFunProcessing_Dominos.jpg
│ ├── diewald_LiquidFunProcessing_Examples1.jpg
│ ├── diewald_LiquidFunProcessing_Examples2.jpg
│ ├── diewald_LiquidFunProcessing_ParticleDrawing.jpg
│ ├── diewald_LiquidFunProcessing_ParticleDrawing1.jpg
│ ├── diewald_LiquidFunProcessing_ParticleEmitter.jpg
│ ├── diewald_LiquidFunProcessing_ParticleRenderGroup.jpg
│ ├── diewald_LiquidFunProcessing_ParticleTypes.jpg
│ ├── diewald_LiquidFunProcessing_PistonStress.jpg
│ ├── diewald_LiquidFunProcessing_Rain.jpg
│ ├── diewald_LiquidFunProcessing_Tumbler.jpg
│ └── diewald_LiquidFunProcessing_WaveMachine.jpg
└── rendermodes
│ ├── diewald_LiquidFunProcessing_RenderDebug.jpg
│ ├── diewald_LiquidFunProcessing_RenderLiquidFx.jpg
│ └── diewald_LiquidFunProcessing_RenderRaw.jpg
└── src
└── com
└── thomasdiewald
└── liquidfun
├── glsl
├── particle_render.frag
├── particle_render.vert
├── particle_render2.frag
└── particle_render2.vert
└── java
├── DwParticleEmitter.java
├── DwUtils.java
├── DwViewportTransform.java
├── DwWorld.java
├── interaction
├── DwInteractionEvent.java
├── DwMouseDragBodies.java
├── DwMouseDragParticles.java
├── DwMouseShootBullet.java
├── DwParticleDestroyer.java
└── DwParticleSpawn.java
└── render
├── DwBody.java
├── DwBodyGroup.java
├── DwDebugDraw.java
├── DwFixture.java
├── DwJoint.java
├── DwParticleRender.java
├── DwParticleRenderGL.java
├── DwParticleRenderGLQuads.java
├── DwParticleRenderGroupCallback.java
├── DwParticleRenderP5.java
└── ShapeStyle.java
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Thomas Diewald
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 | # LiquidFunProcessing
5 | **Box2D/LiquidFun Library for Processing.**
6 |
7 | Particle based fluid simulation and rigid body simulation using [jBox2D/LiquidFun 2.3.0+](https://github.com/jbox2d/jbox2d).
8 |
9 |
10 | ### References
11 |
12 | - LiquidFunProcessing: http://thomasdiewald.com/processing/libraries/liquidfun/reference/index.html
13 | - jBox2d: http://thomasdiewald.com/processing/libraries/jbox2d-2.3.0/doc/index.html
14 |
15 | ### Tutorials, Readings
16 | - Box2D: http://www.iforce2d.net/b2dtut
17 | - LiquidFun: http://google.github.io/liquidfun/Programmers-Guide/html/index.html
18 |
19 |
20 |
21 | ## Download
22 | + [Releases](https://github.com/diwi/LiquidFunProcessing/releases)
23 | + [LiquidFunProcessing Website](http://thomasdiewald.com/processing/libraries/liquidfun)
24 | + Processing IDE -> Library Manager
25 |
26 |
27 |
28 | 
29 |
30 |
31 |
32 | ## Videos
33 |
34 | [](https://vimeo.com/223843930 "LiquidFunProcessing - Chains")
35 | [
](https://vimeo.com/223843846 "LiquidFunProcessing - Bricks")
36 | [
](https://vimeo.com/223843490 "LiquidFunProcessing - WaveMachine")
37 | [
](https://vimeo.com/223843609 "LiquidFunProcessing - ParticleTypes")
38 |
39 |
40 |
41 | ## Examples
42 | The library includes a lot of examples from the original [jbox2d testbed](https://github.com/jbox2d/jbox2d/tree/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests).
43 | For a quick start, each sketch has a couple of default mouse-actions:
44 |
45 | - LMB: drag rigid bodies / particles
46 | - LMB + SHIFT: shoot a bullet
47 | - MMB: spawn particles
48 | - RMB: destroy particles
49 |
50 | ... as well as some key-mapping, e.g. to display the debug-draw, restart, pause/resume.
51 | Of course, each of those can be altered, overwritten or disabled/removed.
52 |
53 |
54 |
55 |
56 | ## Rendermodes
57 |
58 | #### Default renderer, no postprocessing
59 |
60 | particles are rendered as point-sprites and rigid bodies are rendered using the PShape tree structure.
61 |
62 | 
63 |
64 |
65 |
66 | #### Default renderer + Postprocessing
67 |
68 | **LiquidFx** adds some liquid effect and fake shading. [PixelFlow](https://github.com/diwi/PixelFlow) needs to be installed to use it.
69 |
70 | 
71 |
72 |
73 |
74 | #### Debug Draw
75 |
76 | using the box2d world for rendering and basic processing draw calls.
77 |
78 | 
79 |
80 |
81 |
82 | ## Resources
83 |
84 | - jBox2d web: http://www.jbox2d.org/
85 | - jBox2d Testbed: https://github.com/jbox2d/jbox2d/tree/master/jbox2d-testbed
86 | - Box2d Testbed: https://github.com/erincatto/Box2D/tree/master/Box2D/Testbed
87 | - LiquidFun: http://google.github.io/liquidfun/
88 | - **LiquidFun Programmers Guide: http://google.github.io/liquidfun/Programmers-Guide/html/index.html**
89 |
90 |
91 |
92 | ## Installation, Processing IDE
93 |
94 | - Download [Processing 3](https://processing.org/download/?processing)
95 | - Install liquidFunProcessing via the Library Manager.
96 | - Or manually, unzip and put the extracted LiquidFunProcessing folder into the libraries folder of your Processing sketches. Reference and examples are included in the LiquidFunProcessing folder.
97 |
98 | - Also make sure you have the latest graphics card driver installed!
99 |
100 | #### Platforms
101 | Windows, Linux, MacOSX
102 |
103 |
104 |
105 |
106 | ## Dependencies, to run the examples
107 |
108 | - **PixelFlow: https://github.com/diwi/PixelFlow**
109 |
110 |
--------------------------------------------------------------------------------
/examples/box2d_BrickWall/box2d_BrickWall.java:
--------------------------------------------------------------------------------
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_BrickWall;
15 |
16 | import com.thomasdiewald.liquidfun.java.DwWorld;
17 |
18 | import org.jbox2d.collision.shapes.CircleShape;
19 | import org.jbox2d.collision.shapes.PolygonShape;
20 | import org.jbox2d.common.Vec2;
21 | import org.jbox2d.dynamics.Body;
22 | import org.jbox2d.dynamics.BodyDef;
23 | import org.jbox2d.dynamics.BodyType;
24 | import org.jbox2d.dynamics.FixtureDef;
25 |
26 | import processing.core.*;
27 | import processing.opengl.PGraphics2D;
28 |
29 |
30 | public class box2d_BrickWall extends PApplet {
31 |
32 |
33 | //
34 | // Simple stacking demo.
35 | //
36 | //
37 | // Controls:
38 | //
39 | // LMB ... drag bodies
40 | // LMB + SHIFT ... shoot bullet
41 | // MMB ... add particles
42 | // RMB ... remove particles
43 | // 'r' ... reset
44 | // 't' ... update/pause physics
45 | // 'f' ... toggle debug draw
46 | //
47 |
48 |
49 | int viewport_w = 1280;
50 | int viewport_h = 720;
51 | int viewport_x = 230;
52 | int viewport_y = 0;
53 |
54 | boolean UPDATE_PHYSICS = true;
55 | boolean USE_DEBUG_DRAW = false;
56 |
57 | DwWorld world;
58 |
59 | public void settings(){
60 | size(viewport_w, viewport_h, P2D);
61 | smooth(8);
62 | }
63 |
64 | public void setup(){
65 | surface.setLocation(viewport_x, viewport_y);
66 | reset();
67 | frameRate(120);
68 | }
69 |
70 |
71 | public void release(){
72 | if(world != null) world.release(); world = null;
73 | }
74 |
75 | public void reset(){
76 | // release old resources
77 | release();
78 |
79 | world = new DwWorld(this, 20);
80 |
81 | // create scene: rigid bodies, particles, etc ...
82 | initScene();
83 | }
84 |
85 |
86 |
87 | public void draw(){
88 |
89 | if(UPDATE_PHYSICS){
90 | world.update();
91 | }
92 |
93 |
94 | PGraphics2D canvas = (PGraphics2D) this.g;
95 |
96 | canvas.background(32);
97 | canvas.pushMatrix();
98 | world.applyTransform(canvas);
99 | world.drawBulletSpawnTrack(canvas);
100 |
101 | if(USE_DEBUG_DRAW){
102 | world.displayDebugDraw(canvas);
103 | // DwDebugDraw.display(canvas, world);
104 | } else {
105 | world.bodies.display(canvas);
106 | world.particles.display(canvas);
107 | }
108 | canvas.popMatrix();
109 |
110 | // info
111 | int num_bodies = world.getBodyCount();
112 | int num_particles = world.getParticleCount();
113 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
114 | surface.setTitle(txt_fps);
115 | }
116 |
117 |
118 |
119 |
120 |
121 | //////////////////////////////////////////////////////////////////////////////
122 | // User Interaction
123 | //////////////////////////////////////////////////////////////////////////////
124 |
125 | public void keyReleased(){
126 | if(key == 'r') reset();
127 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
128 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
129 | }
130 |
131 |
132 |
133 | //////////////////////////////////////////////////////////////////////////////
134 | // Scene Setup
135 | //////////////////////////////////////////////////////////////////////////////
136 |
137 | public void initScene() {
138 |
139 | float screen_scale = world.transform.screen_scale;
140 | float b2d_screen_w = world.transform.box2d_dimx;
141 | float b2d_screen_h = world.transform.box2d_dimy;
142 | float b2d_thickness = 20 / screen_scale;
143 |
144 | {
145 |
146 | float radius = 25 / screen_scale;
147 | CircleShape circle_shape = new CircleShape();
148 | circle_shape.setRadius(radius);
149 |
150 | FixtureDef fixture_def = new FixtureDef();
151 | fixture_def.shape = circle_shape;
152 | fixture_def.density = 10f;
153 | fixture_def.friction = 0.30f;
154 | fixture_def.restitution = 0.30f;
155 |
156 | BodyDef body_def = new BodyDef();
157 | body_def.type = BodyType.DYNAMIC;
158 | body_def.angle = 0.0f;
159 | body_def.position.x = -1/screen_scale;
160 | body_def.position.y = b2d_screen_h - 10;
161 | body_def.bullet = true;
162 |
163 | Body circle_body = world.createBody(body_def);
164 | circle_body.createFixture(fixture_def);
165 |
166 | world.bodies.add(circle_body, true, color(64, 125, 255), true, color(0), 1f);
167 | }
168 |
169 | { // Walls
170 | BodyDef bd = new BodyDef();
171 | bd.position.set(0, 0);
172 |
173 | Body ground = world.createBody(bd);
174 | PolygonShape sd = new PolygonShape();
175 |
176 | float x, y, w, h;
177 |
178 | // BOTTOM
179 | x = 0;
180 | y = 0;
181 | w = b2d_screen_w;
182 | h = b2d_thickness;
183 | sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
184 | ground.createFixture(sd, 0f);
185 |
186 | // TOP
187 | x = 0;
188 | y = b2d_screen_h;
189 | w = b2d_screen_w;
190 | h = b2d_thickness;
191 | sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
192 | ground.createFixture(sd, 0f);
193 |
194 | // LEFT
195 | x = -b2d_screen_w/2;
196 | y = +b2d_screen_h/2;
197 | w = b2d_thickness;
198 | h = b2d_screen_h - b2d_thickness;
199 | sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
200 | ground.createFixture(sd, 0f);
201 |
202 | // RIGHT
203 | x = +b2d_screen_w/2;
204 | y = +b2d_screen_h/2;
205 | w = b2d_thickness;
206 | h = b2d_screen_h - b2d_thickness;
207 | sd.setAsBox(w/2f, h/2f, new Vec2(x, y), 0.0f);
208 | ground.createFixture(sd, 0f);
209 |
210 | world.bodies.add(ground, true, color(0), !true, color(0), 1f);
211 | }
212 |
213 | createWall(10, 20, 40, 20, 0, 10);
214 |
215 | }
216 |
217 |
218 | public void createWall(int numx, int numy, float dimx, float dimy, float tx, float ty){
219 |
220 | float scree_scale = world.transform.screen_scale;
221 |
222 |
223 | dimx /= scree_scale;
224 | dimy /= scree_scale;
225 |
226 | tx /= scree_scale;
227 | ty /= scree_scale;
228 |
229 | PolygonShape brick_shape = new PolygonShape();
230 | brick_shape.setAsBox(dimx*0.5f, dimy*0.5f);
231 |
232 | PolygonShape brick_shape2 = new PolygonShape();
233 | brick_shape2.setAsBox(dimx*0.25f, dimy*0.5f);
234 |
235 | FixtureDef fixture_def = new FixtureDef();
236 | fixture_def.shape = brick_shape;
237 | fixture_def.density = 30;
238 | fixture_def.friction = 0.50f;
239 | fixture_def.restitution = 0.05f;
240 |
241 | BodyDef body_def = new BodyDef();
242 | body_def.type = BodyType.DYNAMIC;
243 | body_def.angle = 0.0f;
244 | body_def.allowSleep = true;
245 |
246 |
247 | int scol = color(0);
248 | int fcol = color(224,128,64);
249 |
250 | colorMode(HSB, 360,100,100);
251 |
252 | randomSeed(1);
253 |
254 | float ox = 0;
255 | float oy = dimy/2;
256 | for(int y = 0; y < numy; y++){
257 |
258 | float off = 0.5f;
259 |
260 | for(int x = 0; x < numx; x++){
261 | boolean odd_row = (y & 1) == 1;
262 |
263 | ox = -numx * dimx * 0.5f;
264 | ox += odd_row ? dimx * off : 0;
265 |
266 | fixture_def.shape = brick_shape;
267 | if(!odd_row && x == 0){
268 | fixture_def.shape = brick_shape2;
269 | ox += dimx * 0.25;
270 | }
271 | else if(odd_row && x == (numx-1)){
272 | fixture_def.shape = brick_shape2;
273 | ox -= dimx * 0.25;
274 | }
275 |
276 | body_def.position.x = tx + ox + x * (dimx);
277 | body_def.position.y = ty + oy + y * (dimy);
278 |
279 | Body brick = world.createBody(body_def);
280 | brick.createFixture(fixture_def);
281 |
282 | float hsb_h = 20 + random(-3, 3);
283 | float hsb_s = random(70,60);
284 | float hsb_b = random(70,100);
285 | fcol = color(hsb_h, hsb_s, hsb_b);
286 | world.bodies.add(brick, true, fcol, true, scol, 0.5f);
287 | }
288 | }
289 |
290 | colorMode(RGB, 255);
291 |
292 | }
293 |
294 |
295 |
296 |
297 |
298 | public static void main(String args[]) {
299 | PApplet.main(new String[] { box2d_BrickWall.class.getName() });
300 | }
301 |
302 | }
--------------------------------------------------------------------------------
/examples/box2d_Bullet/box2d_Bullet.java:
--------------------------------------------------------------------------------
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_Bullet;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import com.thomasdiewald.liquidfun.java.interaction.DwMouseShootBullet;
19 | import com.thomasdiewald.liquidfun.java.render.DwBodyGroup;
20 |
21 | import org.jbox2d.collision.shapes.EdgeShape;
22 | import org.jbox2d.collision.shapes.PolygonShape;
23 | import org.jbox2d.common.MathUtils;
24 | import org.jbox2d.common.Vec2;
25 | import org.jbox2d.dynamics.Body;
26 | import org.jbox2d.dynamics.BodyDef;
27 | import org.jbox2d.dynamics.BodyType;
28 | import processing.core.*;
29 | import processing.opengl.PGraphics2D;
30 |
31 |
32 | public class box2d_Bullet extends PApplet {
33 |
34 |
35 | //
36 | // Bullet demo.
37 | //
38 | // Controls:
39 | //
40 | // LMB ... drag bodies
41 | // LMB + SHIFT ... shoot bullet
42 | // MMB ... add particles
43 | // RMB ... remove particles
44 | // 'r' ... reset
45 | // 't' ... update/pause physics
46 | // 'f' ... toggle debug draw
47 | //
48 |
49 |
50 | int viewport_w = 1280;
51 | int viewport_h = 720;
52 | int viewport_x = 230;
53 | int viewport_y = 0;
54 |
55 | boolean UPDATE_PHYSICS = true;
56 | boolean USE_DEBUG_DRAW = false;
57 |
58 | DwWorld world;
59 | DwBodyGroup bodies;
60 | DwMouseShootBullet bullet;
61 |
62 | public void settings(){
63 | size(viewport_w, viewport_h, P2D);
64 | smooth(8);
65 | }
66 |
67 | public void setup(){
68 | surface.setLocation(viewport_x, viewport_y);
69 | reset();
70 | frameRate(120);
71 | }
72 |
73 |
74 | public void release(){
75 | if(bodies != null) bodies .release(); bodies = null;
76 | // if(particles != null) particles.release(); particles = null;
77 | if(world != null) world .release(); world = null; }
78 |
79 |
80 | public void reset(){
81 | // release old resources
82 | release();
83 |
84 | world = new DwWorld(this, 22);
85 | world.transform.setScreen(width, height, 40, width/2, height-50);
86 |
87 | // Renderer
88 | bodies = new DwBodyGroup(this, world, world.transform);
89 |
90 | bullet = new DwMouseShootBullet(world, world.transform);
91 |
92 | // create scene: rigid bodies, particles, etc ...
93 | initScene();
94 | }
95 |
96 |
97 |
98 | public void draw(){
99 | if(UPDATE_PHYSICS){
100 | if(frameCount % 120 == 0){
101 | launch();
102 | }
103 | bullet.updateSpawn(mouseX, mouseY);
104 | world.update();
105 | }
106 |
107 | PGraphics2D canvas = (PGraphics2D) this.g;
108 |
109 | canvas.background(32);
110 | canvas.pushMatrix();
111 | world.applyTransform(canvas);
112 | bullet.drawSpawnTrack(canvas);
113 | if(USE_DEBUG_DRAW){
114 | world.displayDebugDraw(canvas);
115 | // DwDebugDraw.display(canvas, world);
116 | } else {
117 | bodies.display(canvas);
118 | }
119 | canvas.popMatrix();
120 |
121 |
122 | // info
123 | int num_bodies = world.getBodyCount();
124 | int num_particles = world.getParticleCount();
125 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
126 | surface.setTitle(txt_fps);
127 | }
128 |
129 |
130 |
131 |
132 |
133 |
134 | //////////////////////////////////////////////////////////////////////////////
135 | // User Interaction
136 | //////////////////////////////////////////////////////////////////////////////
137 | public void keyReleased(){
138 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
139 | if(key == 'r') reset();
140 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
141 | }
142 |
143 | public void mousePressed(){
144 | bullet.beginSpawn(mouseX, mouseY);
145 | }
146 |
147 | public void mouseReleased(){
148 | bullet.endSpawn(mouseX, mouseY);
149 | bodies.add(bullet.popBullet(), true, color(255,32,0), true, color(0), 1f);
150 | }
151 |
152 |
153 |
154 |
155 |
156 |
157 | //////////////////////////////////////////////////////////////////////////////
158 | // Scene Setup
159 | //////////////////////////////////////////////////////////////////////////////
160 |
161 | Body m_body;
162 | Body m_bullet;
163 | float m_x;
164 |
165 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/BulletTest.java
166 | public void initScene() {
167 | {
168 | BodyDef bd = new BodyDef();
169 | bd.position.set(0.0f, 0.0f);
170 | Body body = world.createBody(bd);
171 |
172 | EdgeShape edge = new EdgeShape();
173 |
174 | edge.set(new Vec2(-10.0f, 0.0f), new Vec2(10.0f, 0.0f));
175 | body.createFixture(edge, 0.0f);
176 |
177 | PolygonShape shape = new PolygonShape();
178 | shape.setAsBox(0.2f, 1.0f, new Vec2(0.5f, 1.0f), 0.0f);
179 | body.createFixture(shape, 0.0f);
180 | }
181 |
182 | {
183 | BodyDef bd = new BodyDef();
184 | bd.type = BodyType.DYNAMIC;
185 | bd.position.set(0.0f, 4.0f);
186 |
187 | PolygonShape box = new PolygonShape();
188 | box.setAsBox(2.0f, 0.1f);
189 |
190 | m_body = world.createBody(bd);
191 | m_body.createFixture(box, 1.0f);
192 |
193 | box.setAsBox(0.25f, 0.25f);
194 |
195 | // m_x = RandomFloat(-1.0f, 1.0f);
196 | m_x = -0.06530577f;
197 | bd.position.set(m_x, 10.0f);
198 | bd.bullet = true;
199 |
200 | m_bullet = world.createBody(bd);
201 | m_bullet.createFixture(box, 100.0f);
202 |
203 | m_bullet.setLinearVelocity(new Vec2(0.0f, -50.0f));
204 | }
205 |
206 |
207 | bodies.addAll();
208 | }
209 |
210 |
211 |
212 | public void launch() {
213 | m_body.setTransform(new Vec2(0.0f, 4.0f), 0.0f);
214 | m_body.setLinearVelocity(new Vec2());
215 | m_body.setAngularVelocity(0.0f);
216 |
217 | m_x = MathUtils.randomFloat(-1.0f, 1.0f);
218 | m_bullet.setTransform(new Vec2(m_x, 10.0f), 0.0f);
219 | m_bullet.setLinearVelocity(new Vec2(0.0f, -50.0f));
220 | m_bullet.setAngularVelocity(0.0f);
221 | }
222 |
223 |
224 |
225 | public static void main(String args[]) {
226 | PApplet.main(new String[] { box2d_Bullet.class.getName() });
227 | }
228 |
229 | }
--------------------------------------------------------------------------------
/examples/box2d_Chain_RevoluteJoint/box2d_Chain_RevoluteJoint.java:
--------------------------------------------------------------------------------
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_Chain_RevoluteJoint;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.EdgeShape;
19 | import org.jbox2d.collision.shapes.PolygonShape;
20 | import org.jbox2d.common.Vec2;
21 | import org.jbox2d.dynamics.Body;
22 | import org.jbox2d.dynamics.BodyDef;
23 | import org.jbox2d.dynamics.BodyType;
24 | import org.jbox2d.dynamics.FixtureDef;
25 | import org.jbox2d.dynamics.joints.Joint;
26 | import org.jbox2d.dynamics.joints.RevoluteJointDef;
27 |
28 | import processing.core.*;
29 | import processing.opengl.PGraphics2D;
30 |
31 |
32 | public class box2d_Chain_RevoluteJoint extends PApplet {
33 |
34 |
35 | //
36 | // This examples shows how to use RevoluteJoints.
37 | //
38 | //
39 | // Controls:
40 | //
41 | // LMB ... drag bodies
42 | // LMB + SHIFT ... shoot bullet
43 | // MMB ... add particles
44 | // RMB ... remove particles
45 | // 'r' ... reset
46 | // 't' ... update/pause physics
47 | // 'f' ... toggle debug draw
48 | //
49 |
50 | int viewport_w = 1280;
51 | int viewport_h = 720;
52 | int viewport_x = 230;
53 | int viewport_y = 0;
54 |
55 | boolean UPDATE_PHYSICS = true;
56 | boolean USE_DEBUG_DRAW = false;
57 |
58 | DwWorld world;
59 |
60 | public void settings(){
61 | size(viewport_w, viewport_h, P2D);
62 | smooth(8);
63 | }
64 |
65 |
66 | public void setup(){
67 | surface.setLocation(viewport_x, viewport_y);
68 | reset();
69 | frameRate(120);
70 | }
71 |
72 |
73 | public void release(){
74 | if(world != null) world.release(); world = null;
75 | }
76 |
77 |
78 | public void reset(){
79 | // release old resources
80 | release();
81 |
82 | world = new DwWorld(this, 25);
83 |
84 | // create scene: rigid bodies, particles, etc ...
85 | initScene();
86 | }
87 |
88 |
89 |
90 | public void draw(){
91 |
92 | if(UPDATE_PHYSICS){
93 | world.update();
94 | }
95 |
96 | PGraphics2D canvas = (PGraphics2D) this.g;
97 | canvas.background(32);
98 | canvas.pushMatrix();
99 | world.applyTransform(canvas);
100 | world.drawBulletSpawnTrack(canvas);
101 | if(USE_DEBUG_DRAW){
102 | world.displayDebugDraw(canvas);
103 | // DwDebugDraw.display(canvas, world);
104 | } else {
105 | world.display(canvas);
106 | }
107 | canvas.popMatrix();
108 |
109 | // info
110 | int num_bodies = world.getBodyCount();
111 | int num_particles = world.getParticleCount();
112 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
113 | surface.setTitle(txt_fps);
114 | }
115 |
116 |
117 |
118 | //////////////////////////////////////////////////////////////////////////////
119 | // User Interaction
120 | //////////////////////////////////////////////////////////////////////////////
121 | public void keyReleased(){
122 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
123 | if(key == 'r') reset();
124 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
125 | }
126 |
127 |
128 |
129 | //////////////////////////////////////////////////////////////////////////////
130 | // Scene Setup
131 | //////////////////////////////////////////////////////////////////////////////
132 |
133 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/Chain.java
134 | public void initScene() {
135 |
136 | Body ground = null;
137 | {
138 | BodyDef bd = new BodyDef();
139 | ground = world.createBody(bd);
140 |
141 | EdgeShape shape = new EdgeShape();
142 | shape.set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
143 | ground.createFixture(shape, 0.0f);
144 | }
145 |
146 | {
147 | float seg = 1.5f;
148 |
149 | PolygonShape shape = new PolygonShape();
150 | shape.setAsBox(seg/2, 0.225f);
151 |
152 | FixtureDef fd = new FixtureDef();
153 | fd.shape = shape;
154 | fd.density = 20.0f;
155 | fd.friction = 0.2f;
156 |
157 | RevoluteJointDef jd = new RevoluteJointDef();
158 | jd.collideConnected = false;
159 |
160 | int count = 20;
161 | final float py = 25.0f;
162 | final float px = 5.0f;
163 | Body prevBody = ground;
164 | for (int i = 0; i < count; ++i) {
165 | BodyDef bd = new BodyDef();
166 | bd.type = BodyType.DYNAMIC;
167 | bd.position.set(px + i*seg + seg/2, py);
168 | Body body = world.createBody(bd);
169 | body.createFixture(fd);
170 |
171 | Vec2 anchor = new Vec2(px + i*seg, py);
172 | jd.initialize(prevBody, body, anchor);
173 | Joint joint = world.createJoint(jd);
174 |
175 | float base = 64;
176 | float inorm = i / (float) count;
177 | float r = base + (255-base) * inorm;
178 | float g = base;
179 | float b = 255-r;
180 | world.bodies.add(joint, false, color(0), true, color(base, 255, base), 1);
181 | world.bodies.add(body, true, color(r,g,b), true, color(0), 1);
182 |
183 | prevBody = body;
184 | }
185 | }
186 |
187 | world.bodies.addAll();
188 | }
189 |
190 |
191 |
192 | public static void main(String args[]) {
193 | PApplet.main(new String[] { box2d_Chain_RevoluteJoint.class.getName() });
194 | }
195 |
196 | }
--------------------------------------------------------------------------------
/examples/box2d_Collisions_SensorTest/box2d_Collisions_SensorTest.java:
--------------------------------------------------------------------------------
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_Collisions_SensorTest;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.CircleShape;
19 | import org.jbox2d.collision.shapes.EdgeShape;
20 | import org.jbox2d.common.Settings;
21 | import org.jbox2d.common.Vec2;
22 | import org.jbox2d.dynamics.Body;
23 | import org.jbox2d.dynamics.BodyDef;
24 | import org.jbox2d.dynamics.BodyType;
25 | import org.jbox2d.dynamics.Fixture;
26 | import org.jbox2d.dynamics.FixtureDef;
27 | import org.jbox2d.dynamics.contacts.Contact;
28 | import processing.core.*;
29 | import processing.opengl.PGraphics2D;
30 |
31 |
32 | public class box2d_Collisions_SensorTest extends PApplet {
33 |
34 |
35 | //
36 | // Collision Example.
37 | // A static circle body acts as a sensor and acts as a gravity center.
38 | // When other bodies get in contact with the sensor they are attracted to
39 | // the sensors center.
40 | //
41 | // A contact test is done by iteration through the world-contactlist.
42 | //
43 | //
44 | // Controls:
45 | //
46 | // LMB ... drag bodies
47 | // LMB + SHIFT ... shoot bullet
48 | // MMB ... add particles
49 | // RMB ... remove particles
50 | // 'r' ... reset
51 | // 't' ... update/pause physics
52 | // 'f' ... toggle debug draw
53 | //
54 |
55 |
56 | int viewport_w = 1280;
57 | int viewport_h = 720;
58 | int viewport_x = 230;
59 | int viewport_y = 0;
60 |
61 | boolean UPDATE_PHYSICS = true;
62 | boolean USE_DEBUG_DRAW = false;
63 |
64 | DwWorld world;
65 |
66 | public void settings(){
67 | size(viewport_w, viewport_h, P2D);
68 | smooth(8);
69 | }
70 |
71 |
72 | public void setup(){
73 | surface.setLocation(viewport_x, viewport_y);
74 | reset();
75 | frameRate(120);
76 | }
77 |
78 |
79 | public void release(){
80 | if(world != null) world.release(); world = null;
81 | }
82 |
83 |
84 | public void reset(){
85 | // release old resources
86 | release();
87 |
88 | world = new DwWorld(this, 25);
89 |
90 | // create scene: rigid bodies, particles, etc ...
91 | initScene();
92 | }
93 |
94 |
95 |
96 | public void draw(){
97 |
98 | if(UPDATE_PHYSICS){
99 | updateSensor();
100 | world.update();
101 | }
102 |
103 | PGraphics2D canvas = (PGraphics2D) this.g;
104 | canvas.background(32);
105 | canvas.pushMatrix();
106 | world.applyTransform(canvas);
107 | world.drawBulletSpawnTrack(canvas);
108 | if(USE_DEBUG_DRAW){
109 | world.displayDebugDraw(canvas);
110 | // DwDebugDraw.display(canvas, world);
111 | } else {
112 | world.display(canvas);
113 | }
114 | canvas.popMatrix();
115 |
116 | // info
117 | int num_bodies = world.getBodyCount();
118 | int num_particles = world.getParticleCount();
119 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
120 | surface.setTitle(txt_fps);
121 | }
122 |
123 |
124 |
125 | //////////////////////////////////////////////////////////////////////////////
126 | // User Interaction
127 | //////////////////////////////////////////////////////////////////////////////
128 | public void keyReleased(){
129 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
130 | if(key == 'r') reset();
131 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
132 | }
133 |
134 |
135 |
136 |
137 | //////////////////////////////////////////////////////////////////////////////
138 | // Scene Setup
139 | //////////////////////////////////////////////////////////////////////////////
140 |
141 |
142 | Fixture m_sensor;
143 |
144 | // mod of the original vesion
145 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/SensorTest.java
146 | public void initScene() {
147 |
148 | {
149 | BodyDef bd = new BodyDef();
150 | Body ground = world.createBody(bd);
151 |
152 | { // floor
153 | EdgeShape shape = new EdgeShape();
154 | shape.set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
155 | ground.createFixture(shape, 0.0f);
156 | }
157 |
158 | { // sensor
159 | CircleShape shape = new CircleShape();
160 | shape.m_radius = 5.0f;
161 | shape.m_p.set(0.0f, 10.0f);
162 |
163 | FixtureDef fd = new FixtureDef();
164 | fd.shape = shape;
165 | fd.isSensor = true;
166 | m_sensor = ground.createFixture(fd);
167 | }
168 | world.bodies.add(ground, true, color(255), true, color(0), 1f);
169 | }
170 |
171 | {
172 | BodyDef bd = new BodyDef();
173 | bd.type = BodyType.DYNAMIC;
174 |
175 | CircleShape shape = new CircleShape();
176 | shape.m_radius = 1.0f;
177 |
178 | for (int i = 0; i < 10; ++i) {
179 | bd.position.set(-10.0f + 3.0f * i, 20.0f);
180 | Body body = world.createBody(bd);
181 | body.createFixture(shape, 1.0f);
182 | world.bodies.add(body, true, color(0,255,0), true, color(0), 1f);
183 | }
184 | }
185 |
186 | world.bodies.addAll();
187 | }
188 |
189 |
190 |
191 | public void updateSensor(){
192 |
193 | Body bsensor = m_sensor.getBody();
194 | CircleShape circle = (CircleShape) m_sensor.getShape();
195 | Vec2 sensor_pos = bsensor.getWorldPoint(circle.m_p);
196 |
197 | // iterate through all contacts and apply a force on shapes that overlap the sensor.
198 | for(Contact contact = world.getContactList(); contact != null; contact = contact.m_next){
199 |
200 | Fixture fixtureA = contact.getFixtureA();
201 | Fixture fixtureB = contact.getFixtureB();
202 |
203 | Body body = null;
204 | if(fixtureA == m_sensor) body = fixtureB.getBody();
205 | else if(fixtureB == m_sensor) body = fixtureA.getBody();
206 | else continue;
207 |
208 | Vec2 body_pos = body.getPosition();
209 | Vec2 dist = sensor_pos.sub(body_pos);
210 | if (dist.lengthSquared() > Settings.EPSILON * Settings.EPSILON) {
211 | dist.normalize();
212 | Vec2 force = dist.mulLocal(200f);
213 | body.applyForce(force, body_pos);
214 | }
215 | }
216 | }
217 |
218 |
219 |
220 | public static void main(String args[]) {
221 | PApplet.main(new String[] { box2d_Collisions_SensorTest.class.getName() });
222 | }
223 |
224 | }
--------------------------------------------------------------------------------
/examples/box2d_Collisions_SensorTestCallback/box2d_Collisions_SensorTestCallback.java:
--------------------------------------------------------------------------------
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_Collisions_SensorTestCallback;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import com.thomasdiewald.liquidfun.java.render.DwBody;
19 |
20 | import org.jbox2d.callbacks.ContactImpulse;
21 | import org.jbox2d.callbacks.ContactListener;
22 | import org.jbox2d.collision.Manifold;
23 | import org.jbox2d.collision.shapes.CircleShape;
24 | import org.jbox2d.collision.shapes.EdgeShape;
25 | import org.jbox2d.common.Settings;
26 | import org.jbox2d.common.Vec2;
27 | import org.jbox2d.dynamics.Body;
28 | import org.jbox2d.dynamics.BodyDef;
29 | import org.jbox2d.dynamics.BodyType;
30 | import org.jbox2d.dynamics.Fixture;
31 | import org.jbox2d.dynamics.FixtureDef;
32 | import org.jbox2d.dynamics.contacts.Contact;
33 |
34 | import processing.core.*;
35 | import processing.opengl.PGraphics2D;
36 |
37 |
38 | public class box2d_Collisions_SensorTestCallback extends PApplet {
39 |
40 |
41 | //
42 | // Collision Example.
43 | // A static circle body acts as a sensor and acts as a gravity center.
44 | // When other bodies get in contact with the sensor they are attracted to
45 | // the sensors center.
46 | //
47 | // A contact test is done by implementing a ContactListener.
48 | //
49 | //
50 | // Controls:
51 | //
52 | // LMB ... drag bodies
53 | // LMB + SHIFT ... shoot bullet
54 | // MMB ... add particles
55 | // RMB ... remove particles
56 | // 'r' ... reset
57 | // 't' ... update/pause physics
58 | // 'f' ... toggle debug draw
59 | //
60 |
61 |
62 | int viewport_w = 1280;
63 | int viewport_h = 720;
64 | int viewport_x = 230;
65 | int viewport_y = 0;
66 |
67 | boolean UPDATE_PHYSICS = true;
68 | boolean USE_DEBUG_DRAW = false;
69 |
70 | DwWorld world;
71 |
72 | public void settings(){
73 | size(viewport_w, viewport_h, P2D);
74 | smooth(8);
75 | }
76 |
77 |
78 | public void setup(){
79 | surface.setLocation(viewport_x, viewport_y);
80 | reset();
81 | frameRate(120);
82 | }
83 |
84 |
85 | public void release(){
86 | if(world != null) world.release(); world = null;
87 | }
88 |
89 |
90 | public void reset(){
91 | // release old resources
92 | release();
93 |
94 | world = new DwWorld(this, 25);
95 |
96 | // create scene: rigid bodies, particles, etc ...
97 | initScene();
98 | }
99 |
100 |
101 |
102 | public void draw(){
103 |
104 | if(UPDATE_PHYSICS){
105 | updateSensor();
106 | world.update();
107 | }
108 |
109 | PGraphics2D canvas = (PGraphics2D) this.g;
110 | canvas.background(32);
111 | canvas.pushMatrix();
112 | world.applyTransform(canvas);
113 | world.drawBulletSpawnTrack(canvas);
114 | if(USE_DEBUG_DRAW){
115 | world.displayDebugDraw(canvas);
116 | // DwDebugDraw.display(canvas, world);
117 | } else {
118 | world.display(canvas);
119 | }
120 | canvas.popMatrix();
121 |
122 | // info
123 | int num_bodies = world.getBodyCount();
124 | int num_particles = world.getParticleCount();
125 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
126 | surface.setTitle(txt_fps);
127 | }
128 |
129 |
130 |
131 | //////////////////////////////////////////////////////////////////////////////
132 | // User Interaction
133 | //////////////////////////////////////////////////////////////////////////////
134 | public void keyReleased(){
135 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
136 | if(key == 'r') reset();
137 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
138 | }
139 |
140 |
141 |
142 |
143 | //////////////////////////////////////////////////////////////////////////////
144 | // Scene Setup
145 | //////////////////////////////////////////////////////////////////////////////
146 |
147 | Fixture m_sensor;
148 |
149 | // mod of the original vesion
150 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/SensorTest.java
151 | public void initScene() {
152 |
153 | {
154 | BodyDef bd = new BodyDef();
155 | Body ground = world.createBody(bd);
156 |
157 | { // floor
158 | EdgeShape shape = new EdgeShape();
159 | shape.set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
160 | ground.createFixture(shape, 0.0f);
161 | }
162 |
163 | { // sensor
164 | CircleShape shape = new CircleShape();
165 | shape.m_radius = 5.0f;
166 | shape.m_p.set(0.0f, 10.0f);
167 | FixtureDef fd = new FixtureDef();
168 | fd.shape = shape;
169 | fd.isSensor = true;
170 | m_sensor = ground.createFixture(fd);
171 | }
172 |
173 | world.bodies.add(ground, true, color(255), true, color(0), 1f);
174 | }
175 |
176 | {
177 | BodyDef bd = new BodyDef();
178 | bd.type = BodyType.DYNAMIC;
179 |
180 | CircleShape shape = new CircleShape();
181 | shape.m_radius = 1.0f;
182 |
183 | for (int i = 0; i < 10; ++i) {
184 | bd.position.set(-10.0f + 3.0f * i, 20.0f);
185 | Body body = world.createBody(bd);
186 | body.createFixture(shape, 1.0f);
187 |
188 | DwBody dwbody = world.bodies.add(body, true, color(0,255,0), true, color(0), 1f);
189 | dwbody.m_userData = (Boolean) false;
190 | }
191 | }
192 |
193 | world.setContactListener(new MyContactListener());
194 | }
195 |
196 |
197 | class MyContactListener implements ContactListener{
198 |
199 | void enableSensorAttraction(Fixture fixture, boolean enable){
200 | DwBody dwbody = DwWorld.getShape(fixture.getBody());
201 | if(dwbody != null){
202 | if(dwbody.m_userData instanceof Boolean){
203 | dwbody.m_userData = enable;
204 | }
205 | }
206 | }
207 |
208 | @Override
209 | public void beginContact(Contact contact) {
210 | Fixture fixtureA = contact.getFixtureA();
211 | Fixture fixtureB = contact.getFixtureB();
212 | if (fixtureA == m_sensor) enableSensorAttraction(fixtureB, true);
213 | if (fixtureB == m_sensor) enableSensorAttraction(fixtureA, true);
214 | }
215 |
216 | @Override
217 | public void endContact(Contact contact) {
218 | Fixture fixtureA = contact.getFixtureA();
219 | Fixture fixtureB = contact.getFixtureB();
220 | if (fixtureA == m_sensor) enableSensorAttraction(fixtureB, false);
221 | if (fixtureB == m_sensor) enableSensorAttraction(fixtureA, false);
222 | }
223 |
224 | @Override
225 | public void preSolve(Contact contact, Manifold oldManifold) {
226 | }
227 |
228 | @Override
229 | public void postSolve(Contact contact, ContactImpulse impulse) {
230 | }
231 |
232 | }
233 |
234 |
235 |
236 | public void updateSensor() {
237 |
238 | Body bsensor = m_sensor.getBody();
239 | CircleShape circle = (CircleShape) m_sensor.getShape();
240 | Vec2 sensor_pos = bsensor.getWorldPoint(circle.m_p);
241 |
242 | // Traverse the bodies. Apply a force on shapes that overlap the sensor.
243 | for (Body body = world.getBodyList(); body != null; body = body.getNext()) {
244 | if(body == bsensor){
245 | continue;
246 | }
247 |
248 | boolean is_touching = false;
249 | DwBody dwbody = DwWorld.getShape(body);
250 | if(dwbody != null){
251 | if(dwbody.m_userData instanceof Boolean){
252 | is_touching = (Boolean) dwbody.m_userData;
253 | }
254 | }
255 |
256 |
257 | if (is_touching) {
258 | Vec2 body_pos = body.getPosition();
259 |
260 | Vec2 dist = sensor_pos.sub(body_pos);
261 | if (dist.lengthSquared() > Settings.EPSILON * Settings.EPSILON) {
262 | dist.normalize();
263 | Vec2 force = dist.mulLocal(200f);
264 | body.applyForce(force, body_pos);
265 | }
266 | }
267 | }
268 | }
269 |
270 |
271 |
272 |
273 |
274 |
275 | public static void main(String args[]) {
276 | PApplet.main(new String[] { box2d_Collisions_SensorTestCallback.class.getName() });
277 | }
278 |
279 | }
--------------------------------------------------------------------------------
/examples/box2d_DominoTower/box2d_DominoTower.java:
--------------------------------------------------------------------------------
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_DominoTower;
15 |
16 | import com.thomasdiewald.liquidfun.java.DwWorld;
17 |
18 | import org.jbox2d.collision.shapes.PolygonShape;
19 | import org.jbox2d.common.Vec2;
20 | import org.jbox2d.dynamics.Body;
21 | import org.jbox2d.dynamics.BodyDef;
22 | import org.jbox2d.dynamics.BodyType;
23 | import org.jbox2d.dynamics.FixtureDef;
24 |
25 | import processing.core.*;
26 | import processing.opengl.PGraphics2D;
27 |
28 |
29 | public class box2d_DominoTower extends PApplet {
30 |
31 | //
32 | // Domino stacking example.
33 | //
34 | // Controls:
35 | //
36 | // LMB ... drag bodies
37 | // LMB + SHIFT ... shoot bullet
38 | // MMB ... add particles
39 | // RMB ... remove particles
40 | // 'r' ... reset
41 | // 't' ... update/pause physics
42 | // 'f' ... toggle debug draw
43 | //
44 |
45 |
46 | int viewport_w = 1280;
47 | int viewport_h = 720;
48 | int viewport_x = 230;
49 | int viewport_y = 0;
50 |
51 | boolean UPDATE_PHYSICS = true;
52 | boolean USE_DEBUG_DRAW = false;
53 |
54 | DwWorld world;
55 |
56 |
57 | public void settings(){
58 | size(viewport_w, viewport_h, P2D);
59 | smooth(8);
60 | }
61 |
62 | public void setup(){
63 | surface.setLocation(viewport_x, viewport_y);
64 | reset();
65 | frameRate(120);
66 | }
67 |
68 |
69 | public void release(){
70 | if(world != null) world.release(); world = null;
71 | }
72 |
73 | public void reset(){
74 | // release old resources
75 | release();
76 |
77 | world = new DwWorld(this, 20);
78 |
79 |
80 | // create scene: rigid bodies, particles, etc ...
81 | initScene();
82 | }
83 |
84 |
85 |
86 | public void draw(){
87 |
88 | if(UPDATE_PHYSICS){
89 | world.update();
90 | }
91 |
92 |
93 | PGraphics2D canvas = (PGraphics2D) this.g;
94 | canvas.background(32);
95 | canvas.pushMatrix();
96 | world.applyTransform(canvas);
97 | world.drawBulletSpawnTrack(canvas);
98 | if(USE_DEBUG_DRAW){
99 | world.displayDebugDraw(canvas);
100 | // DwDebugDraw.display(canvas, world);
101 | } else {
102 | world.display(canvas);
103 | }
104 | canvas.popMatrix();
105 |
106 | // info
107 | int num_bodies = world.getBodyCount();
108 | int num_particles = world.getParticleCount();
109 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
110 | surface.setTitle(txt_fps);
111 | }
112 |
113 |
114 |
115 |
116 |
117 | //////////////////////////////////////////////////////////////////////////////
118 | // User Interaction
119 | //////////////////////////////////////////////////////////////////////////////
120 |
121 | public void keyReleased(){
122 | if(key == 'r') reset();
123 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
124 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
125 | }
126 |
127 |
128 |
129 | //////////////////////////////////////////////////////////////////////////////
130 | // Scene Setup
131 | //////////////////////////////////////////////////////////////////////////////
132 |
133 | final float dwidth = .20f;
134 | final float dheight = 1.0f;
135 | float ddensity;// = 10f;
136 | final float dfriction = 0.1f;
137 | int baseCount = 25;
138 |
139 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/DominoTower.java
140 | public void initScene() {
141 |
142 | float screen_scale = world.transform.screen_scale;
143 | float dimx = world.transform.box2d_dimx;
144 | float dimy = world.transform.box2d_dimy;
145 | float thick = 20 / screen_scale;
146 |
147 | { // Floor
148 |
149 | BodyDef bd = new BodyDef();
150 | Body ground = world.createBody(bd);
151 |
152 | PolygonShape sd = new PolygonShape();
153 |
154 | sd.setAsBox(dimx/2, thick);
155 | ground.createFixture(sd, 0);
156 |
157 | sd.setAsBox(thick, dimy/2, new Vec2(-dimx/2, dimy/2), 0);
158 | ground.createFixture(sd, 0);
159 |
160 | sd.setAsBox(thick, dimy/2, new Vec2(+dimx/2, dimy/2), 0);
161 | ground.createFixture(sd, 0);
162 |
163 | world.bodies.add(ground, true, color(0), false, color(0), 1f);
164 | }
165 |
166 | { // Bullets
167 |
168 | Body bullet1;
169 | Body bullet2;
170 |
171 | ddensity = 10f;
172 |
173 | PolygonShape sd = new PolygonShape();
174 | sd.setAsBox(.7f, .7f);
175 |
176 | BodyDef bd = new BodyDef();
177 | bd.type = BodyType.DYNAMIC;
178 | bd.bullet = true;
179 |
180 | FixtureDef fd = new FixtureDef();
181 | fd.shape = sd;
182 | fd.friction = 0f;
183 | fd.restitution = 0.85f;
184 |
185 | fd.density = 25f;
186 | bd.position = new Vec2(30f, 50f);
187 | bullet1 = world.createBody(bd);
188 | bullet1.createFixture(fd);
189 | bullet1.setLinearVelocity(new Vec2(-25f, -25f));
190 | bullet1.setAngularVelocity(6.7f);
191 |
192 | fd.density = 25f;
193 | bd.position = new Vec2(-30, 25f);
194 | bullet2 = world.createBody(bd);
195 | bullet2.createFixture(fd);
196 | bullet2.setLinearVelocity(new Vec2(35f, -10f));
197 | bullet2.setAngularVelocity(-8.3f);
198 |
199 | world.bodies.add(bullet1, true, color(255), false, color(0), 1f);
200 | world.bodies.add(bullet2, true, color(255), false, color(0), 1f);
201 | }
202 |
203 | {
204 | float currX;
205 | // Make base
206 | for (int i = 0; i < baseCount; ++i) {
207 | currX = i * 1.5f * dheight - (1.5f * dheight * baseCount / 2f);
208 | makeDomino(currX, dheight / 2.0f, false);
209 | makeDomino(currX, dheight + dwidth / 2.0f, true);
210 | }
211 | currX = baseCount * 1.5f * dheight - (1.5f * dheight * baseCount / 2f);
212 | // Make 'I's
213 | for (int j = 1; j < baseCount; ++j) {
214 | if (j > 3) ddensity *= .8f;
215 | float currY = dheight * .5f + (dheight + 2f * dwidth) * .99f * j; // y at center of 'I'structure
216 |
217 | for (int i = 0; i < baseCount - j; ++i) {
218 | currX = i * 1.5f * dheight - (1.5f * dheight * (baseCount - j) / 2f);// +parent.random(-.05f,.05f);
219 | ddensity *= 2.5f;
220 | if (i == 0) {
221 | makeDomino(currX - (1.25f * dheight) + .5f * dwidth, currY - dwidth, false);
222 | }
223 | if (i == baseCount - j - 1) {
224 | // if (j != 1) //djm: why is this here? it makes it off balance
225 | makeDomino(currX + (1.25f * dheight) - .5f * dwidth, currY - dwidth, false);
226 | }
227 | ddensity /= 2.5f;
228 | makeDomino(currX, currY, false);
229 | makeDomino(currX, currY + .5f * (dwidth + dheight), true);
230 | makeDomino(currX, currY - .5f * (dwidth + dheight), true);
231 | }
232 | }
233 | }
234 |
235 | }
236 |
237 |
238 | int count = 0;
239 | public void makeDomino(float x, float y, boolean horizontal) {
240 |
241 | float thick = 20 / world.transform.screen_scale;
242 | y += thick;
243 |
244 | PolygonShape sd = new PolygonShape();
245 | sd.setAsBox(.5f * dwidth, .5f * dheight);
246 | FixtureDef fd = new FixtureDef();
247 | fd.shape = sd;
248 | fd.density = ddensity;
249 | BodyDef bd = new BodyDef();
250 | bd.type = BodyType.DYNAMIC;
251 | fd.friction = dfriction;
252 | fd.restitution = 0.65f;
253 | bd.position = new Vec2(x, y);
254 | bd.angle = horizontal ? (float) (Math.PI / 2.0) : 0f;
255 | Body myBody = world.createBody(bd);
256 | myBody.createFixture(fd);
257 |
258 |
259 | colorMode(HSB, 360, 100, 100);
260 | int ch = (count/5) % 360;
261 | int cs = 100;
262 | int cb = 100;
263 | if(horizontal) cb = 50;
264 | int fcol = color(ch, cs, cb);
265 | int scol = color(ch, cs*0.5f, cb*0.5f, 128);
266 | world.bodies.add(myBody, true, fcol, true, scol, 1f);
267 | colorMode(RGB, 255);
268 |
269 | count++;
270 | }
271 |
272 |
273 |
274 |
275 | public static void main(String args[]) {
276 | PApplet.main(new String[] { box2d_DominoTower.class.getName() });
277 | }
278 |
279 | }
--------------------------------------------------------------------------------
/examples/box2d_Dominos/box2d_Dominos.java:
--------------------------------------------------------------------------------
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_Dominos;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.PolygonShape;
19 | import org.jbox2d.common.Vec2;
20 | import org.jbox2d.dynamics.Body;
21 | import org.jbox2d.dynamics.BodyDef;
22 | import org.jbox2d.dynamics.BodyType;
23 | import org.jbox2d.dynamics.FixtureDef;
24 |
25 | import processing.core.*;
26 | import processing.opengl.PGraphics2D;
27 |
28 |
29 | public class box2d_Dominos extends PApplet {
30 |
31 | //
32 | // Domino example.
33 | //
34 | // Controls:
35 | //
36 | // LMB ... drag bodies
37 | // LMB + SHIFT ... shoot bullet
38 | // MMB ... add particles
39 | // RMB ... remove particles
40 | // 'r' ... reset
41 | // 't' ... update/pause physics
42 | // 'f' ... toggle debug draw
43 | //
44 |
45 | int viewport_w = 1280;
46 | int viewport_h = 720;
47 | int viewport_x = 230;
48 | int viewport_y = 0;
49 |
50 | boolean UPDATE_PHYSICS = true;
51 | boolean USE_DEBUG_DRAW = false;
52 |
53 | DwWorld world;
54 |
55 | public void settings(){
56 | size(viewport_w, viewport_h, P2D);
57 | smooth(8);
58 | }
59 |
60 |
61 | public void setup(){
62 | surface.setLocation(viewport_x, viewport_y);
63 | reset();
64 | frameRate(120);
65 | }
66 |
67 |
68 | public void release(){
69 | if(world != null) world.release(); world = null;
70 | }
71 |
72 |
73 | public void reset(){
74 | // release old resources
75 | release();
76 |
77 | world = new DwWorld(this, 25);
78 |
79 | // create scene: rigid bodies, particles, etc ...
80 | initScene();
81 | }
82 |
83 |
84 |
85 | public void draw(){
86 |
87 | if(UPDATE_PHYSICS){
88 | world.update();
89 | }
90 |
91 | PGraphics2D canvas = (PGraphics2D) this.g;
92 | canvas.background(32);
93 | canvas.pushMatrix();
94 | world.applyTransform(canvas);
95 | world.drawBulletSpawnTrack(canvas);
96 | if(USE_DEBUG_DRAW){
97 | world.displayDebugDraw(canvas);
98 | // DwDebugDraw.display(canvas, world);
99 | } else {
100 | world.display(canvas);
101 | }
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 | }
121 |
122 |
123 |
124 | //////////////////////////////////////////////////////////////////////////////
125 | // Scene Setup
126 | //////////////////////////////////////////////////////////////////////////////
127 |
128 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/DominoTest.java
129 | public void initScene() {
130 |
131 | float screen_scale = world.transform.screen_scale;
132 | float dimx = world.transform.box2d_dimx;
133 | float dimy = world.transform.box2d_dimy;
134 | float thick = 20 / screen_scale;
135 |
136 | { // Floor
137 |
138 | BodyDef bd = new BodyDef();
139 | Body ground = world.createBody(bd);
140 |
141 | PolygonShape sd = new PolygonShape();
142 |
143 | sd.setAsBox(dimx/2, thick);
144 | ground.createFixture(sd, 0);
145 |
146 | sd.setAsBox(thick, dimy/2, new Vec2(-dimx/2, dimy/2), 0);
147 | ground.createFixture(sd, 0);
148 |
149 | sd.setAsBox(thick, dimy/2, new Vec2(+dimx/2, dimy/2), 0);
150 | ground.createFixture(sd, 0);
151 |
152 | world.bodies.add(ground, true, color(0), false, color(0), 1f);
153 | }
154 |
155 | { // Platforms
156 | for (int i = 0; i < 4; i++) {
157 | FixtureDef fd = new FixtureDef();
158 | PolygonShape sd = new PolygonShape();
159 | sd.setAsBox(15.0f, 0.125f);
160 | fd.shape = sd;
161 |
162 | BodyDef bd = new BodyDef();
163 | bd.position = new Vec2(0.0f, 5f + 5f * i);
164 | Body body = world.createBody(bd);
165 | body.createFixture(fd);
166 |
167 | world.bodies.add(body, true, color(0), false, color(0), 1f);
168 | }
169 | }
170 |
171 | { // Dominos
172 | FixtureDef fd = new FixtureDef();
173 | PolygonShape sd = new PolygonShape();
174 | sd.setAsBox(0.125f, 2f);
175 | fd.shape = sd;
176 | fd.density = 25.0f;
177 |
178 | BodyDef bd = new BodyDef();
179 | bd.type = BodyType.DYNAMIC;
180 | float friction = .5f;
181 | int num_col = 4;
182 | int num_row = 25;
183 |
184 | colorMode(HSB, 360, 100, 100);
185 |
186 | for (int i = 0; i < num_col; ++i) {
187 | for (int j = 0; j < num_row; j++) {
188 | fd.friction = friction;
189 | bd.position = new Vec2(-14.75f + j * (29.5f / (num_row - 1)), 7.3f + 5f * i);
190 | if (i == 2 && j == 0) {
191 | bd.angle = -0.1f;
192 | bd.position.x += .1f;
193 | } else if (i == 3 && j == num_row - 1) {
194 | bd.angle = .1f;
195 | bd.position.x -= .1f;
196 | } else
197 | bd.angle = 0f;
198 | Body bdomino = world.createBody(bd);
199 | bdomino.createFixture(fd);
200 |
201 | // create shape, and define individual fill
202 | int hue = (int) ((i * num_row + j) / (float)(num_col * num_row) * 360);
203 | int fcol = color(hue, 100, 100);
204 | int scol = color(hue, 50, 50, 128);
205 |
206 | world.bodies.add(bdomino, true, fcol, true, scol, 1f);
207 | }
208 | }
209 |
210 | colorMode(RGB, 255);
211 | }
212 |
213 | }
214 |
215 |
216 |
217 | public static void main(String args[]) {
218 | PApplet.main(new String[] { box2d_Dominos.class.getName() });
219 | }
220 |
221 | }
--------------------------------------------------------------------------------
/examples/box2d_MobileBalanced/box2d_MobileBalanced.java:
--------------------------------------------------------------------------------
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_MobileBalanced;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.PolygonShape;
19 | import org.jbox2d.common.Vec2;
20 | import org.jbox2d.dynamics.Body;
21 | import org.jbox2d.dynamics.BodyDef;
22 | import org.jbox2d.dynamics.BodyType;
23 | import org.jbox2d.dynamics.Fixture;
24 | import org.jbox2d.dynamics.joints.RevoluteJointDef;
25 |
26 | import processing.core.*;
27 | import processing.opengl.PGraphics2D;
28 |
29 |
30 | public class box2d_MobileBalanced extends PApplet {
31 |
32 | //
33 | // A balanced binary tree.
34 | // The Edges are made of bodies, the nodes are made or RevoluteJoints.
35 | //
36 | //
37 | // Controls:
38 | //
39 | // LMB ... drag bodies
40 | // LMB + SHIFT ... shoot bullet
41 | // MMB ... add particles
42 | // RMB ... remove particles
43 | // 'r' ... reset
44 | // 't' ... update/pause physics
45 | // 'f' ... toggle debug draw
46 | //
47 |
48 | int viewport_w = 1280;
49 | int viewport_h = 720;
50 | int viewport_x = 230;
51 | int viewport_y = 0;
52 |
53 | boolean UPDATE_PHYSICS = true;
54 | boolean USE_DEBUG_DRAW = false;
55 |
56 | DwWorld world;
57 |
58 | public void settings(){
59 | size(viewport_w, viewport_h, P2D);
60 | smooth(8);
61 | }
62 |
63 | public void setup(){
64 | surface.setLocation(viewport_x, viewport_y);
65 | reset();
66 | frameRate(120);
67 | }
68 |
69 |
70 | public void release(){
71 | if(world != null) world.release(); world = null;
72 | }
73 |
74 |
75 | public void reset(){
76 | // release old resources
77 | release();
78 |
79 | world = new DwWorld(this, 50);
80 | world.transform.setCamera(0, 18, 50);
81 |
82 | // create scene: rigid bodies, particles, etc ...
83 | initScene();
84 | }
85 |
86 |
87 |
88 | public void draw(){
89 |
90 | if(UPDATE_PHYSICS){
91 | world.update();
92 | }
93 |
94 |
95 | PGraphics2D canvas = (PGraphics2D) this.g;
96 | canvas.background(32);
97 | canvas.pushMatrix();
98 | world.applyTransform(canvas);
99 | world.drawBulletSpawnTrack(canvas);
100 | if(USE_DEBUG_DRAW){
101 | world.displayDebugDraw(canvas);
102 | // DwDebugDraw.display(canvas, world);
103 | } else {
104 | world.display(canvas);
105 | }
106 | canvas.popMatrix();
107 |
108 |
109 | // info
110 | int num_bodies = world.getBodyCount();
111 | int num_particles = world.getParticleCount();
112 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
113 | surface.setTitle(txt_fps);
114 | }
115 |
116 |
117 |
118 |
119 |
120 |
121 | //////////////////////////////////////////////////////////////////////////////
122 | // User Interaction
123 | //////////////////////////////////////////////////////////////////////////////
124 | public void keyReleased(){
125 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
126 | if(key == 'r') reset();
127 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
128 | }
129 |
130 |
131 |
132 |
133 | //////////////////////////////////////////////////////////////////////////////
134 | // Scene Setup
135 | //////////////////////////////////////////////////////////////////////////////
136 |
137 |
138 | int e_depth = 6;
139 |
140 | // https://github.com/erincatto/Box2D/blob/master/Box2D/Testbed/Tests/MobileBalanced.h
141 | public void initScene() {
142 | Body ground = null;
143 | {
144 | BodyDef bd = new BodyDef();
145 | bd.position.set(0.0f, 20.0f);
146 | ground = world.createBody(bd);
147 | }
148 |
149 | float a = 0.5f;
150 | Vec2 h = new Vec2(0.0f, a);
151 |
152 | colorMode(HSB, 1f);
153 |
154 | Body root = AddNode(ground, new Vec2(), 0, 3.0f, a);
155 |
156 | colorMode(RGB, 255);
157 |
158 | RevoluteJointDef jointDef = new RevoluteJointDef();
159 | jointDef.bodyA = ground;
160 | jointDef.bodyB = root;
161 | jointDef.localAnchorA.setZero();
162 | jointDef.localAnchorB = h;
163 | world.createJoint(jointDef);
164 |
165 | world.bodies.addAll();
166 | }
167 |
168 |
169 | Body AddNode(Body parent, Vec2 localAnchor, int depth, float offset, float a){
170 |
171 | a *= 0.90f;
172 |
173 | float fdepth = 1 - depth / (float) (e_depth+1);
174 | float hue = 220 / 360f;
175 |
176 | float density = 20.0f;
177 | Vec2 h = new Vec2(0.0f, a);
178 |
179 | Vec2 p = parent.getPosition().add(localAnchor).sub(h);
180 |
181 | BodyDef bodyDef = new BodyDef();
182 | bodyDef.type = BodyType.DYNAMIC;
183 | bodyDef.position = p;
184 | Body body = world.createBody(bodyDef);
185 | world.bodies.add(body, true, color(0), true, color(0), 1f);
186 |
187 | PolygonShape shape = new PolygonShape();
188 | shape.setAsBox(0.25f * a, a);
189 | Fixture fixture1 = body.createFixture(shape, density);
190 | world.bodies.add(fixture1, true, color(hue, fdepth, 1), true, color(0), 1f);
191 |
192 | if (depth == e_depth){
193 | return body;
194 | }
195 |
196 | shape.setAsBox(offset, 0.25f * a, new Vec2(0, -a), 0.0f);
197 | Fixture fixture2 = body.createFixture(shape, density);
198 | world.bodies.add(fixture2, true, color(hue, fdepth, 1), true, color(0), 1f);
199 |
200 | Vec2 a1 = new Vec2(offset, -a);
201 | Vec2 a2 = new Vec2(-offset, -a);
202 | Body body1 = AddNode(body, a1, depth + 1, 0.5f * offset, a);
203 | Body body2 = AddNode(body, a2, depth + 1, 0.5f * offset, a);
204 |
205 | RevoluteJointDef jointDef = new RevoluteJointDef();
206 | jointDef.bodyA = body;
207 | jointDef.localAnchorB = h;
208 |
209 | jointDef.localAnchorA = a1;
210 | jointDef.bodyB = body1;
211 | world.createJoint(jointDef);
212 |
213 | jointDef.localAnchorA = a2;
214 | jointDef.bodyB = body2;
215 | world.createJoint(jointDef);
216 |
217 | return body;
218 | }
219 |
220 |
221 |
222 |
223 | public static void main(String args[]) {
224 | PApplet.main(new String[] { box2d_MobileBalanced.class.getName() });
225 | }
226 |
227 | }
--------------------------------------------------------------------------------
/examples/box2d_PulleyJoint/box2d_PulleyJoint.java:
--------------------------------------------------------------------------------
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_PulleyJoint;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 |
19 | import org.jbox2d.collision.shapes.CircleShape;
20 | import org.jbox2d.collision.shapes.EdgeShape;
21 | import org.jbox2d.collision.shapes.PolygonShape;
22 | import org.jbox2d.common.Vec2;
23 | import org.jbox2d.dynamics.Body;
24 | import org.jbox2d.dynamics.BodyDef;
25 | import org.jbox2d.dynamics.BodyType;
26 | import org.jbox2d.dynamics.joints.Joint;
27 | import org.jbox2d.dynamics.joints.PulleyJoint;
28 | import org.jbox2d.dynamics.joints.PulleyJointDef;
29 | import processing.core.*;
30 | import processing.opengl.PGraphics2D;
31 |
32 |
33 | public class box2d_PulleyJoint extends PApplet {
34 |
35 | //
36 | // This examples shows how to use PulleyJoints.
37 | //
38 | // Controls:
39 | //
40 | // LMB ... drag bodies
41 | // LMB + SHIFT ... shoot bullet
42 | // MMB ... add particles
43 | // RMB ... remove particles
44 | // 'r' ... reset
45 | // 't' ... update/pause physics
46 | // 'f' ... toggle debug draw
47 | //
48 |
49 | int viewport_w = 1280;
50 | int viewport_h = 720;
51 | int viewport_x = 230;
52 | int viewport_y = 0;
53 |
54 | boolean UPDATE_PHYSICS = true;
55 | boolean USE_DEBUG_DRAW = false;
56 |
57 | DwWorld world;
58 |
59 | public void settings(){
60 | size(viewport_w, viewport_h, P2D);
61 | smooth(8);
62 | }
63 |
64 |
65 | public void setup(){
66 | surface.setLocation(viewport_x, viewport_y);
67 | reset();
68 | frameRate(120);
69 | }
70 |
71 |
72 | public void release(){
73 | if(world != null) world.release(); world = null;
74 | }
75 |
76 |
77 | public void reset(){
78 | // release old resources
79 | release();
80 |
81 | world = new DwWorld(this, 20);
82 |
83 | // create scene: rigid bodies, particles, etc ...
84 | initScene();
85 | }
86 |
87 |
88 |
89 | public void draw(){
90 |
91 | if(UPDATE_PHYSICS){
92 | world.update();
93 | }
94 |
95 | PGraphics2D canvas = (PGraphics2D) this.g;
96 | canvas.background(32);
97 | canvas.pushMatrix();
98 | world.applyTransform(canvas);
99 | world.drawBulletSpawnTrack(canvas);
100 | if(USE_DEBUG_DRAW){
101 | world.displayDebugDraw(canvas);
102 | // DwDebugDraw.display(canvas, world);
103 | } else {
104 | world.display(canvas);
105 | }
106 | canvas.popMatrix();
107 |
108 | // info
109 | int num_bodies = world.getBodyCount();
110 | int num_particles = world.getParticleCount();
111 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
112 | surface.setTitle(txt_fps);
113 | }
114 |
115 |
116 |
117 | //////////////////////////////////////////////////////////////////////////////
118 | // User Interaction
119 | //////////////////////////////////////////////////////////////////////////////
120 | public void keyReleased(){
121 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
122 | if(key == 'r') reset();
123 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
124 | }
125 |
126 |
127 |
128 | //////////////////////////////////////////////////////////////////////////////
129 | // Scene Setup
130 | //////////////////////////////////////////////////////////////////////////////
131 |
132 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/Pulleys.java
133 | public void initScene() {
134 |
135 | float y = 16.0f;
136 | float L = 12.0f;
137 | float a = 1.0f;
138 | float b = 2.0f;
139 | Body ground = null;
140 | {
141 | BodyDef bd = new BodyDef();
142 | ground = world.createBody(bd);
143 |
144 | EdgeShape shape = new EdgeShape();
145 | shape.set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
146 | ground.createFixture(shape, 0.0f);
147 |
148 | CircleShape circle = new CircleShape();
149 | circle.m_radius = 2.0f;
150 |
151 | circle.m_p.set(-10.0f, y + b + L);
152 | ground.createFixture(circle, 0.0f);
153 |
154 | circle.m_p.set(10.0f, y + b + L);
155 | ground.createFixture(circle, 0.0f);
156 |
157 | world.bodies.add(ground, true, color(220, 128), true, color(255), 1f);
158 | }
159 |
160 | {
161 |
162 | PolygonShape shape = new PolygonShape();
163 | shape.setAsBox(a, b);
164 |
165 | BodyDef bd = new BodyDef();
166 | bd.type = BodyType.DYNAMIC;
167 |
168 | bd.position.set(-10.0f, y);
169 | Body body1 = world.createBody(bd);
170 | body1.createFixture(shape, 5.0f);
171 |
172 | bd.position.set(10.0f, y);
173 | Body body2 = world.createBody(bd);
174 | body2.createFixture(shape, 5.0f);
175 |
176 | world.bodies.add(body1, true, color(0,128,255), true, color(0), 1f);
177 | world.bodies.add(body2, true, color(0,128,255), true, color(0), 1f);
178 |
179 | PulleyJointDef pulleyDef = new PulleyJointDef();
180 | Vec2 anchor1 = new Vec2(-10.0f, y + b);
181 | Vec2 anchor2 = new Vec2(10.0f, y + b);
182 | Vec2 groundAnchor1 = new Vec2(-10.0f, y + b + L);
183 | Vec2 groundAnchor2 = new Vec2(10.0f, y + b + L);
184 | pulleyDef.initialize(body1, body2, groundAnchor1, groundAnchor2, anchor1, anchor2, 2.0f);
185 |
186 | Joint m_joint1 = (PulleyJoint) world.createJoint(pulleyDef);
187 |
188 | world.bodies.add(m_joint1, false, color(0), true, color(255,128,64), 1f);
189 | }
190 |
191 |
192 | }
193 |
194 |
195 |
196 | public static void main(String args[]) {
197 | PApplet.main(new String[] { box2d_PulleyJoint.class.getName() });
198 | }
199 |
200 | }
--------------------------------------------------------------------------------
/examples/box2d_RainingBodies/box2d_RainingBodies.java:
--------------------------------------------------------------------------------
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_RainingBodies;
15 |
16 | import com.thomasdiewald.liquidfun.java.DwWorld;
17 | import org.jbox2d.collision.shapes.CircleShape;
18 | import org.jbox2d.collision.shapes.PolygonShape;
19 | import org.jbox2d.collision.shapes.Shape;
20 | import org.jbox2d.common.Vec2;
21 | import org.jbox2d.dynamics.Body;
22 | import org.jbox2d.dynamics.BodyDef;
23 | import org.jbox2d.dynamics.BodyType;
24 | import org.jbox2d.dynamics.Fixture;
25 | import processing.core.*;
26 | import processing.opengl.PGraphics2D;
27 |
28 |
29 | public class box2d_RainingBodies extends PApplet {
30 |
31 | //
32 | // Randomly falling bodies. Automatically removed from the world if the exceed
33 | // some boundary.
34 | //
35 | // Controls:
36 | //
37 | // LMB ... drag bodies
38 | // LMB + SHIFT ... shoot bullet
39 | // MMB ... add particles
40 | // RMB ... remove particles
41 | // 'r' ... reset
42 | // 't' ... update/pause physics
43 | // 'f' ... toggle debug draw
44 | //
45 |
46 |
47 | int viewport_w = 1280;
48 | int viewport_h = 720;
49 | int viewport_x = 230;
50 | int viewport_y = 0;
51 |
52 | boolean UPDATE_PHYSICS = true;
53 | boolean USE_DEBUG_DRAW = false;
54 |
55 | DwWorld world;
56 |
57 | public void settings(){
58 | size(viewport_w, viewport_h, P2D);
59 | smooth(8);
60 | }
61 |
62 | public void setup(){
63 | surface.setLocation(viewport_x, viewport_y);
64 | reset();
65 | frameRate(120);
66 | }
67 |
68 |
69 | public void release(){
70 | if(world != null) world.release(); world = null;
71 | }
72 |
73 | public void reset(){
74 | // release old resources
75 | release();
76 |
77 | world = new DwWorld(this, 20);
78 |
79 | // create scene: rigid bodies, particles, etc ...
80 | initScene();
81 | }
82 |
83 |
84 |
85 | public void draw(){
86 |
87 | if(UPDATE_PHYSICS){
88 | if(frameCount % 10 == 0){
89 | addBodies();
90 | }
91 | world.update();
92 | }
93 |
94 |
95 | PGraphics2D canvas = (PGraphics2D) this.g;
96 |
97 | canvas.background(32);
98 | canvas.pushMatrix();
99 | world.applyTransform(canvas);
100 | world.drawBulletSpawnTrack(canvas);
101 |
102 | if(USE_DEBUG_DRAW){
103 | world.displayDebugDraw(canvas);
104 | // DwDebugDraw.display(canvas, world);
105 | } else {
106 | world.display(canvas);
107 | }
108 | canvas.popMatrix();
109 |
110 | // info
111 | int num_bodies = world.getBodyCount();
112 | int num_particles = world.getParticleCount();
113 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
114 | surface.setTitle(txt_fps);
115 | }
116 |
117 |
118 |
119 |
120 | //////////////////////////////////////////////////////////////////////////////
121 | // User Interaction
122 | //////////////////////////////////////////////////////////////////////////////
123 |
124 | public void keyReleased(){
125 | if(key == 'r') reset();
126 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
127 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
128 | }
129 |
130 |
131 |
132 | //////////////////////////////////////////////////////////////////////////////
133 | // Scene Setup
134 | //////////////////////////////////////////////////////////////////////////////
135 |
136 | int MAX_NUM = 800;
137 | int m_count = 0;
138 |
139 | public void initScene() {
140 |
141 | m_count = 0;
142 |
143 | float screen_scale = world.transform.screen_scale;
144 | float b2d_screen_w = world.transform.box2d_dimx;
145 | float b2d_screen_h = world.transform.box2d_dimy;
146 | float b2d_thickness = 10 / screen_scale;
147 |
148 | { // Walls
149 | BodyDef bd = new BodyDef();
150 | bd.position.set(0, 0);
151 |
152 | Body ground = world.createBody(bd);
153 | PolygonShape sd = new PolygonShape();
154 |
155 | float x, y, w, h;
156 |
157 | float angle = 60 * PI/180;
158 | for(int i = 0; i < 10; i++){
159 | x = random(-0.5f, 0.5f) * b2d_screen_w;
160 | y = random( 0, 0.5f) * b2d_screen_h;
161 | w = random(15, 20);
162 | h = b2d_thickness;
163 | sd.setAsBox(w/2f, h/2f, new Vec2(x, y), random(-1, 1) * angle);
164 | ground.createFixture(sd, 0);
165 | }
166 |
167 | world.bodies.add(ground, true, color(0), !true, color(0), 1f);
168 | }
169 | }
170 |
171 |
172 |
173 | public void addBodies(){
174 | if (world.getBodyCount() < MAX_NUM) {
175 |
176 | float b2d_screen_w = world.transform.box2d_dimx;
177 | float b2d_screen_h = world.transform.box2d_dimy;
178 |
179 | float x = random(-0.4f, 0.4f) * b2d_screen_w;
180 | float y = random(-2f, 2) + b2d_screen_h;
181 |
182 | float w = random(0.5f, 2.2f);
183 | float h = random(0.5f, 1.2f);
184 |
185 | BodyDef bd = new BodyDef();
186 | bd.type = BodyType.DYNAMIC;
187 | bd.position.set(x, y);
188 | Body body = world.createBody(bd);
189 |
190 | Shape shape = null;
191 | if(random(1) < 0.5){
192 | PolygonShape pshape = new PolygonShape();
193 | pshape.setAsBox(w, h, new Vec2(0,0), random(TWO_PI));
194 | shape = pshape;
195 | } else {
196 | CircleShape cshape = new CircleShape();
197 | cshape.m_p.set(0,0);
198 | cshape.m_radius = w / 2f;
199 | shape = cshape;
200 | }
201 |
202 | Fixture fixture = body.createFixture(shape, 0.01f);
203 | fixture.m_friction = 0.1f;
204 | fixture.m_restitution = 0.5f;
205 |
206 | colorMode(HSB, 360, 100, 100);
207 |
208 | float r = (360 * m_count /(float)MAX_NUM) % 360;
209 | float g = 100;
210 | float b = 100;
211 |
212 | world.bodies.add(body, true, color(r,g,b), true, color(r, g, b *0.5f), 1f);
213 | colorMode(RGB, 255, 255, 255);
214 |
215 | m_count++;
216 | }
217 | }
218 |
219 |
220 |
221 |
222 |
223 | public static void main(String args[]) {
224 | PApplet.main(new String[] { box2d_RainingBodies.class.getName() });
225 | }
226 |
227 | }
--------------------------------------------------------------------------------
/examples/box2d_RopeJoint/box2d_RopeJoint.java:
--------------------------------------------------------------------------------
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_RopeJoint;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.EdgeShape;
19 | import org.jbox2d.collision.shapes.PolygonShape;
20 | import org.jbox2d.common.Vec2;
21 | import org.jbox2d.dynamics.Body;
22 | import org.jbox2d.dynamics.BodyDef;
23 | import org.jbox2d.dynamics.BodyType;
24 | import org.jbox2d.dynamics.FixtureDef;
25 | import org.jbox2d.dynamics.joints.Joint;
26 | import org.jbox2d.dynamics.joints.RevoluteJointDef;
27 | import org.jbox2d.dynamics.joints.RopeJointDef;
28 |
29 | import processing.core.*;
30 | import processing.opengl.PGraphics2D;
31 |
32 |
33 | public class box2d_RopeJoint extends PApplet {
34 |
35 | //
36 | // This examples shows how to use RopeJoints.
37 | //
38 | // Controls:
39 | //
40 | // LMB ... drag bodies
41 | // LMB + SHIFT ... shoot bullet
42 | // MMB ... add particles
43 | // RMB ... remove particles
44 | // 'r' ... reset
45 | // 't' ... update/pause physics
46 | // 'f' ... toggle debug draw
47 | // 'j' ... toggle joint
48 | //
49 |
50 | int viewport_w = 1280;
51 | int viewport_h = 720;
52 | int viewport_x = 230;
53 | int viewport_y = 0;
54 |
55 | boolean UPDATE_PHYSICS = true;
56 | boolean USE_DEBUG_DRAW = false;
57 |
58 | DwWorld world;
59 |
60 | public void settings(){
61 | size(viewport_w, viewport_h, P2D);
62 | smooth(8);
63 | }
64 |
65 |
66 | public void setup(){
67 | surface.setLocation(viewport_x, viewport_y);
68 | reset();
69 | frameRate(120);
70 | }
71 |
72 |
73 | public void release(){
74 | if(world != null) world.release(); world = null;
75 | }
76 |
77 |
78 | public void reset(){
79 | // release old resources
80 | release();
81 |
82 | world = new DwWorld(this, 30);
83 |
84 | // create scene: rigid bodies, particles, etc ...
85 | initScene();
86 | }
87 |
88 |
89 |
90 | public void draw(){
91 |
92 | if(UPDATE_PHYSICS){
93 | world.update();
94 | }
95 |
96 | PGraphics2D canvas = (PGraphics2D) this.g;
97 | canvas.background(32);
98 | canvas.pushMatrix();
99 | world.applyTransform(canvas);
100 | world.drawBulletSpawnTrack(canvas);
101 | if(USE_DEBUG_DRAW){
102 | world.displayDebugDraw(canvas);
103 | // DwDebugDraw.display(canvas, world);
104 | } else {
105 | world.display(canvas);
106 | }
107 | canvas.popMatrix();
108 |
109 | // info
110 | int num_bodies = world.getBodyCount();
111 | int num_particles = world.getParticleCount();
112 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
113 | surface.setTitle(txt_fps);
114 | }
115 |
116 |
117 |
118 | //////////////////////////////////////////////////////////////////////////////
119 | // User Interaction
120 | //////////////////////////////////////////////////////////////////////////////
121 | public void keyReleased(){
122 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
123 | if(key == 'r') reset();
124 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
125 |
126 |
127 | if(key == 'j'){
128 | if (m_rope != null) {
129 | world.destroyJoint(m_rope);
130 | m_rope = null;
131 | } else {
132 | m_rope = world.createJoint(m_ropeDef);
133 | world.bodies.add(m_rope, false, color(0), true, color(255,128,0), 2f);
134 | }
135 | }
136 | }
137 |
138 |
139 |
140 | //////////////////////////////////////////////////////////////////////////////
141 | // Scene Setup
142 | //////////////////////////////////////////////////////////////////////////////
143 |
144 | RopeJointDef m_ropeDef;
145 | Joint m_rope;
146 |
147 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/RopeTest.java
148 | public void initScene() {
149 |
150 | Body ground = null;
151 | {
152 | BodyDef bd = new BodyDef();
153 | ground = world.createBody(bd);
154 |
155 | EdgeShape shape = new EdgeShape();
156 | shape.set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
157 | ground.createFixture(shape, 0.0f);
158 | }
159 |
160 | {
161 | PolygonShape shape = new PolygonShape();
162 | shape.setAsBox(0.5f, 0.125f);
163 |
164 | FixtureDef fd = new FixtureDef();
165 | fd.shape = shape;
166 | fd.density = 20.0f;
167 | fd.friction = 0.2f;
168 | fd.filter.categoryBits = 0x0001;
169 | fd.filter.maskBits = 0xFFFF & ~0x0002;
170 |
171 | RevoluteJointDef jd = new RevoluteJointDef();
172 | jd.collideConnected = false;
173 |
174 |
175 | final int N = 10;
176 | final float y = 15.0f;
177 | m_ropeDef = new RopeJointDef();
178 | m_ropeDef.localAnchorA.set(0.0f, y);
179 |
180 | Body prevBody = ground;
181 | for (int i = 0; i < N; ++i) {
182 | BodyDef bd = new BodyDef();
183 | bd.type = BodyType.DYNAMIC;
184 | bd.position.set(0.5f + 1.0f * i, y);
185 | if (i == N - 1) {
186 | shape.setAsBox(1.5f, 1.5f);
187 | fd.density = 100.0f;
188 | fd.filter.categoryBits = 0x0002;
189 | bd.position.set(1.0f * i, y);
190 | bd.angularDamping = 0.4f;
191 | }
192 |
193 | Body body = world.createBody(bd);
194 | body.createFixture(fd);
195 |
196 | world.bodies.add(body, true, color(255 * i/(float)N), true, color(0), 1f);
197 |
198 | Vec2 anchor = new Vec2(i, y);
199 | jd.initialize(prevBody, body, anchor);
200 | Joint joint = world.createJoint(jd);
201 |
202 | world.bodies.add(joint, false, color(0), true, color(0,128,255), 2f);
203 |
204 | prevBody = body;
205 | }
206 |
207 | m_ropeDef.localAnchorB.setZero();
208 |
209 | float extraLength = 0.01f;
210 | m_ropeDef.maxLength = N - 1.0f + extraLength;
211 | m_ropeDef.bodyB = prevBody;
212 | }
213 |
214 | {
215 | m_ropeDef.bodyA = ground;
216 | m_rope = world.createJoint(m_ropeDef);
217 | world.bodies.add(m_rope, false, color(0), true, color(255,128,0), 2f);
218 | }
219 |
220 |
221 | world.bodies.addAll();
222 | }
223 |
224 |
225 |
226 | public static void main(String args[]) {
227 | PApplet.main(new String[] { box2d_RopeJoint.class.getName() });
228 | }
229 |
230 | }
--------------------------------------------------------------------------------
/examples/box2d_Tumbler/box2d_Tumbler.java:
--------------------------------------------------------------------------------
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_Tumbler;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.CircleShape;
19 | import org.jbox2d.collision.shapes.PolygonShape;
20 | import org.jbox2d.common.MathUtils;
21 | import org.jbox2d.common.Vec2;
22 | import org.jbox2d.dynamics.Body;
23 | import org.jbox2d.dynamics.BodyDef;
24 | import org.jbox2d.dynamics.BodyType;
25 | import org.jbox2d.dynamics.Fixture;
26 | import org.jbox2d.dynamics.joints.RevoluteJoint;
27 | import org.jbox2d.dynamics.joints.RevoluteJointDef;
28 |
29 | import processing.core.*;
30 | import processing.opengl.PGraphics2D;
31 |
32 |
33 | public class box2d_Tumbler extends PApplet {
34 |
35 | //
36 | // A square tumbler is animated using a RevoluteJoint (motor).
37 | // Small boxes are dynamically added.
38 | //
39 | // Controls:
40 | //
41 | // LMB ... drag bodies
42 | // LMB + SHIFT ... shoot bullet
43 | // MMB ... add particles
44 | // RMB ... remove particles
45 | // 'r' ... reset
46 | // 't' ... update/pause physics
47 | // 'f' ... toggle debug draw
48 | //
49 |
50 |
51 |
52 | int viewport_w = 1280;
53 | int viewport_h = 720;
54 | int viewport_x = 230;
55 | int viewport_y = 0;
56 |
57 | boolean UPDATE_PHYSICS = true;
58 | boolean USE_DEBUG_DRAW = false;
59 |
60 |
61 | DwWorld world;
62 |
63 | public void settings(){
64 | size(viewport_w, viewport_h, P2D);
65 | smooth(8);
66 | }
67 |
68 | public void setup(){
69 | surface.setLocation(viewport_x, viewport_y);
70 | reset();
71 | frameRate(120);
72 | }
73 |
74 |
75 | public void release(){
76 | if(world != null) world.release(); world = null;
77 | }
78 |
79 |
80 | public void reset(){
81 | // release old resources
82 | release();
83 |
84 | world = new DwWorld(this, 22);
85 | world.transform.setScreen(width, height, 22, width/2, height/2);
86 |
87 | // create scene: rigid bodies, particles, etc ...
88 | initScene();
89 | }
90 |
91 |
92 |
93 | public void draw(){
94 |
95 | if(UPDATE_PHYSICS){
96 | if(frameCount % 4 == 0){
97 | addBodies();
98 | }
99 | world.update();
100 | }
101 |
102 |
103 | PGraphics2D canvas = (PGraphics2D) this.g;
104 | canvas.background(32);
105 | canvas.pushMatrix();
106 | world.applyTransform(canvas);
107 | world.drawBulletSpawnTrack(canvas);
108 | if(USE_DEBUG_DRAW){
109 | world.displayDebugDraw(canvas);
110 | // DwDebugDraw.display(canvas, world);
111 | } else {
112 | world.display(canvas);
113 | }
114 | canvas.popMatrix();
115 |
116 |
117 | // info
118 | int num_bodies = world.getBodyCount();
119 | int num_particles = world.getParticleCount();
120 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
121 | surface.setTitle(txt_fps);
122 | }
123 |
124 |
125 |
126 |
127 |
128 |
129 | //////////////////////////////////////////////////////////////////////////////
130 | // User Interaction
131 | //////////////////////////////////////////////////////////////////////////////
132 | public void keyReleased(){
133 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
134 | if(key == 'r') reset();
135 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
136 | }
137 |
138 |
139 |
140 |
141 | //////////////////////////////////////////////////////////////////////////////
142 | // Scene Setup
143 | //////////////////////////////////////////////////////////////////////////////
144 | int MAX_NUM = 800;
145 | int m_count = 0;
146 | RevoluteJoint m_joint;
147 |
148 |
149 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/Tumbler.java
150 | public void initScene() {
151 |
152 |
153 | {
154 | BodyDef bd = new BodyDef();
155 | Body groundbody = world.createBody(bd);
156 |
157 | bd.type = BodyType.DYNAMIC;
158 | bd.allowSleep = false;
159 | bd.position.set(0.0f, 0.0f);
160 | Body body = world.createBody(bd);
161 |
162 | PolygonShape shape = new PolygonShape();
163 | shape.setAsBox(1, 11.0f, new Vec2(10.0f, 0.0f), 0.0f);
164 | body.createFixture(shape, 15.0f);
165 | shape.setAsBox(1, 11.0f, new Vec2(-10.0f, 0.0f), 0.0f);
166 | body.createFixture(shape, 15.0f);
167 | shape.setAsBox(11.0f, 1, new Vec2(0.0f, 10.0f), 0.0f);
168 | body.createFixture(shape, 15.0f);
169 | shape.setAsBox(11.0f, 1, new Vec2(0.0f, -10.0f), 0.0f);
170 | body.createFixture(shape, 15.0f);
171 |
172 |
173 | CircleShape obstacle = new CircleShape();
174 | obstacle.m_radius = 1;
175 | obstacle.m_p.set(-2, -6.5f);
176 | body.createFixture(obstacle, 115.0f);
177 | obstacle.m_p.set(2, +6.5f);
178 | body.createFixture(obstacle, 115.0f);
179 | // obstacle.m_p.set(-7.5f, 0);
180 | // body.createFixture(obstacle, 15.0f);
181 | // obstacle.m_p.set(+7.5f, 0);
182 | // body.createFixture(obstacle, 15.0f);
183 |
184 |
185 | world.bodies.add(body, true, color(224), true, color(0), 1f);
186 |
187 | RevoluteJointDef jd = new RevoluteJointDef();
188 | jd.bodyA = groundbody;
189 | jd.bodyB = body;
190 | jd.localAnchorA.set(0.0f, 0.0f);
191 | jd.localAnchorB.set(0.0f, 0.0f);
192 | jd.referenceAngle = 0.0f;
193 | jd.motorSpeed = 0.1f * MathUtils.PI;
194 | jd.maxMotorTorque = 1e7f;
195 | jd.enableMotor = true;
196 | m_joint = (RevoluteJoint) world.createJoint(jd);
197 | }
198 | m_count = 0;
199 |
200 |
201 | // creates shapes for all rigid bodies in the world.
202 | world.bodies.addAll();
203 | }
204 |
205 |
206 | public void addBodies(){
207 | if (m_count < MAX_NUM) {
208 |
209 | float x = random(-0.7f, 0.7f);
210 | float y = random(-0.7f, 0.7f);
211 |
212 | BodyDef bd = new BodyDef();
213 | bd.type = BodyType.DYNAMIC;
214 | bd.position.set(x, y);
215 | Body body = world.createBody(bd);
216 |
217 | PolygonShape shape = new PolygonShape();
218 | shape.setAsBox(0.18f, 0.18f);
219 | Fixture fixture = body.createFixture(shape, 0.01f);
220 | fixture.m_friction = 0.1f;
221 | fixture.m_restitution = 0.5f;
222 |
223 | ++m_count;
224 |
225 | colorMode(HSB, 360, 100, 100);
226 | float r = (360 * m_count /(float)MAX_NUM) % 360;
227 | float g = 100;
228 | float b = 100;
229 | world.bodies.add(body, true, color(r,g,b), true, color(r, g, b *0.5f), 1f);
230 | colorMode(RGB, 255, 255, 255);
231 | }
232 | }
233 |
234 |
235 |
236 |
237 | public static void main(String args[]) {
238 | PApplet.main(new String[] { box2d_Tumbler.class.getName() });
239 | }
240 |
241 | }
--------------------------------------------------------------------------------
/examples/box2d_TumblerMod/box2d_TumblerMod.java:
--------------------------------------------------------------------------------
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_TumblerMod;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.ChainShape;
19 | import org.jbox2d.collision.shapes.CircleShape;
20 | import org.jbox2d.collision.shapes.PolygonShape;
21 | import org.jbox2d.common.MathUtils;
22 | import org.jbox2d.common.Vec2;
23 | import org.jbox2d.dynamics.Body;
24 | import org.jbox2d.dynamics.BodyDef;
25 | import org.jbox2d.dynamics.BodyType;
26 | import org.jbox2d.dynamics.Fixture;
27 | import org.jbox2d.dynamics.joints.RevoluteJoint;
28 | import org.jbox2d.dynamics.joints.RevoluteJointDef;
29 |
30 | import processing.core.*;
31 | import processing.opengl.PGraphics2D;
32 |
33 |
34 | public class box2d_TumblerMod extends PApplet {
35 |
36 | //
37 | // A custom shaped tumbler is animated using a RevoluteJoint (motor).
38 | // Small boxes are dynamically added.
39 | //
40 | // Controls:
41 | //
42 | // LMB ... drag bodies
43 | // LMB + SHIFT ... shoot bullet
44 | // MMB ... add particles
45 | // RMB ... remove particles
46 | // 'r' ... reset
47 | // 't' ... update/pause physics
48 | // 'f' ... toggle debug draw
49 | //
50 |
51 | int viewport_w = 1280;
52 | int viewport_h = 720;
53 | int viewport_x = 230;
54 | int viewport_y = 0;
55 |
56 | boolean UPDATE_PHYSICS = true;
57 | boolean USE_DEBUG_DRAW = false;
58 |
59 | DwWorld world;
60 |
61 | public void settings(){
62 | size(viewport_w, viewport_h, P2D);
63 | smooth(8);
64 | }
65 |
66 | public void setup(){
67 | surface.setLocation(viewport_x, viewport_y);
68 | reset();
69 | frameRate(120);
70 | }
71 |
72 |
73 | public void release(){
74 | if(world != null) world.release(); world = null;
75 | }
76 |
77 |
78 | public void reset(){
79 | // release old resources
80 | release();
81 |
82 | // create world
83 | world = new DwWorld(this, 20);
84 | world.transform.setScreen(width, height, 22, width/2, height/2);
85 |
86 | // create scene: rigid bodies, particles, etc ...
87 | initScene();
88 | }
89 |
90 |
91 | public void draw(){
92 |
93 | if(UPDATE_PHYSICS){
94 | if(frameCount % 4 == 0){
95 | addBodies();
96 | }
97 | world.update();
98 | }
99 |
100 |
101 | PGraphics2D canvas = (PGraphics2D) this.g;
102 | canvas.background(32);
103 | canvas.pushMatrix();
104 | world.applyTransform(canvas);
105 | world.drawBulletSpawnTrack(canvas);
106 | if(USE_DEBUG_DRAW){
107 | world.displayDebugDraw(canvas);
108 | // DwDebugDraw.display(canvas, world);
109 | } else {
110 | world.display(canvas);
111 | }
112 | canvas.popMatrix();
113 |
114 |
115 | // info
116 | int num_bodies = world.getBodyCount();
117 | int num_particles = world.getParticleCount();
118 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
119 | surface.setTitle(txt_fps);
120 | }
121 |
122 |
123 |
124 |
125 |
126 |
127 | //////////////////////////////////////////////////////////////////////////////
128 | // User Interaction
129 | //////////////////////////////////////////////////////////////////////////////
130 |
131 | public void keyReleased(){
132 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
133 | if(key == 'r') reset();
134 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
135 | }
136 |
137 |
138 |
139 | //////////////////////////////////////////////////////////////////////////////
140 | // Scene Setup
141 | //////////////////////////////////////////////////////////////////////////////
142 | int MAX_NUM = 800;
143 | RevoluteJoint m_joint;
144 | int m_count;
145 |
146 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/Tumbler.java
147 | public void initScene() {
148 |
149 |
150 | {
151 | BodyDef bd = new BodyDef();
152 | Body groundbody = world.createBody(bd);
153 |
154 | bd.type = BodyType.DYNAMIC;
155 | bd.allowSleep = false;
156 | bd.position.set(0.0f, 0.0f);
157 |
158 | Body bwheel = world.createBody(bd);
159 | // bodies.add(bwheel);
160 |
161 | ChainShape shape = new ChainShape();
162 | int num_verts = 128;
163 | float rad = 10;
164 | float angle_step = (float) (Math.PI * 2 / num_verts);
165 |
166 | float dent_size = 1.5f;
167 | int num_dents = 5;
168 |
169 | // wheel
170 | Vec2[] vertices = new Vec2[num_verts];
171 | for(int i = 0; i < num_verts; i++){
172 | float inorm = (float) ((Math.PI * 2) * i / (float) num_verts);
173 | float rad_off = (float) Math.cos(inorm * num_dents) * dent_size;
174 | float x = (rad + rad_off) * (float) Math.cos(angle_step * i);
175 | float y = (rad + rad_off) * (float) Math.sin(angle_step * i);
176 | vertices[i] = new Vec2(x, y);
177 | }
178 |
179 | shape.createLoop(vertices, num_verts);
180 | Fixture wheel = bwheel.createFixture(shape, 15.0f);
181 | world.bodies.add(wheel, true, color(240), false, color(255), 1f);
182 |
183 | // obstacles inside wheel
184 | CircleShape sobstacle = new CircleShape();
185 | sobstacle.m_radius = 4f/num_dents;
186 | angle_step = (float) (Math.PI * 2 / num_dents);
187 | for(int i = 0; i < num_dents; i++){
188 | float angle = angle_step * 0.5f + angle_step * i;
189 | float radius = rad - 4f;
190 | float x = radius * (float) Math.cos(angle);
191 | float y = radius * (float) Math.sin(angle);
192 | sobstacle.m_p.set(x, y);
193 | Fixture fobstacle = bwheel.createFixture(sobstacle, 150.0f);
194 | world.bodies.add(fobstacle, true, color(64), false, color(255), 1f);
195 | }
196 |
197 | // motor
198 | RevoluteJointDef jd = new RevoluteJointDef();
199 | jd.bodyA = groundbody;
200 | jd.bodyB = bwheel;
201 | jd.localAnchorA.set(0.0f, 0.0f);
202 | jd.localAnchorB.set(0.0f, 0.0f);
203 | jd.referenceAngle = 0.0f;
204 | jd.motorSpeed = 0.1f * MathUtils.PI;
205 | jd.maxMotorTorque = 1000000f;
206 | jd.enableMotor = true;
207 | m_joint = (RevoluteJoint) world.createJoint(jd);
208 | }
209 | m_count = 0;
210 |
211 | }
212 |
213 |
214 | public void addBodies(){
215 | if (m_count < MAX_NUM) {
216 |
217 | float x = random(-0.7f, 0.7f);
218 | float y = random(-0.7f, 0.7f);
219 |
220 | BodyDef bd = new BodyDef();
221 | bd.type = BodyType.DYNAMIC;
222 | bd.position.set(x, y);
223 | Body body = world.createBody(bd);
224 |
225 | PolygonShape shape = new PolygonShape();
226 | shape.setAsBox(0.18f, 0.18f);
227 | Fixture fixture = body.createFixture(shape, 0.01f);
228 | fixture.m_friction = 0.1f;
229 | fixture.m_restitution = 0.5f;
230 |
231 | ++m_count;
232 |
233 | colorMode(HSB, 360, 100, 100);
234 | float hue = (360 * m_count /(float)MAX_NUM) % 360;
235 | world.bodies.add(body, true, color(hue, 100, 100), true, color(hue, 100, 50), 1f);
236 | colorMode(RGB, 255, 255, 255);
237 | }
238 | }
239 |
240 |
241 |
242 |
243 | public static void main(String args[]) {
244 | PApplet.main(new String[] { box2d_TumblerMod.class.getName() });
245 | }
246 |
247 | }
--------------------------------------------------------------------------------
/examples/box2d_VaryingFriction/box2d_VaryingFriction.java:
--------------------------------------------------------------------------------
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_VaryingFriction;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 |
19 | import org.jbox2d.collision.shapes.EdgeShape;
20 | import org.jbox2d.collision.shapes.PolygonShape;
21 | import org.jbox2d.common.Vec2;
22 | import org.jbox2d.dynamics.Body;
23 | import org.jbox2d.dynamics.BodyDef;
24 | import org.jbox2d.dynamics.BodyType;
25 | import org.jbox2d.dynamics.FixtureDef;
26 | import processing.core.*;
27 | import processing.opengl.PGraphics2D;
28 |
29 |
30 | public class box2d_VaryingFriction extends PApplet {
31 |
32 | //
33 | // this examples shows demonstrates the behaviour of different friction-values.
34 | //
35 | // Controls:
36 | //
37 | // LMB ... drag bodies
38 | // LMB + SHIFT ... shoot bullet
39 | // MMB ... add particles
40 | // RMB ... remove particles
41 | // 'r' ... reset
42 | // 't' ... update/pause physics
43 | // 'f' ... toggle debug draw
44 | //
45 |
46 |
47 | int viewport_w = 1280;
48 | int viewport_h = 720;
49 | int viewport_x = 230;
50 | int viewport_y = 0;
51 |
52 | boolean UPDATE_PHYSICS = true;
53 | boolean USE_DEBUG_DRAW = false;
54 |
55 | DwWorld world;
56 |
57 | public void settings(){
58 | size(viewport_w, viewport_h, P2D);
59 | smooth(8);
60 | }
61 |
62 | public void setup(){
63 | surface.setLocation(viewport_x, viewport_y);
64 | reset();
65 | frameRate(120);
66 | }
67 |
68 |
69 | public void release(){
70 | if(world != null) world.release(); world = null;
71 | }
72 |
73 |
74 | public void reset(){
75 | // release old resources
76 | release();
77 |
78 | world = new DwWorld(this, 25);
79 |
80 | // create scene: rigid bodies, particles, etc ...
81 | initScene();
82 | }
83 |
84 |
85 |
86 | public void draw(){
87 |
88 | if(UPDATE_PHYSICS){
89 | world.update();
90 | }
91 |
92 |
93 | PGraphics2D canvas = (PGraphics2D) this.g;
94 | canvas.background(32);
95 | canvas.pushMatrix();
96 | world.applyTransform(canvas);
97 | world.drawBulletSpawnTrack(canvas);
98 | if(USE_DEBUG_DRAW){
99 | world.displayDebugDraw(canvas);
100 | // DwDebugDraw.display(canvas, world);
101 | } else {
102 | world.display(canvas);
103 | }
104 | canvas.popMatrix();
105 |
106 |
107 | // info
108 | int num_bodies = world.getBodyCount();
109 | int num_particles = world.getParticleCount();
110 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
111 | surface.setTitle(txt_fps);
112 | }
113 |
114 |
115 |
116 |
117 |
118 |
119 | //////////////////////////////////////////////////////////////////////////////
120 | // User Interaction
121 | //////////////////////////////////////////////////////////////////////////////
122 | public void keyReleased(){
123 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
124 | if(key == 'r') reset();
125 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
126 | }
127 |
128 |
129 |
130 |
131 | //////////////////////////////////////////////////////////////////////////////
132 | // Scene Setup
133 | //////////////////////////////////////////////////////////////////////////////
134 |
135 |
136 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/VaryingFrictionTest.java
137 | public void initScene() {
138 | {
139 | BodyDef bd = new BodyDef();
140 | Body ground = world.createBody(bd);
141 |
142 | EdgeShape shape = new EdgeShape();
143 | shape.set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
144 | ground.createFixture(shape, 0.0f);
145 |
146 | world.bodies.add(ground, false, color(0), true, color(200), 1f);
147 | }
148 |
149 | {
150 | PolygonShape shape = new PolygonShape();
151 | shape.setAsBox(13.0f, 0.25f);
152 |
153 | BodyDef bd = new BodyDef();
154 | bd.position.set(-4.0f, 22.0f);
155 | bd.angle = -0.25f;
156 |
157 | Body ground = world.createBody(bd);
158 | ground.createFixture(shape, 0.0f);
159 | }
160 |
161 | {
162 | PolygonShape shape = new PolygonShape();
163 | shape.setAsBox(0.25f, 1.0f);
164 |
165 | BodyDef bd = new BodyDef();
166 | bd.position.set(10.5f, 19.0f);
167 |
168 | Body ground = world.createBody(bd);
169 | ground.createFixture(shape, 0.0f);
170 | }
171 |
172 | {
173 | PolygonShape shape = new PolygonShape();
174 | shape.setAsBox(13.0f, 0.25f);
175 |
176 | BodyDef bd = new BodyDef();
177 | bd.position.set(4.0f, 14.0f);
178 | bd.angle = 0.25f;
179 |
180 | Body ground = world.createBody(bd);
181 | ground.createFixture(shape, 0.0f);
182 | }
183 |
184 | {
185 | PolygonShape shape = new PolygonShape();
186 | shape.setAsBox(0.25f, 1.0f);
187 |
188 | BodyDef bd = new BodyDef();
189 | bd.position.set(-10.5f, 11.0f);
190 |
191 | Body ground = world.createBody(bd);
192 | ground.createFixture(shape, 0.0f);
193 | }
194 |
195 | {
196 | PolygonShape shape = new PolygonShape();
197 | shape.setAsBox(13.0f, 0.25f);
198 |
199 | BodyDef bd = new BodyDef();
200 | bd.position.set(-4.0f, 6.0f);
201 | bd.angle = -0.25f;
202 |
203 | Body ground = world.createBody(bd);
204 | ground.createFixture(shape, 0.0f);
205 | }
206 |
207 | {
208 | PolygonShape shape = new PolygonShape();
209 | shape.setAsBox(0.5f, 0.5f);
210 |
211 | FixtureDef fd = new FixtureDef();
212 | fd.shape = shape;
213 | fd.density = 25.0f;
214 |
215 | float friction[] = { 0.75f, 0.5f, 0.35f, 0.1f, 0.0f };
216 |
217 | for (int i = 0; i < 5; ++i) {
218 | BodyDef bd = new BodyDef();
219 | bd.type = BodyType.DYNAMIC;
220 | bd.position.set(-15.0f + 4.0f * i, 28.0f);
221 | Body body = world.createBody(bd);
222 |
223 | fd.friction = friction[i];
224 | body.createFixture(fd);
225 | }
226 | }
227 |
228 | world.bodies.addAll();
229 | }
230 |
231 |
232 |
233 |
234 |
235 |
236 | public static void main(String args[]) {
237 | PApplet.main(new String[] { box2d_VaryingFriction.class.getName() });
238 | }
239 |
240 | }
--------------------------------------------------------------------------------
/examples/box2d_VaryingRestitution/box2d_VaryingRestitution.java:
--------------------------------------------------------------------------------
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_VaryingRestitution;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.CircleShape;
19 | import org.jbox2d.collision.shapes.EdgeShape;
20 | import org.jbox2d.common.Vec2;
21 | import org.jbox2d.dynamics.Body;
22 | import org.jbox2d.dynamics.BodyDef;
23 | import org.jbox2d.dynamics.BodyType;
24 | import org.jbox2d.dynamics.FixtureDef;
25 |
26 | import processing.core.*;
27 | import processing.opengl.PGraphics2D;
28 |
29 |
30 | public class box2d_VaryingRestitution extends PApplet {
31 |
32 | //
33 | // this examples shows demonstrates the behaviour of different restitution-values.
34 | //
35 | // Controls:
36 | //
37 | // LMB ... drag bodies
38 | // LMB + SHIFT ... shoot bullet
39 | // MMB ... add particles
40 | // RMB ... remove particles
41 | // 'r' ... reset
42 | // 't' ... update/pause physics
43 | // 'f' ... toggle debug draw
44 | //
45 |
46 |
47 | int viewport_w = 1280;
48 | int viewport_h = 720;
49 | int viewport_x = 230;
50 | int viewport_y = 0;
51 |
52 | boolean UPDATE_PHYSICS = true;
53 | boolean USE_DEBUG_DRAW = false;
54 |
55 | DwWorld world;
56 |
57 | public void settings(){
58 | size(viewport_w, viewport_h, P2D);
59 | smooth(8);
60 | }
61 |
62 | public void setup(){
63 | surface.setLocation(viewport_x, viewport_y);
64 | reset();
65 | frameRate(120);
66 | }
67 |
68 |
69 | public void release(){
70 | if(world != null) world.release(); world = null;
71 | }
72 |
73 |
74 | public void reset(){
75 | // release old resources
76 | release();
77 |
78 | world = new DwWorld(this, 15);
79 |
80 | // create scene: rigid bodies, particles, etc ...
81 | initScene();
82 | }
83 |
84 |
85 |
86 | public void draw(){
87 |
88 | if(UPDATE_PHYSICS){
89 | world.update();
90 | }
91 |
92 |
93 | PGraphics2D canvas = (PGraphics2D) this.g;
94 | canvas.background(32);
95 | canvas.pushMatrix();
96 | world.applyTransform(canvas);
97 | world.drawBulletSpawnTrack(canvas);
98 | if(USE_DEBUG_DRAW){
99 | world.displayDebugDraw(canvas);
100 | // DwDebugDraw.display(canvas, world);
101 | } else {
102 | world.display(canvas);
103 | }
104 | canvas.popMatrix();
105 |
106 |
107 | // info
108 | int num_bodies = world.getBodyCount();
109 | int num_particles = world.getParticleCount();
110 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
111 | surface.setTitle(txt_fps);
112 | }
113 |
114 |
115 |
116 |
117 |
118 |
119 | //////////////////////////////////////////////////////////////////////////////
120 | // User Interaction
121 | //////////////////////////////////////////////////////////////////////////////
122 | public void keyReleased(){
123 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
124 | if(key == 'r') reset();
125 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
126 | }
127 |
128 |
129 |
130 |
131 | //////////////////////////////////////////////////////////////////////////////
132 | // Scene Setup
133 | //////////////////////////////////////////////////////////////////////////////
134 |
135 |
136 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/VaryingRestitution.java
137 | public void initScene() {
138 | {
139 | BodyDef bd = new BodyDef();
140 | Body ground = world.createBody(bd);
141 |
142 | EdgeShape shape = new EdgeShape();
143 | shape.set(new Vec2(-40.0f, 5.0f), new Vec2(40.0f, 5.0f));
144 | ground.createFixture(shape, 0.0f);
145 |
146 | world.bodies.add(ground, false, color(0), true, color(200), 1f);
147 | }
148 |
149 | {
150 | CircleShape shape = new CircleShape();
151 | shape.m_radius = 0.7f;
152 |
153 | FixtureDef fd = new FixtureDef();
154 | fd.shape = shape;
155 | fd.density = 1.0f;
156 |
157 |
158 | int count = 40;
159 | for (int i = 0; i < count; ++i) {
160 | BodyDef bd = new BodyDef();
161 | bd.type = BodyType.DYNAMIC;
162 | bd.position.set(-count * 0.8f + 1.6f * i, 40.0f);
163 |
164 | Body body = world.createBody(bd);
165 |
166 | fd.restitution = i / (float)count;
167 | body.createFixture(fd);
168 |
169 | float base = 65;
170 | float col = (255 - base) * fd.restitution;
171 |
172 | world.bodies.add(body, true, color(base + col, base, base), false, color(200), 1f);
173 | }
174 | }
175 |
176 | }
177 |
178 |
179 |
180 |
181 |
182 |
183 | public static void main(String args[]) {
184 | PApplet.main(new String[] { box2d_VaryingRestitution.class.getName() });
185 | }
186 |
187 | }
--------------------------------------------------------------------------------
/examples/liquidfun_DamBreak/liquidfun_DamBreak.java:
--------------------------------------------------------------------------------
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 liquidfun_DamBreak;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.ChainShape;
19 | import org.jbox2d.collision.shapes.PolygonShape;
20 | import org.jbox2d.common.Color3f;
21 | import org.jbox2d.common.Vec2;
22 | import org.jbox2d.dynamics.Body;
23 | import org.jbox2d.dynamics.BodyDef;
24 | import org.jbox2d.particle.ParticleGroupDef;
25 | import org.jbox2d.particle.ParticleType;
26 |
27 | import processing.core.*;
28 | import processing.opengl.PGraphics2D;
29 |
30 |
31 | public class liquidfun_DamBreak extends PApplet {
32 |
33 |
34 | //
35 | // Simulation of a clash of two big particle-groups.
36 | //
37 | //
38 | // Controls:
39 | //
40 | // LMB ... drag bodies
41 | // LMB + SHIFT ... shoot bullet
42 | // MMB ... add particles
43 | // RMB ... remove particles
44 | // 'r' ... reset
45 | // 't' ... update/pause physics
46 | // 'f' ... toggle debug draw
47 | //
48 |
49 |
50 | int viewport_w = 1280;
51 | int viewport_h = 720;
52 | int viewport_x = 230;
53 | int viewport_y = 0;
54 |
55 | boolean UPDATE_PHYSICS = true;
56 | boolean USE_DEBUG_DRAW = false;
57 |
58 | DwWorld world;
59 |
60 | // PImage sprite;
61 |
62 | public void settings(){
63 | size(viewport_w, viewport_h, P2D);
64 | smooth(8);
65 | //PJOGL.profile = 3;
66 | }
67 |
68 |
69 | public void setup(){
70 | surface.setLocation(viewport_x, viewport_y);
71 | // sprite = loadImage("sprite.png");
72 |
73 |
74 | reset();
75 | frameRate(120);
76 | }
77 |
78 |
79 | public void release(){
80 | if(world != null) world.release(); world = null;
81 | }
82 |
83 |
84 | public void reset(){
85 | // release old resources
86 | release();
87 |
88 | world = new DwWorld(this, 18);
89 |
90 | // create scene: rigid bodies, particles, etc ...
91 | initScene();
92 | }
93 |
94 |
95 |
96 | public void draw(){
97 | if(UPDATE_PHYSICS){
98 | world.update();
99 | }
100 |
101 | PGraphics2D canvas = (PGraphics2D) this.g;
102 | canvas.background(32);
103 | canvas.pushMatrix();
104 | world.applyTransform(canvas);
105 | world.drawBulletSpawnTrack(canvas);
106 | if(USE_DEBUG_DRAW){
107 | world.displayDebugDraw(canvas);
108 | // DwDebugDraw.display(canvas, world);
109 | } else {
110 | world.display(canvas);
111 | }
112 | canvas.popMatrix();
113 |
114 | // info
115 | int num_bodies = world.getBodyCount();
116 | int num_particles = world.getParticleCount();
117 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
118 | surface.setTitle(txt_fps);
119 | }
120 |
121 |
122 |
123 | //////////////////////////////////////////////////////////////////////////////
124 | // User Interaction
125 | //////////////////////////////////////////////////////////////////////////////
126 | public void keyReleased(){
127 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
128 | if(key == 'r') reset();
129 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
130 | }
131 |
132 |
133 |
134 | //////////////////////////////////////////////////////////////////////////////
135 | // Scene Setup
136 | //////////////////////////////////////////////////////////////////////////////
137 |
138 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/DamBreak.java
139 | public void initScene() {
140 |
141 | float dimx = world.transform.box2d_dimx;
142 | float dimy = world.transform.box2d_dimy;
143 |
144 | float dimxh = dimx/2;
145 | float dimyh = dimy/2;
146 |
147 | {
148 | BodyDef bd = new BodyDef();
149 | Body ground = world.createBody(bd);
150 |
151 | ChainShape shape = new ChainShape();
152 | Vec2[] vertices = {new Vec2(-dimxh, 0), new Vec2(dimxh, 0), new Vec2(dimxh, dimy), new Vec2(-dimxh, dimy)};
153 | shape.createLoop(vertices, 4);
154 | ground.createFixture(shape, 0.0f);
155 |
156 | world.bodies.add(ground, false, color(0), true, color(0), 1f);
157 | }
158 |
159 |
160 |
161 | {
162 | PolygonShape shape = new PolygonShape();
163 | ParticleGroupDef pd = new ParticleGroupDef();
164 |
165 | pd.flags = 0
166 | | ParticleType.b2_waterParticle
167 | | ParticleType.b2_viscousParticle
168 | | ParticleType.b2_colorMixingParticle
169 | // | ParticleType.b2_powderParticle
170 | // | ParticleType.b2_springParticle
171 | // | ParticleType.b2_tensileParticle
172 | ;
173 |
174 | float sx = dimxh * 0.25f;
175 | float sy = dimyh * 0.95f;
176 |
177 | shape.setAsBox(sx, sy, new Vec2(-dimxh/2, dimyh), 0);
178 | pd.shape = shape;
179 | pd.setColor(new Color3f(0.00f, 0.2f, 1));
180 | world.createParticleGroup(pd);
181 |
182 | shape.setAsBox(sx, sy, new Vec2(+dimxh/2, dimyh), 0);
183 | pd.shape = shape;
184 | pd.setColor(new Color3f(1.00f, 0.2f, 0.00f));
185 | world.createParticleGroup(pd);
186 | }
187 | }
188 |
189 |
190 |
191 | public static void main(String args[]) {
192 | PApplet.main(new String[] { liquidfun_DamBreak.class.getName() });
193 | }
194 |
195 | }
--------------------------------------------------------------------------------
/examples/liquidfun_DamBreak_LiquidFx/liquidfun_DamBreak_LiquidFx.java:
--------------------------------------------------------------------------------
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 liquidfun_DamBreak_LiquidFx;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import com.thomasdiewald.pixelflow.java.DwPixelFlow;
19 | import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwLiquidFX;
20 |
21 | import org.jbox2d.collision.shapes.ChainShape;
22 | import org.jbox2d.collision.shapes.PolygonShape;
23 | import org.jbox2d.common.Color3f;
24 | import org.jbox2d.common.Vec2;
25 | import org.jbox2d.dynamics.Body;
26 | import org.jbox2d.dynamics.BodyDef;
27 | import org.jbox2d.particle.ParticleGroupDef;
28 | import org.jbox2d.particle.ParticleType;
29 |
30 | import processing.core.*;
31 | import processing.opengl.PGraphics2D;
32 |
33 |
34 | public class liquidfun_DamBreak_LiquidFx extends PApplet {
35 |
36 | //
37 | // Simulation of a clash of two big particle-groups.
38 | //
39 | // required libraries:
40 | // - PixelFlow, https://github.com/diwi/PixelFlow
41 | //
42 | //
43 | // Controls:
44 | //
45 | // LMB ... drag bodies
46 | // LMB + SHIFT ... shoot bullet
47 | // MMB ... add particles
48 | // RMB ... remove particles
49 | // 'r' ... reset
50 | // 't' ... update/pause physics
51 | // 'f' ... toggle debug draw
52 | // 'g' ... toggle DwLiquidFX
53 | //
54 |
55 | int viewport_w = 1280;
56 | int viewport_h = 720;
57 | int viewport_x = 230;
58 | int viewport_y = 0;
59 |
60 | boolean UPDATE_PHYSICS = true;
61 | boolean USE_DEBUG_DRAW = false;
62 | boolean APPLY_LIQUID_FX = true;
63 |
64 | DwWorld world;
65 |
66 | DwPixelFlow pixelflow;
67 | DwLiquidFX liquidfx;
68 |
69 | PGraphics2D pg_particles;
70 |
71 | // PImage sprite;
72 |
73 | public void settings(){
74 | size(viewport_w, viewport_h, P2D);
75 | smooth(8);
76 | }
77 |
78 |
79 | public void setup(){
80 | surface.setLocation(viewport_x, viewport_y);
81 | // sprite = loadImage("sprite.png");
82 |
83 | pixelflow = new DwPixelFlow(this);
84 | liquidfx = new DwLiquidFX(pixelflow);
85 |
86 | pg_particles = (PGraphics2D) createGraphics(width, height, P2D);
87 |
88 | reset();
89 | frameRate(120);
90 | }
91 |
92 |
93 | public void release(){
94 | if(world != null) world.release(); world = null;
95 | }
96 |
97 |
98 | public void reset(){
99 | // release old resources
100 | release();
101 |
102 | world = new DwWorld(this, 18);
103 | world.particles.param.falloff_exp1 = 3;
104 | world.particles.param.falloff_exp2 = 1;
105 | world.particles.param.radius_scale = 2;
106 |
107 | // create scene: rigid bodies, particles, etc ...
108 | initScene();
109 | }
110 |
111 |
112 |
113 | public void draw(){
114 | if(UPDATE_PHYSICS){
115 | world.update();
116 | }
117 |
118 |
119 | int BACKGROUND = 32;
120 |
121 | if(USE_DEBUG_DRAW){
122 | PGraphics2D canvas = (PGraphics2D) this.g;
123 |
124 | canvas.background(BACKGROUND);
125 | canvas.pushMatrix();
126 | world.applyTransform(canvas);
127 | world.drawBulletSpawnTrack(canvas);
128 | world.displayDebugDraw(canvas);
129 | canvas.popMatrix();
130 | } else {
131 | PGraphics2D canvas = (PGraphics2D) pg_particles;
132 |
133 | canvas.beginDraw();
134 | canvas.clear();
135 | canvas.background(BACKGROUND, 0);
136 | world.applyTransform(canvas);
137 | world.particles.display(canvas, 0);
138 | canvas.endDraw();
139 |
140 | if(APPLY_LIQUID_FX)
141 | {
142 | liquidfx.param.base_LoD = 1;
143 | liquidfx.param.base_blur_radius = 2;
144 | liquidfx.param.base_threshold = 0.7f;
145 | liquidfx.param.highlight_enabled = true;
146 | liquidfx.param.highlight_LoD = 1;
147 | liquidfx.param.highlight_decay = 0.6f;
148 | liquidfx.param.sss_enabled = true;
149 | liquidfx.param.sss_LoD = 3;
150 | liquidfx.param.sss_decay = 0.5f;
151 | liquidfx.apply(canvas);
152 | }
153 |
154 | background(BACKGROUND);
155 | image(canvas, 0, 0);
156 | pushMatrix();
157 | world.applyTransform(this.g);
158 | world.drawBulletSpawnTrack(this.g);
159 | popMatrix();
160 | }
161 |
162 |
163 |
164 |
165 | // info
166 | int num_bodies = world.getBodyCount();
167 | int num_particles = world.getParticleCount();
168 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
169 | surface.setTitle(txt_fps);
170 | }
171 |
172 |
173 |
174 | //////////////////////////////////////////////////////////////////////////////
175 | // User Interaction
176 | //////////////////////////////////////////////////////////////////////////////
177 | public void keyReleased(){
178 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
179 | if(key == 'r') reset();
180 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
181 | if(key == 'g') APPLY_LIQUID_FX = !APPLY_LIQUID_FX;
182 | }
183 |
184 |
185 |
186 | //////////////////////////////////////////////////////////////////////////////
187 | // Scene Setup
188 | //////////////////////////////////////////////////////////////////////////////
189 |
190 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/DamBreak.java
191 | public void initScene() {
192 |
193 | float dimx = world.transform.box2d_dimx;
194 | float dimy = world.transform.box2d_dimy;
195 |
196 | float dimxh = dimx/2;
197 | float dimyh = dimy/2;
198 |
199 | {
200 | BodyDef bd = new BodyDef();
201 | Body ground = world.createBody(bd);
202 |
203 | ChainShape shape = new ChainShape();
204 | Vec2[] vertices = {new Vec2(-dimxh, 0), new Vec2(dimxh, 0), new Vec2(dimxh, dimy), new Vec2(-dimxh, dimy)};
205 | shape.createLoop(vertices, 4);
206 | ground.createFixture(shape, 0.0f);
207 |
208 | world.bodies.add(ground, false, color(0), true, color(0), 1f);
209 | }
210 |
211 |
212 |
213 | {
214 | PolygonShape shape = new PolygonShape();
215 | ParticleGroupDef pd = new ParticleGroupDef();
216 |
217 | pd.flags = 0
218 | | ParticleType.b2_waterParticle
219 | | ParticleType.b2_viscousParticle
220 | | ParticleType.b2_colorMixingParticle
221 | // | ParticleType.b2_powderParticle
222 | // | ParticleType.b2_springParticle
223 | // | ParticleType.b2_tensileParticle
224 | ;
225 |
226 | float sx = dimxh * 0.25f;
227 | float sy = dimyh * 0.95f;
228 |
229 | shape.setAsBox(sx, sy, new Vec2(-dimxh/2, dimyh), 0);
230 | pd.shape = shape;
231 | pd.setColor(new Color3f(0.00f, 0.2f, 1));
232 | world.createParticleGroup(pd);
233 |
234 | shape.setAsBox(sx, sy, new Vec2(+dimxh/2, dimyh), 0);
235 | pd.shape = shape;
236 | pd.setColor(new Color3f(1.00f, 0.2f, 0.00f));
237 | world.createParticleGroup(pd);
238 | }
239 | }
240 |
241 |
242 |
243 | public static void main(String args[]) {
244 | PApplet.main(new String[] { liquidfun_DamBreak_LiquidFx.class.getName() });
245 | }
246 |
247 | }
--------------------------------------------------------------------------------
/examples/liquidfun_DamBreak_PShapeParticles/liquidfun_DamBreak_PShapeParticles.java:
--------------------------------------------------------------------------------
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 liquidfun_DamBreak_PShapeParticles;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import com.thomasdiewald.liquidfun.java.render.DwParticleRenderGL;
19 | import com.thomasdiewald.liquidfun.java.render.DwParticleRenderP5;
20 |
21 | import org.jbox2d.collision.shapes.ChainShape;
22 | import org.jbox2d.collision.shapes.PolygonShape;
23 | import org.jbox2d.common.Color3f;
24 | import org.jbox2d.common.Vec2;
25 | import org.jbox2d.dynamics.Body;
26 | import org.jbox2d.dynamics.BodyDef;
27 | import org.jbox2d.particle.ParticleGroupDef;
28 | import org.jbox2d.particle.ParticleType;
29 |
30 | import processing.core.*;
31 | import processing.opengl.PGraphics2D;
32 |
33 |
34 | public class liquidfun_DamBreak_PShapeParticles extends PApplet {
35 |
36 |
37 | //
38 | // Simulation of a clash of two big particle-groups.
39 | //
40 | //
41 | // Controls:
42 | //
43 | // LMB ... drag bodies
44 | // LMB + SHIFT ... shoot bullet
45 | // MMB ... add particles
46 | // RMB ... remove particles
47 | // 'r' ... reset
48 | // 't' ... update/pause physics
49 | // 'f' ... toggle debug draw
50 | //
51 |
52 |
53 | int viewport_w = 1280;
54 | int viewport_h = 720;
55 | int viewport_x = 230;
56 | int viewport_y = 0;
57 |
58 | boolean UPDATE_PHYSICS = true;
59 | boolean USE_DEBUG_DRAW = false;
60 |
61 | DwWorld world;
62 |
63 | // PImage sprite;
64 |
65 | public void settings(){
66 | size(viewport_w, viewport_h, P2D);
67 | smooth(8);
68 | }
69 |
70 |
71 | public void setup(){
72 | surface.setLocation(viewport_x, viewport_y);
73 | // sprite = loadImage("sprite.png");
74 |
75 |
76 | reset();
77 | frameRate(120);
78 | }
79 |
80 |
81 | public void release(){
82 | if(world != null) world.release(); world = null;
83 | }
84 |
85 |
86 | public void reset(){
87 | // release old resources
88 | release();
89 |
90 | // if false, PShape-Quads are used for particles, instead of openGL points.
91 | // this replaces the default particle renderer (OpenGL) with an alternative
92 | // renderer where particles are rendered as PShape-Quads.
93 | // It renders a bit slower then the OpenGL version and grouped rendering
94 | // is also not possible.
95 | DwWorld.INIT_GL_PARTICLES = false;
96 |
97 | // create world
98 | world = new DwWorld(this, 18);
99 |
100 | // just for checking
101 | System.out.println("PShape Particles = "+(world.particles instanceof DwParticleRenderP5));
102 | System.out.println("OpenGL Particles = "+(world.particles instanceof DwParticleRenderGL));
103 |
104 | // create scene: rigid bodies, particles, etc ...
105 | initScene();
106 | }
107 |
108 |
109 |
110 | public void draw(){
111 | if(UPDATE_PHYSICS){
112 | world.update();
113 | }
114 |
115 | PGraphics2D canvas = (PGraphics2D) this.g;
116 | canvas.background(32);
117 | canvas.pushMatrix();
118 | world.applyTransform(canvas);
119 | world.drawBulletSpawnTrack(canvas);
120 | if(USE_DEBUG_DRAW){
121 | world.displayDebugDraw(canvas);
122 | // DwDebugDraw.display(canvas, world);
123 | } else {
124 | world.display(canvas);
125 | }
126 | canvas.popMatrix();
127 |
128 | // info
129 | int num_bodies = world.getBodyCount();
130 | int num_particles = world.getParticleCount();
131 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
132 | surface.setTitle(txt_fps);
133 | }
134 |
135 |
136 |
137 | //////////////////////////////////////////////////////////////////////////////
138 | // User Interaction
139 | //////////////////////////////////////////////////////////////////////////////
140 | public void keyReleased(){
141 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
142 | if(key == 'r') reset();
143 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
144 | }
145 |
146 |
147 |
148 | //////////////////////////////////////////////////////////////////////////////
149 | // Scene Setup
150 | //////////////////////////////////////////////////////////////////////////////
151 |
152 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/DamBreak.java
153 | public void initScene() {
154 |
155 | float dimx = world.transform.box2d_dimx;
156 | float dimy = world.transform.box2d_dimy;
157 |
158 | float dimxh = dimx/2;
159 | float dimyh = dimy/2;
160 |
161 | {
162 | BodyDef bd = new BodyDef();
163 | Body ground = world.createBody(bd);
164 |
165 | ChainShape shape = new ChainShape();
166 | Vec2[] vertices = {new Vec2(-dimxh, 0), new Vec2(dimxh, 0), new Vec2(dimxh, dimy), new Vec2(-dimxh, dimy)};
167 | shape.createLoop(vertices, 4);
168 | ground.createFixture(shape, 0.0f);
169 |
170 | world.bodies.add(ground, false, color(0), true, color(0), 1f);
171 | }
172 |
173 |
174 |
175 | {
176 | PolygonShape shape = new PolygonShape();
177 | ParticleGroupDef pd = new ParticleGroupDef();
178 |
179 | pd.flags = 0
180 | | ParticleType.b2_waterParticle
181 | | ParticleType.b2_viscousParticle
182 | | ParticleType.b2_colorMixingParticle
183 | // | ParticleType.b2_powderParticle
184 | // | ParticleType.b2_springParticle
185 | // | ParticleType.b2_tensileParticle
186 | ;
187 |
188 | float sx = dimxh * 0.25f;
189 | float sy = dimyh * 0.95f;
190 |
191 | shape.setAsBox(sx, sy, new Vec2(-dimxh/2, dimyh), 0);
192 | pd.shape = shape;
193 | pd.setColor(new Color3f(0.00f, 0.2f, 1));
194 | world.createParticleGroup(pd);
195 |
196 | shape.setAsBox(sx, sy, new Vec2(+dimxh/2, dimyh), 0);
197 | pd.shape = shape;
198 | pd.setColor(new Color3f(1.00f, 0.2f, 0.00f));
199 | world.createParticleGroup(pd);
200 | }
201 | }
202 |
203 |
204 |
205 | public static void main(String args[]) {
206 | PApplet.main(new String[] { liquidfun_DamBreak_PShapeParticles.class.getName() });
207 | }
208 |
209 | }
--------------------------------------------------------------------------------
/examples/liquidfun_LiquidTimer/liquidfun_LiquidTimer.java:
--------------------------------------------------------------------------------
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 liquidfun_LiquidTimer;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.ChainShape;
19 | import org.jbox2d.collision.shapes.EdgeShape;
20 | import org.jbox2d.collision.shapes.PolygonShape;
21 | import org.jbox2d.common.Color3f;
22 | import org.jbox2d.common.Vec2;
23 | import org.jbox2d.dynamics.Body;
24 | import org.jbox2d.dynamics.BodyDef;
25 | import org.jbox2d.particle.ParticleGroupDef;
26 | import org.jbox2d.particle.ParticleType;
27 |
28 | import processing.core.*;
29 | import processing.opengl.PGraphics2D;
30 |
31 |
32 | public class liquidfun_LiquidTimer extends PApplet {
33 |
34 |
35 | //
36 | // Liquid Timer Demo
37 | //
38 | //
39 | //
40 | // Controls:
41 | //
42 | // LMB ... drag bodies
43 | // LMB + SHIFT ... shoot bullet
44 | // MMB ... add particles
45 | // RMB ... remove particles
46 | // 'r' ... reset
47 | // 't' ... update/pause physics
48 | // 'f' ... toggle debug draw
49 | //
50 |
51 |
52 | int viewport_w = 1280;
53 | int viewport_h = 720;
54 | int viewport_x = 230;
55 | int viewport_y = 0;
56 |
57 | boolean UPDATE_PHYSICS = true;
58 | boolean USE_DEBUG_DRAW = false;
59 |
60 | DwWorld world;
61 | // PImage sprite;
62 |
63 | public void settings(){
64 | size(viewport_w, viewport_h, P2D);
65 | smooth(8);
66 | }
67 |
68 |
69 | public void setup(){
70 | surface.setLocation(viewport_x, viewport_y);
71 | // sprite = loadImage("sprite.png");
72 | reset();
73 | frameRate(120);
74 | }
75 |
76 |
77 | public void release(){
78 | if(world != null) world.release(); world = null;
79 | }
80 |
81 |
82 | public void reset(){
83 | // release old resources
84 | release();
85 |
86 | world = new DwWorld(this, 18);
87 |
88 | // create scene: rigid bodies, particles, etc ...
89 | initScene();
90 | }
91 |
92 |
93 |
94 | public void draw(){
95 |
96 | if(UPDATE_PHYSICS){
97 | world.update();
98 | }
99 |
100 | PGraphics2D canvas = (PGraphics2D) this.g;
101 | canvas.background(32);
102 | canvas.pushMatrix();
103 | world.applyTransform(canvas);
104 | world.drawBulletSpawnTrack(canvas);
105 | if(USE_DEBUG_DRAW){
106 | world.displayDebugDraw(canvas);
107 | // DwDebugDraw.display(canvas, world);
108 | } else {
109 | world.display(canvas);
110 | }
111 | canvas.popMatrix();
112 |
113 | // info
114 | int num_bodies = world.getBodyCount();
115 | int num_particles = world.getParticleCount();
116 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
117 | surface.setTitle(txt_fps);
118 | }
119 |
120 |
121 |
122 | //////////////////////////////////////////////////////////////////////////////
123 | // User Interaction
124 | //////////////////////////////////////////////////////////////////////////////
125 | public void keyReleased(){
126 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
127 | if(key == 'r') reset();
128 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
129 | }
130 |
131 |
132 |
133 | //////////////////////////////////////////////////////////////////////////////
134 | // Scene Setup
135 | //////////////////////////////////////////////////////////////////////////////
136 |
137 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/LiquidTimer.java
138 | public void initScene() {
139 |
140 | {
141 | BodyDef bd = new BodyDef();
142 | Body ground = world.createBody(bd);
143 |
144 | ChainShape shape = new ChainShape();
145 | final Vec2[] vertices = {new Vec2(-20, 0), new Vec2(20, 0), new Vec2(20, 40), new Vec2(-20, 40)};
146 | shape.createLoop(vertices, 4);
147 | ground.createFixture(shape, 0.0f);
148 |
149 | world.bodies.add(ground, false, color(0), true, color(255), 1f);
150 | }
151 |
152 |
153 | {
154 | BodyDef bd = new BodyDef();
155 | Body body = world.createBody(bd);
156 | EdgeShape shape = new EdgeShape();
157 | shape.set(new Vec2(-20, 32), new Vec2(-12, 32));
158 | body.createFixture(shape, 0.1f);
159 | world.bodies.add(body, false, color(0), true, color(255), 1f);
160 | }
161 |
162 | {
163 | BodyDef bd = new BodyDef();
164 | Body body = world.createBody(bd);
165 | EdgeShape shape = new EdgeShape();
166 | shape.set(new Vec2(-11, 32), new Vec2(20, 32));
167 | body.createFixture(shape, 0.1f);
168 | world.bodies.add(body, false, color(0), true, color(255), 1f);
169 | }
170 |
171 | {
172 | BodyDef bd = new BodyDef();
173 | Body body = world.createBody(bd);
174 | EdgeShape shape = new EdgeShape();
175 | shape.set(new Vec2(-12, 32), new Vec2(-12, 28));
176 | body.createFixture(shape, 0.1f);
177 | world.bodies.add(body, false, color(0), true, color(255), 1f);
178 | }
179 |
180 | {
181 | BodyDef bd = new BodyDef();
182 | Body body = world.createBody(bd);
183 | EdgeShape shape = new EdgeShape();
184 | shape.set(new Vec2(-11, 32), new Vec2(-11, 28));
185 | body.createFixture(shape, 0.1f);
186 | world.bodies.add(body, false, color(0), true, color(255), 1f);
187 | }
188 |
189 | {
190 | BodyDef bd = new BodyDef();
191 | Body body = world.createBody(bd);
192 | EdgeShape shape = new EdgeShape();
193 | shape.set(new Vec2(-16, 24), new Vec2(8, 20));
194 | body.createFixture(shape, 0.1f);
195 | world.bodies.add(body, false, color(0), true, color(255), 1f);
196 | }
197 |
198 | {
199 | BodyDef bd = new BodyDef();
200 | Body body = world.createBody(bd);
201 | EdgeShape shape = new EdgeShape();
202 | shape.set(new Vec2(16, 16), new Vec2(-8, 12));
203 | body.createFixture(shape, 0.1f);
204 | world.bodies.add(body, false, color(0), true, color(255), 1f);
205 | }
206 |
207 | {
208 | BodyDef bd = new BodyDef();
209 | Body body = world.createBody(bd);
210 | EdgeShape shape = new EdgeShape();
211 | shape.set(new Vec2(-12, 8), new Vec2(-12, 0));
212 | body.createFixture(shape, 0.1f);
213 | world.bodies.add(body, false, color(0), true, color(255), 1f);
214 | }
215 |
216 | {
217 | BodyDef bd = new BodyDef();
218 | Body body = world.createBody(bd);
219 | EdgeShape shape = new EdgeShape();
220 | shape.set(new Vec2(-4, 8), new Vec2(-4, 0));
221 | body.createFixture(shape, 0.1f);
222 | world.bodies.add(body, false, color(0), true, color(255), 1f);
223 | }
224 |
225 | {
226 | BodyDef bd = new BodyDef();
227 | Body body = world.createBody(bd);
228 | EdgeShape shape = new EdgeShape();
229 | shape.set(new Vec2(4, 8), new Vec2(4, 0));
230 | body.createFixture(shape, 0.1f);
231 | world.bodies.add(body, false, color(0), true, color(255), 1f);
232 | }
233 |
234 | {
235 | BodyDef bd = new BodyDef();
236 | Body body = world.createBody(bd);
237 | EdgeShape shape = new EdgeShape();
238 | shape.set(new Vec2(12, 8), new Vec2(12, 0));
239 | body.createFixture(shape, 0.1f);
240 | world.bodies.add(body, false, color(0), true, color(255), 1f);
241 | }
242 |
243 | world.bodies.addAll();
244 |
245 |
246 |
247 | world.setParticleRadius(0.15f);
248 | // world.setParticleDamping(1f);
249 | {
250 | PolygonShape shape = new PolygonShape();
251 | shape.setAsBox(20, 4, new Vec2(0, 36), 0);
252 | ParticleGroupDef pd = new ParticleGroupDef();
253 | pd.flags = ParticleType.b2_waterParticle | ParticleType.b2_viscousParticle;
254 | // pd.flags = ParticleType.b2_tensileParticle | ParticleType.b2_viscousParticle;
255 | pd.shape = shape;
256 | pd.setColor(new Color3f(1, 0.2f, 0.05f));
257 | world.createParticleGroup(pd);
258 | }
259 |
260 | }
261 |
262 |
263 |
264 | public static void main(String args[]) {
265 | PApplet.main(new String[] { liquidfun_LiquidTimer.class.getName() });
266 | }
267 |
268 | }
--------------------------------------------------------------------------------
/examples/liquidfun_WaveMachine/liquidfun_WaveMachine.java:
--------------------------------------------------------------------------------
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 liquidfun_WaveMachine;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import org.jbox2d.collision.shapes.PolygonShape;
19 | import org.jbox2d.common.Color3f;
20 | import org.jbox2d.common.MathUtils;
21 | import org.jbox2d.common.Vec2;
22 | import org.jbox2d.dynamics.Body;
23 | import org.jbox2d.dynamics.BodyDef;
24 | import org.jbox2d.dynamics.BodyType;
25 | import org.jbox2d.dynamics.joints.RevoluteJoint;
26 | import org.jbox2d.dynamics.joints.RevoluteJointDef;
27 | import org.jbox2d.particle.ParticleGroupDef;
28 | import org.jbox2d.particle.ParticleType;
29 |
30 | import processing.core.*;
31 | import processing.opengl.PGraphics2D;
32 |
33 |
34 | public class liquidfun_WaveMachine extends PApplet {
35 |
36 | //
37 | // Wave Machine Example.
38 | //
39 | //
40 | // Controls:
41 | //
42 | // LMB ... drag bodies
43 | // LMB + SHIFT ... shoot bullet
44 | // MMB ... add particles
45 | // RMB ... remove particles
46 | // 'r' ... reset
47 | // 't' ... update/pause physics
48 | // 'f' ... toggle debug draw
49 | //
50 |
51 |
52 | int viewport_w = 1280;
53 | int viewport_h = 720;
54 | int viewport_x = 230;
55 | int viewport_y = 0;
56 |
57 | boolean UPDATE_PHYSICS = true;
58 | boolean USE_DEBUG_DRAW = false;
59 |
60 | DwWorld world;
61 | // PImage sprite;
62 |
63 | public void settings(){
64 | size(viewport_w, viewport_h, P2D);
65 | smooth(8);
66 | }
67 |
68 |
69 | public void setup(){
70 | surface.setLocation(viewport_x, viewport_y);
71 | // sprite = loadImage("sprite.png");
72 | reset();
73 | frameRate(120);
74 | }
75 |
76 |
77 | public void release(){
78 | if(world != null) world.release(); world = null;
79 | }
80 |
81 |
82 | public void reset(){
83 | // release old resources
84 | release();
85 |
86 | world = new DwWorld(this, 20);
87 | world.transform.setScreen(width, height, 20, width/2, height/2);
88 |
89 | // create scene: rigid bodies, particles, etc ...
90 | initScene();
91 | }
92 |
93 |
94 |
95 | public void draw(){
96 |
97 | if(UPDATE_PHYSICS){
98 | wave();
99 | world.update();
100 | }
101 |
102 | PGraphics2D canvas = (PGraphics2D) this.g;
103 | canvas.background(32);
104 | canvas.pushMatrix();
105 | world.applyTransform(canvas);
106 | world.drawBulletSpawnTrack(canvas);
107 | if(USE_DEBUG_DRAW){
108 | world.displayDebugDraw(canvas);
109 | // DwDebugDraw.display(canvas, world);
110 | } else {
111 | world.display(canvas);
112 | }
113 | canvas.popMatrix();
114 |
115 | // info
116 | int num_bodies = world.getBodyCount();
117 | int num_particles = world.getParticleCount();
118 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
119 | surface.setTitle(txt_fps);
120 | }
121 |
122 |
123 |
124 | //////////////////////////////////////////////////////////////////////////////
125 | // User Interaction
126 | //////////////////////////////////////////////////////////////////////////////
127 | public void keyReleased(){
128 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
129 | if(key == 'r') reset();
130 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
131 | }
132 |
133 |
134 |
135 | //////////////////////////////////////////////////////////////////////////////
136 | // Scene Setup
137 | //////////////////////////////////////////////////////////////////////////////
138 |
139 | RevoluteJoint m_joint;
140 | float m_time;
141 |
142 |
143 | public void wave() {
144 | m_time += 1 / 120f;
145 | m_joint.setMotorSpeed(0.1f * MathUtils.cos(m_time) * MathUtils.PI);
146 | }
147 |
148 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/WaveMachine.java
149 | public void initScene() {
150 |
151 | {
152 | BodyDef bd = new BodyDef();
153 | Body ground = world.createBody(bd);
154 |
155 | bd.type = BodyType.DYNAMIC;
156 | bd.allowSleep = false;
157 | bd.position.set(0.0f, 0.0f);
158 | Body body = world.createBody(bd);
159 |
160 | PolygonShape shape = new PolygonShape();
161 | shape.setAsBox(1, 9.5f, new Vec2(19.0f, 0.0f), 0.0f);
162 | body.createFixture(shape, 5.0f);
163 | shape.setAsBox(1, 9.5f, new Vec2(-19.0f, 0.0f), 0.0f);
164 | body.createFixture(shape, 5.0f);
165 | shape.setAsBox(20.0f, 1, new Vec2(0.0f, 11.0f), 0.0f);
166 | body.createFixture(shape, 5.0f);
167 | shape.setAsBox(20.0f, 1, new Vec2(0.0f, -11.0f), 0.0f);
168 | body.createFixture(shape, 5.0f);
169 |
170 | world.bodies.add(body, true, color(0), true, color(0), 1f);
171 |
172 | RevoluteJointDef jd = new RevoluteJointDef();
173 | jd.bodyA = ground;
174 | jd.bodyB = body;
175 | jd.localAnchorA.set(0.0f, 0.0f);
176 | jd.localAnchorB.set(0.0f, 0.0f);
177 | jd.referenceAngle = 0.0f;
178 | jd.motorSpeed = 0.05f * MathUtils.PI;
179 | jd.maxMotorTorque = 1e7f;
180 | jd.enableMotor = true;
181 | m_joint = (RevoluteJoint) world.createJoint(jd);
182 | }
183 |
184 | world.bodies.addAll();
185 |
186 |
187 |
188 | world.setParticleRadius(0.15f);
189 | world.setParticleDamping(0.6f);
190 |
191 | {
192 | ParticleGroupDef pd = new ParticleGroupDef();
193 | pd.flags = ParticleType.b2_waterParticle | ParticleType.b2_viscousParticle;
194 | pd.setColor(new Color3f(1, 0.15f, 0.05f));
195 | PolygonShape shape = new PolygonShape();
196 | shape.setAsBox(17.0f, 9.0f, new Vec2(0.0f, 0.0f), 0.0f);
197 |
198 | pd.shape = shape;
199 | world.createParticleGroup(pd);
200 | }
201 |
202 | m_time = 0;
203 |
204 | }
205 |
206 |
207 |
208 |
209 |
210 | public static void main(String args[]) {
211 | PApplet.main(new String[] { liquidfun_WaveMachine.class.getName() });
212 | }
213 |
214 | }
--------------------------------------------------------------------------------
/examples/liquidfun_WaveMachine_LiquidFx/liquidfun_WaveMachine_LiquidFx.java:
--------------------------------------------------------------------------------
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 liquidfun_WaveMachine_LiquidFx;
15 |
16 |
17 | import com.thomasdiewald.liquidfun.java.DwWorld;
18 | import com.thomasdiewald.pixelflow.java.DwPixelFlow;
19 | import com.thomasdiewald.pixelflow.java.imageprocessing.filter.DwLiquidFX;
20 |
21 | import org.jbox2d.collision.shapes.PolygonShape;
22 | import org.jbox2d.common.Color3f;
23 | import org.jbox2d.common.MathUtils;
24 | import org.jbox2d.common.Vec2;
25 | import org.jbox2d.dynamics.Body;
26 | import org.jbox2d.dynamics.BodyDef;
27 | import org.jbox2d.dynamics.BodyType;
28 | import org.jbox2d.dynamics.joints.RevoluteJoint;
29 | import org.jbox2d.dynamics.joints.RevoluteJointDef;
30 | import org.jbox2d.particle.ParticleGroupDef;
31 | import org.jbox2d.particle.ParticleType;
32 |
33 | import processing.core.*;
34 | import processing.opengl.PGraphics2D;
35 |
36 |
37 | public class liquidfun_WaveMachine_LiquidFx extends PApplet {
38 |
39 | //
40 | // Wave Machine Example.
41 | //
42 | // required libraries:
43 | // - PixelFlow, https://github.com/diwi/PixelFlow
44 | //
45 | //
46 | // Controls:
47 | //
48 | // LMB ... drag bodies
49 | // LMB + SHIFT ... shoot bullet
50 | // MMB ... add particles
51 | // RMB ... remove particles
52 | // 'r' ... reset
53 | // 't' ... update/pause physics
54 | // 'f' ... toggle debug draw
55 | // 'g' ... toggle DwLiquidFX
56 | //
57 |
58 |
59 | int viewport_w = 1280;
60 | int viewport_h = 720;
61 | int viewport_x = 230;
62 | int viewport_y = 0;
63 |
64 | boolean UPDATE_PHYSICS = true;
65 | boolean USE_DEBUG_DRAW = false;
66 | boolean APPLY_LIQUID_FX = true;
67 |
68 | DwWorld world;
69 | // PImage sprite;
70 |
71 | DwPixelFlow pixelflow;
72 | DwLiquidFX liquidfx;
73 |
74 | PGraphics2D pg_particles;
75 |
76 | public void settings(){
77 | size(viewport_w, viewport_h, P2D);
78 | smooth(8);
79 | }
80 |
81 |
82 | public void setup(){
83 | surface.setLocation(viewport_x, viewport_y);
84 | // sprite = loadImage("sprite.png");
85 |
86 | pixelflow = new DwPixelFlow(this);
87 | liquidfx = new DwLiquidFX(pixelflow);
88 |
89 | pg_particles = (PGraphics2D) createGraphics(width, height, P2D);
90 |
91 |
92 | reset();
93 | frameRate(120);
94 | }
95 |
96 |
97 | public void release(){
98 | if(world != null) world.release(); world = null;
99 | }
100 |
101 |
102 | public void reset(){
103 | // release old resources
104 | release();
105 |
106 | world = new DwWorld(this, 20);
107 | world.transform.setScreen(width, height, 20, width/2, height/2);
108 |
109 | // world.particles.param.falloff_exp1 = 2;
110 | // world.particles.param.falloff_exp2 = 2;
111 | // world.particles.param.radius_scale = 3;
112 |
113 | world.particles.param.falloff_exp1 = 3;
114 | world.particles.param.falloff_exp2 = 1;
115 | world.particles.param.radius_scale = 2;
116 |
117 | // create scene: rigid bodies, particles, etc ...
118 | initScene();
119 | }
120 |
121 |
122 |
123 | public void draw(){
124 |
125 | if(UPDATE_PHYSICS){
126 | wave();
127 | world.update();
128 | }
129 |
130 | int BACKGROUND = 32;
131 |
132 | if(USE_DEBUG_DRAW){
133 | PGraphics2D canvas = (PGraphics2D) this.g;
134 |
135 | canvas.background(BACKGROUND);
136 | canvas.pushMatrix();
137 | world.applyTransform(canvas);
138 | world.drawBulletSpawnTrack(canvas);
139 | world.displayDebugDraw(canvas);
140 | canvas.popMatrix();
141 | } else {
142 | PGraphics2D canvas = (PGraphics2D) pg_particles;
143 |
144 | canvas.beginDraw();
145 | canvas.clear();
146 | canvas.background(BACKGROUND, 0);
147 | world.applyTransform(canvas);
148 | world.particles.display(canvas, 0);
149 | canvas.endDraw();
150 |
151 | if(APPLY_LIQUID_FX)
152 | {
153 | liquidfx.param.base_LoD = 1;
154 | liquidfx.param.base_blur_radius = 2;
155 | liquidfx.param.base_threshold = 0.7f;
156 | liquidfx.param.highlight_enabled = true;
157 | liquidfx.param.highlight_LoD = 1;
158 | liquidfx.param.highlight_decay = 0.6f;
159 | liquidfx.param.sss_enabled = true;
160 | liquidfx.param.sss_LoD = 3;
161 | liquidfx.param.sss_decay = 0.5f;
162 | liquidfx.apply(canvas);
163 | }
164 |
165 | background(BACKGROUND);
166 | image(canvas, 0, 0);
167 | pushMatrix();
168 | world.applyTransform(this.g);
169 | world.bodies.display((PGraphics2D) this.g);
170 | world.drawBulletSpawnTrack(this.g);
171 | popMatrix();
172 | }
173 |
174 | // info
175 | int num_bodies = world.getBodyCount();
176 | int num_particles = world.getParticleCount();
177 | String txt_fps = String.format(getClass().getName()+ " [bodies: %d] [particles: %d] [fps %6.2f]", num_bodies, num_particles, frameRate);
178 | surface.setTitle(txt_fps);
179 | }
180 |
181 |
182 |
183 | //////////////////////////////////////////////////////////////////////////////
184 | // User Interaction
185 | //////////////////////////////////////////////////////////////////////////////
186 | public void keyReleased(){
187 | if(key == 't') UPDATE_PHYSICS = !UPDATE_PHYSICS;
188 | if(key == 'r') reset();
189 | if(key == 'f') USE_DEBUG_DRAW = !USE_DEBUG_DRAW;
190 | if(key == 'g') APPLY_LIQUID_FX = !APPLY_LIQUID_FX;
191 | }
192 |
193 |
194 |
195 | //////////////////////////////////////////////////////////////////////////////
196 | // Scene Setup
197 | //////////////////////////////////////////////////////////////////////////////
198 |
199 | RevoluteJoint m_joint;
200 | float m_time;
201 |
202 |
203 | public void wave() {
204 | m_time += 1 / 120f;
205 | m_joint.setMotorSpeed(0.1f * MathUtils.cos(m_time) * MathUtils.PI);
206 | }
207 |
208 | // https://github.com/jbox2d/jbox2d/blob/master/jbox2d-testbed/src/main/java/org/jbox2d/testbed/tests/WaveMachine.java
209 | public void initScene() {
210 |
211 | {
212 | BodyDef bd = new BodyDef();
213 | Body ground = world.createBody(bd);
214 |
215 | bd.type = BodyType.DYNAMIC;
216 | bd.allowSleep = false;
217 | bd.position.set(0.0f, 0.0f);
218 | Body body = world.createBody(bd);
219 |
220 | PolygonShape shape = new PolygonShape();
221 | shape.setAsBox(1, 9.5f, new Vec2(19.0f, 0.0f), 0.0f);
222 | body.createFixture(shape, 5.0f);
223 | shape.setAsBox(1, 9.5f, new Vec2(-19.0f, 0.0f), 0.0f);
224 | body.createFixture(shape, 5.0f);
225 | shape.setAsBox(20.0f, 1, new Vec2(0.0f, 11.0f), 0.0f);
226 | body.createFixture(shape, 5.0f);
227 | shape.setAsBox(20.0f, 1, new Vec2(0.0f, -11.0f), 0.0f);
228 | body.createFixture(shape, 5.0f);
229 |
230 | world.bodies.add(body, true, color(0), true, color(0), 1f);
231 |
232 | RevoluteJointDef jd = new RevoluteJointDef();
233 | jd.bodyA = ground;
234 | jd.bodyB = body;
235 | jd.localAnchorA.set(0.0f, 0.0f);
236 | jd.localAnchorB.set(0.0f, 0.0f);
237 | jd.referenceAngle = 0.0f;
238 | jd.motorSpeed = 0.05f * MathUtils.PI;
239 | jd.maxMotorTorque = 1e7f;
240 | jd.enableMotor = true;
241 | m_joint = (RevoluteJoint) world.createJoint(jd);
242 | }
243 |
244 | world.bodies.addAll();
245 |
246 |
247 |
248 | world.setParticleRadius(0.15f);
249 | world.setParticleDamping(0.6f);
250 |
251 | {
252 | ParticleGroupDef pd = new ParticleGroupDef();
253 | pd.flags = ParticleType.b2_waterParticle | ParticleType.b2_viscousParticle;
254 | // pd.setColor(new Color3f(1, 0.10f, 0.01f));
255 | // pd.setColor(new Color3f(0.05f, 0.15f, 1));
256 | pd.setColor(new Color3f(0.15f, 1, 0.05f));
257 | PolygonShape shape = new PolygonShape();
258 | shape.setAsBox(17.0f, 9.0f, new Vec2(0.0f, 0.0f), 0.0f);
259 |
260 | pd.shape = shape;
261 | world.createParticleGroup(pd);
262 | }
263 |
264 | m_time = 0;
265 |
266 | }
267 |
268 |
269 |
270 |
271 |
272 | public static void main(String args[]) {
273 | PApplet.main(new String[] { liquidfun_WaveMachine_LiquidFx.class.getName() });
274 | }
275 |
276 | }
--------------------------------------------------------------------------------
/screenshots/LiquidFunProcessing_DebugDraw1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/LiquidFunProcessing_DebugDraw1.png
--------------------------------------------------------------------------------
/screenshots/LiquidFunProcessing_Draw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/LiquidFunProcessing_Draw.png
--------------------------------------------------------------------------------
/screenshots/LiquidFunProcessing_Orange.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/LiquidFunProcessing_Orange.png
--------------------------------------------------------------------------------
/screenshots/LiquidFunProcessing_Timer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/LiquidFunProcessing_Timer.png
--------------------------------------------------------------------------------
/screenshots/LiquidFunProcessing_Wavemaschine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/LiquidFunProcessing_Wavemaschine.png
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_BalancedTree.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_BalancedTree.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_BlobJoints.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_BlobJoints.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_Chains.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_Chains.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_CircleStress.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_CircleStress.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_Collisions.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_Collisions.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_DamBreak.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_DamBreak.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_DominoPyramid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_DominoPyramid.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_Dominos.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_Dominos.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_Examples1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_Examples1.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_Examples2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_Examples2.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_ParticleDrawing.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_ParticleDrawing.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_ParticleDrawing1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_ParticleDrawing1.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_ParticleEmitter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_ParticleEmitter.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_ParticleRenderGroup.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_ParticleRenderGroup.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_ParticleTypes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_ParticleTypes.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_PistonStress.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_PistonStress.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_Rain.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_Rain.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_Tumbler.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_Tumbler.jpg
--------------------------------------------------------------------------------
/screenshots/examples/diewald_LiquidFunProcessing_WaveMachine.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/examples/diewald_LiquidFunProcessing_WaveMachine.jpg
--------------------------------------------------------------------------------
/screenshots/rendermodes/diewald_LiquidFunProcessing_RenderDebug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/rendermodes/diewald_LiquidFunProcessing_RenderDebug.jpg
--------------------------------------------------------------------------------
/screenshots/rendermodes/diewald_LiquidFunProcessing_RenderLiquidFx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/rendermodes/diewald_LiquidFunProcessing_RenderLiquidFx.jpg
--------------------------------------------------------------------------------
/screenshots/rendermodes/diewald_LiquidFunProcessing_RenderRaw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diwi/LiquidFunProcessing/9f6560320f2616c243afffd0e61bc7d243908280/screenshots/rendermodes/diewald_LiquidFunProcessing_RenderRaw.jpg
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/glsl/particle_render.frag:
--------------------------------------------------------------------------------
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 | #version 150
15 |
16 | out vec4 fragColor;
17 | in vec4 var_col;
18 |
19 | uniform sampler2D tex_sprite;
20 | uniform float falloff_exp1 = 1.0;
21 | uniform float falloff_exp2 = 1.0;
22 | uniform float falloff_mult = 1.0;
23 | uniform float color_mult = 1.0;
24 |
25 | uniform float use_sprite = 0.0;
26 |
27 | void main() {
28 |
29 | fragColor = var_col * color_mult;
30 |
31 | if(use_sprite == 1.0){
32 | fragColor *= texture(tex_sprite, gl_PointCoord);
33 | } else {
34 | vec2 pcoord_norm = abs(gl_PointCoord * 2.0 - 1.0); // abs[-1, 1]
35 |
36 | float falloff = clamp(length(pcoord_norm), 0.0, 1.0);
37 | falloff = pow(falloff, falloff_exp1);
38 | falloff = 1.0 - falloff;
39 | falloff = pow(falloff, falloff_exp2);
40 |
41 | fragColor.a *= falloff * falloff_mult;
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/glsl/particle_render.vert:
--------------------------------------------------------------------------------
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 | #version 150
15 |
16 | uniform mat4 mat_mvp;
17 | uniform float point_size;
18 |
19 | in vec2 pos; // position
20 | in vec2 vel; // velocity
21 | in vec4 col; // color
22 | in vec2 con; // contact [weight, count]
23 |
24 | out vec4 var_col;
25 |
26 | void main() {
27 | gl_Position = mat_mvp * vec4(pos, 0, 1);
28 | //gl_PointSize = point_size;
29 |
30 | var_col = col;
31 |
32 | // float vel_mag = clamp(length(vel) * 0.8, 0.5, 1.5);
33 | // var_col.rgb *= vel_mag;
34 |
35 |
36 | // float con_mult = clamp(con.x * 0.8, 0.5, 1.5);
37 | // var_col.rgb *= con_mult;
38 |
39 |
40 | float vel_mag = length(vel) / 100.0f;
41 | float con_mult = con.x / 50.0f;
42 |
43 | float sum = 1.0 + (con_mult + vel_mag);
44 | sum *= sum;
45 | sum *= sum;
46 | sum *= sum;
47 | //sum = pow(sum, 10);
48 |
49 |
50 | var_col.rgb *= sum;
51 |
52 | // if(sum > 1.2){
53 | // var_col.rgb = vec3(1.0);
54 | // }
55 |
56 | }
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/glsl/particle_render2.frag:
--------------------------------------------------------------------------------
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 | #version 150
15 |
16 | out vec4 fragColor;
17 | in vec4 tint;
18 |
19 | uniform sampler2D tex_sprite;
20 |
21 | void main() {
22 | fragColor = texture(tex_sprite, gl_PointCoord) * tint;
23 | }
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/glsl/particle_render2.vert:
--------------------------------------------------------------------------------
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 | #version 150
15 |
16 | uniform mat4 mat_mvp;
17 |
18 | in vec2 pos;
19 | in vec4 col;
20 |
21 | out vec4 tint;
22 |
23 | void main() {
24 | gl_Position = mat_mvp * vec4(pos, 0, 1);
25 | tint = col;
26 | }
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/java/DwParticleEmitter.java:
--------------------------------------------------------------------------------
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 com.thomasdiewald.liquidfun.java;
15 |
16 | import org.jbox2d.common.Vec2;
17 | import org.jbox2d.dynamics.World;
18 | import org.jbox2d.particle.ParticleDef;
19 |
20 |
21 | /**
22 | *
23 | * Custom Particle Emitter.
24 | *
25 | * @author Thomas Diewald
26 | *
27 | */
28 | public class DwParticleEmitter {
29 |
30 | public World world;
31 | public DwViewportTransform transform;
32 | public ParticleDef pdef = new ParticleDef();
33 |
34 | public float emit_dir = (float) (Math.PI * 0.5f);
35 | public float emit_vel = 20;
36 | public Vec2 emit_pos = new Vec2();
37 |
38 | public float emit_dir_jitter = 0.2f; // [0, PI*2]
39 | public float emit_vel_jitter = 0.5f; // noise mult
40 | public float emit_pos_jitter = 0.4f; // spawn radius, world-space
41 |
42 |
43 | protected int counter = 0;
44 |
45 | public DwParticleEmitter(World world, DwViewportTransform transform){
46 | this.world = world;
47 | this.transform = transform;
48 | }
49 |
50 |
51 | /**
52 | * inline Emitter-definition.
53 | * Velocity and Position must be defined in screen-space dimensions.
54 | */
55 | public void setInScreen(float pos_x, float pos_y, float vel, float dir_deg, int col_argb, int flags){
56 | emit_pos = transform.getScreen2box(pos_x, pos_y, emit_pos);
57 | emit_vel = vel / transform.screen_scale;
58 | emit_dir = dir_deg * DwUtils.TO_RAD;
59 | pdef.color.set(col_argb);
60 | pdef.flags = flags;
61 | }
62 |
63 | /**
64 | * inline Emitter-definition.
65 | * Velocity and Position must be defined in world-space dimensions.
66 | */
67 | public void setInWorld(float pos_x, float pos_y, float vel, float dir_deg, int col_argb, int flags){
68 | emit_pos.set(pos_x, pos_y);
69 | emit_vel = vel;
70 | emit_dir = dir_deg * DwUtils.TO_RAD;
71 | pdef.color.set(col_argb);
72 | pdef.flags = flags;
73 | }
74 |
75 |
76 |
77 |
78 |
79 | public void emitParticles(int count){
80 | for(int i = 0; i < count; i++){
81 | emitParticle();
82 | }
83 | }
84 |
85 | public void emitParticle(){
86 |
87 | // velocity (noise)
88 | float val1 = (float) (Math.sin(counter / 10f)) * 0.2f;
89 | float val2 = (float) (Math.cos(counter / 100f));
90 | float srandnoise = val1 * val2;
91 |
92 | float rot_angle = emit_dir + srandnoise * emit_dir_jitter;
93 | float vel_mag = emit_vel + srandnoise * emit_vel_jitter;
94 |
95 | float vel_x = (float) (Math.cos(rot_angle) * vel_mag);
96 | float vel_y = (float) (Math.sin(rot_angle) * vel_mag);
97 |
98 | // position
99 | float[] jitter = DwUtils.sampleDisk_Halton(counter, 0.5f);
100 |
101 | float pos_x = emit_pos.x + jitter[0] * emit_pos_jitter;
102 | float pos_y = emit_pos.y + jitter[1] * emit_pos_jitter;
103 |
104 | // create Particle
105 | pdef.position.set(pos_x, pos_y);
106 | pdef.velocity.set(vel_x, vel_y);
107 | world.createParticle(pdef);
108 |
109 | counter++;
110 | }
111 |
112 |
113 | }
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/java/DwViewportTransform.java:
--------------------------------------------------------------------------------
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 | package com.thomasdiewald.liquidfun.java;
14 |
15 | import org.jbox2d.common.IViewportTransform;
16 | import org.jbox2d.common.Mat22;
17 | import org.jbox2d.common.Vec2;
18 |
19 | import processing.core.PApplet;
20 | import processing.core.PGraphics;
21 | import processing.core.PMatrix2D;
22 |
23 | /**
24 | *
25 | *
26 | * Coordinate transformation box2d-world <-> screen
27 | *
28 | * @author Thomas Diewald
29 | *
30 | */
31 | public class DwViewportTransform implements IViewportTransform {
32 |
33 | // flip vertically
34 | protected boolean flip_y = true;
35 |
36 | // box2d stuff
37 | public final Mat22 mat_world_to_screen = new Mat22(1,0,0,1); // identity
38 | public final Mat22 mat_screen_to_world = new Mat22(1,0,0,1); // identity
39 | public final Vec2 center = new Vec2();
40 | public final Vec2 extents = new Vec2();
41 |
42 |
43 | // processing stuff, but more or less the same as above
44 | public final PMatrix2D mat_box2screen = new PMatrix2D();
45 | public final PMatrix2D mat_screen2box = new PMatrix2D();
46 |
47 | public float screen_scale = 15;
48 | public float screen_dimx;
49 | public float screen_dimy;
50 | public float box2d_dimx;
51 | public float box2d_dimy;
52 |
53 |
54 | public DwViewportTransform() {
55 | }
56 |
57 | public DwViewportTransform(PApplet papplet) {
58 | this(papplet.g);
59 | }
60 |
61 | public DwViewportTransform(PGraphics pg) {
62 | float w = pg.width;
63 | float h = pg.height;
64 | float s = screen_scale;
65 | setScreen(w, h, s, w/2, h);
66 | }
67 |
68 | public DwViewportTransform(float screen_w, int screen_h) {
69 | float w = screen_w;
70 | float h = screen_h;
71 | float s = screen_scale;
72 | setScreen(w, h, s, w/2, h);
73 | }
74 |
75 |
76 | public DwViewportTransform(DwViewportTransform vpt) {
77 | flip_y = vpt.flip_y;
78 | setExtents(vpt.extents);
79 | setCamera(vpt.center.x, vpt.center.y, vpt.screen_scale);
80 | }
81 |
82 |
83 | public DwViewportTransform setSceneScale(float scale){
84 | screen_scale = scale;
85 | updateMatrix();
86 | return this;
87 | }
88 |
89 |
90 | public DwViewportTransform setScreen(float dim_x, float dim_y, float scale, float origin_x, float origin_y){
91 |
92 | float dim_xh = dim_x / 2;
93 | float dim_yh = dim_y / 2;
94 |
95 | float cam_x = (origin_x - dim_xh) / scale;
96 | float cam_y = (origin_y - dim_yh) / scale;
97 |
98 | setExtents(dim_xh, dim_yh);
99 | setCamera(cam_x, cam_y, scale);
100 | return this;
101 | }
102 |
103 |
104 | public void setCamera(float x, float y) {
105 | center.set(x, y);
106 | updateMatrix();
107 | }
108 |
109 |
110 |
111 | /**
112 | * set origin, in world
113 | */
114 | @Override
115 | public void setCamera(float x, float y, float scale) {
116 | screen_scale = scale;
117 | center.set(x, y);
118 | updateMatrix();
119 | }
120 |
121 | @Override
122 | public Vec2 getExtents() {
123 | return extents;
124 | }
125 |
126 | /**
127 | * set origin, in screen coords
128 | */
129 | @Override
130 | public void setExtents(Vec2 argExtents) {
131 | setExtents(argExtents.x, argExtents.y);
132 | updateMatrix();
133 | }
134 |
135 | /**
136 | * set origin, in screen coords
137 | */
138 | @Override
139 | public void setExtents(float halfWidth, float halfHeight) {
140 | extents.set(halfWidth, halfHeight);
141 | }
142 |
143 | @Override
144 | public Vec2 getCenter() {
145 | return center;
146 | }
147 |
148 | @Override
149 | public void setCenter(Vec2 argPos) {
150 | center.set(argPos);
151 | }
152 |
153 | @Override
154 | public void setCenter(float x, float y) {
155 | center.set(x, y);
156 | }
157 |
158 | @Override
159 | public boolean isYFlip() {
160 | return flip_y;
161 | }
162 |
163 | @Override
164 | public void setYFlip(boolean yFlip) {
165 | this.flip_y = yFlip;
166 | }
167 |
168 | @Override
169 | public Mat22 getMat22Representation() {
170 | return mat_world_to_screen;
171 | }
172 |
173 | @Override
174 | public void mulByTransform(Mat22 transform) {
175 | // mat.mulLocal(transform);
176 | System.out.println("DwViewportTransform.mulByTransform is not implemented");
177 | }
178 |
179 |
180 |
181 |
182 |
183 |
184 | protected void updateMatrix(){
185 |
186 | // Box2d Matrix:
187 |
188 | // matrix: box2d -> screen
189 | mat_world_to_screen.ex.x = screen_scale;
190 | mat_world_to_screen.ex.y = 0;
191 | mat_world_to_screen.ey.x = 0;
192 | mat_world_to_screen.ey.y = flip_y ? -screen_scale : screen_scale;
193 |
194 | // matrix: screen -> box2d
195 | mat_world_to_screen.invertToOut(mat_screen_to_world);
196 |
197 |
198 | // Processing matrix:
199 |
200 | // matrix: box2d -> screen
201 | mat_box2screen.reset();
202 | mat_box2screen.translate(extents.x, extents.y);
203 | mat_box2screen.scale(screen_scale, flip_y ? -screen_scale : screen_scale);
204 | mat_box2screen.translate(-center.x, -center.y);
205 |
206 | // matrix: screen -> box2d
207 | mat_screen2box.set(mat_box2screen);
208 | mat_screen2box.invert();
209 |
210 |
211 | // screen size
212 | screen_dimx = extents.x * 2;
213 | screen_dimy = extents.y * 2;
214 |
215 | // screen size in box world dimensions
216 | box2d_dimx = screen_dimx / screen_scale;
217 | box2d_dimy = screen_dimy / screen_scale;
218 |
219 | }
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 | @Override
233 | public void getWorldVectorToScreen(Vec2 world, Vec2 screen) {
234 | mat_world_to_screen.mulToOut(world, screen);
235 | }
236 |
237 | @Override
238 | public void getScreenVectorToWorld(Vec2 screen, Vec2 world) {
239 | mat_screen_to_world.mulToOut(screen, world);
240 | }
241 |
242 | @Override
243 | public void getWorldToScreen(Vec2 world, Vec2 screen) {
244 | screen.x = world.x - center.x;
245 | screen.y = world.y - center.y;
246 | mat_world_to_screen.mulToOut(screen, screen);
247 | screen.x += extents.x;
248 | screen.y += extents.y;
249 | }
250 |
251 | @Override
252 | public void getScreenToWorld(Vec2 screen, Vec2 world) {
253 | world.x = screen.x - extents.x;
254 | world.y = screen.y - extents.y;
255 | mat_screen_to_world.mulToOut(world, world);
256 | world.x += center.x;
257 | world.y += center.y;
258 | }
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 | // just some buffers
269 | protected float[] xy1 = new float[2];
270 | protected float[] xy2 = new float[2];
271 |
272 |
273 | public Vec2 getBox2screen(float in_box_x, float in_box_y, Vec2 out_screen){
274 | xy1[0] = in_box_x;
275 | xy1[1] = in_box_y;
276 | mat_box2screen.mult(xy1, xy2);
277 | if(out_screen == null){
278 | return new Vec2(xy2[0], xy2[1]);
279 | }
280 | return out_screen.set(xy2[0], xy2[1]);
281 | }
282 |
283 | public float[] getBox2screen(float in_box_x, float in_box_y, float[] out_screen){
284 | xy1[0] = in_box_x;
285 | xy1[1] = in_box_y;
286 | if(out_screen == null){
287 | out_screen = new float[2];
288 | }
289 | mat_box2screen.mult(xy1, out_screen);
290 | return out_screen;
291 | }
292 |
293 |
294 | public Vec2 getScreen2box(float in_screen_x, float in_screen_y, Vec2 out_box){
295 | xy1[0] = in_screen_x;
296 | xy1[1] = in_screen_y;
297 | mat_screen2box.mult(xy1, xy2);
298 | if(out_box == null){
299 | return new Vec2(xy2[0], xy2[1]);
300 | }
301 | return out_box.set(xy2[0], xy2[1]);
302 | }
303 |
304 |
305 | public float[] getScreen2box(float in_screen_x, float in_screen_y, float[] out_box){
306 | xy1[0] = in_screen_x;
307 | xy1[1] = in_screen_y;
308 | if(out_box == null){
309 | out_box = new float[2];
310 | }
311 | mat_screen2box.mult(xy1, out_box);
312 | return out_box;
313 | }
314 |
315 |
316 |
317 | }
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/java/interaction/DwInteractionEvent.java:
--------------------------------------------------------------------------------
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 | package com.thomasdiewald.liquidfun.java.interaction;
13 |
14 | import processing.event.KeyEvent;
15 | import processing.event.MouseEvent;
16 |
17 |
18 | /**
19 | * Interface for mouse interactions, mainly used by DwWorld to have some
20 | * default interaction handlers.
21 | *
22 | * @author Thomas Diewald
23 | *
24 | */
25 | public interface DwInteractionEvent {
26 |
27 | public void enable(boolean enable);
28 | public boolean isEnabled();
29 |
30 | public boolean isActive();
31 |
32 | public void setMouseButton(int button);
33 | public int getMouseButton();
34 |
35 | public void mouseEvent(MouseEvent event);
36 | public void keyEvent(KeyEvent event);
37 | public void updateEvent();
38 |
39 | public void setMouseOffset(int mouseX_off, int mouseY_off);
40 | }
41 |
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/java/interaction/DwMouseDragBodies.java:
--------------------------------------------------------------------------------
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 | package com.thomasdiewald.liquidfun.java.interaction;
14 |
15 | import org.jbox2d.callbacks.QueryCallback;
16 | import org.jbox2d.collision.AABB;
17 | import org.jbox2d.common.Vec2;
18 | import org.jbox2d.dynamics.Body;
19 | import org.jbox2d.dynamics.BodyDef;
20 | import org.jbox2d.dynamics.BodyType;
21 | import org.jbox2d.dynamics.Fixture;
22 | import org.jbox2d.dynamics.World;
23 | import org.jbox2d.dynamics.joints.MouseJoint;
24 | import org.jbox2d.dynamics.joints.MouseJointDef;
25 |
26 | import com.thomasdiewald.liquidfun.java.DwViewportTransform;
27 |
28 | import processing.core.PConstants;
29 | import processing.event.KeyEvent;
30 | import processing.event.MouseEvent;
31 |
32 |
33 | /**
34 | *
35 | * @author Thomas Diewald
36 | *
37 | */
38 | public class DwMouseDragBodies implements DwInteractionEvent, QueryCallback{
39 |
40 | public World world;
41 | public DwViewportTransform vptransform;
42 |
43 | public boolean active = false;
44 | public AABB aabb = new AABB();
45 | public Vec2 point = new Vec2();
46 | public Fixture fixture = null;
47 | public MouseJoint mouse_joint;
48 |
49 | public final Vec2 mouse = new Vec2();
50 | public float mult_dragforce = 1000000f;
51 | public boolean enable_static_drag = false;
52 |
53 | public int button = PConstants.LEFT;
54 | // public int button = PConstants.CENTER;
55 | // public int button = PConstants.RIGHT;
56 |
57 | public DwMouseDragBodies(World world, DwViewportTransform vptransform){
58 | this.world = world;
59 | this.vptransform = vptransform;
60 | }
61 |
62 | // public boolean query(Vec2 world_xy){
63 | // fixture = null;
64 | // point.set(world_xy);
65 | // aabb.lowerBound.set(point.x - 0.001f, point.y - 0.001f);
66 | // aabb.upperBound.set(point.x + 0.001f, point.y + 0.001f);
67 | // world.queryAABB(this, aabb);
68 | // return fixture != null;
69 | // }
70 |
71 | public boolean query(float screen_x, float screen_y){
72 | vptransform.getScreen2box(screen_x, screen_y, mouse);
73 | fixture = null;
74 | point.set(mouse);
75 | aabb.lowerBound.set(point.x - 0.001f, point.y - 0.001f);
76 | aabb.upperBound.set(point.x + 0.001f, point.y + 0.001f);
77 | world.queryAABB(this, aabb);
78 | return fixture != null;
79 | }
80 |
81 |
82 | public void press(float screen_x, float screen_y) {
83 | if (query(screen_x, screen_y)) {
84 | Body body = fixture.getBody();
85 | MouseJointDef def = new MouseJointDef();
86 | def.bodyA = world.createBody(new BodyDef());
87 | def.bodyB = fixture.getBody();
88 | def.collideConnected = true;
89 | def.target.set(point);
90 | def.maxForce = mult_dragforce * body.getMass();
91 | mouse_joint = (MouseJoint) world.createJoint(def);
92 | body.setAwake(true);
93 | }
94 | active = (mouse_joint != null);
95 | }
96 |
97 |
98 | public void update(float screen_x, float screen_y) {
99 | if (active) {
100 | vptransform.getScreen2box(screen_x, screen_y, mouse);
101 | mouse_joint.setTarget(mouse);
102 | }
103 | }
104 |
105 |
106 | public void release(float screen_x, float screen_y) {
107 | if (active) {
108 | if(body_type_cpy != null){
109 | fixture.getBody().setType(body_type_cpy);
110 | body_type_cpy = null;
111 | }
112 | fixture = null;
113 | world.destroyJoint(mouse_joint);
114 | mouse_joint = null;
115 | }
116 | active = false;
117 | }
118 |
119 |
120 |
121 | public boolean is_enabled = true;
122 |
123 | @Override
124 | public void enable(boolean enable) {
125 | is_enabled = enable;
126 | }
127 |
128 | @Override
129 | public boolean isEnabled() {
130 | return is_enabled;
131 | }
132 |
133 |
134 |
135 | @Override
136 | public boolean isActive(){
137 | return active;
138 | }
139 |
140 | @Override
141 | public void setMouseButton(int button){
142 | this.button = button;
143 | }
144 |
145 | @Override
146 | public int getMouseButton(){
147 | return button;
148 | }
149 |
150 | public BodyType body_type_cpy = null;
151 |
152 | @Override
153 | public boolean reportFixture(Fixture argFixture) {
154 | Body body = argFixture.getBody();
155 |
156 | // static bodies can be moved too, but need to set to dynamic for the
157 | // mouse-joint to work.
158 | BodyType type = body.getType();
159 | if (BodyType.DYNAMIC == type || enable_static_drag) {
160 | if (argFixture.testPoint(point)) {
161 | body_type_cpy = type;
162 | fixture = argFixture;
163 | body.setType(BodyType.DYNAMIC);
164 | return false;
165 | }
166 | }
167 | return true;
168 | }
169 |
170 |
171 | int mouseX_off = 0;
172 | int mouseY_off = 0;
173 | int mouseX;
174 | int mouseY;
175 |
176 | @Override
177 | public void mouseEvent(MouseEvent event){
178 | if(!is_enabled){
179 | return;
180 | }
181 |
182 | mouseX = mouseX_off + event.getX();
183 | mouseY = mouseY_off + event.getY();
184 | if(event.getButton() == this.button){
185 | switch(event.getAction()){
186 | case MouseEvent.PRESS: press (mouseX, mouseY); break;
187 | case MouseEvent.RELEASE: release(mouseX, mouseY); break;
188 | }
189 | }
190 | }
191 |
192 | public int key_combi = 0;
193 | public boolean key_combi_active = true;
194 | public boolean key_combi_enabled = true;
195 |
196 | @Override
197 | public void keyEvent(KeyEvent event){
198 | switch(event.getAction()){
199 | case KeyEvent.PRESS:
200 | key_combi_active = false;
201 | break;
202 | case KeyEvent.RELEASE:
203 | key_combi_active = true;
204 | break;
205 | }
206 | }
207 |
208 | @Override
209 | public void updateEvent(){
210 | update(mouseX, mouseY);
211 | }
212 |
213 | @Override
214 | public void setMouseOffset(int mouseX_off, int mouseY_off){
215 | this.mouseX_off = mouseX_off;
216 | this.mouseY_off = mouseY_off;
217 | }
218 |
219 |
220 |
221 | }
222 |
223 |
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/java/interaction/DwMouseDragParticles.java:
--------------------------------------------------------------------------------
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 | package com.thomasdiewald.liquidfun.java.interaction;
14 |
15 | import org.jbox2d.callbacks.ParticleQueryCallback;
16 | import org.jbox2d.collision.AABB;
17 | import org.jbox2d.collision.shapes.CircleShape;
18 | import org.jbox2d.common.Transform;
19 | import org.jbox2d.common.Vec2;
20 | import org.jbox2d.dynamics.World;
21 |
22 | import com.thomasdiewald.liquidfun.java.DwViewportTransform;
23 |
24 | import processing.core.PConstants;
25 | import processing.event.KeyEvent;
26 | import processing.event.MouseEvent;
27 |
28 |
29 | /**
30 | *
31 | * @author Thomas Diewald
32 | *
33 | */
34 | public class DwMouseDragParticles implements DwInteractionEvent, ParticleQueryCallback {
35 |
36 | public World world;
37 | public DwViewportTransform transform;
38 |
39 | protected DwMouseDragBodies body_dragger;
40 |
41 | public boolean active = false;
42 |
43 |
44 | public int button = PConstants.LEFT;
45 | //public int button = PConstants.CENTER;
46 | //public int button = PConstants.RIGHT;
47 |
48 |
49 | public Transform xf = new Transform();
50 | public AABB aabb = new AABB();
51 | public CircleShape query_shape = new CircleShape();
52 |
53 | public float dt = 1 / 60f;
54 | public Vec2 pos = new Vec2(0, 0);
55 | public Vec2 vel = new Vec2(0, 0);
56 | public Vec2 acc = new Vec2(0, 0);
57 |
58 | public final Vec2 mouse = new Vec2();
59 |
60 | public DwMouseDragParticles(World world, DwViewportTransform transform){
61 | this.world = world;
62 | this.transform = transform;
63 | xf.setIdentity();
64 | query_shape.m_radius = 2;
65 |
66 | body_dragger = new DwMouseDragBodies(world, transform);
67 | }
68 |
69 |
70 | public void press(float screen_x, float screen_y) {
71 | // bodies have priority
72 | if(body_dragger.query(screen_x, screen_y)){
73 | return;
74 | }
75 |
76 | transform.getScreen2box(screen_x, screen_y, mouse);
77 | this.vel.set(0, 0);
78 | this.pos.set(mouse);
79 | query_shape.m_p.set(pos);
80 | query_shape.computeAABB(aabb, xf, 0);
81 | world.queryAABB(this, aabb);
82 | active = true;
83 | }
84 |
85 |
86 | public void update(float screen_x, float screen_y) {
87 | if (active) {
88 | transform.getScreen2box(screen_x, screen_y, mouse);
89 | float delay = 0.1f;
90 | acc.x = 2f / delay * ((mouse.x - pos.x) / delay - vel.x);
91 | acc.y = 2f / delay * ((mouse.y - pos.y) / delay - vel.y);
92 | vel.x += dt * acc.x;
93 | vel.y += dt * acc.y;
94 | pos.x += dt * vel.x;
95 | pos.y += dt * vel.y;
96 | query_shape.m_p.set(pos);
97 | query_shape.computeAABB(aabb, xf, 0);
98 | world.queryAABB(this, aabb);
99 | }
100 | }
101 |
102 | public void release(float screen_x, float screen_y) {
103 | active = false;
104 | }
105 |
106 |
107 | public boolean is_enabled = true;
108 |
109 | @Override
110 | public void enable(boolean enable) {
111 | is_enabled = enable;
112 | }
113 |
114 | @Override
115 | public boolean isEnabled() {
116 | return is_enabled;
117 | }
118 |
119 | @Override
120 | public boolean isActive(){
121 | return active;
122 | }
123 |
124 | @Override
125 | public void setMouseButton(int button){
126 | this.button = button;
127 | }
128 |
129 | @Override
130 | public int getMouseButton(){
131 | return button;
132 | }
133 |
134 | @Override
135 | public boolean reportParticle(int index) {
136 | Vec2 particle_pos = world.getParticlePositionBuffer()[index];
137 | if (query_shape.testPoint(xf, particle_pos)) {
138 | Vec2 particle_vel = world.getParticleVelocityBuffer()[index];
139 | particle_vel.set(vel);
140 | }
141 | return true;
142 | }
143 |
144 |
145 |
146 |
147 |
148 |
149 | int mouseX;
150 | int mouseY;
151 | int mouseX_off = 0;
152 | int mouseY_off = 0;
153 |
154 | @Override
155 | public void mouseEvent(MouseEvent event){
156 | if(!is_enabled){
157 | return;
158 | }
159 | mouseX = mouseX_off + event.getX();
160 | mouseY = mouseY_off + event.getY();
161 | if(event.getButton() == this.button){
162 | switch(event.getAction()){
163 | case MouseEvent.PRESS:
164 | if(key_combi_enabled == key_combi_active){
165 | press(mouseX, mouseY);
166 | }
167 | break;
168 | case MouseEvent.RELEASE:
169 | release(mouseX, mouseY);
170 | break;
171 | }
172 | }
173 | }
174 |
175 | public int key_combi = 0;
176 | public boolean key_combi_active = true;
177 | public boolean key_combi_enabled = true;
178 |
179 | @Override
180 | public void keyEvent(KeyEvent event){
181 | switch(event.getAction()){
182 | case KeyEvent.PRESS:
183 | key_combi_active = false;
184 | break;
185 | case KeyEvent.RELEASE:
186 | key_combi_active = true;
187 | break;
188 | }
189 | }
190 |
191 | @Override
192 | public void updateEvent(){
193 | update(mouseX, mouseY);
194 | }
195 |
196 |
197 | @Override
198 | public void setMouseOffset(int mouseX_off, int mouseY_off){
199 | this.mouseX_off = mouseX_off;
200 | this.mouseY_off = mouseY_off;
201 | }
202 |
203 | }
204 |
--------------------------------------------------------------------------------
/src/com/thomasdiewald/liquidfun/java/interaction/DwMouseShootBullet.java:
--------------------------------------------------------------------------------
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 | package com.thomasdiewald.liquidfun.java.interaction;
14 |
15 |
16 | import java.util.Stack;
17 |
18 | import org.jbox2d.collision.shapes.CircleShape;
19 | import org.jbox2d.common.Vec2;
20 | import org.jbox2d.dynamics.Body;
21 | import org.jbox2d.dynamics.BodyDef;
22 | import org.jbox2d.dynamics.BodyType;
23 | import org.jbox2d.dynamics.FixtureDef;
24 | import org.jbox2d.dynamics.World;
25 |
26 | import com.thomasdiewald.liquidfun.java.DwViewportTransform;
27 |
28 | import processing.core.PConstants;
29 | import processing.core.PGraphics;
30 | import processing.event.KeyEvent;
31 | import processing.event.MouseEvent;
32 |
33 |
34 |
35 | /**
36 | *
37 | * @author Thomas Diewald
38 | *
39 | */
40 | public class DwMouseShootBullet implements DwInteractionEvent {
41 |
42 | public World world;
43 | public DwViewportTransform transform;
44 |
45 | public boolean is_active = false;
46 | public int button = PConstants.LEFT;
47 |
48 | public Vec2 bomb_spawn_start = new Vec2();
49 | public Vec2 bomb_spawn_end = new Vec2();
50 | public Vec2 bomb_velocity = new Vec2();
51 | public float velocity_mult = 2f;
52 | public float density_mult = 1f;
53 |
54 |
55 | public BodyDef body_def = new BodyDef();
56 | public CircleShape cirlce_shape = new CircleShape();
57 | public FixtureDef fixture_def = new FixtureDef();
58 |
59 | protected DwMouseDragBodies body_dragger;
60 |
61 | protected Stack