diff --git a/packages/flutter_sprites/lib/flutter_sprites.dart b/packages/flutter_sprites/lib/flutter_sprites.dart index 97b48b3d5d9..41f68301133 100644 --- a/packages/flutter_sprites/lib/flutter_sprites.dart +++ b/packages/flutter_sprites/lib/flutter_sprites.dart @@ -34,6 +34,7 @@ part 'src/node3d.dart'; part 'src/node_with_size.dart'; part 'src/particle_system.dart'; part 'src/physics_body.dart'; +part 'src/physics_collision_groups.dart'; part 'src/physics_debug.dart'; part 'src/physics_group.dart'; part 'src/physics_joint.dart'; diff --git a/packages/flutter_sprites/lib/src/physics_body.dart b/packages/flutter_sprites/lib/src/physics_body.dart index 62e5df5400c..7d91dda1eaa 100644 --- a/packages/flutter_sprites/lib/src/physics_body.dart +++ b/packages/flutter_sprites/lib/src/physics_body.dart @@ -22,7 +22,9 @@ class PhysicsBody { bool fixedRotation: false, bool bullet: false, bool active: true, - this.gravityScale: 1.0 + this.gravityScale: 1.0, + collisionCategory: "Default", + collisionMask: null }) { this.density = density; this.friction = friction; @@ -38,6 +40,9 @@ class PhysicsBody { this.fixedRotation = fixedRotation; this.bullet = bullet; this.active = active; + + this.collisionCategory = collisionCategory; + this.collisionMask = collisionMask; } Vector2 _lastPosition; @@ -232,6 +237,46 @@ class PhysicsBody { double gravityScale; + Object _collisionCategory = null; + + Object get collisionCategory { + return _collisionCategory; + } + + set collisionCategory(Object collisionCategory) { + _collisionCategory = collisionCategory; + _updateFilter(); + } + + List _collisionMask = null; + + List get collisionMask => _collisionMask; + + set collisionMask(List collisionMask) { + _collisionMask = collisionMask; + _updateFilter(); + } + + box2d.Filter get _b2Filter { + print("_physicsNode: $_physicsNode groups: ${_physicsNode._collisionGroups}"); + box2d.Filter f = new box2d.Filter(); + f.categoryBits = _physicsNode._collisionGroups.getBitmaskForKeys([_collisionCategory]); + f.maskBits = _physicsNode._collisionGroups.getBitmaskForKeys(_collisionMask); + + print("Filter: $f category: ${f.categoryBits} mask: ${f.maskBits}"); + + return f; + } + + void _updateFilter() { + if (_body != null) { + box2d.Filter filter = _b2Filter; + for (box2d.Fixture fixture = _body.getFixtureList(); fixture != null; fixture = fixture.getNext()) { + fixture.setFilterData(filter); + } + } + } + PhysicsWorld _physicsNode; Node _node; @@ -296,6 +341,8 @@ class PhysicsBody { void _attach(PhysicsWorld physicsNode, Node node) { assert(_attached == false); + _physicsNode = physicsNode; + // Account for physics groups Point positionWorld = node._positionToPhysics(node.position, node.parent); double rotationWorld = node._rotationToPhysics(node.rotation, node.parent); @@ -333,7 +380,6 @@ class PhysicsBody { _body.userData = this; - _physicsNode = physicsNode; _node = node; _attached = true; @@ -353,6 +399,7 @@ class PhysicsBody { fixtureDef.restitution = restitution; fixtureDef.density = density; fixtureDef.isSensor = isSensor; + fixtureDef.filter = _b2Filter; // Get shapes List b2Shapes = []; diff --git a/packages/flutter_sprites/lib/src/physics_collision_groups.dart b/packages/flutter_sprites/lib/src/physics_collision_groups.dart new file mode 100644 index 00000000000..6c8a6337053 --- /dev/null +++ b/packages/flutter_sprites/lib/src/physics_collision_groups.dart @@ -0,0 +1,40 @@ +part of flutter_sprites; + +class _PhysicsCollisionGroups { + + _PhysicsCollisionGroups() { + // Make sure there is a default entry in the groups + getBitmaskForKeys(["Default"]); + } + + Map keyLookup = {}; + + List getKeysForBitmask(int bitmask) { + List keys = []; + keyLookup.forEach((key, value) { + if (value & bitmask) { + keys.add(key); + } + }); + return key; + } + + int getBitmaskForKeys(List keys) { + if (keys == null) { + return 0xffff; + } + + int bitmask = 0; + + for (Object key in keys) { + int value = keyLookup[key]; + if (value == null) { + assert(keyLookup.length < 16); + value = 1 << keyLookup.length; + keyLookup[key] = value; + } + bitmask |= value; + } + return bitmask; + } +} diff --git a/packages/flutter_sprites/lib/src/physics_world.dart b/packages/flutter_sprites/lib/src/physics_world.dart index 6a792ca4c3c..14724882451 100644 --- a/packages/flutter_sprites/lib/src/physics_world.dart +++ b/packages/flutter_sprites/lib/src/physics_world.dart @@ -39,6 +39,8 @@ class PhysicsWorld extends Node { _ContactHandler _contactHandler; + _PhysicsCollisionGroups _collisionGroups = new _PhysicsCollisionGroups(); + List _joints = []; List _bodiesScheduledForDestruction = [];