Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions packages/forge2d/lib/src/dynamics/contacts/contact.dart
Original file line number Diff line number Diff line change
Expand Up @@ -161,19 +161,21 @@ abstract class Contact {
this.indexB == indexA);
}

/// Enable/disable this contact. This can be used inside the pre-solve contact
/// listener. The contact is only disabled for the current time step
/// (or sub-step in continuous collisions).
void setEnabled(bool enable) {
if (enable) {
/// Enable or disable this contact.
///
/// This can be used inside [ContactListener.preSolve]. The contact is
/// only disabled for the current time step (or sub-step in continuous
/// collisions).
set isEnabled(bool value) {
if (value) {
flags |= enabledFlag;
} else {
flags &= ~enabledFlag;
}
}

/// Has this contact been disabled?
bool isEnabled() => (flags & enabledFlag) == enabledFlag;
/// Whether this contact is enabled.
bool get isEnabled => (flags & enabledFlag) == enabledFlag;

void resetFriction() {
_friction = Contact.mixFriction(fixtureA.friction, fixtureB.friction);
Expand Down
10 changes: 5 additions & 5 deletions packages/forge2d/lib/src/dynamics/world.dart
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ class World {
}

// Is this contact solid and touching?
if (contact.isEnabled() == false || contact.isTouching() == false) {
if (contact.isEnabled == false || contact.isTouching() == false) {
continue;
}

Expand Down Expand Up @@ -681,7 +681,7 @@ class World {

for (final contact in contactManager.contacts) {
// Is this contact disabled?
if (contact.isEnabled() == false) {
if (contact.isEnabled == false) {
continue;
}

Expand Down Expand Up @@ -798,9 +798,9 @@ class World {
++minContact.toiCount;

// Is the contact solid?
if (minContact.isEnabled() == false || minContact.isTouching() == false) {
if (minContact.isEnabled == false || minContact.isTouching() == false) {
// Restore the sweeps.
minContact.setEnabled(false);
minContact.isEnabled = false;
bodyA.sweep.set(_backup1);
bodyB.sweep.set(_backup2);
bodyA.synchronizeTransform();
Expand Down Expand Up @@ -855,7 +855,7 @@ class World {
contact.update(contactManager.contactListener);

// Was the contact disabled by the user?
if (contact.isEnabled() == false) {
if (contact.isEnabled == false) {
other.sweep.set(_backup1);
other.synchronizeTransform();
continue;
Expand Down
78 changes: 78 additions & 0 deletions packages/forge2d/test/dynamics/contacts/contact_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import 'package:forge2d/forge2d.dart';
import 'package:mocktail/mocktail.dart';
import 'package:test/test.dart';

class _MockFixture extends Mock implements Fixture {}

class _TestContact extends Contact {
_TestContact(
super.fixtureA,
super.indexA,
super.fixtureB,
super.indexB,
);

@override
void evaluate(_, __, ___) => throw UnimplementedError();
}

void main() {
group('Contact', () {
late Fixture fixtureA;
late int indexA;
late Fixture fixtureB;
late int indexB;

setUp(() {
fixtureA = _MockFixture();
when(() => fixtureA.friction).thenReturn(0);
when(() => fixtureA.restitution).thenReturn(0);

fixtureB = _MockFixture();
when(() => fixtureB.friction).thenReturn(0);
when(() => fixtureB.restitution).thenReturn(0);

indexA = 0;
indexB = 0;
});

test('can be instantiated', () {
expect(
_TestContact(
fixtureA,
indexA,
fixtureB,
indexB,
),
isA<Contact>(),
);
});

group('isEnabled', () {
test('true by default', () {
final contact = _TestContact(
fixtureA,
indexA,
fixtureB,
indexB,
);

expect(contact.isEnabled, isTrue);
});

test('can change', () {
final contact = _TestContact(
fixtureA,
indexA,
fixtureB,
indexB,
);

final newIsEnabled = !contact.isEnabled;
contact.isEnabled = newIsEnabled;

expect(contact.isEnabled, equals(newIsEnabled));
});
});
});
}