• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 /*
17  * Copyright 2010 Mario Zechner (contact@badlogicgames.com), Nathan Sweet (admin@esotericsoftware.com)
18  *
19  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
20  * License. You may obtain a copy of the License at
21  *
22  * http://www.apache.org/licenses/LICENSE-2.0
23  *
24  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
25  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
26  * governing permissions and limitations under the License.
27  */
28 
29 package com.badlogic.gdx.tests.box2d;
30 
31 import java.lang.reflect.Field;
32 import java.lang.reflect.Method;
33 
34 import com.badlogic.gdx.Gdx;
35 import com.badlogic.gdx.math.Vector2;
36 import com.badlogic.gdx.physics.box2d.Body;
37 import com.badlogic.gdx.physics.box2d.BodyDef;
38 import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
39 import com.badlogic.gdx.physics.box2d.CircleShape;
40 import com.badlogic.gdx.physics.box2d.Contact;
41 import com.badlogic.gdx.physics.box2d.ContactImpulse;
42 import com.badlogic.gdx.physics.box2d.ContactListener;
43 import com.badlogic.gdx.physics.box2d.EdgeShape;
44 import com.badlogic.gdx.physics.box2d.Fixture;
45 import com.badlogic.gdx.physics.box2d.FixtureDef;
46 import com.badlogic.gdx.physics.box2d.Manifold;
47 import com.badlogic.gdx.physics.box2d.PolygonShape;
48 import com.badlogic.gdx.physics.box2d.World;
49 
50 public class ContactListenerTest extends Box2DTest implements ContactListener {
51 
52 	@Override
createWorld(World world)53 	protected void createWorld (World world) {
54 		world.setContactListener(this);
55 		{
56 			BodyDef bd = new BodyDef();
57 			Body ground = world.createBody(bd);
58 
59 			EdgeShape shape = new EdgeShape();
60 			shape.set(new Vector2(-20, 0), new Vector2(20, 0));
61 			ground.createFixture(shape, 0);
62 			shape.dispose();
63 		}
64 
65 		{
66 			BodyDef bd = new BodyDef();
67 			Body ground = world.createBody(bd);
68 
69 			EdgeShape shape = new EdgeShape();
70 			shape.setRadius(0);
71 			shape.set(new Vector2(-8, 1), new Vector2(-6, 1));
72 			ground.createFixture(shape, 0);
73 			shape.set(new Vector2(-6, 1), new Vector2(-4, 1));
74 			ground.createFixture(shape, 0);
75 			shape.set(new Vector2(-4, 1), new Vector2(-2, 1));
76 			ground.createFixture(shape, 0);
77 			shape.dispose();
78 		}
79 
80 		{
81 			BodyDef bd = new BodyDef();
82 			Body ground = world.createBody(bd);
83 
84 			PolygonShape shape = new PolygonShape();
85 			shape.setAsBox(1, 1, new Vector2(4, 3), 0);
86 			ground.createFixture(shape, 0);
87 			shape.setAsBox(1, 1, new Vector2(6, 3), 0);
88 			ground.createFixture(shape, 0);
89 			shape.setAsBox(1, 1, new Vector2(8, 3), 0);
90 			ground.createFixture(shape, 0);
91 			shape.dispose();
92 		}
93 
94 		{
95 			BodyDef bd = new BodyDef();
96 			Body ground = world.createBody(bd);
97 
98 			EdgeShape shape = new EdgeShape();
99 			float d = 2 * 2 * 0.005f;
100 			shape.setRadius(0);
101 			shape.set(new Vector2(-1 + d, 3), new Vector2(1 - d, 3));
102 			ground.createFixture(shape, 0);
103 			shape.set(new Vector2(1, 3 + d), new Vector2(1, 5 - d));
104 			ground.createFixture(shape, 0);
105 			shape.set(new Vector2(1 - d, 5), new Vector2(-1 + d, 5));
106 			ground.createFixture(shape, 0);
107 			shape.set(new Vector2(-1, 5 - d), new Vector2(-1, 3 + d));
108 			ground.createFixture(shape, 0);
109 			shape.dispose();
110 		}
111 
112 		{
113 			BodyDef bd = new BodyDef();
114 			bd.position.set(-3, 20);
115 			bd.type = BodyType.DynamicBody;
116 			bd.fixedRotation = true;
117 			bd.allowSleep = false;
118 
119 			Body body = world.createBody(bd);
120 
121 			PolygonShape shape = new PolygonShape();
122 			shape.setAsBox(0.5f, 0.5f);
123 
124 			FixtureDef fd = new FixtureDef();
125 			fd.shape = shape;
126 			fd.density = 20.0f;
127 			body.createFixture(fd);
128 			shape.dispose();
129 		}
130 
131 		{
132 			BodyDef bd = new BodyDef();
133 			bd.position.set(-5, 25);
134 			bd.type = BodyType.DynamicBody;
135 			bd.fixedRotation = true;
136 			bd.allowSleep = false;
137 
138 			Body body = world.createBody(bd);
139 
140 			float angle = 0;
141 			float delta = (float)Math.PI / 3;
142 			Vector2[] vertices = new Vector2[6];
143 			for (int i = 0; i < 6; i++) {
144 				vertices[i] = new Vector2(0.5f * (float)Math.cos(angle), 0.5f * (float)Math.sin(angle));
145 				angle += delta;
146 			}
147 
148 			PolygonShape shape = new PolygonShape();
149 			shape.set(vertices);
150 
151 			FixtureDef fd = new FixtureDef();
152 			fd.shape = shape;
153 			fd.density = 20.0f;
154 			body.createFixture(fd);
155 			shape.dispose();
156 		}
157 
158 		{
159 			BodyDef bd = new BodyDef();
160 			bd.position.set(3, 30);
161 			bd.type = BodyType.DynamicBody;
162 			bd.fixedRotation = true;
163 			bd.allowSleep = false;
164 
165 			Body body = world.createBody(bd);
166 
167 			CircleShape shape = new CircleShape();
168 			shape.setRadius(0.5f);
169 
170 			FixtureDef fd = new FixtureDef();
171 			fd.shape = shape;
172 			fd.density = 20.0f;
173 			body.createFixture(fd);
174 			shape.dispose();
175 		}
176 	}
177 
178 	@Override
beginContact(Contact contact)179 	public void beginContact (Contact contact) {
180 		System.out.println(String.format("beginContact() addr=%d", getContactAddr(contact)));
181 		System.out.println(String.format("beginContact() addrA=%d, addrB=%d",
182 			getFixtureAddrA(contact),
183 			getFixtureAddrB(contact)));
184 		System.out.println(String.format("beginContact() fixA=%s, fixB=%s",
185 			contact.getFixtureA(),
186 			contact.getFixtureB()));
187 
188 		final Body toRemove = contact.getFixtureA().getBody().getType() == BodyType.DynamicBody ?
189 			contact.getFixtureA().getBody() :
190 			contact.getFixtureB().getBody();
191 			Gdx.app.postRunnable(new Runnable() {
192 				@Override
193 				public void run () {
194 					world.destroyBody(toRemove);
195 				}
196 			});
197 	}
198 
199 	@Override
endContact(Contact contact)200 	public void endContact (Contact contact) {
201 		System.out.println(String.format("  endContact() addr=%d", getContactAddr(contact)));
202 		System.out.println(String.format("  endContact() addrA=%d, addrB=%d",
203 			getFixtureAddrA(contact),
204 			getFixtureAddrB(contact)));
205 		System.out.println(String.format("  endContact() fixA=%s, fixB=%s",
206 			contact.getFixtureA(),
207 			contact.getFixtureB()));
208 
209 		final Fixture fixtureA = contact.getFixtureA();
210 		final Fixture fixtureB = contact.getFixtureB();
211 		if(fixtureA == null || fixtureB == null) {
212 			throw new RuntimeException("No fixture found.");
213 		}
214 	}
215 
216 	@Override
preSolve(Contact contact, Manifold oldManifold)217 	public void preSolve (Contact contact, Manifold oldManifold) {
218 		// TODO Auto-generated method stub
219 
220 	}
221 
222 	@Override
postSolve(Contact contact, ContactImpulse impulse)223 	public void postSolve (Contact contact, ContactImpulse impulse) {
224 		// TODO Auto-generated method stub
225 
226 	}
227 
getFixtureAddrA(Contact contact)228 	public long getFixtureAddrA(Contact contact) {
229 		try {
230 			long addr = getContactAddr(contact);
231 
232 			Method getFixtureA = contact.getClass().getDeclaredMethod("jniGetFixtureA", long.class);
233 			getFixtureA.setAccessible(true);
234 			return (Long) getFixtureA.invoke(contact, addr);
235 		} catch (Exception e) {
236 			e.printStackTrace();
237 			return 0;
238 		}
239 	}
240 
getFixtureAddrB(Contact contact)241 	public long getFixtureAddrB(Contact contact) {
242 		try {
243 			long addr =getContactAddr(contact);
244 
245 			Method getFixtureB = contact.getClass().getDeclaredMethod("jniGetFixtureB", long.class);
246 			getFixtureB.setAccessible(true);
247 			return (Long) getFixtureB.invoke(contact, addr);
248 		} catch (Exception e) {
249 			e.printStackTrace();
250 			return 0;
251 		}
252 	}
253 
getContactAddr(Contact contact)254 	public long getContactAddr(Contact contact) {
255 		try {
256 			Field addrField = contact.getClass().getDeclaredField("addr");
257 			addrField.setAccessible(true);
258 			return addrField.getLong(contact);
259 		} catch (Exception e) {
260 			e.printStackTrace();
261 			return 0;
262 		}
263 	}
264 }