Commit 2f07811d authored by Viktor Lidholt's avatar Viktor Lidholt

Merge pull request #1800 from vlidholt/master

sprite nodes now caches inverse transforms
parents 5d374288 957061e9
......@@ -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';
......
......@@ -24,6 +24,7 @@ class Node {
double _rotation = 0.0;
Matrix4 _transformMatrix = new Matrix4.identity();
Matrix4 _transformMatrixInverse;
Matrix4 _transformMatrixNodeToBox;
Matrix4 _transformMatrixBoxToNode;
......@@ -246,9 +247,7 @@ class Node {
return position;
} else if (physicsParent is PhysicsGroup) {
// Transform the position
Matrix4 inverseTransform = new Matrix4.copy(physicsParent.transformMatrix);
inverseTransform.invert();
Vector4 parentPos = inverseTransform.transform(new Vector4(position.x, position.y, 0.0, 1.0));
Vector4 parentPos = physicsParent._inverseMatrix().transform(new Vector4(position.x, position.y, 0.0, 1.0));
Point newPos = new Point(parentPos.x, parentPos.y);
return _positionToPhysics(newPos, physicsParent.parent);
} else {
......@@ -531,6 +530,7 @@ class Node {
/// changes that affects the matrix.
void invalidateTransformMatrix() {
_transformMatrix = null;
_transformMatrixInverse = null;
_invalidateToBoxTransformMatrix();
}
......@@ -575,6 +575,14 @@ class Node {
return _transformMatrixBoxToNode;
}
Matrix4 _inverseMatrix() {
if (_transformMatrixInverse == null) {
_transformMatrixInverse = new Matrix4.copy(transformMatrix);
_transformMatrixInverse.invert();
}
return _transformMatrixInverse;
}
/// Converts a point from the coordinate system of the [SpriteBox] to the local coordinate system of the node.
///
/// This method is particularly useful when handling pointer events and need the pointers position in a local
......
......@@ -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>[];
......
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>[];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment