11/*
2- * Copyright (c) 2023 jMonkeyEngine
2+ * Copyright (c) 2023-2026 jMonkeyEngine
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
@@ -53,21 +53,6 @@ public class DefaultContactManager implements ContactManager {
5353 // *************************************************************************
5454 // constants and loggers
5555
56- /**
57- * bitmask to indicate that the {@code onContactEnded()} method of a
58- * particular ContactListener should be invoked
59- */
60- final private static int invokeEnded = 0x2 ;
61- /**
62- * bitmask to indicate that the {@code onContactProcessed()} method of a
63- * particular ContactListener should be invoked
64- */
65- final private static int invokeProcessed = 0x10 ;
66- /**
67- * bitmask to indicate that the {@code onContactStarted()} method of a
68- * particular ContactListener should be invoked
69- */
70- final private static int invokeStarted = 0x80 ;
7156 /**
7257 * message logger for this class
7358 */
@@ -76,21 +61,6 @@ public class DefaultContactManager implements ContactManager {
7661 // *************************************************************************
7762 // fields
7863
79- /**
80- * true to request {@code onContactEnded()} callbacks for the space, false
81- * to skip them
82- */
83- private boolean doEnded = false ;
84- /**
85- * true to request {@code onContactProcessed()} callbacks for the space,
86- * false to skip them
87- */
88- private boolean doProcessed = false ;
89- /**
90- * true to request {@code onContactStarted()} callbacks for the space, false
91- * to skip them
92- */
93- private boolean doStarted = false ;
9464 /**
9565 * registered listeners for delayed notification of ongoing contacts
9666 */
@@ -111,14 +81,20 @@ public class DefaultContactManager implements ContactManager {
11181 */
11282 final private Deque <PhysicsCollisionEvent > startedEvents
11383 = new ArrayDeque <>(99 );
84+ /**
85+ * step flags of callbacks needed by the registered listeners, ORed together
86+ *
87+ * @see com.jme3.bullet.StepFlag
88+ */
89+ private int stepFlags = 0x0 ;
11490 /**
11591 * list of registered listeners for immediate contact notifications
11692 * (parallel with {@code immediateListenerFlags})
11793 */
11894 final private List <ContactListener > immediateListeners = new ArrayList <>(4 );
11995 /**
120- * list of invocation flags for immediate contact notifications (parallel
121- * with {@code immediateListeners})
96+ * list of step flags for immediate contact notifications (parallel with
97+ * {@code immediateListeners})
12298 */
12399 final private List <Integer > immediateListenerFlags = new ArrayList <>(4 );
124100 /**
@@ -158,44 +134,26 @@ public synchronized void addCollisionListener(
158134 assert !startedListeners .contains (listener );
159135
160136 startedListeners .add (listener );
161- this .doStarted = true ;
137+ this .stepFlags |= StepFlag . contactStarted ;
162138 }
163139
164140 /**
165141 * Register the specified listener for immediate contact notifications.
166142 *
167143 * @param listener the listener to register (not null, alias created)
168- * @param doEnded true to enable {@code onContactEnded()} callbacks for the
169- * listener, false to skip them
170- * @param doProcessed true to enable {@code onContactProcessed()} callbacks
171- * for the listener, false to skip them
172- * @param doStarted true to enable {@code onContactStarted()} callbacks for
173- * the listener, false to skip them
144+ * @param stepFlags the step flags for this listener, ORed together
174145 */
175146 @ Override
176- public synchronized void addContactListener (ContactListener listener ,
177- boolean doEnded , boolean doProcessed , boolean doStarted ) {
147+ public synchronized void addContactListener (
148+ ContactListener listener , int stepFlags ) {
178149 Validate .nonNull (listener , "listener" );
179150 assert listener != this ;
180151 assert listener != space ;
181152 assert !immediateListeners .contains (listener );
182153
183154 immediateListeners .add (listener );
184-
185- int encodedFlags = (doEnded ? invokeEnded : 0x0 )
186- | (doProcessed ? invokeProcessed : 0x0 )
187- | (doStarted ? invokeStarted : 0x0 );
188- immediateListenerFlags .add (encodedFlags );
189-
190- if (doEnded ) {
191- this .doEnded = true ;
192- }
193- if (doProcessed ) {
194- this .doProcessed = true ;
195- }
196- if (doStarted ) {
197- this .doStarted = true ;
198- }
155+ immediateListenerFlags .add (stepFlags );
156+ this .stepFlags |= stepFlags ;
199157 }
200158
201159 /**
@@ -215,7 +173,7 @@ public synchronized void addOngoingCollisionListener(
215173 assert !ongoingListeners .contains (listener );
216174
217175 ongoingListeners .add (listener );
218- this .doProcessed = true ;
176+ this .stepFlags |= StepFlag . contactProcessed ;
219177 }
220178
221179 /**
@@ -299,26 +257,46 @@ public synchronized void removeOngoingCollisionListener(
299257 }
300258
301259 /**
302- * Update the associated PhysicsSpace. This method should be invoked from
303- * the thread that created the space.
260+ * Update the associated PhysicsSpace, enabling the specified additional
261+ * callbacks. This method should be invoked from the thread that created the
262+ * space.
304263 *
305264 * @param timeInterval the time interval to simulate (in seconds, ≥0)
306- * @param maxSteps the maximum number of steps of size {@code accuracy}
307- * (≥1) or 0 for a single step of size {@code timeInterval}
265+ * @param maxSteps the maximum number of simulation steps of size
266+ * {@code accuracy} (≥1) or 0 for a single simulation step of size
267+ * {@code timeInterval}
268+ * @param addFlags the desired callbacks, ORed together (default=0x0)
269+ * @see com.jme3.bullet.StepFlag
308270 */
309271 @ Override
310- public void update (float timeInterval , int maxSteps ) {
272+ public void update (float timeInterval , int maxSteps , int addFlags ) {
311273 assert Validate .nonNegative (timeInterval , "time interval" );
312274 assert Validate .nonNegative (maxSteps , "max steps" );
313275
314- space .update (timeInterval , maxSteps , doEnded , doProcessed , doStarted );
276+ int flags = stepFlags | addFlags ;
277+ space .update (timeInterval , maxSteps , flags );
315278 }
316279 // *************************************************************************
317280 // ContactListener methods
318281
319282 /**
320- * Invoked immediately after a contact manifold is destroyed. Skipped if
321- * stepSimulation() was invoked with doEnded=false.
283+ * Invoked immediately before a contact point is added to a manifold.
284+ *
285+ * @param pointId the native ID of the {@code btManifoldPoint} (not zero)
286+ * @param manifoldId the native ID of the {@code btPersistentManifold} (not
287+ * zero)
288+ * @param pcoA the "A" collision object (not null)
289+ * @param pcoB the "B" collision object (not null)
290+ * @return true to accept the contact, or false to reject it
291+ */
292+ @ Override
293+ public boolean onContactConceived (long pointId , long manifoldId ,
294+ PhysicsCollisionObject pcoA , PhysicsCollisionObject pcoB ) {
295+ return true ;
296+ }
297+
298+ /**
299+ * Invoked immediately after a contact manifold is destroyed.
322300 *
323301 * @param manifoldId the native ID of the {@code btPersistentManifold} (not
324302 * zero)
@@ -328,7 +306,7 @@ public void onContactEnded(long manifoldId) {
328306 int numImmediateListeners = immediateListeners .size ();
329307 for (int i = 0 ; i < numImmediateListeners ; ++i ) {
330308 int flags = immediateListenerFlags .get (i );
331- if ((flags & invokeEnded ) != 0x0 ) {
309+ if ((flags & StepFlag . contactEnded ) != 0x0 ) {
332310 ContactListener listener = immediateListeners .get (i );
333311 listener .onContactEnded (manifoldId );
334312 }
@@ -337,8 +315,7 @@ public void onContactEnded(long manifoldId) {
337315
338316 /**
339317 * Invoked immediately after a contact point is refreshed without being
340- * destroyed. Skipped for Sphere-Sphere contacts. Skipped if
341- * stepSimulation() was invoked with doProcessed=false.
318+ * destroyed. Skipped for Sphere-Sphere contacts.
342319 *
343320 * @param pcoA the first involved object (not null)
344321 * @param pcoB the 2nd involved object (not null)
@@ -350,7 +327,7 @@ public void onContactProcessed(PhysicsCollisionObject pcoA,
350327 int numImmediateListeners = immediateListeners .size ();
351328 for (int i = 0 ; i < numImmediateListeners ; ++i ) {
352329 int flags = immediateListenerFlags .get (i );
353- if ((flags & invokeProcessed ) != 0x0 ) {
330+ if ((flags & StepFlag . contactProcessed ) != 0x0 ) {
354331 ContactListener listener = immediateListeners .get (i );
355332 listener .onContactProcessed (pcoA , pcoB , pointId );
356333 }
@@ -366,8 +343,7 @@ public void onContactProcessed(PhysicsCollisionObject pcoA,
366343 }
367344
368345 /**
369- * Invoked immediately after a contact manifold is created. Skipped if
370- * stepSimulation() was invoked with doStarted=false.
346+ * Invoked immediately after a contact manifold is created.
371347 *
372348 * @param manifoldId the native ID of the {@code btPersistentManifold} (not
373349 * zero)
@@ -377,7 +353,7 @@ public void onContactStarted(long manifoldId) {
377353 int numImmediateListeners = immediateListeners .size ();
378354 for (int i = 0 ; i < numImmediateListeners ; ++i ) {
379355 int flags = immediateListenerFlags .get (i );
380- if ((flags & invokeStarted ) != 0x0 ) {
356+ if ((flags & StepFlag . contactStarted ) != 0x0 ) {
381357 ContactListener listener = immediateListeners .get (i );
382358 listener .onContactStarted (manifoldId );
383359 }
@@ -411,19 +387,19 @@ public void onContactStarted(long manifoldId) {
411387 // new private methods
412388
413389 /**
414- * Update the doEnded, doProcessed, and doStarted flags after a listener is
415- * removed.
390+ * Update the {@code stepFlags} field after a listener is removed.
416391 */
417392 private void updateFlags () {
418393 int union = 0x0 ;
419394 for (int flags : immediateListenerFlags ) {
420395 union |= flags ;
421396 }
422-
423- this .doEnded = ((union & invokeEnded ) != 0x0 );
424- this .doProcessed = ((union & invokeProcessed ) != 0x0 )
425- || !ongoingListeners .isEmpty ();
426- this .doStarted = ((union & invokeStarted ) != 0x0 )
427- || !startedListeners .isEmpty ();
397+ if (!ongoingListeners .isEmpty ()) {
398+ union |= StepFlag .contactProcessed ;
399+ }
400+ if (!startedListeners .isEmpty ()) {
401+ union |= StepFlag .contactStarted ;
402+ }
403+ this .stepFlags = union ;
428404 }
429405}
0 commit comments