part of skysprites; abstract class PhysicsJoint { PhysicsJoint(this.bodyA, this.bodyB) { bodyA._joints.add(this); bodyB._joints.add(this); } PhysicsBody bodyA; PhysicsBody bodyB; bool _active = true; box2d.Joint _joint; PhysicsNode _physicsNode; void _completeCreation() { if (bodyA._attached && bodyB._attached) { _attach(bodyA._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.worldAnchor, { double lowerAngle: 0.0, double upperAngle: 0.0, bool enableLimit: false }) : super(bodyA, bodyB) { this.lowerAngle = lowerAngle; this.upperAngle = upperAngle; this.enableLimit = enableLimit; _completeCreation(); } Point worldAnchor; double lowerAngle; double upperAngle; bool enableLimit; box2d.Joint _createB2Joint(PhysicsNode physicsNode) { // Create Joint Definition Vector2 vecAnchor = new Vector2( worldAnchor.x / physicsNode.b2WorldToNodeConversionFactor, worldAnchor.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 PhysicsJointPrismatic extends PhysicsJoint { PhysicsJointPrismatic( PhysicsBody bodyA, PhysicsBody bodyB, this.axis) : super(bodyA, bodyB) { _completeCreation(); } Offset axis; box2d.Joint _createB2Joint(PhysicsNode physicsNode) { box2d.PrismaticJointDef b2Def = new box2d.PrismaticJointDef(); b2Def.initialize(bodyA._body, bodyB._body, bodyA._body.position, new Vector2(axis.dx, axis.dy)); return physicsNode.b2World.createJoint(b2Def); } } class PhysicsJointWeld extends PhysicsJoint { PhysicsJointWeld( PhysicsBody bodyA, PhysicsBody bodyB) : super(bodyA, bodyB) { _completeCreation(); } 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); } }