mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Adds support for collision categories and masks in sprite physics
This commit is contained in:
parent
ac2a8a6601
commit
957061e9ab
@ -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';
|
||||
|
||||
@ -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<Object> _collisionMask = null;
|
||||
|
||||
List<Object> get collisionMask => _collisionMask;
|
||||
|
||||
set collisionMask(List<Object> 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<box2d.Shape> b2Shapes = <box2d.Shape>[];
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
part of flutter_sprites;
|
||||
|
||||
class _PhysicsCollisionGroups {
|
||||
|
||||
_PhysicsCollisionGroups() {
|
||||
// Make sure there is a default entry in the groups
|
||||
getBitmaskForKeys(["Default"]);
|
||||
}
|
||||
|
||||
Map<Object,int> keyLookup = {};
|
||||
|
||||
List<Object> getKeysForBitmask(int bitmask) {
|
||||
List<Object> keys = [];
|
||||
keyLookup.forEach((key, value) {
|
||||
if (value & bitmask) {
|
||||
keys.add(key);
|
||||
}
|
||||
});
|
||||
return key;
|
||||
}
|
||||
|
||||
int getBitmaskForKeys(List<Object> 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;
|
||||
}
|
||||
}
|
||||
@ -39,6 +39,8 @@ class PhysicsWorld extends Node {
|
||||
|
||||
_ContactHandler _contactHandler;
|
||||
|
||||
_PhysicsCollisionGroups _collisionGroups = new _PhysicsCollisionGroups();
|
||||
|
||||
List<PhysicsJoint> _joints = <PhysicsJoint>[];
|
||||
|
||||
List<box2d.Body> _bodiesScheduledForDestruction = <box2d.Body>[];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user