Commit 95a0acea authored by Viktor Lidholt's avatar Viktor Lidholt

Adds basic support for joints in sprite physics

parent 56ac0d9c
......@@ -230,6 +230,8 @@ class PhysicsBody {
box2d.Body _body;
List<PhysicsJoint> _joints = [];
bool _attached = false;
void applyForce(Offset force, Point worldPoint) {
......@@ -338,6 +340,13 @@ class PhysicsBody {
_node = node;
_attached = true;
// Attach any joints
for (PhysicsJoint joint in _joints) {
if (joint.bodyA._attached && joint.bodyB._attached) {
joint._attach(physicsNode);
}
}
}
void _detach() {
......
part of skysprites;
abstract class PhysicsJoint {
PhysicsJoint(this.bodyA, this.bodyB) {
bodyA._joints.add(this);
bodyB._joints.add(this);
if (bodyA._attached && bodyB._attached) {
_attach(bodyA._physicsNode);
}
}
PhysicsBody bodyA;
PhysicsBody bodyB;
bool _active = true;
box2d.Joint _joint;
PhysicsNode _physicsNode;
void _attach(PhysicsNode physicsNode) {
if (_joint == null) {
_physicsNode = physicsNode;
_joint = _createB2Joint(physicsNode);
}
}
void _detach() {
if (_joint != null && _active) {
_physicsNode.b2World.destroyJoint(_joint);
_joint = null;
}
_active = false;
}
box2d.Joint _createB2Joint(PhysicsNode physicsNode);
}
class PhysicsJointRevolute extends PhysicsJoint {
PhysicsJointRevolute(
PhysicsBody bodyA,
PhysicsBody bodyB,
this.anchorWorld, {
double lowerAngle: 0.0,
double upperAngle: 0.0,
bool enableLimit: false
}) : super(bodyA, bodyB) {
this.lowerAngle = lowerAngle;
this.upperAngle = upperAngle;
this.enableLimit = enableLimit;
}
Point anchorWorld;
double lowerAngle;
double upperAngle;
bool enableLimit;
box2d.Joint _createB2Joint(PhysicsNode physicsNode) {
// Create Joint Definition
Vector2 vecAnchor = new Vector2(
anchorWorld.x / physicsNode.b2WorldToNodeConversionFactor,
anchorWorld.y / physicsNode.b2WorldToNodeConversionFactor
);
box2d.RevoluteJointDef b2Def = new box2d.RevoluteJointDef();
b2Def.initialize(bodyA._body, bodyB._body, vecAnchor);
b2Def.enableLimit = enableLimit;
b2Def.lowerAngle = lowerAngle;
b2Def.upperAngle = upperAngle;
// Create joint
return physicsNode.b2World.createJoint(b2Def);
}
}
class PhysicsJointWeld extends PhysicsJoint {
PhysicsJointWeld(
PhysicsBody bodyA,
PhysicsBody bodyB) : super(bodyA, bodyB);
box2d.Joint _createB2Joint(PhysicsNode physicsNode) {
box2d.WeldJointDef b2Def = new box2d.WeldJointDef();
Vector2 middle = new Vector2(
(bodyA._body.position.x + bodyB._body.position.x) / 2.0,
(bodyA._body.position.y + bodyB._body.position.y) / 2.0
);
b2Def.initialize(bodyA._body, bodyB._body, middle);
return physicsNode.b2World.createJoint(b2Def);
}
}
......@@ -83,6 +83,13 @@ class PhysicsNode extends Node {
void _removeBodiesScheduledForDestruction() {
for (box2d.Body b2Body in _bodiesScheduledForDestruction) {
// Destroy any joints before destroying the body
PhysicsBody body = b2Body.userData;
for (PhysicsJoint joint in body._joints) {
joint._detach();
}
// Destroy the body
b2World.destroyBody(b2Body);
}
_bodiesScheduledForDestruction.clear();
......
......@@ -33,6 +33,7 @@ part 'node3d.dart';
part 'node_with_size.dart';
part 'particle_system.dart';
part 'physics_body.dart';
part 'physics_joint.dart';
part 'physics_node.dart';
part 'physics_shape.dart';
part 'sound.dart';
......
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