Skip to content

Commit b5074bc

Browse files
committed
Update to "Add the EventListener class"
DanielChappuis/reactphysics3d@07df001e8bcc55c5 b4915687cd9ddf349ee891f4
1 parent 71bd610 commit b5074bc

File tree

6 files changed

+106
-119
lines changed

6 files changed

+106
-119
lines changed

src/main/java/org/spout/physics/collision/CollisionDetection.java

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ public class CollisionDetection {
6161
private final GJKAlgorithm mNarrowPhaseGJKAlgorithm = new GJKAlgorithm();
6262
private final SphereVsSphereAlgorithm mNarrowPhaseSphereVsSphereAlgorithm = new SphereVsSphereAlgorithm();
6363
private final Set<IntPair> mNoCollisionPairs = new HashSet<>();
64-
private final List<CollisionListener> mCallBacks = new ArrayList<>();
6564
private final LinkedPhase mLinkedPhase;
6665

6766
/**
@@ -79,24 +78,6 @@ public CollisionDetection(CollisionWorld world) {
7978
}
8079
}
8180

82-
/**
83-
* Gets the collision listeners for collision detection.
84-
*
85-
* @return The collision listeners
86-
*/
87-
public List<CollisionListener> getListeners() {
88-
return mCallBacks;
89-
}
90-
91-
/**
92-
* Adds a collision listener for the collision detection.
93-
*
94-
* @param listener The listener to add
95-
*/
96-
public void addListener(CollisionListener listener) {
97-
mCallBacks.add(listener);
98-
}
99-
10081
/**
10182
* Adds a body to the collision detection.
10283
*
@@ -192,20 +173,7 @@ private void computeNarrowPhase() {
192173
if (narrowPhaseAlgorithm.testCollision(body1.getCollisionShape(), body1.getTransform(), body2.getCollisionShape(), body2.getTransform(), contactInfo)) {
193174
contactInfo.setFirstBody((RigidBody) body1);
194175
contactInfo.setSecondBody((RigidBody) body2);
195-
if (mCallBacks.isEmpty()) {
196-
mWorld.notifyNewContact(pair, contactInfo);
197-
} else {
198-
boolean cancel = false;
199-
for (CollisionListener listener : mCallBacks) {
200-
if (listener.onCollide(body1, body2, contactInfo)) {
201-
cancel = true;
202-
break;
203-
}
204-
}
205-
if (!cancel) {
206-
mWorld.notifyNewContact(pair, contactInfo);
207-
}
208-
}
176+
mWorld.notifyNewContact(pair, contactInfo);
209177
}
210178
}
211179
}

src/main/java/org/spout/physics/engine/CollisionWorld.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import org.spout.physics.body.CollisionBody;
4141
import org.spout.physics.collision.BroadPhasePair;
4242
import org.spout.physics.collision.CollisionDetection;
43-
import org.spout.physics.collision.CollisionListener;
4443
import org.spout.physics.collision.RayCaster;
4544
import org.spout.physics.collision.RayCaster.IntersectedBody;
4645
import org.spout.physics.collision.shape.CollisionShape;
@@ -94,15 +93,6 @@ protected CollisionWorld() {
9493
*/
9594
public abstract void updateOverlappingPair(BroadPhasePair pair);
9695

97-
/**
98-
* Adds a collision listener for the collision detection.
99-
*
100-
* @param listener The listener to use
101-
*/
102-
public void addListener(CollisionListener listener) {
103-
mCollisionDetection.addListener(listener);
104-
}
105-
10696
/**
10797
* Gets the set of the bodies of the physics world.
10898
*

src/main/java/org/spout/physics/engine/DynamicsWorld.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public class DynamicsWorld extends CollisionWorld {
9191
private float mSleepLinearVelocity;
9292
private float mSleepAngularVelocity;
9393
private float mTimeBeforeSleep;
94+
private EventListener mEventListener;
9495
private boolean isTicking = false;
9596
// Tick cache
9697
private final Set<RigidBody> mRigidBodiesToAddCache = new HashSet<>();
@@ -288,6 +289,15 @@ public void setTimeBeforeSleep(float timeBeforeSleep) {
288289
mTimeBeforeSleep = timeBeforeSleep;
289290
}
290291

292+
/**
293+
* Sets an event listener object to receive events callbacks. If you use <code>null</code> as an argument, the events callbacks will be disabled.
294+
*
295+
* @param eventListener The event listener, or null for none
296+
*/
297+
public void setEventListener(EventListener eventListener) {
298+
mEventListener = eventListener;
299+
}
300+
291301
/**
292302
* Gets the number of rigid bodies in the world.
293303
*
@@ -367,9 +377,9 @@ public void update() {
367377
updateSleepingBodies();
368378
}
369379
updateRigidBodiesAABB();
370-
resetBodiesForceAndTorque();
371380
}
372381
isTicking = false;
382+
resetBodiesForceAndTorque();
373383
setInterpolationFactorToAllBodies();
374384
disperseCache();
375385
}
@@ -907,9 +917,17 @@ public void notifyNewContact(BroadPhasePair broadPhasePair, ContactPointInfo con
907917
if (overlappingPair == null) {
908918
throw new IllegalArgumentException("broad phase pair is not in the overlapping pairs");
909919
}
920+
if (overlappingPair.getNbContactPoints() == 0) {
921+
if (mEventListener != null) {
922+
mEventListener.beginContact(contactInfo);
923+
}
924+
}
910925
overlappingPair.addContact(contact);
911926
mContactManifolds.add(overlappingPair.getContactManifold());
912927
addContactManifoldToBody(overlappingPair.getContactManifold(), overlappingPair.getFirstBody(), overlappingPair.getSecondBody());
928+
if (mEventListener != null) {
929+
mEventListener.newContact(contactInfo);
930+
}
913931
}
914932

915933
/**

src/main/java/org/spout/physics/collision/CollisionListener.java renamed to src/main/java/org/spout/physics/engine/EventListener.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,26 @@
2424
* License and see <http://spout.in/licensev1> for the full license, including
2525
* the MIT license.
2626
*/
27-
package org.spout.physics.collision;
27+
package org.spout.physics.engine;
2828

29-
import org.spout.physics.body.CollisionBody;
3029
import org.spout.physics.constraint.ContactPoint.ContactPointInfo;
3130

3231
/**
33-
* Reports the collisions between two bodies as they are occurring during the narrow-phase and allows for cancellation of the collision. Each collision will result in a call of {@link
34-
* #onCollide(org.spout.physics.body.CollisionBody, org.spout.physics.body.CollisionBody, ContactPointInfo)}. Implement this interface to listen to them. Use {@link
35-
* org.spout.physics.engine.CollisionWorld#addListener(CollisionListener)} to add a listener.
32+
* This class can be used to receive event callbacks from the physics engine. In order to receive callbacks, you need to create a new class that inherits from this one and you must override the
33+
* methods you need. Then, you need to register your new event listener class to the physics world using the {@link DynamicsWorld#setEventListener(EventListener)} method.
3634
*/
37-
public interface CollisionListener {
35+
public interface EventListener {
3836
/**
39-
* This method is called when two bodies are about to collide in a collision detection. Both bodies are provided, including the contact information, which includes the contact points on each body,
40-
* the penetration depth, and the normal. The method returns a boolean. If it is true, the collision will be canceled.
37+
* Called when a new contact point is found between two bodies that were separated before.
4138
*
42-
* @param body1 The first body
43-
* @param body2 The second body
44-
* @param contactInfo The contact information
45-
* @return Whether or not the collision should be canceled
39+
* @param contactInfo The info for the contact
4640
*/
47-
public boolean onCollide(CollisionBody body1, CollisionBody body2, ContactPointInfo contactInfo);
41+
void beginContact(ContactPointInfo contactInfo);
42+
43+
/**
44+
* Called when a new contact point is found between two bodies.
45+
*
46+
* @param contactInfo The info for the contact
47+
*/
48+
void newContact(ContactPointInfo contactInfo);
4849
}

src/test/java/org/spout/physics/DynamicsWorldTest.java

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,52 +26,67 @@
2626
*/
2727
package org.spout.physics;
2828

29+
import org.junit.Assert;
2930
import org.junit.Test;
3031

3132
import org.spout.physics.body.RigidBody;
3233
import org.spout.physics.collision.shape.BoxShape;
34+
import org.spout.physics.constraint.ContactPoint.ContactPointInfo;
3335
import org.spout.physics.engine.DynamicsWorld;
36+
import org.spout.physics.engine.EventListener;
3437
import org.spout.physics.math.Matrix3x3;
3538
import org.spout.physics.math.Quaternion;
3639
import org.spout.physics.math.Transform;
3740
import org.spout.physics.math.Vector3;
3841

3942
public class DynamicsWorldTest {
4043
private static final float RUN_TIME = 2;
44+
private int beginContactCount = 0;
45+
private int newContactCount = 0;
4146

4247
@Test
4348
public void test() throws InterruptedException {
44-
try {
45-
final float timeStep = ReactDefaults.DEFAULT_TIMESTEP;
46-
final DynamicsWorld world = new DynamicsWorld(new Vector3(0, -9.81f, 0), timeStep);
47-
final BoxShape floorShape = new BoxShape(new Vector3(10, 0.5f, 10));
48-
final Transform floorTransform = new Transform(new Vector3(0, 0, 0), Quaternion.identity());
49-
final Matrix3x3 floorInertia = new Matrix3x3();
50-
final float floorMass = 100;
51-
floorShape.computeLocalInertiaTensor(floorInertia, floorMass);
52-
final RigidBody floor = world.createRigidBody(floorTransform, floorMass, floorInertia, floorShape);
53-
floor.setIsMotionEnabled(false);
54-
final BoxShape boxShape = new BoxShape(new Vector3(1, 1, 1));
55-
final Transform boxTransform = new Transform(new Vector3(0, 5, 0), Quaternion.identity());
56-
final Matrix3x3 boxInertia = new Matrix3x3();
57-
final float boxMass = 5;
58-
boxShape.computeLocalInertiaTensor(boxInertia, boxMass);
59-
final RigidBody box = world.createRigidBody(boxTransform, boxMass, boxInertia, boxShape);
60-
final int stepCount = Math.round((1 / timeStep) * RUN_TIME);
61-
final int sleepTime = Math.round(timeStep * 1000);
62-
world.start();
63-
for (int i = 0; i < stepCount; i++) {
64-
final long start = System.nanoTime();
65-
world.update();
66-
final long delta = Math.round((System.nanoTime() - start) / 1000000d);
67-
Thread.sleep(Math.max(sleepTime - delta, 0));
68-
}
69-
world.destroyRigidBody(floor);
70-
world.destroyRigidBody(box);
71-
world.stop();
72-
} catch (Exception ex) {
73-
ex.printStackTrace();
74-
throw new RuntimeException(ex);
49+
final float timeStep = ReactDefaults.DEFAULT_TIMESTEP;
50+
final DynamicsWorld world = new DynamicsWorld(new Vector3(0, -9.81f, 0), timeStep);
51+
final BoxShape floorShape = new BoxShape(new Vector3(10, 0.5f, 10));
52+
final Transform floorTransform = new Transform(new Vector3(0, 0, 0), Quaternion.identity());
53+
final Matrix3x3 floorInertia = new Matrix3x3();
54+
final float floorMass = 100;
55+
floorShape.computeLocalInertiaTensor(floorInertia, floorMass);
56+
final RigidBody floor = world.createRigidBody(floorTransform, floorMass, floorInertia, floorShape);
57+
floor.setIsMotionEnabled(false);
58+
final BoxShape boxShape = new BoxShape(new Vector3(1, 1, 1));
59+
final Transform boxTransform = new Transform(new Vector3(0, 5, 0), Quaternion.identity());
60+
final Matrix3x3 boxInertia = new Matrix3x3();
61+
final float boxMass = 5;
62+
boxShape.computeLocalInertiaTensor(boxInertia, boxMass);
63+
final RigidBody box = world.createRigidBody(boxTransform, boxMass, boxInertia, boxShape);
64+
final int stepCount = Math.round((1 / timeStep) * RUN_TIME);
65+
final int sleepTime = Math.round(timeStep * 1000);
66+
world.setEventListener(new TestListener());
67+
world.start();
68+
for (int i = 0; i < stepCount; i++) {
69+
final long start = System.nanoTime();
70+
world.update();
71+
final long delta = Math.round((System.nanoTime() - start) / 1000000d);
72+
Thread.sleep(Math.max(sleepTime - delta, 0));
73+
}
74+
world.destroyRigidBody(floor);
75+
world.destroyRigidBody(box);
76+
world.stop();
77+
Assert.assertTrue("There was no contact in the simulation", beginContactCount > 0);
78+
Assert.assertTrue("There were more contacts begun than new contacts", newContactCount > beginContactCount);
79+
}
80+
81+
private class TestListener implements EventListener {
82+
@Override
83+
public void beginContact(ContactPointInfo contactInfo) {
84+
beginContactCount++;
85+
}
86+
87+
@Override
88+
public void newContact(ContactPointInfo contactInfo) {
89+
newContactCount++;
7590
}
7691
}
7792
}

src/test/java/org/spout/physics/SweepAndPruneAlgorithmTest.java

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -42,38 +42,33 @@ public class SweepAndPruneAlgorithmTest {
4242

4343
@Test
4444
public void test() {
45-
try {
46-
final SweepAndPruneAlgorithm sweepAndPrune = new SweepAndPruneAlgorithm(Dummies.newCollisionDetection());
47-
final Set<CollisionBody> bodies = new HashSet<>();
48-
for (int repeat = 0; repeat < 2; repeat++) {
49-
for (int i = 0; i < BODY_COUNT / 10; i++) {
50-
final CollisionBody body = Dummies.newCollisionBody(ID++);
51-
bodies.add(body);
52-
sweepAndPrune.addObject(body, Dummies.newAABB());
53-
}
54-
Assert.assertEquals(BODY_COUNT / 10, sweepAndPrune.getNbObjects());
55-
Assert.assertTrue(countNotNull(sweepAndPrune.getOverlappingPairs()) >= 0);
56-
for (int i = 0; i < BODY_COUNT / 2; i++) {
57-
final AABB aabb = Dummies.newAABB();
58-
final CollisionBody body0 = Dummies.newCollisionBody(ID++);
59-
bodies.add(body0);
60-
sweepAndPrune.addObject(body0, aabb);
61-
final CollisionBody body1 = Dummies.newCollisionBody(ID++);
62-
bodies.add(body1);
63-
sweepAndPrune.addObject(body1, Dummies.newIntersectingAABB(aabb));
64-
}
65-
Assert.assertEquals(BODY_COUNT + BODY_COUNT / 10, sweepAndPrune.getNbObjects());
66-
Assert.assertTrue(countNotNull(sweepAndPrune.getOverlappingPairs()) >= BODY_COUNT / 2);
67-
for (CollisionBody body : bodies) {
68-
sweepAndPrune.removeObject(body);
69-
}
70-
Assert.assertEquals(0, sweepAndPrune.getNbObjects());
71-
bodies.clear();
72-
ID = 0;
45+
final SweepAndPruneAlgorithm sweepAndPrune = new SweepAndPruneAlgorithm(Dummies.newCollisionDetection());
46+
final Set<CollisionBody> bodies = new HashSet<>();
47+
for (int repeat = 0; repeat < 2; repeat++) {
48+
for (int i = 0; i < BODY_COUNT / 10; i++) {
49+
final CollisionBody body = Dummies.newCollisionBody(ID++);
50+
bodies.add(body);
51+
sweepAndPrune.addObject(body, Dummies.newAABB());
7352
}
74-
} catch (Exception ex) {
75-
ex.printStackTrace();
76-
throw new RuntimeException(ex);
53+
Assert.assertEquals(BODY_COUNT / 10, sweepAndPrune.getNbObjects());
54+
Assert.assertTrue(countNotNull(sweepAndPrune.getOverlappingPairs()) >= 0);
55+
for (int i = 0; i < BODY_COUNT / 2; i++) {
56+
final AABB aabb = Dummies.newAABB();
57+
final CollisionBody body0 = Dummies.newCollisionBody(ID++);
58+
bodies.add(body0);
59+
sweepAndPrune.addObject(body0, aabb);
60+
final CollisionBody body1 = Dummies.newCollisionBody(ID++);
61+
bodies.add(body1);
62+
sweepAndPrune.addObject(body1, Dummies.newIntersectingAABB(aabb));
63+
}
64+
Assert.assertEquals(BODY_COUNT + BODY_COUNT / 10, sweepAndPrune.getNbObjects());
65+
Assert.assertTrue(countNotNull(sweepAndPrune.getOverlappingPairs()) >= BODY_COUNT / 2);
66+
for (CollisionBody body : bodies) {
67+
sweepAndPrune.removeObject(body);
68+
}
69+
Assert.assertEquals(0, sweepAndPrune.getNbObjects());
70+
bodies.clear();
71+
ID = 0;
7772
}
7873
}
7974

0 commit comments

Comments
 (0)