Commit 4187bcf9 authored by Viktor Lidholt's avatar Viktor Lidholt

Adds sprite physics groups

parent 623b3ba0
......@@ -35,6 +35,7 @@ part 'src/node_with_size.dart';
part 'src/particle_system.dart';
part 'src/physics_body.dart';
part 'src/physics_debug.dart';
part 'src/physics_group.dart';
part 'src/physics_joint.dart';
part 'src/physics_shape.dart';
part 'src/physics_world.dart';
......
......@@ -132,9 +132,8 @@ class Node {
void set rotation(double rotation) {
assert(rotation != null);
if (_physicsBody != null && parent is PhysicsWorld) {
PhysicsWorld physicsNode = parent;
physicsNode._updateRotation(this.physicsBody, rotation);
if (_physicsBody != null && (parent is PhysicsWorld || parent is PhysicsGroup)) {
_updatePhysicsRotation(physicsBody, rotation, parent);
return;
}
......@@ -142,6 +141,19 @@ class Node {
invalidateTransformMatrix();
}
void _updatePhysicsRotation(PhysicsBody body, double rotation, Node physicsParent) {
if (physicsParent == null) return;
if (physicsParent is PhysicsWorld) {
PhysicsWorld world = physicsParent;
world._updateRotation(body, rotation);
} else if (physicsParent is PhysicsGroup) {
_updatePhysicsRotation(body, rotation + physicsParent.rotation, physicsParent.parent);
} else {
assert(false);
}
}
void _setRotationFromPhysics(double rotation) {
assert(rotation != null);
_rotation = rotation;
......@@ -166,9 +178,8 @@ class Node {
void set position(Point position) {
assert(position != null);
if (_physicsBody != null && parent is PhysicsWorld) {
PhysicsWorld physicsNode = parent;
physicsNode._updatePosition(this.physicsBody, position);
if (_physicsBody != null && (parent is PhysicsWorld || parent is PhysicsGroup)) {
_updatePhysicsPosition(this.physicsBody, position, parent);
return;
}
......@@ -176,6 +187,20 @@ class Node {
invalidateTransformMatrix();
}
void _updatePhysicsPosition(PhysicsBody body, Point position, Node physicsParent) {
if (physicsParent == null) return;
if (physicsParent is PhysicsWorld) {
PhysicsWorld world = physicsParent;
world._updatePosition(body, position);
} else if (physicsParent is PhysicsGroup) {
Vector4 parentPos = physicsParent.transformMatrix.transform(new Vector4(position.x, position.y, 0.0, 1.0));
_updatePhysicsPosition(body, new Point(parentPos.x, parentPos.y), physicsParent.parent);
} else {
assert(false);
}
}
void _setPositionFromPhysics(Point position) {
assert(position != null);
_position = position;
......@@ -310,6 +335,7 @@ class Node {
void addChild(Node child) {
assert(child != null);
assert(child._parent == null);
assert(!(child is PhysicsGroup) || this is PhysicsGroup || this is PhysicsWorld);
_childrenNeedSorting = true;
_children.add(child);
......@@ -318,6 +344,10 @@ class Node {
_childrenLastAddedOrder += 1;
child._addedOrder = _childrenLastAddedOrder;
if (_spriteBox != null) _spriteBox._registerNode(child);
if (child is PhysicsGroup) {
child._attachGroup(child, child._world);
}
}
/// Removes a child from this node.
......@@ -330,6 +360,10 @@ class Node {
child._spriteBox = null;
if (_spriteBox != null) _spriteBox._deregisterNode(child);
}
if (child is PhysicsGroup) {
child._detachGroup(child);
}
}
/// Removes this node from its parent node.
......
part of flutter_sprites;
class PhysicsGroup extends Node {
set scaleX(double scaleX) {
assert(false);
}
set scaleY(double scaleX) {
assert(false);
}
set skewX(double scaleX) {
assert(false);
}
set skewY(double scaleX) {
assert(false);
}
set physicsBody(PhysicsBody body) {
assert(false);
}
set position(Point position) {
super.position = position;
_invalidatePhysicsBodies(this);
}
set rotation(double rotation) {
super.rotation = rotation;
_invalidatePhysicsBodies(this);
}
set scale(double scale) {
super.scale = scale;
_invalidatePhysicsBodies(this);
}
void _invalidatePhysicsBodies(Node node) {
if (_world == null) return;
if (node.physicsBody != null) {
// TODO: Add to list
_world._bodiesScheduledForUpdate.add(node.physicsBody);
}
for (Node child in node.children) {
_invalidatePhysicsBodies(child);
}
}
void addChild(Node node) {
super.addChild(node);
PhysicsWorld world = _world;
if (node.physicsBody != null && world != null) {
node.physicsBody._attach(world, node);
}
if (node is PhysicsGroup) {
_attachGroup(this, world);
}
}
void _attachGroup(PhysicsGroup group, PhysicsWorld world) {
for (Node child in group.children) {
if (child is PhysicsGroup) {
_attachGroup(child, world);
} else if (child.physicsBody != null) {
child.physicsBody._attach(world, child);
}
}
}
void removeChild(Node node) {
super.removeChild(node);
if (node.physicsBody != null) {
node.physicsBody._detach();
}
if (node is PhysicsGroup) {
_detachGroup(this);
}
}
void _detachGroup(PhysicsGroup group) {
for (Node child in group.children) {
if (child is PhysicsGroup) {
_detachGroup(child);
} else if (child.physicsBody != null) {
child.physicsBody._detach();
}
}
}
PhysicsWorld get _world {
if (this.parent is PhysicsWorld)
return this.parent;
if (this.parent is PhysicsGroup) {
PhysicsGroup group = this.parent;
return group._world;
}
return null;
}
}
......@@ -43,6 +43,8 @@ class PhysicsWorld extends Node {
List<box2d.Body> _bodiesScheduledForDestruction = [];
List<PhysicsBody> _bodiesScheduledForUpdate = [];
_PhysicsDebugDraw _debugDraw;
double b2WorldToNodeConversionFactor = 10.0;
......@@ -71,6 +73,14 @@ class PhysicsWorld extends Node {
}
void _stepPhysics(double dt) {
// Update transformations of bodies whose groups have moved
for (PhysicsBody body in _bodiesScheduledForUpdate) {
Node node = body._node;
node._updatePhysicsPosition(body, node.position, node.parent);
node._updatePhysicsRotation(body, node.rotation, node.parent);
}
_bodiesScheduledForUpdate.clear();
// Remove bodies that were marked for destruction during the update phase
_removeBodiesScheduledForDestruction();
......
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