From aace84d7adc12cdc6f452255765a0c29dde42db8 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 19 Jan 2011 20:11:40 +1300 Subject: [PATCH 001/176] Fixed typo in function name --- src/libs/cocos2d/nodes/Node.js | 4 ++-- src/libs/geometry.js | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index be1471b..81895f2 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -305,7 +305,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ } // Rotate - context.rotate(geom.degressToRadians(this.get('rotation'))); + context.rotate(geom.degreesToRadians(this.get('rotation'))); // Scale context.scale(this.scaleX, this.scaleY); @@ -332,7 +332,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ } if(this.rotation != 0) { - this.transformMatrix = geom.affineTransformRotate(this.transformMatrix, -geom.degressToRadians(this.rotation)); + this.transformMatrix = geom.affineTransformRotate(this.transformMatrix, -geom.degreesToRadians(this.rotation)); } if(!(this.scaleX == 1 && this.scaleY == 1)) { this.transformMatrix = geom.affineTransformScale(this.transformMatrix, this.scaleX, this.scaleY); diff --git a/src/libs/geometry.js b/src/libs/geometry.js index debd991..c923633 100644 --- a/src/libs/geometry.js +++ b/src/libs/geometry.js @@ -453,10 +453,17 @@ var geometry = { /** * @returns {Float} */ - degressToRadians: function(angle) { + degreesToRadians: function(angle) { return angle / 180.0 * Math.PI; }, + /** + * @returns {Float} + */ + radiansToDegrees: function(angle) { + return angle * (180.0 / Math.PI); + }, + /** * @returns {Float[]} */ From f1ea4692086893aff6ed39a139b2d34a87e5bf4f Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 19 Jan 2011 20:11:54 +1300 Subject: [PATCH 002/176] Added Box2D module --- src/libs/box2d.js | 12013 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 12013 insertions(+) create mode 100644 src/libs/box2d.js diff --git a/src/libs/box2d.js b/src/libs/box2d.js new file mode 100644 index 0000000..79b08db --- /dev/null +++ b/src/libs/box2d.js @@ -0,0 +1,12013 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ +var a2j = {}; + +var helpers = {}, + Vector; + +(function (a2j, helpers) { + + if(!helpers.flash) helpers.flash = {utils: {Dictionary: Object} }; + else if(!helpers.flash.utils) helpers.flash.utils = {Dictionary: Object}; + else if(!helpers.flash.utils.Dictionary) helpers.flash.utils.Dictionary = Object; + + Vector = window.Array; + + helpers.inherit = function (base) { + var tmpCtr = this; + var empty = helpers.inherit.empty; + empty.prototype = base.prototype; + this.prototype = new empty(); + this.prototype.constructor = tmpCtr; + }; + helpers.inherit.empty = function () {}; + + helpers.trace = function () { + if (window.console && (window.console.log instanceof Function)) window.console.log.apply(window.console, arguments); + }; + helpers.assert = function () { + if (window.console && (window.console.assert instanceof Function)) window.console.assert.apply(window.console, arguments); + }; + + a2j.warn = function warn() { + if (window.console) console.warn.apply(console, arguments); + }; + + a2j.generateCallback = function generateCallback(context, cb) { + return function () { + cb.apply(context, arguments); + }; + }; + + a2j.NVector = function NVector(length) { + if (length === undefined) length = 0; + var tmp = new Array(length || 0); + for (var i = 0; i < length; ++i) + tmp[i] = 0; + return tmp; + }; + + a2j.is = function is(o1, o2) { + if (o1 === null) return false; + if ((o2 instanceof Function) && (o1 instanceof o2)) return true; + if ((o1.constructor.__implements != undefined) && (o1.constructor.__implements[o2])) return true; + return false; + }; + + a2j.parseUInt = function(v) { + return Math.abs(parseInt(v)); + } + +})(a2j, helpers, undefined); + +var Vector_a2j_Number = a2j.NVector; +var Box2D; + +//package structure +if (!Box2D) Box2D = {}; +if (!Box2D.Collision) Box2D.Collision = {}; +if (!Box2D.Collision.Shapes) Box2D.Collision.Shapes = {}; +if (!Box2D.Common) Box2D.Common = {}; +if (!Box2D.Common.Math) Box2D.Common.Math = {}; +if (!Box2D.Dynamics) Box2D.Dynamics = {}; +if (!Box2D.Dynamics.Contacts) Box2D.Dynamics.Contacts = {}; +if (!Box2D.Dynamics.Controllers) Box2D.Dynamics.Controllers = {}; +if (!Box2D.Dynamics.Joints) Box2D.Dynamics.Joints = {}; +//pre-definitions +(function () { + Box2D.Collision.IBroadPhase = 'Box2D.Collision.IBroadPhase'; + + function b2AABB() { + b2AABB.b2AABB.apply(this, arguments); + }; + Box2D.Collision.b2AABB = b2AABB; + + function b2Bound() { + b2Bound.b2Bound.apply(this, arguments); + }; + Box2D.Collision.b2Bound = b2Bound; + + function b2BoundValues() { + b2BoundValues.b2BoundValues.apply(this, arguments); + if (this.constructor === b2BoundValues) this.b2BoundValues.apply(this, arguments); + }; + Box2D.Collision.b2BoundValues = b2BoundValues; + + function b2BroadPhase() { + b2BroadPhase.b2BroadPhase.apply(this, arguments); + if (this.constructor === b2BroadPhase) this.b2BroadPhase.apply(this, arguments); + }; + Box2D.Collision.b2BroadPhase = b2BroadPhase; + + function b2Collision() { + b2Collision.b2Collision.apply(this, arguments); + }; + Box2D.Collision.b2Collision = b2Collision; + + function b2ContactID() { + b2ContactID.b2ContactID.apply(this, arguments); + if (this.constructor === b2ContactID) this.b2ContactID.apply(this, arguments); + }; + Box2D.Collision.b2ContactID = b2ContactID; + + function b2ContactPoint() { + b2ContactPoint.b2ContactPoint.apply(this, arguments); + }; + Box2D.Collision.b2ContactPoint = b2ContactPoint; + + function b2Distance() { + b2Distance.b2Distance.apply(this, arguments); + }; + Box2D.Collision.b2Distance = b2Distance; + + function b2DistanceInput() { + b2DistanceInput.b2DistanceInput.apply(this, arguments); + }; + Box2D.Collision.b2DistanceInput = b2DistanceInput; + + function b2DistanceOutput() { + b2DistanceOutput.b2DistanceOutput.apply(this, arguments); + }; + Box2D.Collision.b2DistanceOutput = b2DistanceOutput; + + function b2DistanceProxy() { + b2DistanceProxy.b2DistanceProxy.apply(this, arguments); + }; + Box2D.Collision.b2DistanceProxy = b2DistanceProxy; + + function b2DynamicTree() { + b2DynamicTree.b2DynamicTree.apply(this, arguments); + if (this.constructor === b2DynamicTree) this.b2DynamicTree.apply(this, arguments); + }; + Box2D.Collision.b2DynamicTree = b2DynamicTree; + + function b2DynamicTreeBroadPhase() { + b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase.apply(this, arguments); + }; + Box2D.Collision.b2DynamicTreeBroadPhase = b2DynamicTreeBroadPhase; + + function b2DynamicTreeNode() { + b2DynamicTreeNode.b2DynamicTreeNode.apply(this, arguments); + }; + Box2D.Collision.b2DynamicTreeNode = b2DynamicTreeNode; + + function b2DynamicTreePair() { + b2DynamicTreePair.b2DynamicTreePair.apply(this, arguments); + }; + Box2D.Collision.b2DynamicTreePair = b2DynamicTreePair; + + function b2Manifold() { + b2Manifold.b2Manifold.apply(this, arguments); + if (this.constructor === b2Manifold) this.b2Manifold.apply(this, arguments); + }; + Box2D.Collision.b2Manifold = b2Manifold; + + function b2ManifoldPoint() { + b2ManifoldPoint.b2ManifoldPoint.apply(this, arguments); + if (this.constructor === b2ManifoldPoint) this.b2ManifoldPoint.apply(this, arguments); + }; + Box2D.Collision.b2ManifoldPoint = b2ManifoldPoint; + + function b2OBB() { + b2OBB.b2OBB.apply(this, arguments); + }; + Box2D.Collision.b2OBB = b2OBB; + + function b2Pair() { + b2Pair.b2Pair.apply(this, arguments); + }; + Box2D.Collision.b2Pair = b2Pair; + + function b2PairManager() { + b2PairManager.b2PairManager.apply(this, arguments); + if (this.constructor === b2PairManager) this.b2PairManager.apply(this, arguments); + }; + Box2D.Collision.b2PairManager = b2PairManager; + + function b2Point() { + b2Point.b2Point.apply(this, arguments); + }; + Box2D.Collision.b2Point = b2Point; + + function b2Proxy() { + b2Proxy.b2Proxy.apply(this, arguments); + }; + Box2D.Collision.b2Proxy = b2Proxy; + + function b2RayCastInput() { + b2RayCastInput.b2RayCastInput.apply(this, arguments); + if (this.constructor === b2RayCastInput) this.b2RayCastInput.apply(this, arguments); + }; + Box2D.Collision.b2RayCastInput = b2RayCastInput; + + function b2RayCastOutput() { + b2RayCastOutput.b2RayCastOutput.apply(this, arguments); + }; + Box2D.Collision.b2RayCastOutput = b2RayCastOutput; + + function b2Segment() { + b2Segment.b2Segment.apply(this, arguments); + }; + Box2D.Collision.b2Segment = b2Segment; + + function b2SeparationFunction() { + b2SeparationFunction.b2SeparationFunction.apply(this, arguments); + }; + Box2D.Collision.b2SeparationFunction = b2SeparationFunction; + + function b2Simplex() { + b2Simplex.b2Simplex.apply(this, arguments); + if (this.constructor === b2Simplex) this.b2Simplex.apply(this, arguments); + }; + Box2D.Collision.b2Simplex = b2Simplex; + + function b2SimplexCache() { + b2SimplexCache.b2SimplexCache.apply(this, arguments); + }; + Box2D.Collision.b2SimplexCache = b2SimplexCache; + + function b2SimplexVertex() { + b2SimplexVertex.b2SimplexVertex.apply(this, arguments); + }; + Box2D.Collision.b2SimplexVertex = b2SimplexVertex; + + function b2TimeOfImpact() { + b2TimeOfImpact.b2TimeOfImpact.apply(this, arguments); + }; + Box2D.Collision.b2TimeOfImpact = b2TimeOfImpact; + + function b2TOIInput() { + b2TOIInput.b2TOIInput.apply(this, arguments); + }; + Box2D.Collision.b2TOIInput = b2TOIInput; + + function b2WorldManifold() { + b2WorldManifold.b2WorldManifold.apply(this, arguments); + if (this.constructor === b2WorldManifold) this.b2WorldManifold.apply(this, arguments); + }; + Box2D.Collision.b2WorldManifold = b2WorldManifold; + + function ClipVertex() { + ClipVertex.ClipVertex.apply(this, arguments); + }; + Box2D.Collision.ClipVertex = ClipVertex; + + function Features() { + Features.Features.apply(this, arguments); + }; + Box2D.Collision.Features = Features; + + function b2CircleShape() { + b2CircleShape.b2CircleShape.apply(this, arguments); + if (this.constructor === b2CircleShape) this.b2CircleShape.apply(this, arguments); + }; + Box2D.Collision.Shapes.b2CircleShape = b2CircleShape; + + function b2EdgeChainDef() { + b2EdgeChainDef.b2EdgeChainDef.apply(this, arguments); + if (this.constructor === b2EdgeChainDef) this.b2EdgeChainDef.apply(this, arguments); + }; + Box2D.Collision.Shapes.b2EdgeChainDef = b2EdgeChainDef; + + function b2EdgeShape() { + b2EdgeShape.b2EdgeShape.apply(this, arguments); + if (this.constructor === b2EdgeShape) this.b2EdgeShape.apply(this, arguments); + }; + Box2D.Collision.Shapes.b2EdgeShape = b2EdgeShape; + + function b2MassData() { + b2MassData.b2MassData.apply(this, arguments); + }; + Box2D.Collision.Shapes.b2MassData = b2MassData; + + function b2PolygonShape() { + b2PolygonShape.b2PolygonShape.apply(this, arguments); + if (this.constructor === b2PolygonShape) this.b2PolygonShape.apply(this, arguments); + }; + Box2D.Collision.Shapes.b2PolygonShape = b2PolygonShape; + + function b2Shape() { + b2Shape.b2Shape.apply(this, arguments); + if (this.constructor === b2Shape) this.b2Shape.apply(this, arguments); + }; + Box2D.Collision.Shapes.b2Shape = b2Shape; + Box2D.Common.b2internal = 'Box2D.Common.b2internal'; + + function b2Color() { + b2Color.b2Color.apply(this, arguments); + if (this.constructor === b2Color) this.b2Color.apply(this, arguments); + }; + Box2D.Common.b2Color = b2Color; + + function b2Settings() { + b2Settings.b2Settings.apply(this, arguments); + }; + Box2D.Common.b2Settings = b2Settings; + + function b2Mat22() { + b2Mat22.b2Mat22.apply(this, arguments); + if (this.constructor === b2Mat22) this.b2Mat22.apply(this, arguments); + }; + Box2D.Common.Math.b2Mat22 = b2Mat22; + + function b2Mat33() { + b2Mat33.b2Mat33.apply(this, arguments); + if (this.constructor === b2Mat33) this.b2Mat33.apply(this, arguments); + }; + Box2D.Common.Math.b2Mat33 = b2Mat33; + + function b2Math() { + b2Math.b2Math.apply(this, arguments); + }; + Box2D.Common.Math.b2Math = b2Math; + + function b2Sweep() { + b2Sweep.b2Sweep.apply(this, arguments); + }; + Box2D.Common.Math.b2Sweep = b2Sweep; + + function b2Transform() { + b2Transform.b2Transform.apply(this, arguments); + if (this.constructor === b2Transform) this.b2Transform.apply(this, arguments); + }; + Box2D.Common.Math.b2Transform = b2Transform; + + function b2Vec2() { + b2Vec2.b2Vec2.apply(this, arguments); + if (this.constructor === b2Vec2) this.b2Vec2.apply(this, arguments); + }; + Box2D.Common.Math.b2Vec2 = b2Vec2; + + function b2Vec3() { + b2Vec3.b2Vec3.apply(this, arguments); + if (this.constructor === b2Vec3) this.b2Vec3.apply(this, arguments); + }; + Box2D.Common.Math.b2Vec3 = b2Vec3; + + function b2Body() { + b2Body.b2Body.apply(this, arguments); + if (this.constructor === b2Body) this.b2Body.apply(this, arguments); + }; + Box2D.Dynamics.b2Body = b2Body; + + function b2BodyDef() { + b2BodyDef.b2BodyDef.apply(this, arguments); + if (this.constructor === b2BodyDef) this.b2BodyDef.apply(this, arguments); + }; + Box2D.Dynamics.b2BodyDef = b2BodyDef; + + function b2ContactFilter() { + b2ContactFilter.b2ContactFilter.apply(this, arguments); + }; + Box2D.Dynamics.b2ContactFilter = b2ContactFilter; + + function b2ContactImpulse() { + b2ContactImpulse.b2ContactImpulse.apply(this, arguments); + }; + Box2D.Dynamics.b2ContactImpulse = b2ContactImpulse; + + function b2ContactListener() { + b2ContactListener.b2ContactListener.apply(this, arguments); + }; + Box2D.Dynamics.b2ContactListener = b2ContactListener; + + function b2ContactManager() { + b2ContactManager.b2ContactManager.apply(this, arguments); + if (this.constructor === b2ContactManager) this.b2ContactManager.apply(this, arguments); + }; + Box2D.Dynamics.b2ContactManager = b2ContactManager; + + function b2DebugDraw() { + b2DebugDraw.b2DebugDraw.apply(this, arguments); + if (this.constructor === b2DebugDraw) this.b2DebugDraw.apply(this, arguments); + }; + Box2D.Dynamics.b2DebugDraw = b2DebugDraw; + + function b2DestructionListener() { + b2DestructionListener.b2DestructionListener.apply(this, arguments); + }; + Box2D.Dynamics.b2DestructionListener = b2DestructionListener; + + function b2FilterData() { + b2FilterData.b2FilterData.apply(this, arguments); + }; + Box2D.Dynamics.b2FilterData = b2FilterData; + + function b2Fixture() { + b2Fixture.b2Fixture.apply(this, arguments); + if (this.constructor === b2Fixture) this.b2Fixture.apply(this, arguments); + }; + Box2D.Dynamics.b2Fixture = b2Fixture; + + function b2FixtureDef() { + b2FixtureDef.b2FixtureDef.apply(this, arguments); + if (this.constructor === b2FixtureDef) this.b2FixtureDef.apply(this, arguments); + }; + Box2D.Dynamics.b2FixtureDef = b2FixtureDef; + + function b2Island() { + b2Island.b2Island.apply(this, arguments); + if (this.constructor === b2Island) this.b2Island.apply(this, arguments); + }; + Box2D.Dynamics.b2Island = b2Island; + + function b2TimeStep() { + b2TimeStep.b2TimeStep.apply(this, arguments); + }; + Box2D.Dynamics.b2TimeStep = b2TimeStep; + + function b2World() { + b2World.b2World.apply(this, arguments); + if (this.constructor === b2World) this.b2World.apply(this, arguments); + }; + Box2D.Dynamics.b2World = b2World; + + function b2CircleContact() { + b2CircleContact.b2CircleContact.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2CircleContact = b2CircleContact; + + function b2Contact() { + b2Contact.b2Contact.apply(this, arguments); + if (this.constructor === b2Contact) this.b2Contact.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2Contact = b2Contact; + + function b2ContactConstraint() { + b2ContactConstraint.b2ContactConstraint.apply(this, arguments); + if (this.constructor === b2ContactConstraint) this.b2ContactConstraint.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2ContactConstraint = b2ContactConstraint; + + function b2ContactConstraintPoint() { + b2ContactConstraintPoint.b2ContactConstraintPoint.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2ContactConstraintPoint = b2ContactConstraintPoint; + + function b2ContactEdge() { + b2ContactEdge.b2ContactEdge.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2ContactEdge = b2ContactEdge; + + function b2ContactFactory() { + b2ContactFactory.b2ContactFactory.apply(this, arguments); + if (this.constructor === b2ContactFactory) this.b2ContactFactory.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2ContactFactory = b2ContactFactory; + + function b2ContactRegister() { + b2ContactRegister.b2ContactRegister.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2ContactRegister = b2ContactRegister; + + function b2ContactResult() { + b2ContactResult.b2ContactResult.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2ContactResult = b2ContactResult; + + function b2ContactSolver() { + b2ContactSolver.b2ContactSolver.apply(this, arguments); + if (this.constructor === b2ContactSolver) this.b2ContactSolver.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2ContactSolver = b2ContactSolver; + + function b2EdgeAndCircleContact() { + b2EdgeAndCircleContact.b2EdgeAndCircleContact.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2EdgeAndCircleContact = b2EdgeAndCircleContact; + + function b2NullContact() { + b2NullContact.b2NullContact.apply(this, arguments); + if (this.constructor === b2NullContact) this.b2NullContact.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2NullContact = b2NullContact; + + function b2PolyAndCircleContact() { + b2PolyAndCircleContact.b2PolyAndCircleContact.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2PolyAndCircleContact = b2PolyAndCircleContact; + + function b2PolyAndEdgeContact() { + b2PolyAndEdgeContact.b2PolyAndEdgeContact.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2PolyAndEdgeContact = b2PolyAndEdgeContact; + + function b2PolygonContact() { + b2PolygonContact.b2PolygonContact.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2PolygonContact = b2PolygonContact; + + function b2PositionSolverManifold() { + b2PositionSolverManifold.b2PositionSolverManifold.apply(this, arguments); + if (this.constructor === b2PositionSolverManifold) this.b2PositionSolverManifold.apply(this, arguments); + }; + Box2D.Dynamics.Contacts.b2PositionSolverManifold = b2PositionSolverManifold; + + function b2BuoyancyController() { + b2BuoyancyController.b2BuoyancyController.apply(this, arguments); + }; + Box2D.Dynamics.Controllers.b2BuoyancyController = b2BuoyancyController; + + function b2ConstantAccelController() { + b2ConstantAccelController.b2ConstantAccelController.apply(this, arguments); + }; + Box2D.Dynamics.Controllers.b2ConstantAccelController = b2ConstantAccelController; + + function b2ConstantForceController() { + b2ConstantForceController.b2ConstantForceController.apply(this, arguments); + }; + Box2D.Dynamics.Controllers.b2ConstantForceController = b2ConstantForceController; + + function b2Controller() { + b2Controller.b2Controller.apply(this, arguments); + }; + Box2D.Dynamics.Controllers.b2Controller = b2Controller; + + function b2ControllerEdge() { + b2ControllerEdge.b2ControllerEdge.apply(this, arguments); + }; + Box2D.Dynamics.Controllers.b2ControllerEdge = b2ControllerEdge; + + function b2GravityController() { + b2GravityController.b2GravityController.apply(this, arguments); + }; + Box2D.Dynamics.Controllers.b2GravityController = b2GravityController; + + function b2TensorDampingController() { + b2TensorDampingController.b2TensorDampingController.apply(this, arguments); + }; + Box2D.Dynamics.Controllers.b2TensorDampingController = b2TensorDampingController; + + function b2DistanceJoint() { + b2DistanceJoint.b2DistanceJoint.apply(this, arguments); + if (this.constructor === b2DistanceJoint) this.b2DistanceJoint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2DistanceJoint = b2DistanceJoint; + + function b2DistanceJointDef() { + b2DistanceJointDef.b2DistanceJointDef.apply(this, arguments); + if (this.constructor === b2DistanceJointDef) this.b2DistanceJointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2DistanceJointDef = b2DistanceJointDef; + + function b2FrictionJoint() { + b2FrictionJoint.b2FrictionJoint.apply(this, arguments); + if (this.constructor === b2FrictionJoint) this.b2FrictionJoint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2FrictionJoint = b2FrictionJoint; + + function b2FrictionJointDef() { + b2FrictionJointDef.b2FrictionJointDef.apply(this, arguments); + if (this.constructor === b2FrictionJointDef) this.b2FrictionJointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2FrictionJointDef = b2FrictionJointDef; + + function b2GearJoint() { + b2GearJoint.b2GearJoint.apply(this, arguments); + if (this.constructor === b2GearJoint) this.b2GearJoint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2GearJoint = b2GearJoint; + + function b2GearJointDef() { + b2GearJointDef.b2GearJointDef.apply(this, arguments); + if (this.constructor === b2GearJointDef) this.b2GearJointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2GearJointDef = b2GearJointDef; + + function b2Jacobian() { + b2Jacobian.b2Jacobian.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2Jacobian = b2Jacobian; + + function b2Joint() { + b2Joint.b2Joint.apply(this, arguments); + if (this.constructor === b2Joint) this.b2Joint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2Joint = b2Joint; + + function b2JointDef() { + b2JointDef.b2JointDef.apply(this, arguments); + if (this.constructor === b2JointDef) this.b2JointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2JointDef = b2JointDef; + + function b2JointEdge() { + b2JointEdge.b2JointEdge.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2JointEdge = b2JointEdge; + + function b2LineJoint() { + b2LineJoint.b2LineJoint.apply(this, arguments); + if (this.constructor === b2LineJoint) this.b2LineJoint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2LineJoint = b2LineJoint; + + function b2LineJointDef() { + b2LineJointDef.b2LineJointDef.apply(this, arguments); + if (this.constructor === b2LineJointDef) this.b2LineJointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2LineJointDef = b2LineJointDef; + + function b2MouseJoint() { + b2MouseJoint.b2MouseJoint.apply(this, arguments); + if (this.constructor === b2MouseJoint) this.b2MouseJoint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2MouseJoint = b2MouseJoint; + + function b2MouseJointDef() { + b2MouseJointDef.b2MouseJointDef.apply(this, arguments); + if (this.constructor === b2MouseJointDef) this.b2MouseJointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2MouseJointDef = b2MouseJointDef; + + function b2PrismaticJoint() { + b2PrismaticJoint.b2PrismaticJoint.apply(this, arguments); + if (this.constructor === b2PrismaticJoint) this.b2PrismaticJoint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2PrismaticJoint = b2PrismaticJoint; + + function b2PrismaticJointDef() { + b2PrismaticJointDef.b2PrismaticJointDef.apply(this, arguments); + if (this.constructor === b2PrismaticJointDef) this.b2PrismaticJointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2PrismaticJointDef = b2PrismaticJointDef; + + function b2PulleyJoint() { + b2PulleyJoint.b2PulleyJoint.apply(this, arguments); + if (this.constructor === b2PulleyJoint) this.b2PulleyJoint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2PulleyJoint = b2PulleyJoint; + + function b2PulleyJointDef() { + b2PulleyJointDef.b2PulleyJointDef.apply(this, arguments); + if (this.constructor === b2PulleyJointDef) this.b2PulleyJointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2PulleyJointDef = b2PulleyJointDef; + + function b2RevoluteJoint() { + b2RevoluteJoint.b2RevoluteJoint.apply(this, arguments); + if (this.constructor === b2RevoluteJoint) this.b2RevoluteJoint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2RevoluteJoint = b2RevoluteJoint; + + function b2RevoluteJointDef() { + b2RevoluteJointDef.b2RevoluteJointDef.apply(this, arguments); + if (this.constructor === b2RevoluteJointDef) this.b2RevoluteJointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2RevoluteJointDef = b2RevoluteJointDef; + + function b2WeldJoint() { + b2WeldJoint.b2WeldJoint.apply(this, arguments); + if (this.constructor === b2WeldJoint) this.b2WeldJoint.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2WeldJoint = b2WeldJoint; + + function b2WeldJointDef() { + b2WeldJointDef.b2WeldJointDef.apply(this, arguments); + if (this.constructor === b2WeldJointDef) this.b2WeldJointDef.apply(this, arguments); + }; + Box2D.Dynamics.Joints.b2WeldJointDef = b2WeldJointDef; +})(); //definitions +_A2J_postDefs = []; /* source: disabled*/ +(function () { + var Dictionary = helpers.flash.utils.Dictionary; + var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; + var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; + var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; + var b2MassData = Box2D.Collision.Shapes.b2MassData; + var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; + var b2Shape = Box2D.Collision.Shapes.b2Shape; + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2internal = Box2D.Common.b2internal; + var b2Mat22 = Box2D.Common.Math.b2Mat22; + var b2Mat33 = Box2D.Common.Math.b2Mat33; + var b2Math = Box2D.Common.Math.b2Math; + var b2Sweep = Box2D.Common.Math.b2Sweep; + var b2Transform = Box2D.Common.Math.b2Transform; + var b2Vec2 = Box2D.Common.Math.b2Vec2; + var b2Vec3 = Box2D.Common.Math.b2Vec3; + var b2AABB = Box2D.Collision.b2AABB; + var b2Bound = Box2D.Collision.b2Bound; + var b2BoundValues = Box2D.Collision.b2BoundValues; + var b2BroadPhase = Box2D.Collision.b2BroadPhase; + var b2Collision = Box2D.Collision.b2Collision; + var b2ContactID = Box2D.Collision.b2ContactID; + var b2ContactPoint = Box2D.Collision.b2ContactPoint; + var b2Distance = Box2D.Collision.b2Distance; + var b2DistanceInput = Box2D.Collision.b2DistanceInput; + var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; + var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; + var b2DynamicTree = Box2D.Collision.b2DynamicTree; + var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; + var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; + var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; + var b2Manifold = Box2D.Collision.b2Manifold; + var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; + var b2OBB = Box2D.Collision.b2OBB; + var b2Pair = Box2D.Collision.b2Pair; + var b2PairManager = Box2D.Collision.b2PairManager; + var b2Point = Box2D.Collision.b2Point; + var b2Proxy = Box2D.Collision.b2Proxy; + var b2RayCastInput = Box2D.Collision.b2RayCastInput; + var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; + var b2Segment = Box2D.Collision.b2Segment; + var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; + var b2Simplex = Box2D.Collision.b2Simplex; + var b2SimplexCache = Box2D.Collision.b2SimplexCache; + var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; + var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; + var b2TOIInput = Box2D.Collision.b2TOIInput; + var b2WorldManifold = Box2D.Collision.b2WorldManifold; + var ClipVertex = Box2D.Collision.ClipVertex; + var Features = Box2D.Collision.Features; + var IBroadPhase = Box2D.Collision.IBroadPhase; + var b2internal = Box2D.Common.b2internal; + var b2internal = Box2D.Common.b2internal; + var b2Vec2 = Box2D.Common.Math.b2Vec2; + var b2AABB = Box2D.Collision.b2AABB; + var b2Bound = Box2D.Collision.b2Bound; + var b2BoundValues = Box2D.Collision.b2BoundValues; + var b2BroadPhase = Box2D.Collision.b2BroadPhase; + var b2Collision = Box2D.Collision.b2Collision; + var b2ContactID = Box2D.Collision.b2ContactID; + var b2ContactPoint = Box2D.Collision.b2ContactPoint; + var b2Distance = Box2D.Collision.b2Distance; + var b2DistanceInput = Box2D.Collision.b2DistanceInput; + var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; + var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; + var b2DynamicTree = Box2D.Collision.b2DynamicTree; + var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; + var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; + var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; + var b2Manifold = Box2D.Collision.b2Manifold; + var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; + var b2OBB = Box2D.Collision.b2OBB; + var b2Pair = Box2D.Collision.b2Pair; + var b2PairManager = Box2D.Collision.b2PairManager; + var b2Point = Box2D.Collision.b2Point; + var b2Proxy = Box2D.Collision.b2Proxy; + var b2RayCastInput = Box2D.Collision.b2RayCastInput; + var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; + var b2Segment = Box2D.Collision.b2Segment; + var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; + var b2Simplex = Box2D.Collision.b2Simplex; + var b2SimplexCache = Box2D.Collision.b2SimplexCache; + var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; + var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; + var b2TOIInput = Box2D.Collision.b2TOIInput; + var b2WorldManifold = Box2D.Collision.b2WorldManifold; + var ClipVertex = Box2D.Collision.ClipVertex; + var Features = Box2D.Collision.Features; + var IBroadPhase = Box2D.Collision.IBroadPhase; + var IBroadPhase = Box2D.Collision.IBroadPhase; + b2AABB.b2AABB = function () { + this.lowerBound = new b2Vec2(); + this.upperBound = new b2Vec2(); + }; + b2AABB.prototype.IsValid = function () { + var dX = this.upperBound.x - this.lowerBound.x; + var dY = this.upperBound.y - this.lowerBound.y; + var valid = dX >= 0.0 && dY >= 0.0; + valid = valid && this.lowerBound.IsValid() && this.upperBound.IsValid(); + return valid; + } + b2AABB.prototype.GetCenter = function () { + return new b2Vec2((this.lowerBound.x + this.upperBound.x) / 2, (this.lowerBound.y + this.upperBound.y) / 2); + } + b2AABB.prototype.GetExtents = function () { + return new b2Vec2((this.upperBound.x - this.lowerBound.x) / 2, (this.upperBound.y - this.lowerBound.y) / 2); + } + b2AABB.prototype.Contains = function (aabb) { + var result = true; + result = result && this.lowerBound.x <= aabb.lowerBound.x; + result = result && this.lowerBound.y <= aabb.lowerBound.y; + result = result && aabb.upperBound.x <= this.upperBound.x; + result = result && aabb.upperBound.y <= this.upperBound.y; + return result; + } + b2AABB.prototype.RayCast = function (output, input) { + var tmin = (-Number.MAX_VALUE); + var tmax = Number.MAX_VALUE; + var pX = input.p1.x; + var pY = input.p1.y; + var dX = input.p2.x - input.p1.x; + var dY = input.p2.y - input.p1.y; + var absDX = Math.abs(dX); + var absDY = Math.abs(dY); + var normal = output.normal; + var inv_d = 0; + var t1 = 0; + var t2 = 0; + var t3 = 0; + var s = 0; { + if (absDX < Number.MIN_VALUE) { + if (pX < this.lowerBound.x || this.upperBound.x < pX) return false; + } + else { + inv_d = 1.0 / dX; + t1 = (this.lowerBound.x - pX) * inv_d; + t2 = (this.upperBound.x - pX) * inv_d; + s = (-1.0); + if (t1 > t2) { + t3 = t1; + t1 = t2; + t2 = t3; + s = 1.0; + } + if (t1 > tmin) { + normal.x = s; + normal.y = 0; + tmin = t1; + } + tmax = Math.min(tmax, t2); + if (tmin > tmax) return false; + } + } { + if (absDY < Number.MIN_VALUE) { + if (pY < this.lowerBound.y || this.upperBound.y < pY) return false; + } + else { + inv_d = 1.0 / dY; + t1 = (this.lowerBound.y - pY) * inv_d; + t2 = (this.upperBound.y - pY) * inv_d; + s = (-1.0); + if (t1 > t2) { + t3 = t1; + t1 = t2; + t2 = t3; + s = 1.0; + } + if (t1 > tmin) { + normal.y = s; + normal.x = 0; + tmin = t1; + } + tmax = Math.min(tmax, t2); + if (tmin > tmax) return false; + } + } + output.fraction = tmin; + return true; + } + b2AABB.prototype.TestOverlap = function (other) { + var d1X = other.lowerBound.x - this.upperBound.x; + var d1Y = other.lowerBound.y - this.upperBound.y; + var d2X = this.lowerBound.x - other.upperBound.x; + var d2Y = this.lowerBound.y - other.upperBound.y; + if (d1X > 0.0 || d1Y > 0.0) return false; + if (d2X > 0.0 || d2Y > 0.0) return false; + return true; + } + b2AABB.prototype.Combine = function (aabb1, aabb2) { + var aabb = new b2AABB(); + if (this.constructor === Box2D.Collision.b2AABB) this._a2j__Combine(aabb1, aabb2); + else aabb._a2j__Combine(aabb1, aabb2); + return aabb; + } + b2AABB.Combine = b2AABB.prototype.Combine; + b2AABB.prototype._a2j__Combine = function (aabb1, aabb2) { + this.lowerBound.x = Math.min(aabb1.lowerBound.x, aabb2.lowerBound.x); + this.lowerBound.y = Math.min(aabb1.lowerBound.y, aabb2.lowerBound.y); + this.upperBound.x = Math.max(aabb1.upperBound.x, aabb2.upperBound.x); + this.upperBound.y = Math.max(aabb1.upperBound.y, aabb2.upperBound.y); + } + b2Bound.b2Bound = function () {}; + b2Bound.prototype.IsLower = function () { + return (this.value & 1) == 0; + } + b2Bound.prototype.IsUpper = function () { + return (this.value & 1) == 1; + } + b2Bound.prototype.Swap = function (b) { + var tempValue = this.value; + var tempProxy = this.proxy; + var tempStabbingCount = this.stabbingCount; + this.value = b.value; + this.proxy = b.proxy; + this.stabbingCount = b.stabbingCount; + b.value = tempValue; + b.proxy = tempProxy; + b.stabbingCount = tempStabbingCount; + } + b2BoundValues.b2BoundValues = function () {}; + b2BoundValues.prototype.b2BoundValues = function () { + this.lowerValues = new Vector_a2j_Number(); + this.lowerValues[0] = 0.0; + this.lowerValues[1] = 0.0; + this.upperValues = new Vector_a2j_Number(); + this.upperValues[0] = 0.0; + this.upperValues[1] = 0.0; + } + b2BroadPhase.b2BroadPhase = function () { + this.m_pairManager = new b2PairManager(); + this.m_proxyPool = new Array(); + this.m_querySortKeys = new Array(); + this.m_queryResults = new Array(); + this.m_quantizationFactor = new b2Vec2(); + }; + b2BroadPhase.prototype.b2BroadPhase = function (worldAABB) { + var i = 0; + this.m_pairManager.Initialize(this); + this.m_worldAABB = worldAABB; + this.m_proxyCount = 0; + this.m_bounds = new Vector(); + for (i = 0; + i < 2; i++) { + this.m_bounds[i] = new Vector(); + } + var dX = worldAABB.upperBound.x - worldAABB.lowerBound.x; + var dY = worldAABB.upperBound.y - worldAABB.lowerBound.y; + this.m_quantizationFactor.x = b2Settings.USHRT_MAX / dX; + this.m_quantizationFactor.y = b2Settings.USHRT_MAX / dY; + this.m_timeStamp = 1; + this.m_queryResultCount = 0; + } + b2BroadPhase.prototype.InRange = function (aabb) { + var dX = 0; + var dY = 0; + var d2X = 0; + var d2Y = 0; + dX = aabb.lowerBound.x; + dY = aabb.lowerBound.y; + dX -= this.m_worldAABB.upperBound.x; + dY -= this.m_worldAABB.upperBound.y; + d2X = this.m_worldAABB.lowerBound.x; + d2Y = this.m_worldAABB.lowerBound.y; + d2X -= aabb.upperBound.x; + d2Y -= aabb.upperBound.y; + dX = b2Math.Max(dX, d2X); + dY = b2Math.Max(dY, d2Y); + return b2Math.Max(dX, dY) < 0.0; + } + b2BroadPhase.prototype.CreateProxy = function (aabb, userData) { + var index = 0; + var proxy; + var i = 0; + var j = 0; + if (!this.m_freeProxy) { + this.m_freeProxy = this.m_proxyPool[this.m_proxyCount] = new b2Proxy(); + this.m_freeProxy.next = null; + this.m_freeProxy.timeStamp = 0; + this.m_freeProxy.overlapCount = b2BroadPhase.b2_invalid; + this.m_freeProxy.userData = null; + for (i = 0; + i < 2; i++) { + j = this.m_proxyCount * 2; + this.m_bounds[i][j++] = new b2Bound(); + this.m_bounds[i][j] = new b2Bound(); + } + } + proxy = this.m_freeProxy; + this.m_freeProxy = proxy.next; + proxy.overlapCount = 0; + proxy.userData = userData; + var boundCount = 2 * this.m_proxyCount; + var lowerValues = new Vector_a2j_Number(); + var upperValues = new Vector_a2j_Number(); + this.ComputeBounds(lowerValues, upperValues, aabb); + for (var axis = 0; axis < 2; ++axis) { + var bounds = this.m_bounds[axis]; + var lowerIndex = 0; + var upperIndex = 0; + var lowerIndexOut = new Vector_a2j_Number(); + lowerIndexOut.push(lowerIndex); + var upperIndexOut = new Vector_a2j_Number(); + upperIndexOut.push(upperIndex); + this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[axis], upperValues[axis], bounds, boundCount, axis); + lowerIndex = lowerIndexOut[0]; + upperIndex = upperIndexOut[0]; + bounds.splice(upperIndex, 0, bounds[bounds.length - 1]); + bounds.length--; + bounds.splice(lowerIndex, 0, bounds[bounds.length - 1]); + bounds.length--; + ++upperIndex; + var tBound1 = bounds[lowerIndex]; + var tBound2 = bounds[upperIndex]; + tBound1.value = lowerValues[axis]; + tBound1.proxy = proxy; + tBound2.value = upperValues[axis]; + tBound2.proxy = proxy; + var tBoundAS3 = bounds[parseInt(lowerIndex - 1)]; + tBound1.stabbingCount = lowerIndex == 0 ? 0 : tBoundAS3.stabbingCount; + tBoundAS3 = bounds[parseInt(upperIndex - 1)]; + tBound2.stabbingCount = tBoundAS3.stabbingCount; + for (index = lowerIndex; + index < upperIndex; ++index) { + tBoundAS3 = bounds[index]; + tBoundAS3.stabbingCount++; + } + for (index = lowerIndex; + index < boundCount + 2; ++index) { + tBound1 = bounds[index]; + var proxy2 = tBound1.proxy; + if (tBound1.IsLower()) { + proxy2.lowerBounds[axis] = index; + } + else { + proxy2.upperBounds[axis] = index; + } + } + }++this.m_proxyCount; + for (i = 0; + i < this.m_queryResultCount; ++i) { + this.m_pairManager.AddBufferedPair(proxy, this.m_queryResults[i]); + } + this.m_queryResultCount = 0; + this.IncrementTimeStamp(); + return proxy; + } + b2BroadPhase.prototype.DestroyProxy = function (proxy_) { + var proxy = (proxy_ instanceof b2Proxy ? proxy_ : null); + var tBound1; + var tBound2; + var boundCount = parseInt(2 * this.m_proxyCount); + for (var axis = 0; axis < 2; ++axis) { + var bounds = this.m_bounds[axis]; + var lowerIndex = proxy.lowerBounds[axis]; + var upperIndex = proxy.upperBounds[axis]; + tBound1 = bounds[lowerIndex]; + var lowerValue = tBound1.value; + tBound2 = bounds[upperIndex]; + var upperValue = tBound2.value; + bounds.splice(upperIndex, 1); + bounds.splice(lowerIndex, 1); + bounds.push(tBound1); + bounds.push(tBound2); + var tEnd = parseInt(boundCount - 2); + for (var index = lowerIndex; index < tEnd; ++index) { + tBound1 = bounds[index]; + var proxy2 = tBound1.proxy; + if (tBound1.IsLower()) { + proxy2.lowerBounds[axis] = index; + } + else { + proxy2.upperBounds[axis] = index; + } + } + tEnd = upperIndex - 1; + for (var index2 = parseInt(lowerIndex); index2 < tEnd; ++index2) { + tBound1 = bounds[index2]; + tBound1.stabbingCount--; + } + var ignore = new Vector_a2j_Number(); + this.QueryAxis(ignore, ignore, lowerValue, upperValue, bounds, boundCount - 2, axis); + } + for (var i = 0; i < this.m_queryResultCount; ++i) { + this.m_pairManager.RemoveBufferedPair(proxy, this.m_queryResults[i]); + } + this.m_queryResultCount = 0; + this.IncrementTimeStamp(); + proxy.userData = null; + proxy.overlapCount = b2BroadPhase.b2_invalid; + proxy.lowerBounds[0] = b2BroadPhase.b2_invalid; + proxy.lowerBounds[1] = b2BroadPhase.b2_invalid; + proxy.upperBounds[0] = b2BroadPhase.b2_invalid; + proxy.upperBounds[1] = b2BroadPhase.b2_invalid; + proxy.next = this.m_freeProxy; + this.m_freeProxy = proxy; + --this.m_proxyCount; + } + b2BroadPhase.prototype.MoveProxy = function (proxy_, aabb, displacement) { + var proxy = (proxy_ instanceof b2Proxy ? proxy_ : null); + var as3arr; + var as3int = 0; + var axis = 0; + var index = 0; + var bound; + var prevBound; + var nextBound; + var nextProxyId = 0; + var nextProxy; + if (proxy == null) { + return; + } + if (aabb.IsValid() == false) { + return; + } + var boundCount = 2 * this.m_proxyCount; + var newValues = new b2BoundValues(); + this.ComputeBounds(newValues.lowerValues, newValues.upperValues, aabb); + var oldValues = new b2BoundValues(); + for (axis = 0; + axis < 2; ++axis) { + bound = this.m_bounds[axis][proxy.lowerBounds[axis]]; + oldValues.lowerValues[axis] = bound.value; + bound = this.m_bounds[axis][proxy.upperBounds[axis]]; + oldValues.upperValues[axis] = bound.value; + } + for (axis = 0; + axis < 2; ++axis) { + var bounds = this.m_bounds[axis]; + var lowerIndex = proxy.lowerBounds[axis]; + var upperIndex = proxy.upperBounds[axis]; + var lowerValue = newValues.lowerValues[axis]; + var upperValue = newValues.upperValues[axis]; + bound = bounds[lowerIndex]; + var deltaLower = parseInt(lowerValue - bound.value); + bound.value = lowerValue; + bound = bounds[upperIndex]; + var deltaUpper = parseInt(upperValue - bound.value); + bound.value = upperValue; + if (deltaLower < 0) { + index = lowerIndex; + while (index > 0 && lowerValue < ((bounds[parseInt(index - 1)] instanceof b2Bound ? bounds[parseInt(index - 1)] : null)).value) { + bound = bounds[index]; + prevBound = bounds[parseInt(index - 1)]; + var prevProxy = prevBound.proxy; + prevBound.stabbingCount++; + if (prevBound.IsUpper() == true) { + if (this.TestOverlapBound(newValues, prevProxy)) { + this.m_pairManager.AddBufferedPair(proxy, prevProxy); + } + as3arr = prevProxy.upperBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.stabbingCount++; + } + else { + as3arr = prevProxy.lowerBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.stabbingCount--; + } + as3arr = proxy.lowerBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.Swap(prevBound); + --index; + } + } + if (deltaUpper > 0) { + index = upperIndex; + while (index < boundCount - 1 && ((bounds[parseInt(index + 1)] instanceof b2Bound ? bounds[parseInt(index + 1)] : null)).value <= upperValue) { + bound = bounds[index]; + nextBound = bounds[parseInt(index + 1)]; + nextProxy = nextBound.proxy; + nextBound.stabbingCount++; + if (nextBound.IsLower() == true) { + if (this.TestOverlapBound(newValues, nextProxy)) { + this.m_pairManager.AddBufferedPair(proxy, nextProxy); + } + as3arr = nextProxy.lowerBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.stabbingCount++; + } + else { + as3arr = nextProxy.upperBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.stabbingCount--; + } + as3arr = proxy.upperBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.Swap(nextBound); + index++; + } + } + if (deltaLower > 0) { + index = lowerIndex; + while (index < boundCount - 1 && ((bounds[parseInt(index + 1)] instanceof b2Bound ? bounds[parseInt(index + 1)] : null)).value <= lowerValue) { + bound = bounds[index]; + nextBound = bounds[parseInt(index + 1)]; + nextProxy = nextBound.proxy; + nextBound.stabbingCount--; + if (nextBound.IsUpper()) { + if (this.TestOverlapBound(oldValues, nextProxy)) { + this.m_pairManager.RemoveBufferedPair(proxy, nextProxy); + } + as3arr = nextProxy.upperBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.stabbingCount--; + } + else { + as3arr = nextProxy.lowerBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.stabbingCount++; + } + as3arr = proxy.lowerBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.Swap(nextBound); + index++; + } + } + if (deltaUpper < 0) { + index = upperIndex; + while (index > 0 && upperValue < ((bounds[parseInt(index - 1)] instanceof b2Bound ? bounds[parseInt(index - 1)] : null)).value) { + bound = bounds[index]; + prevBound = bounds[parseInt(index - 1)]; + prevProxy = prevBound.proxy; + prevBound.stabbingCount--; + if (prevBound.IsLower() == true) { + if (this.TestOverlapBound(oldValues, prevProxy)) { + this.m_pairManager.RemoveBufferedPair(proxy, prevProxy); + } + as3arr = prevProxy.lowerBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.stabbingCount--; + } + else { + as3arr = prevProxy.upperBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.stabbingCount++; + } + as3arr = proxy.upperBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.Swap(prevBound); + index--; + } + } + } + } + b2BroadPhase.prototype.UpdatePairs = function (callback) { + this.m_pairManager.Commit(callback); + } + b2BroadPhase.prototype.TestOverlap = function (proxyA, proxyB) { + var proxyA_ = (proxyA instanceof b2Proxy ? proxyA : null); + var proxyB_ = (proxyB instanceof b2Proxy ? proxyB : null); + if (proxyA_.lowerBounds[0] > proxyB_.upperBounds[0]) return false; + if (proxyB_.lowerBounds[0] > proxyA_.upperBounds[0]) return false; + if (proxyA_.lowerBounds[1] > proxyB_.upperBounds[1]) return false; + if (proxyB_.lowerBounds[1] > proxyA_.upperBounds[1]) return false; + return true; + } + b2BroadPhase.prototype.GetUserData = function (proxy) { + return ((proxy instanceof b2Proxy ? proxy : null)).userData; + } + b2BroadPhase.prototype.GetFatAABB = function (proxy_) { + var aabb = new b2AABB(); + var proxy = (proxy_ instanceof b2Proxy ? proxy_ : null); + aabb.lowerBound.x = this.m_worldAABB.lowerBound.x + this.m_bounds[0][proxy.lowerBounds[0]].value / this.m_quantizationFactor.x; + aabb.lowerBound.y = this.m_worldAABB.lowerBound.y + this.m_bounds[1][proxy.lowerBounds[1]].value / this.m_quantizationFactor.y; + aabb.upperBound.x = this.m_worldAABB.lowerBound.x + this.m_bounds[0][proxy.upperBounds[0]].value / this.m_quantizationFactor.x; + aabb.upperBound.y = this.m_worldAABB.lowerBound.y + this.m_bounds[1][proxy.upperBounds[1]].value / this.m_quantizationFactor.y; + return aabb; + } + b2BroadPhase.prototype.GetProxyCount = function () { + return this.m_proxyCount; + } + b2BroadPhase.prototype.Query = function (callback, aabb) { + var lowerValues = new Vector_a2j_Number(); + var upperValues = new Vector_a2j_Number(); + this.ComputeBounds(lowerValues, upperValues, aabb); + var lowerIndex = 0; + var upperIndex = 0; + var lowerIndexOut = new Vector_a2j_Number(); + lowerIndexOut.push(lowerIndex); + var upperIndexOut = new Vector_a2j_Number(); + upperIndexOut.push(upperIndex); + this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[0], upperValues[0], this.m_bounds[0], 2 * this.m_proxyCount, 0); + this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[1], upperValues[1], this.m_bounds[1], 2 * this.m_proxyCount, 1); + for (var i = 0; i < this.m_queryResultCount; ++i) { + var proxy = this.m_queryResults[i]; + if (!callback(proxy)) { + break; + } + } + this.m_queryResultCount = 0; + this.IncrementTimeStamp(); + } + b2BroadPhase.prototype.Validate = function () { + var pair; + var proxy1; + var proxy2; + var overlap; + for (var axis = 0; axis < 2; ++axis) { + var bounds = this.m_bounds[axis]; + var boundCount = 2 * this.m_proxyCount; + var stabbingCount = 0; + for (var i = 0; i < boundCount; ++i) { + var bound = bounds[i]; + if (bound.IsLower() == true) { + stabbingCount++; + } + else { + stabbingCount--; + } + } + } + } + b2BroadPhase.prototype.Rebalance = function (iterations) { + if (iterations === undefined) iterations = 0; + } + b2BroadPhase.prototype.RayCast = function (callback, input) { + var subInput = new b2RayCastInput(); + subInput.p1.SetV(input.p1); + subInput.p2.SetV(input.p2); + subInput.maxFraction = input.maxFraction; + var dx = (input.p2.x - input.p1.x) * this.m_quantizationFactor.x; + var dy = (input.p2.y - input.p1.y) * this.m_quantizationFactor.y; + var sx = parseInt(dx < (-Number.MIN_VALUE ? (-1) : (dx > Number.MIN_VALUE ? 1 : 0))); + var sy = parseInt(dy < (-Number.MIN_VALUE ? (-1) : (dy > Number.MIN_VALUE ? 1 : 0))); + var p1x = this.m_quantizationFactor.x * (input.p1.x - this.m_worldAABB.lowerBound.x); + var p1y = this.m_quantizationFactor.y * (input.p1.y - this.m_worldAABB.lowerBound.y); + var startValues = new Array(); + var startValues2 = new Array(); + startValues[0] = a2j.parseUInt(p1x) & (b2Settings.USHRT_MAX - 1); + startValues[1] = a2j.parseUInt(p1y) & (b2Settings.USHRT_MAX - 1); + startValues2[0] = startValues[0] + 1; + startValues2[1] = startValues[1] + 1; + var startIndices = new Array(); + var xIndex = 0; + var yIndex = 0; + var proxy; + var lowerIndex = 0; + var upperIndex = 0; + var lowerIndexOut = new Vector_a2j_Number(); + lowerIndexOut.push(lowerIndex); + var upperIndexOut = new Vector_a2j_Number(); + upperIndexOut.push(upperIndex); + this.QueryAxis(lowerIndexOut, upperIndexOut, startValues[0], startValues2[0], this.m_bounds[0], 2 * this.m_proxyCount, 0); + if (sx >= 0) xIndex = upperIndexOut[0] - 1; + else xIndex = lowerIndexOut[0]; + this.QueryAxis(lowerIndexOut, upperIndexOut, startValues[1], startValues2[1], this.m_bounds[1], 2 * this.m_proxyCount, 1); + if (sy >= 0) yIndex = upperIndexOut[0] - 1; + else yIndex = lowerIndexOut[0]; + for (var i = 0; i < this.m_queryResultCount; i++) { + subInput.maxFraction = callback(subInput, this.m_queryResults[i]); + } + for (;;) { + var xProgress = 0; + var yProgress = 0; + xIndex += sx >= 0 ? 1 : (-1); + if (xIndex < 0 || xIndex >= this.m_proxyCount * 2) break; + if (sx != 0) { + xProgress = (this.m_bounds[0][xIndex].value - p1x) / dx; + } + yIndex += sy >= 0 ? 1 : (-1); + if (yIndex < 0 || yIndex >= this.m_proxyCount * 2) break; + if (sy != 0) { + yProgress = (this.m_bounds[1][yIndex].value - p1y) / dy; + } + for (;;) { + if (sy == 0 || (sx != 0 && xProgress < yProgress)) { + if (xProgress > subInput.maxFraction) break; + if (sx > 0 ? this.m_bounds[0][xIndex].IsLower() : this.m_bounds[0][xIndex].IsUpper()) { + proxy = this.m_bounds[0][xIndex].proxy; + if (sy >= 0) { + if (proxy.lowerBounds[1] <= yIndex - 1 && proxy.upperBounds[1] >= yIndex) { + subInput.maxFraction = callback(subInput, proxy); + } + } + else { + if (proxy.lowerBounds[1] <= yIndex && proxy.upperBounds[1] >= yIndex + 1) { + subInput.maxFraction = callback(subInput, proxy); + } + } + } + if (subInput.maxFraction == 0) break; + if (sx > 0) { + xIndex++; + if (xIndex == this.m_proxyCount * 2) break; + } + else { + xIndex--; + if (xIndex < 0) break; + } + xProgress = (this.m_bounds[0][xIndex].value - p1x) / dx; + } + else { + if (yProgress > subInput.maxFraction) break; + if (sy > 0 ? this.m_bounds[1][yIndex].IsLower() : this.m_bounds[1][yIndex].IsUpper()) { + proxy = this.m_bounds[1][yIndex].proxy; + if (sx >= 0) { + if (proxy.lowerBounds[0] <= xIndex - 1 && proxy.upperBounds[0] >= xIndex) { + subInput.maxFraction = callback(subInput, proxy); + } + } + else { + if (proxy.lowerBounds[0] <= xIndex && proxy.upperBounds[0] >= xIndex + 1) { + subInput.maxFraction = callback(subInput, proxy); + } + } + } + if (subInput.maxFraction == 0) break; + if (sy > 0) { + yIndex++; + if (yIndex == this.m_proxyCount * 2) break; + } + else { + yIndex--; + if (yIndex < 0) break; + } + yProgress = (this.m_bounds[1][yIndex].value - p1y) / dy; + } + } + break; + } + this.m_queryResultCount = 0; + this.IncrementTimeStamp(); + return; + } + b2BroadPhase.prototype.ComputeBounds = function (lowerValues, upperValues, aabb) { + var minVertexX = aabb.lowerBound.x; + var minVertexY = aabb.lowerBound.y; + minVertexX = b2Math.Min(minVertexX, this.m_worldAABB.upperBound.x); + minVertexY = b2Math.Min(minVertexY, this.m_worldAABB.upperBound.y); + minVertexX = b2Math.Max(minVertexX, this.m_worldAABB.lowerBound.x); + minVertexY = b2Math.Max(minVertexY, this.m_worldAABB.lowerBound.y); + var maxVertexX = aabb.upperBound.x; + var maxVertexY = aabb.upperBound.y; + maxVertexX = b2Math.Min(maxVertexX, this.m_worldAABB.upperBound.x); + maxVertexY = b2Math.Min(maxVertexY, this.m_worldAABB.upperBound.y); + maxVertexX = b2Math.Max(maxVertexX, this.m_worldAABB.lowerBound.x); + maxVertexY = b2Math.Max(maxVertexY, this.m_worldAABB.lowerBound.y); + lowerValues[0] = a2j.parseUInt(this.m_quantizationFactor.x * (minVertexX - this.m_worldAABB.lowerBound.x)) & (b2Settings.USHRT_MAX - 1); + upperValues[0] = (a2j.parseUInt(this.m_quantizationFactor.x * (maxVertexX - this.m_worldAABB.lowerBound.x)) & 0x0000ffff) | 1; + lowerValues[1] = a2j.parseUInt(this.m_quantizationFactor.y * (minVertexY - this.m_worldAABB.lowerBound.y)) & (b2Settings.USHRT_MAX - 1); + upperValues[1] = (a2j.parseUInt(this.m_quantizationFactor.y * (maxVertexY - this.m_worldAABB.lowerBound.y)) & 0x0000ffff) | 1; + } + b2BroadPhase.prototype.TestOverlapValidate = function (p1, p2) { + for (var axis = 0; axis < 2; ++axis) { + var bounds = this.m_bounds[axis]; + var bound1 = bounds[p1.lowerBounds[axis]]; + var bound2 = bounds[p2.upperBounds[axis]]; + if (bound1.value > bound2.value) return false; + bound1 = bounds[p1.upperBounds[axis]]; + bound2 = bounds[p2.lowerBounds[axis]]; + if (bound1.value < bound2.value) return false; + } + return true; + } + b2BroadPhase.prototype.TestOverlapBound = function (b, p) { + for (var axis = 0; axis < 2; ++axis) { + var bounds = this.m_bounds[axis]; + var bound = bounds[p.upperBounds[axis]]; + if (b.lowerValues[axis] > bound.value) return false; + bound = bounds[p.lowerBounds[axis]]; + if (b.upperValues[axis] < bound.value) return false; + } + return true; + } + b2BroadPhase.prototype.QueryAxis = function (lowerQueryOut, upperQueryOut, lowerValue, upperValue, bounds, boundCount, axis) { + if (lowerValue === undefined) lowerValue = 0; + if (upperValue === undefined) upperValue = 0; + if (boundCount === undefined) boundCount = 0; + if (axis === undefined) axis = 0; + var lowerQuery = this.BinarySearch(bounds, boundCount, lowerValue); + var upperQuery = this.BinarySearch(bounds, boundCount, upperValue); + var bound; + for (var j = lowerQuery; j < upperQuery; ++j) { + bound = bounds[j]; + if (bound.IsLower()) { + this.IncrementOverlapCount(bound.proxy); + } + } + if (lowerQuery > 0) { + var i = parseInt(lowerQuery - 1); + bound = bounds[i]; + var s = parseInt(bound.stabbingCount); + while (s) { + bound = bounds[i]; + if (bound.IsLower()) { + var proxy = bound.proxy; + if (lowerQuery <= proxy.upperBounds[axis]) { + this.IncrementOverlapCount(bound.proxy); + --s; + } + }--i; + } + } + lowerQueryOut[0] = lowerQuery; + upperQueryOut[0] = upperQuery; + } + b2BroadPhase.prototype.IncrementOverlapCount = function (proxy) { + if (proxy.timeStamp < this.m_timeStamp) { + proxy.timeStamp = this.m_timeStamp; + proxy.overlapCount = 1; + } + else { + proxy.overlapCount = 2; + this.m_queryResults[this.m_queryResultCount] = proxy; + ++this.m_queryResultCount; + } + } + b2BroadPhase.prototype.IncrementTimeStamp = function () { + if (this.m_timeStamp == b2Settings.USHRT_MAX) { + for (var i = 0; i < this.m_proxyPool.length; ++i) { + ((this.m_proxyPool[i] instanceof b2Proxy ? this.m_proxyPool[i] : null)).timeStamp = 0; + } + this.m_timeStamp = 1; + } + else { + ++this.m_timeStamp; + } + } + b2BroadPhase.prototype.BinarySearch = function (bounds, count, value) { + if (count === undefined) count = 0; + if (value === undefined) value = 0; + var low = 0; + var high = parseInt(count - 1); + while (low <= high) { + var mid = parseInt(((low + high) / 2)); + var bound = bounds[mid]; + if (bound.value > value) { + high = mid - 1; + } + else if (bound.value < value) { + low = mid + 1; + } + else { + return a2j.parseUInt(mid); + } + } + return a2j.parseUInt(low); + } + b2BroadPhase.BinarySearch = b2BroadPhase.prototype.BinarySearch; + _A2J_postDefs.push(function () { + Box2D.Collision.b2BroadPhase.s_validate = false; + Box2D.Collision.b2BroadPhase.prototype.s_validate = Box2D.Collision.b2BroadPhase.s_validate; + Box2D.Collision.b2BroadPhase.b2_invalid = parseInt(b2Settings.USHRT_MAX); + Box2D.Collision.b2BroadPhase.prototype.b2_invalid = Box2D.Collision.b2BroadPhase.b2_invalid; + Box2D.Collision.b2BroadPhase.b2_nullEdge = parseInt(b2Settings.USHRT_MAX); + Box2D.Collision.b2BroadPhase.prototype.b2_nullEdge = Box2D.Collision.b2BroadPhase.b2_nullEdge; + }); + b2BroadPhase.__implements = {}; + b2BroadPhase.__implements[IBroadPhase] = true; + b2Collision.b2Collision = function () {}; + b2Collision.prototype.ClipSegmentToLine = function (vOut, vIn, normal, offset) { + if (offset === undefined) offset = 0; + var cv; + var numOut = 0; + cv = vIn[0]; + var vIn0 = cv.v; + cv = vIn[1]; + var vIn1 = cv.v; + var distance0 = normal.x * vIn0.x + normal.y * vIn0.y - offset; + var distance1 = normal.x * vIn1.x + normal.y * vIn1.y - offset; + if (distance0 <= 0.0) vOut[numOut++].Set(vIn[0]); + if (distance1 <= 0.0) vOut[numOut++].Set(vIn[1]); + if (distance0 * distance1 < 0.0) { + var interp = distance0 / (distance0 - distance1); + cv = vOut[numOut]; + var tVec = cv.v; + tVec.x = vIn0.x + interp * (vIn1.x - vIn0.x); + tVec.y = vIn0.y + interp * (vIn1.y - vIn0.y); + cv = vOut[numOut]; + var cv2; + if (distance0 > 0.0) { + cv2 = vIn[0]; + cv.id = cv2.id; + } + else { + cv2 = vIn[1]; + cv.id = cv2.id; + }++numOut; + } + return numOut; + } + b2Collision.ClipSegmentToLine = b2Collision.prototype.ClipSegmentToLine; + b2Collision.prototype.EdgeSeparation = function (poly1, xf1, edge1, poly2, xf2) { + if (edge1 === undefined) edge1 = 0; + var count1 = parseInt(poly1.m_vertexCount); + var vertices1 = poly1.m_vertices; + var normals1 = poly1.m_normals; + var count2 = parseInt(poly2.m_vertexCount); + var vertices2 = poly2.m_vertices; + var tMat; + var tVec; + tMat = xf1.R; + tVec = normals1[edge1]; + var normal1WorldX = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var normal1WorldY = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = xf2.R; + var normal1X = (tMat.col1.x * normal1WorldX + tMat.col1.y * normal1WorldY); + var normal1Y = (tMat.col2.x * normal1WorldX + tMat.col2.y * normal1WorldY); + var index = 0; + var minDot = Number.MAX_VALUE; + for (var i = 0; i < count2; ++i) { + tVec = vertices2[i]; + var dot = tVec.x * normal1X + tVec.y * normal1Y; + if (dot < minDot) { + minDot = dot; + index = i; + } + } + tVec = vertices1[edge1]; + tMat = xf1.R; + var v1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var v1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = vertices2[index]; + tMat = xf2.R; + var v2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var v2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + v2X -= v1X; + v2Y -= v1Y; + var separation = v2X * normal1WorldX + v2Y * normal1WorldY; + return separation; + } + b2Collision.EdgeSeparation = b2Collision.prototype.EdgeSeparation; + b2Collision.prototype.FindMaxSeparation = function (edgeIndex, poly1, xf1, poly2, xf2) { + var count1 = parseInt(poly1.m_vertexCount); + var normals1 = poly1.m_normals; + var tVec; + var tMat; + tMat = xf2.R; + tVec = poly2.m_centroid; + var dX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var dY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = xf1.R; + tVec = poly1.m_centroid; + dX -= xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + dY -= xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var dLocal1X = (dX * xf1.R.col1.x + dY * xf1.R.col1.y); + var dLocal1Y = (dX * xf1.R.col2.x + dY * xf1.R.col2.y); + var edge = 0; + var maxDot = (-Number.MAX_VALUE); + for (var i = 0; i < count1; ++i) { + tVec = normals1[i]; + var dot = (tVec.x * dLocal1X + tVec.y * dLocal1Y); + if (dot > maxDot) { + maxDot = dot; + edge = i; + } + } + var s = this.EdgeSeparation(poly1, xf1, edge, poly2, xf2); + var prevEdge = parseInt(edge - 1 >= 0 ? edge - 1 : count1 - 1); + var sPrev = this.EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2); + var nextEdge = parseInt(edge + 1 < count1 ? edge + 1 : 0); + var sNext = this.EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2); + var bestEdge = 0; + var bestSeparation = 0; + var increment = 0; + if (sPrev > s && sPrev > sNext) { + increment = (-1); + bestEdge = prevEdge; + bestSeparation = sPrev; + } + else if (sNext > s) { + increment = 1; + bestEdge = nextEdge; + bestSeparation = sNext; + } + else { + edgeIndex[0] = edge; + return s; + } + while (true) { + if (increment == (-1)) edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1; + else edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;s = this.EdgeSeparation(poly1, xf1, edge, poly2, xf2); + if (s > bestSeparation) { + bestEdge = edge; + bestSeparation = s; + } + else { + break; + } + } + edgeIndex[0] = bestEdge; + return bestSeparation; + } + b2Collision.FindMaxSeparation = b2Collision.prototype.FindMaxSeparation; + b2Collision.prototype.FindIncidentEdge = function (c, poly1, xf1, edge1, poly2, xf2) { + if (edge1 === undefined) edge1 = 0; + var count1 = parseInt(poly1.m_vertexCount); + var normals1 = poly1.m_normals; + var count2 = parseInt(poly2.m_vertexCount); + var vertices2 = poly2.m_vertices; + var normals2 = poly2.m_normals; + var tMat; + var tVec; + tMat = xf1.R; + tVec = normals1[edge1]; + var normal1X = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var normal1Y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = xf2.R; + var tX = (tMat.col1.x * normal1X + tMat.col1.y * normal1Y); + normal1Y = (tMat.col2.x * normal1X + tMat.col2.y * normal1Y); + normal1X = tX; + var index = 0; + var minDot = Number.MAX_VALUE; + for (var i = 0; i < count2; ++i) { + tVec = normals2[i]; + var dot = (normal1X * tVec.x + normal1Y * tVec.y); + if (dot < minDot) { + minDot = dot; + index = i; + } + } + var tClip; + var i1 = parseInt(index); + var i2 = parseInt(i1 + 1 < count2 ? i1 + 1 : 0); + tClip = c[0]; + tVec = vertices2[i1]; + tMat = xf2.R; + tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tClip.id.features.referenceEdge = edge1; + tClip.id.features.incidentEdge = i1; + tClip.id.features.incidentVertex = 0; + tClip = c[1]; + tVec = vertices2[i2]; + tMat = xf2.R; + tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tClip.id.features.referenceEdge = edge1; + tClip.id.features.incidentEdge = i2; + tClip.id.features.incidentVertex = 1; + } + b2Collision.FindIncidentEdge = b2Collision.prototype.FindIncidentEdge; + b2Collision.prototype.MakeClipPointVector = function () { + var r = new Vector(2); + r[0] = new ClipVertex(); + r[1] = new ClipVertex(); + return r; + } + b2Collision.MakeClipPointVector = b2Collision.prototype.MakeClipPointVector; + b2Collision.prototype.CollidePolygons = function (manifold, polyA, xfA, polyB, xfB) { + var cv; + manifold.m_pointCount = 0; + var totalRadius = polyA.m_radius + polyB.m_radius; + var edgeA = 0; + b2Collision.s_edgeAO[0] = edgeA; + var separationA = this.FindMaxSeparation(b2Collision.s_edgeAO, polyA, xfA, polyB, xfB); + edgeA = b2Collision.s_edgeAO[0]; + if (separationA > totalRadius) return; + var edgeB = 0; + b2Collision.s_edgeBO[0] = edgeB; + var separationB = this.FindMaxSeparation(b2Collision.s_edgeBO, polyB, xfB, polyA, xfA); + edgeB = b2Collision.s_edgeBO[0]; + if (separationB > totalRadius) return; + var poly1; + var poly2; + var xf1; + var xf2; + var edge1 = 0; + var flip = 0; + var k_relativeTol = 0.98; + var k_absoluteTol = 0.001; + var tMat; + if (separationB > k_relativeTol * separationA + k_absoluteTol) { + poly1 = polyB; + poly2 = polyA; + xf1 = xfB; + xf2 = xfA; + edge1 = edgeB; + manifold.m_type = b2Manifold.e_faceB; + flip = 1; + } + else { + poly1 = polyA; + poly2 = polyB; + xf1 = xfA; + xf2 = xfB; + edge1 = edgeA; + manifold.m_type = b2Manifold.e_faceA; + flip = 0; + } + var incidentEdge = b2Collision.s_incidentEdge; + this.FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); + var count1 = parseInt(poly1.m_vertexCount); + var vertices1 = poly1.m_vertices; + var local_v11 = vertices1[edge1]; + var local_v12; + if (edge1 + 1 < count1) { + local_v12 = vertices1[parseInt(edge1 + 1)]; + } + else { + local_v12 = vertices1[0]; + } + var localTangent = b2Collision.s_localTangent; + localTangent.Set(local_v12.x - local_v11.x, local_v12.y - local_v11.y); + localTangent.Normalize(); + var localNormal = b2Collision.s_localNormal; + localNormal.x = localTangent.y; + localNormal.y = (-localTangent.x); + var planePoint = b2Collision.s_planePoint; + planePoint.Set(0.5 * (local_v11.x + local_v12.x), 0.5 * (local_v11.y + local_v12.y)); + var tangent = b2Collision.s_tangent; + tMat = xf1.R; + tangent.x = (tMat.col1.x * localTangent.x + tMat.col2.x * localTangent.y); + tangent.y = (tMat.col1.y * localTangent.x + tMat.col2.y * localTangent.y); + var tangent2 = b2Collision.s_tangent2; + tangent2.x = (-tangent.x); + tangent2.y = (-tangent.y); + var normal = b2Collision.s_normal; + normal.x = tangent.y; + normal.y = (-tangent.x); + var v11 = b2Collision.s_v11; + var v12 = b2Collision.s_v12; + v11.x = xf1.position.x + (tMat.col1.x * local_v11.x + tMat.col2.x * local_v11.y); + v11.y = xf1.position.y + (tMat.col1.y * local_v11.x + tMat.col2.y * local_v11.y); + v12.x = xf1.position.x + (tMat.col1.x * local_v12.x + tMat.col2.x * local_v12.y); + v12.y = xf1.position.y + (tMat.col1.y * local_v12.x + tMat.col2.y * local_v12.y); + var frontOffset = normal.x * v11.x + normal.y * v11.y; + var sideOffset1 = (-tangent.x * v11.x) - tangent.y * v11.y + totalRadius; + var sideOffset2 = tangent.x * v12.x + tangent.y * v12.y + totalRadius; + var clipPoints1 = b2Collision.s_clipPoints1; + var clipPoints2 = b2Collision.s_clipPoints2; + var np = 0; + np = this.ClipSegmentToLine(clipPoints1, incidentEdge, tangent2, sideOffset1); + if (np < 2) return; + np = this.ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2); + if (np < 2) return; + manifold.m_localPlaneNormal.SetV(localNormal); + manifold.m_localPoint.SetV(planePoint); + var pointCount = 0; + for (var i = 0; i < b2Settings.b2_maxManifoldPoints; ++i) { + cv = clipPoints2[i]; + var separation = normal.x * cv.v.x + normal.y * cv.v.y - frontOffset; + if (separation <= totalRadius) { + var cp = manifold.m_points[pointCount]; + tMat = xf2.R; + var tX = cv.v.x - xf2.position.x; + var tY = cv.v.y - xf2.position.y; + cp.m_localPoint.x = (tX * tMat.col1.x + tY * tMat.col1.y); + cp.m_localPoint.y = (tX * tMat.col2.x + tY * tMat.col2.y); + cp.m_id.Set(cv.id); + cp.m_id.features.flip = flip; + ++pointCount; + } + } + manifold.m_pointCount = pointCount; + } + b2Collision.CollidePolygons = b2Collision.prototype.CollidePolygons; + b2Collision.prototype.CollideCircles = function (manifold, circle1, xf1, circle2, xf2) { + manifold.m_pointCount = 0; + var tMat; + var tVec; + tMat = xf1.R; + tVec = circle1.m_p; + var p1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var p1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = xf2.R; + tVec = circle2.m_p; + var p2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var p2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var dX = p2X - p1X; + var dY = p2Y - p1Y; + var distSqr = dX * dX + dY * dY; + var radius = circle1.m_radius + circle2.m_radius; + if (distSqr > radius * radius) { + return; + } + manifold.m_type = b2Manifold.e_circles; + manifold.m_localPoint.SetV(circle1.m_p); + manifold.m_localPlaneNormal.SetZero(); + manifold.m_pointCount = 1; + manifold.m_points[0].m_localPoint.SetV(circle2.m_p); + manifold.m_points[0].m_id.key = 0; + } + b2Collision.CollideCircles = b2Collision.prototype.CollideCircles; + b2Collision.prototype.CollidePolygonAndCircle = function (manifold, polygon, xf1, circle, xf2) { + manifold.m_pointCount = 0; + var tPoint; + var dX = 0; + var dY = 0; + var positionX = 0; + var positionY = 0; + var tVec; + var tMat; + tMat = xf2.R; + tVec = circle.m_p; + var cX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var cY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + dX = cX - xf1.position.x; + dY = cY - xf1.position.y; + tMat = xf1.R; + var cLocalX = (dX * tMat.col1.x + dY * tMat.col1.y); + var cLocalY = (dX * tMat.col2.x + dY * tMat.col2.y); + var dist = 0; + var normalIndex = 0; + var separation = (-Number.MAX_VALUE); + var radius = polygon.m_radius + circle.m_radius; + var vertexCount = parseInt(polygon.m_vertexCount); + var vertices = polygon.m_vertices; + var normals = polygon.m_normals; + for (var i = 0; i < vertexCount; ++i) { + tVec = vertices[i]; + dX = cLocalX - tVec.x; + dY = cLocalY - tVec.y; + tVec = normals[i]; + var s = tVec.x * dX + tVec.y * dY; + if (s > radius) { + return; + } + if (s > separation) { + separation = s; + normalIndex = i; + } + } + var vertIndex1 = parseInt(normalIndex); + var vertIndex2 = parseInt(vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0); + var v1 = vertices[vertIndex1]; + var v2 = vertices[vertIndex2]; + if (separation < Number.MIN_VALUE) { + manifold.m_pointCount = 1; + manifold.m_type = b2Manifold.e_faceA; + manifold.m_localPlaneNormal.SetV(normals[normalIndex]); + manifold.m_localPoint.x = 0.5 * (v1.x + v2.x); + manifold.m_localPoint.y = 0.5 * (v1.y + v2.y); + manifold.m_points[0].m_localPoint.SetV(circle.m_p); + manifold.m_points[0].m_id.key = 0; + return; + } + var u1 = (cLocalX - v1.x) * (v2.x - v1.x) + (cLocalY - v1.y) * (v2.y - v1.y); + var u2 = (cLocalX - v2.x) * (v1.x - v2.x) + (cLocalY - v2.y) * (v1.y - v2.y); + if (u1 <= 0.0) { + if ((cLocalX - v1.x) * (cLocalX - v1.x) + (cLocalY - v1.y) * (cLocalY - v1.y) > radius * radius) return; + manifold.m_pointCount = 1; + manifold.m_type = b2Manifold.e_faceA; + manifold.m_localPlaneNormal.x = cLocalX - v1.x; + manifold.m_localPlaneNormal.y = cLocalY - v1.y; + manifold.m_localPlaneNormal.Normalize(); + manifold.m_localPoint.SetV(v1); + manifold.m_points[0].m_localPoint.SetV(circle.m_p); + manifold.m_points[0].m_id.key = 0; + } + else if (u2 <= 0) { + if ((cLocalX - v2.x) * (cLocalX - v2.x) + (cLocalY - v2.y) * (cLocalY - v2.y) > radius * radius) return; + manifold.m_pointCount = 1; + manifold.m_type = b2Manifold.e_faceA; + manifold.m_localPlaneNormal.x = cLocalX - v2.x; + manifold.m_localPlaneNormal.y = cLocalY - v2.y; + manifold.m_localPlaneNormal.Normalize(); + manifold.m_localPoint.SetV(v2); + manifold.m_points[0].m_localPoint.SetV(circle.m_p); + manifold.m_points[0].m_id.key = 0; + } + else { + var faceCenterX = 0.5 * (v1.x + v2.x); + var faceCenterY = 0.5 * (v1.y + v2.y); + separation = (cLocalX - faceCenterX) * normals[vertIndex1].x + (cLocalY - faceCenterY) * normals[vertIndex1].y; + if (separation > radius) return; + manifold.m_pointCount = 1; + manifold.m_type = b2Manifold.e_faceA; + manifold.m_localPlaneNormal.x = normals[vertIndex1].x; + manifold.m_localPlaneNormal.y = normals[vertIndex1].y; + manifold.m_localPlaneNormal.Normalize(); + manifold.m_localPoint.Set(faceCenterX, faceCenterY); + manifold.m_points[0].m_localPoint.SetV(circle.m_p); + manifold.m_points[0].m_id.key = 0; + } + } + b2Collision.CollidePolygonAndCircle = b2Collision.prototype.CollidePolygonAndCircle; + b2Collision.prototype.TestOverlap = function (a, b) { + var t1 = b.lowerBound; + var t2 = a.upperBound; + var d1X = t1.x - t2.x; + var d1Y = t1.y - t2.y; + t1 = a.lowerBound; + t2 = b.upperBound; + var d2X = t1.x - t2.x; + var d2Y = t1.y - t2.y; + if (d1X > 0.0 || d1Y > 0.0) return false; + if (d2X > 0.0 || d2Y > 0.0) return false; + return true; + } + b2Collision.TestOverlap = b2Collision.prototype.TestOverlap; + _A2J_postDefs.push(function () { + Box2D.Collision.b2Collision.s_incidentEdge = b2Collision.MakeClipPointVector(); + Box2D.Collision.b2Collision.prototype.s_incidentEdge = Box2D.Collision.b2Collision.s_incidentEdge; + Box2D.Collision.b2Collision.s_clipPoints1 = b2Collision.MakeClipPointVector(); + Box2D.Collision.b2Collision.prototype.s_clipPoints1 = Box2D.Collision.b2Collision.s_clipPoints1; + Box2D.Collision.b2Collision.s_clipPoints2 = b2Collision.MakeClipPointVector(); + Box2D.Collision.b2Collision.prototype.s_clipPoints2 = Box2D.Collision.b2Collision.s_clipPoints2; + Box2D.Collision.b2Collision.s_edgeAO = new Vector_a2j_Number(1); + Box2D.Collision.b2Collision.prototype.s_edgeAO = Box2D.Collision.b2Collision.s_edgeAO; + Box2D.Collision.b2Collision.s_edgeBO = new Vector_a2j_Number(1); + Box2D.Collision.b2Collision.prototype.s_edgeBO = Box2D.Collision.b2Collision.s_edgeBO; + Box2D.Collision.b2Collision.s_localTangent = new b2Vec2(); + Box2D.Collision.b2Collision.prototype.s_localTangent = Box2D.Collision.b2Collision.s_localTangent; + Box2D.Collision.b2Collision.s_localNormal = new b2Vec2(); + Box2D.Collision.b2Collision.prototype.s_localNormal = Box2D.Collision.b2Collision.s_localNormal; + Box2D.Collision.b2Collision.s_planePoint = new b2Vec2(); + Box2D.Collision.b2Collision.prototype.s_planePoint = Box2D.Collision.b2Collision.s_planePoint; + Box2D.Collision.b2Collision.s_normal = new b2Vec2(); + Box2D.Collision.b2Collision.prototype.s_normal = Box2D.Collision.b2Collision.s_normal; + Box2D.Collision.b2Collision.s_tangent = new b2Vec2(); + Box2D.Collision.b2Collision.prototype.s_tangent = Box2D.Collision.b2Collision.s_tangent; + Box2D.Collision.b2Collision.s_tangent2 = new b2Vec2(); + Box2D.Collision.b2Collision.prototype.s_tangent2 = Box2D.Collision.b2Collision.s_tangent2; + Box2D.Collision.b2Collision.s_v11 = new b2Vec2(); + Box2D.Collision.b2Collision.prototype.s_v11 = Box2D.Collision.b2Collision.s_v11; + Box2D.Collision.b2Collision.s_v12 = new b2Vec2(); + Box2D.Collision.b2Collision.prototype.s_v12 = Box2D.Collision.b2Collision.s_v12; + Box2D.Collision.b2Collision.b2CollidePolyTempVec = new b2Vec2(); + Box2D.Collision.b2Collision.prototype.b2CollidePolyTempVec = Box2D.Collision.b2Collision.b2CollidePolyTempVec; + Box2D.Collision.b2Collision.b2_nullFeature = 0x000000ff; + Box2D.Collision.b2Collision.prototype.b2_nullFeature = Box2D.Collision.b2Collision.b2_nullFeature; + }); + b2ContactID.b2ContactID = function () { + this.features = new Features(); + }; + b2ContactID.prototype.b2ContactID = function () { + this.features._m_id = this; + } + b2ContactID.prototype.Set = function (id) { + this.key = id._key; + } + b2ContactID.prototype.Copy = function () { + var id = new b2ContactID(); + id.key = this.key; + return id; + } + b2ContactID.prototype.__defineGetter__('key', function () { + return this._key; + }); + b2ContactID.prototype.__defineSetter__('key', function (value) { + if (value === undefined) value = 0; + this._key = value; + this.features._referenceEdge = this._key & 0x000000ff; + this.features._incidentEdge = ((this._key & 0x0000ff00) >> 8) & 0x000000ff; + this.features._incidentVertex = ((this._key & 0x00ff0000) >> 16) & 0x000000ff; + this.features._flip = ((this._key & 0xff000000) >> 24) & 0x000000ff; + }); + b2ContactPoint.b2ContactPoint = function () { + this.position = new b2Vec2(); + this.velocity = new b2Vec2(); + this.normal = new b2Vec2(); + this.id = new b2ContactID(); + }; + b2Distance.b2Distance = function () {}; + b2Distance.prototype.Distance = function (output, cache, input) { + ++b2Distance.b2_gjkCalls; + var proxyA = input.proxyA; + var proxyB = input.proxyB; + var transformA = input.transformA; + var transformB = input.transformB; + var simplex = b2Distance.s_simplex; + simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB); + var vertices = simplex.m_vertices; + var k_maxIters = 20; + var saveA = b2Distance.s_saveA; + var saveB = b2Distance.s_saveB; + var saveCount = 0; + var closestPoint = simplex.GetClosestPoint(); + var distanceSqr1 = closestPoint.LengthSquared(); + var distanceSqr2 = distanceSqr1; + var i = 0; + var p; + var iter = 0; + while (iter < k_maxIters) { + saveCount = simplex.m_count; + for (i = 0; + i < saveCount; i++) { + saveA[i] = vertices[i].indexA; + saveB[i] = vertices[i].indexB; + } + switch (simplex.m_count) { + case 1: + break; + case 2: + simplex.Solve2(); + break; + case 3: + simplex.Solve3(); + break; + default: + b2Settings.b2Assert(false); + } + if (simplex.m_count == 3) { + break; + } + p = simplex.GetClosestPoint(); + distanceSqr2 = p.LengthSquared(); + if (distanceSqr2 > distanceSqr1) {} + distanceSqr1 = distanceSqr2; + var d = simplex.GetSearchDirection(); + if (d.LengthSquared() < Number.MIN_VALUE * Number.MIN_VALUE) { + break; + } + var vertex = vertices[simplex.m_count]; + vertex.indexA = proxyA.GetSupport(b2Math.MulTMV(transformA.R, d.GetNegative())); + vertex.wA = b2Math.MulX(transformA, proxyA.GetVertex(vertex.indexA)); + vertex.indexB = proxyB.GetSupport(b2Math.MulTMV(transformB.R, d)); + vertex.wB = b2Math.MulX(transformB, proxyB.GetVertex(vertex.indexB)); + vertex.w = b2Math.SubtractVV(vertex.wB, vertex.wA); + ++iter; + ++b2Distance.b2_gjkIters; + var duplicate = false; + for (i = 0; + i < saveCount; i++) { + if (vertex.indexA == saveA[i] && vertex.indexB == saveB[i]) { + duplicate = true; + break; + } + } + if (duplicate) { + break; + }++simplex.m_count; + } + b2Distance.b2_gjkMaxIters = b2Math.Max(b2Distance.b2_gjkMaxIters, iter); + simplex.GetWitnessPoints(output.pointA, output.pointB); + output.distance = b2Math.SubtractVV(output.pointA, output.pointB).Length(); + output.iterations = iter; + simplex.WriteCache(cache); + if (input.useRadii) { + var rA = proxyA.m_radius; + var rB = proxyB.m_radius; + if (output.distance > rA + rB && output.distance > Number.MIN_VALUE) { + output.distance -= rA + rB; + var normal = b2Math.SubtractVV(output.pointB, output.pointA); + normal.Normalize(); + output.pointA.x += rA * normal.x; + output.pointA.y += rA * normal.y; + output.pointB.x -= rB * normal.x; + output.pointB.y -= rB * normal.y; + } + else { + p = new b2Vec2(); + p.x = .5 * (output.pointA.x + output.pointB.x); + p.y = .5 * (output.pointA.y + output.pointB.y); + output.pointA.x = output.pointB.x = p.x; + output.pointA.y = output.pointB.y = p.y; + output.distance = 0.0; + } + } + } + b2Distance.Distance = b2Distance.prototype.Distance; + _A2J_postDefs.push(function () { + Box2D.Collision.b2Distance.s_simplex = new b2Simplex(); + Box2D.Collision.b2Distance.prototype.s_simplex = Box2D.Collision.b2Distance.s_simplex; + Box2D.Collision.b2Distance.s_saveA = new Vector_a2j_Number(3); + Box2D.Collision.b2Distance.prototype.s_saveA = Box2D.Collision.b2Distance.s_saveA; + Box2D.Collision.b2Distance.s_saveB = new Vector_a2j_Number(3); + Box2D.Collision.b2Distance.prototype.s_saveB = Box2D.Collision.b2Distance.s_saveB; + }); + b2DistanceInput.b2DistanceInput = function () {}; + b2DistanceOutput.b2DistanceOutput = function () { + this.pointA = new b2Vec2(); + this.pointB = new b2Vec2(); + }; + b2DistanceProxy.b2DistanceProxy = function () {}; + b2DistanceProxy.prototype.Set = function (shape) { + switch (shape.GetType()) { + case b2Shape.e_circleShape: + { + var circle = (shape instanceof b2CircleShape ? shape : null); + this.m_vertices = new Vector(1, true); + this.m_vertices[0] = circle.m_p; + this.m_count = 1; + this.m_radius = circle.m_radius; + } + break; + case b2Shape.e_polygonShape: + { + var polygon = (shape instanceof b2PolygonShape ? shape : null); + this.m_vertices = polygon.m_vertices; + this.m_count = polygon.m_vertexCount; + this.m_radius = polygon.m_radius; + } + break; + default: + b2Settings.b2Assert(false); + } + } + b2DistanceProxy.prototype.GetSupport = function (d) { + var bestIndex = 0; + var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; + for (var i = 1; i < this.m_count; ++i) { + var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; + if (value > bestValue) { + bestIndex = i; + bestValue = value; + } + } + return bestIndex; + } + b2DistanceProxy.prototype.GetSupportVertex = function (d) { + var bestIndex = 0; + var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; + for (var i = 1; i < this.m_count; ++i) { + var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; + if (value > bestValue) { + bestIndex = i; + bestValue = value; + } + } + return this.m_vertices[bestIndex]; + } + b2DistanceProxy.prototype.GetVertexCount = function () { + return this.m_count; + } + b2DistanceProxy.prototype.GetVertex = function (index) { + if (index === undefined) index = 0; + b2Settings.b2Assert(0 <= index && index < this.m_count); + return this.m_vertices[index]; + } + b2DynamicTree.b2DynamicTree = function () {}; + b2DynamicTree.prototype.b2DynamicTree = function () { + this.m_root = null; + this.m_freeList = null; + this.m_path = 0; + this.m_insertionCount = 0; + } + b2DynamicTree.prototype.CreateProxy = function (aabb, userData) { + var node = this.AllocateNode(); + var extendX = b2Settings.b2_aabbExtension; + var extendY = b2Settings.b2_aabbExtension; + node.aabb.lowerBound.x = aabb.lowerBound.x - extendX; + node.aabb.lowerBound.y = aabb.lowerBound.y - extendY; + node.aabb.upperBound.x = aabb.upperBound.x + extendX; + node.aabb.upperBound.y = aabb.upperBound.y + extendY; + node.userData = userData; + this.InsertLeaf(node); + return node; + } + b2DynamicTree.prototype.DestroyProxy = function (proxy) { + this.RemoveLeaf(proxy); + this.FreeNode(proxy); + } + b2DynamicTree.prototype.MoveProxy = function (proxy, aabb, displacement) { + b2Settings.b2Assert(proxy.IsLeaf()); + if (proxy.aabb.Contains(aabb)) { + return false; + } + this.RemoveLeaf(proxy); + var extendX = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.x > 0 ? displacement.x : (-displacement.x)); + var extendY = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.y > 0 ? displacement.y : (-displacement.y)); + proxy.aabb.lowerBound.x = aabb.lowerBound.x - extendX; + proxy.aabb.lowerBound.y = aabb.lowerBound.y - extendY; + proxy.aabb.upperBound.x = aabb.upperBound.x + extendX; + proxy.aabb.upperBound.y = aabb.upperBound.y + extendY; + this.InsertLeaf(proxy); + return true; + } + b2DynamicTree.prototype.Rebalance = function (iterations) { + if (iterations === undefined) iterations = 0; + if (this.m_root == null) return; + for (var i = 0; i < iterations; i++) { + var node = this.m_root; + var bit = 0; + while (node.IsLeaf() == false) { + node = (this.m_path >> bit) & 1 ? node.child2 : node.child1; + bit = (bit + 1) & 31; + }++this.m_path; + this.RemoveLeaf(node); + this.InsertLeaf(node); + } + } + b2DynamicTree.prototype.GetFatAABB = function (proxy) { + return proxy.aabb; + } + b2DynamicTree.prototype.GetUserData = function (proxy) { + return proxy.userData; + } + b2DynamicTree.prototype.Query = function (callback, aabb) { + if (this.m_root == null) return; + var stack = new Vector(); + var count = 0; + stack[count++] = this.m_root; + while (count > 0) { + var node = stack[--count]; + if (node.aabb.TestOverlap(aabb)) { + if (node.IsLeaf()) { + var proceed = callback(node); + if (!proceed) return; + } + else { + stack[count++] = node.child1; + stack[count++] = node.child2; + } + } + } + } + b2DynamicTree.prototype.RayCast = function (callback, input) { + if (this.m_root == null) return; + var p1 = input.p1; + var p2 = input.p2; + var r = b2Math.SubtractVV(p1, p2); + r.Normalize(); + var v = b2Math.CrossFV(1.0, r); + var abs_v = b2Math.AbsV(v); + var maxFraction = input.maxFraction; + var segmentAABB = new b2AABB(); + var tX = 0; + var tY = 0; { + tX = p1.x + maxFraction * (p2.x - p1.x); + tY = p1.y + maxFraction * (p2.y - p1.y); + segmentAABB.lowerBound.x = Math.min(p1.x, tX); + segmentAABB.lowerBound.y = Math.min(p1.y, tY); + segmentAABB.upperBound.x = Math.max(p1.x, tX); + segmentAABB.upperBound.y = Math.max(p1.y, tY); + } + var stack = new Vector(); + var count = 0; + stack[count++] = this.m_root; + while (count > 0) { + var node = stack[--count]; + if (node.aabb.TestOverlap(segmentAABB) == false) { + continue; + } + var c = node.aabb.GetCenter(); + var h = node.aabb.GetExtents(); + var separation = Math.abs(v.x * (p1.x - c.x) + v.y * (p1.y - c.y)) - abs_v.x * h.x - abs_v.y * h.y; + if (separation > 0.0) continue; + if (node.IsLeaf()) { + var subInput = new b2RayCastInput(); + subInput.p1 = input.p1; + subInput.p2 = input.p2; + subInput.maxFraction = input.maxFraction; + maxFraction = callback(subInput, node); + if (maxFraction == 0.0) return; + if (maxFraction > 0.0) { + tX = p1.x + maxFraction * (p2.x - p1.x); + tY = p1.y + maxFraction * (p2.y - p1.y); + segmentAABB.lowerBound.x = Math.min(p1.x, tX); + segmentAABB.lowerBound.y = Math.min(p1.y, tY); + segmentAABB.upperBound.x = Math.max(p1.x, tX); + segmentAABB.upperBound.y = Math.max(p1.y, tY); + } + } + else { + stack[count++] = node.child1; + stack[count++] = node.child2; + } + } + } + b2DynamicTree.prototype.AllocateNode = function () { + if (this.m_freeList) { + var node = this.m_freeList; + this.m_freeList = node.parent; + node.parent = null; + node.child1 = null; + node.child2 = null; + return node; + } + return new b2DynamicTreeNode(); + } + b2DynamicTree.prototype.FreeNode = function (node) { + node.parent = this.m_freeList; + this.m_freeList = node; + } + b2DynamicTree.prototype.InsertLeaf = function (leaf) { + ++this.m_insertionCount; + if (this.m_root == null) { + this.m_root = leaf; + this.m_root.parent = null; + return; + } + var center = leaf.aabb.GetCenter(); + var sibling = this.m_root; + if (sibling.IsLeaf() == false) { + do { + var child1 = sibling.child1; + var child2 = sibling.child2; + var norm1 = Math.abs((child1.aabb.lowerBound.x + child1.aabb.upperBound.x) / 2 - center.x) + Math.abs((child1.aabb.lowerBound.y + child1.aabb.upperBound.y) / 2 - center.y); + var norm2 = Math.abs((child2.aabb.lowerBound.x + child2.aabb.upperBound.x) / 2 - center.x) + Math.abs((child2.aabb.lowerBound.y + child2.aabb.upperBound.y) / 2 - center.y); + if (norm1 < norm2) { + sibling = child1; + } + else { + sibling = child2; + } + } + while (sibling.IsLeaf() == false) + } + var node1 = sibling.parent; + var node2 = this.AllocateNode(); + node2.parent = node1; + node2.userData = null; + node2.aabb.Combine(leaf.aabb, sibling.aabb); + if (node1) { + if (sibling.parent.child1 == sibling) { + node1.child1 = node2; + } + else { + node1.child2 = node2; + } + node2.child1 = sibling; + node2.child2 = leaf; + sibling.parent = node2; + leaf.parent = node2; + do { + if (node1.aabb.Contains(node2.aabb)) break; + node1.aabb.Combine(node1.child1.aabb, node1.child2.aabb); + node2 = node1; + node1 = node1.parent; + } + while (node1) + } + else { + node2.child1 = sibling; + node2.child2 = leaf; + sibling.parent = node2; + leaf.parent = node2; + this.m_root = node2; + } + } + b2DynamicTree.prototype.RemoveLeaf = function (leaf) { + if (leaf == this.m_root) { + this.m_root = null; + return; + } + var node2 = leaf.parent; + var node1 = node2.parent; + var sibling; + if (node2.child1 == leaf) { + sibling = node2.child2; + } + else { + sibling = node2.child1; + } + if (node1) { + if (node1.child1 == node2) { + node1.child1 = sibling; + } + else { + node1.child2 = sibling; + } + sibling.parent = node1; + this.FreeNode(node2); + while (node1) { + var oldAABB = node1.aabb; + node1.aabb = b2AABB.Combine(node1.child1.aabb, node1.child2.aabb); + if (oldAABB.Contains(node1.aabb)) break; + node1 = node1.parent; + } + } + else { + this.m_root = sibling; + sibling.parent = null; + this.FreeNode(node2); + } + } + b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase = function () { + this.m_tree = new b2DynamicTree(); + this.m_moveBuffer = new Vector(); + this.m_pairBuffer = new Vector(); + this.m_pairCount = 0; + }; + b2DynamicTreeBroadPhase.prototype.CreateProxy = function (aabb, userData) { + var proxy = this.m_tree.CreateProxy(aabb, userData); + ++this.m_proxyCount; + this.BufferMove(proxy); + return proxy; + } + b2DynamicTreeBroadPhase.prototype.DestroyProxy = function (proxy) { + this.UnBufferMove(proxy); + --this.m_proxyCount; + this.m_tree.DestroyProxy(proxy); + } + b2DynamicTreeBroadPhase.prototype.MoveProxy = function (proxy, aabb, displacement) { + var buffer = this.m_tree.MoveProxy(proxy, aabb, displacement); + if (buffer) { + this.BufferMove(proxy); + } + } + b2DynamicTreeBroadPhase.prototype.TestOverlap = function (proxyA, proxyB) { + var aabbA = this.m_tree.GetFatAABB(proxyA); + var aabbB = this.m_tree.GetFatAABB(proxyB); + return aabbA.TestOverlap(aabbB); + } + b2DynamicTreeBroadPhase.prototype.GetUserData = function (proxy) { + return this.m_tree.GetUserData(proxy); + } + b2DynamicTreeBroadPhase.prototype.GetFatAABB = function (proxy) { + return this.m_tree.GetFatAABB(proxy); + } + b2DynamicTreeBroadPhase.prototype.GetProxyCount = function () { + return this.m_proxyCount; + } + b2DynamicTreeBroadPhase.prototype.UpdatePairs = function (callback) { + var __this = this; + __this.m_pairCount = 0; + var queryProxy; + for (var each in __this.m_moveBuffer) { + queryProxy = __this.m_moveBuffer[each]; { + function QueryCallback(proxy) { + if (proxy == queryProxy) return true; + if (__this.m_pairCount == __this.m_pairBuffer.length) { + __this.m_pairBuffer[__this.m_pairCount] = new b2DynamicTreePair(); + } + var pair = __this.m_pairBuffer[__this.m_pairCount]; + pair.proxyA = proxy < queryProxy ? proxy : queryProxy; + pair.proxyB = proxy >= queryProxy ? proxy : queryProxy;++__this.m_pairCount; + return true; + }; + var fatAABB = __this.m_tree.GetFatAABB(queryProxy); + __this.m_tree.Query(QueryCallback, fatAABB); + } + } + __this.m_moveBuffer.length = 0; + for (var i = 0; i < __this.m_pairCount;) { + var primaryPair = __this.m_pairBuffer[i]; + var userDataA = __this.m_tree.GetUserData(primaryPair.proxyA); + var userDataB = __this.m_tree.GetUserData(primaryPair.proxyB); + callback(userDataA, userDataB); + ++i; + while (i < __this.m_pairCount) { + var pair = __this.m_pairBuffer[i]; + if (pair.proxyA != primaryPair.proxyA || pair.proxyB != primaryPair.proxyB) { + break; + }++i; + } + } + } + b2DynamicTreeBroadPhase.prototype.Query = function (callback, aabb) { + this.m_tree.Query(callback, aabb); + } + b2DynamicTreeBroadPhase.prototype.RayCast = function (callback, input) { + this.m_tree.RayCast(callback, input); + } + b2DynamicTreeBroadPhase.prototype.Validate = function () {} + b2DynamicTreeBroadPhase.prototype.Rebalance = function (iterations) { + if (iterations === undefined) iterations = 0; + this.m_tree.Rebalance(iterations); + } + b2DynamicTreeBroadPhase.prototype.BufferMove = function (proxy) { + this.m_moveBuffer[this.m_moveBuffer.length] = proxy; + } + b2DynamicTreeBroadPhase.prototype.UnBufferMove = function (proxy) { + var i = parseInt(this.m_moveBuffer.indexOf(proxy)); + this.m_moveBuffer.splice(i, 1); + } + b2DynamicTreeBroadPhase.prototype.ComparePairs = function (pair1, pair2) { + return 0; + } + b2DynamicTreeBroadPhase.__implements = {}; + b2DynamicTreeBroadPhase.__implements[IBroadPhase] = true; + b2DynamicTreeNode.b2DynamicTreeNode = function () { + this.aabb = new b2AABB(); + }; + b2DynamicTreeNode.prototype.IsLeaf = function () { + return this.child1 == null; + } + b2DynamicTreePair.b2DynamicTreePair = function () {}; + b2Manifold.b2Manifold = function () { + this.m_pointCount = 0; + }; + b2Manifold.prototype.b2Manifold = function () { + this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); + for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { + this.m_points[i] = new b2ManifoldPoint(); + } + this.m_localPlaneNormal = new b2Vec2(); + this.m_localPoint = new b2Vec2(); + } + b2Manifold.prototype.Reset = function () { + for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { + ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Reset(); + } + this.m_localPlaneNormal.SetZero(); + this.m_localPoint.SetZero(); + this.m_type = 0; + this.m_pointCount = 0; + } + b2Manifold.prototype.Set = function (m) { + this.m_pointCount = m.m_pointCount; + for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { + ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Set(m.m_points[i]); + } + this.m_localPlaneNormal.SetV(m.m_localPlaneNormal); + this.m_localPoint.SetV(m.m_localPoint); + this.m_type = m.m_type; + } + b2Manifold.prototype.Copy = function () { + var copy = new b2Manifold(); + copy.Set(this); + return copy; + } + _A2J_postDefs.push(function () { + Box2D.Collision.b2Manifold.e_circles = 0x0001; + Box2D.Collision.b2Manifold.prototype.e_circles = Box2D.Collision.b2Manifold.e_circles; + Box2D.Collision.b2Manifold.e_faceA = 0x0002; + Box2D.Collision.b2Manifold.prototype.e_faceA = Box2D.Collision.b2Manifold.e_faceA; + Box2D.Collision.b2Manifold.e_faceB = 0x0004; + Box2D.Collision.b2Manifold.prototype.e_faceB = Box2D.Collision.b2Manifold.e_faceB; + }); + b2ManifoldPoint.b2ManifoldPoint = function () { + this.m_localPoint = new b2Vec2(); + this.m_id = new b2ContactID(); + }; + b2ManifoldPoint.prototype.b2ManifoldPoint = function () { + this.Reset(); + } + b2ManifoldPoint.prototype.Reset = function () { + this.m_localPoint.SetZero(); + this.m_normalImpulse = 0.0; + this.m_tangentImpulse = 0.0; + this.m_id.key = 0; + } + b2ManifoldPoint.prototype.Set = function (m) { + this.m_localPoint.SetV(m.m_localPoint); + this.m_normalImpulse = m.m_normalImpulse; + this.m_tangentImpulse = m.m_tangentImpulse; + this.m_id.Set(m.m_id); + } + b2OBB.b2OBB = function () { + this.R = new b2Mat22(); + this.center = new b2Vec2(); + this.extents = new b2Vec2(); + }; + b2Pair.b2Pair = function () { + this.userData = null; + }; + b2Pair.prototype.SetBuffered = function () { + this.status |= b2Pair.e_pairBuffered; + } + b2Pair.prototype.ClearBuffered = function () { + this.status &= ~b2Pair.e_pairBuffered; + } + b2Pair.prototype.IsBuffered = function () { + return (this.status & b2Pair.e_pairBuffered) == b2Pair.e_pairBuffered; + } + b2Pair.prototype.SetRemoved = function () { + this.status |= b2Pair.e_pairRemoved; + } + b2Pair.prototype.ClearRemoved = function () { + this.status &= ~b2Pair.e_pairRemoved; + } + b2Pair.prototype.IsRemoved = function () { + return (this.status & b2Pair.e_pairRemoved) == b2Pair.e_pairRemoved; + } + b2Pair.prototype.SetFinal = function () { + this.status |= b2Pair.e_pairFinal; + } + b2Pair.prototype.IsFinal = function () { + return (this.status & b2Pair.e_pairFinal) == b2Pair.e_pairFinal; + } + _A2J_postDefs.push(function () { + Box2D.Collision.b2Pair.b2_nullProxy = parseInt(b2Settings.USHRT_MAX); + Box2D.Collision.b2Pair.prototype.b2_nullProxy = Box2D.Collision.b2Pair.b2_nullProxy; + Box2D.Collision.b2Pair.e_pairBuffered = 0x0001; + Box2D.Collision.b2Pair.prototype.e_pairBuffered = Box2D.Collision.b2Pair.e_pairBuffered; + Box2D.Collision.b2Pair.e_pairRemoved = 0x0002; + Box2D.Collision.b2Pair.prototype.e_pairRemoved = Box2D.Collision.b2Pair.e_pairRemoved; + Box2D.Collision.b2Pair.e_pairFinal = 0x0004; + Box2D.Collision.b2Pair.prototype.e_pairFinal = Box2D.Collision.b2Pair.e_pairFinal; + }); + b2PairManager.b2PairManager = function () {}; + b2PairManager.prototype.b2PairManager = function () { + this.m_pairs = new Array(); + this.m_pairBuffer = new Array(); + this.m_pairCount = 0; + this.m_pairBufferCount = 0; + this.m_freePair = null; + } + b2PairManager.prototype.Initialize = function (broadPhase) { + this.m_broadPhase = broadPhase; + } + b2PairManager.prototype.AddBufferedPair = function (proxy1, proxy2) { + var pair = this.AddPair(proxy1, proxy2); + if (pair.IsBuffered() == false) { + pair.SetBuffered(); + this.m_pairBuffer[this.m_pairBufferCount] = pair; + ++this.m_pairBufferCount; + } + pair.ClearRemoved(); + if (b2BroadPhase.s_validate) { + this.ValidateBuffer(); + } + } + b2PairManager.prototype.RemoveBufferedPair = function (proxy1, proxy2) { + var pair = this.Find(proxy1, proxy2); + if (pair == null) { + return; + } + if (pair.IsBuffered() == false) { + pair.SetBuffered(); + this.m_pairBuffer[this.m_pairBufferCount] = pair; + ++this.m_pairBufferCount; + } + pair.SetRemoved(); + if (b2BroadPhase.s_validate) { + this.ValidateBuffer(); + } + } + b2PairManager.prototype.Commit = function (callback) { + var i = 0; + var removeCount = 0; + for (i = 0; + i < this.m_pairBufferCount; ++i) { + var pair = this.m_pairBuffer[i]; + pair.ClearBuffered(); + var proxy1 = pair.proxy1; + var proxy2 = pair.proxy2; + if (pair.IsRemoved()) {} else { + if (pair.IsFinal() == false) { + callback(proxy1.userData, proxy2.userData); + } + } + } + this.m_pairBufferCount = 0; + if (b2BroadPhase.s_validate) { + this.ValidateTable(); + } + } + b2PairManager.prototype.AddPair = function (proxy1, proxy2) { + var pair = proxy1.pairs[proxy2]; + if (pair != null) return pair; + if (this.m_freePair == null) { + this.m_freePair = new b2Pair(); + this.m_pairs.push(this.m_freePair); + } + pair = this.m_freePair; + this.m_freePair = pair.next; + pair.proxy1 = proxy1; + pair.proxy2 = proxy2; + pair.status = 0; + pair.userData = null; + pair.next = null; + proxy1.pairs[proxy2] = pair; + proxy2.pairs[proxy1] = pair; + ++this.m_pairCount; + return pair; + } + b2PairManager.prototype.RemovePair = function (proxy1, proxy2) { + var pair = proxy1.pairs[proxy2]; + if (pair == null) { + return null; + } + var userData = pair.userData; + delete proxy1.pairs[proxy2]; + delete proxy2.pairs[proxy1]; + pair.next = this.m_freePair; + pair.proxy1 = null; + pair.proxy2 = null; + pair.userData = null; + pair.status = 0; + this.m_freePair = pair; + --this.m_pairCount; + return userData; + } + b2PairManager.prototype.Find = function (proxy1, proxy2) { + return proxy1.pairs[proxy2]; + } + b2PairManager.prototype.ValidateBuffer = function () {} + b2PairManager.prototype.ValidateTable = function () {} + b2Point.b2Point = function () { + this.p = new b2Vec2(); + }; + b2Point.prototype.Support = function (xf, vX, vY) { + if (vX === undefined) vX = 0; + if (vY === undefined) vY = 0; + return this.p; + } + b2Point.prototype.GetFirstVertex = function (xf) { + return this.p; + } + b2Proxy.b2Proxy = function () { + this.lowerBounds = new Vector_a2j_Number(2); + this.upperBounds = new Vector_a2j_Number(2); + this.pairs = new Dictionary(); + this.userData = null; + }; + b2Proxy.prototype.IsValid = function () { + return this.overlapCount != b2BroadPhase.b2_invalid; + } + b2RayCastInput.b2RayCastInput = function () { + this.p1 = new b2Vec2(); + this.p2 = new b2Vec2(); + }; + b2RayCastInput.prototype.b2RayCastInput = function (p1, p2, maxFraction) { + if (p1 === undefined) p1 = null; + if (p2 === undefined) p2 = null; + if (maxFraction === undefined) maxFraction = 1; + if (p1) this.p1.SetV(p1); + if (p2) this.p2.SetV(p2); + this.maxFraction = maxFraction; + } + b2RayCastOutput.b2RayCastOutput = function () { + this.normal = new b2Vec2(); + }; + b2Segment.b2Segment = function () { + this.p1 = new b2Vec2(); + this.p2 = new b2Vec2(); + }; + b2Segment.prototype.TestSegment = function (lambda, normal, segment, maxLambda) { + if (maxLambda === undefined) maxLambda = 0; + var s = segment.p1; + var rX = segment.p2.x - s.x; + var rY = segment.p2.y - s.y; + var dX = this.p2.x - this.p1.x; + var dY = this.p2.y - this.p1.y; + var nX = dY; + var nY = (-dX); + var k_slop = 100.0 * Number.MIN_VALUE; + var denom = (-(rX * nX + rY * nY)); + if (denom > k_slop) { + var bX = s.x - this.p1.x; + var bY = s.y - this.p1.y; + var a = (bX * nX + bY * nY); + if (0.0 <= a && a <= maxLambda * denom) { + var mu2 = (-rX * bY) + rY * bX; + if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) { + a /= denom; + var nLen = Math.sqrt(nX * nX + nY * nY); + nX /= nLen; + nY /= nLen; + lambda[0] = a; + normal.Set(nX, nY); + return true; + } + } + } + return false; + } + b2Segment.prototype.Extend = function (aabb) { + this.ExtendForward(aabb); + this.ExtendBackward(aabb); + } + b2Segment.prototype.ExtendForward = function (aabb) { + var dX = this.p2.x - this.p1.x; + var dY = this.p2.y - this.p1.y; + var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p1.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p1.x) / dX : Number.POSITIVE_INFINITY, + dY > 0 ? (aabb.upperBound.y - this.p1.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p1.y) / dY : Number.POSITIVE_INFINITY); + this.p2.x = this.p1.x + dX * lambda; + this.p2.y = this.p1.y + dY * lambda; + } + b2Segment.prototype.ExtendBackward = function (aabb) { + var dX = (-this.p2.x) + this.p1.x; + var dY = (-this.p2.y) + this.p1.y; + var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p2.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p2.x) / dX : Number.POSITIVE_INFINITY, + dY > 0 ? (aabb.upperBound.y - this.p2.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p2.y) / dY : Number.POSITIVE_INFINITY); + this.p1.x = this.p2.x + dX * lambda; + this.p1.y = this.p2.y + dY * lambda; + } + b2SeparationFunction.b2SeparationFunction = function () { + this.m_localPoint = new b2Vec2(); + this.m_axis = new b2Vec2(); + }; + b2SeparationFunction.prototype.Initialize = function (cache, proxyA, transformA, proxyB, transformB) { + this.m_proxyA = proxyA; + this.m_proxyB = proxyB; + var count = parseInt(cache.count); + b2Settings.b2Assert(0 < count && count < 3); + var localPointA; + var localPointA1; + var localPointA2; + var localPointB; + var localPointB1; + var localPointB2; + var pointAX = 0; + var pointAY = 0; + var pointBX = 0; + var pointBY = 0; + var normalX = 0; + var normalY = 0; + var tMat; + var tVec; + var s = 0; + var sgn = 0; + if (count == 1) { + this.m_type = b2SeparationFunction.e_points; + localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); + localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); + tVec = localPointA; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointB; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + this.m_axis.x = pointBX - pointAX; + this.m_axis.y = pointBY - pointAY; + this.m_axis.Normalize(); + } + else if (cache.indexB[0] == cache.indexB[1]) { + this.m_type = b2SeparationFunction.e_faceA; + localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); + localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); + localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); + this.m_localPoint.x = 0.5 * (localPointA1.x + localPointA2.x); + this.m_localPoint.y = 0.5 * (localPointA1.y + localPointA2.y); + this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0); + this.m_axis.Normalize(); + tVec = this.m_axis; + tMat = transformA.R; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tVec = this.m_localPoint; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointB; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + s = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; + if (s < 0.0) { + this.m_axis.NegativeSelf(); + } + } + else if (cache.indexA[0] == cache.indexA[0]) { + this.m_type = b2SeparationFunction.e_faceB; + localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); + localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); + localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); + this.m_localPoint.x = 0.5 * (localPointB1.x + localPointB2.x); + this.m_localPoint.y = 0.5 * (localPointB1.y + localPointB2.y); + this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0); + this.m_axis.Normalize(); + tVec = this.m_axis; + tMat = transformB.R; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tVec = this.m_localPoint; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointA; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + s = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; + if (s < 0.0) { + this.m_axis.NegativeSelf(); + } + } + else { + localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); + localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); + localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); + localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); + var pA = b2Math.MulX(transformA, localPointA); + var dA = b2Math.MulMV(transformA.R, b2Math.SubtractVV(localPointA2, localPointA1)); + var pB = b2Math.MulX(transformB, localPointB); + var dB = b2Math.MulMV(transformB.R, b2Math.SubtractVV(localPointB2, localPointB1)); + var a = dA.x * dA.x + dA.y * dA.y; + var e = dB.x * dB.x + dB.y * dB.y; + var r = b2Math.SubtractVV(dB, dA); + var c = dA.x * r.x + dA.y * r.y; + var f = dB.x * r.x + dB.y * r.y; + var b = dA.x * dB.x + dA.y * dB.y; + var denom = a * e - b * b; + s = 0.0; + if (denom != 0.0) { + s = b2Math.Clamp((b * f - c * e) / denom, 0.0, 1.0); + } + var t = (b * s + f) / e; + if (t < 0.0) { + t = 0.0; + s = b2Math.Clamp((b - c) / a, 0.0, 1.0); + } + localPointA = new b2Vec2(); + localPointA.x = localPointA1.x + s * (localPointA2.x - localPointA1.x); + localPointA.y = localPointA1.y + s * (localPointA2.y - localPointA1.y); + localPointB = new b2Vec2(); + localPointB.x = localPointB1.x + s * (localPointB2.x - localPointB1.x); + localPointB.y = localPointB1.y + s * (localPointB2.y - localPointB1.y); + if (s == 0.0 || s == 1.0) { + this.m_type = b2SeparationFunction.e_faceB; + this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0); + this.m_axis.Normalize(); + this.m_localPoint = localPointB; + tVec = this.m_axis; + tMat = transformB.R; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tVec = this.m_localPoint; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointA; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + sgn = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; + if (s < 0.0) { + this.m_axis.NegativeSelf(); + } + } + else { + this.m_type = b2SeparationFunction.e_faceA; + this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0); + this.m_localPoint = localPointA; + tVec = this.m_axis; + tMat = transformA.R; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tVec = this.m_localPoint; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointB; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + sgn = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; + if (s < 0.0) { + this.m_axis.NegativeSelf(); + } + } + } + } + b2SeparationFunction.prototype.Evaluate = function (transformA, transformB) { + var axisA; + var axisB; + var localPointA; + var localPointB; + var pointA; + var pointB; + var seperation = 0; + var normal; + switch (this.m_type) { + case b2SeparationFunction.e_points: + { + axisA = b2Math.MulTMV(transformA.R, this.m_axis); + axisB = b2Math.MulTMV(transformB.R, this.m_axis.GetNegative()); + localPointA = this.m_proxyA.GetSupportVertex(axisA); + localPointB = this.m_proxyB.GetSupportVertex(axisB); + pointA = b2Math.MulX(transformA, localPointA); + pointB = b2Math.MulX(transformB, localPointB); + seperation = (pointB.x - pointA.x) * this.m_axis.x + (pointB.y - pointA.y) * this.m_axis.y; + return seperation; + } + case b2SeparationFunction.e_faceA: + { + normal = b2Math.MulMV(transformA.R, this.m_axis); + pointA = b2Math.MulX(transformA, this.m_localPoint); + axisB = b2Math.MulTMV(transformB.R, normal.GetNegative()); + localPointB = this.m_proxyB.GetSupportVertex(axisB); + pointB = b2Math.MulX(transformB, localPointB); + seperation = (pointB.x - pointA.x) * normal.x + (pointB.y - pointA.y) * normal.y; + return seperation; + } + case b2SeparationFunction.e_faceB: + { + normal = b2Math.MulMV(transformB.R, this.m_axis); + pointB = b2Math.MulX(transformB, this.m_localPoint); + axisA = b2Math.MulTMV(transformA.R, normal.GetNegative()); + localPointA = this.m_proxyA.GetSupportVertex(axisA); + pointA = b2Math.MulX(transformA, localPointA); + seperation = (pointA.x - pointB.x) * normal.x + (pointA.y - pointB.y) * normal.y; + return seperation; + } + default: + b2Settings.b2Assert(false); + return 0.0; + } + } + _A2J_postDefs.push(function () { + Box2D.Collision.b2SeparationFunction.e_points = 0x01; + Box2D.Collision.b2SeparationFunction.prototype.e_points = Box2D.Collision.b2SeparationFunction.e_points; + Box2D.Collision.b2SeparationFunction.e_faceA = 0x02; + Box2D.Collision.b2SeparationFunction.prototype.e_faceA = Box2D.Collision.b2SeparationFunction.e_faceA; + Box2D.Collision.b2SeparationFunction.e_faceB = 0x04; + Box2D.Collision.b2SeparationFunction.prototype.e_faceB = Box2D.Collision.b2SeparationFunction.e_faceB; + }); + b2Simplex.b2Simplex = function () { + this.m_v1 = new b2SimplexVertex(); + this.m_v2 = new b2SimplexVertex(); + this.m_v3 = new b2SimplexVertex(); + this.m_vertices = new Vector(3); + }; + b2Simplex.prototype.b2Simplex = function () { + this.m_vertices[0] = this.m_v1; + this.m_vertices[1] = this.m_v2; + this.m_vertices[2] = this.m_v3; + } + b2Simplex.prototype.ReadCache = function (cache, proxyA, transformA, proxyB, transformB) { + b2Settings.b2Assert(0 <= cache.count && cache.count <= 3); + var wALocal; + var wBLocal; + this.m_count = cache.count; + var vertices = this.m_vertices; + for (var i = 0; i < this.m_count; i++) { + var v = vertices[i]; + v.indexA = cache.indexA[i]; + v.indexB = cache.indexB[i]; + wALocal = proxyA.GetVertex(v.indexA); + wBLocal = proxyB.GetVertex(v.indexB); + v.wA = b2Math.MulX(transformA, wALocal); + v.wB = b2Math.MulX(transformB, wBLocal); + v.w = b2Math.SubtractVV(v.wB, v.wA); + v.a = 0; + } + if (this.m_count > 1) { + var metric1 = cache.metric; + var metric2 = this.GetMetric(); + if (metric2 < .5 * metric1 || 2.0 * metric1 < metric2 || metric2 < Number.MIN_VALUE) { + this.m_count = 0; + } + } + if (this.m_count == 0) { + v = vertices[0]; + v.indexA = 0; + v.indexB = 0; + wALocal = proxyA.GetVertex(0); + wBLocal = proxyB.GetVertex(0); + v.wA = b2Math.MulX(transformA, wALocal); + v.wB = b2Math.MulX(transformB, wBLocal); + v.w = b2Math.SubtractVV(v.wB, v.wA); + this.m_count = 1; + } + } + b2Simplex.prototype.WriteCache = function (cache) { + cache.metric = this.GetMetric(); + cache.count = a2j.parseUInt(this.m_count); + var vertices = this.m_vertices; + for (var i = 0; i < this.m_count; i++) { + cache.indexA[i] = a2j.parseUInt(vertices[i].indexA); + cache.indexB[i] = a2j.parseUInt(vertices[i].indexB); + } + } + b2Simplex.prototype.GetSearchDirection = function () { + switch (this.m_count) { + case 1: + return this.m_v1.w.GetNegative(); + case 2: + { + var e12 = b2Math.SubtractVV(this.m_v2.w, this.m_v1.w); + var sgn = b2Math.CrossVV(e12, this.m_v1.w.GetNegative()); + if (sgn > 0.0) { + return b2Math.CrossFV(1.0, e12); + } + else { + return b2Math.CrossVF(e12, 1.0); + } + } + default: + b2Settings.b2Assert(false); + return new b2Vec2(); + } + } + b2Simplex.prototype.GetClosestPoint = function () { + switch (this.m_count) { + case 0: + b2Settings.b2Assert(false); + return new b2Vec2(); + case 1: + return this.m_v1.w; + case 2: + return new b2Vec2(this.m_v1.a * this.m_v1.w.x + this.m_v2.a * this.m_v2.w.x, this.m_v1.a * this.m_v1.w.y + this.m_v2.a * this.m_v2.w.y); + default: + b2Settings.b2Assert(false); + return new b2Vec2(); + } + } + b2Simplex.prototype.GetWitnessPoints = function (pA, pB) { + switch (this.m_count) { + case 0: + b2Settings.b2Assert(false); + break; + case 1: + pA.SetV(this.m_v1.wA); + pB.SetV(this.m_v1.wB); + break; + case 2: + pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x; + pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y; + pB.x = this.m_v1.a * this.m_v1.wB.x + this.m_v2.a * this.m_v2.wB.x; + pB.y = this.m_v1.a * this.m_v1.wB.y + this.m_v2.a * this.m_v2.wB.y; + break; + case 3: + pB.x = pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x + this.m_v3.a * this.m_v3.wA.x; + pB.y = pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y + this.m_v3.a * this.m_v3.wA.y; + break; + default: + b2Settings.b2Assert(false); + break; + } + } + b2Simplex.prototype.GetMetric = function () { + switch (this.m_count) { + case 0: + b2Settings.b2Assert(false); + return 0.0; + case 1: + return 0.0; + case 2: + return b2Math.SubtractVV(this.m_v1.w, this.m_v2.w).Length(); + case 3: + return b2Math.CrossVV(b2Math.SubtractVV(this.m_v2.w, this.m_v1.w), b2Math.SubtractVV(this.m_v3.w, this.m_v1.w)); + default: + b2Settings.b2Assert(false); + return 0.0; + } + } + b2Simplex.prototype.Solve2 = function () { + var w1 = this.m_v1.w; + var w2 = this.m_v2.w; + var e12 = b2Math.SubtractVV(w2, w1); + var d12_2 = (-(w1.x * e12.x + w1.y * e12.y)); + if (d12_2 <= 0.0) { + this.m_v1.a = 1.0; + this.m_count = 1; + return; + } + var d12_1 = (w2.x * e12.x + w2.y * e12.y); + if (d12_1 <= 0.0) { + this.m_v2.a = 1.0; + this.m_count = 1; + this.m_v1.Set(this.m_v2); + return; + } + var inv_d12 = 1.0 / (d12_1 + d12_2); + this.m_v1.a = d12_1 * inv_d12; + this.m_v2.a = d12_2 * inv_d12; + this.m_count = 2; + } + b2Simplex.prototype.Solve3 = function () { + var w1 = this.m_v1.w; + var w2 = this.m_v2.w; + var w3 = this.m_v3.w; + var e12 = b2Math.SubtractVV(w2, w1); + var w1e12 = b2Math.Dot(w1, e12); + var w2e12 = b2Math.Dot(w2, e12); + var d12_1 = w2e12; + var d12_2 = (-w1e12); + var e13 = b2Math.SubtractVV(w3, w1); + var w1e13 = b2Math.Dot(w1, e13); + var w3e13 = b2Math.Dot(w3, e13); + var d13_1 = w3e13; + var d13_2 = (-w1e13); + var e23 = b2Math.SubtractVV(w3, w2); + var w2e23 = b2Math.Dot(w2, e23); + var w3e23 = b2Math.Dot(w3, e23); + var d23_1 = w3e23; + var d23_2 = (-w2e23); + var n123 = b2Math.CrossVV(e12, e13); + var d123_1 = n123 * b2Math.CrossVV(w2, w3); + var d123_2 = n123 * b2Math.CrossVV(w3, w1); + var d123_3 = n123 * b2Math.CrossVV(w1, w2); + if (d12_2 <= 0.0 && d13_2 <= 0.0) { + this.m_v1.a = 1.0; + this.m_count = 1; + return; + } + if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0) { + var inv_d12 = 1.0 / (d12_1 + d12_2); + this.m_v1.a = d12_1 * inv_d12; + this.m_v2.a = d12_2 * inv_d12; + this.m_count = 2; + return; + } + if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0) { + var inv_d13 = 1.0 / (d13_1 + d13_2); + this.m_v1.a = d13_1 * inv_d13; + this.m_v3.a = d13_2 * inv_d13; + this.m_count = 2; + this.m_v2.Set(this.m_v3); + return; + } + if (d12_1 <= 0.0 && d23_2 <= 0.0) { + this.m_v2.a = 1.0; + this.m_count = 1; + this.m_v1.Set(this.m_v2); + return; + } + if (d13_1 <= 0.0 && d23_1 <= 0.0) { + this.m_v3.a = 1.0; + this.m_count = 1; + this.m_v1.Set(this.m_v3); + return; + } + if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0) { + var inv_d23 = 1.0 / (d23_1 + d23_2); + this.m_v2.a = d23_1 * inv_d23; + this.m_v3.a = d23_2 * inv_d23; + this.m_count = 2; + this.m_v1.Set(this.m_v3); + return; + } + var inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3); + this.m_v1.a = d123_1 * inv_d123; + this.m_v2.a = d123_2 * inv_d123; + this.m_v3.a = d123_3 * inv_d123; + this.m_count = 3; + } + b2SimplexCache.b2SimplexCache = function () { + this.indexA = new Vector_a2j_Number(3); + this.indexB = new Vector_a2j_Number(3); + }; + b2SimplexVertex.b2SimplexVertex = function () {}; + b2SimplexVertex.prototype.Set = function (other) { + this.wA.SetV(other.wA); + this.wB.SetV(other.wB); + this.w.SetV(other.w); + this.a = other.a; + this.indexA = other.indexA; + this.indexB = other.indexB; + } + b2TimeOfImpact.b2TimeOfImpact = function () {}; + b2TimeOfImpact.prototype.TimeOfImpact = function (input) { + ++b2TimeOfImpact.b2_toiCalls; + var proxyA = input.proxyA; + var proxyB = input.proxyB; + var sweepA = input.sweepA; + var sweepB = input.sweepB; + b2Settings.b2Assert(sweepA.t0 == sweepB.t0); + b2Settings.b2Assert(1.0 - sweepA.t0 > Number.MIN_VALUE); + var radius = proxyA.m_radius + proxyB.m_radius; + var tolerance = input.tolerance; + var alpha = 0.0; + var k_maxIterations = 1000; + var iter = 0; + var target = 0.0; + b2TimeOfImpact.s_cache.count = 0; + b2TimeOfImpact.s_distanceInput.useRadii = false; + for (;;) { + sweepA.GetTransform(b2TimeOfImpact.s_xfA, alpha); + sweepB.GetTransform(b2TimeOfImpact.s_xfB, alpha); + b2TimeOfImpact.s_distanceInput.proxyA = proxyA; + b2TimeOfImpact.s_distanceInput.proxyB = proxyB; + b2TimeOfImpact.s_distanceInput.transformA = b2TimeOfImpact.s_xfA; + b2TimeOfImpact.s_distanceInput.transformB = b2TimeOfImpact.s_xfB; + b2Distance.Distance(b2TimeOfImpact.s_distanceOutput, b2TimeOfImpact.s_cache, b2TimeOfImpact.s_distanceInput); + if (b2TimeOfImpact.s_distanceOutput.distance <= 0.0) { + alpha = 1.0; + break; + } + b2TimeOfImpact.s_fcn.Initialize(b2TimeOfImpact.s_cache, proxyA, b2TimeOfImpact.s_xfA, proxyB, b2TimeOfImpact.s_xfB); + var separation = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); + if (separation <= 0.0) { + alpha = 1.0; + break; + } + if (iter == 0) { + if (separation > radius) { + target = b2Math.Max(radius - tolerance, 0.75 * radius); + } + else { + target = b2Math.Max(separation - tolerance, 0.02 * radius); + } + } + if (separation - target < 0.5 * tolerance) { + if (iter == 0) { + alpha = 1.0; + break; + } + break; + } + var newAlpha = alpha; { + var x1 = alpha; + var x2 = 1.0; + var f1 = separation; + sweepA.GetTransform(b2TimeOfImpact.s_xfA, x2); + sweepB.GetTransform(b2TimeOfImpact.s_xfB, x2); + var f2 = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); + if (f2 >= target) { + alpha = 1.0; + break; + } + var rootIterCount = 0; + for (;;) { + var x = 0; + if (rootIterCount & 1) { + x = x1 + (target - f1) * (x2 - x1) / (f2 - f1); + } + else { + x = 0.5 * (x1 + x2); + } + sweepA.GetTransform(b2TimeOfImpact.s_xfA, x); + sweepB.GetTransform(b2TimeOfImpact.s_xfB, x); + var f = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); + if (b2Math.Abs(f - target) < 0.025 * tolerance) { + newAlpha = x; + break; + } + if (f > target) { + x1 = x; + f1 = f; + } + else { + x2 = x; + f2 = f; + }++rootIterCount; + ++b2TimeOfImpact.b2_toiRootIters; + if (rootIterCount == 50) { + break; + } + } + b2TimeOfImpact.b2_toiMaxRootIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxRootIters, rootIterCount); + } + if (newAlpha < (1.0 + 100.0 * Number.MIN_VALUE) * alpha) { + break; + } + alpha = newAlpha; + iter++; + ++b2TimeOfImpact.b2_toiIters; + if (iter == k_maxIterations) { + break; + } + } + b2TimeOfImpact.b2_toiMaxIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxIters, iter); + return alpha; + } + b2TimeOfImpact.TimeOfImpact = b2TimeOfImpact.prototype.TimeOfImpact; + _A2J_postDefs.push(function () { + Box2D.Collision.b2TimeOfImpact.b2_toiCalls = 0; + Box2D.Collision.b2TimeOfImpact.prototype.b2_toiCalls = Box2D.Collision.b2TimeOfImpact.b2_toiCalls; + Box2D.Collision.b2TimeOfImpact.b2_toiIters = 0; + Box2D.Collision.b2TimeOfImpact.prototype.b2_toiIters = Box2D.Collision.b2TimeOfImpact.b2_toiIters; + Box2D.Collision.b2TimeOfImpact.b2_toiMaxIters = 0; + Box2D.Collision.b2TimeOfImpact.prototype.b2_toiMaxIters = Box2D.Collision.b2TimeOfImpact.b2_toiMaxIters; + Box2D.Collision.b2TimeOfImpact.b2_toiRootIters = 0; + Box2D.Collision.b2TimeOfImpact.prototype.b2_toiRootIters = Box2D.Collision.b2TimeOfImpact.b2_toiRootIters; + Box2D.Collision.b2TimeOfImpact.b2_toiMaxRootIters = 0; + Box2D.Collision.b2TimeOfImpact.prototype.b2_toiMaxRootIters = Box2D.Collision.b2TimeOfImpact.b2_toiMaxRootIters; + Box2D.Collision.b2TimeOfImpact.s_cache = new b2SimplexCache(); + Box2D.Collision.b2TimeOfImpact.prototype.s_cache = Box2D.Collision.b2TimeOfImpact.s_cache; + Box2D.Collision.b2TimeOfImpact.s_distanceInput = new b2DistanceInput(); + Box2D.Collision.b2TimeOfImpact.prototype.s_distanceInput = Box2D.Collision.b2TimeOfImpact.s_distanceInput; + Box2D.Collision.b2TimeOfImpact.s_xfA = new b2Transform(); + Box2D.Collision.b2TimeOfImpact.prototype.s_xfA = Box2D.Collision.b2TimeOfImpact.s_xfA; + Box2D.Collision.b2TimeOfImpact.s_xfB = new b2Transform(); + Box2D.Collision.b2TimeOfImpact.prototype.s_xfB = Box2D.Collision.b2TimeOfImpact.s_xfB; + Box2D.Collision.b2TimeOfImpact.s_fcn = new b2SeparationFunction(); + Box2D.Collision.b2TimeOfImpact.prototype.s_fcn = Box2D.Collision.b2TimeOfImpact.s_fcn; + Box2D.Collision.b2TimeOfImpact.s_distanceOutput = new b2DistanceOutput(); + Box2D.Collision.b2TimeOfImpact.prototype.s_distanceOutput = Box2D.Collision.b2TimeOfImpact.s_distanceOutput; + }); + b2TOIInput.b2TOIInput = function () { + this.proxyA = new b2DistanceProxy(); + this.proxyB = new b2DistanceProxy(); + this.sweepA = new b2Sweep(); + this.sweepB = new b2Sweep(); + }; + b2WorldManifold.b2WorldManifold = function () { + this.m_normal = new b2Vec2(); + }; + b2WorldManifold.prototype.b2WorldManifold = function () { + this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); + for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { + this.m_points[i] = new b2Vec2(); + } + } + b2WorldManifold.prototype.Initialize = function (manifold, xfA, radiusA, xfB, radiusB) { + if (radiusA === undefined) radiusA = 0; + if (radiusB === undefined) radiusB = 0; + if (manifold.m_pointCount == 0) { + return; + } + var i = 0; + var tVec; + var tMat; + var normalX = 0; + var normalY = 0; + var planePointX = 0; + var planePointY = 0; + var clipPointX = 0; + var clipPointY = 0; + switch (manifold.m_type) { + case b2Manifold.e_circles: + { + tMat = xfA.R; + tVec = manifold.m_localPoint; + var pointAX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + var pointAY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = xfB.R; + tVec = manifold.m_points[0].m_localPoint; + var pointBX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + var pointBY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + var dX = pointBX - pointAX; + var dY = pointBY - pointAY; + var d2 = dX * dX + dY * dY; + if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) { + var d = Math.sqrt(d2); + this.m_normal.x = dX / d; + this.m_normal.y = dY / d; + } + else { + this.m_normal.x = 1; + this.m_normal.y = 0; + } + var cAX = pointAX + radiusA * this.m_normal.x; + var cAY = pointAY + radiusA * this.m_normal.y; + var cBX = pointBX - radiusB * this.m_normal.x; + var cBY = pointBY - radiusB * this.m_normal.y; + this.m_points[0].x = 0.5 * (cAX + cBX); + this.m_points[0].y = 0.5 * (cAY + cBY); + } + break; + case b2Manifold.e_faceA: + { + tMat = xfA.R; + tVec = manifold.m_localPlaneNormal; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = xfA.R; + tVec = manifold.m_localPoint; + planePointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + planePointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_normal.x = normalX; + this.m_normal.y = normalY; + for (i = 0; + i < manifold.m_pointCount; i++) { + tMat = xfB.R; + tVec = manifold.m_points[i].m_localPoint; + clipPointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + clipPointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_points[i].x = clipPointX + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalX; + this.m_points[i].y = clipPointY + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalY; + } + } + break; + case b2Manifold.e_faceB: + { + tMat = xfB.R; + tVec = manifold.m_localPlaneNormal; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = xfB.R; + tVec = manifold.m_localPoint; + planePointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + planePointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_normal.x = (-normalX); + this.m_normal.y = (-normalY); + for (i = 0; + i < manifold.m_pointCount; i++) { + tMat = xfA.R; + tVec = manifold.m_points[i].m_localPoint; + clipPointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + clipPointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_points[i].x = clipPointX + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalX; + this.m_points[i].y = clipPointY + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalY; + } + } + break; + } + } + ClipVertex.ClipVertex = function () { + this.v = new b2Vec2(); + this.id = new b2ContactID(); + }; + ClipVertex.prototype.Set = function (other) { + this.v.SetV(other.v); + this.id.Set(other.id); + } + Features.Features = function () {}; + Features.prototype.__defineGetter__('referenceEdge', function () { + return this._referenceEdge; + }); + Features.prototype.__defineSetter__('referenceEdge', function (value) { + if (value === undefined) value = 0; + this._referenceEdge = value; + this._m_id._key = (this._m_id._key & 0xffffff00) | (this._referenceEdge & 0x000000ff); + }); + Features.prototype.__defineGetter__('incidentEdge', function () { + return this._incidentEdge; + }); + Features.prototype.__defineSetter__('incidentEdge', function (value) { + if (value === undefined) value = 0; + this._incidentEdge = value; + this._m_id._key = (this._m_id._key & 0xffff00ff) | ((this._incidentEdge << 8) & 0x0000ff00); + }); + Features.prototype.__defineGetter__('incidentVertex', function () { + return this._incidentVertex; + }); + Features.prototype.__defineSetter__('incidentVertex', function (value) { + if (value === undefined) value = 0; + this._incidentVertex = value; + this._m_id._key = (this._m_id._key & 0xff00ffff) | ((this._incidentVertex << 16) & 0x00ff0000); + }); + Features.prototype.__defineGetter__('flip', function () { + return this._flip; + }); + Features.prototype.__defineSetter__('flip', function (value) { + if (value === undefined) value = 0; + this._flip = value; + this._m_id._key = (this._m_id._key & 0x00ffffff) | ((this._flip << 24) & 0xff000000); + }); +})(); /* source: disabled*/ +(function () { + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; + var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; + var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; + var b2MassData = Box2D.Collision.Shapes.b2MassData; + var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; + var b2Shape = Box2D.Collision.Shapes.b2Shape; + var b2Mat22 = Box2D.Common.Math.b2Mat22; + var b2Mat33 = Box2D.Common.Math.b2Mat33; + var b2Math = Box2D.Common.Math.b2Math; + var b2Sweep = Box2D.Common.Math.b2Sweep; + var b2Transform = Box2D.Common.Math.b2Transform; + var b2Vec2 = Box2D.Common.Math.b2Vec2; + var b2Vec3 = Box2D.Common.Math.b2Vec3; + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2Body = Box2D.Dynamics.b2Body; + var b2BodyDef = Box2D.Dynamics.b2BodyDef; + var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; + var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; + var b2ContactListener = Box2D.Dynamics.b2ContactListener; + var b2ContactManager = Box2D.Dynamics.b2ContactManager; + var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; + var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; + var b2FilterData = Box2D.Dynamics.b2FilterData; + var b2Fixture = Box2D.Dynamics.b2Fixture; + var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; + var b2Island = Box2D.Dynamics.b2Island; + var b2TimeStep = Box2D.Dynamics.b2TimeStep; + var b2World = Box2D.Dynamics.b2World; + var b2AABB = Box2D.Collision.b2AABB; + var b2Bound = Box2D.Collision.b2Bound; + var b2BoundValues = Box2D.Collision.b2BoundValues; + var b2BroadPhase = Box2D.Collision.b2BroadPhase; + var b2Collision = Box2D.Collision.b2Collision; + var b2ContactID = Box2D.Collision.b2ContactID; + var b2ContactPoint = Box2D.Collision.b2ContactPoint; + var b2Distance = Box2D.Collision.b2Distance; + var b2DistanceInput = Box2D.Collision.b2DistanceInput; + var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; + var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; + var b2DynamicTree = Box2D.Collision.b2DynamicTree; + var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; + var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; + var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; + var b2Manifold = Box2D.Collision.b2Manifold; + var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; + var b2OBB = Box2D.Collision.b2OBB; + var b2Pair = Box2D.Collision.b2Pair; + var b2PairManager = Box2D.Collision.b2PairManager; + var b2Point = Box2D.Collision.b2Point; + var b2Proxy = Box2D.Collision.b2Proxy; + var b2RayCastInput = Box2D.Collision.b2RayCastInput; + var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; + var b2Segment = Box2D.Collision.b2Segment; + var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; + var b2Simplex = Box2D.Collision.b2Simplex; + var b2SimplexCache = Box2D.Collision.b2SimplexCache; + var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; + var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; + var b2TOIInput = Box2D.Collision.b2TOIInput; + var b2WorldManifold = Box2D.Collision.b2WorldManifold; + var ClipVertex = Box2D.Collision.ClipVertex; + var Features = Box2D.Collision.Features; + var IBroadPhase = Box2D.Collision.IBroadPhase; + var b2internal = Box2D.Common.b2internal; + var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; + var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; + var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; + var b2MassData = Box2D.Collision.Shapes.b2MassData; + var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; + var b2Shape = Box2D.Collision.Shapes.b2Shape; + helpers.inherit.call(b2CircleShape, Box2D.Collision.Shapes.b2Shape); + b2CircleShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype; + b2CircleShape.b2CircleShape = function () { + Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments); + this.m_p = new b2Vec2(); + }; + b2CircleShape.prototype.Copy = function () { + var s = new b2CircleShape(); + s.Set(this); + return s; + } + b2CircleShape.prototype.Set = function (other) { + this.__super.Set.call(this, other); + if (a2j.is(other, b2CircleShape)) { + var other2 = (other instanceof b2CircleShape ? other : null); + this.m_p.SetV(other2.m_p); + } + } + b2CircleShape.prototype.TestPoint = function (transform, p) { + var tMat = transform.R; + var dX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); + var dY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); + dX = p.x - dX; + dY = p.y - dY; + return (dX * dX + dY * dY) <= this.m_radius * this.m_radius; + } + b2CircleShape.prototype.RayCast = function (output, input, transform) { + var tMat = transform.R; + var positionX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); + var positionY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); + var sX = input.p1.x - positionX; + var sY = input.p1.y - positionY; + var b = (sX * sX + sY * sY) - this.m_radius * this.m_radius; + var rX = input.p2.x - input.p1.x; + var rY = input.p2.y - input.p1.y; + var c = (sX * rX + sY * rY); + var rr = (rX * rX + rY * rY); + var sigma = c * c - rr * b; + if (sigma < 0.0 || rr < Number.MIN_VALUE) { + return false; + } + var a = (-(c + Math.sqrt(sigma))); + if (0.0 <= a && a <= input.maxFraction * rr) { + a /= rr; + output.fraction = a; + output.normal.x = sX + a * rX; + output.normal.y = sY + a * rY; + output.normal.Normalize(); + return true; + } + return false; + } + b2CircleShape.prototype.ComputeAABB = function (aabb, transform) { + var tMat = transform.R; + var pX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); + var pY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); + aabb.lowerBound.Set(pX - this.m_radius, pY - this.m_radius); + aabb.upperBound.Set(pX + this.m_radius, pY + this.m_radius); + } + b2CircleShape.prototype.ComputeMass = function (massData, density) { + if (density === undefined) density = 0; + massData.mass = density * b2Settings.b2_pi * this.m_radius * this.m_radius; + massData.center.SetV(this.m_p); + massData.I = massData.mass * (0.5 * this.m_radius * this.m_radius + (this.m_p.x * this.m_p.x + this.m_p.y * this.m_p.y)); + } + b2CircleShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { + if (offset === undefined) offset = 0; + var p = b2Math.MulX(xf, this.m_p); + var l = (-(b2Math.Dot(normal, p) - offset)); + if (l < (-this.m_radius) + Number.MIN_VALUE) { + return 0; + } + if (l > this.m_radius) { + c.SetV(p); + return Math.PI * this.m_radius * this.m_radius; + } + var r2 = this.m_radius * this.m_radius; + var l2 = l * l; + var area = r2 * (Math.asin(l / this.m_radius) + Math.PI / 2) + l * Math.sqrt(r2 - l2); + var com = (-2 / 3 * Math.pow(r2 - l2, 1.5) / area); + c.x = p.x + normal.x * com; + c.y = p.y + normal.y * com; + return area; + } + b2CircleShape.prototype.GetLocalPosition = function () { + return this.m_p; + } + b2CircleShape.prototype.SetLocalPosition = function (position) { + this.m_p.SetV(position); + } + b2CircleShape.prototype.GetRadius = function () { + return this.m_radius; + } + b2CircleShape.prototype.SetRadius = function (radius) { + if (radius === undefined) radius = 0; + this.m_radius = radius; + } + b2CircleShape.prototype.b2CircleShape = function (radius) { + if (radius === undefined) radius = 0; + this.__super.b2Shape.call(this); + this.m_type = this.e_circleShape; + this.m_radius = radius; + } + b2EdgeChainDef.b2EdgeChainDef = function () {}; + b2EdgeChainDef.prototype.b2EdgeChainDef = function () { + this.vertexCount = 0; + this.isALoop = true; + this.vertices = []; + } + helpers.inherit.call(b2EdgeShape, Box2D.Collision.Shapes.b2Shape); + b2EdgeShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype; + b2EdgeShape.b2EdgeShape = function () { + Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments); + this.s_supportVec = new b2Vec2(); + this.m_v1 = new b2Vec2(); + this.m_v2 = new b2Vec2(); + this.m_coreV1 = new b2Vec2(); + this.m_coreV2 = new b2Vec2(); + this.m_normal = new b2Vec2(); + this.m_direction = new b2Vec2(); + this.m_cornerDir1 = new b2Vec2(); + this.m_cornerDir2 = new b2Vec2(); + }; + b2EdgeShape.prototype.TestPoint = function (transform, p) { + return false; + } + b2EdgeShape.prototype.RayCast = function (output, input, transform) { + var tMat; + var rX = input.p2.x - input.p1.x; + var rY = input.p2.y - input.p1.y; + tMat = transform.R; + var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); + var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); + var nX = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y) - v1Y; + var nY = (-(transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y) - v1X)); + var k_slop = 100.0 * Number.MIN_VALUE; + var denom = (-(rX * nX + rY * nY)); + if (denom > k_slop) { + var bX = input.p1.x - v1X; + var bY = input.p1.y - v1Y; + var a = (bX * nX + bY * nY); + if (0.0 <= a && a <= input.maxFraction * denom) { + var mu2 = (-rX * bY) + rY * bX; + if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) { + a /= denom; + output.fraction = a; + var nLen = Math.sqrt(nX * nX + nY * nY); + output.normal.x = nX / nLen; + output.normal.y = nY / nLen; + return true; + } + } + } + return false; + } + b2EdgeShape.prototype.ComputeAABB = function (aabb, transform) { + var tMat = transform.R; + var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); + var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); + var v2X = transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y); + var v2Y = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y); + if (v1X < v2X) { + aabb.lowerBound.x = v1X; + aabb.upperBound.x = v2X; + } + else { + aabb.lowerBound.x = v2X; + aabb.upperBound.x = v1X; + } + if (v1Y < v2Y) { + aabb.lowerBound.y = v1Y; + aabb.upperBound.y = v2Y; + } + else { + aabb.lowerBound.y = v2Y; + aabb.upperBound.y = v1Y; + } + } + b2EdgeShape.prototype.ComputeMass = function (massData, density) { + if (density === undefined) density = 0; + massData.mass = 0; + massData.center.SetV(this.m_v1); + massData.I = 0; + } + b2EdgeShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { + if (offset === undefined) offset = 0; + var v0 = new b2Vec2(normal.x * offset, normal.y * offset); + var v1 = b2Math.MulX(xf, this.m_v1); + var v2 = b2Math.MulX(xf, this.m_v2); + var d1 = b2Math.Dot(normal, v1) - offset; + var d2 = b2Math.Dot(normal, v2) - offset; + if (d1 > 0) { + if (d2 > 0) { + return 0; + } + else { + v1.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x; + v1.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y; + } + } + else { + if (d2 > 0) { + v2.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x; + v2.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y; + } + else {} + } + c.x = (v0.x + v1.x + v2.x) / 3; + c.y = (v0.y + v1.y + v2.y) / 3; + return 0.5 * ((v1.x - v0.x) * (v2.y - v0.y) - (v1.y - v0.y) * (v2.x - v0.x)); + } + b2EdgeShape.prototype.GetLength = function () { + return this.m_length; + } + b2EdgeShape.prototype.GetVertex1 = function () { + return this.m_v1; + } + b2EdgeShape.prototype.GetVertex2 = function () { + return this.m_v2; + } + b2EdgeShape.prototype.GetCoreVertex1 = function () { + return this.m_coreV1; + } + b2EdgeShape.prototype.GetCoreVertex2 = function () { + return this.m_coreV2; + } + b2EdgeShape.prototype.GetNormalVector = function () { + return this.m_normal; + } + b2EdgeShape.prototype.GetDirectionVector = function () { + return this.m_direction; + } + b2EdgeShape.prototype.GetCorner1Vector = function () { + return this.m_cornerDir1; + } + b2EdgeShape.prototype.GetCorner2Vector = function () { + return this.m_cornerDir2; + } + b2EdgeShape.prototype.Corner1IsConvex = function () { + return this.m_cornerConvex1; + } + b2EdgeShape.prototype.Corner2IsConvex = function () { + return this.m_cornerConvex2; + } + b2EdgeShape.prototype.GetFirstVertex = function (xf) { + var tMat = xf.R; + return new b2Vec2(xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y), xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y)); + } + b2EdgeShape.prototype.GetNextEdge = function () { + return this.m_nextEdge; + } + b2EdgeShape.prototype.GetPrevEdge = function () { + return this.m_prevEdge; + } + b2EdgeShape.prototype.Support = function (xf, dX, dY) { + if (dX === undefined) dX = 0; + if (dY === undefined) dY = 0; + var tMat = xf.R; + var v1X = xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y); + var v1Y = xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y); + var v2X = xf.position.x + (tMat.col1.x * this.m_coreV2.x + tMat.col2.x * this.m_coreV2.y); + var v2Y = xf.position.y + (tMat.col1.y * this.m_coreV2.x + tMat.col2.y * this.m_coreV2.y); + if ((v1X * dX + v1Y * dY) > (v2X * dX + v2Y * dY)) { + this.s_supportVec.x = v1X; + this.s_supportVec.y = v1Y; + } + else { + this.s_supportVec.x = v2X; + this.s_supportVec.y = v2Y; + } + return this.s_supportVec; + } + b2EdgeShape.prototype.b2EdgeShape = function (v1, v2) { + this.__super.b2Shape.call(this); + this.m_type = this.e_edgeShape; + this.m_prevEdge = null; + this.m_nextEdge = null; + this.m_v1 = v1; + this.m_v2 = v2; + this.m_direction.Set(this.m_v2.x - this.m_v1.x, this.m_v2.y - this.m_v1.y); + this.m_length = this.m_direction.Normalize(); + this.m_normal.Set(this.m_direction.y, (-this.m_direction.x)); + this.m_coreV1.Set((-b2Settings.b2_toiSlop * (this.m_normal.x - this.m_direction.x)) + this.m_v1.x, (-b2Settings.b2_toiSlop * (this.m_normal.y - this.m_direction.y)) + this.m_v1.y); + this.m_coreV2.Set((-b2Settings.b2_toiSlop * (this.m_normal.x + this.m_direction.x)) + this.m_v2.x, (-b2Settings.b2_toiSlop * (this.m_normal.y + this.m_direction.y)) + this.m_v2.y); + this.m_cornerDir1 = this.m_normal; + this.m_cornerDir2.Set((-this.m_normal.x), (-this.m_normal.y)); + } + b2EdgeShape.prototype.SetPrevEdge = function (edge, core, cornerDir, convex) { + this.m_prevEdge = edge; + this.m_coreV1 = core; + this.m_cornerDir1 = cornerDir; + this.m_cornerConvex1 = convex; + } + b2EdgeShape.prototype.SetNextEdge = function (edge, core, cornerDir, convex) { + this.m_nextEdge = edge; + this.m_coreV2 = core; + this.m_cornerDir2 = cornerDir; + this.m_cornerConvex2 = convex; + } + b2MassData.b2MassData = function () { + this.mass = 0.0; + this.center = new b2Vec2(0, 0); + this.I = 0.0; + }; + helpers.inherit.call(b2PolygonShape, Box2D.Collision.Shapes.b2Shape); + b2PolygonShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype; + b2PolygonShape.b2PolygonShape = function () { + Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments); + }; + b2PolygonShape.prototype.Copy = function () { + var s = new b2PolygonShape(); + s.Set(this); + return s; + } + b2PolygonShape.prototype.Set = function (other) { + this.__super.Set.call(this, other); + if (a2j.is(other, b2PolygonShape)) { + var other2 = (other instanceof b2PolygonShape ? other : null); + this.m_centroid.SetV(other2.m_centroid); + this.m_vertexCount = other2.m_vertexCount; + this.Reserve(this.m_vertexCount); + for (var i = 0; i < this.m_vertexCount; i++) { + this.m_vertices[i].SetV(other2.m_vertices[i]); + this.m_normals[i].SetV(other2.m_normals[i]); + } + } + } + b2PolygonShape.prototype.SetAsArray = function (vertices, vertexCount) { + if (vertexCount === undefined) vertexCount = 0; + var v = new Vector(); + var tVec; + for (var each in vertices) { + tVec = vertices[each]; { + v.push(tVec); + } + } + this.SetAsVector(v, vertexCount); + } + b2PolygonShape.prototype.AsArray = function (vertices, vertexCount) { + if (vertexCount === undefined) vertexCount = 0; + var polygonShape = new b2PolygonShape(); + polygonShape.SetAsArray(vertices, vertexCount); + return polygonShape; + } + b2PolygonShape.AsArray = b2PolygonShape.prototype.AsArray; + b2PolygonShape.prototype.SetAsVector = function (vertices, vertexCount) { + if (vertexCount === undefined) vertexCount = 0; + if (vertexCount == 0) vertexCount = vertices.length; + b2Settings.b2Assert(2 <= vertexCount); + this.m_vertexCount = vertexCount; + this.Reserve(vertexCount); + var i = 0; + for (i = 0; + i < this.m_vertexCount; i++) { + this.m_vertices[i].SetV(vertices[i]); + } + for (i = 0; + i < this.m_vertexCount; ++i) { + var i1 = parseInt(i); + var i2 = parseInt(i + 1 < this.m_vertexCount ? i + 1 : 0); + var edge = b2Math.SubtractVV(this.m_vertices[i2], this.m_vertices[i1]); + b2Settings.b2Assert(edge.LengthSquared() > Number.MIN_VALUE); + this.m_normals[i].SetV(b2Math.CrossVF(edge, 1.0)); + this.m_normals[i].Normalize(); + } + this.m_centroid = this.ComputeCentroid(this.m_vertices, this.m_vertexCount); + } + b2PolygonShape.prototype.AsVector = function (vertices, vertexCount) { + if (vertexCount === undefined) vertexCount = 0; + var polygonShape = new b2PolygonShape(); + polygonShape.SetAsVector(vertices, vertexCount); + return polygonShape; + } + b2PolygonShape.AsVector = b2PolygonShape.prototype.AsVector; + b2PolygonShape.prototype.SetAsBox = function (hx, hy) { + if (hx === undefined) hx = 0; + if (hy === undefined) hy = 0; + this.m_vertexCount = 4; + this.Reserve(4); + this.m_vertices[0].Set((-hx), (-hy)); + this.m_vertices[1].Set(hx, (-hy)); + this.m_vertices[2].Set(hx, hy); + this.m_vertices[3].Set((-hx), hy); + this.m_normals[0].Set(0.0, (-1.0)); + this.m_normals[1].Set(1.0, 0.0); + this.m_normals[2].Set(0.0, 1.0); + this.m_normals[3].Set((-1.0), 0.0); + this.m_centroid.SetZero(); + } + b2PolygonShape.prototype.AsBox = function (hx, hy) { + if (hx === undefined) hx = 0; + if (hy === undefined) hy = 0; + var polygonShape = new b2PolygonShape(); + polygonShape.SetAsBox(hx, hy); + return polygonShape; + } + b2PolygonShape.AsBox = b2PolygonShape.prototype.AsBox; + b2PolygonShape.prototype.SetAsOrientedBox = function (hx, hy, center, angle) { + if (hx === undefined) hx = 0; + if (hy === undefined) hy = 0; + if (center === undefined) center = null; + if (angle === undefined) angle = 0.0; + this.m_vertexCount = 4; + this.Reserve(4); + this.m_vertices[0].Set((-hx), (-hy)); + this.m_vertices[1].Set(hx, (-hy)); + this.m_vertices[2].Set(hx, hy); + this.m_vertices[3].Set((-hx), hy); + this.m_normals[0].Set(0.0, (-1.0)); + this.m_normals[1].Set(1.0, 0.0); + this.m_normals[2].Set(0.0, 1.0); + this.m_normals[3].Set((-1.0), 0.0); + this.m_centroid = center; + var xf = new b2Transform(); + xf.position = center; + xf.R.Set(angle); + for (var i = 0; i < this.m_vertexCount; ++i) { + this.m_vertices[i] = b2Math.MulX(xf, this.m_vertices[i]); + this.m_normals[i] = b2Math.MulMV(xf.R, this.m_normals[i]); + } + } + b2PolygonShape.prototype.AsOrientedBox = function (hx, hy, center, angle) { + if (hx === undefined) hx = 0; + if (hy === undefined) hy = 0; + if (center === undefined) center = null; + if (angle === undefined) angle = 0.0; + var polygonShape = new b2PolygonShape(); + polygonShape.SetAsOrientedBox(hx, hy, center, angle); + return polygonShape; + } + b2PolygonShape.AsOrientedBox = b2PolygonShape.prototype.AsOrientedBox; + b2PolygonShape.prototype.SetAsEdge = function (v1, v2) { + this.m_vertexCount = 2; + this.Reserve(2); + this.m_vertices[0].SetV(v1); + this.m_vertices[1].SetV(v2); + this.m_centroid.x = 0.5 * (v1.x + v2.x); + this.m_centroid.y = 0.5 * (v1.y + v2.y); + this.m_normals[0] = b2Math.CrossVF(b2Math.SubtractVV(v2, v1), 1.0); + this.m_normals[0].Normalize(); + this.m_normals[1].x = (-this.m_normals[0].x); + this.m_normals[1].y = (-this.m_normals[0].y); + } + b2PolygonShape.prototype.AsEdge = function (v1, v2) { + var polygonShape = new b2PolygonShape(); + polygonShape.SetAsEdge(v1, v2); + return polygonShape; + } + b2PolygonShape.AsEdge = b2PolygonShape.prototype.AsEdge; + b2PolygonShape.prototype.TestPoint = function (xf, p) { + var tVec; + var tMat = xf.R; + var tX = p.x - xf.position.x; + var tY = p.y - xf.position.y; + var pLocalX = (tX * tMat.col1.x + tY * tMat.col1.y); + var pLocalY = (tX * tMat.col2.x + tY * tMat.col2.y); + for (var i = 0; i < this.m_vertexCount; ++i) { + tVec = this.m_vertices[i]; + tX = pLocalX - tVec.x; + tY = pLocalY - tVec.y; + tVec = this.m_normals[i]; + var dot = (tVec.x * tX + tVec.y * tY); + if (dot > 0.0) { + return false; + } + } + return true; + } + b2PolygonShape.prototype.RayCast = function (output, input, transform) { + var lower = 0.0; + var upper = input.maxFraction; + var tX = 0; + var tY = 0; + var tMat; + var tVec; + tX = input.p1.x - transform.position.x; + tY = input.p1.y - transform.position.y; + tMat = transform.R; + var p1X = (tX * tMat.col1.x + tY * tMat.col1.y); + var p1Y = (tX * tMat.col2.x + tY * tMat.col2.y); + tX = input.p2.x - transform.position.x; + tY = input.p2.y - transform.position.y; + tMat = transform.R; + var p2X = (tX * tMat.col1.x + tY * tMat.col1.y); + var p2Y = (tX * tMat.col2.x + tY * tMat.col2.y); + var dX = p2X - p1X; + var dY = p2Y - p1Y; + var index = parseInt((-1)); + for (var i = 0; i < this.m_vertexCount; ++i) { + tVec = this.m_vertices[i]; + tX = tVec.x - p1X; + tY = tVec.y - p1Y; + tVec = this.m_normals[i]; + var numerator = (tVec.x * tX + tVec.y * tY); + var denominator = (tVec.x * dX + tVec.y * dY); + if (denominator == 0.0) { + if (numerator < 0.0) { + return false; + } + } + else { + if (denominator < 0.0 && numerator < lower * denominator) { + lower = numerator / denominator; + index = i; + } + else if (denominator > 0.0 && numerator < upper * denominator) { + upper = numerator / denominator; + } + } + if (upper < lower - Number.MIN_VALUE) { + return false; + } + } + if (index >= 0) { + output.fraction = lower; + tMat = transform.R; + tVec = this.m_normals[index]; + output.normal.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + output.normal.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + return true; + } + return false; + } + b2PolygonShape.prototype.ComputeAABB = function (aabb, xf) { + var tMat = xf.R; + var tVec = this.m_vertices[0]; + var lowerX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var lowerY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var upperX = lowerX; + var upperY = lowerY; + for (var i = 1; i < this.m_vertexCount; ++i) { + tVec = this.m_vertices[i]; + var vX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var vY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + lowerX = lowerX < vX ? lowerX : vX; + lowerY = lowerY < vY ? lowerY : vY; + upperX = upperX > vX ? upperX : vX; + upperY = upperY > vY ? upperY : vY; + } + aabb.lowerBound.x = lowerX - this.m_radius; + aabb.lowerBound.y = lowerY - this.m_radius; + aabb.upperBound.x = upperX + this.m_radius; + aabb.upperBound.y = upperY + this.m_radius; + } + b2PolygonShape.prototype.ComputeMass = function (massData, density) { + if (density === undefined) density = 0; + if (this.m_vertexCount == 2) { + massData.center.x = 0.5 * (this.m_vertices[0].x + this.m_vertices[1].x); + massData.center.y = 0.5 * (this.m_vertices[0].y + this.m_vertices[1].y); + massData.mass = 0.0; + massData.I = 0.0; + return; + } + var centerX = 0.0; + var centerY = 0.0; + var area = 0.0; + var I = 0.0; + var p1X = 0.0; + var p1Y = 0.0; + var k_inv3 = 1.0 / 3.0; + for (var i = 0; i < this.m_vertexCount; ++i) { + var p2 = this.m_vertices[i]; + var p3 = i + 1 < this.m_vertexCount ? this.m_vertices[parseInt(i + 1)] : this.m_vertices[0]; + var e1X = p2.x - p1X; + var e1Y = p2.y - p1Y; + var e2X = p3.x - p1X; + var e2Y = p3.y - p1Y; + var D = e1X * e2Y - e1Y * e2X; + var triangleArea = 0.5 * D;area += triangleArea; + centerX += triangleArea * k_inv3 * (p1X + p2.x + p3.x); + centerY += triangleArea * k_inv3 * (p1Y + p2.y + p3.y); + var px = p1X; + var py = p1Y; + var ex1 = e1X; + var ey1 = e1Y; + var ex2 = e2X; + var ey2 = e2Y; + var intx2 = k_inv3 * (0.25 * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5 * px * px; + var inty2 = k_inv3 * (0.25 * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5 * py * py;I += D * (intx2 + inty2); + } + massData.mass = density * area; + centerX *= 1.0 / area; + centerY *= 1.0 / area; + massData.center.Set(centerX, centerY); + massData.I = density * I; + } + b2PolygonShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { + if (offset === undefined) offset = 0; + var normalL = b2Math.MulTMV(xf.R, normal); + var offsetL = offset - b2Math.Dot(normal, xf.position); + var depths = new Vector_a2j_Number(); + var diveCount = 0; + var intoIndex = parseInt((-1)); + var outoIndex = parseInt((-1)); + var lastSubmerged = false; + var i = 0; + for (i = 0; + i < this.m_vertexCount; ++i) { + depths[i] = b2Math.Dot(normalL, this.m_vertices[i]) - offsetL; + var isSubmerged = depths[i] < (-Number.MIN_VALUE); + if (i > 0) { + if (isSubmerged) { + if (!lastSubmerged) { + intoIndex = i - 1; + diveCount++; + } + } + else { + if (lastSubmerged) { + outoIndex = i - 1; + diveCount++; + } + } + } + lastSubmerged = isSubmerged; + } + switch (diveCount) { + case 0: + if (lastSubmerged) { + var md = new b2MassData(); + this.ComputeMass(md, 1); + c.SetV(b2Math.MulX(xf, md.center)); + return md.mass; + } + else { + return 0; + } + break; + case 1: + if (intoIndex == (-1)) { + intoIndex = this.m_vertexCount - 1; + } + else { + outoIndex = this.m_vertexCount - 1; + } + break; + } + var intoIndex2 = parseInt((intoIndex + 1) % this.m_vertexCount); + var outoIndex2 = parseInt((outoIndex + 1) % this.m_vertexCount); + var intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]); + var outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]); + var intoVec = new b2Vec2(this.m_vertices[intoIndex].x * (1 - intoLamdda) + this.m_vertices[intoIndex2].x * intoLamdda, this.m_vertices[intoIndex].y * (1 - intoLamdda) + this.m_vertices[intoIndex2].y * intoLamdda); + var outoVec = new b2Vec2(this.m_vertices[outoIndex].x * (1 - outoLamdda) + this.m_vertices[outoIndex2].x * outoLamdda, this.m_vertices[outoIndex].y * (1 - outoLamdda) + this.m_vertices[outoIndex2].y * outoLamdda); + var area = 0; + var center = new b2Vec2(); + var p2 = this.m_vertices[intoIndex2]; + var p3; + i = intoIndex2; + while (i != outoIndex2) { + i = (i + 1) % this.m_vertexCount; + if (i == outoIndex2) p3 = outoVec; + else p3 = this.m_vertices[i]; + var triangleArea = 0.5 * ((p2.x - intoVec.x) * (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x)); + area += triangleArea; + center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3; + center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3; + p2 = p3; + } + center.Multiply(1 / area); + c.SetV(b2Math.MulX(xf, center)); + return area; + } + b2PolygonShape.prototype.GetVertexCount = function () { + return this.m_vertexCount; + } + b2PolygonShape.prototype.GetVertices = function () { + return this.m_vertices; + } + b2PolygonShape.prototype.GetNormals = function () { + return this.m_normals; + } + b2PolygonShape.prototype.GetSupport = function (d) { + var bestIndex = 0; + var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; + for (var i = 1; i < this.m_vertexCount; ++i) { + var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; + if (value > bestValue) { + bestIndex = i; + bestValue = value; + } + } + return bestIndex; + } + b2PolygonShape.prototype.GetSupportVertex = function (d) { + var bestIndex = 0; + var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; + for (var i = 1; i < this.m_vertexCount; ++i) { + var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; + if (value > bestValue) { + bestIndex = i; + bestValue = value; + } + } + return this.m_vertices[bestIndex]; + } + b2PolygonShape.prototype.Validate = function () { + return false; + } + b2PolygonShape.prototype.b2PolygonShape = function () { + this.__super.b2Shape.call(this); + this.m_type = this.e_polygonShape; + this.m_centroid = new b2Vec2(); + this.m_vertices = new Vector(); + this.m_normals = new Vector(); + } + b2PolygonShape.prototype.Reserve = function (count) { + if (count === undefined) count = 0; + for (var i = parseInt(this.m_vertices.length); i < count; i++) { + this.m_vertices[i] = new b2Vec2(); + this.m_normals[i] = new b2Vec2(); + } + } + b2PolygonShape.prototype.ComputeCentroid = function (vs, count) { + if (count === undefined) count = 0; + var c = new b2Vec2(); + var area = 0.0; + var p1X = 0.0; + var p1Y = 0.0; + var inv3 = 1.0 / 3.0; + for (var i = 0; i < count; ++i) { + var p2 = vs[i]; + var p3 = i + 1 < count ? vs[parseInt(i + 1)] : vs[0]; + var e1X = p2.x - p1X; + var e1Y = p2.y - p1Y; + var e2X = p3.x - p1X; + var e2Y = p3.y - p1Y; + var D = (e1X * e2Y - e1Y * e2X); + var triangleArea = 0.5 * D;area += triangleArea; + c.x += triangleArea * inv3 * (p1X + p2.x + p3.x); + c.y += triangleArea * inv3 * (p1Y + p2.y + p3.y); + } + c.x *= 1.0 / area; + c.y *= 1.0 / area; + return c; + } + b2PolygonShape.ComputeCentroid = b2PolygonShape.prototype.ComputeCentroid; + b2PolygonShape.prototype.ComputeOBB = function (obb, vs, count) { + if (count === undefined) count = 0; + var i = 0; + var p = new Vector(count + 1); + for (i = 0; + i < count; ++i) { + p[i] = vs[i]; + } + p[count] = p[0]; + var minArea = Number.MAX_VALUE; + for (i = 1; + i <= count; ++i) { + var root = p[parseInt(i - 1)]; + var uxX = p[i].x - root.x; + var uxY = p[i].y - root.y; + var length = Math.sqrt(uxX * uxX + uxY * uxY); + uxX /= length; + uxY /= length; + var uyX = (-uxY); + var uyY = uxX; + var lowerX = Number.MAX_VALUE; + var lowerY = Number.MAX_VALUE; + var upperX = (-Number.MAX_VALUE); + var upperY = (-Number.MAX_VALUE); + for (var j = 0; j < count; ++j) { + var dX = p[j].x - root.x; + var dY = p[j].y - root.y; + var rX = (uxX * dX + uxY * dY); + var rY = (uyX * dX + uyY * dY); + if (rX < lowerX) lowerX = rX; + if (rY < lowerY) lowerY = rY; + if (rX > upperX) upperX = rX; + if (rY > upperY) upperY = rY; + } + var area = (upperX - lowerX) * (upperY - lowerY); + if (area < 0.95 * minArea) { + minArea = area; + obb.R.col1.x = uxX; + obb.R.col1.y = uxY; + obb.R.col2.x = uyX; + obb.R.col2.y = uyY; + var centerX = 0.5 * (lowerX + upperX); + var centerY = 0.5 * (lowerY + upperY); + var tMat = obb.R; + obb.center.x = root.x + (tMat.col1.x * centerX + tMat.col2.x * centerY); + obb.center.y = root.y + (tMat.col1.y * centerX + tMat.col2.y * centerY); + obb.extents.x = 0.5 * (upperX - lowerX); + obb.extents.y = 0.5 * (upperY - lowerY); + } + } + } + b2PolygonShape.ComputeOBB = b2PolygonShape.prototype.ComputeOBB; + _A2J_postDefs.push(function () { + Box2D.Collision.Shapes.b2PolygonShape.s_mat = new b2Mat22(); + Box2D.Collision.Shapes.b2PolygonShape.prototype.s_mat = Box2D.Collision.Shapes.b2PolygonShape.s_mat; + }); + b2Shape.b2Shape = function () {}; + b2Shape.prototype.Copy = function () { + return null; + } + b2Shape.prototype.Set = function (other) { + this.m_radius = other.m_radius; + } + b2Shape.prototype.GetType = function () { + return this.m_type; + } + b2Shape.prototype.TestPoint = function (xf, p) { + return false; + } + b2Shape.prototype.RayCast = function (output, input, transform) { + return false; + } + b2Shape.prototype.ComputeAABB = function (aabb, xf) {} + b2Shape.prototype.ComputeMass = function (massData, density) { + if (density === undefined) density = 0; + } + b2Shape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { + if (offset === undefined) offset = 0; + return 0; + } + b2Shape.prototype.TestOverlap = function (shape1, transform1, shape2, transform2) { + var input = new b2DistanceInput(); + input.proxyA = new b2DistanceProxy(); + input.proxyA.Set(shape1); + input.proxyB = new b2DistanceProxy(); + input.proxyB.Set(shape2); + input.transformA = transform1; + input.transformB = transform2; + input.useRadii = true; + var simplexCache = new b2SimplexCache(); + simplexCache.count = 0; + var output = new b2DistanceOutput(); + b2Distance.Distance(output, simplexCache, input); + return output.distance < 10.0 * Number.MIN_VALUE; + } + b2Shape.TestOverlap = b2Shape.prototype.TestOverlap; + b2Shape.prototype.b2Shape = function () { + this.m_type = b2Shape.e_unknownShape; + this.m_radius = b2Settings.b2_linearSlop; + } + _A2J_postDefs.push(function () { + Box2D.Collision.Shapes.b2Shape.e_unknownShape = parseInt((-1)); + Box2D.Collision.Shapes.b2Shape.prototype.e_unknownShape = Box2D.Collision.Shapes.b2Shape.e_unknownShape; + Box2D.Collision.Shapes.b2Shape.e_circleShape = 0; + Box2D.Collision.Shapes.b2Shape.prototype.e_circleShape = Box2D.Collision.Shapes.b2Shape.e_circleShape; + Box2D.Collision.Shapes.b2Shape.e_polygonShape = 1; + Box2D.Collision.Shapes.b2Shape.prototype.e_polygonShape = Box2D.Collision.Shapes.b2Shape.e_polygonShape; + Box2D.Collision.Shapes.b2Shape.e_edgeShape = 2; + Box2D.Collision.Shapes.b2Shape.prototype.e_edgeShape = Box2D.Collision.Shapes.b2Shape.e_edgeShape; + Box2D.Collision.Shapes.b2Shape.e_shapeTypeCount = 3; + Box2D.Collision.Shapes.b2Shape.prototype.e_shapeTypeCount = Box2D.Collision.Shapes.b2Shape.e_shapeTypeCount; + Box2D.Collision.Shapes.b2Shape.e_hitCollide = 1; + Box2D.Collision.Shapes.b2Shape.prototype.e_hitCollide = Box2D.Collision.Shapes.b2Shape.e_hitCollide; + Box2D.Collision.Shapes.b2Shape.e_missCollide = 0; + Box2D.Collision.Shapes.b2Shape.prototype.e_missCollide = Box2D.Collision.Shapes.b2Shape.e_missCollide; + Box2D.Collision.Shapes.b2Shape.e_startsInsideCollide = parseInt((-1)); + Box2D.Collision.Shapes.b2Shape.prototype.e_startsInsideCollide = Box2D.Collision.Shapes.b2Shape.e_startsInsideCollide; + }); +})(); /* source: disabled*/ +(function () { + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2Mat22 = Box2D.Common.Math.b2Mat22; + var b2Mat33 = Box2D.Common.Math.b2Mat33; + var b2Math = Box2D.Common.Math.b2Math; + var b2Sweep = Box2D.Common.Math.b2Sweep; + var b2Transform = Box2D.Common.Math.b2Transform; + var b2Vec2 = Box2D.Common.Math.b2Vec2; + var b2Vec3 = Box2D.Common.Math.b2Vec3; + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2internal = Box2D.Common.b2internal; + b2Color.b2Color = function () { + this._r = 0; + this._g = 0; + this._b = 0; + }; + b2Color.prototype.b2Color = function (rr, gg, bb) { + if (rr === undefined) rr = 0; + if (gg === undefined) gg = 0; + if (bb === undefined) bb = 0; + this._r = a2j.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0)); + this._g = a2j.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0)); + this._b = a2j.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0)); + } + b2Color.prototype.Set = function (rr, gg, bb) { + if (rr === undefined) rr = 0; + if (gg === undefined) gg = 0; + if (bb === undefined) bb = 0; + this._r = a2j.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0)); + this._g = a2j.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0)); + this._b = a2j.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0)); + } + b2Color.prototype.__defineSetter__('r', function (rr) { + if (rr === undefined) rr = 0; + this._r = a2j.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0)); + }); + b2Color.prototype.__defineSetter__('g', function (gg) { + if (gg === undefined) gg = 0; + this._g = a2j.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0)); + }); + b2Color.prototype.__defineSetter__('b', function (bb) { + if (bb === undefined) bb = 0; + this._b = a2j.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0)); + }); + b2Color.prototype.__defineGetter__('color', function () { + return (this._r << 16) | (this._g << 8) | (this._b); + }); + b2Settings.b2Settings = function () {}; + b2Settings.prototype.b2MixFriction = function (friction1, friction2) { + if (friction1 === undefined) friction1 = 0; + if (friction2 === undefined) friction2 = 0; + return Math.sqrt(friction1 * friction2); + } + b2Settings.b2MixFriction = b2Settings.prototype.b2MixFriction; + b2Settings.prototype.b2MixRestitution = function (restitution1, restitution2) { + if (restitution1 === undefined) restitution1 = 0; + if (restitution2 === undefined) restitution2 = 0; + return restitution1 > restitution2 ? restitution1 : restitution2; + } + b2Settings.b2MixRestitution = b2Settings.prototype.b2MixRestitution; + b2Settings.prototype.b2Assert = function (a) { + if (!a) { + throw "Assertion Failed"; + } + } + b2Settings.b2Assert = b2Settings.prototype.b2Assert; + _A2J_postDefs.push(function () { + Box2D.Common.b2Settings.VERSION = "2.1alpha"; + Box2D.Common.b2Settings.prototype.VERSION = Box2D.Common.b2Settings.VERSION; + Box2D.Common.b2Settings.USHRT_MAX = 0x0000ffff; + Box2D.Common.b2Settings.prototype.USHRT_MAX = Box2D.Common.b2Settings.USHRT_MAX; + Box2D.Common.b2Settings.b2_pi = Math.PI; + Box2D.Common.b2Settings.prototype.b2_pi = Box2D.Common.b2Settings.b2_pi; + Box2D.Common.b2Settings.b2_maxManifoldPoints = 2; + Box2D.Common.b2Settings.prototype.b2_maxManifoldPoints = Box2D.Common.b2Settings.b2_maxManifoldPoints; + Box2D.Common.b2Settings.b2_aabbExtension = 0.1; + Box2D.Common.b2Settings.prototype.b2_aabbExtension = Box2D.Common.b2Settings.b2_aabbExtension; + Box2D.Common.b2Settings.b2_aabbMultiplier = 2.0; + Box2D.Common.b2Settings.prototype.b2_aabbMultiplier = Box2D.Common.b2Settings.b2_aabbMultiplier; + Box2D.Common.b2Settings.b2_polygonRadius = 2.0 * b2Settings.b2_linearSlop; + Box2D.Common.b2Settings.prototype.b2_polygonRadius = Box2D.Common.b2Settings.b2_polygonRadius; + Box2D.Common.b2Settings.b2_linearSlop = 0.005; + Box2D.Common.b2Settings.prototype.b2_linearSlop = Box2D.Common.b2Settings.b2_linearSlop; + Box2D.Common.b2Settings.b2_angularSlop = 2.0 / 180.0 * b2Settings.b2_pi; + Box2D.Common.b2Settings.prototype.b2_angularSlop = Box2D.Common.b2Settings.b2_angularSlop; + Box2D.Common.b2Settings.b2_toiSlop = 8.0 * b2Settings.b2_linearSlop; + Box2D.Common.b2Settings.prototype.b2_toiSlop = Box2D.Common.b2Settings.b2_toiSlop; + Box2D.Common.b2Settings.b2_maxTOIContactsPerIsland = 32; + Box2D.Common.b2Settings.prototype.b2_maxTOIContactsPerIsland = Box2D.Common.b2Settings.b2_maxTOIContactsPerIsland; + Box2D.Common.b2Settings.b2_maxTOIJointsPerIsland = 32; + Box2D.Common.b2Settings.prototype.b2_maxTOIJointsPerIsland = Box2D.Common.b2Settings.b2_maxTOIJointsPerIsland; + Box2D.Common.b2Settings.b2_velocityThreshold = 1.0; + Box2D.Common.b2Settings.prototype.b2_velocityThreshold = Box2D.Common.b2Settings.b2_velocityThreshold; + Box2D.Common.b2Settings.b2_maxLinearCorrection = 0.2; + Box2D.Common.b2Settings.prototype.b2_maxLinearCorrection = Box2D.Common.b2Settings.b2_maxLinearCorrection; + Box2D.Common.b2Settings.b2_maxAngularCorrection = 8.0 / 180.0 * b2Settings.b2_pi; + Box2D.Common.b2Settings.prototype.b2_maxAngularCorrection = Box2D.Common.b2Settings.b2_maxAngularCorrection; + Box2D.Common.b2Settings.b2_maxTranslation = 2.0; + Box2D.Common.b2Settings.prototype.b2_maxTranslation = Box2D.Common.b2Settings.b2_maxTranslation; + Box2D.Common.b2Settings.b2_maxTranslationSquared = b2Settings.b2_maxTranslation * b2Settings.b2_maxTranslation; + Box2D.Common.b2Settings.prototype.b2_maxTranslationSquared = Box2D.Common.b2Settings.b2_maxTranslationSquared; + Box2D.Common.b2Settings.b2_maxRotation = 0.5 * b2Settings.b2_pi; + Box2D.Common.b2Settings.prototype.b2_maxRotation = Box2D.Common.b2Settings.b2_maxRotation; + Box2D.Common.b2Settings.b2_maxRotationSquared = b2Settings.b2_maxRotation * b2Settings.b2_maxRotation; + Box2D.Common.b2Settings.prototype.b2_maxRotationSquared = Box2D.Common.b2Settings.b2_maxRotationSquared; + Box2D.Common.b2Settings.b2_contactBaumgarte = 0.2; + Box2D.Common.b2Settings.prototype.b2_contactBaumgarte = Box2D.Common.b2Settings.b2_contactBaumgarte; + Box2D.Common.b2Settings.b2_timeToSleep = 0.5; + Box2D.Common.b2Settings.prototype.b2_timeToSleep = Box2D.Common.b2Settings.b2_timeToSleep; + Box2D.Common.b2Settings.b2_linearSleepTolerance = 0.01; + Box2D.Common.b2Settings.prototype.b2_linearSleepTolerance = Box2D.Common.b2Settings.b2_linearSleepTolerance; + Box2D.Common.b2Settings.b2_angularSleepTolerance = 2.0 / 180.0 * b2Settings.b2_pi; + Box2D.Common.b2Settings.prototype.b2_angularSleepTolerance = Box2D.Common.b2Settings.b2_angularSleepTolerance; + }); +})(); /* source: disabled*/ +(function () { + var b2AABB = Box2D.Collision.b2AABB; + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2Mat22 = Box2D.Common.Math.b2Mat22; + var b2Mat33 = Box2D.Common.Math.b2Mat33; + var b2Math = Box2D.Common.Math.b2Math; + var b2Sweep = Box2D.Common.Math.b2Sweep; + var b2Transform = Box2D.Common.Math.b2Transform; + var b2Vec2 = Box2D.Common.Math.b2Vec2; + var b2Vec3 = Box2D.Common.Math.b2Vec3; + b2Mat22.b2Mat22 = function () { + this.col1 = new b2Vec2(); + this.col2 = new b2Vec2(); + }; + b2Mat22.prototype.b2Mat22 = function () { + this.SetIdentity(); + } + b2Mat22.prototype.FromAngle = function (angle) { + if (angle === undefined) angle = 0; + var mat = new b2Mat22(); + mat.Set(angle); + return mat; + } + b2Mat22.FromAngle = b2Mat22.prototype.FromAngle; + b2Mat22.prototype.FromVV = function (c1, c2) { + var mat = new b2Mat22(); + mat.SetVV(c1, c2); + return mat; + } + b2Mat22.FromVV = b2Mat22.prototype.FromVV; + b2Mat22.prototype.Set = function (angle) { + if (angle === undefined) angle = 0; + var c = Math.cos(angle); + var s = Math.sin(angle); + this.col1.x = c; + this.col2.x = (-s); + this.col1.y = s; + this.col2.y = c; + } + b2Mat22.prototype.SetVV = function (c1, c2) { + this.col1.SetV(c1); + this.col2.SetV(c2); + } + b2Mat22.prototype.Copy = function () { + var mat = new b2Mat22(); + mat.SetM(this); + return mat; + } + b2Mat22.prototype.SetM = function (m) { + this.col1.SetV(m.col1); + this.col2.SetV(m.col2); + } + b2Mat22.prototype.AddM = function (m) { + this.col1.x += m.col1.x; + this.col1.y += m.col1.y; + this.col2.x += m.col2.x; + this.col2.y += m.col2.y; + } + b2Mat22.prototype.SetIdentity = function () { + this.col1.x = 1.0; + this.col2.x = 0.0; + this.col1.y = 0.0; + this.col2.y = 1.0; + } + b2Mat22.prototype.SetZero = function () { + this.col1.x = 0.0; + this.col2.x = 0.0; + this.col1.y = 0.0; + this.col2.y = 0.0; + } + b2Mat22.prototype.GetAngle = function () { + return Math.atan2(this.col1.y, this.col1.x); + } + b2Mat22.prototype.GetInverse = function (out) { + var a = this.col1.x; + var b = this.col2.x; + var c = this.col1.y; + var d = this.col2.y; + var det = a * d - b * c; + if (det != 0.0) { + det = 1.0 / det; + } + out.col1.x = det * d; + out.col2.x = (-det * b); + out.col1.y = (-det * c); + out.col2.y = det * a; + return out; + } + b2Mat22.prototype.Solve = function (out, bX, bY) { + if (bX === undefined) bX = 0; + if (bY === undefined) bY = 0; + var a11 = this.col1.x; + var a12 = this.col2.x; + var a21 = this.col1.y; + var a22 = this.col2.y; + var det = a11 * a22 - a12 * a21; + if (det != 0.0) { + det = 1.0 / det; + } + out.x = det * (a22 * bX - a12 * bY); + out.y = det * (a11 * bY - a21 * bX); + return out; + } + b2Mat22.prototype.Abs = function () { + this.col1.Abs(); + this.col2.Abs(); + } + b2Mat33.b2Mat33 = function () { + this.col1 = new b2Vec3(); + this.col2 = new b2Vec3(); + this.col3 = new b2Vec3(); + }; + b2Mat33.prototype.b2Mat33 = function (c1, c2, c3) { + if (c1 === undefined) c1 = null; + if (c2 === undefined) c2 = null; + if (c3 === undefined) c3 = null; + if (!c1 && !c2 && !c3) { + this.col1.SetZero(); + this.col2.SetZero(); + this.col3.SetZero(); + } + else { + this.col1.SetV(c1); + this.col2.SetV(c2); + this.col3.SetV(c3); + } + } + b2Mat33.prototype.SetVVV = function (c1, c2, c3) { + this.col1.SetV(c1); + this.col2.SetV(c2); + this.col3.SetV(c3); + } + b2Mat33.prototype.Copy = function () { + return new b2Mat33(this.col1, this.col2, this.col3); + } + b2Mat33.prototype.SetM = function (m) { + this.col1.SetV(m.col1); + this.col2.SetV(m.col2); + this.col3.SetV(m.col3); + } + b2Mat33.prototype.AddM = function (m) { + this.col1.x += m.col1.x; + this.col1.y += m.col1.y; + this.col1.z += m.col1.z; + this.col2.x += m.col2.x; + this.col2.y += m.col2.y; + this.col2.z += m.col2.z; + this.col3.x += m.col3.x; + this.col3.y += m.col3.y; + this.col3.z += m.col3.z; + } + b2Mat33.prototype.SetIdentity = function () { + this.col1.x = 1.0; + this.col2.x = 0.0; + this.col3.x = 0.0; + this.col1.y = 0.0; + this.col2.y = 1.0; + this.col3.y = 0.0; + this.col1.z = 0.0; + this.col2.z = 0.0; + this.col3.z = 1.0; + } + b2Mat33.prototype.SetZero = function () { + this.col1.x = 0.0; + this.col2.x = 0.0; + this.col3.x = 0.0; + this.col1.y = 0.0; + this.col2.y = 0.0; + this.col3.y = 0.0; + this.col1.z = 0.0; + this.col2.z = 0.0; + this.col3.z = 0.0; + } + b2Mat33.prototype.Solve22 = function (out, bX, bY) { + if (bX === undefined) bX = 0; + if (bY === undefined) bY = 0; + var a11 = this.col1.x; + var a12 = this.col2.x; + var a21 = this.col1.y; + var a22 = this.col2.y; + var det = a11 * a22 - a12 * a21; + if (det != 0.0) { + det = 1.0 / det; + } + out.x = det * (a22 * bX - a12 * bY); + out.y = det * (a11 * bY - a21 * bX); + return out; + } + b2Mat33.prototype.Solve33 = function (out, bX, bY, bZ) { + if (bX === undefined) bX = 0; + if (bY === undefined) bY = 0; + if (bZ === undefined) bZ = 0; + var a11 = this.col1.x; + var a21 = this.col1.y; + var a31 = this.col1.z; + var a12 = this.col2.x; + var a22 = this.col2.y; + var a32 = this.col2.z; + var a13 = this.col3.x; + var a23 = this.col3.y; + var a33 = this.col3.z; + var det = a11 * (a22 * a33 - a32 * a23) + a21 * (a32 * a13 - a12 * a33) + a31 * (a12 * a23 - a22 * a13); + if (det != 0.0) { + det = 1.0 / det; + } + out.x = det * (bX * (a22 * a33 - a32 * a23) + bY * (a32 * a13 - a12 * a33) + bZ * (a12 * a23 - a22 * a13)); + out.y = det * (a11 * (bY * a33 - bZ * a23) + a21 * (bZ * a13 - bX * a33) + a31 * (bX * a23 - bY * a13)); + out.z = det * (a11 * (a22 * bZ - a32 * bY) + a21 * (a32 * bX - a12 * bZ) + a31 * (a12 * bY - a22 * bX)); + return out; + } + b2Math.b2Math = function () {}; + b2Math.prototype.IsValid = function (x) { + if (x === undefined) x = 0; + return isFinite(x); + } + b2Math.IsValid = b2Math.prototype.IsValid; + b2Math.prototype.Dot = function (a, b) { + return a.x * b.x + a.y * b.y; + } + b2Math.Dot = b2Math.prototype.Dot; + b2Math.prototype.CrossVV = function (a, b) { + return a.x * b.y - a.y * b.x; + } + b2Math.CrossVV = b2Math.prototype.CrossVV; + b2Math.prototype.CrossVF = function (a, s) { + if (s === undefined) s = 0; + var v = new b2Vec2(s * a.y, (-s * a.x)); + return v; + } + b2Math.CrossVF = b2Math.prototype.CrossVF; + b2Math.prototype.CrossFV = function (s, a) { + if (s === undefined) s = 0; + var v = new b2Vec2((-s * a.y), s * a.x); + return v; + } + b2Math.CrossFV = b2Math.prototype.CrossFV; + b2Math.prototype.MulMV = function (A, v) { + var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y); + return u; + } + b2Math.MulMV = b2Math.prototype.MulMV; + b2Math.prototype.MulTMV = function (A, v) { + var u = new b2Vec2(this.Dot(v, A.col1), this.Dot(v, A.col2)); + return u; + } + b2Math.MulTMV = b2Math.prototype.MulTMV; + b2Math.prototype.MulX = function (T, v) { + var a = this.MulMV(T.R, v); + a.x += T.position.x; + a.y += T.position.y; + return a; + } + b2Math.MulX = b2Math.prototype.MulX; + b2Math.prototype.MulXT = function (T, v) { + var a = this.SubtractVV(v, T.position); + var tX = (a.x * T.R.col1.x + a.y * T.R.col1.y); + a.y = (a.x * T.R.col2.x + a.y * T.R.col2.y); + a.x = tX; + return a; + } + b2Math.MulXT = b2Math.prototype.MulXT; + b2Math.prototype.AddVV = function (a, b) { + var v = new b2Vec2(a.x + b.x, a.y + b.y); + return v; + } + b2Math.AddVV = b2Math.prototype.AddVV; + b2Math.prototype.SubtractVV = function (a, b) { + var v = new b2Vec2(a.x - b.x, a.y - b.y); + return v; + } + b2Math.SubtractVV = b2Math.prototype.SubtractVV; + b2Math.prototype.Distance = function (a, b) { + var cX = a.x - b.x; + var cY = a.y - b.y; + return Math.sqrt(cX * cX + cY * cY); + } + b2Math.Distance = b2Math.prototype.Distance; + b2Math.prototype.DistanceSquared = function (a, b) { + var cX = a.x - b.x; + var cY = a.y - b.y; + return (cX * cX + cY * cY); + } + b2Math.DistanceSquared = b2Math.prototype.DistanceSquared; + b2Math.prototype.MulFV = function (s, a) { + if (s === undefined) s = 0; + var v = new b2Vec2(s * a.x, s * a.y); + return v; + } + b2Math.MulFV = b2Math.prototype.MulFV; + b2Math.prototype.AddMM = function (A, B) { + var C = b2Mat22.FromVV(this.AddVV(A.col1, B.col1), this.AddVV(A.col2, B.col2)); + return C; + } + b2Math.AddMM = b2Math.prototype.AddMM; + b2Math.prototype.MulMM = function (A, B) { + var C = b2Mat22.FromVV(this.MulMV(A, B.col1), this.MulMV(A, B.col2)); + return C; + } + b2Math.MulMM = b2Math.prototype.MulMM; + b2Math.prototype.MulTMM = function (A, B) { + var c1 = new b2Vec2(this.Dot(A.col1, B.col1), this.Dot(A.col2, B.col1)); + var c2 = new b2Vec2(this.Dot(A.col1, B.col2), this.Dot(A.col2, B.col2)); + var C = b2Mat22.FromVV(c1, c2); + return C; + } + b2Math.MulTMM = b2Math.prototype.MulTMM; + b2Math.prototype.Abs = function (a) { + if (a === undefined) a = 0; + return a > 0.0 ? a : (-a); + } + b2Math.Abs = b2Math.prototype.Abs; + b2Math.prototype.AbsV = function (a) { + var b = new b2Vec2(this.Abs(a.x), this.Abs(a.y)); + return b; + } + b2Math.AbsV = b2Math.prototype.AbsV; + b2Math.prototype.AbsM = function (A) { + var B = b2Mat22.FromVV(this.AbsV(A.col1), this.AbsV(A.col2)); + return B; + } + b2Math.AbsM = b2Math.prototype.AbsM; + b2Math.prototype.Min = function (a, b) { + if (a === undefined) a = 0; + if (b === undefined) b = 0; + return a < b ? a : b; + } + b2Math.Min = b2Math.prototype.Min; + b2Math.prototype.MinV = function (a, b) { + var c = new b2Vec2(this.Min(a.x, b.x), this.Min(a.y, b.y)); + return c; + } + b2Math.MinV = b2Math.prototype.MinV; + b2Math.prototype.Max = function (a, b) { + if (a === undefined) a = 0; + if (b === undefined) b = 0; + return a > b ? a : b; + } + b2Math.Max = b2Math.prototype.Max; + b2Math.prototype.MaxV = function (a, b) { + var c = new b2Vec2(this.Max(a.x, b.x), this.Max(a.y, b.y)); + return c; + } + b2Math.MaxV = b2Math.prototype.MaxV; + b2Math.prototype.Clamp = function (a, low, high) { + if (a === undefined) a = 0; + if (low === undefined) low = 0; + if (high === undefined) high = 0; + return a < low ? low : a > high ? high : a; + } + b2Math.Clamp = b2Math.prototype.Clamp; + b2Math.prototype.ClampV = function (a, low, high) { + return this.MaxV(low, this.MinV(a, high)); + } + b2Math.ClampV = b2Math.prototype.ClampV; + b2Math.prototype.Swap = function (a, b) { + var tmp = a[0]; + a[0] = b[0]; + b[0] = tmp; + } + b2Math.Swap = b2Math.prototype.Swap; + b2Math.prototype.Random = function () { + return Math.random() * 2 - 1; + } + b2Math.Random = b2Math.prototype.Random; + b2Math.prototype.RandomRange = function (lo, hi) { + if (lo === undefined) lo = 0; + if (hi === undefined) hi = 0; + var r = Math.random(); + r = (hi - lo) * r + lo; + return r; + } + b2Math.RandomRange = b2Math.prototype.RandomRange; + b2Math.prototype.NextPowerOfTwo = function (x) { + if (x === undefined) x = 0; + x |= (x >> 1) & 0x7FFFFFFF; + x |= (x >> 2) & 0x3FFFFFFF; + x |= (x >> 4) & 0x0FFFFFFF; + x |= (x >> 8) & 0x00FFFFFF; + x |= (x >> 16) & 0x0000FFFF; + return x + 1; + } + b2Math.NextPowerOfTwo = b2Math.prototype.NextPowerOfTwo; + b2Math.prototype.IsPowerOfTwo = function (x) { + if (x === undefined) x = 0; + var result = x > 0 && (x & (x - 1)) == 0; + return result; + } + b2Math.IsPowerOfTwo = b2Math.prototype.IsPowerOfTwo; + _A2J_postDefs.push(function () { + Box2D.Common.Math.b2Math.b2Vec2_zero = new b2Vec2(0.0, 0.0); + Box2D.Common.Math.b2Math.prototype.b2Vec2_zero = Box2D.Common.Math.b2Math.b2Vec2_zero; + Box2D.Common.Math.b2Math.b2Mat22_identity = b2Mat22.FromVV(new b2Vec2(1.0, 0.0), new b2Vec2(0.0, 1.0)); + Box2D.Common.Math.b2Math.prototype.b2Mat22_identity = Box2D.Common.Math.b2Math.b2Mat22_identity; + Box2D.Common.Math.b2Math.b2Transform_identity = new b2Transform(b2Math.b2Vec2_zero, b2Math.b2Mat22_identity); + Box2D.Common.Math.b2Math.prototype.b2Transform_identity = Box2D.Common.Math.b2Math.b2Transform_identity; + }); + b2Sweep.b2Sweep = function () { + this.localCenter = new b2Vec2(); + this.c0 = new b2Vec2; + this.c = new b2Vec2(); + }; + b2Sweep.prototype.Set = function (other) { + this.localCenter.SetV(other.localCenter); + this.c0.SetV(other.c0); + this.c.SetV(other.c); + this.a0 = other.a0; + this.a = other.a; + this.t0 = other.t0; + } + b2Sweep.prototype.Copy = function () { + var copy = new b2Sweep(); + copy.localCenter.SetV(this.localCenter); + copy.c0.SetV(this.c0); + copy.c.SetV(this.c); + copy.a0 = this.a0; + copy.a = this.a; + copy.t0 = this.t0; + return copy; + } + b2Sweep.prototype.GetTransform = function (xf, alpha) { + if (alpha === undefined) alpha = 0; + xf.position.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x; + xf.position.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y; + var angle = (1.0 - alpha) * this.a0 + alpha * this.a; + xf.R.Set(angle); + var tMat = xf.R; + xf.position.x -= (tMat.col1.x * this.localCenter.x + tMat.col2.x * this.localCenter.y); + xf.position.y -= (tMat.col1.y * this.localCenter.x + tMat.col2.y * this.localCenter.y); + } + b2Sweep.prototype.Advance = function (t) { + if (t === undefined) t = 0; + if (this.t0 < t && 1.0 - this.t0 > Number.MIN_VALUE) { + var alpha = (t - this.t0) / (1.0 - this.t0); + this.c0.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x; + this.c0.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y; + this.a0 = (1.0 - alpha) * this.a0 + alpha * this.a; + this.t0 = t; + } + } + b2Transform.b2Transform = function () { + this.position = new b2Vec2; + this.R = new b2Mat22(); + }; + b2Transform.prototype.b2Transform = function (pos, r) { + if (pos === undefined) pos = null; + if (r === undefined) r = null; + if (pos) { + this.position.SetV(pos); + this.R.SetM(r); + } + } + b2Transform.prototype.Initialize = function (pos, r) { + this.position.SetV(pos); + this.R.SetM(r); + } + b2Transform.prototype.SetIdentity = function () { + this.position.SetZero(); + this.R.SetIdentity(); + } + b2Transform.prototype.Set = function (x) { + this.position.SetV(x.position); + this.R.SetM(x.R); + } + b2Transform.prototype.GetAngle = function () { + return Math.atan2(this.R.col1.y, this.R.col1.x); + } + b2Vec2.b2Vec2 = function () {}; + b2Vec2.prototype.b2Vec2 = function (x_, y_) { + if (x_ === undefined) x_ = 0; + if (y_ === undefined) y_ = 0; + this.x = x_; + this.y = y_; + } + b2Vec2.prototype.SetZero = function () { + this.x = 0.0; + this.y = 0.0; + } + b2Vec2.prototype.Set = function (x_, y_) { + if (x_ === undefined) x_ = 0; + if (y_ === undefined) y_ = 0; + this.x = x_; + this.y = y_; + } + b2Vec2.prototype.SetV = function (v) { + this.x = v.x; + this.y = v.y; + } + b2Vec2.prototype.GetNegative = function () { + return new b2Vec2((-this.x), (-this.y)); + } + b2Vec2.prototype.NegativeSelf = function () { + this.x = (-this.x); + this.y = (-this.y); + } + b2Vec2.prototype.Make = function (x_, y_) { + if (x_ === undefined) x_ = 0; + if (y_ === undefined) y_ = 0; + return new b2Vec2(x_, y_); + } + b2Vec2.Make = b2Vec2.prototype.Make; + b2Vec2.prototype.Copy = function () { + return new b2Vec2(this.x, this.y); + } + b2Vec2.prototype.Add = function (v) { + this.x += v.x; + this.y += v.y; + } + b2Vec2.prototype.Subtract = function (v) { + this.x -= v.x; + this.y -= v.y; + } + b2Vec2.prototype.Multiply = function (a) { + if (a === undefined) a = 0; + this.x *= a; + this.y *= a; + } + b2Vec2.prototype.MulM = function (A) { + var tX = this.x; + this.x = A.col1.x * tX + A.col2.x * this.y; + this.y = A.col1.y * tX + A.col2.y * this.y; + } + b2Vec2.prototype.MulTM = function (A) { + var tX = b2Math.Dot(this, A.col1); + this.y = b2Math.Dot(this, A.col2); + this.x = tX; + } + b2Vec2.prototype.CrossVF = function (s) { + if (s === undefined) s = 0; + var tX = this.x; + this.x = s * this.y; + this.y = (-s * tX); + } + b2Vec2.prototype.CrossFV = function (s) { + if (s === undefined) s = 0; + var tX = this.x; + this.x = (-s * this.y); + this.y = s * tX; + } + b2Vec2.prototype.MinV = function (b) { + this.x = this.x < b.x ? this.x : b.x; + this.y = this.y < b.y ? this.y : b.y; + } + b2Vec2.prototype.MaxV = function (b) { + this.x = this.x > b.x ? this.x : b.x; + this.y = this.y > b.y ? this.y : b.y; + } + b2Vec2.prototype.Abs = function () { + if (this.x < 0) this.x = (-this.x); + if (this.y < 0) this.y = (-this.y); + } + b2Vec2.prototype.Length = function () { + return Math.sqrt(this.x * this.x + this.y * this.y); + } + b2Vec2.prototype.LengthSquared = function () { + return (this.x * this.x + this.y * this.y); + } + b2Vec2.prototype.Normalize = function () { + var length = Math.sqrt(this.x * this.x + this.y * this.y); + if (length < Number.MIN_VALUE) { + return 0.0; + } + var invLength = 1.0 / length; + this.x *= invLength; + this.y *= invLength; + return length; + } + b2Vec2.prototype.IsValid = function () { + return b2Math.IsValid(this.x) && b2Math.IsValid(this.y); + } + b2Vec3.b2Vec3 = function () {}; + b2Vec3.prototype.b2Vec3 = function (x, y, z) { + if (x === undefined) x = 0; + if (y === undefined) y = 0; + if (z === undefined) z = 0; + this.x = x; + this.y = y; + this.z = z; + } + b2Vec3.prototype.SetZero = function () { + this.x = this.y = this.z = 0.0; + } + b2Vec3.prototype.Set = function (x, y, z) { + if (x === undefined) x = 0; + if (y === undefined) y = 0; + if (z === undefined) z = 0; + this.x = x; + this.y = y; + this.z = z; + } + b2Vec3.prototype.SetV = function (v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + } + b2Vec3.prototype.GetNegative = function () { + return new b2Vec3((-this.x), (-this.y), (-this.z)); + } + b2Vec3.prototype.NegativeSelf = function () { + this.x = (-this.x); + this.y = (-this.y); + this.z = (-this.z); + } + b2Vec3.prototype.Copy = function () { + return new b2Vec3(this.x, this.y, this.z); + } + b2Vec3.prototype.Add = function (v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + } + b2Vec3.prototype.Subtract = function (v) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + } + b2Vec3.prototype.Multiply = function (a) { + if (a === undefined) a = 0; + this.x *= a; + this.y *= a; + this.z *= a; + } +})(); /* source: disabled*/ +(function () { + var b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge; + var b2Mat22 = Box2D.Common.Math.b2Mat22; + var b2Mat33 = Box2D.Common.Math.b2Mat33; + var b2Math = Box2D.Common.Math.b2Math; + var b2Sweep = Box2D.Common.Math.b2Sweep; + var b2Transform = Box2D.Common.Math.b2Transform; + var b2Vec2 = Box2D.Common.Math.b2Vec2; + var b2Vec3 = Box2D.Common.Math.b2Vec3; + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2AABB = Box2D.Collision.b2AABB; + var b2Bound = Box2D.Collision.b2Bound; + var b2BoundValues = Box2D.Collision.b2BoundValues; + var b2BroadPhase = Box2D.Collision.b2BroadPhase; + var b2Collision = Box2D.Collision.b2Collision; + var b2ContactID = Box2D.Collision.b2ContactID; + var b2ContactPoint = Box2D.Collision.b2ContactPoint; + var b2Distance = Box2D.Collision.b2Distance; + var b2DistanceInput = Box2D.Collision.b2DistanceInput; + var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; + var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; + var b2DynamicTree = Box2D.Collision.b2DynamicTree; + var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; + var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; + var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; + var b2Manifold = Box2D.Collision.b2Manifold; + var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; + var b2OBB = Box2D.Collision.b2OBB; + var b2Pair = Box2D.Collision.b2Pair; + var b2PairManager = Box2D.Collision.b2PairManager; + var b2Point = Box2D.Collision.b2Point; + var b2Proxy = Box2D.Collision.b2Proxy; + var b2RayCastInput = Box2D.Collision.b2RayCastInput; + var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; + var b2Segment = Box2D.Collision.b2Segment; + var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; + var b2Simplex = Box2D.Collision.b2Simplex; + var b2SimplexCache = Box2D.Collision.b2SimplexCache; + var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; + var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; + var b2TOIInput = Box2D.Collision.b2TOIInput; + var b2WorldManifold = Box2D.Collision.b2WorldManifold; + var ClipVertex = Box2D.Collision.ClipVertex; + var Features = Box2D.Collision.Features; + var IBroadPhase = Box2D.Collision.IBroadPhase; + var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; + var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; + var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; + var b2MassData = Box2D.Collision.Shapes.b2MassData; + var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; + var b2Shape = Box2D.Collision.Shapes.b2Shape; + var b2Body = Box2D.Dynamics.b2Body; + var b2BodyDef = Box2D.Dynamics.b2BodyDef; + var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; + var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; + var b2ContactListener = Box2D.Dynamics.b2ContactListener; + var b2ContactManager = Box2D.Dynamics.b2ContactManager; + var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; + var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; + var b2FilterData = Box2D.Dynamics.b2FilterData; + var b2Fixture = Box2D.Dynamics.b2Fixture; + var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; + var b2Island = Box2D.Dynamics.b2Island; + var b2TimeStep = Box2D.Dynamics.b2TimeStep; + var b2World = Box2D.Dynamics.b2World; + var b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact; + var b2Contact = Box2D.Dynamics.Contacts.b2Contact; + var b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint; + var b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint; + var b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge; + var b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory; + var b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister; + var b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult; + var b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver; + var b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact; + var b2NullContact = Box2D.Dynamics.Contacts.b2NullContact; + var b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact; + var b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact; + var b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact; + var b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold; + var b2Controller = Box2D.Dynamics.Controllers.b2Controller; + var b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge; + var b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint; + var b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef; + var b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint; + var b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef; + var b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint; + var b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef; + var b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian; + var b2Joint = Box2D.Dynamics.Joints.b2Joint; + var b2JointDef = Box2D.Dynamics.Joints.b2JointDef; + var b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge; + var b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint; + var b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef; + var b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint; + var b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef; + var b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint; + var b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef; + var b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint; + var b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef; + var b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint; + var b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef; + var b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint; + var b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef; + var b2internal = Box2D.Common.b2internal; + var b2Body = Box2D.Dynamics.b2Body; + var b2BodyDef = Box2D.Dynamics.b2BodyDef; + var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; + var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; + var b2ContactListener = Box2D.Dynamics.b2ContactListener; + var b2ContactManager = Box2D.Dynamics.b2ContactManager; + var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; + var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; + var b2FilterData = Box2D.Dynamics.b2FilterData; + var b2Fixture = Box2D.Dynamics.b2Fixture; + var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; + var b2Island = Box2D.Dynamics.b2Island; + var b2TimeStep = Box2D.Dynamics.b2TimeStep; + var b2World = Box2D.Dynamics.b2World; + b2Body.b2Body = function () { + this.m_xf = new b2Transform(); + this.m_sweep = new b2Sweep(); + this.m_linearVelocity = new b2Vec2(); + this.m_force = new b2Vec2(); + }; + b2Body.prototype.connectEdges = function (s1, s2, angle1) { + if (angle1 === undefined) angle1 = 0; + var angle2 = Math.atan2(s2.GetDirectionVector().y, s2.GetDirectionVector().x); + var coreOffset = Math.tan((angle2 - angle1) * 0.5); + var core = b2Math.MulFV(coreOffset, s2.GetDirectionVector()); + core = b2Math.SubtractVV(core, s2.GetNormalVector()); + core = b2Math.MulFV(b2Settings.b2_toiSlop, core); + core = b2Math.AddVV(core, s2.GetVertex1()); + var cornerDir = b2Math.AddVV(s1.GetDirectionVector(), s2.GetDirectionVector()); + cornerDir.Normalize(); + var convex = b2Math.Dot(s1.GetDirectionVector(), s2.GetNormalVector()) > 0.0; + s1.SetNextEdge(s2, core, cornerDir, convex); + s2.SetPrevEdge(s1, core, cornerDir, convex); + return angle2; + } + b2Body.prototype.CreateFixture = function (def) { + if (this.m_world.IsLocked() == true) { + return null; + } + var fixture = new b2Fixture(); + fixture.Create(this, this.m_xf, def); + if (this.m_flags & b2Body.e_activeFlag) { + var broadPhase = this.m_world.m_contactManager.m_broadPhase; + fixture.CreateProxy(broadPhase, this.m_xf); + } + fixture.m_next = this.m_fixtureList; + this.m_fixtureList = fixture; + ++this.m_fixtureCount; + fixture.m_body = this; + if (fixture.m_density > 0.0) { + this.ResetMassData(); + } + this.m_world.m_flags |= b2World.e_newFixture; + return fixture; + } + b2Body.prototype.CreateFixture2 = function (shape, density) { + if (density === undefined) density = 0.0; + var def = new b2FixtureDef(); + def.shape = shape; + def.density = density; + return this.CreateFixture(def); + } + b2Body.prototype.DestroyFixture = function (fixture) { + if (this.m_world.IsLocked() == true) { + return; + } + var node = this.m_fixtureList; + var ppF = null; + var found = false; + while (node != null) { + if (node == fixture) { + if (ppF) ppF.m_next = fixture.m_next; + else this.m_fixtureList = fixture.m_next; + found = true; + break; + } + ppF = node; + node = node.m_next; + } + var edge = this.m_contactList; + while (edge) { + var c = edge.contact; + edge = edge.next; + var fixtureA = c.GetFixtureA(); + var fixtureB = c.GetFixtureB(); + if (fixture == fixtureA || fixture == fixtureB) { + this.m_world.m_contactManager.Destroy(c); + } + } + if (this.m_flags & b2Body.e_activeFlag) { + var broadPhase = this.m_world.m_contactManager.m_broadPhase; + fixture.DestroyProxy(broadPhase); + } + else {} + fixture.Destroy(); + fixture.m_body = null; + fixture.m_next = null; + --this.m_fixtureCount; + this.ResetMassData(); + } + b2Body.prototype.SetPositionAndAngle = function (position, angle) { + if (angle === undefined) angle = 0; + var f; + if (this.m_world.IsLocked() == true) { + return; + } + this.m_xf.R.Set(angle); + this.m_xf.position.SetV(position); + var tMat = this.m_xf.R; + var tVec = this.m_sweep.localCenter; + this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + this.m_sweep.c.x += this.m_xf.position.x; + this.m_sweep.c.y += this.m_xf.position.y; + this.m_sweep.c0.SetV(this.m_sweep.c); + this.m_sweep.a0 = this.m_sweep.a = angle; + var broadPhase = this.m_world.m_contactManager.m_broadPhase; + for (f = this.m_fixtureList; + f; f = f.m_next) { + f.Synchronize(broadPhase, this.m_xf, this.m_xf); + } + this.m_world.m_contactManager.FindNewContacts(); + } + b2Body.prototype.SetTransform = function (xf) { + this.SetPositionAndAngle(xf.position, xf.GetAngle()); + } + b2Body.prototype.GetTransform = function () { + return this.m_xf; + } + b2Body.prototype.GetPosition = function () { + return this.m_xf.position; + } + b2Body.prototype.SetPosition = function (position) { + this.SetPositionAndAngle(position, this.GetAngle()); + } + b2Body.prototype.GetAngle = function () { + return this.m_sweep.a; + } + b2Body.prototype.SetAngle = function (angle) { + if (angle === undefined) angle = 0; + this.SetPositionAndAngle(this.GetPosition(), angle); + } + b2Body.prototype.GetWorldCenter = function () { + return this.m_sweep.c; + } + b2Body.prototype.GetLocalCenter = function () { + return this.m_sweep.localCenter; + } + b2Body.prototype.SetLinearVelocity = function (v) { + if (this.m_type == b2Body.b2_staticBody) { + return; + } + this.m_linearVelocity.SetV(v); + } + b2Body.prototype.GetLinearVelocity = function () { + return this.m_linearVelocity; + } + b2Body.prototype.SetAngularVelocity = function (omega) { + if (omega === undefined) omega = 0; + if (this.m_type == b2Body.b2_staticBody) { + return; + } + this.m_angularVelocity = omega; + } + b2Body.prototype.GetAngularVelocity = function () { + return this.m_angularVelocity; + } + b2Body.prototype.GetDefinition = function () { + var bd = new b2BodyDef(); + bd.type = this.GetType(); + bd.allowSleep = (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag; + bd.angle = this.GetAngle(); + bd.angularDamping = this.m_angularDamping; + bd.angularVelocity = this.m_angularVelocity; + bd.fixedRotation = (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag; + bd.bullet = (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag; + bd.awake = (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag; + bd.linearDamping = this.m_linearDamping; + bd.linearVelocity.SetV(this.GetLinearVelocity()); + bd.position = this.GetPosition(); + bd.userData = this.GetUserData(); + return bd; + } + b2Body.prototype.ApplyForce = function (force, point) { + if (this.m_type != b2Body.b2_dynamicBody) { + return; + } + if (this.IsAwake() == false) { + this.SetAwake(true); + } + this.m_force.x += force.x; + this.m_force.y += force.y; + this.m_torque += ((point.x - this.m_sweep.c.x) * force.y - (point.y - this.m_sweep.c.y) * force.x); + } + b2Body.prototype.ApplyTorque = function (torque) { + if (torque === undefined) torque = 0; + if (this.m_type != b2Body.b2_dynamicBody) { + return; + } + if (this.IsAwake() == false) { + this.SetAwake(true); + } + this.m_torque += torque; + } + b2Body.prototype.ApplyImpulse = function (impulse, point) { + if (this.m_type != b2Body.b2_dynamicBody) { + return; + } + if (this.IsAwake() == false) { + this.SetAwake(true); + } + this.m_linearVelocity.x += this.m_invMass * impulse.x; + this.m_linearVelocity.y += this.m_invMass * impulse.y; + this.m_angularVelocity += this.m_invI * ((point.x - this.m_sweep.c.x) * impulse.y - (point.y - this.m_sweep.c.y) * impulse.x); + } + b2Body.prototype.Split = function (callback) { + var linearVelocity = this.GetLinearVelocity().Copy(); + var angularVelocity = this.GetAngularVelocity(); + var center = this.GetWorldCenter(); + var body1 = this; + var body2 = this.m_world.CreateBody(this.GetDefinition()); + var prev; + for (var f = body1.m_fixtureList; f;) { + if (callback(f)) { + var next = f.m_next; + if (prev) { + prev.m_next = next; + } + else { + body1.m_fixtureList = next; + } + body1.m_fixtureCount--; + f.m_next = body2.m_fixtureList; + body2.m_fixtureList = f; + body2.m_fixtureCount++; + f.m_body = body2; + f = next; + } + else { + prev = f; + f = f.m_next; + } + } + body1.ResetMassData(); + body2.ResetMassData(); + var center1 = body1.GetWorldCenter(); + var center2 = body2.GetWorldCenter(); + var velocity1 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center1, center))); + var velocity2 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center2, center))); + body1.SetLinearVelocity(velocity1); + body2.SetLinearVelocity(velocity2); + body1.SetAngularVelocity(angularVelocity); + body2.SetAngularVelocity(angularVelocity); + body1.SynchronizeFixtures(); + body2.SynchronizeFixtures(); + return body2; + } + b2Body.prototype.Merge = function (other) { + var f; + for (f = other.m_fixtureList; + f;) { + var next = f.m_next; + other.m_fixtureCount--; + f.m_next = this.m_fixtureList; + this.m_fixtureList = f; + this.m_fixtureCount++; + f.m_body = body2; + f = next; + } + body1.m_fixtureCount = 0; + var body1 = this; + var body2 = other; + var center1 = body1.GetWorldCenter(); + var center2 = body2.GetWorldCenter(); + var velocity1 = body1.GetLinearVelocity().Copy(); + var velocity2 = body2.GetLinearVelocity().Copy(); + var angular1 = body1.GetAngularVelocity(); + var angular = body2.GetAngularVelocity(); + body1.ResetMassData(); + this.SynchronizeFixtures(); + } + b2Body.prototype.GetMass = function () { + return this.m_mass; + } + b2Body.prototype.GetInertia = function () { + return this.m_I; + } + b2Body.prototype.GetMassData = function (data) { + data.mass = this.m_mass; + data.I = this.m_I; + data.center.SetV(this.m_sweep.localCenter); + } + b2Body.prototype.SetMassData = function (massData) { + b2Settings.b2Assert(this.m_world.IsLocked() == false); + if (this.m_world.IsLocked() == true) { + return; + } + if (this.m_type != b2Body.b2_dynamicBody) { + return; + } + this.m_invMass = 0.0; + this.m_I = 0.0; + this.m_invI = 0.0; + this.m_mass = massData.mass; + if (this.m_mass <= 0.0) { + this.m_mass = 1.0; + } + this.m_invMass = 1.0 / this.m_mass; + if (massData.I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { + this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y); + this.m_invI = 1.0 / this.m_I; + } + var oldCenter = this.m_sweep.c.Copy(); + this.m_sweep.localCenter.SetV(massData.center); + this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); + this.m_sweep.c.SetV(this.m_sweep.c0); + this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y)); + this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x)); + } + b2Body.prototype.ResetMassData = function () { + this.m_mass = 0.0; + this.m_invMass = 0.0; + this.m_I = 0.0; + this.m_invI = 0.0; + this.m_sweep.localCenter.SetZero(); + if (this.m_type == b2Body.b2_staticBody || this.m_type == b2Body.b2_kinematicBody) { + return; + } + var center = b2Vec2.Make(0, 0); + for (var f = this.m_fixtureList; f; f = f.m_next) { + if (f.m_density == 0.0) { + continue; + } + var massData = f.GetMassData(); + this.m_mass += massData.mass; + center.x += massData.center.x * massData.mass; + center.y += massData.center.y * massData.mass; + this.m_I += massData.I; + } + if (this.m_mass > 0.0) { + this.m_invMass = 1.0 / this.m_mass; + center.x *= this.m_invMass; + center.y *= this.m_invMass; + } + else { + this.m_mass = 1.0; + this.m_invMass = 1.0; + } + if (this.m_I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { + this.m_I -= this.m_mass * (center.x * center.x + center.y * center.y); + this.m_I *= this.m_inertiaScale; + b2Settings.b2Assert(this.m_I > 0); + this.m_invI = 1.0 / this.m_I; + } + else { + this.m_I = 0.0; + this.m_invI = 0.0; + } + var oldCenter = this.m_sweep.c.Copy(); + this.m_sweep.localCenter.SetV(center); + this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); + this.m_sweep.c.SetV(this.m_sweep.c0); + this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y)); + this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x)); + } + b2Body.prototype.GetWorldPoint = function (localPoint) { + var A = this.m_xf.R; + var u = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); + u.x += this.m_xf.position.x; + u.y += this.m_xf.position.y; + return u; + } + b2Body.prototype.GetWorldVector = function (localVector) { + return b2Math.MulMV(this.m_xf.R, localVector); + } + b2Body.prototype.GetLocalPoint = function (worldPoint) { + return b2Math.MulXT(this.m_xf, worldPoint); + } + b2Body.prototype.GetLocalVector = function (worldVector) { + return b2Math.MulTMV(this.m_xf.R, worldVector); + } + b2Body.prototype.GetLinearVelocityFromWorldPoint = function (worldPoint) { + return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)); + } + b2Body.prototype.GetLinearVelocityFromLocalPoint = function (localPoint) { + var A = this.m_xf.R; + var worldPoint = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); + worldPoint.x += this.m_xf.position.x; + worldPoint.y += this.m_xf.position.y; + return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)); + } + b2Body.prototype.GetLinearDamping = function () { + return this.m_linearDamping; + } + b2Body.prototype.SetLinearDamping = function (linearDamping) { + if (linearDamping === undefined) linearDamping = 0; + this.m_linearDamping = linearDamping; + } + b2Body.prototype.GetAngularDamping = function () { + return this.m_angularDamping; + } + b2Body.prototype.SetAngularDamping = function (angularDamping) { + if (angularDamping === undefined) angularDamping = 0; + this.m_angularDamping = angularDamping; + } + b2Body.prototype.SetType = function (type) { + if (type === undefined) type = 0; + if (this.m_type == type) { + return; + } + this.m_type = type; + this.ResetMassData(); + if (this.m_type == b2Body.b2_staticBody) { + this.m_linearVelocity.SetZero(); + this.m_angularVelocity = 0.0; + } + this.SetAwake(true); + this.m_force.SetZero(); + this.m_torque = 0.0; + for (var ce = this.m_contactList; ce; ce = ce.next) { + ce.contact.FlagForFiltering(); + } + } + b2Body.prototype.GetType = function () { + return this.m_type; + } + b2Body.prototype.SetBullet = function (flag) { + if (flag) { + this.m_flags |= b2Body.e_bulletFlag; + } + else { + this.m_flags &= ~b2Body.e_bulletFlag; + } + } + b2Body.prototype.IsBullet = function () { + return (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag; + } + b2Body.prototype.SetSleepingAllowed = function (flag) { + if (flag) { + this.m_flags |= b2Body.e_allowSleepFlag; + } + else { + this.m_flags &= ~b2Body.e_allowSleepFlag; + this.SetAwake(true); + } + } + b2Body.prototype.SetAwake = function (flag) { + if (flag) { + this.m_flags |= b2Body.e_awakeFlag; + this.m_sleepTime = 0.0; + } + else { + this.m_flags &= ~b2Body.e_awakeFlag; + this.m_sleepTime = 0.0; + this.m_linearVelocity.SetZero(); + this.m_angularVelocity = 0.0; + this.m_force.SetZero(); + this.m_torque = 0.0; + } + } + b2Body.prototype.IsAwake = function () { + return (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag; + } + b2Body.prototype.SetFixedRotation = function (fixed) { + if (fixed) { + this.m_flags |= b2Body.e_fixedRotationFlag; + } + else { + this.m_flags &= ~b2Body.e_fixedRotationFlag; + } + this.ResetMassData(); + } + b2Body.prototype.IsFixedRotation = function () { + return (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag; + } + b2Body.prototype.SetActive = function (flag) { + if (flag == this.IsActive()) { + return; + } + var broadPhase; + var f; + if (flag) { + this.m_flags |= b2Body.e_activeFlag; + broadPhase = this.m_world.m_contactManager.m_broadPhase; + for (f = this.m_fixtureList; + f; f = f.m_next) { + f.CreateProxy(broadPhase, this.m_xf); + } + } + else { + this.m_flags &= ~b2Body.e_activeFlag; + broadPhase = this.m_world.m_contactManager.m_broadPhase; + for (f = this.m_fixtureList; + f; f = f.m_next) { + f.DestroyProxy(broadPhase); + } + var ce = this.m_contactList; + while (ce) { + var ce0 = ce; + ce = ce.next; + this.m_world.m_contactManager.Destroy(ce0.contact); + } + this.m_contactList = null; + } + } + b2Body.prototype.IsActive = function () { + return (this.m_flags & b2Body.e_activeFlag) == b2Body.e_activeFlag; + } + b2Body.prototype.IsSleepingAllowed = function () { + return (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag; + } + b2Body.prototype.GetFixtureList = function () { + return this.m_fixtureList; + } + b2Body.prototype.GetJointList = function () { + return this.m_jointList; + } + b2Body.prototype.GetControllerList = function () { + return this.m_controllerList; + } + b2Body.prototype.GetContactList = function () { + return this.m_contactList; + } + b2Body.prototype.GetNext = function () { + return this.m_next; + } + b2Body.prototype.GetUserData = function () { + return this.m_userData; + } + b2Body.prototype.SetUserData = function (data) { + this.m_userData = data; + } + b2Body.prototype.GetWorld = function () { + return this.m_world; + } + b2Body.prototype.b2Body = function (bd, world) { + this.m_flags = 0; + if (bd.bullet) { + this.m_flags |= b2Body.e_bulletFlag; + } + if (bd.fixedRotation) { + this.m_flags |= b2Body.e_fixedRotationFlag; + } + if (bd.allowSleep) { + this.m_flags |= b2Body.e_allowSleepFlag; + } + if (bd.awake) { + this.m_flags |= b2Body.e_awakeFlag; + } + if (bd.active) { + this.m_flags |= b2Body.e_activeFlag; + } + this.m_world = world; + this.m_xf.position.SetV(bd.position); + this.m_xf.R.Set(bd.angle); + this.m_sweep.localCenter.SetZero(); + this.m_sweep.t0 = 1.0; + this.m_sweep.a0 = this.m_sweep.a = bd.angle; + var tMat = this.m_xf.R; + var tVec = this.m_sweep.localCenter; + this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + this.m_sweep.c.x += this.m_xf.position.x; + this.m_sweep.c.y += this.m_xf.position.y; + this.m_sweep.c0.SetV(this.m_sweep.c); + this.m_jointList = null; + this.m_controllerList = null; + this.m_contactList = null; + this.m_controllerCount = 0; + this.m_prev = null; + this.m_next = null; + this.m_linearVelocity.SetV(bd.linearVelocity); + this.m_angularVelocity = bd.angularVelocity; + this.m_linearDamping = bd.linearDamping; + this.m_angularDamping = bd.angularDamping; + this.m_force.Set(0.0, 0.0); + this.m_torque = 0.0; + this.m_sleepTime = 0.0; + this.m_type = bd.type; + if (this.m_type == b2Body.b2_dynamicBody) { + this.m_mass = 1.0; + this.m_invMass = 1.0; + } + else { + this.m_mass = 0.0; + this.m_invMass = 0.0; + } + this.m_I = 0.0; + this.m_invI = 0.0; + this.m_inertiaScale = bd.inertiaScale; + this.m_userData = bd.userData; + this.m_fixtureList = null; + this.m_fixtureCount = 0; + } + b2Body.prototype.SynchronizeFixtures = function () { + var xf1 = b2Body.s_xf1; + xf1.R.Set(this.m_sweep.a0); + var tMat = xf1.R; + var tVec = this.m_sweep.localCenter; + xf1.position.x = this.m_sweep.c0.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + xf1.position.y = this.m_sweep.c0.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var f; + var broadPhase = this.m_world.m_contactManager.m_broadPhase; + for (f = this.m_fixtureList; + f; f = f.m_next) { + f.Synchronize(broadPhase, xf1, this.m_xf); + } + } + b2Body.prototype.SynchronizeTransform = function () { + this.m_xf.R.Set(this.m_sweep.a); + var tMat = this.m_xf.R; + var tVec = this.m_sweep.localCenter; + this.m_xf.position.x = this.m_sweep.c.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + this.m_xf.position.y = this.m_sweep.c.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + } + b2Body.prototype.ShouldCollide = function (other) { + if (this.m_type != b2Body.b2_dynamicBody && other.m_type != b2Body.b2_dynamicBody) { + return false; + } + for (var jn = this.m_jointList; jn; jn = jn.next) { + if (jn.other == other) if (jn.joint.m_collideConnected == false) { + return false; + } + } + return true; + } + b2Body.prototype.Advance = function (t) { + if (t === undefined) t = 0; + this.m_sweep.Advance(t); + this.m_sweep.c.SetV(this.m_sweep.c0); + this.m_sweep.a = this.m_sweep.a0; + this.SynchronizeTransform(); + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.b2Body.s_xf1 = new b2Transform(); + Box2D.Dynamics.b2Body.prototype.s_xf1 = Box2D.Dynamics.b2Body.s_xf1; + Box2D.Dynamics.b2Body.e_islandFlag = 0x0001; + Box2D.Dynamics.b2Body.prototype.e_islandFlag = Box2D.Dynamics.b2Body.e_islandFlag; + Box2D.Dynamics.b2Body.e_awakeFlag = 0x0002; + Box2D.Dynamics.b2Body.prototype.e_awakeFlag = Box2D.Dynamics.b2Body.e_awakeFlag; + Box2D.Dynamics.b2Body.e_allowSleepFlag = 0x0004; + Box2D.Dynamics.b2Body.prototype.e_allowSleepFlag = Box2D.Dynamics.b2Body.e_allowSleepFlag; + Box2D.Dynamics.b2Body.e_bulletFlag = 0x0008; + Box2D.Dynamics.b2Body.prototype.e_bulletFlag = Box2D.Dynamics.b2Body.e_bulletFlag; + Box2D.Dynamics.b2Body.e_fixedRotationFlag = 0x0010; + Box2D.Dynamics.b2Body.prototype.e_fixedRotationFlag = Box2D.Dynamics.b2Body.e_fixedRotationFlag; + Box2D.Dynamics.b2Body.e_activeFlag = 0x0020; + Box2D.Dynamics.b2Body.prototype.e_activeFlag = Box2D.Dynamics.b2Body.e_activeFlag; + Box2D.Dynamics.b2Body.b2_staticBody = 0; + Box2D.Dynamics.b2Body.prototype.b2_staticBody = Box2D.Dynamics.b2Body.b2_staticBody; + Box2D.Dynamics.b2Body.b2_kinematicBody = 1; + Box2D.Dynamics.b2Body.prototype.b2_kinematicBody = Box2D.Dynamics.b2Body.b2_kinematicBody; + Box2D.Dynamics.b2Body.b2_dynamicBody = 2; + Box2D.Dynamics.b2Body.prototype.b2_dynamicBody = Box2D.Dynamics.b2Body.b2_dynamicBody; + }); + b2BodyDef.b2BodyDef = function () { + this.position = new b2Vec2(); + this.linearVelocity = new b2Vec2(); + }; + b2BodyDef.prototype.b2BodyDef = function () { + this.userData = null; + this.position.Set(0.0, 0.0); + this.angle = 0.0; + this.linearVelocity.Set(0, 0); + this.angularVelocity = 0.0; + this.linearDamping = 0.0; + this.angularDamping = 0.0; + this.allowSleep = true; + this.awake = true; + this.fixedRotation = false; + this.bullet = false; + this.type = b2Body.b2_staticBody; + this.active = true; + this.inertiaScale = 1.0; + } + b2ContactFilter.b2ContactFilter = function () {}; + b2ContactFilter.prototype.ShouldCollide = function (fixtureA, fixtureB) { + var filter1 = fixtureA.GetFilterData(); + var filter2 = fixtureB.GetFilterData(); + if (filter1.groupIndex == filter2.groupIndex && filter1.groupIndex != 0) { + return filter1.groupIndex > 0; + } + var collide = (filter1.maskBits & filter2.categoryBits) != 0 && (filter1.categoryBits & filter2.maskBits) != 0; + return collide; + } + b2ContactFilter.prototype.RayCollide = function (userData, fixture) { + if (!userData) return true; + return this.ShouldCollide((userData instanceof b2Fixture ? userData : null), fixture); + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.b2ContactFilter.b2_defaultFilter = new b2ContactFilter(); + Box2D.Dynamics.b2ContactFilter.prototype.b2_defaultFilter = Box2D.Dynamics.b2ContactFilter.b2_defaultFilter; + }); + b2ContactImpulse.b2ContactImpulse = function () { + this.normalImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); + this.tangentImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); + }; + b2ContactListener.b2ContactListener = function () {}; + b2ContactListener.prototype.BeginContact = function (contact) {} + b2ContactListener.prototype.EndContact = function (contact) {} + b2ContactListener.prototype.PreSolve = function (contact, oldManifold) {} + b2ContactListener.prototype.PostSolve = function (contact, impulse) {} + _A2J_postDefs.push(function () { + Box2D.Dynamics.b2ContactListener.b2_defaultListener = new b2ContactListener(); + Box2D.Dynamics.b2ContactListener.prototype.b2_defaultListener = Box2D.Dynamics.b2ContactListener.b2_defaultListener; + }); + b2ContactManager.b2ContactManager = function () {}; + b2ContactManager.prototype.b2ContactManager = function () { + this.m_world = null; + this.m_contactCount = 0; + this.m_contactFilter = b2ContactFilter.b2_defaultFilter; + this.m_contactListener = b2ContactListener.b2_defaultListener; + this.m_contactFactory = new b2ContactFactory(this.m_allocator); + this.m_broadPhase = new b2DynamicTreeBroadPhase(); + } + b2ContactManager.prototype.AddPair = function (proxyUserDataA, proxyUserDataB) { + var fixtureA = (proxyUserDataA instanceof b2Fixture ? proxyUserDataA : null); + var fixtureB = (proxyUserDataB instanceof b2Fixture ? proxyUserDataB : null); + var bodyA = fixtureA.GetBody(); + var bodyB = fixtureB.GetBody(); + if (bodyA == bodyB) return; + var edge = bodyB.GetContactList(); + while (edge) { + if (edge.other == bodyA) { + var fA = edge.contact.GetFixtureA(); + var fB = edge.contact.GetFixtureB(); + if (fA == fixtureA && fB == fixtureB) return; + if (fA == fixtureB && fB == fixtureA) return; + } + edge = edge.next; + } + if (bodyB.ShouldCollide(bodyA) == false) { + return; + } + if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { + return; + } + var c = this.m_contactFactory.Create(fixtureA, fixtureB); + fixtureA = c.GetFixtureA(); + fixtureB = c.GetFixtureB(); + bodyA = fixtureA.m_body; + bodyB = fixtureB.m_body; + c.m_prev = null; + c.m_next = this.m_world.m_contactList; + if (this.m_world.m_contactList != null) { + this.m_world.m_contactList.m_prev = c; + } + this.m_world.m_contactList = c; + c.m_nodeA.contact = c; + c.m_nodeA.other = bodyB; + c.m_nodeA.prev = null; + c.m_nodeA.next = bodyA.m_contactList; + if (bodyA.m_contactList != null) { + bodyA.m_contactList.prev = c.m_nodeA; + } + bodyA.m_contactList = c.m_nodeA; + c.m_nodeB.contact = c; + c.m_nodeB.other = bodyA; + c.m_nodeB.prev = null; + c.m_nodeB.next = bodyB.m_contactList; + if (bodyB.m_contactList != null) { + bodyB.m_contactList.prev = c.m_nodeB; + } + bodyB.m_contactList = c.m_nodeB; + ++this.m_world.m_contactCount; + return; + } + b2ContactManager.prototype.FindNewContacts = function () { + this.m_broadPhase.UpdatePairs(a2j.generateCallback(this, this.AddPair)); + } + b2ContactManager.prototype.Destroy = function (c) { + var fixtureA = c.GetFixtureA(); + var fixtureB = c.GetFixtureB(); + var bodyA = fixtureA.GetBody(); + var bodyB = fixtureB.GetBody(); + if (c.IsTouching()) { + this.m_contactListener.EndContact(c); + } + if (c.m_prev) { + c.m_prev.m_next = c.m_next; + } + if (c.m_next) { + c.m_next.m_prev = c.m_prev; + } + if (c == this.m_world.m_contactList) { + this.m_world.m_contactList = c.m_next; + } + if (c.m_nodeA.prev) { + c.m_nodeA.prev.next = c.m_nodeA.next; + } + if (c.m_nodeA.next) { + c.m_nodeA.next.prev = c.m_nodeA.prev; + } + if (c.m_nodeA == bodyA.m_contactList) { + bodyA.m_contactList = c.m_nodeA.next; + } + if (c.m_nodeB.prev) { + c.m_nodeB.prev.next = c.m_nodeB.next; + } + if (c.m_nodeB.next) { + c.m_nodeB.next.prev = c.m_nodeB.prev; + } + if (c.m_nodeB == bodyB.m_contactList) { + bodyB.m_contactList = c.m_nodeB.next; + } + this.m_contactFactory.Destroy(c); + --this.m_contactCount; + } + b2ContactManager.prototype.Collide = function () { + var c = this.m_world.m_contactList; + while (c) { + var fixtureA = c.GetFixtureA(); + var fixtureB = c.GetFixtureB(); + var bodyA = fixtureA.GetBody(); + var bodyB = fixtureB.GetBody(); + if (bodyA.IsAwake() == false && bodyB.IsAwake() == false) { + c = c.GetNext(); + continue; + } + if (c.m_flags & b2Contact.e_filterFlag) { + if (bodyB.ShouldCollide(bodyA) == false) { + var cNuke = c; + c = cNuke.GetNext(); + this.Destroy(cNuke); + continue; + } + if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { + cNuke = c; + c = cNuke.GetNext(); + this.Destroy(cNuke); + continue; + } + c.m_flags &= ~b2Contact.e_filterFlag; + } + var proxyA = fixtureA.m_proxy; + var proxyB = fixtureB.m_proxy; + var overlap = this.m_broadPhase.TestOverlap(proxyA, proxyB); + if (overlap == false) { + cNuke = c; + c = cNuke.GetNext(); + this.Destroy(cNuke); + continue; + } + c.Update(this.m_contactListener); + c = c.GetNext(); + } + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.b2ContactManager.s_evalCP = new b2ContactPoint(); + Box2D.Dynamics.b2ContactManager.prototype.s_evalCP = Box2D.Dynamics.b2ContactManager.s_evalCP; + }); + b2DebugDraw.b2DebugDraw = function () {}; + b2DebugDraw.prototype.b2DebugDraw = function () { + m_drawFlags = 0; + } + b2DebugDraw.prototype.SetFlags = function (flags) { + if (flags === undefined) flags = 0; + } + b2DebugDraw.prototype.GetFlags = function () {} + b2DebugDraw.prototype.AppendFlags = function (flags) { + if (flags === undefined) flags = 0; + } + b2DebugDraw.prototype.ClearFlags = function (flags) { + if (flags === undefined) flags = 0; + } + b2DebugDraw.prototype.SetSprite = function (sprite) {} + b2DebugDraw.prototype.GetSprite = function () {} + b2DebugDraw.prototype.SetDrawScale = function (drawScale) { + if (drawScale === undefined) drawScale = 0; + } + b2DebugDraw.prototype.GetDrawScale = function () {} + b2DebugDraw.prototype.SetLineThickness = function (lineThickness) { + if (lineThickness === undefined) lineThickness = 0; + } + b2DebugDraw.prototype.GetLineThickness = function () {} + b2DebugDraw.prototype.SetAlpha = function (alpha) { + if (alpha === undefined) alpha = 0; + } + b2DebugDraw.prototype.GetAlpha = function () {} + b2DebugDraw.prototype.SetFillAlpha = function (alpha) { + if (alpha === undefined) alpha = 0; + } + b2DebugDraw.prototype.GetFillAlpha = function () {} + b2DebugDraw.prototype.SetXFormScale = function (xformScale) { + if (xformScale === undefined) xformScale = 0; + } + b2DebugDraw.prototype.GetXFormScale = function () {} + b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) { + if (vertexCount === undefined) vertexCount = 0; + } + b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) { + if (vertexCount === undefined) vertexCount = 0; + } + b2DebugDraw.prototype.DrawCircle = function (center, radius, color) { + if (radius === undefined) radius = 0; + } + b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) { + if (radius === undefined) radius = 0; + } + b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) {} + b2DebugDraw.prototype.DrawTransform = function (xf) {} + _A2J_postDefs.push(function () { + Box2D.Dynamics.b2DebugDraw.e_shapeBit = 0x0001; + Box2D.Dynamics.b2DebugDraw.prototype.e_shapeBit = Box2D.Dynamics.b2DebugDraw.e_shapeBit; + Box2D.Dynamics.b2DebugDraw.e_jointBit = 0x0002; + Box2D.Dynamics.b2DebugDraw.prototype.e_jointBit = Box2D.Dynamics.b2DebugDraw.e_jointBit; + Box2D.Dynamics.b2DebugDraw.e_aabbBit = 0x0004; + Box2D.Dynamics.b2DebugDraw.prototype.e_aabbBit = Box2D.Dynamics.b2DebugDraw.e_aabbBit; + Box2D.Dynamics.b2DebugDraw.e_pairBit = 0x0008; + Box2D.Dynamics.b2DebugDraw.prototype.e_pairBit = Box2D.Dynamics.b2DebugDraw.e_pairBit; + Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit = 0x0010; + Box2D.Dynamics.b2DebugDraw.prototype.e_centerOfMassBit = Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit; + Box2D.Dynamics.b2DebugDraw.e_controllerBit = 0x0020; + Box2D.Dynamics.b2DebugDraw.prototype.e_controllerBit = Box2D.Dynamics.b2DebugDraw.e_controllerBit; + }); + b2DestructionListener.b2DestructionListener = function () {}; + b2DestructionListener.prototype.SayGoodbyeJoint = function (joint) {} + b2DestructionListener.prototype.SayGoodbyeFixture = function (fixture) {} + b2FilterData.b2FilterData = function () { + this.categoryBits = 0x0001; + this.maskBits = 0xFFFF; + this.groupIndex = 0; + }; + b2FilterData.prototype.Copy = function () { + var copy = new b2FilterData(); + copy.categoryBits = this.categoryBits; + copy.maskBits = this.maskBits; + copy.groupIndex = this.groupIndex; + return copy; + } + b2Fixture.b2Fixture = function () { + this.m_filter = new b2FilterData(); + }; + b2Fixture.prototype.GetType = function () { + return this.m_shape.GetType(); + } + b2Fixture.prototype.GetShape = function () { + return this.m_shape; + } + b2Fixture.prototype.SetSensor = function (sensor) { + if (this.m_isSensor == sensor) return; + this.m_isSensor = sensor; + if (this.m_body == null) return; + var edge = this.m_body.GetContactList(); + while (edge) { + var contact = edge.contact; + var fixtureA = contact.GetFixtureA(); + var fixtureB = contact.GetFixtureB(); + if (fixtureA == this || fixtureB == this) contact.SetSensor(fixtureA.IsSensor() || fixtureB.IsSensor()); + edge = edge.next; + } + } + b2Fixture.prototype.IsSensor = function () { + return this.m_isSensor; + } + b2Fixture.prototype.SetFilterData = function (filter) { + this.m_filter = filter.Copy(); + if (this.m_body) return; + var edge = this.m_body.GetContactList(); + while (edge) { + var contact = edge.contact; + var fixtureA = contact.GetFixtureA(); + var fixtureB = contact.GetFixtureB(); + if (fixtureA == this || fixtureB == this) contact.FlagForFiltering(); + edge = edge.next; + } + } + b2Fixture.prototype.GetFilterData = function () { + return this.m_filter.Copy(); + } + b2Fixture.prototype.GetBody = function () { + return this.m_body; + } + b2Fixture.prototype.GetNext = function () { + return this.m_next; + } + b2Fixture.prototype.GetUserData = function () { + return this.m_userData; + } + b2Fixture.prototype.SetUserData = function (data) { + this.m_userData = data; + } + b2Fixture.prototype.TestPoint = function (p) { + return this.m_shape.TestPoint(this.m_body.GetTransform(), p); + } + b2Fixture.prototype.RayCast = function (output, input) { + return this.m_shape.RayCast(output, input, this.m_body.GetTransform()); + } + b2Fixture.prototype.GetMassData = function (massData) { + if (massData === undefined) massData = null; + if (massData == null) { + massData = new b2MassData(); + } + this.m_shape.ComputeMass(massData, this.m_density); + return massData; + } + b2Fixture.prototype.SetDensity = function (density) { + if (density === undefined) density = 0; + this.m_density = density; + } + b2Fixture.prototype.GetDensity = function () { + return this.m_density; + } + b2Fixture.prototype.GetFriction = function () { + return this.m_friction; + } + b2Fixture.prototype.SetFriction = function (friction) { + if (friction === undefined) friction = 0; + this.m_friction = friction; + } + b2Fixture.prototype.GetRestitution = function () { + return this.m_restitution; + } + b2Fixture.prototype.SetRestitution = function (restitution) { + if (restitution === undefined) restitution = 0; + this.m_restitution = restitution; + } + b2Fixture.prototype.GetAABB = function () { + return this.m_aabb; + } + b2Fixture.prototype.b2Fixture = function () { + this.m_aabb = new b2AABB(); + this.m_userData = null; + this.m_body = null; + this.m_next = null; + this.m_shape = null; + this.m_density = 0.0; + this.m_friction = 0.0; + this.m_restitution = 0.0; + } + b2Fixture.prototype.Create = function (body, xf, def) { + this.m_userData = def.userData; + this.m_friction = def.friction; + this.m_restitution = def.restitution; + this.m_body = body; + this.m_next = null; + this.m_filter = def.filter.Copy(); + this.m_isSensor = def.isSensor; + this.m_shape = def.shape.Copy(); + this.m_density = def.density; + } + b2Fixture.prototype.Destroy = function () { + this.m_shape = null; + } + b2Fixture.prototype.CreateProxy = function (broadPhase, xf) { + this.m_shape.ComputeAABB(this.m_aabb, xf); + this.m_proxy = broadPhase.CreateProxy(this.m_aabb, this); + } + b2Fixture.prototype.DestroyProxy = function (broadPhase) { + if (this.m_proxy == null) { + return; + } + broadPhase.DestroyProxy(this.m_proxy); + this.m_proxy = null; + } + b2Fixture.prototype.Synchronize = function (broadPhase, transform1, transform2) { + if (!this.m_proxy) return; + var aabb1 = new b2AABB(); + var aabb2 = new b2AABB(); + this.m_shape.ComputeAABB(aabb1, transform1); + this.m_shape.ComputeAABB(aabb2, transform2); + this.m_aabb.Combine(aabb1, aabb2); + var displacement = b2Math.SubtractVV(transform2.position, transform1.position); + broadPhase.MoveProxy(this.m_proxy, this.m_aabb, displacement); + } + b2FixtureDef.b2FixtureDef = function () { + this.filter = new b2FilterData(); + }; + b2FixtureDef.prototype.b2FixtureDef = function () { + this.shape = null; + this.userData = null; + this.friction = 0.2; + this.restitution = 0.0; + this.density = 0.0; + this.filter.categoryBits = 0x0001; + this.filter.maskBits = 0xFFFF; + this.filter.groupIndex = 0; + this.isSensor = false; + } + b2Island.b2Island = function () {}; + b2Island.prototype.b2Island = function () { + this.m_bodies = new Vector(); + this.m_contacts = new Vector(); + this.m_joints = new Vector(); + } + b2Island.prototype.Initialize = function (bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) { + if (bodyCapacity === undefined) bodyCapacity = 0; + if (contactCapacity === undefined) contactCapacity = 0; + if (jointCapacity === undefined) jointCapacity = 0; + var i = 0; + this.m_bodyCapacity = bodyCapacity; + this.m_contactCapacity = contactCapacity; + this.m_jointCapacity = jointCapacity; + this.m_bodyCount = 0; + this.m_contactCount = 0; + this.m_jointCount = 0; + this.m_allocator = allocator; + this.m_listener = listener; + this.m_contactSolver = contactSolver; + for (i = this.m_bodies.length; + i < bodyCapacity; i++) + this.m_bodies[i] = null; + for (i = this.m_contacts.length; + i < contactCapacity; i++) + this.m_contacts[i] = null; + for (i = this.m_joints.length; + i < jointCapacity; i++) + this.m_joints[i] = null; + } + b2Island.prototype.Clear = function () { + this.m_bodyCount = 0; + this.m_contactCount = 0; + this.m_jointCount = 0; + } + b2Island.prototype.Solve = function (step, gravity, allowSleep) { + var i = 0; + var j = 0; + var b; + var joint; + for (i = 0; + i < this.m_bodyCount; ++i) { + b = this.m_bodies[i]; + if (b.GetType() != b2Body.b2_dynamicBody) continue; + b.m_linearVelocity.x += step.dt * (gravity.x + b.m_invMass * b.m_force.x); + b.m_linearVelocity.y += step.dt * (gravity.y + b.m_invMass * b.m_force.y); + b.m_angularVelocity += step.dt * b.m_invI * b.m_torque; + b.m_linearVelocity.Multiply(b2Math.Clamp(1.0 - step.dt * b.m_linearDamping, 0.0, 1.0)); + b.m_angularVelocity *= b2Math.Clamp(1.0 - step.dt * b.m_angularDamping, 0.0, 1.0); + } + this.m_contactSolver.Initialize(step, this.m_contacts, this.m_contactCount, this.m_allocator); + var contactSolver = this.m_contactSolver; + contactSolver.InitVelocityConstraints(step); + for (i = 0; + i < this.m_jointCount; ++i) { + joint = this.m_joints[i]; + joint.InitVelocityConstraints(step); + } + for (i = 0; + i < step.velocityIterations; ++i) { + for (j = 0; + j < this.m_jointCount; ++j) { + joint = this.m_joints[j]; + joint.SolveVelocityConstraints(step); + } + contactSolver.SolveVelocityConstraints(); + } + for (i = 0; + i < this.m_jointCount; ++i) { + joint = this.m_joints[i]; + joint.FinalizeVelocityConstraints(); + } + contactSolver.FinalizeVelocityConstraints(); + for (i = 0; + i < this.m_bodyCount; ++i) { + b = this.m_bodies[i]; + if (b.GetType() == b2Body.b2_staticBody) continue; + var translationX = step.dt * b.m_linearVelocity.x; + var translationY = step.dt * b.m_linearVelocity.y; + if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) { + b.m_linearVelocity.Normalize(); + b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * step.inv_dt; + b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * step.inv_dt; + } + var rotation = step.dt * b.m_angularVelocity; + if (rotation * rotation > b2Settings.b2_maxRotationSquared) { + if (b.m_angularVelocity < 0.0) { + b.m_angularVelocity = (-b2Settings.b2_maxRotation * step.inv_dt); + } + else { + b.m_angularVelocity = b2Settings.b2_maxRotation * step.inv_dt; + } + } + b.m_sweep.c0.SetV(b.m_sweep.c); + b.m_sweep.a0 = b.m_sweep.a; + b.m_sweep.c.x += step.dt * b.m_linearVelocity.x; + b.m_sweep.c.y += step.dt * b.m_linearVelocity.y; + b.m_sweep.a += step.dt * b.m_angularVelocity; + b.SynchronizeTransform(); + } + for (i = 0; + i < step.positionIterations; ++i) { + var contactsOkay = contactSolver.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); + var jointsOkay = true; + for (j = 0; + j < this.m_jointCount; ++j) { + joint = this.m_joints[j]; + var jointOkay = joint.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); + jointsOkay = jointsOkay && jointOkay; + } + if (contactsOkay && jointsOkay) { + break; + } + } + this.Report(contactSolver.m_constraints); + if (allowSleep) { + var minSleepTime = Number.MAX_VALUE; + var linTolSqr = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance; + var angTolSqr = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance; + for (i = 0; + i < this.m_bodyCount; ++i) { + b = this.m_bodies[i]; + if (b.GetType() == b2Body.b2_staticBody) { + continue; + } + if ((b.m_flags & b2Body.e_allowSleepFlag) == 0) { + b.m_sleepTime = 0.0; + minSleepTime = 0.0; + } + if ((b.m_flags & b2Body.e_allowSleepFlag) == 0 || b.m_angularVelocity * b.m_angularVelocity > angTolSqr || b2Math.Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr) { + b.m_sleepTime = 0.0; + minSleepTime = 0.0; + } + else { + b.m_sleepTime += step.dt; + minSleepTime = b2Math.Min(minSleepTime, b.m_sleepTime); + } + } + if (minSleepTime >= b2Settings.b2_timeToSleep) { + for (i = 0; + i < this.m_bodyCount; ++i) { + b = this.m_bodies[i]; + b.SetAwake(false); + } + } + } + } + b2Island.prototype.SolveTOI = function (subStep) { + var i = 0; + var j = 0; + this.m_contactSolver.Initialize(subStep, this.m_contacts, this.m_contactCount, this.m_allocator); + var contactSolver = this.m_contactSolver; + for (i = 0; + i < this.m_jointCount; ++i) { + this.m_joints[i].InitVelocityConstraints(subStep); + } + for (i = 0; + i < subStep.velocityIterations; ++i) { + contactSolver.SolveVelocityConstraints(); + for (j = 0; + j < this.m_jointCount; ++j) { + this.m_joints[j].SolveVelocityConstraints(subStep); + } + } + for (i = 0; + i < this.m_bodyCount; ++i) { + var b = this.m_bodies[i]; + if (b.GetType() == b2Body.b2_staticBody) continue; + var translationX = subStep.dt * b.m_linearVelocity.x; + var translationY = subStep.dt * b.m_linearVelocity.y; + if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) { + b.m_linearVelocity.Normalize(); + b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * subStep.inv_dt; + b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * subStep.inv_dt; + } + var rotation = subStep.dt * b.m_angularVelocity; + if (rotation * rotation > b2Settings.b2_maxRotationSquared) { + if (b.m_angularVelocity < 0.0) { + b.m_angularVelocity = (-b2Settings.b2_maxRotation * subStep.inv_dt); + } + else { + b.m_angularVelocity = b2Settings.b2_maxRotation * subStep.inv_dt; + } + } + b.m_sweep.c0.SetV(b.m_sweep.c); + b.m_sweep.a0 = b.m_sweep.a; + b.m_sweep.c.x += subStep.dt * b.m_linearVelocity.x; + b.m_sweep.c.y += subStep.dt * b.m_linearVelocity.y; + b.m_sweep.a += subStep.dt * b.m_angularVelocity; + b.SynchronizeTransform(); + } + var k_toiBaumgarte = 0.75; + for (i = 0; + i < subStep.positionIterations; ++i) { + var contactsOkay = contactSolver.SolvePositionConstraints(k_toiBaumgarte); + var jointsOkay = true; + for (j = 0; + j < this.m_jointCount; ++j) { + var jointOkay = this.m_joints[j].SolvePositionConstraints(b2Settings.b2_contactBaumgarte); + jointsOkay = jointsOkay && jointOkay; + } + if (contactsOkay && jointsOkay) { + break; + } + } + this.Report(contactSolver.m_constraints); + } + b2Island.prototype.Report = function (constraints) { + if (this.m_listener == null) { + return; + } + for (var i = 0; i < this.m_contactCount; ++i) { + var c = this.m_contacts[i]; + var cc = constraints[i]; + for (var j = 0; j < cc.pointCount; ++j) { + b2Island.s_impulse.normalImpulses[j] = cc.points[j].normalImpulse; + b2Island.s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse; + } + this.m_listener.PostSolve(c, b2Island.s_impulse); + } + } + b2Island.prototype.AddBody = function (body) { + body.m_islandIndex = this.m_bodyCount; + this.m_bodies[this.m_bodyCount++] = body; + } + b2Island.prototype.AddContact = function (contact) { + this.m_contacts[this.m_contactCount++] = contact; + } + b2Island.prototype.AddJoint = function (joint) { + this.m_joints[this.m_jointCount++] = joint; + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.b2Island.s_impulse = new b2ContactImpulse(); + Box2D.Dynamics.b2Island.prototype.s_impulse = Box2D.Dynamics.b2Island.s_impulse; + }); + b2TimeStep.b2TimeStep = function () {}; + b2TimeStep.prototype.Set = function (step) { + this.dt = step.dt; + this.inv_dt = step.inv_dt; + this.positionIterations = step.positionIterations; + this.velocityIterations = step.velocityIterations; + this.warmStarting = step.warmStarting; + } + b2World.b2World = function () { + this.s_stack = new Vector(); + this.m_contactManager = new b2ContactManager(); + this.m_contactSolver = new b2ContactSolver(); + this.m_island = new b2Island(); + }; + b2World.prototype.b2World = function (gravity, doSleep) { + this.m_destructionListener = null; + this.m_debugDraw = null; + this.m_bodyList = null; + this.m_contactList = null; + this.m_jointList = null; + this.m_controllerList = null; + this.m_bodyCount = 0; + this.m_contactCount = 0; + this.m_jointCount = 0; + this.m_controllerCount = 0; + b2World.m_warmStarting = true; + b2World.m_continuousPhysics = true; + this.m_allowSleep = doSleep; + this.m_gravity = gravity; + this.m_inv_dt0 = 0.0; + this.m_contactManager.m_world = this; + var bd = new b2BodyDef(); + this.m_groundBody = this.CreateBody(bd); + } + b2World.prototype.SetDestructionListener = function (listener) { + this.m_destructionListener = listener; + } + b2World.prototype.SetContactFilter = function (filter) { + this.m_contactManager.m_contactFilter = filter; + } + b2World.prototype.SetContactListener = function (listener) { + this.m_contactManager.m_contactListener = listener; + } + b2World.prototype.SetDebugDraw = function (debugDraw) { + this.m_debugDraw = debugDraw; + } + b2World.prototype.SetBroadPhase = function (broadPhase) { + var oldBroadPhase = this.m_contactManager.m_broadPhase; + this.m_contactManager.m_broadPhase = broadPhase; + for (var b = this.m_bodyList; b; b = b.m_next) { + for (var f = b.m_fixtureList; f; f = f.m_next) { + f.m_proxy = broadPhase.CreateProxy(oldBroadPhase.GetFatAABB(f.m_proxy), f); + } + } + } + b2World.prototype.Validate = function () { + this.m_contactManager.m_broadPhase.Validate(); + } + b2World.prototype.GetProxyCount = function () { + return this.m_contactManager.m_broadPhase.GetProxyCount(); + } + b2World.prototype.CreateBody = function (def) { + if (this.IsLocked() == true) { + return null; + } + var b = new b2Body(def, this); + b.m_prev = null; + b.m_next = this.m_bodyList; + if (this.m_bodyList) { + this.m_bodyList.m_prev = b; + } + this.m_bodyList = b; + ++this.m_bodyCount; + return b; + } + b2World.prototype.DestroyBody = function (b) { + if (this.IsLocked() == true) { + return; + } + var jn = b.m_jointList; + while (jn) { + var jn0 = jn; + jn = jn.next; + if (this.m_destructionListener) { + this.m_destructionListener.SayGoodbyeJoint(jn0.joint); + } + this.DestroyJoint(jn0.joint); + } + var coe = b.m_controllerList; + while (coe) { + var coe0 = coe; + coe = coe.nextController; + coe0.controller.RemoveBody(b); + } + var ce = b.m_contactList; + while (ce) { + var ce0 = ce; + ce = ce.next; + this.m_contactManager.Destroy(ce0.contact); + } + b.m_contactList = null; + var f = b.m_fixtureList; + while (f) { + var f0 = f; + f = f.m_next; + if (this.m_destructionListener) { + this.m_destructionListener.SayGoodbyeFixture(f0); + } + f0.DestroyProxy(this.m_contactManager.m_broadPhase); + f0.Destroy(); + } + b.m_fixtureList = null; + b.m_fixtureCount = 0; + if (b.m_prev) { + b.m_prev.m_next = b.m_next; + } + if (b.m_next) { + b.m_next.m_prev = b.m_prev; + } + if (b == this.m_bodyList) { + this.m_bodyList = b.m_next; + }--this.m_bodyCount; + } + b2World.prototype.CreateJoint = function (def) { + var j = b2Joint.Create(def, null); + j.m_prev = null; + j.m_next = this.m_jointList; + if (this.m_jointList) { + this.m_jointList.m_prev = j; + } + this.m_jointList = j; + ++this.m_jointCount; + j.m_edgeA.joint = j; + j.m_edgeA.other = j.m_bodyB; + j.m_edgeA.prev = null; + j.m_edgeA.next = j.m_bodyA.m_jointList; + if (j.m_bodyA.m_jointList) j.m_bodyA.m_jointList.prev = j.m_edgeA; + j.m_bodyA.m_jointList = j.m_edgeA; + j.m_edgeB.joint = j; + j.m_edgeB.other = j.m_bodyA; + j.m_edgeB.prev = null; + j.m_edgeB.next = j.m_bodyB.m_jointList; + if (j.m_bodyB.m_jointList) j.m_bodyB.m_jointList.prev = j.m_edgeB; + j.m_bodyB.m_jointList = j.m_edgeB; + var bodyA = def.bodyA; + var bodyB = def.bodyB; + if (def.collideConnected == false) { + var edge = bodyB.GetContactList(); + while (edge) { + if (edge.other == bodyA) { + edge.contact.FlagForFiltering(); + } + edge = edge.next; + } + } + return j; + } + b2World.prototype.DestroyJoint = function (j) { + var collideConnected = j.m_collideConnected; + if (j.m_prev) { + j.m_prev.m_next = j.m_next; + } + if (j.m_next) { + j.m_next.m_prev = j.m_prev; + } + if (j == this.m_jointList) { + this.m_jointList = j.m_next; + } + var bodyA = j.m_bodyA; + var bodyB = j.m_bodyB; + bodyA.SetAwake(true); + bodyB.SetAwake(true); + if (j.m_edgeA.prev) { + j.m_edgeA.prev.next = j.m_edgeA.next; + } + if (j.m_edgeA.next) { + j.m_edgeA.next.prev = j.m_edgeA.prev; + } + if (j.m_edgeA == bodyA.m_jointList) { + bodyA.m_jointList = j.m_edgeA.next; + } + j.m_edgeA.prev = null; + j.m_edgeA.next = null; + if (j.m_edgeB.prev) { + j.m_edgeB.prev.next = j.m_edgeB.next; + } + if (j.m_edgeB.next) { + j.m_edgeB.next.prev = j.m_edgeB.prev; + } + if (j.m_edgeB == bodyB.m_jointList) { + bodyB.m_jointList = j.m_edgeB.next; + } + j.m_edgeB.prev = null; + j.m_edgeB.next = null; + b2Joint.Destroy(j, null); + --this.m_jointCount; + if (collideConnected == false) { + var edge = bodyB.GetContactList(); + while (edge) { + if (edge.other == bodyA) { + edge.contact.FlagForFiltering(); + } + edge = edge.next; + } + } + } + b2World.prototype.AddController = function (c) { + c.m_next = this.m_controllerList; + c.m_prev = null; + this.m_controllerList = c; + c.m_world = this; + this.m_controllerCount++; + return c; + } + b2World.prototype.RemoveController = function (c) { + if (c.m_prev) c.m_prev.m_next = c.m_next; + if (c.m_next) c.m_next.m_prev = c.m_prev; + if (this.m_controllerList == c) this.m_controllerList = c.m_next; + this.m_controllerCount--; + } + b2World.prototype.CreateController = function (controller) { + if (controller.m_world != this) throw new Error("Controller can only be a member of one world"); + controller.m_next = this.m_controllerList; + controller.m_prev = null; + if (this.m_controllerList) this.m_controllerList.m_prev = controller; + this.m_controllerList = controller; + ++this.m_controllerCount; + controller.m_world = this; + return controller; + } + b2World.prototype.DestroyController = function (controller) { + controller.Clear(); + if (controller.m_next) controller.m_next.m_prev = controller.m_prev; + if (controller.m_prev) controller.m_prev.m_next = controller.m_next; + if (controller == this.m_controllerList) this.m_controllerList = controller.m_next; + --this.m_controllerCount; + } + b2World.prototype.SetWarmStarting = function (flag) { + b2World.m_warmStarting = flag; + } + b2World.prototype.SetContinuousPhysics = function (flag) { + b2World.m_continuousPhysics = flag; + } + b2World.prototype.GetBodyCount = function () { + return this.m_bodyCount; + } + b2World.prototype.GetJointCount = function () { + return this.m_jointCount; + } + b2World.prototype.GetContactCount = function () { + return this.m_contactCount; + } + b2World.prototype.SetGravity = function (gravity) { + this.m_gravity = gravity; + } + b2World.prototype.GetGravity = function () { + return this.m_gravity; + } + b2World.prototype.GetGroundBody = function () { + return this.m_groundBody; + } + b2World.prototype.Step = function (dt, velocityIterations, positionIterations) { + if (dt === undefined) dt = 0; + if (velocityIterations === undefined) velocityIterations = 0; + if (positionIterations === undefined) positionIterations = 0; + if (this.m_flags & b2World.e_newFixture) { + this.m_contactManager.FindNewContacts(); + this.m_flags &= ~b2World.e_newFixture; + } + this.m_flags |= b2World.e_locked; + var step = b2World.s_timestep2; + step.dt = dt; + step.velocityIterations = velocityIterations; + step.positionIterations = positionIterations; + if (dt > 0.0) { + step.inv_dt = 1.0 / dt; + } + else { + step.inv_dt = 0.0; + } + step.dtRatio = this.m_inv_dt0 * dt; + step.warmStarting = b2World.m_warmStarting; + this.m_contactManager.Collide(); + if (step.dt > 0.0) { + this.Solve(step); + } + if (b2World.m_continuousPhysics && step.dt > 0.0) { + this.SolveTOI(step); + } + if (step.dt > 0.0) { + this.m_inv_dt0 = step.inv_dt; + } + this.m_flags &= ~b2World.e_locked; + } + b2World.prototype.ClearForces = function () { + for (var body = this.m_bodyList; body; body = body.m_next) { + body.m_force.SetZero(); + body.m_torque = 0.0; + } + } + b2World.prototype.DrawDebugData = function () { + if (this.m_debugDraw == null) { + return; + } + this.m_debugDraw.m_sprite.graphics.clear(); + var flags = this.m_debugDraw.GetFlags(); + var i = 0; + var b; + var f; + var s; + var j; + var bp; + var invQ = new b2Vec2; + var x1 = new b2Vec2; + var x2 = new b2Vec2; + var xf; + var b1 = new b2AABB(); + var b2 = new b2AABB(); + var vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()]; + var color = new b2Color(0, 0, 0); + if (flags & b2DebugDraw.e_shapeBit) { + for (b = this.m_bodyList; + b; b = b.m_next) { + xf = b.m_xf; + for (f = b.GetFixtureList(); + f; f = f.m_next) { + s = f.GetShape(); + if (b.IsActive() == false) { + color.Set(0.5, 0.5, 0.3); + this.DrawShape(s, xf, color); + } + else if (b.GetType() == b2Body.b2_staticBody) { + color.Set(0.5, 0.9, 0.5); + this.DrawShape(s, xf, color); + } + else if (b.GetType() == b2Body.b2_kinematicBody) { + color.Set(0.5, 0.5, 0.9); + this.DrawShape(s, xf, color); + } + else if (b.IsAwake() == false) { + color.Set(0.6, 0.6, 0.6); + this.DrawShape(s, xf, color); + } + else { + color.Set(0.9, 0.7, 0.7); + this.DrawShape(s, xf, color); + } + } + } + } + if (flags & b2DebugDraw.e_jointBit) { + for (j = this.m_jointList; + j; j = j.m_next) { + this.DrawJoint(j); + } + } + if (flags & b2DebugDraw.e_controllerBit) { + for (var c = this.m_controllerList; c; c = c.m_next) { + c.Draw(this.m_debugDraw); + } + } + if (flags & b2DebugDraw.e_pairBit) { + color.Set(0.3, 0.9, 0.9); + for (var contact = this.m_contactManager.m_contactList; contact; contact = contact.GetNext()) { + var fixtureA = contact.GetFixtureA(); + var fixtureB = contact.GetFixtureB(); + var cA = fixtureA.GetAABB().GetCenter(); + var cB = fixtureB.GetAABB().GetCenter(); + this.m_debugDraw.DrawSegment(cA, cB, color); + } + } + if (flags & b2DebugDraw.e_aabbBit) { + bp = this.m_contactManager.m_broadPhase; + vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()]; + for (b = this.m_bodyList; + b; b = b.GetNext()) { + if (b.IsActive() == false) { + continue; + } + for (f = b.GetFixtureList(); + f; f = f.GetNext()) { + var aabb = bp.GetFatAABB(f.m_proxy); + vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y); + vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y); + vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); + vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); + this.m_debugDraw.DrawPolygon(vs, 4, color); + } + } + } + if (flags & b2DebugDraw.e_centerOfMassBit) { + for (b = this.m_bodyList; + b; b = b.m_next) { + xf = b2World.s_xf; + xf.R = b.m_xf.R; + xf.position = b.GetWorldCenter(); + this.m_debugDraw.DrawTransform(xf); + } + } + } + b2World.prototype.QueryAABB = function (callback, aabb) { + var __this = this; + var broadPhase = __this.m_contactManager.m_broadPhase; + + function WorldQueryWrapper(proxy) { + return callback(broadPhase.GetUserData(proxy)); + }; + broadPhase.Query(WorldQueryWrapper, aabb); + } + b2World.prototype.QueryShape = function (callback, shape, transform) { + var __this = this; + if (transform === undefined) transform = null; + if (transform == null) { + transform = new b2Transform(); + transform.SetIdentity(); + } + var broadPhase = __this.m_contactManager.m_broadPhase; + + function WorldQueryWrapper(proxy) { + var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null); + if (b2Shape.TestOverlap(shape, transform, fixture.GetShape(), fixture.GetBody().GetTransform())) return callback(fixture); + return true; + }; + var aabb = new b2AABB(); + shape.ComputeAABB(aabb, transform); + broadPhase.Query(WorldQueryWrapper, aabb); + } + b2World.prototype.QueryPoint = function (callback, p) { + var __this = this; + var broadPhase = __this.m_contactManager.m_broadPhase; + + function WorldQueryWrapper(proxy) { + var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null); + if (fixture.TestPoint(p)) return callback(fixture); + return true; + }; + var aabb = new b2AABB(); + aabb.lowerBound.Set(p.x - b2Settings.b2_linearSlop, p.y - b2Settings.b2_linearSlop); + aabb.upperBound.Set(p.x + b2Settings.b2_linearSlop, p.y + b2Settings.b2_linearSlop); + broadPhase.Query(WorldQueryWrapper, aabb); + } + b2World.prototype.RayCast = function (callback, point1, point2) { + var __this = this; + var broadPhase = __this.m_contactManager.m_broadPhase; + var output = new b2RayCastOutput; + + function RayCastWrapper(input, proxy) { + var userData = broadPhase.GetUserData(proxy); + var fixture = (userData instanceof b2Fixture ? userData : null); + var hit = fixture.RayCast(output, input); + if (hit) { + var fraction = output.fraction; + var point = new b2Vec2((1.0 - fraction) * point1.x + fraction * point2.x, (1.0 - fraction) * point1.y + fraction * point2.y); + return callback(fixture, point, output.normal, fraction); + } + return input.maxFraction; + }; + var input = new b2RayCastInput(point1, point2); + broadPhase.RayCast(RayCastWrapper, input); + } + b2World.prototype.RayCastOne = function (point1, point2) { + var __this = this; + var result; + + function RayCastOneWrapper(fixture, point, normal, fraction) { + if (fraction === undefined) fraction = 0; + result = fixture; + return fraction; + }; + __this.RayCast(RayCastOneWrapper, point1, point2); + return result; + } + b2World.prototype.RayCastAll = function (point1, point2) { + var __this = this; + var result = new Vector(); + + function RayCastAllWrapper(fixture, point, normal, fraction) { + if (fraction === undefined) fraction = 0; + result[result.length] = fixture; + return 1; + }; + __this.RayCast(RayCastAllWrapper, point1, point2); + return result; + } + b2World.prototype.GetBodyList = function () { + return this.m_bodyList; + } + b2World.prototype.GetJointList = function () { + return this.m_jointList; + } + b2World.prototype.GetContactList = function () { + return this.m_contactList; + } + b2World.prototype.IsLocked = function () { + return (this.m_flags & b2World.e_locked) > 0; + } + b2World.prototype.Solve = function (step) { + var b; + for (var controller = this.m_controllerList; controller; controller = controller.m_next) { + controller.Step(step); + } + var island = this.m_island; + island.Initialize(this.m_bodyCount, this.m_contactCount, this.m_jointCount, null, this.m_contactManager.m_contactListener, this.m_contactSolver); + for (b = this.m_bodyList; + b; b = b.m_next) { + b.m_flags &= ~b2Body.e_islandFlag; + } + for (var c = this.m_contactList; c; c = c.m_next) { + c.m_flags &= ~b2Contact.e_islandFlag; + } + for (var j = this.m_jointList; j; j = j.m_next) { + j.m_islandFlag = false; + } + var stackSize = parseInt(this.m_bodyCount); + var stack = this.s_stack; + for (var seed = this.m_bodyList; seed; seed = seed.m_next) { + if (seed.m_flags & b2Body.e_islandFlag) { + continue; + } + if (seed.IsAwake() == false || seed.IsActive() == false) { + continue; + } + if (seed.GetType() == b2Body.b2_staticBody) { + continue; + } + island.Clear(); + var stackCount = 0; + stack[stackCount++] = seed; + seed.m_flags |= b2Body.e_islandFlag; + while (stackCount > 0) { + b = stack[--stackCount]; + island.AddBody(b); + if (b.IsAwake() == false) { + b.SetAwake(true); + } + if (b.GetType() == b2Body.b2_staticBody) { + continue; + } + var other; + for (var ce = b.m_contactList; ce; ce = ce.next) { + if (ce.contact.m_flags & b2Contact.e_islandFlag) { + continue; + } + if (ce.contact.IsSensor() == true || ce.contact.IsEnabled() == false || ce.contact.IsTouching() == false) { + continue; + } + island.AddContact(ce.contact); + ce.contact.m_flags |= b2Contact.e_islandFlag; + other = ce.other; + if (other.m_flags & b2Body.e_islandFlag) { + continue; + } + stack[stackCount++] = other; + other.m_flags |= b2Body.e_islandFlag; + } + for (var jn = b.m_jointList; jn; jn = jn.next) { + if (jn.joint.m_islandFlag == true) { + continue; + } + other = jn.other; + if (other.IsActive() == false) { + continue; + } + island.AddJoint(jn.joint); + jn.joint.m_islandFlag = true; + if (other.m_flags & b2Body.e_islandFlag) { + continue; + } + stack[stackCount++] = other; + other.m_flags |= b2Body.e_islandFlag; + } + } + island.Solve(step, this.m_gravity, this.m_allowSleep); + for (var i = 0; i < island.m_bodyCount; ++i) { + b = island.m_bodies[i]; + if (b.GetType() == b2Body.b2_staticBody) { + b.m_flags &= ~b2Body.e_islandFlag; + } + } + } + for (i = 0; + i < stack.length; ++i) { + if (!stack[i]) break; + stack[i] = null; + } + for (b = this.m_bodyList; + b; b = b.m_next) { + if (b.IsAwake() == false || b.IsActive() == false) { + continue; + } + if (b.GetType() == b2Body.b2_staticBody) { + continue; + } + b.SynchronizeFixtures(); + } + this.m_contactManager.FindNewContacts(); + } + b2World.prototype.SolveTOI = function (step) { + var b; + var fA; + var fB; + var bA; + var bB; + var cEdge; + var j; + var island = this.m_island; + island.Initialize(this.m_bodyCount, b2Settings.b2_maxTOIContactsPerIsland, b2Settings.b2_maxTOIJointsPerIsland, null, this.m_contactManager.m_contactListener, this.m_contactSolver); + var queue = b2World.s_queue; + for (b = this.m_bodyList; + b; b = b.m_next) { + b.m_flags &= ~b2Body.e_islandFlag; + b.m_sweep.t0 = 0.0; + } + var c; + for (c = this.m_contactList; + c; c = c.m_next) { + c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag); + } + for (j = this.m_jointList; + j; j = j.m_next) { + j.m_islandFlag = false; + } + for (;;) { + var minContact = null; + var minTOI = 1.0; + for (c = this.m_contactList; + c; c = c.m_next) { + if (c.IsSensor() == true || c.IsEnabled() == false || c.IsContinuous() == false) { + continue; + } + var toi = 1.0; + if (c.m_flags & b2Contact.e_toiFlag) { + toi = c.m_toi; + } + else { + fA = c.m_fixtureA; + fB = c.m_fixtureB; + bA = fA.m_body; + bB = fB.m_body; + if ((bA.GetType() != b2Body.b2_dynamicBody || bA.IsAwake() == false) && (bB.GetType() != b2Body.b2_dynamicBody || bB.IsAwake() == false)) { + continue; + } + var t0 = bA.m_sweep.t0; + if (bA.m_sweep.t0 < bB.m_sweep.t0) { + t0 = bB.m_sweep.t0; + bA.m_sweep.Advance(t0); + } + else if (bB.m_sweep.t0 < bA.m_sweep.t0) { + t0 = bA.m_sweep.t0; + bB.m_sweep.Advance(t0); + } + toi = c.ComputeTOI(bA.m_sweep, bB.m_sweep); + b2Settings.b2Assert(0.0 <= toi && toi <= 1.0); + if (toi > 0.0 && toi < 1.0) { + toi = (1.0 - toi) * t0 + toi; + if (toi > 1) toi = 1; + } + c.m_toi = toi; + c.m_flags |= b2Contact.e_toiFlag; + } + if (Number.MIN_VALUE < toi && toi < minTOI) { + minContact = c; + minTOI = toi; + } + } + if (minContact == null || 1.0 - 100.0 * Number.MIN_VALUE < minTOI) { + break; + } + fA = minContact.m_fixtureA; + fB = minContact.m_fixtureB; + bA = fA.m_body; + bB = fB.m_body; + b2World.s_backupA.Set(bA.m_sweep); + b2World.s_backupB.Set(bB.m_sweep); + bA.Advance(minTOI); + bB.Advance(minTOI); + minContact.Update(this.m_contactManager.m_contactListener); + minContact.m_flags &= ~b2Contact.e_toiFlag; + if (minContact.IsSensor() == true || minContact.IsEnabled() == false) { + bA.m_sweep.Set(b2World.s_backupA); + bB.m_sweep.Set(b2World.s_backupB); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + continue; + } + if (minContact.IsTouching() == false) { + continue; + } + var seed = bA; + if (seed.GetType() != b2Body.b2_dynamicBody) { + seed = bB; + } + island.Clear(); + var queueStart = 0; + var queueSize = 0; + queue[queueStart + queueSize++] = seed; + seed.m_flags |= b2Body.e_islandFlag; + while (queueSize > 0) { + b = queue[queueStart++]; + --queueSize; + island.AddBody(b); + if (b.IsAwake() == false) { + b.SetAwake(true); + } + if (b.GetType() != b2Body.b2_dynamicBody) { + continue; + } + for (cEdge = b.m_contactList; + cEdge; cEdge = cEdge.next) { + if (island.m_contactCount == island.m_contactCapacity) { + break; + } + if (cEdge.contact.m_flags & b2Contact.e_islandFlag) { + continue; + } + if (cEdge.contact.IsSensor() == true || cEdge.contact.IsEnabled() == false || cEdge.contact.IsTouching() == false) { + continue; + } + island.AddContact(cEdge.contact); + cEdge.contact.m_flags |= b2Contact.e_islandFlag; + var other = cEdge.other; + if (other.m_flags & b2Body.e_islandFlag) { + continue; + } + if (other.GetType() != b2Body.b2_staticBody) { + other.Advance(minTOI); + other.SetAwake(true); + } + queue[queueStart + queueSize] = other; + ++queueSize; + other.m_flags |= b2Body.e_islandFlag; + } + for (var jEdge = b.m_jointList; jEdge; jEdge = jEdge.next) { + if (island.m_jointCount == island.m_jointCapacity) continue; + if (jEdge.joint.m_islandFlag == true) continue; + other = jEdge.other; + if (other.IsActive() == false) { + continue; + } + island.AddJoint(jEdge.joint); + jEdge.joint.m_islandFlag = true; + if (other.m_flags & b2Body.e_islandFlag) continue; + if (other.GetType() != b2Body.b2_staticBody) { + other.Advance(minTOI); + other.SetAwake(true); + } + queue[queueStart + queueSize] = other; + ++queueSize; + other.m_flags |= b2Body.e_islandFlag; + } + } + var subStep = b2World.s_timestep; + subStep.warmStarting = false; + subStep.dt = (1.0 - minTOI) * step.dt; + subStep.inv_dt = 1.0 / subStep.dt; + subStep.dtRatio = 0.0; + subStep.velocityIterations = step.velocityIterations; + subStep.positionIterations = step.positionIterations; + island.SolveTOI(subStep); + var i = 0; + for (i = 0; + i < island.m_bodyCount; ++i) { + b = island.m_bodies[i]; + b.m_flags &= ~b2Body.e_islandFlag; + if (b.IsAwake() == false) { + continue; + } + if (b.GetType() != b2Body.b2_dynamicBody) { + continue; + } + b.SynchronizeFixtures(); + for (cEdge = b.m_contactList; + cEdge; cEdge = cEdge.next) { + cEdge.contact.m_flags &= ~b2Contact.e_toiFlag; + } + } + for (i = 0; + i < island.m_contactCount; ++i) { + c = island.m_contacts[i]; + c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag); + } + for (i = 0; + i < island.m_jointCount; ++i) { + j = island.m_joints[i]; + j.m_islandFlag = false; + } + this.m_contactManager.FindNewContacts(); + } + } + b2World.prototype.DrawJoint = function (joint) { + var b1 = joint.GetBodyA(); + var b2 = joint.GetBodyB(); + var xf1 = b1.m_xf; + var xf2 = b2.m_xf; + var x1 = xf1.position; + var x2 = xf2.position; + var p1 = joint.GetAnchorA(); + var p2 = joint.GetAnchorB(); + var color = b2World.s_jointColor; + switch (joint.m_type) { + case b2Joint.e_distanceJoint: + this.m_debugDraw.DrawSegment(p1, p2, color); + break; + case b2Joint.e_pulleyJoint: + { + var pulley = ((joint instanceof b2PulleyJoint ? joint : null)); + var s1 = pulley.GetGroundAnchorA(); + var s2 = pulley.GetGroundAnchorB(); + this.m_debugDraw.DrawSegment(s1, p1, color); + this.m_debugDraw.DrawSegment(s2, p2, color); + this.m_debugDraw.DrawSegment(s1, s2, color); + } + break; + case b2Joint.e_mouseJoint: + this.m_debugDraw.DrawSegment(p1, p2, color); + break; + default: + if (b1 != this.m_groundBody) this.m_debugDraw.DrawSegment(x1, p1, color); + this.m_debugDraw.DrawSegment(p1, p2, color); + if (b2 != this.m_groundBody) this.m_debugDraw.DrawSegment(x2, p2, color); + } + } + b2World.prototype.DrawShape = function (shape, xf, color) { + switch (shape.m_type) { + case b2Shape.e_circleShape: + { + var circle = ((shape instanceof b2CircleShape ? shape : null)); + var center = b2Math.MulX(xf, circle.m_p); + var radius = circle.m_radius; + var axis = xf.R.col1; + this.m_debugDraw.DrawSolidCircle(center, radius, axis, color); + } + break; + case b2Shape.e_polygonShape: + { + var i = 0; + var poly = ((shape instanceof b2PolygonShape ? shape : null)); + var vertexCount = parseInt(poly.GetVertexCount()); + var localVertices = poly.GetVertices(); + var vertices = new Vector(vertexCount); + for (i = 0; + i < vertexCount; ++i) { + vertices[i] = b2Math.MulX(xf, localVertices[i]); + } + this.m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color); + } + break; + case b2Shape.e_edgeShape: + { + var edge = (shape instanceof b2EdgeShape ? shape : null); + this.m_debugDraw.DrawSegment(b2Math.MulX(xf, edge.GetVertex1()), b2Math.MulX(xf, edge.GetVertex2()), color); + } + break; + } + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.b2World.s_timestep2 = new b2TimeStep(); + Box2D.Dynamics.b2World.prototype.s_timestep2 = Box2D.Dynamics.b2World.s_timestep2; + Box2D.Dynamics.b2World.s_xf = new b2Transform(); + Box2D.Dynamics.b2World.prototype.s_xf = Box2D.Dynamics.b2World.s_xf; + Box2D.Dynamics.b2World.s_backupA = new b2Sweep(); + Box2D.Dynamics.b2World.prototype.s_backupA = Box2D.Dynamics.b2World.s_backupA; + Box2D.Dynamics.b2World.s_backupB = new b2Sweep(); + Box2D.Dynamics.b2World.prototype.s_backupB = Box2D.Dynamics.b2World.s_backupB; + Box2D.Dynamics.b2World.s_timestep = new b2TimeStep(); + Box2D.Dynamics.b2World.prototype.s_timestep = Box2D.Dynamics.b2World.s_timestep; + Box2D.Dynamics.b2World.s_queue = new Vector(); + Box2D.Dynamics.b2World.prototype.s_queue = Box2D.Dynamics.b2World.s_queue; + Box2D.Dynamics.b2World.s_jointColor = new b2Color(0.5, 0.8, 0.8); + Box2D.Dynamics.b2World.prototype.s_jointColor = Box2D.Dynamics.b2World.s_jointColor; + Box2D.Dynamics.b2World.e_newFixture = 0x0001; + Box2D.Dynamics.b2World.prototype.e_newFixture = Box2D.Dynamics.b2World.e_newFixture; + Box2D.Dynamics.b2World.e_locked = 0x0002; + Box2D.Dynamics.b2World.prototype.e_locked = Box2D.Dynamics.b2World.e_locked; + }); +})(); /* source: disabled*/ +(function () { + var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; + var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; + var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; + var b2MassData = Box2D.Collision.Shapes.b2MassData; + var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; + var b2Shape = Box2D.Collision.Shapes.b2Shape; + var b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact; + var b2Contact = Box2D.Dynamics.Contacts.b2Contact; + var b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint; + var b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint; + var b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge; + var b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory; + var b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister; + var b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult; + var b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver; + var b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact; + var b2NullContact = Box2D.Dynamics.Contacts.b2NullContact; + var b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact; + var b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact; + var b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact; + var b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold; + var b2Body = Box2D.Dynamics.b2Body; + var b2BodyDef = Box2D.Dynamics.b2BodyDef; + var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; + var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; + var b2ContactListener = Box2D.Dynamics.b2ContactListener; + var b2ContactManager = Box2D.Dynamics.b2ContactManager; + var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; + var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; + var b2FilterData = Box2D.Dynamics.b2FilterData; + var b2Fixture = Box2D.Dynamics.b2Fixture; + var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; + var b2Island = Box2D.Dynamics.b2Island; + var b2TimeStep = Box2D.Dynamics.b2TimeStep; + var b2World = Box2D.Dynamics.b2World; + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2Mat22 = Box2D.Common.Math.b2Mat22; + var b2Mat33 = Box2D.Common.Math.b2Mat33; + var b2Math = Box2D.Common.Math.b2Math; + var b2Sweep = Box2D.Common.Math.b2Sweep; + var b2Transform = Box2D.Common.Math.b2Transform; + var b2Vec2 = Box2D.Common.Math.b2Vec2; + var b2Vec3 = Box2D.Common.Math.b2Vec3; + var b2AABB = Box2D.Collision.b2AABB; + var b2Bound = Box2D.Collision.b2Bound; + var b2BoundValues = Box2D.Collision.b2BoundValues; + var b2BroadPhase = Box2D.Collision.b2BroadPhase; + var b2Collision = Box2D.Collision.b2Collision; + var b2ContactID = Box2D.Collision.b2ContactID; + var b2ContactPoint = Box2D.Collision.b2ContactPoint; + var b2Distance = Box2D.Collision.b2Distance; + var b2DistanceInput = Box2D.Collision.b2DistanceInput; + var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; + var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; + var b2DynamicTree = Box2D.Collision.b2DynamicTree; + var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; + var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; + var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; + var b2Manifold = Box2D.Collision.b2Manifold; + var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; + var b2OBB = Box2D.Collision.b2OBB; + var b2Pair = Box2D.Collision.b2Pair; + var b2PairManager = Box2D.Collision.b2PairManager; + var b2Point = Box2D.Collision.b2Point; + var b2Proxy = Box2D.Collision.b2Proxy; + var b2RayCastInput = Box2D.Collision.b2RayCastInput; + var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; + var b2Segment = Box2D.Collision.b2Segment; + var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; + var b2Simplex = Box2D.Collision.b2Simplex; + var b2SimplexCache = Box2D.Collision.b2SimplexCache; + var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; + var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; + var b2TOIInput = Box2D.Collision.b2TOIInput; + var b2WorldManifold = Box2D.Collision.b2WorldManifold; + var ClipVertex = Box2D.Collision.ClipVertex; + var Features = Box2D.Collision.Features; + var IBroadPhase = Box2D.Collision.IBroadPhase; + var b2internal = Box2D.Common.b2internal; + var b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact; + var b2Contact = Box2D.Dynamics.Contacts.b2Contact; + var b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint; + var b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint; + var b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge; + var b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory; + var b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister; + var b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult; + var b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver; + var b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact; + var b2NullContact = Box2D.Dynamics.Contacts.b2NullContact; + var b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact; + var b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact; + var b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact; + var b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold; + helpers.inherit.call(b2CircleContact, Box2D.Dynamics.Contacts.b2Contact); + b2CircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; + b2CircleContact.b2CircleContact = function () { + Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); + }; + b2CircleContact.prototype.Create = function (allocator) { + return new b2CircleContact(); + } + b2CircleContact.Create = b2CircleContact.prototype.Create; + b2CircleContact.prototype.Destroy = function (contact, allocator) {} + b2CircleContact.Destroy = b2CircleContact.prototype.Destroy; + b2CircleContact.prototype.Reset = function (fixtureA, fixtureB) { + this.__super.Reset.call(this, fixtureA, fixtureB); + } + b2CircleContact.prototype.Evaluate = function () { + var bA = this.m_fixtureA.GetBody(); + var bB = this.m_fixtureB.GetBody(); + b2Collision.CollideCircles(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2CircleShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); + } + b2Contact.b2Contact = function () { + this.m_nodeA = new b2ContactEdge(); + this.m_nodeB = new b2ContactEdge(); + this.m_manifold = new b2Manifold(); + this.m_oldManifold = new b2Manifold(); + }; + b2Contact.prototype.GetManifold = function () { + return this.m_manifold; + } + b2Contact.prototype.GetWorldManifold = function (worldManifold) { + var bodyA = this.m_fixtureA.GetBody(); + var bodyB = this.m_fixtureB.GetBody(); + var shapeA = this.m_fixtureA.GetShape(); + var shapeB = this.m_fixtureB.GetShape(); + worldManifold.Initialize(this.m_manifold, bodyA.GetTransform(), shapeA.m_radius, bodyB.GetTransform(), shapeB.m_radius); + } + b2Contact.prototype.IsTouching = function () { + return (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag; + } + b2Contact.prototype.IsContinuous = function () { + return (this.m_flags & b2Contact.e_continuousFlag) == b2Contact.e_continuousFlag; + } + b2Contact.prototype.SetSensor = function (sensor) { + if (sensor) { + this.m_flags |= b2Contact.e_sensorFlag; + } + else { + this.m_flags &= ~b2Contact.e_sensorFlag; + } + } + b2Contact.prototype.IsSensor = function () { + return (this.m_flags & b2Contact.e_sensorFlag) == b2Contact.e_sensorFlag; + } + b2Contact.prototype.SetEnabled = function (flag) { + if (flag) { + this.m_flags |= b2Contact.e_enabledFlag; + } + else { + this.m_flags &= ~b2Contact.e_enabledFlag; + } + } + b2Contact.prototype.IsEnabled = function () { + return (this.m_flags & b2Contact.e_enabledFlag) == b2Contact.e_enabledFlag; + } + b2Contact.prototype.GetNext = function () { + return this.m_next; + } + b2Contact.prototype.GetFixtureA = function () { + return this.m_fixtureA; + } + b2Contact.prototype.GetFixtureB = function () { + return this.m_fixtureB; + } + b2Contact.prototype.FlagForFiltering = function () { + this.m_flags |= b2Contact.e_filterFlag; + } + b2Contact.prototype.b2Contact = function () {} + b2Contact.prototype.Reset = function (fixtureA, fixtureB) { + if (fixtureA === undefined) fixtureA = null; + if (fixtureB === undefined) fixtureB = null; + this.m_flags = b2Contact.e_enabledFlag; + if (!fixtureA || !fixtureB) { + this.m_fixtureA = null; + this.m_fixtureB = null; + return; + } + if (fixtureA.IsSensor() || fixtureB.IsSensor()) { + this.m_flags |= b2Contact.e_sensorFlag; + } + var bodyA = fixtureA.GetBody(); + var bodyB = fixtureB.GetBody(); + if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { + this.m_flags |= b2Contact.e_continuousFlag; + } + this.m_fixtureA = fixtureA; + this.m_fixtureB = fixtureB; + this.m_manifold.m_pointCount = 0; + this.m_prev = null; + this.m_next = null; + this.m_nodeA.contact = null; + this.m_nodeA.prev = null; + this.m_nodeA.next = null; + this.m_nodeA.other = null; + this.m_nodeB.contact = null; + this.m_nodeB.prev = null; + this.m_nodeB.next = null; + this.m_nodeB.other = null; + } + b2Contact.prototype.Update = function (listener) { + var tManifold = this.m_oldManifold; + this.m_oldManifold = this.m_manifold; + this.m_manifold = tManifold; + this.m_flags |= b2Contact.e_enabledFlag; + var touching = false; + var wasTouching = (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag; + var bodyA = this.m_fixtureA.m_body; + var bodyB = this.m_fixtureB.m_body; + var aabbOverlap = this.m_fixtureA.m_aabb.TestOverlap(this.m_fixtureB.m_aabb); + if (this.m_flags & b2Contact.e_sensorFlag) { + if (aabbOverlap) { + var shapeA = this.m_fixtureA.GetShape(); + var shapeB = this.m_fixtureB.GetShape(); + var xfA = bodyA.GetTransform(); + var xfB = bodyB.GetTransform(); + touching = b2Shape.TestOverlap(shapeA, xfA, shapeB, xfB); + } + this.m_manifold.m_pointCount = 0; + } + else { + if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { + this.m_flags |= b2Contact.e_continuousFlag; + } + else { + this.m_flags &= ~b2Contact.e_continuousFlag; + } + if (aabbOverlap) { + this.Evaluate(); + touching = this.m_manifold.m_pointCount > 0; + for (var i = 0; i < this.m_manifold.m_pointCount; ++i) { + var mp2 = this.m_manifold.m_points[i]; + mp2.m_normalImpulse = 0.0; + mp2.m_tangentImpulse = 0.0; + var id2 = mp2.m_id; + for (var j = 0; j < this.m_oldManifold.m_pointCount; ++j) { + var mp1 = this.m_oldManifold.m_points[j]; + if (mp1.m_id.key == id2.key) { + mp2.m_normalImpulse = mp1.m_normalImpulse; + mp2.m_tangentImpulse = mp1.m_tangentImpulse; + break; + } + } + } + } + else { + this.m_manifold.m_pointCount = 0; + } + if (touching != wasTouching) { + bodyA.SetAwake(true); + bodyB.SetAwake(true); + } + } + if (touching) { + this.m_flags |= b2Contact.e_touchingFlag; + } + else { + this.m_flags &= ~b2Contact.e_touchingFlag; + } + if (wasTouching == false && touching == true) { + listener.BeginContact(this); + } + if (wasTouching == true && touching == false) { + listener.EndContact(this); + } + if ((this.m_flags & b2Contact.e_sensorFlag) == 0) { + listener.PreSolve(this, this.m_oldManifold); + } + } + b2Contact.prototype.Evaluate = function () {} + b2Contact.prototype.ComputeTOI = function (sweepA, sweepB) { + b2Contact.s_input.proxyA.Set(this.m_fixtureA.GetShape()); + b2Contact.s_input.proxyB.Set(this.m_fixtureB.GetShape()); + b2Contact.s_input.sweepA = sweepA; + b2Contact.s_input.sweepB = sweepB; + b2Contact.s_input.tolerance = b2Settings.b2_linearSlop; + return b2TimeOfImpact.TimeOfImpact(b2Contact.s_input); + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.Contacts.b2Contact.e_sensorFlag = 0x0001; + Box2D.Dynamics.Contacts.b2Contact.prototype.e_sensorFlag = Box2D.Dynamics.Contacts.b2Contact.e_sensorFlag; + Box2D.Dynamics.Contacts.b2Contact.e_continuousFlag = 0x0002; + Box2D.Dynamics.Contacts.b2Contact.prototype.e_continuousFlag = Box2D.Dynamics.Contacts.b2Contact.e_continuousFlag; + Box2D.Dynamics.Contacts.b2Contact.e_islandFlag = 0x0004; + Box2D.Dynamics.Contacts.b2Contact.prototype.e_islandFlag = Box2D.Dynamics.Contacts.b2Contact.e_islandFlag; + Box2D.Dynamics.Contacts.b2Contact.e_toiFlag = 0x0008; + Box2D.Dynamics.Contacts.b2Contact.prototype.e_toiFlag = Box2D.Dynamics.Contacts.b2Contact.e_toiFlag; + Box2D.Dynamics.Contacts.b2Contact.e_touchingFlag = 0x0010; + Box2D.Dynamics.Contacts.b2Contact.prototype.e_touchingFlag = Box2D.Dynamics.Contacts.b2Contact.e_touchingFlag; + Box2D.Dynamics.Contacts.b2Contact.e_enabledFlag = 0x0020; + Box2D.Dynamics.Contacts.b2Contact.prototype.e_enabledFlag = Box2D.Dynamics.Contacts.b2Contact.e_enabledFlag; + Box2D.Dynamics.Contacts.b2Contact.e_filterFlag = 0x0040; + Box2D.Dynamics.Contacts.b2Contact.prototype.e_filterFlag = Box2D.Dynamics.Contacts.b2Contact.e_filterFlag; + Box2D.Dynamics.Contacts.b2Contact.s_input = new b2TOIInput(); + Box2D.Dynamics.Contacts.b2Contact.prototype.s_input = Box2D.Dynamics.Contacts.b2Contact.s_input; + }); + b2ContactConstraint.b2ContactConstraint = function () { + this.localPlaneNormal = new b2Vec2(); + this.localPoint = new b2Vec2(); + this.normal = new b2Vec2(); + this.normalMass = new b2Mat22(); + this.K = new b2Mat22(); + }; + b2ContactConstraint.prototype.b2ContactConstraint = function () { + this.points = new Vector(b2Settings.b2_maxManifoldPoints); + for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { + this.points[i] = new b2ContactConstraintPoint(); + } + } + b2ContactConstraintPoint.b2ContactConstraintPoint = function () { + this.localPoint = new b2Vec2(); + this.rA = new b2Vec2(); + this.rB = new b2Vec2(); + }; + b2ContactEdge.b2ContactEdge = function () {}; + b2ContactFactory.b2ContactFactory = function () {}; + b2ContactFactory.prototype.b2ContactFactory = function (allocator) { + this.m_allocator = allocator; + this.InitializeRegisters(); + } + b2ContactFactory.prototype.AddType = function (createFcn, destroyFcn, type1, type2) { + if (type1 === undefined) type1 = 0; + if (type2 === undefined) type2 = 0; + this.m_registers[type1][type2].createFcn = createFcn; + this.m_registers[type1][type2].destroyFcn = destroyFcn; + this.m_registers[type1][type2].primary = true; + if (type1 != type2) { + this.m_registers[type2][type1].createFcn = createFcn; + this.m_registers[type2][type1].destroyFcn = destroyFcn; + this.m_registers[type2][type1].primary = false; + } + } + b2ContactFactory.prototype.InitializeRegisters = function () { + this.m_registers = new Vector(b2Shape.e_shapeTypeCount); + for (var i = 0; i < b2Shape.e_shapeTypeCount; i++) { + this.m_registers[i] = new Vector(b2Shape.e_shapeTypeCount); + for (var j = 0; j < b2Shape.e_shapeTypeCount; j++) { + this.m_registers[i][j] = new b2ContactRegister(); + } + } + this.AddType(b2CircleContact.Create, b2CircleContact.Destroy, b2Shape.e_circleShape, b2Shape.e_circleShape); + this.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_circleShape); + this.AddType(b2PolygonContact.Create, b2PolygonContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_polygonShape); + this.AddType(b2EdgeAndCircleContact.Create, b2EdgeAndCircleContact.Destroy, b2Shape.e_edgeShape, b2Shape.e_circleShape); + this.AddType(b2PolyAndEdgeContact.Create, b2PolyAndEdgeContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_edgeShape); + } + b2ContactFactory.prototype.Create = function (fixtureA, fixtureB) { + var type1 = parseInt(fixtureA.GetType()); + var type2 = parseInt(fixtureB.GetType()); + var reg = this.m_registers[type1][type2]; + var c; + if (reg.pool) { + c = reg.pool; + reg.pool = c.m_next; + reg.poolCount--; + c.Reset(fixtureA, fixtureB); + return c; + } + var createFcn = reg.createFcn; + if (createFcn != null) { + if (reg.primary) { + c = createFcn(this.m_allocator); + c.Reset(fixtureA, fixtureB); + return c; + } + else { + c = createFcn(this.m_allocator); + c.Reset(fixtureB, fixtureA); + return c; + } + } + else { + return null; + } + } + b2ContactFactory.prototype.Destroy = function (contact) { + if (contact.m_manifold.m_pointCount > 0) { + contact.m_fixtureA.m_body.SetAwake(true); + contact.m_fixtureB.m_body.SetAwake(true); + } + var type1 = parseInt(contact.m_fixtureA.GetType()); + var type2 = parseInt(contact.m_fixtureB.GetType()); + var reg = this.m_registers[type1][type2]; + if (true) { + reg.poolCount++; + contact.m_next = reg.pool; + reg.pool = contact; + } + var destroyFcn = reg.destroyFcn; + destroyFcn(contact, this.m_allocator); + } + b2ContactRegister.b2ContactRegister = function () {}; + b2ContactResult.b2ContactResult = function () { + this.position = new b2Vec2(); + this.normal = new b2Vec2(); + this.id = new b2ContactID(); + }; + b2ContactSolver.b2ContactSolver = function () { + this.m_step = new b2TimeStep(); + this.m_constraints = new Vector(); + }; + b2ContactSolver.prototype.b2ContactSolver = function () {} + b2ContactSolver.prototype.Initialize = function (step, contacts, contactCount, allocator) { + if (contactCount === undefined) contactCount = 0; + var contact; + this.m_step.Set(step); + this.m_allocator = allocator; + var i = 0; + var tVec; + var tMat; + this.m_constraintCount = contactCount; + while (this.m_constraints.length < this.m_constraintCount) { + this.m_constraints[this.m_constraints.length] = new b2ContactConstraint(); + } + for (i = 0; + i < contactCount; ++i) { + contact = contacts[i]; + var fixtureA = contact.m_fixtureA; + var fixtureB = contact.m_fixtureB; + var shapeA = fixtureA.m_shape; + var shapeB = fixtureB.m_shape; + var radiusA = shapeA.m_radius; + var radiusB = shapeB.m_radius; + var bodyA = fixtureA.m_body; + var bodyB = fixtureB.m_body; + var manifold = contact.GetManifold(); + var friction = b2Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction()); + var restitution = b2Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution()); + var vAX = bodyA.m_linearVelocity.x; + var vAY = bodyA.m_linearVelocity.y; + var vBX = bodyB.m_linearVelocity.x; + var vBY = bodyB.m_linearVelocity.y; + var wA = bodyA.m_angularVelocity; + var wB = bodyB.m_angularVelocity; + b2Settings.b2Assert(manifold.m_pointCount > 0); + b2ContactSolver.s_worldManifold.Initialize(manifold, bodyA.m_xf, radiusA, bodyB.m_xf, radiusB); + var normalX = b2ContactSolver.s_worldManifold.m_normal.x; + var normalY = b2ContactSolver.s_worldManifold.m_normal.y; + var cc = this.m_constraints[i]; + cc.bodyA = bodyA; + cc.bodyB = bodyB; + cc.manifold = manifold; + cc.normal.x = normalX; + cc.normal.y = normalY; + cc.pointCount = manifold.m_pointCount; + cc.friction = friction; + cc.restitution = restitution; + cc.localPlaneNormal.x = manifold.m_localPlaneNormal.x; + cc.localPlaneNormal.y = manifold.m_localPlaneNormal.y; + cc.localPoint.x = manifold.m_localPoint.x; + cc.localPoint.y = manifold.m_localPoint.y; + cc.radius = radiusA + radiusB; + cc.type = manifold.m_type; + for (var k = 0; k < cc.pointCount; ++k) { + var cp = manifold.m_points[k]; + var ccp = cc.points[k]; + ccp.normalImpulse = cp.m_normalImpulse; + ccp.tangentImpulse = cp.m_tangentImpulse; + ccp.localPoint.SetV(cp.m_localPoint); + var rAX = ccp.rA.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyA.m_sweep.c.x; + var rAY = ccp.rA.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyA.m_sweep.c.y; + var rBX = ccp.rB.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyB.m_sweep.c.x; + var rBY = ccp.rB.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyB.m_sweep.c.y; + var rnA = rAX * normalY - rAY * normalX; + var rnB = rBX * normalY - rBY * normalX; + rnA *= rnA; + rnB *= rnB; + var kNormal = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rnA + bodyB.m_invI * rnB; + ccp.normalMass = 1.0 / kNormal; + var kEqualized = bodyA.m_mass * bodyA.m_invMass + bodyB.m_mass * bodyB.m_invMass; + kEqualized += bodyA.m_mass * bodyA.m_invI * rnA + bodyB.m_mass * bodyB.m_invI * rnB; + ccp.equalizedMass = 1.0 / kEqualized; + var tangentX = normalY; + var tangentY = (-normalX); + var rtA = rAX * tangentY - rAY * tangentX; + var rtB = rBX * tangentY - rBY * tangentX; + rtA *= rtA; + rtB *= rtB; + var kTangent = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rtA + bodyB.m_invI * rtB; + ccp.tangentMass = 1.0 / kTangent; + ccp.velocityBias = 0.0; + var tX = vBX + ((-wB * rBY)) - vAX - ((-wA * rAY)); + var tY = vBY + (wB * rBX) - vAY - (wA * rAX); + var vRel = cc.normal.x * tX + cc.normal.y * tY; + if (vRel < (-b2Settings.b2_velocityThreshold)) { + ccp.velocityBias += (-cc.restitution * vRel); + } + } + if (cc.pointCount == 2) { + var ccp1 = cc.points[0]; + var ccp2 = cc.points[1]; + var invMassA = bodyA.m_invMass; + var invIA = bodyA.m_invI; + var invMassB = bodyB.m_invMass; + var invIB = bodyB.m_invI; + var rn1A = ccp1.rA.x * normalY - ccp1.rA.y * normalX; + var rn1B = ccp1.rB.x * normalY - ccp1.rB.y * normalX; + var rn2A = ccp2.rA.x * normalY - ccp2.rA.y * normalX; + var rn2B = ccp2.rB.x * normalY - ccp2.rB.y * normalX; + var k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B; + var k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B; + var k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B; + var k_maxConditionNumber = 100.0; + if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { + cc.K.col1.Set(k11, k12); + cc.K.col2.Set(k12, k22); + cc.K.GetInverse(cc.normalMass); + } + else { + cc.pointCount = 1; + } + } + } + } + b2ContactSolver.prototype.InitVelocityConstraints = function (step) { + var tVec; + var tVec2; + var tMat; + for (var i = 0; i < this.m_constraintCount; ++i) { + var c = this.m_constraints[i]; + var bodyA = c.bodyA; + var bodyB = c.bodyB; + var invMassA = bodyA.m_invMass; + var invIA = bodyA.m_invI; + var invMassB = bodyB.m_invMass; + var invIB = bodyB.m_invI; + var normalX = c.normal.x; + var normalY = c.normal.y; + var tangentX = normalY; + var tangentY = (-normalX); + var tX = 0; + var j = 0; + var tCount = 0; + if (step.warmStarting) { + tCount = c.pointCount; + for (j = 0; + j < tCount; ++j) { + var ccp = c.points[j]; + ccp.normalImpulse *= step.dtRatio; + ccp.tangentImpulse *= step.dtRatio; + var PX = ccp.normalImpulse * normalX + ccp.tangentImpulse * tangentX; + var PY = ccp.normalImpulse * normalY + ccp.tangentImpulse * tangentY; + bodyA.m_angularVelocity -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); + bodyA.m_linearVelocity.x -= invMassA * PX; + bodyA.m_linearVelocity.y -= invMassA * PY; + bodyB.m_angularVelocity += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); + bodyB.m_linearVelocity.x += invMassB * PX; + bodyB.m_linearVelocity.y += invMassB * PY; + } + } + else { + tCount = c.pointCount; + for (j = 0; + j < tCount; ++j) { + var ccp2 = c.points[j]; + ccp2.normalImpulse = 0.0; + ccp2.tangentImpulse = 0.0; + } + } + } + } + b2ContactSolver.prototype.SolveVelocityConstraints = function () { + var j = 0; + var ccp; + var rAX = 0; + var rAY = 0; + var rBX = 0; + var rBY = 0; + var dvX = 0; + var dvY = 0; + var vn = 0; + var vt = 0; + var lambda = 0; + var maxFriction = 0; + var newImpulse = 0; + var PX = 0; + var PY = 0; + var dX = 0; + var dY = 0; + var P1X = 0; + var P1Y = 0; + var P2X = 0; + var P2Y = 0; + var tMat; + var tVec; + for (var i = 0; i < this.m_constraintCount; ++i) { + var c = this.m_constraints[i]; + var bodyA = c.bodyA; + var bodyB = c.bodyB; + var wA = bodyA.m_angularVelocity; + var wB = bodyB.m_angularVelocity; + var vA = bodyA.m_linearVelocity; + var vB = bodyB.m_linearVelocity; + var invMassA = bodyA.m_invMass; + var invIA = bodyA.m_invI; + var invMassB = bodyB.m_invMass; + var invIB = bodyB.m_invI; + var normalX = c.normal.x; + var normalY = c.normal.y; + var tangentX = normalY; + var tangentY = (-normalX); + var friction = c.friction; + var tX = 0; + for (j = 0; + j < c.pointCount; j++) { + ccp = c.points[j]; + dvX = vB.x - wB * ccp.rB.y - vA.x + wA * ccp.rA.y; + dvY = vB.y + wB * ccp.rB.x - vA.y - wA * ccp.rA.x; + vt = dvX * tangentX + dvY * tangentY; + lambda = ccp.tangentMass * (-vt); + maxFriction = friction * ccp.normalImpulse; + newImpulse = b2Math.Clamp(ccp.tangentImpulse + lambda, (-maxFriction), maxFriction); + lambda = newImpulse - ccp.tangentImpulse; + PX = lambda * tangentX; + PY = lambda * tangentY; + vA.x -= invMassA * PX; + vA.y -= invMassA * PY; + wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); + vB.x += invMassB * PX; + vB.y += invMassB * PY; + wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); + ccp.tangentImpulse = newImpulse; + } + var tCount = parseInt(c.pointCount); + if (c.pointCount == 1) { + ccp = c.points[0]; + dvX = vB.x + ((-wB * ccp.rB.y)) - vA.x - ((-wA * ccp.rA.y)); + dvY = vB.y + (wB * ccp.rB.x) - vA.y - (wA * ccp.rA.x); + vn = dvX * normalX + dvY * normalY; + lambda = (-ccp.normalMass * (vn - ccp.velocityBias)); + newImpulse = ccp.normalImpulse + lambda; + newImpulse = newImpulse > 0 ? newImpulse : 0.0; + lambda = newImpulse - ccp.normalImpulse; + PX = lambda * normalX; + PY = lambda * normalY; + vA.x -= invMassA * PX; + vA.y -= invMassA * PY; + wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); + vB.x += invMassB * PX; + vB.y += invMassB * PY; + wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); + ccp.normalImpulse = newImpulse; + } + else { + var cp1 = c.points[0]; + var cp2 = c.points[1]; + var aX = cp1.normalImpulse; + var aY = cp2.normalImpulse; + var dv1X = vB.x - wB * cp1.rB.y - vA.x + wA * cp1.rA.y; + var dv1Y = vB.y + wB * cp1.rB.x - vA.y - wA * cp1.rA.x; + var dv2X = vB.x - wB * cp2.rB.y - vA.x + wA * cp2.rA.y; + var dv2Y = vB.y + wB * cp2.rB.x - vA.y - wA * cp2.rA.x; + var vn1 = dv1X * normalX + dv1Y * normalY; + var vn2 = dv2X * normalX + dv2Y * normalY; + var bX = vn1 - cp1.velocityBias; + var bY = vn2 - cp2.velocityBias; + tMat = c.K; + bX -= tMat.col1.x * aX + tMat.col2.x * aY; + bY -= tMat.col1.y * aX + tMat.col2.y * aY; + var k_errorTol = 0.001; + for (;;) { + tMat = c.normalMass; + var xX = (-(tMat.col1.x * bX + tMat.col2.x * bY)); + var xY = (-(tMat.col1.y * bX + tMat.col2.y * bY)); + if (xX >= 0.0 && xY >= 0.0) { + dX = xX - aX; + dY = xY - aY; + P1X = dX * normalX; + P1Y = dX * normalY; + P2X = dY * normalX; + P2Y = dY * normalY; + vA.x -= invMassA * (P1X + P2X); + vA.y -= invMassA * (P1Y + P2Y); + wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); + vB.x += invMassB * (P1X + P2X); + vB.y += invMassB * (P1Y + P2Y); + wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); + cp1.normalImpulse = xX; + cp2.normalImpulse = xY; + break; + } + xX = (-cp1.normalMass * bX); + xY = 0.0; + vn1 = 0.0; + vn2 = c.K.col1.y * xX + bY; + if (xX >= 0.0 && vn2 >= 0.0) { + dX = xX - aX; + dY = xY - aY; + P1X = dX * normalX; + P1Y = dX * normalY; + P2X = dY * normalX; + P2Y = dY * normalY; + vA.x -= invMassA * (P1X + P2X); + vA.y -= invMassA * (P1Y + P2Y); + wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); + vB.x += invMassB * (P1X + P2X); + vB.y += invMassB * (P1Y + P2Y); + wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); + cp1.normalImpulse = xX; + cp2.normalImpulse = xY; + break; + } + xX = 0.0; + xY = (-cp2.normalMass * bY); + vn1 = c.K.col2.x * xY + bX; + vn2 = 0.0; + if (xY >= 0.0 && vn1 >= 0.0) { + dX = xX - aX; + dY = xY - aY; + P1X = dX * normalX; + P1Y = dX * normalY; + P2X = dY * normalX; + P2Y = dY * normalY; + vA.x -= invMassA * (P1X + P2X); + vA.y -= invMassA * (P1Y + P2Y); + wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); + vB.x += invMassB * (P1X + P2X); + vB.y += invMassB * (P1Y + P2Y); + wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); + cp1.normalImpulse = xX; + cp2.normalImpulse = xY; + break; + } + xX = 0.0; + xY = 0.0; + vn1 = bX; + vn2 = bY; + if (vn1 >= 0.0 && vn2 >= 0.0) { + dX = xX - aX; + dY = xY - aY; + P1X = dX * normalX; + P1Y = dX * normalY; + P2X = dY * normalX; + P2Y = dY * normalY; + vA.x -= invMassA * (P1X + P2X); + vA.y -= invMassA * (P1Y + P2Y); + wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); + vB.x += invMassB * (P1X + P2X); + vB.y += invMassB * (P1Y + P2Y); + wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); + cp1.normalImpulse = xX; + cp2.normalImpulse = xY; + break; + } + break; + } + } + bodyA.m_angularVelocity = wA; + bodyB.m_angularVelocity = wB; + } + } + b2ContactSolver.prototype.FinalizeVelocityConstraints = function () { + for (var i = 0; i < this.m_constraintCount; ++i) { + var c = this.m_constraints[i]; + var m = c.manifold; + for (var j = 0; j < c.pointCount; ++j) { + var point1 = m.m_points[j]; + var point2 = c.points[j]; + point1.m_normalImpulse = point2.normalImpulse; + point1.m_tangentImpulse = point2.tangentImpulse; + } + } + } + b2ContactSolver.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + var minSeparation = 0.0; + for (var i = 0; i < this.m_constraintCount; i++) { + var c = this.m_constraints[i]; + var bodyA = c.bodyA; + var bodyB = c.bodyB; + var invMassA = bodyA.m_mass * bodyA.m_invMass; + var invIA = bodyA.m_mass * bodyA.m_invI; + var invMassB = bodyB.m_mass * bodyB.m_invMass; + var invIB = bodyB.m_mass * bodyB.m_invI; + b2ContactSolver.s_psm.Initialize(c); + var normal = b2ContactSolver.s_psm.m_normal; + for (var j = 0; j < c.pointCount; j++) { + var ccp = c.points[j]; + var point = b2ContactSolver.s_psm.m_points[j]; + var separation = b2ContactSolver.s_psm.m_separations[j]; + var rAX = point.x - bodyA.m_sweep.c.x; + var rAY = point.y - bodyA.m_sweep.c.y; + var rBX = point.x - bodyB.m_sweep.c.x; + var rBY = point.y - bodyB.m_sweep.c.y; + minSeparation = minSeparation < separation ? minSeparation : separation; + var C = b2Math.Clamp(baumgarte * (separation + b2Settings.b2_linearSlop), (-b2Settings.b2_maxLinearCorrection), 0.0); + var impulse = (-ccp.equalizedMass * C); + var PX = impulse * normal.x; + var PY = impulse * normal.y;bodyA.m_sweep.c.x -= invMassA * PX; + bodyA.m_sweep.c.y -= invMassA * PY; + bodyA.m_sweep.a -= invIA * (rAX * PY - rAY * PX); + bodyA.SynchronizeTransform(); + bodyB.m_sweep.c.x += invMassB * PX; + bodyB.m_sweep.c.y += invMassB * PY; + bodyB.m_sweep.a += invIB * (rBX * PY - rBY * PX); + bodyB.SynchronizeTransform(); + } + } + return minSeparation > (-1.5 * b2Settings.b2_linearSlop); + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.Contacts.b2ContactSolver.s_worldManifold = new b2WorldManifold(); + Box2D.Dynamics.Contacts.b2ContactSolver.prototype.s_worldManifold = Box2D.Dynamics.Contacts.b2ContactSolver.s_worldManifold; + Box2D.Dynamics.Contacts.b2ContactSolver.s_psm = new b2PositionSolverManifold(); + Box2D.Dynamics.Contacts.b2ContactSolver.prototype.s_psm = Box2D.Dynamics.Contacts.b2ContactSolver.s_psm; + }); + helpers.inherit.call(b2EdgeAndCircleContact, Box2D.Dynamics.Contacts.b2Contact); + b2EdgeAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; + b2EdgeAndCircleContact.b2EdgeAndCircleContact = function () { + Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); + }; + b2EdgeAndCircleContact.prototype.Create = function (allocator) { + return new b2EdgeAndCircleContact(); + } + b2EdgeAndCircleContact.Create = b2EdgeAndCircleContact.prototype.Create; + b2EdgeAndCircleContact.prototype.Destroy = function (contact, allocator) {} + b2EdgeAndCircleContact.Destroy = b2EdgeAndCircleContact.prototype.Destroy; + b2EdgeAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) { + this.__super.Reset.call(this, fixtureA, fixtureB); + } + b2EdgeAndCircleContact.prototype.Evaluate = function () { + var bA = this.m_fixtureA.GetBody(); + var bB = this.m_fixtureB.GetBody(); + this.b2CollideEdgeAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2EdgeShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); + } + b2EdgeAndCircleContact.prototype.b2CollideEdgeAndCircle = function (manifold, edge, xf1, circle, xf2) {} + helpers.inherit.call(b2NullContact, Box2D.Dynamics.Contacts.b2Contact); + b2NullContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; + b2NullContact.b2NullContact = function () { + Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); + }; + b2NullContact.prototype.b2NullContact = function () { + this.__super.b2Contact.call(this); + } + b2NullContact.prototype.Evaluate = function () {} + helpers.inherit.call(b2PolyAndCircleContact, Box2D.Dynamics.Contacts.b2Contact); + b2PolyAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; + b2PolyAndCircleContact.b2PolyAndCircleContact = function () { + Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); + }; + b2PolyAndCircleContact.prototype.Create = function (allocator) { + return new b2PolyAndCircleContact(); + } + b2PolyAndCircleContact.Create = b2PolyAndCircleContact.prototype.Create; + b2PolyAndCircleContact.prototype.Destroy = function (contact, allocator) {} + b2PolyAndCircleContact.Destroy = b2PolyAndCircleContact.prototype.Destroy; + b2PolyAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) { + this.__super.Reset.call(this, fixtureA, fixtureB); + b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); + b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_circleShape); + } + b2PolyAndCircleContact.prototype.Evaluate = function () { + var bA = this.m_fixtureA.m_body; + var bB = this.m_fixtureB.m_body; + b2Collision.CollidePolygonAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); + } + helpers.inherit.call(b2PolyAndEdgeContact, Box2D.Dynamics.Contacts.b2Contact); + b2PolyAndEdgeContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; + b2PolyAndEdgeContact.b2PolyAndEdgeContact = function () { + Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); + }; + b2PolyAndEdgeContact.prototype.Create = function (allocator) { + return new b2PolyAndEdgeContact(); + } + b2PolyAndEdgeContact.Create = b2PolyAndEdgeContact.prototype.Create; + b2PolyAndEdgeContact.prototype.Destroy = function (contact, allocator) {} + b2PolyAndEdgeContact.Destroy = b2PolyAndEdgeContact.prototype.Destroy; + b2PolyAndEdgeContact.prototype.Reset = function (fixtureA, fixtureB) { + this.__super.Reset.call(this, fixtureA, fixtureB); + b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); + b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_edgeShape); + } + b2PolyAndEdgeContact.prototype.Evaluate = function () { + var bA = this.m_fixtureA.GetBody(); + var bB = this.m_fixtureB.GetBody(); + this.b2CollidePolyAndEdge(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2EdgeShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); + } + b2PolyAndEdgeContact.prototype.b2CollidePolyAndEdge = function (manifold, polygon, xf1, edge, xf2) {} + helpers.inherit.call(b2PolygonContact, Box2D.Dynamics.Contacts.b2Contact); + b2PolygonContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; + b2PolygonContact.b2PolygonContact = function () { + Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); + }; + b2PolygonContact.prototype.Create = function (allocator) { + return new b2PolygonContact(); + } + b2PolygonContact.Create = b2PolygonContact.prototype.Create; + b2PolygonContact.prototype.Destroy = function (contact, allocator) {} + b2PolygonContact.Destroy = b2PolygonContact.prototype.Destroy; + b2PolygonContact.prototype.Reset = function (fixtureA, fixtureB) { + this.__super.Reset.call(this, fixtureA, fixtureB); + } + b2PolygonContact.prototype.Evaluate = function () { + var bA = this.m_fixtureA.GetBody(); + var bB = this.m_fixtureB.GetBody(); + b2Collision.CollidePolygons(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2PolygonShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); + } + b2PositionSolverManifold.b2PositionSolverManifold = function () {}; + b2PositionSolverManifold.prototype.b2PositionSolverManifold = function () { + this.m_normal = new b2Vec2(); + this.m_separations = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); + this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); + for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { + this.m_points[i] = new b2Vec2(); + } + } + b2PositionSolverManifold.prototype.Initialize = function (cc) { + b2Settings.b2Assert(cc.pointCount > 0); + var i = 0; + var clipPointX = 0; + var clipPointY = 0; + var tMat; + var tVec; + var planePointX = 0; + var planePointY = 0; + switch (cc.type) { + case b2Manifold.e_circles: + { + tMat = cc.bodyA.m_xf.R; + tVec = cc.localPoint; + var pointAX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var pointAY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = cc.bodyB.m_xf.R; + tVec = cc.points[0].localPoint; + var pointBX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var pointBY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var dX = pointBX - pointAX; + var dY = pointBY - pointAY; + var d2 = dX * dX + dY * dY; + if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) { + var d = Math.sqrt(d2); + this.m_normal.x = dX / d; + this.m_normal.y = dY / d; + } + else { + this.m_normal.x = 1.0; + this.m_normal.y = 0.0; + } + this.m_points[0].x = 0.5 * (pointAX + pointBX); + this.m_points[0].y = 0.5 * (pointAY + pointBY); + this.m_separations[0] = dX * this.m_normal.x + dY * this.m_normal.y - cc.radius; + } + break; + case b2Manifold.e_faceA: + { + tMat = cc.bodyA.m_xf.R; + tVec = cc.localPlaneNormal; + this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = cc.bodyA.m_xf.R; + tVec = cc.localPoint; + planePointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + planePointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = cc.bodyB.m_xf.R; + for (i = 0; + i < cc.pointCount; ++i) { + tVec = cc.points[i].localPoint; + clipPointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + clipPointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; + this.m_points[i].x = clipPointX; + this.m_points[i].y = clipPointY; + } + } + break; + case b2Manifold.e_faceB: + { + tMat = cc.bodyB.m_xf.R; + tVec = cc.localPlaneNormal; + this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = cc.bodyB.m_xf.R; + tVec = cc.localPoint; + planePointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + planePointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = cc.bodyA.m_xf.R; + for (i = 0; + i < cc.pointCount; ++i) { + tVec = cc.points[i].localPoint; + clipPointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + clipPointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; + this.m_points[i].Set(clipPointX, clipPointY); + } + this.m_normal.x *= (-1); + this.m_normal.y *= (-1); + } + break; + } + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointA = new b2Vec2(); + Box2D.Dynamics.Contacts.b2PositionSolverManifold.prototype.circlePointA = Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointA; + Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointB = new b2Vec2(); + Box2D.Dynamics.Contacts.b2PositionSolverManifold.prototype.circlePointB = Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointB; + }); +})(); /* source: disabled*/ +(function () { + var b2Body = Box2D.Dynamics.b2Body; + var b2BodyDef = Box2D.Dynamics.b2BodyDef; + var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; + var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; + var b2ContactListener = Box2D.Dynamics.b2ContactListener; + var b2ContactManager = Box2D.Dynamics.b2ContactManager; + var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; + var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; + var b2FilterData = Box2D.Dynamics.b2FilterData; + var b2Fixture = Box2D.Dynamics.b2Fixture; + var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; + var b2Island = Box2D.Dynamics.b2Island; + var b2TimeStep = Box2D.Dynamics.b2TimeStep; + var b2World = Box2D.Dynamics.b2World; + var b2Mat22 = Box2D.Common.Math.b2Mat22; + var b2Mat33 = Box2D.Common.Math.b2Mat33; + var b2Math = Box2D.Common.Math.b2Math; + var b2Sweep = Box2D.Common.Math.b2Sweep; + var b2Transform = Box2D.Common.Math.b2Transform; + var b2Vec2 = Box2D.Common.Math.b2Vec2; + var b2Vec3 = Box2D.Common.Math.b2Vec3; + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; + var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; + var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; + var b2MassData = Box2D.Collision.Shapes.b2MassData; + var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; + var b2Shape = Box2D.Collision.Shapes.b2Shape; + var b2Body = Box2D.Dynamics.b2Body; + var b2BodyDef = Box2D.Dynamics.b2BodyDef; + var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; + var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; + var b2ContactListener = Box2D.Dynamics.b2ContactListener; + var b2ContactManager = Box2D.Dynamics.b2ContactManager; + var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; + var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; + var b2FilterData = Box2D.Dynamics.b2FilterData; + var b2Fixture = Box2D.Dynamics.b2Fixture; + var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; + var b2Island = Box2D.Dynamics.b2Island; + var b2TimeStep = Box2D.Dynamics.b2TimeStep; + var b2World = Box2D.Dynamics.b2World; + var b2BuoyancyController = Box2D.Dynamics.Controllers.b2BuoyancyController; + var b2ConstantAccelController = Box2D.Dynamics.Controllers.b2ConstantAccelController; + var b2ConstantForceController = Box2D.Dynamics.Controllers.b2ConstantForceController; + var b2Controller = Box2D.Dynamics.Controllers.b2Controller; + var b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge; + var b2GravityController = Box2D.Dynamics.Controllers.b2GravityController; + var b2TensorDampingController = Box2D.Dynamics.Controllers.b2TensorDampingController; + helpers.inherit.call(b2BuoyancyController, Box2D.Dynamics.Controllers.b2Controller); + b2BuoyancyController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; + b2BuoyancyController.b2BuoyancyController = function () { + Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); + this.normal = new b2Vec2(0, (-1)); + this.offset = 0; + this.density = 0; + this.velocity = new b2Vec2(0, 0); + this.linearDrag = 2; + this.angularDrag = 1; + this.useDensity = false; + this.useWorldGravity = true; + this.gravity = null; + }; + b2BuoyancyController.prototype.Step = function (step) { + if (!this.m_bodyList) return; + if (this.useWorldGravity) { + this.gravity = this.GetWorld().GetGravity().Copy(); + } + for (var i = this.m_bodyList; i; i = i.nextBody) { + var body = i.body; + if (body.IsAwake() == false) { + continue; + } + var areac = new b2Vec2(); + var massc = new b2Vec2(); + var area = 0.0; + var mass = 0.0; + for (var fixture = body.GetFixtureList(); fixture; fixture = fixture.GetNext()) { + var sc = new b2Vec2(); + var sarea = fixture.GetShape().ComputeSubmergedArea(this.normal, this.offset, body.GetTransform(), sc); + area += sarea; + areac.x += sarea * sc.x; + areac.y += sarea * sc.y; + var shapeDensity = 0; + if (this.useDensity) { + shapeDensity = 1; + } + else { + shapeDensity = 1; + } + mass += sarea * shapeDensity; + massc.x += sarea * sc.x * shapeDensity; + massc.y += sarea * sc.y * shapeDensity; + } + areac.x /= area; + areac.y /= area; + massc.x /= mass; + massc.y /= mass; + if (area < Number.MIN_VALUE) continue; + var buoyancyForce = this.gravity.GetNegative(); + buoyancyForce.Multiply(this.density * area); + body.ApplyForce(buoyancyForce, massc); + var dragForce = body.GetLinearVelocityFromWorldPoint(areac); + dragForce.Subtract(this.velocity); + dragForce.Multiply((-this.linearDrag * area)); + body.ApplyForce(dragForce, areac); + body.ApplyTorque((-body.GetInertia() / body.GetMass() * area * body.GetAngularVelocity() * this.angularDrag)); + } + } + b2BuoyancyController.prototype.Draw = function (debugDraw) { + var r = 1000; + var p1 = new b2Vec2(); + var p2 = new b2Vec2(); + p1.x = this.normal.x * this.offset + this.normal.y * r; + p1.y = this.normal.y * this.offset - this.normal.x * r; + p2.x = this.normal.x * this.offset - this.normal.y * r; + p2.y = this.normal.y * this.offset + this.normal.x * r; + var color = new b2Color(0, 0, 1); + debugDraw.DrawSegment(p1, p2, color); + } + helpers.inherit.call(b2ConstantAccelController, Box2D.Dynamics.Controllers.b2Controller); + b2ConstantAccelController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; + b2ConstantAccelController.b2ConstantAccelController = function () { + Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); + this.A = new b2Vec2(0, 0); + }; + b2ConstantAccelController.prototype.Step = function (step) { + var smallA = new b2Vec2(this.A.x * step.dt, this.A.y * step.dt); + for (var i = this.m_bodyList; i; i = i.nextBody) { + var body = i.body; + if (!body.IsAwake()) continue; + body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + smallA.x, body.GetLinearVelocity().y + smallA.y)); + } + } + helpers.inherit.call(b2ConstantForceController, Box2D.Dynamics.Controllers.b2Controller); + b2ConstantForceController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; + b2ConstantForceController.b2ConstantForceController = function () { + Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); + this.F = new b2Vec2(0, 0); + }; + b2ConstantForceController.prototype.Step = function (step) { + for (var i = this.m_bodyList; i; i = i.nextBody) { + var body = i.body; + if (!body.IsAwake()) continue; + body.ApplyForce(this.F, body.GetWorldCenter()); + } + } + b2Controller.b2Controller = function () {}; + b2Controller.prototype.Step = function (step) {} + b2Controller.prototype.Draw = function (debugDraw) {} + b2Controller.prototype.AddBody = function (body) { + var edge = new b2ControllerEdge(); + edge.controller = this; + edge.body = body; + edge.nextBody = this.m_bodyList; + edge.prevBody = null; + this.m_bodyList = edge; + if (edge.nextBody) edge.nextBody.prevBody = edge; + this.m_bodyCount++; + edge.nextController = body.m_controllerList; + edge.prevController = null; + body.m_controllerList = edge; + if (edge.nextController) edge.nextController.prevController = edge; + body.m_controllerCount++; + } + b2Controller.prototype.RemoveBody = function (body) { + var edge = body.m_controllerList; + while (edge && edge.controller != this) + edge = edge.nextController; + if (edge.prevBody) edge.prevBody.nextBody = edge.nextBody; + if (edge.nextBody) edge.nextBody.prevBody = edge.prevBody; + if (edge.nextController) edge.nextController.prevController = edge.prevController; + if (edge.prevController) edge.prevController.nextController = edge.nextController; + if (this.m_bodyList == edge) this.m_bodyList = edge.nextBody; + if (body.m_controllerList == edge) body.m_controllerList = edge.nextController; + body.m_controllerCount--; + this.m_bodyCount--; + } + b2Controller.prototype.Clear = function () { + while (this.m_bodyList) + this.RemoveBody(this.m_bodyList.body); + } + b2Controller.prototype.GetNext = function () { + return this.m_next; + } + b2Controller.prototype.GetWorld = function () { + return this.m_world; + } + b2Controller.prototype.GetBodyList = function () { + return this.m_bodyList; + } + b2ControllerEdge.b2ControllerEdge = function () {}; + helpers.inherit.call(b2GravityController, Box2D.Dynamics.Controllers.b2Controller); + b2GravityController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; + b2GravityController.b2GravityController = function () { + Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); + this.G = 1; + this.invSqr = true; + }; + b2GravityController.prototype.Step = function (step) { + var i = null; + var body1 = null; + var p1 = null; + var mass1 = 0; + var j = null; + var body2 = null; + var p2 = null; + var dx = 0; + var dy = 0; + var r2 = 0; + var f = null; + if (this.invSqr) { + for (i = this.m_bodyList; + i; i = i.nextBody) { + body1 = i.body; + p1 = body1.GetWorldCenter(); + mass1 = body1.GetMass(); + for (j = this.m_bodyList; + j != i; j = j.nextBody) { + body2 = j.body; + p2 = body2.GetWorldCenter(); + dx = p2.x - p1.x; + dy = p2.y - p1.y; + r2 = dx * dx + dy * dy; + if (r2 < Number.MIN_VALUE) continue; + f = new b2Vec2(dx, dy); + f.Multiply(this.G / r2 / Math.sqrt(r2) * mass1 * body2.GetMass()); + if (body1.IsAwake()) body1.ApplyForce(f, p1); + f.Multiply((-1)); + if (body2.IsAwake()) body2.ApplyForce(f, p2); + } + } + } + else { + for (i = this.m_bodyList; + i; i = i.nextBody) { + body1 = i.body; + p1 = body1.GetWorldCenter(); + mass1 = body1.GetMass(); + for (j = this.m_bodyList; + j != i; j = j.nextBody) { + body2 = j.body; + p2 = body2.GetWorldCenter(); + dx = p2.x - p1.x; + dy = p2.y - p1.y; + r2 = dx * dx + dy * dy; + if (r2 < Number.MIN_VALUE) continue; + f = new b2Vec2(dx, dy); + f.Multiply(this.G / r2 * mass1 * body2.GetMass()); + if (body1.IsAwake()) body1.ApplyForce(f, p1); + f.Multiply((-1)); + if (body2.IsAwake()) body2.ApplyForce(f, p2); + } + } + } + } + helpers.inherit.call(b2TensorDampingController, Box2D.Dynamics.Controllers.b2Controller); + b2TensorDampingController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; + b2TensorDampingController.b2TensorDampingController = function () { + Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); + this.T = new b2Mat22(); + this.maxTimestep = 0; + }; + b2TensorDampingController.prototype.SetAxisAligned = function (xDamping, yDamping) { + if (xDamping === undefined) xDamping = 0; + if (yDamping === undefined) yDamping = 0; + this.T.col1.x = (-xDamping); + this.T.col1.y = 0; + this.T.col2.x = 0; + this.T.col2.y = (-yDamping); + if (xDamping > 0 || yDamping > 0) { + this.maxTimestep = 1 / Math.max(xDamping, yDamping); + } + else { + this.maxTimestep = 0; + } + } + b2TensorDampingController.prototype.Step = function (step) { + var timestep = step.dt; + if (timestep <= Number.MIN_VALUE) return; + if (timestep > this.maxTimestep && this.maxTimestep > 0) timestep = this.maxTimestep; + for (var i = this.m_bodyList; i; i = i.nextBody) { + var body = i.body; + if (!body.IsAwake()) { + continue; + } + var damping = body.GetWorldVector(b2Math.MulMV(this.T, body.GetLocalVector(body.GetLinearVelocity()))); + body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + damping.x * timestep, body.GetLinearVelocity().y + damping.y * timestep)); + } + } +})(); /* source: disabled*/ +(function () { + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2Color = Box2D.Common.b2Color; + var b2internal = Box2D.Common.b2internal; + var b2Settings = Box2D.Common.b2Settings; + var b2internal = Box2D.Common.b2internal; + var b2Mat22 = Box2D.Common.Math.b2Mat22; + var b2Mat33 = Box2D.Common.Math.b2Mat33; + var b2Math = Box2D.Common.Math.b2Math; + var b2Sweep = Box2D.Common.Math.b2Sweep; + var b2Transform = Box2D.Common.Math.b2Transform; + var b2Vec2 = Box2D.Common.Math.b2Vec2; + var b2Vec3 = Box2D.Common.Math.b2Vec3; + var b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint; + var b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef; + var b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint; + var b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef; + var b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint; + var b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef; + var b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian; + var b2Joint = Box2D.Dynamics.Joints.b2Joint; + var b2JointDef = Box2D.Dynamics.Joints.b2JointDef; + var b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge; + var b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint; + var b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef; + var b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint; + var b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef; + var b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint; + var b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef; + var b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint; + var b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef; + var b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint; + var b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef; + var b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint; + var b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef; + var b2Body = Box2D.Dynamics.b2Body; + var b2BodyDef = Box2D.Dynamics.b2BodyDef; + var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; + var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; + var b2ContactListener = Box2D.Dynamics.b2ContactListener; + var b2ContactManager = Box2D.Dynamics.b2ContactManager; + var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; + var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; + var b2FilterData = Box2D.Dynamics.b2FilterData; + var b2Fixture = Box2D.Dynamics.b2Fixture; + var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; + var b2Island = Box2D.Dynamics.b2Island; + var b2TimeStep = Box2D.Dynamics.b2TimeStep; + var b2World = Box2D.Dynamics.b2World; + var b2internal = Box2D.Common.b2internal; + var b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint; + var b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef; + var b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint; + var b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef; + var b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint; + var b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef; + var b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian; + var b2Joint = Box2D.Dynamics.Joints.b2Joint; + var b2JointDef = Box2D.Dynamics.Joints.b2JointDef; + var b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge; + var b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint; + var b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef; + var b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint; + var b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef; + var b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint; + var b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef; + var b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint; + var b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef; + var b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint; + var b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef; + var b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint; + var b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef; + helpers.inherit.call(b2DistanceJoint, Box2D.Dynamics.Joints.b2Joint); + b2DistanceJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; + b2DistanceJoint.b2DistanceJoint = function () { + Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); + this.m_localAnchor1 = new b2Vec2(); + this.m_localAnchor2 = new b2Vec2(); + this.m_u = new b2Vec2(); + }; + b2DistanceJoint.prototype.GetAnchorA = function () { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); + } + b2DistanceJoint.prototype.GetAnchorB = function () { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); + } + b2DistanceJoint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return new b2Vec2(inv_dt * this.m_impulse * this.m_u.x, inv_dt * this.m_impulse * this.m_u.y); + } + b2DistanceJoint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return 0.0; + } + b2DistanceJoint.prototype.GetLength = function () { + return this.m_length; + } + b2DistanceJoint.prototype.SetLength = function (length) { + if (length === undefined) length = 0; + this.m_length = length; + } + b2DistanceJoint.prototype.GetFrequency = function () { + return this.m_frequencyHz; + } + b2DistanceJoint.prototype.SetFrequency = function (hz) { + if (hz === undefined) hz = 0; + this.m_frequencyHz = hz; + } + b2DistanceJoint.prototype.GetDampingRatio = function () { + return this.m_dampingRatio; + } + b2DistanceJoint.prototype.SetDampingRatio = function (ratio) { + if (ratio === undefined) ratio = 0; + this.m_dampingRatio = ratio; + } + b2DistanceJoint.prototype.b2DistanceJoint = function (def) { + this.__super.b2Joint.call(this, def); + var tMat; + var tX = 0; + var tY = 0; + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_length = def.length; + this.m_frequencyHz = def.frequencyHz; + this.m_dampingRatio = def.dampingRatio; + this.m_impulse = 0.0; + this.m_gamma = 0.0; + this.m_bias = 0.0; + } + b2DistanceJoint.prototype.InitVelocityConstraints = function (step) { + var tMat; + var tX = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + this.m_u.x = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + this.m_u.y = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + var length = Math.sqrt(this.m_u.x * this.m_u.x + this.m_u.y * this.m_u.y); + if (length > b2Settings.b2_linearSlop) { + this.m_u.Multiply(1.0 / length); + } + else { + this.m_u.SetZero(); + } + var cr1u = (r1X * this.m_u.y - r1Y * this.m_u.x); + var cr2u = (r2X * this.m_u.y - r2Y * this.m_u.x); + var invMass = bA.m_invMass + bA.m_invI * cr1u * cr1u + bB.m_invMass + bB.m_invI * cr2u * cr2u; + this.m_mass = invMass != 0.0 ? 1.0 / invMass : 0.0; + if (this.m_frequencyHz > 0.0) { + var C = length - this.m_length; + var omega = 2.0 * Math.PI * this.m_frequencyHz; + var d = 2.0 * this.m_mass * this.m_dampingRatio * omega; + var k = this.m_mass * omega * omega; + this.m_gamma = step.dt * (d + step.dt * k); + this.m_gamma = this.m_gamma != 0.0 ? 1 / this.m_gamma : 0.0; + this.m_bias = C * step.dt * k * this.m_gamma; + this.m_mass = invMass + this.m_gamma; + this.m_mass = this.m_mass != 0.0 ? 1.0 / this.m_mass : 0.0; + } + if (step.warmStarting) { + this.m_impulse *= step.dtRatio; + var PX = this.m_impulse * this.m_u.x; + var PY = this.m_impulse * this.m_u.y; + bA.m_linearVelocity.x -= bA.m_invMass * PX; + bA.m_linearVelocity.y -= bA.m_invMass * PY; + bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); + bB.m_linearVelocity.x += bB.m_invMass * PX; + bB.m_linearVelocity.y += bB.m_invMass * PY; + bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX); + } + else { + this.m_impulse = 0.0; + } + } + b2DistanceJoint.prototype.SolveVelocityConstraints = function (step) { + var tMat; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y)); + var v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X); + var v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y)); + var v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X); + var Cdot = (this.m_u.x * (v2X - v1X) + this.m_u.y * (v2Y - v1Y)); + var impulse = (-this.m_mass * (Cdot + this.m_bias + this.m_gamma * this.m_impulse)); + this.m_impulse += impulse; + var PX = impulse * this.m_u.x; + var PY = impulse * this.m_u.y; + bA.m_linearVelocity.x -= bA.m_invMass * PX; + bA.m_linearVelocity.y -= bA.m_invMass * PY; + bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); + bB.m_linearVelocity.x += bB.m_invMass * PX; + bB.m_linearVelocity.y += bB.m_invMass * PY; + bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX); + } + b2DistanceJoint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + var tMat; + if (this.m_frequencyHz > 0.0) { + return true; + } + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + var length = Math.sqrt(dX * dX + dY * dY); + dX /= length; + dY /= length; + var C = length - this.m_length; + C = b2Math.Clamp(C, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection); + var impulse = (-this.m_mass * C); + this.m_u.Set(dX, dY); + var PX = impulse * this.m_u.x; + var PY = impulse * this.m_u.y; + bA.m_sweep.c.x -= bA.m_invMass * PX; + bA.m_sweep.c.y -= bA.m_invMass * PY; + bA.m_sweep.a -= bA.m_invI * (r1X * PY - r1Y * PX); + bB.m_sweep.c.x += bB.m_invMass * PX; + bB.m_sweep.c.y += bB.m_invMass * PY; + bB.m_sweep.a += bB.m_invI * (r2X * PY - r2Y * PX); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return b2Math.Abs(C) < b2Settings.b2_linearSlop; + } + helpers.inherit.call(b2DistanceJointDef, Box2D.Dynamics.Joints.b2JointDef); + b2DistanceJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; + b2DistanceJointDef.b2DistanceJointDef = function () { + Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + }; + b2DistanceJointDef.prototype.b2DistanceJointDef = function () { + this.__super.b2JointDef.call(this); + this.type = b2Joint.e_distanceJoint; + this.length = 1.0; + this.frequencyHz = 0.0; + this.dampingRatio = 0.0; + } + b2DistanceJointDef.prototype.Initialize = function (bA, bB, anchorA, anchorB) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchorA)); + this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchorB)); + var dX = anchorB.x - anchorA.x; + var dY = anchorB.y - anchorA.y; + this.length = Math.sqrt(dX * dX + dY * dY); + this.frequencyHz = 0.0; + this.dampingRatio = 0.0; + } + helpers.inherit.call(b2FrictionJoint, Box2D.Dynamics.Joints.b2Joint); + b2FrictionJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; + b2FrictionJoint.b2FrictionJoint = function () { + Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + this.m_linearMass = new b2Mat22(); + this.m_linearImpulse = new b2Vec2(); + }; + b2FrictionJoint.prototype.GetAnchorA = function () { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA); + } + b2FrictionJoint.prototype.GetAnchorB = function () { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB); + } + b2FrictionJoint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return new b2Vec2(inv_dt * this.m_linearImpulse.x, inv_dt * this.m_linearImpulse.y); + } + b2FrictionJoint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return inv_dt * this.m_angularImpulse; + } + b2FrictionJoint.prototype.SetMaxForce = function (force) { + if (force === undefined) force = 0; + this.m_maxForce = force; + } + b2FrictionJoint.prototype.GetMaxForce = function () { + return this.m_maxForce; + } + b2FrictionJoint.prototype.SetMaxTorque = function (torque) { + if (torque === undefined) torque = 0; + this.m_maxTorque = torque; + } + b2FrictionJoint.prototype.GetMaxTorque = function () { + return this.m_maxTorque; + } + b2FrictionJoint.prototype.b2FrictionJoint = function (def) { + this.__super.b2Joint.call(this, def); + this.m_localAnchorA.SetV(def.localAnchorA); + this.m_localAnchorB.SetV(def.localAnchorB); + this.m_linearMass.SetZero(); + this.m_angularMass = 0.0; + this.m_linearImpulse.SetZero(); + this.m_angularImpulse = 0.0; + this.m_maxForce = def.maxForce; + this.m_maxTorque = def.maxTorque; + } + b2FrictionJoint.prototype.InitVelocityConstraints = function (step) { + var tMat; + var tX = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); + rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); + rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); + rBX = tX; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + var K = new b2Mat22(); + K.col1.x = mA + mB; + K.col2.x = 0.0; + K.col1.y = 0.0; + K.col2.y = mA + mB; + K.col1.x += iA * rAY * rAY; + K.col2.x += (-iA * rAX * rAY); + K.col1.y += (-iA * rAX * rAY); + K.col2.y += iA * rAX * rAX; + K.col1.x += iB * rBY * rBY; + K.col2.x += (-iB * rBX * rBY); + K.col1.y += (-iB * rBX * rBY); + K.col2.y += iB * rBX * rBX; + K.GetInverse(this.m_linearMass); + this.m_angularMass = iA + iB; + if (this.m_angularMass > 0.0) { + this.m_angularMass = 1.0 / this.m_angularMass; + } + if (step.warmStarting) { + this.m_linearImpulse.x *= step.dtRatio; + this.m_linearImpulse.y *= step.dtRatio; + this.m_angularImpulse *= step.dtRatio; + var P = this.m_linearImpulse; + bA.m_linearVelocity.x -= mA * P.x; + bA.m_linearVelocity.y -= mA * P.y; + bA.m_angularVelocity -= iA * (rAX * P.y - rAY * P.x + this.m_angularImpulse); + bB.m_linearVelocity.x += mB * P.x; + bB.m_linearVelocity.y += mB * P.y; + bB.m_angularVelocity += iB * (rBX * P.y - rBY * P.x + this.m_angularImpulse); + } + else { + this.m_linearImpulse.SetZero(); + this.m_angularImpulse = 0.0; + } + } + b2FrictionJoint.prototype.SolveVelocityConstraints = function (step) { + var tMat; + var tX = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var vA = bA.m_linearVelocity; + var wA = bA.m_angularVelocity; + var vB = bB.m_linearVelocity; + var wB = bB.m_angularVelocity; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); + rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); + rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); + rBX = tX; + var maxImpulse = 0; { + var Cdot = wB - wA; + var impulse = (-this.m_angularMass * Cdot); + var oldImpulse = this.m_angularImpulse; + maxImpulse = step.dt * this.m_maxTorque; + this.m_angularImpulse = b2Math.Clamp(this.m_angularImpulse + impulse, (-maxImpulse), maxImpulse); + impulse = this.m_angularImpulse - oldImpulse; + wA -= iA * impulse; + wB += iB * impulse; + } { + var CdotX = vB.x - wB * rBY - vA.x + wA * rAY; + var CdotY = vB.y + wB * rBX - vA.y - wA * rAX; + var impulseV = b2Math.MulMV(this.m_linearMass, new b2Vec2((-CdotX), (-CdotY))); + var oldImpulseV = this.m_linearImpulse.Copy(); + this.m_linearImpulse.Add(impulseV); + maxImpulse = step.dt * this.m_maxForce; + if (this.m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) { + this.m_linearImpulse.Normalize(); + this.m_linearImpulse.Multiply(maxImpulse); + } + impulseV = b2Math.SubtractVV(this.m_linearImpulse, oldImpulseV); + vA.x -= mA * impulseV.x; + vA.y -= mA * impulseV.y; + wA -= iA * (rAX * impulseV.y - rAY * impulseV.x); + vB.x += mB * impulseV.x; + vB.y += mB * impulseV.y; + wB += iB * (rBX * impulseV.y - rBY * impulseV.x); + } + bA.m_angularVelocity = wA; + bB.m_angularVelocity = wB; + } + b2FrictionJoint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + return true; + } + helpers.inherit.call(b2FrictionJointDef, Box2D.Dynamics.Joints.b2JointDef); + b2FrictionJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; + b2FrictionJointDef.b2FrictionJointDef = function () { + Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + }; + b2FrictionJointDef.prototype.b2FrictionJointDef = function () { + this.__super.b2JointDef.call(this); + this.type = b2Joint.e_frictionJoint; + this.maxForce = 0.0; + this.maxTorque = 0.0; + } + b2FrictionJointDef.prototype.Initialize = function (bA, bB, anchor) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); + this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)); + } + helpers.inherit.call(b2GearJoint, Box2D.Dynamics.Joints.b2Joint); + b2GearJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; + b2GearJoint.b2GearJoint = function () { + Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); + this.m_groundAnchor1 = new b2Vec2(); + this.m_groundAnchor2 = new b2Vec2(); + this.m_localAnchor1 = new b2Vec2(); + this.m_localAnchor2 = new b2Vec2(); + this.m_J = new b2Jacobian(); + }; + b2GearJoint.prototype.GetAnchorA = function () { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); + } + b2GearJoint.prototype.GetAnchorB = function () { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); + } + b2GearJoint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return new b2Vec2(inv_dt * this.m_impulse * this.m_J.linearB.x, inv_dt * this.m_impulse * this.m_J.linearB.y); + } + b2GearJoint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + var tMat = this.m_bodyB.m_xf.R; + var rX = this.m_localAnchor1.x - this.m_bodyB.m_sweep.localCenter.x; + var rY = this.m_localAnchor1.y - this.m_bodyB.m_sweep.localCenter.y; + var tX = tMat.col1.x * rX + tMat.col2.x * rY; + rY = tMat.col1.y * rX + tMat.col2.y * rY; + rX = tX; + var PX = this.m_impulse * this.m_J.linearB.x; + var PY = this.m_impulse * this.m_J.linearB.y; + return inv_dt * (this.m_impulse * this.m_J.angularB - rX * PY + rY * PX); + } + b2GearJoint.prototype.GetRatio = function () { + return this.m_ratio; + } + b2GearJoint.prototype.SetRatio = function (ratio) { + if (ratio === undefined) ratio = 0; + this.m_ratio = ratio; + } + b2GearJoint.prototype.b2GearJoint = function (def) { + this.__super.b2Joint.call(this, def); + var type1 = parseInt(def.joint1.m_type); + var type2 = parseInt(def.joint2.m_type); + this.m_revolute1 = null; + this.m_prismatic1 = null; + this.m_revolute2 = null; + this.m_prismatic2 = null; + var coordinate1 = 0; + var coordinate2 = 0; + this.m_ground1 = def.joint1.GetBodyA(); + this.m_bodyA = def.joint1.GetBodyB(); + if (type1 == b2Joint.e_revoluteJoint) { + this.m_revolute1 = (def.joint1 instanceof b2RevoluteJoint ? def.joint1 : null); + this.m_groundAnchor1.SetV(this.m_revolute1.m_localAnchor1); + this.m_localAnchor1.SetV(this.m_revolute1.m_localAnchor2); + coordinate1 = this.m_revolute1.GetJointAngle(); + } + else { + this.m_prismatic1 = (def.joint1 instanceof b2PrismaticJoint ? def.joint1 : null); + this.m_groundAnchor1.SetV(this.m_prismatic1.m_localAnchor1); + this.m_localAnchor1.SetV(this.m_prismatic1.m_localAnchor2); + coordinate1 = this.m_prismatic1.GetJointTranslation(); + } + this.m_ground2 = def.joint2.GetBodyA(); + this.m_bodyB = def.joint2.GetBodyB(); + if (type2 == b2Joint.e_revoluteJoint) { + this.m_revolute2 = (def.joint2 instanceof b2RevoluteJoint ? def.joint2 : null); + this.m_groundAnchor2.SetV(this.m_revolute2.m_localAnchor1); + this.m_localAnchor2.SetV(this.m_revolute2.m_localAnchor2); + coordinate2 = this.m_revolute2.GetJointAngle(); + } + else { + this.m_prismatic2 = (def.joint2 instanceof b2PrismaticJoint ? def.joint2 : null); + this.m_groundAnchor2.SetV(this.m_prismatic2.m_localAnchor1); + this.m_localAnchor2.SetV(this.m_prismatic2.m_localAnchor2); + coordinate2 = this.m_prismatic2.GetJointTranslation(); + } + this.m_ratio = def.ratio; + this.m_constant = coordinate1 + this.m_ratio * coordinate2; + this.m_impulse = 0.0; + } + b2GearJoint.prototype.InitVelocityConstraints = function (step) { + var g1 = this.m_ground1; + var g2 = this.m_ground2; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var ugX = 0; + var ugY = 0; + var rX = 0; + var rY = 0; + var tMat; + var tVec; + var crug = 0; + var tX = 0; + var K = 0.0; + this.m_J.SetZero(); + if (this.m_revolute1) { + this.m_J.angularA = (-1.0); + K += bA.m_invI; + } + else { + tMat = g1.m_xf.R; + tVec = this.m_prismatic1.m_localXAxis1; + ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = bA.m_xf.R; + rX = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + rY = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * rX + tMat.col2.x * rY; + rY = tMat.col1.y * rX + tMat.col2.y * rY; + rX = tX; + crug = rX * ugY - rY * ugX; + this.m_J.linearA.Set((-ugX), (-ugY)); + this.m_J.angularA = (-crug); + K += bA.m_invMass + bA.m_invI * crug * crug; + } + if (this.m_revolute2) { + this.m_J.angularB = (-this.m_ratio); + K += this.m_ratio * this.m_ratio * bB.m_invI; + } + else { + tMat = g2.m_xf.R; + tVec = this.m_prismatic2.m_localXAxis1; + ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = bB.m_xf.R; + rX = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + rY = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * rX + tMat.col2.x * rY; + rY = tMat.col1.y * rX + tMat.col2.y * rY; + rX = tX; + crug = rX * ugY - rY * ugX; + this.m_J.linearB.Set((-this.m_ratio * ugX), (-this.m_ratio * ugY)); + this.m_J.angularB = (-this.m_ratio * crug); + K += this.m_ratio * this.m_ratio * (bB.m_invMass + bB.m_invI * crug * crug); + } + this.m_mass = K > 0.0 ? 1.0 / K : 0.0; + if (step.warmStarting) { + bA.m_linearVelocity.x += bA.m_invMass * this.m_impulse * this.m_J.linearA.x; + bA.m_linearVelocity.y += bA.m_invMass * this.m_impulse * this.m_J.linearA.y; + bA.m_angularVelocity += bA.m_invI * this.m_impulse * this.m_J.angularA; + bB.m_linearVelocity.x += bB.m_invMass * this.m_impulse * this.m_J.linearB.x; + bB.m_linearVelocity.y += bB.m_invMass * this.m_impulse * this.m_J.linearB.y; + bB.m_angularVelocity += bB.m_invI * this.m_impulse * this.m_J.angularB; + } + else { + this.m_impulse = 0.0; + } + } + b2GearJoint.prototype.SolveVelocityConstraints = function (step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var Cdot = this.m_J.Compute(bA.m_linearVelocity, bA.m_angularVelocity, bB.m_linearVelocity, bB.m_angularVelocity); + var impulse = (-this.m_mass * Cdot); + this.m_impulse += impulse; + bA.m_linearVelocity.x += bA.m_invMass * impulse * this.m_J.linearA.x; + bA.m_linearVelocity.y += bA.m_invMass * impulse * this.m_J.linearA.y; + bA.m_angularVelocity += bA.m_invI * impulse * this.m_J.angularA; + bB.m_linearVelocity.x += bB.m_invMass * impulse * this.m_J.linearB.x; + bB.m_linearVelocity.y += bB.m_invMass * impulse * this.m_J.linearB.y; + bB.m_angularVelocity += bB.m_invI * impulse * this.m_J.angularB; + } + b2GearJoint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + var linearError = 0.0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var coordinate1 = 0; + var coordinate2 = 0; + if (this.m_revolute1) { + coordinate1 = this.m_revolute1.GetJointAngle(); + } + else { + coordinate1 = this.m_prismatic1.GetJointTranslation(); + } + if (this.m_revolute2) { + coordinate2 = this.m_revolute2.GetJointAngle(); + } + else { + coordinate2 = this.m_prismatic2.GetJointTranslation(); + } + var C = this.m_constant - (coordinate1 + this.m_ratio * coordinate2); + var impulse = (-this.m_mass * C); + bA.m_sweep.c.x += bA.m_invMass * impulse * this.m_J.linearA.x; + bA.m_sweep.c.y += bA.m_invMass * impulse * this.m_J.linearA.y; + bA.m_sweep.a += bA.m_invI * impulse * this.m_J.angularA; + bB.m_sweep.c.x += bB.m_invMass * impulse * this.m_J.linearB.x; + bB.m_sweep.c.y += bB.m_invMass * impulse * this.m_J.linearB.y; + bB.m_sweep.a += bB.m_invI * impulse * this.m_J.angularB; + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return linearError < b2Settings.b2_linearSlop; + } + helpers.inherit.call(b2GearJointDef, Box2D.Dynamics.Joints.b2JointDef); + b2GearJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; + b2GearJointDef.b2GearJointDef = function () { + Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); + }; + b2GearJointDef.prototype.b2GearJointDef = function () { + this.__super.b2JointDef.call(this); + this.type = b2Joint.e_gearJoint; + this.joint1 = null; + this.joint2 = null; + this.ratio = 1.0; + } + b2Jacobian.b2Jacobian = function () { + this.linearA = new b2Vec2(); + this.linearB = new b2Vec2(); + }; + b2Jacobian.prototype.SetZero = function () { + this.linearA.SetZero(); + this.angularA = 0.0; + this.linearB.SetZero(); + this.angularB = 0.0; + } + b2Jacobian.prototype.Set = function (x1, a1, x2, a2) { + if (a1 === undefined) a1 = 0; + if (a2 === undefined) a2 = 0; + this.linearA.SetV(x1); + this.angularA = a1; + this.linearB.SetV(x2); + this.angularB = a2; + } + b2Jacobian.prototype.Compute = function (x1, a1, x2, a2) { + if (a1 === undefined) a1 = 0; + if (a2 === undefined) a2 = 0; + return (this.linearA.x * x1.x + this.linearA.y * x1.y) + this.angularA * a1 + (this.linearB.x * x2.x + this.linearB.y * x2.y) + this.angularB * a2; + } + b2Joint.b2Joint = function () { + this.m_edgeA = new b2JointEdge(); + this.m_edgeB = new b2JointEdge(); + this.m_localCenterA = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + }; + b2Joint.prototype.GetType = function () { + return this.m_type; + } + b2Joint.prototype.GetAnchorA = function () { + return null; + } + b2Joint.prototype.GetAnchorB = function () { + return null; + } + b2Joint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return null; + } + b2Joint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return 0.0; + } + b2Joint.prototype.GetBodyA = function () { + return this.m_bodyA; + } + b2Joint.prototype.GetBodyB = function () { + return this.m_bodyB; + } + b2Joint.prototype.GetNext = function () { + return this.m_next; + } + b2Joint.prototype.GetUserData = function () { + return this.m_userData; + } + b2Joint.prototype.SetUserData = function (data) { + this.m_userData = data; + } + b2Joint.prototype.IsActive = function () { + return this.m_bodyA.IsActive() && this.m_bodyB.IsActive(); + } + b2Joint.prototype.Create = function (def, allocator) { + var joint = null; + switch (def.type) { + case b2Joint.e_distanceJoint: + { + joint = new b2DistanceJoint((def instanceof b2DistanceJointDef ? def : null)); + } + break; + case b2Joint.e_mouseJoint: + { + joint = new b2MouseJoint((def instanceof b2MouseJointDef ? def : null)); + } + break; + case b2Joint.e_prismaticJoint: + { + joint = new b2PrismaticJoint((def instanceof b2PrismaticJointDef ? def : null)); + } + break; + case b2Joint.e_revoluteJoint: + { + joint = new b2RevoluteJoint((def instanceof b2RevoluteJointDef ? def : null)); + } + break; + case b2Joint.e_pulleyJoint: + { + joint = new b2PulleyJoint((def instanceof b2PulleyJointDef ? def : null)); + } + break; + case b2Joint.e_gearJoint: + { + joint = new b2GearJoint((def instanceof b2GearJointDef ? def : null)); + } + break; + case b2Joint.e_lineJoint: + { + joint = new b2LineJoint((def instanceof b2LineJointDef ? def : null)); + } + break; + case b2Joint.e_weldJoint: + { + joint = new b2WeldJoint((def instanceof b2WeldJointDef ? def : null)); + } + break; + case b2Joint.e_frictionJoint: + { + joint = new b2FrictionJoint((def instanceof b2FrictionJointDef ? def : null)); + } + break; + default: + break; + } + return joint; + } + b2Joint.Create = b2Joint.prototype.Create; + b2Joint.prototype.Destroy = function (joint, allocator) {} + b2Joint.Destroy = b2Joint.prototype.Destroy; + b2Joint.prototype.b2Joint = function (def) { + b2Settings.b2Assert(def.bodyA != def.bodyB); + this.m_type = def.type; + this.m_prev = null; + this.m_next = null; + this.m_bodyA = def.bodyA; + this.m_bodyB = def.bodyB; + this.m_collideConnected = def.collideConnected; + this.m_islandFlag = false; + this.m_userData = def.userData; + } + b2Joint.prototype.InitVelocityConstraints = function (step) {} + b2Joint.prototype.SolveVelocityConstraints = function (step) {} + b2Joint.prototype.FinalizeVelocityConstraints = function () {} + b2Joint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + return false; + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.Joints.b2Joint.e_unknownJoint = 0; + Box2D.Dynamics.Joints.b2Joint.prototype.e_unknownJoint = Box2D.Dynamics.Joints.b2Joint.e_unknownJoint; + Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint = 1; + Box2D.Dynamics.Joints.b2Joint.prototype.e_revoluteJoint = Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint; + Box2D.Dynamics.Joints.b2Joint.e_prismaticJoint = 2; + Box2D.Dynamics.Joints.b2Joint.prototype.e_prismaticJoint = Box2D.Dynamics.Joints.b2Joint.e_prismaticJoint; + Box2D.Dynamics.Joints.b2Joint.e_distanceJoint = 3; + Box2D.Dynamics.Joints.b2Joint.prototype.e_distanceJoint = Box2D.Dynamics.Joints.b2Joint.e_distanceJoint; + Box2D.Dynamics.Joints.b2Joint.e_pulleyJoint = 4; + Box2D.Dynamics.Joints.b2Joint.prototype.e_pulleyJoint = Box2D.Dynamics.Joints.b2Joint.e_pulleyJoint; + Box2D.Dynamics.Joints.b2Joint.e_mouseJoint = 5; + Box2D.Dynamics.Joints.b2Joint.prototype.e_mouseJoint = Box2D.Dynamics.Joints.b2Joint.e_mouseJoint; + Box2D.Dynamics.Joints.b2Joint.e_gearJoint = 6; + Box2D.Dynamics.Joints.b2Joint.prototype.e_gearJoint = Box2D.Dynamics.Joints.b2Joint.e_gearJoint; + Box2D.Dynamics.Joints.b2Joint.e_lineJoint = 7; + Box2D.Dynamics.Joints.b2Joint.prototype.e_lineJoint = Box2D.Dynamics.Joints.b2Joint.e_lineJoint; + Box2D.Dynamics.Joints.b2Joint.e_weldJoint = 8; + Box2D.Dynamics.Joints.b2Joint.prototype.e_weldJoint = Box2D.Dynamics.Joints.b2Joint.e_weldJoint; + Box2D.Dynamics.Joints.b2Joint.e_frictionJoint = 9; + Box2D.Dynamics.Joints.b2Joint.prototype.e_frictionJoint = Box2D.Dynamics.Joints.b2Joint.e_frictionJoint; + Box2D.Dynamics.Joints.b2Joint.e_inactiveLimit = 0; + Box2D.Dynamics.Joints.b2Joint.prototype.e_inactiveLimit = Box2D.Dynamics.Joints.b2Joint.e_inactiveLimit; + Box2D.Dynamics.Joints.b2Joint.e_atLowerLimit = 1; + Box2D.Dynamics.Joints.b2Joint.prototype.e_atLowerLimit = Box2D.Dynamics.Joints.b2Joint.e_atLowerLimit; + Box2D.Dynamics.Joints.b2Joint.e_atUpperLimit = 2; + Box2D.Dynamics.Joints.b2Joint.prototype.e_atUpperLimit = Box2D.Dynamics.Joints.b2Joint.e_atUpperLimit; + Box2D.Dynamics.Joints.b2Joint.e_equalLimits = 3; + Box2D.Dynamics.Joints.b2Joint.prototype.e_equalLimits = Box2D.Dynamics.Joints.b2Joint.e_equalLimits; + }); + b2JointDef.b2JointDef = function () {}; + b2JointDef.prototype.b2JointDef = function () { + this.type = b2Joint.e_unknownJoint; + this.userData = null; + this.bodyA = null; + this.bodyB = null; + this.collideConnected = false; + } + b2JointEdge.b2JointEdge = function () {}; + helpers.inherit.call(b2LineJoint, Box2D.Dynamics.Joints.b2Joint); + b2LineJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; + b2LineJoint.b2LineJoint = function () { + Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); + this.m_localAnchor1 = new b2Vec2(); + this.m_localAnchor2 = new b2Vec2(); + this.m_localXAxis1 = new b2Vec2(); + this.m_localYAxis1 = new b2Vec2(); + this.m_axis = new b2Vec2(); + this.m_perp = new b2Vec2(); + this.m_K = new b2Mat22(); + this.m_impulse = new b2Vec2(); + }; + b2LineJoint.prototype.GetAnchorA = function () { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); + } + b2LineJoint.prototype.GetAnchorB = function () { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); + } + b2LineJoint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y)); + } + b2LineJoint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return inv_dt * this.m_impulse.y; + } + b2LineJoint.prototype.GetJointTranslation = function () { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var p1 = bA.GetWorldPoint(this.m_localAnchor1); + var p2 = bB.GetWorldPoint(this.m_localAnchor2); + var dX = p2.x - p1.x; + var dY = p2.y - p1.y; + var axis = bA.GetWorldVector(this.m_localXAxis1); + var translation = axis.x * dX + axis.y * dY; + return translation; + } + b2LineJoint.prototype.GetJointSpeed = function () { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var p1X = bA.m_sweep.c.x + r1X; + var p1Y = bA.m_sweep.c.y + r1Y; + var p2X = bB.m_sweep.c.x + r2X; + var p2Y = bB.m_sweep.c.y + r2Y; + var dX = p2X - p1X; + var dY = p2Y - p1Y; + var axis = bA.GetWorldVector(this.m_localXAxis1); + var v1 = bA.m_linearVelocity; + var v2 = bB.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var w2 = bB.m_angularVelocity; + var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X))); + return speed; + } + b2LineJoint.prototype.IsLimitEnabled = function () { + return this.m_enableLimit; + } + b2LineJoint.prototype.EnableLimit = function (flag) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableLimit = flag; + } + b2LineJoint.prototype.GetLowerLimit = function () { + return this.m_lowerTranslation; + } + b2LineJoint.prototype.GetUpperLimit = function () { + return this.m_upperTranslation; + } + b2LineJoint.prototype.SetLimits = function (lower, upper) { + if (lower === undefined) lower = 0; + if (upper === undefined) upper = 0; + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_lowerTranslation = lower; + this.m_upperTranslation = upper; + } + b2LineJoint.prototype.IsMotorEnabled = function () { + return this.m_enableMotor; + } + b2LineJoint.prototype.EnableMotor = function (flag) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableMotor = flag; + } + b2LineJoint.prototype.SetMotorSpeed = function (speed) { + if (speed === undefined) speed = 0; + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_motorSpeed = speed; + } + b2LineJoint.prototype.GetMotorSpeed = function () { + return this.m_motorSpeed; + } + b2LineJoint.prototype.SetMaxMotorForce = function (force) { + if (force === undefined) force = 0; + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_maxMotorForce = force; + } + b2LineJoint.prototype.GetMaxMotorForce = function () { + return this.m_maxMotorForce; + } + b2LineJoint.prototype.GetMotorForce = function () { + return this.m_motorImpulse; + } + b2LineJoint.prototype.b2LineJoint = function (def) { + this.__super.b2Joint.call(this, def); + var tMat; + var tX = 0; + var tY = 0; + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_localXAxis1.SetV(def.localAxisA); + this.m_localYAxis1.x = (-this.m_localXAxis1.y); + this.m_localYAxis1.y = this.m_localXAxis1.x; + this.m_impulse.SetZero(); + this.m_motorMass = 0.0; + this.m_motorImpulse = 0.0; + this.m_lowerTranslation = def.lowerTranslation; + this.m_upperTranslation = def.upperTranslation; + this.m_maxMotorForce = def.maxMotorForce; + this.m_motorSpeed = def.motorSpeed; + this.m_enableLimit = def.enableLimit; + this.m_enableMotor = def.enableMotor; + this.m_limitState = this.e_inactiveLimit; + this.m_axis.SetZero(); + this.m_perp.SetZero(); + } + b2LineJoint.prototype.InitVelocityConstraints = function (step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var tX = 0; + this.m_localCenterA.SetV(bA.GetLocalCenter()); + this.m_localCenterB.SetV(bB.GetLocalCenter()); + var xf1 = bA.GetTransform(); + var xf2 = bB.GetTransform(); + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; + var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; + var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + this.m_invMassA = bA.m_invMass; + this.m_invMassB = bB.m_invMass; + this.m_invIA = bA.m_invI; + this.m_invIB = bB.m_invI; { + this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); + this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; + this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; + this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; + this.m_motorMass = this.m_motorMass > Number.MIN_VALUE ? 1.0 / this.m_motorMass : 0.0; + } { + this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); + this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; + this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; + var m1 = this.m_invMassA; + var m2 = this.m_invMassB; + var i1 = this.m_invIA; + var i2 = this.m_invIB; + this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; + this.m_K.col2.x = this.m_K.col1.y; + this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; + } + if (this.m_enableLimit) { + var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; + if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { + this.m_limitState = this.e_equalLimits; + } + else if (jointTransition <= this.m_lowerTranslation) { + if (this.m_limitState != this.e_atLowerLimit) { + this.m_limitState = this.e_atLowerLimit; + this.m_impulse.y = 0.0; + } + } + else if (jointTransition >= this.m_upperTranslation) { + if (this.m_limitState != this.e_atUpperLimit) { + this.m_limitState = this.e_atUpperLimit; + this.m_impulse.y = 0.0; + } + } + else { + this.m_limitState = this.e_inactiveLimit; + this.m_impulse.y = 0.0; + } + } + else { + this.m_limitState = this.e_inactiveLimit; + } + if (this.m_enableMotor == false) { + this.m_motorImpulse = 0.0; + } + if (step.warmStarting) { + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + this.m_motorImpulse *= step.dtRatio; + var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x; + var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y; + var L1 = this.m_impulse.x * this.m_s1 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a1; + var L2 = this.m_impulse.x * this.m_s2 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a2; + bA.m_linearVelocity.x -= this.m_invMassA * PX; + bA.m_linearVelocity.y -= this.m_invMassA * PY; + bA.m_angularVelocity -= this.m_invIA * L1; + bB.m_linearVelocity.x += this.m_invMassB * PX; + bB.m_linearVelocity.y += this.m_invMassB * PY; + bB.m_angularVelocity += this.m_invIB * L2; + } + else { + this.m_impulse.SetZero(); + this.m_motorImpulse = 0.0; + } + } + b2LineJoint.prototype.SolveVelocityConstraints = function (step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var v1 = bA.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var v2 = bB.m_linearVelocity; + var w2 = bB.m_angularVelocity; + var PX = 0; + var PY = 0; + var L1 = 0; + var L2 = 0; + if (this.m_enableMotor && this.m_limitState != this.e_equalLimits) { + var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; + var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); + var oldImpulse = this.m_motorImpulse; + var maxImpulse = step.dt * this.m_maxMotorForce; + this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); + impulse = this.m_motorImpulse - oldImpulse; + PX = impulse * this.m_axis.x; + PY = impulse * this.m_axis.y; + L1 = impulse * this.m_a1; + L2 = impulse * this.m_a2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2; + } + var Cdot1 = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; + if (this.m_enableLimit && this.m_limitState != this.e_inactiveLimit) { + var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; + var f1 = this.m_impulse.Copy(); + var df = this.m_K.Solve(new b2Vec2(), (-Cdot1), (-Cdot2)); + this.m_impulse.Add(df); + if (this.m_limitState == this.e_atLowerLimit) { + this.m_impulse.y = b2Math.Max(this.m_impulse.y, 0.0); + } + else if (this.m_limitState == this.e_atUpperLimit) { + this.m_impulse.y = b2Math.Min(this.m_impulse.y, 0.0); + } + var b = (-Cdot1) - (this.m_impulse.y - f1.y) * this.m_K.col2.x; + var f2r = 0; + if (this.m_K.col1.x != 0.0) { + f2r = b / this.m_K.col1.x + f1.x; + } + else { + f2r = f1.x; + } + this.m_impulse.x = f2r; + df.x = this.m_impulse.x - f1.x; + df.y = this.m_impulse.y - f1.y; + PX = df.x * this.m_perp.x + df.y * this.m_axis.x; + PY = df.x * this.m_perp.y + df.y * this.m_axis.y; + L1 = df.x * this.m_s1 + df.y * this.m_a1; + L2 = df.x * this.m_s2 + df.y * this.m_a2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2; + } + else { + var df2 = 0; + if (this.m_K.col1.x != 0.0) { + df2 = ((-Cdot1)) / this.m_K.col1.x; + } + else { + df2 = 0.0; + } + this.m_impulse.x += df2; + PX = df2 * this.m_perp.x; + PY = df2 * this.m_perp.y; + L1 = df2 * this.m_s1; + L2 = df2 * this.m_s2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2; + } + bA.m_linearVelocity.SetV(v1); + bA.m_angularVelocity = w1; + bB.m_linearVelocity.SetV(v2); + bB.m_angularVelocity = w2; + } + b2LineJoint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + var limitC = 0; + var oldLimitImpulse = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var c1 = bA.m_sweep.c; + var a1 = bA.m_sweep.a; + var c2 = bB.m_sweep.c; + var a2 = bB.m_sweep.a; + var tMat; + var tX = 0; + var m1 = 0; + var m2 = 0; + var i1 = 0; + var i2 = 0; + var linearError = 0.0; + var angularError = 0.0; + var active = false; + var C2 = 0.0; + var R1 = b2Mat22.FromAngle(a1); + var R2 = b2Mat22.FromAngle(a2); + tMat = R1; + var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; + var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = R2; + var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; + var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var dX = c2.x + r2X - c1.x - r1X; + var dY = c2.y + r2Y - c1.y - r1Y; + if (this.m_enableLimit) { + this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); + this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; + this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; + var translation = this.m_axis.x * dX + this.m_axis.y * dY; + if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { + C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection); + linearError = b2Math.Abs(translation); + active = true; + } + else if (translation <= this.m_lowerTranslation) { + C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); + linearError = this.m_lowerTranslation - translation; + active = true; + } + else if (translation >= this.m_upperTranslation) { + C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection); + linearError = translation - this.m_upperTranslation; + active = true; + } + } + this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); + this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; + this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; + var impulse = new b2Vec2(); + var C1 = this.m_perp.x * dX + this.m_perp.y * dY; + linearError = b2Math.Max(linearError, b2Math.Abs(C1)); + angularError = 0.0; + if (active) { + m1 = this.m_invMassA; + m2 = this.m_invMassB; + i1 = this.m_invIA; + i2 = this.m_invIB; + this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; + this.m_K.col2.x = this.m_K.col1.y; + this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; + this.m_K.Solve(impulse, (-C1), (-C2)); + } + else { + m1 = this.m_invMassA; + m2 = this.m_invMassB; + i1 = this.m_invIA; + i2 = this.m_invIB; + var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + var impulse1 = 0; + if (k11 != 0.0) { + impulse1 = ((-C1)) / k11; + } + else { + impulse1 = 0.0; + } + impulse.x = impulse1; + impulse.y = 0.0; + } + var PX = impulse.x * this.m_perp.x + impulse.y * this.m_axis.x; + var PY = impulse.x * this.m_perp.y + impulse.y * this.m_axis.y; + var L1 = impulse.x * this.m_s1 + impulse.y * this.m_a1; + var L2 = impulse.x * this.m_s2 + impulse.y * this.m_a2; + c1.x -= this.m_invMassA * PX; + c1.y -= this.m_invMassA * PY; + a1 -= this.m_invIA * L1; + c2.x += this.m_invMassB * PX; + c2.y += this.m_invMassB * PY; + a2 += this.m_invIB * L2; + bA.m_sweep.a = a1; + bB.m_sweep.a = a2; + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; + } + helpers.inherit.call(b2LineJointDef, Box2D.Dynamics.Joints.b2JointDef); + b2LineJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; + b2LineJointDef.b2LineJointDef = function () { + Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + this.localAxisA = new b2Vec2(); + }; + b2LineJointDef.prototype.b2LineJointDef = function () { + this.__super.b2JointDef.call(this); + this.type = b2Joint.e_lineJoint; + this.localAxisA.Set(1.0, 0.0); + this.enableLimit = false; + this.lowerTranslation = 0.0; + this.upperTranslation = 0.0; + this.enableMotor = false; + this.maxMotorForce = 0.0; + this.motorSpeed = 0.0; + } + b2LineJointDef.prototype.Initialize = function (bA, bB, anchor, axis) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA = this.bodyA.GetLocalPoint(anchor); + this.localAnchorB = this.bodyB.GetLocalPoint(anchor); + this.localAxisA = this.bodyA.GetLocalVector(axis); + } + helpers.inherit.call(b2MouseJoint, Box2D.Dynamics.Joints.b2Joint); + b2MouseJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; + b2MouseJoint.b2MouseJoint = function () { + Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); + this.K = new b2Mat22(); + this.K1 = new b2Mat22(); + this.K2 = new b2Mat22(); + this.m_localAnchor = new b2Vec2(); + this.m_target = new b2Vec2(); + this.m_impulse = new b2Vec2(); + this.m_mass = new b2Mat22(); + this.m_C = new b2Vec2(); + }; + b2MouseJoint.prototype.GetAnchorA = function () { + return this.m_target; + } + b2MouseJoint.prototype.GetAnchorB = function () { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor); + } + b2MouseJoint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y); + } + b2MouseJoint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return 0.0; + } + b2MouseJoint.prototype.GetTarget = function () { + return this.m_target; + } + b2MouseJoint.prototype.SetTarget = function (target) { + if (this.m_bodyB.IsAwake() == false) { + this.m_bodyB.SetAwake(true); + } + this.m_target = target; + } + b2MouseJoint.prototype.GetMaxForce = function () { + return this.m_maxForce; + } + b2MouseJoint.prototype.SetMaxForce = function (maxForce) { + if (maxForce === undefined) maxForce = 0; + this.m_maxForce = maxForce; + } + b2MouseJoint.prototype.GetFrequency = function () { + return this.m_frequencyHz; + } + b2MouseJoint.prototype.SetFrequency = function (hz) { + if (hz === undefined) hz = 0; + this.m_frequencyHz = hz; + } + b2MouseJoint.prototype.GetDampingRatio = function () { + return this.m_dampingRatio; + } + b2MouseJoint.prototype.SetDampingRatio = function (ratio) { + if (ratio === undefined) ratio = 0; + this.m_dampingRatio = ratio; + } + b2MouseJoint.prototype.b2MouseJoint = function (def) { + this.__super.b2Joint.call(this, def); + this.m_target.SetV(def.target); + var tX = this.m_target.x - this.m_bodyB.m_xf.position.x; + var tY = this.m_target.y - this.m_bodyB.m_xf.position.y; + var tMat = this.m_bodyB.m_xf.R; + this.m_localAnchor.x = (tX * tMat.col1.x + tY * tMat.col1.y); + this.m_localAnchor.y = (tX * tMat.col2.x + tY * tMat.col2.y); + this.m_maxForce = def.maxForce; + this.m_impulse.SetZero(); + this.m_frequencyHz = def.frequencyHz; + this.m_dampingRatio = def.dampingRatio; + this.m_beta = 0.0; + this.m_gamma = 0.0; + } + b2MouseJoint.prototype.InitVelocityConstraints = function (step) { + var b = this.m_bodyB; + var mass = b.GetMass(); + var omega = 2.0 * Math.PI * this.m_frequencyHz; + var d = 2.0 * mass * this.m_dampingRatio * omega; + var k = mass * omega * omega; + this.m_gamma = step.dt * (d + step.dt * k); + this.m_gamma = this.m_gamma != 0 ? 1 / this.m_gamma : 0.0; + this.m_beta = step.dt * k * this.m_gamma; + var tMat;tMat = b.m_xf.R; + var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; + var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; + var tX = (tMat.col1.x * rX + tMat.col2.x * rY);rY = (tMat.col1.y * rX + tMat.col2.y * rY); + rX = tX; + var invMass = b.m_invMass; + var invI = b.m_invI;this.K1.col1.x = invMass; + this.K1.col2.x = 0.0; + this.K1.col1.y = 0.0; + this.K1.col2.y = invMass; + this.K2.col1.x = invI * rY * rY; + this.K2.col2.x = (-invI * rX * rY); + this.K2.col1.y = (-invI * rX * rY); + this.K2.col2.y = invI * rX * rX; + this.K.SetM(this.K1); + this.K.AddM(this.K2); + this.K.col1.x += this.m_gamma; + this.K.col2.y += this.m_gamma; + this.K.GetInverse(this.m_mass); + this.m_C.x = b.m_sweep.c.x + rX - this.m_target.x; + this.m_C.y = b.m_sweep.c.y + rY - this.m_target.y; + b.m_angularVelocity *= 0.98; + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + b.m_linearVelocity.x += invMass * this.m_impulse.x; + b.m_linearVelocity.y += invMass * this.m_impulse.y; + b.m_angularVelocity += invI * (rX * this.m_impulse.y - rY * this.m_impulse.x); + } + b2MouseJoint.prototype.SolveVelocityConstraints = function (step) { + var b = this.m_bodyB; + var tMat; + var tX = 0; + var tY = 0; + tMat = b.m_xf.R; + var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; + var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; + tX = (tMat.col1.x * rX + tMat.col2.x * rY); + rY = (tMat.col1.y * rX + tMat.col2.y * rY); + rX = tX; + var CdotX = b.m_linearVelocity.x + ((-b.m_angularVelocity * rY)); + var CdotY = b.m_linearVelocity.y + (b.m_angularVelocity * rX); + tMat = this.m_mass; + tX = CdotX + this.m_beta * this.m_C.x + this.m_gamma * this.m_impulse.x; + tY = CdotY + this.m_beta * this.m_C.y + this.m_gamma * this.m_impulse.y; + var impulseX = (-(tMat.col1.x * tX + tMat.col2.x * tY)); + var impulseY = (-(tMat.col1.y * tX + tMat.col2.y * tY)); + var oldImpulseX = this.m_impulse.x; + var oldImpulseY = this.m_impulse.y; + this.m_impulse.x += impulseX; + this.m_impulse.y += impulseY; + var maxImpulse = step.dt * this.m_maxForce; + if (this.m_impulse.LengthSquared() > maxImpulse * maxImpulse) { + this.m_impulse.Multiply(maxImpulse / this.m_impulse.Length()); + } + impulseX = this.m_impulse.x - oldImpulseX; + impulseY = this.m_impulse.y - oldImpulseY; + b.m_linearVelocity.x += b.m_invMass * impulseX; + b.m_linearVelocity.y += b.m_invMass * impulseY; + b.m_angularVelocity += b.m_invI * (rX * impulseY - rY * impulseX); + } + b2MouseJoint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + return true; + } + helpers.inherit.call(b2MouseJointDef, Box2D.Dynamics.Joints.b2JointDef); + b2MouseJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; + b2MouseJointDef.b2MouseJointDef = function () { + Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); + this.target = new b2Vec2(); + }; + b2MouseJointDef.prototype.b2MouseJointDef = function () { + this.__super.b2JointDef.call(this); + this.type = b2Joint.e_mouseJoint; + this.maxForce = 0.0; + this.frequencyHz = 5.0; + this.dampingRatio = 0.7; + } + helpers.inherit.call(b2PrismaticJoint, Box2D.Dynamics.Joints.b2Joint); + b2PrismaticJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; + b2PrismaticJoint.b2PrismaticJoint = function () { + Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); + this.m_localAnchor1 = new b2Vec2(); + this.m_localAnchor2 = new b2Vec2(); + this.m_localXAxis1 = new b2Vec2(); + this.m_localYAxis1 = new b2Vec2(); + this.m_axis = new b2Vec2(); + this.m_perp = new b2Vec2(); + this.m_K = new b2Mat33(); + this.m_impulse = new b2Vec3(); + }; + b2PrismaticJoint.prototype.GetAnchorA = function () { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); + } + b2PrismaticJoint.prototype.GetAnchorB = function () { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); + } + b2PrismaticJoint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y)); + } + b2PrismaticJoint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return inv_dt * this.m_impulse.y; + } + b2PrismaticJoint.prototype.GetJointTranslation = function () { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var p1 = bA.GetWorldPoint(this.m_localAnchor1); + var p2 = bB.GetWorldPoint(this.m_localAnchor2); + var dX = p2.x - p1.x; + var dY = p2.y - p1.y; + var axis = bA.GetWorldVector(this.m_localXAxis1); + var translation = axis.x * dX + axis.y * dY; + return translation; + } + b2PrismaticJoint.prototype.GetJointSpeed = function () { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var p1X = bA.m_sweep.c.x + r1X; + var p1Y = bA.m_sweep.c.y + r1Y; + var p2X = bB.m_sweep.c.x + r2X; + var p2Y = bB.m_sweep.c.y + r2Y; + var dX = p2X - p1X; + var dY = p2Y - p1Y; + var axis = bA.GetWorldVector(this.m_localXAxis1); + var v1 = bA.m_linearVelocity; + var v2 = bB.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var w2 = bB.m_angularVelocity; + var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X))); + return speed; + } + b2PrismaticJoint.prototype.IsLimitEnabled = function () { + return this.m_enableLimit; + } + b2PrismaticJoint.prototype.EnableLimit = function (flag) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableLimit = flag; + } + b2PrismaticJoint.prototype.GetLowerLimit = function () { + return this.m_lowerTranslation; + } + b2PrismaticJoint.prototype.GetUpperLimit = function () { + return this.m_upperTranslation; + } + b2PrismaticJoint.prototype.SetLimits = function (lower, upper) { + if (lower === undefined) lower = 0; + if (upper === undefined) upper = 0; + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_lowerTranslation = lower; + this.m_upperTranslation = upper; + } + b2PrismaticJoint.prototype.IsMotorEnabled = function () { + return this.m_enableMotor; + } + b2PrismaticJoint.prototype.EnableMotor = function (flag) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableMotor = flag; + } + b2PrismaticJoint.prototype.SetMotorSpeed = function (speed) { + if (speed === undefined) speed = 0; + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_motorSpeed = speed; + } + b2PrismaticJoint.prototype.GetMotorSpeed = function () { + return this.m_motorSpeed; + } + b2PrismaticJoint.prototype.SetMaxMotorForce = function (force) { + if (force === undefined) force = 0; + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_maxMotorForce = force; + } + b2PrismaticJoint.prototype.GetMotorForce = function () { + return this.m_motorImpulse; + } + b2PrismaticJoint.prototype.b2PrismaticJoint = function (def) { + this.__super.b2Joint.call(this, def); + var tMat; + var tX = 0; + var tY = 0; + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_localXAxis1.SetV(def.localAxisA); + this.m_localYAxis1.x = (-this.m_localXAxis1.y); + this.m_localYAxis1.y = this.m_localXAxis1.x; + this.m_refAngle = def.referenceAngle; + this.m_impulse.SetZero(); + this.m_motorMass = 0.0; + this.m_motorImpulse = 0.0; + this.m_lowerTranslation = def.lowerTranslation; + this.m_upperTranslation = def.upperTranslation; + this.m_maxMotorForce = def.maxMotorForce; + this.m_motorSpeed = def.motorSpeed; + this.m_enableLimit = def.enableLimit; + this.m_enableMotor = def.enableMotor; + this.m_limitState = this.e_inactiveLimit; + this.m_axis.SetZero(); + this.m_perp.SetZero(); + } + b2PrismaticJoint.prototype.InitVelocityConstraints = function (step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var tX = 0; + this.m_localCenterA.SetV(bA.GetLocalCenter()); + this.m_localCenterB.SetV(bB.GetLocalCenter()); + var xf1 = bA.GetTransform(); + var xf2 = bB.GetTransform(); + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; + var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; + var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + this.m_invMassA = bA.m_invMass; + this.m_invMassB = bB.m_invMass; + this.m_invIA = bA.m_invI; + this.m_invIB = bB.m_invI; { + this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); + this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; + this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; + this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; + if (this.m_motorMass > Number.MIN_VALUE) this.m_motorMass = 1.0 / this.m_motorMass; + } { + this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); + this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; + this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; + var m1 = this.m_invMassA; + var m2 = this.m_invMassB; + var i1 = this.m_invIA; + var i2 = this.m_invIB; + this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; + this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; + this.m_K.col2.x = this.m_K.col1.y; + this.m_K.col2.y = i1 + i2; + this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; + this.m_K.col3.x = this.m_K.col1.z; + this.m_K.col3.y = this.m_K.col2.z; + this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; + } + if (this.m_enableLimit) { + var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; + if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { + this.m_limitState = this.e_equalLimits; + } + else if (jointTransition <= this.m_lowerTranslation) { + if (this.m_limitState != this.e_atLowerLimit) { + this.m_limitState = this.e_atLowerLimit; + this.m_impulse.z = 0.0; + } + } + else if (jointTransition >= this.m_upperTranslation) { + if (this.m_limitState != this.e_atUpperLimit) { + this.m_limitState = this.e_atUpperLimit; + this.m_impulse.z = 0.0; + } + } + else { + this.m_limitState = this.e_inactiveLimit; + this.m_impulse.z = 0.0; + } + } + else { + this.m_limitState = this.e_inactiveLimit; + } + if (this.m_enableMotor == false) { + this.m_motorImpulse = 0.0; + } + if (step.warmStarting) { + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + this.m_motorImpulse *= step.dtRatio; + var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x; + var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y; + var L1 = this.m_impulse.x * this.m_s1 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a1; + var L2 = this.m_impulse.x * this.m_s2 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a2; + bA.m_linearVelocity.x -= this.m_invMassA * PX; + bA.m_linearVelocity.y -= this.m_invMassA * PY; + bA.m_angularVelocity -= this.m_invIA * L1; + bB.m_linearVelocity.x += this.m_invMassB * PX; + bB.m_linearVelocity.y += this.m_invMassB * PY; + bB.m_angularVelocity += this.m_invIB * L2; + } + else { + this.m_impulse.SetZero(); + this.m_motorImpulse = 0.0; + } + } + b2PrismaticJoint.prototype.SolveVelocityConstraints = function (step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var v1 = bA.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var v2 = bB.m_linearVelocity; + var w2 = bB.m_angularVelocity; + var PX = 0; + var PY = 0; + var L1 = 0; + var L2 = 0; + if (this.m_enableMotor && this.m_limitState != this.e_equalLimits) { + var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; + var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); + var oldImpulse = this.m_motorImpulse; + var maxImpulse = step.dt * this.m_maxMotorForce; + this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); + impulse = this.m_motorImpulse - oldImpulse; + PX = impulse * this.m_axis.x; + PY = impulse * this.m_axis.y; + L1 = impulse * this.m_a1; + L2 = impulse * this.m_a2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2; + } + var Cdot1X = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; + var Cdot1Y = w2 - w1; + if (this.m_enableLimit && this.m_limitState != this.e_inactiveLimit) { + var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; + var f1 = this.m_impulse.Copy(); + var df = this.m_K.Solve33(new b2Vec3(), (-Cdot1X), (-Cdot1Y), (-Cdot2)); + this.m_impulse.Add(df); + if (this.m_limitState == this.e_atLowerLimit) { + this.m_impulse.z = b2Math.Max(this.m_impulse.z, 0.0); + } + else if (this.m_limitState == this.e_atUpperLimit) { + this.m_impulse.z = b2Math.Min(this.m_impulse.z, 0.0); + } + var bX = (-Cdot1X) - (this.m_impulse.z - f1.z) * this.m_K.col3.x; + var bY = (-Cdot1Y) - (this.m_impulse.z - f1.z) * this.m_K.col3.y; + var f2r = this.m_K.Solve22(new b2Vec2(), bX, bY); + f2r.x += f1.x; + f2r.y += f1.y; + this.m_impulse.x = f2r.x; + this.m_impulse.y = f2r.y; + df.x = this.m_impulse.x - f1.x; + df.y = this.m_impulse.y - f1.y; + df.z = this.m_impulse.z - f1.z; + PX = df.x * this.m_perp.x + df.z * this.m_axis.x; + PY = df.x * this.m_perp.y + df.z * this.m_axis.y; + L1 = df.x * this.m_s1 + df.y + df.z * this.m_a1; + L2 = df.x * this.m_s2 + df.y + df.z * this.m_a2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2; + } + else { + var df2 = this.m_K.Solve22(new b2Vec2(), (-Cdot1X), (-Cdot1Y)); + this.m_impulse.x += df2.x; + this.m_impulse.y += df2.y; + PX = df2.x * this.m_perp.x; + PY = df2.x * this.m_perp.y; + L1 = df2.x * this.m_s1 + df2.y; + L2 = df2.x * this.m_s2 + df2.y; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2; + } + bA.m_linearVelocity.SetV(v1); + bA.m_angularVelocity = w1; + bB.m_linearVelocity.SetV(v2); + bB.m_angularVelocity = w2; + } + b2PrismaticJoint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + var limitC = 0; + var oldLimitImpulse = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var c1 = bA.m_sweep.c; + var a1 = bA.m_sweep.a; + var c2 = bB.m_sweep.c; + var a2 = bB.m_sweep.a; + var tMat; + var tX = 0; + var m1 = 0; + var m2 = 0; + var i1 = 0; + var i2 = 0; + var linearError = 0.0; + var angularError = 0.0; + var active = false; + var C2 = 0.0; + var R1 = b2Mat22.FromAngle(a1); + var R2 = b2Mat22.FromAngle(a2); + tMat = R1; + var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; + var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = R2; + var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; + var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var dX = c2.x + r2X - c1.x - r1X; + var dY = c2.y + r2Y - c1.y - r1Y; + if (this.m_enableLimit) { + this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); + this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; + this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; + var translation = this.m_axis.x * dX + this.m_axis.y * dY; + if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { + C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection); + linearError = b2Math.Abs(translation); + active = true; + } + else if (translation <= this.m_lowerTranslation) { + C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); + linearError = this.m_lowerTranslation - translation; + active = true; + } + else if (translation >= this.m_upperTranslation) { + C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection); + linearError = translation - this.m_upperTranslation; + active = true; + } + } + this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); + this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; + this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; + var impulse = new b2Vec3(); + var C1X = this.m_perp.x * dX + this.m_perp.y * dY; + var C1Y = a2 - a1 - this.m_refAngle; + linearError = b2Math.Max(linearError, b2Math.Abs(C1X)); + angularError = b2Math.Abs(C1Y); + if (active) { + m1 = this.m_invMassA; + m2 = this.m_invMassB; + i1 = this.m_invIA; + i2 = this.m_invIB; + this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; + this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; + this.m_K.col2.x = this.m_K.col1.y; + this.m_K.col2.y = i1 + i2; + this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; + this.m_K.col3.x = this.m_K.col1.z; + this.m_K.col3.y = this.m_K.col2.z; + this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; + this.m_K.Solve33(impulse, (-C1X), (-C1Y), (-C2)); + } + else { + m1 = this.m_invMassA; + m2 = this.m_invMassB; + i1 = this.m_invIA; + i2 = this.m_invIB; + var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + var k12 = i1 * this.m_s1 + i2 * this.m_s2; + var k22 = i1 + i2; + this.m_K.col1.Set(k11, k12, 0.0); + this.m_K.col2.Set(k12, k22, 0.0); + var impulse1 = this.m_K.Solve22(new b2Vec2(), (-C1X), (-C1Y)); + impulse.x = impulse1.x; + impulse.y = impulse1.y; + impulse.z = 0.0; + } + var PX = impulse.x * this.m_perp.x + impulse.z * this.m_axis.x; + var PY = impulse.x * this.m_perp.y + impulse.z * this.m_axis.y; + var L1 = impulse.x * this.m_s1 + impulse.y + impulse.z * this.m_a1; + var L2 = impulse.x * this.m_s2 + impulse.y + impulse.z * this.m_a2; + c1.x -= this.m_invMassA * PX; + c1.y -= this.m_invMassA * PY; + a1 -= this.m_invIA * L1; + c2.x += this.m_invMassB * PX; + c2.y += this.m_invMassB * PY; + a2 += this.m_invIB * L2; + bA.m_sweep.a = a1; + bB.m_sweep.a = a2; + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; + } + helpers.inherit.call(b2PrismaticJointDef, Box2D.Dynamics.Joints.b2JointDef); + b2PrismaticJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; + b2PrismaticJointDef.b2PrismaticJointDef = function () { + Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + this.localAxisA = new b2Vec2(); + }; + b2PrismaticJointDef.prototype.b2PrismaticJointDef = function () { + this.__super.b2JointDef.call(this); + this.type = b2Joint.e_prismaticJoint; + this.localAxisA.Set(1.0, 0.0); + this.referenceAngle = 0.0; + this.enableLimit = false; + this.lowerTranslation = 0.0; + this.upperTranslation = 0.0; + this.enableMotor = false; + this.maxMotorForce = 0.0; + this.motorSpeed = 0.0; + } + b2PrismaticJointDef.prototype.Initialize = function (bA, bB, anchor, axis) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA = this.bodyA.GetLocalPoint(anchor); + this.localAnchorB = this.bodyB.GetLocalPoint(anchor); + this.localAxisA = this.bodyA.GetLocalVector(axis); + this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); + } + helpers.inherit.call(b2PulleyJoint, Box2D.Dynamics.Joints.b2Joint); + b2PulleyJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; + b2PulleyJoint.b2PulleyJoint = function () { + Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); + this.m_groundAnchor1 = new b2Vec2(); + this.m_groundAnchor2 = new b2Vec2(); + this.m_localAnchor1 = new b2Vec2(); + this.m_localAnchor2 = new b2Vec2(); + this.m_u1 = new b2Vec2(); + this.m_u2 = new b2Vec2(); + }; + b2PulleyJoint.prototype.GetAnchorA = function () { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); + } + b2PulleyJoint.prototype.GetAnchorB = function () { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); + } + b2PulleyJoint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return new b2Vec2(inv_dt * this.m_impulse * this.m_u2.x, inv_dt * this.m_impulse * this.m_u2.y); + } + b2PulleyJoint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return 0.0; + } + b2PulleyJoint.prototype.GetGroundAnchorA = function () { + var a = this.m_ground.m_xf.position.Copy(); + a.Add(this.m_groundAnchor1); + return a; + } + b2PulleyJoint.prototype.GetGroundAnchorB = function () { + var a = this.m_ground.m_xf.position.Copy(); + a.Add(this.m_groundAnchor2); + return a; + } + b2PulleyJoint.prototype.GetLength1 = function () { + var p = this.m_bodyA.GetWorldPoint(this.m_localAnchor1); + var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; + var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; + var dX = p.x - sX; + var dY = p.y - sY; + return Math.sqrt(dX * dX + dY * dY); + } + b2PulleyJoint.prototype.GetLength2 = function () { + var p = this.m_bodyB.GetWorldPoint(this.m_localAnchor2); + var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; + var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; + var dX = p.x - sX; + var dY = p.y - sY; + return Math.sqrt(dX * dX + dY * dY); + } + b2PulleyJoint.prototype.GetRatio = function () { + return this.m_ratio; + } + b2PulleyJoint.prototype.b2PulleyJoint = function (def) { + this.__super.b2Joint.call(this, def); + var tMat; + var tX = 0; + var tY = 0; + this.m_ground = this.m_bodyA.m_world.m_groundBody; + this.m_groundAnchor1.x = def.groundAnchorA.x - this.m_ground.m_xf.position.x; + this.m_groundAnchor1.y = def.groundAnchorA.y - this.m_ground.m_xf.position.y; + this.m_groundAnchor2.x = def.groundAnchorB.x - this.m_ground.m_xf.position.x; + this.m_groundAnchor2.y = def.groundAnchorB.y - this.m_ground.m_xf.position.y; + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_ratio = def.ratio; + this.m_constant = def.lengthA + this.m_ratio * def.lengthB; + this.m_maxLength1 = b2Math.Min(def.maxLengthA, this.m_constant - this.m_ratio * b2PulleyJoint.b2_minPulleyLength); + this.m_maxLength2 = b2Math.Min(def.maxLengthB, (this.m_constant - b2PulleyJoint.b2_minPulleyLength) / this.m_ratio); + this.m_impulse = 0.0; + this.m_limitImpulse1 = 0.0; + this.m_limitImpulse2 = 0.0; + } + b2PulleyJoint.prototype.InitVelocityConstraints = function (step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var p1X = bA.m_sweep.c.x + r1X; + var p1Y = bA.m_sweep.c.y + r1Y; + var p2X = bB.m_sweep.c.x + r2X; + var p2Y = bB.m_sweep.c.y + r2Y; + var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; + var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; + var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; + var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; + this.m_u1.Set(p1X - s1X, p1Y - s1Y); + this.m_u2.Set(p2X - s2X, p2Y - s2Y); + var length1 = this.m_u1.Length(); + var length2 = this.m_u2.Length(); + if (length1 > b2Settings.b2_linearSlop) { + this.m_u1.Multiply(1.0 / length1); + } + else { + this.m_u1.SetZero(); + } + if (length2 > b2Settings.b2_linearSlop) { + this.m_u2.Multiply(1.0 / length2); + } + else { + this.m_u2.SetZero(); + } + var C = this.m_constant - length1 - this.m_ratio * length2; + if (C > 0.0) { + this.m_state = this.e_inactiveLimit; + this.m_impulse = 0.0; + } + else { + this.m_state = this.e_atUpperLimit; + } + if (length1 < this.m_maxLength1) { + this.m_limitState1 = this.e_inactiveLimit; + this.m_limitImpulse1 = 0.0; + } + else { + this.m_limitState1 = this.e_atUpperLimit; + } + if (length2 < this.m_maxLength2) { + this.m_limitState2 = this.e_inactiveLimit; + this.m_limitImpulse2 = 0.0; + } + else { + this.m_limitState2 = this.e_atUpperLimit; + } + var cr1u1 = r1X * this.m_u1.y - r1Y * this.m_u1.x; + var cr2u2 = r2X * this.m_u2.y - r2Y * this.m_u2.x; + this.m_limitMass1 = bA.m_invMass + bA.m_invI * cr1u1 * cr1u1; + this.m_limitMass2 = bB.m_invMass + bB.m_invI * cr2u2 * cr2u2; + this.m_pulleyMass = this.m_limitMass1 + this.m_ratio * this.m_ratio * this.m_limitMass2; + this.m_limitMass1 = 1.0 / this.m_limitMass1; + this.m_limitMass2 = 1.0 / this.m_limitMass2; + this.m_pulleyMass = 1.0 / this.m_pulleyMass; + if (step.warmStarting) { + this.m_impulse *= step.dtRatio; + this.m_limitImpulse1 *= step.dtRatio; + this.m_limitImpulse2 *= step.dtRatio; + var P1X = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.x; + var P1Y = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.y; + var P2X = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.x; + var P2Y = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.y; + bA.m_linearVelocity.x += bA.m_invMass * P1X; + bA.m_linearVelocity.y += bA.m_invMass * P1Y; + bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); + bB.m_linearVelocity.x += bB.m_invMass * P2X; + bB.m_linearVelocity.y += bB.m_invMass * P2Y; + bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X); + } + else { + this.m_impulse = 0.0; + this.m_limitImpulse1 = 0.0; + this.m_limitImpulse2 = 0.0; + } + } + b2PulleyJoint.prototype.SolveVelocityConstraints = function (step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var v1X = 0; + var v1Y = 0; + var v2X = 0; + var v2Y = 0; + var P1X = 0; + var P1Y = 0; + var P2X = 0; + var P2Y = 0; + var Cdot = 0; + var impulse = 0; + var oldImpulse = 0; + if (this.m_state == this.e_atUpperLimit) { + v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y)); + v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X); + v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y)); + v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X); + Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y)) - this.m_ratio * (this.m_u2.x * v2X + this.m_u2.y * v2Y); + impulse = this.m_pulleyMass * ((-Cdot)); + oldImpulse = this.m_impulse; + this.m_impulse = b2Math.Max(0.0, this.m_impulse + impulse); + impulse = this.m_impulse - oldImpulse; + P1X = (-impulse * this.m_u1.x); + P1Y = (-impulse * this.m_u1.y); + P2X = (-this.m_ratio * impulse * this.m_u2.x); + P2Y = (-this.m_ratio * impulse * this.m_u2.y); + bA.m_linearVelocity.x += bA.m_invMass * P1X; + bA.m_linearVelocity.y += bA.m_invMass * P1Y; + bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); + bB.m_linearVelocity.x += bB.m_invMass * P2X; + bB.m_linearVelocity.y += bB.m_invMass * P2Y; + bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X); + } + if (this.m_limitState1 == this.e_atUpperLimit) { + v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y)); + v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X); + Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y)); + impulse = (-this.m_limitMass1 * Cdot); + oldImpulse = this.m_limitImpulse1; + this.m_limitImpulse1 = b2Math.Max(0.0, this.m_limitImpulse1 + impulse); + impulse = this.m_limitImpulse1 - oldImpulse; + P1X = (-impulse * this.m_u1.x); + P1Y = (-impulse * this.m_u1.y); + bA.m_linearVelocity.x += bA.m_invMass * P1X; + bA.m_linearVelocity.y += bA.m_invMass * P1Y; + bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); + } + if (this.m_limitState2 == this.e_atUpperLimit) { + v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y)); + v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X); + Cdot = (-(this.m_u2.x * v2X + this.m_u2.y * v2Y)); + impulse = (-this.m_limitMass2 * Cdot); + oldImpulse = this.m_limitImpulse2; + this.m_limitImpulse2 = b2Math.Max(0.0, this.m_limitImpulse2 + impulse); + impulse = this.m_limitImpulse2 - oldImpulse; + P2X = (-impulse * this.m_u2.x); + P2Y = (-impulse * this.m_u2.y); + bB.m_linearVelocity.x += bB.m_invMass * P2X; + bB.m_linearVelocity.y += bB.m_invMass * P2Y; + bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X); + } + } + b2PulleyJoint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; + var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; + var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; + var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; + var r1X = 0; + var r1Y = 0; + var r2X = 0; + var r2Y = 0; + var p1X = 0; + var p1Y = 0; + var p2X = 0; + var p2Y = 0; + var length1 = 0; + var length2 = 0; + var C = 0; + var impulse = 0; + var oldImpulse = 0; + var oldLimitPositionImpulse = 0; + var tX = 0; + var linearError = 0.0; + if (this.m_state == this.e_atUpperLimit) { + tMat = bA.m_xf.R; + r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + p1X = bA.m_sweep.c.x + r1X; + p1Y = bA.m_sweep.c.y + r1Y; + p2X = bB.m_sweep.c.x + r2X; + p2Y = bB.m_sweep.c.y + r2Y; + this.m_u1.Set(p1X - s1X, p1Y - s1Y); + this.m_u2.Set(p2X - s2X, p2Y - s2Y); + length1 = this.m_u1.Length(); + length2 = this.m_u2.Length(); + if (length1 > b2Settings.b2_linearSlop) { + this.m_u1.Multiply(1.0 / length1); + } + else { + this.m_u1.SetZero(); + } + if (length2 > b2Settings.b2_linearSlop) { + this.m_u2.Multiply(1.0 / length2); + } + else { + this.m_u2.SetZero(); + } + C = this.m_constant - length1 - this.m_ratio * length2; + linearError = b2Math.Max(linearError, (-C)); + C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); + impulse = (-this.m_pulleyMass * C); + p1X = (-impulse * this.m_u1.x); + p1Y = (-impulse * this.m_u1.y); + p2X = (-this.m_ratio * impulse * this.m_u2.x); + p2Y = (-this.m_ratio * impulse * this.m_u2.y); + bA.m_sweep.c.x += bA.m_invMass * p1X; + bA.m_sweep.c.y += bA.m_invMass * p1Y; + bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); + bB.m_sweep.c.x += bB.m_invMass * p2X; + bB.m_sweep.c.y += bB.m_invMass * p2Y; + bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + } + if (this.m_limitState1 == this.e_atUpperLimit) { + tMat = bA.m_xf.R; + r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + p1X = bA.m_sweep.c.x + r1X; + p1Y = bA.m_sweep.c.y + r1Y; + this.m_u1.Set(p1X - s1X, p1Y - s1Y); + length1 = this.m_u1.Length(); + if (length1 > b2Settings.b2_linearSlop) { + this.m_u1.x *= 1.0 / length1; + this.m_u1.y *= 1.0 / length1; + } + else { + this.m_u1.SetZero(); + } + C = this.m_maxLength1 - length1; + linearError = b2Math.Max(linearError, (-C)); + C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); + impulse = (-this.m_limitMass1 * C); + p1X = (-impulse * this.m_u1.x); + p1Y = (-impulse * this.m_u1.y); + bA.m_sweep.c.x += bA.m_invMass * p1X; + bA.m_sweep.c.y += bA.m_invMass * p1Y; + bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); + bA.SynchronizeTransform(); + } + if (this.m_limitState2 == this.e_atUpperLimit) { + tMat = bB.m_xf.R; + r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + p2X = bB.m_sweep.c.x + r2X; + p2Y = bB.m_sweep.c.y + r2Y; + this.m_u2.Set(p2X - s2X, p2Y - s2Y); + length2 = this.m_u2.Length(); + if (length2 > b2Settings.b2_linearSlop) { + this.m_u2.x *= 1.0 / length2; + this.m_u2.y *= 1.0 / length2; + } + else { + this.m_u2.SetZero(); + } + C = this.m_maxLength2 - length2; + linearError = b2Math.Max(linearError, (-C)); + C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); + impulse = (-this.m_limitMass2 * C); + p2X = (-impulse * this.m_u2.x); + p2Y = (-impulse * this.m_u2.y); + bB.m_sweep.c.x += bB.m_invMass * p2X; + bB.m_sweep.c.y += bB.m_invMass * p2Y; + bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); + bB.SynchronizeTransform(); + } + return linearError < b2Settings.b2_linearSlop; + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.Joints.b2PulleyJoint.b2_minPulleyLength = 2.0; + Box2D.Dynamics.Joints.b2PulleyJoint.prototype.b2_minPulleyLength = Box2D.Dynamics.Joints.b2PulleyJoint.b2_minPulleyLength; + }); + helpers.inherit.call(b2PulleyJointDef, Box2D.Dynamics.Joints.b2JointDef); + b2PulleyJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; + b2PulleyJointDef.b2PulleyJointDef = function () { + Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); + this.groundAnchorA = new b2Vec2(); + this.groundAnchorB = new b2Vec2(); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + }; + b2PulleyJointDef.prototype.b2PulleyJointDef = function () { + this.__super.b2JointDef.call(this); + this.type = b2Joint.e_pulleyJoint; + this.groundAnchorA.Set((-1.0), 1.0); + this.groundAnchorB.Set(1.0, 1.0); + this.localAnchorA.Set((-1.0), 0.0); + this.localAnchorB.Set(1.0, 0.0); + this.lengthA = 0.0; + this.maxLengthA = 0.0; + this.lengthB = 0.0; + this.maxLengthB = 0.0; + this.ratio = 1.0; + this.collideConnected = true; + } + b2PulleyJointDef.prototype.Initialize = function (bA, bB, gaA, gaB, anchorA, anchorB, r) { + if (r === undefined) r = 0; + this.bodyA = bA; + this.bodyB = bB; + this.groundAnchorA.SetV(gaA); + this.groundAnchorB.SetV(gaB); + this.localAnchorA = this.bodyA.GetLocalPoint(anchorA); + this.localAnchorB = this.bodyB.GetLocalPoint(anchorB); + var d1X = anchorA.x - gaA.x; + var d1Y = anchorA.y - gaA.y; + this.lengthA = Math.sqrt(d1X * d1X + d1Y * d1Y); + var d2X = anchorB.x - gaB.x; + var d2Y = anchorB.y - gaB.y; + this.lengthB = Math.sqrt(d2X * d2X + d2Y * d2Y); + this.ratio = r; + var C = this.lengthA + this.ratio * this.lengthB; + this.maxLengthA = C - this.ratio * b2PulleyJoint.b2_minPulleyLength; + this.maxLengthB = (C - b2PulleyJoint.b2_minPulleyLength) / this.ratio; + } + helpers.inherit.call(b2RevoluteJoint, Box2D.Dynamics.Joints.b2Joint); + b2RevoluteJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; + b2RevoluteJoint.b2RevoluteJoint = function () { + Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); + this.K = new b2Mat22(); + this.K1 = new b2Mat22(); + this.K2 = new b2Mat22(); + this.K3 = new b2Mat22(); + this.impulse3 = new b2Vec3(); + this.impulse2 = new b2Vec2(); + this.reduced = new b2Vec2(); + this.m_localAnchor1 = new b2Vec2(); + this.m_localAnchor2 = new b2Vec2(); + this.m_impulse = new b2Vec3(); + this.m_mass = new b2Mat33(); + }; + b2RevoluteJoint.prototype.GetAnchorA = function () { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); + } + b2RevoluteJoint.prototype.GetAnchorB = function () { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); + } + b2RevoluteJoint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y); + } + b2RevoluteJoint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return inv_dt * this.m_impulse.z; + } + b2RevoluteJoint.prototype.GetJointAngle = function () { + return this.m_bodyB.m_sweep.a - this.m_bodyA.m_sweep.a - this.m_referenceAngle; + } + b2RevoluteJoint.prototype.GetJointSpeed = function () { + return this.m_bodyB.m_angularVelocity - this.m_bodyA.m_angularVelocity; + } + b2RevoluteJoint.prototype.IsLimitEnabled = function () { + return this.m_enableLimit; + } + b2RevoluteJoint.prototype.EnableLimit = function (flag) { + this.m_enableLimit = flag; + } + b2RevoluteJoint.prototype.GetLowerLimit = function () { + return this.m_lowerAngle; + } + b2RevoluteJoint.prototype.GetUpperLimit = function () { + return this.m_upperAngle; + } + b2RevoluteJoint.prototype.SetLimits = function (lower, upper) { + if (lower === undefined) lower = 0; + if (upper === undefined) upper = 0; + this.m_lowerAngle = lower; + this.m_upperAngle = upper; + } + b2RevoluteJoint.prototype.IsMotorEnabled = function () { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + return this.m_enableMotor; + } + b2RevoluteJoint.prototype.EnableMotor = function (flag) { + this.m_enableMotor = flag; + } + b2RevoluteJoint.prototype.SetMotorSpeed = function (speed) { + if (speed === undefined) speed = 0; + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_motorSpeed = speed; + } + b2RevoluteJoint.prototype.GetMotorSpeed = function () { + return this.m_motorSpeed; + } + b2RevoluteJoint.prototype.SetMaxMotorTorque = function (torque) { + if (torque === undefined) torque = 0; + this.m_maxMotorTorque = torque; + } + b2RevoluteJoint.prototype.GetMotorTorque = function () { + return this.m_maxMotorTorque; + } + b2RevoluteJoint.prototype.b2RevoluteJoint = function (def) { + this.__super.b2Joint.call(this, def); + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_referenceAngle = def.referenceAngle; + this.m_impulse.SetZero(); + this.m_motorImpulse = 0.0; + this.m_lowerAngle = def.lowerAngle; + this.m_upperAngle = def.upperAngle; + this.m_maxMotorTorque = def.maxMotorTorque; + this.m_motorSpeed = def.motorSpeed; + this.m_enableLimit = def.enableLimit; + this.m_enableMotor = def.enableMotor; + this.m_limitState = this.e_inactiveLimit; + } + b2RevoluteJoint.prototype.InitVelocityConstraints = function (step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var tX = 0; + if (this.m_enableMotor || this.m_enableLimit) {} + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var m1 = bA.m_invMass; + var m2 = bB.m_invMass; + var i1 = bA.m_invI; + var i2 = bB.m_invI; + this.m_mass.col1.x = m1 + m2 + r1Y * r1Y * i1 + r2Y * r2Y * i2; + this.m_mass.col2.x = (-r1Y * r1X * i1) - r2Y * r2X * i2; + this.m_mass.col3.x = (-r1Y * i1) - r2Y * i2; + this.m_mass.col1.y = this.m_mass.col2.x; + this.m_mass.col2.y = m1 + m2 + r1X * r1X * i1 + r2X * r2X * i2; + this.m_mass.col3.y = r1X * i1 + r2X * i2; + this.m_mass.col1.z = this.m_mass.col3.x; + this.m_mass.col2.z = this.m_mass.col3.y; + this.m_mass.col3.z = i1 + i2; + this.m_motorMass = 1.0 / (i1 + i2); + if (this.m_enableMotor == false) { + this.m_motorImpulse = 0.0; + } + if (this.m_enableLimit) { + var jointAngle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; + if (b2Math.Abs(this.m_upperAngle - this.m_lowerAngle) < 2.0 * b2Settings.b2_angularSlop) { + this.m_limitState = this.e_equalLimits; + } + else if (jointAngle <= this.m_lowerAngle) { + if (this.m_limitState != this.e_atLowerLimit) { + this.m_impulse.z = 0.0; + } + this.m_limitState = this.e_atLowerLimit; + } + else if (jointAngle >= this.m_upperAngle) { + if (this.m_limitState != this.e_atUpperLimit) { + this.m_impulse.z = 0.0; + } + this.m_limitState = this.e_atUpperLimit; + } + else { + this.m_limitState = this.e_inactiveLimit; + this.m_impulse.z = 0.0; + } + } + else { + this.m_limitState = this.e_inactiveLimit; + } + if (step.warmStarting) { + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + this.m_motorImpulse *= step.dtRatio; + var PX = this.m_impulse.x; + var PY = this.m_impulse.y; + bA.m_linearVelocity.x -= m1 * PX; + bA.m_linearVelocity.y -= m1 * PY; + bA.m_angularVelocity -= i1 * ((r1X * PY - r1Y * PX) + this.m_motorImpulse + this.m_impulse.z); + bB.m_linearVelocity.x += m2 * PX; + bB.m_linearVelocity.y += m2 * PY; + bB.m_angularVelocity += i2 * ((r2X * PY - r2Y * PX) + this.m_motorImpulse + this.m_impulse.z); + } + else { + this.m_impulse.SetZero(); + this.m_motorImpulse = 0.0; + } + } + b2RevoluteJoint.prototype.SolveVelocityConstraints = function (step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var tX = 0; + var newImpulse = 0; + var r1X = 0; + var r1Y = 0; + var r2X = 0; + var r2Y = 0; + var v1 = bA.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var v2 = bB.m_linearVelocity; + var w2 = bB.m_angularVelocity; + var m1 = bA.m_invMass; + var m2 = bB.m_invMass; + var i1 = bA.m_invI; + var i2 = bB.m_invI; + if (this.m_enableMotor && this.m_limitState != this.e_equalLimits) { + var Cdot = w2 - w1 - this.m_motorSpeed; + var impulse = this.m_motorMass * ((-Cdot)); + var oldImpulse = this.m_motorImpulse; + var maxImpulse = step.dt * this.m_maxMotorTorque; + this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); + impulse = this.m_motorImpulse - oldImpulse; + w1 -= i1 * impulse; + w2 += i2 * impulse; + } + if (this.m_enableLimit && this.m_limitState != this.e_inactiveLimit) { + tMat = bA.m_xf.R; + r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var Cdot1X = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y)); + var Cdot1Y = v2.y + (w2 * r2X) - v1.y - (w1 * r1X); + var Cdot2 = w2 - w1; + this.m_mass.Solve33(this.impulse3, (-Cdot1X), (-Cdot1Y), (-Cdot2)); + if (this.m_limitState == this.e_equalLimits) { + this.m_impulse.Add(this.impulse3); + } + else if (this.m_limitState == this.e_atLowerLimit) { + newImpulse = this.m_impulse.z + this.impulse3.z; + if (newImpulse < 0.0) { + this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y)); + this.impulse3.x = this.reduced.x; + this.impulse3.y = this.reduced.y; + this.impulse3.z = (-this.m_impulse.z); + this.m_impulse.x += this.reduced.x; + this.m_impulse.y += this.reduced.y; + this.m_impulse.z = 0.0; + } + } + else if (this.m_limitState == this.e_atUpperLimit) { + newImpulse = this.m_impulse.z + this.impulse3.z; + if (newImpulse > 0.0) { + this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y)); + this.impulse3.x = this.reduced.x; + this.impulse3.y = this.reduced.y; + this.impulse3.z = (-this.m_impulse.z); + this.m_impulse.x += this.reduced.x; + this.m_impulse.y += this.reduced.y; + this.m_impulse.z = 0.0; + } + } + v1.x -= m1 * this.impulse3.x; + v1.y -= m1 * this.impulse3.y; + w1 -= i1 * (r1X * this.impulse3.y - r1Y * this.impulse3.x + this.impulse3.z); + v2.x += m2 * this.impulse3.x; + v2.y += m2 * this.impulse3.y; + w2 += i2 * (r2X * this.impulse3.y - r2Y * this.impulse3.x + this.impulse3.z); + } + else { + tMat = bA.m_xf.R; + r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var CdotX = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y)); + var CdotY = v2.y + (w2 * r2X) - v1.y - (w1 * r1X); + this.m_mass.Solve22(this.impulse2, (-CdotX), (-CdotY)); + this.m_impulse.x += this.impulse2.x; + this.m_impulse.y += this.impulse2.y; + v1.x -= m1 * this.impulse2.x; + v1.y -= m1 * this.impulse2.y; + w1 -= i1 * (r1X * this.impulse2.y - r1Y * this.impulse2.x); + v2.x += m2 * this.impulse2.x; + v2.y += m2 * this.impulse2.y; + w2 += i2 * (r2X * this.impulse2.y - r2Y * this.impulse2.x); + } + bA.m_linearVelocity.SetV(v1); + bA.m_angularVelocity = w1; + bB.m_linearVelocity.SetV(v2); + bB.m_angularVelocity = w2; + } + b2RevoluteJoint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + var oldLimitImpulse = 0; + var C = 0; + var tMat; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var angularError = 0.0; + var positionError = 0.0; + var tX = 0; + var impulseX = 0; + var impulseY = 0; + if (this.m_enableLimit && this.m_limitState != this.e_inactiveLimit) { + var angle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; + var limitImpulse = 0.0; + if (this.m_limitState == this.e_equalLimits) { + C = b2Math.Clamp(angle - this.m_lowerAngle, (-b2Settings.b2_maxAngularCorrection), b2Settings.b2_maxAngularCorrection); + limitImpulse = (-this.m_motorMass * C); + angularError = b2Math.Abs(C); + } + else if (this.m_limitState == this.e_atLowerLimit) { + C = angle - this.m_lowerAngle; + angularError = (-C); + C = b2Math.Clamp(C + b2Settings.b2_angularSlop, (-b2Settings.b2_maxAngularCorrection), 0.0); + limitImpulse = (-this.m_motorMass * C); + } + else if (this.m_limitState == this.e_atUpperLimit) { + C = angle - this.m_upperAngle; + angularError = C; + C = b2Math.Clamp(C - b2Settings.b2_angularSlop, 0.0, b2Settings.b2_maxAngularCorrection); + limitImpulse = (-this.m_motorMass * C); + } + bA.m_sweep.a -= bA.m_invI * limitImpulse; + bB.m_sweep.a += bB.m_invI * limitImpulse; + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + } { + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); + r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); + r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); + r2X = tX; + var CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + var CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + var CLengthSquared = CX * CX + CY * CY; + var CLength = Math.sqrt(CLengthSquared); + positionError = CLength; + var invMass1 = bA.m_invMass; + var invMass2 = bB.m_invMass; + var invI1 = bA.m_invI; + var invI2 = bB.m_invI; + var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop; + if (CLengthSquared > k_allowedStretch * k_allowedStretch) { + var uX = CX / CLength; + var uY = CY / CLength; + var k = invMass1 + invMass2; + var m = 1.0 / k; + impulseX = m * ((-CX)); + impulseY = m * ((-CY)); + var k_beta = 0.5; + bA.m_sweep.c.x -= k_beta * invMass1 * impulseX; + bA.m_sweep.c.y -= k_beta * invMass1 * impulseY; + bB.m_sweep.c.x += k_beta * invMass2 * impulseX; + bB.m_sweep.c.y += k_beta * invMass2 * impulseY; + CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + } + this.K1.col1.x = invMass1 + invMass2; + this.K1.col2.x = 0.0; + this.K1.col1.y = 0.0; + this.K1.col2.y = invMass1 + invMass2; + this.K2.col1.x = invI1 * r1Y * r1Y; + this.K2.col2.x = (-invI1 * r1X * r1Y); + this.K2.col1.y = (-invI1 * r1X * r1Y); + this.K2.col2.y = invI1 * r1X * r1X; + this.K3.col1.x = invI2 * r2Y * r2Y; + this.K3.col2.x = (-invI2 * r2X * r2Y); + this.K3.col1.y = (-invI2 * r2X * r2Y); + this.K3.col2.y = invI2 * r2X * r2X; + this.K.SetM(this.K1); + this.K.AddM(this.K2); + this.K.AddM(this.K3); + this.K.Solve(b2RevoluteJoint.tImpulse, (-CX), (-CY)); + impulseX = b2RevoluteJoint.tImpulse.x; + impulseY = b2RevoluteJoint.tImpulse.y; + bA.m_sweep.c.x -= bA.m_invMass * impulseX; + bA.m_sweep.c.y -= bA.m_invMass * impulseY; + bA.m_sweep.a -= bA.m_invI * (r1X * impulseY - r1Y * impulseX); + bB.m_sweep.c.x += bB.m_invMass * impulseX; + bB.m_sweep.c.y += bB.m_invMass * impulseY; + bB.m_sweep.a += bB.m_invI * (r2X * impulseY - r2Y * impulseX); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + } + return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; + } + _A2J_postDefs.push(function () { + Box2D.Dynamics.Joints.b2RevoluteJoint.tImpulse = new b2Vec2(); + Box2D.Dynamics.Joints.b2RevoluteJoint.prototype.tImpulse = Box2D.Dynamics.Joints.b2RevoluteJoint.tImpulse; + }); + helpers.inherit.call(b2RevoluteJointDef, Box2D.Dynamics.Joints.b2JointDef); + b2RevoluteJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; + b2RevoluteJointDef.b2RevoluteJointDef = function () { + Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + }; + b2RevoluteJointDef.prototype.b2RevoluteJointDef = function () { + this.__super.b2JointDef.call(this); + this.type = b2Joint.e_revoluteJoint; + this.localAnchorA.Set(0.0, 0.0); + this.localAnchorB.Set(0.0, 0.0); + this.referenceAngle = 0.0; + this.lowerAngle = 0.0; + this.upperAngle = 0.0; + this.maxMotorTorque = 0.0; + this.motorSpeed = 0.0; + this.enableLimit = false; + this.enableMotor = false; + } + b2RevoluteJointDef.prototype.Initialize = function (bA, bB, anchor) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA = this.bodyA.GetLocalPoint(anchor); + this.localAnchorB = this.bodyB.GetLocalPoint(anchor); + this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); + } + helpers.inherit.call(b2WeldJoint, Box2D.Dynamics.Joints.b2Joint); + b2WeldJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; + b2WeldJoint.b2WeldJoint = function () { + Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + this.m_impulse = new b2Vec3(); + this.m_mass = new b2Mat33(); + }; + b2WeldJoint.prototype.GetAnchorA = function () { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA); + } + b2WeldJoint.prototype.GetAnchorB = function () { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB); + } + b2WeldJoint.prototype.GetReactionForce = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y); + } + b2WeldJoint.prototype.GetReactionTorque = function (inv_dt) { + if (inv_dt === undefined) inv_dt = 0; + return inv_dt * this.m_impulse.z; + } + b2WeldJoint.prototype.b2WeldJoint = function (def) { + this.__super.b2Joint.call(this, def); + this.m_localAnchorA.SetV(def.localAnchorA); + this.m_localAnchorB.SetV(def.localAnchorB); + this.m_referenceAngle = def.referenceAngle; + this.m_impulse.SetZero(); + this.m_mass = new b2Mat33(); + } + b2WeldJoint.prototype.InitVelocityConstraints = function (step) { + var tMat; + var tX = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); + rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); + rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); + rBX = tX; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; + this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB; + this.m_mass.col3.x = (-rAY * iA) - rBY * iB; + this.m_mass.col1.y = this.m_mass.col2.x; + this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; + this.m_mass.col3.y = rAX * iA + rBX * iB; + this.m_mass.col1.z = this.m_mass.col3.x; + this.m_mass.col2.z = this.m_mass.col3.y; + this.m_mass.col3.z = iA + iB; + if (step.warmStarting) { + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + this.m_impulse.z *= step.dtRatio; + bA.m_linearVelocity.x -= mA * this.m_impulse.x; + bA.m_linearVelocity.y -= mA * this.m_impulse.y; + bA.m_angularVelocity -= iA * (rAX * this.m_impulse.y - rAY * this.m_impulse.x + this.m_impulse.z); + bB.m_linearVelocity.x += mB * this.m_impulse.x; + bB.m_linearVelocity.y += mB * this.m_impulse.y; + bB.m_angularVelocity += iB * (rBX * this.m_impulse.y - rBY * this.m_impulse.x + this.m_impulse.z); + } + else { + this.m_impulse.SetZero(); + } + } + b2WeldJoint.prototype.SolveVelocityConstraints = function (step) { + var tMat; + var tX = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var vA = bA.m_linearVelocity; + var wA = bA.m_angularVelocity; + var vB = bB.m_linearVelocity; + var wB = bB.m_angularVelocity; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); + rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); + rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); + rBX = tX; + var Cdot1X = vB.x - wB * rBY - vA.x + wA * rAY; + var Cdot1Y = vB.y + wB * rBX - vA.y - wA * rAX; + var Cdot2 = wB - wA; + var impulse = new b2Vec3(); + this.m_mass.Solve33(impulse, (-Cdot1X), (-Cdot1Y), (-Cdot2)); + this.m_impulse.Add(impulse); + vA.x -= mA * impulse.x; + vA.y -= mA * impulse.y; + wA -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); + vB.x += mB * impulse.x; + vB.y += mB * impulse.y; + wB += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); + bA.m_angularVelocity = wA; + bB.m_angularVelocity = wB; + } + b2WeldJoint.prototype.SolvePositionConstraints = function (baumgarte) { + if (baumgarte === undefined) baumgarte = 0; + var tMat; + var tX = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); + rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); + rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); + rBX = tX; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + var C1X = bB.m_sweep.c.x + rBX - bA.m_sweep.c.x - rAX; + var C1Y = bB.m_sweep.c.y + rBY - bA.m_sweep.c.y - rAY; + var C2 = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; + var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop; + var positionError = Math.sqrt(C1X * C1X + C1Y * C1Y); + var angularError = b2Math.Abs(C2); + if (positionError > k_allowedStretch) { + iA *= 1.0; + iB *= 1.0; + } + this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; + this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB; + this.m_mass.col3.x = (-rAY * iA) - rBY * iB; + this.m_mass.col1.y = this.m_mass.col2.x; + this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; + this.m_mass.col3.y = rAX * iA + rBX * iB; + this.m_mass.col1.z = this.m_mass.col3.x; + this.m_mass.col2.z = this.m_mass.col3.y; + this.m_mass.col3.z = iA + iB; + var impulse = new b2Vec3(); + this.m_mass.Solve33(impulse, (-C1X), (-C1Y), (-C2)); + bA.m_sweep.c.x -= mA * impulse.x; + bA.m_sweep.c.y -= mA * impulse.y; + bA.m_sweep.a -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); + bB.m_sweep.c.x += mB * impulse.x; + bB.m_sweep.c.y += mB * impulse.y; + bB.m_sweep.a += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; + } + helpers.inherit.call(b2WeldJointDef, Box2D.Dynamics.Joints.b2JointDef); + b2WeldJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; + b2WeldJointDef.b2WeldJointDef = function () { + Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + }; + b2WeldJointDef.prototype.b2WeldJointDef = function () { + this.__super.b2JointDef.call(this); + this.type = b2Joint.e_weldJoint; + this.referenceAngle = 0.0; + } + b2WeldJointDef.prototype.Initialize = function (bA, bB, anchor) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); + this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)); + this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); + } +})(); +var Vector_a2j_Number = a2j.NVector; +//post-definitions +for (var i = 0; i < _A2J_postDefs.length; ++i) _A2J_postDefs[i]();(function() { + function b2DebugDraw() { + b2DebugDraw.b2DebugDraw.apply(this, arguments); + if (this.constructor === b2DebugDraw) this.b2DebugDraw.apply(this, arguments); + } + Box2D.Dynamics.b2DebugDraw = b2DebugDraw; +})(); +var _A2J_postDefs = []; +(function() { + var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; + b2DebugDraw.b2DebugDraw = function () { + this.m_drawScale = 1.0; + this.m_lineThickness = 1.0; + this.m_alpha = 1.0; + this.m_fillAlpha = 1.0; + this.m_xformScale = 1.0; + var __this = this; + //#WORKAROUND + this.m_sprite = {graphics: {clear: + function() {__this.m_ctx.clearRect(0,0,__this.m_ctx.canvas.width,__this.m_ctx.canvas.height)} + }}; + }; + b2DebugDraw.prototype._color = function(color, alpha) { + return "rgba("+ ((color & 0xFF0000) >> 16) +","+ ((color & 0xFF00) >> 8) +","+ + (color & 0xFF) +","+ alpha +")"; + }; + b2DebugDraw.prototype.b2DebugDraw = function () { + this.m_drawFlags = 0; + }; + b2DebugDraw.prototype.SetFlags = function (flags) { + if (flags === undefined) flags = 0; + this.m_drawFlags = flags; + }; + b2DebugDraw.prototype.GetFlags = function () { + return this.m_drawFlags; + }; + b2DebugDraw.prototype.AppendFlags = function (flags) { + if (flags === undefined) flags = 0; + this.m_drawFlags |= flags; + }; + b2DebugDraw.prototype.ClearFlags = function (flags) { + if (flags === undefined) flags = 0; + this.m_drawFlags &= ~flags; + }; + b2DebugDraw.prototype.SetSprite = function (sprite) { + this.m_ctx = sprite; + }; + b2DebugDraw.prototype.GetSprite = function () { + return this.m_ctx; + }; + b2DebugDraw.prototype.SetDrawScale = function (drawScale) { + if (drawScale === undefined) drawScale = 0; + this.m_drawScale = drawScale; + }; + b2DebugDraw.prototype.GetDrawScale = function () { + return this.m_drawScale; + }; + b2DebugDraw.prototype.SetLineThickness = function (lineThickness) { + if (lineThickness === undefined) lineThickness = 0; + this.m_lineThickness = lineThickness; + this.m_ctx.strokeWidth = lineThickness; + }; + b2DebugDraw.prototype.GetLineThickness = function () { + return this.m_lineThickness; + }; + b2DebugDraw.prototype.SetAlpha = function (alpha) { + if (alpha === undefined) alpha = 0; + this.m_alpha = alpha; + }; + b2DebugDraw.prototype.GetAlpha = function () { + return this.m_alpha; + }; + b2DebugDraw.prototype.SetFillAlpha = function (alpha) { + if (alpha === undefined) alpha = 0; + this.m_fillAlpha = alpha; + }; + b2DebugDraw.prototype.GetFillAlpha = function () { + return this.m_fillAlpha; + }; + b2DebugDraw.prototype.SetXFormScale = function (xformScale) { + if (xformScale === undefined) xformScale = 0; + this.m_xformScale = xformScale; + }; + b2DebugDraw.prototype.GetXFormScale = function () { + return this.m_xformScale; + }; + b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) { + if(!vertexCount) return; + var s = this.m_ctx; + var drawScale = this.m_drawScale; + s.beginPath(); + s.strokeStyle = this._color(color.color, this.m_alpha); + s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale); + for (var i = 1; i < vertexCount; i++) { + s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale); + } + s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale); + s.closePath(); + s.stroke(); + }; + b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) { + if(!vertexCount) return; + var s = this.m_ctx; + var drawScale = this.m_drawScale; + s.beginPath(); + s.strokeStyle = this._color(color.color, this.m_alpha); + s.fillStyle = this._color(color.color, this.m_fillAlpha); + s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale); + for (var i = 1; i < vertexCount; i++) { + s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale); + } + s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale); + s.closePath(); + s.fill(); + s.stroke(); + }; + b2DebugDraw.prototype.DrawCircle = function (center, radius, color) { + if(!radius) return; + var s = this.m_ctx; + var drawScale = this.m_drawScale; + s.beginPath(); + s.strokeStyle = this._color(color.color, this.m_alpha); + s.arc(center.x * drawScale, center.y * drawScale, radius * drawScale, 0, Math.PI*2, true); + s.closePath(); + s.stroke(); + }; + b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) { + /*if (radius === undefined) radius = 0; + this.m_ctx.graphics.lineStyle(this.m_lineThickness, color.color, this.m_alpha); + this.m_ctx.graphics.moveTo(0, 0); + this.m_ctx.graphics.beginFill(color.color, this.m_fillAlpha); + this.m_ctx.graphics.drawCircle(center.x * this.m_drawScale, center.y * this.m_drawScale, radius * this.m_drawScale); + this.m_ctx.graphics.endFill(); + this.m_ctx.graphics.moveTo(center.x * this.m_drawScale, center.y * this.m_drawScale); + this.m_ctx.graphics.lineTo((center.x + axis.x * radius) * this.m_drawScale, (center.y + axis.y * radius) * this.m_drawScale); + */ + if(!radius) return; + var s = this.m_ctx + , drawScale = this.m_drawScale + , cx = center.x * drawScale + , cy = center.y * drawScale + ; + s.moveTo(0, 0); + s.beginPath(); + s.strokeStyle = this._color(color.color, this.m_alpha); + s.fillStyle = this._color(color.color, this.m_fillAlpha); + s.arc(cx, cy, radius * drawScale, 0, Math.PI*2, true); + s.moveTo(cx, cy); + s.lineTo((center.x + axis.x * radius) * drawScale, (center.y + axis.y * radius) * drawScale); + s.closePath(); + s.fill(); + s.stroke(); + }; + b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) { + var s = this.m_ctx + , drawScale = this.m_drawScale + ; + s.strokeStyle = this._color(color.color, this.m_alpha); + s.beginPath(); + s.moveTo(p1.x * drawScale, p1.y * drawScale); + s.lineTo(p2.x * drawScale, p2.y * drawScale); + s.closePath(); + s.stroke(); + }; + b2DebugDraw.prototype.DrawTransform = function (xf) { + var s = this.m_ctx + , drawScale = this.m_drawScale + ; + s.beginPath(); + s.strokeStyle = this._color(0xff0000, this.m_alpha); + s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale); + s.lineTo((xf.position.x + this.m_xformScale * xf.R.col1.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col1.y) * drawScale); + + s.strokeStyle = this._color(0xff00, this.m_alpha); + s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale); + s.lineTo((xf.position.x + this.m_xformScale * xf.R.col2.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col2.y) * drawScale); + s.closePath(); + s.stroke(); + }; + _A2J_postDefs.push(function () { + Box2D.Dynamics.b2DebugDraw.e_shapeBit = 0x0001; + Box2D.Dynamics.b2DebugDraw.prototype.e_shapeBit = Box2D.Dynamics.b2DebugDraw.e_shapeBit; + Box2D.Dynamics.b2DebugDraw.e_jointBit = 0x0002; + Box2D.Dynamics.b2DebugDraw.prototype.e_jointBit = Box2D.Dynamics.b2DebugDraw.e_jointBit; + Box2D.Dynamics.b2DebugDraw.e_aabbBit = 0x0004; + Box2D.Dynamics.b2DebugDraw.prototype.e_aabbBit = Box2D.Dynamics.b2DebugDraw.e_aabbBit; + Box2D.Dynamics.b2DebugDraw.e_pairBit = 0x0008; + Box2D.Dynamics.b2DebugDraw.prototype.e_pairBit = Box2D.Dynamics.b2DebugDraw.e_pairBit; + Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit = 0x0010; + Box2D.Dynamics.b2DebugDraw.prototype.e_centerOfMassBit = Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit; + Box2D.Dynamics.b2DebugDraw.e_controllerBit = 0x0020; + Box2D.Dynamics.b2DebugDraw.prototype.e_controllerBit = Box2D.Dynamics.b2DebugDraw.e_controllerBit; + }); +})(); + +//post-definitions +for (var i = 0; i < _A2J_postDefs.length; ++i) _A2J_postDefs[i](); + + +module.exports = Box2D From 11a7caf2173dd68551dd0297ec891daad0b4fce1 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 20 Jan 2011 18:10:20 +1300 Subject: [PATCH 003/176] Replaced box2dweb with box2d.js --- src/libs/box2d.js | 23376 +++++++++++++++++++++----------------------- 1 file changed, 11377 insertions(+), 11999 deletions(-) diff --git a/src/libs/box2d.js b/src/libs/box2d.js index 79b08db..a143ee8 100644 --- a/src/libs/box2d.js +++ b/src/libs/box2d.js @@ -1,12013 +1,11391 @@ -/* -* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. -*/ -var a2j = {}; - -var helpers = {}, - Vector; - -(function (a2j, helpers) { - - if(!helpers.flash) helpers.flash = {utils: {Dictionary: Object} }; - else if(!helpers.flash.utils) helpers.flash.utils = {Dictionary: Object}; - else if(!helpers.flash.utils.Dictionary) helpers.flash.utils.Dictionary = Object; - - Vector = window.Array; - - helpers.inherit = function (base) { - var tmpCtr = this; - var empty = helpers.inherit.empty; - empty.prototype = base.prototype; - this.prototype = new empty(); - this.prototype.constructor = tmpCtr; - }; - helpers.inherit.empty = function () {}; - - helpers.trace = function () { - if (window.console && (window.console.log instanceof Function)) window.console.log.apply(window.console, arguments); - }; - helpers.assert = function () { - if (window.console && (window.console.assert instanceof Function)) window.console.assert.apply(window.console, arguments); - }; - - a2j.warn = function warn() { - if (window.console) console.warn.apply(console, arguments); - }; - - a2j.generateCallback = function generateCallback(context, cb) { - return function () { - cb.apply(context, arguments); - }; - }; - - a2j.NVector = function NVector(length) { - if (length === undefined) length = 0; - var tmp = new Array(length || 0); - for (var i = 0; i < length; ++i) - tmp[i] = 0; - return tmp; - }; - - a2j.is = function is(o1, o2) { - if (o1 === null) return false; - if ((o2 instanceof Function) && (o1 instanceof o2)) return true; - if ((o1.constructor.__implements != undefined) && (o1.constructor.__implements[o2])) return true; - return false; - }; - - a2j.parseUInt = function(v) { - return Math.abs(parseInt(v)); - } - -})(a2j, helpers, undefined); - -var Vector_a2j_Number = a2j.NVector; -var Box2D; - -//package structure -if (!Box2D) Box2D = {}; -if (!Box2D.Collision) Box2D.Collision = {}; -if (!Box2D.Collision.Shapes) Box2D.Collision.Shapes = {}; -if (!Box2D.Common) Box2D.Common = {}; -if (!Box2D.Common.Math) Box2D.Common.Math = {}; -if (!Box2D.Dynamics) Box2D.Dynamics = {}; -if (!Box2D.Dynamics.Contacts) Box2D.Dynamics.Contacts = {}; -if (!Box2D.Dynamics.Controllers) Box2D.Dynamics.Controllers = {}; -if (!Box2D.Dynamics.Joints) Box2D.Dynamics.Joints = {}; -//pre-definitions -(function () { - Box2D.Collision.IBroadPhase = 'Box2D.Collision.IBroadPhase'; - - function b2AABB() { - b2AABB.b2AABB.apply(this, arguments); - }; - Box2D.Collision.b2AABB = b2AABB; - - function b2Bound() { - b2Bound.b2Bound.apply(this, arguments); - }; - Box2D.Collision.b2Bound = b2Bound; - - function b2BoundValues() { - b2BoundValues.b2BoundValues.apply(this, arguments); - if (this.constructor === b2BoundValues) this.b2BoundValues.apply(this, arguments); - }; - Box2D.Collision.b2BoundValues = b2BoundValues; - - function b2BroadPhase() { - b2BroadPhase.b2BroadPhase.apply(this, arguments); - if (this.constructor === b2BroadPhase) this.b2BroadPhase.apply(this, arguments); - }; - Box2D.Collision.b2BroadPhase = b2BroadPhase; - - function b2Collision() { - b2Collision.b2Collision.apply(this, arguments); - }; - Box2D.Collision.b2Collision = b2Collision; - - function b2ContactID() { - b2ContactID.b2ContactID.apply(this, arguments); - if (this.constructor === b2ContactID) this.b2ContactID.apply(this, arguments); - }; - Box2D.Collision.b2ContactID = b2ContactID; - - function b2ContactPoint() { - b2ContactPoint.b2ContactPoint.apply(this, arguments); - }; - Box2D.Collision.b2ContactPoint = b2ContactPoint; - - function b2Distance() { - b2Distance.b2Distance.apply(this, arguments); - }; - Box2D.Collision.b2Distance = b2Distance; - - function b2DistanceInput() { - b2DistanceInput.b2DistanceInput.apply(this, arguments); - }; - Box2D.Collision.b2DistanceInput = b2DistanceInput; - - function b2DistanceOutput() { - b2DistanceOutput.b2DistanceOutput.apply(this, arguments); - }; - Box2D.Collision.b2DistanceOutput = b2DistanceOutput; - - function b2DistanceProxy() { - b2DistanceProxy.b2DistanceProxy.apply(this, arguments); - }; - Box2D.Collision.b2DistanceProxy = b2DistanceProxy; - - function b2DynamicTree() { - b2DynamicTree.b2DynamicTree.apply(this, arguments); - if (this.constructor === b2DynamicTree) this.b2DynamicTree.apply(this, arguments); - }; - Box2D.Collision.b2DynamicTree = b2DynamicTree; - - function b2DynamicTreeBroadPhase() { - b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase.apply(this, arguments); - }; - Box2D.Collision.b2DynamicTreeBroadPhase = b2DynamicTreeBroadPhase; - - function b2DynamicTreeNode() { - b2DynamicTreeNode.b2DynamicTreeNode.apply(this, arguments); - }; - Box2D.Collision.b2DynamicTreeNode = b2DynamicTreeNode; - - function b2DynamicTreePair() { - b2DynamicTreePair.b2DynamicTreePair.apply(this, arguments); - }; - Box2D.Collision.b2DynamicTreePair = b2DynamicTreePair; - - function b2Manifold() { - b2Manifold.b2Manifold.apply(this, arguments); - if (this.constructor === b2Manifold) this.b2Manifold.apply(this, arguments); - }; - Box2D.Collision.b2Manifold = b2Manifold; - - function b2ManifoldPoint() { - b2ManifoldPoint.b2ManifoldPoint.apply(this, arguments); - if (this.constructor === b2ManifoldPoint) this.b2ManifoldPoint.apply(this, arguments); - }; - Box2D.Collision.b2ManifoldPoint = b2ManifoldPoint; - - function b2OBB() { - b2OBB.b2OBB.apply(this, arguments); - }; - Box2D.Collision.b2OBB = b2OBB; - - function b2Pair() { - b2Pair.b2Pair.apply(this, arguments); - }; - Box2D.Collision.b2Pair = b2Pair; - - function b2PairManager() { - b2PairManager.b2PairManager.apply(this, arguments); - if (this.constructor === b2PairManager) this.b2PairManager.apply(this, arguments); - }; - Box2D.Collision.b2PairManager = b2PairManager; - - function b2Point() { - b2Point.b2Point.apply(this, arguments); - }; - Box2D.Collision.b2Point = b2Point; - - function b2Proxy() { - b2Proxy.b2Proxy.apply(this, arguments); - }; - Box2D.Collision.b2Proxy = b2Proxy; - - function b2RayCastInput() { - b2RayCastInput.b2RayCastInput.apply(this, arguments); - if (this.constructor === b2RayCastInput) this.b2RayCastInput.apply(this, arguments); - }; - Box2D.Collision.b2RayCastInput = b2RayCastInput; - - function b2RayCastOutput() { - b2RayCastOutput.b2RayCastOutput.apply(this, arguments); - }; - Box2D.Collision.b2RayCastOutput = b2RayCastOutput; - - function b2Segment() { - b2Segment.b2Segment.apply(this, arguments); - }; - Box2D.Collision.b2Segment = b2Segment; - - function b2SeparationFunction() { - b2SeparationFunction.b2SeparationFunction.apply(this, arguments); - }; - Box2D.Collision.b2SeparationFunction = b2SeparationFunction; - - function b2Simplex() { - b2Simplex.b2Simplex.apply(this, arguments); - if (this.constructor === b2Simplex) this.b2Simplex.apply(this, arguments); - }; - Box2D.Collision.b2Simplex = b2Simplex; - - function b2SimplexCache() { - b2SimplexCache.b2SimplexCache.apply(this, arguments); - }; - Box2D.Collision.b2SimplexCache = b2SimplexCache; - - function b2SimplexVertex() { - b2SimplexVertex.b2SimplexVertex.apply(this, arguments); - }; - Box2D.Collision.b2SimplexVertex = b2SimplexVertex; - - function b2TimeOfImpact() { - b2TimeOfImpact.b2TimeOfImpact.apply(this, arguments); - }; - Box2D.Collision.b2TimeOfImpact = b2TimeOfImpact; - - function b2TOIInput() { - b2TOIInput.b2TOIInput.apply(this, arguments); - }; - Box2D.Collision.b2TOIInput = b2TOIInput; - - function b2WorldManifold() { - b2WorldManifold.b2WorldManifold.apply(this, arguments); - if (this.constructor === b2WorldManifold) this.b2WorldManifold.apply(this, arguments); - }; - Box2D.Collision.b2WorldManifold = b2WorldManifold; - - function ClipVertex() { - ClipVertex.ClipVertex.apply(this, arguments); - }; - Box2D.Collision.ClipVertex = ClipVertex; - - function Features() { - Features.Features.apply(this, arguments); - }; - Box2D.Collision.Features = Features; - - function b2CircleShape() { - b2CircleShape.b2CircleShape.apply(this, arguments); - if (this.constructor === b2CircleShape) this.b2CircleShape.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2CircleShape = b2CircleShape; - - function b2EdgeChainDef() { - b2EdgeChainDef.b2EdgeChainDef.apply(this, arguments); - if (this.constructor === b2EdgeChainDef) this.b2EdgeChainDef.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2EdgeChainDef = b2EdgeChainDef; - - function b2EdgeShape() { - b2EdgeShape.b2EdgeShape.apply(this, arguments); - if (this.constructor === b2EdgeShape) this.b2EdgeShape.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2EdgeShape = b2EdgeShape; - - function b2MassData() { - b2MassData.b2MassData.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2MassData = b2MassData; - - function b2PolygonShape() { - b2PolygonShape.b2PolygonShape.apply(this, arguments); - if (this.constructor === b2PolygonShape) this.b2PolygonShape.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2PolygonShape = b2PolygonShape; - - function b2Shape() { - b2Shape.b2Shape.apply(this, arguments); - if (this.constructor === b2Shape) this.b2Shape.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2Shape = b2Shape; - Box2D.Common.b2internal = 'Box2D.Common.b2internal'; - - function b2Color() { - b2Color.b2Color.apply(this, arguments); - if (this.constructor === b2Color) this.b2Color.apply(this, arguments); - }; - Box2D.Common.b2Color = b2Color; - - function b2Settings() { - b2Settings.b2Settings.apply(this, arguments); - }; - Box2D.Common.b2Settings = b2Settings; - - function b2Mat22() { - b2Mat22.b2Mat22.apply(this, arguments); - if (this.constructor === b2Mat22) this.b2Mat22.apply(this, arguments); - }; - Box2D.Common.Math.b2Mat22 = b2Mat22; - - function b2Mat33() { - b2Mat33.b2Mat33.apply(this, arguments); - if (this.constructor === b2Mat33) this.b2Mat33.apply(this, arguments); - }; - Box2D.Common.Math.b2Mat33 = b2Mat33; - - function b2Math() { - b2Math.b2Math.apply(this, arguments); - }; - Box2D.Common.Math.b2Math = b2Math; - - function b2Sweep() { - b2Sweep.b2Sweep.apply(this, arguments); - }; - Box2D.Common.Math.b2Sweep = b2Sweep; - - function b2Transform() { - b2Transform.b2Transform.apply(this, arguments); - if (this.constructor === b2Transform) this.b2Transform.apply(this, arguments); - }; - Box2D.Common.Math.b2Transform = b2Transform; - - function b2Vec2() { - b2Vec2.b2Vec2.apply(this, arguments); - if (this.constructor === b2Vec2) this.b2Vec2.apply(this, arguments); - }; - Box2D.Common.Math.b2Vec2 = b2Vec2; - - function b2Vec3() { - b2Vec3.b2Vec3.apply(this, arguments); - if (this.constructor === b2Vec3) this.b2Vec3.apply(this, arguments); - }; - Box2D.Common.Math.b2Vec3 = b2Vec3; - - function b2Body() { - b2Body.b2Body.apply(this, arguments); - if (this.constructor === b2Body) this.b2Body.apply(this, arguments); - }; - Box2D.Dynamics.b2Body = b2Body; - - function b2BodyDef() { - b2BodyDef.b2BodyDef.apply(this, arguments); - if (this.constructor === b2BodyDef) this.b2BodyDef.apply(this, arguments); - }; - Box2D.Dynamics.b2BodyDef = b2BodyDef; - - function b2ContactFilter() { - b2ContactFilter.b2ContactFilter.apply(this, arguments); - }; - Box2D.Dynamics.b2ContactFilter = b2ContactFilter; - - function b2ContactImpulse() { - b2ContactImpulse.b2ContactImpulse.apply(this, arguments); - }; - Box2D.Dynamics.b2ContactImpulse = b2ContactImpulse; - - function b2ContactListener() { - b2ContactListener.b2ContactListener.apply(this, arguments); - }; - Box2D.Dynamics.b2ContactListener = b2ContactListener; - - function b2ContactManager() { - b2ContactManager.b2ContactManager.apply(this, arguments); - if (this.constructor === b2ContactManager) this.b2ContactManager.apply(this, arguments); - }; - Box2D.Dynamics.b2ContactManager = b2ContactManager; - - function b2DebugDraw() { - b2DebugDraw.b2DebugDraw.apply(this, arguments); - if (this.constructor === b2DebugDraw) this.b2DebugDraw.apply(this, arguments); - }; - Box2D.Dynamics.b2DebugDraw = b2DebugDraw; - - function b2DestructionListener() { - b2DestructionListener.b2DestructionListener.apply(this, arguments); - }; - Box2D.Dynamics.b2DestructionListener = b2DestructionListener; - - function b2FilterData() { - b2FilterData.b2FilterData.apply(this, arguments); - }; - Box2D.Dynamics.b2FilterData = b2FilterData; - - function b2Fixture() { - b2Fixture.b2Fixture.apply(this, arguments); - if (this.constructor === b2Fixture) this.b2Fixture.apply(this, arguments); - }; - Box2D.Dynamics.b2Fixture = b2Fixture; - - function b2FixtureDef() { - b2FixtureDef.b2FixtureDef.apply(this, arguments); - if (this.constructor === b2FixtureDef) this.b2FixtureDef.apply(this, arguments); - }; - Box2D.Dynamics.b2FixtureDef = b2FixtureDef; - - function b2Island() { - b2Island.b2Island.apply(this, arguments); - if (this.constructor === b2Island) this.b2Island.apply(this, arguments); - }; - Box2D.Dynamics.b2Island = b2Island; - - function b2TimeStep() { - b2TimeStep.b2TimeStep.apply(this, arguments); - }; - Box2D.Dynamics.b2TimeStep = b2TimeStep; - - function b2World() { - b2World.b2World.apply(this, arguments); - if (this.constructor === b2World) this.b2World.apply(this, arguments); - }; - Box2D.Dynamics.b2World = b2World; - - function b2CircleContact() { - b2CircleContact.b2CircleContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2CircleContact = b2CircleContact; - - function b2Contact() { - b2Contact.b2Contact.apply(this, arguments); - if (this.constructor === b2Contact) this.b2Contact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2Contact = b2Contact; - - function b2ContactConstraint() { - b2ContactConstraint.b2ContactConstraint.apply(this, arguments); - if (this.constructor === b2ContactConstraint) this.b2ContactConstraint.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactConstraint = b2ContactConstraint; - - function b2ContactConstraintPoint() { - b2ContactConstraintPoint.b2ContactConstraintPoint.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactConstraintPoint = b2ContactConstraintPoint; - - function b2ContactEdge() { - b2ContactEdge.b2ContactEdge.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactEdge = b2ContactEdge; - - function b2ContactFactory() { - b2ContactFactory.b2ContactFactory.apply(this, arguments); - if (this.constructor === b2ContactFactory) this.b2ContactFactory.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactFactory = b2ContactFactory; - - function b2ContactRegister() { - b2ContactRegister.b2ContactRegister.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactRegister = b2ContactRegister; - - function b2ContactResult() { - b2ContactResult.b2ContactResult.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactResult = b2ContactResult; - - function b2ContactSolver() { - b2ContactSolver.b2ContactSolver.apply(this, arguments); - if (this.constructor === b2ContactSolver) this.b2ContactSolver.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactSolver = b2ContactSolver; - - function b2EdgeAndCircleContact() { - b2EdgeAndCircleContact.b2EdgeAndCircleContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2EdgeAndCircleContact = b2EdgeAndCircleContact; - - function b2NullContact() { - b2NullContact.b2NullContact.apply(this, arguments); - if (this.constructor === b2NullContact) this.b2NullContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2NullContact = b2NullContact; - - function b2PolyAndCircleContact() { - b2PolyAndCircleContact.b2PolyAndCircleContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2PolyAndCircleContact = b2PolyAndCircleContact; - - function b2PolyAndEdgeContact() { - b2PolyAndEdgeContact.b2PolyAndEdgeContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2PolyAndEdgeContact = b2PolyAndEdgeContact; - - function b2PolygonContact() { - b2PolygonContact.b2PolygonContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2PolygonContact = b2PolygonContact; - - function b2PositionSolverManifold() { - b2PositionSolverManifold.b2PositionSolverManifold.apply(this, arguments); - if (this.constructor === b2PositionSolverManifold) this.b2PositionSolverManifold.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2PositionSolverManifold = b2PositionSolverManifold; - - function b2BuoyancyController() { - b2BuoyancyController.b2BuoyancyController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2BuoyancyController = b2BuoyancyController; - - function b2ConstantAccelController() { - b2ConstantAccelController.b2ConstantAccelController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2ConstantAccelController = b2ConstantAccelController; - - function b2ConstantForceController() { - b2ConstantForceController.b2ConstantForceController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2ConstantForceController = b2ConstantForceController; - - function b2Controller() { - b2Controller.b2Controller.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2Controller = b2Controller; - - function b2ControllerEdge() { - b2ControllerEdge.b2ControllerEdge.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2ControllerEdge = b2ControllerEdge; - - function b2GravityController() { - b2GravityController.b2GravityController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2GravityController = b2GravityController; - - function b2TensorDampingController() { - b2TensorDampingController.b2TensorDampingController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2TensorDampingController = b2TensorDampingController; - - function b2DistanceJoint() { - b2DistanceJoint.b2DistanceJoint.apply(this, arguments); - if (this.constructor === b2DistanceJoint) this.b2DistanceJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2DistanceJoint = b2DistanceJoint; - - function b2DistanceJointDef() { - b2DistanceJointDef.b2DistanceJointDef.apply(this, arguments); - if (this.constructor === b2DistanceJointDef) this.b2DistanceJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2DistanceJointDef = b2DistanceJointDef; - - function b2FrictionJoint() { - b2FrictionJoint.b2FrictionJoint.apply(this, arguments); - if (this.constructor === b2FrictionJoint) this.b2FrictionJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2FrictionJoint = b2FrictionJoint; - - function b2FrictionJointDef() { - b2FrictionJointDef.b2FrictionJointDef.apply(this, arguments); - if (this.constructor === b2FrictionJointDef) this.b2FrictionJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2FrictionJointDef = b2FrictionJointDef; - - function b2GearJoint() { - b2GearJoint.b2GearJoint.apply(this, arguments); - if (this.constructor === b2GearJoint) this.b2GearJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2GearJoint = b2GearJoint; - - function b2GearJointDef() { - b2GearJointDef.b2GearJointDef.apply(this, arguments); - if (this.constructor === b2GearJointDef) this.b2GearJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2GearJointDef = b2GearJointDef; - - function b2Jacobian() { - b2Jacobian.b2Jacobian.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2Jacobian = b2Jacobian; - - function b2Joint() { - b2Joint.b2Joint.apply(this, arguments); - if (this.constructor === b2Joint) this.b2Joint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2Joint = b2Joint; - - function b2JointDef() { - b2JointDef.b2JointDef.apply(this, arguments); - if (this.constructor === b2JointDef) this.b2JointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2JointDef = b2JointDef; - - function b2JointEdge() { - b2JointEdge.b2JointEdge.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2JointEdge = b2JointEdge; - - function b2LineJoint() { - b2LineJoint.b2LineJoint.apply(this, arguments); - if (this.constructor === b2LineJoint) this.b2LineJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2LineJoint = b2LineJoint; - - function b2LineJointDef() { - b2LineJointDef.b2LineJointDef.apply(this, arguments); - if (this.constructor === b2LineJointDef) this.b2LineJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2LineJointDef = b2LineJointDef; - - function b2MouseJoint() { - b2MouseJoint.b2MouseJoint.apply(this, arguments); - if (this.constructor === b2MouseJoint) this.b2MouseJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2MouseJoint = b2MouseJoint; - - function b2MouseJointDef() { - b2MouseJointDef.b2MouseJointDef.apply(this, arguments); - if (this.constructor === b2MouseJointDef) this.b2MouseJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2MouseJointDef = b2MouseJointDef; - - function b2PrismaticJoint() { - b2PrismaticJoint.b2PrismaticJoint.apply(this, arguments); - if (this.constructor === b2PrismaticJoint) this.b2PrismaticJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2PrismaticJoint = b2PrismaticJoint; - - function b2PrismaticJointDef() { - b2PrismaticJointDef.b2PrismaticJointDef.apply(this, arguments); - if (this.constructor === b2PrismaticJointDef) this.b2PrismaticJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2PrismaticJointDef = b2PrismaticJointDef; - - function b2PulleyJoint() { - b2PulleyJoint.b2PulleyJoint.apply(this, arguments); - if (this.constructor === b2PulleyJoint) this.b2PulleyJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2PulleyJoint = b2PulleyJoint; - - function b2PulleyJointDef() { - b2PulleyJointDef.b2PulleyJointDef.apply(this, arguments); - if (this.constructor === b2PulleyJointDef) this.b2PulleyJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2PulleyJointDef = b2PulleyJointDef; - - function b2RevoluteJoint() { - b2RevoluteJoint.b2RevoluteJoint.apply(this, arguments); - if (this.constructor === b2RevoluteJoint) this.b2RevoluteJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2RevoluteJoint = b2RevoluteJoint; - - function b2RevoluteJointDef() { - b2RevoluteJointDef.b2RevoluteJointDef.apply(this, arguments); - if (this.constructor === b2RevoluteJointDef) this.b2RevoluteJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2RevoluteJointDef = b2RevoluteJointDef; - - function b2WeldJoint() { - b2WeldJoint.b2WeldJoint.apply(this, arguments); - if (this.constructor === b2WeldJoint) this.b2WeldJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2WeldJoint = b2WeldJoint; - - function b2WeldJointDef() { - b2WeldJointDef.b2WeldJointDef.apply(this, arguments); - if (this.constructor === b2WeldJointDef) this.b2WeldJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2WeldJointDef = b2WeldJointDef; -})(); //definitions -_A2J_postDefs = []; /* source: disabled*/ -(function () { - var Dictionary = helpers.flash.utils.Dictionary; - var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; - var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; - var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; - var b2MassData = Box2D.Collision.Shapes.b2MassData; - var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; - var b2Shape = Box2D.Collision.Shapes.b2Shape; - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2internal = Box2D.Common.b2internal; - var b2Mat22 = Box2D.Common.Math.b2Mat22; - var b2Mat33 = Box2D.Common.Math.b2Mat33; - var b2Math = Box2D.Common.Math.b2Math; - var b2Sweep = Box2D.Common.Math.b2Sweep; - var b2Transform = Box2D.Common.Math.b2Transform; - var b2Vec2 = Box2D.Common.Math.b2Vec2; - var b2Vec3 = Box2D.Common.Math.b2Vec3; - var b2AABB = Box2D.Collision.b2AABB; - var b2Bound = Box2D.Collision.b2Bound; - var b2BoundValues = Box2D.Collision.b2BoundValues; - var b2BroadPhase = Box2D.Collision.b2BroadPhase; - var b2Collision = Box2D.Collision.b2Collision; - var b2ContactID = Box2D.Collision.b2ContactID; - var b2ContactPoint = Box2D.Collision.b2ContactPoint; - var b2Distance = Box2D.Collision.b2Distance; - var b2DistanceInput = Box2D.Collision.b2DistanceInput; - var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; - var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; - var b2DynamicTree = Box2D.Collision.b2DynamicTree; - var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; - var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; - var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; - var b2Manifold = Box2D.Collision.b2Manifold; - var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; - var b2OBB = Box2D.Collision.b2OBB; - var b2Pair = Box2D.Collision.b2Pair; - var b2PairManager = Box2D.Collision.b2PairManager; - var b2Point = Box2D.Collision.b2Point; - var b2Proxy = Box2D.Collision.b2Proxy; - var b2RayCastInput = Box2D.Collision.b2RayCastInput; - var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; - var b2Segment = Box2D.Collision.b2Segment; - var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; - var b2Simplex = Box2D.Collision.b2Simplex; - var b2SimplexCache = Box2D.Collision.b2SimplexCache; - var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; - var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; - var b2TOIInput = Box2D.Collision.b2TOIInput; - var b2WorldManifold = Box2D.Collision.b2WorldManifold; - var ClipVertex = Box2D.Collision.ClipVertex; - var Features = Box2D.Collision.Features; - var IBroadPhase = Box2D.Collision.IBroadPhase; - var b2internal = Box2D.Common.b2internal; - var b2internal = Box2D.Common.b2internal; - var b2Vec2 = Box2D.Common.Math.b2Vec2; - var b2AABB = Box2D.Collision.b2AABB; - var b2Bound = Box2D.Collision.b2Bound; - var b2BoundValues = Box2D.Collision.b2BoundValues; - var b2BroadPhase = Box2D.Collision.b2BroadPhase; - var b2Collision = Box2D.Collision.b2Collision; - var b2ContactID = Box2D.Collision.b2ContactID; - var b2ContactPoint = Box2D.Collision.b2ContactPoint; - var b2Distance = Box2D.Collision.b2Distance; - var b2DistanceInput = Box2D.Collision.b2DistanceInput; - var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; - var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; - var b2DynamicTree = Box2D.Collision.b2DynamicTree; - var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; - var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; - var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; - var b2Manifold = Box2D.Collision.b2Manifold; - var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; - var b2OBB = Box2D.Collision.b2OBB; - var b2Pair = Box2D.Collision.b2Pair; - var b2PairManager = Box2D.Collision.b2PairManager; - var b2Point = Box2D.Collision.b2Point; - var b2Proxy = Box2D.Collision.b2Proxy; - var b2RayCastInput = Box2D.Collision.b2RayCastInput; - var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; - var b2Segment = Box2D.Collision.b2Segment; - var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; - var b2Simplex = Box2D.Collision.b2Simplex; - var b2SimplexCache = Box2D.Collision.b2SimplexCache; - var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; - var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; - var b2TOIInput = Box2D.Collision.b2TOIInput; - var b2WorldManifold = Box2D.Collision.b2WorldManifold; - var ClipVertex = Box2D.Collision.ClipVertex; - var Features = Box2D.Collision.Features; - var IBroadPhase = Box2D.Collision.IBroadPhase; - var IBroadPhase = Box2D.Collision.IBroadPhase; - b2AABB.b2AABB = function () { - this.lowerBound = new b2Vec2(); - this.upperBound = new b2Vec2(); - }; - b2AABB.prototype.IsValid = function () { - var dX = this.upperBound.x - this.lowerBound.x; - var dY = this.upperBound.y - this.lowerBound.y; - var valid = dX >= 0.0 && dY >= 0.0; - valid = valid && this.lowerBound.IsValid() && this.upperBound.IsValid(); - return valid; - } - b2AABB.prototype.GetCenter = function () { - return new b2Vec2((this.lowerBound.x + this.upperBound.x) / 2, (this.lowerBound.y + this.upperBound.y) / 2); - } - b2AABB.prototype.GetExtents = function () { - return new b2Vec2((this.upperBound.x - this.lowerBound.x) / 2, (this.upperBound.y - this.lowerBound.y) / 2); - } - b2AABB.prototype.Contains = function (aabb) { - var result = true; - result = result && this.lowerBound.x <= aabb.lowerBound.x; - result = result && this.lowerBound.y <= aabb.lowerBound.y; - result = result && aabb.upperBound.x <= this.upperBound.x; - result = result && aabb.upperBound.y <= this.upperBound.y; - return result; - } - b2AABB.prototype.RayCast = function (output, input) { - var tmin = (-Number.MAX_VALUE); - var tmax = Number.MAX_VALUE; - var pX = input.p1.x; - var pY = input.p1.y; - var dX = input.p2.x - input.p1.x; - var dY = input.p2.y - input.p1.y; - var absDX = Math.abs(dX); - var absDY = Math.abs(dY); - var normal = output.normal; - var inv_d = 0; - var t1 = 0; - var t2 = 0; - var t3 = 0; - var s = 0; { - if (absDX < Number.MIN_VALUE) { - if (pX < this.lowerBound.x || this.upperBound.x < pX) return false; - } - else { - inv_d = 1.0 / dX; - t1 = (this.lowerBound.x - pX) * inv_d; - t2 = (this.upperBound.x - pX) * inv_d; - s = (-1.0); - if (t1 > t2) { - t3 = t1; - t1 = t2; - t2 = t3; - s = 1.0; - } - if (t1 > tmin) { - normal.x = s; - normal.y = 0; - tmin = t1; - } - tmax = Math.min(tmax, t2); - if (tmin > tmax) return false; - } - } { - if (absDY < Number.MIN_VALUE) { - if (pY < this.lowerBound.y || this.upperBound.y < pY) return false; - } - else { - inv_d = 1.0 / dY; - t1 = (this.lowerBound.y - pY) * inv_d; - t2 = (this.upperBound.y - pY) * inv_d; - s = (-1.0); - if (t1 > t2) { - t3 = t1; - t1 = t2; - t2 = t3; - s = 1.0; - } - if (t1 > tmin) { - normal.y = s; - normal.x = 0; - tmin = t1; - } - tmax = Math.min(tmax, t2); - if (tmin > tmax) return false; - } - } - output.fraction = tmin; - return true; - } - b2AABB.prototype.TestOverlap = function (other) { - var d1X = other.lowerBound.x - this.upperBound.x; - var d1Y = other.lowerBound.y - this.upperBound.y; - var d2X = this.lowerBound.x - other.upperBound.x; - var d2Y = this.lowerBound.y - other.upperBound.y; - if (d1X > 0.0 || d1Y > 0.0) return false; - if (d2X > 0.0 || d2Y > 0.0) return false; - return true; - } - b2AABB.prototype.Combine = function (aabb1, aabb2) { - var aabb = new b2AABB(); - if (this.constructor === Box2D.Collision.b2AABB) this._a2j__Combine(aabb1, aabb2); - else aabb._a2j__Combine(aabb1, aabb2); - return aabb; - } - b2AABB.Combine = b2AABB.prototype.Combine; - b2AABB.prototype._a2j__Combine = function (aabb1, aabb2) { - this.lowerBound.x = Math.min(aabb1.lowerBound.x, aabb2.lowerBound.x); - this.lowerBound.y = Math.min(aabb1.lowerBound.y, aabb2.lowerBound.y); - this.upperBound.x = Math.max(aabb1.upperBound.x, aabb2.upperBound.x); - this.upperBound.y = Math.max(aabb1.upperBound.y, aabb2.upperBound.y); - } - b2Bound.b2Bound = function () {}; - b2Bound.prototype.IsLower = function () { - return (this.value & 1) == 0; - } - b2Bound.prototype.IsUpper = function () { - return (this.value & 1) == 1; - } - b2Bound.prototype.Swap = function (b) { - var tempValue = this.value; - var tempProxy = this.proxy; - var tempStabbingCount = this.stabbingCount; - this.value = b.value; - this.proxy = b.proxy; - this.stabbingCount = b.stabbingCount; - b.value = tempValue; - b.proxy = tempProxy; - b.stabbingCount = tempStabbingCount; - } - b2BoundValues.b2BoundValues = function () {}; - b2BoundValues.prototype.b2BoundValues = function () { - this.lowerValues = new Vector_a2j_Number(); - this.lowerValues[0] = 0.0; - this.lowerValues[1] = 0.0; - this.upperValues = new Vector_a2j_Number(); - this.upperValues[0] = 0.0; - this.upperValues[1] = 0.0; - } - b2BroadPhase.b2BroadPhase = function () { - this.m_pairManager = new b2PairManager(); - this.m_proxyPool = new Array(); - this.m_querySortKeys = new Array(); - this.m_queryResults = new Array(); - this.m_quantizationFactor = new b2Vec2(); - }; - b2BroadPhase.prototype.b2BroadPhase = function (worldAABB) { - var i = 0; - this.m_pairManager.Initialize(this); - this.m_worldAABB = worldAABB; - this.m_proxyCount = 0; - this.m_bounds = new Vector(); - for (i = 0; - i < 2; i++) { - this.m_bounds[i] = new Vector(); - } - var dX = worldAABB.upperBound.x - worldAABB.lowerBound.x; - var dY = worldAABB.upperBound.y - worldAABB.lowerBound.y; - this.m_quantizationFactor.x = b2Settings.USHRT_MAX / dX; - this.m_quantizationFactor.y = b2Settings.USHRT_MAX / dY; - this.m_timeStamp = 1; - this.m_queryResultCount = 0; - } - b2BroadPhase.prototype.InRange = function (aabb) { - var dX = 0; - var dY = 0; - var d2X = 0; - var d2Y = 0; - dX = aabb.lowerBound.x; - dY = aabb.lowerBound.y; - dX -= this.m_worldAABB.upperBound.x; - dY -= this.m_worldAABB.upperBound.y; - d2X = this.m_worldAABB.lowerBound.x; - d2Y = this.m_worldAABB.lowerBound.y; - d2X -= aabb.upperBound.x; - d2Y -= aabb.upperBound.y; - dX = b2Math.Max(dX, d2X); - dY = b2Math.Max(dY, d2Y); - return b2Math.Max(dX, dY) < 0.0; - } - b2BroadPhase.prototype.CreateProxy = function (aabb, userData) { - var index = 0; - var proxy; - var i = 0; - var j = 0; - if (!this.m_freeProxy) { - this.m_freeProxy = this.m_proxyPool[this.m_proxyCount] = new b2Proxy(); - this.m_freeProxy.next = null; - this.m_freeProxy.timeStamp = 0; - this.m_freeProxy.overlapCount = b2BroadPhase.b2_invalid; - this.m_freeProxy.userData = null; - for (i = 0; - i < 2; i++) { - j = this.m_proxyCount * 2; - this.m_bounds[i][j++] = new b2Bound(); - this.m_bounds[i][j] = new b2Bound(); - } - } - proxy = this.m_freeProxy; - this.m_freeProxy = proxy.next; - proxy.overlapCount = 0; - proxy.userData = userData; - var boundCount = 2 * this.m_proxyCount; - var lowerValues = new Vector_a2j_Number(); - var upperValues = new Vector_a2j_Number(); - this.ComputeBounds(lowerValues, upperValues, aabb); - for (var axis = 0; axis < 2; ++axis) { - var bounds = this.m_bounds[axis]; - var lowerIndex = 0; - var upperIndex = 0; - var lowerIndexOut = new Vector_a2j_Number(); - lowerIndexOut.push(lowerIndex); - var upperIndexOut = new Vector_a2j_Number(); - upperIndexOut.push(upperIndex); - this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[axis], upperValues[axis], bounds, boundCount, axis); - lowerIndex = lowerIndexOut[0]; - upperIndex = upperIndexOut[0]; - bounds.splice(upperIndex, 0, bounds[bounds.length - 1]); - bounds.length--; - bounds.splice(lowerIndex, 0, bounds[bounds.length - 1]); - bounds.length--; - ++upperIndex; - var tBound1 = bounds[lowerIndex]; - var tBound2 = bounds[upperIndex]; - tBound1.value = lowerValues[axis]; - tBound1.proxy = proxy; - tBound2.value = upperValues[axis]; - tBound2.proxy = proxy; - var tBoundAS3 = bounds[parseInt(lowerIndex - 1)]; - tBound1.stabbingCount = lowerIndex == 0 ? 0 : tBoundAS3.stabbingCount; - tBoundAS3 = bounds[parseInt(upperIndex - 1)]; - tBound2.stabbingCount = tBoundAS3.stabbingCount; - for (index = lowerIndex; - index < upperIndex; ++index) { - tBoundAS3 = bounds[index]; - tBoundAS3.stabbingCount++; - } - for (index = lowerIndex; - index < boundCount + 2; ++index) { - tBound1 = bounds[index]; - var proxy2 = tBound1.proxy; - if (tBound1.IsLower()) { - proxy2.lowerBounds[axis] = index; - } - else { - proxy2.upperBounds[axis] = index; - } - } - }++this.m_proxyCount; - for (i = 0; - i < this.m_queryResultCount; ++i) { - this.m_pairManager.AddBufferedPair(proxy, this.m_queryResults[i]); - } - this.m_queryResultCount = 0; - this.IncrementTimeStamp(); - return proxy; - } - b2BroadPhase.prototype.DestroyProxy = function (proxy_) { - var proxy = (proxy_ instanceof b2Proxy ? proxy_ : null); - var tBound1; - var tBound2; - var boundCount = parseInt(2 * this.m_proxyCount); - for (var axis = 0; axis < 2; ++axis) { - var bounds = this.m_bounds[axis]; - var lowerIndex = proxy.lowerBounds[axis]; - var upperIndex = proxy.upperBounds[axis]; - tBound1 = bounds[lowerIndex]; - var lowerValue = tBound1.value; - tBound2 = bounds[upperIndex]; - var upperValue = tBound2.value; - bounds.splice(upperIndex, 1); - bounds.splice(lowerIndex, 1); - bounds.push(tBound1); - bounds.push(tBound2); - var tEnd = parseInt(boundCount - 2); - for (var index = lowerIndex; index < tEnd; ++index) { - tBound1 = bounds[index]; - var proxy2 = tBound1.proxy; - if (tBound1.IsLower()) { - proxy2.lowerBounds[axis] = index; - } - else { - proxy2.upperBounds[axis] = index; - } - } - tEnd = upperIndex - 1; - for (var index2 = parseInt(lowerIndex); index2 < tEnd; ++index2) { - tBound1 = bounds[index2]; - tBound1.stabbingCount--; - } - var ignore = new Vector_a2j_Number(); - this.QueryAxis(ignore, ignore, lowerValue, upperValue, bounds, boundCount - 2, axis); - } - for (var i = 0; i < this.m_queryResultCount; ++i) { - this.m_pairManager.RemoveBufferedPair(proxy, this.m_queryResults[i]); - } - this.m_queryResultCount = 0; - this.IncrementTimeStamp(); - proxy.userData = null; - proxy.overlapCount = b2BroadPhase.b2_invalid; - proxy.lowerBounds[0] = b2BroadPhase.b2_invalid; - proxy.lowerBounds[1] = b2BroadPhase.b2_invalid; - proxy.upperBounds[0] = b2BroadPhase.b2_invalid; - proxy.upperBounds[1] = b2BroadPhase.b2_invalid; - proxy.next = this.m_freeProxy; - this.m_freeProxy = proxy; - --this.m_proxyCount; - } - b2BroadPhase.prototype.MoveProxy = function (proxy_, aabb, displacement) { - var proxy = (proxy_ instanceof b2Proxy ? proxy_ : null); - var as3arr; - var as3int = 0; - var axis = 0; - var index = 0; - var bound; - var prevBound; - var nextBound; - var nextProxyId = 0; - var nextProxy; - if (proxy == null) { - return; - } - if (aabb.IsValid() == false) { - return; - } - var boundCount = 2 * this.m_proxyCount; - var newValues = new b2BoundValues(); - this.ComputeBounds(newValues.lowerValues, newValues.upperValues, aabb); - var oldValues = new b2BoundValues(); - for (axis = 0; - axis < 2; ++axis) { - bound = this.m_bounds[axis][proxy.lowerBounds[axis]]; - oldValues.lowerValues[axis] = bound.value; - bound = this.m_bounds[axis][proxy.upperBounds[axis]]; - oldValues.upperValues[axis] = bound.value; - } - for (axis = 0; - axis < 2; ++axis) { - var bounds = this.m_bounds[axis]; - var lowerIndex = proxy.lowerBounds[axis]; - var upperIndex = proxy.upperBounds[axis]; - var lowerValue = newValues.lowerValues[axis]; - var upperValue = newValues.upperValues[axis]; - bound = bounds[lowerIndex]; - var deltaLower = parseInt(lowerValue - bound.value); - bound.value = lowerValue; - bound = bounds[upperIndex]; - var deltaUpper = parseInt(upperValue - bound.value); - bound.value = upperValue; - if (deltaLower < 0) { - index = lowerIndex; - while (index > 0 && lowerValue < ((bounds[parseInt(index - 1)] instanceof b2Bound ? bounds[parseInt(index - 1)] : null)).value) { - bound = bounds[index]; - prevBound = bounds[parseInt(index - 1)]; - var prevProxy = prevBound.proxy; - prevBound.stabbingCount++; - if (prevBound.IsUpper() == true) { - if (this.TestOverlapBound(newValues, prevProxy)) { - this.m_pairManager.AddBufferedPair(proxy, prevProxy); - } - as3arr = prevProxy.upperBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.stabbingCount++; - } - else { - as3arr = prevProxy.lowerBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.stabbingCount--; - } - as3arr = proxy.lowerBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.Swap(prevBound); - --index; - } - } - if (deltaUpper > 0) { - index = upperIndex; - while (index < boundCount - 1 && ((bounds[parseInt(index + 1)] instanceof b2Bound ? bounds[parseInt(index + 1)] : null)).value <= upperValue) { - bound = bounds[index]; - nextBound = bounds[parseInt(index + 1)]; - nextProxy = nextBound.proxy; - nextBound.stabbingCount++; - if (nextBound.IsLower() == true) { - if (this.TestOverlapBound(newValues, nextProxy)) { - this.m_pairManager.AddBufferedPair(proxy, nextProxy); - } - as3arr = nextProxy.lowerBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.stabbingCount++; - } - else { - as3arr = nextProxy.upperBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.stabbingCount--; - } - as3arr = proxy.upperBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.Swap(nextBound); - index++; - } - } - if (deltaLower > 0) { - index = lowerIndex; - while (index < boundCount - 1 && ((bounds[parseInt(index + 1)] instanceof b2Bound ? bounds[parseInt(index + 1)] : null)).value <= lowerValue) { - bound = bounds[index]; - nextBound = bounds[parseInt(index + 1)]; - nextProxy = nextBound.proxy; - nextBound.stabbingCount--; - if (nextBound.IsUpper()) { - if (this.TestOverlapBound(oldValues, nextProxy)) { - this.m_pairManager.RemoveBufferedPair(proxy, nextProxy); - } - as3arr = nextProxy.upperBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.stabbingCount--; - } - else { - as3arr = nextProxy.lowerBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.stabbingCount++; - } - as3arr = proxy.lowerBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.Swap(nextBound); - index++; - } - } - if (deltaUpper < 0) { - index = upperIndex; - while (index > 0 && upperValue < ((bounds[parseInt(index - 1)] instanceof b2Bound ? bounds[parseInt(index - 1)] : null)).value) { - bound = bounds[index]; - prevBound = bounds[parseInt(index - 1)]; - prevProxy = prevBound.proxy; - prevBound.stabbingCount--; - if (prevBound.IsLower() == true) { - if (this.TestOverlapBound(oldValues, prevProxy)) { - this.m_pairManager.RemoveBufferedPair(proxy, prevProxy); - } - as3arr = prevProxy.lowerBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.stabbingCount--; - } - else { - as3arr = prevProxy.upperBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.stabbingCount++; - } - as3arr = proxy.upperBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.Swap(prevBound); - index--; - } - } - } - } - b2BroadPhase.prototype.UpdatePairs = function (callback) { - this.m_pairManager.Commit(callback); - } - b2BroadPhase.prototype.TestOverlap = function (proxyA, proxyB) { - var proxyA_ = (proxyA instanceof b2Proxy ? proxyA : null); - var proxyB_ = (proxyB instanceof b2Proxy ? proxyB : null); - if (proxyA_.lowerBounds[0] > proxyB_.upperBounds[0]) return false; - if (proxyB_.lowerBounds[0] > proxyA_.upperBounds[0]) return false; - if (proxyA_.lowerBounds[1] > proxyB_.upperBounds[1]) return false; - if (proxyB_.lowerBounds[1] > proxyA_.upperBounds[1]) return false; - return true; - } - b2BroadPhase.prototype.GetUserData = function (proxy) { - return ((proxy instanceof b2Proxy ? proxy : null)).userData; - } - b2BroadPhase.prototype.GetFatAABB = function (proxy_) { - var aabb = new b2AABB(); - var proxy = (proxy_ instanceof b2Proxy ? proxy_ : null); - aabb.lowerBound.x = this.m_worldAABB.lowerBound.x + this.m_bounds[0][proxy.lowerBounds[0]].value / this.m_quantizationFactor.x; - aabb.lowerBound.y = this.m_worldAABB.lowerBound.y + this.m_bounds[1][proxy.lowerBounds[1]].value / this.m_quantizationFactor.y; - aabb.upperBound.x = this.m_worldAABB.lowerBound.x + this.m_bounds[0][proxy.upperBounds[0]].value / this.m_quantizationFactor.x; - aabb.upperBound.y = this.m_worldAABB.lowerBound.y + this.m_bounds[1][proxy.upperBounds[1]].value / this.m_quantizationFactor.y; - return aabb; - } - b2BroadPhase.prototype.GetProxyCount = function () { - return this.m_proxyCount; - } - b2BroadPhase.prototype.Query = function (callback, aabb) { - var lowerValues = new Vector_a2j_Number(); - var upperValues = new Vector_a2j_Number(); - this.ComputeBounds(lowerValues, upperValues, aabb); - var lowerIndex = 0; - var upperIndex = 0; - var lowerIndexOut = new Vector_a2j_Number(); - lowerIndexOut.push(lowerIndex); - var upperIndexOut = new Vector_a2j_Number(); - upperIndexOut.push(upperIndex); - this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[0], upperValues[0], this.m_bounds[0], 2 * this.m_proxyCount, 0); - this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[1], upperValues[1], this.m_bounds[1], 2 * this.m_proxyCount, 1); - for (var i = 0; i < this.m_queryResultCount; ++i) { - var proxy = this.m_queryResults[i]; - if (!callback(proxy)) { - break; - } - } - this.m_queryResultCount = 0; - this.IncrementTimeStamp(); - } - b2BroadPhase.prototype.Validate = function () { - var pair; - var proxy1; - var proxy2; - var overlap; - for (var axis = 0; axis < 2; ++axis) { - var bounds = this.m_bounds[axis]; - var boundCount = 2 * this.m_proxyCount; - var stabbingCount = 0; - for (var i = 0; i < boundCount; ++i) { - var bound = bounds[i]; - if (bound.IsLower() == true) { - stabbingCount++; - } - else { - stabbingCount--; - } - } - } - } - b2BroadPhase.prototype.Rebalance = function (iterations) { - if (iterations === undefined) iterations = 0; - } - b2BroadPhase.prototype.RayCast = function (callback, input) { - var subInput = new b2RayCastInput(); - subInput.p1.SetV(input.p1); - subInput.p2.SetV(input.p2); +function extend(a, b) { + for(var c in b) { + a[c] = b[c] + } +} +function isInstanceOf(obj, _constructor) { + while(typeof obj === "object") { + if(obj.constructor === _constructor) { + return true + } + obj = obj._super + } + return false +} +;var b2BoundValues = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2BoundValues.prototype.__constructor = function() { + this.lowerValues = new Array; + this.lowerValues[0] = 0; + this.lowerValues[1] = 0; + this.upperValues = new Array; + this.upperValues[0] = 0; + this.upperValues[1] = 0 +}; +b2BoundValues.prototype.__varz = function() { +}; +b2BoundValues.prototype.lowerValues = null; +b2BoundValues.prototype.upperValues = null;var b2PairManager = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2PairManager.prototype.__constructor = function() { + this.m_pairs = new Array; + this.m_pairBuffer = new Array; + this.m_pairCount = 0; + this.m_pairBufferCount = 0; + this.m_freePair = null +}; +b2PairManager.prototype.__varz = function() { +}; +b2PairManager.prototype.AddPair = function(proxy1, proxy2) { + var pair = proxy1.pairs[proxy2]; + if(pair != null) { + return pair + } + if(this.m_freePair == null) { + this.m_freePair = new b2Pair; + this.m_pairs.push(this.m_freePair) + } + pair = this.m_freePair; + this.m_freePair = pair.next; + pair.proxy1 = proxy1; + pair.proxy2 = proxy2; + pair.status = 0; + pair.userData = null; + pair.next = null; + proxy1.pairs[proxy2] = pair; + proxy2.pairs[proxy1] = pair; + ++this.m_pairCount; + return pair +}; +b2PairManager.prototype.RemovePair = function(proxy1, proxy2) { + var pair = proxy1.pairs[proxy2]; + if(pair == null) { + return null + } + var userData = pair.userData; + delete proxy1.pairs[proxy2]; + delete proxy2.pairs[proxy1]; + pair.next = this.m_freePair; + pair.proxy1 = null; + pair.proxy2 = null; + pair.userData = null; + pair.status = 0; + this.m_freePair = pair; + --this.m_pairCount; + return userData +}; +b2PairManager.prototype.Find = function(proxy1, proxy2) { + return proxy1.pairs[proxy2] +}; +b2PairManager.prototype.ValidateBuffer = function() { +}; +b2PairManager.prototype.ValidateTable = function() { +}; +b2PairManager.prototype.Initialize = function(broadPhase) { + this.m_broadPhase = broadPhase +}; +b2PairManager.prototype.AddBufferedPair = function(proxy1, proxy2) { + var pair = this.AddPair(proxy1, proxy2); + if(pair.IsBuffered() == false) { + pair.SetBuffered(); + this.m_pairBuffer[this.m_pairBufferCount] = pair; + ++this.m_pairBufferCount + } + pair.ClearRemoved(); + if(b2BroadPhase.s_validate) { + this.ValidateBuffer() + } +}; +b2PairManager.prototype.RemoveBufferedPair = function(proxy1, proxy2) { + var pair = this.Find(proxy1, proxy2); + if(pair == null) { + return + } + if(pair.IsBuffered() == false) { + pair.SetBuffered(); + this.m_pairBuffer[this.m_pairBufferCount] = pair; + ++this.m_pairBufferCount + } + pair.SetRemoved(); + if(b2BroadPhase.s_validate) { + this.ValidateBuffer() + } +}; +b2PairManager.prototype.Commit = function(callback) { + var i = 0; + var removeCount = 0; + for(i = 0;i < this.m_pairBufferCount;++i) { + var pair = this.m_pairBuffer[i]; + pair.ClearBuffered(); + var proxy1 = pair.proxy1; + var proxy2 = pair.proxy2; + if(pair.IsRemoved()) { + }else { + if(pair.IsFinal() == false) { + callback(proxy1.userData, proxy2.userData) + } + } + } + this.m_pairBufferCount = 0; + if(b2BroadPhase.s_validate) { + this.ValidateTable() + } +}; +b2PairManager.prototype.m_broadPhase = null; +b2PairManager.prototype.m_pairs = null; +b2PairManager.prototype.m_freePair = null; +b2PairManager.prototype.m_pairCount = 0; +b2PairManager.prototype.m_pairBuffer = null; +b2PairManager.prototype.m_pairBufferCount = 0;var b2TimeStep = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2TimeStep.prototype.__constructor = function() { +}; +b2TimeStep.prototype.__varz = function() { +}; +b2TimeStep.prototype.Set = function(step) { + this.dt = step.dt; + this.inv_dt = step.inv_dt; + this.positionIterations = step.positionIterations; + this.velocityIterations = step.velocityIterations; + this.warmStarting = step.warmStarting +}; +b2TimeStep.prototype.dt = null; +b2TimeStep.prototype.inv_dt = null; +b2TimeStep.prototype.dtRatio = null; +b2TimeStep.prototype.velocityIterations = 0; +b2TimeStep.prototype.positionIterations = 0; +b2TimeStep.prototype.warmStarting = null;var b2Controller = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Controller.prototype.__constructor = function() { +}; +b2Controller.prototype.__varz = function() { +}; +b2Controller.prototype.Step = function(step) { +}; +b2Controller.prototype.Draw = function(debugDraw) { +}; +b2Controller.prototype.AddBody = function(body) { + var edge = new b2ControllerEdge; + edge.controller = this; + edge.body = body; + edge.nextBody = m_bodyList; + edge.prevBody = null; + m_bodyList = edge; + if(edge.nextBody) { + edge.nextBody.prevBody = edge + } + m_bodyCount++; + edge.nextController = body.m_controllerList; + edge.prevController = null; + body.m_controllerList = edge; + if(edge.nextController) { + edge.nextController.prevController = edge + } + body.m_controllerCount++ +}; +b2Controller.prototype.RemoveBody = function(body) { + var edge = body.m_controllerList; + while(edge && edge.controller != this) { + edge = edge.nextController + } + if(edge.prevBody) { + edge.prevBody.nextBody = edge.nextBody + } + if(edge.nextBody) { + edge.nextBody.prevBody = edge.prevBody + } + if(edge.nextController) { + edge.nextController.prevController = edge.prevController + } + if(edge.prevController) { + edge.prevController.nextController = edge.nextController + } + if(m_bodyList == edge) { + m_bodyList = edge.nextBody + } + if(body.m_controllerList == edge) { + body.m_controllerList = edge.nextController + } + body.m_controllerCount--; + m_bodyCount-- +}; +b2Controller.prototype.Clear = function() { + while(m_bodyList) { + this.RemoveBody(m_bodyList.body) + } +}; +b2Controller.prototype.GetNext = function() { + return this.m_next +}; +b2Controller.prototype.GetWorld = function() { + return this.m_world +}; +b2Controller.prototype.GetBodyList = function() { + return m_bodyList +}; +b2Controller.prototype.m_next = null; +b2Controller.prototype.m_prev = null; +b2Controller.prototype.m_world = null;var b2GravityController = function() { + b2Controller.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2GravityController.prototype, b2Controller.prototype); +b2GravityController.prototype._super = b2Controller.prototype; +b2GravityController.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2GravityController.prototype.__varz = function() { +}; +b2GravityController.prototype.Step = function(step) { + var i = null; + var body1 = null; + var p1 = null; + var mass1 = 0; + var j = null; + var body2 = null; + var p2 = null; + var dx = 0; + var dy = 0; + var r2 = 0; + var f = null; + if(this.invSqr) { + for(i = m_bodyList;i;i = i.nextBody) { + body1 = i.body; + p1 = body1.GetWorldCenter(); + mass1 = body1.GetMass(); + for(j = m_bodyList;j != i;j = j.nextBody) { + body2 = j.body; + p2 = body2.GetWorldCenter(); + dx = p2.x - p1.x; + dy = p2.y - p1.y; + r2 = dx * dx + dy * dy; + if(r2 < Number.MIN_VALUE) { + continue + } + f = new b2Vec2(dx, dy); + f.Multiply(this.G / r2 / Math.sqrt(r2) * mass1 * body2.GetMass()); + if(body1.IsAwake()) { + body1.ApplyForce(f, p1) + } + f.Multiply(-1); + if(body2.IsAwake()) { + body2.ApplyForce(f, p2) + } + } + } + }else { + for(i = m_bodyList;i;i = i.nextBody) { + body1 = i.body; + p1 = body1.GetWorldCenter(); + mass1 = body1.GetMass(); + for(j = m_bodyList;j != i;j = j.nextBody) { + body2 = j.body; + p2 = body2.GetWorldCenter(); + dx = p2.x - p1.x; + dy = p2.y - p1.y; + r2 = dx * dx + dy * dy; + if(r2 < Number.MIN_VALUE) { + continue + } + f = new b2Vec2(dx, dy); + f.Multiply(this.G / r2 * mass1 * body2.GetMass()); + if(body1.IsAwake()) { + body1.ApplyForce(f, p1) + } + f.Multiply(-1); + if(body2.IsAwake()) { + body2.ApplyForce(f, p2) + } + } + } + } +}; +b2GravityController.prototype.G = 1; +b2GravityController.prototype.invSqr = true;var b2DestructionListener = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2DestructionListener.prototype.__constructor = function() { +}; +b2DestructionListener.prototype.__varz = function() { +}; +b2DestructionListener.prototype.SayGoodbyeJoint = function(joint) { +}; +b2DestructionListener.prototype.SayGoodbyeFixture = function(fixture) { +};var b2ContactEdge = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactEdge.prototype.__constructor = function() { +}; +b2ContactEdge.prototype.__varz = function() { +}; +b2ContactEdge.prototype.other = null; +b2ContactEdge.prototype.contact = null; +b2ContactEdge.prototype.prev = null; +b2ContactEdge.prototype.next = null;var b2EdgeChainDef = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2EdgeChainDef.prototype.__constructor = function() { + this.vertexCount = 0; + this.isALoop = true; + this.vertices = [] +}; +b2EdgeChainDef.prototype.__varz = function() { +}; +b2EdgeChainDef.prototype.vertices = null; +b2EdgeChainDef.prototype.vertexCount = null; +b2EdgeChainDef.prototype.isALoop = null;var b2Vec2 = function(x_, y_) { + if(arguments.length == 2) { + this.x = x_; + this.y = y_ + } +}; +b2Vec2.Make = function(x_, y_) { + return new b2Vec2(x_, y_) +}; +b2Vec2.prototype.SetZero = function() { + this.x = 0; + this.y = 0 +}; +b2Vec2.prototype.Set = function(x_, y_) { + this.x = x_; + this.y = y_ +}; +b2Vec2.prototype.SetV = function(v) { + this.x = v.x; + this.y = v.y +}; +b2Vec2.prototype.GetNegative = function() { + return new b2Vec2(-this.x, -this.y) +}; +b2Vec2.prototype.NegativeSelf = function() { + this.x = -this.x; + this.y = -this.y +}; +b2Vec2.prototype.Copy = function() { + return new b2Vec2(this.x, this.y) +}; +b2Vec2.prototype.Add = function(v) { + this.x += v.x; + this.y += v.y +}; +b2Vec2.prototype.Subtract = function(v) { + this.x -= v.x; + this.y -= v.y +}; +b2Vec2.prototype.Multiply = function(a) { + this.x *= a; + this.y *= a +}; +b2Vec2.prototype.MulM = function(A) { + var tX = this.x; + this.x = A.col1.x * tX + A.col2.x * this.y; + this.y = A.col1.y * tX + A.col2.y * this.y +}; +b2Vec2.prototype.MulTM = function(A) { + var tX = b2Math.Dot(this, A.col1); + this.y = b2Math.Dot(this, A.col2); + this.x = tX +}; +b2Vec2.prototype.CrossVF = function(s) { + var tX = this.x; + this.x = s * this.y; + this.y = -s * tX +}; +b2Vec2.prototype.CrossFV = function(s) { + var tX = this.x; + this.x = -s * this.y; + this.y = s * tX +}; +b2Vec2.prototype.MinV = function(b) { + this.x = this.x < b.x ? this.x : b.x; + this.y = this.y < b.y ? this.y : b.y +}; +b2Vec2.prototype.MaxV = function(b) { + this.x = this.x > b.x ? this.x : b.x; + this.y = this.y > b.y ? this.y : b.y +}; +b2Vec2.prototype.Abs = function() { + if(this.x < 0) { + this.x = -this.x + } + if(this.y < 0) { + this.y = -this.y + } +}; +b2Vec2.prototype.Length = function() { + return Math.sqrt(this.x * this.x + this.y * this.y) +}; +b2Vec2.prototype.LengthSquared = function() { + return this.x * this.x + this.y * this.y +}; +b2Vec2.prototype.Normalize = function() { + var length = Math.sqrt(this.x * this.x + this.y * this.y); + if(length < Number.MIN_VALUE) { + return 0 + } + var invLength = 1 / length; + this.x *= invLength; + this.y *= invLength; + return length +}; +b2Vec2.prototype.IsValid = function() { + return b2Math.IsValid(this.x) && b2Math.IsValid(this.y) +}; +b2Vec2.prototype.x = 0; +b2Vec2.prototype.y = 0;var b2Vec3 = function(x, y, z) { + if(arguments.length == 3) { + this.x = x; + this.y = y; + this.z = z + } +}; +b2Vec3.prototype.SetZero = function() { + this.x = this.y = this.z = 0 +}; +b2Vec3.prototype.Set = function(x, y, z) { + this.x = x; + this.y = y; + this.z = z +}; +b2Vec3.prototype.SetV = function(v) { + this.x = v.x; + this.y = v.y; + this.z = v.z +}; +b2Vec3.prototype.GetNegative = function() { + return new b2Vec3(-this.x, -this.y, -this.z) +}; +b2Vec3.prototype.NegativeSelf = function() { + this.x = -this.x; + this.y = -this.y; + this.z = -this.z +}; +b2Vec3.prototype.Copy = function() { + return new b2Vec3(this.x, this.y, this.z) +}; +b2Vec3.prototype.Add = function(v) { + this.x += v.x; + this.y += v.y; + this.z += v.z +}; +b2Vec3.prototype.Subtract = function(v) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z +}; +b2Vec3.prototype.Multiply = function(a) { + this.x *= a; + this.y *= a; + this.z *= a +}; +b2Vec3.prototype.x = 0; +b2Vec3.prototype.y = 0; +b2Vec3.prototype.z = 0;var b2DistanceProxy = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2DistanceProxy.prototype.__constructor = function() { +}; +b2DistanceProxy.prototype.__varz = function() { +}; +b2DistanceProxy.prototype.Set = function(shape) { + switch(shape.GetType()) { + case b2Shape.e_circleShape: + var circle = shape; + this.m_vertices = new Array(1); + this.m_vertices[0] = circle.m_p; + this.m_count = 1; + this.m_radius = circle.m_radius; + break; + case b2Shape.e_polygonShape: + var polygon = shape; + this.m_vertices = polygon.m_vertices; + this.m_count = polygon.m_vertexCount; + this.m_radius = polygon.m_radius; + break; + default: + b2Settings.b2Assert(false) + } +}; +b2DistanceProxy.prototype.GetSupport = function(d) { + var bestIndex = 0; + var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; + for(var i = 1;i < this.m_count;++i) { + var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; + if(value > bestValue) { + bestIndex = i; + bestValue = value + } + } + return bestIndex +}; +b2DistanceProxy.prototype.GetSupportVertex = function(d) { + var bestIndex = 0; + var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; + for(var i = 1;i < this.m_count;++i) { + var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; + if(value > bestValue) { + bestIndex = i; + bestValue = value + } + } + return this.m_vertices[bestIndex] +}; +b2DistanceProxy.prototype.GetVertexCount = function() { + return this.m_count +}; +b2DistanceProxy.prototype.GetVertex = function(index) { + b2Settings.b2Assert(0 <= index && index < this.m_count); + return this.m_vertices[index] +}; +b2DistanceProxy.prototype.m_vertices = null; +b2DistanceProxy.prototype.m_count = 0; +b2DistanceProxy.prototype.m_radius = null;var b2ContactFactory = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactFactory.prototype.__constructor = function() { +}; +b2ContactFactory.prototype.__varz = function() { + this.InitializeRegisters() +}; +b2ContactFactory.prototype.AddType = function(createFcn, destroyFcn, type1, type2) { + this.m_registers[type1][type2].createFcn = createFcn; + this.m_registers[type1][type2].destroyFcn = destroyFcn; + this.m_registers[type1][type2].primary = true; + if(type1 != type2) { + this.m_registers[type2][type1].createFcn = createFcn; + this.m_registers[type2][type1].destroyFcn = destroyFcn; + this.m_registers[type2][type1].primary = false + } +}; +b2ContactFactory.prototype.InitializeRegisters = function() { + this.m_registers = new Array(b2Shape.e_shapeTypeCount); + for(var i = 0;i < b2Shape.e_shapeTypeCount;i++) { + this.m_registers[i] = new Array(b2Shape.e_shapeTypeCount); + for(var j = 0;j < b2Shape.e_shapeTypeCount;j++) { + this.m_registers[i][j] = new b2ContactRegister + } + } + this.AddType(b2CircleContact.Create, b2CircleContact.Destroy, b2Shape.e_circleShape, b2Shape.e_circleShape); + this.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_circleShape); + this.AddType(b2PolygonContact.Create, b2PolygonContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_polygonShape); + this.AddType(b2EdgeAndCircleContact.Create, b2EdgeAndCircleContact.Destroy, b2Shape.e_edgeShape, b2Shape.e_circleShape); + this.AddType(b2PolyAndEdgeContact.Create, b2PolyAndEdgeContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_edgeShape) +}; +b2ContactFactory.prototype.Create = function(fixtureA, fixtureB) { + var type1 = fixtureA.GetType(); + var type2 = fixtureB.GetType(); + var reg = this.m_registers[type1][type2]; + var c; + if(reg.pool) { + c = reg.pool; + reg.pool = c.m_next; + reg.poolCount--; + c.Reset(fixtureA, fixtureB); + return c + } + var createFcn = reg.createFcn; + if(createFcn != null) { + if(reg.primary) { + c = createFcn(this.m_allocator); + c.Reset(fixtureA, fixtureB); + return c + }else { + c = createFcn(this.m_allocator); + c.Reset(fixtureB, fixtureA); + return c + } + }else { + return null + } +}; +b2ContactFactory.prototype.Destroy = function(contact) { + if(contact.m_manifold.m_pointCount > 0) { + contact.m_fixtureA.m_body.SetAwake(true); + contact.m_fixtureB.m_body.SetAwake(true) + } + var type1 = contact.m_fixtureA.GetType(); + var type2 = contact.m_fixtureB.GetType(); + var reg = this.m_registers[type1][type2]; + if(true) { + reg.poolCount++; + contact.m_next = reg.pool; + reg.pool = contact + } + var destroyFcn = reg.destroyFcn; + destroyFcn(contact, this.m_allocator) +}; +b2ContactFactory.prototype.m_registers = null; +b2ContactFactory.prototype.m_allocator = null;var b2ConstantAccelController = function() { + b2Controller.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2ConstantAccelController.prototype, b2Controller.prototype); +b2ConstantAccelController.prototype._super = b2Controller.prototype; +b2ConstantAccelController.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2ConstantAccelController.prototype.__varz = function() { + this.A = new b2Vec2(0, 0) +}; +b2ConstantAccelController.prototype.Step = function(step) { + var smallA = new b2Vec2(this.A.x * step.dt, this.A.y * step.dt); + for(var i = m_bodyList;i;i = i.nextBody) { + var body = i.body; + if(!body.IsAwake()) { + continue + } + body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + smallA.x, body.GetLinearVelocity().y + smallA.y)) + } +}; +b2ConstantAccelController.prototype.A = new b2Vec2(0, 0);var b2SeparationFunction = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2SeparationFunction.prototype.__constructor = function() { +}; +b2SeparationFunction.prototype.__varz = function() { + this.m_localPoint = new b2Vec2; + this.m_axis = new b2Vec2 +}; +b2SeparationFunction.e_points = 1; +b2SeparationFunction.e_faceA = 2; +b2SeparationFunction.e_faceB = 4; +b2SeparationFunction.prototype.Initialize = function(cache, proxyA, transformA, proxyB, transformB) { + this.m_proxyA = proxyA; + this.m_proxyB = proxyB; + var count = cache.count; + b2Settings.b2Assert(0 < count && count < 3); + var localPointA; + var localPointA1; + var localPointA2; + var localPointB; + var localPointB1; + var localPointB2; + var pointAX; + var pointAY; + var pointBX; + var pointBY; + var normalX; + var normalY; + var tMat; + var tVec; + var s; + var sgn; + if(count == 1) { + this.m_type = b2SeparationFunction.e_points; + localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); + localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); + tVec = localPointA; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointB; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + this.m_axis.x = pointBX - pointAX; + this.m_axis.y = pointBY - pointAY; + this.m_axis.Normalize() + }else { + if(cache.indexB[0] == cache.indexB[1]) { + this.m_type = b2SeparationFunction.e_faceA; + localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); + localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); + localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); + this.m_localPoint.x = 0.5 * (localPointA1.x + localPointA2.x); + this.m_localPoint.y = 0.5 * (localPointA1.y + localPointA2.y); + this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1); + this.m_axis.Normalize(); + tVec = this.m_axis; + tMat = transformA.R; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tVec = this.m_localPoint; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointB; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + s = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; + if(s < 0) { + this.m_axis.NegativeSelf() + } + }else { + if(cache.indexA[0] == cache.indexA[0]) { + this.m_type = b2SeparationFunction.e_faceB; + localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); + localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); + localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); + this.m_localPoint.x = 0.5 * (localPointB1.x + localPointB2.x); + this.m_localPoint.y = 0.5 * (localPointB1.y + localPointB2.y); + this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1); + this.m_axis.Normalize(); + tVec = this.m_axis; + tMat = transformB.R; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tVec = this.m_localPoint; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointA; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + s = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; + if(s < 0) { + this.m_axis.NegativeSelf() + } + }else { + localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); + localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); + localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); + localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); + var pA = b2Math.MulX(transformA, localPointA); + var dA = b2Math.MulMV(transformA.R, b2Math.SubtractVV(localPointA2, localPointA1)); + var pB = b2Math.MulX(transformB, localPointB); + var dB = b2Math.MulMV(transformB.R, b2Math.SubtractVV(localPointB2, localPointB1)); + var a = dA.x * dA.x + dA.y * dA.y; + var e = dB.x * dB.x + dB.y * dB.y; + var r = b2Math.SubtractVV(dB, dA); + var c = dA.x * r.x + dA.y * r.y; + var f = dB.x * r.x + dB.y * r.y; + var b = dA.x * dB.x + dA.y * dB.y; + var denom = a * e - b * b; + s = 0; + if(denom != 0) { + s = b2Math.Clamp((b * f - c * e) / denom, 0, 1) + } + var t = (b * s + f) / e; + if(t < 0) { + t = 0; + s = b2Math.Clamp((b - c) / a, 0, 1) + } + localPointA = new b2Vec2; + localPointA.x = localPointA1.x + s * (localPointA2.x - localPointA1.x); + localPointA.y = localPointA1.y + s * (localPointA2.y - localPointA1.y); + localPointB = new b2Vec2; + localPointB.x = localPointB1.x + s * (localPointB2.x - localPointB1.x); + localPointB.y = localPointB1.y + s * (localPointB2.y - localPointB1.y); + if(s == 0 || s == 1) { + this.m_type = b2SeparationFunction.e_faceB; + this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1); + this.m_axis.Normalize(); + this.m_localPoint = localPointB; + tVec = this.m_axis; + tMat = transformB.R; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tVec = this.m_localPoint; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointA; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + sgn = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; + if(s < 0) { + this.m_axis.NegativeSelf() + } + }else { + this.m_type = b2SeparationFunction.e_faceA; + this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1); + this.m_localPoint = localPointA; + tVec = this.m_axis; + tMat = transformA.R; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tVec = this.m_localPoint; + tMat = transformA.R; + pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = localPointB; + tMat = transformB.R; + pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + sgn = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; + if(s < 0) { + this.m_axis.NegativeSelf() + } + } + } + } + } +}; +b2SeparationFunction.prototype.Evaluate = function(transformA, transformB) { + var axisA; + var axisB; + var localPointA; + var localPointB; + var pointA; + var pointB; + var seperation; + var normal; + switch(this.m_type) { + case b2SeparationFunction.e_points: + axisA = b2Math.MulTMV(transformA.R, this.m_axis); + axisB = b2Math.MulTMV(transformB.R, this.m_axis.GetNegative()); + localPointA = this.m_proxyA.GetSupportVertex(axisA); + localPointB = this.m_proxyB.GetSupportVertex(axisB); + pointA = b2Math.MulX(transformA, localPointA); + pointB = b2Math.MulX(transformB, localPointB); + seperation = (pointB.x - pointA.x) * this.m_axis.x + (pointB.y - pointA.y) * this.m_axis.y; + return seperation; + case b2SeparationFunction.e_faceA: + normal = b2Math.MulMV(transformA.R, this.m_axis); + pointA = b2Math.MulX(transformA, this.m_localPoint); + axisB = b2Math.MulTMV(transformB.R, normal.GetNegative()); + localPointB = this.m_proxyB.GetSupportVertex(axisB); + pointB = b2Math.MulX(transformB, localPointB); + seperation = (pointB.x - pointA.x) * normal.x + (pointB.y - pointA.y) * normal.y; + return seperation; + case b2SeparationFunction.e_faceB: + normal = b2Math.MulMV(transformB.R, this.m_axis); + pointB = b2Math.MulX(transformB, this.m_localPoint); + axisA = b2Math.MulTMV(transformA.R, normal.GetNegative()); + localPointA = this.m_proxyA.GetSupportVertex(axisA); + pointA = b2Math.MulX(transformA, localPointA); + seperation = (pointA.x - pointB.x) * normal.x + (pointA.y - pointB.y) * normal.y; + return seperation; + default: + b2Settings.b2Assert(false); + return 0 + } +}; +b2SeparationFunction.prototype.m_proxyA = null; +b2SeparationFunction.prototype.m_proxyB = null; +b2SeparationFunction.prototype.m_type = 0; +b2SeparationFunction.prototype.m_localPoint = new b2Vec2; +b2SeparationFunction.prototype.m_axis = new b2Vec2;var b2DynamicTreePair = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2DynamicTreePair.prototype.__constructor = function() { +}; +b2DynamicTreePair.prototype.__varz = function() { +}; +b2DynamicTreePair.prototype.proxyA = null; +b2DynamicTreePair.prototype.proxyB = null;var b2ContactConstraintPoint = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactConstraintPoint.prototype.__constructor = function() { +}; +b2ContactConstraintPoint.prototype.__varz = function() { + this.localPoint = new b2Vec2; + this.rA = new b2Vec2; + this.rB = new b2Vec2 +}; +b2ContactConstraintPoint.prototype.localPoint = new b2Vec2; +b2ContactConstraintPoint.prototype.rA = new b2Vec2; +b2ContactConstraintPoint.prototype.rB = new b2Vec2; +b2ContactConstraintPoint.prototype.normalImpulse = null; +b2ContactConstraintPoint.prototype.tangentImpulse = null; +b2ContactConstraintPoint.prototype.normalMass = null; +b2ContactConstraintPoint.prototype.tangentMass = null; +b2ContactConstraintPoint.prototype.equalizedMass = null; +b2ContactConstraintPoint.prototype.velocityBias = null;var b2ControllerEdge = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ControllerEdge.prototype.__constructor = function() { +}; +b2ControllerEdge.prototype.__varz = function() { +}; +b2ControllerEdge.prototype.controller = null; +b2ControllerEdge.prototype.body = null; +b2ControllerEdge.prototype.prevBody = null; +b2ControllerEdge.prototype.nextBody = null; +b2ControllerEdge.prototype.prevController = null; +b2ControllerEdge.prototype.nextController = null;var b2DistanceInput = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2DistanceInput.prototype.__constructor = function() { +}; +b2DistanceInput.prototype.__varz = function() { +}; +b2DistanceInput.prototype.proxyA = null; +b2DistanceInput.prototype.proxyB = null; +b2DistanceInput.prototype.transformA = null; +b2DistanceInput.prototype.transformB = null; +b2DistanceInput.prototype.useRadii = null;var b2Settings = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Settings.prototype.__constructor = function() { +}; +b2Settings.prototype.__varz = function() { +}; +b2Settings.b2MixFriction = function(friction1, friction2) { + return Math.sqrt(friction1 * friction2) +}; +b2Settings.b2MixRestitution = function(restitution1, restitution2) { + return restitution1 > restitution2 ? restitution1 : restitution2 +}; +b2Settings.b2Assert = function(a) { + if(!a) { + throw"Assertion Failed"; + } +}; +b2Settings.VERSION = "2.1alpha"; +b2Settings.USHRT_MAX = 65535; +b2Settings.b2_pi = Math.PI; +b2Settings.b2_maxManifoldPoints = 2; +b2Settings.b2_aabbExtension = 0.1; +b2Settings.b2_aabbMultiplier = 2; +b2Settings.b2_polygonRadius = 2 * b2Settings.b2_linearSlop; +b2Settings.b2_linearSlop = 0.0050; +b2Settings.b2_angularSlop = 2 / 180 * b2Settings.b2_pi; +b2Settings.b2_toiSlop = 8 * b2Settings.b2_linearSlop; +b2Settings.b2_maxTOIContactsPerIsland = 32; +b2Settings.b2_maxTOIJointsPerIsland = 32; +b2Settings.b2_velocityThreshold = 1; +b2Settings.b2_maxLinearCorrection = 0.2; +b2Settings.b2_maxAngularCorrection = 8 / 180 * b2Settings.b2_pi; +b2Settings.b2_maxTranslation = 2; +b2Settings.b2_maxTranslationSquared = b2Settings.b2_maxTranslation * b2Settings.b2_maxTranslation; +b2Settings.b2_maxRotation = 0.5 * b2Settings.b2_pi; +b2Settings.b2_maxRotationSquared = b2Settings.b2_maxRotation * b2Settings.b2_maxRotation; +b2Settings.b2_contactBaumgarte = 0.2; +b2Settings.b2_timeToSleep = 0.5; +b2Settings.b2_linearSleepTolerance = 0.01; +b2Settings.b2_angularSleepTolerance = 2 / 180 * b2Settings.b2_pi;var b2Proxy = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Proxy.prototype.__constructor = function() { +}; +b2Proxy.prototype.__varz = function() { + this.lowerBounds = new Array(2); + this.upperBounds = new Array(2); + this.pairs = new Object +}; +b2Proxy.prototype.IsValid = function() { + return this.overlapCount != b2BroadPhase.b2_invalid +}; +b2Proxy.prototype.lowerBounds = new Array(2); +b2Proxy.prototype.upperBounds = new Array(2); +b2Proxy.prototype.overlapCount = 0; +b2Proxy.prototype.timeStamp = 0; +b2Proxy.prototype.pairs = new Object; +b2Proxy.prototype.next = null; +b2Proxy.prototype.userData = null;var b2Point = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Point.prototype.__constructor = function() { +}; +b2Point.prototype.__varz = function() { + this.p = new b2Vec2 +}; +b2Point.prototype.Support = function(xf, vX, vY) { + return this.p +}; +b2Point.prototype.GetFirstVertex = function(xf) { + return this.p +}; +b2Point.prototype.p = new b2Vec2;var b2WorldManifold = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2WorldManifold.prototype.__constructor = function() { + this.m_points = new Array(b2Settings.b2_maxManifoldPoints); + for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { + this.m_points[i] = new b2Vec2 + } +}; +b2WorldManifold.prototype.__varz = function() { + this.m_normal = new b2Vec2 +}; +b2WorldManifold.prototype.Initialize = function(manifold, xfA, radiusA, xfB, radiusB) { + if(manifold.m_pointCount == 0) { + return + } + var i = 0; + var tVec; + var tMat; + var normalX; + var normalY; + var planePointX; + var planePointY; + var clipPointX; + var clipPointY; + switch(manifold.m_type) { + case b2Manifold.e_circles: + tMat = xfA.R; + tVec = manifold.m_localPoint; + var pointAX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + var pointAY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = xfB.R; + tVec = manifold.m_points[0].m_localPoint; + var pointBX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + var pointBY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + var dX = pointBX - pointAX; + var dY = pointBY - pointAY; + var d2 = dX * dX + dY * dY; + if(d2 > Number.MIN_VALUE * Number.MIN_VALUE) { + var d = Math.sqrt(d2); + this.m_normal.x = dX / d; + this.m_normal.y = dY / d + }else { + this.m_normal.x = 1; + this.m_normal.y = 0 + } + var cAX = pointAX + radiusA * this.m_normal.x; + var cAY = pointAY + radiusA * this.m_normal.y; + var cBX = pointBX - radiusB * this.m_normal.x; + var cBY = pointBY - radiusB * this.m_normal.y; + this.m_points[0].x = 0.5 * (cAX + cBX); + this.m_points[0].y = 0.5 * (cAY + cBY); + break; + case b2Manifold.e_faceA: + tMat = xfA.R; + tVec = manifold.m_localPlaneNormal; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = xfA.R; + tVec = manifold.m_localPoint; + planePointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + planePointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_normal.x = normalX; + this.m_normal.y = normalY; + for(i = 0;i < manifold.m_pointCount;i++) { + tMat = xfB.R; + tVec = manifold.m_points[i].m_localPoint; + clipPointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + clipPointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_points[i].x = clipPointX + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalX; + this.m_points[i].y = clipPointY + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalY + } + break; + case b2Manifold.e_faceB: + tMat = xfB.R; + tVec = manifold.m_localPlaneNormal; + normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = xfB.R; + tVec = manifold.m_localPoint; + planePointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + planePointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_normal.x = -normalX; + this.m_normal.y = -normalY; + for(i = 0;i < manifold.m_pointCount;i++) { + tMat = xfA.R; + tVec = manifold.m_points[i].m_localPoint; + clipPointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + clipPointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_points[i].x = clipPointX + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalX; + this.m_points[i].y = clipPointY + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalY + } + break + } +}; +b2WorldManifold.prototype.m_normal = new b2Vec2; +b2WorldManifold.prototype.m_points = null;var b2RayCastOutput = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2RayCastOutput.prototype.__constructor = function() { +}; +b2RayCastOutput.prototype.__varz = function() { + this.normal = new b2Vec2 +}; +b2RayCastOutput.prototype.normal = new b2Vec2; +b2RayCastOutput.prototype.fraction = null;var b2ConstantForceController = function() { + b2Controller.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2ConstantForceController.prototype, b2Controller.prototype); +b2ConstantForceController.prototype._super = b2Controller.prototype; +b2ConstantForceController.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2ConstantForceController.prototype.__varz = function() { + this.F = new b2Vec2(0, 0) +}; +b2ConstantForceController.prototype.Step = function(step) { + for(var i = m_bodyList;i;i = i.nextBody) { + var body = i.body; + if(!body.IsAwake()) { + continue + } + body.ApplyForce(this.F, body.GetWorldCenter()) + } +}; +b2ConstantForceController.prototype.F = new b2Vec2(0, 0);var b2MassData = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2MassData.prototype.__constructor = function() { +}; +b2MassData.prototype.__varz = function() { + this.center = new b2Vec2(0, 0) +}; +b2MassData.prototype.mass = 0; +b2MassData.prototype.center = new b2Vec2(0, 0); +b2MassData.prototype.I = 0;var b2DynamicTree = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2DynamicTree.prototype.__constructor = function() { + this.m_root = null; + this.m_freeList = null; + this.m_path = 0; + this.m_insertionCount = 0 +}; +b2DynamicTree.prototype.__varz = function() { +}; +b2DynamicTree.prototype.AllocateNode = function() { + if(this.m_freeList) { + var node = this.m_freeList; + this.m_freeList = node.parent; + node.parent = null; + node.child1 = null; + node.child2 = null; + return node + } + return new b2DynamicTreeNode +}; +b2DynamicTree.prototype.FreeNode = function(node) { + node.parent = this.m_freeList; + this.m_freeList = node +}; +b2DynamicTree.prototype.InsertLeaf = function(leaf) { + ++this.m_insertionCount; + if(this.m_root == null) { + this.m_root = leaf; + this.m_root.parent = null; + return + } + var center = leaf.aabb.GetCenter(); + var sibling = this.m_root; + if(sibling.IsLeaf() == false) { + do { + var child1 = sibling.child1; + var child2 = sibling.child2; + var norm1 = Math.abs((child1.aabb.lowerBound.x + child1.aabb.upperBound.x) / 2 - center.x) + Math.abs((child1.aabb.lowerBound.y + child1.aabb.upperBound.y) / 2 - center.y); + var norm2 = Math.abs((child2.aabb.lowerBound.x + child2.aabb.upperBound.x) / 2 - center.x) + Math.abs((child2.aabb.lowerBound.y + child2.aabb.upperBound.y) / 2 - center.y); + if(norm1 < norm2) { + sibling = child1 + }else { + sibling = child2 + } + }while(sibling.IsLeaf() == false) + } + var node1 = sibling.parent; + var node2 = this.AllocateNode(); + node2.parent = node1; + node2.userData = null; + node2.aabb.Combine(leaf.aabb, sibling.aabb); + if(node1) { + if(sibling.parent.child1 == sibling) { + node1.child1 = node2 + }else { + node1.child2 = node2 + } + node2.child1 = sibling; + node2.child2 = leaf; + sibling.parent = node2; + leaf.parent = node2; + do { + if(node1.aabb.Contains(node2.aabb)) { + break + } + node1.aabb.Combine(node1.child1.aabb, node1.child2.aabb); + node2 = node1; + node1 = node1.parent + }while(node1) + }else { + node2.child1 = sibling; + node2.child2 = leaf; + sibling.parent = node2; + leaf.parent = node2; + this.m_root = node2 + } +}; +b2DynamicTree.prototype.RemoveLeaf = function(leaf) { + if(leaf == this.m_root) { + this.m_root = null; + return + } + var node2 = leaf.parent; + var node1 = node2.parent; + var sibling; + if(node2.child1 == leaf) { + sibling = node2.child2 + }else { + sibling = node2.child1 + } + if(node1) { + if(node1.child1 == node2) { + node1.child1 = sibling + }else { + node1.child2 = sibling + } + sibling.parent = node1; + this.FreeNode(node2); + while(node1) { + var oldAABB = node1.aabb; + node1.aabb = b2AABB.Combine(node1.child1.aabb, node1.child2.aabb); + if(oldAABB.Contains(node1.aabb)) { + break + } + node1 = node1.parent + } + }else { + this.m_root = sibling; + sibling.parent = null; + this.FreeNode(node2) + } +}; +b2DynamicTree.prototype.CreateProxy = function(aabb, userData) { + var node = this.AllocateNode(); + var extendX = b2Settings.b2_aabbExtension; + var extendY = b2Settings.b2_aabbExtension; + node.aabb.lowerBound.x = aabb.lowerBound.x - extendX; + node.aabb.lowerBound.y = aabb.lowerBound.y - extendY; + node.aabb.upperBound.x = aabb.upperBound.x + extendX; + node.aabb.upperBound.y = aabb.upperBound.y + extendY; + node.userData = userData; + this.InsertLeaf(node); + return node +}; +b2DynamicTree.prototype.DestroyProxy = function(proxy) { + this.RemoveLeaf(proxy); + this.FreeNode(proxy) +}; +b2DynamicTree.prototype.MoveProxy = function(proxy, aabb, displacement) { + b2Settings.b2Assert(proxy.IsLeaf()); + if(proxy.aabb.Contains(aabb)) { + return false + } + this.RemoveLeaf(proxy); + var extendX = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.x > 0 ? displacement.x : -displacement.x); + var extendY = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.y > 0 ? displacement.y : -displacement.y); + proxy.aabb.lowerBound.x = aabb.lowerBound.x - extendX; + proxy.aabb.lowerBound.y = aabb.lowerBound.y - extendY; + proxy.aabb.upperBound.x = aabb.upperBound.x + extendX; + proxy.aabb.upperBound.y = aabb.upperBound.y + extendY; + this.InsertLeaf(proxy); + return true +}; +b2DynamicTree.prototype.Rebalance = function(iterations) { + if(this.m_root == null) { + return + } + for(var i = 0;i < iterations;i++) { + var node = this.m_root; + var bit = 0; + while(node.IsLeaf() == false) { + node = this.m_path >> bit & 1 ? node.child2 : node.child1; + bit = bit + 1 & 31 + } + ++this.m_path; + this.RemoveLeaf(node); + this.InsertLeaf(node) + } +}; +b2DynamicTree.prototype.GetFatAABB = function(proxy) { + return proxy.aabb +}; +b2DynamicTree.prototype.GetUserData = function(proxy) { + return proxy.userData +}; +b2DynamicTree.prototype.Query = function(callback, aabb) { + if(this.m_root == null) { + return + } + var stack = new Array; + var count = 0; + stack[count++] = this.m_root; + while(count > 0) { + var node = stack[--count]; + if(node.aabb.TestOverlap(aabb)) { + if(node.IsLeaf()) { + var proceed = callback(node); + if(!proceed) { + return + } + }else { + stack[count++] = node.child1; + stack[count++] = node.child2 + } + } + } +}; +b2DynamicTree.prototype.RayCast = function(callback, input) { + if(this.m_root == null) { + return + } + var p1 = input.p1; + var p2 = input.p2; + var r = b2Math.SubtractVV(p1, p2); + r.Normalize(); + var v = b2Math.CrossFV(1, r); + var abs_v = b2Math.AbsV(v); + var maxFraction = input.maxFraction; + var segmentAABB = new b2AABB; + var tX; + var tY; + tX = p1.x + maxFraction * (p2.x - p1.x); + tY = p1.y + maxFraction * (p2.y - p1.y); + segmentAABB.lowerBound.x = Math.min(p1.x, tX); + segmentAABB.lowerBound.y = Math.min(p1.y, tY); + segmentAABB.upperBound.x = Math.max(p1.x, tX); + segmentAABB.upperBound.y = Math.max(p1.y, tY); + var stack = new Array; + var count = 0; + stack[count++] = this.m_root; + while(count > 0) { + var node = stack[--count]; + if(node.aabb.TestOverlap(segmentAABB) == false) { + continue + } + var c = node.aabb.GetCenter(); + var h = node.aabb.GetExtents(); + var separation = Math.abs(v.x * (p1.x - c.x) + v.y * (p1.y - c.y)) - abs_v.x * h.x - abs_v.y * h.y; + if(separation > 0) { + continue + } + if(node.IsLeaf()) { + var subInput = new b2RayCastInput; + subInput.p1 = input.p1; + subInput.p2 = input.p2; subInput.maxFraction = input.maxFraction; - var dx = (input.p2.x - input.p1.x) * this.m_quantizationFactor.x; - var dy = (input.p2.y - input.p1.y) * this.m_quantizationFactor.y; - var sx = parseInt(dx < (-Number.MIN_VALUE ? (-1) : (dx > Number.MIN_VALUE ? 1 : 0))); - var sy = parseInt(dy < (-Number.MIN_VALUE ? (-1) : (dy > Number.MIN_VALUE ? 1 : 0))); - var p1x = this.m_quantizationFactor.x * (input.p1.x - this.m_worldAABB.lowerBound.x); - var p1y = this.m_quantizationFactor.y * (input.p1.y - this.m_worldAABB.lowerBound.y); - var startValues = new Array(); - var startValues2 = new Array(); - startValues[0] = a2j.parseUInt(p1x) & (b2Settings.USHRT_MAX - 1); - startValues[1] = a2j.parseUInt(p1y) & (b2Settings.USHRT_MAX - 1); - startValues2[0] = startValues[0] + 1; - startValues2[1] = startValues[1] + 1; - var startIndices = new Array(); - var xIndex = 0; - var yIndex = 0; - var proxy; - var lowerIndex = 0; - var upperIndex = 0; - var lowerIndexOut = new Vector_a2j_Number(); - lowerIndexOut.push(lowerIndex); - var upperIndexOut = new Vector_a2j_Number(); - upperIndexOut.push(upperIndex); - this.QueryAxis(lowerIndexOut, upperIndexOut, startValues[0], startValues2[0], this.m_bounds[0], 2 * this.m_proxyCount, 0); - if (sx >= 0) xIndex = upperIndexOut[0] - 1; - else xIndex = lowerIndexOut[0]; - this.QueryAxis(lowerIndexOut, upperIndexOut, startValues[1], startValues2[1], this.m_bounds[1], 2 * this.m_proxyCount, 1); - if (sy >= 0) yIndex = upperIndexOut[0] - 1; - else yIndex = lowerIndexOut[0]; - for (var i = 0; i < this.m_queryResultCount; i++) { - subInput.maxFraction = callback(subInput, this.m_queryResults[i]); - } - for (;;) { - var xProgress = 0; - var yProgress = 0; - xIndex += sx >= 0 ? 1 : (-1); - if (xIndex < 0 || xIndex >= this.m_proxyCount * 2) break; - if (sx != 0) { - xProgress = (this.m_bounds[0][xIndex].value - p1x) / dx; - } - yIndex += sy >= 0 ? 1 : (-1); - if (yIndex < 0 || yIndex >= this.m_proxyCount * 2) break; - if (sy != 0) { - yProgress = (this.m_bounds[1][yIndex].value - p1y) / dy; - } - for (;;) { - if (sy == 0 || (sx != 0 && xProgress < yProgress)) { - if (xProgress > subInput.maxFraction) break; - if (sx > 0 ? this.m_bounds[0][xIndex].IsLower() : this.m_bounds[0][xIndex].IsUpper()) { - proxy = this.m_bounds[0][xIndex].proxy; - if (sy >= 0) { - if (proxy.lowerBounds[1] <= yIndex - 1 && proxy.upperBounds[1] >= yIndex) { - subInput.maxFraction = callback(subInput, proxy); - } - } - else { - if (proxy.lowerBounds[1] <= yIndex && proxy.upperBounds[1] >= yIndex + 1) { - subInput.maxFraction = callback(subInput, proxy); - } - } - } - if (subInput.maxFraction == 0) break; - if (sx > 0) { - xIndex++; - if (xIndex == this.m_proxyCount * 2) break; - } - else { - xIndex--; - if (xIndex < 0) break; - } - xProgress = (this.m_bounds[0][xIndex].value - p1x) / dx; - } - else { - if (yProgress > subInput.maxFraction) break; - if (sy > 0 ? this.m_bounds[1][yIndex].IsLower() : this.m_bounds[1][yIndex].IsUpper()) { - proxy = this.m_bounds[1][yIndex].proxy; - if (sx >= 0) { - if (proxy.lowerBounds[0] <= xIndex - 1 && proxy.upperBounds[0] >= xIndex) { - subInput.maxFraction = callback(subInput, proxy); - } - } - else { - if (proxy.lowerBounds[0] <= xIndex && proxy.upperBounds[0] >= xIndex + 1) { - subInput.maxFraction = callback(subInput, proxy); - } - } - } - if (subInput.maxFraction == 0) break; - if (sy > 0) { - yIndex++; - if (yIndex == this.m_proxyCount * 2) break; - } - else { - yIndex--; - if (yIndex < 0) break; - } - yProgress = (this.m_bounds[1][yIndex].value - p1y) / dy; - } - } - break; - } - this.m_queryResultCount = 0; - this.IncrementTimeStamp(); - return; - } - b2BroadPhase.prototype.ComputeBounds = function (lowerValues, upperValues, aabb) { - var minVertexX = aabb.lowerBound.x; - var minVertexY = aabb.lowerBound.y; - minVertexX = b2Math.Min(minVertexX, this.m_worldAABB.upperBound.x); - minVertexY = b2Math.Min(minVertexY, this.m_worldAABB.upperBound.y); - minVertexX = b2Math.Max(minVertexX, this.m_worldAABB.lowerBound.x); - minVertexY = b2Math.Max(minVertexY, this.m_worldAABB.lowerBound.y); - var maxVertexX = aabb.upperBound.x; - var maxVertexY = aabb.upperBound.y; - maxVertexX = b2Math.Min(maxVertexX, this.m_worldAABB.upperBound.x); - maxVertexY = b2Math.Min(maxVertexY, this.m_worldAABB.upperBound.y); - maxVertexX = b2Math.Max(maxVertexX, this.m_worldAABB.lowerBound.x); - maxVertexY = b2Math.Max(maxVertexY, this.m_worldAABB.lowerBound.y); - lowerValues[0] = a2j.parseUInt(this.m_quantizationFactor.x * (minVertexX - this.m_worldAABB.lowerBound.x)) & (b2Settings.USHRT_MAX - 1); - upperValues[0] = (a2j.parseUInt(this.m_quantizationFactor.x * (maxVertexX - this.m_worldAABB.lowerBound.x)) & 0x0000ffff) | 1; - lowerValues[1] = a2j.parseUInt(this.m_quantizationFactor.y * (minVertexY - this.m_worldAABB.lowerBound.y)) & (b2Settings.USHRT_MAX - 1); - upperValues[1] = (a2j.parseUInt(this.m_quantizationFactor.y * (maxVertexY - this.m_worldAABB.lowerBound.y)) & 0x0000ffff) | 1; - } - b2BroadPhase.prototype.TestOverlapValidate = function (p1, p2) { - for (var axis = 0; axis < 2; ++axis) { - var bounds = this.m_bounds[axis]; - var bound1 = bounds[p1.lowerBounds[axis]]; - var bound2 = bounds[p2.upperBounds[axis]]; - if (bound1.value > bound2.value) return false; - bound1 = bounds[p1.upperBounds[axis]]; - bound2 = bounds[p2.lowerBounds[axis]]; - if (bound1.value < bound2.value) return false; - } - return true; - } - b2BroadPhase.prototype.TestOverlapBound = function (b, p) { - for (var axis = 0; axis < 2; ++axis) { - var bounds = this.m_bounds[axis]; - var bound = bounds[p.upperBounds[axis]]; - if (b.lowerValues[axis] > bound.value) return false; - bound = bounds[p.lowerBounds[axis]]; - if (b.upperValues[axis] < bound.value) return false; - } - return true; - } - b2BroadPhase.prototype.QueryAxis = function (lowerQueryOut, upperQueryOut, lowerValue, upperValue, bounds, boundCount, axis) { - if (lowerValue === undefined) lowerValue = 0; - if (upperValue === undefined) upperValue = 0; - if (boundCount === undefined) boundCount = 0; - if (axis === undefined) axis = 0; - var lowerQuery = this.BinarySearch(bounds, boundCount, lowerValue); - var upperQuery = this.BinarySearch(bounds, boundCount, upperValue); - var bound; - for (var j = lowerQuery; j < upperQuery; ++j) { - bound = bounds[j]; - if (bound.IsLower()) { - this.IncrementOverlapCount(bound.proxy); - } - } - if (lowerQuery > 0) { - var i = parseInt(lowerQuery - 1); - bound = bounds[i]; - var s = parseInt(bound.stabbingCount); - while (s) { - bound = bounds[i]; - if (bound.IsLower()) { - var proxy = bound.proxy; - if (lowerQuery <= proxy.upperBounds[axis]) { - this.IncrementOverlapCount(bound.proxy); - --s; - } - }--i; - } - } - lowerQueryOut[0] = lowerQuery; - upperQueryOut[0] = upperQuery; - } - b2BroadPhase.prototype.IncrementOverlapCount = function (proxy) { - if (proxy.timeStamp < this.m_timeStamp) { - proxy.timeStamp = this.m_timeStamp; - proxy.overlapCount = 1; - } - else { - proxy.overlapCount = 2; - this.m_queryResults[this.m_queryResultCount] = proxy; - ++this.m_queryResultCount; - } - } - b2BroadPhase.prototype.IncrementTimeStamp = function () { - if (this.m_timeStamp == b2Settings.USHRT_MAX) { - for (var i = 0; i < this.m_proxyPool.length; ++i) { - ((this.m_proxyPool[i] instanceof b2Proxy ? this.m_proxyPool[i] : null)).timeStamp = 0; - } - this.m_timeStamp = 1; - } - else { - ++this.m_timeStamp; - } - } - b2BroadPhase.prototype.BinarySearch = function (bounds, count, value) { - if (count === undefined) count = 0; - if (value === undefined) value = 0; - var low = 0; - var high = parseInt(count - 1); - while (low <= high) { - var mid = parseInt(((low + high) / 2)); - var bound = bounds[mid]; - if (bound.value > value) { - high = mid - 1; - } - else if (bound.value < value) { - low = mid + 1; - } - else { - return a2j.parseUInt(mid); - } - } - return a2j.parseUInt(low); - } - b2BroadPhase.BinarySearch = b2BroadPhase.prototype.BinarySearch; - _A2J_postDefs.push(function () { - Box2D.Collision.b2BroadPhase.s_validate = false; - Box2D.Collision.b2BroadPhase.prototype.s_validate = Box2D.Collision.b2BroadPhase.s_validate; - Box2D.Collision.b2BroadPhase.b2_invalid = parseInt(b2Settings.USHRT_MAX); - Box2D.Collision.b2BroadPhase.prototype.b2_invalid = Box2D.Collision.b2BroadPhase.b2_invalid; - Box2D.Collision.b2BroadPhase.b2_nullEdge = parseInt(b2Settings.USHRT_MAX); - Box2D.Collision.b2BroadPhase.prototype.b2_nullEdge = Box2D.Collision.b2BroadPhase.b2_nullEdge; - }); - b2BroadPhase.__implements = {}; - b2BroadPhase.__implements[IBroadPhase] = true; - b2Collision.b2Collision = function () {}; - b2Collision.prototype.ClipSegmentToLine = function (vOut, vIn, normal, offset) { - if (offset === undefined) offset = 0; - var cv; - var numOut = 0; - cv = vIn[0]; - var vIn0 = cv.v; - cv = vIn[1]; - var vIn1 = cv.v; - var distance0 = normal.x * vIn0.x + normal.y * vIn0.y - offset; - var distance1 = normal.x * vIn1.x + normal.y * vIn1.y - offset; - if (distance0 <= 0.0) vOut[numOut++].Set(vIn[0]); - if (distance1 <= 0.0) vOut[numOut++].Set(vIn[1]); - if (distance0 * distance1 < 0.0) { - var interp = distance0 / (distance0 - distance1); - cv = vOut[numOut]; - var tVec = cv.v; - tVec.x = vIn0.x + interp * (vIn1.x - vIn0.x); - tVec.y = vIn0.y + interp * (vIn1.y - vIn0.y); - cv = vOut[numOut]; - var cv2; - if (distance0 > 0.0) { - cv2 = vIn[0]; - cv.id = cv2.id; - } - else { - cv2 = vIn[1]; - cv.id = cv2.id; - }++numOut; - } - return numOut; - } - b2Collision.ClipSegmentToLine = b2Collision.prototype.ClipSegmentToLine; - b2Collision.prototype.EdgeSeparation = function (poly1, xf1, edge1, poly2, xf2) { - if (edge1 === undefined) edge1 = 0; - var count1 = parseInt(poly1.m_vertexCount); - var vertices1 = poly1.m_vertices; - var normals1 = poly1.m_normals; - var count2 = parseInt(poly2.m_vertexCount); - var vertices2 = poly2.m_vertices; - var tMat; - var tVec; - tMat = xf1.R; - tVec = normals1[edge1]; - var normal1WorldX = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var normal1WorldY = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf2.R; - var normal1X = (tMat.col1.x * normal1WorldX + tMat.col1.y * normal1WorldY); - var normal1Y = (tMat.col2.x * normal1WorldX + tMat.col2.y * normal1WorldY); - var index = 0; - var minDot = Number.MAX_VALUE; - for (var i = 0; i < count2; ++i) { - tVec = vertices2[i]; - var dot = tVec.x * normal1X + tVec.y * normal1Y; - if (dot < minDot) { - minDot = dot; - index = i; - } - } - tVec = vertices1[edge1]; - tMat = xf1.R; - var v1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var v1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = vertices2[index]; - tMat = xf2.R; - var v2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var v2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - v2X -= v1X; - v2Y -= v1Y; - var separation = v2X * normal1WorldX + v2Y * normal1WorldY; - return separation; - } - b2Collision.EdgeSeparation = b2Collision.prototype.EdgeSeparation; - b2Collision.prototype.FindMaxSeparation = function (edgeIndex, poly1, xf1, poly2, xf2) { - var count1 = parseInt(poly1.m_vertexCount); - var normals1 = poly1.m_normals; - var tVec; - var tMat; - tMat = xf2.R; - tVec = poly2.m_centroid; - var dX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var dY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf1.R; - tVec = poly1.m_centroid; - dX -= xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - dY -= xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var dLocal1X = (dX * xf1.R.col1.x + dY * xf1.R.col1.y); - var dLocal1Y = (dX * xf1.R.col2.x + dY * xf1.R.col2.y); - var edge = 0; - var maxDot = (-Number.MAX_VALUE); - for (var i = 0; i < count1; ++i) { - tVec = normals1[i]; - var dot = (tVec.x * dLocal1X + tVec.y * dLocal1Y); - if (dot > maxDot) { - maxDot = dot; - edge = i; - } - } - var s = this.EdgeSeparation(poly1, xf1, edge, poly2, xf2); - var prevEdge = parseInt(edge - 1 >= 0 ? edge - 1 : count1 - 1); - var sPrev = this.EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2); - var nextEdge = parseInt(edge + 1 < count1 ? edge + 1 : 0); - var sNext = this.EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2); - var bestEdge = 0; - var bestSeparation = 0; - var increment = 0; - if (sPrev > s && sPrev > sNext) { - increment = (-1); - bestEdge = prevEdge; - bestSeparation = sPrev; - } - else if (sNext > s) { - increment = 1; - bestEdge = nextEdge; - bestSeparation = sNext; - } - else { - edgeIndex[0] = edge; - return s; - } - while (true) { - if (increment == (-1)) edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1; - else edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;s = this.EdgeSeparation(poly1, xf1, edge, poly2, xf2); - if (s > bestSeparation) { - bestEdge = edge; - bestSeparation = s; - } - else { - break; - } - } - edgeIndex[0] = bestEdge; - return bestSeparation; - } - b2Collision.FindMaxSeparation = b2Collision.prototype.FindMaxSeparation; - b2Collision.prototype.FindIncidentEdge = function (c, poly1, xf1, edge1, poly2, xf2) { - if (edge1 === undefined) edge1 = 0; - var count1 = parseInt(poly1.m_vertexCount); - var normals1 = poly1.m_normals; - var count2 = parseInt(poly2.m_vertexCount); - var vertices2 = poly2.m_vertices; - var normals2 = poly2.m_normals; - var tMat; - var tVec; - tMat = xf1.R; - tVec = normals1[edge1]; - var normal1X = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var normal1Y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf2.R; - var tX = (tMat.col1.x * normal1X + tMat.col1.y * normal1Y); - normal1Y = (tMat.col2.x * normal1X + tMat.col2.y * normal1Y); - normal1X = tX; - var index = 0; - var minDot = Number.MAX_VALUE; - for (var i = 0; i < count2; ++i) { - tVec = normals2[i]; - var dot = (normal1X * tVec.x + normal1Y * tVec.y); - if (dot < minDot) { - minDot = dot; - index = i; - } - } - var tClip; - var i1 = parseInt(index); - var i2 = parseInt(i1 + 1 < count2 ? i1 + 1 : 0); - tClip = c[0]; - tVec = vertices2[i1]; - tMat = xf2.R; - tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tClip.id.features.referenceEdge = edge1; - tClip.id.features.incidentEdge = i1; - tClip.id.features.incidentVertex = 0; - tClip = c[1]; - tVec = vertices2[i2]; - tMat = xf2.R; - tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tClip.id.features.referenceEdge = edge1; - tClip.id.features.incidentEdge = i2; - tClip.id.features.incidentVertex = 1; - } - b2Collision.FindIncidentEdge = b2Collision.prototype.FindIncidentEdge; - b2Collision.prototype.MakeClipPointVector = function () { - var r = new Vector(2); - r[0] = new ClipVertex(); - r[1] = new ClipVertex(); - return r; - } - b2Collision.MakeClipPointVector = b2Collision.prototype.MakeClipPointVector; - b2Collision.prototype.CollidePolygons = function (manifold, polyA, xfA, polyB, xfB) { - var cv; - manifold.m_pointCount = 0; - var totalRadius = polyA.m_radius + polyB.m_radius; - var edgeA = 0; - b2Collision.s_edgeAO[0] = edgeA; - var separationA = this.FindMaxSeparation(b2Collision.s_edgeAO, polyA, xfA, polyB, xfB); - edgeA = b2Collision.s_edgeAO[0]; - if (separationA > totalRadius) return; - var edgeB = 0; - b2Collision.s_edgeBO[0] = edgeB; - var separationB = this.FindMaxSeparation(b2Collision.s_edgeBO, polyB, xfB, polyA, xfA); - edgeB = b2Collision.s_edgeBO[0]; - if (separationB > totalRadius) return; - var poly1; - var poly2; - var xf1; - var xf2; - var edge1 = 0; - var flip = 0; - var k_relativeTol = 0.98; - var k_absoluteTol = 0.001; - var tMat; - if (separationB > k_relativeTol * separationA + k_absoluteTol) { - poly1 = polyB; - poly2 = polyA; - xf1 = xfB; - xf2 = xfA; - edge1 = edgeB; - manifold.m_type = b2Manifold.e_faceB; - flip = 1; - } - else { - poly1 = polyA; - poly2 = polyB; - xf1 = xfA; - xf2 = xfB; - edge1 = edgeA; - manifold.m_type = b2Manifold.e_faceA; - flip = 0; - } - var incidentEdge = b2Collision.s_incidentEdge; - this.FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); - var count1 = parseInt(poly1.m_vertexCount); - var vertices1 = poly1.m_vertices; - var local_v11 = vertices1[edge1]; - var local_v12; - if (edge1 + 1 < count1) { - local_v12 = vertices1[parseInt(edge1 + 1)]; - } - else { - local_v12 = vertices1[0]; - } - var localTangent = b2Collision.s_localTangent; - localTangent.Set(local_v12.x - local_v11.x, local_v12.y - local_v11.y); - localTangent.Normalize(); - var localNormal = b2Collision.s_localNormal; - localNormal.x = localTangent.y; - localNormal.y = (-localTangent.x); - var planePoint = b2Collision.s_planePoint; - planePoint.Set(0.5 * (local_v11.x + local_v12.x), 0.5 * (local_v11.y + local_v12.y)); - var tangent = b2Collision.s_tangent; - tMat = xf1.R; - tangent.x = (tMat.col1.x * localTangent.x + tMat.col2.x * localTangent.y); - tangent.y = (tMat.col1.y * localTangent.x + tMat.col2.y * localTangent.y); - var tangent2 = b2Collision.s_tangent2; - tangent2.x = (-tangent.x); - tangent2.y = (-tangent.y); - var normal = b2Collision.s_normal; - normal.x = tangent.y; - normal.y = (-tangent.x); - var v11 = b2Collision.s_v11; - var v12 = b2Collision.s_v12; - v11.x = xf1.position.x + (tMat.col1.x * local_v11.x + tMat.col2.x * local_v11.y); - v11.y = xf1.position.y + (tMat.col1.y * local_v11.x + tMat.col2.y * local_v11.y); - v12.x = xf1.position.x + (tMat.col1.x * local_v12.x + tMat.col2.x * local_v12.y); - v12.y = xf1.position.y + (tMat.col1.y * local_v12.x + tMat.col2.y * local_v12.y); - var frontOffset = normal.x * v11.x + normal.y * v11.y; - var sideOffset1 = (-tangent.x * v11.x) - tangent.y * v11.y + totalRadius; - var sideOffset2 = tangent.x * v12.x + tangent.y * v12.y + totalRadius; - var clipPoints1 = b2Collision.s_clipPoints1; - var clipPoints2 = b2Collision.s_clipPoints2; - var np = 0; - np = this.ClipSegmentToLine(clipPoints1, incidentEdge, tangent2, sideOffset1); - if (np < 2) return; - np = this.ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2); - if (np < 2) return; - manifold.m_localPlaneNormal.SetV(localNormal); - manifold.m_localPoint.SetV(planePoint); - var pointCount = 0; - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; ++i) { - cv = clipPoints2[i]; - var separation = normal.x * cv.v.x + normal.y * cv.v.y - frontOffset; - if (separation <= totalRadius) { - var cp = manifold.m_points[pointCount]; - tMat = xf2.R; - var tX = cv.v.x - xf2.position.x; - var tY = cv.v.y - xf2.position.y; - cp.m_localPoint.x = (tX * tMat.col1.x + tY * tMat.col1.y); - cp.m_localPoint.y = (tX * tMat.col2.x + tY * tMat.col2.y); - cp.m_id.Set(cv.id); - cp.m_id.features.flip = flip; - ++pointCount; - } - } - manifold.m_pointCount = pointCount; - } - b2Collision.CollidePolygons = b2Collision.prototype.CollidePolygons; - b2Collision.prototype.CollideCircles = function (manifold, circle1, xf1, circle2, xf2) { - manifold.m_pointCount = 0; - var tMat; - var tVec; - tMat = xf1.R; - tVec = circle1.m_p; - var p1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var p1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf2.R; - tVec = circle2.m_p; - var p2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var p2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var distSqr = dX * dX + dY * dY; - var radius = circle1.m_radius + circle2.m_radius; - if (distSqr > radius * radius) { - return; - } - manifold.m_type = b2Manifold.e_circles; - manifold.m_localPoint.SetV(circle1.m_p); - manifold.m_localPlaneNormal.SetZero(); - manifold.m_pointCount = 1; - manifold.m_points[0].m_localPoint.SetV(circle2.m_p); - manifold.m_points[0].m_id.key = 0; - } - b2Collision.CollideCircles = b2Collision.prototype.CollideCircles; - b2Collision.prototype.CollidePolygonAndCircle = function (manifold, polygon, xf1, circle, xf2) { - manifold.m_pointCount = 0; - var tPoint; - var dX = 0; - var dY = 0; - var positionX = 0; - var positionY = 0; - var tVec; - var tMat; - tMat = xf2.R; - tVec = circle.m_p; - var cX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var cY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - dX = cX - xf1.position.x; - dY = cY - xf1.position.y; - tMat = xf1.R; - var cLocalX = (dX * tMat.col1.x + dY * tMat.col1.y); - var cLocalY = (dX * tMat.col2.x + dY * tMat.col2.y); - var dist = 0; - var normalIndex = 0; - var separation = (-Number.MAX_VALUE); - var radius = polygon.m_radius + circle.m_radius; - var vertexCount = parseInt(polygon.m_vertexCount); - var vertices = polygon.m_vertices; - var normals = polygon.m_normals; - for (var i = 0; i < vertexCount; ++i) { - tVec = vertices[i]; - dX = cLocalX - tVec.x; - dY = cLocalY - tVec.y; - tVec = normals[i]; - var s = tVec.x * dX + tVec.y * dY; - if (s > radius) { - return; - } - if (s > separation) { - separation = s; - normalIndex = i; - } - } - var vertIndex1 = parseInt(normalIndex); - var vertIndex2 = parseInt(vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0); - var v1 = vertices[vertIndex1]; - var v2 = vertices[vertIndex2]; - if (separation < Number.MIN_VALUE) { - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.SetV(normals[normalIndex]); - manifold.m_localPoint.x = 0.5 * (v1.x + v2.x); - manifold.m_localPoint.y = 0.5 * (v1.y + v2.y); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0; - return; - } - var u1 = (cLocalX - v1.x) * (v2.x - v1.x) + (cLocalY - v1.y) * (v2.y - v1.y); - var u2 = (cLocalX - v2.x) * (v1.x - v2.x) + (cLocalY - v2.y) * (v1.y - v2.y); - if (u1 <= 0.0) { - if ((cLocalX - v1.x) * (cLocalX - v1.x) + (cLocalY - v1.y) * (cLocalY - v1.y) > radius * radius) return; - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.x = cLocalX - v1.x; - manifold.m_localPlaneNormal.y = cLocalY - v1.y; - manifold.m_localPlaneNormal.Normalize(); - manifold.m_localPoint.SetV(v1); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0; - } - else if (u2 <= 0) { - if ((cLocalX - v2.x) * (cLocalX - v2.x) + (cLocalY - v2.y) * (cLocalY - v2.y) > radius * radius) return; - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.x = cLocalX - v2.x; - manifold.m_localPlaneNormal.y = cLocalY - v2.y; - manifold.m_localPlaneNormal.Normalize(); - manifold.m_localPoint.SetV(v2); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0; - } - else { - var faceCenterX = 0.5 * (v1.x + v2.x); - var faceCenterY = 0.5 * (v1.y + v2.y); - separation = (cLocalX - faceCenterX) * normals[vertIndex1].x + (cLocalY - faceCenterY) * normals[vertIndex1].y; - if (separation > radius) return; - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.x = normals[vertIndex1].x; - manifold.m_localPlaneNormal.y = normals[vertIndex1].y; - manifold.m_localPlaneNormal.Normalize(); - manifold.m_localPoint.Set(faceCenterX, faceCenterY); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0; - } - } - b2Collision.CollidePolygonAndCircle = b2Collision.prototype.CollidePolygonAndCircle; - b2Collision.prototype.TestOverlap = function (a, b) { - var t1 = b.lowerBound; - var t2 = a.upperBound; - var d1X = t1.x - t2.x; - var d1Y = t1.y - t2.y; - t1 = a.lowerBound; - t2 = b.upperBound; - var d2X = t1.x - t2.x; - var d2Y = t1.y - t2.y; - if (d1X > 0.0 || d1Y > 0.0) return false; - if (d2X > 0.0 || d2Y > 0.0) return false; - return true; - } - b2Collision.TestOverlap = b2Collision.prototype.TestOverlap; - _A2J_postDefs.push(function () { - Box2D.Collision.b2Collision.s_incidentEdge = b2Collision.MakeClipPointVector(); - Box2D.Collision.b2Collision.prototype.s_incidentEdge = Box2D.Collision.b2Collision.s_incidentEdge; - Box2D.Collision.b2Collision.s_clipPoints1 = b2Collision.MakeClipPointVector(); - Box2D.Collision.b2Collision.prototype.s_clipPoints1 = Box2D.Collision.b2Collision.s_clipPoints1; - Box2D.Collision.b2Collision.s_clipPoints2 = b2Collision.MakeClipPointVector(); - Box2D.Collision.b2Collision.prototype.s_clipPoints2 = Box2D.Collision.b2Collision.s_clipPoints2; - Box2D.Collision.b2Collision.s_edgeAO = new Vector_a2j_Number(1); - Box2D.Collision.b2Collision.prototype.s_edgeAO = Box2D.Collision.b2Collision.s_edgeAO; - Box2D.Collision.b2Collision.s_edgeBO = new Vector_a2j_Number(1); - Box2D.Collision.b2Collision.prototype.s_edgeBO = Box2D.Collision.b2Collision.s_edgeBO; - Box2D.Collision.b2Collision.s_localTangent = new b2Vec2(); - Box2D.Collision.b2Collision.prototype.s_localTangent = Box2D.Collision.b2Collision.s_localTangent; - Box2D.Collision.b2Collision.s_localNormal = new b2Vec2(); - Box2D.Collision.b2Collision.prototype.s_localNormal = Box2D.Collision.b2Collision.s_localNormal; - Box2D.Collision.b2Collision.s_planePoint = new b2Vec2(); - Box2D.Collision.b2Collision.prototype.s_planePoint = Box2D.Collision.b2Collision.s_planePoint; - Box2D.Collision.b2Collision.s_normal = new b2Vec2(); - Box2D.Collision.b2Collision.prototype.s_normal = Box2D.Collision.b2Collision.s_normal; - Box2D.Collision.b2Collision.s_tangent = new b2Vec2(); - Box2D.Collision.b2Collision.prototype.s_tangent = Box2D.Collision.b2Collision.s_tangent; - Box2D.Collision.b2Collision.s_tangent2 = new b2Vec2(); - Box2D.Collision.b2Collision.prototype.s_tangent2 = Box2D.Collision.b2Collision.s_tangent2; - Box2D.Collision.b2Collision.s_v11 = new b2Vec2(); - Box2D.Collision.b2Collision.prototype.s_v11 = Box2D.Collision.b2Collision.s_v11; - Box2D.Collision.b2Collision.s_v12 = new b2Vec2(); - Box2D.Collision.b2Collision.prototype.s_v12 = Box2D.Collision.b2Collision.s_v12; - Box2D.Collision.b2Collision.b2CollidePolyTempVec = new b2Vec2(); - Box2D.Collision.b2Collision.prototype.b2CollidePolyTempVec = Box2D.Collision.b2Collision.b2CollidePolyTempVec; - Box2D.Collision.b2Collision.b2_nullFeature = 0x000000ff; - Box2D.Collision.b2Collision.prototype.b2_nullFeature = Box2D.Collision.b2Collision.b2_nullFeature; - }); - b2ContactID.b2ContactID = function () { - this.features = new Features(); - }; - b2ContactID.prototype.b2ContactID = function () { - this.features._m_id = this; - } - b2ContactID.prototype.Set = function (id) { - this.key = id._key; - } - b2ContactID.prototype.Copy = function () { - var id = new b2ContactID(); - id.key = this.key; - return id; - } - b2ContactID.prototype.__defineGetter__('key', function () { - return this._key; - }); - b2ContactID.prototype.__defineSetter__('key', function (value) { - if (value === undefined) value = 0; - this._key = value; - this.features._referenceEdge = this._key & 0x000000ff; - this.features._incidentEdge = ((this._key & 0x0000ff00) >> 8) & 0x000000ff; - this.features._incidentVertex = ((this._key & 0x00ff0000) >> 16) & 0x000000ff; - this.features._flip = ((this._key & 0xff000000) >> 24) & 0x000000ff; - }); - b2ContactPoint.b2ContactPoint = function () { - this.position = new b2Vec2(); - this.velocity = new b2Vec2(); - this.normal = new b2Vec2(); - this.id = new b2ContactID(); - }; - b2Distance.b2Distance = function () {}; - b2Distance.prototype.Distance = function (output, cache, input) { - ++b2Distance.b2_gjkCalls; - var proxyA = input.proxyA; - var proxyB = input.proxyB; - var transformA = input.transformA; - var transformB = input.transformB; - var simplex = b2Distance.s_simplex; - simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB); - var vertices = simplex.m_vertices; - var k_maxIters = 20; - var saveA = b2Distance.s_saveA; - var saveB = b2Distance.s_saveB; - var saveCount = 0; - var closestPoint = simplex.GetClosestPoint(); - var distanceSqr1 = closestPoint.LengthSquared(); - var distanceSqr2 = distanceSqr1; - var i = 0; - var p; - var iter = 0; - while (iter < k_maxIters) { - saveCount = simplex.m_count; - for (i = 0; - i < saveCount; i++) { - saveA[i] = vertices[i].indexA; - saveB[i] = vertices[i].indexB; - } - switch (simplex.m_count) { - case 1: - break; - case 2: - simplex.Solve2(); - break; - case 3: - simplex.Solve3(); - break; - default: - b2Settings.b2Assert(false); - } - if (simplex.m_count == 3) { - break; - } - p = simplex.GetClosestPoint(); - distanceSqr2 = p.LengthSquared(); - if (distanceSqr2 > distanceSqr1) {} - distanceSqr1 = distanceSqr2; - var d = simplex.GetSearchDirection(); - if (d.LengthSquared() < Number.MIN_VALUE * Number.MIN_VALUE) { - break; - } - var vertex = vertices[simplex.m_count]; - vertex.indexA = proxyA.GetSupport(b2Math.MulTMV(transformA.R, d.GetNegative())); - vertex.wA = b2Math.MulX(transformA, proxyA.GetVertex(vertex.indexA)); - vertex.indexB = proxyB.GetSupport(b2Math.MulTMV(transformB.R, d)); - vertex.wB = b2Math.MulX(transformB, proxyB.GetVertex(vertex.indexB)); - vertex.w = b2Math.SubtractVV(vertex.wB, vertex.wA); - ++iter; - ++b2Distance.b2_gjkIters; - var duplicate = false; - for (i = 0; - i < saveCount; i++) { - if (vertex.indexA == saveA[i] && vertex.indexB == saveB[i]) { - duplicate = true; - break; - } - } - if (duplicate) { - break; - }++simplex.m_count; - } - b2Distance.b2_gjkMaxIters = b2Math.Max(b2Distance.b2_gjkMaxIters, iter); - simplex.GetWitnessPoints(output.pointA, output.pointB); - output.distance = b2Math.SubtractVV(output.pointA, output.pointB).Length(); - output.iterations = iter; - simplex.WriteCache(cache); - if (input.useRadii) { - var rA = proxyA.m_radius; - var rB = proxyB.m_radius; - if (output.distance > rA + rB && output.distance > Number.MIN_VALUE) { - output.distance -= rA + rB; - var normal = b2Math.SubtractVV(output.pointB, output.pointA); - normal.Normalize(); - output.pointA.x += rA * normal.x; - output.pointA.y += rA * normal.y; - output.pointB.x -= rB * normal.x; - output.pointB.y -= rB * normal.y; - } - else { - p = new b2Vec2(); - p.x = .5 * (output.pointA.x + output.pointB.x); - p.y = .5 * (output.pointA.y + output.pointB.y); - output.pointA.x = output.pointB.x = p.x; - output.pointA.y = output.pointB.y = p.y; - output.distance = 0.0; - } - } - } - b2Distance.Distance = b2Distance.prototype.Distance; - _A2J_postDefs.push(function () { - Box2D.Collision.b2Distance.s_simplex = new b2Simplex(); - Box2D.Collision.b2Distance.prototype.s_simplex = Box2D.Collision.b2Distance.s_simplex; - Box2D.Collision.b2Distance.s_saveA = new Vector_a2j_Number(3); - Box2D.Collision.b2Distance.prototype.s_saveA = Box2D.Collision.b2Distance.s_saveA; - Box2D.Collision.b2Distance.s_saveB = new Vector_a2j_Number(3); - Box2D.Collision.b2Distance.prototype.s_saveB = Box2D.Collision.b2Distance.s_saveB; - }); - b2DistanceInput.b2DistanceInput = function () {}; - b2DistanceOutput.b2DistanceOutput = function () { - this.pointA = new b2Vec2(); - this.pointB = new b2Vec2(); - }; - b2DistanceProxy.b2DistanceProxy = function () {}; - b2DistanceProxy.prototype.Set = function (shape) { - switch (shape.GetType()) { - case b2Shape.e_circleShape: - { - var circle = (shape instanceof b2CircleShape ? shape : null); - this.m_vertices = new Vector(1, true); - this.m_vertices[0] = circle.m_p; - this.m_count = 1; - this.m_radius = circle.m_radius; - } - break; - case b2Shape.e_polygonShape: - { - var polygon = (shape instanceof b2PolygonShape ? shape : null); - this.m_vertices = polygon.m_vertices; - this.m_count = polygon.m_vertexCount; - this.m_radius = polygon.m_radius; - } - break; - default: - b2Settings.b2Assert(false); - } - } - b2DistanceProxy.prototype.GetSupport = function (d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for (var i = 1; i < this.m_count; ++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if (value > bestValue) { - bestIndex = i; - bestValue = value; - } - } - return bestIndex; - } - b2DistanceProxy.prototype.GetSupportVertex = function (d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for (var i = 1; i < this.m_count; ++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if (value > bestValue) { - bestIndex = i; - bestValue = value; - } - } - return this.m_vertices[bestIndex]; - } - b2DistanceProxy.prototype.GetVertexCount = function () { - return this.m_count; - } - b2DistanceProxy.prototype.GetVertex = function (index) { - if (index === undefined) index = 0; - b2Settings.b2Assert(0 <= index && index < this.m_count); - return this.m_vertices[index]; - } - b2DynamicTree.b2DynamicTree = function () {}; - b2DynamicTree.prototype.b2DynamicTree = function () { - this.m_root = null; - this.m_freeList = null; - this.m_path = 0; - this.m_insertionCount = 0; - } - b2DynamicTree.prototype.CreateProxy = function (aabb, userData) { - var node = this.AllocateNode(); - var extendX = b2Settings.b2_aabbExtension; - var extendY = b2Settings.b2_aabbExtension; - node.aabb.lowerBound.x = aabb.lowerBound.x - extendX; - node.aabb.lowerBound.y = aabb.lowerBound.y - extendY; - node.aabb.upperBound.x = aabb.upperBound.x + extendX; - node.aabb.upperBound.y = aabb.upperBound.y + extendY; - node.userData = userData; - this.InsertLeaf(node); - return node; - } - b2DynamicTree.prototype.DestroyProxy = function (proxy) { - this.RemoveLeaf(proxy); - this.FreeNode(proxy); - } - b2DynamicTree.prototype.MoveProxy = function (proxy, aabb, displacement) { - b2Settings.b2Assert(proxy.IsLeaf()); - if (proxy.aabb.Contains(aabb)) { - return false; - } - this.RemoveLeaf(proxy); - var extendX = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.x > 0 ? displacement.x : (-displacement.x)); - var extendY = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.y > 0 ? displacement.y : (-displacement.y)); - proxy.aabb.lowerBound.x = aabb.lowerBound.x - extendX; - proxy.aabb.lowerBound.y = aabb.lowerBound.y - extendY; - proxy.aabb.upperBound.x = aabb.upperBound.x + extendX; - proxy.aabb.upperBound.y = aabb.upperBound.y + extendY; - this.InsertLeaf(proxy); - return true; - } - b2DynamicTree.prototype.Rebalance = function (iterations) { - if (iterations === undefined) iterations = 0; - if (this.m_root == null) return; - for (var i = 0; i < iterations; i++) { - var node = this.m_root; - var bit = 0; - while (node.IsLeaf() == false) { - node = (this.m_path >> bit) & 1 ? node.child2 : node.child1; - bit = (bit + 1) & 31; - }++this.m_path; - this.RemoveLeaf(node); - this.InsertLeaf(node); - } - } - b2DynamicTree.prototype.GetFatAABB = function (proxy) { - return proxy.aabb; - } - b2DynamicTree.prototype.GetUserData = function (proxy) { - return proxy.userData; - } - b2DynamicTree.prototype.Query = function (callback, aabb) { - if (this.m_root == null) return; - var stack = new Vector(); - var count = 0; - stack[count++] = this.m_root; - while (count > 0) { - var node = stack[--count]; - if (node.aabb.TestOverlap(aabb)) { - if (node.IsLeaf()) { - var proceed = callback(node); - if (!proceed) return; - } - else { - stack[count++] = node.child1; - stack[count++] = node.child2; + maxFraction = callback(subInput, node); + if(maxFraction == 0) { + return + } + tX = p1.x + maxFraction * (p2.x - p1.x); + tY = p1.y + maxFraction * (p2.y - p1.y); + segmentAABB.lowerBound.x = Math.min(p1.x, tX); + segmentAABB.lowerBound.y = Math.min(p1.y, tY); + segmentAABB.upperBound.x = Math.max(p1.x, tX); + segmentAABB.upperBound.y = Math.max(p1.y, tY) + }else { + stack[count++] = node.child1; + stack[count++] = node.child2 + } + } +}; +b2DynamicTree.prototype.m_root = null; +b2DynamicTree.prototype.m_freeList = null; +b2DynamicTree.prototype.m_path = 0; +b2DynamicTree.prototype.m_insertionCount = 0;var b2JointEdge = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2JointEdge.prototype.__constructor = function() { +}; +b2JointEdge.prototype.__varz = function() { +}; +b2JointEdge.prototype.other = null; +b2JointEdge.prototype.joint = null; +b2JointEdge.prototype.prev = null; +b2JointEdge.prototype.next = null;var b2RayCastInput = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2RayCastInput.prototype.__constructor = function() { +}; +b2RayCastInput.prototype.__varz = function() { + this.p1 = new b2Vec2; + this.p2 = new b2Vec2 +}; +b2RayCastInput.prototype.p1 = new b2Vec2; +b2RayCastInput.prototype.p2 = new b2Vec2; +b2RayCastInput.prototype.maxFraction = null;var Features = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +Features.prototype.__constructor = function() { +}; +Features.prototype.__varz = function() { +}; +Features.prototype.__defineGetter__("referenceEdge", function() { + return this._referenceEdge +}); +Features.prototype.__defineSetter__("referenceEdge", function(value) { + this._referenceEdge = value; + this._m_id._key = this._m_id._key & 4294967040 | this._referenceEdge & 255 +}); +Features.prototype.__defineGetter__("incidentEdge", function() { + return this._incidentEdge +}); +Features.prototype.__defineSetter__("incidentEdge", function(value) { + this._incidentEdge = value; + this._m_id._key = this._m_id._key & 4294902015 | this._incidentEdge << 8 & 65280 +}); +Features.prototype.__defineGetter__("incidentVertex", function() { + return this._incidentVertex +}); +Features.prototype.__defineSetter__("incidentVertex", function(value) { + this._incidentVertex = value; + this._m_id._key = this._m_id._key & 4278255615 | this._incidentVertex << 16 & 16711680 +}); +Features.prototype.__defineGetter__("flip", function() { + return this._flip +}); +Features.prototype.__defineSetter__("flip", function(value) { + this._flip = value; + this._m_id._key = this._m_id._key & 16777215 | this._flip << 24 & 4278190080 +}); +Features.prototype._referenceEdge = 0; +Features.prototype._incidentEdge = 0; +Features.prototype._incidentVertex = 0; +Features.prototype._flip = 0; +Features.prototype._m_id = null;var b2FilterData = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2FilterData.prototype.__constructor = function() { +}; +b2FilterData.prototype.__varz = function() { + this.categoryBits = 1; + this.maskBits = 65535 +}; +b2FilterData.prototype.Copy = function() { + var copy = new b2FilterData; + copy.categoryBits = this.categoryBits; + copy.maskBits = this.maskBits; + copy.groupIndex = this.groupIndex; + return copy +}; +b2FilterData.prototype.categoryBits = 1; +b2FilterData.prototype.maskBits = 65535; +b2FilterData.prototype.groupIndex = 0;var b2AABB = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2AABB.prototype.__constructor = function() { +}; +b2AABB.prototype.__varz = function() { + this.lowerBound = new b2Vec2; + this.upperBound = new b2Vec2 +}; +b2AABB.Combine = function(aabb1, aabb2) { + var aabb = new b2AABB; + aabb.Combine(aabb1, aabb2); + return aabb +}; +b2AABB.prototype.IsValid = function() { + var dX = this.upperBound.x - this.lowerBound.x; + var dY = this.upperBound.y - this.lowerBound.y; + var valid = dX >= 0 && dY >= 0; + valid = valid && this.lowerBound.IsValid() && this.upperBound.IsValid(); + return valid +}; +b2AABB.prototype.GetCenter = function() { + return new b2Vec2((this.lowerBound.x + this.upperBound.x) / 2, (this.lowerBound.y + this.upperBound.y) / 2) +}; +b2AABB.prototype.GetExtents = function() { + return new b2Vec2((this.upperBound.x - this.lowerBound.x) / 2, (this.upperBound.y - this.lowerBound.y) / 2) +}; +b2AABB.prototype.Contains = function(aabb) { + var result = true && this.lowerBound.x <= aabb.lowerBound.x && this.lowerBound.y <= aabb.lowerBound.y && aabb.upperBound.x <= this.upperBound.x && aabb.upperBound.y <= this.upperBound.y; + return result +}; +b2AABB.prototype.RayCast = function(output, input) { + var tmin = -Number.MAX_VALUE; + var tmax = Number.MAX_VALUE; + var pX = input.p1.x; + var pY = input.p1.y; + var dX = input.p2.x - input.p1.x; + var dY = input.p2.y - input.p1.y; + var absDX = Math.abs(dX); + var absDY = Math.abs(dY); + var normal = output.normal; + var inv_d; + var t1; + var t2; + var t3; + var s; + if(absDX < Number.MIN_VALUE) { + if(pX < this.lowerBound.x || this.upperBound.x < pX) { + return false + } + }else { + inv_d = 1 / dX; + t1 = (this.lowerBound.x - pX) * inv_d; + t2 = (this.upperBound.x - pX) * inv_d; + s = -1; + if(t1 > t2) { + t3 = t1; + t1 = t2; + t2 = t3; + s = 1 + } + if(t1 > tmin) { + normal.x = s; + normal.y = 0; + tmin = t1 + } + tmax = Math.min(tmax, t2); + if(tmin > tmax) { + return false + } + } + if(absDY < Number.MIN_VALUE) { + if(pY < this.lowerBound.y || this.upperBound.y < pY) { + return false + } + }else { + inv_d = 1 / dY; + t1 = (this.lowerBound.y - pY) * inv_d; + t2 = (this.upperBound.y - pY) * inv_d; + s = -1; + if(t1 > t2) { + t3 = t1; + t1 = t2; + t2 = t3; + s = 1 + } + if(t1 > tmin) { + normal.y = s; + normal.x = 0; + tmin = t1 + } + tmax = Math.min(tmax, t2); + if(tmin > tmax) { + return false + } + } + output.fraction = tmin; + return true +}; +b2AABB.prototype.TestOverlap = function(other) { + var d1X = other.lowerBound.x - this.upperBound.x; + var d1Y = other.lowerBound.y - this.upperBound.y; + var d2X = this.lowerBound.x - other.upperBound.x; + var d2Y = this.lowerBound.y - other.upperBound.y; + if(d1X > 0 || d1Y > 0) { + return false + } + if(d2X > 0 || d2Y > 0) { + return false + } + return true +}; +b2AABB.prototype.Combine = function(aabb1, aabb2) { + this.lowerBound.x = Math.min(aabb1.lowerBound.x, aabb2.lowerBound.x); + this.lowerBound.y = Math.min(aabb1.lowerBound.y, aabb2.lowerBound.y); + this.upperBound.x = Math.max(aabb1.upperBound.x, aabb2.upperBound.x); + this.upperBound.y = Math.max(aabb1.upperBound.y, aabb2.upperBound.y) +}; +b2AABB.prototype.lowerBound = new b2Vec2; +b2AABB.prototype.upperBound = new b2Vec2;var b2Jacobian = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Jacobian.prototype.__constructor = function() { +}; +b2Jacobian.prototype.__varz = function() { + this.linearA = new b2Vec2; + this.linearB = new b2Vec2 +}; +b2Jacobian.prototype.SetZero = function() { + this.linearA.SetZero(); + this.angularA = 0; + this.linearB.SetZero(); + this.angularB = 0 +}; +b2Jacobian.prototype.Set = function(x1, a1, x2, a2) { + this.linearA.SetV(x1); + this.angularA = a1; + this.linearB.SetV(x2); + this.angularB = a2 +}; +b2Jacobian.prototype.Compute = function(x1, a1, x2, a2) { + return this.linearA.x * x1.x + this.linearA.y * x1.y + this.angularA * a1 + (this.linearB.x * x2.x + this.linearB.y * x2.y) + this.angularB * a2 +}; +b2Jacobian.prototype.linearA = new b2Vec2; +b2Jacobian.prototype.angularA = null; +b2Jacobian.prototype.linearB = new b2Vec2; +b2Jacobian.prototype.angularB = null;var b2Bound = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Bound.prototype.__constructor = function() { +}; +b2Bound.prototype.__varz = function() { +}; +b2Bound.prototype.IsLower = function() { + return(this.value & 1) == 0 +}; +b2Bound.prototype.IsUpper = function() { + return(this.value & 1) == 1 +}; +b2Bound.prototype.Swap = function(b) { + var tempValue = this.value; + var tempProxy = this.proxy; + var tempStabbingCount = this.stabbingCount; + this.value = b.value; + this.proxy = b.proxy; + this.stabbingCount = b.stabbingCount; + b.value = tempValue; + b.proxy = tempProxy; + b.stabbingCount = tempStabbingCount +}; +b2Bound.prototype.value = 0; +b2Bound.prototype.proxy = null; +b2Bound.prototype.stabbingCount = 0;var b2SimplexVertex = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2SimplexVertex.prototype.__constructor = function() { +}; +b2SimplexVertex.prototype.__varz = function() { +}; +b2SimplexVertex.prototype.Set = function(other) { + this.wA.SetV(other.wA); + this.wB.SetV(other.wB); + this.w.SetV(other.w); + this.a = other.a; + this.indexA = other.indexA; + this.indexB = other.indexB +}; +b2SimplexVertex.prototype.wA = null; +b2SimplexVertex.prototype.wB = null; +b2SimplexVertex.prototype.w = null; +b2SimplexVertex.prototype.a = null; +b2SimplexVertex.prototype.indexA = 0; +b2SimplexVertex.prototype.indexB = 0;var b2Mat22 = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Mat22.prototype.__constructor = function() { + this.col1.x = this.col2.y = 1 +}; +b2Mat22.prototype.__varz = function() { + this.col1 = new b2Vec2; + this.col2 = new b2Vec2 +}; +b2Mat22.FromAngle = function(angle) { + var mat = new b2Mat22; + mat.Set(angle); + return mat +}; +b2Mat22.FromVV = function(c1, c2) { + var mat = new b2Mat22; + mat.SetVV(c1, c2); + return mat +}; +b2Mat22.prototype.Set = function(angle) { + var c = Math.cos(angle); + var s = Math.sin(angle); + this.col1.x = c; + this.col2.x = -s; + this.col1.y = s; + this.col2.y = c +}; +b2Mat22.prototype.SetVV = function(c1, c2) { + this.col1.SetV(c1); + this.col2.SetV(c2) +}; +b2Mat22.prototype.Copy = function() { + var mat = new b2Mat22; + mat.SetM(this); + return mat +}; +b2Mat22.prototype.SetM = function(m) { + this.col1.SetV(m.col1); + this.col2.SetV(m.col2) +}; +b2Mat22.prototype.AddM = function(m) { + this.col1.x += m.col1.x; + this.col1.y += m.col1.y; + this.col2.x += m.col2.x; + this.col2.y += m.col2.y +}; +b2Mat22.prototype.SetIdentity = function() { + this.col1.x = 1; + this.col2.x = 0; + this.col1.y = 0; + this.col2.y = 1 +}; +b2Mat22.prototype.SetZero = function() { + this.col1.x = 0; + this.col2.x = 0; + this.col1.y = 0; + this.col2.y = 0 +}; +b2Mat22.prototype.GetAngle = function() { + return Math.atan2(this.col1.y, this.col1.x) +}; +b2Mat22.prototype.GetInverse = function(out) { + var a = this.col1.x; + var b = this.col2.x; + var c = this.col1.y; + var d = this.col2.y; + var det = a * d - b * c; + if(det != 0) { + det = 1 / det + } + out.col1.x = det * d; + out.col2.x = -det * b; + out.col1.y = -det * c; + out.col2.y = det * a; + return out +}; +b2Mat22.prototype.Solve = function(out, bX, bY) { + var a11 = this.col1.x; + var a12 = this.col2.x; + var a21 = this.col1.y; + var a22 = this.col2.y; + var det = a11 * a22 - a12 * a21; + if(det != 0) { + det = 1 / det + } + out.x = det * (a22 * bX - a12 * bY); + out.y = det * (a11 * bY - a21 * bX); + return out +}; +b2Mat22.prototype.Abs = function() { + this.col1.Abs(); + this.col2.Abs() +}; +b2Mat22.prototype.col1 = new b2Vec2; +b2Mat22.prototype.col2 = new b2Vec2;var b2SimplexCache = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2SimplexCache.prototype.__constructor = function() { +}; +b2SimplexCache.prototype.__varz = function() { + this.indexA = new Array(3); + this.indexB = new Array(3) +}; +b2SimplexCache.prototype.metric = null; +b2SimplexCache.prototype.count = 0; +b2SimplexCache.prototype.indexA = new Array(3); +b2SimplexCache.prototype.indexB = new Array(3);var b2Shape = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Shape.prototype.__constructor = function() { + this.m_type = b2Shape.e_unknownShape; + this.m_radius = b2Settings.b2_linearSlop +}; +b2Shape.prototype.__varz = function() { +}; +b2Shape.TestOverlap = function(shape1, transform1, shape2, transform2) { + var input = new b2DistanceInput; + input.proxyA = new b2DistanceProxy; + input.proxyA.Set(shape1); + input.proxyB = new b2DistanceProxy; + input.proxyB.Set(shape2); + input.transformA = transform1; + input.transformB = transform2; + input.useRadii = true; + var simplexCache = new b2SimplexCache; + simplexCache.count = 0; + var output = new b2DistanceOutput; + b2Distance.Distance(output, simplexCache, input); + return output.distance < 10 * Number.MIN_VALUE +}; +b2Shape.e_hitCollide = 1; +b2Shape.e_missCollide = 0; +b2Shape.e_startsInsideCollide = -1; +b2Shape.e_unknownShape = -1; +b2Shape.e_circleShape = 0; +b2Shape.e_polygonShape = 1; +b2Shape.e_edgeShape = 2; +b2Shape.e_shapeTypeCount = 3; +b2Shape.prototype.Copy = function() { + return null +}; +b2Shape.prototype.Set = function(other) { + this.m_radius = other.m_radius +}; +b2Shape.prototype.GetType = function() { + return this.m_type +}; +b2Shape.prototype.TestPoint = function(xf, p) { + return false +}; +b2Shape.prototype.RayCast = function(output, input, transform) { + return false +}; +b2Shape.prototype.ComputeAABB = function(aabb, xf) { +}; +b2Shape.prototype.ComputeMass = function(massData, density) { +}; +b2Shape.prototype.ComputeSubmergedArea = function(normal, offset, xf, c) { + return 0 +}; +b2Shape.prototype.m_type = 0; +b2Shape.prototype.m_radius = null;var b2Segment = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Segment.prototype.__constructor = function() { +}; +b2Segment.prototype.__varz = function() { + this.p1 = new b2Vec2; + this.p2 = new b2Vec2 +}; +b2Segment.prototype.TestSegment = function(lambda, normal, segment, maxLambda) { + var s = segment.p1; + var rX = segment.p2.x - s.x; + var rY = segment.p2.y - s.y; + var dX = this.p2.x - this.p1.x; + var dY = this.p2.y - this.p1.y; + var nX = dY; + var nY = -dX; + var k_slop = 100 * Number.MIN_VALUE; + var denom = -(rX * nX + rY * nY); + if(denom > k_slop) { + var bX = s.x - this.p1.x; + var bY = s.y - this.p1.y; + var a = bX * nX + bY * nY; + if(0 <= a && a <= maxLambda * denom) { + var mu2 = -rX * bY + rY * bX; + if(-k_slop * denom <= mu2 && mu2 <= denom * (1 + k_slop)) { + a /= denom; + var nLen = Math.sqrt(nX * nX + nY * nY); + nX /= nLen; + nY /= nLen; + lambda[0] = a; + normal.Set(nX, nY); + return true + } + } + } + return false +}; +b2Segment.prototype.Extend = function(aabb) { + this.ExtendForward(aabb); + this.ExtendBackward(aabb) +}; +b2Segment.prototype.ExtendForward = function(aabb) { + var dX = this.p2.x - this.p1.x; + var dY = this.p2.y - this.p1.y; + var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p1.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p1.x) / dX : Number.POSITIVE_INFINITY, dY > 0 ? (aabb.upperBound.y - this.p1.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p1.y) / dY : Number.POSITIVE_INFINITY); + this.p2.x = this.p1.x + dX * lambda; + this.p2.y = this.p1.y + dY * lambda +}; +b2Segment.prototype.ExtendBackward = function(aabb) { + var dX = -this.p2.x + this.p1.x; + var dY = -this.p2.y + this.p1.y; + var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p2.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p2.x) / dX : Number.POSITIVE_INFINITY, dY > 0 ? (aabb.upperBound.y - this.p2.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p2.y) / dY : Number.POSITIVE_INFINITY); + this.p1.x = this.p2.x + dX * lambda; + this.p1.y = this.p2.y + dY * lambda +}; +b2Segment.prototype.p1 = new b2Vec2; +b2Segment.prototype.p2 = new b2Vec2;var b2ContactRegister = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactRegister.prototype.__constructor = function() { +}; +b2ContactRegister.prototype.__varz = function() { +}; +b2ContactRegister.prototype.createFcn = null; +b2ContactRegister.prototype.destroyFcn = null; +b2ContactRegister.prototype.primary = null; +b2ContactRegister.prototype.pool = null; +b2ContactRegister.prototype.poolCount = 0;var b2DebugDraw = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2DebugDraw.prototype.__constructor = function() { + this.m_drawFlags = 0 +}; +b2DebugDraw.prototype.__varz = function() { +}; +b2DebugDraw.e_shapeBit = 1; +b2DebugDraw.e_jointBit = 2; +b2DebugDraw.e_aabbBit = 4; +b2DebugDraw.e_pairBit = 8; +b2DebugDraw.e_centerOfMassBit = 16; +b2DebugDraw.e_controllerBit = 32; +b2DebugDraw.prototype.SetFlags = function(flags) { + this.m_drawFlags = flags +}; +b2DebugDraw.prototype.GetFlags = function() { + return this.m_drawFlags +}; +b2DebugDraw.prototype.AppendFlags = function(flags) { + this.m_drawFlags |= flags +}; +b2DebugDraw.prototype.ClearFlags = function(flags) { + this.m_drawFlags &= ~flags +}; +b2DebugDraw.prototype.SetSprite = function(sprite) { + this.m_sprite = sprite +}; +b2DebugDraw.prototype.GetSprite = function() { + return this.m_sprite +}; +b2DebugDraw.prototype.SetDrawScale = function(drawScale) { + this.m_drawScale = drawScale +}; +b2DebugDraw.prototype.GetDrawScale = function() { + return this.m_drawScale +}; +b2DebugDraw.prototype.SetLineThickness = function(lineThickness) { + this.m_lineThickness = lineThickness +}; +b2DebugDraw.prototype.GetLineThickness = function() { + return this.m_lineThickness +}; +b2DebugDraw.prototype.SetAlpha = function(alpha) { + this.m_alpha = alpha +}; +b2DebugDraw.prototype.GetAlpha = function() { + return this.m_alpha +}; +b2DebugDraw.prototype.SetFillAlpha = function(alpha) { + this.m_fillAlpha = alpha +}; +b2DebugDraw.prototype.GetFillAlpha = function() { + return this.m_fillAlpha +}; +b2DebugDraw.prototype.SetXFormScale = function(xformScale) { + this.m_xformScale = xformScale +}; +b2DebugDraw.prototype.GetXFormScale = function() { + return this.m_xformScale +}; +b2DebugDraw.prototype.Clear = function() { + this.m_sprite.clearRect(0, 0, this.m_sprite.canvas.width, this.m_sprite.canvas.height) +}; +b2DebugDraw.prototype.Y = function(y) { + return this.m_sprite.canvas.height - y +}; +b2DebugDraw.prototype.ToWorldPoint = function(localPoint) { + return new b2Vec2(localPoint.x / this.m_drawScale, this.Y(localPoint.y) / this.m_drawScale) +}; +b2DebugDraw.prototype.ColorStyle = function(color, alpha) { + return"rgba(" + color.r + ", " + color.g + ", " + color.b + ", " + alpha + ")" +}; +b2DebugDraw.prototype.DrawPolygon = function(vertices, vertexCount, color) { + this.m_sprite.graphics.lineStyle(this.m_lineThickness, color.color, this.m_alpha); + this.m_sprite.graphics.moveTo(vertices[0].x * this.m_drawScale, vertices[0].y * this.m_drawScale); + for(var i = 1;i < vertexCount;i++) { + this.m_sprite.graphics.lineTo(vertices[i].x * this.m_drawScale, vertices[i].y * this.m_drawScale) + } + this.m_sprite.graphics.lineTo(vertices[0].x * this.m_drawScale, vertices[0].y * this.m_drawScale) +}; +b2DebugDraw.prototype.DrawSolidPolygon = function(vertices, vertexCount, color) { + this.m_sprite.strokeSyle = this.ColorStyle(color, this.m_alpha); + this.m_sprite.lineWidth = this.m_lineThickness; + this.m_sprite.fillStyle = this.ColorStyle(color, this.m_fillAlpha); + this.m_sprite.beginPath(); + this.m_sprite.moveTo(vertices[0].x * this.m_drawScale, this.Y(vertices[0].y * this.m_drawScale)); + for(var i = 1;i < vertexCount;i++) { + this.m_sprite.lineTo(vertices[i].x * this.m_drawScale, this.Y(vertices[i].y * this.m_drawScale)) + } + this.m_sprite.lineTo(vertices[0].x * this.m_drawScale, this.Y(vertices[0].y * this.m_drawScale)); + this.m_sprite.fill(); + this.m_sprite.stroke(); + this.m_sprite.closePath() +}; +b2DebugDraw.prototype.DrawCircle = function(center, radius, color) { + this.m_sprite.graphics.lineStyle(this.m_lineThickness, color.color, this.m_alpha); + this.m_sprite.graphics.drawCircle(center.x * this.m_drawScale, center.y * this.m_drawScale, radius * this.m_drawScale) +}; +b2DebugDraw.prototype.DrawSolidCircle = function(center, radius, axis, color) { + this.m_sprite.strokeSyle = this.ColorStyle(color, this.m_alpha); + this.m_sprite.lineWidth = this.m_lineThickness; + this.m_sprite.fillStyle = this.ColorStyle(color, this.m_fillAlpha); + this.m_sprite.beginPath(); + this.m_sprite.arc(center.x * this.m_drawScale, this.Y(center.y * this.m_drawScale), radius * this.m_drawScale, 0, Math.PI * 2, true); + this.m_sprite.fill(); + this.m_sprite.stroke(); + this.m_sprite.closePath() +}; +b2DebugDraw.prototype.DrawSegment = function(p1, p2, color) { + this.m_sprite.lineWidth = this.m_lineThickness; + this.m_sprite.strokeSyle = this.ColorStyle(color, this.m_alpha); + this.m_sprite.beginPath(); + this.m_sprite.moveTo(p1.x * this.m_drawScale, this.Y(p1.y * this.m_drawScale)); + this.m_sprite.lineTo(p2.x * this.m_drawScale, this.Y(p2.y * this.m_drawScale)); + this.m_sprite.stroke(); + this.m_sprite.closePath() +}; +b2DebugDraw.prototype.DrawTransform = function(xf) { + this.m_sprite.lineWidth = this.m_lineThickness; + this.m_sprite.strokeSyle = this.ColorStyle(new b2Color(255, 0, 0), this.m_alpha); + this.m_sprite.beginPath(); + this.m_sprite.moveTo(xf.position.x * this.m_drawScale, this.Y(xf.position.y * this.m_drawScale)); + this.m_sprite.lineTo((xf.position.x + this.m_xformScale * xf.R.col1.x) * this.m_drawScale, this.Y((xf.position.y + this.m_xformScale * xf.R.col1.y) * this.m_drawScale)); + this.m_sprite.stroke(); + this.m_sprite.closePath(); + this.m_sprite.strokeSyle = this.ColorStyle(new b2Color(0, 255, 0), this.m_alpha); + this.m_sprite.beginPath(); + this.m_sprite.moveTo(xf.position.x * this.m_drawScale, this.Y(xf.position.y * this.m_drawScale)); + this.m_sprite.lineTo((xf.position.x + this.m_xformScale * xf.R.col2.x) * this.m_drawScale, this.Y((xf.position.y + this.m_xformScale * xf.R.col2.y) * this.m_drawScale)); + this.m_sprite.stroke(); + this.m_sprite.closePath() +}; +b2DebugDraw.prototype.m_drawFlags = 0; +b2DebugDraw.prototype.m_sprite = null; +b2DebugDraw.prototype.m_drawScale = 1; +b2DebugDraw.prototype.m_lineThickness = 1; +b2DebugDraw.prototype.m_alpha = 1; +b2DebugDraw.prototype.m_fillAlpha = 1; +b2DebugDraw.prototype.m_xformScale = 1;var b2Sweep = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Sweep.prototype.__constructor = function() { +}; +b2Sweep.prototype.__varz = function() { + this.localCenter = new b2Vec2; + this.c0 = new b2Vec2; + this.c = new b2Vec2 +}; +b2Sweep.prototype.Set = function(other) { + this.localCenter.SetV(other.localCenter); + this.c0.SetV(other.c0); + this.c.SetV(other.c); + this.a0 = other.a0; + this.a = other.a; + this.t0 = other.t0 +}; +b2Sweep.prototype.Copy = function() { + var copy = new b2Sweep; + copy.localCenter.SetV(this.localCenter); + copy.c0.SetV(this.c0); + copy.c.SetV(this.c); + copy.a0 = this.a0; + copy.a = this.a; + copy.t0 = this.t0; + return copy +}; +b2Sweep.prototype.GetTransform = function(xf, alpha) { + xf.position.x = (1 - alpha) * this.c0.x + alpha * this.c.x; + xf.position.y = (1 - alpha) * this.c0.y + alpha * this.c.y; + var angle = (1 - alpha) * this.a0 + alpha * this.a; + xf.R.Set(angle); + var tMat = xf.R; + xf.position.x -= tMat.col1.x * this.localCenter.x + tMat.col2.x * this.localCenter.y; + xf.position.y -= tMat.col1.y * this.localCenter.x + tMat.col2.y * this.localCenter.y +}; +b2Sweep.prototype.Advance = function(t) { + if(this.t0 < t && 1 - this.t0 > Number.MIN_VALUE) { + var alpha = (t - this.t0) / (1 - this.t0); + this.c0.x = (1 - alpha) * this.c0.x + alpha * this.c.x; + this.c0.y = (1 - alpha) * this.c0.y + alpha * this.c.y; + this.a0 = (1 - alpha) * this.a0 + alpha * this.a; + this.t0 = t + } +}; +b2Sweep.prototype.localCenter = new b2Vec2; +b2Sweep.prototype.c0 = new b2Vec2; +b2Sweep.prototype.c = new b2Vec2; +b2Sweep.prototype.a0 = null; +b2Sweep.prototype.a = null; +b2Sweep.prototype.t0 = null;var b2DistanceOutput = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2DistanceOutput.prototype.__constructor = function() { +}; +b2DistanceOutput.prototype.__varz = function() { + this.pointA = new b2Vec2; + this.pointB = new b2Vec2 +}; +b2DistanceOutput.prototype.pointA = new b2Vec2; +b2DistanceOutput.prototype.pointB = new b2Vec2; +b2DistanceOutput.prototype.distance = null; +b2DistanceOutput.prototype.iterations = 0;var b2Mat33 = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Mat33.prototype.__constructor = function(c1, c2, c3) { + if(!c1 && !c2 && !c3) { + this.col1.SetZero(); + this.col2.SetZero(); + this.col3.SetZero() + }else { + this.col1.SetV(c1); + this.col2.SetV(c2); + this.col3.SetV(c3) + } +}; +b2Mat33.prototype.__varz = function() { + this.col1 = new b2Vec3; + this.col2 = new b2Vec3; + this.col3 = new b2Vec3 +}; +b2Mat33.prototype.SetVVV = function(c1, c2, c3) { + this.col1.SetV(c1); + this.col2.SetV(c2); + this.col3.SetV(c3) +}; +b2Mat33.prototype.Copy = function() { + return new b2Mat33(this.col1, this.col2, this.col3) +}; +b2Mat33.prototype.SetM = function(m) { + this.col1.SetV(m.col1); + this.col2.SetV(m.col2); + this.col3.SetV(m.col3) +}; +b2Mat33.prototype.AddM = function(m) { + this.col1.x += m.col1.x; + this.col1.y += m.col1.y; + this.col1.z += m.col1.z; + this.col2.x += m.col2.x; + this.col2.y += m.col2.y; + this.col2.z += m.col2.z; + this.col3.x += m.col3.x; + this.col3.y += m.col3.y; + this.col3.z += m.col3.z +}; +b2Mat33.prototype.SetIdentity = function() { + this.col1.x = 1; + this.col2.x = 0; + this.col3.x = 0; + this.col1.y = 0; + this.col2.y = 1; + this.col3.y = 0; + this.col1.z = 0; + this.col2.z = 0; + this.col3.z = 1 +}; +b2Mat33.prototype.SetZero = function() { + this.col1.x = 0; + this.col2.x = 0; + this.col3.x = 0; + this.col1.y = 0; + this.col2.y = 0; + this.col3.y = 0; + this.col1.z = 0; + this.col2.z = 0; + this.col3.z = 0 +}; +b2Mat33.prototype.Solve22 = function(out, bX, bY) { + var a11 = this.col1.x; + var a12 = this.col2.x; + var a21 = this.col1.y; + var a22 = this.col2.y; + var det = a11 * a22 - a12 * a21; + if(det != 0) { + det = 1 / det + } + out.x = det * (a22 * bX - a12 * bY); + out.y = det * (a11 * bY - a21 * bX); + return out +}; +b2Mat33.prototype.Solve33 = function(out, bX, bY, bZ) { + var a11 = this.col1.x; + var a21 = this.col1.y; + var a31 = this.col1.z; + var a12 = this.col2.x; + var a22 = this.col2.y; + var a32 = this.col2.z; + var a13 = this.col3.x; + var a23 = this.col3.y; + var a33 = this.col3.z; + var det = a11 * (a22 * a33 - a32 * a23) + a21 * (a32 * a13 - a12 * a33) + a31 * (a12 * a23 - a22 * a13); + if(det != 0) { + det = 1 / det + } + out.x = det * (bX * (a22 * a33 - a32 * a23) + bY * (a32 * a13 - a12 * a33) + bZ * (a12 * a23 - a22 * a13)); + out.y = det * (a11 * (bY * a33 - bZ * a23) + a21 * (bZ * a13 - bX * a33) + a31 * (bX * a23 - bY * a13)); + out.z = det * (a11 * (a22 * bZ - a32 * bY) + a21 * (a32 * bX - a12 * bZ) + a31 * (a12 * bY - a22 * bX)); + return out +}; +b2Mat33.prototype.col1 = new b2Vec3; +b2Mat33.prototype.col2 = new b2Vec3; +b2Mat33.prototype.col3 = new b2Vec3;var b2PositionSolverManifold = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2PositionSolverManifold.prototype.__constructor = function() { + this.m_normal = new b2Vec2; + this.m_separations = new Array(b2Settings.b2_maxManifoldPoints); + this.m_points = new Array(b2Settings.b2_maxManifoldPoints); + for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { + this.m_points[i] = new b2Vec2 + } +}; +b2PositionSolverManifold.prototype.__varz = function() { +}; +b2PositionSolverManifold.circlePointA = new b2Vec2; +b2PositionSolverManifold.circlePointB = new b2Vec2; +b2PositionSolverManifold.prototype.Initialize = function(cc) { + b2Settings.b2Assert(cc.pointCount > 0); + var i = 0; + var clipPointX; + var clipPointY; + var tMat; + var tVec; + var planePointX; + var planePointY; + switch(cc.type) { + case b2Manifold.e_circles: + tMat = cc.bodyA.m_xf.R; + tVec = cc.localPoint; + var pointAX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var pointAY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = cc.bodyB.m_xf.R; + tVec = cc.points[0].localPoint; + var pointBX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var pointBY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var dX = pointBX - pointAX; + var dY = pointBY - pointAY; + var d2 = dX * dX + dY * dY; + if(d2 > Number.MIN_VALUE * Number.MIN_VALUE) { + var d = Math.sqrt(d2); + this.m_normal.x = dX / d; + this.m_normal.y = dY / d + }else { + this.m_normal.x = 1; + this.m_normal.y = 0 + } + this.m_points[0].x = 0.5 * (pointAX + pointBX); + this.m_points[0].y = 0.5 * (pointAY + pointBY); + this.m_separations[0] = dX * this.m_normal.x + dY * this.m_normal.y - cc.radius; + break; + case b2Manifold.e_faceA: + tMat = cc.bodyA.m_xf.R; + tVec = cc.localPlaneNormal; + this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = cc.bodyA.m_xf.R; + tVec = cc.localPoint; + planePointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + planePointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = cc.bodyB.m_xf.R; + for(i = 0;i < cc.pointCount;++i) { + tVec = cc.points[i].localPoint; + clipPointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + clipPointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; + this.m_points[i].x = clipPointX; + this.m_points[i].y = clipPointY + } + break; + case b2Manifold.e_faceB: + tMat = cc.bodyB.m_xf.R; + tVec = cc.localPlaneNormal; + this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = cc.bodyB.m_xf.R; + tVec = cc.localPoint; + planePointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + planePointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = cc.bodyA.m_xf.R; + for(i = 0;i < cc.pointCount;++i) { + tVec = cc.points[i].localPoint; + clipPointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + clipPointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; + this.m_points[i].Set(clipPointX, clipPointY) + } + this.m_normal.x *= -1; + this.m_normal.y *= -1; + break + } +}; +b2PositionSolverManifold.prototype.m_normal = null; +b2PositionSolverManifold.prototype.m_points = null; +b2PositionSolverManifold.prototype.m_separations = null;var b2OBB = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2OBB.prototype.__constructor = function() { +}; +b2OBB.prototype.__varz = function() { + this.R = new b2Mat22; + this.center = new b2Vec2; + this.extents = new b2Vec2 +}; +b2OBB.prototype.R = new b2Mat22; +b2OBB.prototype.center = new b2Vec2; +b2OBB.prototype.extents = new b2Vec2;var b2Pair = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Pair.prototype.__constructor = function() { +}; +b2Pair.prototype.__varz = function() { +}; +b2Pair.b2_nullProxy = b2Settings.USHRT_MAX; +b2Pair.e_pairBuffered = 1; +b2Pair.e_pairRemoved = 2; +b2Pair.e_pairFinal = 4; +b2Pair.prototype.SetBuffered = function() { + this.status |= b2Pair.e_pairBuffered +}; +b2Pair.prototype.ClearBuffered = function() { + this.status &= ~b2Pair.e_pairBuffered +}; +b2Pair.prototype.IsBuffered = function() { + return(this.status & b2Pair.e_pairBuffered) == b2Pair.e_pairBuffered +}; +b2Pair.prototype.SetRemoved = function() { + this.status |= b2Pair.e_pairRemoved +}; +b2Pair.prototype.ClearRemoved = function() { + this.status &= ~b2Pair.e_pairRemoved +}; +b2Pair.prototype.IsRemoved = function() { + return(this.status & b2Pair.e_pairRemoved) == b2Pair.e_pairRemoved +}; +b2Pair.prototype.SetFinal = function() { + this.status |= b2Pair.e_pairFinal +}; +b2Pair.prototype.IsFinal = function() { + return(this.status & b2Pair.e_pairFinal) == b2Pair.e_pairFinal +}; +b2Pair.prototype.userData = null; +b2Pair.prototype.proxy1 = null; +b2Pair.prototype.proxy2 = null; +b2Pair.prototype.next = null; +b2Pair.prototype.status = 0;var b2FixtureDef = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2FixtureDef.prototype.__constructor = function() { + this.shape = null; + this.userData = null; + this.friction = 0.2; + this.restitution = 0; + this.density = 0; + this.filter.categoryBits = 1; + this.filter.maskBits = 65535; + this.filter.groupIndex = 0; + this.isSensor = false +}; +b2FixtureDef.prototype.__varz = function() { + this.filter = new b2FilterData +}; +b2FixtureDef.prototype.shape = null; +b2FixtureDef.prototype.userData = null; +b2FixtureDef.prototype.friction = null; +b2FixtureDef.prototype.restitution = null; +b2FixtureDef.prototype.density = null; +b2FixtureDef.prototype.isSensor = null; +b2FixtureDef.prototype.filter = new b2FilterData;var b2ContactID = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactID.prototype.__constructor = function() { + this.features._m_id = this +}; +b2ContactID.prototype.__varz = function() { + this.features = new Features +}; +b2ContactID.prototype.Set = function(id) { + key = id._key +}; +b2ContactID.prototype.Copy = function() { + var id = new b2ContactID; + id.key = key; + return id +}; +b2ContactID.prototype.__defineSetter__("key", function() { + return this._key +}); +b2ContactID.prototype.__defineSetter__("key", function(value) { + this._key = value; + this.features._referenceEdge = this._key & 255; + this.features._incidentEdge = (this._key & 65280) >> 8 & 255; + this.features._incidentVertex = (this._key & 16711680) >> 16 & 255; + this.features._flip = (this._key & 4278190080) >> 24 & 255 +}); +b2ContactID.prototype._key = 0; +b2ContactID.prototype.features = new Features;var b2Transform = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Transform.prototype.__constructor = function(pos, r) { + if(pos) { + this.position.SetV(pos); + this.R.SetM(r) + } +}; +b2Transform.prototype.__varz = function() { + this.position = new b2Vec2; + this.R = new b2Mat22 +}; +b2Transform.prototype.Initialize = function(pos, r) { + this.position.SetV(pos); + this.R.SetM(r) +}; +b2Transform.prototype.SetIdentity = function() { + this.position.SetZero(); + this.R.SetIdentity() +}; +b2Transform.prototype.Set = function(x) { + this.position.SetV(x.position); + this.R.SetM(x.R) +}; +b2Transform.prototype.GetAngle = function() { + return Math.atan2(this.R.col1.y, this.R.col1.x) +}; +b2Transform.prototype.position = new b2Vec2; +b2Transform.prototype.R = new b2Mat22;var b2EdgeShape = function() { + b2Shape.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2EdgeShape.prototype, b2Shape.prototype); +b2EdgeShape.prototype._super = b2Shape.prototype; +b2EdgeShape.prototype.__constructor = function(v1, v2) { + this._super.__constructor.apply(this, []); + this.m_type = b2Shape.e_edgeShape; + this.m_prevEdge = null; + this.m_nextEdge = null; + this.m_v1 = v1; + this.m_v2 = v2; + this.m_direction.Set(this.m_v2.x - this.m_v1.x, this.m_v2.y - this.m_v1.y); + this.m_length = this.m_direction.Normalize(); + this.m_normal.Set(this.m_direction.y, -this.m_direction.x); + this.m_coreV1.Set(-b2Settings.b2_toiSlop * (this.m_normal.x - this.m_direction.x) + this.m_v1.x, -b2Settings.b2_toiSlop * (this.m_normal.y - this.m_direction.y) + this.m_v1.y); + this.m_coreV2.Set(-b2Settings.b2_toiSlop * (this.m_normal.x + this.m_direction.x) + this.m_v2.x, -b2Settings.b2_toiSlop * (this.m_normal.y + this.m_direction.y) + this.m_v2.y); + this.m_cornerDir1 = this.m_normal; + this.m_cornerDir2.Set(-this.m_normal.x, -this.m_normal.y) +}; +b2EdgeShape.prototype.__varz = function() { + this.s_supportVec = new b2Vec2; + this.m_v1 = new b2Vec2; + this.m_v2 = new b2Vec2; + this.m_coreV1 = new b2Vec2; + this.m_coreV2 = new b2Vec2; + this.m_normal = new b2Vec2; + this.m_direction = new b2Vec2; + this.m_cornerDir1 = new b2Vec2; + this.m_cornerDir2 = new b2Vec2 +}; +b2EdgeShape.prototype.SetPrevEdge = function(edge, core, cornerDir, convex) { + this.m_prevEdge = edge; + this.m_coreV1 = core; + this.m_cornerDir1 = cornerDir; + this.m_cornerConvex1 = convex +}; +b2EdgeShape.prototype.SetNextEdge = function(edge, core, cornerDir, convex) { + this.m_nextEdge = edge; + this.m_coreV2 = core; + this.m_cornerDir2 = cornerDir; + this.m_cornerConvex2 = convex +}; +b2EdgeShape.prototype.TestPoint = function(transform, p) { + return false +}; +b2EdgeShape.prototype.RayCast = function(output, input, transform) { + var tMat; + var rX = input.p2.x - input.p1.x; + var rY = input.p2.y - input.p1.y; + tMat = transform.R; + var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); + var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); + var nX = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y) - v1Y; + var nY = -(transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y) - v1X); + var k_slop = 100 * Number.MIN_VALUE; + var denom = -(rX * nX + rY * nY); + if(denom > k_slop) { + var bX = input.p1.x - v1X; + var bY = input.p1.y - v1Y; + var a = bX * nX + bY * nY; + if(0 <= a && a <= input.maxFraction * denom) { + var mu2 = -rX * bY + rY * bX; + if(-k_slop * denom <= mu2 && mu2 <= denom * (1 + k_slop)) { + a /= denom; + output.fraction = a; + var nLen = Math.sqrt(nX * nX + nY * nY); + output.normal.x = nX / nLen; + output.normal.y = nY / nLen; + return true + } + } + } + return false +}; +b2EdgeShape.prototype.ComputeAABB = function(aabb, transform) { + var tMat = transform.R; + var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); + var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); + var v2X = transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y); + var v2Y = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y); + if(v1X < v2X) { + aabb.lowerBound.x = v1X; + aabb.upperBound.x = v2X + }else { + aabb.lowerBound.x = v2X; + aabb.upperBound.x = v1X + } + if(v1Y < v2Y) { + aabb.lowerBound.y = v1Y; + aabb.upperBound.y = v2Y + }else { + aabb.lowerBound.y = v2Y; + aabb.upperBound.y = v1Y + } +}; +b2EdgeShape.prototype.ComputeMass = function(massData, density) { + massData.mass = 0; + massData.center.SetV(this.m_v1); + massData.I = 0 +}; +b2EdgeShape.prototype.ComputeSubmergedArea = function(normal, offset, xf, c) { + var v0 = new b2Vec2(normal.x * offset, normal.y * offset); + var v1 = b2Math.MulX(xf, this.m_v1); + var v2 = b2Math.MulX(xf, this.m_v2); + var d1 = b2Math.Dot(normal, v1) - offset; + var d2 = b2Math.Dot(normal, v2) - offset; + if(d1 > 0) { + if(d2 > 0) { + return 0 + }else { + v1.x = -d2 / (d1 - d2) * v1.x + d1 / (d1 - d2) * v2.x; + v1.y = -d2 / (d1 - d2) * v1.y + d1 / (d1 - d2) * v2.y + } + }else { + if(d2 > 0) { + v2.x = -d2 / (d1 - d2) * v1.x + d1 / (d1 - d2) * v2.x; + v2.y = -d2 / (d1 - d2) * v1.y + d1 / (d1 - d2) * v2.y + }else { + } + } + c.x = (v0.x + v1.x + v2.x) / 3; + c.y = (v0.y + v1.y + v2.y) / 3; + return 0.5 * ((v1.x - v0.x) * (v2.y - v0.y) - (v1.y - v0.y) * (v2.x - v0.x)) +}; +b2EdgeShape.prototype.GetLength = function() { + return this.m_length +}; +b2EdgeShape.prototype.GetVertex1 = function() { + return this.m_v1 +}; +b2EdgeShape.prototype.GetVertex2 = function() { + return this.m_v2 +}; +b2EdgeShape.prototype.GetCoreVertex1 = function() { + return this.m_coreV1 +}; +b2EdgeShape.prototype.GetCoreVertex2 = function() { + return this.m_coreV2 +}; +b2EdgeShape.prototype.GetNormalVector = function() { + return this.m_normal +}; +b2EdgeShape.prototype.GetDirectionVector = function() { + return this.m_direction +}; +b2EdgeShape.prototype.GetCorner1Vector = function() { + return this.m_cornerDir1 +}; +b2EdgeShape.prototype.GetCorner2Vector = function() { + return this.m_cornerDir2 +}; +b2EdgeShape.prototype.Corner1IsConvex = function() { + return this.m_cornerConvex1 +}; +b2EdgeShape.prototype.Corner2IsConvex = function() { + return this.m_cornerConvex2 +}; +b2EdgeShape.prototype.GetFirstVertex = function(xf) { + var tMat = xf.R; + return new b2Vec2(xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y), xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y)) +}; +b2EdgeShape.prototype.GetNextEdge = function() { + return this.m_nextEdge +}; +b2EdgeShape.prototype.GetPrevEdge = function() { + return this.m_prevEdge +}; +b2EdgeShape.prototype.Support = function(xf, dX, dY) { + var tMat = xf.R; + var v1X = xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y); + var v1Y = xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y); + var v2X = xf.position.x + (tMat.col1.x * this.m_coreV2.x + tMat.col2.x * this.m_coreV2.y); + var v2Y = xf.position.y + (tMat.col1.y * this.m_coreV2.x + tMat.col2.y * this.m_coreV2.y); + if(v1X * dX + v1Y * dY > v2X * dX + v2Y * dY) { + this.s_supportVec.x = v1X; + this.s_supportVec.y = v1Y + }else { + this.s_supportVec.x = v2X; + this.s_supportVec.y = v2Y + } + return this.s_supportVec +}; +b2EdgeShape.prototype.s_supportVec = new b2Vec2; +b2EdgeShape.prototype.m_v1 = new b2Vec2; +b2EdgeShape.prototype.m_v2 = new b2Vec2; +b2EdgeShape.prototype.m_coreV1 = new b2Vec2; +b2EdgeShape.prototype.m_coreV2 = new b2Vec2; +b2EdgeShape.prototype.m_length = null; +b2EdgeShape.prototype.m_normal = new b2Vec2; +b2EdgeShape.prototype.m_direction = new b2Vec2; +b2EdgeShape.prototype.m_cornerDir1 = new b2Vec2; +b2EdgeShape.prototype.m_cornerDir2 = new b2Vec2; +b2EdgeShape.prototype.m_cornerConvex1 = null; +b2EdgeShape.prototype.m_cornerConvex2 = null; +b2EdgeShape.prototype.m_nextEdge = null; +b2EdgeShape.prototype.m_prevEdge = null;var b2BuoyancyController = function() { + b2Controller.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2BuoyancyController.prototype, b2Controller.prototype); +b2BuoyancyController.prototype._super = b2Controller.prototype; +b2BuoyancyController.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2BuoyancyController.prototype.__varz = function() { + this.normal = new b2Vec2(0, -1); + this.velocity = new b2Vec2(0, 0) +}; +b2BuoyancyController.prototype.Step = function(step) { + if(!m_bodyList) { + return + } + if(this.useWorldGravity) { + this.gravity = this.GetWorld().GetGravity().Copy() + } + for(var i = m_bodyList;i;i = i.nextBody) { + var body = i.body; + if(body.IsAwake() == false) { + continue + } + var areac = new b2Vec2; + var massc = new b2Vec2; + var area = 0; + var mass = 0; + for(var fixture = body.GetFixtureList();fixture;fixture = fixture.GetNext()) { + var sc = new b2Vec2; + var sarea = fixture.GetShape().ComputeSubmergedArea(this.normal, this.offset, body.GetTransform(), sc); + area += sarea; + areac.x += sarea * sc.x; + areac.y += sarea * sc.y; + var shapeDensity; + if(this.useDensity) { + shapeDensity = 1 + }else { + shapeDensity = 1 + } + mass += sarea * shapeDensity; + massc.x += sarea * sc.x * shapeDensity; + massc.y += sarea * sc.y * shapeDensity + } + areac.x /= area; + areac.y /= area; + massc.x /= mass; + massc.y /= mass; + if(area < Number.MIN_VALUE) { + continue + } + var buoyancyForce = this.gravity.GetNegative(); + buoyancyForce.Multiply(this.density * area); + body.ApplyForce(buoyancyForce, massc); + var dragForce = body.GetLinearVelocityFromWorldPoint(areac); + dragForce.Subtract(this.velocity); + dragForce.Multiply(-this.linearDrag * area); + body.ApplyForce(dragForce, areac); + body.ApplyTorque(-body.GetInertia() / body.GetMass() * area * body.GetAngularVelocity() * this.angularDrag) + } +}; +b2BuoyancyController.prototype.Draw = function(debugDraw) { + var r = 1E3; + var p1 = new b2Vec2; + var p2 = new b2Vec2; + p1.x = this.normal.x * this.offset + this.normal.y * r; + p1.y = this.normal.y * this.offset - this.normal.x * r; + p2.x = this.normal.x * this.offset - this.normal.y * r; + p2.y = this.normal.y * this.offset + this.normal.x * r; + var color = new b2Color(0, 0, 1); + debugDraw.DrawSegment(p1, p2, color) +}; +b2BuoyancyController.prototype.normal = new b2Vec2(0, -1); +b2BuoyancyController.prototype.offset = 0; +b2BuoyancyController.prototype.density = 0; +b2BuoyancyController.prototype.velocity = new b2Vec2(0, 0); +b2BuoyancyController.prototype.linearDrag = 2; +b2BuoyancyController.prototype.angularDrag = 1; +b2BuoyancyController.prototype.useDensity = false; +b2BuoyancyController.prototype.useWorldGravity = true; +b2BuoyancyController.prototype.gravity = null;var b2Body = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Body.prototype.__constructor = function(bd, world) { + this.m_flags = 0; + if(bd.bullet) { + this.m_flags |= b2Body.e_bulletFlag + } + if(bd.fixedRotation) { + this.m_flags |= b2Body.e_fixedRotationFlag + } + if(bd.allowSleep) { + this.m_flags |= b2Body.e_allowSleepFlag + } + if(bd.awake) { + this.m_flags |= b2Body.e_awakeFlag + } + if(bd.active) { + this.m_flags |= b2Body.e_activeFlag + } + this.m_world = world; + this.m_xf.position.SetV(bd.position); + this.m_xf.R.Set(bd.angle); + this.m_sweep.localCenter.SetZero(); + this.m_sweep.t0 = 1; + this.m_sweep.a0 = this.m_sweep.a = bd.angle; + var tMat = this.m_xf.R; + var tVec = this.m_sweep.localCenter; + this.m_sweep.c.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + this.m_sweep.c.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_sweep.c.x += this.m_xf.position.x; + this.m_sweep.c.y += this.m_xf.position.y; + this.m_sweep.c0.SetV(this.m_sweep.c); + this.m_jointList = null; + this.m_controllerList = null; + this.m_contactList = null; + this.m_controllerCount = 0; + this.m_prev = null; + this.m_next = null; + this.m_linearVelocity.SetV(bd.linearVelocity); + this.m_angularVelocity = bd.angularVelocity; + this.m_linearDamping = bd.linearDamping; + this.m_angularDamping = bd.angularDamping; + this.m_force.Set(0, 0); + this.m_torque = 0; + this.m_sleepTime = 0; + this.m_type = bd.type; + if(this.m_type == b2Body.b2_dynamicBody) { + this.m_mass = 1; + this.m_invMass = 1 + }else { + this.m_mass = 0; + this.m_invMass = 0 + } + this.m_I = 0; + this.m_invI = 0; + this.m_inertiaScale = bd.inertiaScale; + this.m_userData = bd.userData; + this.m_fixtureList = null; + this.m_fixtureCount = 0 +}; +b2Body.prototype.__varz = function() { + this.m_xf = new b2Transform; + this.m_sweep = new b2Sweep; + this.m_linearVelocity = new b2Vec2; + this.m_force = new b2Vec2 +}; +b2Body.b2_staticBody = 0; +b2Body.b2_kinematicBody = 1; +b2Body.b2_dynamicBody = 2; +b2Body.s_xf1 = new b2Transform; +b2Body.e_islandFlag = 1; +b2Body.e_awakeFlag = 2; +b2Body.e_allowSleepFlag = 4; +b2Body.e_bulletFlag = 8; +b2Body.e_fixedRotationFlag = 16; +b2Body.e_activeFlag = 32; +b2Body.prototype.connectEdges = function(s1, s2, angle1) { + var angle2 = Math.atan2(s2.GetDirectionVector().y, s2.GetDirectionVector().x); + var coreOffset = Math.tan((angle2 - angle1) * 0.5); + var core = b2Math.MulFV(coreOffset, s2.GetDirectionVector()); + core = b2Math.SubtractVV(core, s2.GetNormalVector()); + core = b2Math.MulFV(b2Settings.b2_toiSlop, core); + core = b2Math.AddVV(core, s2.GetVertex1()); + var cornerDir = b2Math.AddVV(s1.GetDirectionVector(), s2.GetDirectionVector()); + cornerDir.Normalize(); + var convex = b2Math.Dot(s1.GetDirectionVector(), s2.GetNormalVector()) > 0; + s1.SetNextEdge(s2, core, cornerDir, convex); + s2.SetPrevEdge(s1, core, cornerDir, convex); + return angle2 +}; +b2Body.prototype.SynchronizeFixtures = function() { + var xf1 = b2Body.s_xf1; + xf1.R.Set(this.m_sweep.a0); + var tMat = xf1.R; + var tVec = this.m_sweep.localCenter; + xf1.position.x = this.m_sweep.c0.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + xf1.position.y = this.m_sweep.c0.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var f; + var broadPhase = this.m_world.m_contactManager.m_broadPhase; + for(f = this.m_fixtureList;f;f = f.m_next) { + f.Synchronize(broadPhase, xf1, this.m_xf) + } +}; +b2Body.prototype.SynchronizeTransform = function() { + this.m_xf.R.Set(this.m_sweep.a); + var tMat = this.m_xf.R; + var tVec = this.m_sweep.localCenter; + this.m_xf.position.x = this.m_sweep.c.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + this.m_xf.position.y = this.m_sweep.c.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y) +}; +b2Body.prototype.ShouldCollide = function(other) { + if(this.m_type != b2Body.b2_dynamicBody && other.m_type != b2Body.b2_dynamicBody) { + return false + } + for(var jn = this.m_jointList;jn;jn = jn.next) { + if(jn.other == other) { + if(jn.joint.m_collideConnected == false) { + return false + } + } + } + return true +}; +b2Body.prototype.Advance = function(t) { + this.m_sweep.Advance(t); + this.m_sweep.c.SetV(this.m_sweep.c0); + this.m_sweep.a = this.m_sweep.a0; + this.SynchronizeTransform() +}; +b2Body.prototype.CreateFixture = function(def) { + if(this.m_world.IsLocked() == true) { + return null + } + var fixture = new b2Fixture; + fixture.Create(this, this.m_xf, def); + if(this.m_flags & b2Body.e_activeFlag) { + var broadPhase = this.m_world.m_contactManager.m_broadPhase; + fixture.CreateProxy(broadPhase, this.m_xf) + } + fixture.m_next = this.m_fixtureList; + this.m_fixtureList = fixture; + ++this.m_fixtureCount; + fixture.m_body = this; + if(fixture.m_density > 0) { + this.ResetMassData() + } + this.m_world.m_flags |= b2World.e_newFixture; + return fixture +}; +b2Body.prototype.CreateFixture2 = function(shape, density) { + var def = new b2FixtureDef; + def.shape = shape; + def.density = density; + return this.CreateFixture(def) +}; +b2Body.prototype.DestroyFixture = function(fixture) { + if(this.m_world.IsLocked() == true) { + return + } + var node = this.m_fixtureList; + var ppF = null; + var found = false; + while(node != null) { + if(node == fixture) { + if(ppF) { + ppF.m_next = fixture.m_next + }else { + this.m_fixtureList = fixture.m_next + } + found = true; + break + } + ppF = node; + node = node.m_next + } + var edge = this.m_contactList; + while(edge) { + var c = edge.contact; + edge = edge.next; + var fixtureA = c.GetFixtureA(); + var fixtureB = c.GetFixtureB(); + if(fixture == fixtureA || fixture == fixtureB) { + this.m_world.m_contactManager.Destroy(c) + } + } + if(this.m_flags & b2Body.e_activeFlag) { + var broadPhase = this.m_world.m_contactManager.m_broadPhase; + fixture.DestroyProxy(broadPhase) + }else { + } + fixture.Destroy(); + fixture.m_body = null; + fixture.m_next = null; + --this.m_fixtureCount; + this.ResetMassData() +}; +b2Body.prototype.SetPositionAndAngle = function(position, angle) { + var f; + if(this.m_world.IsLocked() == true) { + return + } + this.m_xf.R.Set(angle); + this.m_xf.position.SetV(position); + var tMat = this.m_xf.R; + var tVec = this.m_sweep.localCenter; + this.m_sweep.c.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + this.m_sweep.c.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + this.m_sweep.c.x += this.m_xf.position.x; + this.m_sweep.c.y += this.m_xf.position.y; + this.m_sweep.c0.SetV(this.m_sweep.c); + this.m_sweep.a0 = this.m_sweep.a = angle; + var broadPhase = this.m_world.m_contactManager.m_broadPhase; + for(f = this.m_fixtureList;f;f = f.m_next) { + f.Synchronize(broadPhase, this.m_xf, this.m_xf) + } + this.m_world.m_contactManager.FindNewContacts() +}; +b2Body.prototype.SetTransform = function(xf) { + this.SetPositionAndAngle(xf.position, xf.GetAngle()) +}; +b2Body.prototype.GetTransform = function() { + return this.m_xf +}; +b2Body.prototype.GetPosition = function() { + return this.m_xf.position +}; +b2Body.prototype.SetPosition = function(position) { + this.SetPositionAndAngle(position, this.GetAngle()) +}; +b2Body.prototype.GetAngle = function() { + return this.m_sweep.a +}; +b2Body.prototype.SetAngle = function(angle) { + this.SetPositionAndAngle(this.GetPosition(), angle) +}; +b2Body.prototype.GetWorldCenter = function() { + return this.m_sweep.c +}; +b2Body.prototype.GetLocalCenter = function() { + return this.m_sweep.localCenter +}; +b2Body.prototype.SetLinearVelocity = function(v) { + if(this.m_type == b2Body.b2_staticBody) { + return + } + this.m_linearVelocity.SetV(v) +}; +b2Body.prototype.GetLinearVelocity = function() { + return this.m_linearVelocity +}; +b2Body.prototype.SetAngularVelocity = function(omega) { + if(this.m_type == b2Body.b2_staticBody) { + return + } + this.m_angularVelocity = omega +}; +b2Body.prototype.GetAngularVelocity = function() { + return this.m_angularVelocity +}; +b2Body.prototype.GetDefinition = function() { + var bd = new b2BodyDef; + bd.type = this.GetType(); + bd.allowSleep = (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag; + bd.angle = this.GetAngle(); + bd.angularDamping = this.m_angularDamping; + bd.angularVelocity = this.m_angularVelocity; + bd.fixedRotation = (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag; + bd.bullet = (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag; + bd.awake = (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag; + bd.linearDamping = this.m_linearDamping; + bd.linearVelocity.SetV(this.GetLinearVelocity()); + bd.position = this.GetPosition(); + bd.userData = this.GetUserData(); + return bd +}; +b2Body.prototype.ApplyForce = function(force, point) { + if(this.m_type != b2Body.b2_dynamicBody) { + return + } + if(this.IsAwake() == false) { + this.SetAwake(true) + } + this.m_force.x += force.x; + this.m_force.y += force.y; + this.m_torque += (point.x - this.m_sweep.c.x) * force.y - (point.y - this.m_sweep.c.y) * force.x +}; +b2Body.prototype.ApplyTorque = function(torque) { + if(this.m_type != b2Body.b2_dynamicBody) { + return + } + if(this.IsAwake() == false) { + this.SetAwake(true) + } + this.m_torque += torque +}; +b2Body.prototype.ApplyImpulse = function(impulse, point) { + if(this.m_type != b2Body.b2_dynamicBody) { + return + } + if(this.IsAwake() == false) { + this.SetAwake(true) + } + this.m_linearVelocity.x += this.m_invMass * impulse.x; + this.m_linearVelocity.y += this.m_invMass * impulse.y; + this.m_angularVelocity += this.m_invI * ((point.x - this.m_sweep.c.x) * impulse.y - (point.y - this.m_sweep.c.y) * impulse.x) +}; +b2Body.prototype.Split = function(callback) { + var linearVelocity = this.GetLinearVelocity().Copy(); + var angularVelocity = this.GetAngularVelocity(); + var center = this.GetWorldCenter(); + var body1 = this; + var body2 = this.m_world.CreateBody(this.GetDefinition()); + var prev; + for(var f = body1.m_fixtureList;f;) { + if(callback(f)) { + var next = f.m_next; + if(prev) { + prev.m_next = next + }else { + body1.m_fixtureList = next + } + body1.m_fixtureCount--; + f.m_next = body2.m_fixtureList; + body2.m_fixtureList = f; + body2.m_fixtureCount++; + f.m_body = body2; + f = next + }else { + prev = f; + f = f.m_next + } + } + body1.ResetMassData(); + body2.ResetMassData(); + var center1 = body1.GetWorldCenter(); + var center2 = body2.GetWorldCenter(); + var velocity1 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center1, center))); + var velocity2 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center2, center))); + body1.SetLinearVelocity(velocity1); + body2.SetLinearVelocity(velocity2); + body1.SetAngularVelocity(angularVelocity); + body2.SetAngularVelocity(angularVelocity); + body1.SynchronizeFixtures(); + body2.SynchronizeFixtures(); + return body2 +}; +b2Body.prototype.Merge = function(other) { + var f; + for(f = other.m_fixtureList;f;) { + var next = f.m_next; + other.m_fixtureCount--; + f.m_next = this.m_fixtureList; + this.m_fixtureList = f; + this.m_fixtureCount++; + f.m_body = body2; + f = next + } + body1.m_fixtureCount = 0; + var body1 = this; + var body2 = other; + var center1 = body1.GetWorldCenter(); + var center2 = body2.GetWorldCenter(); + var velocity1 = body1.GetLinearVelocity().Copy(); + var velocity2 = body2.GetLinearVelocity().Copy(); + var angular1 = body1.GetAngularVelocity(); + var angular = body2.GetAngularVelocity(); + body1.ResetMassData(); + this.SynchronizeFixtures() +}; +b2Body.prototype.GetMass = function() { + return this.m_mass +}; +b2Body.prototype.GetInertia = function() { + return this.m_I +}; +b2Body.prototype.GetMassData = function(data) { + data.mass = this.m_mass; + data.I = this.m_I; + data.center.SetV(this.m_sweep.localCenter) +}; +b2Body.prototype.SetMassData = function(massData) { + b2Settings.b2Assert(this.m_world.IsLocked() == false); + if(this.m_world.IsLocked() == true) { + return + } + if(this.m_type != b2Body.b2_dynamicBody) { + return + } + this.m_invMass = 0; + this.m_I = 0; + this.m_invI = 0; + this.m_mass = massData.mass; + if(this.m_mass <= 0) { + this.m_mass = 1 + } + this.m_invMass = 1 / this.m_mass; + if(massData.I > 0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { + this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y); + this.m_invI = 1 / this.m_I + } + var oldCenter = this.m_sweep.c.Copy(); + this.m_sweep.localCenter.SetV(massData.center); + this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); + this.m_sweep.c.SetV(this.m_sweep.c0); + this.m_linearVelocity.x += this.m_angularVelocity * -(this.m_sweep.c.y - oldCenter.y); + this.m_linearVelocity.y += this.m_angularVelocity * +(this.m_sweep.c.x - oldCenter.x) +}; +b2Body.prototype.ResetMassData = function() { + this.m_mass = 0; + this.m_invMass = 0; + this.m_I = 0; + this.m_invI = 0; + this.m_sweep.localCenter.SetZero(); + if(this.m_type == b2Body.b2_staticBody || this.m_type == b2Body.b2_kinematicBody) { + return + } + var center = b2Vec2.Make(0, 0); + for(var f = this.m_fixtureList;f;f = f.m_next) { + if(f.m_density == 0) { + continue + } + var massData = f.GetMassData(); + this.m_mass += massData.mass; + center.x += massData.center.x * massData.mass; + center.y += massData.center.y * massData.mass; + this.m_I += massData.I + } + if(this.m_mass > 0) { + this.m_invMass = 1 / this.m_mass; + center.x *= this.m_invMass; + center.y *= this.m_invMass + }else { + this.m_mass = 1; + this.m_invMass = 1 + } + if(this.m_I > 0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { + this.m_I -= this.m_mass * (center.x * center.x + center.y * center.y); + this.m_I *= this.m_inertiaScale; + b2Settings.b2Assert(this.m_I > 0); + this.m_invI = 1 / this.m_I + }else { + this.m_I = 0; + this.m_invI = 0 + } + var oldCenter = this.m_sweep.c.Copy(); + this.m_sweep.localCenter.SetV(center); + this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); + this.m_sweep.c.SetV(this.m_sweep.c0); + this.m_linearVelocity.x += this.m_angularVelocity * -(this.m_sweep.c.y - oldCenter.y); + this.m_linearVelocity.y += this.m_angularVelocity * +(this.m_sweep.c.x - oldCenter.x) +}; +b2Body.prototype.GetWorldPoint = function(localPoint) { + var A = this.m_xf.R; + var u = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); + u.x += this.m_xf.position.x; + u.y += this.m_xf.position.y; + return u +}; +b2Body.prototype.GetWorldVector = function(localVector) { + return b2Math.MulMV(this.m_xf.R, localVector) +}; +b2Body.prototype.GetLocalPoint = function(worldPoint) { + return b2Math.MulXT(this.m_xf, worldPoint) +}; +b2Body.prototype.GetLocalVector = function(worldVector) { + return b2Math.MulTMV(this.m_xf.R, worldVector) +}; +b2Body.prototype.GetLinearVelocityFromWorldPoint = function(worldPoint) { + return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)) +}; +b2Body.prototype.GetLinearVelocityFromLocalPoint = function(localPoint) { + var A = this.m_xf.R; + var worldPoint = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); + worldPoint.x += this.m_xf.position.x; + worldPoint.y += this.m_xf.position.y; + return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)) +}; +b2Body.prototype.GetLinearDamping = function() { + return this.m_linearDamping +}; +b2Body.prototype.SetLinearDamping = function(linearDamping) { + this.m_linearDamping = linearDamping +}; +b2Body.prototype.GetAngularDamping = function() { + return this.m_angularDamping +}; +b2Body.prototype.SetAngularDamping = function(angularDamping) { + this.m_angularDamping = angularDamping +}; +b2Body.prototype.SetType = function(type) { + if(this.m_type == type) { + return + } + this.m_type = type; + this.ResetMassData(); + if(this.m_type == b2Body.b2_staticBody) { + this.m_linearVelocity.SetZero(); + this.m_angularVelocity = 0 + } + this.SetAwake(true); + this.m_force.SetZero(); + this.m_torque = 0; + for(var ce = this.m_contactList;ce;ce = ce.next) { + ce.contact.FlagForFiltering() + } +}; +b2Body.prototype.GetType = function() { + return this.m_type +}; +b2Body.prototype.SetBullet = function(flag) { + if(flag) { + this.m_flags |= b2Body.e_bulletFlag + }else { + this.m_flags &= ~b2Body.e_bulletFlag + } +}; +b2Body.prototype.IsBullet = function() { + return(this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag +}; +b2Body.prototype.SetSleepingAllowed = function(flag) { + if(flag) { + this.m_flags |= b2Body.e_allowSleepFlag + }else { + this.m_flags &= ~b2Body.e_allowSleepFlag; + this.SetAwake(true) + } +}; +b2Body.prototype.SetAwake = function(flag) { + if(flag) { + this.m_flags |= b2Body.e_awakeFlag; + this.m_sleepTime = 0 + }else { + this.m_flags &= ~b2Body.e_awakeFlag; + this.m_sleepTime = 0; + this.m_linearVelocity.SetZero(); + this.m_angularVelocity = 0; + this.m_force.SetZero(); + this.m_torque = 0 + } +}; +b2Body.prototype.IsAwake = function() { + return(this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag +}; +b2Body.prototype.SetFixedRotation = function(fixed) { + if(fixed) { + this.m_flags |= b2Body.e_fixedRotationFlag + }else { + this.m_flags &= ~b2Body.e_fixedRotationFlag + } + this.ResetMassData() +}; +b2Body.prototype.IsFixedRotation = function() { + return(this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag +}; +b2Body.prototype.SetActive = function(flag) { + if(flag == this.IsActive()) { + return + } + var broadPhase; + var f; + if(flag) { + this.m_flags |= b2Body.e_activeFlag; + broadPhase = this.m_world.m_contactManager.m_broadPhase; + for(f = this.m_fixtureList;f;f = f.m_next) { + f.CreateProxy(broadPhase, this.m_xf) + } + }else { + this.m_flags &= ~b2Body.e_activeFlag; + broadPhase = this.m_world.m_contactManager.m_broadPhase; + for(f = this.m_fixtureList;f;f = f.m_next) { + f.DestroyProxy(broadPhase) + } + var ce = this.m_contactList; + while(ce) { + var ce0 = ce; + ce = ce.next; + this.m_world.m_contactManager.Destroy(ce0.contact) + } + this.m_contactList = null + } +}; +b2Body.prototype.IsActive = function() { + return(this.m_flags & b2Body.e_activeFlag) == b2Body.e_activeFlag +}; +b2Body.prototype.IsSleepingAllowed = function() { + return(this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag +}; +b2Body.prototype.GetFixtureList = function() { + return this.m_fixtureList +}; +b2Body.prototype.GetJointList = function() { + return this.m_jointList +}; +b2Body.prototype.GetControllerList = function() { + return this.m_controllerList +}; +b2Body.prototype.GetContactList = function() { + return this.m_contactList +}; +b2Body.prototype.GetNext = function() { + return this.m_next +}; +b2Body.prototype.GetUserData = function() { + return this.m_userData +}; +b2Body.prototype.SetUserData = function(data) { + this.m_userData = data +}; +b2Body.prototype.GetWorld = function() { + return this.m_world +}; +b2Body.prototype.m_flags = 0; +b2Body.prototype.m_type = 0; +b2Body.prototype.m_islandIndex = 0; +b2Body.prototype.m_xf = new b2Transform; +b2Body.prototype.m_sweep = new b2Sweep; +b2Body.prototype.m_linearVelocity = new b2Vec2; +b2Body.prototype.m_angularVelocity = null; +b2Body.prototype.m_force = new b2Vec2; +b2Body.prototype.m_torque = null; +b2Body.prototype.m_world = null; +b2Body.prototype.m_prev = null; +b2Body.prototype.m_next = null; +b2Body.prototype.m_fixtureList = null; +b2Body.prototype.m_fixtureCount = 0; +b2Body.prototype.m_controllerList = null; +b2Body.prototype.m_controllerCount = 0; +b2Body.prototype.m_jointList = null; +b2Body.prototype.m_contactList = null; +b2Body.prototype.m_mass = null; +b2Body.prototype.m_invMass = null; +b2Body.prototype.m_I = null; +b2Body.prototype.m_invI = null; +b2Body.prototype.m_inertiaScale = null; +b2Body.prototype.m_linearDamping = null; +b2Body.prototype.m_angularDamping = null; +b2Body.prototype.m_sleepTime = null; +b2Body.prototype.m_userData = null;var b2ContactImpulse = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactImpulse.prototype.__constructor = function() { +}; +b2ContactImpulse.prototype.__varz = function() { + this.normalImpulses = new Array(b2Settings.b2_maxManifoldPoints); + this.tangentImpulses = new Array(b2Settings.b2_maxManifoldPoints) +}; +b2ContactImpulse.prototype.normalImpulses = new Array(b2Settings.b2_maxManifoldPoints); +b2ContactImpulse.prototype.tangentImpulses = new Array(b2Settings.b2_maxManifoldPoints);var b2TensorDampingController = function() { + b2Controller.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2TensorDampingController.prototype, b2Controller.prototype); +b2TensorDampingController.prototype._super = b2Controller.prototype; +b2TensorDampingController.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2TensorDampingController.prototype.__varz = function() { + this.T = new b2Mat22 +}; +b2TensorDampingController.prototype.SetAxisAligned = function(xDamping, yDamping) { + this.T.col1.x = -xDamping; + this.T.col1.y = 0; + this.T.col2.x = 0; + this.T.col2.y = -yDamping; + if(xDamping > 0 || yDamping > 0) { + this.maxTimestep = 1 / Math.max(xDamping, yDamping) + }else { + this.maxTimestep = 0 + } +}; +b2TensorDampingController.prototype.Step = function(step) { + var timestep = step.dt; + if(timestep <= Number.MIN_VALUE) { + return + } + if(timestep > this.maxTimestep && this.maxTimestep > 0) { + timestep = this.maxTimestep + } + for(var i = m_bodyList;i;i = i.nextBody) { + var body = i.body; + if(!body.IsAwake()) { + continue + } + var damping = body.GetWorldVector(b2Math.MulMV(this.T, body.GetLocalVector(body.GetLinearVelocity()))); + body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + damping.x * timestep, body.GetLinearVelocity().y + damping.y * timestep)) + } +}; +b2TensorDampingController.prototype.T = new b2Mat22; +b2TensorDampingController.prototype.maxTimestep = 0;var b2ManifoldPoint = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ManifoldPoint.prototype.__constructor = function() { + this.Reset() +}; +b2ManifoldPoint.prototype.__varz = function() { + this.m_localPoint = new b2Vec2; + this.m_id = new b2ContactID +}; +b2ManifoldPoint.prototype.Reset = function() { + this.m_localPoint.SetZero(); + this.m_normalImpulse = 0; + this.m_tangentImpulse = 0; + this.m_id.key = 0 +}; +b2ManifoldPoint.prototype.Set = function(m) { + this.m_localPoint.SetV(m.m_localPoint); + this.m_normalImpulse = m.m_normalImpulse; + this.m_tangentImpulse = m.m_tangentImpulse; + this.m_id.Set(m.m_id) +}; +b2ManifoldPoint.prototype.m_localPoint = new b2Vec2; +b2ManifoldPoint.prototype.m_normalImpulse = null; +b2ManifoldPoint.prototype.m_tangentImpulse = null; +b2ManifoldPoint.prototype.m_id = new b2ContactID;var b2PolygonShape = function() { + b2Shape.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2PolygonShape.prototype, b2Shape.prototype); +b2PolygonShape.prototype._super = b2Shape.prototype; +b2PolygonShape.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.m_type = b2Shape.e_polygonShape; + this.m_centroid = new b2Vec2; + this.m_vertices = new Array; + this.m_normals = new Array +}; +b2PolygonShape.prototype.__varz = function() { +}; +b2PolygonShape.AsArray = function(vertices, vertexCount) { + var polygonShape = new b2PolygonShape; + polygonShape.SetAsArray(vertices, vertexCount); + return polygonShape +}; +b2PolygonShape.AsVector = function(vertices, vertexCount) { + var polygonShape = new b2PolygonShape; + polygonShape.SetAsVector(vertices, vertexCount); + return polygonShape +}; +b2PolygonShape.AsBox = function(hx, hy) { + var polygonShape = new b2PolygonShape; + polygonShape.SetAsBox(hx, hy); + return polygonShape +}; +b2PolygonShape.AsOrientedBox = function(hx, hy, center, angle) { + var polygonShape = new b2PolygonShape; + polygonShape.SetAsOrientedBox(hx, hy, center, angle); + return polygonShape +}; +b2PolygonShape.AsEdge = function(v1, v2) { + var polygonShape = new b2PolygonShape; + polygonShape.SetAsEdge(v1, v2); + return polygonShape +}; +b2PolygonShape.ComputeCentroid = function(vs, count) { + var c = new b2Vec2; + var area = 0; + var p1X = 0; + var p1Y = 0; + var inv3 = 1 / 3; + for(var i = 0;i < count;++i) { + var p2 = vs[i]; + var p3 = i + 1 < count ? vs[parseInt(i + 1)] : vs[0]; + var e1X = p2.x - p1X; + var e1Y = p2.y - p1Y; + var e2X = p3.x - p1X; + var e2Y = p3.y - p1Y; + var D = e1X * e2Y - e1Y * e2X; + var triangleArea = 0.5 * D; + area += triangleArea; + c.x += triangleArea * inv3 * (p1X + p2.x + p3.x); + c.y += triangleArea * inv3 * (p1Y + p2.y + p3.y) + } + c.x *= 1 / area; + c.y *= 1 / area; + return c +}; +b2PolygonShape.ComputeOBB = function(obb, vs, count) { + var i = 0; + var p = new Array(count + 1); + for(i = 0;i < count;++i) { + p[i] = vs[i] + } + p[count] = p[0]; + var minArea = Number.MAX_VALUE; + for(i = 1;i <= count;++i) { + var root = p[parseInt(i - 1)]; + var uxX = p[i].x - root.x; + var uxY = p[i].y - root.y; + var length = Math.sqrt(uxX * uxX + uxY * uxY); + uxX /= length; + uxY /= length; + var uyX = -uxY; + var uyY = uxX; + var lowerX = Number.MAX_VALUE; + var lowerY = Number.MAX_VALUE; + var upperX = -Number.MAX_VALUE; + var upperY = -Number.MAX_VALUE; + for(var j = 0;j < count;++j) { + var dX = p[j].x - root.x; + var dY = p[j].y - root.y; + var rX = uxX * dX + uxY * dY; + var rY = uyX * dX + uyY * dY; + if(rX < lowerX) { + lowerX = rX + } + if(rY < lowerY) { + lowerY = rY + } + if(rX > upperX) { + upperX = rX + } + if(rY > upperY) { + upperY = rY + } + } + var area = (upperX - lowerX) * (upperY - lowerY); + if(area < 0.95 * minArea) { + minArea = area; + obb.R.col1.x = uxX; + obb.R.col1.y = uxY; + obb.R.col2.x = uyX; + obb.R.col2.y = uyY; + var centerX = 0.5 * (lowerX + upperX); + var centerY = 0.5 * (lowerY + upperY); + var tMat = obb.R; + obb.center.x = root.x + (tMat.col1.x * centerX + tMat.col2.x * centerY); + obb.center.y = root.y + (tMat.col1.y * centerX + tMat.col2.y * centerY); + obb.extents.x = 0.5 * (upperX - lowerX); + obb.extents.y = 0.5 * (upperY - lowerY) + } + } +}; +b2PolygonShape.s_mat = new b2Mat22; +b2PolygonShape.prototype.Validate = function() { + return false +}; +b2PolygonShape.prototype.Reserve = function(count) { + for(var i = this.m_vertices.length;i < count;i++) { + this.m_vertices[i] = new b2Vec2; + this.m_normals[i] = new b2Vec2 + } +}; +b2PolygonShape.prototype.Copy = function() { + var s = new b2PolygonShape; + s.Set(this); + return s +}; +b2PolygonShape.prototype.Set = function(other) { + this._super.Set.apply(this, [other]); + if(isInstanceOf(other, b2PolygonShape)) { + var other2 = other; + this.m_centroid.SetV(other2.m_centroid); + this.m_vertexCount = other2.m_vertexCount; + this.Reserve(this.m_vertexCount); + for(var i = 0;i < this.m_vertexCount;i++) { + this.m_vertices[i].SetV(other2.m_vertices[i]); + this.m_normals[i].SetV(other2.m_normals[i]) + } + } +}; +b2PolygonShape.prototype.SetAsArray = function(vertices, vertexCount) { + var v = new Array; + for(var i = 0, tVec = null;i < vertices.length, tVec = vertices[i];i++) { + v.push(tVec) + } + this.SetAsVector(v, vertexCount) +}; +b2PolygonShape.prototype.SetAsVector = function(vertices, vertexCount) { + if(typeof vertexCount == "undefined") { + vertexCount = vertices.length + } + b2Settings.b2Assert(2 <= vertexCount); + this.m_vertexCount = vertexCount; + this.Reserve(vertexCount); + var i = 0; + for(i = 0;i < this.m_vertexCount;i++) { + this.m_vertices[i].SetV(vertices[i]) + } + for(i = 0;i < this.m_vertexCount;++i) { + var i1 = i; + var i2 = i + 1 < this.m_vertexCount ? i + 1 : 0; + var edge = b2Math.SubtractVV(this.m_vertices[i2], this.m_vertices[i1]); + b2Settings.b2Assert(edge.LengthSquared() > Number.MIN_VALUE); + this.m_normals[i].SetV(b2Math.CrossVF(edge, 1)); + this.m_normals[i].Normalize() + } + this.m_centroid = b2PolygonShape.ComputeCentroid(this.m_vertices, this.m_vertexCount) +}; +b2PolygonShape.prototype.SetAsBox = function(hx, hy) { + this.m_vertexCount = 4; + this.Reserve(4); + this.m_vertices[0].Set(-hx, -hy); + this.m_vertices[1].Set(hx, -hy); + this.m_vertices[2].Set(hx, hy); + this.m_vertices[3].Set(-hx, hy); + this.m_normals[0].Set(0, -1); + this.m_normals[1].Set(1, 0); + this.m_normals[2].Set(0, 1); + this.m_normals[3].Set(-1, 0); + this.m_centroid.SetZero() +}; +b2PolygonShape.prototype.SetAsOrientedBox = function(hx, hy, center, angle) { + this.m_vertexCount = 4; + this.Reserve(4); + this.m_vertices[0].Set(-hx, -hy); + this.m_vertices[1].Set(hx, -hy); + this.m_vertices[2].Set(hx, hy); + this.m_vertices[3].Set(-hx, hy); + this.m_normals[0].Set(0, -1); + this.m_normals[1].Set(1, 0); + this.m_normals[2].Set(0, 1); + this.m_normals[3].Set(-1, 0); + this.m_centroid = center; + var xf = new b2Transform; + xf.position = center; + xf.R.Set(angle); + for(var i = 0;i < this.m_vertexCount;++i) { + this.m_vertices[i] = b2Math.MulX(xf, this.m_vertices[i]); + this.m_normals[i] = b2Math.MulMV(xf.R, this.m_normals[i]) + } +}; +b2PolygonShape.prototype.SetAsEdge = function(v1, v2) { + this.m_vertexCount = 2; + this.Reserve(2); + this.m_vertices[0].SetV(v1); + this.m_vertices[1].SetV(v2); + this.m_centroid.x = 0.5 * (v1.x + v2.x); + this.m_centroid.y = 0.5 * (v1.y + v2.y); + this.m_normals[0] = b2Math.CrossVF(b2Math.SubtractVV(v2, v1), 1); + this.m_normals[0].Normalize(); + this.m_normals[1].x = -this.m_normals[0].x; + this.m_normals[1].y = -this.m_normals[0].y +}; +b2PolygonShape.prototype.TestPoint = function(xf, p) { + var tVec; + var tMat = xf.R; + var tX = p.x - xf.position.x; + var tY = p.y - xf.position.y; + var pLocalX = tX * tMat.col1.x + tY * tMat.col1.y; + var pLocalY = tX * tMat.col2.x + tY * tMat.col2.y; + for(var i = 0;i < this.m_vertexCount;++i) { + tVec = this.m_vertices[i]; + tX = pLocalX - tVec.x; + tY = pLocalY - tVec.y; + tVec = this.m_normals[i]; + var dot = tVec.x * tX + tVec.y * tY; + if(dot > 0) { + return false + } + } + return true +}; +b2PolygonShape.prototype.RayCast = function(output, input, transform) { + var lower = 0; + var upper = input.maxFraction; + var tX; + var tY; + var tMat; + var tVec; + tX = input.p1.x - transform.position.x; + tY = input.p1.y - transform.position.y; + tMat = transform.R; + var p1X = tX * tMat.col1.x + tY * tMat.col1.y; + var p1Y = tX * tMat.col2.x + tY * tMat.col2.y; + tX = input.p2.x - transform.position.x; + tY = input.p2.y - transform.position.y; + tMat = transform.R; + var p2X = tX * tMat.col1.x + tY * tMat.col1.y; + var p2Y = tX * tMat.col2.x + tY * tMat.col2.y; + var dX = p2X - p1X; + var dY = p2Y - p1Y; + var index = -1; + for(var i = 0;i < this.m_vertexCount;++i) { + tVec = this.m_vertices[i]; + tX = tVec.x - p1X; + tY = tVec.y - p1Y; + tVec = this.m_normals[i]; + var numerator = tVec.x * tX + tVec.y * tY; + var denominator = tVec.x * dX + tVec.y * dY; + if(denominator == 0) { + if(numerator < 0) { + return false + } + }else { + if(denominator < 0 && numerator < lower * denominator) { + lower = numerator / denominator; + index = i + }else { + if(denominator > 0 && numerator < upper * denominator) { + upper = numerator / denominator + } + } + } + if(upper < lower - Number.MIN_VALUE) { + return false + } + } + if(index >= 0) { + output.fraction = lower; + tMat = transform.R; + tVec = this.m_normals[index]; + output.normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + output.normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + return true + } + return false +}; +b2PolygonShape.prototype.ComputeAABB = function(aabb, xf) { + var tMat = xf.R; + var tVec = this.m_vertices[0]; + var lowerX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var lowerY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var upperX = lowerX; + var upperY = lowerY; + for(var i = 1;i < this.m_vertexCount;++i) { + tVec = this.m_vertices[i]; + var vX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var vY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + lowerX = lowerX < vX ? lowerX : vX; + lowerY = lowerY < vY ? lowerY : vY; + upperX = upperX > vX ? upperX : vX; + upperY = upperY > vY ? upperY : vY + } + aabb.lowerBound.x = lowerX - this.m_radius; + aabb.lowerBound.y = lowerY - this.m_radius; + aabb.upperBound.x = upperX + this.m_radius; + aabb.upperBound.y = upperY + this.m_radius +}; +b2PolygonShape.prototype.ComputeMass = function(massData, density) { + if(this.m_vertexCount == 2) { + massData.center.x = 0.5 * (this.m_vertices[0].x + this.m_vertices[1].x); + massData.center.y = 0.5 * (this.m_vertices[0].y + this.m_vertices[1].y); + massData.mass = 0; + massData.I = 0; + return + } + var centerX = 0; + var centerY = 0; + var area = 0; + var I = 0; + var p1X = 0; + var p1Y = 0; + var k_inv3 = 1 / 3; + for(var i = 0;i < this.m_vertexCount;++i) { + var p2 = this.m_vertices[i]; + var p3 = i + 1 < this.m_vertexCount ? this.m_vertices[parseInt(i + 1)] : this.m_vertices[0]; + var e1X = p2.x - p1X; + var e1Y = p2.y - p1Y; + var e2X = p3.x - p1X; + var e2Y = p3.y - p1Y; + var D = e1X * e2Y - e1Y * e2X; + var triangleArea = 0.5 * D; + area += triangleArea; + centerX += triangleArea * k_inv3 * (p1X + p2.x + p3.x); + centerY += triangleArea * k_inv3 * (p1Y + p2.y + p3.y); + var px = p1X; + var py = p1Y; + var ex1 = e1X; + var ey1 = e1Y; + var ex2 = e2X; + var ey2 = e2Y; + var intx2 = k_inv3 * (0.25 * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5 * px * px; + var inty2 = k_inv3 * (0.25 * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5 * py * py; + I += D * (intx2 + inty2) + } + massData.mass = density * area; + centerX *= 1 / area; + centerY *= 1 / area; + massData.center.Set(centerX, centerY); + massData.I = density * I +}; +b2PolygonShape.prototype.ComputeSubmergedArea = function(normal, offset, xf, c) { + var normalL = b2Math.MulTMV(xf.R, normal); + var offsetL = offset - b2Math.Dot(normal, xf.position); + var depths = new Array; + var diveCount = 0; + var intoIndex = -1; + var outoIndex = -1; + var lastSubmerged = false; + var i = 0; + for(i = 0;i < this.m_vertexCount;++i) { + depths[i] = b2Math.Dot(normalL, this.m_vertices[i]) - offsetL; + var isSubmerged = depths[i] < -Number.MIN_VALUE; + if(i > 0) { + if(isSubmerged) { + if(!lastSubmerged) { + intoIndex = i - 1; + diveCount++ + } + }else { + if(lastSubmerged) { + outoIndex = i - 1; + diveCount++ + } + } + } + lastSubmerged = isSubmerged + } + switch(diveCount) { + case 0: + if(lastSubmerged) { + var md = new b2MassData; + this.ComputeMass(md, 1); + c.SetV(b2Math.MulX(xf, md.center)); + return md.mass + }else { + return 0 + } + break; + case 1: + if(intoIndex == -1) { + intoIndex = this.m_vertexCount - 1 + }else { + outoIndex = this.m_vertexCount - 1 + } + break + } + var intoIndex2 = (intoIndex + 1) % this.m_vertexCount; + var outoIndex2 = (outoIndex + 1) % this.m_vertexCount; + var intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]); + var outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]); + var intoVec = new b2Vec2(this.m_vertices[intoIndex].x * (1 - intoLamdda) + this.m_vertices[intoIndex2].x * intoLamdda, this.m_vertices[intoIndex].y * (1 - intoLamdda) + this.m_vertices[intoIndex2].y * intoLamdda); + var outoVec = new b2Vec2(this.m_vertices[outoIndex].x * (1 - outoLamdda) + this.m_vertices[outoIndex2].x * outoLamdda, this.m_vertices[outoIndex].y * (1 - outoLamdda) + this.m_vertices[outoIndex2].y * outoLamdda); + var area = 0; + var center = new b2Vec2; + var p2 = this.m_vertices[intoIndex2]; + var p3; + i = intoIndex2; + while(i != outoIndex2) { + i = (i + 1) % this.m_vertexCount; + if(i == outoIndex2) { + p3 = outoVec + }else { + p3 = this.m_vertices[i] + } + var triangleArea = 0.5 * ((p2.x - intoVec.x) * (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x)); + area += triangleArea; + center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3; + center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3; + p2 = p3 + } + center.Multiply(1 / area); + c.SetV(b2Math.MulX(xf, center)); + return area +}; +b2PolygonShape.prototype.GetVertexCount = function() { + return this.m_vertexCount +}; +b2PolygonShape.prototype.GetVertices = function() { + return this.m_vertices +}; +b2PolygonShape.prototype.GetNormals = function() { + return this.m_normals +}; +b2PolygonShape.prototype.GetSupport = function(d) { + var bestIndex = 0; + var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; + for(var i = 1;i < this.m_vertexCount;++i) { + var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; + if(value > bestValue) { + bestIndex = i; + bestValue = value + } + } + return bestIndex +}; +b2PolygonShape.prototype.GetSupportVertex = function(d) { + var bestIndex = 0; + var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; + for(var i = 1;i < this.m_vertexCount;++i) { + var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; + if(value > bestValue) { + bestIndex = i; + bestValue = value + } + } + return this.m_vertices[bestIndex] +}; +b2PolygonShape.prototype.m_centroid = null; +b2PolygonShape.prototype.m_vertices = null; +b2PolygonShape.prototype.m_normals = null; +b2PolygonShape.prototype.m_vertexCount = 0;var b2Fixture = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Fixture.prototype.__constructor = function() { + this.m_aabb = new b2AABB; + this.m_userData = null; + this.m_body = null; + this.m_next = null; + this.m_shape = null; + this.m_density = 0; + this.m_friction = 0; + this.m_restitution = 0 +}; +b2Fixture.prototype.__varz = function() { + this.m_filter = new b2FilterData +}; +b2Fixture.prototype.Create = function(body, xf, def) { + this.m_userData = def.userData; + this.m_friction = def.friction; + this.m_restitution = def.restitution; + this.m_body = body; + this.m_next = null; + this.m_filter = def.filter.Copy(); + this.m_isSensor = def.isSensor; + this.m_shape = def.shape.Copy(); + this.m_density = def.density +}; +b2Fixture.prototype.Destroy = function() { + this.m_shape = null +}; +b2Fixture.prototype.CreateProxy = function(broadPhase, xf) { + this.m_shape.ComputeAABB(this.m_aabb, xf); + this.m_proxy = broadPhase.CreateProxy(this.m_aabb, this) +}; +b2Fixture.prototype.DestroyProxy = function(broadPhase) { + if(this.m_proxy == null) { + return + } + broadPhase.DestroyProxy(this.m_proxy); + this.m_proxy = null +}; +b2Fixture.prototype.Synchronize = function(broadPhase, transform1, transform2) { + if(!this.m_proxy) { + return + } + var aabb1 = new b2AABB; + var aabb2 = new b2AABB; + this.m_shape.ComputeAABB(aabb1, transform1); + this.m_shape.ComputeAABB(aabb2, transform2); + this.m_aabb.Combine(aabb1, aabb2); + var displacement = b2Math.SubtractVV(transform2.position, transform1.position); + broadPhase.MoveProxy(this.m_proxy, this.m_aabb, displacement) +}; +b2Fixture.prototype.GetType = function() { + return this.m_shape.GetType() +}; +b2Fixture.prototype.GetShape = function() { + return this.m_shape +}; +b2Fixture.prototype.SetSensor = function(sensor) { + if(this.m_isSensor == sensor) { + return + } + this.m_isSensor = sensor; + if(this.m_body == null) { + return + } + var edge = this.m_body.GetContactList(); + while(edge) { + var contact = edge.contact; + var fixtureA = contact.GetFixtureA(); + var fixtureB = contact.GetFixtureB(); + if(fixtureA == this || fixtureB == this) { + contact.SetSensor(fixtureA.IsSensor() || fixtureB.IsSensor()) + } + edge = edge.next + } +}; +b2Fixture.prototype.IsSensor = function() { + return this.m_isSensor +}; +b2Fixture.prototype.SetFilterData = function(filter) { + this.m_filter = filter.Copy(); + if(this.m_body) { + return + } + var edge = this.m_body.GetContactList(); + while(edge) { + var contact = edge.contact; + var fixtureA = contact.GetFixtureA(); + var fixtureB = contact.GetFixtureB(); + if(fixtureA == this || fixtureB == this) { + contact.FlagForFiltering() + } + edge = edge.next + } +}; +b2Fixture.prototype.GetFilterData = function() { + return this.m_filter.Copy() +}; +b2Fixture.prototype.GetBody = function() { + return this.m_body +}; +b2Fixture.prototype.GetNext = function() { + return this.m_next +}; +b2Fixture.prototype.GetUserData = function() { + return this.m_userData +}; +b2Fixture.prototype.SetUserData = function(data) { + this.m_userData = data +}; +b2Fixture.prototype.TestPoint = function(p) { + return this.m_shape.TestPoint(this.m_body.GetTransform(), p) +}; +b2Fixture.prototype.RayCast = function(output, input) { + return this.m_shape.RayCast(output, input, this.m_body.GetTransform()) +}; +b2Fixture.prototype.GetMassData = function(massData) { + if(massData == null) { + massData = new b2MassData + } + this.m_shape.ComputeMass(massData, this.m_density); + return massData +}; +b2Fixture.prototype.SetDensity = function(density) { + this.m_density = density +}; +b2Fixture.prototype.GetDensity = function() { + return this.m_density +}; +b2Fixture.prototype.GetFriction = function() { + return this.m_friction +}; +b2Fixture.prototype.SetFriction = function(friction) { + this.m_friction = friction +}; +b2Fixture.prototype.GetRestitution = function() { + return this.m_restitution +}; +b2Fixture.prototype.SetRestitution = function(restitution) { + this.m_restitution = restitution +}; +b2Fixture.prototype.GetAABB = function() { + return this.m_aabb +}; +b2Fixture.prototype.m_massData = null; +b2Fixture.prototype.m_aabb = null; +b2Fixture.prototype.m_density = null; +b2Fixture.prototype.m_next = null; +b2Fixture.prototype.m_body = null; +b2Fixture.prototype.m_shape = null; +b2Fixture.prototype.m_friction = null; +b2Fixture.prototype.m_restitution = null; +b2Fixture.prototype.m_proxy = null; +b2Fixture.prototype.m_filter = new b2FilterData; +b2Fixture.prototype.m_isSensor = null; +b2Fixture.prototype.m_userData = null;var b2DynamicTreeNode = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2DynamicTreeNode.prototype.__constructor = function() { +}; +b2DynamicTreeNode.prototype.__varz = function() { + this.aabb = new b2AABB +}; +b2DynamicTreeNode.prototype.IsLeaf = function() { + return this.child1 == null +}; +b2DynamicTreeNode.prototype.userData = null; +b2DynamicTreeNode.prototype.aabb = new b2AABB; +b2DynamicTreeNode.prototype.parent = null; +b2DynamicTreeNode.prototype.child1 = null; +b2DynamicTreeNode.prototype.child2 = null;var b2BodyDef = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2BodyDef.prototype.__constructor = function() { + this.userData = null; + this.position.Set(0, 0); + this.angle = 0; + this.linearVelocity.Set(0, 0); + this.angularVelocity = 0; + this.linearDamping = 0; + this.angularDamping = 0; + this.allowSleep = true; + this.awake = true; + this.fixedRotation = false; + this.bullet = false; + this.type = b2Body.b2_staticBody; + this.active = true; + this.inertiaScale = 1 +}; +b2BodyDef.prototype.__varz = function() { + this.position = new b2Vec2; + this.linearVelocity = new b2Vec2 +}; +b2BodyDef.prototype.type = 0; +b2BodyDef.prototype.position = new b2Vec2; +b2BodyDef.prototype.angle = null; +b2BodyDef.prototype.linearVelocity = new b2Vec2; +b2BodyDef.prototype.angularVelocity = null; +b2BodyDef.prototype.linearDamping = null; +b2BodyDef.prototype.angularDamping = null; +b2BodyDef.prototype.allowSleep = null; +b2BodyDef.prototype.awake = null; +b2BodyDef.prototype.fixedRotation = null; +b2BodyDef.prototype.bullet = null; +b2BodyDef.prototype.active = null; +b2BodyDef.prototype.userData = null; +b2BodyDef.prototype.inertiaScale = null;var b2DynamicTreeBroadPhase = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2DynamicTreeBroadPhase.prototype.__constructor = function() { +}; +b2DynamicTreeBroadPhase.prototype.__varz = function() { + this.m_tree = new b2DynamicTree; + this.m_moveBuffer = new Array; + this.m_pairBuffer = new Array +}; +b2DynamicTreeBroadPhase.prototype.BufferMove = function(proxy) { + this.m_moveBuffer[this.m_moveBuffer.length] = proxy +}; +b2DynamicTreeBroadPhase.prototype.UnBufferMove = function(proxy) { + var i = this.m_moveBuffer.indexOf(proxy); + this.m_moveBuffer.splice(i, 1) +}; +b2DynamicTreeBroadPhase.prototype.ComparePairs = function(pair1, pair2) { + return 0 +}; +b2DynamicTreeBroadPhase.prototype.CreateProxy = function(aabb, userData) { + var proxy = this.m_tree.CreateProxy(aabb, userData); + ++this.m_proxyCount; + this.BufferMove(proxy); + return proxy +}; +b2DynamicTreeBroadPhase.prototype.DestroyProxy = function(proxy) { + this.UnBufferMove(proxy); + --this.m_proxyCount; + this.m_tree.DestroyProxy(proxy) +}; +b2DynamicTreeBroadPhase.prototype.MoveProxy = function(proxy, aabb, displacement) { + var buffer = this.m_tree.MoveProxy(proxy, aabb, displacement); + if(buffer) { + this.BufferMove(proxy) + } +}; +b2DynamicTreeBroadPhase.prototype.TestOverlap = function(proxyA, proxyB) { + var aabbA = this.m_tree.GetFatAABB(proxyA); + var aabbB = this.m_tree.GetFatAABB(proxyB); + return aabbA.TestOverlap(aabbB) +}; +b2DynamicTreeBroadPhase.prototype.GetUserData = function(proxy) { + return this.m_tree.GetUserData(proxy) +}; +b2DynamicTreeBroadPhase.prototype.GetFatAABB = function(proxy) { + return this.m_tree.GetFatAABB(proxy) +}; +b2DynamicTreeBroadPhase.prototype.GetProxyCount = function() { + return this.m_proxyCount +}; +b2DynamicTreeBroadPhase.prototype.UpdatePairs = function(callback) { + this.m_pairCount = 0; + for(var i = 0, queryProxy = null;i < this.m_moveBuffer.length, queryProxy = this.m_moveBuffer[i];i++) { + var that = this; + function QueryCallback(proxy) { + if(proxy == queryProxy) { + return true + } + if(that.m_pairCount == that.m_pairBuffer.length) { + that.m_pairBuffer[that.m_pairCount] = new b2DynamicTreePair + } + var pair = that.m_pairBuffer[that.m_pairCount]; + pair.proxyA = proxy < queryProxy ? proxy : queryProxy; + pair.proxyB = proxy >= queryProxy ? proxy : queryProxy; + ++that.m_pairCount; + return true + } + var fatAABB = this.m_tree.GetFatAABB(queryProxy); + this.m_tree.Query(QueryCallback, fatAABB) + } + this.m_moveBuffer.length = 0; + for(var i = 0;i < this.m_pairCount;) { + var primaryPair = this.m_pairBuffer[i]; + var userDataA = this.m_tree.GetUserData(primaryPair.proxyA); + var userDataB = this.m_tree.GetUserData(primaryPair.proxyB); + callback(userDataA, userDataB); + ++i; + while(i < this.m_pairCount) { + var pair = this.m_pairBuffer[i]; + if(pair.proxyA != primaryPair.proxyA || pair.proxyB != primaryPair.proxyB) { + break + } + ++i + } + } +}; +b2DynamicTreeBroadPhase.prototype.Query = function(callback, aabb) { + this.m_tree.Query(callback, aabb) +}; +b2DynamicTreeBroadPhase.prototype.RayCast = function(callback, input) { + this.m_tree.RayCast(callback, input) +}; +b2DynamicTreeBroadPhase.prototype.Validate = function() { +}; +b2DynamicTreeBroadPhase.prototype.Rebalance = function(iterations) { + this.m_tree.Rebalance(iterations) +}; +b2DynamicTreeBroadPhase.prototype.m_tree = new b2DynamicTree; +b2DynamicTreeBroadPhase.prototype.m_proxyCount = 0; +b2DynamicTreeBroadPhase.prototype.m_moveBuffer = new Array; +b2DynamicTreeBroadPhase.prototype.m_pairBuffer = new Array; +b2DynamicTreeBroadPhase.prototype.m_pairCount = 0;var b2BroadPhase = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2BroadPhase.prototype.__constructor = function(worldAABB) { + var i = 0; + this.m_pairManager.Initialize(this); + this.m_worldAABB = worldAABB; + this.m_proxyCount = 0; + this.m_bounds = new Array; + for(i = 0;i < 2;i++) { + this.m_bounds[i] = new Array + } + var dX = worldAABB.upperBound.x - worldAABB.lowerBound.x; + var dY = worldAABB.upperBound.y - worldAABB.lowerBound.y; + this.m_quantizationFactor.x = b2Settings.USHRT_MAX / dX; + this.m_quantizationFactor.y = b2Settings.USHRT_MAX / dY; + this.m_timeStamp = 1; + this.m_queryResultCount = 0 +}; +b2BroadPhase.prototype.__varz = function() { + this.m_pairManager = new b2PairManager; + this.m_proxyPool = new Array; + this.m_querySortKeys = new Array; + this.m_queryResults = new Array; + this.m_quantizationFactor = new b2Vec2 +}; +b2BroadPhase.BinarySearch = function(bounds, count, value) { + var low = 0; + var high = count - 1; + while(low <= high) { + var mid = Math.round((low + high) / 2); + var bound = bounds[mid]; + if(bound.value > value) { + high = mid - 1 + }else { + if(bound.value < value) { + low = mid + 1 + }else { + return parseInt(mid) + } + } + } + return parseInt(low) +}; +b2BroadPhase.s_validate = false; +b2BroadPhase.b2_invalid = b2Settings.USHRT_MAX; +b2BroadPhase.b2_nullEdge = b2Settings.USHRT_MAX; +b2BroadPhase.prototype.ComputeBounds = function(lowerValues, upperValues, aabb) { + var minVertexX = aabb.lowerBound.x; + var minVertexY = aabb.lowerBound.y; + minVertexX = b2Math.Min(minVertexX, this.m_worldAABB.upperBound.x); + minVertexY = b2Math.Min(minVertexY, this.m_worldAABB.upperBound.y); + minVertexX = b2Math.Max(minVertexX, this.m_worldAABB.lowerBound.x); + minVertexY = b2Math.Max(minVertexY, this.m_worldAABB.lowerBound.y); + var maxVertexX = aabb.upperBound.x; + var maxVertexY = aabb.upperBound.y; + maxVertexX = b2Math.Min(maxVertexX, this.m_worldAABB.upperBound.x); + maxVertexY = b2Math.Min(maxVertexY, this.m_worldAABB.upperBound.y); + maxVertexX = b2Math.Max(maxVertexX, this.m_worldAABB.lowerBound.x); + maxVertexY = b2Math.Max(maxVertexY, this.m_worldAABB.lowerBound.y); + lowerValues[0] = parseInt(this.m_quantizationFactor.x * (minVertexX - this.m_worldAABB.lowerBound.x)) & b2Settings.USHRT_MAX - 1; + upperValues[0] = parseInt(this.m_quantizationFactor.x * (maxVertexX - this.m_worldAABB.lowerBound.x)) % 65535 | 1; + lowerValues[1] = parseInt(this.m_quantizationFactor.y * (minVertexY - this.m_worldAABB.lowerBound.y)) & b2Settings.USHRT_MAX - 1; + upperValues[1] = parseInt(this.m_quantizationFactor.y * (maxVertexY - this.m_worldAABB.lowerBound.y)) % 65535 | 1 +}; +b2BroadPhase.prototype.TestOverlapValidate = function(p1, p2) { + for(var axis = 0;axis < 2;++axis) { + var bounds = this.m_bounds[axis]; + var bound1 = bounds[p1.lowerBounds[axis]]; + var bound2 = bounds[p2.upperBounds[axis]]; + if(bound1.value > bound2.value) { + return false + } + bound1 = bounds[p1.upperBounds[axis]]; + bound2 = bounds[p2.lowerBounds[axis]]; + if(bound1.value < bound2.value) { + return false + } + } + return true +}; +b2BroadPhase.prototype.QueryAxis = function(lowerQueryOut, upperQueryOut, lowerValue, upperValue, bounds, boundCount, axis) { + var lowerQuery = b2BroadPhase.BinarySearch(bounds, boundCount, lowerValue); + var upperQuery = b2BroadPhase.BinarySearch(bounds, boundCount, upperValue); + var bound; + for(var j = lowerQuery;j < upperQuery;++j) { + bound = bounds[j]; + if(bound.IsLower()) { + this.IncrementOverlapCount(bound.proxy) + } + } + if(lowerQuery > 0) { + var i = lowerQuery - 1; + bound = bounds[i]; + var s = bound.stabbingCount; + while(s) { + bound = bounds[i]; + if(bound.IsLower()) { + var proxy = bound.proxy; + if(lowerQuery <= proxy.upperBounds[axis]) { + this.IncrementOverlapCount(bound.proxy); + --s + } + } + --i + } + } + lowerQueryOut[0] = lowerQuery; + upperQueryOut[0] = upperQuery +}; +b2BroadPhase.prototype.IncrementOverlapCount = function(proxy) { + if(proxy.timeStamp < this.m_timeStamp) { + proxy.timeStamp = this.m_timeStamp; + proxy.overlapCount = 1 + }else { + proxy.overlapCount = 2; + this.m_queryResults[this.m_queryResultCount] = proxy; + ++this.m_queryResultCount + } +}; +b2BroadPhase.prototype.IncrementTimeStamp = function() { + if(this.m_timeStamp == b2Settings.USHRT_MAX) { + for(var i = 0;i < this.m_proxyPool.length;++i) { + this.m_proxyPool[i].timeStamp = 0 + } + this.m_timeStamp = 1 + }else { + ++this.m_timeStamp + } +}; +b2BroadPhase.prototype.InRange = function(aabb) { + var dX; + var dY; + var d2X; + var d2Y; + dX = aabb.lowerBound.x; + dY = aabb.lowerBound.y; + dX -= this.m_worldAABB.upperBound.x; + dY -= this.m_worldAABB.upperBound.y; + d2X = this.m_worldAABB.lowerBound.x; + d2Y = this.m_worldAABB.lowerBound.y; + d2X -= aabb.upperBound.x; + d2Y -= aabb.upperBound.y; + dX = b2Math.Max(dX, d2X); + dY = b2Math.Max(dY, d2Y); + return b2Math.Max(dX, dY) < 0 +}; +b2BroadPhase.prototype.CreateProxy = function(aabb, userData) { + var index = 0; + var proxy; + var i = 0; + var j = 0; + if(!this.m_freeProxy) { + this.m_freeProxy = this.m_proxyPool[this.m_proxyCount] = new b2Proxy; + this.m_freeProxy.next = null; + this.m_freeProxy.timeStamp = 0; + this.m_freeProxy.overlapCount = b2BroadPhase.b2_invalid; + this.m_freeProxy.userData = null; + for(i = 0;i < 2;i++) { + j = this.m_proxyCount * 2; + this.m_bounds[i][j++] = new b2Bound; + this.m_bounds[i][j] = new b2Bound + } + } + proxy = this.m_freeProxy; + this.m_freeProxy = proxy.next; + proxy.overlapCount = 0; + proxy.userData = userData; + var boundCount = 2 * this.m_proxyCount; + var lowerValues = new Array; + var upperValues = new Array; + this.ComputeBounds(lowerValues, upperValues, aabb); + for(var axis = 0;axis < 2;++axis) { + var bounds = this.m_bounds[axis]; + var lowerIndex = 0; + var upperIndex = 0; + var lowerIndexOut = new Array; + lowerIndexOut.push(lowerIndex); + var upperIndexOut = new Array; + upperIndexOut.push(upperIndex); + this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[axis], upperValues[axis], bounds, boundCount, axis); + lowerIndex = lowerIndexOut[0]; + upperIndex = upperIndexOut[0]; + bounds.splice(upperIndex, 0, bounds[bounds.length - 1]); + bounds.length--; + bounds.splice(lowerIndex, 0, bounds[bounds.length - 1]); + bounds.length--; + ++upperIndex; + var tBound1 = bounds[lowerIndex]; + var tBound2 = bounds[upperIndex]; + tBound1.value = lowerValues[axis]; + tBound1.proxy = proxy; + tBound2.value = upperValues[axis]; + tBound2.proxy = proxy; + var tBoundAS3 = bounds[parseInt(lowerIndex - 1)]; + tBound1.stabbingCount = lowerIndex == 0 ? 0 : tBoundAS3.stabbingCount; + tBoundAS3 = bounds[parseInt(upperIndex - 1)]; + tBound2.stabbingCount = tBoundAS3.stabbingCount; + for(index = lowerIndex;index < upperIndex;++index) { + tBoundAS3 = bounds[index]; + tBoundAS3.stabbingCount++ + } + for(index = lowerIndex;index < boundCount + 2;++index) { + tBound1 = bounds[index]; + var proxy2 = tBound1.proxy; + if(tBound1.IsLower()) { + proxy2.lowerBounds[axis] = index + }else { + proxy2.upperBounds[axis] = index + } + } + } + ++this.m_proxyCount; + for(i = 0;i < this.m_queryResultCount;++i) { + this.m_pairManager.AddBufferedPair(proxy, this.m_queryResults[i]) + } + this.m_queryResultCount = 0; + this.IncrementTimeStamp(); + return proxy +}; +b2BroadPhase.prototype.DestroyProxy = function(proxy_) { + var proxy = proxy_; + var tBound1; + var tBound2; + var boundCount = 2 * this.m_proxyCount; + for(var axis = 0;axis < 2;++axis) { + var bounds = this.m_bounds[axis]; + var lowerIndex = proxy.lowerBounds[axis]; + var upperIndex = proxy.upperBounds[axis]; + tBound1 = bounds[lowerIndex]; + var lowerValue = tBound1.value; + tBound2 = bounds[upperIndex]; + var upperValue = tBound2.value; + bounds.splice(upperIndex, 1); + bounds.splice(lowerIndex, 1); + bounds.push(tBound1); + bounds.push(tBound2); + var tEnd = boundCount - 2; + for(var index = lowerIndex;index < tEnd;++index) { + tBound1 = bounds[index]; + var proxy2 = tBound1.proxy; + if(tBound1.IsLower()) { + proxy2.lowerBounds[axis] = index + }else { + proxy2.upperBounds[axis] = index + } + } + tEnd = upperIndex - 1; + for(var index2 = lowerIndex;index2 < tEnd;++index2) { + tBound1 = bounds[index2]; + tBound1.stabbingCount-- + } + var ignore = new Array; + this.QueryAxis(ignore, ignore, lowerValue, upperValue, bounds, boundCount - 2, axis) + } + for(var i = 0;i < this.m_queryResultCount;++i) { + this.m_pairManager.RemoveBufferedPair(proxy, this.m_queryResults[i]) + } + this.m_queryResultCount = 0; + this.IncrementTimeStamp(); + proxy.userData = null; + proxy.overlapCount = b2BroadPhase.b2_invalid; + proxy.lowerBounds[0] = b2BroadPhase.b2_invalid; + proxy.lowerBounds[1] = b2BroadPhase.b2_invalid; + proxy.upperBounds[0] = b2BroadPhase.b2_invalid; + proxy.upperBounds[1] = b2BroadPhase.b2_invalid; + proxy.next = this.m_freeProxy; + this.m_freeProxy = proxy; + --this.m_proxyCount +}; +b2BroadPhase.prototype.MoveProxy = function(proxy_, aabb, displacement) { + var proxy = proxy_; + var as3arr; + var as3int = 0; + var axis = 0; + var index = 0; + var bound; + var prevBound; + var nextBound; + var nextProxyId = 0; + var nextProxy; + if(proxy == null) { + return + } + if(aabb.IsValid() == false) { + return + } + var boundCount = 2 * this.m_proxyCount; + var newValues = new b2BoundValues; + this.ComputeBounds(newValues.lowerValues, newValues.upperValues, aabb); + var oldValues = new b2BoundValues; + for(axis = 0;axis < 2;++axis) { + bound = this.m_bounds[axis][proxy.lowerBounds[axis]]; + oldValues.lowerValues[axis] = bound.value; + bound = this.m_bounds[axis][proxy.upperBounds[axis]]; + oldValues.upperValues[axis] = bound.value + } + for(axis = 0;axis < 2;++axis) { + var bounds = this.m_bounds[axis]; + var lowerIndex = proxy.lowerBounds[axis]; + var upperIndex = proxy.upperBounds[axis]; + var lowerValue = newValues.lowerValues[axis]; + var upperValue = newValues.upperValues[axis]; + bound = bounds[lowerIndex]; + var deltaLower = lowerValue - bound.value; + bound.value = lowerValue; + bound = bounds[upperIndex]; + var deltaUpper = upperValue - bound.value; + bound.value = upperValue; + if(deltaLower < 0) { + index = lowerIndex; + while(index > 0 && lowerValue < bounds[parseInt(index - 1)].value) { + bound = bounds[index]; + prevBound = bounds[parseInt(index - 1)]; + var prevProxy = prevBound.proxy; + prevBound.stabbingCount++; + if(prevBound.IsUpper() == true) { + if(this.TestOverlapBound(newValues, prevProxy)) { + this.m_pairManager.AddBufferedPair(proxy, prevProxy) + } + as3arr = prevProxy.upperBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.stabbingCount++ + }else { + as3arr = prevProxy.lowerBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.stabbingCount-- + } + as3arr = proxy.lowerBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.Swap(prevBound); + --index + } + } + if(deltaUpper > 0) { + index = upperIndex; + while(index < boundCount - 1 && bounds[parseInt(index + 1)].value <= upperValue) { + bound = bounds[index]; + nextBound = bounds[parseInt(index + 1)]; + nextProxy = nextBound.proxy; + nextBound.stabbingCount++; + if(nextBound.IsLower() == true) { + if(this.TestOverlapBound(newValues, nextProxy)) { + this.m_pairManager.AddBufferedPair(proxy, nextProxy) + } + as3arr = nextProxy.lowerBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.stabbingCount++ + }else { + as3arr = nextProxy.upperBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.stabbingCount-- + } + as3arr = proxy.upperBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.Swap(nextBound); + index++ + } + } + if(deltaLower > 0) { + index = lowerIndex; + while(index < boundCount - 1 && bounds[parseInt(index + 1)].value <= lowerValue) { + bound = bounds[index]; + nextBound = bounds[parseInt(index + 1)]; + nextProxy = nextBound.proxy; + nextBound.stabbingCount--; + if(nextBound.IsUpper()) { + if(this.TestOverlapBound(oldValues, nextProxy)) { + this.m_pairManager.RemoveBufferedPair(proxy, nextProxy) + } + as3arr = nextProxy.upperBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.stabbingCount-- + }else { + as3arr = nextProxy.lowerBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.stabbingCount++ + } + as3arr = proxy.lowerBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.Swap(nextBound); + index++ + } + } + if(deltaUpper < 0) { + index = upperIndex; + while(index > 0 && upperValue < bounds[parseInt(index - 1)].value) { + bound = bounds[index]; + prevBound = bounds[parseInt(index - 1)]; + prevProxy = prevBound.proxy; + prevBound.stabbingCount--; + if(prevBound.IsLower() == true) { + if(this.TestOverlapBound(oldValues, prevProxy)) { + this.m_pairManager.RemoveBufferedPair(proxy, prevProxy) + } + as3arr = prevProxy.lowerBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.stabbingCount-- + }else { + as3arr = prevProxy.upperBounds; + as3int = as3arr[axis]; + as3int++; + as3arr[axis] = as3int; + bound.stabbingCount++ + } + as3arr = proxy.upperBounds; + as3int = as3arr[axis]; + as3int--; + as3arr[axis] = as3int; + bound.Swap(prevBound); + index-- + } + } + } +}; +b2BroadPhase.prototype.UpdatePairs = function(callback) { + this.m_pairManager.Commit(callback) +}; +b2BroadPhase.prototype.TestOverlap = function(proxyA, proxyB) { + var proxyA_ = proxyA; + var proxyB_ = proxyB; + if(proxyA_.lowerBounds[0] > proxyB_.upperBounds[0]) { + return false + } + if(proxyB_.lowerBounds[0] > proxyA_.upperBounds[0]) { + return false + } + if(proxyA_.lowerBounds[1] > proxyB_.upperBounds[1]) { + return false + } + if(proxyB_.lowerBounds[1] > proxyA_.upperBounds[1]) { + return false + } + return true +}; +b2BroadPhase.prototype.GetUserData = function(proxy) { + return proxy.userData +}; +b2BroadPhase.prototype.GetFatAABB = function(proxy_) { + var aabb = new b2AABB; + var proxy = proxy_; + aabb.lowerBound.x = this.m_worldAABB.lowerBound.x + this.m_bounds[0][proxy.lowerBounds[0]].value / this.m_quantizationFactor.x; + aabb.lowerBound.y = this.m_worldAABB.lowerBound.y + this.m_bounds[1][proxy.lowerBounds[1]].value / this.m_quantizationFactor.y; + aabb.upperBound.x = this.m_worldAABB.lowerBound.x + this.m_bounds[0][proxy.upperBounds[0]].value / this.m_quantizationFactor.x; + aabb.upperBound.y = this.m_worldAABB.lowerBound.y + this.m_bounds[1][proxy.upperBounds[1]].value / this.m_quantizationFactor.y; + return aabb +}; +b2BroadPhase.prototype.GetProxyCount = function() { + return this.m_proxyCount +}; +b2BroadPhase.prototype.Query = function(callback, aabb) { + var lowerValues = new Array; + var upperValues = new Array; + this.ComputeBounds(lowerValues, upperValues, aabb); + var lowerIndex = 0; + var upperIndex = 0; + var lowerIndexOut = new Array; + lowerIndexOut.push(lowerIndex); + var upperIndexOut = new Array; + upperIndexOut.push(upperIndex); + this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[0], upperValues[0], this.m_bounds[0], 2 * this.m_proxyCount, 0); + this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[1], upperValues[1], this.m_bounds[1], 2 * this.m_proxyCount, 1); + for(var i = 0;i < this.m_queryResultCount;++i) { + var proxy = this.m_queryResults[i]; + if(!callback(proxy)) { + break + } + } + this.m_queryResultCount = 0; + this.IncrementTimeStamp() +}; +b2BroadPhase.prototype.Validate = function() { + var pair; + var proxy1; + var proxy2; + var overlap; + for(var axis = 0;axis < 2;++axis) { + var bounds = this.m_bounds[axis]; + var boundCount = 2 * this.m_proxyCount; + var stabbingCount = 0; + for(var i = 0;i < boundCount;++i) { + var bound = bounds[i]; + if(bound.IsLower() == true) { + stabbingCount++ + }else { + stabbingCount-- + } + } + } +}; +b2BroadPhase.prototype.Rebalance = function(iterations) { +}; +b2BroadPhase.prototype.RayCast = function(callback, input) { + var subInput = new b2RayCastInput; + subInput.p1.SetV(input.p1); + subInput.p2.SetV(input.p2); + subInput.maxFraction = input.maxFraction; + var dx = (input.p2.x - input.p1.x) * this.m_quantizationFactor.x; + var dy = (input.p2.y - input.p1.y) * this.m_quantizationFactor.y; + var sx = dx < -Number.MIN_VALUE ? -1 : dx > Number.MIN_VALUE ? 1 : 0; + var sy = dy < -Number.MIN_VALUE ? -1 : dy > Number.MIN_VALUE ? 1 : 0; + var p1x = this.m_quantizationFactor.x * (input.p1.x - this.m_worldAABB.lowerBound.x); + var p1y = this.m_quantizationFactor.y * (input.p1.y - this.m_worldAABB.lowerBound.y); + var startValues = new Array; + var startValues2 = new Array; + startValues[0] = parseInt(p1x) & b2Settings.USHRT_MAX - 1; + startValues[1] = parseInt(p1y) & b2Settings.USHRT_MAX - 1; + startValues2[0] = startValues[0] + 1; + startValues2[1] = startValues[1] + 1; + var startIndices = new Array; + var xIndex = 0; + var yIndex = 0; + var proxy; + var lowerIndex = 0; + var upperIndex = 0; + var lowerIndexOut = new Array; + lowerIndexOut.push(lowerIndex); + var upperIndexOut = new Array; + upperIndexOut.push(upperIndex); + this.QueryAxis(lowerIndexOut, upperIndexOut, startValues[0], startValues2[0], this.m_bounds[0], 2 * this.m_proxyCount, 0); + if(sx >= 0) { + xIndex = upperIndexOut[0] - 1 + }else { + xIndex = lowerIndexOut[0] + } + this.QueryAxis(lowerIndexOut, upperIndexOut, startValues[1], startValues2[1], this.m_bounds[1], 2 * this.m_proxyCount, 1); + if(sy >= 0) { + yIndex = upperIndexOut[0] - 1 + }else { + yIndex = lowerIndexOut[0] + } + for(var i = 0;i < this.m_queryResultCount;i++) { + subInput.maxFraction = callback(this.m_queryResults[i], subInput) + } + for(;;) { + var xProgress = 0; + var yProgress = 0; + xIndex += sx >= 0 ? 1 : -1; + if(xIndex < 0 || xIndex >= this.m_proxyCount * 2) { + break + } + if(sx != 0) { + xProgress = (this.m_bounds[0][xIndex].value - p1x) / dx + } + yIndex += sy >= 0 ? 1 : -1; + if(yIndex < 0 || yIndex >= this.m_proxyCount * 2) { + break + } + if(sy != 0) { + yProgress = (this.m_bounds[1][yIndex].value - p1y) / dy + } + for(;;) { + if(sy == 0 || sx != 0 && xProgress < yProgress) { + if(xProgress > subInput.maxFraction) { + break + } + if(sx > 0 ? this.m_bounds[0][xIndex].IsLower() : this.m_bounds[0][xIndex].IsUpper()) { + proxy = this.m_bounds[0][xIndex].proxy; + if(sy >= 0) { + if(proxy.lowerBounds[1] <= yIndex - 1 && proxy.upperBounds[1] >= yIndex) { + subInput.maxFraction = callback(proxy, subInput) } - } - } - } - b2DynamicTree.prototype.RayCast = function (callback, input) { - if (this.m_root == null) return; - var p1 = input.p1; - var p2 = input.p2; - var r = b2Math.SubtractVV(p1, p2); - r.Normalize(); - var v = b2Math.CrossFV(1.0, r); - var abs_v = b2Math.AbsV(v); - var maxFraction = input.maxFraction; - var segmentAABB = new b2AABB(); - var tX = 0; - var tY = 0; { - tX = p1.x + maxFraction * (p2.x - p1.x); - tY = p1.y + maxFraction * (p2.y - p1.y); - segmentAABB.lowerBound.x = Math.min(p1.x, tX); - segmentAABB.lowerBound.y = Math.min(p1.y, tY); - segmentAABB.upperBound.x = Math.max(p1.x, tX); - segmentAABB.upperBound.y = Math.max(p1.y, tY); - } - var stack = new Vector(); - var count = 0; - stack[count++] = this.m_root; - while (count > 0) { - var node = stack[--count]; - if (node.aabb.TestOverlap(segmentAABB) == false) { - continue; - } - var c = node.aabb.GetCenter(); - var h = node.aabb.GetExtents(); - var separation = Math.abs(v.x * (p1.x - c.x) + v.y * (p1.y - c.y)) - abs_v.x * h.x - abs_v.y * h.y; - if (separation > 0.0) continue; - if (node.IsLeaf()) { - var subInput = new b2RayCastInput(); - subInput.p1 = input.p1; - subInput.p2 = input.p2; - subInput.maxFraction = input.maxFraction; - maxFraction = callback(subInput, node); - if (maxFraction == 0.0) return; - if (maxFraction > 0.0) { - tX = p1.x + maxFraction * (p2.x - p1.x); - tY = p1.y + maxFraction * (p2.y - p1.y); - segmentAABB.lowerBound.x = Math.min(p1.x, tX); - segmentAABB.lowerBound.y = Math.min(p1.y, tY); - segmentAABB.upperBound.x = Math.max(p1.x, tX); - segmentAABB.upperBound.y = Math.max(p1.y, tY); + }else { + if(proxy.lowerBounds[1] <= yIndex && proxy.upperBounds[1] >= yIndex + 1) { + subInput.maxFraction = callback(proxy, subInput) } - } - else { - stack[count++] = node.child1; - stack[count++] = node.child2; - } - } - } - b2DynamicTree.prototype.AllocateNode = function () { - if (this.m_freeList) { - var node = this.m_freeList; - this.m_freeList = node.parent; - node.parent = null; - node.child1 = null; - node.child2 = null; - return node; - } - return new b2DynamicTreeNode(); - } - b2DynamicTree.prototype.FreeNode = function (node) { - node.parent = this.m_freeList; - this.m_freeList = node; - } - b2DynamicTree.prototype.InsertLeaf = function (leaf) { - ++this.m_insertionCount; - if (this.m_root == null) { - this.m_root = leaf; - this.m_root.parent = null; - return; - } - var center = leaf.aabb.GetCenter(); - var sibling = this.m_root; - if (sibling.IsLeaf() == false) { - do { - var child1 = sibling.child1; - var child2 = sibling.child2; - var norm1 = Math.abs((child1.aabb.lowerBound.x + child1.aabb.upperBound.x) / 2 - center.x) + Math.abs((child1.aabb.lowerBound.y + child1.aabb.upperBound.y) / 2 - center.y); - var norm2 = Math.abs((child2.aabb.lowerBound.x + child2.aabb.upperBound.x) / 2 - center.x) + Math.abs((child2.aabb.lowerBound.y + child2.aabb.upperBound.y) / 2 - center.y); - if (norm1 < norm2) { - sibling = child1; + } + } + if(subInput.maxFraction == 0) { + break + } + if(sx > 0) { + xIndex++; + if(xIndex == this.m_proxyCount * 2) { + break + } + }else { + xIndex--; + if(xIndex < 0) { + break + } + } + xProgress = (this.m_bounds[0][xIndex].value - p1x) / dx + }else { + if(yProgress > subInput.maxFraction) { + break + } + if(sy > 0 ? this.m_bounds[1][yIndex].IsLower() : this.m_bounds[1][yIndex].IsUpper()) { + proxy = this.m_bounds[1][yIndex].proxy; + if(sx >= 0) { + if(proxy.lowerBounds[0] <= xIndex - 1 && proxy.upperBounds[0] >= xIndex) { + subInput.maxFraction = callback(proxy, subInput) } - else { - sibling = child2; + }else { + if(proxy.lowerBounds[0] <= xIndex && proxy.upperBounds[0] >= xIndex + 1) { + subInput.maxFraction = callback(proxy, subInput) } - } - while (sibling.IsLeaf() == false) - } - var node1 = sibling.parent; - var node2 = this.AllocateNode(); - node2.parent = node1; - node2.userData = null; - node2.aabb.Combine(leaf.aabb, sibling.aabb); - if (node1) { - if (sibling.parent.child1 == sibling) { - node1.child1 = node2; - } - else { - node1.child2 = node2; - } - node2.child1 = sibling; - node2.child2 = leaf; - sibling.parent = node2; - leaf.parent = node2; - do { - if (node1.aabb.Contains(node2.aabb)) break; - node1.aabb.Combine(node1.child1.aabb, node1.child2.aabb); - node2 = node1; - node1 = node1.parent; - } - while (node1) - } - else { - node2.child1 = sibling; - node2.child2 = leaf; - sibling.parent = node2; - leaf.parent = node2; - this.m_root = node2; - } - } - b2DynamicTree.prototype.RemoveLeaf = function (leaf) { - if (leaf == this.m_root) { - this.m_root = null; - return; - } - var node2 = leaf.parent; - var node1 = node2.parent; - var sibling; - if (node2.child1 == leaf) { - sibling = node2.child2; - } - else { - sibling = node2.child1; - } - if (node1) { - if (node1.child1 == node2) { - node1.child1 = sibling; - } - else { - node1.child2 = sibling; - } - sibling.parent = node1; - this.FreeNode(node2); - while (node1) { - var oldAABB = node1.aabb; - node1.aabb = b2AABB.Combine(node1.child1.aabb, node1.child2.aabb); - if (oldAABB.Contains(node1.aabb)) break; - node1 = node1.parent; - } - } - else { - this.m_root = sibling; - sibling.parent = null; - this.FreeNode(node2); - } - } - b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase = function () { - this.m_tree = new b2DynamicTree(); - this.m_moveBuffer = new Vector(); - this.m_pairBuffer = new Vector(); - this.m_pairCount = 0; - }; - b2DynamicTreeBroadPhase.prototype.CreateProxy = function (aabb, userData) { - var proxy = this.m_tree.CreateProxy(aabb, userData); - ++this.m_proxyCount; - this.BufferMove(proxy); - return proxy; - } - b2DynamicTreeBroadPhase.prototype.DestroyProxy = function (proxy) { - this.UnBufferMove(proxy); - --this.m_proxyCount; - this.m_tree.DestroyProxy(proxy); - } - b2DynamicTreeBroadPhase.prototype.MoveProxy = function (proxy, aabb, displacement) { - var buffer = this.m_tree.MoveProxy(proxy, aabb, displacement); - if (buffer) { - this.BufferMove(proxy); - } - } - b2DynamicTreeBroadPhase.prototype.TestOverlap = function (proxyA, proxyB) { - var aabbA = this.m_tree.GetFatAABB(proxyA); - var aabbB = this.m_tree.GetFatAABB(proxyB); - return aabbA.TestOverlap(aabbB); - } - b2DynamicTreeBroadPhase.prototype.GetUserData = function (proxy) { - return this.m_tree.GetUserData(proxy); - } - b2DynamicTreeBroadPhase.prototype.GetFatAABB = function (proxy) { - return this.m_tree.GetFatAABB(proxy); - } - b2DynamicTreeBroadPhase.prototype.GetProxyCount = function () { - return this.m_proxyCount; - } - b2DynamicTreeBroadPhase.prototype.UpdatePairs = function (callback) { - var __this = this; - __this.m_pairCount = 0; - var queryProxy; - for (var each in __this.m_moveBuffer) { - queryProxy = __this.m_moveBuffer[each]; { - function QueryCallback(proxy) { - if (proxy == queryProxy) return true; - if (__this.m_pairCount == __this.m_pairBuffer.length) { - __this.m_pairBuffer[__this.m_pairCount] = new b2DynamicTreePair(); - } - var pair = __this.m_pairBuffer[__this.m_pairCount]; - pair.proxyA = proxy < queryProxy ? proxy : queryProxy; - pair.proxyB = proxy >= queryProxy ? proxy : queryProxy;++__this.m_pairCount; - return true; - }; - var fatAABB = __this.m_tree.GetFatAABB(queryProxy); - __this.m_tree.Query(QueryCallback, fatAABB); - } - } - __this.m_moveBuffer.length = 0; - for (var i = 0; i < __this.m_pairCount;) { - var primaryPair = __this.m_pairBuffer[i]; - var userDataA = __this.m_tree.GetUserData(primaryPair.proxyA); - var userDataB = __this.m_tree.GetUserData(primaryPair.proxyB); - callback(userDataA, userDataB); - ++i; - while (i < __this.m_pairCount) { - var pair = __this.m_pairBuffer[i]; - if (pair.proxyA != primaryPair.proxyA || pair.proxyB != primaryPair.proxyB) { - break; - }++i; - } - } - } - b2DynamicTreeBroadPhase.prototype.Query = function (callback, aabb) { - this.m_tree.Query(callback, aabb); - } - b2DynamicTreeBroadPhase.prototype.RayCast = function (callback, input) { - this.m_tree.RayCast(callback, input); - } - b2DynamicTreeBroadPhase.prototype.Validate = function () {} - b2DynamicTreeBroadPhase.prototype.Rebalance = function (iterations) { - if (iterations === undefined) iterations = 0; - this.m_tree.Rebalance(iterations); - } - b2DynamicTreeBroadPhase.prototype.BufferMove = function (proxy) { - this.m_moveBuffer[this.m_moveBuffer.length] = proxy; - } - b2DynamicTreeBroadPhase.prototype.UnBufferMove = function (proxy) { - var i = parseInt(this.m_moveBuffer.indexOf(proxy)); - this.m_moveBuffer.splice(i, 1); - } - b2DynamicTreeBroadPhase.prototype.ComparePairs = function (pair1, pair2) { + } + } + if(subInput.maxFraction == 0) { + break + } + if(sy > 0) { + yIndex++; + if(yIndex == this.m_proxyCount * 2) { + break + } + }else { + yIndex--; + if(yIndex < 0) { + break + } + } + yProgress = (this.m_bounds[1][yIndex].value - p1y) / dy + } + } + break + } + this.m_queryResultCount = 0; + this.IncrementTimeStamp(); + return +}; +b2BroadPhase.prototype.TestOverlapBound = function(b, p) { + for(var axis = 0;axis < 2;++axis) { + var bounds = this.m_bounds[axis]; + var bound = bounds[p.upperBounds[axis]]; + if(b.lowerValues[axis] > bound.value) { + return false + } + bound = bounds[p.lowerBounds[axis]]; + if(b.upperValues[axis] < bound.value) { + return false + } + } + return true +}; +b2BroadPhase.prototype.m_pairManager = new b2PairManager; +b2BroadPhase.prototype.m_proxyPool = new Array; +b2BroadPhase.prototype.m_freeProxy = null; +b2BroadPhase.prototype.m_bounds = null; +b2BroadPhase.prototype.m_querySortKeys = new Array; +b2BroadPhase.prototype.m_queryResults = new Array; +b2BroadPhase.prototype.m_queryResultCount = 0; +b2BroadPhase.prototype.m_worldAABB = null; +b2BroadPhase.prototype.m_quantizationFactor = new b2Vec2; +b2BroadPhase.prototype.m_proxyCount = 0; +b2BroadPhase.prototype.m_timeStamp = 0;var b2Manifold = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Manifold.prototype.__constructor = function() { + this.m_points = new Array(b2Settings.b2_maxManifoldPoints); + for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { + this.m_points[i] = new b2ManifoldPoint + } + this.m_localPlaneNormal = new b2Vec2; + this.m_localPoint = new b2Vec2 +}; +b2Manifold.prototype.__varz = function() { +}; +b2Manifold.e_circles = 1; +b2Manifold.e_faceA = 2; +b2Manifold.e_faceB = 4; +b2Manifold.prototype.Reset = function() { + for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { + this.m_points[i].Reset() + } + this.m_localPlaneNormal.SetZero(); + this.m_localPoint.SetZero(); + this.m_type = 0; + this.m_pointCount = 0 +}; +b2Manifold.prototype.Set = function(m) { + this.m_pointCount = m.m_pointCount; + for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { + this.m_points[i].Set(m.m_points[i]) + } + this.m_localPlaneNormal.SetV(m.m_localPlaneNormal); + this.m_localPoint.SetV(m.m_localPoint); + this.m_type = m.m_type +}; +b2Manifold.prototype.Copy = function() { + var copy = new b2Manifold; + copy.Set(this); + return copy +}; +b2Manifold.prototype.m_points = null; +b2Manifold.prototype.m_localPlaneNormal = null; +b2Manifold.prototype.m_localPoint = null; +b2Manifold.prototype.m_type = 0; +b2Manifold.prototype.m_pointCount = 0;var b2CircleShape = function() { + b2Shape.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2CircleShape.prototype, b2Shape.prototype); +b2CircleShape.prototype._super = b2Shape.prototype; +b2CircleShape.prototype.__constructor = function(radius) { + this._super.__constructor.apply(this, []); + this.m_type = b2Shape.e_circleShape; + this.m_radius = radius +}; +b2CircleShape.prototype.__varz = function() { + this.m_p = new b2Vec2 +}; +b2CircleShape.prototype.Copy = function() { + var s = new b2CircleShape; + s.Set(this); + return s +}; +b2CircleShape.prototype.Set = function(other) { + this._super.Set.apply(this, [other]); + if(isInstanceOf(other, b2CircleShape)) { + var other2 = other; + this.m_p.SetV(other2.m_p) + } +}; +b2CircleShape.prototype.TestPoint = function(transform, p) { + var tMat = transform.R; + var dX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); + var dY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); + dX = p.x - dX; + dY = p.y - dY; + return dX * dX + dY * dY <= this.m_radius * this.m_radius +}; +b2CircleShape.prototype.RayCast = function(output, input, transform) { + var tMat = transform.R; + var positionX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); + var positionY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); + var sX = input.p1.x - positionX; + var sY = input.p1.y - positionY; + var b = sX * sX + sY * sY - this.m_radius * this.m_radius; + var rX = input.p2.x - input.p1.x; + var rY = input.p2.y - input.p1.y; + var c = sX * rX + sY * rY; + var rr = rX * rX + rY * rY; + var sigma = c * c - rr * b; + if(sigma < 0 || rr < Number.MIN_VALUE) { + return false + } + var a = -(c + Math.sqrt(sigma)); + if(0 <= a && a <= input.maxFraction * rr) { + a /= rr; + output.fraction = a; + output.normal.x = sX + a * rX; + output.normal.y = sY + a * rY; + output.normal.Normalize(); + return true + } + return false +}; +b2CircleShape.prototype.ComputeAABB = function(aabb, transform) { + var tMat = transform.R; + var pX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); + var pY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); + aabb.lowerBound.Set(pX - this.m_radius, pY - this.m_radius); + aabb.upperBound.Set(pX + this.m_radius, pY + this.m_radius) +}; +b2CircleShape.prototype.ComputeMass = function(massData, density) { + massData.mass = density * b2Settings.b2_pi * this.m_radius * this.m_radius; + massData.center.SetV(this.m_p); + massData.I = massData.mass * (0.5 * this.m_radius * this.m_radius + (this.m_p.x * this.m_p.x + this.m_p.y * this.m_p.y)) +}; +b2CircleShape.prototype.ComputeSubmergedArea = function(normal, offset, xf, c) { + var p = b2Math.MulX(xf, this.m_p); + var l = -(b2Math.Dot(normal, p) - offset); + if(l < -this.m_radius + Number.MIN_VALUE) { + return 0 + } + if(l > this.m_radius) { + c.SetV(p); + return Math.PI * this.m_radius * this.m_radius + } + var r2 = this.m_radius * this.m_radius; + var l2 = l * l; + var area = r2 * (Math.asin(l / this.m_radius) + Math.PI / 2) + l * Math.sqrt(r2 - l2); + var com = -2 / 3 * Math.pow(r2 - l2, 1.5) / area; + c.x = p.x + normal.x * com; + c.y = p.y + normal.y * com; + return area +}; +b2CircleShape.prototype.GetLocalPosition = function() { + return this.m_p +}; +b2CircleShape.prototype.SetLocalPosition = function(position) { + this.m_p.SetV(position) +}; +b2CircleShape.prototype.GetRadius = function() { + return this.m_radius +}; +b2CircleShape.prototype.SetRadius = function(radius) { + this.m_radius = radius +}; +b2CircleShape.prototype.m_p = new b2Vec2;var b2Joint = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Joint.prototype.__constructor = function(def) { + b2Settings.b2Assert(def.bodyA != def.bodyB); + this.m_type = def.type; + this.m_prev = null; + this.m_next = null; + this.m_bodyA = def.bodyA; + this.m_bodyB = def.bodyB; + this.m_collideConnected = def.collideConnected; + this.m_islandFlag = false; + this.m_userData = def.userData +}; +b2Joint.prototype.__varz = function() { + this.m_edgeA = new b2JointEdge; + this.m_edgeB = new b2JointEdge; + this.m_localCenterA = new b2Vec2; + this.m_localCenterB = new b2Vec2 +}; +b2Joint.Create = function(def, allocator) { + var joint = null; + switch(def.type) { + case b2Joint.e_distanceJoint: + joint = new b2DistanceJoint(def); + break; + case b2Joint.e_mouseJoint: + joint = new b2MouseJoint(def); + break; + case b2Joint.e_prismaticJoint: + joint = new b2PrismaticJoint(def); + break; + case b2Joint.e_revoluteJoint: + joint = new b2RevoluteJoint(def); + break; + case b2Joint.e_pulleyJoint: + joint = new b2PulleyJoint(def); + break; + case b2Joint.e_gearJoint: + joint = new b2GearJoint(def); + break; + case b2Joint.e_lineJoint: + joint = new b2LineJoint(def); + break; + case b2Joint.e_weldJoint: + joint = new b2WeldJoint(def); + break; + case b2Joint.e_frictionJoint: + joint = new b2FrictionJoint(def); + break; + default: + break + } + return joint +}; +b2Joint.Destroy = function(joint, allocator) { +}; +b2Joint.e_unknownJoint = 0; +b2Joint.e_revoluteJoint = 1; +b2Joint.e_prismaticJoint = 2; +b2Joint.e_distanceJoint = 3; +b2Joint.e_pulleyJoint = 4; +b2Joint.e_mouseJoint = 5; +b2Joint.e_gearJoint = 6; +b2Joint.e_lineJoint = 7; +b2Joint.e_weldJoint = 8; +b2Joint.e_frictionJoint = 9; +b2Joint.e_inactiveLimit = 0; +b2Joint.e_atLowerLimit = 1; +b2Joint.e_atUpperLimit = 2; +b2Joint.e_equalLimits = 3; +b2Joint.prototype.InitVelocityConstraints = function(step) { +}; +b2Joint.prototype.SolveVelocityConstraints = function(step) { +}; +b2Joint.prototype.FinalizeVelocityConstraints = function() { +}; +b2Joint.prototype.SolvePositionConstraints = function(baumgarte) { + return false +}; +b2Joint.prototype.GetType = function() { + return this.m_type +}; +b2Joint.prototype.GetAnchorA = function() { + return null +}; +b2Joint.prototype.GetAnchorB = function() { + return null +}; +b2Joint.prototype.GetReactionForce = function(inv_dt) { + return null +}; +b2Joint.prototype.GetReactionTorque = function(inv_dt) { + return 0 +}; +b2Joint.prototype.GetBodyA = function() { + return this.m_bodyA +}; +b2Joint.prototype.GetBodyB = function() { + return this.m_bodyB +}; +b2Joint.prototype.GetNext = function() { + return this.m_next +}; +b2Joint.prototype.GetUserData = function() { + return this.m_userData +}; +b2Joint.prototype.SetUserData = function(data) { + this.m_userData = data +}; +b2Joint.prototype.IsActive = function() { + return this.m_bodyA.IsActive() && this.m_bodyB.IsActive() +}; +b2Joint.prototype.m_type = 0; +b2Joint.prototype.m_prev = null; +b2Joint.prototype.m_next = null; +b2Joint.prototype.m_edgeA = new b2JointEdge; +b2Joint.prototype.m_edgeB = new b2JointEdge; +b2Joint.prototype.m_bodyA = null; +b2Joint.prototype.m_bodyB = null; +b2Joint.prototype.m_islandFlag = null; +b2Joint.prototype.m_collideConnected = null; +b2Joint.prototype.m_userData = null; +b2Joint.prototype.m_localCenterA = new b2Vec2; +b2Joint.prototype.m_localCenterB = new b2Vec2; +b2Joint.prototype.m_invMassA = null; +b2Joint.prototype.m_invMassB = null; +b2Joint.prototype.m_invIA = null; +b2Joint.prototype.m_invIB = null;var b2LineJoint = function() { + b2Joint.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2LineJoint.prototype, b2Joint.prototype); +b2LineJoint.prototype._super = b2Joint.prototype; +b2LineJoint.prototype.__constructor = function(def) { + this._super.__constructor.apply(this, [def]); + var tMat; + var tX; + var tY; + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_localXAxis1.SetV(def.localAxisA); + this.m_localYAxis1.x = -this.m_localXAxis1.y; + this.m_localYAxis1.y = this.m_localXAxis1.x; + this.m_impulse.SetZero(); + this.m_motorMass = 0; + this.m_motorImpulse = 0; + this.m_lowerTranslation = def.lowerTranslation; + this.m_upperTranslation = def.upperTranslation; + this.m_maxMotorForce = def.maxMotorForce; + this.m_motorSpeed = def.motorSpeed; + this.m_enableLimit = def.enableLimit; + this.m_enableMotor = def.enableMotor; + this.m_limitState = b2Joint.e_inactiveLimit; + this.m_axis.SetZero(); + this.m_perp.SetZero() +}; +b2LineJoint.prototype.__varz = function() { + this.m_localAnchor1 = new b2Vec2; + this.m_localAnchor2 = new b2Vec2; + this.m_localXAxis1 = new b2Vec2; + this.m_localYAxis1 = new b2Vec2; + this.m_axis = new b2Vec2; + this.m_perp = new b2Vec2; + this.m_K = new b2Mat22; + this.m_impulse = new b2Vec2 +}; +b2LineJoint.prototype.InitVelocityConstraints = function(step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var tX; + this.m_localCenterA.SetV(bA.GetLocalCenter()); + this.m_localCenterB.SetV(bB.GetLocalCenter()); + var xf1 = bA.GetTransform(); + var xf2 = bB.GetTransform(); + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; + var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; + var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + this.m_invMassA = bA.m_invMass; + this.m_invMassB = bB.m_invMass; + this.m_invIA = bA.m_invI; + this.m_invIB = bB.m_invI; + this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); + this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; + this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; + this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; + this.m_motorMass = this.m_motorMass > Number.MIN_VALUE ? 1 / this.m_motorMass : 0; + this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); + this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; + this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; + var m1 = this.m_invMassA; + var m2 = this.m_invMassB; + var i1 = this.m_invIA; + var i2 = this.m_invIB; + this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; + this.m_K.col2.x = this.m_K.col1.y; + this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; + if(this.m_enableLimit) { + var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; + if(b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2 * b2Settings.b2_linearSlop) { + this.m_limitState = b2Joint.e_equalLimits + }else { + if(jointTransition <= this.m_lowerTranslation) { + if(this.m_limitState != b2Joint.e_atLowerLimit) { + this.m_limitState = b2Joint.e_atLowerLimit; + this.m_impulse.y = 0 + } + }else { + if(jointTransition >= this.m_upperTranslation) { + if(this.m_limitState != b2Joint.e_atUpperLimit) { + this.m_limitState = b2Joint.e_atUpperLimit; + this.m_impulse.y = 0 + } + }else { + this.m_limitState = b2Joint.e_inactiveLimit; + this.m_impulse.y = 0 + } + } + } + }else { + this.m_limitState = b2Joint.e_inactiveLimit + } + if(this.m_enableMotor == false) { + this.m_motorImpulse = 0 + } + if(step.warmStarting) { + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + this.m_motorImpulse *= step.dtRatio; + var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x; + var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y; + var L1 = this.m_impulse.x * this.m_s1 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a1; + var L2 = this.m_impulse.x * this.m_s2 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a2; + bA.m_linearVelocity.x -= this.m_invMassA * PX; + bA.m_linearVelocity.y -= this.m_invMassA * PY; + bA.m_angularVelocity -= this.m_invIA * L1; + bB.m_linearVelocity.x += this.m_invMassB * PX; + bB.m_linearVelocity.y += this.m_invMassB * PY; + bB.m_angularVelocity += this.m_invIB * L2 + }else { + this.m_impulse.SetZero(); + this.m_motorImpulse = 0 + } +}; +b2LineJoint.prototype.SolveVelocityConstraints = function(step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var v1 = bA.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var v2 = bB.m_linearVelocity; + var w2 = bB.m_angularVelocity; + var PX; + var PY; + var L1; + var L2; + if(this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) { + var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; + var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); + var oldImpulse = this.m_motorImpulse; + var maxImpulse = step.dt * this.m_maxMotorForce; + this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = this.m_motorImpulse - oldImpulse; + PX = impulse * this.m_axis.x; + PY = impulse * this.m_axis.y; + L1 = impulse * this.m_a1; + L2 = impulse * this.m_a2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2 + } + var Cdot1 = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; + if(this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { + var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; + var f1 = this.m_impulse.Copy(); + var df = this.m_K.Solve(new b2Vec2, -Cdot1, -Cdot2); + this.m_impulse.Add(df); + if(this.m_limitState == b2Joint.e_atLowerLimit) { + this.m_impulse.y = b2Math.Max(this.m_impulse.y, 0) + }else { + if(this.m_limitState == b2Joint.e_atUpperLimit) { + this.m_impulse.y = b2Math.Min(this.m_impulse.y, 0) + } + } + var b = -Cdot1 - (this.m_impulse.y - f1.y) * this.m_K.col2.x; + var f2r; + if(this.m_K.col1.x != 0) { + f2r = b / this.m_K.col1.x + f1.x + }else { + f2r = f1.x + } + this.m_impulse.x = f2r; + df.x = this.m_impulse.x - f1.x; + df.y = this.m_impulse.y - f1.y; + PX = df.x * this.m_perp.x + df.y * this.m_axis.x; + PY = df.x * this.m_perp.y + df.y * this.m_axis.y; + L1 = df.x * this.m_s1 + df.y * this.m_a1; + L2 = df.x * this.m_s2 + df.y * this.m_a2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2 + }else { + var df2; + if(this.m_K.col1.x != 0) { + df2 = -Cdot1 / this.m_K.col1.x + }else { + df2 = 0 + } + this.m_impulse.x += df2; + PX = df2 * this.m_perp.x; + PY = df2 * this.m_perp.y; + L1 = df2 * this.m_s1; + L2 = df2 * this.m_s2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2 + } + bA.m_linearVelocity.SetV(v1); + bA.m_angularVelocity = w1; + bB.m_linearVelocity.SetV(v2); + bB.m_angularVelocity = w2 +}; +b2LineJoint.prototype.SolvePositionConstraints = function(baumgarte) { + var limitC; + var oldLimitImpulse; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var c1 = bA.m_sweep.c; + var a1 = bA.m_sweep.a; + var c2 = bB.m_sweep.c; + var a2 = bB.m_sweep.a; + var tMat; + var tX; + var m1; + var m2; + var i1; + var i2; + var linearError = 0; + var angularError = 0; + var active = false; + var C2 = 0; + var R1 = b2Mat22.FromAngle(a1); + var R2 = b2Mat22.FromAngle(a2); + tMat = R1; + var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; + var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = R2; + var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; + var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var dX = c2.x + r2X - c1.x - r1X; + var dY = c2.y + r2Y - c1.y - r1Y; + if(this.m_enableLimit) { + this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); + this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; + this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; + var translation = this.m_axis.x * dX + this.m_axis.y * dY; + if(b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2 * b2Settings.b2_linearSlop) { + C2 = b2Math.Clamp(translation, -b2Settings.b2_maxLinearCorrection, b2Settings.b2_maxLinearCorrection); + linearError = b2Math.Abs(translation); + active = true + }else { + if(translation <= this.m_lowerTranslation) { + C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); + linearError = this.m_lowerTranslation - translation; + active = true + }else { + if(translation >= this.m_upperTranslation) { + C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0, b2Settings.b2_maxLinearCorrection); + linearError = translation - this.m_upperTranslation; + active = true + } + } + } + } + this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); + this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; + this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; + var impulse = new b2Vec2; + var C1 = this.m_perp.x * dX + this.m_perp.y * dY; + linearError = b2Math.Max(linearError, b2Math.Abs(C1)); + angularError = 0; + if(active) { + m1 = this.m_invMassA; + m2 = this.m_invMassB; + i1 = this.m_invIA; + i2 = this.m_invIB; + this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; + this.m_K.col2.x = this.m_K.col1.y; + this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; + this.m_K.Solve(impulse, -C1, -C2) + }else { + m1 = this.m_invMassA; + m2 = this.m_invMassB; + i1 = this.m_invIA; + i2 = this.m_invIB; + var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + var impulse1; + if(k11 != 0) { + impulse1 = -C1 / k11 + }else { + impulse1 = 0 + } + impulse.x = impulse1; + impulse.y = 0 + } + var PX = impulse.x * this.m_perp.x + impulse.y * this.m_axis.x; + var PY = impulse.x * this.m_perp.y + impulse.y * this.m_axis.y; + var L1 = impulse.x * this.m_s1 + impulse.y * this.m_a1; + var L2 = impulse.x * this.m_s2 + impulse.y * this.m_a2; + c1.x -= this.m_invMassA * PX; + c1.y -= this.m_invMassA * PY; + a1 -= this.m_invIA * L1; + c2.x += this.m_invMassB * PX; + c2.y += this.m_invMassB * PY; + a2 += this.m_invIB * L2; + bA.m_sweep.a = a1; + bB.m_sweep.a = a2; + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop +}; +b2LineJoint.prototype.GetAnchorA = function() { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) +}; +b2LineJoint.prototype.GetAnchorB = function() { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) +}; +b2LineJoint.prototype.GetReactionForce = function(inv_dt) { + return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y)) +}; +b2LineJoint.prototype.GetReactionTorque = function(inv_dt) { + return inv_dt * this.m_impulse.y +}; +b2LineJoint.prototype.GetJointTranslation = function() { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var p1 = bA.GetWorldPoint(this.m_localAnchor1); + var p2 = bB.GetWorldPoint(this.m_localAnchor2); + var dX = p2.x - p1.x; + var dY = p2.y - p1.y; + var axis = bA.GetWorldVector(this.m_localXAxis1); + var translation = axis.x * dX + axis.y * dY; + return translation +}; +b2LineJoint.prototype.GetJointSpeed = function() { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var p1X = bA.m_sweep.c.x + r1X; + var p1Y = bA.m_sweep.c.y + r1Y; + var p2X = bB.m_sweep.c.x + r2X; + var p2Y = bB.m_sweep.c.y + r2Y; + var dX = p2X - p1X; + var dY = p2Y - p1Y; + var axis = bA.GetWorldVector(this.m_localXAxis1); + var v1 = bA.m_linearVelocity; + var v2 = bB.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var w2 = bB.m_angularVelocity; + var speed = dX * -w1 * axis.y + dY * w1 * axis.x + (axis.x * (v2.x + -w2 * r2Y - v1.x - -w1 * r1Y) + axis.y * (v2.y + w2 * r2X - v1.y - w1 * r1X)); + return speed +}; +b2LineJoint.prototype.IsLimitEnabled = function() { + return this.m_enableLimit +}; +b2LineJoint.prototype.EnableLimit = function(flag) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableLimit = flag +}; +b2LineJoint.prototype.GetLowerLimit = function() { + return this.m_lowerTranslation +}; +b2LineJoint.prototype.GetUpperLimit = function() { + return this.m_upperTranslation +}; +b2LineJoint.prototype.SetLimits = function(lower, upper) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_lowerTranslation = lower; + this.m_upperTranslation = upper +}; +b2LineJoint.prototype.IsMotorEnabled = function() { + return this.m_enableMotor +}; +b2LineJoint.prototype.EnableMotor = function(flag) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableMotor = flag +}; +b2LineJoint.prototype.SetMotorSpeed = function(speed) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_motorSpeed = speed +}; +b2LineJoint.prototype.GetMotorSpeed = function() { + return this.m_motorSpeed +}; +b2LineJoint.prototype.SetMaxMotorForce = function(force) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_maxMotorForce = force +}; +b2LineJoint.prototype.GetMaxMotorForce = function() { + return this.m_maxMotorForce +}; +b2LineJoint.prototype.GetMotorForce = function() { + return this.m_motorImpulse +}; +b2LineJoint.prototype.m_localAnchor1 = new b2Vec2; +b2LineJoint.prototype.m_localAnchor2 = new b2Vec2; +b2LineJoint.prototype.m_localXAxis1 = new b2Vec2; +b2LineJoint.prototype.m_localYAxis1 = new b2Vec2; +b2LineJoint.prototype.m_axis = new b2Vec2; +b2LineJoint.prototype.m_perp = new b2Vec2; +b2LineJoint.prototype.m_s1 = null; +b2LineJoint.prototype.m_s2 = null; +b2LineJoint.prototype.m_a1 = null; +b2LineJoint.prototype.m_a2 = null; +b2LineJoint.prototype.m_K = new b2Mat22; +b2LineJoint.prototype.m_impulse = new b2Vec2; +b2LineJoint.prototype.m_motorMass = null; +b2LineJoint.prototype.m_motorImpulse = null; +b2LineJoint.prototype.m_lowerTranslation = null; +b2LineJoint.prototype.m_upperTranslation = null; +b2LineJoint.prototype.m_maxMotorForce = null; +b2LineJoint.prototype.m_motorSpeed = null; +b2LineJoint.prototype.m_enableLimit = null; +b2LineJoint.prototype.m_enableMotor = null; +b2LineJoint.prototype.m_limitState = 0;var b2ContactSolver = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactSolver.prototype.__constructor = function() { +}; +b2ContactSolver.prototype.__varz = function() { + this.m_step = new b2TimeStep; + this.m_constraints = new Array +}; +b2ContactSolver.s_worldManifold = new b2WorldManifold; +b2ContactSolver.s_psm = new b2PositionSolverManifold; +b2ContactSolver.prototype.Initialize = function(step, contacts, contactCount, allocator) { + var contact; + this.m_step.Set(step); + this.m_allocator = allocator; + var i = 0; + var tVec; + var tMat; + this.m_constraintCount = contactCount; + while(this.m_constraints.length < this.m_constraintCount) { + this.m_constraints[this.m_constraints.length] = new b2ContactConstraint + } + for(i = 0;i < contactCount;++i) { + contact = contacts[i]; + var fixtureA = contact.m_fixtureA; + var fixtureB = contact.m_fixtureB; + var shapeA = fixtureA.m_shape; + var shapeB = fixtureB.m_shape; + var radiusA = shapeA.m_radius; + var radiusB = shapeB.m_radius; + var bodyA = fixtureA.m_body; + var bodyB = fixtureB.m_body; + var manifold = contact.GetManifold(); + var friction = b2Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction()); + var restitution = b2Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution()); + var vAX = bodyA.m_linearVelocity.x; + var vAY = bodyA.m_linearVelocity.y; + var vBX = bodyB.m_linearVelocity.x; + var vBY = bodyB.m_linearVelocity.y; + var wA = bodyA.m_angularVelocity; + var wB = bodyB.m_angularVelocity; + b2Settings.b2Assert(manifold.m_pointCount > 0); + b2ContactSolver.s_worldManifold.Initialize(manifold, bodyA.m_xf, radiusA, bodyB.m_xf, radiusB); + var normalX = b2ContactSolver.s_worldManifold.m_normal.x; + var normalY = b2ContactSolver.s_worldManifold.m_normal.y; + var cc = this.m_constraints[i]; + cc.bodyA = bodyA; + cc.bodyB = bodyB; + cc.manifold = manifold; + cc.normal.x = normalX; + cc.normal.y = normalY; + cc.pointCount = manifold.m_pointCount; + cc.friction = friction; + cc.restitution = restitution; + cc.localPlaneNormal.x = manifold.m_localPlaneNormal.x; + cc.localPlaneNormal.y = manifold.m_localPlaneNormal.y; + cc.localPoint.x = manifold.m_localPoint.x; + cc.localPoint.y = manifold.m_localPoint.y; + cc.radius = radiusA + radiusB; + cc.type = manifold.m_type; + for(var k = 0;k < cc.pointCount;++k) { + var cp = manifold.m_points[k]; + var ccp = cc.points[k]; + ccp.normalImpulse = cp.m_normalImpulse; + ccp.tangentImpulse = cp.m_tangentImpulse; + ccp.localPoint.SetV(cp.m_localPoint); + var rAX = ccp.rA.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyA.m_sweep.c.x; + var rAY = ccp.rA.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyA.m_sweep.c.y; + var rBX = ccp.rB.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyB.m_sweep.c.x; + var rBY = ccp.rB.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyB.m_sweep.c.y; + var rnA = rAX * normalY - rAY * normalX; + var rnB = rBX * normalY - rBY * normalX; + rnA *= rnA; + rnB *= rnB; + var kNormal = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rnA + bodyB.m_invI * rnB; + ccp.normalMass = 1 / kNormal; + var kEqualized = bodyA.m_mass * bodyA.m_invMass + bodyB.m_mass * bodyB.m_invMass; + kEqualized += bodyA.m_mass * bodyA.m_invI * rnA + bodyB.m_mass * bodyB.m_invI * rnB; + ccp.equalizedMass = 1 / kEqualized; + var tangentX = normalY; + var tangentY = -normalX; + var rtA = rAX * tangentY - rAY * tangentX; + var rtB = rBX * tangentY - rBY * tangentX; + rtA *= rtA; + rtB *= rtB; + var kTangent = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rtA + bodyB.m_invI * rtB; + ccp.tangentMass = 1 / kTangent; + ccp.velocityBias = 0; + var tX = vBX + -wB * rBY - vAX - -wA * rAY; + var tY = vBY + wB * rBX - vAY - wA * rAX; + var vRel = cc.normal.x * tX + cc.normal.y * tY; + if(vRel < -b2Settings.b2_velocityThreshold) { + ccp.velocityBias += -cc.restitution * vRel + } + } + if(cc.pointCount == 2) { + var ccp1 = cc.points[0]; + var ccp2 = cc.points[1]; + var invMassA = bodyA.m_invMass; + var invIA = bodyA.m_invI; + var invMassB = bodyB.m_invMass; + var invIB = bodyB.m_invI; + var rn1A = ccp1.rA.x * normalY - ccp1.rA.y * normalX; + var rn1B = ccp1.rB.x * normalY - ccp1.rB.y * normalX; + var rn2A = ccp2.rA.x * normalY - ccp2.rA.y * normalX; + var rn2B = ccp2.rB.x * normalY - ccp2.rB.y * normalX; + var k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B; + var k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B; + var k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B; + var k_maxConditionNumber = 100; + if(k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { + cc.K.col1.Set(k11, k12); + cc.K.col2.Set(k12, k22); + cc.K.GetInverse(cc.normalMass) + }else { + cc.pointCount = 1 + } + } + } +}; +b2ContactSolver.prototype.InitVelocityConstraints = function(step) { + var tVec; + var tVec2; + var tMat; + for(var i = 0;i < this.m_constraintCount;++i) { + var c = this.m_constraints[i]; + var bodyA = c.bodyA; + var bodyB = c.bodyB; + var invMassA = bodyA.m_invMass; + var invIA = bodyA.m_invI; + var invMassB = bodyB.m_invMass; + var invIB = bodyB.m_invI; + var normalX = c.normal.x; + var normalY = c.normal.y; + var tangentX = normalY; + var tangentY = -normalX; + var tX; + var j = 0; + var tCount = 0; + if(step.warmStarting) { + tCount = c.pointCount; + for(j = 0;j < tCount;++j) { + var ccp = c.points[j]; + ccp.normalImpulse *= step.dtRatio; + ccp.tangentImpulse *= step.dtRatio; + var PX = ccp.normalImpulse * normalX + ccp.tangentImpulse * tangentX; + var PY = ccp.normalImpulse * normalY + ccp.tangentImpulse * tangentY; + bodyA.m_angularVelocity -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); + bodyA.m_linearVelocity.x -= invMassA * PX; + bodyA.m_linearVelocity.y -= invMassA * PY; + bodyB.m_angularVelocity += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); + bodyB.m_linearVelocity.x += invMassB * PX; + bodyB.m_linearVelocity.y += invMassB * PY + } + }else { + tCount = c.pointCount; + for(j = 0;j < tCount;++j) { + var ccp2 = c.points[j]; + ccp2.normalImpulse = 0; + ccp2.tangentImpulse = 0 + } + } + } +}; +b2ContactSolver.prototype.SolveVelocityConstraints = function() { + var j = 0; + var ccp; + var rAX; + var rAY; + var rBX; + var rBY; + var dvX; + var dvY; + var vn; + var vt; + var lambda; + var maxFriction; + var newImpulse; + var PX; + var PY; + var dX; + var dY; + var P1X; + var P1Y; + var P2X; + var P2Y; + var tMat; + var tVec; + for(var i = 0;i < this.m_constraintCount;++i) { + var c = this.m_constraints[i]; + var bodyA = c.bodyA; + var bodyB = c.bodyB; + var wA = bodyA.m_angularVelocity; + var wB = bodyB.m_angularVelocity; + var vA = bodyA.m_linearVelocity; + var vB = bodyB.m_linearVelocity; + var invMassA = bodyA.m_invMass; + var invIA = bodyA.m_invI; + var invMassB = bodyB.m_invMass; + var invIB = bodyB.m_invI; + var normalX = c.normal.x; + var normalY = c.normal.y; + var tangentX = normalY; + var tangentY = -normalX; + var friction = c.friction; + var tX; + for(j = 0;j < c.pointCount;j++) { + ccp = c.points[j]; + dvX = vB.x - wB * ccp.rB.y - vA.x + wA * ccp.rA.y; + dvY = vB.y + wB * ccp.rB.x - vA.y - wA * ccp.rA.x; + vt = dvX * tangentX + dvY * tangentY; + lambda = ccp.tangentMass * -vt; + maxFriction = friction * ccp.normalImpulse; + newImpulse = b2Math.Clamp(ccp.tangentImpulse + lambda, -maxFriction, maxFriction); + lambda = newImpulse - ccp.tangentImpulse; + PX = lambda * tangentX; + PY = lambda * tangentY; + vA.x -= invMassA * PX; + vA.y -= invMassA * PY; + wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); + vB.x += invMassB * PX; + vB.y += invMassB * PY; + wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); + ccp.tangentImpulse = newImpulse + } + var tCount = c.pointCount; + if(c.pointCount == 1) { + ccp = c.points[0]; + dvX = vB.x + -wB * ccp.rB.y - vA.x - -wA * ccp.rA.y; + dvY = vB.y + wB * ccp.rB.x - vA.y - wA * ccp.rA.x; + vn = dvX * normalX + dvY * normalY; + lambda = -ccp.normalMass * (vn - ccp.velocityBias); + newImpulse = ccp.normalImpulse + lambda; + newImpulse = newImpulse > 0 ? newImpulse : 0; + lambda = newImpulse - ccp.normalImpulse; + PX = lambda * normalX; + PY = lambda * normalY; + vA.x -= invMassA * PX; + vA.y -= invMassA * PY; + wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); + vB.x += invMassB * PX; + vB.y += invMassB * PY; + wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); + ccp.normalImpulse = newImpulse + }else { + var cp1 = c.points[0]; + var cp2 = c.points[1]; + var aX = cp1.normalImpulse; + var aY = cp2.normalImpulse; + var dv1X = vB.x - wB * cp1.rB.y - vA.x + wA * cp1.rA.y; + var dv1Y = vB.y + wB * cp1.rB.x - vA.y - wA * cp1.rA.x; + var dv2X = vB.x - wB * cp2.rB.y - vA.x + wA * cp2.rA.y; + var dv2Y = vB.y + wB * cp2.rB.x - vA.y - wA * cp2.rA.x; + var vn1 = dv1X * normalX + dv1Y * normalY; + var vn2 = dv2X * normalX + dv2Y * normalY; + var bX = vn1 - cp1.velocityBias; + var bY = vn2 - cp2.velocityBias; + tMat = c.K; + bX -= tMat.col1.x * aX + tMat.col2.x * aY; + bY -= tMat.col1.y * aX + tMat.col2.y * aY; + var k_errorTol = 0.0010; + for(;;) { + tMat = c.normalMass; + var xX = -(tMat.col1.x * bX + tMat.col2.x * bY); + var xY = -(tMat.col1.y * bX + tMat.col2.y * bY); + if(xX >= 0 && xY >= 0) { + dX = xX - aX; + dY = xY - aY; + P1X = dX * normalX; + P1Y = dX * normalY; + P2X = dY * normalX; + P2Y = dY * normalY; + vA.x -= invMassA * (P1X + P2X); + vA.y -= invMassA * (P1Y + P2Y); + wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); + vB.x += invMassB * (P1X + P2X); + vB.y += invMassB * (P1Y + P2Y); + wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); + cp1.normalImpulse = xX; + cp2.normalImpulse = xY; + break + } + xX = -cp1.normalMass * bX; + xY = 0; + vn1 = 0; + vn2 = c.K.col1.y * xX + bY; + if(xX >= 0 && vn2 >= 0) { + dX = xX - aX; + dY = xY - aY; + P1X = dX * normalX; + P1Y = dX * normalY; + P2X = dY * normalX; + P2Y = dY * normalY; + vA.x -= invMassA * (P1X + P2X); + vA.y -= invMassA * (P1Y + P2Y); + wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); + vB.x += invMassB * (P1X + P2X); + vB.y += invMassB * (P1Y + P2Y); + wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); + cp1.normalImpulse = xX; + cp2.normalImpulse = xY; + break + } + xX = 0; + xY = -cp2.normalMass * bY; + vn1 = c.K.col2.x * xY + bX; + vn2 = 0; + if(xY >= 0 && vn1 >= 0) { + dX = xX - aX; + dY = xY - aY; + P1X = dX * normalX; + P1Y = dX * normalY; + P2X = dY * normalX; + P2Y = dY * normalY; + vA.x -= invMassA * (P1X + P2X); + vA.y -= invMassA * (P1Y + P2Y); + wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); + vB.x += invMassB * (P1X + P2X); + vB.y += invMassB * (P1Y + P2Y); + wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); + cp1.normalImpulse = xX; + cp2.normalImpulse = xY; + break + } + xX = 0; + xY = 0; + vn1 = bX; + vn2 = bY; + if(vn1 >= 0 && vn2 >= 0) { + dX = xX - aX; + dY = xY - aY; + P1X = dX * normalX; + P1Y = dX * normalY; + P2X = dY * normalX; + P2Y = dY * normalY; + vA.x -= invMassA * (P1X + P2X); + vA.y -= invMassA * (P1Y + P2Y); + wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); + vB.x += invMassB * (P1X + P2X); + vB.y += invMassB * (P1Y + P2Y); + wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); + cp1.normalImpulse = xX; + cp2.normalImpulse = xY; + break + } + break + } + } + bodyA.m_angularVelocity = wA; + bodyB.m_angularVelocity = wB + } +}; +b2ContactSolver.prototype.FinalizeVelocityConstraints = function() { + for(var i = 0;i < this.m_constraintCount;++i) { + var c = this.m_constraints[i]; + var m = c.manifold; + for(var j = 0;j < c.pointCount;++j) { + var point1 = m.m_points[j]; + var point2 = c.points[j]; + point1.m_normalImpulse = point2.normalImpulse; + point1.m_tangentImpulse = point2.tangentImpulse + } + } +}; +b2ContactSolver.prototype.SolvePositionConstraints = function(baumgarte) { + var minSeparation = 0; + for(var i = 0;i < this.m_constraintCount;i++) { + var c = this.m_constraints[i]; + var bodyA = c.bodyA; + var bodyB = c.bodyB; + var invMassA = bodyA.m_mass * bodyA.m_invMass; + var invIA = bodyA.m_mass * bodyA.m_invI; + var invMassB = bodyB.m_mass * bodyB.m_invMass; + var invIB = bodyB.m_mass * bodyB.m_invI; + b2ContactSolver.s_psm.Initialize(c); + var normal = b2ContactSolver.s_psm.m_normal; + for(var j = 0;j < c.pointCount;j++) { + var ccp = c.points[j]; + var point = b2ContactSolver.s_psm.m_points[j]; + var separation = b2ContactSolver.s_psm.m_separations[j]; + var rAX = point.x - bodyA.m_sweep.c.x; + var rAY = point.y - bodyA.m_sweep.c.y; + var rBX = point.x - bodyB.m_sweep.c.x; + var rBY = point.y - bodyB.m_sweep.c.y; + minSeparation = minSeparation < separation ? minSeparation : separation; + var C = b2Math.Clamp(baumgarte * (separation + b2Settings.b2_linearSlop), -b2Settings.b2_maxLinearCorrection, 0); + var impulse = -ccp.equalizedMass * C; + var PX = impulse * normal.x; + var PY = impulse * normal.y; + bodyA.m_sweep.c.x -= invMassA * PX; + bodyA.m_sweep.c.y -= invMassA * PY; + bodyA.m_sweep.a -= invIA * (rAX * PY - rAY * PX); + bodyA.SynchronizeTransform(); + bodyB.m_sweep.c.x += invMassB * PX; + bodyB.m_sweep.c.y += invMassB * PY; + bodyB.m_sweep.a += invIB * (rBX * PY - rBY * PX); + bodyB.SynchronizeTransform() + } + } + return minSeparation > -1.5 * b2Settings.b2_linearSlop +}; +b2ContactSolver.prototype.m_step = new b2TimeStep; +b2ContactSolver.prototype.m_allocator = null; +b2ContactSolver.prototype.m_constraints = new Array; +b2ContactSolver.prototype.m_constraintCount = 0;var b2Simplex = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Simplex.prototype.__constructor = function() { + this.m_vertices[0] = this.m_v1; + this.m_vertices[1] = this.m_v2; + this.m_vertices[2] = this.m_v3 +}; +b2Simplex.prototype.__varz = function() { + this.m_v1 = new b2SimplexVertex; + this.m_v2 = new b2SimplexVertex; + this.m_v3 = new b2SimplexVertex; + this.m_vertices = new Array(3) +}; +b2Simplex.prototype.ReadCache = function(cache, proxyA, transformA, proxyB, transformB) { + b2Settings.b2Assert(0 <= cache.count && cache.count <= 3); + var wALocal; + var wBLocal; + this.m_count = cache.count; + var vertices = this.m_vertices; + for(var i = 0;i < this.m_count;i++) { + var v = vertices[i]; + v.indexA = cache.indexA[i]; + v.indexB = cache.indexB[i]; + wALocal = proxyA.GetVertex(v.indexA); + wBLocal = proxyB.GetVertex(v.indexB); + v.wA = b2Math.MulX(transformA, wALocal); + v.wB = b2Math.MulX(transformB, wBLocal); + v.w = b2Math.SubtractVV(v.wB, v.wA); + v.a = 0 + } + if(this.m_count > 1) { + var metric1 = cache.metric; + var metric2 = this.GetMetric(); + if(metric2 < 0.5 * metric1 || 2 * metric1 < metric2 || metric2 < Number.MIN_VALUE) { + this.m_count = 0 + } + } + if(this.m_count == 0) { + v = vertices[0]; + v.indexA = 0; + v.indexB = 0; + wALocal = proxyA.GetVertex(0); + wBLocal = proxyB.GetVertex(0); + v.wA = b2Math.MulX(transformA, wALocal); + v.wB = b2Math.MulX(transformB, wBLocal); + v.w = b2Math.SubtractVV(v.wB, v.wA); + this.m_count = 1 + } +}; +b2Simplex.prototype.WriteCache = function(cache) { + cache.metric = this.GetMetric(); + cache.count = parseInt(this.m_count); + var vertices = this.m_vertices; + for(var i = 0;i < this.m_count;i++) { + cache.indexA[i] = parseInt(vertices[i].indexA); + cache.indexB[i] = parseInt(vertices[i].indexB) + } +}; +b2Simplex.prototype.GetSearchDirection = function() { + switch(this.m_count) { + case 1: + return this.m_v1.w.GetNegative(); + case 2: + var e12 = b2Math.SubtractVV(this.m_v2.w, this.m_v1.w); + var sgn = b2Math.CrossVV(e12, this.m_v1.w.GetNegative()); + if(sgn > 0) { + return b2Math.CrossFV(1, e12) + }else { + return b2Math.CrossVF(e12, 1) + } + ; + default: + b2Settings.b2Assert(false); + return new b2Vec2 + } +}; +b2Simplex.prototype.GetClosestPoint = function() { + switch(this.m_count) { + case 0: + b2Settings.b2Assert(false); + return new b2Vec2; + case 1: + return this.m_v1.w; + case 2: + return new b2Vec2(this.m_v1.a * this.m_v1.w.x + this.m_v2.a * this.m_v2.w.x, this.m_v1.a * this.m_v1.w.y + this.m_v2.a * this.m_v2.w.y); + default: + b2Settings.b2Assert(false); + return new b2Vec2 + } +}; +b2Simplex.prototype.GetWitnessPoints = function(pA, pB) { + switch(this.m_count) { + case 0: + b2Settings.b2Assert(false); + break; + case 1: + pA.SetV(this.m_v1.wA); + pB.SetV(this.m_v1.wB); + break; + case 2: + pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x; + pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y; + pB.x = this.m_v1.a * this.m_v1.wB.x + this.m_v2.a * this.m_v2.wB.x; + pB.y = this.m_v1.a * this.m_v1.wB.y + this.m_v2.a * this.m_v2.wB.y; + break; + case 3: + pB.x = pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x + this.m_v3.a * this.m_v3.wA.x; + pB.y = pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y + this.m_v3.a * this.m_v3.wA.y; + break; + default: + b2Settings.b2Assert(false); + break + } +}; +b2Simplex.prototype.GetMetric = function() { + switch(this.m_count) { + case 0: + b2Settings.b2Assert(false); return 0; - } - b2DynamicTreeBroadPhase.__implements = {}; - b2DynamicTreeBroadPhase.__implements[IBroadPhase] = true; - b2DynamicTreeNode.b2DynamicTreeNode = function () { - this.aabb = new b2AABB(); - }; - b2DynamicTreeNode.prototype.IsLeaf = function () { - return this.child1 == null; - } - b2DynamicTreePair.b2DynamicTreePair = function () {}; - b2Manifold.b2Manifold = function () { - this.m_pointCount = 0; - }; - b2Manifold.prototype.b2Manifold = function () { - this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - this.m_points[i] = new b2ManifoldPoint(); - } - this.m_localPlaneNormal = new b2Vec2(); - this.m_localPoint = new b2Vec2(); - } - b2Manifold.prototype.Reset = function () { - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Reset(); - } - this.m_localPlaneNormal.SetZero(); - this.m_localPoint.SetZero(); - this.m_type = 0; - this.m_pointCount = 0; - } - b2Manifold.prototype.Set = function (m) { - this.m_pointCount = m.m_pointCount; - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Set(m.m_points[i]); - } - this.m_localPlaneNormal.SetV(m.m_localPlaneNormal); - this.m_localPoint.SetV(m.m_localPoint); - this.m_type = m.m_type; - } - b2Manifold.prototype.Copy = function () { - var copy = new b2Manifold(); - copy.Set(this); - return copy; - } - _A2J_postDefs.push(function () { - Box2D.Collision.b2Manifold.e_circles = 0x0001; - Box2D.Collision.b2Manifold.prototype.e_circles = Box2D.Collision.b2Manifold.e_circles; - Box2D.Collision.b2Manifold.e_faceA = 0x0002; - Box2D.Collision.b2Manifold.prototype.e_faceA = Box2D.Collision.b2Manifold.e_faceA; - Box2D.Collision.b2Manifold.e_faceB = 0x0004; - Box2D.Collision.b2Manifold.prototype.e_faceB = Box2D.Collision.b2Manifold.e_faceB; - }); - b2ManifoldPoint.b2ManifoldPoint = function () { - this.m_localPoint = new b2Vec2(); - this.m_id = new b2ContactID(); - }; - b2ManifoldPoint.prototype.b2ManifoldPoint = function () { - this.Reset(); - } - b2ManifoldPoint.prototype.Reset = function () { - this.m_localPoint.SetZero(); - this.m_normalImpulse = 0.0; - this.m_tangentImpulse = 0.0; - this.m_id.key = 0; - } - b2ManifoldPoint.prototype.Set = function (m) { - this.m_localPoint.SetV(m.m_localPoint); - this.m_normalImpulse = m.m_normalImpulse; - this.m_tangentImpulse = m.m_tangentImpulse; - this.m_id.Set(m.m_id); - } - b2OBB.b2OBB = function () { - this.R = new b2Mat22(); - this.center = new b2Vec2(); - this.extents = new b2Vec2(); - }; - b2Pair.b2Pair = function () { - this.userData = null; - }; - b2Pair.prototype.SetBuffered = function () { - this.status |= b2Pair.e_pairBuffered; - } - b2Pair.prototype.ClearBuffered = function () { - this.status &= ~b2Pair.e_pairBuffered; - } - b2Pair.prototype.IsBuffered = function () { - return (this.status & b2Pair.e_pairBuffered) == b2Pair.e_pairBuffered; - } - b2Pair.prototype.SetRemoved = function () { - this.status |= b2Pair.e_pairRemoved; - } - b2Pair.prototype.ClearRemoved = function () { - this.status &= ~b2Pair.e_pairRemoved; - } - b2Pair.prototype.IsRemoved = function () { - return (this.status & b2Pair.e_pairRemoved) == b2Pair.e_pairRemoved; - } - b2Pair.prototype.SetFinal = function () { - this.status |= b2Pair.e_pairFinal; - } - b2Pair.prototype.IsFinal = function () { - return (this.status & b2Pair.e_pairFinal) == b2Pair.e_pairFinal; - } - _A2J_postDefs.push(function () { - Box2D.Collision.b2Pair.b2_nullProxy = parseInt(b2Settings.USHRT_MAX); - Box2D.Collision.b2Pair.prototype.b2_nullProxy = Box2D.Collision.b2Pair.b2_nullProxy; - Box2D.Collision.b2Pair.e_pairBuffered = 0x0001; - Box2D.Collision.b2Pair.prototype.e_pairBuffered = Box2D.Collision.b2Pair.e_pairBuffered; - Box2D.Collision.b2Pair.e_pairRemoved = 0x0002; - Box2D.Collision.b2Pair.prototype.e_pairRemoved = Box2D.Collision.b2Pair.e_pairRemoved; - Box2D.Collision.b2Pair.e_pairFinal = 0x0004; - Box2D.Collision.b2Pair.prototype.e_pairFinal = Box2D.Collision.b2Pair.e_pairFinal; - }); - b2PairManager.b2PairManager = function () {}; - b2PairManager.prototype.b2PairManager = function () { - this.m_pairs = new Array(); - this.m_pairBuffer = new Array(); - this.m_pairCount = 0; - this.m_pairBufferCount = 0; - this.m_freePair = null; - } - b2PairManager.prototype.Initialize = function (broadPhase) { - this.m_broadPhase = broadPhase; - } - b2PairManager.prototype.AddBufferedPair = function (proxy1, proxy2) { - var pair = this.AddPair(proxy1, proxy2); - if (pair.IsBuffered() == false) { - pair.SetBuffered(); - this.m_pairBuffer[this.m_pairBufferCount] = pair; - ++this.m_pairBufferCount; - } - pair.ClearRemoved(); - if (b2BroadPhase.s_validate) { - this.ValidateBuffer(); - } - } - b2PairManager.prototype.RemoveBufferedPair = function (proxy1, proxy2) { - var pair = this.Find(proxy1, proxy2); - if (pair == null) { - return; - } - if (pair.IsBuffered() == false) { - pair.SetBuffered(); - this.m_pairBuffer[this.m_pairBufferCount] = pair; - ++this.m_pairBufferCount; - } - pair.SetRemoved(); - if (b2BroadPhase.s_validate) { - this.ValidateBuffer(); - } - } - b2PairManager.prototype.Commit = function (callback) { - var i = 0; - var removeCount = 0; - for (i = 0; - i < this.m_pairBufferCount; ++i) { - var pair = this.m_pairBuffer[i]; - pair.ClearBuffered(); - var proxy1 = pair.proxy1; - var proxy2 = pair.proxy2; - if (pair.IsRemoved()) {} else { - if (pair.IsFinal() == false) { - callback(proxy1.userData, proxy2.userData); - } - } - } - this.m_pairBufferCount = 0; - if (b2BroadPhase.s_validate) { - this.ValidateTable(); - } - } - b2PairManager.prototype.AddPair = function (proxy1, proxy2) { - var pair = proxy1.pairs[proxy2]; - if (pair != null) return pair; - if (this.m_freePair == null) { - this.m_freePair = new b2Pair(); - this.m_pairs.push(this.m_freePair); - } - pair = this.m_freePair; - this.m_freePair = pair.next; - pair.proxy1 = proxy1; - pair.proxy2 = proxy2; - pair.status = 0; - pair.userData = null; - pair.next = null; - proxy1.pairs[proxy2] = pair; - proxy2.pairs[proxy1] = pair; - ++this.m_pairCount; - return pair; - } - b2PairManager.prototype.RemovePair = function (proxy1, proxy2) { - var pair = proxy1.pairs[proxy2]; - if (pair == null) { - return null; - } - var userData = pair.userData; - delete proxy1.pairs[proxy2]; - delete proxy2.pairs[proxy1]; - pair.next = this.m_freePair; - pair.proxy1 = null; - pair.proxy2 = null; - pair.userData = null; - pair.status = 0; - this.m_freePair = pair; - --this.m_pairCount; - return userData; - } - b2PairManager.prototype.Find = function (proxy1, proxy2) { - return proxy1.pairs[proxy2]; - } - b2PairManager.prototype.ValidateBuffer = function () {} - b2PairManager.prototype.ValidateTable = function () {} - b2Point.b2Point = function () { - this.p = new b2Vec2(); - }; - b2Point.prototype.Support = function (xf, vX, vY) { - if (vX === undefined) vX = 0; - if (vY === undefined) vY = 0; - return this.p; - } - b2Point.prototype.GetFirstVertex = function (xf) { - return this.p; - } - b2Proxy.b2Proxy = function () { - this.lowerBounds = new Vector_a2j_Number(2); - this.upperBounds = new Vector_a2j_Number(2); - this.pairs = new Dictionary(); - this.userData = null; - }; - b2Proxy.prototype.IsValid = function () { - return this.overlapCount != b2BroadPhase.b2_invalid; - } - b2RayCastInput.b2RayCastInput = function () { - this.p1 = new b2Vec2(); - this.p2 = new b2Vec2(); - }; - b2RayCastInput.prototype.b2RayCastInput = function (p1, p2, maxFraction) { - if (p1 === undefined) p1 = null; - if (p2 === undefined) p2 = null; - if (maxFraction === undefined) maxFraction = 1; - if (p1) this.p1.SetV(p1); - if (p2) this.p2.SetV(p2); - this.maxFraction = maxFraction; - } - b2RayCastOutput.b2RayCastOutput = function () { - this.normal = new b2Vec2(); - }; - b2Segment.b2Segment = function () { - this.p1 = new b2Vec2(); - this.p2 = new b2Vec2(); - }; - b2Segment.prototype.TestSegment = function (lambda, normal, segment, maxLambda) { - if (maxLambda === undefined) maxLambda = 0; - var s = segment.p1; - var rX = segment.p2.x - s.x; - var rY = segment.p2.y - s.y; - var dX = this.p2.x - this.p1.x; - var dY = this.p2.y - this.p1.y; - var nX = dY; - var nY = (-dX); - var k_slop = 100.0 * Number.MIN_VALUE; - var denom = (-(rX * nX + rY * nY)); - if (denom > k_slop) { - var bX = s.x - this.p1.x; - var bY = s.y - this.p1.y; - var a = (bX * nX + bY * nY); - if (0.0 <= a && a <= maxLambda * denom) { - var mu2 = (-rX * bY) + rY * bX; - if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) { - a /= denom; - var nLen = Math.sqrt(nX * nX + nY * nY); - nX /= nLen; - nY /= nLen; - lambda[0] = a; - normal.Set(nX, nY); - return true; - } - } - } - return false; - } - b2Segment.prototype.Extend = function (aabb) { - this.ExtendForward(aabb); - this.ExtendBackward(aabb); - } - b2Segment.prototype.ExtendForward = function (aabb) { - var dX = this.p2.x - this.p1.x; - var dY = this.p2.y - this.p1.y; - var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p1.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p1.x) / dX : Number.POSITIVE_INFINITY, - dY > 0 ? (aabb.upperBound.y - this.p1.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p1.y) / dY : Number.POSITIVE_INFINITY); - this.p2.x = this.p1.x + dX * lambda; - this.p2.y = this.p1.y + dY * lambda; - } - b2Segment.prototype.ExtendBackward = function (aabb) { - var dX = (-this.p2.x) + this.p1.x; - var dY = (-this.p2.y) + this.p1.y; - var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p2.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p2.x) / dX : Number.POSITIVE_INFINITY, - dY > 0 ? (aabb.upperBound.y - this.p2.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p2.y) / dY : Number.POSITIVE_INFINITY); - this.p1.x = this.p2.x + dX * lambda; - this.p1.y = this.p2.y + dY * lambda; - } - b2SeparationFunction.b2SeparationFunction = function () { - this.m_localPoint = new b2Vec2(); - this.m_axis = new b2Vec2(); - }; - b2SeparationFunction.prototype.Initialize = function (cache, proxyA, transformA, proxyB, transformB) { - this.m_proxyA = proxyA; - this.m_proxyB = proxyB; - var count = parseInt(cache.count); - b2Settings.b2Assert(0 < count && count < 3); - var localPointA; - var localPointA1; - var localPointA2; - var localPointB; - var localPointB1; - var localPointB2; - var pointAX = 0; - var pointAY = 0; - var pointBX = 0; - var pointBY = 0; - var normalX = 0; - var normalY = 0; - var tMat; - var tVec; - var s = 0; - var sgn = 0; - if (count == 1) { - this.m_type = b2SeparationFunction.e_points; - localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); - localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); - tVec = localPointA; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointB; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_axis.x = pointBX - pointAX; - this.m_axis.y = pointBY - pointAY; - this.m_axis.Normalize(); - } - else if (cache.indexB[0] == cache.indexB[1]) { - this.m_type = b2SeparationFunction.e_faceA; - localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); - localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); - localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); - this.m_localPoint.x = 0.5 * (localPointA1.x + localPointA2.x); - this.m_localPoint.y = 0.5 * (localPointA1.y + localPointA2.y); - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0); - this.m_axis.Normalize(); - tVec = this.m_axis; - tMat = transformA.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointB; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - s = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; - if (s < 0.0) { - this.m_axis.NegativeSelf(); - } - } - else if (cache.indexA[0] == cache.indexA[0]) { - this.m_type = b2SeparationFunction.e_faceB; - localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); - localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); - localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); - this.m_localPoint.x = 0.5 * (localPointB1.x + localPointB2.x); - this.m_localPoint.y = 0.5 * (localPointB1.y + localPointB2.y); - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0); - this.m_axis.Normalize(); - tVec = this.m_axis; - tMat = transformB.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointA; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - s = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; - if (s < 0.0) { - this.m_axis.NegativeSelf(); - } - } - else { - localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); - localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); - localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); - localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); - var pA = b2Math.MulX(transformA, localPointA); - var dA = b2Math.MulMV(transformA.R, b2Math.SubtractVV(localPointA2, localPointA1)); - var pB = b2Math.MulX(transformB, localPointB); - var dB = b2Math.MulMV(transformB.R, b2Math.SubtractVV(localPointB2, localPointB1)); - var a = dA.x * dA.x + dA.y * dA.y; - var e = dB.x * dB.x + dB.y * dB.y; - var r = b2Math.SubtractVV(dB, dA); - var c = dA.x * r.x + dA.y * r.y; - var f = dB.x * r.x + dB.y * r.y; - var b = dA.x * dB.x + dA.y * dB.y; - var denom = a * e - b * b; - s = 0.0; - if (denom != 0.0) { - s = b2Math.Clamp((b * f - c * e) / denom, 0.0, 1.0); - } - var t = (b * s + f) / e; - if (t < 0.0) { - t = 0.0; - s = b2Math.Clamp((b - c) / a, 0.0, 1.0); - } - localPointA = new b2Vec2(); - localPointA.x = localPointA1.x + s * (localPointA2.x - localPointA1.x); - localPointA.y = localPointA1.y + s * (localPointA2.y - localPointA1.y); - localPointB = new b2Vec2(); - localPointB.x = localPointB1.x + s * (localPointB2.x - localPointB1.x); - localPointB.y = localPointB1.y + s * (localPointB2.y - localPointB1.y); - if (s == 0.0 || s == 1.0) { - this.m_type = b2SeparationFunction.e_faceB; - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0); - this.m_axis.Normalize(); - this.m_localPoint = localPointB; - tVec = this.m_axis; - tMat = transformB.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointA; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - sgn = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; - if (s < 0.0) { - this.m_axis.NegativeSelf(); - } - } - else { - this.m_type = b2SeparationFunction.e_faceA; - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0); - this.m_localPoint = localPointA; - tVec = this.m_axis; - tMat = transformA.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointB; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - sgn = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; - if (s < 0.0) { - this.m_axis.NegativeSelf(); - } - } - } - } - b2SeparationFunction.prototype.Evaluate = function (transformA, transformB) { - var axisA; - var axisB; - var localPointA; - var localPointB; - var pointA; - var pointB; - var seperation = 0; - var normal; - switch (this.m_type) { - case b2SeparationFunction.e_points: - { - axisA = b2Math.MulTMV(transformA.R, this.m_axis); - axisB = b2Math.MulTMV(transformB.R, this.m_axis.GetNegative()); - localPointA = this.m_proxyA.GetSupportVertex(axisA); - localPointB = this.m_proxyB.GetSupportVertex(axisB); - pointA = b2Math.MulX(transformA, localPointA); - pointB = b2Math.MulX(transformB, localPointB); - seperation = (pointB.x - pointA.x) * this.m_axis.x + (pointB.y - pointA.y) * this.m_axis.y; - return seperation; - } - case b2SeparationFunction.e_faceA: - { - normal = b2Math.MulMV(transformA.R, this.m_axis); - pointA = b2Math.MulX(transformA, this.m_localPoint); - axisB = b2Math.MulTMV(transformB.R, normal.GetNegative()); - localPointB = this.m_proxyB.GetSupportVertex(axisB); - pointB = b2Math.MulX(transformB, localPointB); - seperation = (pointB.x - pointA.x) * normal.x + (pointB.y - pointA.y) * normal.y; - return seperation; - } - case b2SeparationFunction.e_faceB: - { - normal = b2Math.MulMV(transformB.R, this.m_axis); - pointB = b2Math.MulX(transformB, this.m_localPoint); - axisA = b2Math.MulTMV(transformA.R, normal.GetNegative()); - localPointA = this.m_proxyA.GetSupportVertex(axisA); - pointA = b2Math.MulX(transformA, localPointA); - seperation = (pointA.x - pointB.x) * normal.x + (pointA.y - pointB.y) * normal.y; - return seperation; - } - default: - b2Settings.b2Assert(false); - return 0.0; - } - } - _A2J_postDefs.push(function () { - Box2D.Collision.b2SeparationFunction.e_points = 0x01; - Box2D.Collision.b2SeparationFunction.prototype.e_points = Box2D.Collision.b2SeparationFunction.e_points; - Box2D.Collision.b2SeparationFunction.e_faceA = 0x02; - Box2D.Collision.b2SeparationFunction.prototype.e_faceA = Box2D.Collision.b2SeparationFunction.e_faceA; - Box2D.Collision.b2SeparationFunction.e_faceB = 0x04; - Box2D.Collision.b2SeparationFunction.prototype.e_faceB = Box2D.Collision.b2SeparationFunction.e_faceB; - }); - b2Simplex.b2Simplex = function () { - this.m_v1 = new b2SimplexVertex(); - this.m_v2 = new b2SimplexVertex(); - this.m_v3 = new b2SimplexVertex(); - this.m_vertices = new Vector(3); - }; - b2Simplex.prototype.b2Simplex = function () { - this.m_vertices[0] = this.m_v1; - this.m_vertices[1] = this.m_v2; - this.m_vertices[2] = this.m_v3; - } - b2Simplex.prototype.ReadCache = function (cache, proxyA, transformA, proxyB, transformB) { - b2Settings.b2Assert(0 <= cache.count && cache.count <= 3); - var wALocal; - var wBLocal; - this.m_count = cache.count; - var vertices = this.m_vertices; - for (var i = 0; i < this.m_count; i++) { - var v = vertices[i]; - v.indexA = cache.indexA[i]; - v.indexB = cache.indexB[i]; - wALocal = proxyA.GetVertex(v.indexA); - wBLocal = proxyB.GetVertex(v.indexB); - v.wA = b2Math.MulX(transformA, wALocal); - v.wB = b2Math.MulX(transformB, wBLocal); - v.w = b2Math.SubtractVV(v.wB, v.wA); - v.a = 0; - } - if (this.m_count > 1) { - var metric1 = cache.metric; - var metric2 = this.GetMetric(); - if (metric2 < .5 * metric1 || 2.0 * metric1 < metric2 || metric2 < Number.MIN_VALUE) { - this.m_count = 0; - } - } - if (this.m_count == 0) { - v = vertices[0]; - v.indexA = 0; - v.indexB = 0; - wALocal = proxyA.GetVertex(0); - wBLocal = proxyB.GetVertex(0); - v.wA = b2Math.MulX(transformA, wALocal); - v.wB = b2Math.MulX(transformB, wBLocal); - v.w = b2Math.SubtractVV(v.wB, v.wA); - this.m_count = 1; - } - } - b2Simplex.prototype.WriteCache = function (cache) { - cache.metric = this.GetMetric(); - cache.count = a2j.parseUInt(this.m_count); - var vertices = this.m_vertices; - for (var i = 0; i < this.m_count; i++) { - cache.indexA[i] = a2j.parseUInt(vertices[i].indexA); - cache.indexB[i] = a2j.parseUInt(vertices[i].indexB); - } - } - b2Simplex.prototype.GetSearchDirection = function () { - switch (this.m_count) { - case 1: - return this.m_v1.w.GetNegative(); - case 2: - { - var e12 = b2Math.SubtractVV(this.m_v2.w, this.m_v1.w); - var sgn = b2Math.CrossVV(e12, this.m_v1.w.GetNegative()); - if (sgn > 0.0) { - return b2Math.CrossFV(1.0, e12); - } - else { - return b2Math.CrossVF(e12, 1.0); - } - } - default: - b2Settings.b2Assert(false); - return new b2Vec2(); - } - } - b2Simplex.prototype.GetClosestPoint = function () { - switch (this.m_count) { - case 0: - b2Settings.b2Assert(false); - return new b2Vec2(); - case 1: - return this.m_v1.w; - case 2: - return new b2Vec2(this.m_v1.a * this.m_v1.w.x + this.m_v2.a * this.m_v2.w.x, this.m_v1.a * this.m_v1.w.y + this.m_v2.a * this.m_v2.w.y); - default: - b2Settings.b2Assert(false); - return new b2Vec2(); - } - } - b2Simplex.prototype.GetWitnessPoints = function (pA, pB) { - switch (this.m_count) { - case 0: - b2Settings.b2Assert(false); - break; - case 1: - pA.SetV(this.m_v1.wA); - pB.SetV(this.m_v1.wB); - break; - case 2: - pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x; - pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y; - pB.x = this.m_v1.a * this.m_v1.wB.x + this.m_v2.a * this.m_v2.wB.x; - pB.y = this.m_v1.a * this.m_v1.wB.y + this.m_v2.a * this.m_v2.wB.y; - break; - case 3: - pB.x = pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x + this.m_v3.a * this.m_v3.wA.x; - pB.y = pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y + this.m_v3.a * this.m_v3.wA.y; - break; - default: - b2Settings.b2Assert(false); - break; - } - } - b2Simplex.prototype.GetMetric = function () { - switch (this.m_count) { - case 0: - b2Settings.b2Assert(false); - return 0.0; + case 1: + return 0; + case 2: + return b2Math.SubtractVV(this.m_v1.w, this.m_v2.w).Length(); + case 3: + return b2Math.CrossVV(b2Math.SubtractVV(this.m_v2.w, this.m_v1.w), b2Math.SubtractVV(this.m_v3.w, this.m_v1.w)); + default: + b2Settings.b2Assert(false); + return 0 + } +}; +b2Simplex.prototype.Solve2 = function() { + var w1 = this.m_v1.w; + var w2 = this.m_v2.w; + var e12 = b2Math.SubtractVV(w2, w1); + var d12_2 = -(w1.x * e12.x + w1.y * e12.y); + if(d12_2 <= 0) { + this.m_v1.a = 1; + this.m_count = 1; + return + } + var d12_1 = w2.x * e12.x + w2.y * e12.y; + if(d12_1 <= 0) { + this.m_v2.a = 1; + this.m_count = 1; + this.m_v1.Set(this.m_v2); + return + } + var inv_d12 = 1 / (d12_1 + d12_2); + this.m_v1.a = d12_1 * inv_d12; + this.m_v2.a = d12_2 * inv_d12; + this.m_count = 2 +}; +b2Simplex.prototype.Solve3 = function() { + var w1 = this.m_v1.w; + var w2 = this.m_v2.w; + var w3 = this.m_v3.w; + var e12 = b2Math.SubtractVV(w2, w1); + var w1e12 = b2Math.Dot(w1, e12); + var w2e12 = b2Math.Dot(w2, e12); + var d12_1 = w2e12; + var d12_2 = -w1e12; + var e13 = b2Math.SubtractVV(w3, w1); + var w1e13 = b2Math.Dot(w1, e13); + var w3e13 = b2Math.Dot(w3, e13); + var d13_1 = w3e13; + var d13_2 = -w1e13; + var e23 = b2Math.SubtractVV(w3, w2); + var w2e23 = b2Math.Dot(w2, e23); + var w3e23 = b2Math.Dot(w3, e23); + var d23_1 = w3e23; + var d23_2 = -w2e23; + var n123 = b2Math.CrossVV(e12, e13); + var d123_1 = n123 * b2Math.CrossVV(w2, w3); + var d123_2 = n123 * b2Math.CrossVV(w3, w1); + var d123_3 = n123 * b2Math.CrossVV(w1, w2); + if(d12_2 <= 0 && d13_2 <= 0) { + this.m_v1.a = 1; + this.m_count = 1; + return + } + if(d12_1 > 0 && d12_2 > 0 && d123_3 <= 0) { + var inv_d12 = 1 / (d12_1 + d12_2); + this.m_v1.a = d12_1 * inv_d12; + this.m_v2.a = d12_2 * inv_d12; + this.m_count = 2; + return + } + if(d13_1 > 0 && d13_2 > 0 && d123_2 <= 0) { + var inv_d13 = 1 / (d13_1 + d13_2); + this.m_v1.a = d13_1 * inv_d13; + this.m_v3.a = d13_2 * inv_d13; + this.m_count = 2; + this.m_v2.Set(this.m_v3); + return + } + if(d12_1 <= 0 && d23_2 <= 0) { + this.m_v2.a = 1; + this.m_count = 1; + this.m_v1.Set(this.m_v2); + return + } + if(d13_1 <= 0 && d23_1 <= 0) { + this.m_v3.a = 1; + this.m_count = 1; + this.m_v1.Set(this.m_v3); + return + } + if(d23_1 > 0 && d23_2 > 0 && d123_1 <= 0) { + var inv_d23 = 1 / (d23_1 + d23_2); + this.m_v2.a = d23_1 * inv_d23; + this.m_v3.a = d23_2 * inv_d23; + this.m_count = 2; + this.m_v1.Set(this.m_v3); + return + } + var inv_d123 = 1 / (d123_1 + d123_2 + d123_3); + this.m_v1.a = d123_1 * inv_d123; + this.m_v2.a = d123_2 * inv_d123; + this.m_v3.a = d123_3 * inv_d123; + this.m_count = 3 +}; +b2Simplex.prototype.m_v1 = new b2SimplexVertex; +b2Simplex.prototype.m_v2 = new b2SimplexVertex; +b2Simplex.prototype.m_v3 = new b2SimplexVertex; +b2Simplex.prototype.m_vertices = new Array(3); +b2Simplex.prototype.m_count = 0;var b2WeldJoint = function() { + b2Joint.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2WeldJoint.prototype, b2Joint.prototype); +b2WeldJoint.prototype._super = b2Joint.prototype; +b2WeldJoint.prototype.__constructor = function(def) { + this._super.__constructor.apply(this, [def]); + this.m_localAnchorA.SetV(def.localAnchorA); + this.m_localAnchorB.SetV(def.localAnchorB); + this.m_referenceAngle = def.referenceAngle; + this.m_impulse.SetZero(); + this.m_mass = new b2Mat33 +}; +b2WeldJoint.prototype.__varz = function() { + this.m_localAnchorA = new b2Vec2; + this.m_localAnchorB = new b2Vec2; + this.m_impulse = new b2Vec3; + this.m_mass = new b2Mat33 +}; +b2WeldJoint.prototype.InitVelocityConstraints = function(step) { + var tMat; + var tX; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * rAX + tMat.col2.x * rAY; + rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * rBX + tMat.col2.x * rBY; + rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; + rBX = tX; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; + this.m_mass.col2.x = -rAY * rAX * iA - rBY * rBX * iB; + this.m_mass.col3.x = -rAY * iA - rBY * iB; + this.m_mass.col1.y = this.m_mass.col2.x; + this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; + this.m_mass.col3.y = rAX * iA + rBX * iB; + this.m_mass.col1.z = this.m_mass.col3.x; + this.m_mass.col2.z = this.m_mass.col3.y; + this.m_mass.col3.z = iA + iB; + if(step.warmStarting) { + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + this.m_impulse.z *= step.dtRatio; + bA.m_linearVelocity.x -= mA * this.m_impulse.x; + bA.m_linearVelocity.y -= mA * this.m_impulse.y; + bA.m_angularVelocity -= iA * (rAX * this.m_impulse.y - rAY * this.m_impulse.x + this.m_impulse.z); + bB.m_linearVelocity.x += mB * this.m_impulse.x; + bB.m_linearVelocity.y += mB * this.m_impulse.y; + bB.m_angularVelocity += iB * (rBX * this.m_impulse.y - rBY * this.m_impulse.x + this.m_impulse.z) + }else { + this.m_impulse.SetZero() + } +}; +b2WeldJoint.prototype.SolveVelocityConstraints = function(step) { + var tMat; + var tX; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var vA = bA.m_linearVelocity; + var wA = bA.m_angularVelocity; + var vB = bB.m_linearVelocity; + var wB = bB.m_angularVelocity; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * rAX + tMat.col2.x * rAY; + rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * rBX + tMat.col2.x * rBY; + rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; + rBX = tX; + var Cdot1X = vB.x - wB * rBY - vA.x + wA * rAY; + var Cdot1Y = vB.y + wB * rBX - vA.y - wA * rAX; + var Cdot2 = wB - wA; + var impulse = new b2Vec3; + this.m_mass.Solve33(impulse, -Cdot1X, -Cdot1Y, -Cdot2); + this.m_impulse.Add(impulse); + vA.x -= mA * impulse.x; + vA.y -= mA * impulse.y; + wA -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); + vB.x += mB * impulse.x; + vB.y += mB * impulse.y; + wB += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); + bA.m_angularVelocity = wA; + bB.m_angularVelocity = wB +}; +b2WeldJoint.prototype.SolvePositionConstraints = function(baumgarte) { + var tMat; + var tX; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * rAX + tMat.col2.x * rAY; + rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * rBX + tMat.col2.x * rBY; + rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; + rBX = tX; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + var C1X = bB.m_sweep.c.x + rBX - bA.m_sweep.c.x - rAX; + var C1Y = bB.m_sweep.c.y + rBY - bA.m_sweep.c.y - rAY; + var C2 = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; + var k_allowedStretch = 10 * b2Settings.b2_linearSlop; + var positionError = Math.sqrt(C1X * C1X + C1Y * C1Y); + var angularError = b2Math.Abs(C2); + if(positionError > k_allowedStretch) { + iA *= 1; + iB *= 1 + } + this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; + this.m_mass.col2.x = -rAY * rAX * iA - rBY * rBX * iB; + this.m_mass.col3.x = -rAY * iA - rBY * iB; + this.m_mass.col1.y = this.m_mass.col2.x; + this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; + this.m_mass.col3.y = rAX * iA + rBX * iB; + this.m_mass.col1.z = this.m_mass.col3.x; + this.m_mass.col2.z = this.m_mass.col3.y; + this.m_mass.col3.z = iA + iB; + var impulse = new b2Vec3; + this.m_mass.Solve33(impulse, -C1X, -C1Y, -C2); + bA.m_sweep.c.x -= mA * impulse.x; + bA.m_sweep.c.y -= mA * impulse.y; + bA.m_sweep.a -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); + bB.m_sweep.c.x += mB * impulse.x; + bB.m_sweep.c.y += mB * impulse.y; + bB.m_sweep.a += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop +}; +b2WeldJoint.prototype.GetAnchorA = function() { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA) +}; +b2WeldJoint.prototype.GetAnchorB = function() { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB) +}; +b2WeldJoint.prototype.GetReactionForce = function(inv_dt) { + return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y) +}; +b2WeldJoint.prototype.GetReactionTorque = function(inv_dt) { + return inv_dt * this.m_impulse.z +}; +b2WeldJoint.prototype.m_localAnchorA = new b2Vec2; +b2WeldJoint.prototype.m_localAnchorB = new b2Vec2; +b2WeldJoint.prototype.m_referenceAngle = null; +b2WeldJoint.prototype.m_impulse = new b2Vec3; +b2WeldJoint.prototype.m_mass = new b2Mat33;var b2Math = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Math.prototype.__constructor = function() { +}; +b2Math.prototype.__varz = function() { +}; +b2Math.IsValid = function(x) { + return isFinite(x) +}; +b2Math.Dot = function(a, b) { + return a.x * b.x + a.y * b.y +}; +b2Math.CrossVV = function(a, b) { + return a.x * b.y - a.y * b.x +}; +b2Math.CrossVF = function(a, s) { + var v = new b2Vec2(s * a.y, -s * a.x); + return v +}; +b2Math.CrossFV = function(s, a) { + var v = new b2Vec2(-s * a.y, s * a.x); + return v +}; +b2Math.MulMV = function(A, v) { + var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y); + return u +}; +b2Math.MulTMV = function(A, v) { + var u = new b2Vec2(b2Math.Dot(v, A.col1), b2Math.Dot(v, A.col2)); + return u +}; +b2Math.MulX = function(T, v) { + var a = b2Math.MulMV(T.R, v); + a.x += T.position.x; + a.y += T.position.y; + return a +}; +b2Math.MulXT = function(T, v) { + var a = b2Math.SubtractVV(v, T.position); + var tX = a.x * T.R.col1.x + a.y * T.R.col1.y; + a.y = a.x * T.R.col2.x + a.y * T.R.col2.y; + a.x = tX; + return a +}; +b2Math.AddVV = function(a, b) { + var v = new b2Vec2(a.x + b.x, a.y + b.y); + return v +}; +b2Math.SubtractVV = function(a, b) { + var v = new b2Vec2(a.x - b.x, a.y - b.y); + return v +}; +b2Math.Distance = function(a, b) { + var cX = a.x - b.x; + var cY = a.y - b.y; + return Math.sqrt(cX * cX + cY * cY) +}; +b2Math.DistanceSquared = function(a, b) { + var cX = a.x - b.x; + var cY = a.y - b.y; + return cX * cX + cY * cY +}; +b2Math.MulFV = function(s, a) { + var v = new b2Vec2(s * a.x, s * a.y); + return v +}; +b2Math.AddMM = function(A, B) { + var C = b2Mat22.FromVV(b2Math.AddVV(A.col1, B.col1), b2Math.AddVV(A.col2, B.col2)); + return C +}; +b2Math.MulMM = function(A, B) { + var C = b2Mat22.FromVV(b2Math.MulMV(A, B.col1), b2Math.MulMV(A, B.col2)); + return C +}; +b2Math.MulTMM = function(A, B) { + var c1 = new b2Vec2(b2Math.Dot(A.col1, B.col1), b2Math.Dot(A.col2, B.col1)); + var c2 = new b2Vec2(b2Math.Dot(A.col1, B.col2), b2Math.Dot(A.col2, B.col2)); + var C = b2Mat22.FromVV(c1, c2); + return C +}; +b2Math.Abs = function(a) { + return a > 0 ? a : -a +}; +b2Math.AbsV = function(a) { + var b = new b2Vec2(b2Math.Abs(a.x), b2Math.Abs(a.y)); + return b +}; +b2Math.AbsM = function(A) { + var B = b2Mat22.FromVV(b2Math.AbsV(A.col1), b2Math.AbsV(A.col2)); + return B +}; +b2Math.Min = function(a, b) { + return a < b ? a : b +}; +b2Math.MinV = function(a, b) { + var c = new b2Vec2(b2Math.Min(a.x, b.x), b2Math.Min(a.y, b.y)); + return c +}; +b2Math.Max = function(a, b) { + return a > b ? a : b +}; +b2Math.MaxV = function(a, b) { + var c = new b2Vec2(b2Math.Max(a.x, b.x), b2Math.Max(a.y, b.y)); + return c +}; +b2Math.Clamp = function(a, low, high) { + return a < low ? low : a > high ? high : a +}; +b2Math.ClampV = function(a, low, high) { + return b2Math.MaxV(low, b2Math.MinV(a, high)) +}; +b2Math.Swap = function(a, b) { + var tmp = a[0]; + a[0] = b[0]; + b[0] = tmp +}; +b2Math.Random = function() { + return Math.random() * 2 - 1 +}; +b2Math.RandomRange = function(lo, hi) { + var r = Math.random(); + r = (hi - lo) * r + lo; + return r +}; +b2Math.NextPowerOfTwo = function(x) { + x |= x >> 1 & 2147483647; + x |= x >> 2 & 1073741823; + x |= x >> 4 & 268435455; + x |= x >> 8 & 16777215; + x |= x >> 16 & 65535; + return x + 1 +}; +b2Math.IsPowerOfTwo = function(x) { + var result = x > 0 && (x & x - 1) == 0; + return result +}; +b2Math.b2Vec2_zero = new b2Vec2(0, 0); +b2Math.b2Mat22_identity = b2Mat22.FromVV(new b2Vec2(1, 0), new b2Vec2(0, 1)); +b2Math.b2Transform_identity = new b2Transform(b2Math.b2Vec2_zero, b2Math.b2Mat22_identity);var b2PulleyJoint = function() { + b2Joint.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2PulleyJoint.prototype, b2Joint.prototype); +b2PulleyJoint.prototype._super = b2Joint.prototype; +b2PulleyJoint.prototype.__constructor = function(def) { + this._super.__constructor.apply(this, [def]); + var tMat; + var tX; + var tY; + this.m_ground = this.m_bodyA.m_world.m_groundBody; + this.m_groundAnchor1.x = def.groundAnchorA.x - this.m_ground.m_xf.position.x; + this.m_groundAnchor1.y = def.groundAnchorA.y - this.m_ground.m_xf.position.y; + this.m_groundAnchor2.x = def.groundAnchorB.x - this.m_ground.m_xf.position.x; + this.m_groundAnchor2.y = def.groundAnchorB.y - this.m_ground.m_xf.position.y; + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_ratio = def.ratio; + this.m_constant = def.lengthA + this.m_ratio * def.lengthB; + this.m_maxLength1 = b2Math.Min(def.maxLengthA, this.m_constant - this.m_ratio * b2PulleyJoint.b2_minPulleyLength); + this.m_maxLength2 = b2Math.Min(def.maxLengthB, (this.m_constant - b2PulleyJoint.b2_minPulleyLength) / this.m_ratio); + this.m_impulse = 0; + this.m_limitImpulse1 = 0; + this.m_limitImpulse2 = 0 +}; +b2PulleyJoint.prototype.__varz = function() { + this.m_groundAnchor1 = new b2Vec2; + this.m_groundAnchor2 = new b2Vec2; + this.m_localAnchor1 = new b2Vec2; + this.m_localAnchor2 = new b2Vec2; + this.m_u1 = new b2Vec2; + this.m_u2 = new b2Vec2 +}; +b2PulleyJoint.b2_minPulleyLength = 2; +b2PulleyJoint.prototype.InitVelocityConstraints = function(step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var p1X = bA.m_sweep.c.x + r1X; + var p1Y = bA.m_sweep.c.y + r1Y; + var p2X = bB.m_sweep.c.x + r2X; + var p2Y = bB.m_sweep.c.y + r2Y; + var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; + var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; + var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; + var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; + this.m_u1.Set(p1X - s1X, p1Y - s1Y); + this.m_u2.Set(p2X - s2X, p2Y - s2Y); + var length1 = this.m_u1.Length(); + var length2 = this.m_u2.Length(); + if(length1 > b2Settings.b2_linearSlop) { + this.m_u1.Multiply(1 / length1) + }else { + this.m_u1.SetZero() + } + if(length2 > b2Settings.b2_linearSlop) { + this.m_u2.Multiply(1 / length2) + }else { + this.m_u2.SetZero() + } + var C = this.m_constant - length1 - this.m_ratio * length2; + if(C > 0) { + this.m_state = b2Joint.e_inactiveLimit; + this.m_impulse = 0 + }else { + this.m_state = b2Joint.e_atUpperLimit + } + if(length1 < this.m_maxLength1) { + this.m_limitState1 = b2Joint.e_inactiveLimit; + this.m_limitImpulse1 = 0 + }else { + this.m_limitState1 = b2Joint.e_atUpperLimit + } + if(length2 < this.m_maxLength2) { + this.m_limitState2 = b2Joint.e_inactiveLimit; + this.m_limitImpulse2 = 0 + }else { + this.m_limitState2 = b2Joint.e_atUpperLimit + } + var cr1u1 = r1X * this.m_u1.y - r1Y * this.m_u1.x; + var cr2u2 = r2X * this.m_u2.y - r2Y * this.m_u2.x; + this.m_limitMass1 = bA.m_invMass + bA.m_invI * cr1u1 * cr1u1; + this.m_limitMass2 = bB.m_invMass + bB.m_invI * cr2u2 * cr2u2; + this.m_pulleyMass = this.m_limitMass1 + this.m_ratio * this.m_ratio * this.m_limitMass2; + this.m_limitMass1 = 1 / this.m_limitMass1; + this.m_limitMass2 = 1 / this.m_limitMass2; + this.m_pulleyMass = 1 / this.m_pulleyMass; + if(step.warmStarting) { + this.m_impulse *= step.dtRatio; + this.m_limitImpulse1 *= step.dtRatio; + this.m_limitImpulse2 *= step.dtRatio; + var P1X = (-this.m_impulse - this.m_limitImpulse1) * this.m_u1.x; + var P1Y = (-this.m_impulse - this.m_limitImpulse1) * this.m_u1.y; + var P2X = (-this.m_ratio * this.m_impulse - this.m_limitImpulse2) * this.m_u2.x; + var P2Y = (-this.m_ratio * this.m_impulse - this.m_limitImpulse2) * this.m_u2.y; + bA.m_linearVelocity.x += bA.m_invMass * P1X; + bA.m_linearVelocity.y += bA.m_invMass * P1Y; + bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); + bB.m_linearVelocity.x += bB.m_invMass * P2X; + bB.m_linearVelocity.y += bB.m_invMass * P2Y; + bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X) + }else { + this.m_impulse = 0; + this.m_limitImpulse1 = 0; + this.m_limitImpulse2 = 0 + } +}; +b2PulleyJoint.prototype.SolveVelocityConstraints = function(step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var v1X; + var v1Y; + var v2X; + var v2Y; + var P1X; + var P1Y; + var P2X; + var P2Y; + var Cdot; + var impulse; + var oldImpulse; + if(this.m_state == b2Joint.e_atUpperLimit) { + v1X = bA.m_linearVelocity.x + -bA.m_angularVelocity * r1Y; + v1Y = bA.m_linearVelocity.y + bA.m_angularVelocity * r1X; + v2X = bB.m_linearVelocity.x + -bB.m_angularVelocity * r2Y; + v2Y = bB.m_linearVelocity.y + bB.m_angularVelocity * r2X; + Cdot = -(this.m_u1.x * v1X + this.m_u1.y * v1Y) - this.m_ratio * (this.m_u2.x * v2X + this.m_u2.y * v2Y); + impulse = this.m_pulleyMass * -Cdot; + oldImpulse = this.m_impulse; + this.m_impulse = b2Math.Max(0, this.m_impulse + impulse); + impulse = this.m_impulse - oldImpulse; + P1X = -impulse * this.m_u1.x; + P1Y = -impulse * this.m_u1.y; + P2X = -this.m_ratio * impulse * this.m_u2.x; + P2Y = -this.m_ratio * impulse * this.m_u2.y; + bA.m_linearVelocity.x += bA.m_invMass * P1X; + bA.m_linearVelocity.y += bA.m_invMass * P1Y; + bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); + bB.m_linearVelocity.x += bB.m_invMass * P2X; + bB.m_linearVelocity.y += bB.m_invMass * P2Y; + bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X) + } + if(this.m_limitState1 == b2Joint.e_atUpperLimit) { + v1X = bA.m_linearVelocity.x + -bA.m_angularVelocity * r1Y; + v1Y = bA.m_linearVelocity.y + bA.m_angularVelocity * r1X; + Cdot = -(this.m_u1.x * v1X + this.m_u1.y * v1Y); + impulse = -this.m_limitMass1 * Cdot; + oldImpulse = this.m_limitImpulse1; + this.m_limitImpulse1 = b2Math.Max(0, this.m_limitImpulse1 + impulse); + impulse = this.m_limitImpulse1 - oldImpulse; + P1X = -impulse * this.m_u1.x; + P1Y = -impulse * this.m_u1.y; + bA.m_linearVelocity.x += bA.m_invMass * P1X; + bA.m_linearVelocity.y += bA.m_invMass * P1Y; + bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X) + } + if(this.m_limitState2 == b2Joint.e_atUpperLimit) { + v2X = bB.m_linearVelocity.x + -bB.m_angularVelocity * r2Y; + v2Y = bB.m_linearVelocity.y + bB.m_angularVelocity * r2X; + Cdot = -(this.m_u2.x * v2X + this.m_u2.y * v2Y); + impulse = -this.m_limitMass2 * Cdot; + oldImpulse = this.m_limitImpulse2; + this.m_limitImpulse2 = b2Math.Max(0, this.m_limitImpulse2 + impulse); + impulse = this.m_limitImpulse2 - oldImpulse; + P2X = -impulse * this.m_u2.x; + P2Y = -impulse * this.m_u2.y; + bB.m_linearVelocity.x += bB.m_invMass * P2X; + bB.m_linearVelocity.y += bB.m_invMass * P2Y; + bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X) + } +}; +b2PulleyJoint.prototype.SolvePositionConstraints = function(baumgarte) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; + var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; + var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; + var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; + var r1X; + var r1Y; + var r2X; + var r2Y; + var p1X; + var p1Y; + var p2X; + var p2Y; + var length1; + var length2; + var C; + var impulse; + var oldImpulse; + var oldLimitPositionImpulse; + var tX; + var linearError = 0; + if(this.m_state == b2Joint.e_atUpperLimit) { + tMat = bA.m_xf.R; + r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + p1X = bA.m_sweep.c.x + r1X; + p1Y = bA.m_sweep.c.y + r1Y; + p2X = bB.m_sweep.c.x + r2X; + p2Y = bB.m_sweep.c.y + r2Y; + this.m_u1.Set(p1X - s1X, p1Y - s1Y); + this.m_u2.Set(p2X - s2X, p2Y - s2Y); + length1 = this.m_u1.Length(); + length2 = this.m_u2.Length(); + if(length1 > b2Settings.b2_linearSlop) { + this.m_u1.Multiply(1 / length1) + }else { + this.m_u1.SetZero() + } + if(length2 > b2Settings.b2_linearSlop) { + this.m_u2.Multiply(1 / length2) + }else { + this.m_u2.SetZero() + } + C = this.m_constant - length1 - this.m_ratio * length2; + linearError = b2Math.Max(linearError, -C); + C = b2Math.Clamp(C + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); + impulse = -this.m_pulleyMass * C; + p1X = -impulse * this.m_u1.x; + p1Y = -impulse * this.m_u1.y; + p2X = -this.m_ratio * impulse * this.m_u2.x; + p2Y = -this.m_ratio * impulse * this.m_u2.y; + bA.m_sweep.c.x += bA.m_invMass * p1X; + bA.m_sweep.c.y += bA.m_invMass * p1Y; + bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); + bB.m_sweep.c.x += bB.m_invMass * p2X; + bB.m_sweep.c.y += bB.m_invMass * p2Y; + bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); + bA.SynchronizeTransform(); + bB.SynchronizeTransform() + } + if(this.m_limitState1 == b2Joint.e_atUpperLimit) { + tMat = bA.m_xf.R; + r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + p1X = bA.m_sweep.c.x + r1X; + p1Y = bA.m_sweep.c.y + r1Y; + this.m_u1.Set(p1X - s1X, p1Y - s1Y); + length1 = this.m_u1.Length(); + if(length1 > b2Settings.b2_linearSlop) { + this.m_u1.x *= 1 / length1; + this.m_u1.y *= 1 / length1 + }else { + this.m_u1.SetZero() + } + C = this.m_maxLength1 - length1; + linearError = b2Math.Max(linearError, -C); + C = b2Math.Clamp(C + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); + impulse = -this.m_limitMass1 * C; + p1X = -impulse * this.m_u1.x; + p1Y = -impulse * this.m_u1.y; + bA.m_sweep.c.x += bA.m_invMass * p1X; + bA.m_sweep.c.y += bA.m_invMass * p1Y; + bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); + bA.SynchronizeTransform() + } + if(this.m_limitState2 == b2Joint.e_atUpperLimit) { + tMat = bB.m_xf.R; + r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + p2X = bB.m_sweep.c.x + r2X; + p2Y = bB.m_sweep.c.y + r2Y; + this.m_u2.Set(p2X - s2X, p2Y - s2Y); + length2 = this.m_u2.Length(); + if(length2 > b2Settings.b2_linearSlop) { + this.m_u2.x *= 1 / length2; + this.m_u2.y *= 1 / length2 + }else { + this.m_u2.SetZero() + } + C = this.m_maxLength2 - length2; + linearError = b2Math.Max(linearError, -C); + C = b2Math.Clamp(C + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); + impulse = -this.m_limitMass2 * C; + p2X = -impulse * this.m_u2.x; + p2Y = -impulse * this.m_u2.y; + bB.m_sweep.c.x += bB.m_invMass * p2X; + bB.m_sweep.c.y += bB.m_invMass * p2Y; + bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); + bB.SynchronizeTransform() + } + return linearError < b2Settings.b2_linearSlop +}; +b2PulleyJoint.prototype.GetAnchorA = function() { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) +}; +b2PulleyJoint.prototype.GetAnchorB = function() { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) +}; +b2PulleyJoint.prototype.GetReactionForce = function(inv_dt) { + return new b2Vec2(inv_dt * this.m_impulse * this.m_u2.x, inv_dt * this.m_impulse * this.m_u2.y) +}; +b2PulleyJoint.prototype.GetReactionTorque = function(inv_dt) { + return 0 +}; +b2PulleyJoint.prototype.GetGroundAnchorA = function() { + var a = this.m_ground.m_xf.position.Copy(); + a.Add(this.m_groundAnchor1); + return a +}; +b2PulleyJoint.prototype.GetGroundAnchorB = function() { + var a = this.m_ground.m_xf.position.Copy(); + a.Add(this.m_groundAnchor2); + return a +}; +b2PulleyJoint.prototype.GetLength1 = function() { + var p = this.m_bodyA.GetWorldPoint(this.m_localAnchor1); + var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; + var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; + var dX = p.x - sX; + var dY = p.y - sY; + return Math.sqrt(dX * dX + dY * dY) +}; +b2PulleyJoint.prototype.GetLength2 = function() { + var p = this.m_bodyB.GetWorldPoint(this.m_localAnchor2); + var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; + var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; + var dX = p.x - sX; + var dY = p.y - sY; + return Math.sqrt(dX * dX + dY * dY) +}; +b2PulleyJoint.prototype.GetRatio = function() { + return this.m_ratio +}; +b2PulleyJoint.prototype.m_ground = null; +b2PulleyJoint.prototype.m_groundAnchor1 = new b2Vec2; +b2PulleyJoint.prototype.m_groundAnchor2 = new b2Vec2; +b2PulleyJoint.prototype.m_localAnchor1 = new b2Vec2; +b2PulleyJoint.prototype.m_localAnchor2 = new b2Vec2; +b2PulleyJoint.prototype.m_u1 = new b2Vec2; +b2PulleyJoint.prototype.m_u2 = new b2Vec2; +b2PulleyJoint.prototype.m_constant = null; +b2PulleyJoint.prototype.m_ratio = null; +b2PulleyJoint.prototype.m_maxLength1 = null; +b2PulleyJoint.prototype.m_maxLength2 = null; +b2PulleyJoint.prototype.m_pulleyMass = null; +b2PulleyJoint.prototype.m_limitMass1 = null; +b2PulleyJoint.prototype.m_limitMass2 = null; +b2PulleyJoint.prototype.m_impulse = null; +b2PulleyJoint.prototype.m_limitImpulse1 = null; +b2PulleyJoint.prototype.m_limitImpulse2 = null; +b2PulleyJoint.prototype.m_state = 0; +b2PulleyJoint.prototype.m_limitState1 = 0; +b2PulleyJoint.prototype.m_limitState2 = 0;var b2PrismaticJoint = function() { + b2Joint.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2PrismaticJoint.prototype, b2Joint.prototype); +b2PrismaticJoint.prototype._super = b2Joint.prototype; +b2PrismaticJoint.prototype.__constructor = function(def) { + this._super.__constructor.apply(this, [def]); + var tMat; + var tX; + var tY; + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_localXAxis1.SetV(def.localAxisA); + this.m_localYAxis1.x = -this.m_localXAxis1.y; + this.m_localYAxis1.y = this.m_localXAxis1.x; + this.m_refAngle = def.referenceAngle; + this.m_impulse.SetZero(); + this.m_motorMass = 0; + this.m_motorImpulse = 0; + this.m_lowerTranslation = def.lowerTranslation; + this.m_upperTranslation = def.upperTranslation; + this.m_maxMotorForce = def.maxMotorForce; + this.m_motorSpeed = def.motorSpeed; + this.m_enableLimit = def.enableLimit; + this.m_enableMotor = def.enableMotor; + this.m_limitState = b2Joint.e_inactiveLimit; + this.m_axis.SetZero(); + this.m_perp.SetZero() +}; +b2PrismaticJoint.prototype.__varz = function() { + this.m_localAnchor1 = new b2Vec2; + this.m_localAnchor2 = new b2Vec2; + this.m_localXAxis1 = new b2Vec2; + this.m_localYAxis1 = new b2Vec2; + this.m_axis = new b2Vec2; + this.m_perp = new b2Vec2; + this.m_K = new b2Mat33; + this.m_impulse = new b2Vec3 +}; +b2PrismaticJoint.prototype.InitVelocityConstraints = function(step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var tX; + this.m_localCenterA.SetV(bA.GetLocalCenter()); + this.m_localCenterB.SetV(bB.GetLocalCenter()); + var xf1 = bA.GetTransform(); + var xf2 = bB.GetTransform(); + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; + var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; + var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + this.m_invMassA = bA.m_invMass; + this.m_invMassB = bB.m_invMass; + this.m_invIA = bA.m_invI; + this.m_invIB = bB.m_invI; + this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); + this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; + this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; + this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; + if(this.m_motorMass > Number.MIN_VALUE) { + this.m_motorMass = 1 / this.m_motorMass + } + this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); + this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; + this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; + var m1 = this.m_invMassA; + var m2 = this.m_invMassB; + var i1 = this.m_invIA; + var i2 = this.m_invIB; + this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; + this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; + this.m_K.col2.x = this.m_K.col1.y; + this.m_K.col2.y = i1 + i2; + this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; + this.m_K.col3.x = this.m_K.col1.z; + this.m_K.col3.y = this.m_K.col2.z; + this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; + if(this.m_enableLimit) { + var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; + if(b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2 * b2Settings.b2_linearSlop) { + this.m_limitState = b2Joint.e_equalLimits + }else { + if(jointTransition <= this.m_lowerTranslation) { + if(this.m_limitState != b2Joint.e_atLowerLimit) { + this.m_limitState = b2Joint.e_atLowerLimit; + this.m_impulse.z = 0 + } + }else { + if(jointTransition >= this.m_upperTranslation) { + if(this.m_limitState != b2Joint.e_atUpperLimit) { + this.m_limitState = b2Joint.e_atUpperLimit; + this.m_impulse.z = 0 + } + }else { + this.m_limitState = b2Joint.e_inactiveLimit; + this.m_impulse.z = 0 + } + } + } + }else { + this.m_limitState = b2Joint.e_inactiveLimit + } + if(this.m_enableMotor == false) { + this.m_motorImpulse = 0 + } + if(step.warmStarting) { + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + this.m_motorImpulse *= step.dtRatio; + var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x; + var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y; + var L1 = this.m_impulse.x * this.m_s1 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a1; + var L2 = this.m_impulse.x * this.m_s2 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a2; + bA.m_linearVelocity.x -= this.m_invMassA * PX; + bA.m_linearVelocity.y -= this.m_invMassA * PY; + bA.m_angularVelocity -= this.m_invIA * L1; + bB.m_linearVelocity.x += this.m_invMassB * PX; + bB.m_linearVelocity.y += this.m_invMassB * PY; + bB.m_angularVelocity += this.m_invIB * L2 + }else { + this.m_impulse.SetZero(); + this.m_motorImpulse = 0 + } +}; +b2PrismaticJoint.prototype.SolveVelocityConstraints = function(step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var v1 = bA.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var v2 = bB.m_linearVelocity; + var w2 = bB.m_angularVelocity; + var PX; + var PY; + var L1; + var L2; + if(this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) { + var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; + var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); + var oldImpulse = this.m_motorImpulse; + var maxImpulse = step.dt * this.m_maxMotorForce; + this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = this.m_motorImpulse - oldImpulse; + PX = impulse * this.m_axis.x; + PY = impulse * this.m_axis.y; + L1 = impulse * this.m_a1; + L2 = impulse * this.m_a2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2 + } + var Cdot1X = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; + var Cdot1Y = w2 - w1; + if(this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { + var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; + var f1 = this.m_impulse.Copy(); + var df = this.m_K.Solve33(new b2Vec3, -Cdot1X, -Cdot1Y, -Cdot2); + this.m_impulse.Add(df); + if(this.m_limitState == b2Joint.e_atLowerLimit) { + this.m_impulse.z = b2Math.Max(this.m_impulse.z, 0) + }else { + if(this.m_limitState == b2Joint.e_atUpperLimit) { + this.m_impulse.z = b2Math.Min(this.m_impulse.z, 0) + } + } + var bX = -Cdot1X - (this.m_impulse.z - f1.z) * this.m_K.col3.x; + var bY = -Cdot1Y - (this.m_impulse.z - f1.z) * this.m_K.col3.y; + var f2r = this.m_K.Solve22(new b2Vec2, bX, bY); + f2r.x += f1.x; + f2r.y += f1.y; + this.m_impulse.x = f2r.x; + this.m_impulse.y = f2r.y; + df.x = this.m_impulse.x - f1.x; + df.y = this.m_impulse.y - f1.y; + df.z = this.m_impulse.z - f1.z; + PX = df.x * this.m_perp.x + df.z * this.m_axis.x; + PY = df.x * this.m_perp.y + df.z * this.m_axis.y; + L1 = df.x * this.m_s1 + df.y + df.z * this.m_a1; + L2 = df.x * this.m_s2 + df.y + df.z * this.m_a2; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2 + }else { + var df2 = this.m_K.Solve22(new b2Vec2, -Cdot1X, -Cdot1Y); + this.m_impulse.x += df2.x; + this.m_impulse.y += df2.y; + PX = df2.x * this.m_perp.x; + PY = df2.x * this.m_perp.y; + L1 = df2.x * this.m_s1 + df2.y; + L2 = df2.x * this.m_s2 + df2.y; + v1.x -= this.m_invMassA * PX; + v1.y -= this.m_invMassA * PY; + w1 -= this.m_invIA * L1; + v2.x += this.m_invMassB * PX; + v2.y += this.m_invMassB * PY; + w2 += this.m_invIB * L2 + } + bA.m_linearVelocity.SetV(v1); + bA.m_angularVelocity = w1; + bB.m_linearVelocity.SetV(v2); + bB.m_angularVelocity = w2 +}; +b2PrismaticJoint.prototype.SolvePositionConstraints = function(baumgarte) { + var limitC; + var oldLimitImpulse; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var c1 = bA.m_sweep.c; + var a1 = bA.m_sweep.a; + var c2 = bB.m_sweep.c; + var a2 = bB.m_sweep.a; + var tMat; + var tX; + var m1; + var m2; + var i1; + var i2; + var linearError = 0; + var angularError = 0; + var active = false; + var C2 = 0; + var R1 = b2Mat22.FromAngle(a1); + var R2 = b2Mat22.FromAngle(a2); + tMat = R1; + var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; + var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = R2; + var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; + var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var dX = c2.x + r2X - c1.x - r1X; + var dY = c2.y + r2Y - c1.y - r1Y; + if(this.m_enableLimit) { + this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); + this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; + this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; + var translation = this.m_axis.x * dX + this.m_axis.y * dY; + if(b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2 * b2Settings.b2_linearSlop) { + C2 = b2Math.Clamp(translation, -b2Settings.b2_maxLinearCorrection, b2Settings.b2_maxLinearCorrection); + linearError = b2Math.Abs(translation); + active = true + }else { + if(translation <= this.m_lowerTranslation) { + C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); + linearError = this.m_lowerTranslation - translation; + active = true + }else { + if(translation >= this.m_upperTranslation) { + C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0, b2Settings.b2_maxLinearCorrection); + linearError = translation - this.m_upperTranslation; + active = true + } + } + } + } + this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); + this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; + this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; + var impulse = new b2Vec3; + var C1X = this.m_perp.x * dX + this.m_perp.y * dY; + var C1Y = a2 - a1 - this.m_refAngle; + linearError = b2Math.Max(linearError, b2Math.Abs(C1X)); + angularError = b2Math.Abs(C1Y); + if(active) { + m1 = this.m_invMassA; + m2 = this.m_invMassB; + i1 = this.m_invIA; + i2 = this.m_invIB; + this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; + this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; + this.m_K.col2.x = this.m_K.col1.y; + this.m_K.col2.y = i1 + i2; + this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; + this.m_K.col3.x = this.m_K.col1.z; + this.m_K.col3.y = this.m_K.col2.z; + this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; + this.m_K.Solve33(impulse, -C1X, -C1Y, -C2) + }else { + m1 = this.m_invMassA; + m2 = this.m_invMassB; + i1 = this.m_invIA; + i2 = this.m_invIB; + var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; + var k12 = i1 * this.m_s1 + i2 * this.m_s2; + var k22 = i1 + i2; + this.m_K.col1.Set(k11, k12, 0); + this.m_K.col2.Set(k12, k22, 0); + var impulse1 = this.m_K.Solve22(new b2Vec2, -C1X, -C1Y); + impulse.x = impulse1.x; + impulse.y = impulse1.y; + impulse.z = 0 + } + var PX = impulse.x * this.m_perp.x + impulse.z * this.m_axis.x; + var PY = impulse.x * this.m_perp.y + impulse.z * this.m_axis.y; + var L1 = impulse.x * this.m_s1 + impulse.y + impulse.z * this.m_a1; + var L2 = impulse.x * this.m_s2 + impulse.y + impulse.z * this.m_a2; + c1.x -= this.m_invMassA * PX; + c1.y -= this.m_invMassA * PY; + a1 -= this.m_invIA * L1; + c2.x += this.m_invMassB * PX; + c2.y += this.m_invMassB * PY; + a2 += this.m_invIB * L2; + bA.m_sweep.a = a1; + bB.m_sweep.a = a2; + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop +}; +b2PrismaticJoint.prototype.GetAnchorA = function() { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) +}; +b2PrismaticJoint.prototype.GetAnchorB = function() { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) +}; +b2PrismaticJoint.prototype.GetReactionForce = function(inv_dt) { + return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y)) +}; +b2PrismaticJoint.prototype.GetReactionTorque = function(inv_dt) { + return inv_dt * this.m_impulse.y +}; +b2PrismaticJoint.prototype.GetJointTranslation = function() { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var p1 = bA.GetWorldPoint(this.m_localAnchor1); + var p2 = bB.GetWorldPoint(this.m_localAnchor2); + var dX = p2.x - p1.x; + var dY = p2.y - p1.y; + var axis = bA.GetWorldVector(this.m_localXAxis1); + var translation = axis.x * dX + axis.y * dY; + return translation +}; +b2PrismaticJoint.prototype.GetJointSpeed = function() { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var p1X = bA.m_sweep.c.x + r1X; + var p1Y = bA.m_sweep.c.y + r1Y; + var p2X = bB.m_sweep.c.x + r2X; + var p2Y = bB.m_sweep.c.y + r2Y; + var dX = p2X - p1X; + var dY = p2Y - p1Y; + var axis = bA.GetWorldVector(this.m_localXAxis1); + var v1 = bA.m_linearVelocity; + var v2 = bB.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var w2 = bB.m_angularVelocity; + var speed = dX * -w1 * axis.y + dY * w1 * axis.x + (axis.x * (v2.x + -w2 * r2Y - v1.x - -w1 * r1Y) + axis.y * (v2.y + w2 * r2X - v1.y - w1 * r1X)); + return speed +}; +b2PrismaticJoint.prototype.IsLimitEnabled = function() { + return this.m_enableLimit +}; +b2PrismaticJoint.prototype.EnableLimit = function(flag) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableLimit = flag +}; +b2PrismaticJoint.prototype.GetLowerLimit = function() { + return this.m_lowerTranslation +}; +b2PrismaticJoint.prototype.GetUpperLimit = function() { + return this.m_upperTranslation +}; +b2PrismaticJoint.prototype.SetLimits = function(lower, upper) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_lowerTranslation = lower; + this.m_upperTranslation = upper +}; +b2PrismaticJoint.prototype.IsMotorEnabled = function() { + return this.m_enableMotor +}; +b2PrismaticJoint.prototype.EnableMotor = function(flag) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableMotor = flag +}; +b2PrismaticJoint.prototype.SetMotorSpeed = function(speed) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_motorSpeed = speed +}; +b2PrismaticJoint.prototype.GetMotorSpeed = function() { + return this.m_motorSpeed +}; +b2PrismaticJoint.prototype.SetMaxMotorForce = function(force) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_maxMotorForce = force +}; +b2PrismaticJoint.prototype.GetMotorForce = function() { + return this.m_motorImpulse +}; +b2PrismaticJoint.prototype.m_localAnchor1 = new b2Vec2; +b2PrismaticJoint.prototype.m_localAnchor2 = new b2Vec2; +b2PrismaticJoint.prototype.m_localXAxis1 = new b2Vec2; +b2PrismaticJoint.prototype.m_localYAxis1 = new b2Vec2; +b2PrismaticJoint.prototype.m_refAngle = null; +b2PrismaticJoint.prototype.m_axis = new b2Vec2; +b2PrismaticJoint.prototype.m_perp = new b2Vec2; +b2PrismaticJoint.prototype.m_s1 = null; +b2PrismaticJoint.prototype.m_s2 = null; +b2PrismaticJoint.prototype.m_a1 = null; +b2PrismaticJoint.prototype.m_a2 = null; +b2PrismaticJoint.prototype.m_K = new b2Mat33; +b2PrismaticJoint.prototype.m_impulse = new b2Vec3; +b2PrismaticJoint.prototype.m_motorMass = null; +b2PrismaticJoint.prototype.m_motorImpulse = null; +b2PrismaticJoint.prototype.m_lowerTranslation = null; +b2PrismaticJoint.prototype.m_upperTranslation = null; +b2PrismaticJoint.prototype.m_maxMotorForce = null; +b2PrismaticJoint.prototype.m_motorSpeed = null; +b2PrismaticJoint.prototype.m_enableLimit = null; +b2PrismaticJoint.prototype.m_enableMotor = null; +b2PrismaticJoint.prototype.m_limitState = 0;var b2RevoluteJoint = function() { + b2Joint.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2RevoluteJoint.prototype, b2Joint.prototype); +b2RevoluteJoint.prototype._super = b2Joint.prototype; +b2RevoluteJoint.prototype.__constructor = function(def) { + this._super.__constructor.apply(this, [def]); + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_referenceAngle = def.referenceAngle; + this.m_impulse.SetZero(); + this.m_motorImpulse = 0; + this.m_lowerAngle = def.lowerAngle; + this.m_upperAngle = def.upperAngle; + this.m_maxMotorTorque = def.maxMotorTorque; + this.m_motorSpeed = def.motorSpeed; + this.m_enableLimit = def.enableLimit; + this.m_enableMotor = def.enableMotor; + this.m_limitState = b2Joint.e_inactiveLimit +}; +b2RevoluteJoint.prototype.__varz = function() { + this.K = new b2Mat22; + this.K1 = new b2Mat22; + this.K2 = new b2Mat22; + this.K3 = new b2Mat22; + this.impulse3 = new b2Vec3; + this.impulse2 = new b2Vec2; + this.reduced = new b2Vec2; + this.m_localAnchor1 = new b2Vec2; + this.m_localAnchor2 = new b2Vec2; + this.m_impulse = new b2Vec3; + this.m_mass = new b2Mat33 +}; +b2RevoluteJoint.tImpulse = new b2Vec2; +b2RevoluteJoint.prototype.InitVelocityConstraints = function(step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var tX; + if(this.m_enableMotor || this.m_enableLimit) { + } + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var m1 = bA.m_invMass; + var m2 = bB.m_invMass; + var i1 = bA.m_invI; + var i2 = bB.m_invI; + this.m_mass.col1.x = m1 + m2 + r1Y * r1Y * i1 + r2Y * r2Y * i2; + this.m_mass.col2.x = -r1Y * r1X * i1 - r2Y * r2X * i2; + this.m_mass.col3.x = -r1Y * i1 - r2Y * i2; + this.m_mass.col1.y = this.m_mass.col2.x; + this.m_mass.col2.y = m1 + m2 + r1X * r1X * i1 + r2X * r2X * i2; + this.m_mass.col3.y = r1X * i1 + r2X * i2; + this.m_mass.col1.z = this.m_mass.col3.x; + this.m_mass.col2.z = this.m_mass.col3.y; + this.m_mass.col3.z = i1 + i2; + this.m_motorMass = 1 / (i1 + i2); + if(this.m_enableMotor == false) { + this.m_motorImpulse = 0 + } + if(this.m_enableLimit) { + var jointAngle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; + if(b2Math.Abs(this.m_upperAngle - this.m_lowerAngle) < 2 * b2Settings.b2_angularSlop) { + this.m_limitState = b2Joint.e_equalLimits + }else { + if(jointAngle <= this.m_lowerAngle) { + if(this.m_limitState != b2Joint.e_atLowerLimit) { + this.m_impulse.z = 0 + } + this.m_limitState = b2Joint.e_atLowerLimit + }else { + if(jointAngle >= this.m_upperAngle) { + if(this.m_limitState != b2Joint.e_atUpperLimit) { + this.m_impulse.z = 0 + } + this.m_limitState = b2Joint.e_atUpperLimit + }else { + this.m_limitState = b2Joint.e_inactiveLimit; + this.m_impulse.z = 0 + } + } + } + }else { + this.m_limitState = b2Joint.e_inactiveLimit + } + if(step.warmStarting) { + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + this.m_motorImpulse *= step.dtRatio; + var PX = this.m_impulse.x; + var PY = this.m_impulse.y; + bA.m_linearVelocity.x -= m1 * PX; + bA.m_linearVelocity.y -= m1 * PY; + bA.m_angularVelocity -= i1 * (r1X * PY - r1Y * PX + this.m_motorImpulse + this.m_impulse.z); + bB.m_linearVelocity.x += m2 * PX; + bB.m_linearVelocity.y += m2 * PY; + bB.m_angularVelocity += i2 * (r2X * PY - r2Y * PX + this.m_motorImpulse + this.m_impulse.z) + }else { + this.m_impulse.SetZero(); + this.m_motorImpulse = 0 + } +}; +b2RevoluteJoint.prototype.SolveVelocityConstraints = function(step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var tMat; + var tX; + var newImpulse; + var r1X; + var r1Y; + var r2X; + var r2Y; + var v1 = bA.m_linearVelocity; + var w1 = bA.m_angularVelocity; + var v2 = bB.m_linearVelocity; + var w2 = bB.m_angularVelocity; + var m1 = bA.m_invMass; + var m2 = bB.m_invMass; + var i1 = bA.m_invI; + var i2 = bB.m_invI; + if(this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) { + var Cdot = w2 - w1 - this.m_motorSpeed; + var impulse = this.m_motorMass * -Cdot; + var oldImpulse = this.m_motorImpulse; + var maxImpulse = step.dt * this.m_maxMotorTorque; + this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = this.m_motorImpulse - oldImpulse; + w1 -= i1 * impulse; + w2 += i2 * impulse + } + if(this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { + tMat = bA.m_xf.R; + r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var Cdot1X = v2.x + -w2 * r2Y - v1.x - -w1 * r1Y; + var Cdot1Y = v2.y + w2 * r2X - v1.y - w1 * r1X; + var Cdot2 = w2 - w1; + this.m_mass.Solve33(this.impulse3, -Cdot1X, -Cdot1Y, -Cdot2); + if(this.m_limitState == b2Joint.e_equalLimits) { + this.m_impulse.Add(this.impulse3) + }else { + if(this.m_limitState == b2Joint.e_atLowerLimit) { + newImpulse = this.m_impulse.z + this.impulse3.z; + if(newImpulse < 0) { + this.m_mass.Solve22(this.reduced, -Cdot1X, -Cdot1Y); + this.impulse3.x = this.reduced.x; + this.impulse3.y = this.reduced.y; + this.impulse3.z = -this.m_impulse.z; + this.m_impulse.x += this.reduced.x; + this.m_impulse.y += this.reduced.y; + this.m_impulse.z = 0 + } + }else { + if(this.m_limitState == b2Joint.e_atUpperLimit) { + newImpulse = this.m_impulse.z + this.impulse3.z; + if(newImpulse > 0) { + this.m_mass.Solve22(this.reduced, -Cdot1X, -Cdot1Y); + this.impulse3.x = this.reduced.x; + this.impulse3.y = this.reduced.y; + this.impulse3.z = -this.m_impulse.z; + this.m_impulse.x += this.reduced.x; + this.m_impulse.y += this.reduced.y; + this.m_impulse.z = 0 + } + } + } + } + v1.x -= m1 * this.impulse3.x; + v1.y -= m1 * this.impulse3.y; + w1 -= i1 * (r1X * this.impulse3.y - r1Y * this.impulse3.x + this.impulse3.z); + v2.x += m2 * this.impulse3.x; + v2.y += m2 * this.impulse3.y; + w2 += i2 * (r2X * this.impulse3.y - r2Y * this.impulse3.x + this.impulse3.z) + }else { + tMat = bA.m_xf.R; + r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var CdotX = v2.x + -w2 * r2Y - v1.x - -w1 * r1Y; + var CdotY = v2.y + w2 * r2X - v1.y - w1 * r1X; + this.m_mass.Solve22(this.impulse2, -CdotX, -CdotY); + this.m_impulse.x += this.impulse2.x; + this.m_impulse.y += this.impulse2.y; + v1.x -= m1 * this.impulse2.x; + v1.y -= m1 * this.impulse2.y; + w1 -= i1 * (r1X * this.impulse2.y - r1Y * this.impulse2.x); + v2.x += m2 * this.impulse2.x; + v2.y += m2 * this.impulse2.y; + w2 += i2 * (r2X * this.impulse2.y - r2Y * this.impulse2.x) + } + bA.m_linearVelocity.SetV(v1); + bA.m_angularVelocity = w1; + bB.m_linearVelocity.SetV(v2); + bB.m_angularVelocity = w2 +}; +b2RevoluteJoint.prototype.SolvePositionConstraints = function(baumgarte) { + var oldLimitImpulse; + var C; + var tMat; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var angularError = 0; + var positionError = 0; + var tX; + var impulseX; + var impulseY; + if(this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { + var angle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; + var limitImpulse = 0; + if(this.m_limitState == b2Joint.e_equalLimits) { + C = b2Math.Clamp(angle - this.m_lowerAngle, -b2Settings.b2_maxAngularCorrection, b2Settings.b2_maxAngularCorrection); + limitImpulse = -this.m_motorMass * C; + angularError = b2Math.Abs(C) + }else { + if(this.m_limitState == b2Joint.e_atLowerLimit) { + C = angle - this.m_lowerAngle; + angularError = -C; + C = b2Math.Clamp(C + b2Settings.b2_angularSlop, -b2Settings.b2_maxAngularCorrection, 0); + limitImpulse = -this.m_motorMass * C + }else { + if(this.m_limitState == b2Joint.e_atUpperLimit) { + C = angle - this.m_upperAngle; + angularError = C; + C = b2Math.Clamp(C - b2Settings.b2_angularSlop, 0, b2Settings.b2_maxAngularCorrection); + limitImpulse = -this.m_motorMass * C + } + } + } + bA.m_sweep.a -= bA.m_invI * limitImpulse; + bB.m_sweep.a += bB.m_invI * limitImpulse; + bA.SynchronizeTransform(); + bB.SynchronizeTransform() + } + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + var CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + var CLengthSquared = CX * CX + CY * CY; + var CLength = Math.sqrt(CLengthSquared); + positionError = CLength; + var invMass1 = bA.m_invMass; + var invMass2 = bB.m_invMass; + var invI1 = bA.m_invI; + var invI2 = bB.m_invI; + var k_allowedStretch = 10 * b2Settings.b2_linearSlop; + if(CLengthSquared > k_allowedStretch * k_allowedStretch) { + var uX = CX / CLength; + var uY = CY / CLength; + var k = invMass1 + invMass2; + var m = 1 / k; + impulseX = m * -CX; + impulseY = m * -CY; + var k_beta = 0.5; + bA.m_sweep.c.x -= k_beta * invMass1 * impulseX; + bA.m_sweep.c.y -= k_beta * invMass1 * impulseY; + bB.m_sweep.c.x += k_beta * invMass2 * impulseX; + bB.m_sweep.c.y += k_beta * invMass2 * impulseY; + CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y + } + this.K1.col1.x = invMass1 + invMass2; + this.K1.col2.x = 0; + this.K1.col1.y = 0; + this.K1.col2.y = invMass1 + invMass2; + this.K2.col1.x = invI1 * r1Y * r1Y; + this.K2.col2.x = -invI1 * r1X * r1Y; + this.K2.col1.y = -invI1 * r1X * r1Y; + this.K2.col2.y = invI1 * r1X * r1X; + this.K3.col1.x = invI2 * r2Y * r2Y; + this.K3.col2.x = -invI2 * r2X * r2Y; + this.K3.col1.y = -invI2 * r2X * r2Y; + this.K3.col2.y = invI2 * r2X * r2X; + this.K.SetM(this.K1); + this.K.AddM(this.K2); + this.K.AddM(this.K3); + this.K.Solve(b2RevoluteJoint.tImpulse, -CX, -CY); + impulseX = b2RevoluteJoint.tImpulse.x; + impulseY = b2RevoluteJoint.tImpulse.y; + bA.m_sweep.c.x -= bA.m_invMass * impulseX; + bA.m_sweep.c.y -= bA.m_invMass * impulseY; + bA.m_sweep.a -= bA.m_invI * (r1X * impulseY - r1Y * impulseX); + bB.m_sweep.c.x += bB.m_invMass * impulseX; + bB.m_sweep.c.y += bB.m_invMass * impulseY; + bB.m_sweep.a += bB.m_invI * (r2X * impulseY - r2Y * impulseX); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop +}; +b2RevoluteJoint.prototype.GetAnchorA = function() { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) +}; +b2RevoluteJoint.prototype.GetAnchorB = function() { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) +}; +b2RevoluteJoint.prototype.GetReactionForce = function(inv_dt) { + return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y) +}; +b2RevoluteJoint.prototype.GetReactionTorque = function(inv_dt) { + return inv_dt * this.m_impulse.z +}; +b2RevoluteJoint.prototype.GetJointAngle = function() { + return this.m_bodyB.m_sweep.a - this.m_bodyA.m_sweep.a - this.m_referenceAngle +}; +b2RevoluteJoint.prototype.GetJointSpeed = function() { + return this.m_bodyB.m_angularVelocity - this.m_bodyA.m_angularVelocity +}; +b2RevoluteJoint.prototype.IsLimitEnabled = function() { + return this.m_enableLimit +}; +b2RevoluteJoint.prototype.EnableLimit = function(flag) { + this.m_enableLimit = flag +}; +b2RevoluteJoint.prototype.GetLowerLimit = function() { + return this.m_lowerAngle +}; +b2RevoluteJoint.prototype.GetUpperLimit = function() { + return this.m_upperAngle +}; +b2RevoluteJoint.prototype.SetLimits = function(lower, upper) { + this.m_lowerAngle = lower; + this.m_upperAngle = upper +}; +b2RevoluteJoint.prototype.IsMotorEnabled = function() { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + return this.m_enableMotor +}; +b2RevoluteJoint.prototype.EnableMotor = function(flag) { + this.m_enableMotor = flag +}; +b2RevoluteJoint.prototype.SetMotorSpeed = function(speed) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_motorSpeed = speed +}; +b2RevoluteJoint.prototype.GetMotorSpeed = function() { + return this.m_motorSpeed +}; +b2RevoluteJoint.prototype.SetMaxMotorTorque = function(torque) { + this.m_maxMotorTorque = torque +}; +b2RevoluteJoint.prototype.GetMotorTorque = function() { + return this.m_maxMotorTorque +}; +b2RevoluteJoint.prototype.K = new b2Mat22; +b2RevoluteJoint.prototype.K1 = new b2Mat22; +b2RevoluteJoint.prototype.K2 = new b2Mat22; +b2RevoluteJoint.prototype.K3 = new b2Mat22; +b2RevoluteJoint.prototype.impulse3 = new b2Vec3; +b2RevoluteJoint.prototype.impulse2 = new b2Vec2; +b2RevoluteJoint.prototype.reduced = new b2Vec2; +b2RevoluteJoint.prototype.m_localAnchor1 = new b2Vec2; +b2RevoluteJoint.prototype.m_localAnchor2 = new b2Vec2; +b2RevoluteJoint.prototype.m_impulse = new b2Vec3; +b2RevoluteJoint.prototype.m_motorImpulse = null; +b2RevoluteJoint.prototype.m_mass = new b2Mat33; +b2RevoluteJoint.prototype.m_motorMass = null; +b2RevoluteJoint.prototype.m_enableMotor = null; +b2RevoluteJoint.prototype.m_maxMotorTorque = null; +b2RevoluteJoint.prototype.m_motorSpeed = null; +b2RevoluteJoint.prototype.m_enableLimit = null; +b2RevoluteJoint.prototype.m_referenceAngle = null; +b2RevoluteJoint.prototype.m_lowerAngle = null; +b2RevoluteJoint.prototype.m_upperAngle = null; +b2RevoluteJoint.prototype.m_limitState = 0;var b2JointDef = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2JointDef.prototype.__constructor = function() { + this.type = b2Joint.e_unknownJoint; + this.userData = null; + this.bodyA = null; + this.bodyB = null; + this.collideConnected = false +}; +b2JointDef.prototype.__varz = function() { +}; +b2JointDef.prototype.type = 0; +b2JointDef.prototype.userData = null; +b2JointDef.prototype.bodyA = null; +b2JointDef.prototype.bodyB = null; +b2JointDef.prototype.collideConnected = null;var b2LineJointDef = function() { + b2JointDef.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2LineJointDef.prototype, b2JointDef.prototype); +b2LineJointDef.prototype._super = b2JointDef.prototype; +b2LineJointDef.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.type = b2Joint.e_lineJoint; + this.localAxisA.Set(1, 0); + this.enableLimit = false; + this.lowerTranslation = 0; + this.upperTranslation = 0; + this.enableMotor = false; + this.maxMotorForce = 0; + this.motorSpeed = 0 +}; +b2LineJointDef.prototype.__varz = function() { + this.localAnchorA = new b2Vec2; + this.localAnchorB = new b2Vec2; + this.localAxisA = new b2Vec2 +}; +b2LineJointDef.prototype.Initialize = function(bA, bB, anchor, axis) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA = this.bodyA.GetLocalPoint(anchor); + this.localAnchorB = this.bodyB.GetLocalPoint(anchor); + this.localAxisA = this.bodyA.GetLocalVector(axis) +}; +b2LineJointDef.prototype.localAnchorA = new b2Vec2; +b2LineJointDef.prototype.localAnchorB = new b2Vec2; +b2LineJointDef.prototype.localAxisA = new b2Vec2; +b2LineJointDef.prototype.enableLimit = null; +b2LineJointDef.prototype.lowerTranslation = null; +b2LineJointDef.prototype.upperTranslation = null; +b2LineJointDef.prototype.enableMotor = null; +b2LineJointDef.prototype.maxMotorForce = null; +b2LineJointDef.prototype.motorSpeed = null;var b2DistanceJoint = function() { + b2Joint.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2DistanceJoint.prototype, b2Joint.prototype); +b2DistanceJoint.prototype._super = b2Joint.prototype; +b2DistanceJoint.prototype.__constructor = function(def) { + this._super.__constructor.apply(this, [def]); + var tMat; + var tX; + var tY; + this.m_localAnchor1.SetV(def.localAnchorA); + this.m_localAnchor2.SetV(def.localAnchorB); + this.m_length = def.length; + this.m_frequencyHz = def.frequencyHz; + this.m_dampingRatio = def.dampingRatio; + this.m_impulse = 0; + this.m_gamma = 0; + this.m_bias = 0 +}; +b2DistanceJoint.prototype.__varz = function() { + this.m_localAnchor1 = new b2Vec2; + this.m_localAnchor2 = new b2Vec2; + this.m_u = new b2Vec2 +}; +b2DistanceJoint.prototype.InitVelocityConstraints = function(step) { + var tMat; + var tX; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + this.m_u.x = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + this.m_u.y = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + var length = Math.sqrt(this.m_u.x * this.m_u.x + this.m_u.y * this.m_u.y); + if(length > b2Settings.b2_linearSlop) { + this.m_u.Multiply(1 / length) + }else { + this.m_u.SetZero() + } + var cr1u = r1X * this.m_u.y - r1Y * this.m_u.x; + var cr2u = r2X * this.m_u.y - r2Y * this.m_u.x; + var invMass = bA.m_invMass + bA.m_invI * cr1u * cr1u + bB.m_invMass + bB.m_invI * cr2u * cr2u; + this.m_mass = invMass != 0 ? 1 / invMass : 0; + if(this.m_frequencyHz > 0) { + var C = length - this.m_length; + var omega = 2 * Math.PI * this.m_frequencyHz; + var d = 2 * this.m_mass * this.m_dampingRatio * omega; + var k = this.m_mass * omega * omega; + this.m_gamma = step.dt * (d + step.dt * k); + this.m_gamma = this.m_gamma != 0 ? 1 / this.m_gamma : 0; + this.m_bias = C * step.dt * k * this.m_gamma; + this.m_mass = invMass + this.m_gamma; + this.m_mass = this.m_mass != 0 ? 1 / this.m_mass : 0 + } + if(step.warmStarting) { + this.m_impulse *= step.dtRatio; + var PX = this.m_impulse * this.m_u.x; + var PY = this.m_impulse * this.m_u.y; + bA.m_linearVelocity.x -= bA.m_invMass * PX; + bA.m_linearVelocity.y -= bA.m_invMass * PY; + bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); + bB.m_linearVelocity.x += bB.m_invMass * PX; + bB.m_linearVelocity.y += bB.m_invMass * PY; + bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX) + }else { + this.m_impulse = 0 + } +}; +b2DistanceJoint.prototype.SolveVelocityConstraints = function(step) { + var tMat; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var v1X = bA.m_linearVelocity.x + -bA.m_angularVelocity * r1Y; + var v1Y = bA.m_linearVelocity.y + bA.m_angularVelocity * r1X; + var v2X = bB.m_linearVelocity.x + -bB.m_angularVelocity * r2Y; + var v2Y = bB.m_linearVelocity.y + bB.m_angularVelocity * r2X; + var Cdot = this.m_u.x * (v2X - v1X) + this.m_u.y * (v2Y - v1Y); + var impulse = -this.m_mass * (Cdot + this.m_bias + this.m_gamma * this.m_impulse); + this.m_impulse += impulse; + var PX = impulse * this.m_u.x; + var PY = impulse * this.m_u.y; + bA.m_linearVelocity.x -= bA.m_invMass * PX; + bA.m_linearVelocity.y -= bA.m_invMass * PY; + bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); + bB.m_linearVelocity.x += bB.m_invMass * PX; + bB.m_linearVelocity.y += bB.m_invMass * PY; + bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX) +}; +b2DistanceJoint.prototype.SolvePositionConstraints = function(baumgarte) { + var tMat; + if(this.m_frequencyHz > 0) { + return true + } + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; + r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; + r1X = tX; + tMat = bB.m_xf.R; + var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; + r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; + r2X = tX; + var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; + var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; + var length = Math.sqrt(dX * dX + dY * dY); + dX /= length; + dY /= length; + var C = length - this.m_length; + C = b2Math.Clamp(C, -b2Settings.b2_maxLinearCorrection, b2Settings.b2_maxLinearCorrection); + var impulse = -this.m_mass * C; + this.m_u.Set(dX, dY); + var PX = impulse * this.m_u.x; + var PY = impulse * this.m_u.y; + bA.m_sweep.c.x -= bA.m_invMass * PX; + bA.m_sweep.c.y -= bA.m_invMass * PY; + bA.m_sweep.a -= bA.m_invI * (r1X * PY - r1Y * PX); + bB.m_sweep.c.x += bB.m_invMass * PX; + bB.m_sweep.c.y += bB.m_invMass * PY; + bB.m_sweep.a += bB.m_invI * (r2X * PY - r2Y * PX); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return b2Math.Abs(C) < b2Settings.b2_linearSlop +}; +b2DistanceJoint.prototype.GetAnchorA = function() { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) +}; +b2DistanceJoint.prototype.GetAnchorB = function() { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) +}; +b2DistanceJoint.prototype.GetReactionForce = function(inv_dt) { + return new b2Vec2(inv_dt * this.m_impulse * this.m_u.x, inv_dt * this.m_impulse * this.m_u.y) +}; +b2DistanceJoint.prototype.GetReactionTorque = function(inv_dt) { + return 0 +}; +b2DistanceJoint.prototype.GetLength = function() { + return this.m_length +}; +b2DistanceJoint.prototype.SetLength = function(length) { + this.m_length = length +}; +b2DistanceJoint.prototype.GetFrequency = function() { + return this.m_frequencyHz +}; +b2DistanceJoint.prototype.SetFrequency = function(hz) { + this.m_frequencyHz = hz +}; +b2DistanceJoint.prototype.GetDampingRatio = function() { + return this.m_dampingRatio +}; +b2DistanceJoint.prototype.SetDampingRatio = function(ratio) { + this.m_dampingRatio = ratio +}; +b2DistanceJoint.prototype.m_localAnchor1 = new b2Vec2; +b2DistanceJoint.prototype.m_localAnchor2 = new b2Vec2; +b2DistanceJoint.prototype.m_u = new b2Vec2; +b2DistanceJoint.prototype.m_frequencyHz = null; +b2DistanceJoint.prototype.m_dampingRatio = null; +b2DistanceJoint.prototype.m_gamma = null; +b2DistanceJoint.prototype.m_bias = null; +b2DistanceJoint.prototype.m_impulse = null; +b2DistanceJoint.prototype.m_mass = null; +b2DistanceJoint.prototype.m_length = null;var b2PulleyJointDef = function() { + b2JointDef.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2PulleyJointDef.prototype, b2JointDef.prototype); +b2PulleyJointDef.prototype._super = b2JointDef.prototype; +b2PulleyJointDef.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.type = b2Joint.e_pulleyJoint; + this.groundAnchorA.Set(-1, 1); + this.groundAnchorB.Set(1, 1); + this.localAnchorA.Set(-1, 0); + this.localAnchorB.Set(1, 0); + this.lengthA = 0; + this.maxLengthA = 0; + this.lengthB = 0; + this.maxLengthB = 0; + this.ratio = 1; + this.collideConnected = true +}; +b2PulleyJointDef.prototype.__varz = function() { + this.groundAnchorA = new b2Vec2; + this.groundAnchorB = new b2Vec2; + this.localAnchorA = new b2Vec2; + this.localAnchorB = new b2Vec2 +}; +b2PulleyJointDef.prototype.Initialize = function(bA, bB, gaA, gaB, anchorA, anchorB, r) { + this.bodyA = bA; + this.bodyB = bB; + this.groundAnchorA.SetV(gaA); + this.groundAnchorB.SetV(gaB); + this.localAnchorA = this.bodyA.GetLocalPoint(anchorA); + this.localAnchorB = this.bodyB.GetLocalPoint(anchorB); + var d1X = anchorA.x - gaA.x; + var d1Y = anchorA.y - gaA.y; + this.lengthA = Math.sqrt(d1X * d1X + d1Y * d1Y); + var d2X = anchorB.x - gaB.x; + var d2Y = anchorB.y - gaB.y; + this.lengthB = Math.sqrt(d2X * d2X + d2Y * d2Y); + this.ratio = r; + var C = this.lengthA + this.ratio * this.lengthB; + this.maxLengthA = C - this.ratio * b2PulleyJoint.b2_minPulleyLength; + this.maxLengthB = (C - b2PulleyJoint.b2_minPulleyLength) / this.ratio +}; +b2PulleyJointDef.prototype.groundAnchorA = new b2Vec2; +b2PulleyJointDef.prototype.groundAnchorB = new b2Vec2; +b2PulleyJointDef.prototype.localAnchorA = new b2Vec2; +b2PulleyJointDef.prototype.localAnchorB = new b2Vec2; +b2PulleyJointDef.prototype.lengthA = null; +b2PulleyJointDef.prototype.maxLengthA = null; +b2PulleyJointDef.prototype.lengthB = null; +b2PulleyJointDef.prototype.maxLengthB = null; +b2PulleyJointDef.prototype.ratio = null;var b2DistanceJointDef = function() { + b2JointDef.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2DistanceJointDef.prototype, b2JointDef.prototype); +b2DistanceJointDef.prototype._super = b2JointDef.prototype; +b2DistanceJointDef.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.type = b2Joint.e_distanceJoint; + this.length = 1; + this.frequencyHz = 0; + this.dampingRatio = 0 +}; +b2DistanceJointDef.prototype.__varz = function() { + this.localAnchorA = new b2Vec2; + this.localAnchorB = new b2Vec2 +}; +b2DistanceJointDef.prototype.Initialize = function(bA, bB, anchorA, anchorB) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchorA)); + this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchorB)); + var dX = anchorB.x - anchorA.x; + var dY = anchorB.y - anchorA.y; + this.length = Math.sqrt(dX * dX + dY * dY); + this.frequencyHz = 0; + this.dampingRatio = 0 +}; +b2DistanceJointDef.prototype.localAnchorA = new b2Vec2; +b2DistanceJointDef.prototype.localAnchorB = new b2Vec2; +b2DistanceJointDef.prototype.length = null; +b2DistanceJointDef.prototype.frequencyHz = null; +b2DistanceJointDef.prototype.dampingRatio = null;var b2FrictionJointDef = function() { + b2JointDef.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2FrictionJointDef.prototype, b2JointDef.prototype); +b2FrictionJointDef.prototype._super = b2JointDef.prototype; +b2FrictionJointDef.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.type = b2Joint.e_frictionJoint; + this.maxForce = 0; + this.maxTorque = 0 +}; +b2FrictionJointDef.prototype.__varz = function() { + this.localAnchorA = new b2Vec2; + this.localAnchorB = new b2Vec2 +}; +b2FrictionJointDef.prototype.Initialize = function(bA, bB, anchor) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); + this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)) +}; +b2FrictionJointDef.prototype.localAnchorA = new b2Vec2; +b2FrictionJointDef.prototype.localAnchorB = new b2Vec2; +b2FrictionJointDef.prototype.maxForce = null; +b2FrictionJointDef.prototype.maxTorque = null;var b2WeldJointDef = function() { + b2JointDef.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2WeldJointDef.prototype, b2JointDef.prototype); +b2WeldJointDef.prototype._super = b2JointDef.prototype; +b2WeldJointDef.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.type = b2Joint.e_weldJoint; + this.referenceAngle = 0 +}; +b2WeldJointDef.prototype.__varz = function() { + this.localAnchorA = new b2Vec2; + this.localAnchorB = new b2Vec2 +}; +b2WeldJointDef.prototype.Initialize = function(bA, bB, anchor) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); + this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)); + this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle() +}; +b2WeldJointDef.prototype.localAnchorA = new b2Vec2; +b2WeldJointDef.prototype.localAnchorB = new b2Vec2; +b2WeldJointDef.prototype.referenceAngle = null;var b2GearJointDef = function() { + b2JointDef.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2GearJointDef.prototype, b2JointDef.prototype); +b2GearJointDef.prototype._super = b2JointDef.prototype; +b2GearJointDef.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.type = b2Joint.e_gearJoint; + this.joint1 = null; + this.joint2 = null; + this.ratio = 1 +}; +b2GearJointDef.prototype.__varz = function() { +}; +b2GearJointDef.prototype.joint1 = null; +b2GearJointDef.prototype.joint2 = null; +b2GearJointDef.prototype.ratio = null;var b2Color = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Color.prototype.__constructor = function(rr, gg, bb) { + this._r = parseInt(255 * b2Math.Clamp(rr, 0, 1)); + this._g = parseInt(255 * b2Math.Clamp(gg, 0, 1)); + this._b = parseInt(255 * b2Math.Clamp(bb, 0, 1)) +}; +b2Color.prototype.__varz = function() { +}; +b2Color.prototype.Set = function(rr, gg, bb) { + this._r = parseInt(255 * b2Math.Clamp(rr, 0, 1)); + this._g = parseInt(255 * b2Math.Clamp(gg, 0, 1)); + this._b = parseInt(255 * b2Math.Clamp(bb, 0, 1)) +}; +b2Color.prototype.__defineGetter__("r", function() { + return this._r +}); +b2Color.prototype.__defineSetter__("r", function(rr) { + this._r = parseInt(255 * b2Math.Clamp(rr, 0, 1)) +}); +b2Color.prototype.__defineGetter__("g", function() { + return this._g +}); +b2Color.prototype.__defineSetter__("g", function(gg) { + this._g = parseInt(255 * b2Math.Clamp(gg, 0, 1)) +}); +b2Color.prototype.__defineGetter__("b", function() { + return this._g +}); +b2Color.prototype.__defineSetter__("b", function(bb) { + this._b = parseInt(255 * b2Math.Clamp(bb, 0, 1)) +}); +b2Color.prototype.__defineGetter__("color", function() { + return this._r << 16 | this._g << 8 | this._b +}); +b2Color.prototype._r = 0; +b2Color.prototype._g = 0; +b2Color.prototype._b = 0;var b2FrictionJoint = function() { + b2Joint.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2FrictionJoint.prototype, b2Joint.prototype); +b2FrictionJoint.prototype._super = b2Joint.prototype; +b2FrictionJoint.prototype.__constructor = function(def) { + this._super.__constructor.apply(this, [def]); + this.m_localAnchorA.SetV(def.localAnchorA); + this.m_localAnchorB.SetV(def.localAnchorB); + this.m_linearMass.SetZero(); + this.m_angularMass = 0; + this.m_linearImpulse.SetZero(); + this.m_angularImpulse = 0; + this.m_maxForce = def.maxForce; + this.m_maxTorque = def.maxTorque +}; +b2FrictionJoint.prototype.__varz = function() { + this.m_localAnchorA = new b2Vec2; + this.m_localAnchorB = new b2Vec2; + this.m_linearImpulse = new b2Vec2; + this.m_linearMass = new b2Mat22 +}; +b2FrictionJoint.prototype.InitVelocityConstraints = function(step) { + var tMat; + var tX; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * rAX + tMat.col2.x * rAY; + rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * rBX + tMat.col2.x * rBY; + rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; + rBX = tX; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + var K = new b2Mat22; + K.col1.x = mA + mB; + K.col2.x = 0; + K.col1.y = 0; + K.col2.y = mA + mB; + K.col1.x += iA * rAY * rAY; + K.col2.x += -iA * rAX * rAY; + K.col1.y += -iA * rAX * rAY; + K.col2.y += iA * rAX * rAX; + K.col1.x += iB * rBY * rBY; + K.col2.x += -iB * rBX * rBY; + K.col1.y += -iB * rBX * rBY; + K.col2.y += iB * rBX * rBX; + K.GetInverse(this.m_linearMass); + this.m_angularMass = iA + iB; + if(this.m_angularMass > 0) { + this.m_angularMass = 1 / this.m_angularMass + } + if(step.warmStarting) { + this.m_linearImpulse.x *= step.dtRatio; + this.m_linearImpulse.y *= step.dtRatio; + this.m_angularImpulse *= step.dtRatio; + var P = this.m_linearImpulse; + bA.m_linearVelocity.x -= mA * P.x; + bA.m_linearVelocity.y -= mA * P.y; + bA.m_angularVelocity -= iA * (rAX * P.y - rAY * P.x + this.m_angularImpulse); + bB.m_linearVelocity.x += mB * P.x; + bB.m_linearVelocity.y += mB * P.y; + bB.m_angularVelocity += iB * (rBX * P.y - rBY * P.x + this.m_angularImpulse) + }else { + this.m_linearImpulse.SetZero(); + this.m_angularImpulse = 0 + } +}; +b2FrictionJoint.prototype.SolveVelocityConstraints = function(step) { + var tMat; + var tX; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var vA = bA.m_linearVelocity; + var wA = bA.m_angularVelocity; + var vB = bB.m_linearVelocity; + var wB = bB.m_angularVelocity; + var mA = bA.m_invMass; + var mB = bB.m_invMass; + var iA = bA.m_invI; + var iB = bB.m_invI; + tMat = bA.m_xf.R; + var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; + var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * rAX + tMat.col2.x * rAY; + rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; + rAX = tX; + tMat = bB.m_xf.R; + var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; + var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * rBX + tMat.col2.x * rBY; + rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; + rBX = tX; + var maxImpulse; + var Cdot = wB - wA; + var impulse = -this.m_angularMass * Cdot; + var oldImpulse = this.m_angularImpulse; + maxImpulse = step.dt * this.m_maxTorque; + this.m_angularImpulse = b2Math.Clamp(this.m_angularImpulse + impulse, -maxImpulse, maxImpulse); + impulse = this.m_angularImpulse - oldImpulse; + wA -= iA * impulse; + wB += iB * impulse; + var CdotX = vB.x - wB * rBY - vA.x + wA * rAY; + var CdotY = vB.y + wB * rBX - vA.y - wA * rAX; + var impulseV = b2Math.MulMV(this.m_linearMass, new b2Vec2(-CdotX, -CdotY)); + var oldImpulseV = this.m_linearImpulse.Copy(); + this.m_linearImpulse.Add(impulseV); + maxImpulse = step.dt * this.m_maxForce; + if(this.m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) { + this.m_linearImpulse.Normalize(); + this.m_linearImpulse.Multiply(maxImpulse) + } + impulseV = b2Math.SubtractVV(this.m_linearImpulse, oldImpulseV); + vA.x -= mA * impulseV.x; + vA.y -= mA * impulseV.y; + wA -= iA * (rAX * impulseV.y - rAY * impulseV.x); + vB.x += mB * impulseV.x; + vB.y += mB * impulseV.y; + wB += iB * (rBX * impulseV.y - rBY * impulseV.x); + bA.m_angularVelocity = wA; + bB.m_angularVelocity = wB +}; +b2FrictionJoint.prototype.SolvePositionConstraints = function(baumgarte) { + return true +}; +b2FrictionJoint.prototype.GetAnchorA = function() { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA) +}; +b2FrictionJoint.prototype.GetAnchorB = function() { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB) +}; +b2FrictionJoint.prototype.GetReactionForce = function(inv_dt) { + return new b2Vec2(inv_dt * this.m_linearImpulse.x, inv_dt * this.m_linearImpulse.y) +}; +b2FrictionJoint.prototype.GetReactionTorque = function(inv_dt) { + return inv_dt * this.m_angularImpulse +}; +b2FrictionJoint.prototype.SetMaxForce = function(force) { + this.m_maxForce = force +}; +b2FrictionJoint.prototype.GetMaxForce = function() { + return this.m_maxForce +}; +b2FrictionJoint.prototype.SetMaxTorque = function(torque) { + this.m_maxTorque = torque +}; +b2FrictionJoint.prototype.GetMaxTorque = function() { + return this.m_maxTorque +}; +b2FrictionJoint.prototype.m_localAnchorA = new b2Vec2; +b2FrictionJoint.prototype.m_localAnchorB = new b2Vec2; +b2FrictionJoint.prototype.m_linearImpulse = new b2Vec2; +b2FrictionJoint.prototype.m_angularImpulse = null; +b2FrictionJoint.prototype.m_maxForce = null; +b2FrictionJoint.prototype.m_maxTorque = null; +b2FrictionJoint.prototype.m_linearMass = new b2Mat22; +b2FrictionJoint.prototype.m_angularMass = null;var b2Distance = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Distance.prototype.__constructor = function() { +}; +b2Distance.prototype.__varz = function() { +}; +b2Distance.Distance = function(output, cache, input) { + ++b2Distance.b2_gjkCalls; + var proxyA = input.proxyA; + var proxyB = input.proxyB; + var transformA = input.transformA; + var transformB = input.transformB; + var simplex = b2Distance.s_simplex; + simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB); + var vertices = simplex.m_vertices; + var k_maxIters = 20; + var saveA = b2Distance.s_saveA; + var saveB = b2Distance.s_saveB; + var saveCount = 0; + var closestPoint = simplex.GetClosestPoint(); + var distanceSqr1 = closestPoint.LengthSquared(); + var distanceSqr2 = distanceSqr1; + var i = 0; + var p; + var iter = 0; + while(iter < k_maxIters) { + saveCount = simplex.m_count; + for(i = 0;i < saveCount;i++) { + saveA[i] = vertices[i].indexA; + saveB[i] = vertices[i].indexB + } + switch(simplex.m_count) { case 1: - return 0.0; + break; case 2: - return b2Math.SubtractVV(this.m_v1.w, this.m_v2.w).Length(); + simplex.Solve2(); + break; case 3: - return b2Math.CrossVV(b2Math.SubtractVV(this.m_v2.w, this.m_v1.w), b2Math.SubtractVV(this.m_v3.w, this.m_v1.w)); + simplex.Solve3(); + break; default: - b2Settings.b2Assert(false); - return 0.0; - } - } - b2Simplex.prototype.Solve2 = function () { - var w1 = this.m_v1.w; - var w2 = this.m_v2.w; - var e12 = b2Math.SubtractVV(w2, w1); - var d12_2 = (-(w1.x * e12.x + w1.y * e12.y)); - if (d12_2 <= 0.0) { - this.m_v1.a = 1.0; - this.m_count = 1; - return; - } - var d12_1 = (w2.x * e12.x + w2.y * e12.y); - if (d12_1 <= 0.0) { - this.m_v2.a = 1.0; - this.m_count = 1; - this.m_v1.Set(this.m_v2); - return; - } - var inv_d12 = 1.0 / (d12_1 + d12_2); - this.m_v1.a = d12_1 * inv_d12; - this.m_v2.a = d12_2 * inv_d12; - this.m_count = 2; - } - b2Simplex.prototype.Solve3 = function () { - var w1 = this.m_v1.w; - var w2 = this.m_v2.w; - var w3 = this.m_v3.w; - var e12 = b2Math.SubtractVV(w2, w1); - var w1e12 = b2Math.Dot(w1, e12); - var w2e12 = b2Math.Dot(w2, e12); - var d12_1 = w2e12; - var d12_2 = (-w1e12); - var e13 = b2Math.SubtractVV(w3, w1); - var w1e13 = b2Math.Dot(w1, e13); - var w3e13 = b2Math.Dot(w3, e13); - var d13_1 = w3e13; - var d13_2 = (-w1e13); - var e23 = b2Math.SubtractVV(w3, w2); - var w2e23 = b2Math.Dot(w2, e23); - var w3e23 = b2Math.Dot(w3, e23); - var d23_1 = w3e23; - var d23_2 = (-w2e23); - var n123 = b2Math.CrossVV(e12, e13); - var d123_1 = n123 * b2Math.CrossVV(w2, w3); - var d123_2 = n123 * b2Math.CrossVV(w3, w1); - var d123_3 = n123 * b2Math.CrossVV(w1, w2); - if (d12_2 <= 0.0 && d13_2 <= 0.0) { - this.m_v1.a = 1.0; - this.m_count = 1; - return; - } - if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0) { - var inv_d12 = 1.0 / (d12_1 + d12_2); - this.m_v1.a = d12_1 * inv_d12; - this.m_v2.a = d12_2 * inv_d12; - this.m_count = 2; - return; - } - if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0) { - var inv_d13 = 1.0 / (d13_1 + d13_2); - this.m_v1.a = d13_1 * inv_d13; - this.m_v3.a = d13_2 * inv_d13; - this.m_count = 2; - this.m_v2.Set(this.m_v3); - return; - } - if (d12_1 <= 0.0 && d23_2 <= 0.0) { - this.m_v2.a = 1.0; - this.m_count = 1; - this.m_v1.Set(this.m_v2); - return; - } - if (d13_1 <= 0.0 && d23_1 <= 0.0) { - this.m_v3.a = 1.0; - this.m_count = 1; - this.m_v1.Set(this.m_v3); - return; - } - if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0) { - var inv_d23 = 1.0 / (d23_1 + d23_2); - this.m_v2.a = d23_1 * inv_d23; - this.m_v3.a = d23_2 * inv_d23; - this.m_count = 2; - this.m_v1.Set(this.m_v3); - return; - } - var inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3); - this.m_v1.a = d123_1 * inv_d123; - this.m_v2.a = d123_2 * inv_d123; - this.m_v3.a = d123_3 * inv_d123; - this.m_count = 3; - } - b2SimplexCache.b2SimplexCache = function () { - this.indexA = new Vector_a2j_Number(3); - this.indexB = new Vector_a2j_Number(3); - }; - b2SimplexVertex.b2SimplexVertex = function () {}; - b2SimplexVertex.prototype.Set = function (other) { - this.wA.SetV(other.wA); - this.wB.SetV(other.wB); - this.w.SetV(other.w); - this.a = other.a; - this.indexA = other.indexA; - this.indexB = other.indexB; - } - b2TimeOfImpact.b2TimeOfImpact = function () {}; - b2TimeOfImpact.prototype.TimeOfImpact = function (input) { - ++b2TimeOfImpact.b2_toiCalls; - var proxyA = input.proxyA; - var proxyB = input.proxyB; - var sweepA = input.sweepA; - var sweepB = input.sweepB; - b2Settings.b2Assert(sweepA.t0 == sweepB.t0); - b2Settings.b2Assert(1.0 - sweepA.t0 > Number.MIN_VALUE); - var radius = proxyA.m_radius + proxyB.m_radius; - var tolerance = input.tolerance; - var alpha = 0.0; - var k_maxIterations = 1000; - var iter = 0; - var target = 0.0; - b2TimeOfImpact.s_cache.count = 0; - b2TimeOfImpact.s_distanceInput.useRadii = false; - for (;;) { - sweepA.GetTransform(b2TimeOfImpact.s_xfA, alpha); - sweepB.GetTransform(b2TimeOfImpact.s_xfB, alpha); - b2TimeOfImpact.s_distanceInput.proxyA = proxyA; - b2TimeOfImpact.s_distanceInput.proxyB = proxyB; - b2TimeOfImpact.s_distanceInput.transformA = b2TimeOfImpact.s_xfA; - b2TimeOfImpact.s_distanceInput.transformB = b2TimeOfImpact.s_xfB; - b2Distance.Distance(b2TimeOfImpact.s_distanceOutput, b2TimeOfImpact.s_cache, b2TimeOfImpact.s_distanceInput); - if (b2TimeOfImpact.s_distanceOutput.distance <= 0.0) { - alpha = 1.0; - break; - } - b2TimeOfImpact.s_fcn.Initialize(b2TimeOfImpact.s_cache, proxyA, b2TimeOfImpact.s_xfA, proxyB, b2TimeOfImpact.s_xfB); - var separation = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); - if (separation <= 0.0) { - alpha = 1.0; - break; - } - if (iter == 0) { - if (separation > radius) { - target = b2Math.Max(radius - tolerance, 0.75 * radius); - } - else { - target = b2Math.Max(separation - tolerance, 0.02 * radius); - } - } - if (separation - target < 0.5 * tolerance) { - if (iter == 0) { - alpha = 1.0; - break; - } - break; - } - var newAlpha = alpha; { - var x1 = alpha; - var x2 = 1.0; - var f1 = separation; - sweepA.GetTransform(b2TimeOfImpact.s_xfA, x2); - sweepB.GetTransform(b2TimeOfImpact.s_xfB, x2); - var f2 = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); - if (f2 >= target) { - alpha = 1.0; - break; - } - var rootIterCount = 0; - for (;;) { - var x = 0; - if (rootIterCount & 1) { - x = x1 + (target - f1) * (x2 - x1) / (f2 - f1); - } - else { - x = 0.5 * (x1 + x2); - } - sweepA.GetTransform(b2TimeOfImpact.s_xfA, x); - sweepB.GetTransform(b2TimeOfImpact.s_xfB, x); - var f = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); - if (b2Math.Abs(f - target) < 0.025 * tolerance) { - newAlpha = x; - break; - } - if (f > target) { - x1 = x; - f1 = f; - } - else { - x2 = x; - f2 = f; - }++rootIterCount; - ++b2TimeOfImpact.b2_toiRootIters; - if (rootIterCount == 50) { - break; - } - } - b2TimeOfImpact.b2_toiMaxRootIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxRootIters, rootIterCount); - } - if (newAlpha < (1.0 + 100.0 * Number.MIN_VALUE) * alpha) { - break; - } - alpha = newAlpha; - iter++; - ++b2TimeOfImpact.b2_toiIters; - if (iter == k_maxIterations) { - break; - } - } - b2TimeOfImpact.b2_toiMaxIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxIters, iter); - return alpha; - } - b2TimeOfImpact.TimeOfImpact = b2TimeOfImpact.prototype.TimeOfImpact; - _A2J_postDefs.push(function () { - Box2D.Collision.b2TimeOfImpact.b2_toiCalls = 0; - Box2D.Collision.b2TimeOfImpact.prototype.b2_toiCalls = Box2D.Collision.b2TimeOfImpact.b2_toiCalls; - Box2D.Collision.b2TimeOfImpact.b2_toiIters = 0; - Box2D.Collision.b2TimeOfImpact.prototype.b2_toiIters = Box2D.Collision.b2TimeOfImpact.b2_toiIters; - Box2D.Collision.b2TimeOfImpact.b2_toiMaxIters = 0; - Box2D.Collision.b2TimeOfImpact.prototype.b2_toiMaxIters = Box2D.Collision.b2TimeOfImpact.b2_toiMaxIters; - Box2D.Collision.b2TimeOfImpact.b2_toiRootIters = 0; - Box2D.Collision.b2TimeOfImpact.prototype.b2_toiRootIters = Box2D.Collision.b2TimeOfImpact.b2_toiRootIters; - Box2D.Collision.b2TimeOfImpact.b2_toiMaxRootIters = 0; - Box2D.Collision.b2TimeOfImpact.prototype.b2_toiMaxRootIters = Box2D.Collision.b2TimeOfImpact.b2_toiMaxRootIters; - Box2D.Collision.b2TimeOfImpact.s_cache = new b2SimplexCache(); - Box2D.Collision.b2TimeOfImpact.prototype.s_cache = Box2D.Collision.b2TimeOfImpact.s_cache; - Box2D.Collision.b2TimeOfImpact.s_distanceInput = new b2DistanceInput(); - Box2D.Collision.b2TimeOfImpact.prototype.s_distanceInput = Box2D.Collision.b2TimeOfImpact.s_distanceInput; - Box2D.Collision.b2TimeOfImpact.s_xfA = new b2Transform(); - Box2D.Collision.b2TimeOfImpact.prototype.s_xfA = Box2D.Collision.b2TimeOfImpact.s_xfA; - Box2D.Collision.b2TimeOfImpact.s_xfB = new b2Transform(); - Box2D.Collision.b2TimeOfImpact.prototype.s_xfB = Box2D.Collision.b2TimeOfImpact.s_xfB; - Box2D.Collision.b2TimeOfImpact.s_fcn = new b2SeparationFunction(); - Box2D.Collision.b2TimeOfImpact.prototype.s_fcn = Box2D.Collision.b2TimeOfImpact.s_fcn; - Box2D.Collision.b2TimeOfImpact.s_distanceOutput = new b2DistanceOutput(); - Box2D.Collision.b2TimeOfImpact.prototype.s_distanceOutput = Box2D.Collision.b2TimeOfImpact.s_distanceOutput; - }); - b2TOIInput.b2TOIInput = function () { - this.proxyA = new b2DistanceProxy(); - this.proxyB = new b2DistanceProxy(); - this.sweepA = new b2Sweep(); - this.sweepB = new b2Sweep(); - }; - b2WorldManifold.b2WorldManifold = function () { - this.m_normal = new b2Vec2(); - }; - b2WorldManifold.prototype.b2WorldManifold = function () { - this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - this.m_points[i] = new b2Vec2(); - } - } - b2WorldManifold.prototype.Initialize = function (manifold, xfA, radiusA, xfB, radiusB) { - if (radiusA === undefined) radiusA = 0; - if (radiusB === undefined) radiusB = 0; - if (manifold.m_pointCount == 0) { - return; - } - var i = 0; - var tVec; - var tMat; - var normalX = 0; - var normalY = 0; - var planePointX = 0; - var planePointY = 0; - var clipPointX = 0; - var clipPointY = 0; - switch (manifold.m_type) { - case b2Manifold.e_circles: - { - tMat = xfA.R; - tVec = manifold.m_localPoint; - var pointAX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - var pointAY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xfB.R; - tVec = manifold.m_points[0].m_localPoint; - var pointBX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - var pointBY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - var dX = pointBX - pointAX; - var dY = pointBY - pointAY; - var d2 = dX * dX + dY * dY; - if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) { - var d = Math.sqrt(d2); - this.m_normal.x = dX / d; - this.m_normal.y = dY / d; - } - else { - this.m_normal.x = 1; - this.m_normal.y = 0; - } - var cAX = pointAX + radiusA * this.m_normal.x; - var cAY = pointAY + radiusA * this.m_normal.y; - var cBX = pointBX - radiusB * this.m_normal.x; - var cBY = pointBY - radiusB * this.m_normal.y; - this.m_points[0].x = 0.5 * (cAX + cBX); - this.m_points[0].y = 0.5 * (cAY + cBY); - } - break; - case b2Manifold.e_faceA: - { - tMat = xfA.R; - tVec = manifold.m_localPlaneNormal; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xfA.R; - tVec = manifold.m_localPoint; - planePointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - planePointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_normal.x = normalX; - this.m_normal.y = normalY; - for (i = 0; - i < manifold.m_pointCount; i++) { - tMat = xfB.R; - tVec = manifold.m_points[i].m_localPoint; - clipPointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - clipPointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_points[i].x = clipPointX + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalX; - this.m_points[i].y = clipPointY + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalY; - } - } - break; - case b2Manifold.e_faceB: - { - tMat = xfB.R; - tVec = manifold.m_localPlaneNormal; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xfB.R; - tVec = manifold.m_localPoint; - planePointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - planePointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_normal.x = (-normalX); - this.m_normal.y = (-normalY); - for (i = 0; - i < manifold.m_pointCount; i++) { - tMat = xfA.R; - tVec = manifold.m_points[i].m_localPoint; - clipPointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - clipPointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_points[i].x = clipPointX + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalX; - this.m_points[i].y = clipPointY + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalY; - } - } - break; - } - } - ClipVertex.ClipVertex = function () { - this.v = new b2Vec2(); - this.id = new b2ContactID(); - }; - ClipVertex.prototype.Set = function (other) { - this.v.SetV(other.v); - this.id.Set(other.id); - } - Features.Features = function () {}; - Features.prototype.__defineGetter__('referenceEdge', function () { - return this._referenceEdge; - }); - Features.prototype.__defineSetter__('referenceEdge', function (value) { - if (value === undefined) value = 0; - this._referenceEdge = value; - this._m_id._key = (this._m_id._key & 0xffffff00) | (this._referenceEdge & 0x000000ff); - }); - Features.prototype.__defineGetter__('incidentEdge', function () { - return this._incidentEdge; - }); - Features.prototype.__defineSetter__('incidentEdge', function (value) { - if (value === undefined) value = 0; - this._incidentEdge = value; - this._m_id._key = (this._m_id._key & 0xffff00ff) | ((this._incidentEdge << 8) & 0x0000ff00); - }); - Features.prototype.__defineGetter__('incidentVertex', function () { - return this._incidentVertex; - }); - Features.prototype.__defineSetter__('incidentVertex', function (value) { - if (value === undefined) value = 0; - this._incidentVertex = value; - this._m_id._key = (this._m_id._key & 0xff00ffff) | ((this._incidentVertex << 16) & 0x00ff0000); - }); - Features.prototype.__defineGetter__('flip', function () { - return this._flip; - }); - Features.prototype.__defineSetter__('flip', function (value) { - if (value === undefined) value = 0; - this._flip = value; - this._m_id._key = (this._m_id._key & 0x00ffffff) | ((this._flip << 24) & 0xff000000); - }); -})(); /* source: disabled*/ -(function () { - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; - var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; - var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; - var b2MassData = Box2D.Collision.Shapes.b2MassData; - var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; - var b2Shape = Box2D.Collision.Shapes.b2Shape; - var b2Mat22 = Box2D.Common.Math.b2Mat22; - var b2Mat33 = Box2D.Common.Math.b2Mat33; - var b2Math = Box2D.Common.Math.b2Math; - var b2Sweep = Box2D.Common.Math.b2Sweep; - var b2Transform = Box2D.Common.Math.b2Transform; - var b2Vec2 = Box2D.Common.Math.b2Vec2; - var b2Vec3 = Box2D.Common.Math.b2Vec3; - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2Body = Box2D.Dynamics.b2Body; - var b2BodyDef = Box2D.Dynamics.b2BodyDef; - var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; - var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; - var b2ContactListener = Box2D.Dynamics.b2ContactListener; - var b2ContactManager = Box2D.Dynamics.b2ContactManager; - var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; - var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; - var b2FilterData = Box2D.Dynamics.b2FilterData; - var b2Fixture = Box2D.Dynamics.b2Fixture; - var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; - var b2Island = Box2D.Dynamics.b2Island; - var b2TimeStep = Box2D.Dynamics.b2TimeStep; - var b2World = Box2D.Dynamics.b2World; - var b2AABB = Box2D.Collision.b2AABB; - var b2Bound = Box2D.Collision.b2Bound; - var b2BoundValues = Box2D.Collision.b2BoundValues; - var b2BroadPhase = Box2D.Collision.b2BroadPhase; - var b2Collision = Box2D.Collision.b2Collision; - var b2ContactID = Box2D.Collision.b2ContactID; - var b2ContactPoint = Box2D.Collision.b2ContactPoint; - var b2Distance = Box2D.Collision.b2Distance; - var b2DistanceInput = Box2D.Collision.b2DistanceInput; - var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; - var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; - var b2DynamicTree = Box2D.Collision.b2DynamicTree; - var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; - var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; - var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; - var b2Manifold = Box2D.Collision.b2Manifold; - var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; - var b2OBB = Box2D.Collision.b2OBB; - var b2Pair = Box2D.Collision.b2Pair; - var b2PairManager = Box2D.Collision.b2PairManager; - var b2Point = Box2D.Collision.b2Point; - var b2Proxy = Box2D.Collision.b2Proxy; - var b2RayCastInput = Box2D.Collision.b2RayCastInput; - var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; - var b2Segment = Box2D.Collision.b2Segment; - var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; - var b2Simplex = Box2D.Collision.b2Simplex; - var b2SimplexCache = Box2D.Collision.b2SimplexCache; - var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; - var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; - var b2TOIInput = Box2D.Collision.b2TOIInput; - var b2WorldManifold = Box2D.Collision.b2WorldManifold; - var ClipVertex = Box2D.Collision.ClipVertex; - var Features = Box2D.Collision.Features; - var IBroadPhase = Box2D.Collision.IBroadPhase; - var b2internal = Box2D.Common.b2internal; - var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; - var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; - var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; - var b2MassData = Box2D.Collision.Shapes.b2MassData; - var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; - var b2Shape = Box2D.Collision.Shapes.b2Shape; - helpers.inherit.call(b2CircleShape, Box2D.Collision.Shapes.b2Shape); - b2CircleShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype; - b2CircleShape.b2CircleShape = function () { - Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments); - this.m_p = new b2Vec2(); - }; - b2CircleShape.prototype.Copy = function () { - var s = new b2CircleShape(); - s.Set(this); - return s; - } - b2CircleShape.prototype.Set = function (other) { - this.__super.Set.call(this, other); - if (a2j.is(other, b2CircleShape)) { - var other2 = (other instanceof b2CircleShape ? other : null); - this.m_p.SetV(other2.m_p); - } - } - b2CircleShape.prototype.TestPoint = function (transform, p) { - var tMat = transform.R; - var dX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); - var dY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); - dX = p.x - dX; - dY = p.y - dY; - return (dX * dX + dY * dY) <= this.m_radius * this.m_radius; - } - b2CircleShape.prototype.RayCast = function (output, input, transform) { - var tMat = transform.R; - var positionX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); - var positionY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); - var sX = input.p1.x - positionX; - var sY = input.p1.y - positionY; - var b = (sX * sX + sY * sY) - this.m_radius * this.m_radius; - var rX = input.p2.x - input.p1.x; - var rY = input.p2.y - input.p1.y; - var c = (sX * rX + sY * rY); - var rr = (rX * rX + rY * rY); - var sigma = c * c - rr * b; - if (sigma < 0.0 || rr < Number.MIN_VALUE) { - return false; - } - var a = (-(c + Math.sqrt(sigma))); - if (0.0 <= a && a <= input.maxFraction * rr) { - a /= rr; - output.fraction = a; - output.normal.x = sX + a * rX; - output.normal.y = sY + a * rY; - output.normal.Normalize(); - return true; - } - return false; - } - b2CircleShape.prototype.ComputeAABB = function (aabb, transform) { - var tMat = transform.R; - var pX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); - var pY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); - aabb.lowerBound.Set(pX - this.m_radius, pY - this.m_radius); - aabb.upperBound.Set(pX + this.m_radius, pY + this.m_radius); - } - b2CircleShape.prototype.ComputeMass = function (massData, density) { - if (density === undefined) density = 0; - massData.mass = density * b2Settings.b2_pi * this.m_radius * this.m_radius; - massData.center.SetV(this.m_p); - massData.I = massData.mass * (0.5 * this.m_radius * this.m_radius + (this.m_p.x * this.m_p.x + this.m_p.y * this.m_p.y)); - } - b2CircleShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { - if (offset === undefined) offset = 0; - var p = b2Math.MulX(xf, this.m_p); - var l = (-(b2Math.Dot(normal, p) - offset)); - if (l < (-this.m_radius) + Number.MIN_VALUE) { - return 0; - } - if (l > this.m_radius) { - c.SetV(p); - return Math.PI * this.m_radius * this.m_radius; - } - var r2 = this.m_radius * this.m_radius; - var l2 = l * l; - var area = r2 * (Math.asin(l / this.m_radius) + Math.PI / 2) + l * Math.sqrt(r2 - l2); - var com = (-2 / 3 * Math.pow(r2 - l2, 1.5) / area); - c.x = p.x + normal.x * com; - c.y = p.y + normal.y * com; - return area; - } - b2CircleShape.prototype.GetLocalPosition = function () { - return this.m_p; - } - b2CircleShape.prototype.SetLocalPosition = function (position) { - this.m_p.SetV(position); - } - b2CircleShape.prototype.GetRadius = function () { - return this.m_radius; - } - b2CircleShape.prototype.SetRadius = function (radius) { - if (radius === undefined) radius = 0; - this.m_radius = radius; - } - b2CircleShape.prototype.b2CircleShape = function (radius) { - if (radius === undefined) radius = 0; - this.__super.b2Shape.call(this); - this.m_type = this.e_circleShape; - this.m_radius = radius; - } - b2EdgeChainDef.b2EdgeChainDef = function () {}; - b2EdgeChainDef.prototype.b2EdgeChainDef = function () { - this.vertexCount = 0; - this.isALoop = true; - this.vertices = []; - } - helpers.inherit.call(b2EdgeShape, Box2D.Collision.Shapes.b2Shape); - b2EdgeShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype; - b2EdgeShape.b2EdgeShape = function () { - Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments); - this.s_supportVec = new b2Vec2(); - this.m_v1 = new b2Vec2(); - this.m_v2 = new b2Vec2(); - this.m_coreV1 = new b2Vec2(); - this.m_coreV2 = new b2Vec2(); - this.m_normal = new b2Vec2(); - this.m_direction = new b2Vec2(); - this.m_cornerDir1 = new b2Vec2(); - this.m_cornerDir2 = new b2Vec2(); - }; - b2EdgeShape.prototype.TestPoint = function (transform, p) { - return false; - } - b2EdgeShape.prototype.RayCast = function (output, input, transform) { - var tMat; - var rX = input.p2.x - input.p1.x; - var rY = input.p2.y - input.p1.y; - tMat = transform.R; - var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); - var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); - var nX = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y) - v1Y; - var nY = (-(transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y) - v1X)); - var k_slop = 100.0 * Number.MIN_VALUE; - var denom = (-(rX * nX + rY * nY)); - if (denom > k_slop) { - var bX = input.p1.x - v1X; - var bY = input.p1.y - v1Y; - var a = (bX * nX + bY * nY); - if (0.0 <= a && a <= input.maxFraction * denom) { - var mu2 = (-rX * bY) + rY * bX; - if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) { - a /= denom; - output.fraction = a; - var nLen = Math.sqrt(nX * nX + nY * nY); - output.normal.x = nX / nLen; - output.normal.y = nY / nLen; - return true; - } - } - } - return false; - } - b2EdgeShape.prototype.ComputeAABB = function (aabb, transform) { - var tMat = transform.R; - var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); - var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); - var v2X = transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y); - var v2Y = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y); - if (v1X < v2X) { - aabb.lowerBound.x = v1X; - aabb.upperBound.x = v2X; - } - else { - aabb.lowerBound.x = v2X; - aabb.upperBound.x = v1X; - } - if (v1Y < v2Y) { - aabb.lowerBound.y = v1Y; - aabb.upperBound.y = v2Y; - } - else { - aabb.lowerBound.y = v2Y; - aabb.upperBound.y = v1Y; - } - } - b2EdgeShape.prototype.ComputeMass = function (massData, density) { - if (density === undefined) density = 0; - massData.mass = 0; - massData.center.SetV(this.m_v1); - massData.I = 0; - } - b2EdgeShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { - if (offset === undefined) offset = 0; - var v0 = new b2Vec2(normal.x * offset, normal.y * offset); - var v1 = b2Math.MulX(xf, this.m_v1); - var v2 = b2Math.MulX(xf, this.m_v2); - var d1 = b2Math.Dot(normal, v1) - offset; - var d2 = b2Math.Dot(normal, v2) - offset; - if (d1 > 0) { - if (d2 > 0) { - return 0; - } - else { - v1.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x; - v1.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y; - } - } - else { - if (d2 > 0) { - v2.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x; - v2.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y; - } - else {} - } - c.x = (v0.x + v1.x + v2.x) / 3; - c.y = (v0.y + v1.y + v2.y) / 3; - return 0.5 * ((v1.x - v0.x) * (v2.y - v0.y) - (v1.y - v0.y) * (v2.x - v0.x)); - } - b2EdgeShape.prototype.GetLength = function () { - return this.m_length; - } - b2EdgeShape.prototype.GetVertex1 = function () { - return this.m_v1; - } - b2EdgeShape.prototype.GetVertex2 = function () { - return this.m_v2; - } - b2EdgeShape.prototype.GetCoreVertex1 = function () { - return this.m_coreV1; - } - b2EdgeShape.prototype.GetCoreVertex2 = function () { - return this.m_coreV2; - } - b2EdgeShape.prototype.GetNormalVector = function () { - return this.m_normal; - } - b2EdgeShape.prototype.GetDirectionVector = function () { - return this.m_direction; - } - b2EdgeShape.prototype.GetCorner1Vector = function () { - return this.m_cornerDir1; - } - b2EdgeShape.prototype.GetCorner2Vector = function () { - return this.m_cornerDir2; - } - b2EdgeShape.prototype.Corner1IsConvex = function () { - return this.m_cornerConvex1; - } - b2EdgeShape.prototype.Corner2IsConvex = function () { - return this.m_cornerConvex2; - } - b2EdgeShape.prototype.GetFirstVertex = function (xf) { - var tMat = xf.R; - return new b2Vec2(xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y), xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y)); - } - b2EdgeShape.prototype.GetNextEdge = function () { - return this.m_nextEdge; - } - b2EdgeShape.prototype.GetPrevEdge = function () { - return this.m_prevEdge; - } - b2EdgeShape.prototype.Support = function (xf, dX, dY) { - if (dX === undefined) dX = 0; - if (dY === undefined) dY = 0; - var tMat = xf.R; - var v1X = xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y); - var v1Y = xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y); - var v2X = xf.position.x + (tMat.col1.x * this.m_coreV2.x + tMat.col2.x * this.m_coreV2.y); - var v2Y = xf.position.y + (tMat.col1.y * this.m_coreV2.x + tMat.col2.y * this.m_coreV2.y); - if ((v1X * dX + v1Y * dY) > (v2X * dX + v2Y * dY)) { - this.s_supportVec.x = v1X; - this.s_supportVec.y = v1Y; - } - else { - this.s_supportVec.x = v2X; - this.s_supportVec.y = v2Y; - } - return this.s_supportVec; - } - b2EdgeShape.prototype.b2EdgeShape = function (v1, v2) { - this.__super.b2Shape.call(this); - this.m_type = this.e_edgeShape; - this.m_prevEdge = null; - this.m_nextEdge = null; - this.m_v1 = v1; - this.m_v2 = v2; - this.m_direction.Set(this.m_v2.x - this.m_v1.x, this.m_v2.y - this.m_v1.y); - this.m_length = this.m_direction.Normalize(); - this.m_normal.Set(this.m_direction.y, (-this.m_direction.x)); - this.m_coreV1.Set((-b2Settings.b2_toiSlop * (this.m_normal.x - this.m_direction.x)) + this.m_v1.x, (-b2Settings.b2_toiSlop * (this.m_normal.y - this.m_direction.y)) + this.m_v1.y); - this.m_coreV2.Set((-b2Settings.b2_toiSlop * (this.m_normal.x + this.m_direction.x)) + this.m_v2.x, (-b2Settings.b2_toiSlop * (this.m_normal.y + this.m_direction.y)) + this.m_v2.y); - this.m_cornerDir1 = this.m_normal; - this.m_cornerDir2.Set((-this.m_normal.x), (-this.m_normal.y)); - } - b2EdgeShape.prototype.SetPrevEdge = function (edge, core, cornerDir, convex) { - this.m_prevEdge = edge; - this.m_coreV1 = core; - this.m_cornerDir1 = cornerDir; - this.m_cornerConvex1 = convex; - } - b2EdgeShape.prototype.SetNextEdge = function (edge, core, cornerDir, convex) { - this.m_nextEdge = edge; - this.m_coreV2 = core; - this.m_cornerDir2 = cornerDir; - this.m_cornerConvex2 = convex; - } - b2MassData.b2MassData = function () { - this.mass = 0.0; - this.center = new b2Vec2(0, 0); - this.I = 0.0; - }; - helpers.inherit.call(b2PolygonShape, Box2D.Collision.Shapes.b2Shape); - b2PolygonShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype; - b2PolygonShape.b2PolygonShape = function () { - Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments); - }; - b2PolygonShape.prototype.Copy = function () { - var s = new b2PolygonShape(); - s.Set(this); - return s; - } - b2PolygonShape.prototype.Set = function (other) { - this.__super.Set.call(this, other); - if (a2j.is(other, b2PolygonShape)) { - var other2 = (other instanceof b2PolygonShape ? other : null); - this.m_centroid.SetV(other2.m_centroid); - this.m_vertexCount = other2.m_vertexCount; - this.Reserve(this.m_vertexCount); - for (var i = 0; i < this.m_vertexCount; i++) { - this.m_vertices[i].SetV(other2.m_vertices[i]); - this.m_normals[i].SetV(other2.m_normals[i]); - } - } - } - b2PolygonShape.prototype.SetAsArray = function (vertices, vertexCount) { - if (vertexCount === undefined) vertexCount = 0; - var v = new Vector(); - var tVec; - for (var each in vertices) { - tVec = vertices[each]; { - v.push(tVec); - } - } - this.SetAsVector(v, vertexCount); - } - b2PolygonShape.prototype.AsArray = function (vertices, vertexCount) { - if (vertexCount === undefined) vertexCount = 0; - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsArray(vertices, vertexCount); - return polygonShape; - } - b2PolygonShape.AsArray = b2PolygonShape.prototype.AsArray; - b2PolygonShape.prototype.SetAsVector = function (vertices, vertexCount) { - if (vertexCount === undefined) vertexCount = 0; - if (vertexCount == 0) vertexCount = vertices.length; - b2Settings.b2Assert(2 <= vertexCount); - this.m_vertexCount = vertexCount; - this.Reserve(vertexCount); - var i = 0; - for (i = 0; - i < this.m_vertexCount; i++) { - this.m_vertices[i].SetV(vertices[i]); - } - for (i = 0; - i < this.m_vertexCount; ++i) { - var i1 = parseInt(i); - var i2 = parseInt(i + 1 < this.m_vertexCount ? i + 1 : 0); - var edge = b2Math.SubtractVV(this.m_vertices[i2], this.m_vertices[i1]); - b2Settings.b2Assert(edge.LengthSquared() > Number.MIN_VALUE); - this.m_normals[i].SetV(b2Math.CrossVF(edge, 1.0)); - this.m_normals[i].Normalize(); - } - this.m_centroid = this.ComputeCentroid(this.m_vertices, this.m_vertexCount); - } - b2PolygonShape.prototype.AsVector = function (vertices, vertexCount) { - if (vertexCount === undefined) vertexCount = 0; - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsVector(vertices, vertexCount); - return polygonShape; - } - b2PolygonShape.AsVector = b2PolygonShape.prototype.AsVector; - b2PolygonShape.prototype.SetAsBox = function (hx, hy) { - if (hx === undefined) hx = 0; - if (hy === undefined) hy = 0; - this.m_vertexCount = 4; - this.Reserve(4); - this.m_vertices[0].Set((-hx), (-hy)); - this.m_vertices[1].Set(hx, (-hy)); - this.m_vertices[2].Set(hx, hy); - this.m_vertices[3].Set((-hx), hy); - this.m_normals[0].Set(0.0, (-1.0)); - this.m_normals[1].Set(1.0, 0.0); - this.m_normals[2].Set(0.0, 1.0); - this.m_normals[3].Set((-1.0), 0.0); - this.m_centroid.SetZero(); - } - b2PolygonShape.prototype.AsBox = function (hx, hy) { - if (hx === undefined) hx = 0; - if (hy === undefined) hy = 0; - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsBox(hx, hy); - return polygonShape; - } - b2PolygonShape.AsBox = b2PolygonShape.prototype.AsBox; - b2PolygonShape.prototype.SetAsOrientedBox = function (hx, hy, center, angle) { - if (hx === undefined) hx = 0; - if (hy === undefined) hy = 0; - if (center === undefined) center = null; - if (angle === undefined) angle = 0.0; - this.m_vertexCount = 4; - this.Reserve(4); - this.m_vertices[0].Set((-hx), (-hy)); - this.m_vertices[1].Set(hx, (-hy)); - this.m_vertices[2].Set(hx, hy); - this.m_vertices[3].Set((-hx), hy); - this.m_normals[0].Set(0.0, (-1.0)); - this.m_normals[1].Set(1.0, 0.0); - this.m_normals[2].Set(0.0, 1.0); - this.m_normals[3].Set((-1.0), 0.0); - this.m_centroid = center; - var xf = new b2Transform(); - xf.position = center; - xf.R.Set(angle); - for (var i = 0; i < this.m_vertexCount; ++i) { - this.m_vertices[i] = b2Math.MulX(xf, this.m_vertices[i]); - this.m_normals[i] = b2Math.MulMV(xf.R, this.m_normals[i]); - } - } - b2PolygonShape.prototype.AsOrientedBox = function (hx, hy, center, angle) { - if (hx === undefined) hx = 0; - if (hy === undefined) hy = 0; - if (center === undefined) center = null; - if (angle === undefined) angle = 0.0; - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsOrientedBox(hx, hy, center, angle); - return polygonShape; - } - b2PolygonShape.AsOrientedBox = b2PolygonShape.prototype.AsOrientedBox; - b2PolygonShape.prototype.SetAsEdge = function (v1, v2) { - this.m_vertexCount = 2; - this.Reserve(2); - this.m_vertices[0].SetV(v1); - this.m_vertices[1].SetV(v2); - this.m_centroid.x = 0.5 * (v1.x + v2.x); - this.m_centroid.y = 0.5 * (v1.y + v2.y); - this.m_normals[0] = b2Math.CrossVF(b2Math.SubtractVV(v2, v1), 1.0); - this.m_normals[0].Normalize(); - this.m_normals[1].x = (-this.m_normals[0].x); - this.m_normals[1].y = (-this.m_normals[0].y); - } - b2PolygonShape.prototype.AsEdge = function (v1, v2) { - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsEdge(v1, v2); - return polygonShape; - } - b2PolygonShape.AsEdge = b2PolygonShape.prototype.AsEdge; - b2PolygonShape.prototype.TestPoint = function (xf, p) { - var tVec; - var tMat = xf.R; - var tX = p.x - xf.position.x; - var tY = p.y - xf.position.y; - var pLocalX = (tX * tMat.col1.x + tY * tMat.col1.y); - var pLocalY = (tX * tMat.col2.x + tY * tMat.col2.y); - for (var i = 0; i < this.m_vertexCount; ++i) { - tVec = this.m_vertices[i]; - tX = pLocalX - tVec.x; - tY = pLocalY - tVec.y; - tVec = this.m_normals[i]; - var dot = (tVec.x * tX + tVec.y * tY); - if (dot > 0.0) { - return false; - } - } - return true; - } - b2PolygonShape.prototype.RayCast = function (output, input, transform) { - var lower = 0.0; - var upper = input.maxFraction; - var tX = 0; - var tY = 0; - var tMat; - var tVec; - tX = input.p1.x - transform.position.x; - tY = input.p1.y - transform.position.y; - tMat = transform.R; - var p1X = (tX * tMat.col1.x + tY * tMat.col1.y); - var p1Y = (tX * tMat.col2.x + tY * tMat.col2.y); - tX = input.p2.x - transform.position.x; - tY = input.p2.y - transform.position.y; - tMat = transform.R; - var p2X = (tX * tMat.col1.x + tY * tMat.col1.y); - var p2Y = (tX * tMat.col2.x + tY * tMat.col2.y); - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var index = parseInt((-1)); - for (var i = 0; i < this.m_vertexCount; ++i) { - tVec = this.m_vertices[i]; - tX = tVec.x - p1X; - tY = tVec.y - p1Y; - tVec = this.m_normals[i]; - var numerator = (tVec.x * tX + tVec.y * tY); - var denominator = (tVec.x * dX + tVec.y * dY); - if (denominator == 0.0) { - if (numerator < 0.0) { - return false; - } - } - else { - if (denominator < 0.0 && numerator < lower * denominator) { - lower = numerator / denominator; - index = i; - } - else if (denominator > 0.0 && numerator < upper * denominator) { - upper = numerator / denominator; - } - } - if (upper < lower - Number.MIN_VALUE) { - return false; - } - } - if (index >= 0) { - output.fraction = lower; - tMat = transform.R; - tVec = this.m_normals[index]; - output.normal.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - output.normal.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - return true; - } - return false; - } - b2PolygonShape.prototype.ComputeAABB = function (aabb, xf) { - var tMat = xf.R; - var tVec = this.m_vertices[0]; - var lowerX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var lowerY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var upperX = lowerX; - var upperY = lowerY; - for (var i = 1; i < this.m_vertexCount; ++i) { - tVec = this.m_vertices[i]; - var vX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var vY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - lowerX = lowerX < vX ? lowerX : vX; - lowerY = lowerY < vY ? lowerY : vY; - upperX = upperX > vX ? upperX : vX; - upperY = upperY > vY ? upperY : vY; - } - aabb.lowerBound.x = lowerX - this.m_radius; - aabb.lowerBound.y = lowerY - this.m_radius; - aabb.upperBound.x = upperX + this.m_radius; - aabb.upperBound.y = upperY + this.m_radius; - } - b2PolygonShape.prototype.ComputeMass = function (massData, density) { - if (density === undefined) density = 0; - if (this.m_vertexCount == 2) { - massData.center.x = 0.5 * (this.m_vertices[0].x + this.m_vertices[1].x); - massData.center.y = 0.5 * (this.m_vertices[0].y + this.m_vertices[1].y); - massData.mass = 0.0; - massData.I = 0.0; - return; - } - var centerX = 0.0; - var centerY = 0.0; - var area = 0.0; - var I = 0.0; - var p1X = 0.0; - var p1Y = 0.0; - var k_inv3 = 1.0 / 3.0; - for (var i = 0; i < this.m_vertexCount; ++i) { - var p2 = this.m_vertices[i]; - var p3 = i + 1 < this.m_vertexCount ? this.m_vertices[parseInt(i + 1)] : this.m_vertices[0]; - var e1X = p2.x - p1X; - var e1Y = p2.y - p1Y; - var e2X = p3.x - p1X; - var e2Y = p3.y - p1Y; - var D = e1X * e2Y - e1Y * e2X; - var triangleArea = 0.5 * D;area += triangleArea; - centerX += triangleArea * k_inv3 * (p1X + p2.x + p3.x); - centerY += triangleArea * k_inv3 * (p1Y + p2.y + p3.y); - var px = p1X; - var py = p1Y; - var ex1 = e1X; - var ey1 = e1Y; - var ex2 = e2X; - var ey2 = e2Y; - var intx2 = k_inv3 * (0.25 * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5 * px * px; - var inty2 = k_inv3 * (0.25 * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5 * py * py;I += D * (intx2 + inty2); - } - massData.mass = density * area; - centerX *= 1.0 / area; - centerY *= 1.0 / area; - massData.center.Set(centerX, centerY); - massData.I = density * I; - } - b2PolygonShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { - if (offset === undefined) offset = 0; - var normalL = b2Math.MulTMV(xf.R, normal); - var offsetL = offset - b2Math.Dot(normal, xf.position); - var depths = new Vector_a2j_Number(); - var diveCount = 0; - var intoIndex = parseInt((-1)); - var outoIndex = parseInt((-1)); - var lastSubmerged = false; - var i = 0; - for (i = 0; - i < this.m_vertexCount; ++i) { - depths[i] = b2Math.Dot(normalL, this.m_vertices[i]) - offsetL; - var isSubmerged = depths[i] < (-Number.MIN_VALUE); - if (i > 0) { - if (isSubmerged) { - if (!lastSubmerged) { - intoIndex = i - 1; - diveCount++; - } - } - else { - if (lastSubmerged) { - outoIndex = i - 1; - diveCount++; - } - } - } - lastSubmerged = isSubmerged; - } - switch (diveCount) { - case 0: - if (lastSubmerged) { - var md = new b2MassData(); - this.ComputeMass(md, 1); - c.SetV(b2Math.MulX(xf, md.center)); - return md.mass; - } - else { - return 0; - } - break; - case 1: - if (intoIndex == (-1)) { - intoIndex = this.m_vertexCount - 1; - } - else { - outoIndex = this.m_vertexCount - 1; - } - break; - } - var intoIndex2 = parseInt((intoIndex + 1) % this.m_vertexCount); - var outoIndex2 = parseInt((outoIndex + 1) % this.m_vertexCount); - var intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]); - var outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]); - var intoVec = new b2Vec2(this.m_vertices[intoIndex].x * (1 - intoLamdda) + this.m_vertices[intoIndex2].x * intoLamdda, this.m_vertices[intoIndex].y * (1 - intoLamdda) + this.m_vertices[intoIndex2].y * intoLamdda); - var outoVec = new b2Vec2(this.m_vertices[outoIndex].x * (1 - outoLamdda) + this.m_vertices[outoIndex2].x * outoLamdda, this.m_vertices[outoIndex].y * (1 - outoLamdda) + this.m_vertices[outoIndex2].y * outoLamdda); - var area = 0; - var center = new b2Vec2(); - var p2 = this.m_vertices[intoIndex2]; - var p3; - i = intoIndex2; - while (i != outoIndex2) { - i = (i + 1) % this.m_vertexCount; - if (i == outoIndex2) p3 = outoVec; - else p3 = this.m_vertices[i]; - var triangleArea = 0.5 * ((p2.x - intoVec.x) * (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x)); - area += triangleArea; - center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3; - center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3; - p2 = p3; - } - center.Multiply(1 / area); - c.SetV(b2Math.MulX(xf, center)); - return area; - } - b2PolygonShape.prototype.GetVertexCount = function () { - return this.m_vertexCount; - } - b2PolygonShape.prototype.GetVertices = function () { - return this.m_vertices; - } - b2PolygonShape.prototype.GetNormals = function () { - return this.m_normals; - } - b2PolygonShape.prototype.GetSupport = function (d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for (var i = 1; i < this.m_vertexCount; ++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if (value > bestValue) { - bestIndex = i; - bestValue = value; - } - } - return bestIndex; - } - b2PolygonShape.prototype.GetSupportVertex = function (d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for (var i = 1; i < this.m_vertexCount; ++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if (value > bestValue) { - bestIndex = i; - bestValue = value; - } - } - return this.m_vertices[bestIndex]; - } - b2PolygonShape.prototype.Validate = function () { - return false; - } - b2PolygonShape.prototype.b2PolygonShape = function () { - this.__super.b2Shape.call(this); - this.m_type = this.e_polygonShape; - this.m_centroid = new b2Vec2(); - this.m_vertices = new Vector(); - this.m_normals = new Vector(); - } - b2PolygonShape.prototype.Reserve = function (count) { - if (count === undefined) count = 0; - for (var i = parseInt(this.m_vertices.length); i < count; i++) { - this.m_vertices[i] = new b2Vec2(); - this.m_normals[i] = new b2Vec2(); + b2Settings.b2Assert(false) + } + if(simplex.m_count == 3) { + break + } + p = simplex.GetClosestPoint(); + distanceSqr2 = p.LengthSquared(); + if(distanceSqr2 > distanceSqr1) { + } + distanceSqr1 = distanceSqr2; + var d = simplex.GetSearchDirection(); + if(d.LengthSquared() < Number.MIN_VALUE * Number.MIN_VALUE) { + break + } + var vertex = vertices[simplex.m_count]; + vertex.indexA = proxyA.GetSupport(b2Math.MulTMV(transformA.R, d.GetNegative())); + vertex.wA = b2Math.MulX(transformA, proxyA.GetVertex(vertex.indexA)); + vertex.indexB = proxyB.GetSupport(b2Math.MulTMV(transformB.R, d)); + vertex.wB = b2Math.MulX(transformB, proxyB.GetVertex(vertex.indexB)); + vertex.w = b2Math.SubtractVV(vertex.wB, vertex.wA); + ++iter; + ++b2Distance.b2_gjkIters; + var duplicate = false; + for(i = 0;i < saveCount;i++) { + if(vertex.indexA == saveA[i] && vertex.indexB == saveB[i]) { + duplicate = true; + break + } + } + if(duplicate) { + break + } + ++simplex.m_count + } + b2Distance.b2_gjkMaxIters = b2Math.Max(b2Distance.b2_gjkMaxIters, iter); + simplex.GetWitnessPoints(output.pointA, output.pointB); + output.distance = b2Math.SubtractVV(output.pointA, output.pointB).Length(); + output.iterations = iter; + simplex.WriteCache(cache); + if(input.useRadii) { + var rA = proxyA.m_radius; + var rB = proxyB.m_radius; + if(output.distance > rA + rB && output.distance > Number.MIN_VALUE) { + output.distance -= rA + rB; + var normal = b2Math.SubtractVV(output.pointB, output.pointA); + normal.Normalize(); + output.pointA.x += rA * normal.x; + output.pointA.y += rA * normal.y; + output.pointB.x -= rB * normal.x; + output.pointB.y -= rB * normal.y + }else { + p = new b2Vec2; + p.x = 0.5 * (output.pointA.x + output.pointB.x); + p.y = 0.5 * (output.pointA.y + output.pointB.y); + output.pointA.x = output.pointB.x = p.x; + output.pointA.y = output.pointB.y = p.y; + output.distance = 0 + } + } +}; +b2Distance.b2_gjkCalls = 0; +b2Distance.b2_gjkIters = 0; +b2Distance.b2_gjkMaxIters = 0; +b2Distance.s_simplex = new b2Simplex; +b2Distance.s_saveA = new Array(3); +b2Distance.s_saveB = new Array(3);var b2MouseJoint = function() { + b2Joint.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2MouseJoint.prototype, b2Joint.prototype); +b2MouseJoint.prototype._super = b2Joint.prototype; +b2MouseJoint.prototype.__constructor = function(def) { + this._super.__constructor.apply(this, [def]); + this.m_target.SetV(def.target); + var tX = this.m_target.x - this.m_bodyB.m_xf.position.x; + var tY = this.m_target.y - this.m_bodyB.m_xf.position.y; + var tMat = this.m_bodyB.m_xf.R; + this.m_localAnchor.x = tX * tMat.col1.x + tY * tMat.col1.y; + this.m_localAnchor.y = tX * tMat.col2.x + tY * tMat.col2.y; + this.m_maxForce = def.maxForce; + this.m_impulse.SetZero(); + this.m_frequencyHz = def.frequencyHz; + this.m_dampingRatio = def.dampingRatio; + this.m_beta = 0; + this.m_gamma = 0 +}; +b2MouseJoint.prototype.__varz = function() { + this.K = new b2Mat22; + this.K1 = new b2Mat22; + this.K2 = new b2Mat22; + this.m_localAnchor = new b2Vec2; + this.m_target = new b2Vec2; + this.m_impulse = new b2Vec2; + this.m_mass = new b2Mat22; + this.m_C = new b2Vec2 +}; +b2MouseJoint.prototype.InitVelocityConstraints = function(step) { + var b = this.m_bodyB; + var mass = b.GetMass(); + var omega = 2 * Math.PI * this.m_frequencyHz; + var d = 2 * mass * this.m_dampingRatio * omega; + var k = mass * omega * omega; + this.m_gamma = step.dt * (d + step.dt * k); + this.m_gamma = this.m_gamma != 0 ? 1 / this.m_gamma : 0; + this.m_beta = step.dt * k * this.m_gamma; + var tMat; + tMat = b.m_xf.R; + var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; + var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; + var tX = tMat.col1.x * rX + tMat.col2.x * rY; + rY = tMat.col1.y * rX + tMat.col2.y * rY; + rX = tX; + var invMass = b.m_invMass; + var invI = b.m_invI; + this.K1.col1.x = invMass; + this.K1.col2.x = 0; + this.K1.col1.y = 0; + this.K1.col2.y = invMass; + this.K2.col1.x = invI * rY * rY; + this.K2.col2.x = -invI * rX * rY; + this.K2.col1.y = -invI * rX * rY; + this.K2.col2.y = invI * rX * rX; + this.K.SetM(this.K1); + this.K.AddM(this.K2); + this.K.col1.x += this.m_gamma; + this.K.col2.y += this.m_gamma; + this.K.GetInverse(this.m_mass); + this.m_C.x = b.m_sweep.c.x + rX - this.m_target.x; + this.m_C.y = b.m_sweep.c.y + rY - this.m_target.y; + b.m_angularVelocity *= 0.98; + this.m_impulse.x *= step.dtRatio; + this.m_impulse.y *= step.dtRatio; + b.m_linearVelocity.x += invMass * this.m_impulse.x; + b.m_linearVelocity.y += invMass * this.m_impulse.y; + b.m_angularVelocity += invI * (rX * this.m_impulse.y - rY * this.m_impulse.x) +}; +b2MouseJoint.prototype.SolveVelocityConstraints = function(step) { + var b = this.m_bodyB; + var tMat; + var tX; + var tY; + tMat = b.m_xf.R; + var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; + var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; + tX = tMat.col1.x * rX + tMat.col2.x * rY; + rY = tMat.col1.y * rX + tMat.col2.y * rY; + rX = tX; + var CdotX = b.m_linearVelocity.x + -b.m_angularVelocity * rY; + var CdotY = b.m_linearVelocity.y + b.m_angularVelocity * rX; + tMat = this.m_mass; + tX = CdotX + this.m_beta * this.m_C.x + this.m_gamma * this.m_impulse.x; + tY = CdotY + this.m_beta * this.m_C.y + this.m_gamma * this.m_impulse.y; + var impulseX = -(tMat.col1.x * tX + tMat.col2.x * tY); + var impulseY = -(tMat.col1.y * tX + tMat.col2.y * tY); + var oldImpulseX = this.m_impulse.x; + var oldImpulseY = this.m_impulse.y; + this.m_impulse.x += impulseX; + this.m_impulse.y += impulseY; + var maxImpulse = step.dt * this.m_maxForce; + if(this.m_impulse.LengthSquared() > maxImpulse * maxImpulse) { + this.m_impulse.Multiply(maxImpulse / this.m_impulse.Length()) + } + impulseX = this.m_impulse.x - oldImpulseX; + impulseY = this.m_impulse.y - oldImpulseY; + b.m_linearVelocity.x += b.m_invMass * impulseX; + b.m_linearVelocity.y += b.m_invMass * impulseY; + b.m_angularVelocity += b.m_invI * (rX * impulseY - rY * impulseX) +}; +b2MouseJoint.prototype.SolvePositionConstraints = function(baumgarte) { + return true +}; +b2MouseJoint.prototype.GetAnchorA = function() { + return this.m_target +}; +b2MouseJoint.prototype.GetAnchorB = function() { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor) +}; +b2MouseJoint.prototype.GetReactionForce = function(inv_dt) { + return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y) +}; +b2MouseJoint.prototype.GetReactionTorque = function(inv_dt) { + return 0 +}; +b2MouseJoint.prototype.GetTarget = function() { + return this.m_target +}; +b2MouseJoint.prototype.SetTarget = function(target) { + if(this.m_bodyB.IsAwake() == false) { + this.m_bodyB.SetAwake(true) + } + this.m_target = target +}; +b2MouseJoint.prototype.GetMaxForce = function() { + return this.m_maxForce +}; +b2MouseJoint.prototype.SetMaxForce = function(maxForce) { + this.m_maxForce = maxForce +}; +b2MouseJoint.prototype.GetFrequency = function() { + return this.m_frequencyHz +}; +b2MouseJoint.prototype.SetFrequency = function(hz) { + this.m_frequencyHz = hz +}; +b2MouseJoint.prototype.GetDampingRatio = function() { + return this.m_dampingRatio +}; +b2MouseJoint.prototype.SetDampingRatio = function(ratio) { + this.m_dampingRatio = ratio +}; +b2MouseJoint.prototype.K = new b2Mat22; +b2MouseJoint.prototype.K1 = new b2Mat22; +b2MouseJoint.prototype.K2 = new b2Mat22; +b2MouseJoint.prototype.m_localAnchor = new b2Vec2; +b2MouseJoint.prototype.m_target = new b2Vec2; +b2MouseJoint.prototype.m_impulse = new b2Vec2; +b2MouseJoint.prototype.m_mass = new b2Mat22; +b2MouseJoint.prototype.m_C = new b2Vec2; +b2MouseJoint.prototype.m_maxForce = null; +b2MouseJoint.prototype.m_frequencyHz = null; +b2MouseJoint.prototype.m_dampingRatio = null; +b2MouseJoint.prototype.m_beta = null; +b2MouseJoint.prototype.m_gamma = null;var b2PrismaticJointDef = function() { + b2JointDef.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2PrismaticJointDef.prototype, b2JointDef.prototype); +b2PrismaticJointDef.prototype._super = b2JointDef.prototype; +b2PrismaticJointDef.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.type = b2Joint.e_prismaticJoint; + this.localAxisA.Set(1, 0); + this.referenceAngle = 0; + this.enableLimit = false; + this.lowerTranslation = 0; + this.upperTranslation = 0; + this.enableMotor = false; + this.maxMotorForce = 0; + this.motorSpeed = 0 +}; +b2PrismaticJointDef.prototype.__varz = function() { + this.localAnchorA = new b2Vec2; + this.localAnchorB = new b2Vec2; + this.localAxisA = new b2Vec2 +}; +b2PrismaticJointDef.prototype.Initialize = function(bA, bB, anchor, axis) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA = this.bodyA.GetLocalPoint(anchor); + this.localAnchorB = this.bodyB.GetLocalPoint(anchor); + this.localAxisA = this.bodyA.GetLocalVector(axis); + this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle() +}; +b2PrismaticJointDef.prototype.localAnchorA = new b2Vec2; +b2PrismaticJointDef.prototype.localAnchorB = new b2Vec2; +b2PrismaticJointDef.prototype.localAxisA = new b2Vec2; +b2PrismaticJointDef.prototype.referenceAngle = null; +b2PrismaticJointDef.prototype.enableLimit = null; +b2PrismaticJointDef.prototype.lowerTranslation = null; +b2PrismaticJointDef.prototype.upperTranslation = null; +b2PrismaticJointDef.prototype.enableMotor = null; +b2PrismaticJointDef.prototype.maxMotorForce = null; +b2PrismaticJointDef.prototype.motorSpeed = null;var b2TimeOfImpact = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2TimeOfImpact.prototype.__constructor = function() { +}; +b2TimeOfImpact.prototype.__varz = function() { +}; +b2TimeOfImpact.TimeOfImpact = function(input) { + ++b2TimeOfImpact.b2_toiCalls; + var proxyA = input.proxyA; + var proxyB = input.proxyB; + var sweepA = input.sweepA; + var sweepB = input.sweepB; + b2Settings.b2Assert(sweepA.t0 == sweepB.t0); + b2Settings.b2Assert(1 - sweepA.t0 > Number.MIN_VALUE); + var radius = proxyA.m_radius + proxyB.m_radius; + var tolerance = input.tolerance; + var alpha = 0; + var k_maxIterations = 1E3; + var iter = 0; + var target = 0; + b2TimeOfImpact.s_cache.count = 0; + b2TimeOfImpact.s_distanceInput.useRadii = false; + for(;;) { + sweepA.GetTransform(b2TimeOfImpact.s_xfA, alpha); + sweepB.GetTransform(b2TimeOfImpact.s_xfB, alpha); + b2TimeOfImpact.s_distanceInput.proxyA = proxyA; + b2TimeOfImpact.s_distanceInput.proxyB = proxyB; + b2TimeOfImpact.s_distanceInput.transformA = b2TimeOfImpact.s_xfA; + b2TimeOfImpact.s_distanceInput.transformB = b2TimeOfImpact.s_xfB; + b2Distance.Distance(b2TimeOfImpact.s_distanceOutput, b2TimeOfImpact.s_cache, b2TimeOfImpact.s_distanceInput); + if(b2TimeOfImpact.s_distanceOutput.distance <= 0) { + alpha = 1; + break + } + b2TimeOfImpact.s_fcn.Initialize(b2TimeOfImpact.s_cache, proxyA, b2TimeOfImpact.s_xfA, proxyB, b2TimeOfImpact.s_xfB); + var separation = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); + if(separation <= 0) { + alpha = 1; + break + } + if(iter == 0) { + if(separation > radius) { + target = b2Math.Max(radius - tolerance, 0.75 * radius) + }else { + target = b2Math.Max(separation - tolerance, 0.02 * radius) + } + } + if(separation - target < 0.5 * tolerance) { + if(iter == 0) { + alpha = 1; + break + } + break + } + var newAlpha = alpha; + var x1 = alpha; + var x2 = 1; + var f1 = separation; + sweepA.GetTransform(b2TimeOfImpact.s_xfA, x2); + sweepB.GetTransform(b2TimeOfImpact.s_xfB, x2); + var f2 = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); + if(f2 >= target) { + alpha = 1; + break + } + var rootIterCount = 0; + for(;;) { + var x; + if(rootIterCount & 1) { + x = x1 + (target - f1) * (x2 - x1) / (f2 - f1) + }else { + x = 0.5 * (x1 + x2) + } + sweepA.GetTransform(b2TimeOfImpact.s_xfA, x); + sweepB.GetTransform(b2TimeOfImpact.s_xfB, x); + var f = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); + if(b2Math.Abs(f - target) < 0.025 * tolerance) { + newAlpha = x; + break + } + if(f > target) { + x1 = x; + f1 = f + }else { + x2 = x; + f2 = f + } + ++rootIterCount; + ++b2TimeOfImpact.b2_toiRootIters; + if(rootIterCount == 50) { + break + } + } + b2TimeOfImpact.b2_toiMaxRootIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxRootIters, rootIterCount); + if(newAlpha < (1 + 100 * Number.MIN_VALUE) * alpha) { + break + } + alpha = newAlpha; + iter++; + ++b2TimeOfImpact.b2_toiIters; + if(iter == k_maxIterations) { + break + } + } + b2TimeOfImpact.b2_toiMaxIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxIters, iter); + return alpha +}; +b2TimeOfImpact.b2_toiCalls = 0; +b2TimeOfImpact.b2_toiIters = 0; +b2TimeOfImpact.b2_toiMaxIters = 0; +b2TimeOfImpact.b2_toiRootIters = 0; +b2TimeOfImpact.b2_toiMaxRootIters = 0; +b2TimeOfImpact.s_cache = new b2SimplexCache; +b2TimeOfImpact.s_distanceInput = new b2DistanceInput; +b2TimeOfImpact.s_xfA = new b2Transform; +b2TimeOfImpact.s_xfB = new b2Transform; +b2TimeOfImpact.s_fcn = new b2SeparationFunction; +b2TimeOfImpact.s_distanceOutput = new b2DistanceOutput;var b2GearJoint = function() { + b2Joint.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2GearJoint.prototype, b2Joint.prototype); +b2GearJoint.prototype._super = b2Joint.prototype; +b2GearJoint.prototype.__constructor = function(def) { + this._super.__constructor.apply(this, [def]); + var type1 = def.joint1.m_type; + var type2 = def.joint2.m_type; + this.m_revolute1 = null; + this.m_prismatic1 = null; + this.m_revolute2 = null; + this.m_prismatic2 = null; + var coordinate1; + var coordinate2; + this.m_ground1 = def.joint1.GetBodyA(); + this.m_bodyA = def.joint1.GetBodyB(); + if(type1 == b2Joint.e_revoluteJoint) { + this.m_revolute1 = def.joint1; + this.m_groundAnchor1.SetV(this.m_revolute1.m_localAnchor1); + this.m_localAnchor1.SetV(this.m_revolute1.m_localAnchor2); + coordinate1 = this.m_revolute1.GetJointAngle() + }else { + this.m_prismatic1 = def.joint1; + this.m_groundAnchor1.SetV(this.m_prismatic1.m_localAnchor1); + this.m_localAnchor1.SetV(this.m_prismatic1.m_localAnchor2); + coordinate1 = this.m_prismatic1.GetJointTranslation() + } + this.m_ground2 = def.joint2.GetBodyA(); + this.m_bodyB = def.joint2.GetBodyB(); + if(type2 == b2Joint.e_revoluteJoint) { + this.m_revolute2 = def.joint2; + this.m_groundAnchor2.SetV(this.m_revolute2.m_localAnchor1); + this.m_localAnchor2.SetV(this.m_revolute2.m_localAnchor2); + coordinate2 = this.m_revolute2.GetJointAngle() + }else { + this.m_prismatic2 = def.joint2; + this.m_groundAnchor2.SetV(this.m_prismatic2.m_localAnchor1); + this.m_localAnchor2.SetV(this.m_prismatic2.m_localAnchor2); + coordinate2 = this.m_prismatic2.GetJointTranslation() + } + this.m_ratio = def.ratio; + this.m_constant = coordinate1 + this.m_ratio * coordinate2; + this.m_impulse = 0 +}; +b2GearJoint.prototype.__varz = function() { + this.m_groundAnchor1 = new b2Vec2; + this.m_groundAnchor2 = new b2Vec2; + this.m_localAnchor1 = new b2Vec2; + this.m_localAnchor2 = new b2Vec2; + this.m_J = new b2Jacobian +}; +b2GearJoint.prototype.InitVelocityConstraints = function(step) { + var g1 = this.m_ground1; + var g2 = this.m_ground2; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var ugX; + var ugY; + var rX; + var rY; + var tMat; + var tVec; + var crug; + var tX; + var K = 0; + this.m_J.SetZero(); + if(this.m_revolute1) { + this.m_J.angularA = -1; + K += bA.m_invI + }else { + tMat = g1.m_xf.R; + tVec = this.m_prismatic1.m_localXAxis1; + ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = bA.m_xf.R; + rX = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; + rY = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; + tX = tMat.col1.x * rX + tMat.col2.x * rY; + rY = tMat.col1.y * rX + tMat.col2.y * rY; + rX = tX; + crug = rX * ugY - rY * ugX; + this.m_J.linearA.Set(-ugX, -ugY); + this.m_J.angularA = -crug; + K += bA.m_invMass + bA.m_invI * crug * crug + } + if(this.m_revolute2) { + this.m_J.angularB = -this.m_ratio; + K += this.m_ratio * this.m_ratio * bB.m_invI + }else { + tMat = g2.m_xf.R; + tVec = this.m_prismatic2.m_localXAxis1; + ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = bB.m_xf.R; + rX = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; + rY = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; + tX = tMat.col1.x * rX + tMat.col2.x * rY; + rY = tMat.col1.y * rX + tMat.col2.y * rY; + rX = tX; + crug = rX * ugY - rY * ugX; + this.m_J.linearB.Set(-this.m_ratio * ugX, -this.m_ratio * ugY); + this.m_J.angularB = -this.m_ratio * crug; + K += this.m_ratio * this.m_ratio * (bB.m_invMass + bB.m_invI * crug * crug) + } + this.m_mass = K > 0 ? 1 / K : 0; + if(step.warmStarting) { + bA.m_linearVelocity.x += bA.m_invMass * this.m_impulse * this.m_J.linearA.x; + bA.m_linearVelocity.y += bA.m_invMass * this.m_impulse * this.m_J.linearA.y; + bA.m_angularVelocity += bA.m_invI * this.m_impulse * this.m_J.angularA; + bB.m_linearVelocity.x += bB.m_invMass * this.m_impulse * this.m_J.linearB.x; + bB.m_linearVelocity.y += bB.m_invMass * this.m_impulse * this.m_J.linearB.y; + bB.m_angularVelocity += bB.m_invI * this.m_impulse * this.m_J.angularB + }else { + this.m_impulse = 0 + } +}; +b2GearJoint.prototype.SolveVelocityConstraints = function(step) { + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var Cdot = this.m_J.Compute(bA.m_linearVelocity, bA.m_angularVelocity, bB.m_linearVelocity, bB.m_angularVelocity); + var impulse = -this.m_mass * Cdot; + this.m_impulse += impulse; + bA.m_linearVelocity.x += bA.m_invMass * impulse * this.m_J.linearA.x; + bA.m_linearVelocity.y += bA.m_invMass * impulse * this.m_J.linearA.y; + bA.m_angularVelocity += bA.m_invI * impulse * this.m_J.angularA; + bB.m_linearVelocity.x += bB.m_invMass * impulse * this.m_J.linearB.x; + bB.m_linearVelocity.y += bB.m_invMass * impulse * this.m_J.linearB.y; + bB.m_angularVelocity += bB.m_invI * impulse * this.m_J.angularB +}; +b2GearJoint.prototype.SolvePositionConstraints = function(baumgarte) { + var linearError = 0; + var bA = this.m_bodyA; + var bB = this.m_bodyB; + var coordinate1; + var coordinate2; + if(this.m_revolute1) { + coordinate1 = this.m_revolute1.GetJointAngle() + }else { + coordinate1 = this.m_prismatic1.GetJointTranslation() + } + if(this.m_revolute2) { + coordinate2 = this.m_revolute2.GetJointAngle() + }else { + coordinate2 = this.m_prismatic2.GetJointTranslation() + } + var C = this.m_constant - (coordinate1 + this.m_ratio * coordinate2); + var impulse = -this.m_mass * C; + bA.m_sweep.c.x += bA.m_invMass * impulse * this.m_J.linearA.x; + bA.m_sweep.c.y += bA.m_invMass * impulse * this.m_J.linearA.y; + bA.m_sweep.a += bA.m_invI * impulse * this.m_J.angularA; + bB.m_sweep.c.x += bB.m_invMass * impulse * this.m_J.linearB.x; + bB.m_sweep.c.y += bB.m_invMass * impulse * this.m_J.linearB.y; + bB.m_sweep.a += bB.m_invI * impulse * this.m_J.angularB; + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + return linearError < b2Settings.b2_linearSlop +}; +b2GearJoint.prototype.GetAnchorA = function() { + return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) +}; +b2GearJoint.prototype.GetAnchorB = function() { + return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) +}; +b2GearJoint.prototype.GetReactionForce = function(inv_dt) { + return new b2Vec2(inv_dt * this.m_impulse * this.m_J.linearB.x, inv_dt * this.m_impulse * this.m_J.linearB.y) +}; +b2GearJoint.prototype.GetReactionTorque = function(inv_dt) { + var tMat = this.m_bodyB.m_xf.R; + var rX = this.m_localAnchor1.x - this.m_bodyB.m_sweep.localCenter.x; + var rY = this.m_localAnchor1.y - this.m_bodyB.m_sweep.localCenter.y; + var tX = tMat.col1.x * rX + tMat.col2.x * rY; + rY = tMat.col1.y * rX + tMat.col2.y * rY; + rX = tX; + var PX = this.m_impulse * this.m_J.linearB.x; + var PY = this.m_impulse * this.m_J.linearB.y; + return inv_dt * (this.m_impulse * this.m_J.angularB - rX * PY + rY * PX) +}; +b2GearJoint.prototype.GetRatio = function() { + return this.m_ratio +}; +b2GearJoint.prototype.SetRatio = function(ratio) { + this.m_ratio = ratio +}; +b2GearJoint.prototype.m_ground1 = null; +b2GearJoint.prototype.m_ground2 = null; +b2GearJoint.prototype.m_revolute1 = null; +b2GearJoint.prototype.m_prismatic1 = null; +b2GearJoint.prototype.m_revolute2 = null; +b2GearJoint.prototype.m_prismatic2 = null; +b2GearJoint.prototype.m_groundAnchor1 = new b2Vec2; +b2GearJoint.prototype.m_groundAnchor2 = new b2Vec2; +b2GearJoint.prototype.m_localAnchor1 = new b2Vec2; +b2GearJoint.prototype.m_localAnchor2 = new b2Vec2; +b2GearJoint.prototype.m_J = new b2Jacobian; +b2GearJoint.prototype.m_constant = null; +b2GearJoint.prototype.m_ratio = null; +b2GearJoint.prototype.m_mass = null; +b2GearJoint.prototype.m_impulse = null;var b2TOIInput = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2TOIInput.prototype.__constructor = function() { +}; +b2TOIInput.prototype.__varz = function() { + this.proxyA = new b2DistanceProxy; + this.proxyB = new b2DistanceProxy; + this.sweepA = new b2Sweep; + this.sweepB = new b2Sweep +}; +b2TOIInput.prototype.proxyA = new b2DistanceProxy; +b2TOIInput.prototype.proxyB = new b2DistanceProxy; +b2TOIInput.prototype.sweepA = new b2Sweep; +b2TOIInput.prototype.sweepB = new b2Sweep; +b2TOIInput.prototype.tolerance = null;var b2RevoluteJointDef = function() { + b2JointDef.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2RevoluteJointDef.prototype, b2JointDef.prototype); +b2RevoluteJointDef.prototype._super = b2JointDef.prototype; +b2RevoluteJointDef.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.type = b2Joint.e_revoluteJoint; + this.localAnchorA.Set(0, 0); + this.localAnchorB.Set(0, 0); + this.referenceAngle = 0; + this.lowerAngle = 0; + this.upperAngle = 0; + this.maxMotorTorque = 0; + this.motorSpeed = 0; + this.enableLimit = false; + this.enableMotor = false +}; +b2RevoluteJointDef.prototype.__varz = function() { + this.localAnchorA = new b2Vec2; + this.localAnchorB = new b2Vec2 +}; +b2RevoluteJointDef.prototype.Initialize = function(bA, bB, anchor) { + this.bodyA = bA; + this.bodyB = bB; + this.localAnchorA = this.bodyA.GetLocalPoint(anchor); + this.localAnchorB = this.bodyB.GetLocalPoint(anchor); + this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle() +}; +b2RevoluteJointDef.prototype.localAnchorA = new b2Vec2; +b2RevoluteJointDef.prototype.localAnchorB = new b2Vec2; +b2RevoluteJointDef.prototype.referenceAngle = null; +b2RevoluteJointDef.prototype.enableLimit = null; +b2RevoluteJointDef.prototype.lowerAngle = null; +b2RevoluteJointDef.prototype.upperAngle = null; +b2RevoluteJointDef.prototype.enableMotor = null; +b2RevoluteJointDef.prototype.motorSpeed = null; +b2RevoluteJointDef.prototype.maxMotorTorque = null;var b2MouseJointDef = function() { + b2JointDef.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2MouseJointDef.prototype, b2JointDef.prototype); +b2MouseJointDef.prototype._super = b2JointDef.prototype; +b2MouseJointDef.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments); + this.type = b2Joint.e_mouseJoint; + this.maxForce = 0; + this.frequencyHz = 5; + this.dampingRatio = 0.7 +}; +b2MouseJointDef.prototype.__varz = function() { + this.target = new b2Vec2 +}; +b2MouseJointDef.prototype.target = new b2Vec2; +b2MouseJointDef.prototype.maxForce = null; +b2MouseJointDef.prototype.frequencyHz = null; +b2MouseJointDef.prototype.dampingRatio = null;var b2Contact = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Contact.prototype.__constructor = function() { +}; +b2Contact.prototype.__varz = function() { + this.m_nodeA = new b2ContactEdge; + this.m_nodeB = new b2ContactEdge; + this.m_manifold = new b2Manifold; + this.m_oldManifold = new b2Manifold +}; +b2Contact.s_input = new b2TOIInput; +b2Contact.e_sensorFlag = 1; +b2Contact.e_continuousFlag = 2; +b2Contact.e_islandFlag = 4; +b2Contact.e_toiFlag = 8; +b2Contact.e_touchingFlag = 16; +b2Contact.e_enabledFlag = 32; +b2Contact.e_filterFlag = 64; +b2Contact.prototype.Reset = function(fixtureA, fixtureB) { + this.m_flags = b2Contact.e_enabledFlag; + if(!fixtureA || !fixtureB) { + this.m_fixtureA = null; + this.m_fixtureB = null; + return + } + if(fixtureA.IsSensor() || fixtureB.IsSensor()) { + this.m_flags |= b2Contact.e_sensorFlag + } + var bodyA = fixtureA.GetBody(); + var bodyB = fixtureB.GetBody(); + if(bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { + this.m_flags |= b2Contact.e_continuousFlag + } + this.m_fixtureA = fixtureA; + this.m_fixtureB = fixtureB; + this.m_manifold.m_pointCount = 0; + this.m_prev = null; + this.m_next = null; + this.m_nodeA.contact = null; + this.m_nodeA.prev = null; + this.m_nodeA.next = null; + this.m_nodeA.other = null; + this.m_nodeB.contact = null; + this.m_nodeB.prev = null; + this.m_nodeB.next = null; + this.m_nodeB.other = null +}; +b2Contact.prototype.Update = function(listener) { + var tManifold = this.m_oldManifold; + this.m_oldManifold = this.m_manifold; + this.m_manifold = tManifold; + this.m_flags |= b2Contact.e_enabledFlag; + var touching = false; + var wasTouching = (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag; + var bodyA = this.m_fixtureA.m_body; + var bodyB = this.m_fixtureB.m_body; + var aabbOverlap = this.m_fixtureA.m_aabb.TestOverlap(this.m_fixtureB.m_aabb); + if(this.m_flags & b2Contact.e_sensorFlag) { + if(aabbOverlap) { + var shapeA = this.m_fixtureA.GetShape(); + var shapeB = this.m_fixtureB.GetShape(); + var xfA = bodyA.GetTransform(); + var xfB = bodyB.GetTransform(); + touching = b2Shape.TestOverlap(shapeA, xfA, shapeB, xfB) + } + this.m_manifold.m_pointCount = 0 + }else { + if(bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { + this.m_flags |= b2Contact.e_continuousFlag + }else { + this.m_flags &= ~b2Contact.e_continuousFlag + } + if(aabbOverlap) { + this.Evaluate(); + touching = this.m_manifold.m_pointCount > 0; + for(var i = 0;i < this.m_manifold.m_pointCount;++i) { + var mp2 = this.m_manifold.m_points[i]; + mp2.m_normalImpulse = 0; + mp2.m_tangentImpulse = 0; + var id2 = mp2.m_id; + for(var j = 0;j < this.m_oldManifold.m_pointCount;++j) { + var mp1 = this.m_oldManifold.m_points[j]; + if(mp1.m_id.key == id2.key) { + mp2.m_normalImpulse = mp1.m_normalImpulse; + mp2.m_tangentImpulse = mp1.m_tangentImpulse; + break + } + } + } + }else { + this.m_manifold.m_pointCount = 0 + } + if(touching != wasTouching) { + bodyA.SetAwake(true); + bodyB.SetAwake(true) + } + } + if(touching) { + this.m_flags |= b2Contact.e_touchingFlag + }else { + this.m_flags &= ~b2Contact.e_touchingFlag + } + if(wasTouching == false && touching == true) { + listener.BeginContact(this) + } + if(wasTouching == true && touching == false) { + listener.EndContact(this) + } + if((this.m_flags & b2Contact.e_sensorFlag) == 0) { + listener.PreSolve(this, this.m_oldManifold) + } +}; +b2Contact.prototype.Evaluate = function() { +}; +b2Contact.prototype.ComputeTOI = function(sweepA, sweepB) { + b2Contact.s_input.proxyA.Set(this.m_fixtureA.GetShape()); + b2Contact.s_input.proxyB.Set(this.m_fixtureB.GetShape()); + b2Contact.s_input.sweepA = sweepA; + b2Contact.s_input.sweepB = sweepB; + b2Contact.s_input.tolerance = b2Settings.b2_linearSlop; + return b2TimeOfImpact.TimeOfImpact(b2Contact.s_input) +}; +b2Contact.prototype.GetManifold = function() { + return this.m_manifold +}; +b2Contact.prototype.GetWorldManifold = function(worldManifold) { + var bodyA = this.m_fixtureA.GetBody(); + var bodyB = this.m_fixtureB.GetBody(); + var shapeA = this.m_fixtureA.GetShape(); + var shapeB = this.m_fixtureB.GetShape(); + worldManifold.Initialize(this.m_manifold, bodyA.GetTransform(), shapeA.m_radius, bodyB.GetTransform(), shapeB.m_radius) +}; +b2Contact.prototype.IsTouching = function() { + return(this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag +}; +b2Contact.prototype.IsContinuous = function() { + return(this.m_flags & b2Contact.e_continuousFlag) == b2Contact.e_continuousFlag +}; +b2Contact.prototype.SetSensor = function(sensor) { + if(sensor) { + this.m_flags |= b2Contact.e_sensorFlag + }else { + this.m_flags &= ~b2Contact.e_sensorFlag + } +}; +b2Contact.prototype.IsSensor = function() { + return(this.m_flags & b2Contact.e_sensorFlag) == b2Contact.e_sensorFlag +}; +b2Contact.prototype.SetEnabled = function(flag) { + if(flag) { + this.m_flags |= b2Contact.e_enabledFlag + }else { + this.m_flags &= ~b2Contact.e_enabledFlag + } +}; +b2Contact.prototype.IsEnabled = function() { + return(this.m_flags & b2Contact.e_enabledFlag) == b2Contact.e_enabledFlag +}; +b2Contact.prototype.GetNext = function() { + return this.m_next +}; +b2Contact.prototype.GetFixtureA = function() { + return this.m_fixtureA +}; +b2Contact.prototype.GetFixtureB = function() { + return this.m_fixtureB +}; +b2Contact.prototype.FlagForFiltering = function() { + this.m_flags |= b2Contact.e_filterFlag +}; +b2Contact.prototype.m_flags = 0; +b2Contact.prototype.m_prev = null; +b2Contact.prototype.m_next = null; +b2Contact.prototype.m_nodeA = new b2ContactEdge; +b2Contact.prototype.m_nodeB = new b2ContactEdge; +b2Contact.prototype.m_fixtureA = null; +b2Contact.prototype.m_fixtureB = null; +b2Contact.prototype.m_manifold = new b2Manifold; +b2Contact.prototype.m_oldManifold = new b2Manifold; +b2Contact.prototype.m_toi = null;var b2ContactConstraint = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactConstraint.prototype.__constructor = function() { + this.points = new Array(b2Settings.b2_maxManifoldPoints); + for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { + this.points[i] = new b2ContactConstraintPoint + } +}; +b2ContactConstraint.prototype.__varz = function() { + this.localPlaneNormal = new b2Vec2; + this.localPoint = new b2Vec2; + this.normal = new b2Vec2; + this.normalMass = new b2Mat22; + this.K = new b2Mat22 +}; +b2ContactConstraint.prototype.points = null; +b2ContactConstraint.prototype.localPlaneNormal = new b2Vec2; +b2ContactConstraint.prototype.localPoint = new b2Vec2; +b2ContactConstraint.prototype.normal = new b2Vec2; +b2ContactConstraint.prototype.normalMass = new b2Mat22; +b2ContactConstraint.prototype.K = new b2Mat22; +b2ContactConstraint.prototype.bodyA = null; +b2ContactConstraint.prototype.bodyB = null; +b2ContactConstraint.prototype.type = 0; +b2ContactConstraint.prototype.radius = null; +b2ContactConstraint.prototype.friction = null; +b2ContactConstraint.prototype.restitution = null; +b2ContactConstraint.prototype.pointCount = 0; +b2ContactConstraint.prototype.manifold = null;var b2ContactResult = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactResult.prototype.__constructor = function() { +}; +b2ContactResult.prototype.__varz = function() { + this.position = new b2Vec2; + this.normal = new b2Vec2; + this.id = new b2ContactID +}; +b2ContactResult.prototype.shape1 = null; +b2ContactResult.prototype.shape2 = null; +b2ContactResult.prototype.position = new b2Vec2; +b2ContactResult.prototype.normal = new b2Vec2; +b2ContactResult.prototype.normalImpulse = null; +b2ContactResult.prototype.tangentImpulse = null; +b2ContactResult.prototype.id = new b2ContactID;var b2PolygonContact = function() { + b2Contact.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2PolygonContact.prototype, b2Contact.prototype); +b2PolygonContact.prototype._super = b2Contact.prototype; +b2PolygonContact.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2PolygonContact.prototype.__varz = function() { +}; +b2PolygonContact.Create = function(allocator) { + return new b2PolygonContact +}; +b2PolygonContact.Destroy = function(contact, allocator) { +}; +b2PolygonContact.prototype.Evaluate = function() { + var bA = this.m_fixtureA.GetBody(); + var bB = this.m_fixtureB.GetBody(); + b2Collision.CollidePolygons(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) +}; +b2PolygonContact.prototype.Reset = function(fixtureA, fixtureB) { + this._super.Reset.apply(this, [fixtureA, fixtureB]) +};var ClipVertex = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +ClipVertex.prototype.__constructor = function() { +}; +ClipVertex.prototype.__varz = function() { + this.v = new b2Vec2; + this.id = new b2ContactID +}; +ClipVertex.prototype.Set = function(other) { + this.v.SetV(other.v); + this.id.Set(other.id) +}; +ClipVertex.prototype.v = new b2Vec2; +ClipVertex.prototype.id = new b2ContactID;var b2ContactFilter = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactFilter.prototype.__constructor = function() { +}; +b2ContactFilter.prototype.__varz = function() { +}; +b2ContactFilter.b2_defaultFilter = new b2ContactFilter; +b2ContactFilter.prototype.ShouldCollide = function(fixtureA, fixtureB) { + var filter1 = fixtureA.GetFilterData(); + var filter2 = fixtureB.GetFilterData(); + if(filter1.groupIndex == filter2.groupIndex && filter1.groupIndex != 0) { + return filter1.groupIndex > 0 + } + var collide = (filter1.maskBits & filter2.categoryBits) != 0 && (filter1.categoryBits & filter2.maskBits) != 0; + return collide +}; +b2ContactFilter.prototype.RayCollide = function(userData, fixture) { + if(!userData) { + return true + } + return this.ShouldCollide(userData, fixture) +};var b2NullContact = function() { + b2Contact.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2NullContact.prototype, b2Contact.prototype); +b2NullContact.prototype._super = b2Contact.prototype; +b2NullContact.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2NullContact.prototype.__varz = function() { +}; +b2NullContact.prototype.Evaluate = function() { +};var b2ContactListener = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactListener.prototype.__constructor = function() { +}; +b2ContactListener.prototype.__varz = function() { +}; +b2ContactListener.b2_defaultListener = new b2ContactListener; +b2ContactListener.prototype.BeginContact = function(contact) { +}; +b2ContactListener.prototype.EndContact = function(contact) { +}; +b2ContactListener.prototype.PreSolve = function(contact, oldManifold) { +}; +b2ContactListener.prototype.PostSolve = function(contact, impulse) { +};var b2Island = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Island.prototype.__constructor = function() { + this.m_bodies = new Array; + this.m_contacts = new Array; + this.m_joints = new Array +}; +b2Island.prototype.__varz = function() { +}; +b2Island.s_impulse = new b2ContactImpulse; +b2Island.prototype.Initialize = function(bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) { + var i = 0; + this.m_bodyCapacity = bodyCapacity; + this.m_contactCapacity = contactCapacity; + this.m_jointCapacity = jointCapacity; + this.m_bodyCount = 0; + this.m_contactCount = 0; + this.m_jointCount = 0; + this.m_allocator = allocator; + this.m_listener = listener; + this.m_contactSolver = contactSolver; + for(i = this.m_bodies.length;i < bodyCapacity;i++) { + this.m_bodies[i] = null + } + for(i = this.m_contacts.length;i < contactCapacity;i++) { + this.m_contacts[i] = null + } + for(i = this.m_joints.length;i < jointCapacity;i++) { + this.m_joints[i] = null + } +}; +b2Island.prototype.Clear = function() { + this.m_bodyCount = 0; + this.m_contactCount = 0; + this.m_jointCount = 0 +}; +b2Island.prototype.Solve = function(step, gravity, allowSleep) { + var i = 0; + var j = 0; + var b; + var joint; + for(i = 0;i < this.m_bodyCount;++i) { + b = this.m_bodies[i]; + if(b.GetType() != b2Body.b2_dynamicBody) { + continue + } + b.m_linearVelocity.x += step.dt * (gravity.x + b.m_invMass * b.m_force.x); + b.m_linearVelocity.y += step.dt * (gravity.y + b.m_invMass * b.m_force.y); + b.m_angularVelocity += step.dt * b.m_invI * b.m_torque; + b.m_linearVelocity.Multiply(b2Math.Clamp(1 - step.dt * b.m_linearDamping, 0, 1)); + b.m_angularVelocity *= b2Math.Clamp(1 - step.dt * b.m_angularDamping, 0, 1) + } + this.m_contactSolver.Initialize(step, this.m_contacts, this.m_contactCount, this.m_allocator); + var contactSolver = this.m_contactSolver; + contactSolver.InitVelocityConstraints(step); + for(i = 0;i < this.m_jointCount;++i) { + joint = this.m_joints[i]; + joint.InitVelocityConstraints(step) + } + for(i = 0;i < step.velocityIterations;++i) { + for(j = 0;j < this.m_jointCount;++j) { + joint = this.m_joints[j]; + joint.SolveVelocityConstraints(step) + } + contactSolver.SolveVelocityConstraints() + } + for(i = 0;i < this.m_jointCount;++i) { + joint = this.m_joints[i]; + joint.FinalizeVelocityConstraints() + } + contactSolver.FinalizeVelocityConstraints(); + for(i = 0;i < this.m_bodyCount;++i) { + b = this.m_bodies[i]; + if(b.GetType() == b2Body.b2_staticBody) { + continue + } + var translationX = step.dt * b.m_linearVelocity.x; + var translationY = step.dt * b.m_linearVelocity.y; + if(translationX * translationX + translationY * translationY > b2Settings.b2_maxTranslationSquared) { + b.m_linearVelocity.Normalize(); + b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * step.inv_dt; + b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * step.inv_dt + } + var rotation = step.dt * b.m_angularVelocity; + if(rotation * rotation > b2Settings.b2_maxRotationSquared) { + if(b.m_angularVelocity < 0) { + b.m_angularVelocity = -b2Settings.b2_maxRotation * step.inv_dt + }else { + b.m_angularVelocity = b2Settings.b2_maxRotation * step.inv_dt + } + } + b.m_sweep.c0.SetV(b.m_sweep.c); + b.m_sweep.a0 = b.m_sweep.a; + b.m_sweep.c.x += step.dt * b.m_linearVelocity.x; + b.m_sweep.c.y += step.dt * b.m_linearVelocity.y; + b.m_sweep.a += step.dt * b.m_angularVelocity; + b.SynchronizeTransform() + } + for(i = 0;i < step.positionIterations;++i) { + var contactsOkay = contactSolver.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); + var jointsOkay = true; + for(j = 0;j < this.m_jointCount;++j) { + joint = this.m_joints[j]; + var jointOkay = joint.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); + jointsOkay = jointsOkay && jointOkay + } + if(contactsOkay && jointsOkay) { + break + } + } + this.Report(contactSolver.m_constraints); + if(allowSleep) { + var minSleepTime = Number.MAX_VALUE; + var linTolSqr = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance; + var angTolSqr = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance; + for(i = 0;i < this.m_bodyCount;++i) { + b = this.m_bodies[i]; + if(b.GetType() == b2Body.b2_staticBody) { + continue + } + if((b.m_flags & b2Body.e_allowSleepFlag) == 0) { + b.m_sleepTime = 0; + minSleepTime = 0 + } + if((b.m_flags & b2Body.e_allowSleepFlag) == 0 || b.m_angularVelocity * b.m_angularVelocity > angTolSqr || b2Math.Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr) { + b.m_sleepTime = 0; + minSleepTime = 0 + }else { + b.m_sleepTime += step.dt; + minSleepTime = b2Math.Min(minSleepTime, b.m_sleepTime) + } + } + if(minSleepTime >= b2Settings.b2_timeToSleep) { + for(i = 0;i < this.m_bodyCount;++i) { + b = this.m_bodies[i]; + b.SetAwake(false) + } + } + } +}; +b2Island.prototype.SolveTOI = function(subStep) { + var i = 0; + var j = 0; + this.m_contactSolver.Initialize(subStep, this.m_contacts, this.m_contactCount, this.m_allocator); + var contactSolver = this.m_contactSolver; + for(i = 0;i < this.m_jointCount;++i) { + this.m_joints[i].InitVelocityConstraints(subStep) + } + for(i = 0;i < subStep.velocityIterations;++i) { + contactSolver.SolveVelocityConstraints(); + for(j = 0;j < this.m_jointCount;++j) { + this.m_joints[j].SolveVelocityConstraints(subStep) + } + } + for(i = 0;i < this.m_bodyCount;++i) { + var b = this.m_bodies[i]; + if(b.GetType() == b2Body.b2_staticBody) { + continue + } + var translationX = subStep.dt * b.m_linearVelocity.x; + var translationY = subStep.dt * b.m_linearVelocity.y; + if(translationX * translationX + translationY * translationY > b2Settings.b2_maxTranslationSquared) { + b.m_linearVelocity.Normalize(); + b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * subStep.inv_dt; + b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * subStep.inv_dt + } + var rotation = subStep.dt * b.m_angularVelocity; + if(rotation * rotation > b2Settings.b2_maxRotationSquared) { + if(b.m_angularVelocity < 0) { + b.m_angularVelocity = -b2Settings.b2_maxRotation * subStep.inv_dt + }else { + b.m_angularVelocity = b2Settings.b2_maxRotation * subStep.inv_dt + } + } + b.m_sweep.c0.SetV(b.m_sweep.c); + b.m_sweep.a0 = b.m_sweep.a; + b.m_sweep.c.x += subStep.dt * b.m_linearVelocity.x; + b.m_sweep.c.y += subStep.dt * b.m_linearVelocity.y; + b.m_sweep.a += subStep.dt * b.m_angularVelocity; + b.SynchronizeTransform() + } + var k_toiBaumgarte = 0.75; + for(i = 0;i < subStep.positionIterations;++i) { + var contactsOkay = contactSolver.SolvePositionConstraints(k_toiBaumgarte); + var jointsOkay = true; + for(j = 0;j < this.m_jointCount;++j) { + var jointOkay = this.m_joints[j].SolvePositionConstraints(b2Settings.b2_contactBaumgarte); + jointsOkay = jointsOkay && jointOkay + } + if(contactsOkay && jointsOkay) { + break + } + } + this.Report(contactSolver.m_constraints) +}; +b2Island.prototype.Report = function(constraints) { + if(this.m_listener == null) { + return + } + for(var i = 0;i < this.m_contactCount;++i) { + var c = this.m_contacts[i]; + var cc = constraints[i]; + for(var j = 0;j < cc.pointCount;++j) { + b2Island.s_impulse.normalImpulses[j] = cc.points[j].normalImpulse; + b2Island.s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse + } + this.m_listener.PostSolve(c, b2Island.s_impulse) + } +}; +b2Island.prototype.AddBody = function(body) { + body.m_islandIndex = this.m_bodyCount; + this.m_bodies[this.m_bodyCount++] = body +}; +b2Island.prototype.AddContact = function(contact) { + this.m_contacts[this.m_contactCount++] = contact +}; +b2Island.prototype.AddJoint = function(joint) { + this.m_joints[this.m_jointCount++] = joint +}; +b2Island.prototype.m_allocator = null; +b2Island.prototype.m_listener = null; +b2Island.prototype.m_contactSolver = null; +b2Island.prototype.m_bodies = null; +b2Island.prototype.m_contacts = null; +b2Island.prototype.m_joints = null; +b2Island.prototype.m_bodyCount = 0; +b2Island.prototype.m_jointCount = 0; +b2Island.prototype.m_contactCount = 0; +b2Island.prototype.m_bodyCapacity = 0; +b2Island.prototype.m_contactCapacity = 0; +b2Island.prototype.m_jointCapacity = 0;var b2PolyAndEdgeContact = function() { + b2Contact.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2PolyAndEdgeContact.prototype, b2Contact.prototype); +b2PolyAndEdgeContact.prototype._super = b2Contact.prototype; +b2PolyAndEdgeContact.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2PolyAndEdgeContact.prototype.__varz = function() { +}; +b2PolyAndEdgeContact.Create = function(allocator) { + return new b2PolyAndEdgeContact +}; +b2PolyAndEdgeContact.Destroy = function(contact, allocator) { +}; +b2PolyAndEdgeContact.prototype.Evaluate = function() { + var bA = this.m_fixtureA.GetBody(); + var bB = this.m_fixtureB.GetBody(); + this.b2CollidePolyAndEdge(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) +}; +b2PolyAndEdgeContact.prototype.b2CollidePolyAndEdge = function(manifold, polygon, xf1, edge, xf2) { +}; +b2PolyAndEdgeContact.prototype.Reset = function(fixtureA, fixtureB) { + this._super.Reset.apply(this, [fixtureA, fixtureB]); + b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); + b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_edgeShape) +};var b2Collision = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2Collision.prototype.__constructor = function() { +}; +b2Collision.prototype.__varz = function() { +}; +b2Collision.MakeClipPointVector = function() { + var r = new Array(2); + r[0] = new ClipVertex; + r[1] = new ClipVertex; + return r +}; +b2Collision.ClipSegmentToLine = function(vOut, vIn, normal, offset) { + var cv; + var numOut = 0; + cv = vIn[0]; + var vIn0 = cv.v; + cv = vIn[1]; + var vIn1 = cv.v; + var distance0 = normal.x * vIn0.x + normal.y * vIn0.y - offset; + var distance1 = normal.x * vIn1.x + normal.y * vIn1.y - offset; + if(distance0 <= 0) { + vOut[numOut++].Set(vIn[0]) + } + if(distance1 <= 0) { + vOut[numOut++].Set(vIn[1]) + } + if(distance0 * distance1 < 0) { + var interp = distance0 / (distance0 - distance1); + cv = vOut[numOut]; + var tVec = cv.v; + tVec.x = vIn0.x + interp * (vIn1.x - vIn0.x); + tVec.y = vIn0.y + interp * (vIn1.y - vIn0.y); + cv = vOut[numOut]; + var cv2; + if(distance0 > 0) { + cv2 = vIn[0]; + cv.id = cv2.id + }else { + cv2 = vIn[1]; + cv.id = cv2.id + } + ++numOut + } + return numOut +}; +b2Collision.EdgeSeparation = function(poly1, xf1, edge1, poly2, xf2) { + var count1 = poly1.m_vertexCount; + var vertices1 = poly1.m_vertices; + var normals1 = poly1.m_normals; + var count2 = poly2.m_vertexCount; + var vertices2 = poly2.m_vertices; + var tMat; + var tVec; + tMat = xf1.R; + tVec = normals1[edge1]; + var normal1WorldX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + var normal1WorldY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = xf2.R; + var normal1X = tMat.col1.x * normal1WorldX + tMat.col1.y * normal1WorldY; + var normal1Y = tMat.col2.x * normal1WorldX + tMat.col2.y * normal1WorldY; + var index = 0; + var minDot = Number.MAX_VALUE; + for(var i = 0;i < count2;++i) { + tVec = vertices2[i]; + var dot = tVec.x * normal1X + tVec.y * normal1Y; + if(dot < minDot) { + minDot = dot; + index = i + } + } + tVec = vertices1[edge1]; + tMat = xf1.R; + var v1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var v1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tVec = vertices2[index]; + tMat = xf2.R; + var v2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var v2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + v2X -= v1X; + v2Y -= v1Y; + var separation = v2X * normal1WorldX + v2Y * normal1WorldY; + return separation +}; +b2Collision.FindMaxSeparation = function(edgeIndex, poly1, xf1, poly2, xf2) { + var count1 = poly1.m_vertexCount; + var normals1 = poly1.m_normals; + var tVec; + var tMat; + tMat = xf2.R; + tVec = poly2.m_centroid; + var dX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var dY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = xf1.R; + tVec = poly1.m_centroid; + dX -= xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + dY -= xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var dLocal1X = dX * xf1.R.col1.x + dY * xf1.R.col1.y; + var dLocal1Y = dX * xf1.R.col2.x + dY * xf1.R.col2.y; + var edge = 0; + var maxDot = -Number.MAX_VALUE; + for(var i = 0;i < count1;++i) { + tVec = normals1[i]; + var dot = tVec.x * dLocal1X + tVec.y * dLocal1Y; + if(dot > maxDot) { + maxDot = dot; + edge = i + } + } + var s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2); + var prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1; + var sPrev = b2Collision.EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2); + var nextEdge = edge + 1 < count1 ? edge + 1 : 0; + var sNext = b2Collision.EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2); + var bestEdge = 0; + var bestSeparation; + var increment = 0; + if(sPrev > s && sPrev > sNext) { + increment = -1; + bestEdge = prevEdge; + bestSeparation = sPrev + }else { + if(sNext > s) { + increment = 1; + bestEdge = nextEdge; + bestSeparation = sNext + }else { + edgeIndex[0] = edge; + return s + } + } + while(true) { + if(increment == -1) { + edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1 + }else { + edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0 + } + s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2); + if(s > bestSeparation) { + bestEdge = edge; + bestSeparation = s + }else { + break + } + } + edgeIndex[0] = bestEdge; + return bestSeparation +}; +b2Collision.FindIncidentEdge = function(c, poly1, xf1, edge1, poly2, xf2) { + var count1 = poly1.m_vertexCount; + var normals1 = poly1.m_normals; + var count2 = poly2.m_vertexCount; + var vertices2 = poly2.m_vertices; + var normals2 = poly2.m_normals; + var tMat; + var tVec; + tMat = xf1.R; + tVec = normals1[edge1]; + var normal1X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; + var normal1Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; + tMat = xf2.R; + var tX = tMat.col1.x * normal1X + tMat.col1.y * normal1Y; + normal1Y = tMat.col2.x * normal1X + tMat.col2.y * normal1Y; + normal1X = tX; + var index = 0; + var minDot = Number.MAX_VALUE; + for(var i = 0;i < count2;++i) { + tVec = normals2[i]; + var dot = normal1X * tVec.x + normal1Y * tVec.y; + if(dot < minDot) { + minDot = dot; + index = i + } + } + var tClip; + var i1 = index; + var i2 = i1 + 1 < count2 ? i1 + 1 : 0; + tClip = c[0]; + tVec = vertices2[i1]; + tMat = xf2.R; + tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tClip.id.features.referenceEdge = edge1; + tClip.id.features.incidentEdge = i1; + tClip.id.features.incidentVertex = 0; + tClip = c[1]; + tVec = vertices2[i2]; + tMat = xf2.R; + tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tClip.id.features.referenceEdge = edge1; + tClip.id.features.incidentEdge = i2; + tClip.id.features.incidentVertex = 1 +}; +b2Collision.CollidePolygons = function(manifold, polyA, xfA, polyB, xfB) { + var cv; + manifold.m_pointCount = 0; + var totalRadius = polyA.m_radius + polyB.m_radius; + var edgeA = 0; + b2Collision.s_edgeAO[0] = edgeA; + var separationA = b2Collision.FindMaxSeparation(b2Collision.s_edgeAO, polyA, xfA, polyB, xfB); + edgeA = b2Collision.s_edgeAO[0]; + if(separationA > totalRadius) { + return + } + var edgeB = 0; + b2Collision.s_edgeBO[0] = edgeB; + var separationB = b2Collision.FindMaxSeparation(b2Collision.s_edgeBO, polyB, xfB, polyA, xfA); + edgeB = b2Collision.s_edgeBO[0]; + if(separationB > totalRadius) { + return + } + var poly1; + var poly2; + var xf1; + var xf2; + var edge1 = 0; + var flip = 0; + var k_relativeTol = 0.98; + var k_absoluteTol = 0.0010; + var tMat; + if(separationB > k_relativeTol * separationA + k_absoluteTol) { + poly1 = polyB; + poly2 = polyA; + xf1 = xfB; + xf2 = xfA; + edge1 = edgeB; + manifold.m_type = b2Manifold.e_faceB; + flip = 1 + }else { + poly1 = polyA; + poly2 = polyB; + xf1 = xfA; + xf2 = xfB; + edge1 = edgeA; + manifold.m_type = b2Manifold.e_faceA; + flip = 0 + } + var incidentEdge = b2Collision.s_incidentEdge; + b2Collision.FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); + var count1 = poly1.m_vertexCount; + var vertices1 = poly1.m_vertices; + var local_v11 = vertices1[edge1]; + var local_v12; + if(edge1 + 1 < count1) { + local_v12 = vertices1[parseInt(edge1 + 1)] + }else { + local_v12 = vertices1[0] + } + var localTangent = b2Collision.s_localTangent; + localTangent.Set(local_v12.x - local_v11.x, local_v12.y - local_v11.y); + localTangent.Normalize(); + var localNormal = b2Collision.s_localNormal; + localNormal.x = localTangent.y; + localNormal.y = -localTangent.x; + var planePoint = b2Collision.s_planePoint; + planePoint.Set(0.5 * (local_v11.x + local_v12.x), 0.5 * (local_v11.y + local_v12.y)); + var tangent = b2Collision.s_tangent; + tMat = xf1.R; + tangent.x = tMat.col1.x * localTangent.x + tMat.col2.x * localTangent.y; + tangent.y = tMat.col1.y * localTangent.x + tMat.col2.y * localTangent.y; + var tangent2 = b2Collision.s_tangent2; + tangent2.x = -tangent.x; + tangent2.y = -tangent.y; + var normal = b2Collision.s_normal; + normal.x = tangent.y; + normal.y = -tangent.x; + var v11 = b2Collision.s_v11; + var v12 = b2Collision.s_v12; + v11.x = xf1.position.x + (tMat.col1.x * local_v11.x + tMat.col2.x * local_v11.y); + v11.y = xf1.position.y + (tMat.col1.y * local_v11.x + tMat.col2.y * local_v11.y); + v12.x = xf1.position.x + (tMat.col1.x * local_v12.x + tMat.col2.x * local_v12.y); + v12.y = xf1.position.y + (tMat.col1.y * local_v12.x + tMat.col2.y * local_v12.y); + var frontOffset = normal.x * v11.x + normal.y * v11.y; + var sideOffset1 = -tangent.x * v11.x - tangent.y * v11.y + totalRadius; + var sideOffset2 = tangent.x * v12.x + tangent.y * v12.y + totalRadius; + var clipPoints1 = b2Collision.s_clipPoints1; + var clipPoints2 = b2Collision.s_clipPoints2; + var np = 0; + np = b2Collision.ClipSegmentToLine(clipPoints1, incidentEdge, tangent2, sideOffset1); + if(np < 2) { + return + } + np = b2Collision.ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2); + if(np < 2) { + return + } + manifold.m_localPlaneNormal.SetV(localNormal); + manifold.m_localPoint.SetV(planePoint); + var pointCount = 0; + for(var i = 0;i < b2Settings.b2_maxManifoldPoints;++i) { + cv = clipPoints2[i]; + var separation = normal.x * cv.v.x + normal.y * cv.v.y - frontOffset; + if(separation <= totalRadius) { + var cp = manifold.m_points[pointCount]; + tMat = xf2.R; + var tX = cv.v.x - xf2.position.x; + var tY = cv.v.y - xf2.position.y; + cp.m_localPoint.x = tX * tMat.col1.x + tY * tMat.col1.y; + cp.m_localPoint.y = tX * tMat.col2.x + tY * tMat.col2.y; + cp.m_id.Set(cv.id); + cp.m_id.features.flip = flip; + ++pointCount + } + } + manifold.m_pointCount = pointCount +}; +b2Collision.CollideCircles = function(manifold, circle1, xf1, circle2, xf2) { + manifold.m_pointCount = 0; + var tMat; + var tVec; + tMat = xf1.R; + tVec = circle1.m_p; + var p1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var p1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + tMat = xf2.R; + tVec = circle2.m_p; + var p2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var p2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + var dX = p2X - p1X; + var dY = p2Y - p1Y; + var distSqr = dX * dX + dY * dY; + var radius = circle1.m_radius + circle2.m_radius; + if(distSqr > radius * radius) { + return + } + manifold.m_type = b2Manifold.e_circles; + manifold.m_localPoint.SetV(circle1.m_p); + manifold.m_localPlaneNormal.SetZero(); + manifold.m_pointCount = 1; + manifold.m_points[0].m_localPoint.SetV(circle2.m_p); + manifold.m_points[0].m_id.key = 0 +}; +b2Collision.CollidePolygonAndCircle = function(manifold, polygon, xf1, circle, xf2) { + manifold.m_pointCount = 0; + var tPoint; + var dX; + var dY; + var positionX; + var positionY; + var tVec; + var tMat; + tMat = xf2.R; + tVec = circle.m_p; + var cX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); + var cY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); + dX = cX - xf1.position.x; + dY = cY - xf1.position.y; + tMat = xf1.R; + var cLocalX = dX * tMat.col1.x + dY * tMat.col1.y; + var cLocalY = dX * tMat.col2.x + dY * tMat.col2.y; + var dist; + var normalIndex = 0; + var separation = -Number.MAX_VALUE; + var radius = polygon.m_radius + circle.m_radius; + var vertexCount = polygon.m_vertexCount; + var vertices = polygon.m_vertices; + var normals = polygon.m_normals; + for(var i = 0;i < vertexCount;++i) { + tVec = vertices[i]; + dX = cLocalX - tVec.x; + dY = cLocalY - tVec.y; + tVec = normals[i]; + var s = tVec.x * dX + tVec.y * dY; + if(s > radius) { + return + } + if(s > separation) { + separation = s; + normalIndex = i + } + } + var vertIndex1 = normalIndex; + var vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0; + var v1 = vertices[vertIndex1]; + var v2 = vertices[vertIndex2]; + if(separation < Number.MIN_VALUE) { + manifold.m_pointCount = 1; + manifold.m_type = b2Manifold.e_faceA; + manifold.m_localPlaneNormal.SetV(normals[normalIndex]); + manifold.m_localPoint.x = 0.5 * (v1.x + v2.x); + manifold.m_localPoint.y = 0.5 * (v1.y + v2.y); + manifold.m_points[0].m_localPoint.SetV(circle.m_p); + manifold.m_points[0].m_id.key = 0; + return + } + var u1 = (cLocalX - v1.x) * (v2.x - v1.x) + (cLocalY - v1.y) * (v2.y - v1.y); + var u2 = (cLocalX - v2.x) * (v1.x - v2.x) + (cLocalY - v2.y) * (v1.y - v2.y); + if(u1 <= 0) { + if((cLocalX - v1.x) * (cLocalX - v1.x) + (cLocalY - v1.y) * (cLocalY - v1.y) > radius * radius) { + return + } + manifold.m_pointCount = 1; + manifold.m_type = b2Manifold.e_faceA; + manifold.m_localPlaneNormal.x = cLocalX - v1.x; + manifold.m_localPlaneNormal.y = cLocalY - v1.y; + manifold.m_localPlaneNormal.Normalize(); + manifold.m_localPoint.SetV(v1); + manifold.m_points[0].m_localPoint.SetV(circle.m_p); + manifold.m_points[0].m_id.key = 0 + }else { + if(u2 <= 0) { + if((cLocalX - v2.x) * (cLocalX - v2.x) + (cLocalY - v2.y) * (cLocalY - v2.y) > radius * radius) { + return } - } - b2PolygonShape.prototype.ComputeCentroid = function (vs, count) { - if (count === undefined) count = 0; - var c = new b2Vec2(); - var area = 0.0; - var p1X = 0.0; - var p1Y = 0.0; - var inv3 = 1.0 / 3.0; - for (var i = 0; i < count; ++i) { - var p2 = vs[i]; - var p3 = i + 1 < count ? vs[parseInt(i + 1)] : vs[0]; - var e1X = p2.x - p1X; - var e1Y = p2.y - p1Y; - var e2X = p3.x - p1X; - var e2Y = p3.y - p1Y; - var D = (e1X * e2Y - e1Y * e2X); - var triangleArea = 0.5 * D;area += triangleArea; - c.x += triangleArea * inv3 * (p1X + p2.x + p3.x); - c.y += triangleArea * inv3 * (p1Y + p2.y + p3.y); + manifold.m_pointCount = 1; + manifold.m_type = b2Manifold.e_faceA; + manifold.m_localPlaneNormal.x = cLocalX - v2.x; + manifold.m_localPlaneNormal.y = cLocalY - v2.y; + manifold.m_localPlaneNormal.Normalize(); + manifold.m_localPoint.SetV(v2); + manifold.m_points[0].m_localPoint.SetV(circle.m_p); + manifold.m_points[0].m_id.key = 0 + }else { + var faceCenterX = 0.5 * (v1.x + v2.x); + var faceCenterY = 0.5 * (v1.y + v2.y); + separation = (cLocalX - faceCenterX) * normals[vertIndex1].x + (cLocalY - faceCenterY) * normals[vertIndex1].y; + if(separation > radius) { + return } - c.x *= 1.0 / area; - c.y *= 1.0 / area; - return c; - } - b2PolygonShape.ComputeCentroid = b2PolygonShape.prototype.ComputeCentroid; - b2PolygonShape.prototype.ComputeOBB = function (obb, vs, count) { - if (count === undefined) count = 0; + manifold.m_pointCount = 1; + manifold.m_type = b2Manifold.e_faceA; + manifold.m_localPlaneNormal.x = normals[vertIndex1].x; + manifold.m_localPlaneNormal.y = normals[vertIndex1].y; + manifold.m_localPlaneNormal.Normalize(); + manifold.m_localPoint.Set(faceCenterX, faceCenterY); + manifold.m_points[0].m_localPoint.SetV(circle.m_p); + manifold.m_points[0].m_id.key = 0 + } + } +}; +b2Collision.TestOverlap = function(a, b) { + var t1 = b.lowerBound; + var t2 = a.upperBound; + var d1X = t1.x - t2.x; + var d1Y = t1.y - t2.y; + t1 = a.lowerBound; + t2 = b.upperBound; + var d2X = t1.x - t2.x; + var d2Y = t1.y - t2.y; + if(d1X > 0 || d1Y > 0) { + return false + } + if(d2X > 0 || d2Y > 0) { + return false + } + return true +}; +b2Collision.b2_nullFeature = 255; +b2Collision.s_incidentEdge = b2Collision.MakeClipPointVector(); +b2Collision.s_clipPoints1 = b2Collision.MakeClipPointVector(); +b2Collision.s_clipPoints2 = b2Collision.MakeClipPointVector(); +b2Collision.s_edgeAO = new Array(1); +b2Collision.s_edgeBO = new Array(1); +b2Collision.s_localTangent = new b2Vec2; +b2Collision.s_localNormal = new b2Vec2; +b2Collision.s_planePoint = new b2Vec2; +b2Collision.s_normal = new b2Vec2; +b2Collision.s_tangent = new b2Vec2; +b2Collision.s_tangent2 = new b2Vec2; +b2Collision.s_v11 = new b2Vec2; +b2Collision.s_v12 = new b2Vec2; +b2Collision.b2CollidePolyTempVec = new b2Vec2;var b2PolyAndCircleContact = function() { + b2Contact.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2PolyAndCircleContact.prototype, b2Contact.prototype); +b2PolyAndCircleContact.prototype._super = b2Contact.prototype; +b2PolyAndCircleContact.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2PolyAndCircleContact.prototype.__varz = function() { +}; +b2PolyAndCircleContact.Create = function(allocator) { + return new b2PolyAndCircleContact +}; +b2PolyAndCircleContact.Destroy = function(contact, allocator) { +}; +b2PolyAndCircleContact.prototype.Evaluate = function() { + var bA = this.m_fixtureA.m_body; + var bB = this.m_fixtureB.m_body; + b2Collision.CollidePolygonAndCircle(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) +}; +b2PolyAndCircleContact.prototype.Reset = function(fixtureA, fixtureB) { + this._super.Reset.apply(this, [fixtureA, fixtureB]); + b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); + b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_circleShape) +};var b2ContactPoint = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactPoint.prototype.__constructor = function() { +}; +b2ContactPoint.prototype.__varz = function() { + this.position = new b2Vec2; + this.velocity = new b2Vec2; + this.normal = new b2Vec2; + this.id = new b2ContactID +}; +b2ContactPoint.prototype.shape1 = null; +b2ContactPoint.prototype.shape2 = null; +b2ContactPoint.prototype.position = new b2Vec2; +b2ContactPoint.prototype.velocity = new b2Vec2; +b2ContactPoint.prototype.normal = new b2Vec2; +b2ContactPoint.prototype.separation = null; +b2ContactPoint.prototype.friction = null; +b2ContactPoint.prototype.restitution = null; +b2ContactPoint.prototype.id = new b2ContactID;var b2CircleContact = function() { + b2Contact.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2CircleContact.prototype, b2Contact.prototype); +b2CircleContact.prototype._super = b2Contact.prototype; +b2CircleContact.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2CircleContact.prototype.__varz = function() { +}; +b2CircleContact.Create = function(allocator) { + return new b2CircleContact +}; +b2CircleContact.Destroy = function(contact, allocator) { +}; +b2CircleContact.prototype.Evaluate = function() { + var bA = this.m_fixtureA.GetBody(); + var bB = this.m_fixtureB.GetBody(); + b2Collision.CollideCircles(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) +}; +b2CircleContact.prototype.Reset = function(fixtureA, fixtureB) { + this._super.Reset.apply(this, [fixtureA, fixtureB]) +};var b2EdgeAndCircleContact = function() { + b2Contact.prototype.__varz.call(this); + this.__varz(); + this.__constructor.apply(this, arguments) +}; +extend(b2EdgeAndCircleContact.prototype, b2Contact.prototype); +b2EdgeAndCircleContact.prototype._super = b2Contact.prototype; +b2EdgeAndCircleContact.prototype.__constructor = function() { + this._super.__constructor.apply(this, arguments) +}; +b2EdgeAndCircleContact.prototype.__varz = function() { +}; +b2EdgeAndCircleContact.Create = function(allocator) { + return new b2EdgeAndCircleContact +}; +b2EdgeAndCircleContact.Destroy = function(contact, allocator) { +}; +b2EdgeAndCircleContact.prototype.Evaluate = function() { + var bA = this.m_fixtureA.GetBody(); + var bB = this.m_fixtureB.GetBody(); + this.b2CollideEdgeAndCircle(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) +}; +b2EdgeAndCircleContact.prototype.b2CollideEdgeAndCircle = function(manifold, edge, xf1, circle, xf2) { +}; +b2EdgeAndCircleContact.prototype.Reset = function(fixtureA, fixtureB) { + this._super.Reset.apply(this, [fixtureA, fixtureB]) +};var b2ContactManager = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2ContactManager.prototype.__constructor = function() { + this.m_world = null; + this.m_contactCount = 0; + this.m_contactFilter = b2ContactFilter.b2_defaultFilter; + this.m_contactListener = b2ContactListener.b2_defaultListener; + this.m_contactFactory = new b2ContactFactory(this.m_allocator); + this.m_broadPhase = new b2DynamicTreeBroadPhase +}; +b2ContactManager.prototype.__varz = function() { +}; +b2ContactManager.s_evalCP = new b2ContactPoint; +b2ContactManager.prototype.AddPair = function(proxyUserDataA, proxyUserDataB) { + var fixtureA = proxyUserDataA; + var fixtureB = proxyUserDataB; + var bodyA = fixtureA.GetBody(); + var bodyB = fixtureB.GetBody(); + if(bodyA == bodyB) { + return + } + var edge = bodyB.GetContactList(); + while(edge) { + if(edge.other == bodyA) { + var fA = edge.contact.GetFixtureA(); + var fB = edge.contact.GetFixtureB(); + if(fA == fixtureA && fB == fixtureB) { + return + } + if(fA == fixtureB && fB == fixtureA) { + return + } + } + edge = edge.next + } + if(bodyB.ShouldCollide(bodyA) == false) { + return + } + if(this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { + return + } + var c = this.m_contactFactory.Create(fixtureA, fixtureB); + fixtureA = c.GetFixtureA(); + fixtureB = c.GetFixtureB(); + bodyA = fixtureA.m_body; + bodyB = fixtureB.m_body; + c.m_prev = null; + c.m_next = this.m_world.m_contactList; + if(this.m_world.m_contactList != null) { + this.m_world.m_contactList.m_prev = c + } + this.m_world.m_contactList = c; + c.m_nodeA.contact = c; + c.m_nodeA.other = bodyB; + c.m_nodeA.prev = null; + c.m_nodeA.next = bodyA.m_contactList; + if(bodyA.m_contactList != null) { + bodyA.m_contactList.prev = c.m_nodeA + } + bodyA.m_contactList = c.m_nodeA; + c.m_nodeB.contact = c; + c.m_nodeB.other = bodyA; + c.m_nodeB.prev = null; + c.m_nodeB.next = bodyB.m_contactList; + if(bodyB.m_contactList != null) { + bodyB.m_contactList.prev = c.m_nodeB + } + bodyB.m_contactList = c.m_nodeB; + ++this.m_world.m_contactCount; + return +}; +b2ContactManager.prototype.FindNewContacts = function() { + var that = this; + this.m_broadPhase.UpdatePairs(function(a, b) { + return that.AddPair(a, b) + }) +}; +b2ContactManager.prototype.Destroy = function(c) { + var fixtureA = c.GetFixtureA(); + var fixtureB = c.GetFixtureB(); + var bodyA = fixtureA.GetBody(); + var bodyB = fixtureB.GetBody(); + if(c.IsTouching()) { + this.m_contactListener.EndContact(c) + } + if(c.m_prev) { + c.m_prev.m_next = c.m_next + } + if(c.m_next) { + c.m_next.m_prev = c.m_prev + } + if(c == this.m_world.m_contactList) { + this.m_world.m_contactList = c.m_next + } + if(c.m_nodeA.prev) { + c.m_nodeA.prev.next = c.m_nodeA.next + } + if(c.m_nodeA.next) { + c.m_nodeA.next.prev = c.m_nodeA.prev + } + if(c.m_nodeA == bodyA.m_contactList) { + bodyA.m_contactList = c.m_nodeA.next + } + if(c.m_nodeB.prev) { + c.m_nodeB.prev.next = c.m_nodeB.next + } + if(c.m_nodeB.next) { + c.m_nodeB.next.prev = c.m_nodeB.prev + } + if(c.m_nodeB == bodyB.m_contactList) { + bodyB.m_contactList = c.m_nodeB.next + } + this.m_contactFactory.Destroy(c); + --this.m_contactCount +}; +b2ContactManager.prototype.Collide = function() { + var c = this.m_world.m_contactList; + while(c) { + var fixtureA = c.GetFixtureA(); + var fixtureB = c.GetFixtureB(); + var bodyA = fixtureA.GetBody(); + var bodyB = fixtureB.GetBody(); + if(bodyA.IsAwake() == false && bodyB.IsAwake() == false) { + c = c.GetNext(); + continue + } + if(c.m_flags & b2Contact.e_filterFlag) { + if(bodyB.ShouldCollide(bodyA) == false) { + var cNuke = c; + c = cNuke.GetNext(); + this.Destroy(cNuke); + continue + } + if(this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { + cNuke = c; + c = cNuke.GetNext(); + this.Destroy(cNuke); + continue + } + c.m_flags &= ~b2Contact.e_filterFlag + } + var proxyA = fixtureA.m_proxy; + var proxyB = fixtureB.m_proxy; + var overlap = this.m_broadPhase.TestOverlap(proxyA, proxyB); + if(overlap == false) { + cNuke = c; + c = cNuke.GetNext(); + this.Destroy(cNuke); + continue + } + c.Update(this.m_contactListener); + c = c.GetNext() + } +}; +b2ContactManager.prototype.m_world = null; +b2ContactManager.prototype.m_broadPhase = null; +b2ContactManager.prototype.m_contactList = null; +b2ContactManager.prototype.m_contactCount = 0; +b2ContactManager.prototype.m_contactFilter = null; +b2ContactManager.prototype.m_contactListener = null; +b2ContactManager.prototype.m_contactFactory = null; +b2ContactManager.prototype.m_allocator = null;var b2World = function() { + this.__varz(); + this.__constructor.apply(this, arguments) +}; +b2World.prototype.__constructor = function(gravity, doSleep) { + this.m_destructionListener = null; + this.m_debugDraw = null; + this.m_bodyList = null; + this.m_contactList = null; + this.m_jointList = null; + this.m_controllerList = null; + this.m_bodyCount = 0; + this.m_contactCount = 0; + this.m_jointCount = 0; + this.m_controllerCount = 0; + b2World.m_warmStarting = true; + b2World.m_continuousPhysics = true; + this.m_allowSleep = doSleep; + this.m_gravity = gravity; + this.m_inv_dt0 = 0; + this.m_contactManager.m_world = this; + var bd = new b2BodyDef; + this.m_groundBody = this.CreateBody(bd) +}; +b2World.prototype.__varz = function() { + this.s_stack = new Array; + this.m_contactManager = new b2ContactManager; + this.m_contactSolver = new b2ContactSolver; + this.m_island = new b2Island +}; +b2World.s_timestep2 = new b2TimeStep; +b2World.s_backupA = new b2Sweep; +b2World.s_backupB = new b2Sweep; +b2World.s_timestep = new b2TimeStep; +b2World.s_queue = new Array; +b2World.e_newFixture = 1; +b2World.e_locked = 2; +b2World.s_xf = new b2Transform; +b2World.s_jointColor = new b2Color(0.5, 0.8, 0.8); +b2World.m_warmStarting = null; +b2World.m_continuousPhysics = null; +b2World.prototype.Solve = function(step) { + var b; + for(var controller = this.m_controllerList;controller;controller = controller.m_next) { + controller.Step(step) + } + var island = this.m_island; + island.Initialize(this.m_bodyCount, this.m_contactCount, this.m_jointCount, null, this.m_contactManager.m_contactListener, this.m_contactSolver); + for(b = this.m_bodyList;b;b = b.m_next) { + b.m_flags &= ~b2Body.e_islandFlag + } + for(var c = this.m_contactList;c;c = c.m_next) { + c.m_flags &= ~b2Contact.e_islandFlag + } + for(var j = this.m_jointList;j;j = j.m_next) { + j.m_islandFlag = false + } + var stackSize = this.m_bodyCount; + var stack = this.s_stack; + for(var seed = this.m_bodyList;seed;seed = seed.m_next) { + if(seed.m_flags & b2Body.e_islandFlag) { + continue + } + if(seed.IsAwake() == false || seed.IsActive() == false) { + continue + } + if(seed.GetType() == b2Body.b2_staticBody) { + continue + } + island.Clear(); + var stackCount = 0; + stack[stackCount++] = seed; + seed.m_flags |= b2Body.e_islandFlag; + while(stackCount > 0) { + b = stack[--stackCount]; + island.AddBody(b); + if(b.IsAwake() == false) { + b.SetAwake(true) + } + if(b.GetType() == b2Body.b2_staticBody) { + continue + } + var other; + for(var ce = b.m_contactList;ce;ce = ce.next) { + if(ce.contact.m_flags & b2Contact.e_islandFlag) { + continue + } + if(ce.contact.IsSensor() == true || ce.contact.IsEnabled() == false || ce.contact.IsTouching() == false) { + continue + } + island.AddContact(ce.contact); + ce.contact.m_flags |= b2Contact.e_islandFlag; + other = ce.other; + if(other.m_flags & b2Body.e_islandFlag) { + continue + } + stack[stackCount++] = other; + other.m_flags |= b2Body.e_islandFlag + } + for(var jn = b.m_jointList;jn;jn = jn.next) { + if(jn.joint.m_islandFlag == true) { + continue + } + other = jn.other; + if(other.IsActive() == false) { + continue + } + island.AddJoint(jn.joint); + jn.joint.m_islandFlag = true; + if(other.m_flags & b2Body.e_islandFlag) { + continue + } + stack[stackCount++] = other; + other.m_flags |= b2Body.e_islandFlag + } + } + island.Solve(step, this.m_gravity, this.m_allowSleep); + for(var i = 0;i < island.m_bodyCount;++i) { + b = island.m_bodies[i]; + if(b.GetType() == b2Body.b2_staticBody) { + b.m_flags &= ~b2Body.e_islandFlag + } + } + } + for(i = 0;i < stack.length;++i) { + if(!stack[i]) { + break + } + stack[i] = null + } + for(b = this.m_bodyList;b;b = b.m_next) { + if(b.IsAwake() == false || b.IsActive() == false) { + continue + } + if(b.GetType() == b2Body.b2_staticBody) { + continue + } + b.SynchronizeFixtures() + } + this.m_contactManager.FindNewContacts() +}; +b2World.prototype.SolveTOI = function(step) { + var b; + var fA; + var fB; + var bA; + var bB; + var cEdge; + var j; + var island = this.m_island; + island.Initialize(this.m_bodyCount, b2Settings.b2_maxTOIContactsPerIsland, b2Settings.b2_maxTOIJointsPerIsland, null, this.m_contactManager.m_contactListener, this.m_contactSolver); + var queue = b2World.s_queue; + for(b = this.m_bodyList;b;b = b.m_next) { + b.m_flags &= ~b2Body.e_islandFlag; + b.m_sweep.t0 = 0 + } + var c; + for(c = this.m_contactList;c;c = c.m_next) { + c.m_flags &= ~(b2Contact.e_toiFlag | b2Contact.e_islandFlag) + } + for(j = this.m_jointList;j;j = j.m_next) { + j.m_islandFlag = false + } + for(;;) { + var minContact = null; + var minTOI = 1; + for(c = this.m_contactList;c;c = c.m_next) { + if(c.IsSensor() == true || c.IsEnabled() == false || c.IsContinuous() == false) { + continue + } + var toi = 1; + if(c.m_flags & b2Contact.e_toiFlag) { + toi = c.m_toi + }else { + fA = c.m_fixtureA; + fB = c.m_fixtureB; + bA = fA.m_body; + bB = fB.m_body; + if((bA.GetType() != b2Body.b2_dynamicBody || bA.IsAwake() == false) && (bB.GetType() != b2Body.b2_dynamicBody || bB.IsAwake() == false)) { + continue + } + var t0 = bA.m_sweep.t0; + if(bA.m_sweep.t0 < bB.m_sweep.t0) { + t0 = bB.m_sweep.t0; + bA.m_sweep.Advance(t0) + }else { + if(bB.m_sweep.t0 < bA.m_sweep.t0) { + t0 = bA.m_sweep.t0; + bB.m_sweep.Advance(t0) + } + } + toi = c.ComputeTOI(bA.m_sweep, bB.m_sweep); + b2Settings.b2Assert(0 <= toi && toi <= 1); + if(toi > 0 && toi < 1) { + toi = (1 - toi) * t0 + toi; + if(toi > 1) { + toi = 1 + } + } + c.m_toi = toi; + c.m_flags |= b2Contact.e_toiFlag + } + if(Number.MIN_VALUE < toi && toi < minTOI) { + minContact = c; + minTOI = toi + } + } + if(minContact == null || 1 - 100 * Number.MIN_VALUE < minTOI) { + break + } + fA = minContact.m_fixtureA; + fB = minContact.m_fixtureB; + bA = fA.m_body; + bB = fB.m_body; + b2World.s_backupA.Set(bA.m_sweep); + b2World.s_backupB.Set(bB.m_sweep); + bA.Advance(minTOI); + bB.Advance(minTOI); + minContact.Update(this.m_contactManager.m_contactListener); + minContact.m_flags &= ~b2Contact.e_toiFlag; + if(minContact.IsSensor() == true || minContact.IsEnabled() == false) { + bA.m_sweep.Set(b2World.s_backupA); + bB.m_sweep.Set(b2World.s_backupB); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + continue + } + if(minContact.IsTouching() == false) { + continue + } + var seed = bA; + if(seed.GetType() != b2Body.b2_dynamicBody) { + seed = bB + } + island.Clear(); + var queueStart = 0; + var queueSize = 0; + queue[queueStart + queueSize++] = seed; + seed.m_flags |= b2Body.e_islandFlag; + while(queueSize > 0) { + b = queue[queueStart++]; + --queueSize; + island.AddBody(b); + if(b.IsAwake() == false) { + b.SetAwake(true) + } + if(b.GetType() != b2Body.b2_dynamicBody) { + continue + } + for(cEdge = b.m_contactList;cEdge;cEdge = cEdge.next) { + if(island.m_contactCount == island.m_contactCapacity) { + break + } + if(cEdge.contact.m_flags & b2Contact.e_islandFlag) { + continue + } + if(cEdge.contact.IsSensor() == true || cEdge.contact.IsEnabled() == false || cEdge.contact.IsTouching() == false) { + continue + } + island.AddContact(cEdge.contact); + cEdge.contact.m_flags |= b2Contact.e_islandFlag; + var other = cEdge.other; + if(other.m_flags & b2Body.e_islandFlag) { + continue + } + if(other.GetType() != b2Body.b2_staticBody) { + other.Advance(minTOI); + other.SetAwake(true) + } + queue[queueStart + queueSize] = other; + ++queueSize; + other.m_flags |= b2Body.e_islandFlag + } + for(var jEdge = b.m_jointList;jEdge;jEdge = jEdge.next) { + if(island.m_jointCount == island.m_jointCapacity) { + continue + } + if(jEdge.joint.m_islandFlag == true) { + continue + } + other = jEdge.other; + if(other.IsActive() == false) { + continue + } + island.AddJoint(jEdge.joint); + jEdge.joint.m_islandFlag = true; + if(other.m_flags & b2Body.e_islandFlag) { + continue + } + if(other.GetType() != b2Body.b2_staticBody) { + other.Advance(minTOI); + other.SetAwake(true) + } + queue[queueStart + queueSize] = other; + ++queueSize; + other.m_flags |= b2Body.e_islandFlag + } + } + var subStep = b2World.s_timestep; + subStep.warmStarting = false; + subStep.dt = (1 - minTOI) * step.dt; + subStep.inv_dt = 1 / subStep.dt; + subStep.dtRatio = 0; + subStep.velocityIterations = step.velocityIterations; + subStep.positionIterations = step.positionIterations; + island.SolveTOI(subStep); + var i = 0; + for(i = 0;i < island.m_bodyCount;++i) { + b = island.m_bodies[i]; + b.m_flags &= ~b2Body.e_islandFlag; + if(b.IsAwake() == false) { + continue + } + if(b.GetType() != b2Body.b2_dynamicBody) { + continue + } + b.SynchronizeFixtures(); + for(cEdge = b.m_contactList;cEdge;cEdge = cEdge.next) { + cEdge.contact.m_flags &= ~b2Contact.e_toiFlag + } + } + for(i = 0;i < island.m_contactCount;++i) { + c = island.m_contacts[i]; + c.m_flags &= ~(b2Contact.e_toiFlag | b2Contact.e_islandFlag) + } + for(i = 0;i < island.m_jointCount;++i) { + j = island.m_joints[i]; + j.m_islandFlag = false + } + this.m_contactManager.FindNewContacts() + } +}; +b2World.prototype.DrawJoint = function(joint) { + var b1 = joint.GetBodyA(); + var b2 = joint.GetBodyB(); + var xf1 = b1.m_xf; + var xf2 = b2.m_xf; + var x1 = xf1.position; + var x2 = xf2.position; + var p1 = joint.GetAnchorA(); + var p2 = joint.GetAnchorB(); + var color = b2World.s_jointColor; + switch(joint.m_type) { + case b2Joint.e_distanceJoint: + this.m_debugDraw.DrawSegment(p1, p2, color); + break; + case b2Joint.e_pulleyJoint: + var pulley = joint; + var s1 = pulley.GetGroundAnchorA(); + var s2 = pulley.GetGroundAnchorB(); + this.m_debugDraw.DrawSegment(s1, p1, color); + this.m_debugDraw.DrawSegment(s2, p2, color); + this.m_debugDraw.DrawSegment(s1, s2, color); + break; + case b2Joint.e_mouseJoint: + this.m_debugDraw.DrawSegment(p1, p2, color); + break; + default: + if(b1 != this.m_groundBody) { + this.m_debugDraw.DrawSegment(x1, p1, color) + } + this.m_debugDraw.DrawSegment(p1, p2, color); + if(b2 != this.m_groundBody) { + this.m_debugDraw.DrawSegment(x2, p2, color) + } + } +}; +b2World.prototype.DrawShape = function(shape, xf, color) { + switch(shape.m_type) { + case b2Shape.e_circleShape: + var circle = shape; + var center = b2Math.MulX(xf, circle.m_p); + var radius = circle.m_radius; + var axis = xf.R.col1; + this.m_debugDraw.DrawSolidCircle(center, radius, axis, color); + break; + case b2Shape.e_polygonShape: var i = 0; - var p = new Vector(count + 1); - for (i = 0; - i < count; ++i) { - p[i] = vs[i]; - } - p[count] = p[0]; - var minArea = Number.MAX_VALUE; - for (i = 1; - i <= count; ++i) { - var root = p[parseInt(i - 1)]; - var uxX = p[i].x - root.x; - var uxY = p[i].y - root.y; - var length = Math.sqrt(uxX * uxX + uxY * uxY); - uxX /= length; - uxY /= length; - var uyX = (-uxY); - var uyY = uxX; - var lowerX = Number.MAX_VALUE; - var lowerY = Number.MAX_VALUE; - var upperX = (-Number.MAX_VALUE); - var upperY = (-Number.MAX_VALUE); - for (var j = 0; j < count; ++j) { - var dX = p[j].x - root.x; - var dY = p[j].y - root.y; - var rX = (uxX * dX + uxY * dY); - var rY = (uyX * dX + uyY * dY); - if (rX < lowerX) lowerX = rX; - if (rY < lowerY) lowerY = rY; - if (rX > upperX) upperX = rX; - if (rY > upperY) upperY = rY; - } - var area = (upperX - lowerX) * (upperY - lowerY); - if (area < 0.95 * minArea) { - minArea = area; - obb.R.col1.x = uxX; - obb.R.col1.y = uxY; - obb.R.col2.x = uyX; - obb.R.col2.y = uyY; - var centerX = 0.5 * (lowerX + upperX); - var centerY = 0.5 * (lowerY + upperY); - var tMat = obb.R; - obb.center.x = root.x + (tMat.col1.x * centerX + tMat.col2.x * centerY); - obb.center.y = root.y + (tMat.col1.y * centerX + tMat.col2.y * centerY); - obb.extents.x = 0.5 * (upperX - lowerX); - obb.extents.y = 0.5 * (upperY - lowerY); - } - } - } - b2PolygonShape.ComputeOBB = b2PolygonShape.prototype.ComputeOBB; - _A2J_postDefs.push(function () { - Box2D.Collision.Shapes.b2PolygonShape.s_mat = new b2Mat22(); - Box2D.Collision.Shapes.b2PolygonShape.prototype.s_mat = Box2D.Collision.Shapes.b2PolygonShape.s_mat; - }); - b2Shape.b2Shape = function () {}; - b2Shape.prototype.Copy = function () { - return null; - } - b2Shape.prototype.Set = function (other) { - this.m_radius = other.m_radius; - } - b2Shape.prototype.GetType = function () { - return this.m_type; - } - b2Shape.prototype.TestPoint = function (xf, p) { - return false; - } - b2Shape.prototype.RayCast = function (output, input, transform) { - return false; - } - b2Shape.prototype.ComputeAABB = function (aabb, xf) {} - b2Shape.prototype.ComputeMass = function (massData, density) { - if (density === undefined) density = 0; - } - b2Shape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { - if (offset === undefined) offset = 0; - return 0; - } - b2Shape.prototype.TestOverlap = function (shape1, transform1, shape2, transform2) { - var input = new b2DistanceInput(); - input.proxyA = new b2DistanceProxy(); - input.proxyA.Set(shape1); - input.proxyB = new b2DistanceProxy(); - input.proxyB.Set(shape2); - input.transformA = transform1; - input.transformB = transform2; - input.useRadii = true; - var simplexCache = new b2SimplexCache(); - simplexCache.count = 0; - var output = new b2DistanceOutput(); - b2Distance.Distance(output, simplexCache, input); - return output.distance < 10.0 * Number.MIN_VALUE; - } - b2Shape.TestOverlap = b2Shape.prototype.TestOverlap; - b2Shape.prototype.b2Shape = function () { - this.m_type = b2Shape.e_unknownShape; - this.m_radius = b2Settings.b2_linearSlop; - } - _A2J_postDefs.push(function () { - Box2D.Collision.Shapes.b2Shape.e_unknownShape = parseInt((-1)); - Box2D.Collision.Shapes.b2Shape.prototype.e_unknownShape = Box2D.Collision.Shapes.b2Shape.e_unknownShape; - Box2D.Collision.Shapes.b2Shape.e_circleShape = 0; - Box2D.Collision.Shapes.b2Shape.prototype.e_circleShape = Box2D.Collision.Shapes.b2Shape.e_circleShape; - Box2D.Collision.Shapes.b2Shape.e_polygonShape = 1; - Box2D.Collision.Shapes.b2Shape.prototype.e_polygonShape = Box2D.Collision.Shapes.b2Shape.e_polygonShape; - Box2D.Collision.Shapes.b2Shape.e_edgeShape = 2; - Box2D.Collision.Shapes.b2Shape.prototype.e_edgeShape = Box2D.Collision.Shapes.b2Shape.e_edgeShape; - Box2D.Collision.Shapes.b2Shape.e_shapeTypeCount = 3; - Box2D.Collision.Shapes.b2Shape.prototype.e_shapeTypeCount = Box2D.Collision.Shapes.b2Shape.e_shapeTypeCount; - Box2D.Collision.Shapes.b2Shape.e_hitCollide = 1; - Box2D.Collision.Shapes.b2Shape.prototype.e_hitCollide = Box2D.Collision.Shapes.b2Shape.e_hitCollide; - Box2D.Collision.Shapes.b2Shape.e_missCollide = 0; - Box2D.Collision.Shapes.b2Shape.prototype.e_missCollide = Box2D.Collision.Shapes.b2Shape.e_missCollide; - Box2D.Collision.Shapes.b2Shape.e_startsInsideCollide = parseInt((-1)); - Box2D.Collision.Shapes.b2Shape.prototype.e_startsInsideCollide = Box2D.Collision.Shapes.b2Shape.e_startsInsideCollide; - }); -})(); /* source: disabled*/ -(function () { - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2Mat22 = Box2D.Common.Math.b2Mat22; - var b2Mat33 = Box2D.Common.Math.b2Mat33; - var b2Math = Box2D.Common.Math.b2Math; - var b2Sweep = Box2D.Common.Math.b2Sweep; - var b2Transform = Box2D.Common.Math.b2Transform; - var b2Vec2 = Box2D.Common.Math.b2Vec2; - var b2Vec3 = Box2D.Common.Math.b2Vec3; - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2internal = Box2D.Common.b2internal; - b2Color.b2Color = function () { - this._r = 0; - this._g = 0; - this._b = 0; - }; - b2Color.prototype.b2Color = function (rr, gg, bb) { - if (rr === undefined) rr = 0; - if (gg === undefined) gg = 0; - if (bb === undefined) bb = 0; - this._r = a2j.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0)); - this._g = a2j.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0)); - this._b = a2j.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0)); - } - b2Color.prototype.Set = function (rr, gg, bb) { - if (rr === undefined) rr = 0; - if (gg === undefined) gg = 0; - if (bb === undefined) bb = 0; - this._r = a2j.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0)); - this._g = a2j.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0)); - this._b = a2j.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0)); - } - b2Color.prototype.__defineSetter__('r', function (rr) { - if (rr === undefined) rr = 0; - this._r = a2j.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0)); - }); - b2Color.prototype.__defineSetter__('g', function (gg) { - if (gg === undefined) gg = 0; - this._g = a2j.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0)); - }); - b2Color.prototype.__defineSetter__('b', function (bb) { - if (bb === undefined) bb = 0; - this._b = a2j.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0)); - }); - b2Color.prototype.__defineGetter__('color', function () { - return (this._r << 16) | (this._g << 8) | (this._b); - }); - b2Settings.b2Settings = function () {}; - b2Settings.prototype.b2MixFriction = function (friction1, friction2) { - if (friction1 === undefined) friction1 = 0; - if (friction2 === undefined) friction2 = 0; - return Math.sqrt(friction1 * friction2); - } - b2Settings.b2MixFriction = b2Settings.prototype.b2MixFriction; - b2Settings.prototype.b2MixRestitution = function (restitution1, restitution2) { - if (restitution1 === undefined) restitution1 = 0; - if (restitution2 === undefined) restitution2 = 0; - return restitution1 > restitution2 ? restitution1 : restitution2; - } - b2Settings.b2MixRestitution = b2Settings.prototype.b2MixRestitution; - b2Settings.prototype.b2Assert = function (a) { - if (!a) { - throw "Assertion Failed"; - } - } - b2Settings.b2Assert = b2Settings.prototype.b2Assert; - _A2J_postDefs.push(function () { - Box2D.Common.b2Settings.VERSION = "2.1alpha"; - Box2D.Common.b2Settings.prototype.VERSION = Box2D.Common.b2Settings.VERSION; - Box2D.Common.b2Settings.USHRT_MAX = 0x0000ffff; - Box2D.Common.b2Settings.prototype.USHRT_MAX = Box2D.Common.b2Settings.USHRT_MAX; - Box2D.Common.b2Settings.b2_pi = Math.PI; - Box2D.Common.b2Settings.prototype.b2_pi = Box2D.Common.b2Settings.b2_pi; - Box2D.Common.b2Settings.b2_maxManifoldPoints = 2; - Box2D.Common.b2Settings.prototype.b2_maxManifoldPoints = Box2D.Common.b2Settings.b2_maxManifoldPoints; - Box2D.Common.b2Settings.b2_aabbExtension = 0.1; - Box2D.Common.b2Settings.prototype.b2_aabbExtension = Box2D.Common.b2Settings.b2_aabbExtension; - Box2D.Common.b2Settings.b2_aabbMultiplier = 2.0; - Box2D.Common.b2Settings.prototype.b2_aabbMultiplier = Box2D.Common.b2Settings.b2_aabbMultiplier; - Box2D.Common.b2Settings.b2_polygonRadius = 2.0 * b2Settings.b2_linearSlop; - Box2D.Common.b2Settings.prototype.b2_polygonRadius = Box2D.Common.b2Settings.b2_polygonRadius; - Box2D.Common.b2Settings.b2_linearSlop = 0.005; - Box2D.Common.b2Settings.prototype.b2_linearSlop = Box2D.Common.b2Settings.b2_linearSlop; - Box2D.Common.b2Settings.b2_angularSlop = 2.0 / 180.0 * b2Settings.b2_pi; - Box2D.Common.b2Settings.prototype.b2_angularSlop = Box2D.Common.b2Settings.b2_angularSlop; - Box2D.Common.b2Settings.b2_toiSlop = 8.0 * b2Settings.b2_linearSlop; - Box2D.Common.b2Settings.prototype.b2_toiSlop = Box2D.Common.b2Settings.b2_toiSlop; - Box2D.Common.b2Settings.b2_maxTOIContactsPerIsland = 32; - Box2D.Common.b2Settings.prototype.b2_maxTOIContactsPerIsland = Box2D.Common.b2Settings.b2_maxTOIContactsPerIsland; - Box2D.Common.b2Settings.b2_maxTOIJointsPerIsland = 32; - Box2D.Common.b2Settings.prototype.b2_maxTOIJointsPerIsland = Box2D.Common.b2Settings.b2_maxTOIJointsPerIsland; - Box2D.Common.b2Settings.b2_velocityThreshold = 1.0; - Box2D.Common.b2Settings.prototype.b2_velocityThreshold = Box2D.Common.b2Settings.b2_velocityThreshold; - Box2D.Common.b2Settings.b2_maxLinearCorrection = 0.2; - Box2D.Common.b2Settings.prototype.b2_maxLinearCorrection = Box2D.Common.b2Settings.b2_maxLinearCorrection; - Box2D.Common.b2Settings.b2_maxAngularCorrection = 8.0 / 180.0 * b2Settings.b2_pi; - Box2D.Common.b2Settings.prototype.b2_maxAngularCorrection = Box2D.Common.b2Settings.b2_maxAngularCorrection; - Box2D.Common.b2Settings.b2_maxTranslation = 2.0; - Box2D.Common.b2Settings.prototype.b2_maxTranslation = Box2D.Common.b2Settings.b2_maxTranslation; - Box2D.Common.b2Settings.b2_maxTranslationSquared = b2Settings.b2_maxTranslation * b2Settings.b2_maxTranslation; - Box2D.Common.b2Settings.prototype.b2_maxTranslationSquared = Box2D.Common.b2Settings.b2_maxTranslationSquared; - Box2D.Common.b2Settings.b2_maxRotation = 0.5 * b2Settings.b2_pi; - Box2D.Common.b2Settings.prototype.b2_maxRotation = Box2D.Common.b2Settings.b2_maxRotation; - Box2D.Common.b2Settings.b2_maxRotationSquared = b2Settings.b2_maxRotation * b2Settings.b2_maxRotation; - Box2D.Common.b2Settings.prototype.b2_maxRotationSquared = Box2D.Common.b2Settings.b2_maxRotationSquared; - Box2D.Common.b2Settings.b2_contactBaumgarte = 0.2; - Box2D.Common.b2Settings.prototype.b2_contactBaumgarte = Box2D.Common.b2Settings.b2_contactBaumgarte; - Box2D.Common.b2Settings.b2_timeToSleep = 0.5; - Box2D.Common.b2Settings.prototype.b2_timeToSleep = Box2D.Common.b2Settings.b2_timeToSleep; - Box2D.Common.b2Settings.b2_linearSleepTolerance = 0.01; - Box2D.Common.b2Settings.prototype.b2_linearSleepTolerance = Box2D.Common.b2Settings.b2_linearSleepTolerance; - Box2D.Common.b2Settings.b2_angularSleepTolerance = 2.0 / 180.0 * b2Settings.b2_pi; - Box2D.Common.b2Settings.prototype.b2_angularSleepTolerance = Box2D.Common.b2Settings.b2_angularSleepTolerance; - }); -})(); /* source: disabled*/ -(function () { - var b2AABB = Box2D.Collision.b2AABB; - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2Mat22 = Box2D.Common.Math.b2Mat22; - var b2Mat33 = Box2D.Common.Math.b2Mat33; - var b2Math = Box2D.Common.Math.b2Math; - var b2Sweep = Box2D.Common.Math.b2Sweep; - var b2Transform = Box2D.Common.Math.b2Transform; - var b2Vec2 = Box2D.Common.Math.b2Vec2; - var b2Vec3 = Box2D.Common.Math.b2Vec3; - b2Mat22.b2Mat22 = function () { - this.col1 = new b2Vec2(); - this.col2 = new b2Vec2(); - }; - b2Mat22.prototype.b2Mat22 = function () { - this.SetIdentity(); - } - b2Mat22.prototype.FromAngle = function (angle) { - if (angle === undefined) angle = 0; - var mat = new b2Mat22(); - mat.Set(angle); - return mat; - } - b2Mat22.FromAngle = b2Mat22.prototype.FromAngle; - b2Mat22.prototype.FromVV = function (c1, c2) { - var mat = new b2Mat22(); - mat.SetVV(c1, c2); - return mat; - } - b2Mat22.FromVV = b2Mat22.prototype.FromVV; - b2Mat22.prototype.Set = function (angle) { - if (angle === undefined) angle = 0; - var c = Math.cos(angle); - var s = Math.sin(angle); - this.col1.x = c; - this.col2.x = (-s); - this.col1.y = s; - this.col2.y = c; - } - b2Mat22.prototype.SetVV = function (c1, c2) { - this.col1.SetV(c1); - this.col2.SetV(c2); - } - b2Mat22.prototype.Copy = function () { - var mat = new b2Mat22(); - mat.SetM(this); - return mat; - } - b2Mat22.prototype.SetM = function (m) { - this.col1.SetV(m.col1); - this.col2.SetV(m.col2); - } - b2Mat22.prototype.AddM = function (m) { - this.col1.x += m.col1.x; - this.col1.y += m.col1.y; - this.col2.x += m.col2.x; - this.col2.y += m.col2.y; - } - b2Mat22.prototype.SetIdentity = function () { - this.col1.x = 1.0; - this.col2.x = 0.0; - this.col1.y = 0.0; - this.col2.y = 1.0; - } - b2Mat22.prototype.SetZero = function () { - this.col1.x = 0.0; - this.col2.x = 0.0; - this.col1.y = 0.0; - this.col2.y = 0.0; - } - b2Mat22.prototype.GetAngle = function () { - return Math.atan2(this.col1.y, this.col1.x); - } - b2Mat22.prototype.GetInverse = function (out) { - var a = this.col1.x; - var b = this.col2.x; - var c = this.col1.y; - var d = this.col2.y; - var det = a * d - b * c; - if (det != 0.0) { - det = 1.0 / det; - } - out.col1.x = det * d; - out.col2.x = (-det * b); - out.col1.y = (-det * c); - out.col2.y = det * a; - return out; - } - b2Mat22.prototype.Solve = function (out, bX, bY) { - if (bX === undefined) bX = 0; - if (bY === undefined) bY = 0; - var a11 = this.col1.x; - var a12 = this.col2.x; - var a21 = this.col1.y; - var a22 = this.col2.y; - var det = a11 * a22 - a12 * a21; - if (det != 0.0) { - det = 1.0 / det; - } - out.x = det * (a22 * bX - a12 * bY); - out.y = det * (a11 * bY - a21 * bX); - return out; - } - b2Mat22.prototype.Abs = function () { - this.col1.Abs(); - this.col2.Abs(); - } - b2Mat33.b2Mat33 = function () { - this.col1 = new b2Vec3(); - this.col2 = new b2Vec3(); - this.col3 = new b2Vec3(); - }; - b2Mat33.prototype.b2Mat33 = function (c1, c2, c3) { - if (c1 === undefined) c1 = null; - if (c2 === undefined) c2 = null; - if (c3 === undefined) c3 = null; - if (!c1 && !c2 && !c3) { - this.col1.SetZero(); - this.col2.SetZero(); - this.col3.SetZero(); - } - else { - this.col1.SetV(c1); - this.col2.SetV(c2); - this.col3.SetV(c3); - } - } - b2Mat33.prototype.SetVVV = function (c1, c2, c3) { - this.col1.SetV(c1); - this.col2.SetV(c2); - this.col3.SetV(c3); - } - b2Mat33.prototype.Copy = function () { - return new b2Mat33(this.col1, this.col2, this.col3); - } - b2Mat33.prototype.SetM = function (m) { - this.col1.SetV(m.col1); - this.col2.SetV(m.col2); - this.col3.SetV(m.col3); - } - b2Mat33.prototype.AddM = function (m) { - this.col1.x += m.col1.x; - this.col1.y += m.col1.y; - this.col1.z += m.col1.z; - this.col2.x += m.col2.x; - this.col2.y += m.col2.y; - this.col2.z += m.col2.z; - this.col3.x += m.col3.x; - this.col3.y += m.col3.y; - this.col3.z += m.col3.z; - } - b2Mat33.prototype.SetIdentity = function () { - this.col1.x = 1.0; - this.col2.x = 0.0; - this.col3.x = 0.0; - this.col1.y = 0.0; - this.col2.y = 1.0; - this.col3.y = 0.0; - this.col1.z = 0.0; - this.col2.z = 0.0; - this.col3.z = 1.0; - } - b2Mat33.prototype.SetZero = function () { - this.col1.x = 0.0; - this.col2.x = 0.0; - this.col3.x = 0.0; - this.col1.y = 0.0; - this.col2.y = 0.0; - this.col3.y = 0.0; - this.col1.z = 0.0; - this.col2.z = 0.0; - this.col3.z = 0.0; - } - b2Mat33.prototype.Solve22 = function (out, bX, bY) { - if (bX === undefined) bX = 0; - if (bY === undefined) bY = 0; - var a11 = this.col1.x; - var a12 = this.col2.x; - var a21 = this.col1.y; - var a22 = this.col2.y; - var det = a11 * a22 - a12 * a21; - if (det != 0.0) { - det = 1.0 / det; - } - out.x = det * (a22 * bX - a12 * bY); - out.y = det * (a11 * bY - a21 * bX); - return out; - } - b2Mat33.prototype.Solve33 = function (out, bX, bY, bZ) { - if (bX === undefined) bX = 0; - if (bY === undefined) bY = 0; - if (bZ === undefined) bZ = 0; - var a11 = this.col1.x; - var a21 = this.col1.y; - var a31 = this.col1.z; - var a12 = this.col2.x; - var a22 = this.col2.y; - var a32 = this.col2.z; - var a13 = this.col3.x; - var a23 = this.col3.y; - var a33 = this.col3.z; - var det = a11 * (a22 * a33 - a32 * a23) + a21 * (a32 * a13 - a12 * a33) + a31 * (a12 * a23 - a22 * a13); - if (det != 0.0) { - det = 1.0 / det; - } - out.x = det * (bX * (a22 * a33 - a32 * a23) + bY * (a32 * a13 - a12 * a33) + bZ * (a12 * a23 - a22 * a13)); - out.y = det * (a11 * (bY * a33 - bZ * a23) + a21 * (bZ * a13 - bX * a33) + a31 * (bX * a23 - bY * a13)); - out.z = det * (a11 * (a22 * bZ - a32 * bY) + a21 * (a32 * bX - a12 * bZ) + a31 * (a12 * bY - a22 * bX)); - return out; - } - b2Math.b2Math = function () {}; - b2Math.prototype.IsValid = function (x) { - if (x === undefined) x = 0; - return isFinite(x); - } - b2Math.IsValid = b2Math.prototype.IsValid; - b2Math.prototype.Dot = function (a, b) { - return a.x * b.x + a.y * b.y; - } - b2Math.Dot = b2Math.prototype.Dot; - b2Math.prototype.CrossVV = function (a, b) { - return a.x * b.y - a.y * b.x; - } - b2Math.CrossVV = b2Math.prototype.CrossVV; - b2Math.prototype.CrossVF = function (a, s) { - if (s === undefined) s = 0; - var v = new b2Vec2(s * a.y, (-s * a.x)); - return v; - } - b2Math.CrossVF = b2Math.prototype.CrossVF; - b2Math.prototype.CrossFV = function (s, a) { - if (s === undefined) s = 0; - var v = new b2Vec2((-s * a.y), s * a.x); - return v; - } - b2Math.CrossFV = b2Math.prototype.CrossFV; - b2Math.prototype.MulMV = function (A, v) { - var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y); - return u; - } - b2Math.MulMV = b2Math.prototype.MulMV; - b2Math.prototype.MulTMV = function (A, v) { - var u = new b2Vec2(this.Dot(v, A.col1), this.Dot(v, A.col2)); - return u; - } - b2Math.MulTMV = b2Math.prototype.MulTMV; - b2Math.prototype.MulX = function (T, v) { - var a = this.MulMV(T.R, v); - a.x += T.position.x; - a.y += T.position.y; - return a; - } - b2Math.MulX = b2Math.prototype.MulX; - b2Math.prototype.MulXT = function (T, v) { - var a = this.SubtractVV(v, T.position); - var tX = (a.x * T.R.col1.x + a.y * T.R.col1.y); - a.y = (a.x * T.R.col2.x + a.y * T.R.col2.y); - a.x = tX; - return a; - } - b2Math.MulXT = b2Math.prototype.MulXT; - b2Math.prototype.AddVV = function (a, b) { - var v = new b2Vec2(a.x + b.x, a.y + b.y); - return v; - } - b2Math.AddVV = b2Math.prototype.AddVV; - b2Math.prototype.SubtractVV = function (a, b) { - var v = new b2Vec2(a.x - b.x, a.y - b.y); - return v; - } - b2Math.SubtractVV = b2Math.prototype.SubtractVV; - b2Math.prototype.Distance = function (a, b) { - var cX = a.x - b.x; - var cY = a.y - b.y; - return Math.sqrt(cX * cX + cY * cY); - } - b2Math.Distance = b2Math.prototype.Distance; - b2Math.prototype.DistanceSquared = function (a, b) { - var cX = a.x - b.x; - var cY = a.y - b.y; - return (cX * cX + cY * cY); - } - b2Math.DistanceSquared = b2Math.prototype.DistanceSquared; - b2Math.prototype.MulFV = function (s, a) { - if (s === undefined) s = 0; - var v = new b2Vec2(s * a.x, s * a.y); - return v; - } - b2Math.MulFV = b2Math.prototype.MulFV; - b2Math.prototype.AddMM = function (A, B) { - var C = b2Mat22.FromVV(this.AddVV(A.col1, B.col1), this.AddVV(A.col2, B.col2)); - return C; - } - b2Math.AddMM = b2Math.prototype.AddMM; - b2Math.prototype.MulMM = function (A, B) { - var C = b2Mat22.FromVV(this.MulMV(A, B.col1), this.MulMV(A, B.col2)); - return C; - } - b2Math.MulMM = b2Math.prototype.MulMM; - b2Math.prototype.MulTMM = function (A, B) { - var c1 = new b2Vec2(this.Dot(A.col1, B.col1), this.Dot(A.col2, B.col1)); - var c2 = new b2Vec2(this.Dot(A.col1, B.col2), this.Dot(A.col2, B.col2)); - var C = b2Mat22.FromVV(c1, c2); - return C; - } - b2Math.MulTMM = b2Math.prototype.MulTMM; - b2Math.prototype.Abs = function (a) { - if (a === undefined) a = 0; - return a > 0.0 ? a : (-a); - } - b2Math.Abs = b2Math.prototype.Abs; - b2Math.prototype.AbsV = function (a) { - var b = new b2Vec2(this.Abs(a.x), this.Abs(a.y)); - return b; - } - b2Math.AbsV = b2Math.prototype.AbsV; - b2Math.prototype.AbsM = function (A) { - var B = b2Mat22.FromVV(this.AbsV(A.col1), this.AbsV(A.col2)); - return B; - } - b2Math.AbsM = b2Math.prototype.AbsM; - b2Math.prototype.Min = function (a, b) { - if (a === undefined) a = 0; - if (b === undefined) b = 0; - return a < b ? a : b; - } - b2Math.Min = b2Math.prototype.Min; - b2Math.prototype.MinV = function (a, b) { - var c = new b2Vec2(this.Min(a.x, b.x), this.Min(a.y, b.y)); - return c; - } - b2Math.MinV = b2Math.prototype.MinV; - b2Math.prototype.Max = function (a, b) { - if (a === undefined) a = 0; - if (b === undefined) b = 0; - return a > b ? a : b; - } - b2Math.Max = b2Math.prototype.Max; - b2Math.prototype.MaxV = function (a, b) { - var c = new b2Vec2(this.Max(a.x, b.x), this.Max(a.y, b.y)); - return c; - } - b2Math.MaxV = b2Math.prototype.MaxV; - b2Math.prototype.Clamp = function (a, low, high) { - if (a === undefined) a = 0; - if (low === undefined) low = 0; - if (high === undefined) high = 0; - return a < low ? low : a > high ? high : a; - } - b2Math.Clamp = b2Math.prototype.Clamp; - b2Math.prototype.ClampV = function (a, low, high) { - return this.MaxV(low, this.MinV(a, high)); - } - b2Math.ClampV = b2Math.prototype.ClampV; - b2Math.prototype.Swap = function (a, b) { - var tmp = a[0]; - a[0] = b[0]; - b[0] = tmp; - } - b2Math.Swap = b2Math.prototype.Swap; - b2Math.prototype.Random = function () { - return Math.random() * 2 - 1; - } - b2Math.Random = b2Math.prototype.Random; - b2Math.prototype.RandomRange = function (lo, hi) { - if (lo === undefined) lo = 0; - if (hi === undefined) hi = 0; - var r = Math.random(); - r = (hi - lo) * r + lo; - return r; - } - b2Math.RandomRange = b2Math.prototype.RandomRange; - b2Math.prototype.NextPowerOfTwo = function (x) { - if (x === undefined) x = 0; - x |= (x >> 1) & 0x7FFFFFFF; - x |= (x >> 2) & 0x3FFFFFFF; - x |= (x >> 4) & 0x0FFFFFFF; - x |= (x >> 8) & 0x00FFFFFF; - x |= (x >> 16) & 0x0000FFFF; - return x + 1; - } - b2Math.NextPowerOfTwo = b2Math.prototype.NextPowerOfTwo; - b2Math.prototype.IsPowerOfTwo = function (x) { - if (x === undefined) x = 0; - var result = x > 0 && (x & (x - 1)) == 0; - return result; - } - b2Math.IsPowerOfTwo = b2Math.prototype.IsPowerOfTwo; - _A2J_postDefs.push(function () { - Box2D.Common.Math.b2Math.b2Vec2_zero = new b2Vec2(0.0, 0.0); - Box2D.Common.Math.b2Math.prototype.b2Vec2_zero = Box2D.Common.Math.b2Math.b2Vec2_zero; - Box2D.Common.Math.b2Math.b2Mat22_identity = b2Mat22.FromVV(new b2Vec2(1.0, 0.0), new b2Vec2(0.0, 1.0)); - Box2D.Common.Math.b2Math.prototype.b2Mat22_identity = Box2D.Common.Math.b2Math.b2Mat22_identity; - Box2D.Common.Math.b2Math.b2Transform_identity = new b2Transform(b2Math.b2Vec2_zero, b2Math.b2Mat22_identity); - Box2D.Common.Math.b2Math.prototype.b2Transform_identity = Box2D.Common.Math.b2Math.b2Transform_identity; - }); - b2Sweep.b2Sweep = function () { - this.localCenter = new b2Vec2(); - this.c0 = new b2Vec2; - this.c = new b2Vec2(); - }; - b2Sweep.prototype.Set = function (other) { - this.localCenter.SetV(other.localCenter); - this.c0.SetV(other.c0); - this.c.SetV(other.c); - this.a0 = other.a0; - this.a = other.a; - this.t0 = other.t0; - } - b2Sweep.prototype.Copy = function () { - var copy = new b2Sweep(); - copy.localCenter.SetV(this.localCenter); - copy.c0.SetV(this.c0); - copy.c.SetV(this.c); - copy.a0 = this.a0; - copy.a = this.a; - copy.t0 = this.t0; - return copy; - } - b2Sweep.prototype.GetTransform = function (xf, alpha) { - if (alpha === undefined) alpha = 0; - xf.position.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x; - xf.position.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y; - var angle = (1.0 - alpha) * this.a0 + alpha * this.a; - xf.R.Set(angle); - var tMat = xf.R; - xf.position.x -= (tMat.col1.x * this.localCenter.x + tMat.col2.x * this.localCenter.y); - xf.position.y -= (tMat.col1.y * this.localCenter.x + tMat.col2.y * this.localCenter.y); - } - b2Sweep.prototype.Advance = function (t) { - if (t === undefined) t = 0; - if (this.t0 < t && 1.0 - this.t0 > Number.MIN_VALUE) { - var alpha = (t - this.t0) / (1.0 - this.t0); - this.c0.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x; - this.c0.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y; - this.a0 = (1.0 - alpha) * this.a0 + alpha * this.a; - this.t0 = t; - } - } - b2Transform.b2Transform = function () { - this.position = new b2Vec2; - this.R = new b2Mat22(); - }; - b2Transform.prototype.b2Transform = function (pos, r) { - if (pos === undefined) pos = null; - if (r === undefined) r = null; - if (pos) { - this.position.SetV(pos); - this.R.SetM(r); - } - } - b2Transform.prototype.Initialize = function (pos, r) { - this.position.SetV(pos); - this.R.SetM(r); - } - b2Transform.prototype.SetIdentity = function () { - this.position.SetZero(); - this.R.SetIdentity(); - } - b2Transform.prototype.Set = function (x) { - this.position.SetV(x.position); - this.R.SetM(x.R); - } - b2Transform.prototype.GetAngle = function () { - return Math.atan2(this.R.col1.y, this.R.col1.x); - } - b2Vec2.b2Vec2 = function () {}; - b2Vec2.prototype.b2Vec2 = function (x_, y_) { - if (x_ === undefined) x_ = 0; - if (y_ === undefined) y_ = 0; - this.x = x_; - this.y = y_; - } - b2Vec2.prototype.SetZero = function () { - this.x = 0.0; - this.y = 0.0; - } - b2Vec2.prototype.Set = function (x_, y_) { - if (x_ === undefined) x_ = 0; - if (y_ === undefined) y_ = 0; - this.x = x_; - this.y = y_; - } - b2Vec2.prototype.SetV = function (v) { - this.x = v.x; - this.y = v.y; - } - b2Vec2.prototype.GetNegative = function () { - return new b2Vec2((-this.x), (-this.y)); - } - b2Vec2.prototype.NegativeSelf = function () { - this.x = (-this.x); - this.y = (-this.y); - } - b2Vec2.prototype.Make = function (x_, y_) { - if (x_ === undefined) x_ = 0; - if (y_ === undefined) y_ = 0; - return new b2Vec2(x_, y_); - } - b2Vec2.Make = b2Vec2.prototype.Make; - b2Vec2.prototype.Copy = function () { - return new b2Vec2(this.x, this.y); - } - b2Vec2.prototype.Add = function (v) { - this.x += v.x; - this.y += v.y; - } - b2Vec2.prototype.Subtract = function (v) { - this.x -= v.x; - this.y -= v.y; - } - b2Vec2.prototype.Multiply = function (a) { - if (a === undefined) a = 0; - this.x *= a; - this.y *= a; - } - b2Vec2.prototype.MulM = function (A) { - var tX = this.x; - this.x = A.col1.x * tX + A.col2.x * this.y; - this.y = A.col1.y * tX + A.col2.y * this.y; - } - b2Vec2.prototype.MulTM = function (A) { - var tX = b2Math.Dot(this, A.col1); - this.y = b2Math.Dot(this, A.col2); - this.x = tX; - } - b2Vec2.prototype.CrossVF = function (s) { - if (s === undefined) s = 0; - var tX = this.x; - this.x = s * this.y; - this.y = (-s * tX); - } - b2Vec2.prototype.CrossFV = function (s) { - if (s === undefined) s = 0; - var tX = this.x; - this.x = (-s * this.y); - this.y = s * tX; - } - b2Vec2.prototype.MinV = function (b) { - this.x = this.x < b.x ? this.x : b.x; - this.y = this.y < b.y ? this.y : b.y; - } - b2Vec2.prototype.MaxV = function (b) { - this.x = this.x > b.x ? this.x : b.x; - this.y = this.y > b.y ? this.y : b.y; - } - b2Vec2.prototype.Abs = function () { - if (this.x < 0) this.x = (-this.x); - if (this.y < 0) this.y = (-this.y); - } - b2Vec2.prototype.Length = function () { - return Math.sqrt(this.x * this.x + this.y * this.y); - } - b2Vec2.prototype.LengthSquared = function () { - return (this.x * this.x + this.y * this.y); - } - b2Vec2.prototype.Normalize = function () { - var length = Math.sqrt(this.x * this.x + this.y * this.y); - if (length < Number.MIN_VALUE) { - return 0.0; - } - var invLength = 1.0 / length; - this.x *= invLength; - this.y *= invLength; - return length; - } - b2Vec2.prototype.IsValid = function () { - return b2Math.IsValid(this.x) && b2Math.IsValid(this.y); - } - b2Vec3.b2Vec3 = function () {}; - b2Vec3.prototype.b2Vec3 = function (x, y, z) { - if (x === undefined) x = 0; - if (y === undefined) y = 0; - if (z === undefined) z = 0; - this.x = x; - this.y = y; - this.z = z; - } - b2Vec3.prototype.SetZero = function () { - this.x = this.y = this.z = 0.0; - } - b2Vec3.prototype.Set = function (x, y, z) { - if (x === undefined) x = 0; - if (y === undefined) y = 0; - if (z === undefined) z = 0; - this.x = x; - this.y = y; - this.z = z; - } - b2Vec3.prototype.SetV = function (v) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - } - b2Vec3.prototype.GetNegative = function () { - return new b2Vec3((-this.x), (-this.y), (-this.z)); - } - b2Vec3.prototype.NegativeSelf = function () { - this.x = (-this.x); - this.y = (-this.y); - this.z = (-this.z); - } - b2Vec3.prototype.Copy = function () { - return new b2Vec3(this.x, this.y, this.z); - } - b2Vec3.prototype.Add = function (v) { - this.x += v.x; - this.y += v.y; - this.z += v.z; - } - b2Vec3.prototype.Subtract = function (v) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - } - b2Vec3.prototype.Multiply = function (a) { - if (a === undefined) a = 0; - this.x *= a; - this.y *= a; - this.z *= a; - } -})(); /* source: disabled*/ -(function () { - var b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge; - var b2Mat22 = Box2D.Common.Math.b2Mat22; - var b2Mat33 = Box2D.Common.Math.b2Mat33; - var b2Math = Box2D.Common.Math.b2Math; - var b2Sweep = Box2D.Common.Math.b2Sweep; - var b2Transform = Box2D.Common.Math.b2Transform; - var b2Vec2 = Box2D.Common.Math.b2Vec2; - var b2Vec3 = Box2D.Common.Math.b2Vec3; - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2AABB = Box2D.Collision.b2AABB; - var b2Bound = Box2D.Collision.b2Bound; - var b2BoundValues = Box2D.Collision.b2BoundValues; - var b2BroadPhase = Box2D.Collision.b2BroadPhase; - var b2Collision = Box2D.Collision.b2Collision; - var b2ContactID = Box2D.Collision.b2ContactID; - var b2ContactPoint = Box2D.Collision.b2ContactPoint; - var b2Distance = Box2D.Collision.b2Distance; - var b2DistanceInput = Box2D.Collision.b2DistanceInput; - var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; - var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; - var b2DynamicTree = Box2D.Collision.b2DynamicTree; - var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; - var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; - var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; - var b2Manifold = Box2D.Collision.b2Manifold; - var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; - var b2OBB = Box2D.Collision.b2OBB; - var b2Pair = Box2D.Collision.b2Pair; - var b2PairManager = Box2D.Collision.b2PairManager; - var b2Point = Box2D.Collision.b2Point; - var b2Proxy = Box2D.Collision.b2Proxy; - var b2RayCastInput = Box2D.Collision.b2RayCastInput; - var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; - var b2Segment = Box2D.Collision.b2Segment; - var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; - var b2Simplex = Box2D.Collision.b2Simplex; - var b2SimplexCache = Box2D.Collision.b2SimplexCache; - var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; - var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; - var b2TOIInput = Box2D.Collision.b2TOIInput; - var b2WorldManifold = Box2D.Collision.b2WorldManifold; - var ClipVertex = Box2D.Collision.ClipVertex; - var Features = Box2D.Collision.Features; - var IBroadPhase = Box2D.Collision.IBroadPhase; - var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; - var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; - var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; - var b2MassData = Box2D.Collision.Shapes.b2MassData; - var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; - var b2Shape = Box2D.Collision.Shapes.b2Shape; - var b2Body = Box2D.Dynamics.b2Body; - var b2BodyDef = Box2D.Dynamics.b2BodyDef; - var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; - var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; - var b2ContactListener = Box2D.Dynamics.b2ContactListener; - var b2ContactManager = Box2D.Dynamics.b2ContactManager; - var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; - var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; - var b2FilterData = Box2D.Dynamics.b2FilterData; - var b2Fixture = Box2D.Dynamics.b2Fixture; - var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; - var b2Island = Box2D.Dynamics.b2Island; - var b2TimeStep = Box2D.Dynamics.b2TimeStep; - var b2World = Box2D.Dynamics.b2World; - var b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact; - var b2Contact = Box2D.Dynamics.Contacts.b2Contact; - var b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint; - var b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint; - var b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge; - var b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory; - var b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister; - var b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult; - var b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver; - var b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact; - var b2NullContact = Box2D.Dynamics.Contacts.b2NullContact; - var b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact; - var b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact; - var b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact; - var b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold; - var b2Controller = Box2D.Dynamics.Controllers.b2Controller; - var b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge; - var b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint; - var b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef; - var b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint; - var b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef; - var b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint; - var b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef; - var b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian; - var b2Joint = Box2D.Dynamics.Joints.b2Joint; - var b2JointDef = Box2D.Dynamics.Joints.b2JointDef; - var b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge; - var b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint; - var b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef; - var b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint; - var b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef; - var b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint; - var b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef; - var b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint; - var b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef; - var b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint; - var b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef; - var b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint; - var b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef; - var b2internal = Box2D.Common.b2internal; - var b2Body = Box2D.Dynamics.b2Body; - var b2BodyDef = Box2D.Dynamics.b2BodyDef; - var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; - var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; - var b2ContactListener = Box2D.Dynamics.b2ContactListener; - var b2ContactManager = Box2D.Dynamics.b2ContactManager; - var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; - var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; - var b2FilterData = Box2D.Dynamics.b2FilterData; - var b2Fixture = Box2D.Dynamics.b2Fixture; - var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; - var b2Island = Box2D.Dynamics.b2Island; - var b2TimeStep = Box2D.Dynamics.b2TimeStep; - var b2World = Box2D.Dynamics.b2World; - b2Body.b2Body = function () { - this.m_xf = new b2Transform(); - this.m_sweep = new b2Sweep(); - this.m_linearVelocity = new b2Vec2(); - this.m_force = new b2Vec2(); - }; - b2Body.prototype.connectEdges = function (s1, s2, angle1) { - if (angle1 === undefined) angle1 = 0; - var angle2 = Math.atan2(s2.GetDirectionVector().y, s2.GetDirectionVector().x); - var coreOffset = Math.tan((angle2 - angle1) * 0.5); - var core = b2Math.MulFV(coreOffset, s2.GetDirectionVector()); - core = b2Math.SubtractVV(core, s2.GetNormalVector()); - core = b2Math.MulFV(b2Settings.b2_toiSlop, core); - core = b2Math.AddVV(core, s2.GetVertex1()); - var cornerDir = b2Math.AddVV(s1.GetDirectionVector(), s2.GetDirectionVector()); - cornerDir.Normalize(); - var convex = b2Math.Dot(s1.GetDirectionVector(), s2.GetNormalVector()) > 0.0; - s1.SetNextEdge(s2, core, cornerDir, convex); - s2.SetPrevEdge(s1, core, cornerDir, convex); - return angle2; - } - b2Body.prototype.CreateFixture = function (def) { - if (this.m_world.IsLocked() == true) { - return null; - } - var fixture = new b2Fixture(); - fixture.Create(this, this.m_xf, def); - if (this.m_flags & b2Body.e_activeFlag) { - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - fixture.CreateProxy(broadPhase, this.m_xf); - } - fixture.m_next = this.m_fixtureList; - this.m_fixtureList = fixture; - ++this.m_fixtureCount; - fixture.m_body = this; - if (fixture.m_density > 0.0) { - this.ResetMassData(); - } - this.m_world.m_flags |= b2World.e_newFixture; - return fixture; - } - b2Body.prototype.CreateFixture2 = function (shape, density) { - if (density === undefined) density = 0.0; - var def = new b2FixtureDef(); - def.shape = shape; - def.density = density; - return this.CreateFixture(def); - } - b2Body.prototype.DestroyFixture = function (fixture) { - if (this.m_world.IsLocked() == true) { - return; - } - var node = this.m_fixtureList; - var ppF = null; - var found = false; - while (node != null) { - if (node == fixture) { - if (ppF) ppF.m_next = fixture.m_next; - else this.m_fixtureList = fixture.m_next; - found = true; - break; - } - ppF = node; - node = node.m_next; - } - var edge = this.m_contactList; - while (edge) { - var c = edge.contact; - edge = edge.next; - var fixtureA = c.GetFixtureA(); - var fixtureB = c.GetFixtureB(); - if (fixture == fixtureA || fixture == fixtureB) { - this.m_world.m_contactManager.Destroy(c); - } - } - if (this.m_flags & b2Body.e_activeFlag) { - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - fixture.DestroyProxy(broadPhase); - } - else {} - fixture.Destroy(); - fixture.m_body = null; - fixture.m_next = null; - --this.m_fixtureCount; - this.ResetMassData(); - } - b2Body.prototype.SetPositionAndAngle = function (position, angle) { - if (angle === undefined) angle = 0; - var f; - if (this.m_world.IsLocked() == true) { - return; - } - this.m_xf.R.Set(angle); - this.m_xf.position.SetV(position); - var tMat = this.m_xf.R; - var tVec = this.m_sweep.localCenter; - this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_sweep.c.x += this.m_xf.position.x; - this.m_sweep.c.y += this.m_xf.position.y; - this.m_sweep.c0.SetV(this.m_sweep.c); - this.m_sweep.a0 = this.m_sweep.a = angle; - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - for (f = this.m_fixtureList; - f; f = f.m_next) { - f.Synchronize(broadPhase, this.m_xf, this.m_xf); - } - this.m_world.m_contactManager.FindNewContacts(); - } - b2Body.prototype.SetTransform = function (xf) { - this.SetPositionAndAngle(xf.position, xf.GetAngle()); - } - b2Body.prototype.GetTransform = function () { - return this.m_xf; - } - b2Body.prototype.GetPosition = function () { - return this.m_xf.position; - } - b2Body.prototype.SetPosition = function (position) { - this.SetPositionAndAngle(position, this.GetAngle()); - } - b2Body.prototype.GetAngle = function () { - return this.m_sweep.a; - } - b2Body.prototype.SetAngle = function (angle) { - if (angle === undefined) angle = 0; - this.SetPositionAndAngle(this.GetPosition(), angle); - } - b2Body.prototype.GetWorldCenter = function () { - return this.m_sweep.c; - } - b2Body.prototype.GetLocalCenter = function () { - return this.m_sweep.localCenter; - } - b2Body.prototype.SetLinearVelocity = function (v) { - if (this.m_type == b2Body.b2_staticBody) { - return; - } - this.m_linearVelocity.SetV(v); - } - b2Body.prototype.GetLinearVelocity = function () { - return this.m_linearVelocity; - } - b2Body.prototype.SetAngularVelocity = function (omega) { - if (omega === undefined) omega = 0; - if (this.m_type == b2Body.b2_staticBody) { - return; - } - this.m_angularVelocity = omega; - } - b2Body.prototype.GetAngularVelocity = function () { - return this.m_angularVelocity; - } - b2Body.prototype.GetDefinition = function () { - var bd = new b2BodyDef(); - bd.type = this.GetType(); - bd.allowSleep = (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag; - bd.angle = this.GetAngle(); - bd.angularDamping = this.m_angularDamping; - bd.angularVelocity = this.m_angularVelocity; - bd.fixedRotation = (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag; - bd.bullet = (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag; - bd.awake = (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag; - bd.linearDamping = this.m_linearDamping; - bd.linearVelocity.SetV(this.GetLinearVelocity()); - bd.position = this.GetPosition(); - bd.userData = this.GetUserData(); - return bd; - } - b2Body.prototype.ApplyForce = function (force, point) { - if (this.m_type != b2Body.b2_dynamicBody) { - return; - } - if (this.IsAwake() == false) { - this.SetAwake(true); - } - this.m_force.x += force.x; - this.m_force.y += force.y; - this.m_torque += ((point.x - this.m_sweep.c.x) * force.y - (point.y - this.m_sweep.c.y) * force.x); - } - b2Body.prototype.ApplyTorque = function (torque) { - if (torque === undefined) torque = 0; - if (this.m_type != b2Body.b2_dynamicBody) { - return; - } - if (this.IsAwake() == false) { - this.SetAwake(true); - } - this.m_torque += torque; - } - b2Body.prototype.ApplyImpulse = function (impulse, point) { - if (this.m_type != b2Body.b2_dynamicBody) { - return; - } - if (this.IsAwake() == false) { - this.SetAwake(true); - } - this.m_linearVelocity.x += this.m_invMass * impulse.x; - this.m_linearVelocity.y += this.m_invMass * impulse.y; - this.m_angularVelocity += this.m_invI * ((point.x - this.m_sweep.c.x) * impulse.y - (point.y - this.m_sweep.c.y) * impulse.x); - } - b2Body.prototype.Split = function (callback) { - var linearVelocity = this.GetLinearVelocity().Copy(); - var angularVelocity = this.GetAngularVelocity(); - var center = this.GetWorldCenter(); - var body1 = this; - var body2 = this.m_world.CreateBody(this.GetDefinition()); - var prev; - for (var f = body1.m_fixtureList; f;) { - if (callback(f)) { - var next = f.m_next; - if (prev) { - prev.m_next = next; + var poly = shape; + var vertexCount = poly.GetVertexCount(); + var localVertices = poly.GetVertices(); + var vertices = new Array(vertexCount); + for(i = 0;i < vertexCount;++i) { + vertices[i] = b2Math.MulX(xf, localVertices[i]) + } + this.m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color); + break; + case b2Shape.e_edgeShape: + var edge = shape; + this.m_debugDraw.DrawSegment(b2Math.MulX(xf, edge.GetVertex1()), b2Math.MulX(xf, edge.GetVertex2()), color); + break + } +}; +b2World.prototype.SetDestructionListener = function(listener) { + this.m_destructionListener = listener +}; +b2World.prototype.SetContactFilter = function(filter) { + this.m_contactManager.m_contactFilter = filter +}; +b2World.prototype.SetContactListener = function(listener) { + this.m_contactManager.m_contactListener = listener +}; +b2World.prototype.SetDebugDraw = function(debugDraw) { + this.m_debugDraw = debugDraw +}; +b2World.prototype.SetBroadPhase = function(broadPhase) { + var oldBroadPhase = this.m_contactManager.m_broadPhase; + this.m_contactManager.m_broadPhase = broadPhase; + for(var b = this.m_bodyList;b;b = b.m_next) { + for(var f = b.m_fixtureList;f;f = f.m_next) { + f.m_proxy = broadPhase.CreateProxy(oldBroadPhase.GetFatAABB(f.m_proxy), f) + } + } +}; +b2World.prototype.Validate = function() { + this.m_contactManager.m_broadPhase.Validate() +}; +b2World.prototype.GetProxyCount = function() { + return this.m_contactManager.m_broadPhase.GetProxyCount() +}; +b2World.prototype.CreateBody = function(def) { + if(this.IsLocked() == true) { + return null + } + var b = new b2Body(def, this); + b.m_prev = null; + b.m_next = this.m_bodyList; + if(this.m_bodyList) { + this.m_bodyList.m_prev = b + } + this.m_bodyList = b; + ++this.m_bodyCount; + return b +}; +b2World.prototype.DestroyBody = function(b) { + if(this.IsLocked() == true) { + return + } + var jn = b.m_jointList; + while(jn) { + var jn0 = jn; + jn = jn.next; + if(this.m_destructionListener) { + this.m_destructionListener.SayGoodbyeJoint(jn0.joint) + } + this.DestroyJoint(jn0.joint) + } + var coe = b.m_controllerList; + while(coe) { + var coe0 = coe; + coe = coe.nextController; + coe0.controller.RemoveBody(b) + } + var ce = b.m_contactList; + while(ce) { + var ce0 = ce; + ce = ce.next; + this.m_contactManager.Destroy(ce0.contact) + } + b.m_contactList = null; + var f = b.m_fixtureList; + while(f) { + var f0 = f; + f = f.m_next; + if(this.m_destructionListener) { + this.m_destructionListener.SayGoodbyeFixture(f0) + } + f0.DestroyProxy(this.m_contactManager.m_broadPhase); + f0.Destroy() + } + b.m_fixtureList = null; + b.m_fixtureCount = 0; + if(b.m_prev) { + b.m_prev.m_next = b.m_next + } + if(b.m_next) { + b.m_next.m_prev = b.m_prev + } + if(b == this.m_bodyList) { + this.m_bodyList = b.m_next + } + --this.m_bodyCount +}; +b2World.prototype.CreateJoint = function(def) { + var j = b2Joint.Create(def, null); + j.m_prev = null; + j.m_next = this.m_jointList; + if(this.m_jointList) { + this.m_jointList.m_prev = j + } + this.m_jointList = j; + ++this.m_jointCount; + j.m_edgeA.joint = j; + j.m_edgeA.other = j.m_bodyB; + j.m_edgeA.prev = null; + j.m_edgeA.next = j.m_bodyA.m_jointList; + if(j.m_bodyA.m_jointList) { + j.m_bodyA.m_jointList.prev = j.m_edgeA + } + j.m_bodyA.m_jointList = j.m_edgeA; + j.m_edgeB.joint = j; + j.m_edgeB.other = j.m_bodyA; + j.m_edgeB.prev = null; + j.m_edgeB.next = j.m_bodyB.m_jointList; + if(j.m_bodyB.m_jointList) { + j.m_bodyB.m_jointList.prev = j.m_edgeB + } + j.m_bodyB.m_jointList = j.m_edgeB; + var bodyA = def.bodyA; + var bodyB = def.bodyB; + if(def.collideConnected == false) { + var edge = bodyB.GetContactList(); + while(edge) { + if(edge.other == bodyA) { + edge.contact.FlagForFiltering() + } + edge = edge.next + } + } + return j +}; +b2World.prototype.DestroyJoint = function(j) { + var collideConnected = j.m_collideConnected; + if(j.m_prev) { + j.m_prev.m_next = j.m_next + } + if(j.m_next) { + j.m_next.m_prev = j.m_prev + } + if(j == this.m_jointList) { + this.m_jointList = j.m_next + } + var bodyA = j.m_bodyA; + var bodyB = j.m_bodyB; + bodyA.SetAwake(true); + bodyB.SetAwake(true); + if(j.m_edgeA.prev) { + j.m_edgeA.prev.next = j.m_edgeA.next + } + if(j.m_edgeA.next) { + j.m_edgeA.next.prev = j.m_edgeA.prev + } + if(j.m_edgeA == bodyA.m_jointList) { + bodyA.m_jointList = j.m_edgeA.next + } + j.m_edgeA.prev = null; + j.m_edgeA.next = null; + if(j.m_edgeB.prev) { + j.m_edgeB.prev.next = j.m_edgeB.next + } + if(j.m_edgeB.next) { + j.m_edgeB.next.prev = j.m_edgeB.prev + } + if(j.m_edgeB == bodyB.m_jointList) { + bodyB.m_jointList = j.m_edgeB.next + } + j.m_edgeB.prev = null; + j.m_edgeB.next = null; + b2Joint.Destroy(j, null); + --this.m_jointCount; + if(collideConnected == false) { + var edge = bodyB.GetContactList(); + while(edge) { + if(edge.other == bodyA) { + edge.contact.FlagForFiltering() + } + edge = edge.next + } + } +}; +b2World.prototype.AddController = function(c) { + c.m_next = this.m_controllerList; + c.m_prev = null; + this.m_controllerList = c; + c.m_world = this; + this.m_controllerCount++; + return c +}; +b2World.prototype.RemoveController = function(c) { + if(c.m_prev) { + c.m_prev.m_next = c.m_next + } + if(c.m_next) { + c.m_next.m_prev = c.m_prev + } + if(this.m_controllerList == c) { + this.m_controllerList = c.m_next + } + this.m_controllerCount-- +}; +b2World.prototype.CreateController = function(controller) { + if(controller.m_world != this) { + throw new Error("Controller can only be a member of one world"); + } + controller.m_next = this.m_controllerList; + controller.m_prev = null; + if(this.m_controllerList) { + this.m_controllerList.m_prev = controller + } + this.m_controllerList = controller; + ++this.m_controllerCount; + controller.m_world = this; + return controller +}; +b2World.prototype.DestroyController = function(controller) { + controller.Clear(); + if(controller.m_next) { + controller.m_next.m_prev = controller.m_prev + } + if(controller.m_prev) { + controller.m_prev.m_next = controller.m_next + } + if(controller == this.m_controllerList) { + this.m_controllerList = controller.m_next + } + --this.m_controllerCount +}; +b2World.prototype.SetWarmStarting = function(flag) { + b2World.m_warmStarting = flag +}; +b2World.prototype.SetContinuousPhysics = function(flag) { + b2World.m_continuousPhysics = flag +}; +b2World.prototype.GetBodyCount = function() { + return this.m_bodyCount +}; +b2World.prototype.GetJointCount = function() { + return this.m_jointCount +}; +b2World.prototype.GetContactCount = function() { + return this.m_contactCount +}; +b2World.prototype.SetGravity = function(gravity) { + this.m_gravity = gravity +}; +b2World.prototype.GetGravity = function() { + return this.m_gravity +}; +b2World.prototype.GetGroundBody = function() { + return this.m_groundBody +}; +b2World.prototype.Step = function(dt, velocityIterations, positionIterations) { + if(this.m_flags & b2World.e_newFixture) { + this.m_contactManager.FindNewContacts(); + this.m_flags &= ~b2World.e_newFixture + } + this.m_flags |= b2World.e_locked; + var step = b2World.s_timestep2; + step.dt = dt; + step.velocityIterations = velocityIterations; + step.positionIterations = positionIterations; + if(dt > 0) { + step.inv_dt = 1 / dt + }else { + step.inv_dt = 0 + } + step.dtRatio = this.m_inv_dt0 * dt; + step.warmStarting = b2World.m_warmStarting; + this.m_contactManager.Collide(); + if(step.dt > 0) { + this.Solve(step) + } + if(b2World.m_continuousPhysics && step.dt > 0) { + this.SolveTOI(step) + } + if(step.dt > 0) { + this.m_inv_dt0 = step.inv_dt + } + this.m_flags &= ~b2World.e_locked +}; +b2World.prototype.ClearForces = function() { + for(var body = this.m_bodyList;body;body = body.m_next) { + body.m_force.SetZero(); + body.m_torque = 0 + } +}; +b2World.prototype.DrawDebugData = function() { + if(this.m_debugDraw == null) { + return + } + this.m_debugDraw.Clear(); + var flags = this.m_debugDraw.GetFlags(); + var i = 0; + var b; + var f; + var s; + var j; + var bp; + var invQ = new b2Vec2; + var x1 = new b2Vec2; + var x2 = new b2Vec2; + var xf; + var b1 = new b2AABB; + var b2 = new b2AABB; + var vs = [new b2Vec2, new b2Vec2, new b2Vec2, new b2Vec2]; + var color = new b2Color(0, 0, 0); + if(flags & b2DebugDraw.e_shapeBit) { + for(b = this.m_bodyList;b;b = b.m_next) { + xf = b.m_xf; + for(f = b.GetFixtureList();f;f = f.m_next) { + s = f.GetShape(); + if(b.IsActive() == false) { + color.Set(0.5, 0.5, 0.3); + this.DrawShape(s, xf, color) + }else { + if(b.GetType() == b2Body.b2_staticBody) { + color.Set(0.5, 0.9, 0.5); + this.DrawShape(s, xf, color) + }else { + if(b.GetType() == b2Body.b2_kinematicBody) { + color.Set(0.5, 0.5, 0.9); + this.DrawShape(s, xf, color) + }else { + if(b.IsAwake() == false) { + color.Set(0.6, 0.6, 0.6); + this.DrawShape(s, xf, color) + }else { + color.Set(0.9, 0.7, 0.7); + this.DrawShape(s, xf, color) + } } - else { - body1.m_fixtureList = next; - } - body1.m_fixtureCount--; - f.m_next = body2.m_fixtureList; - body2.m_fixtureList = f; - body2.m_fixtureCount++; - f.m_body = body2; - f = next; - } - else { - prev = f; - f = f.m_next; - } - } - body1.ResetMassData(); - body2.ResetMassData(); - var center1 = body1.GetWorldCenter(); - var center2 = body2.GetWorldCenter(); - var velocity1 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center1, center))); - var velocity2 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center2, center))); - body1.SetLinearVelocity(velocity1); - body2.SetLinearVelocity(velocity2); - body1.SetAngularVelocity(angularVelocity); - body2.SetAngularVelocity(angularVelocity); - body1.SynchronizeFixtures(); - body2.SynchronizeFixtures(); - return body2; - } - b2Body.prototype.Merge = function (other) { - var f; - for (f = other.m_fixtureList; - f;) { - var next = f.m_next; - other.m_fixtureCount--; - f.m_next = this.m_fixtureList; - this.m_fixtureList = f; - this.m_fixtureCount++; - f.m_body = body2; - f = next; - } - body1.m_fixtureCount = 0; - var body1 = this; - var body2 = other; - var center1 = body1.GetWorldCenter(); - var center2 = body2.GetWorldCenter(); - var velocity1 = body1.GetLinearVelocity().Copy(); - var velocity2 = body2.GetLinearVelocity().Copy(); - var angular1 = body1.GetAngularVelocity(); - var angular = body2.GetAngularVelocity(); - body1.ResetMassData(); - this.SynchronizeFixtures(); - } - b2Body.prototype.GetMass = function () { - return this.m_mass; - } - b2Body.prototype.GetInertia = function () { - return this.m_I; - } - b2Body.prototype.GetMassData = function (data) { - data.mass = this.m_mass; - data.I = this.m_I; - data.center.SetV(this.m_sweep.localCenter); - } - b2Body.prototype.SetMassData = function (massData) { - b2Settings.b2Assert(this.m_world.IsLocked() == false); - if (this.m_world.IsLocked() == true) { - return; - } - if (this.m_type != b2Body.b2_dynamicBody) { - return; - } - this.m_invMass = 0.0; - this.m_I = 0.0; - this.m_invI = 0.0; - this.m_mass = massData.mass; - if (this.m_mass <= 0.0) { - this.m_mass = 1.0; - } - this.m_invMass = 1.0 / this.m_mass; - if (massData.I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { - this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y); - this.m_invI = 1.0 / this.m_I; - } - var oldCenter = this.m_sweep.c.Copy(); - this.m_sweep.localCenter.SetV(massData.center); - this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); - this.m_sweep.c.SetV(this.m_sweep.c0); - this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y)); - this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x)); - } - b2Body.prototype.ResetMassData = function () { - this.m_mass = 0.0; - this.m_invMass = 0.0; - this.m_I = 0.0; - this.m_invI = 0.0; - this.m_sweep.localCenter.SetZero(); - if (this.m_type == b2Body.b2_staticBody || this.m_type == b2Body.b2_kinematicBody) { - return; - } - var center = b2Vec2.Make(0, 0); - for (var f = this.m_fixtureList; f; f = f.m_next) { - if (f.m_density == 0.0) { - continue; - } - var massData = f.GetMassData(); - this.m_mass += massData.mass; - center.x += massData.center.x * massData.mass; - center.y += massData.center.y * massData.mass; - this.m_I += massData.I; - } - if (this.m_mass > 0.0) { - this.m_invMass = 1.0 / this.m_mass; - center.x *= this.m_invMass; - center.y *= this.m_invMass; - } - else { - this.m_mass = 1.0; - this.m_invMass = 1.0; - } - if (this.m_I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { - this.m_I -= this.m_mass * (center.x * center.x + center.y * center.y); - this.m_I *= this.m_inertiaScale; - b2Settings.b2Assert(this.m_I > 0); - this.m_invI = 1.0 / this.m_I; - } - else { - this.m_I = 0.0; - this.m_invI = 0.0; - } - var oldCenter = this.m_sweep.c.Copy(); - this.m_sweep.localCenter.SetV(center); - this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); - this.m_sweep.c.SetV(this.m_sweep.c0); - this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y)); - this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x)); - } - b2Body.prototype.GetWorldPoint = function (localPoint) { - var A = this.m_xf.R; - var u = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); - u.x += this.m_xf.position.x; - u.y += this.m_xf.position.y; - return u; - } - b2Body.prototype.GetWorldVector = function (localVector) { - return b2Math.MulMV(this.m_xf.R, localVector); - } - b2Body.prototype.GetLocalPoint = function (worldPoint) { - return b2Math.MulXT(this.m_xf, worldPoint); - } - b2Body.prototype.GetLocalVector = function (worldVector) { - return b2Math.MulTMV(this.m_xf.R, worldVector); - } - b2Body.prototype.GetLinearVelocityFromWorldPoint = function (worldPoint) { - return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)); - } - b2Body.prototype.GetLinearVelocityFromLocalPoint = function (localPoint) { - var A = this.m_xf.R; - var worldPoint = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); - worldPoint.x += this.m_xf.position.x; - worldPoint.y += this.m_xf.position.y; - return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)); - } - b2Body.prototype.GetLinearDamping = function () { - return this.m_linearDamping; - } - b2Body.prototype.SetLinearDamping = function (linearDamping) { - if (linearDamping === undefined) linearDamping = 0; - this.m_linearDamping = linearDamping; - } - b2Body.prototype.GetAngularDamping = function () { - return this.m_angularDamping; - } - b2Body.prototype.SetAngularDamping = function (angularDamping) { - if (angularDamping === undefined) angularDamping = 0; - this.m_angularDamping = angularDamping; - } - b2Body.prototype.SetType = function (type) { - if (type === undefined) type = 0; - if (this.m_type == type) { - return; - } - this.m_type = type; - this.ResetMassData(); - if (this.m_type == b2Body.b2_staticBody) { - this.m_linearVelocity.SetZero(); - this.m_angularVelocity = 0.0; - } - this.SetAwake(true); - this.m_force.SetZero(); - this.m_torque = 0.0; - for (var ce = this.m_contactList; ce; ce = ce.next) { - ce.contact.FlagForFiltering(); - } - } - b2Body.prototype.GetType = function () { - return this.m_type; - } - b2Body.prototype.SetBullet = function (flag) { - if (flag) { - this.m_flags |= b2Body.e_bulletFlag; - } - else { - this.m_flags &= ~b2Body.e_bulletFlag; - } - } - b2Body.prototype.IsBullet = function () { - return (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag; - } - b2Body.prototype.SetSleepingAllowed = function (flag) { - if (flag) { - this.m_flags |= b2Body.e_allowSleepFlag; - } - else { - this.m_flags &= ~b2Body.e_allowSleepFlag; - this.SetAwake(true); - } - } - b2Body.prototype.SetAwake = function (flag) { - if (flag) { - this.m_flags |= b2Body.e_awakeFlag; - this.m_sleepTime = 0.0; - } - else { - this.m_flags &= ~b2Body.e_awakeFlag; - this.m_sleepTime = 0.0; - this.m_linearVelocity.SetZero(); - this.m_angularVelocity = 0.0; - this.m_force.SetZero(); - this.m_torque = 0.0; - } - } - b2Body.prototype.IsAwake = function () { - return (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag; - } - b2Body.prototype.SetFixedRotation = function (fixed) { - if (fixed) { - this.m_flags |= b2Body.e_fixedRotationFlag; - } - else { - this.m_flags &= ~b2Body.e_fixedRotationFlag; - } - this.ResetMassData(); - } - b2Body.prototype.IsFixedRotation = function () { - return (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag; - } - b2Body.prototype.SetActive = function (flag) { - if (flag == this.IsActive()) { - return; - } - var broadPhase; - var f; - if (flag) { - this.m_flags |= b2Body.e_activeFlag; - broadPhase = this.m_world.m_contactManager.m_broadPhase; - for (f = this.m_fixtureList; - f; f = f.m_next) { - f.CreateProxy(broadPhase, this.m_xf); - } - } - else { - this.m_flags &= ~b2Body.e_activeFlag; - broadPhase = this.m_world.m_contactManager.m_broadPhase; - for (f = this.m_fixtureList; - f; f = f.m_next) { - f.DestroyProxy(broadPhase); - } - var ce = this.m_contactList; - while (ce) { - var ce0 = ce; - ce = ce.next; - this.m_world.m_contactManager.Destroy(ce0.contact); - } - this.m_contactList = null; - } - } - b2Body.prototype.IsActive = function () { - return (this.m_flags & b2Body.e_activeFlag) == b2Body.e_activeFlag; - } - b2Body.prototype.IsSleepingAllowed = function () { - return (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag; - } - b2Body.prototype.GetFixtureList = function () { - return this.m_fixtureList; - } - b2Body.prototype.GetJointList = function () { - return this.m_jointList; - } - b2Body.prototype.GetControllerList = function () { - return this.m_controllerList; - } - b2Body.prototype.GetContactList = function () { - return this.m_contactList; - } - b2Body.prototype.GetNext = function () { - return this.m_next; - } - b2Body.prototype.GetUserData = function () { - return this.m_userData; - } - b2Body.prototype.SetUserData = function (data) { - this.m_userData = data; - } - b2Body.prototype.GetWorld = function () { - return this.m_world; - } - b2Body.prototype.b2Body = function (bd, world) { - this.m_flags = 0; - if (bd.bullet) { - this.m_flags |= b2Body.e_bulletFlag; - } - if (bd.fixedRotation) { - this.m_flags |= b2Body.e_fixedRotationFlag; - } - if (bd.allowSleep) { - this.m_flags |= b2Body.e_allowSleepFlag; - } - if (bd.awake) { - this.m_flags |= b2Body.e_awakeFlag; - } - if (bd.active) { - this.m_flags |= b2Body.e_activeFlag; - } - this.m_world = world; - this.m_xf.position.SetV(bd.position); - this.m_xf.R.Set(bd.angle); - this.m_sweep.localCenter.SetZero(); - this.m_sweep.t0 = 1.0; - this.m_sweep.a0 = this.m_sweep.a = bd.angle; - var tMat = this.m_xf.R; - var tVec = this.m_sweep.localCenter; - this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_sweep.c.x += this.m_xf.position.x; - this.m_sweep.c.y += this.m_xf.position.y; - this.m_sweep.c0.SetV(this.m_sweep.c); - this.m_jointList = null; - this.m_controllerList = null; - this.m_contactList = null; - this.m_controllerCount = 0; - this.m_prev = null; - this.m_next = null; - this.m_linearVelocity.SetV(bd.linearVelocity); - this.m_angularVelocity = bd.angularVelocity; - this.m_linearDamping = bd.linearDamping; - this.m_angularDamping = bd.angularDamping; - this.m_force.Set(0.0, 0.0); - this.m_torque = 0.0; - this.m_sleepTime = 0.0; - this.m_type = bd.type; - if (this.m_type == b2Body.b2_dynamicBody) { - this.m_mass = 1.0; - this.m_invMass = 1.0; - } - else { - this.m_mass = 0.0; - this.m_invMass = 0.0; - } - this.m_I = 0.0; - this.m_invI = 0.0; - this.m_inertiaScale = bd.inertiaScale; - this.m_userData = bd.userData; - this.m_fixtureList = null; - this.m_fixtureCount = 0; - } - b2Body.prototype.SynchronizeFixtures = function () { - var xf1 = b2Body.s_xf1; - xf1.R.Set(this.m_sweep.a0); - var tMat = xf1.R; - var tVec = this.m_sweep.localCenter; - xf1.position.x = this.m_sweep.c0.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - xf1.position.y = this.m_sweep.c0.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var f; - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - for (f = this.m_fixtureList; - f; f = f.m_next) { - f.Synchronize(broadPhase, xf1, this.m_xf); - } - } - b2Body.prototype.SynchronizeTransform = function () { - this.m_xf.R.Set(this.m_sweep.a); - var tMat = this.m_xf.R; - var tVec = this.m_sweep.localCenter; - this.m_xf.position.x = this.m_sweep.c.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - this.m_xf.position.y = this.m_sweep.c.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - } - b2Body.prototype.ShouldCollide = function (other) { - if (this.m_type != b2Body.b2_dynamicBody && other.m_type != b2Body.b2_dynamicBody) { - return false; - } - for (var jn = this.m_jointList; jn; jn = jn.next) { - if (jn.other == other) if (jn.joint.m_collideConnected == false) { - return false; - } - } - return true; - } - b2Body.prototype.Advance = function (t) { - if (t === undefined) t = 0; - this.m_sweep.Advance(t); - this.m_sweep.c.SetV(this.m_sweep.c0); - this.m_sweep.a = this.m_sweep.a0; - this.SynchronizeTransform(); - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.b2Body.s_xf1 = new b2Transform(); - Box2D.Dynamics.b2Body.prototype.s_xf1 = Box2D.Dynamics.b2Body.s_xf1; - Box2D.Dynamics.b2Body.e_islandFlag = 0x0001; - Box2D.Dynamics.b2Body.prototype.e_islandFlag = Box2D.Dynamics.b2Body.e_islandFlag; - Box2D.Dynamics.b2Body.e_awakeFlag = 0x0002; - Box2D.Dynamics.b2Body.prototype.e_awakeFlag = Box2D.Dynamics.b2Body.e_awakeFlag; - Box2D.Dynamics.b2Body.e_allowSleepFlag = 0x0004; - Box2D.Dynamics.b2Body.prototype.e_allowSleepFlag = Box2D.Dynamics.b2Body.e_allowSleepFlag; - Box2D.Dynamics.b2Body.e_bulletFlag = 0x0008; - Box2D.Dynamics.b2Body.prototype.e_bulletFlag = Box2D.Dynamics.b2Body.e_bulletFlag; - Box2D.Dynamics.b2Body.e_fixedRotationFlag = 0x0010; - Box2D.Dynamics.b2Body.prototype.e_fixedRotationFlag = Box2D.Dynamics.b2Body.e_fixedRotationFlag; - Box2D.Dynamics.b2Body.e_activeFlag = 0x0020; - Box2D.Dynamics.b2Body.prototype.e_activeFlag = Box2D.Dynamics.b2Body.e_activeFlag; - Box2D.Dynamics.b2Body.b2_staticBody = 0; - Box2D.Dynamics.b2Body.prototype.b2_staticBody = Box2D.Dynamics.b2Body.b2_staticBody; - Box2D.Dynamics.b2Body.b2_kinematicBody = 1; - Box2D.Dynamics.b2Body.prototype.b2_kinematicBody = Box2D.Dynamics.b2Body.b2_kinematicBody; - Box2D.Dynamics.b2Body.b2_dynamicBody = 2; - Box2D.Dynamics.b2Body.prototype.b2_dynamicBody = Box2D.Dynamics.b2Body.b2_dynamicBody; - }); - b2BodyDef.b2BodyDef = function () { - this.position = new b2Vec2(); - this.linearVelocity = new b2Vec2(); - }; - b2BodyDef.prototype.b2BodyDef = function () { - this.userData = null; - this.position.Set(0.0, 0.0); - this.angle = 0.0; - this.linearVelocity.Set(0, 0); - this.angularVelocity = 0.0; - this.linearDamping = 0.0; - this.angularDamping = 0.0; - this.allowSleep = true; - this.awake = true; - this.fixedRotation = false; - this.bullet = false; - this.type = b2Body.b2_staticBody; - this.active = true; - this.inertiaScale = 1.0; - } - b2ContactFilter.b2ContactFilter = function () {}; - b2ContactFilter.prototype.ShouldCollide = function (fixtureA, fixtureB) { - var filter1 = fixtureA.GetFilterData(); - var filter2 = fixtureB.GetFilterData(); - if (filter1.groupIndex == filter2.groupIndex && filter1.groupIndex != 0) { - return filter1.groupIndex > 0; - } - var collide = (filter1.maskBits & filter2.categoryBits) != 0 && (filter1.categoryBits & filter2.maskBits) != 0; - return collide; - } - b2ContactFilter.prototype.RayCollide = function (userData, fixture) { - if (!userData) return true; - return this.ShouldCollide((userData instanceof b2Fixture ? userData : null), fixture); - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.b2ContactFilter.b2_defaultFilter = new b2ContactFilter(); - Box2D.Dynamics.b2ContactFilter.prototype.b2_defaultFilter = Box2D.Dynamics.b2ContactFilter.b2_defaultFilter; - }); - b2ContactImpulse.b2ContactImpulse = function () { - this.normalImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); - this.tangentImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); - }; - b2ContactListener.b2ContactListener = function () {}; - b2ContactListener.prototype.BeginContact = function (contact) {} - b2ContactListener.prototype.EndContact = function (contact) {} - b2ContactListener.prototype.PreSolve = function (contact, oldManifold) {} - b2ContactListener.prototype.PostSolve = function (contact, impulse) {} - _A2J_postDefs.push(function () { - Box2D.Dynamics.b2ContactListener.b2_defaultListener = new b2ContactListener(); - Box2D.Dynamics.b2ContactListener.prototype.b2_defaultListener = Box2D.Dynamics.b2ContactListener.b2_defaultListener; - }); - b2ContactManager.b2ContactManager = function () {}; - b2ContactManager.prototype.b2ContactManager = function () { - this.m_world = null; - this.m_contactCount = 0; - this.m_contactFilter = b2ContactFilter.b2_defaultFilter; - this.m_contactListener = b2ContactListener.b2_defaultListener; - this.m_contactFactory = new b2ContactFactory(this.m_allocator); - this.m_broadPhase = new b2DynamicTreeBroadPhase(); - } - b2ContactManager.prototype.AddPair = function (proxyUserDataA, proxyUserDataB) { - var fixtureA = (proxyUserDataA instanceof b2Fixture ? proxyUserDataA : null); - var fixtureB = (proxyUserDataB instanceof b2Fixture ? proxyUserDataB : null); - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if (bodyA == bodyB) return; - var edge = bodyB.GetContactList(); - while (edge) { - if (edge.other == bodyA) { - var fA = edge.contact.GetFixtureA(); - var fB = edge.contact.GetFixtureB(); - if (fA == fixtureA && fB == fixtureB) return; - if (fA == fixtureB && fB == fixtureA) return; - } - edge = edge.next; - } - if (bodyB.ShouldCollide(bodyA) == false) { - return; - } - if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { - return; - } - var c = this.m_contactFactory.Create(fixtureA, fixtureB); - fixtureA = c.GetFixtureA(); - fixtureB = c.GetFixtureB(); - bodyA = fixtureA.m_body; - bodyB = fixtureB.m_body; - c.m_prev = null; - c.m_next = this.m_world.m_contactList; - if (this.m_world.m_contactList != null) { - this.m_world.m_contactList.m_prev = c; - } - this.m_world.m_contactList = c; - c.m_nodeA.contact = c; - c.m_nodeA.other = bodyB; - c.m_nodeA.prev = null; - c.m_nodeA.next = bodyA.m_contactList; - if (bodyA.m_contactList != null) { - bodyA.m_contactList.prev = c.m_nodeA; - } - bodyA.m_contactList = c.m_nodeA; - c.m_nodeB.contact = c; - c.m_nodeB.other = bodyA; - c.m_nodeB.prev = null; - c.m_nodeB.next = bodyB.m_contactList; - if (bodyB.m_contactList != null) { - bodyB.m_contactList.prev = c.m_nodeB; - } - bodyB.m_contactList = c.m_nodeB; - ++this.m_world.m_contactCount; - return; - } - b2ContactManager.prototype.FindNewContacts = function () { - this.m_broadPhase.UpdatePairs(a2j.generateCallback(this, this.AddPair)); - } - b2ContactManager.prototype.Destroy = function (c) { - var fixtureA = c.GetFixtureA(); - var fixtureB = c.GetFixtureB(); - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if (c.IsTouching()) { - this.m_contactListener.EndContact(c); - } - if (c.m_prev) { - c.m_prev.m_next = c.m_next; - } - if (c.m_next) { - c.m_next.m_prev = c.m_prev; - } - if (c == this.m_world.m_contactList) { - this.m_world.m_contactList = c.m_next; - } - if (c.m_nodeA.prev) { - c.m_nodeA.prev.next = c.m_nodeA.next; - } - if (c.m_nodeA.next) { - c.m_nodeA.next.prev = c.m_nodeA.prev; - } - if (c.m_nodeA == bodyA.m_contactList) { - bodyA.m_contactList = c.m_nodeA.next; - } - if (c.m_nodeB.prev) { - c.m_nodeB.prev.next = c.m_nodeB.next; - } - if (c.m_nodeB.next) { - c.m_nodeB.next.prev = c.m_nodeB.prev; - } - if (c.m_nodeB == bodyB.m_contactList) { - bodyB.m_contactList = c.m_nodeB.next; - } - this.m_contactFactory.Destroy(c); - --this.m_contactCount; - } - b2ContactManager.prototype.Collide = function () { - var c = this.m_world.m_contactList; - while (c) { - var fixtureA = c.GetFixtureA(); - var fixtureB = c.GetFixtureB(); - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if (bodyA.IsAwake() == false && bodyB.IsAwake() == false) { - c = c.GetNext(); - continue; - } - if (c.m_flags & b2Contact.e_filterFlag) { - if (bodyB.ShouldCollide(bodyA) == false) { - var cNuke = c; - c = cNuke.GetNext(); - this.Destroy(cNuke); - continue; - } - if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { - cNuke = c; - c = cNuke.GetNext(); - this.Destroy(cNuke); - continue; - } - c.m_flags &= ~b2Contact.e_filterFlag; - } - var proxyA = fixtureA.m_proxy; - var proxyB = fixtureB.m_proxy; - var overlap = this.m_broadPhase.TestOverlap(proxyA, proxyB); - if (overlap == false) { - cNuke = c; - c = cNuke.GetNext(); - this.Destroy(cNuke); - continue; - } - c.Update(this.m_contactListener); - c = c.GetNext(); - } - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.b2ContactManager.s_evalCP = new b2ContactPoint(); - Box2D.Dynamics.b2ContactManager.prototype.s_evalCP = Box2D.Dynamics.b2ContactManager.s_evalCP; - }); - b2DebugDraw.b2DebugDraw = function () {}; - b2DebugDraw.prototype.b2DebugDraw = function () { - m_drawFlags = 0; - } - b2DebugDraw.prototype.SetFlags = function (flags) { - if (flags === undefined) flags = 0; - } - b2DebugDraw.prototype.GetFlags = function () {} - b2DebugDraw.prototype.AppendFlags = function (flags) { - if (flags === undefined) flags = 0; - } - b2DebugDraw.prototype.ClearFlags = function (flags) { - if (flags === undefined) flags = 0; - } - b2DebugDraw.prototype.SetSprite = function (sprite) {} - b2DebugDraw.prototype.GetSprite = function () {} - b2DebugDraw.prototype.SetDrawScale = function (drawScale) { - if (drawScale === undefined) drawScale = 0; - } - b2DebugDraw.prototype.GetDrawScale = function () {} - b2DebugDraw.prototype.SetLineThickness = function (lineThickness) { - if (lineThickness === undefined) lineThickness = 0; - } - b2DebugDraw.prototype.GetLineThickness = function () {} - b2DebugDraw.prototype.SetAlpha = function (alpha) { - if (alpha === undefined) alpha = 0; - } - b2DebugDraw.prototype.GetAlpha = function () {} - b2DebugDraw.prototype.SetFillAlpha = function (alpha) { - if (alpha === undefined) alpha = 0; - } - b2DebugDraw.prototype.GetFillAlpha = function () {} - b2DebugDraw.prototype.SetXFormScale = function (xformScale) { - if (xformScale === undefined) xformScale = 0; - } - b2DebugDraw.prototype.GetXFormScale = function () {} - b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) { - if (vertexCount === undefined) vertexCount = 0; - } - b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) { - if (vertexCount === undefined) vertexCount = 0; - } - b2DebugDraw.prototype.DrawCircle = function (center, radius, color) { - if (radius === undefined) radius = 0; - } - b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) { - if (radius === undefined) radius = 0; - } - b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) {} - b2DebugDraw.prototype.DrawTransform = function (xf) {} - _A2J_postDefs.push(function () { - Box2D.Dynamics.b2DebugDraw.e_shapeBit = 0x0001; - Box2D.Dynamics.b2DebugDraw.prototype.e_shapeBit = Box2D.Dynamics.b2DebugDraw.e_shapeBit; - Box2D.Dynamics.b2DebugDraw.e_jointBit = 0x0002; - Box2D.Dynamics.b2DebugDraw.prototype.e_jointBit = Box2D.Dynamics.b2DebugDraw.e_jointBit; - Box2D.Dynamics.b2DebugDraw.e_aabbBit = 0x0004; - Box2D.Dynamics.b2DebugDraw.prototype.e_aabbBit = Box2D.Dynamics.b2DebugDraw.e_aabbBit; - Box2D.Dynamics.b2DebugDraw.e_pairBit = 0x0008; - Box2D.Dynamics.b2DebugDraw.prototype.e_pairBit = Box2D.Dynamics.b2DebugDraw.e_pairBit; - Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit = 0x0010; - Box2D.Dynamics.b2DebugDraw.prototype.e_centerOfMassBit = Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit; - Box2D.Dynamics.b2DebugDraw.e_controllerBit = 0x0020; - Box2D.Dynamics.b2DebugDraw.prototype.e_controllerBit = Box2D.Dynamics.b2DebugDraw.e_controllerBit; - }); - b2DestructionListener.b2DestructionListener = function () {}; - b2DestructionListener.prototype.SayGoodbyeJoint = function (joint) {} - b2DestructionListener.prototype.SayGoodbyeFixture = function (fixture) {} - b2FilterData.b2FilterData = function () { - this.categoryBits = 0x0001; - this.maskBits = 0xFFFF; - this.groupIndex = 0; - }; - b2FilterData.prototype.Copy = function () { - var copy = new b2FilterData(); - copy.categoryBits = this.categoryBits; - copy.maskBits = this.maskBits; - copy.groupIndex = this.groupIndex; - return copy; - } - b2Fixture.b2Fixture = function () { - this.m_filter = new b2FilterData(); - }; - b2Fixture.prototype.GetType = function () { - return this.m_shape.GetType(); - } - b2Fixture.prototype.GetShape = function () { - return this.m_shape; - } - b2Fixture.prototype.SetSensor = function (sensor) { - if (this.m_isSensor == sensor) return; - this.m_isSensor = sensor; - if (this.m_body == null) return; - var edge = this.m_body.GetContactList(); - while (edge) { - var contact = edge.contact; - var fixtureA = contact.GetFixtureA(); - var fixtureB = contact.GetFixtureB(); - if (fixtureA == this || fixtureB == this) contact.SetSensor(fixtureA.IsSensor() || fixtureB.IsSensor()); - edge = edge.next; - } - } - b2Fixture.prototype.IsSensor = function () { - return this.m_isSensor; - } - b2Fixture.prototype.SetFilterData = function (filter) { - this.m_filter = filter.Copy(); - if (this.m_body) return; - var edge = this.m_body.GetContactList(); - while (edge) { - var contact = edge.contact; - var fixtureA = contact.GetFixtureA(); - var fixtureB = contact.GetFixtureB(); - if (fixtureA == this || fixtureB == this) contact.FlagForFiltering(); - edge = edge.next; - } - } - b2Fixture.prototype.GetFilterData = function () { - return this.m_filter.Copy(); - } - b2Fixture.prototype.GetBody = function () { - return this.m_body; - } - b2Fixture.prototype.GetNext = function () { - return this.m_next; - } - b2Fixture.prototype.GetUserData = function () { - return this.m_userData; - } - b2Fixture.prototype.SetUserData = function (data) { - this.m_userData = data; - } - b2Fixture.prototype.TestPoint = function (p) { - return this.m_shape.TestPoint(this.m_body.GetTransform(), p); - } - b2Fixture.prototype.RayCast = function (output, input) { - return this.m_shape.RayCast(output, input, this.m_body.GetTransform()); - } - b2Fixture.prototype.GetMassData = function (massData) { - if (massData === undefined) massData = null; - if (massData == null) { - massData = new b2MassData(); - } - this.m_shape.ComputeMass(massData, this.m_density); - return massData; - } - b2Fixture.prototype.SetDensity = function (density) { - if (density === undefined) density = 0; - this.m_density = density; - } - b2Fixture.prototype.GetDensity = function () { - return this.m_density; - } - b2Fixture.prototype.GetFriction = function () { - return this.m_friction; - } - b2Fixture.prototype.SetFriction = function (friction) { - if (friction === undefined) friction = 0; - this.m_friction = friction; - } - b2Fixture.prototype.GetRestitution = function () { - return this.m_restitution; - } - b2Fixture.prototype.SetRestitution = function (restitution) { - if (restitution === undefined) restitution = 0; - this.m_restitution = restitution; - } - b2Fixture.prototype.GetAABB = function () { - return this.m_aabb; - } - b2Fixture.prototype.b2Fixture = function () { - this.m_aabb = new b2AABB(); - this.m_userData = null; - this.m_body = null; - this.m_next = null; - this.m_shape = null; - this.m_density = 0.0; - this.m_friction = 0.0; - this.m_restitution = 0.0; - } - b2Fixture.prototype.Create = function (body, xf, def) { - this.m_userData = def.userData; - this.m_friction = def.friction; - this.m_restitution = def.restitution; - this.m_body = body; - this.m_next = null; - this.m_filter = def.filter.Copy(); - this.m_isSensor = def.isSensor; - this.m_shape = def.shape.Copy(); - this.m_density = def.density; - } - b2Fixture.prototype.Destroy = function () { - this.m_shape = null; - } - b2Fixture.prototype.CreateProxy = function (broadPhase, xf) { - this.m_shape.ComputeAABB(this.m_aabb, xf); - this.m_proxy = broadPhase.CreateProxy(this.m_aabb, this); - } - b2Fixture.prototype.DestroyProxy = function (broadPhase) { - if (this.m_proxy == null) { - return; - } - broadPhase.DestroyProxy(this.m_proxy); - this.m_proxy = null; - } - b2Fixture.prototype.Synchronize = function (broadPhase, transform1, transform2) { - if (!this.m_proxy) return; - var aabb1 = new b2AABB(); - var aabb2 = new b2AABB(); - this.m_shape.ComputeAABB(aabb1, transform1); - this.m_shape.ComputeAABB(aabb2, transform2); - this.m_aabb.Combine(aabb1, aabb2); - var displacement = b2Math.SubtractVV(transform2.position, transform1.position); - broadPhase.MoveProxy(this.m_proxy, this.m_aabb, displacement); - } - b2FixtureDef.b2FixtureDef = function () { - this.filter = new b2FilterData(); - }; - b2FixtureDef.prototype.b2FixtureDef = function () { - this.shape = null; - this.userData = null; - this.friction = 0.2; - this.restitution = 0.0; - this.density = 0.0; - this.filter.categoryBits = 0x0001; - this.filter.maskBits = 0xFFFF; - this.filter.groupIndex = 0; - this.isSensor = false; - } - b2Island.b2Island = function () {}; - b2Island.prototype.b2Island = function () { - this.m_bodies = new Vector(); - this.m_contacts = new Vector(); - this.m_joints = new Vector(); - } - b2Island.prototype.Initialize = function (bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) { - if (bodyCapacity === undefined) bodyCapacity = 0; - if (contactCapacity === undefined) contactCapacity = 0; - if (jointCapacity === undefined) jointCapacity = 0; - var i = 0; - this.m_bodyCapacity = bodyCapacity; - this.m_contactCapacity = contactCapacity; - this.m_jointCapacity = jointCapacity; - this.m_bodyCount = 0; - this.m_contactCount = 0; - this.m_jointCount = 0; - this.m_allocator = allocator; - this.m_listener = listener; - this.m_contactSolver = contactSolver; - for (i = this.m_bodies.length; - i < bodyCapacity; i++) - this.m_bodies[i] = null; - for (i = this.m_contacts.length; - i < contactCapacity; i++) - this.m_contacts[i] = null; - for (i = this.m_joints.length; - i < jointCapacity; i++) - this.m_joints[i] = null; - } - b2Island.prototype.Clear = function () { - this.m_bodyCount = 0; - this.m_contactCount = 0; - this.m_jointCount = 0; - } - b2Island.prototype.Solve = function (step, gravity, allowSleep) { - var i = 0; - var j = 0; - var b; - var joint; - for (i = 0; - i < this.m_bodyCount; ++i) { - b = this.m_bodies[i]; - if (b.GetType() != b2Body.b2_dynamicBody) continue; - b.m_linearVelocity.x += step.dt * (gravity.x + b.m_invMass * b.m_force.x); - b.m_linearVelocity.y += step.dt * (gravity.y + b.m_invMass * b.m_force.y); - b.m_angularVelocity += step.dt * b.m_invI * b.m_torque; - b.m_linearVelocity.Multiply(b2Math.Clamp(1.0 - step.dt * b.m_linearDamping, 0.0, 1.0)); - b.m_angularVelocity *= b2Math.Clamp(1.0 - step.dt * b.m_angularDamping, 0.0, 1.0); - } - this.m_contactSolver.Initialize(step, this.m_contacts, this.m_contactCount, this.m_allocator); - var contactSolver = this.m_contactSolver; - contactSolver.InitVelocityConstraints(step); - for (i = 0; - i < this.m_jointCount; ++i) { - joint = this.m_joints[i]; - joint.InitVelocityConstraints(step); - } - for (i = 0; - i < step.velocityIterations; ++i) { - for (j = 0; - j < this.m_jointCount; ++j) { - joint = this.m_joints[j]; - joint.SolveVelocityConstraints(step); - } - contactSolver.SolveVelocityConstraints(); - } - for (i = 0; - i < this.m_jointCount; ++i) { - joint = this.m_joints[i]; - joint.FinalizeVelocityConstraints(); - } - contactSolver.FinalizeVelocityConstraints(); - for (i = 0; - i < this.m_bodyCount; ++i) { - b = this.m_bodies[i]; - if (b.GetType() == b2Body.b2_staticBody) continue; - var translationX = step.dt * b.m_linearVelocity.x; - var translationY = step.dt * b.m_linearVelocity.y; - if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) { - b.m_linearVelocity.Normalize(); - b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * step.inv_dt; - b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * step.inv_dt; - } - var rotation = step.dt * b.m_angularVelocity; - if (rotation * rotation > b2Settings.b2_maxRotationSquared) { - if (b.m_angularVelocity < 0.0) { - b.m_angularVelocity = (-b2Settings.b2_maxRotation * step.inv_dt); - } - else { - b.m_angularVelocity = b2Settings.b2_maxRotation * step.inv_dt; - } - } - b.m_sweep.c0.SetV(b.m_sweep.c); - b.m_sweep.a0 = b.m_sweep.a; - b.m_sweep.c.x += step.dt * b.m_linearVelocity.x; - b.m_sweep.c.y += step.dt * b.m_linearVelocity.y; - b.m_sweep.a += step.dt * b.m_angularVelocity; - b.SynchronizeTransform(); - } - for (i = 0; - i < step.positionIterations; ++i) { - var contactsOkay = contactSolver.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); - var jointsOkay = true; - for (j = 0; - j < this.m_jointCount; ++j) { - joint = this.m_joints[j]; - var jointOkay = joint.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); - jointsOkay = jointsOkay && jointOkay; - } - if (contactsOkay && jointsOkay) { - break; - } - } - this.Report(contactSolver.m_constraints); - if (allowSleep) { - var minSleepTime = Number.MAX_VALUE; - var linTolSqr = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance; - var angTolSqr = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance; - for (i = 0; - i < this.m_bodyCount; ++i) { - b = this.m_bodies[i]; - if (b.GetType() == b2Body.b2_staticBody) { - continue; - } - if ((b.m_flags & b2Body.e_allowSleepFlag) == 0) { - b.m_sleepTime = 0.0; - minSleepTime = 0.0; - } - if ((b.m_flags & b2Body.e_allowSleepFlag) == 0 || b.m_angularVelocity * b.m_angularVelocity > angTolSqr || b2Math.Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr) { - b.m_sleepTime = 0.0; - minSleepTime = 0.0; - } - else { - b.m_sleepTime += step.dt; - minSleepTime = b2Math.Min(minSleepTime, b.m_sleepTime); - } - } - if (minSleepTime >= b2Settings.b2_timeToSleep) { - for (i = 0; - i < this.m_bodyCount; ++i) { - b = this.m_bodies[i]; - b.SetAwake(false); - } - } - } - } - b2Island.prototype.SolveTOI = function (subStep) { - var i = 0; - var j = 0; - this.m_contactSolver.Initialize(subStep, this.m_contacts, this.m_contactCount, this.m_allocator); - var contactSolver = this.m_contactSolver; - for (i = 0; - i < this.m_jointCount; ++i) { - this.m_joints[i].InitVelocityConstraints(subStep); - } - for (i = 0; - i < subStep.velocityIterations; ++i) { - contactSolver.SolveVelocityConstraints(); - for (j = 0; - j < this.m_jointCount; ++j) { - this.m_joints[j].SolveVelocityConstraints(subStep); - } - } - for (i = 0; - i < this.m_bodyCount; ++i) { - var b = this.m_bodies[i]; - if (b.GetType() == b2Body.b2_staticBody) continue; - var translationX = subStep.dt * b.m_linearVelocity.x; - var translationY = subStep.dt * b.m_linearVelocity.y; - if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) { - b.m_linearVelocity.Normalize(); - b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * subStep.inv_dt; - b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * subStep.inv_dt; - } - var rotation = subStep.dt * b.m_angularVelocity; - if (rotation * rotation > b2Settings.b2_maxRotationSquared) { - if (b.m_angularVelocity < 0.0) { - b.m_angularVelocity = (-b2Settings.b2_maxRotation * subStep.inv_dt); - } - else { - b.m_angularVelocity = b2Settings.b2_maxRotation * subStep.inv_dt; - } - } - b.m_sweep.c0.SetV(b.m_sweep.c); - b.m_sweep.a0 = b.m_sweep.a; - b.m_sweep.c.x += subStep.dt * b.m_linearVelocity.x; - b.m_sweep.c.y += subStep.dt * b.m_linearVelocity.y; - b.m_sweep.a += subStep.dt * b.m_angularVelocity; - b.SynchronizeTransform(); - } - var k_toiBaumgarte = 0.75; - for (i = 0; - i < subStep.positionIterations; ++i) { - var contactsOkay = contactSolver.SolvePositionConstraints(k_toiBaumgarte); - var jointsOkay = true; - for (j = 0; - j < this.m_jointCount; ++j) { - var jointOkay = this.m_joints[j].SolvePositionConstraints(b2Settings.b2_contactBaumgarte); - jointsOkay = jointsOkay && jointOkay; - } - if (contactsOkay && jointsOkay) { - break; - } - } - this.Report(contactSolver.m_constraints); - } - b2Island.prototype.Report = function (constraints) { - if (this.m_listener == null) { - return; - } - for (var i = 0; i < this.m_contactCount; ++i) { - var c = this.m_contacts[i]; - var cc = constraints[i]; - for (var j = 0; j < cc.pointCount; ++j) { - b2Island.s_impulse.normalImpulses[j] = cc.points[j].normalImpulse; - b2Island.s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse; - } - this.m_listener.PostSolve(c, b2Island.s_impulse); - } - } - b2Island.prototype.AddBody = function (body) { - body.m_islandIndex = this.m_bodyCount; - this.m_bodies[this.m_bodyCount++] = body; - } - b2Island.prototype.AddContact = function (contact) { - this.m_contacts[this.m_contactCount++] = contact; - } - b2Island.prototype.AddJoint = function (joint) { - this.m_joints[this.m_jointCount++] = joint; - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.b2Island.s_impulse = new b2ContactImpulse(); - Box2D.Dynamics.b2Island.prototype.s_impulse = Box2D.Dynamics.b2Island.s_impulse; - }); - b2TimeStep.b2TimeStep = function () {}; - b2TimeStep.prototype.Set = function (step) { - this.dt = step.dt; - this.inv_dt = step.inv_dt; - this.positionIterations = step.positionIterations; - this.velocityIterations = step.velocityIterations; - this.warmStarting = step.warmStarting; - } - b2World.b2World = function () { - this.s_stack = new Vector(); - this.m_contactManager = new b2ContactManager(); - this.m_contactSolver = new b2ContactSolver(); - this.m_island = new b2Island(); - }; - b2World.prototype.b2World = function (gravity, doSleep) { - this.m_destructionListener = null; - this.m_debugDraw = null; - this.m_bodyList = null; - this.m_contactList = null; - this.m_jointList = null; - this.m_controllerList = null; - this.m_bodyCount = 0; - this.m_contactCount = 0; - this.m_jointCount = 0; - this.m_controllerCount = 0; - b2World.m_warmStarting = true; - b2World.m_continuousPhysics = true; - this.m_allowSleep = doSleep; - this.m_gravity = gravity; - this.m_inv_dt0 = 0.0; - this.m_contactManager.m_world = this; - var bd = new b2BodyDef(); - this.m_groundBody = this.CreateBody(bd); - } - b2World.prototype.SetDestructionListener = function (listener) { - this.m_destructionListener = listener; - } - b2World.prototype.SetContactFilter = function (filter) { - this.m_contactManager.m_contactFilter = filter; - } - b2World.prototype.SetContactListener = function (listener) { - this.m_contactManager.m_contactListener = listener; - } - b2World.prototype.SetDebugDraw = function (debugDraw) { - this.m_debugDraw = debugDraw; - } - b2World.prototype.SetBroadPhase = function (broadPhase) { - var oldBroadPhase = this.m_contactManager.m_broadPhase; - this.m_contactManager.m_broadPhase = broadPhase; - for (var b = this.m_bodyList; b; b = b.m_next) { - for (var f = b.m_fixtureList; f; f = f.m_next) { - f.m_proxy = broadPhase.CreateProxy(oldBroadPhase.GetFatAABB(f.m_proxy), f); - } - } - } - b2World.prototype.Validate = function () { - this.m_contactManager.m_broadPhase.Validate(); - } - b2World.prototype.GetProxyCount = function () { - return this.m_contactManager.m_broadPhase.GetProxyCount(); - } - b2World.prototype.CreateBody = function (def) { - if (this.IsLocked() == true) { - return null; - } - var b = new b2Body(def, this); - b.m_prev = null; - b.m_next = this.m_bodyList; - if (this.m_bodyList) { - this.m_bodyList.m_prev = b; - } - this.m_bodyList = b; - ++this.m_bodyCount; - return b; - } - b2World.prototype.DestroyBody = function (b) { - if (this.IsLocked() == true) { - return; - } - var jn = b.m_jointList; - while (jn) { - var jn0 = jn; - jn = jn.next; - if (this.m_destructionListener) { - this.m_destructionListener.SayGoodbyeJoint(jn0.joint); - } - this.DestroyJoint(jn0.joint); - } - var coe = b.m_controllerList; - while (coe) { - var coe0 = coe; - coe = coe.nextController; - coe0.controller.RemoveBody(b); - } - var ce = b.m_contactList; - while (ce) { - var ce0 = ce; - ce = ce.next; - this.m_contactManager.Destroy(ce0.contact); - } - b.m_contactList = null; - var f = b.m_fixtureList; - while (f) { - var f0 = f; - f = f.m_next; - if (this.m_destructionListener) { - this.m_destructionListener.SayGoodbyeFixture(f0); - } - f0.DestroyProxy(this.m_contactManager.m_broadPhase); - f0.Destroy(); - } - b.m_fixtureList = null; - b.m_fixtureCount = 0; - if (b.m_prev) { - b.m_prev.m_next = b.m_next; - } - if (b.m_next) { - b.m_next.m_prev = b.m_prev; - } - if (b == this.m_bodyList) { - this.m_bodyList = b.m_next; - }--this.m_bodyCount; - } - b2World.prototype.CreateJoint = function (def) { - var j = b2Joint.Create(def, null); - j.m_prev = null; - j.m_next = this.m_jointList; - if (this.m_jointList) { - this.m_jointList.m_prev = j; - } - this.m_jointList = j; - ++this.m_jointCount; - j.m_edgeA.joint = j; - j.m_edgeA.other = j.m_bodyB; - j.m_edgeA.prev = null; - j.m_edgeA.next = j.m_bodyA.m_jointList; - if (j.m_bodyA.m_jointList) j.m_bodyA.m_jointList.prev = j.m_edgeA; - j.m_bodyA.m_jointList = j.m_edgeA; - j.m_edgeB.joint = j; - j.m_edgeB.other = j.m_bodyA; - j.m_edgeB.prev = null; - j.m_edgeB.next = j.m_bodyB.m_jointList; - if (j.m_bodyB.m_jointList) j.m_bodyB.m_jointList.prev = j.m_edgeB; - j.m_bodyB.m_jointList = j.m_edgeB; - var bodyA = def.bodyA; - var bodyB = def.bodyB; - if (def.collideConnected == false) { - var edge = bodyB.GetContactList(); - while (edge) { - if (edge.other == bodyA) { - edge.contact.FlagForFiltering(); - } - edge = edge.next; - } - } - return j; - } - b2World.prototype.DestroyJoint = function (j) { - var collideConnected = j.m_collideConnected; - if (j.m_prev) { - j.m_prev.m_next = j.m_next; - } - if (j.m_next) { - j.m_next.m_prev = j.m_prev; - } - if (j == this.m_jointList) { - this.m_jointList = j.m_next; - } - var bodyA = j.m_bodyA; - var bodyB = j.m_bodyB; - bodyA.SetAwake(true); - bodyB.SetAwake(true); - if (j.m_edgeA.prev) { - j.m_edgeA.prev.next = j.m_edgeA.next; - } - if (j.m_edgeA.next) { - j.m_edgeA.next.prev = j.m_edgeA.prev; - } - if (j.m_edgeA == bodyA.m_jointList) { - bodyA.m_jointList = j.m_edgeA.next; - } - j.m_edgeA.prev = null; - j.m_edgeA.next = null; - if (j.m_edgeB.prev) { - j.m_edgeB.prev.next = j.m_edgeB.next; - } - if (j.m_edgeB.next) { - j.m_edgeB.next.prev = j.m_edgeB.prev; - } - if (j.m_edgeB == bodyB.m_jointList) { - bodyB.m_jointList = j.m_edgeB.next; - } - j.m_edgeB.prev = null; - j.m_edgeB.next = null; - b2Joint.Destroy(j, null); - --this.m_jointCount; - if (collideConnected == false) { - var edge = bodyB.GetContactList(); - while (edge) { - if (edge.other == bodyA) { - edge.contact.FlagForFiltering(); - } - edge = edge.next; - } - } - } - b2World.prototype.AddController = function (c) { - c.m_next = this.m_controllerList; - c.m_prev = null; - this.m_controllerList = c; - c.m_world = this; - this.m_controllerCount++; - return c; - } - b2World.prototype.RemoveController = function (c) { - if (c.m_prev) c.m_prev.m_next = c.m_next; - if (c.m_next) c.m_next.m_prev = c.m_prev; - if (this.m_controllerList == c) this.m_controllerList = c.m_next; - this.m_controllerCount--; - } - b2World.prototype.CreateController = function (controller) { - if (controller.m_world != this) throw new Error("Controller can only be a member of one world"); - controller.m_next = this.m_controllerList; - controller.m_prev = null; - if (this.m_controllerList) this.m_controllerList.m_prev = controller; - this.m_controllerList = controller; - ++this.m_controllerCount; - controller.m_world = this; - return controller; - } - b2World.prototype.DestroyController = function (controller) { - controller.Clear(); - if (controller.m_next) controller.m_next.m_prev = controller.m_prev; - if (controller.m_prev) controller.m_prev.m_next = controller.m_next; - if (controller == this.m_controllerList) this.m_controllerList = controller.m_next; - --this.m_controllerCount; - } - b2World.prototype.SetWarmStarting = function (flag) { - b2World.m_warmStarting = flag; - } - b2World.prototype.SetContinuousPhysics = function (flag) { - b2World.m_continuousPhysics = flag; - } - b2World.prototype.GetBodyCount = function () { - return this.m_bodyCount; - } - b2World.prototype.GetJointCount = function () { - return this.m_jointCount; - } - b2World.prototype.GetContactCount = function () { - return this.m_contactCount; - } - b2World.prototype.SetGravity = function (gravity) { - this.m_gravity = gravity; - } - b2World.prototype.GetGravity = function () { - return this.m_gravity; - } - b2World.prototype.GetGroundBody = function () { - return this.m_groundBody; - } - b2World.prototype.Step = function (dt, velocityIterations, positionIterations) { - if (dt === undefined) dt = 0; - if (velocityIterations === undefined) velocityIterations = 0; - if (positionIterations === undefined) positionIterations = 0; - if (this.m_flags & b2World.e_newFixture) { - this.m_contactManager.FindNewContacts(); - this.m_flags &= ~b2World.e_newFixture; - } - this.m_flags |= b2World.e_locked; - var step = b2World.s_timestep2; - step.dt = dt; - step.velocityIterations = velocityIterations; - step.positionIterations = positionIterations; - if (dt > 0.0) { - step.inv_dt = 1.0 / dt; - } - else { - step.inv_dt = 0.0; - } - step.dtRatio = this.m_inv_dt0 * dt; - step.warmStarting = b2World.m_warmStarting; - this.m_contactManager.Collide(); - if (step.dt > 0.0) { - this.Solve(step); - } - if (b2World.m_continuousPhysics && step.dt > 0.0) { - this.SolveTOI(step); - } - if (step.dt > 0.0) { - this.m_inv_dt0 = step.inv_dt; - } - this.m_flags &= ~b2World.e_locked; - } - b2World.prototype.ClearForces = function () { - for (var body = this.m_bodyList; body; body = body.m_next) { - body.m_force.SetZero(); - body.m_torque = 0.0; - } - } - b2World.prototype.DrawDebugData = function () { - if (this.m_debugDraw == null) { - return; - } - this.m_debugDraw.m_sprite.graphics.clear(); - var flags = this.m_debugDraw.GetFlags(); - var i = 0; - var b; - var f; - var s; - var j; - var bp; - var invQ = new b2Vec2; - var x1 = new b2Vec2; - var x2 = new b2Vec2; - var xf; - var b1 = new b2AABB(); - var b2 = new b2AABB(); - var vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()]; - var color = new b2Color(0, 0, 0); - if (flags & b2DebugDraw.e_shapeBit) { - for (b = this.m_bodyList; - b; b = b.m_next) { - xf = b.m_xf; - for (f = b.GetFixtureList(); - f; f = f.m_next) { - s = f.GetShape(); - if (b.IsActive() == false) { - color.Set(0.5, 0.5, 0.3); - this.DrawShape(s, xf, color); - } - else if (b.GetType() == b2Body.b2_staticBody) { - color.Set(0.5, 0.9, 0.5); - this.DrawShape(s, xf, color); - } - else if (b.GetType() == b2Body.b2_kinematicBody) { - color.Set(0.5, 0.5, 0.9); - this.DrawShape(s, xf, color); - } - else if (b.IsAwake() == false) { - color.Set(0.6, 0.6, 0.6); - this.DrawShape(s, xf, color); - } - else { - color.Set(0.9, 0.7, 0.7); - this.DrawShape(s, xf, color); - } - } - } - } - if (flags & b2DebugDraw.e_jointBit) { - for (j = this.m_jointList; - j; j = j.m_next) { - this.DrawJoint(j); - } - } - if (flags & b2DebugDraw.e_controllerBit) { - for (var c = this.m_controllerList; c; c = c.m_next) { - c.Draw(this.m_debugDraw); - } - } - if (flags & b2DebugDraw.e_pairBit) { - color.Set(0.3, 0.9, 0.9); - for (var contact = this.m_contactManager.m_contactList; contact; contact = contact.GetNext()) { - var fixtureA = contact.GetFixtureA(); - var fixtureB = contact.GetFixtureB(); - var cA = fixtureA.GetAABB().GetCenter(); - var cB = fixtureB.GetAABB().GetCenter(); - this.m_debugDraw.DrawSegment(cA, cB, color); - } - } - if (flags & b2DebugDraw.e_aabbBit) { - bp = this.m_contactManager.m_broadPhase; - vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()]; - for (b = this.m_bodyList; - b; b = b.GetNext()) { - if (b.IsActive() == false) { - continue; - } - for (f = b.GetFixtureList(); - f; f = f.GetNext()) { - var aabb = bp.GetFatAABB(f.m_proxy); - vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y); - vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y); - vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); - vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); - this.m_debugDraw.DrawPolygon(vs, 4, color); - } - } - } - if (flags & b2DebugDraw.e_centerOfMassBit) { - for (b = this.m_bodyList; - b; b = b.m_next) { - xf = b2World.s_xf; - xf.R = b.m_xf.R; - xf.position = b.GetWorldCenter(); - this.m_debugDraw.DrawTransform(xf); - } - } - } - b2World.prototype.QueryAABB = function (callback, aabb) { - var __this = this; - var broadPhase = __this.m_contactManager.m_broadPhase; - - function WorldQueryWrapper(proxy) { - return callback(broadPhase.GetUserData(proxy)); - }; - broadPhase.Query(WorldQueryWrapper, aabb); - } - b2World.prototype.QueryShape = function (callback, shape, transform) { - var __this = this; - if (transform === undefined) transform = null; - if (transform == null) { - transform = new b2Transform(); - transform.SetIdentity(); - } - var broadPhase = __this.m_contactManager.m_broadPhase; - - function WorldQueryWrapper(proxy) { - var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null); - if (b2Shape.TestOverlap(shape, transform, fixture.GetShape(), fixture.GetBody().GetTransform())) return callback(fixture); - return true; - }; - var aabb = new b2AABB(); - shape.ComputeAABB(aabb, transform); - broadPhase.Query(WorldQueryWrapper, aabb); - } - b2World.prototype.QueryPoint = function (callback, p) { - var __this = this; - var broadPhase = __this.m_contactManager.m_broadPhase; - - function WorldQueryWrapper(proxy) { - var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null); - if (fixture.TestPoint(p)) return callback(fixture); - return true; - }; - var aabb = new b2AABB(); - aabb.lowerBound.Set(p.x - b2Settings.b2_linearSlop, p.y - b2Settings.b2_linearSlop); - aabb.upperBound.Set(p.x + b2Settings.b2_linearSlop, p.y + b2Settings.b2_linearSlop); - broadPhase.Query(WorldQueryWrapper, aabb); - } - b2World.prototype.RayCast = function (callback, point1, point2) { - var __this = this; - var broadPhase = __this.m_contactManager.m_broadPhase; - var output = new b2RayCastOutput; - - function RayCastWrapper(input, proxy) { - var userData = broadPhase.GetUserData(proxy); - var fixture = (userData instanceof b2Fixture ? userData : null); - var hit = fixture.RayCast(output, input); - if (hit) { - var fraction = output.fraction; - var point = new b2Vec2((1.0 - fraction) * point1.x + fraction * point2.x, (1.0 - fraction) * point1.y + fraction * point2.y); - return callback(fixture, point, output.normal, fraction); - } - return input.maxFraction; - }; - var input = new b2RayCastInput(point1, point2); - broadPhase.RayCast(RayCastWrapper, input); - } - b2World.prototype.RayCastOne = function (point1, point2) { - var __this = this; - var result; - - function RayCastOneWrapper(fixture, point, normal, fraction) { - if (fraction === undefined) fraction = 0; - result = fixture; - return fraction; - }; - __this.RayCast(RayCastOneWrapper, point1, point2); - return result; - } - b2World.prototype.RayCastAll = function (point1, point2) { - var __this = this; - var result = new Vector(); - - function RayCastAllWrapper(fixture, point, normal, fraction) { - if (fraction === undefined) fraction = 0; - result[result.length] = fixture; - return 1; - }; - __this.RayCast(RayCastAllWrapper, point1, point2); - return result; - } - b2World.prototype.GetBodyList = function () { - return this.m_bodyList; - } - b2World.prototype.GetJointList = function () { - return this.m_jointList; - } - b2World.prototype.GetContactList = function () { - return this.m_contactList; - } - b2World.prototype.IsLocked = function () { - return (this.m_flags & b2World.e_locked) > 0; - } - b2World.prototype.Solve = function (step) { - var b; - for (var controller = this.m_controllerList; controller; controller = controller.m_next) { - controller.Step(step); - } - var island = this.m_island; - island.Initialize(this.m_bodyCount, this.m_contactCount, this.m_jointCount, null, this.m_contactManager.m_contactListener, this.m_contactSolver); - for (b = this.m_bodyList; - b; b = b.m_next) { - b.m_flags &= ~b2Body.e_islandFlag; - } - for (var c = this.m_contactList; c; c = c.m_next) { - c.m_flags &= ~b2Contact.e_islandFlag; - } - for (var j = this.m_jointList; j; j = j.m_next) { - j.m_islandFlag = false; - } - var stackSize = parseInt(this.m_bodyCount); - var stack = this.s_stack; - for (var seed = this.m_bodyList; seed; seed = seed.m_next) { - if (seed.m_flags & b2Body.e_islandFlag) { - continue; - } - if (seed.IsAwake() == false || seed.IsActive() == false) { - continue; - } - if (seed.GetType() == b2Body.b2_staticBody) { - continue; - } - island.Clear(); - var stackCount = 0; - stack[stackCount++] = seed; - seed.m_flags |= b2Body.e_islandFlag; - while (stackCount > 0) { - b = stack[--stackCount]; - island.AddBody(b); - if (b.IsAwake() == false) { - b.SetAwake(true); - } - if (b.GetType() == b2Body.b2_staticBody) { - continue; - } - var other; - for (var ce = b.m_contactList; ce; ce = ce.next) { - if (ce.contact.m_flags & b2Contact.e_islandFlag) { - continue; - } - if (ce.contact.IsSensor() == true || ce.contact.IsEnabled() == false || ce.contact.IsTouching() == false) { - continue; - } - island.AddContact(ce.contact); - ce.contact.m_flags |= b2Contact.e_islandFlag; - other = ce.other; - if (other.m_flags & b2Body.e_islandFlag) { - continue; - } - stack[stackCount++] = other; - other.m_flags |= b2Body.e_islandFlag; - } - for (var jn = b.m_jointList; jn; jn = jn.next) { - if (jn.joint.m_islandFlag == true) { - continue; - } - other = jn.other; - if (other.IsActive() == false) { - continue; - } - island.AddJoint(jn.joint); - jn.joint.m_islandFlag = true; - if (other.m_flags & b2Body.e_islandFlag) { - continue; - } - stack[stackCount++] = other; - other.m_flags |= b2Body.e_islandFlag; - } - } - island.Solve(step, this.m_gravity, this.m_allowSleep); - for (var i = 0; i < island.m_bodyCount; ++i) { - b = island.m_bodies[i]; - if (b.GetType() == b2Body.b2_staticBody) { - b.m_flags &= ~b2Body.e_islandFlag; - } - } - } - for (i = 0; - i < stack.length; ++i) { - if (!stack[i]) break; - stack[i] = null; - } - for (b = this.m_bodyList; - b; b = b.m_next) { - if (b.IsAwake() == false || b.IsActive() == false) { - continue; - } - if (b.GetType() == b2Body.b2_staticBody) { - continue; - } - b.SynchronizeFixtures(); - } - this.m_contactManager.FindNewContacts(); - } - b2World.prototype.SolveTOI = function (step) { - var b; - var fA; - var fB; - var bA; - var bB; - var cEdge; - var j; - var island = this.m_island; - island.Initialize(this.m_bodyCount, b2Settings.b2_maxTOIContactsPerIsland, b2Settings.b2_maxTOIJointsPerIsland, null, this.m_contactManager.m_contactListener, this.m_contactSolver); - var queue = b2World.s_queue; - for (b = this.m_bodyList; - b; b = b.m_next) { - b.m_flags &= ~b2Body.e_islandFlag; - b.m_sweep.t0 = 0.0; - } - var c; - for (c = this.m_contactList; - c; c = c.m_next) { - c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag); - } - for (j = this.m_jointList; - j; j = j.m_next) { - j.m_islandFlag = false; - } - for (;;) { - var minContact = null; - var minTOI = 1.0; - for (c = this.m_contactList; - c; c = c.m_next) { - if (c.IsSensor() == true || c.IsEnabled() == false || c.IsContinuous() == false) { - continue; - } - var toi = 1.0; - if (c.m_flags & b2Contact.e_toiFlag) { - toi = c.m_toi; - } - else { - fA = c.m_fixtureA; - fB = c.m_fixtureB; - bA = fA.m_body; - bB = fB.m_body; - if ((bA.GetType() != b2Body.b2_dynamicBody || bA.IsAwake() == false) && (bB.GetType() != b2Body.b2_dynamicBody || bB.IsAwake() == false)) { - continue; - } - var t0 = bA.m_sweep.t0; - if (bA.m_sweep.t0 < bB.m_sweep.t0) { - t0 = bB.m_sweep.t0; - bA.m_sweep.Advance(t0); - } - else if (bB.m_sweep.t0 < bA.m_sweep.t0) { - t0 = bA.m_sweep.t0; - bB.m_sweep.Advance(t0); - } - toi = c.ComputeTOI(bA.m_sweep, bB.m_sweep); - b2Settings.b2Assert(0.0 <= toi && toi <= 1.0); - if (toi > 0.0 && toi < 1.0) { - toi = (1.0 - toi) * t0 + toi; - if (toi > 1) toi = 1; - } - c.m_toi = toi; - c.m_flags |= b2Contact.e_toiFlag; - } - if (Number.MIN_VALUE < toi && toi < minTOI) { - minContact = c; - minTOI = toi; - } - } - if (minContact == null || 1.0 - 100.0 * Number.MIN_VALUE < minTOI) { - break; - } - fA = minContact.m_fixtureA; - fB = minContact.m_fixtureB; - bA = fA.m_body; - bB = fB.m_body; - b2World.s_backupA.Set(bA.m_sweep); - b2World.s_backupB.Set(bB.m_sweep); - bA.Advance(minTOI); - bB.Advance(minTOI); - minContact.Update(this.m_contactManager.m_contactListener); - minContact.m_flags &= ~b2Contact.e_toiFlag; - if (minContact.IsSensor() == true || minContact.IsEnabled() == false) { - bA.m_sweep.Set(b2World.s_backupA); - bB.m_sweep.Set(b2World.s_backupB); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - continue; - } - if (minContact.IsTouching() == false) { - continue; - } - var seed = bA; - if (seed.GetType() != b2Body.b2_dynamicBody) { - seed = bB; - } - island.Clear(); - var queueStart = 0; - var queueSize = 0; - queue[queueStart + queueSize++] = seed; - seed.m_flags |= b2Body.e_islandFlag; - while (queueSize > 0) { - b = queue[queueStart++]; - --queueSize; - island.AddBody(b); - if (b.IsAwake() == false) { - b.SetAwake(true); - } - if (b.GetType() != b2Body.b2_dynamicBody) { - continue; - } - for (cEdge = b.m_contactList; - cEdge; cEdge = cEdge.next) { - if (island.m_contactCount == island.m_contactCapacity) { - break; - } - if (cEdge.contact.m_flags & b2Contact.e_islandFlag) { - continue; - } - if (cEdge.contact.IsSensor() == true || cEdge.contact.IsEnabled() == false || cEdge.contact.IsTouching() == false) { - continue; - } - island.AddContact(cEdge.contact); - cEdge.contact.m_flags |= b2Contact.e_islandFlag; - var other = cEdge.other; - if (other.m_flags & b2Body.e_islandFlag) { - continue; - } - if (other.GetType() != b2Body.b2_staticBody) { - other.Advance(minTOI); - other.SetAwake(true); - } - queue[queueStart + queueSize] = other; - ++queueSize; - other.m_flags |= b2Body.e_islandFlag; - } - for (var jEdge = b.m_jointList; jEdge; jEdge = jEdge.next) { - if (island.m_jointCount == island.m_jointCapacity) continue; - if (jEdge.joint.m_islandFlag == true) continue; - other = jEdge.other; - if (other.IsActive() == false) { - continue; - } - island.AddJoint(jEdge.joint); - jEdge.joint.m_islandFlag = true; - if (other.m_flags & b2Body.e_islandFlag) continue; - if (other.GetType() != b2Body.b2_staticBody) { - other.Advance(minTOI); - other.SetAwake(true); - } - queue[queueStart + queueSize] = other; - ++queueSize; - other.m_flags |= b2Body.e_islandFlag; - } - } - var subStep = b2World.s_timestep; - subStep.warmStarting = false; - subStep.dt = (1.0 - minTOI) * step.dt; - subStep.inv_dt = 1.0 / subStep.dt; - subStep.dtRatio = 0.0; - subStep.velocityIterations = step.velocityIterations; - subStep.positionIterations = step.positionIterations; - island.SolveTOI(subStep); - var i = 0; - for (i = 0; - i < island.m_bodyCount; ++i) { - b = island.m_bodies[i]; - b.m_flags &= ~b2Body.e_islandFlag; - if (b.IsAwake() == false) { - continue; - } - if (b.GetType() != b2Body.b2_dynamicBody) { - continue; - } - b.SynchronizeFixtures(); - for (cEdge = b.m_contactList; - cEdge; cEdge = cEdge.next) { - cEdge.contact.m_flags &= ~b2Contact.e_toiFlag; - } - } - for (i = 0; - i < island.m_contactCount; ++i) { - c = island.m_contacts[i]; - c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag); - } - for (i = 0; - i < island.m_jointCount; ++i) { - j = island.m_joints[i]; - j.m_islandFlag = false; - } - this.m_contactManager.FindNewContacts(); - } - } - b2World.prototype.DrawJoint = function (joint) { - var b1 = joint.GetBodyA(); - var b2 = joint.GetBodyB(); - var xf1 = b1.m_xf; - var xf2 = b2.m_xf; - var x1 = xf1.position; - var x2 = xf2.position; - var p1 = joint.GetAnchorA(); - var p2 = joint.GetAnchorB(); - var color = b2World.s_jointColor; - switch (joint.m_type) { - case b2Joint.e_distanceJoint: - this.m_debugDraw.DrawSegment(p1, p2, color); - break; - case b2Joint.e_pulleyJoint: - { - var pulley = ((joint instanceof b2PulleyJoint ? joint : null)); - var s1 = pulley.GetGroundAnchorA(); - var s2 = pulley.GetGroundAnchorB(); - this.m_debugDraw.DrawSegment(s1, p1, color); - this.m_debugDraw.DrawSegment(s2, p2, color); - this.m_debugDraw.DrawSegment(s1, s2, color); - } - break; - case b2Joint.e_mouseJoint: - this.m_debugDraw.DrawSegment(p1, p2, color); - break; - default: - if (b1 != this.m_groundBody) this.m_debugDraw.DrawSegment(x1, p1, color); - this.m_debugDraw.DrawSegment(p1, p2, color); - if (b2 != this.m_groundBody) this.m_debugDraw.DrawSegment(x2, p2, color); - } - } - b2World.prototype.DrawShape = function (shape, xf, color) { - switch (shape.m_type) { - case b2Shape.e_circleShape: - { - var circle = ((shape instanceof b2CircleShape ? shape : null)); - var center = b2Math.MulX(xf, circle.m_p); - var radius = circle.m_radius; - var axis = xf.R.col1; - this.m_debugDraw.DrawSolidCircle(center, radius, axis, color); - } - break; - case b2Shape.e_polygonShape: - { - var i = 0; - var poly = ((shape instanceof b2PolygonShape ? shape : null)); - var vertexCount = parseInt(poly.GetVertexCount()); - var localVertices = poly.GetVertices(); - var vertices = new Vector(vertexCount); - for (i = 0; - i < vertexCount; ++i) { - vertices[i] = b2Math.MulX(xf, localVertices[i]); - } - this.m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color); - } - break; - case b2Shape.e_edgeShape: - { - var edge = (shape instanceof b2EdgeShape ? shape : null); - this.m_debugDraw.DrawSegment(b2Math.MulX(xf, edge.GetVertex1()), b2Math.MulX(xf, edge.GetVertex2()), color); - } - break; - } - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.b2World.s_timestep2 = new b2TimeStep(); - Box2D.Dynamics.b2World.prototype.s_timestep2 = Box2D.Dynamics.b2World.s_timestep2; - Box2D.Dynamics.b2World.s_xf = new b2Transform(); - Box2D.Dynamics.b2World.prototype.s_xf = Box2D.Dynamics.b2World.s_xf; - Box2D.Dynamics.b2World.s_backupA = new b2Sweep(); - Box2D.Dynamics.b2World.prototype.s_backupA = Box2D.Dynamics.b2World.s_backupA; - Box2D.Dynamics.b2World.s_backupB = new b2Sweep(); - Box2D.Dynamics.b2World.prototype.s_backupB = Box2D.Dynamics.b2World.s_backupB; - Box2D.Dynamics.b2World.s_timestep = new b2TimeStep(); - Box2D.Dynamics.b2World.prototype.s_timestep = Box2D.Dynamics.b2World.s_timestep; - Box2D.Dynamics.b2World.s_queue = new Vector(); - Box2D.Dynamics.b2World.prototype.s_queue = Box2D.Dynamics.b2World.s_queue; - Box2D.Dynamics.b2World.s_jointColor = new b2Color(0.5, 0.8, 0.8); - Box2D.Dynamics.b2World.prototype.s_jointColor = Box2D.Dynamics.b2World.s_jointColor; - Box2D.Dynamics.b2World.e_newFixture = 0x0001; - Box2D.Dynamics.b2World.prototype.e_newFixture = Box2D.Dynamics.b2World.e_newFixture; - Box2D.Dynamics.b2World.e_locked = 0x0002; - Box2D.Dynamics.b2World.prototype.e_locked = Box2D.Dynamics.b2World.e_locked; - }); -})(); /* source: disabled*/ -(function () { - var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; - var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; - var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; - var b2MassData = Box2D.Collision.Shapes.b2MassData; - var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; - var b2Shape = Box2D.Collision.Shapes.b2Shape; - var b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact; - var b2Contact = Box2D.Dynamics.Contacts.b2Contact; - var b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint; - var b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint; - var b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge; - var b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory; - var b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister; - var b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult; - var b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver; - var b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact; - var b2NullContact = Box2D.Dynamics.Contacts.b2NullContact; - var b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact; - var b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact; - var b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact; - var b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold; - var b2Body = Box2D.Dynamics.b2Body; - var b2BodyDef = Box2D.Dynamics.b2BodyDef; - var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; - var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; - var b2ContactListener = Box2D.Dynamics.b2ContactListener; - var b2ContactManager = Box2D.Dynamics.b2ContactManager; - var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; - var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; - var b2FilterData = Box2D.Dynamics.b2FilterData; - var b2Fixture = Box2D.Dynamics.b2Fixture; - var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; - var b2Island = Box2D.Dynamics.b2Island; - var b2TimeStep = Box2D.Dynamics.b2TimeStep; - var b2World = Box2D.Dynamics.b2World; - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2Mat22 = Box2D.Common.Math.b2Mat22; - var b2Mat33 = Box2D.Common.Math.b2Mat33; - var b2Math = Box2D.Common.Math.b2Math; - var b2Sweep = Box2D.Common.Math.b2Sweep; - var b2Transform = Box2D.Common.Math.b2Transform; - var b2Vec2 = Box2D.Common.Math.b2Vec2; - var b2Vec3 = Box2D.Common.Math.b2Vec3; - var b2AABB = Box2D.Collision.b2AABB; - var b2Bound = Box2D.Collision.b2Bound; - var b2BoundValues = Box2D.Collision.b2BoundValues; - var b2BroadPhase = Box2D.Collision.b2BroadPhase; - var b2Collision = Box2D.Collision.b2Collision; - var b2ContactID = Box2D.Collision.b2ContactID; - var b2ContactPoint = Box2D.Collision.b2ContactPoint; - var b2Distance = Box2D.Collision.b2Distance; - var b2DistanceInput = Box2D.Collision.b2DistanceInput; - var b2DistanceOutput = Box2D.Collision.b2DistanceOutput; - var b2DistanceProxy = Box2D.Collision.b2DistanceProxy; - var b2DynamicTree = Box2D.Collision.b2DynamicTree; - var b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase; - var b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode; - var b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair; - var b2Manifold = Box2D.Collision.b2Manifold; - var b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint; - var b2OBB = Box2D.Collision.b2OBB; - var b2Pair = Box2D.Collision.b2Pair; - var b2PairManager = Box2D.Collision.b2PairManager; - var b2Point = Box2D.Collision.b2Point; - var b2Proxy = Box2D.Collision.b2Proxy; - var b2RayCastInput = Box2D.Collision.b2RayCastInput; - var b2RayCastOutput = Box2D.Collision.b2RayCastOutput; - var b2Segment = Box2D.Collision.b2Segment; - var b2SeparationFunction = Box2D.Collision.b2SeparationFunction; - var b2Simplex = Box2D.Collision.b2Simplex; - var b2SimplexCache = Box2D.Collision.b2SimplexCache; - var b2SimplexVertex = Box2D.Collision.b2SimplexVertex; - var b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact; - var b2TOIInput = Box2D.Collision.b2TOIInput; - var b2WorldManifold = Box2D.Collision.b2WorldManifold; - var ClipVertex = Box2D.Collision.ClipVertex; - var Features = Box2D.Collision.Features; - var IBroadPhase = Box2D.Collision.IBroadPhase; - var b2internal = Box2D.Common.b2internal; - var b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact; - var b2Contact = Box2D.Dynamics.Contacts.b2Contact; - var b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint; - var b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint; - var b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge; - var b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory; - var b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister; - var b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult; - var b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver; - var b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact; - var b2NullContact = Box2D.Dynamics.Contacts.b2NullContact; - var b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact; - var b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact; - var b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact; - var b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold; - helpers.inherit.call(b2CircleContact, Box2D.Dynamics.Contacts.b2Contact); - b2CircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2CircleContact.b2CircleContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2CircleContact.prototype.Create = function (allocator) { - return new b2CircleContact(); - } - b2CircleContact.Create = b2CircleContact.prototype.Create; - b2CircleContact.prototype.Destroy = function (contact, allocator) {} - b2CircleContact.Destroy = b2CircleContact.prototype.Destroy; - b2CircleContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - } - b2CircleContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - b2Collision.CollideCircles(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2CircleShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - b2Contact.b2Contact = function () { - this.m_nodeA = new b2ContactEdge(); - this.m_nodeB = new b2ContactEdge(); - this.m_manifold = new b2Manifold(); - this.m_oldManifold = new b2Manifold(); - }; - b2Contact.prototype.GetManifold = function () { - return this.m_manifold; - } - b2Contact.prototype.GetWorldManifold = function (worldManifold) { - var bodyA = this.m_fixtureA.GetBody(); - var bodyB = this.m_fixtureB.GetBody(); - var shapeA = this.m_fixtureA.GetShape(); - var shapeB = this.m_fixtureB.GetShape(); - worldManifold.Initialize(this.m_manifold, bodyA.GetTransform(), shapeA.m_radius, bodyB.GetTransform(), shapeB.m_radius); - } - b2Contact.prototype.IsTouching = function () { - return (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag; - } - b2Contact.prototype.IsContinuous = function () { - return (this.m_flags & b2Contact.e_continuousFlag) == b2Contact.e_continuousFlag; - } - b2Contact.prototype.SetSensor = function (sensor) { - if (sensor) { - this.m_flags |= b2Contact.e_sensorFlag; - } - else { - this.m_flags &= ~b2Contact.e_sensorFlag; - } - } - b2Contact.prototype.IsSensor = function () { - return (this.m_flags & b2Contact.e_sensorFlag) == b2Contact.e_sensorFlag; - } - b2Contact.prototype.SetEnabled = function (flag) { - if (flag) { - this.m_flags |= b2Contact.e_enabledFlag; - } - else { - this.m_flags &= ~b2Contact.e_enabledFlag; - } - } - b2Contact.prototype.IsEnabled = function () { - return (this.m_flags & b2Contact.e_enabledFlag) == b2Contact.e_enabledFlag; - } - b2Contact.prototype.GetNext = function () { - return this.m_next; - } - b2Contact.prototype.GetFixtureA = function () { - return this.m_fixtureA; - } - b2Contact.prototype.GetFixtureB = function () { - return this.m_fixtureB; - } - b2Contact.prototype.FlagForFiltering = function () { - this.m_flags |= b2Contact.e_filterFlag; - } - b2Contact.prototype.b2Contact = function () {} - b2Contact.prototype.Reset = function (fixtureA, fixtureB) { - if (fixtureA === undefined) fixtureA = null; - if (fixtureB === undefined) fixtureB = null; - this.m_flags = b2Contact.e_enabledFlag; - if (!fixtureA || !fixtureB) { - this.m_fixtureA = null; - this.m_fixtureB = null; - return; - } - if (fixtureA.IsSensor() || fixtureB.IsSensor()) { - this.m_flags |= b2Contact.e_sensorFlag; - } - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { - this.m_flags |= b2Contact.e_continuousFlag; - } - this.m_fixtureA = fixtureA; - this.m_fixtureB = fixtureB; - this.m_manifold.m_pointCount = 0; - this.m_prev = null; - this.m_next = null; - this.m_nodeA.contact = null; - this.m_nodeA.prev = null; - this.m_nodeA.next = null; - this.m_nodeA.other = null; - this.m_nodeB.contact = null; - this.m_nodeB.prev = null; - this.m_nodeB.next = null; - this.m_nodeB.other = null; - } - b2Contact.prototype.Update = function (listener) { - var tManifold = this.m_oldManifold; - this.m_oldManifold = this.m_manifold; - this.m_manifold = tManifold; - this.m_flags |= b2Contact.e_enabledFlag; - var touching = false; - var wasTouching = (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag; - var bodyA = this.m_fixtureA.m_body; - var bodyB = this.m_fixtureB.m_body; - var aabbOverlap = this.m_fixtureA.m_aabb.TestOverlap(this.m_fixtureB.m_aabb); - if (this.m_flags & b2Contact.e_sensorFlag) { - if (aabbOverlap) { - var shapeA = this.m_fixtureA.GetShape(); - var shapeB = this.m_fixtureB.GetShape(); - var xfA = bodyA.GetTransform(); - var xfB = bodyB.GetTransform(); - touching = b2Shape.TestOverlap(shapeA, xfA, shapeB, xfB); - } - this.m_manifold.m_pointCount = 0; - } - else { - if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { - this.m_flags |= b2Contact.e_continuousFlag; - } - else { - this.m_flags &= ~b2Contact.e_continuousFlag; - } - if (aabbOverlap) { - this.Evaluate(); - touching = this.m_manifold.m_pointCount > 0; - for (var i = 0; i < this.m_manifold.m_pointCount; ++i) { - var mp2 = this.m_manifold.m_points[i]; - mp2.m_normalImpulse = 0.0; - mp2.m_tangentImpulse = 0.0; - var id2 = mp2.m_id; - for (var j = 0; j < this.m_oldManifold.m_pointCount; ++j) { - var mp1 = this.m_oldManifold.m_points[j]; - if (mp1.m_id.key == id2.key) { - mp2.m_normalImpulse = mp1.m_normalImpulse; - mp2.m_tangentImpulse = mp1.m_tangentImpulse; - break; - } - } - } - } - else { - this.m_manifold.m_pointCount = 0; - } - if (touching != wasTouching) { - bodyA.SetAwake(true); - bodyB.SetAwake(true); - } - } - if (touching) { - this.m_flags |= b2Contact.e_touchingFlag; - } - else { - this.m_flags &= ~b2Contact.e_touchingFlag; - } - if (wasTouching == false && touching == true) { - listener.BeginContact(this); - } - if (wasTouching == true && touching == false) { - listener.EndContact(this); - } - if ((this.m_flags & b2Contact.e_sensorFlag) == 0) { - listener.PreSolve(this, this.m_oldManifold); - } - } - b2Contact.prototype.Evaluate = function () {} - b2Contact.prototype.ComputeTOI = function (sweepA, sweepB) { - b2Contact.s_input.proxyA.Set(this.m_fixtureA.GetShape()); - b2Contact.s_input.proxyB.Set(this.m_fixtureB.GetShape()); - b2Contact.s_input.sweepA = sweepA; - b2Contact.s_input.sweepB = sweepB; - b2Contact.s_input.tolerance = b2Settings.b2_linearSlop; - return b2TimeOfImpact.TimeOfImpact(b2Contact.s_input); - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.Contacts.b2Contact.e_sensorFlag = 0x0001; - Box2D.Dynamics.Contacts.b2Contact.prototype.e_sensorFlag = Box2D.Dynamics.Contacts.b2Contact.e_sensorFlag; - Box2D.Dynamics.Contacts.b2Contact.e_continuousFlag = 0x0002; - Box2D.Dynamics.Contacts.b2Contact.prototype.e_continuousFlag = Box2D.Dynamics.Contacts.b2Contact.e_continuousFlag; - Box2D.Dynamics.Contacts.b2Contact.e_islandFlag = 0x0004; - Box2D.Dynamics.Contacts.b2Contact.prototype.e_islandFlag = Box2D.Dynamics.Contacts.b2Contact.e_islandFlag; - Box2D.Dynamics.Contacts.b2Contact.e_toiFlag = 0x0008; - Box2D.Dynamics.Contacts.b2Contact.prototype.e_toiFlag = Box2D.Dynamics.Contacts.b2Contact.e_toiFlag; - Box2D.Dynamics.Contacts.b2Contact.e_touchingFlag = 0x0010; - Box2D.Dynamics.Contacts.b2Contact.prototype.e_touchingFlag = Box2D.Dynamics.Contacts.b2Contact.e_touchingFlag; - Box2D.Dynamics.Contacts.b2Contact.e_enabledFlag = 0x0020; - Box2D.Dynamics.Contacts.b2Contact.prototype.e_enabledFlag = Box2D.Dynamics.Contacts.b2Contact.e_enabledFlag; - Box2D.Dynamics.Contacts.b2Contact.e_filterFlag = 0x0040; - Box2D.Dynamics.Contacts.b2Contact.prototype.e_filterFlag = Box2D.Dynamics.Contacts.b2Contact.e_filterFlag; - Box2D.Dynamics.Contacts.b2Contact.s_input = new b2TOIInput(); - Box2D.Dynamics.Contacts.b2Contact.prototype.s_input = Box2D.Dynamics.Contacts.b2Contact.s_input; - }); - b2ContactConstraint.b2ContactConstraint = function () { - this.localPlaneNormal = new b2Vec2(); - this.localPoint = new b2Vec2(); - this.normal = new b2Vec2(); - this.normalMass = new b2Mat22(); - this.K = new b2Mat22(); - }; - b2ContactConstraint.prototype.b2ContactConstraint = function () { - this.points = new Vector(b2Settings.b2_maxManifoldPoints); - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - this.points[i] = new b2ContactConstraintPoint(); - } - } - b2ContactConstraintPoint.b2ContactConstraintPoint = function () { - this.localPoint = new b2Vec2(); - this.rA = new b2Vec2(); - this.rB = new b2Vec2(); - }; - b2ContactEdge.b2ContactEdge = function () {}; - b2ContactFactory.b2ContactFactory = function () {}; - b2ContactFactory.prototype.b2ContactFactory = function (allocator) { - this.m_allocator = allocator; - this.InitializeRegisters(); - } - b2ContactFactory.prototype.AddType = function (createFcn, destroyFcn, type1, type2) { - if (type1 === undefined) type1 = 0; - if (type2 === undefined) type2 = 0; - this.m_registers[type1][type2].createFcn = createFcn; - this.m_registers[type1][type2].destroyFcn = destroyFcn; - this.m_registers[type1][type2].primary = true; - if (type1 != type2) { - this.m_registers[type2][type1].createFcn = createFcn; - this.m_registers[type2][type1].destroyFcn = destroyFcn; - this.m_registers[type2][type1].primary = false; - } - } - b2ContactFactory.prototype.InitializeRegisters = function () { - this.m_registers = new Vector(b2Shape.e_shapeTypeCount); - for (var i = 0; i < b2Shape.e_shapeTypeCount; i++) { - this.m_registers[i] = new Vector(b2Shape.e_shapeTypeCount); - for (var j = 0; j < b2Shape.e_shapeTypeCount; j++) { - this.m_registers[i][j] = new b2ContactRegister(); - } - } - this.AddType(b2CircleContact.Create, b2CircleContact.Destroy, b2Shape.e_circleShape, b2Shape.e_circleShape); - this.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_circleShape); - this.AddType(b2PolygonContact.Create, b2PolygonContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_polygonShape); - this.AddType(b2EdgeAndCircleContact.Create, b2EdgeAndCircleContact.Destroy, b2Shape.e_edgeShape, b2Shape.e_circleShape); - this.AddType(b2PolyAndEdgeContact.Create, b2PolyAndEdgeContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_edgeShape); - } - b2ContactFactory.prototype.Create = function (fixtureA, fixtureB) { - var type1 = parseInt(fixtureA.GetType()); - var type2 = parseInt(fixtureB.GetType()); - var reg = this.m_registers[type1][type2]; - var c; - if (reg.pool) { - c = reg.pool; - reg.pool = c.m_next; - reg.poolCount--; - c.Reset(fixtureA, fixtureB); - return c; - } - var createFcn = reg.createFcn; - if (createFcn != null) { - if (reg.primary) { - c = createFcn(this.m_allocator); - c.Reset(fixtureA, fixtureB); - return c; - } - else { - c = createFcn(this.m_allocator); - c.Reset(fixtureB, fixtureA); - return c; - } - } - else { - return null; - } - } - b2ContactFactory.prototype.Destroy = function (contact) { - if (contact.m_manifold.m_pointCount > 0) { - contact.m_fixtureA.m_body.SetAwake(true); - contact.m_fixtureB.m_body.SetAwake(true); - } - var type1 = parseInt(contact.m_fixtureA.GetType()); - var type2 = parseInt(contact.m_fixtureB.GetType()); - var reg = this.m_registers[type1][type2]; - if (true) { - reg.poolCount++; - contact.m_next = reg.pool; - reg.pool = contact; - } - var destroyFcn = reg.destroyFcn; - destroyFcn(contact, this.m_allocator); - } - b2ContactRegister.b2ContactRegister = function () {}; - b2ContactResult.b2ContactResult = function () { - this.position = new b2Vec2(); - this.normal = new b2Vec2(); - this.id = new b2ContactID(); - }; - b2ContactSolver.b2ContactSolver = function () { - this.m_step = new b2TimeStep(); - this.m_constraints = new Vector(); - }; - b2ContactSolver.prototype.b2ContactSolver = function () {} - b2ContactSolver.prototype.Initialize = function (step, contacts, contactCount, allocator) { - if (contactCount === undefined) contactCount = 0; - var contact; - this.m_step.Set(step); - this.m_allocator = allocator; - var i = 0; - var tVec; - var tMat; - this.m_constraintCount = contactCount; - while (this.m_constraints.length < this.m_constraintCount) { - this.m_constraints[this.m_constraints.length] = new b2ContactConstraint(); - } - for (i = 0; - i < contactCount; ++i) { - contact = contacts[i]; - var fixtureA = contact.m_fixtureA; - var fixtureB = contact.m_fixtureB; - var shapeA = fixtureA.m_shape; - var shapeB = fixtureB.m_shape; - var radiusA = shapeA.m_radius; - var radiusB = shapeB.m_radius; - var bodyA = fixtureA.m_body; - var bodyB = fixtureB.m_body; - var manifold = contact.GetManifold(); - var friction = b2Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction()); - var restitution = b2Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution()); - var vAX = bodyA.m_linearVelocity.x; - var vAY = bodyA.m_linearVelocity.y; - var vBX = bodyB.m_linearVelocity.x; - var vBY = bodyB.m_linearVelocity.y; - var wA = bodyA.m_angularVelocity; - var wB = bodyB.m_angularVelocity; - b2Settings.b2Assert(manifold.m_pointCount > 0); - b2ContactSolver.s_worldManifold.Initialize(manifold, bodyA.m_xf, radiusA, bodyB.m_xf, radiusB); - var normalX = b2ContactSolver.s_worldManifold.m_normal.x; - var normalY = b2ContactSolver.s_worldManifold.m_normal.y; - var cc = this.m_constraints[i]; - cc.bodyA = bodyA; - cc.bodyB = bodyB; - cc.manifold = manifold; - cc.normal.x = normalX; - cc.normal.y = normalY; - cc.pointCount = manifold.m_pointCount; - cc.friction = friction; - cc.restitution = restitution; - cc.localPlaneNormal.x = manifold.m_localPlaneNormal.x; - cc.localPlaneNormal.y = manifold.m_localPlaneNormal.y; - cc.localPoint.x = manifold.m_localPoint.x; - cc.localPoint.y = manifold.m_localPoint.y; - cc.radius = radiusA + radiusB; - cc.type = manifold.m_type; - for (var k = 0; k < cc.pointCount; ++k) { - var cp = manifold.m_points[k]; - var ccp = cc.points[k]; - ccp.normalImpulse = cp.m_normalImpulse; - ccp.tangentImpulse = cp.m_tangentImpulse; - ccp.localPoint.SetV(cp.m_localPoint); - var rAX = ccp.rA.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyA.m_sweep.c.x; - var rAY = ccp.rA.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyA.m_sweep.c.y; - var rBX = ccp.rB.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyB.m_sweep.c.x; - var rBY = ccp.rB.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyB.m_sweep.c.y; - var rnA = rAX * normalY - rAY * normalX; - var rnB = rBX * normalY - rBY * normalX; - rnA *= rnA; - rnB *= rnB; - var kNormal = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rnA + bodyB.m_invI * rnB; - ccp.normalMass = 1.0 / kNormal; - var kEqualized = bodyA.m_mass * bodyA.m_invMass + bodyB.m_mass * bodyB.m_invMass; - kEqualized += bodyA.m_mass * bodyA.m_invI * rnA + bodyB.m_mass * bodyB.m_invI * rnB; - ccp.equalizedMass = 1.0 / kEqualized; - var tangentX = normalY; - var tangentY = (-normalX); - var rtA = rAX * tangentY - rAY * tangentX; - var rtB = rBX * tangentY - rBY * tangentX; - rtA *= rtA; - rtB *= rtB; - var kTangent = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rtA + bodyB.m_invI * rtB; - ccp.tangentMass = 1.0 / kTangent; - ccp.velocityBias = 0.0; - var tX = vBX + ((-wB * rBY)) - vAX - ((-wA * rAY)); - var tY = vBY + (wB * rBX) - vAY - (wA * rAX); - var vRel = cc.normal.x * tX + cc.normal.y * tY; - if (vRel < (-b2Settings.b2_velocityThreshold)) { - ccp.velocityBias += (-cc.restitution * vRel); - } - } - if (cc.pointCount == 2) { - var ccp1 = cc.points[0]; - var ccp2 = cc.points[1]; - var invMassA = bodyA.m_invMass; - var invIA = bodyA.m_invI; - var invMassB = bodyB.m_invMass; - var invIB = bodyB.m_invI; - var rn1A = ccp1.rA.x * normalY - ccp1.rA.y * normalX; - var rn1B = ccp1.rB.x * normalY - ccp1.rB.y * normalX; - var rn2A = ccp2.rA.x * normalY - ccp2.rA.y * normalX; - var rn2B = ccp2.rB.x * normalY - ccp2.rB.y * normalX; - var k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B; - var k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B; - var k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B; - var k_maxConditionNumber = 100.0; - if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { - cc.K.col1.Set(k11, k12); - cc.K.col2.Set(k12, k22); - cc.K.GetInverse(cc.normalMass); - } - else { - cc.pointCount = 1; - } - } - } - } - b2ContactSolver.prototype.InitVelocityConstraints = function (step) { - var tVec; - var tVec2; - var tMat; - for (var i = 0; i < this.m_constraintCount; ++i) { - var c = this.m_constraints[i]; - var bodyA = c.bodyA; - var bodyB = c.bodyB; - var invMassA = bodyA.m_invMass; - var invIA = bodyA.m_invI; - var invMassB = bodyB.m_invMass; - var invIB = bodyB.m_invI; - var normalX = c.normal.x; - var normalY = c.normal.y; - var tangentX = normalY; - var tangentY = (-normalX); - var tX = 0; - var j = 0; - var tCount = 0; - if (step.warmStarting) { - tCount = c.pointCount; - for (j = 0; - j < tCount; ++j) { - var ccp = c.points[j]; - ccp.normalImpulse *= step.dtRatio; - ccp.tangentImpulse *= step.dtRatio; - var PX = ccp.normalImpulse * normalX + ccp.tangentImpulse * tangentX; - var PY = ccp.normalImpulse * normalY + ccp.tangentImpulse * tangentY; - bodyA.m_angularVelocity -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); - bodyA.m_linearVelocity.x -= invMassA * PX; - bodyA.m_linearVelocity.y -= invMassA * PY; - bodyB.m_angularVelocity += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); - bodyB.m_linearVelocity.x += invMassB * PX; - bodyB.m_linearVelocity.y += invMassB * PY; - } - } - else { - tCount = c.pointCount; - for (j = 0; - j < tCount; ++j) { - var ccp2 = c.points[j]; - ccp2.normalImpulse = 0.0; - ccp2.tangentImpulse = 0.0; - } - } - } - } - b2ContactSolver.prototype.SolveVelocityConstraints = function () { - var j = 0; - var ccp; - var rAX = 0; - var rAY = 0; - var rBX = 0; - var rBY = 0; - var dvX = 0; - var dvY = 0; - var vn = 0; - var vt = 0; - var lambda = 0; - var maxFriction = 0; - var newImpulse = 0; - var PX = 0; - var PY = 0; - var dX = 0; - var dY = 0; - var P1X = 0; - var P1Y = 0; - var P2X = 0; - var P2Y = 0; - var tMat; - var tVec; - for (var i = 0; i < this.m_constraintCount; ++i) { - var c = this.m_constraints[i]; - var bodyA = c.bodyA; - var bodyB = c.bodyB; - var wA = bodyA.m_angularVelocity; - var wB = bodyB.m_angularVelocity; - var vA = bodyA.m_linearVelocity; - var vB = bodyB.m_linearVelocity; - var invMassA = bodyA.m_invMass; - var invIA = bodyA.m_invI; - var invMassB = bodyB.m_invMass; - var invIB = bodyB.m_invI; - var normalX = c.normal.x; - var normalY = c.normal.y; - var tangentX = normalY; - var tangentY = (-normalX); - var friction = c.friction; - var tX = 0; - for (j = 0; - j < c.pointCount; j++) { - ccp = c.points[j]; - dvX = vB.x - wB * ccp.rB.y - vA.x + wA * ccp.rA.y; - dvY = vB.y + wB * ccp.rB.x - vA.y - wA * ccp.rA.x; - vt = dvX * tangentX + dvY * tangentY; - lambda = ccp.tangentMass * (-vt); - maxFriction = friction * ccp.normalImpulse; - newImpulse = b2Math.Clamp(ccp.tangentImpulse + lambda, (-maxFriction), maxFriction); - lambda = newImpulse - ccp.tangentImpulse; - PX = lambda * tangentX; - PY = lambda * tangentY; - vA.x -= invMassA * PX; - vA.y -= invMassA * PY; - wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); - vB.x += invMassB * PX; - vB.y += invMassB * PY; - wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); - ccp.tangentImpulse = newImpulse; - } - var tCount = parseInt(c.pointCount); - if (c.pointCount == 1) { - ccp = c.points[0]; - dvX = vB.x + ((-wB * ccp.rB.y)) - vA.x - ((-wA * ccp.rA.y)); - dvY = vB.y + (wB * ccp.rB.x) - vA.y - (wA * ccp.rA.x); - vn = dvX * normalX + dvY * normalY; - lambda = (-ccp.normalMass * (vn - ccp.velocityBias)); - newImpulse = ccp.normalImpulse + lambda; - newImpulse = newImpulse > 0 ? newImpulse : 0.0; - lambda = newImpulse - ccp.normalImpulse; - PX = lambda * normalX; - PY = lambda * normalY; - vA.x -= invMassA * PX; - vA.y -= invMassA * PY; - wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); - vB.x += invMassB * PX; - vB.y += invMassB * PY; - wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); - ccp.normalImpulse = newImpulse; - } - else { - var cp1 = c.points[0]; - var cp2 = c.points[1]; - var aX = cp1.normalImpulse; - var aY = cp2.normalImpulse; - var dv1X = vB.x - wB * cp1.rB.y - vA.x + wA * cp1.rA.y; - var dv1Y = vB.y + wB * cp1.rB.x - vA.y - wA * cp1.rA.x; - var dv2X = vB.x - wB * cp2.rB.y - vA.x + wA * cp2.rA.y; - var dv2Y = vB.y + wB * cp2.rB.x - vA.y - wA * cp2.rA.x; - var vn1 = dv1X * normalX + dv1Y * normalY; - var vn2 = dv2X * normalX + dv2Y * normalY; - var bX = vn1 - cp1.velocityBias; - var bY = vn2 - cp2.velocityBias; - tMat = c.K; - bX -= tMat.col1.x * aX + tMat.col2.x * aY; - bY -= tMat.col1.y * aX + tMat.col2.y * aY; - var k_errorTol = 0.001; - for (;;) { - tMat = c.normalMass; - var xX = (-(tMat.col1.x * bX + tMat.col2.x * bY)); - var xY = (-(tMat.col1.y * bX + tMat.col2.y * bY)); - if (xX >= 0.0 && xY >= 0.0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break; - } - xX = (-cp1.normalMass * bX); - xY = 0.0; - vn1 = 0.0; - vn2 = c.K.col1.y * xX + bY; - if (xX >= 0.0 && vn2 >= 0.0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break; - } - xX = 0.0; - xY = (-cp2.normalMass * bY); - vn1 = c.K.col2.x * xY + bX; - vn2 = 0.0; - if (xY >= 0.0 && vn1 >= 0.0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break; - } - xX = 0.0; - xY = 0.0; - vn1 = bX; - vn2 = bY; - if (vn1 >= 0.0 && vn2 >= 0.0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break; - } - break; - } - } - bodyA.m_angularVelocity = wA; - bodyB.m_angularVelocity = wB; - } - } - b2ContactSolver.prototype.FinalizeVelocityConstraints = function () { - for (var i = 0; i < this.m_constraintCount; ++i) { - var c = this.m_constraints[i]; - var m = c.manifold; - for (var j = 0; j < c.pointCount; ++j) { - var point1 = m.m_points[j]; - var point2 = c.points[j]; - point1.m_normalImpulse = point2.normalImpulse; - point1.m_tangentImpulse = point2.tangentImpulse; - } - } - } - b2ContactSolver.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var minSeparation = 0.0; - for (var i = 0; i < this.m_constraintCount; i++) { - var c = this.m_constraints[i]; - var bodyA = c.bodyA; - var bodyB = c.bodyB; - var invMassA = bodyA.m_mass * bodyA.m_invMass; - var invIA = bodyA.m_mass * bodyA.m_invI; - var invMassB = bodyB.m_mass * bodyB.m_invMass; - var invIB = bodyB.m_mass * bodyB.m_invI; - b2ContactSolver.s_psm.Initialize(c); - var normal = b2ContactSolver.s_psm.m_normal; - for (var j = 0; j < c.pointCount; j++) { - var ccp = c.points[j]; - var point = b2ContactSolver.s_psm.m_points[j]; - var separation = b2ContactSolver.s_psm.m_separations[j]; - var rAX = point.x - bodyA.m_sweep.c.x; - var rAY = point.y - bodyA.m_sweep.c.y; - var rBX = point.x - bodyB.m_sweep.c.x; - var rBY = point.y - bodyB.m_sweep.c.y; - minSeparation = minSeparation < separation ? minSeparation : separation; - var C = b2Math.Clamp(baumgarte * (separation + b2Settings.b2_linearSlop), (-b2Settings.b2_maxLinearCorrection), 0.0); - var impulse = (-ccp.equalizedMass * C); - var PX = impulse * normal.x; - var PY = impulse * normal.y;bodyA.m_sweep.c.x -= invMassA * PX; - bodyA.m_sweep.c.y -= invMassA * PY; - bodyA.m_sweep.a -= invIA * (rAX * PY - rAY * PX); - bodyA.SynchronizeTransform(); - bodyB.m_sweep.c.x += invMassB * PX; - bodyB.m_sweep.c.y += invMassB * PY; - bodyB.m_sweep.a += invIB * (rBX * PY - rBY * PX); - bodyB.SynchronizeTransform(); - } - } - return minSeparation > (-1.5 * b2Settings.b2_linearSlop); - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.Contacts.b2ContactSolver.s_worldManifold = new b2WorldManifold(); - Box2D.Dynamics.Contacts.b2ContactSolver.prototype.s_worldManifold = Box2D.Dynamics.Contacts.b2ContactSolver.s_worldManifold; - Box2D.Dynamics.Contacts.b2ContactSolver.s_psm = new b2PositionSolverManifold(); - Box2D.Dynamics.Contacts.b2ContactSolver.prototype.s_psm = Box2D.Dynamics.Contacts.b2ContactSolver.s_psm; - }); - helpers.inherit.call(b2EdgeAndCircleContact, Box2D.Dynamics.Contacts.b2Contact); - b2EdgeAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2EdgeAndCircleContact.b2EdgeAndCircleContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2EdgeAndCircleContact.prototype.Create = function (allocator) { - return new b2EdgeAndCircleContact(); - } - b2EdgeAndCircleContact.Create = b2EdgeAndCircleContact.prototype.Create; - b2EdgeAndCircleContact.prototype.Destroy = function (contact, allocator) {} - b2EdgeAndCircleContact.Destroy = b2EdgeAndCircleContact.prototype.Destroy; - b2EdgeAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - } - b2EdgeAndCircleContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - this.b2CollideEdgeAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2EdgeShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - b2EdgeAndCircleContact.prototype.b2CollideEdgeAndCircle = function (manifold, edge, xf1, circle, xf2) {} - helpers.inherit.call(b2NullContact, Box2D.Dynamics.Contacts.b2Contact); - b2NullContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2NullContact.b2NullContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2NullContact.prototype.b2NullContact = function () { - this.__super.b2Contact.call(this); - } - b2NullContact.prototype.Evaluate = function () {} - helpers.inherit.call(b2PolyAndCircleContact, Box2D.Dynamics.Contacts.b2Contact); - b2PolyAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2PolyAndCircleContact.b2PolyAndCircleContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2PolyAndCircleContact.prototype.Create = function (allocator) { - return new b2PolyAndCircleContact(); - } - b2PolyAndCircleContact.Create = b2PolyAndCircleContact.prototype.Create; - b2PolyAndCircleContact.prototype.Destroy = function (contact, allocator) {} - b2PolyAndCircleContact.Destroy = b2PolyAndCircleContact.prototype.Destroy; - b2PolyAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); - b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_circleShape); - } - b2PolyAndCircleContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.m_body; - var bB = this.m_fixtureB.m_body; - b2Collision.CollidePolygonAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - helpers.inherit.call(b2PolyAndEdgeContact, Box2D.Dynamics.Contacts.b2Contact); - b2PolyAndEdgeContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2PolyAndEdgeContact.b2PolyAndEdgeContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2PolyAndEdgeContact.prototype.Create = function (allocator) { - return new b2PolyAndEdgeContact(); - } - b2PolyAndEdgeContact.Create = b2PolyAndEdgeContact.prototype.Create; - b2PolyAndEdgeContact.prototype.Destroy = function (contact, allocator) {} - b2PolyAndEdgeContact.Destroy = b2PolyAndEdgeContact.prototype.Destroy; - b2PolyAndEdgeContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); - b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_edgeShape); - } - b2PolyAndEdgeContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - this.b2CollidePolyAndEdge(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2EdgeShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - b2PolyAndEdgeContact.prototype.b2CollidePolyAndEdge = function (manifold, polygon, xf1, edge, xf2) {} - helpers.inherit.call(b2PolygonContact, Box2D.Dynamics.Contacts.b2Contact); - b2PolygonContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2PolygonContact.b2PolygonContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2PolygonContact.prototype.Create = function (allocator) { - return new b2PolygonContact(); - } - b2PolygonContact.Create = b2PolygonContact.prototype.Create; - b2PolygonContact.prototype.Destroy = function (contact, allocator) {} - b2PolygonContact.Destroy = b2PolygonContact.prototype.Destroy; - b2PolygonContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - } - b2PolygonContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - b2Collision.CollidePolygons(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2PolygonShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - b2PositionSolverManifold.b2PositionSolverManifold = function () {}; - b2PositionSolverManifold.prototype.b2PositionSolverManifold = function () { - this.m_normal = new b2Vec2(); - this.m_separations = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); - this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - this.m_points[i] = new b2Vec2(); - } - } - b2PositionSolverManifold.prototype.Initialize = function (cc) { - b2Settings.b2Assert(cc.pointCount > 0); - var i = 0; - var clipPointX = 0; - var clipPointY = 0; - var tMat; - var tVec; - var planePointX = 0; - var planePointY = 0; - switch (cc.type) { - case b2Manifold.e_circles: - { - tMat = cc.bodyA.m_xf.R; - tVec = cc.localPoint; - var pointAX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var pointAY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = cc.bodyB.m_xf.R; - tVec = cc.points[0].localPoint; - var pointBX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var pointBY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var dX = pointBX - pointAX; - var dY = pointBY - pointAY; - var d2 = dX * dX + dY * dY; - if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) { - var d = Math.sqrt(d2); - this.m_normal.x = dX / d; - this.m_normal.y = dY / d; - } - else { - this.m_normal.x = 1.0; - this.m_normal.y = 0.0; - } - this.m_points[0].x = 0.5 * (pointAX + pointBX); - this.m_points[0].y = 0.5 * (pointAY + pointBY); - this.m_separations[0] = dX * this.m_normal.x + dY * this.m_normal.y - cc.radius; - } - break; - case b2Manifold.e_faceA: - { - tMat = cc.bodyA.m_xf.R; - tVec = cc.localPlaneNormal; - this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = cc.bodyA.m_xf.R; - tVec = cc.localPoint; - planePointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - planePointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = cc.bodyB.m_xf.R; - for (i = 0; - i < cc.pointCount; ++i) { - tVec = cc.points[i].localPoint; - clipPointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - clipPointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; - this.m_points[i].x = clipPointX; - this.m_points[i].y = clipPointY; - } - } - break; - case b2Manifold.e_faceB: - { - tMat = cc.bodyB.m_xf.R; - tVec = cc.localPlaneNormal; - this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = cc.bodyB.m_xf.R; - tVec = cc.localPoint; - planePointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - planePointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = cc.bodyA.m_xf.R; - for (i = 0; - i < cc.pointCount; ++i) { - tVec = cc.points[i].localPoint; - clipPointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - clipPointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; - this.m_points[i].Set(clipPointX, clipPointY); - } - this.m_normal.x *= (-1); - this.m_normal.y *= (-1); - } - break; - } - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointA = new b2Vec2(); - Box2D.Dynamics.Contacts.b2PositionSolverManifold.prototype.circlePointA = Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointA; - Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointB = new b2Vec2(); - Box2D.Dynamics.Contacts.b2PositionSolverManifold.prototype.circlePointB = Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointB; - }); -})(); /* source: disabled*/ -(function () { - var b2Body = Box2D.Dynamics.b2Body; - var b2BodyDef = Box2D.Dynamics.b2BodyDef; - var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; - var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; - var b2ContactListener = Box2D.Dynamics.b2ContactListener; - var b2ContactManager = Box2D.Dynamics.b2ContactManager; - var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; - var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; - var b2FilterData = Box2D.Dynamics.b2FilterData; - var b2Fixture = Box2D.Dynamics.b2Fixture; - var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; - var b2Island = Box2D.Dynamics.b2Island; - var b2TimeStep = Box2D.Dynamics.b2TimeStep; - var b2World = Box2D.Dynamics.b2World; - var b2Mat22 = Box2D.Common.Math.b2Mat22; - var b2Mat33 = Box2D.Common.Math.b2Mat33; - var b2Math = Box2D.Common.Math.b2Math; - var b2Sweep = Box2D.Common.Math.b2Sweep; - var b2Transform = Box2D.Common.Math.b2Transform; - var b2Vec2 = Box2D.Common.Math.b2Vec2; - var b2Vec3 = Box2D.Common.Math.b2Vec3; - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; - var b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef; - var b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape; - var b2MassData = Box2D.Collision.Shapes.b2MassData; - var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; - var b2Shape = Box2D.Collision.Shapes.b2Shape; - var b2Body = Box2D.Dynamics.b2Body; - var b2BodyDef = Box2D.Dynamics.b2BodyDef; - var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; - var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; - var b2ContactListener = Box2D.Dynamics.b2ContactListener; - var b2ContactManager = Box2D.Dynamics.b2ContactManager; - var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; - var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; - var b2FilterData = Box2D.Dynamics.b2FilterData; - var b2Fixture = Box2D.Dynamics.b2Fixture; - var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; - var b2Island = Box2D.Dynamics.b2Island; - var b2TimeStep = Box2D.Dynamics.b2TimeStep; - var b2World = Box2D.Dynamics.b2World; - var b2BuoyancyController = Box2D.Dynamics.Controllers.b2BuoyancyController; - var b2ConstantAccelController = Box2D.Dynamics.Controllers.b2ConstantAccelController; - var b2ConstantForceController = Box2D.Dynamics.Controllers.b2ConstantForceController; - var b2Controller = Box2D.Dynamics.Controllers.b2Controller; - var b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge; - var b2GravityController = Box2D.Dynamics.Controllers.b2GravityController; - var b2TensorDampingController = Box2D.Dynamics.Controllers.b2TensorDampingController; - helpers.inherit.call(b2BuoyancyController, Box2D.Dynamics.Controllers.b2Controller); - b2BuoyancyController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2BuoyancyController.b2BuoyancyController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.normal = new b2Vec2(0, (-1)); - this.offset = 0; - this.density = 0; - this.velocity = new b2Vec2(0, 0); - this.linearDrag = 2; - this.angularDrag = 1; - this.useDensity = false; - this.useWorldGravity = true; - this.gravity = null; - }; - b2BuoyancyController.prototype.Step = function (step) { - if (!this.m_bodyList) return; - if (this.useWorldGravity) { - this.gravity = this.GetWorld().GetGravity().Copy(); - } - for (var i = this.m_bodyList; i; i = i.nextBody) { - var body = i.body; - if (body.IsAwake() == false) { - continue; - } - var areac = new b2Vec2(); - var massc = new b2Vec2(); - var area = 0.0; - var mass = 0.0; - for (var fixture = body.GetFixtureList(); fixture; fixture = fixture.GetNext()) { - var sc = new b2Vec2(); - var sarea = fixture.GetShape().ComputeSubmergedArea(this.normal, this.offset, body.GetTransform(), sc); - area += sarea; - areac.x += sarea * sc.x; - areac.y += sarea * sc.y; - var shapeDensity = 0; - if (this.useDensity) { - shapeDensity = 1; - } - else { - shapeDensity = 1; - } - mass += sarea * shapeDensity; - massc.x += sarea * sc.x * shapeDensity; - massc.y += sarea * sc.y * shapeDensity; - } - areac.x /= area; - areac.y /= area; - massc.x /= mass; - massc.y /= mass; - if (area < Number.MIN_VALUE) continue; - var buoyancyForce = this.gravity.GetNegative(); - buoyancyForce.Multiply(this.density * area); - body.ApplyForce(buoyancyForce, massc); - var dragForce = body.GetLinearVelocityFromWorldPoint(areac); - dragForce.Subtract(this.velocity); - dragForce.Multiply((-this.linearDrag * area)); - body.ApplyForce(dragForce, areac); - body.ApplyTorque((-body.GetInertia() / body.GetMass() * area * body.GetAngularVelocity() * this.angularDrag)); - } - } - b2BuoyancyController.prototype.Draw = function (debugDraw) { - var r = 1000; - var p1 = new b2Vec2(); - var p2 = new b2Vec2(); - p1.x = this.normal.x * this.offset + this.normal.y * r; - p1.y = this.normal.y * this.offset - this.normal.x * r; - p2.x = this.normal.x * this.offset - this.normal.y * r; - p2.y = this.normal.y * this.offset + this.normal.x * r; - var color = new b2Color(0, 0, 1); - debugDraw.DrawSegment(p1, p2, color); - } - helpers.inherit.call(b2ConstantAccelController, Box2D.Dynamics.Controllers.b2Controller); - b2ConstantAccelController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2ConstantAccelController.b2ConstantAccelController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.A = new b2Vec2(0, 0); - }; - b2ConstantAccelController.prototype.Step = function (step) { - var smallA = new b2Vec2(this.A.x * step.dt, this.A.y * step.dt); - for (var i = this.m_bodyList; i; i = i.nextBody) { - var body = i.body; - if (!body.IsAwake()) continue; - body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + smallA.x, body.GetLinearVelocity().y + smallA.y)); - } - } - helpers.inherit.call(b2ConstantForceController, Box2D.Dynamics.Controllers.b2Controller); - b2ConstantForceController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2ConstantForceController.b2ConstantForceController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.F = new b2Vec2(0, 0); - }; - b2ConstantForceController.prototype.Step = function (step) { - for (var i = this.m_bodyList; i; i = i.nextBody) { - var body = i.body; - if (!body.IsAwake()) continue; - body.ApplyForce(this.F, body.GetWorldCenter()); - } - } - b2Controller.b2Controller = function () {}; - b2Controller.prototype.Step = function (step) {} - b2Controller.prototype.Draw = function (debugDraw) {} - b2Controller.prototype.AddBody = function (body) { - var edge = new b2ControllerEdge(); - edge.controller = this; - edge.body = body; - edge.nextBody = this.m_bodyList; - edge.prevBody = null; - this.m_bodyList = edge; - if (edge.nextBody) edge.nextBody.prevBody = edge; - this.m_bodyCount++; - edge.nextController = body.m_controllerList; - edge.prevController = null; - body.m_controllerList = edge; - if (edge.nextController) edge.nextController.prevController = edge; - body.m_controllerCount++; - } - b2Controller.prototype.RemoveBody = function (body) { - var edge = body.m_controllerList; - while (edge && edge.controller != this) - edge = edge.nextController; - if (edge.prevBody) edge.prevBody.nextBody = edge.nextBody; - if (edge.nextBody) edge.nextBody.prevBody = edge.prevBody; - if (edge.nextController) edge.nextController.prevController = edge.prevController; - if (edge.prevController) edge.prevController.nextController = edge.nextController; - if (this.m_bodyList == edge) this.m_bodyList = edge.nextBody; - if (body.m_controllerList == edge) body.m_controllerList = edge.nextController; - body.m_controllerCount--; - this.m_bodyCount--; - } - b2Controller.prototype.Clear = function () { - while (this.m_bodyList) - this.RemoveBody(this.m_bodyList.body); - } - b2Controller.prototype.GetNext = function () { - return this.m_next; - } - b2Controller.prototype.GetWorld = function () { - return this.m_world; - } - b2Controller.prototype.GetBodyList = function () { - return this.m_bodyList; - } - b2ControllerEdge.b2ControllerEdge = function () {}; - helpers.inherit.call(b2GravityController, Box2D.Dynamics.Controllers.b2Controller); - b2GravityController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2GravityController.b2GravityController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.G = 1; - this.invSqr = true; - }; - b2GravityController.prototype.Step = function (step) { - var i = null; - var body1 = null; - var p1 = null; - var mass1 = 0; - var j = null; - var body2 = null; - var p2 = null; - var dx = 0; - var dy = 0; - var r2 = 0; - var f = null; - if (this.invSqr) { - for (i = this.m_bodyList; - i; i = i.nextBody) { - body1 = i.body; - p1 = body1.GetWorldCenter(); - mass1 = body1.GetMass(); - for (j = this.m_bodyList; - j != i; j = j.nextBody) { - body2 = j.body; - p2 = body2.GetWorldCenter(); - dx = p2.x - p1.x; - dy = p2.y - p1.y; - r2 = dx * dx + dy * dy; - if (r2 < Number.MIN_VALUE) continue; - f = new b2Vec2(dx, dy); - f.Multiply(this.G / r2 / Math.sqrt(r2) * mass1 * body2.GetMass()); - if (body1.IsAwake()) body1.ApplyForce(f, p1); - f.Multiply((-1)); - if (body2.IsAwake()) body2.ApplyForce(f, p2); - } - } - } - else { - for (i = this.m_bodyList; - i; i = i.nextBody) { - body1 = i.body; - p1 = body1.GetWorldCenter(); - mass1 = body1.GetMass(); - for (j = this.m_bodyList; - j != i; j = j.nextBody) { - body2 = j.body; - p2 = body2.GetWorldCenter(); - dx = p2.x - p1.x; - dy = p2.y - p1.y; - r2 = dx * dx + dy * dy; - if (r2 < Number.MIN_VALUE) continue; - f = new b2Vec2(dx, dy); - f.Multiply(this.G / r2 * mass1 * body2.GetMass()); - if (body1.IsAwake()) body1.ApplyForce(f, p1); - f.Multiply((-1)); - if (body2.IsAwake()) body2.ApplyForce(f, p2); - } - } - } - } - helpers.inherit.call(b2TensorDampingController, Box2D.Dynamics.Controllers.b2Controller); - b2TensorDampingController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2TensorDampingController.b2TensorDampingController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.T = new b2Mat22(); - this.maxTimestep = 0; - }; - b2TensorDampingController.prototype.SetAxisAligned = function (xDamping, yDamping) { - if (xDamping === undefined) xDamping = 0; - if (yDamping === undefined) yDamping = 0; - this.T.col1.x = (-xDamping); - this.T.col1.y = 0; - this.T.col2.x = 0; - this.T.col2.y = (-yDamping); - if (xDamping > 0 || yDamping > 0) { - this.maxTimestep = 1 / Math.max(xDamping, yDamping); - } - else { - this.maxTimestep = 0; - } - } - b2TensorDampingController.prototype.Step = function (step) { - var timestep = step.dt; - if (timestep <= Number.MIN_VALUE) return; - if (timestep > this.maxTimestep && this.maxTimestep > 0) timestep = this.maxTimestep; - for (var i = this.m_bodyList; i; i = i.nextBody) { - var body = i.body; - if (!body.IsAwake()) { - continue; - } - var damping = body.GetWorldVector(b2Math.MulMV(this.T, body.GetLocalVector(body.GetLinearVelocity()))); - body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + damping.x * timestep, body.GetLinearVelocity().y + damping.y * timestep)); - } - } -})(); /* source: disabled*/ -(function () { - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2Color = Box2D.Common.b2Color; - var b2internal = Box2D.Common.b2internal; - var b2Settings = Box2D.Common.b2Settings; - var b2internal = Box2D.Common.b2internal; - var b2Mat22 = Box2D.Common.Math.b2Mat22; - var b2Mat33 = Box2D.Common.Math.b2Mat33; - var b2Math = Box2D.Common.Math.b2Math; - var b2Sweep = Box2D.Common.Math.b2Sweep; - var b2Transform = Box2D.Common.Math.b2Transform; - var b2Vec2 = Box2D.Common.Math.b2Vec2; - var b2Vec3 = Box2D.Common.Math.b2Vec3; - var b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint; - var b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef; - var b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint; - var b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef; - var b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint; - var b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef; - var b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian; - var b2Joint = Box2D.Dynamics.Joints.b2Joint; - var b2JointDef = Box2D.Dynamics.Joints.b2JointDef; - var b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge; - var b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint; - var b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef; - var b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint; - var b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef; - var b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint; - var b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef; - var b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint; - var b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef; - var b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint; - var b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef; - var b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint; - var b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef; - var b2Body = Box2D.Dynamics.b2Body; - var b2BodyDef = Box2D.Dynamics.b2BodyDef; - var b2ContactFilter = Box2D.Dynamics.b2ContactFilter; - var b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse; - var b2ContactListener = Box2D.Dynamics.b2ContactListener; - var b2ContactManager = Box2D.Dynamics.b2ContactManager; - var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; - var b2DestructionListener = Box2D.Dynamics.b2DestructionListener; - var b2FilterData = Box2D.Dynamics.b2FilterData; - var b2Fixture = Box2D.Dynamics.b2Fixture; - var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; - var b2Island = Box2D.Dynamics.b2Island; - var b2TimeStep = Box2D.Dynamics.b2TimeStep; - var b2World = Box2D.Dynamics.b2World; - var b2internal = Box2D.Common.b2internal; - var b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint; - var b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef; - var b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint; - var b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef; - var b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint; - var b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef; - var b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian; - var b2Joint = Box2D.Dynamics.Joints.b2Joint; - var b2JointDef = Box2D.Dynamics.Joints.b2JointDef; - var b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge; - var b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint; - var b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef; - var b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint; - var b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef; - var b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint; - var b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef; - var b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint; - var b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef; - var b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint; - var b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef; - var b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint; - var b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef; - helpers.inherit.call(b2DistanceJoint, Box2D.Dynamics.Joints.b2Joint); - b2DistanceJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2DistanceJoint.b2DistanceJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_u = new b2Vec2(); - }; - b2DistanceJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2DistanceJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2DistanceJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse * this.m_u.x, inv_dt * this.m_impulse * this.m_u.y); - } - b2DistanceJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return 0.0; - } - b2DistanceJoint.prototype.GetLength = function () { - return this.m_length; - } - b2DistanceJoint.prototype.SetLength = function (length) { - if (length === undefined) length = 0; - this.m_length = length; - } - b2DistanceJoint.prototype.GetFrequency = function () { - return this.m_frequencyHz; - } - b2DistanceJoint.prototype.SetFrequency = function (hz) { - if (hz === undefined) hz = 0; - this.m_frequencyHz = hz; - } - b2DistanceJoint.prototype.GetDampingRatio = function () { - return this.m_dampingRatio; - } - b2DistanceJoint.prototype.SetDampingRatio = function (ratio) { - if (ratio === undefined) ratio = 0; - this.m_dampingRatio = ratio; - } - b2DistanceJoint.prototype.b2DistanceJoint = function (def) { - this.__super.b2Joint.call(this, def); - var tMat; - var tX = 0; - var tY = 0; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_length = def.length; - this.m_frequencyHz = def.frequencyHz; - this.m_dampingRatio = def.dampingRatio; - this.m_impulse = 0.0; - this.m_gamma = 0.0; - this.m_bias = 0.0; - } - b2DistanceJoint.prototype.InitVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - this.m_u.x = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - this.m_u.y = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - var length = Math.sqrt(this.m_u.x * this.m_u.x + this.m_u.y * this.m_u.y); - if (length > b2Settings.b2_linearSlop) { - this.m_u.Multiply(1.0 / length); - } - else { - this.m_u.SetZero(); - } - var cr1u = (r1X * this.m_u.y - r1Y * this.m_u.x); - var cr2u = (r2X * this.m_u.y - r2Y * this.m_u.x); - var invMass = bA.m_invMass + bA.m_invI * cr1u * cr1u + bB.m_invMass + bB.m_invI * cr2u * cr2u; - this.m_mass = invMass != 0.0 ? 1.0 / invMass : 0.0; - if (this.m_frequencyHz > 0.0) { - var C = length - this.m_length; - var omega = 2.0 * Math.PI * this.m_frequencyHz; - var d = 2.0 * this.m_mass * this.m_dampingRatio * omega; - var k = this.m_mass * omega * omega; - this.m_gamma = step.dt * (d + step.dt * k); - this.m_gamma = this.m_gamma != 0.0 ? 1 / this.m_gamma : 0.0; - this.m_bias = C * step.dt * k * this.m_gamma; - this.m_mass = invMass + this.m_gamma; - this.m_mass = this.m_mass != 0.0 ? 1.0 / this.m_mass : 0.0; - } - if (step.warmStarting) { - this.m_impulse *= step.dtRatio; - var PX = this.m_impulse * this.m_u.x; - var PY = this.m_impulse * this.m_u.y; - bA.m_linearVelocity.x -= bA.m_invMass * PX; - bA.m_linearVelocity.y -= bA.m_invMass * PY; - bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); - bB.m_linearVelocity.x += bB.m_invMass * PX; - bB.m_linearVelocity.y += bB.m_invMass * PY; - bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX); - } - else { - this.m_impulse = 0.0; - } - } - b2DistanceJoint.prototype.SolveVelocityConstraints = function (step) { - var tMat; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y)); - var v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X); - var v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y)); - var v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X); - var Cdot = (this.m_u.x * (v2X - v1X) + this.m_u.y * (v2Y - v1Y)); - var impulse = (-this.m_mass * (Cdot + this.m_bias + this.m_gamma * this.m_impulse)); - this.m_impulse += impulse; - var PX = impulse * this.m_u.x; - var PY = impulse * this.m_u.y; - bA.m_linearVelocity.x -= bA.m_invMass * PX; - bA.m_linearVelocity.y -= bA.m_invMass * PY; - bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); - bB.m_linearVelocity.x += bB.m_invMass * PX; - bB.m_linearVelocity.y += bB.m_invMass * PY; - bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX); - } - b2DistanceJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var tMat; - if (this.m_frequencyHz > 0.0) { - return true; - } - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - var length = Math.sqrt(dX * dX + dY * dY); - dX /= length; - dY /= length; - var C = length - this.m_length; - C = b2Math.Clamp(C, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection); - var impulse = (-this.m_mass * C); - this.m_u.Set(dX, dY); - var PX = impulse * this.m_u.x; - var PY = impulse * this.m_u.y; - bA.m_sweep.c.x -= bA.m_invMass * PX; - bA.m_sweep.c.y -= bA.m_invMass * PY; - bA.m_sweep.a -= bA.m_invI * (r1X * PY - r1Y * PX); - bB.m_sweep.c.x += bB.m_invMass * PX; - bB.m_sweep.c.y += bB.m_invMass * PY; - bB.m_sweep.a += bB.m_invI * (r2X * PY - r2Y * PX); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return b2Math.Abs(C) < b2Settings.b2_linearSlop; - } - helpers.inherit.call(b2DistanceJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2DistanceJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2DistanceJointDef.b2DistanceJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2DistanceJointDef.prototype.b2DistanceJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_distanceJoint; - this.length = 1.0; - this.frequencyHz = 0.0; - this.dampingRatio = 0.0; - } - b2DistanceJointDef.prototype.Initialize = function (bA, bB, anchorA, anchorB) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchorA)); - this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchorB)); - var dX = anchorB.x - anchorA.x; - var dY = anchorB.y - anchorA.y; - this.length = Math.sqrt(dX * dX + dY * dY); - this.frequencyHz = 0.0; - this.dampingRatio = 0.0; - } - helpers.inherit.call(b2FrictionJoint, Box2D.Dynamics.Joints.b2Joint); - b2FrictionJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2FrictionJoint.b2FrictionJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchorA = new b2Vec2(); - this.m_localAnchorB = new b2Vec2(); - this.m_linearMass = new b2Mat22(); - this.m_linearImpulse = new b2Vec2(); - }; - b2FrictionJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchorA); - } - b2FrictionJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchorB); - } - b2FrictionJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_linearImpulse.x, inv_dt * this.m_linearImpulse.y); - } - b2FrictionJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_angularImpulse; - } - b2FrictionJoint.prototype.SetMaxForce = function (force) { - if (force === undefined) force = 0; - this.m_maxForce = force; - } - b2FrictionJoint.prototype.GetMaxForce = function () { - return this.m_maxForce; - } - b2FrictionJoint.prototype.SetMaxTorque = function (torque) { - if (torque === undefined) torque = 0; - this.m_maxTorque = torque; - } - b2FrictionJoint.prototype.GetMaxTorque = function () { - return this.m_maxTorque; - } - b2FrictionJoint.prototype.b2FrictionJoint = function (def) { - this.__super.b2Joint.call(this, def); - this.m_localAnchorA.SetV(def.localAnchorA); - this.m_localAnchorB.SetV(def.localAnchorB); - this.m_linearMass.SetZero(); - this.m_angularMass = 0.0; - this.m_linearImpulse.SetZero(); - this.m_angularImpulse = 0.0; - this.m_maxForce = def.maxForce; - this.m_maxTorque = def.maxTorque; - } - b2FrictionJoint.prototype.InitVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - var K = new b2Mat22(); - K.col1.x = mA + mB; - K.col2.x = 0.0; - K.col1.y = 0.0; - K.col2.y = mA + mB; - K.col1.x += iA * rAY * rAY; - K.col2.x += (-iA * rAX * rAY); - K.col1.y += (-iA * rAX * rAY); - K.col2.y += iA * rAX * rAX; - K.col1.x += iB * rBY * rBY; - K.col2.x += (-iB * rBX * rBY); - K.col1.y += (-iB * rBX * rBY); - K.col2.y += iB * rBX * rBX; - K.GetInverse(this.m_linearMass); - this.m_angularMass = iA + iB; - if (this.m_angularMass > 0.0) { - this.m_angularMass = 1.0 / this.m_angularMass; - } - if (step.warmStarting) { - this.m_linearImpulse.x *= step.dtRatio; - this.m_linearImpulse.y *= step.dtRatio; - this.m_angularImpulse *= step.dtRatio; - var P = this.m_linearImpulse; - bA.m_linearVelocity.x -= mA * P.x; - bA.m_linearVelocity.y -= mA * P.y; - bA.m_angularVelocity -= iA * (rAX * P.y - rAY * P.x + this.m_angularImpulse); - bB.m_linearVelocity.x += mB * P.x; - bB.m_linearVelocity.y += mB * P.y; - bB.m_angularVelocity += iB * (rBX * P.y - rBY * P.x + this.m_angularImpulse); - } - else { - this.m_linearImpulse.SetZero(); - this.m_angularImpulse = 0.0; - } - } - b2FrictionJoint.prototype.SolveVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var vA = bA.m_linearVelocity; - var wA = bA.m_angularVelocity; - var vB = bB.m_linearVelocity; - var wB = bB.m_angularVelocity; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var maxImpulse = 0; { - var Cdot = wB - wA; - var impulse = (-this.m_angularMass * Cdot); - var oldImpulse = this.m_angularImpulse; - maxImpulse = step.dt * this.m_maxTorque; - this.m_angularImpulse = b2Math.Clamp(this.m_angularImpulse + impulse, (-maxImpulse), maxImpulse); - impulse = this.m_angularImpulse - oldImpulse; - wA -= iA * impulse; - wB += iB * impulse; - } { - var CdotX = vB.x - wB * rBY - vA.x + wA * rAY; - var CdotY = vB.y + wB * rBX - vA.y - wA * rAX; - var impulseV = b2Math.MulMV(this.m_linearMass, new b2Vec2((-CdotX), (-CdotY))); - var oldImpulseV = this.m_linearImpulse.Copy(); - this.m_linearImpulse.Add(impulseV); - maxImpulse = step.dt * this.m_maxForce; - if (this.m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) { - this.m_linearImpulse.Normalize(); - this.m_linearImpulse.Multiply(maxImpulse); - } - impulseV = b2Math.SubtractVV(this.m_linearImpulse, oldImpulseV); - vA.x -= mA * impulseV.x; - vA.y -= mA * impulseV.y; - wA -= iA * (rAX * impulseV.y - rAY * impulseV.x); - vB.x += mB * impulseV.x; - vB.y += mB * impulseV.y; - wB += iB * (rBX * impulseV.y - rBY * impulseV.x); - } - bA.m_angularVelocity = wA; - bB.m_angularVelocity = wB; - } - b2FrictionJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - return true; - } - helpers.inherit.call(b2FrictionJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2FrictionJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2FrictionJointDef.b2FrictionJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2FrictionJointDef.prototype.b2FrictionJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_frictionJoint; - this.maxForce = 0.0; - this.maxTorque = 0.0; - } - b2FrictionJointDef.prototype.Initialize = function (bA, bB, anchor) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); - this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)); - } - helpers.inherit.call(b2GearJoint, Box2D.Dynamics.Joints.b2Joint); - b2GearJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2GearJoint.b2GearJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_groundAnchor1 = new b2Vec2(); - this.m_groundAnchor2 = new b2Vec2(); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_J = new b2Jacobian(); - }; - b2GearJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2GearJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2GearJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse * this.m_J.linearB.x, inv_dt * this.m_impulse * this.m_J.linearB.y); - } - b2GearJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - var tMat = this.m_bodyB.m_xf.R; - var rX = this.m_localAnchor1.x - this.m_bodyB.m_sweep.localCenter.x; - var rY = this.m_localAnchor1.y - this.m_bodyB.m_sweep.localCenter.y; - var tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - var PX = this.m_impulse * this.m_J.linearB.x; - var PY = this.m_impulse * this.m_J.linearB.y; - return inv_dt * (this.m_impulse * this.m_J.angularB - rX * PY + rY * PX); - } - b2GearJoint.prototype.GetRatio = function () { - return this.m_ratio; - } - b2GearJoint.prototype.SetRatio = function (ratio) { - if (ratio === undefined) ratio = 0; - this.m_ratio = ratio; - } - b2GearJoint.prototype.b2GearJoint = function (def) { - this.__super.b2Joint.call(this, def); - var type1 = parseInt(def.joint1.m_type); - var type2 = parseInt(def.joint2.m_type); - this.m_revolute1 = null; - this.m_prismatic1 = null; - this.m_revolute2 = null; - this.m_prismatic2 = null; - var coordinate1 = 0; - var coordinate2 = 0; - this.m_ground1 = def.joint1.GetBodyA(); - this.m_bodyA = def.joint1.GetBodyB(); - if (type1 == b2Joint.e_revoluteJoint) { - this.m_revolute1 = (def.joint1 instanceof b2RevoluteJoint ? def.joint1 : null); - this.m_groundAnchor1.SetV(this.m_revolute1.m_localAnchor1); - this.m_localAnchor1.SetV(this.m_revolute1.m_localAnchor2); - coordinate1 = this.m_revolute1.GetJointAngle(); - } - else { - this.m_prismatic1 = (def.joint1 instanceof b2PrismaticJoint ? def.joint1 : null); - this.m_groundAnchor1.SetV(this.m_prismatic1.m_localAnchor1); - this.m_localAnchor1.SetV(this.m_prismatic1.m_localAnchor2); - coordinate1 = this.m_prismatic1.GetJointTranslation(); - } - this.m_ground2 = def.joint2.GetBodyA(); - this.m_bodyB = def.joint2.GetBodyB(); - if (type2 == b2Joint.e_revoluteJoint) { - this.m_revolute2 = (def.joint2 instanceof b2RevoluteJoint ? def.joint2 : null); - this.m_groundAnchor2.SetV(this.m_revolute2.m_localAnchor1); - this.m_localAnchor2.SetV(this.m_revolute2.m_localAnchor2); - coordinate2 = this.m_revolute2.GetJointAngle(); - } - else { - this.m_prismatic2 = (def.joint2 instanceof b2PrismaticJoint ? def.joint2 : null); - this.m_groundAnchor2.SetV(this.m_prismatic2.m_localAnchor1); - this.m_localAnchor2.SetV(this.m_prismatic2.m_localAnchor2); - coordinate2 = this.m_prismatic2.GetJointTranslation(); - } - this.m_ratio = def.ratio; - this.m_constant = coordinate1 + this.m_ratio * coordinate2; - this.m_impulse = 0.0; - } - b2GearJoint.prototype.InitVelocityConstraints = function (step) { - var g1 = this.m_ground1; - var g2 = this.m_ground2; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var ugX = 0; - var ugY = 0; - var rX = 0; - var rY = 0; - var tMat; - var tVec; - var crug = 0; - var tX = 0; - var K = 0.0; - this.m_J.SetZero(); - if (this.m_revolute1) { - this.m_J.angularA = (-1.0); - K += bA.m_invI; - } - else { - tMat = g1.m_xf.R; - tVec = this.m_prismatic1.m_localXAxis1; - ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = bA.m_xf.R; - rX = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - rY = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - crug = rX * ugY - rY * ugX; - this.m_J.linearA.Set((-ugX), (-ugY)); - this.m_J.angularA = (-crug); - K += bA.m_invMass + bA.m_invI * crug * crug; - } - if (this.m_revolute2) { - this.m_J.angularB = (-this.m_ratio); - K += this.m_ratio * this.m_ratio * bB.m_invI; - } - else { - tMat = g2.m_xf.R; - tVec = this.m_prismatic2.m_localXAxis1; - ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = bB.m_xf.R; - rX = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - rY = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - crug = rX * ugY - rY * ugX; - this.m_J.linearB.Set((-this.m_ratio * ugX), (-this.m_ratio * ugY)); - this.m_J.angularB = (-this.m_ratio * crug); - K += this.m_ratio * this.m_ratio * (bB.m_invMass + bB.m_invI * crug * crug); - } - this.m_mass = K > 0.0 ? 1.0 / K : 0.0; - if (step.warmStarting) { - bA.m_linearVelocity.x += bA.m_invMass * this.m_impulse * this.m_J.linearA.x; - bA.m_linearVelocity.y += bA.m_invMass * this.m_impulse * this.m_J.linearA.y; - bA.m_angularVelocity += bA.m_invI * this.m_impulse * this.m_J.angularA; - bB.m_linearVelocity.x += bB.m_invMass * this.m_impulse * this.m_J.linearB.x; - bB.m_linearVelocity.y += bB.m_invMass * this.m_impulse * this.m_J.linearB.y; - bB.m_angularVelocity += bB.m_invI * this.m_impulse * this.m_J.angularB; - } - else { - this.m_impulse = 0.0; - } - } - b2GearJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var Cdot = this.m_J.Compute(bA.m_linearVelocity, bA.m_angularVelocity, bB.m_linearVelocity, bB.m_angularVelocity); - var impulse = (-this.m_mass * Cdot); - this.m_impulse += impulse; - bA.m_linearVelocity.x += bA.m_invMass * impulse * this.m_J.linearA.x; - bA.m_linearVelocity.y += bA.m_invMass * impulse * this.m_J.linearA.y; - bA.m_angularVelocity += bA.m_invI * impulse * this.m_J.angularA; - bB.m_linearVelocity.x += bB.m_invMass * impulse * this.m_J.linearB.x; - bB.m_linearVelocity.y += bB.m_invMass * impulse * this.m_J.linearB.y; - bB.m_angularVelocity += bB.m_invI * impulse * this.m_J.angularB; - } - b2GearJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var linearError = 0.0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var coordinate1 = 0; - var coordinate2 = 0; - if (this.m_revolute1) { - coordinate1 = this.m_revolute1.GetJointAngle(); - } - else { - coordinate1 = this.m_prismatic1.GetJointTranslation(); - } - if (this.m_revolute2) { - coordinate2 = this.m_revolute2.GetJointAngle(); - } - else { - coordinate2 = this.m_prismatic2.GetJointTranslation(); - } - var C = this.m_constant - (coordinate1 + this.m_ratio * coordinate2); - var impulse = (-this.m_mass * C); - bA.m_sweep.c.x += bA.m_invMass * impulse * this.m_J.linearA.x; - bA.m_sweep.c.y += bA.m_invMass * impulse * this.m_J.linearA.y; - bA.m_sweep.a += bA.m_invI * impulse * this.m_J.angularA; - bB.m_sweep.c.x += bB.m_invMass * impulse * this.m_J.linearB.x; - bB.m_sweep.c.y += bB.m_invMass * impulse * this.m_J.linearB.y; - bB.m_sweep.a += bB.m_invI * impulse * this.m_J.angularB; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return linearError < b2Settings.b2_linearSlop; - } - helpers.inherit.call(b2GearJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2GearJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2GearJointDef.b2GearJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - }; - b2GearJointDef.prototype.b2GearJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_gearJoint; - this.joint1 = null; - this.joint2 = null; - this.ratio = 1.0; - } - b2Jacobian.b2Jacobian = function () { - this.linearA = new b2Vec2(); - this.linearB = new b2Vec2(); - }; - b2Jacobian.prototype.SetZero = function () { - this.linearA.SetZero(); - this.angularA = 0.0; - this.linearB.SetZero(); - this.angularB = 0.0; - } - b2Jacobian.prototype.Set = function (x1, a1, x2, a2) { - if (a1 === undefined) a1 = 0; - if (a2 === undefined) a2 = 0; - this.linearA.SetV(x1); - this.angularA = a1; - this.linearB.SetV(x2); - this.angularB = a2; - } - b2Jacobian.prototype.Compute = function (x1, a1, x2, a2) { - if (a1 === undefined) a1 = 0; - if (a2 === undefined) a2 = 0; - return (this.linearA.x * x1.x + this.linearA.y * x1.y) + this.angularA * a1 + (this.linearB.x * x2.x + this.linearB.y * x2.y) + this.angularB * a2; - } - b2Joint.b2Joint = function () { - this.m_edgeA = new b2JointEdge(); - this.m_edgeB = new b2JointEdge(); - this.m_localCenterA = new b2Vec2(); - this.m_localCenterB = new b2Vec2(); - }; - b2Joint.prototype.GetType = function () { - return this.m_type; - } - b2Joint.prototype.GetAnchorA = function () { - return null; - } - b2Joint.prototype.GetAnchorB = function () { - return null; - } - b2Joint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return null; - } - b2Joint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return 0.0; - } - b2Joint.prototype.GetBodyA = function () { - return this.m_bodyA; - } - b2Joint.prototype.GetBodyB = function () { - return this.m_bodyB; - } - b2Joint.prototype.GetNext = function () { - return this.m_next; - } - b2Joint.prototype.GetUserData = function () { - return this.m_userData; - } - b2Joint.prototype.SetUserData = function (data) { - this.m_userData = data; - } - b2Joint.prototype.IsActive = function () { - return this.m_bodyA.IsActive() && this.m_bodyB.IsActive(); - } - b2Joint.prototype.Create = function (def, allocator) { - var joint = null; - switch (def.type) { - case b2Joint.e_distanceJoint: - { - joint = new b2DistanceJoint((def instanceof b2DistanceJointDef ? def : null)); - } - break; - case b2Joint.e_mouseJoint: - { - joint = new b2MouseJoint((def instanceof b2MouseJointDef ? def : null)); - } - break; - case b2Joint.e_prismaticJoint: - { - joint = new b2PrismaticJoint((def instanceof b2PrismaticJointDef ? def : null)); - } - break; - case b2Joint.e_revoluteJoint: - { - joint = new b2RevoluteJoint((def instanceof b2RevoluteJointDef ? def : null)); - } - break; - case b2Joint.e_pulleyJoint: - { - joint = new b2PulleyJoint((def instanceof b2PulleyJointDef ? def : null)); - } - break; - case b2Joint.e_gearJoint: - { - joint = new b2GearJoint((def instanceof b2GearJointDef ? def : null)); - } - break; - case b2Joint.e_lineJoint: - { - joint = new b2LineJoint((def instanceof b2LineJointDef ? def : null)); - } - break; - case b2Joint.e_weldJoint: - { - joint = new b2WeldJoint((def instanceof b2WeldJointDef ? def : null)); - } - break; - case b2Joint.e_frictionJoint: - { - joint = new b2FrictionJoint((def instanceof b2FrictionJointDef ? def : null)); - } - break; - default: - break; - } - return joint; - } - b2Joint.Create = b2Joint.prototype.Create; - b2Joint.prototype.Destroy = function (joint, allocator) {} - b2Joint.Destroy = b2Joint.prototype.Destroy; - b2Joint.prototype.b2Joint = function (def) { - b2Settings.b2Assert(def.bodyA != def.bodyB); - this.m_type = def.type; - this.m_prev = null; - this.m_next = null; - this.m_bodyA = def.bodyA; - this.m_bodyB = def.bodyB; - this.m_collideConnected = def.collideConnected; - this.m_islandFlag = false; - this.m_userData = def.userData; - } - b2Joint.prototype.InitVelocityConstraints = function (step) {} - b2Joint.prototype.SolveVelocityConstraints = function (step) {} - b2Joint.prototype.FinalizeVelocityConstraints = function () {} - b2Joint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - return false; - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.Joints.b2Joint.e_unknownJoint = 0; - Box2D.Dynamics.Joints.b2Joint.prototype.e_unknownJoint = Box2D.Dynamics.Joints.b2Joint.e_unknownJoint; - Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint = 1; - Box2D.Dynamics.Joints.b2Joint.prototype.e_revoluteJoint = Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint; - Box2D.Dynamics.Joints.b2Joint.e_prismaticJoint = 2; - Box2D.Dynamics.Joints.b2Joint.prototype.e_prismaticJoint = Box2D.Dynamics.Joints.b2Joint.e_prismaticJoint; - Box2D.Dynamics.Joints.b2Joint.e_distanceJoint = 3; - Box2D.Dynamics.Joints.b2Joint.prototype.e_distanceJoint = Box2D.Dynamics.Joints.b2Joint.e_distanceJoint; - Box2D.Dynamics.Joints.b2Joint.e_pulleyJoint = 4; - Box2D.Dynamics.Joints.b2Joint.prototype.e_pulleyJoint = Box2D.Dynamics.Joints.b2Joint.e_pulleyJoint; - Box2D.Dynamics.Joints.b2Joint.e_mouseJoint = 5; - Box2D.Dynamics.Joints.b2Joint.prototype.e_mouseJoint = Box2D.Dynamics.Joints.b2Joint.e_mouseJoint; - Box2D.Dynamics.Joints.b2Joint.e_gearJoint = 6; - Box2D.Dynamics.Joints.b2Joint.prototype.e_gearJoint = Box2D.Dynamics.Joints.b2Joint.e_gearJoint; - Box2D.Dynamics.Joints.b2Joint.e_lineJoint = 7; - Box2D.Dynamics.Joints.b2Joint.prototype.e_lineJoint = Box2D.Dynamics.Joints.b2Joint.e_lineJoint; - Box2D.Dynamics.Joints.b2Joint.e_weldJoint = 8; - Box2D.Dynamics.Joints.b2Joint.prototype.e_weldJoint = Box2D.Dynamics.Joints.b2Joint.e_weldJoint; - Box2D.Dynamics.Joints.b2Joint.e_frictionJoint = 9; - Box2D.Dynamics.Joints.b2Joint.prototype.e_frictionJoint = Box2D.Dynamics.Joints.b2Joint.e_frictionJoint; - Box2D.Dynamics.Joints.b2Joint.e_inactiveLimit = 0; - Box2D.Dynamics.Joints.b2Joint.prototype.e_inactiveLimit = Box2D.Dynamics.Joints.b2Joint.e_inactiveLimit; - Box2D.Dynamics.Joints.b2Joint.e_atLowerLimit = 1; - Box2D.Dynamics.Joints.b2Joint.prototype.e_atLowerLimit = Box2D.Dynamics.Joints.b2Joint.e_atLowerLimit; - Box2D.Dynamics.Joints.b2Joint.e_atUpperLimit = 2; - Box2D.Dynamics.Joints.b2Joint.prototype.e_atUpperLimit = Box2D.Dynamics.Joints.b2Joint.e_atUpperLimit; - Box2D.Dynamics.Joints.b2Joint.e_equalLimits = 3; - Box2D.Dynamics.Joints.b2Joint.prototype.e_equalLimits = Box2D.Dynamics.Joints.b2Joint.e_equalLimits; - }); - b2JointDef.b2JointDef = function () {}; - b2JointDef.prototype.b2JointDef = function () { - this.type = b2Joint.e_unknownJoint; - this.userData = null; - this.bodyA = null; - this.bodyB = null; - this.collideConnected = false; - } - b2JointEdge.b2JointEdge = function () {}; - helpers.inherit.call(b2LineJoint, Box2D.Dynamics.Joints.b2Joint); - b2LineJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2LineJoint.b2LineJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_localXAxis1 = new b2Vec2(); - this.m_localYAxis1 = new b2Vec2(); - this.m_axis = new b2Vec2(); - this.m_perp = new b2Vec2(); - this.m_K = new b2Mat22(); - this.m_impulse = new b2Vec2(); - }; - b2LineJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2LineJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2LineJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y)); - } - b2LineJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_impulse.y; - } - b2LineJoint.prototype.GetJointTranslation = function () { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var p1 = bA.GetWorldPoint(this.m_localAnchor1); - var p2 = bB.GetWorldPoint(this.m_localAnchor2); - var dX = p2.x - p1.x; - var dY = p2.y - p1.y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var translation = axis.x * dX + axis.y * dY; - return translation; - } - b2LineJoint.prototype.GetJointSpeed = function () { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var p1X = bA.m_sweep.c.x + r1X; - var p1Y = bA.m_sweep.c.y + r1Y; - var p2X = bB.m_sweep.c.x + r2X; - var p2Y = bB.m_sweep.c.y + r2Y; - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var v1 = bA.m_linearVelocity; - var v2 = bB.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var w2 = bB.m_angularVelocity; - var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X))); - return speed; - } - b2LineJoint.prototype.IsLimitEnabled = function () { - return this.m_enableLimit; - } - b2LineJoint.prototype.EnableLimit = function (flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableLimit = flag; - } - b2LineJoint.prototype.GetLowerLimit = function () { - return this.m_lowerTranslation; - } - b2LineJoint.prototype.GetUpperLimit = function () { - return this.m_upperTranslation; - } - b2LineJoint.prototype.SetLimits = function (lower, upper) { - if (lower === undefined) lower = 0; - if (upper === undefined) upper = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_lowerTranslation = lower; - this.m_upperTranslation = upper; - } - b2LineJoint.prototype.IsMotorEnabled = function () { - return this.m_enableMotor; - } - b2LineJoint.prototype.EnableMotor = function (flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableMotor = flag; - } - b2LineJoint.prototype.SetMotorSpeed = function (speed) { - if (speed === undefined) speed = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_motorSpeed = speed; - } - b2LineJoint.prototype.GetMotorSpeed = function () { - return this.m_motorSpeed; - } - b2LineJoint.prototype.SetMaxMotorForce = function (force) { - if (force === undefined) force = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_maxMotorForce = force; - } - b2LineJoint.prototype.GetMaxMotorForce = function () { - return this.m_maxMotorForce; - } - b2LineJoint.prototype.GetMotorForce = function () { - return this.m_motorImpulse; - } - b2LineJoint.prototype.b2LineJoint = function (def) { - this.__super.b2Joint.call(this, def); - var tMat; - var tX = 0; - var tY = 0; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_localXAxis1.SetV(def.localAxisA); - this.m_localYAxis1.x = (-this.m_localXAxis1.y); - this.m_localYAxis1.y = this.m_localXAxis1.x; - this.m_impulse.SetZero(); - this.m_motorMass = 0.0; - this.m_motorImpulse = 0.0; - this.m_lowerTranslation = def.lowerTranslation; - this.m_upperTranslation = def.upperTranslation; - this.m_maxMotorForce = def.maxMotorForce; - this.m_motorSpeed = def.motorSpeed; - this.m_enableLimit = def.enableLimit; - this.m_enableMotor = def.enableMotor; - this.m_limitState = this.e_inactiveLimit; - this.m_axis.SetZero(); - this.m_perp.SetZero(); - } - b2LineJoint.prototype.InitVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX = 0; - this.m_localCenterA.SetV(bA.GetLocalCenter()); - this.m_localCenterB.SetV(bB.GetLocalCenter()); - var xf1 = bA.GetTransform(); - var xf2 = bB.GetTransform(); - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - this.m_invMassA = bA.m_invMass; - this.m_invMassB = bB.m_invMass; - this.m_invIA = bA.m_invI; - this.m_invIB = bB.m_invI; { - this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; - this.m_motorMass = this.m_motorMass > Number.MIN_VALUE ? 1.0 / this.m_motorMass : 0.0; - } { - this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var m1 = this.m_invMassA; - var m2 = this.m_invMassB; - var i1 = this.m_invIA; - var i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - } - if (this.m_enableLimit) { - var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; - if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { - this.m_limitState = this.e_equalLimits; - } - else if (jointTransition <= this.m_lowerTranslation) { - if (this.m_limitState != this.e_atLowerLimit) { - this.m_limitState = this.e_atLowerLimit; - this.m_impulse.y = 0.0; - } - } - else if (jointTransition >= this.m_upperTranslation) { - if (this.m_limitState != this.e_atUpperLimit) { - this.m_limitState = this.e_atUpperLimit; - this.m_impulse.y = 0.0; - } - } - else { - this.m_limitState = this.e_inactiveLimit; - this.m_impulse.y = 0.0; - } - } - else { - this.m_limitState = this.e_inactiveLimit; - } - if (this.m_enableMotor == false) { - this.m_motorImpulse = 0.0; - } - if (step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_motorImpulse *= step.dtRatio; - var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x; - var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y; - var L1 = this.m_impulse.x * this.m_s1 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a1; - var L2 = this.m_impulse.x * this.m_s2 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a2; - bA.m_linearVelocity.x -= this.m_invMassA * PX; - bA.m_linearVelocity.y -= this.m_invMassA * PY; - bA.m_angularVelocity -= this.m_invIA * L1; - bB.m_linearVelocity.x += this.m_invMassB * PX; - bB.m_linearVelocity.y += this.m_invMassB * PY; - bB.m_angularVelocity += this.m_invIB * L2; - } - else { - this.m_impulse.SetZero(); - this.m_motorImpulse = 0.0; - } - } - b2LineJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var v1 = bA.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var v2 = bB.m_linearVelocity; - var w2 = bB.m_angularVelocity; - var PX = 0; - var PY = 0; - var L1 = 0; - var L2 = 0; - if (this.m_enableMotor && this.m_limitState != this.e_equalLimits) { - var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); - var oldImpulse = this.m_motorImpulse; - var maxImpulse = step.dt * this.m_maxMotorForce; - this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); - impulse = this.m_motorImpulse - oldImpulse; - PX = impulse * this.m_axis.x; - PY = impulse * this.m_axis.y; - L1 = impulse * this.m_a1; - L2 = impulse * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - var Cdot1 = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; - if (this.m_enableLimit && this.m_limitState != this.e_inactiveLimit) { - var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var f1 = this.m_impulse.Copy(); - var df = this.m_K.Solve(new b2Vec2(), (-Cdot1), (-Cdot2)); - this.m_impulse.Add(df); - if (this.m_limitState == this.e_atLowerLimit) { - this.m_impulse.y = b2Math.Max(this.m_impulse.y, 0.0); - } - else if (this.m_limitState == this.e_atUpperLimit) { - this.m_impulse.y = b2Math.Min(this.m_impulse.y, 0.0); - } - var b = (-Cdot1) - (this.m_impulse.y - f1.y) * this.m_K.col2.x; - var f2r = 0; - if (this.m_K.col1.x != 0.0) { - f2r = b / this.m_K.col1.x + f1.x; - } - else { - f2r = f1.x; - } - this.m_impulse.x = f2r; - df.x = this.m_impulse.x - f1.x; - df.y = this.m_impulse.y - f1.y; - PX = df.x * this.m_perp.x + df.y * this.m_axis.x; - PY = df.x * this.m_perp.y + df.y * this.m_axis.y; - L1 = df.x * this.m_s1 + df.y * this.m_a1; - L2 = df.x * this.m_s2 + df.y * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - else { - var df2 = 0; - if (this.m_K.col1.x != 0.0) { - df2 = ((-Cdot1)) / this.m_K.col1.x; - } - else { - df2 = 0.0; - } - this.m_impulse.x += df2; - PX = df2 * this.m_perp.x; - PY = df2 * this.m_perp.y; - L1 = df2 * this.m_s1; - L2 = df2 * this.m_s2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - bA.m_linearVelocity.SetV(v1); - bA.m_angularVelocity = w1; - bB.m_linearVelocity.SetV(v2); - bB.m_angularVelocity = w2; - } - b2LineJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var limitC = 0; - var oldLimitImpulse = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var c1 = bA.m_sweep.c; - var a1 = bA.m_sweep.a; - var c2 = bB.m_sweep.c; - var a2 = bB.m_sweep.a; - var tMat; - var tX = 0; - var m1 = 0; - var m2 = 0; - var i1 = 0; - var i2 = 0; - var linearError = 0.0; - var angularError = 0.0; - var active = false; - var C2 = 0.0; - var R1 = b2Mat22.FromAngle(a1); - var R2 = b2Mat22.FromAngle(a2); - tMat = R1; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = R2; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = c2.x + r2X - c1.x - r1X; - var dY = c2.y + r2Y - c1.y - r1Y; - if (this.m_enableLimit) { - this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - var translation = this.m_axis.x * dX + this.m_axis.y * dY; - if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { - C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection); - linearError = b2Math.Abs(translation); - active = true; - } - else if (translation <= this.m_lowerTranslation) { - C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - linearError = this.m_lowerTranslation - translation; - active = true; - } - else if (translation >= this.m_upperTranslation) { - C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection); - linearError = translation - this.m_upperTranslation; - active = true; - } - } - this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var impulse = new b2Vec2(); - var C1 = this.m_perp.x * dX + this.m_perp.y * dY; - linearError = b2Math.Max(linearError, b2Math.Abs(C1)); - angularError = 0.0; - if (active) { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - this.m_K.Solve(impulse, (-C1), (-C2)); - } - else { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - var impulse1 = 0; - if (k11 != 0.0) { - impulse1 = ((-C1)) / k11; - } - else { - impulse1 = 0.0; - } - impulse.x = impulse1; - impulse.y = 0.0; - } - var PX = impulse.x * this.m_perp.x + impulse.y * this.m_axis.x; - var PY = impulse.x * this.m_perp.y + impulse.y * this.m_axis.y; - var L1 = impulse.x * this.m_s1 + impulse.y * this.m_a1; - var L2 = impulse.x * this.m_s2 + impulse.y * this.m_a2; - c1.x -= this.m_invMassA * PX; - c1.y -= this.m_invMassA * PY; - a1 -= this.m_invIA * L1; - c2.x += this.m_invMassB * PX; - c2.y += this.m_invMassB * PY; - a2 += this.m_invIB * L2; - bA.m_sweep.a = a1; - bB.m_sweep.a = a2; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; - } - helpers.inherit.call(b2LineJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2LineJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2LineJointDef.b2LineJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - this.localAxisA = new b2Vec2(); - }; - b2LineJointDef.prototype.b2LineJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_lineJoint; - this.localAxisA.Set(1.0, 0.0); - this.enableLimit = false; - this.lowerTranslation = 0.0; - this.upperTranslation = 0.0; - this.enableMotor = false; - this.maxMotorForce = 0.0; - this.motorSpeed = 0.0; - } - b2LineJointDef.prototype.Initialize = function (bA, bB, anchor, axis) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA = this.bodyA.GetLocalPoint(anchor); - this.localAnchorB = this.bodyB.GetLocalPoint(anchor); - this.localAxisA = this.bodyA.GetLocalVector(axis); - } - helpers.inherit.call(b2MouseJoint, Box2D.Dynamics.Joints.b2Joint); - b2MouseJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2MouseJoint.b2MouseJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.K = new b2Mat22(); - this.K1 = new b2Mat22(); - this.K2 = new b2Mat22(); - this.m_localAnchor = new b2Vec2(); - this.m_target = new b2Vec2(); - this.m_impulse = new b2Vec2(); - this.m_mass = new b2Mat22(); - this.m_C = new b2Vec2(); - }; - b2MouseJoint.prototype.GetAnchorA = function () { - return this.m_target; - } - b2MouseJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor); - } - b2MouseJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y); - } - b2MouseJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return 0.0; - } - b2MouseJoint.prototype.GetTarget = function () { - return this.m_target; - } - b2MouseJoint.prototype.SetTarget = function (target) { - if (this.m_bodyB.IsAwake() == false) { - this.m_bodyB.SetAwake(true); - } - this.m_target = target; - } - b2MouseJoint.prototype.GetMaxForce = function () { - return this.m_maxForce; - } - b2MouseJoint.prototype.SetMaxForce = function (maxForce) { - if (maxForce === undefined) maxForce = 0; - this.m_maxForce = maxForce; - } - b2MouseJoint.prototype.GetFrequency = function () { - return this.m_frequencyHz; - } - b2MouseJoint.prototype.SetFrequency = function (hz) { - if (hz === undefined) hz = 0; - this.m_frequencyHz = hz; - } - b2MouseJoint.prototype.GetDampingRatio = function () { - return this.m_dampingRatio; - } - b2MouseJoint.prototype.SetDampingRatio = function (ratio) { - if (ratio === undefined) ratio = 0; - this.m_dampingRatio = ratio; - } - b2MouseJoint.prototype.b2MouseJoint = function (def) { - this.__super.b2Joint.call(this, def); - this.m_target.SetV(def.target); - var tX = this.m_target.x - this.m_bodyB.m_xf.position.x; - var tY = this.m_target.y - this.m_bodyB.m_xf.position.y; - var tMat = this.m_bodyB.m_xf.R; - this.m_localAnchor.x = (tX * tMat.col1.x + tY * tMat.col1.y); - this.m_localAnchor.y = (tX * tMat.col2.x + tY * tMat.col2.y); - this.m_maxForce = def.maxForce; - this.m_impulse.SetZero(); - this.m_frequencyHz = def.frequencyHz; - this.m_dampingRatio = def.dampingRatio; - this.m_beta = 0.0; - this.m_gamma = 0.0; - } - b2MouseJoint.prototype.InitVelocityConstraints = function (step) { - var b = this.m_bodyB; - var mass = b.GetMass(); - var omega = 2.0 * Math.PI * this.m_frequencyHz; - var d = 2.0 * mass * this.m_dampingRatio * omega; - var k = mass * omega * omega; - this.m_gamma = step.dt * (d + step.dt * k); - this.m_gamma = this.m_gamma != 0 ? 1 / this.m_gamma : 0.0; - this.m_beta = step.dt * k * this.m_gamma; - var tMat;tMat = b.m_xf.R; - var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; - var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; - var tX = (tMat.col1.x * rX + tMat.col2.x * rY);rY = (tMat.col1.y * rX + tMat.col2.y * rY); - rX = tX; - var invMass = b.m_invMass; - var invI = b.m_invI;this.K1.col1.x = invMass; - this.K1.col2.x = 0.0; - this.K1.col1.y = 0.0; - this.K1.col2.y = invMass; - this.K2.col1.x = invI * rY * rY; - this.K2.col2.x = (-invI * rX * rY); - this.K2.col1.y = (-invI * rX * rY); - this.K2.col2.y = invI * rX * rX; - this.K.SetM(this.K1); - this.K.AddM(this.K2); - this.K.col1.x += this.m_gamma; - this.K.col2.y += this.m_gamma; - this.K.GetInverse(this.m_mass); - this.m_C.x = b.m_sweep.c.x + rX - this.m_target.x; - this.m_C.y = b.m_sweep.c.y + rY - this.m_target.y; - b.m_angularVelocity *= 0.98; - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - b.m_linearVelocity.x += invMass * this.m_impulse.x; - b.m_linearVelocity.y += invMass * this.m_impulse.y; - b.m_angularVelocity += invI * (rX * this.m_impulse.y - rY * this.m_impulse.x); - } - b2MouseJoint.prototype.SolveVelocityConstraints = function (step) { - var b = this.m_bodyB; - var tMat; - var tX = 0; - var tY = 0; - tMat = b.m_xf.R; - var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; - var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; - tX = (tMat.col1.x * rX + tMat.col2.x * rY); - rY = (tMat.col1.y * rX + tMat.col2.y * rY); - rX = tX; - var CdotX = b.m_linearVelocity.x + ((-b.m_angularVelocity * rY)); - var CdotY = b.m_linearVelocity.y + (b.m_angularVelocity * rX); - tMat = this.m_mass; - tX = CdotX + this.m_beta * this.m_C.x + this.m_gamma * this.m_impulse.x; - tY = CdotY + this.m_beta * this.m_C.y + this.m_gamma * this.m_impulse.y; - var impulseX = (-(tMat.col1.x * tX + tMat.col2.x * tY)); - var impulseY = (-(tMat.col1.y * tX + tMat.col2.y * tY)); - var oldImpulseX = this.m_impulse.x; - var oldImpulseY = this.m_impulse.y; - this.m_impulse.x += impulseX; - this.m_impulse.y += impulseY; - var maxImpulse = step.dt * this.m_maxForce; - if (this.m_impulse.LengthSquared() > maxImpulse * maxImpulse) { - this.m_impulse.Multiply(maxImpulse / this.m_impulse.Length()); - } - impulseX = this.m_impulse.x - oldImpulseX; - impulseY = this.m_impulse.y - oldImpulseY; - b.m_linearVelocity.x += b.m_invMass * impulseX; - b.m_linearVelocity.y += b.m_invMass * impulseY; - b.m_angularVelocity += b.m_invI * (rX * impulseY - rY * impulseX); - } - b2MouseJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - return true; - } - helpers.inherit.call(b2MouseJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2MouseJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2MouseJointDef.b2MouseJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.target = new b2Vec2(); - }; - b2MouseJointDef.prototype.b2MouseJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_mouseJoint; - this.maxForce = 0.0; - this.frequencyHz = 5.0; - this.dampingRatio = 0.7; - } - helpers.inherit.call(b2PrismaticJoint, Box2D.Dynamics.Joints.b2Joint); - b2PrismaticJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2PrismaticJoint.b2PrismaticJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_localXAxis1 = new b2Vec2(); - this.m_localYAxis1 = new b2Vec2(); - this.m_axis = new b2Vec2(); - this.m_perp = new b2Vec2(); - this.m_K = new b2Mat33(); - this.m_impulse = new b2Vec3(); - }; - b2PrismaticJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2PrismaticJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2PrismaticJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y)); - } - b2PrismaticJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_impulse.y; - } - b2PrismaticJoint.prototype.GetJointTranslation = function () { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var p1 = bA.GetWorldPoint(this.m_localAnchor1); - var p2 = bB.GetWorldPoint(this.m_localAnchor2); - var dX = p2.x - p1.x; - var dY = p2.y - p1.y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var translation = axis.x * dX + axis.y * dY; - return translation; - } - b2PrismaticJoint.prototype.GetJointSpeed = function () { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var p1X = bA.m_sweep.c.x + r1X; - var p1Y = bA.m_sweep.c.y + r1Y; - var p2X = bB.m_sweep.c.x + r2X; - var p2Y = bB.m_sweep.c.y + r2Y; - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var v1 = bA.m_linearVelocity; - var v2 = bB.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var w2 = bB.m_angularVelocity; - var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X))); - return speed; - } - b2PrismaticJoint.prototype.IsLimitEnabled = function () { - return this.m_enableLimit; - } - b2PrismaticJoint.prototype.EnableLimit = function (flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableLimit = flag; - } - b2PrismaticJoint.prototype.GetLowerLimit = function () { - return this.m_lowerTranslation; - } - b2PrismaticJoint.prototype.GetUpperLimit = function () { - return this.m_upperTranslation; - } - b2PrismaticJoint.prototype.SetLimits = function (lower, upper) { - if (lower === undefined) lower = 0; - if (upper === undefined) upper = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_lowerTranslation = lower; - this.m_upperTranslation = upper; - } - b2PrismaticJoint.prototype.IsMotorEnabled = function () { - return this.m_enableMotor; - } - b2PrismaticJoint.prototype.EnableMotor = function (flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableMotor = flag; - } - b2PrismaticJoint.prototype.SetMotorSpeed = function (speed) { - if (speed === undefined) speed = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_motorSpeed = speed; - } - b2PrismaticJoint.prototype.GetMotorSpeed = function () { - return this.m_motorSpeed; - } - b2PrismaticJoint.prototype.SetMaxMotorForce = function (force) { - if (force === undefined) force = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_maxMotorForce = force; - } - b2PrismaticJoint.prototype.GetMotorForce = function () { - return this.m_motorImpulse; - } - b2PrismaticJoint.prototype.b2PrismaticJoint = function (def) { - this.__super.b2Joint.call(this, def); - var tMat; - var tX = 0; - var tY = 0; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_localXAxis1.SetV(def.localAxisA); - this.m_localYAxis1.x = (-this.m_localXAxis1.y); - this.m_localYAxis1.y = this.m_localXAxis1.x; - this.m_refAngle = def.referenceAngle; - this.m_impulse.SetZero(); - this.m_motorMass = 0.0; - this.m_motorImpulse = 0.0; - this.m_lowerTranslation = def.lowerTranslation; - this.m_upperTranslation = def.upperTranslation; - this.m_maxMotorForce = def.maxMotorForce; - this.m_motorSpeed = def.motorSpeed; - this.m_enableLimit = def.enableLimit; - this.m_enableMotor = def.enableMotor; - this.m_limitState = this.e_inactiveLimit; - this.m_axis.SetZero(); - this.m_perp.SetZero(); - } - b2PrismaticJoint.prototype.InitVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX = 0; - this.m_localCenterA.SetV(bA.GetLocalCenter()); - this.m_localCenterB.SetV(bB.GetLocalCenter()); - var xf1 = bA.GetTransform(); - var xf2 = bB.GetTransform(); - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - this.m_invMassA = bA.m_invMass; - this.m_invMassB = bB.m_invMass; - this.m_invIA = bA.m_invI; - this.m_invIB = bB.m_invI; { - this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; - if (this.m_motorMass > Number.MIN_VALUE) this.m_motorMass = 1.0 / this.m_motorMass; - } { - this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var m1 = this.m_invMassA; - var m2 = this.m_invMassB; - var i1 = this.m_invIA; - var i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; - this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = i1 + i2; - this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; - this.m_K.col3.x = this.m_K.col1.z; - this.m_K.col3.y = this.m_K.col2.z; - this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - } - if (this.m_enableLimit) { - var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; - if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { - this.m_limitState = this.e_equalLimits; - } - else if (jointTransition <= this.m_lowerTranslation) { - if (this.m_limitState != this.e_atLowerLimit) { - this.m_limitState = this.e_atLowerLimit; - this.m_impulse.z = 0.0; - } - } - else if (jointTransition >= this.m_upperTranslation) { - if (this.m_limitState != this.e_atUpperLimit) { - this.m_limitState = this.e_atUpperLimit; - this.m_impulse.z = 0.0; - } - } - else { - this.m_limitState = this.e_inactiveLimit; - this.m_impulse.z = 0.0; - } - } - else { - this.m_limitState = this.e_inactiveLimit; - } - if (this.m_enableMotor == false) { - this.m_motorImpulse = 0.0; - } - if (step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_motorImpulse *= step.dtRatio; - var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x; - var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y; - var L1 = this.m_impulse.x * this.m_s1 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a1; - var L2 = this.m_impulse.x * this.m_s2 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a2; - bA.m_linearVelocity.x -= this.m_invMassA * PX; - bA.m_linearVelocity.y -= this.m_invMassA * PY; - bA.m_angularVelocity -= this.m_invIA * L1; - bB.m_linearVelocity.x += this.m_invMassB * PX; - bB.m_linearVelocity.y += this.m_invMassB * PY; - bB.m_angularVelocity += this.m_invIB * L2; - } - else { - this.m_impulse.SetZero(); - this.m_motorImpulse = 0.0; - } - } - b2PrismaticJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var v1 = bA.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var v2 = bB.m_linearVelocity; - var w2 = bB.m_angularVelocity; - var PX = 0; - var PY = 0; - var L1 = 0; - var L2 = 0; - if (this.m_enableMotor && this.m_limitState != this.e_equalLimits) { - var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); - var oldImpulse = this.m_motorImpulse; - var maxImpulse = step.dt * this.m_maxMotorForce; - this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); - impulse = this.m_motorImpulse - oldImpulse; - PX = impulse * this.m_axis.x; - PY = impulse * this.m_axis.y; - L1 = impulse * this.m_a1; - L2 = impulse * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - var Cdot1X = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; - var Cdot1Y = w2 - w1; - if (this.m_enableLimit && this.m_limitState != this.e_inactiveLimit) { - var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var f1 = this.m_impulse.Copy(); - var df = this.m_K.Solve33(new b2Vec3(), (-Cdot1X), (-Cdot1Y), (-Cdot2)); - this.m_impulse.Add(df); - if (this.m_limitState == this.e_atLowerLimit) { - this.m_impulse.z = b2Math.Max(this.m_impulse.z, 0.0); - } - else if (this.m_limitState == this.e_atUpperLimit) { - this.m_impulse.z = b2Math.Min(this.m_impulse.z, 0.0); - } - var bX = (-Cdot1X) - (this.m_impulse.z - f1.z) * this.m_K.col3.x; - var bY = (-Cdot1Y) - (this.m_impulse.z - f1.z) * this.m_K.col3.y; - var f2r = this.m_K.Solve22(new b2Vec2(), bX, bY); - f2r.x += f1.x; - f2r.y += f1.y; - this.m_impulse.x = f2r.x; - this.m_impulse.y = f2r.y; - df.x = this.m_impulse.x - f1.x; - df.y = this.m_impulse.y - f1.y; - df.z = this.m_impulse.z - f1.z; - PX = df.x * this.m_perp.x + df.z * this.m_axis.x; - PY = df.x * this.m_perp.y + df.z * this.m_axis.y; - L1 = df.x * this.m_s1 + df.y + df.z * this.m_a1; - L2 = df.x * this.m_s2 + df.y + df.z * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - else { - var df2 = this.m_K.Solve22(new b2Vec2(), (-Cdot1X), (-Cdot1Y)); - this.m_impulse.x += df2.x; - this.m_impulse.y += df2.y; - PX = df2.x * this.m_perp.x; - PY = df2.x * this.m_perp.y; - L1 = df2.x * this.m_s1 + df2.y; - L2 = df2.x * this.m_s2 + df2.y; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - bA.m_linearVelocity.SetV(v1); - bA.m_angularVelocity = w1; - bB.m_linearVelocity.SetV(v2); - bB.m_angularVelocity = w2; - } - b2PrismaticJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var limitC = 0; - var oldLimitImpulse = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var c1 = bA.m_sweep.c; - var a1 = bA.m_sweep.a; - var c2 = bB.m_sweep.c; - var a2 = bB.m_sweep.a; - var tMat; - var tX = 0; - var m1 = 0; - var m2 = 0; - var i1 = 0; - var i2 = 0; - var linearError = 0.0; - var angularError = 0.0; - var active = false; - var C2 = 0.0; - var R1 = b2Mat22.FromAngle(a1); - var R2 = b2Mat22.FromAngle(a2); - tMat = R1; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = R2; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = c2.x + r2X - c1.x - r1X; - var dY = c2.y + r2Y - c1.y - r1Y; - if (this.m_enableLimit) { - this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - var translation = this.m_axis.x * dX + this.m_axis.y * dY; - if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { - C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection); - linearError = b2Math.Abs(translation); - active = true; - } - else if (translation <= this.m_lowerTranslation) { - C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - linearError = this.m_lowerTranslation - translation; - active = true; - } - else if (translation >= this.m_upperTranslation) { - C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection); - linearError = translation - this.m_upperTranslation; - active = true; - } - } - this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var impulse = new b2Vec3(); - var C1X = this.m_perp.x * dX + this.m_perp.y * dY; - var C1Y = a2 - a1 - this.m_refAngle; - linearError = b2Math.Max(linearError, b2Math.Abs(C1X)); - angularError = b2Math.Abs(C1Y); - if (active) { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; - this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = i1 + i2; - this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; - this.m_K.col3.x = this.m_K.col1.z; - this.m_K.col3.y = this.m_K.col2.z; - this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - this.m_K.Solve33(impulse, (-C1X), (-C1Y), (-C2)); - } - else { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - var k12 = i1 * this.m_s1 + i2 * this.m_s2; - var k22 = i1 + i2; - this.m_K.col1.Set(k11, k12, 0.0); - this.m_K.col2.Set(k12, k22, 0.0); - var impulse1 = this.m_K.Solve22(new b2Vec2(), (-C1X), (-C1Y)); - impulse.x = impulse1.x; - impulse.y = impulse1.y; - impulse.z = 0.0; - } - var PX = impulse.x * this.m_perp.x + impulse.z * this.m_axis.x; - var PY = impulse.x * this.m_perp.y + impulse.z * this.m_axis.y; - var L1 = impulse.x * this.m_s1 + impulse.y + impulse.z * this.m_a1; - var L2 = impulse.x * this.m_s2 + impulse.y + impulse.z * this.m_a2; - c1.x -= this.m_invMassA * PX; - c1.y -= this.m_invMassA * PY; - a1 -= this.m_invIA * L1; - c2.x += this.m_invMassB * PX; - c2.y += this.m_invMassB * PY; - a2 += this.m_invIB * L2; - bA.m_sweep.a = a1; - bB.m_sweep.a = a2; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; - } - helpers.inherit.call(b2PrismaticJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2PrismaticJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2PrismaticJointDef.b2PrismaticJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - this.localAxisA = new b2Vec2(); - }; - b2PrismaticJointDef.prototype.b2PrismaticJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_prismaticJoint; - this.localAxisA.Set(1.0, 0.0); - this.referenceAngle = 0.0; - this.enableLimit = false; - this.lowerTranslation = 0.0; - this.upperTranslation = 0.0; - this.enableMotor = false; - this.maxMotorForce = 0.0; - this.motorSpeed = 0.0; - } - b2PrismaticJointDef.prototype.Initialize = function (bA, bB, anchor, axis) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA = this.bodyA.GetLocalPoint(anchor); - this.localAnchorB = this.bodyB.GetLocalPoint(anchor); - this.localAxisA = this.bodyA.GetLocalVector(axis); - this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); - } - helpers.inherit.call(b2PulleyJoint, Box2D.Dynamics.Joints.b2Joint); - b2PulleyJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2PulleyJoint.b2PulleyJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_groundAnchor1 = new b2Vec2(); - this.m_groundAnchor2 = new b2Vec2(); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_u1 = new b2Vec2(); - this.m_u2 = new b2Vec2(); - }; - b2PulleyJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2PulleyJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2PulleyJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse * this.m_u2.x, inv_dt * this.m_impulse * this.m_u2.y); - } - b2PulleyJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return 0.0; - } - b2PulleyJoint.prototype.GetGroundAnchorA = function () { - var a = this.m_ground.m_xf.position.Copy(); - a.Add(this.m_groundAnchor1); - return a; - } - b2PulleyJoint.prototype.GetGroundAnchorB = function () { - var a = this.m_ground.m_xf.position.Copy(); - a.Add(this.m_groundAnchor2); - return a; - } - b2PulleyJoint.prototype.GetLength1 = function () { - var p = this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; - var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; - var dX = p.x - sX; - var dY = p.y - sY; - return Math.sqrt(dX * dX + dY * dY); - } - b2PulleyJoint.prototype.GetLength2 = function () { - var p = this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; - var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; - var dX = p.x - sX; - var dY = p.y - sY; - return Math.sqrt(dX * dX + dY * dY); - } - b2PulleyJoint.prototype.GetRatio = function () { - return this.m_ratio; - } - b2PulleyJoint.prototype.b2PulleyJoint = function (def) { - this.__super.b2Joint.call(this, def); - var tMat; - var tX = 0; - var tY = 0; - this.m_ground = this.m_bodyA.m_world.m_groundBody; - this.m_groundAnchor1.x = def.groundAnchorA.x - this.m_ground.m_xf.position.x; - this.m_groundAnchor1.y = def.groundAnchorA.y - this.m_ground.m_xf.position.y; - this.m_groundAnchor2.x = def.groundAnchorB.x - this.m_ground.m_xf.position.x; - this.m_groundAnchor2.y = def.groundAnchorB.y - this.m_ground.m_xf.position.y; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_ratio = def.ratio; - this.m_constant = def.lengthA + this.m_ratio * def.lengthB; - this.m_maxLength1 = b2Math.Min(def.maxLengthA, this.m_constant - this.m_ratio * b2PulleyJoint.b2_minPulleyLength); - this.m_maxLength2 = b2Math.Min(def.maxLengthB, (this.m_constant - b2PulleyJoint.b2_minPulleyLength) / this.m_ratio); - this.m_impulse = 0.0; - this.m_limitImpulse1 = 0.0; - this.m_limitImpulse2 = 0.0; - } - b2PulleyJoint.prototype.InitVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var p1X = bA.m_sweep.c.x + r1X; - var p1Y = bA.m_sweep.c.y + r1Y; - var p2X = bB.m_sweep.c.x + r2X; - var p2Y = bB.m_sweep.c.y + r2Y; - var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; - var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; - var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; - var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; - this.m_u1.Set(p1X - s1X, p1Y - s1Y); - this.m_u2.Set(p2X - s2X, p2Y - s2Y); - var length1 = this.m_u1.Length(); - var length2 = this.m_u2.Length(); - if (length1 > b2Settings.b2_linearSlop) { - this.m_u1.Multiply(1.0 / length1); - } - else { - this.m_u1.SetZero(); - } - if (length2 > b2Settings.b2_linearSlop) { - this.m_u2.Multiply(1.0 / length2); - } - else { - this.m_u2.SetZero(); - } - var C = this.m_constant - length1 - this.m_ratio * length2; - if (C > 0.0) { - this.m_state = this.e_inactiveLimit; - this.m_impulse = 0.0; - } - else { - this.m_state = this.e_atUpperLimit; - } - if (length1 < this.m_maxLength1) { - this.m_limitState1 = this.e_inactiveLimit; - this.m_limitImpulse1 = 0.0; - } - else { - this.m_limitState1 = this.e_atUpperLimit; - } - if (length2 < this.m_maxLength2) { - this.m_limitState2 = this.e_inactiveLimit; - this.m_limitImpulse2 = 0.0; - } - else { - this.m_limitState2 = this.e_atUpperLimit; - } - var cr1u1 = r1X * this.m_u1.y - r1Y * this.m_u1.x; - var cr2u2 = r2X * this.m_u2.y - r2Y * this.m_u2.x; - this.m_limitMass1 = bA.m_invMass + bA.m_invI * cr1u1 * cr1u1; - this.m_limitMass2 = bB.m_invMass + bB.m_invI * cr2u2 * cr2u2; - this.m_pulleyMass = this.m_limitMass1 + this.m_ratio * this.m_ratio * this.m_limitMass2; - this.m_limitMass1 = 1.0 / this.m_limitMass1; - this.m_limitMass2 = 1.0 / this.m_limitMass2; - this.m_pulleyMass = 1.0 / this.m_pulleyMass; - if (step.warmStarting) { - this.m_impulse *= step.dtRatio; - this.m_limitImpulse1 *= step.dtRatio; - this.m_limitImpulse2 *= step.dtRatio; - var P1X = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.x; - var P1Y = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.y; - var P2X = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.x; - var P2Y = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.y; - bA.m_linearVelocity.x += bA.m_invMass * P1X; - bA.m_linearVelocity.y += bA.m_invMass * P1Y; - bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); - bB.m_linearVelocity.x += bB.m_invMass * P2X; - bB.m_linearVelocity.y += bB.m_invMass * P2Y; - bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X); - } - else { - this.m_impulse = 0.0; - this.m_limitImpulse1 = 0.0; - this.m_limitImpulse2 = 0.0; - } - } - b2PulleyJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var v1X = 0; - var v1Y = 0; - var v2X = 0; - var v2Y = 0; - var P1X = 0; - var P1Y = 0; - var P2X = 0; - var P2Y = 0; - var Cdot = 0; - var impulse = 0; - var oldImpulse = 0; - if (this.m_state == this.e_atUpperLimit) { - v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y)); - v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X); - v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y)); - v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X); - Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y)) - this.m_ratio * (this.m_u2.x * v2X + this.m_u2.y * v2Y); - impulse = this.m_pulleyMass * ((-Cdot)); - oldImpulse = this.m_impulse; - this.m_impulse = b2Math.Max(0.0, this.m_impulse + impulse); - impulse = this.m_impulse - oldImpulse; - P1X = (-impulse * this.m_u1.x); - P1Y = (-impulse * this.m_u1.y); - P2X = (-this.m_ratio * impulse * this.m_u2.x); - P2Y = (-this.m_ratio * impulse * this.m_u2.y); - bA.m_linearVelocity.x += bA.m_invMass * P1X; - bA.m_linearVelocity.y += bA.m_invMass * P1Y; - bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); - bB.m_linearVelocity.x += bB.m_invMass * P2X; - bB.m_linearVelocity.y += bB.m_invMass * P2Y; - bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X); - } - if (this.m_limitState1 == this.e_atUpperLimit) { - v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y)); - v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X); - Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y)); - impulse = (-this.m_limitMass1 * Cdot); - oldImpulse = this.m_limitImpulse1; - this.m_limitImpulse1 = b2Math.Max(0.0, this.m_limitImpulse1 + impulse); - impulse = this.m_limitImpulse1 - oldImpulse; - P1X = (-impulse * this.m_u1.x); - P1Y = (-impulse * this.m_u1.y); - bA.m_linearVelocity.x += bA.m_invMass * P1X; - bA.m_linearVelocity.y += bA.m_invMass * P1Y; - bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); - } - if (this.m_limitState2 == this.e_atUpperLimit) { - v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y)); - v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X); - Cdot = (-(this.m_u2.x * v2X + this.m_u2.y * v2Y)); - impulse = (-this.m_limitMass2 * Cdot); - oldImpulse = this.m_limitImpulse2; - this.m_limitImpulse2 = b2Math.Max(0.0, this.m_limitImpulse2 + impulse); - impulse = this.m_limitImpulse2 - oldImpulse; - P2X = (-impulse * this.m_u2.x); - P2Y = (-impulse * this.m_u2.y); - bB.m_linearVelocity.x += bB.m_invMass * P2X; - bB.m_linearVelocity.y += bB.m_invMass * P2Y; - bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X); - } - } - b2PulleyJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; - var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; - var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; - var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; - var r1X = 0; - var r1Y = 0; - var r2X = 0; - var r2Y = 0; - var p1X = 0; - var p1Y = 0; - var p2X = 0; - var p2Y = 0; - var length1 = 0; - var length2 = 0; - var C = 0; - var impulse = 0; - var oldImpulse = 0; - var oldLimitPositionImpulse = 0; - var tX = 0; - var linearError = 0.0; - if (this.m_state == this.e_atUpperLimit) { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - p1X = bA.m_sweep.c.x + r1X; - p1Y = bA.m_sweep.c.y + r1Y; - p2X = bB.m_sweep.c.x + r2X; - p2Y = bB.m_sweep.c.y + r2Y; - this.m_u1.Set(p1X - s1X, p1Y - s1Y); - this.m_u2.Set(p2X - s2X, p2Y - s2Y); - length1 = this.m_u1.Length(); - length2 = this.m_u2.Length(); - if (length1 > b2Settings.b2_linearSlop) { - this.m_u1.Multiply(1.0 / length1); - } - else { - this.m_u1.SetZero(); - } - if (length2 > b2Settings.b2_linearSlop) { - this.m_u2.Multiply(1.0 / length2); - } - else { - this.m_u2.SetZero(); - } - C = this.m_constant - length1 - this.m_ratio * length2; - linearError = b2Math.Max(linearError, (-C)); - C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - impulse = (-this.m_pulleyMass * C); - p1X = (-impulse * this.m_u1.x); - p1Y = (-impulse * this.m_u1.y); - p2X = (-this.m_ratio * impulse * this.m_u2.x); - p2Y = (-this.m_ratio * impulse * this.m_u2.y); - bA.m_sweep.c.x += bA.m_invMass * p1X; - bA.m_sweep.c.y += bA.m_invMass * p1Y; - bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); - bB.m_sweep.c.x += bB.m_invMass * p2X; - bB.m_sweep.c.y += bB.m_invMass * p2Y; - bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - } - if (this.m_limitState1 == this.e_atUpperLimit) { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - p1X = bA.m_sweep.c.x + r1X; - p1Y = bA.m_sweep.c.y + r1Y; - this.m_u1.Set(p1X - s1X, p1Y - s1Y); - length1 = this.m_u1.Length(); - if (length1 > b2Settings.b2_linearSlop) { - this.m_u1.x *= 1.0 / length1; - this.m_u1.y *= 1.0 / length1; - } - else { - this.m_u1.SetZero(); - } - C = this.m_maxLength1 - length1; - linearError = b2Math.Max(linearError, (-C)); - C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - impulse = (-this.m_limitMass1 * C); - p1X = (-impulse * this.m_u1.x); - p1Y = (-impulse * this.m_u1.y); - bA.m_sweep.c.x += bA.m_invMass * p1X; - bA.m_sweep.c.y += bA.m_invMass * p1Y; - bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); - bA.SynchronizeTransform(); - } - if (this.m_limitState2 == this.e_atUpperLimit) { - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - p2X = bB.m_sweep.c.x + r2X; - p2Y = bB.m_sweep.c.y + r2Y; - this.m_u2.Set(p2X - s2X, p2Y - s2Y); - length2 = this.m_u2.Length(); - if (length2 > b2Settings.b2_linearSlop) { - this.m_u2.x *= 1.0 / length2; - this.m_u2.y *= 1.0 / length2; - } - else { - this.m_u2.SetZero(); - } - C = this.m_maxLength2 - length2; - linearError = b2Math.Max(linearError, (-C)); - C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - impulse = (-this.m_limitMass2 * C); - p2X = (-impulse * this.m_u2.x); - p2Y = (-impulse * this.m_u2.y); - bB.m_sweep.c.x += bB.m_invMass * p2X; - bB.m_sweep.c.y += bB.m_invMass * p2Y; - bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); - bB.SynchronizeTransform(); - } - return linearError < b2Settings.b2_linearSlop; - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.Joints.b2PulleyJoint.b2_minPulleyLength = 2.0; - Box2D.Dynamics.Joints.b2PulleyJoint.prototype.b2_minPulleyLength = Box2D.Dynamics.Joints.b2PulleyJoint.b2_minPulleyLength; - }); - helpers.inherit.call(b2PulleyJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2PulleyJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2PulleyJointDef.b2PulleyJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.groundAnchorA = new b2Vec2(); - this.groundAnchorB = new b2Vec2(); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2PulleyJointDef.prototype.b2PulleyJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_pulleyJoint; - this.groundAnchorA.Set((-1.0), 1.0); - this.groundAnchorB.Set(1.0, 1.0); - this.localAnchorA.Set((-1.0), 0.0); - this.localAnchorB.Set(1.0, 0.0); - this.lengthA = 0.0; - this.maxLengthA = 0.0; - this.lengthB = 0.0; - this.maxLengthB = 0.0; - this.ratio = 1.0; - this.collideConnected = true; - } - b2PulleyJointDef.prototype.Initialize = function (bA, bB, gaA, gaB, anchorA, anchorB, r) { - if (r === undefined) r = 0; - this.bodyA = bA; - this.bodyB = bB; - this.groundAnchorA.SetV(gaA); - this.groundAnchorB.SetV(gaB); - this.localAnchorA = this.bodyA.GetLocalPoint(anchorA); - this.localAnchorB = this.bodyB.GetLocalPoint(anchorB); - var d1X = anchorA.x - gaA.x; - var d1Y = anchorA.y - gaA.y; - this.lengthA = Math.sqrt(d1X * d1X + d1Y * d1Y); - var d2X = anchorB.x - gaB.x; - var d2Y = anchorB.y - gaB.y; - this.lengthB = Math.sqrt(d2X * d2X + d2Y * d2Y); - this.ratio = r; - var C = this.lengthA + this.ratio * this.lengthB; - this.maxLengthA = C - this.ratio * b2PulleyJoint.b2_minPulleyLength; - this.maxLengthB = (C - b2PulleyJoint.b2_minPulleyLength) / this.ratio; - } - helpers.inherit.call(b2RevoluteJoint, Box2D.Dynamics.Joints.b2Joint); - b2RevoluteJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2RevoluteJoint.b2RevoluteJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.K = new b2Mat22(); - this.K1 = new b2Mat22(); - this.K2 = new b2Mat22(); - this.K3 = new b2Mat22(); - this.impulse3 = new b2Vec3(); - this.impulse2 = new b2Vec2(); - this.reduced = new b2Vec2(); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_impulse = new b2Vec3(); - this.m_mass = new b2Mat33(); - }; - b2RevoluteJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2RevoluteJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2RevoluteJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y); - } - b2RevoluteJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_impulse.z; - } - b2RevoluteJoint.prototype.GetJointAngle = function () { - return this.m_bodyB.m_sweep.a - this.m_bodyA.m_sweep.a - this.m_referenceAngle; - } - b2RevoluteJoint.prototype.GetJointSpeed = function () { - return this.m_bodyB.m_angularVelocity - this.m_bodyA.m_angularVelocity; - } - b2RevoluteJoint.prototype.IsLimitEnabled = function () { - return this.m_enableLimit; - } - b2RevoluteJoint.prototype.EnableLimit = function (flag) { - this.m_enableLimit = flag; - } - b2RevoluteJoint.prototype.GetLowerLimit = function () { - return this.m_lowerAngle; - } - b2RevoluteJoint.prototype.GetUpperLimit = function () { - return this.m_upperAngle; - } - b2RevoluteJoint.prototype.SetLimits = function (lower, upper) { - if (lower === undefined) lower = 0; - if (upper === undefined) upper = 0; - this.m_lowerAngle = lower; - this.m_upperAngle = upper; - } - b2RevoluteJoint.prototype.IsMotorEnabled = function () { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - return this.m_enableMotor; - } - b2RevoluteJoint.prototype.EnableMotor = function (flag) { - this.m_enableMotor = flag; - } - b2RevoluteJoint.prototype.SetMotorSpeed = function (speed) { - if (speed === undefined) speed = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_motorSpeed = speed; - } - b2RevoluteJoint.prototype.GetMotorSpeed = function () { - return this.m_motorSpeed; - } - b2RevoluteJoint.prototype.SetMaxMotorTorque = function (torque) { - if (torque === undefined) torque = 0; - this.m_maxMotorTorque = torque; - } - b2RevoluteJoint.prototype.GetMotorTorque = function () { - return this.m_maxMotorTorque; - } - b2RevoluteJoint.prototype.b2RevoluteJoint = function (def) { - this.__super.b2Joint.call(this, def); - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_referenceAngle = def.referenceAngle; - this.m_impulse.SetZero(); - this.m_motorImpulse = 0.0; - this.m_lowerAngle = def.lowerAngle; - this.m_upperAngle = def.upperAngle; - this.m_maxMotorTorque = def.maxMotorTorque; - this.m_motorSpeed = def.motorSpeed; - this.m_enableLimit = def.enableLimit; - this.m_enableMotor = def.enableMotor; - this.m_limitState = this.e_inactiveLimit; - } - b2RevoluteJoint.prototype.InitVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX = 0; - if (this.m_enableMotor || this.m_enableLimit) {} - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var m1 = bA.m_invMass; - var m2 = bB.m_invMass; - var i1 = bA.m_invI; - var i2 = bB.m_invI; - this.m_mass.col1.x = m1 + m2 + r1Y * r1Y * i1 + r2Y * r2Y * i2; - this.m_mass.col2.x = (-r1Y * r1X * i1) - r2Y * r2X * i2; - this.m_mass.col3.x = (-r1Y * i1) - r2Y * i2; - this.m_mass.col1.y = this.m_mass.col2.x; - this.m_mass.col2.y = m1 + m2 + r1X * r1X * i1 + r2X * r2X * i2; - this.m_mass.col3.y = r1X * i1 + r2X * i2; - this.m_mass.col1.z = this.m_mass.col3.x; - this.m_mass.col2.z = this.m_mass.col3.y; - this.m_mass.col3.z = i1 + i2; - this.m_motorMass = 1.0 / (i1 + i2); - if (this.m_enableMotor == false) { - this.m_motorImpulse = 0.0; - } - if (this.m_enableLimit) { - var jointAngle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; - if (b2Math.Abs(this.m_upperAngle - this.m_lowerAngle) < 2.0 * b2Settings.b2_angularSlop) { - this.m_limitState = this.e_equalLimits; - } - else if (jointAngle <= this.m_lowerAngle) { - if (this.m_limitState != this.e_atLowerLimit) { - this.m_impulse.z = 0.0; - } - this.m_limitState = this.e_atLowerLimit; - } - else if (jointAngle >= this.m_upperAngle) { - if (this.m_limitState != this.e_atUpperLimit) { - this.m_impulse.z = 0.0; - } - this.m_limitState = this.e_atUpperLimit; - } - else { - this.m_limitState = this.e_inactiveLimit; - this.m_impulse.z = 0.0; - } - } - else { - this.m_limitState = this.e_inactiveLimit; - } - if (step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_motorImpulse *= step.dtRatio; - var PX = this.m_impulse.x; - var PY = this.m_impulse.y; - bA.m_linearVelocity.x -= m1 * PX; - bA.m_linearVelocity.y -= m1 * PY; - bA.m_angularVelocity -= i1 * ((r1X * PY - r1Y * PX) + this.m_motorImpulse + this.m_impulse.z); - bB.m_linearVelocity.x += m2 * PX; - bB.m_linearVelocity.y += m2 * PY; - bB.m_angularVelocity += i2 * ((r2X * PY - r2Y * PX) + this.m_motorImpulse + this.m_impulse.z); - } - else { - this.m_impulse.SetZero(); - this.m_motorImpulse = 0.0; - } - } - b2RevoluteJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX = 0; - var newImpulse = 0; - var r1X = 0; - var r1Y = 0; - var r2X = 0; - var r2Y = 0; - var v1 = bA.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var v2 = bB.m_linearVelocity; - var w2 = bB.m_angularVelocity; - var m1 = bA.m_invMass; - var m2 = bB.m_invMass; - var i1 = bA.m_invI; - var i2 = bB.m_invI; - if (this.m_enableMotor && this.m_limitState != this.e_equalLimits) { - var Cdot = w2 - w1 - this.m_motorSpeed; - var impulse = this.m_motorMass * ((-Cdot)); - var oldImpulse = this.m_motorImpulse; - var maxImpulse = step.dt * this.m_maxMotorTorque; - this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); - impulse = this.m_motorImpulse - oldImpulse; - w1 -= i1 * impulse; - w2 += i2 * impulse; - } - if (this.m_enableLimit && this.m_limitState != this.e_inactiveLimit) { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var Cdot1X = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y)); - var Cdot1Y = v2.y + (w2 * r2X) - v1.y - (w1 * r1X); - var Cdot2 = w2 - w1; - this.m_mass.Solve33(this.impulse3, (-Cdot1X), (-Cdot1Y), (-Cdot2)); - if (this.m_limitState == this.e_equalLimits) { - this.m_impulse.Add(this.impulse3); - } - else if (this.m_limitState == this.e_atLowerLimit) { - newImpulse = this.m_impulse.z + this.impulse3.z; - if (newImpulse < 0.0) { - this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y)); - this.impulse3.x = this.reduced.x; - this.impulse3.y = this.reduced.y; - this.impulse3.z = (-this.m_impulse.z); - this.m_impulse.x += this.reduced.x; - this.m_impulse.y += this.reduced.y; - this.m_impulse.z = 0.0; - } - } - else if (this.m_limitState == this.e_atUpperLimit) { - newImpulse = this.m_impulse.z + this.impulse3.z; - if (newImpulse > 0.0) { - this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y)); - this.impulse3.x = this.reduced.x; - this.impulse3.y = this.reduced.y; - this.impulse3.z = (-this.m_impulse.z); - this.m_impulse.x += this.reduced.x; - this.m_impulse.y += this.reduced.y; - this.m_impulse.z = 0.0; - } - } - v1.x -= m1 * this.impulse3.x; - v1.y -= m1 * this.impulse3.y; - w1 -= i1 * (r1X * this.impulse3.y - r1Y * this.impulse3.x + this.impulse3.z); - v2.x += m2 * this.impulse3.x; - v2.y += m2 * this.impulse3.y; - w2 += i2 * (r2X * this.impulse3.y - r2Y * this.impulse3.x + this.impulse3.z); - } - else { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var CdotX = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y)); - var CdotY = v2.y + (w2 * r2X) - v1.y - (w1 * r1X); - this.m_mass.Solve22(this.impulse2, (-CdotX), (-CdotY)); - this.m_impulse.x += this.impulse2.x; - this.m_impulse.y += this.impulse2.y; - v1.x -= m1 * this.impulse2.x; - v1.y -= m1 * this.impulse2.y; - w1 -= i1 * (r1X * this.impulse2.y - r1Y * this.impulse2.x); - v2.x += m2 * this.impulse2.x; - v2.y += m2 * this.impulse2.y; - w2 += i2 * (r2X * this.impulse2.y - r2Y * this.impulse2.x); - } - bA.m_linearVelocity.SetV(v1); - bA.m_angularVelocity = w1; - bB.m_linearVelocity.SetV(v2); - bB.m_angularVelocity = w2; - } - b2RevoluteJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var oldLimitImpulse = 0; - var C = 0; - var tMat; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var angularError = 0.0; - var positionError = 0.0; - var tX = 0; - var impulseX = 0; - var impulseY = 0; - if (this.m_enableLimit && this.m_limitState != this.e_inactiveLimit) { - var angle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; - var limitImpulse = 0.0; - if (this.m_limitState == this.e_equalLimits) { - C = b2Math.Clamp(angle - this.m_lowerAngle, (-b2Settings.b2_maxAngularCorrection), b2Settings.b2_maxAngularCorrection); - limitImpulse = (-this.m_motorMass * C); - angularError = b2Math.Abs(C); - } - else if (this.m_limitState == this.e_atLowerLimit) { - C = angle - this.m_lowerAngle; - angularError = (-C); - C = b2Math.Clamp(C + b2Settings.b2_angularSlop, (-b2Settings.b2_maxAngularCorrection), 0.0); - limitImpulse = (-this.m_motorMass * C); - } - else if (this.m_limitState == this.e_atUpperLimit) { - C = angle - this.m_upperAngle; - angularError = C; - C = b2Math.Clamp(C - b2Settings.b2_angularSlop, 0.0, b2Settings.b2_maxAngularCorrection); - limitImpulse = (-this.m_motorMass * C); - } - bA.m_sweep.a -= bA.m_invI * limitImpulse; - bB.m_sweep.a += bB.m_invI * limitImpulse; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - } { - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - var CLengthSquared = CX * CX + CY * CY; - var CLength = Math.sqrt(CLengthSquared); - positionError = CLength; - var invMass1 = bA.m_invMass; - var invMass2 = bB.m_invMass; - var invI1 = bA.m_invI; - var invI2 = bB.m_invI; - var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop; - if (CLengthSquared > k_allowedStretch * k_allowedStretch) { - var uX = CX / CLength; - var uY = CY / CLength; - var k = invMass1 + invMass2; - var m = 1.0 / k; - impulseX = m * ((-CX)); - impulseY = m * ((-CY)); - var k_beta = 0.5; - bA.m_sweep.c.x -= k_beta * invMass1 * impulseX; - bA.m_sweep.c.y -= k_beta * invMass1 * impulseY; - bB.m_sweep.c.x += k_beta * invMass2 * impulseX; - bB.m_sweep.c.y += k_beta * invMass2 * impulseY; - CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - } - this.K1.col1.x = invMass1 + invMass2; - this.K1.col2.x = 0.0; - this.K1.col1.y = 0.0; - this.K1.col2.y = invMass1 + invMass2; - this.K2.col1.x = invI1 * r1Y * r1Y; - this.K2.col2.x = (-invI1 * r1X * r1Y); - this.K2.col1.y = (-invI1 * r1X * r1Y); - this.K2.col2.y = invI1 * r1X * r1X; - this.K3.col1.x = invI2 * r2Y * r2Y; - this.K3.col2.x = (-invI2 * r2X * r2Y); - this.K3.col1.y = (-invI2 * r2X * r2Y); - this.K3.col2.y = invI2 * r2X * r2X; - this.K.SetM(this.K1); - this.K.AddM(this.K2); - this.K.AddM(this.K3); - this.K.Solve(b2RevoluteJoint.tImpulse, (-CX), (-CY)); - impulseX = b2RevoluteJoint.tImpulse.x; - impulseY = b2RevoluteJoint.tImpulse.y; - bA.m_sweep.c.x -= bA.m_invMass * impulseX; - bA.m_sweep.c.y -= bA.m_invMass * impulseY; - bA.m_sweep.a -= bA.m_invI * (r1X * impulseY - r1Y * impulseX); - bB.m_sweep.c.x += bB.m_invMass * impulseX; - bB.m_sweep.c.y += bB.m_invMass * impulseY; - bB.m_sweep.a += bB.m_invI * (r2X * impulseY - r2Y * impulseX); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - } - return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; - } - _A2J_postDefs.push(function () { - Box2D.Dynamics.Joints.b2RevoluteJoint.tImpulse = new b2Vec2(); - Box2D.Dynamics.Joints.b2RevoluteJoint.prototype.tImpulse = Box2D.Dynamics.Joints.b2RevoluteJoint.tImpulse; - }); - helpers.inherit.call(b2RevoluteJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2RevoluteJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2RevoluteJointDef.b2RevoluteJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2RevoluteJointDef.prototype.b2RevoluteJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_revoluteJoint; - this.localAnchorA.Set(0.0, 0.0); - this.localAnchorB.Set(0.0, 0.0); - this.referenceAngle = 0.0; - this.lowerAngle = 0.0; - this.upperAngle = 0.0; - this.maxMotorTorque = 0.0; - this.motorSpeed = 0.0; - this.enableLimit = false; - this.enableMotor = false; - } - b2RevoluteJointDef.prototype.Initialize = function (bA, bB, anchor) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA = this.bodyA.GetLocalPoint(anchor); - this.localAnchorB = this.bodyB.GetLocalPoint(anchor); - this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); - } - helpers.inherit.call(b2WeldJoint, Box2D.Dynamics.Joints.b2Joint); - b2WeldJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2WeldJoint.b2WeldJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchorA = new b2Vec2(); - this.m_localAnchorB = new b2Vec2(); - this.m_impulse = new b2Vec3(); - this.m_mass = new b2Mat33(); - }; - b2WeldJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchorA); - } - b2WeldJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchorB); - } - b2WeldJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y); - } - b2WeldJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_impulse.z; - } - b2WeldJoint.prototype.b2WeldJoint = function (def) { - this.__super.b2Joint.call(this, def); - this.m_localAnchorA.SetV(def.localAnchorA); - this.m_localAnchorB.SetV(def.localAnchorB); - this.m_referenceAngle = def.referenceAngle; - this.m_impulse.SetZero(); - this.m_mass = new b2Mat33(); - } - b2WeldJoint.prototype.InitVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; - this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB; - this.m_mass.col3.x = (-rAY * iA) - rBY * iB; - this.m_mass.col1.y = this.m_mass.col2.x; - this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; - this.m_mass.col3.y = rAX * iA + rBX * iB; - this.m_mass.col1.z = this.m_mass.col3.x; - this.m_mass.col2.z = this.m_mass.col3.y; - this.m_mass.col3.z = iA + iB; - if (step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_impulse.z *= step.dtRatio; - bA.m_linearVelocity.x -= mA * this.m_impulse.x; - bA.m_linearVelocity.y -= mA * this.m_impulse.y; - bA.m_angularVelocity -= iA * (rAX * this.m_impulse.y - rAY * this.m_impulse.x + this.m_impulse.z); - bB.m_linearVelocity.x += mB * this.m_impulse.x; - bB.m_linearVelocity.y += mB * this.m_impulse.y; - bB.m_angularVelocity += iB * (rBX * this.m_impulse.y - rBY * this.m_impulse.x + this.m_impulse.z); - } - else { - this.m_impulse.SetZero(); - } - } - b2WeldJoint.prototype.SolveVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var vA = bA.m_linearVelocity; - var wA = bA.m_angularVelocity; - var vB = bB.m_linearVelocity; - var wB = bB.m_angularVelocity; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var Cdot1X = vB.x - wB * rBY - vA.x + wA * rAY; - var Cdot1Y = vB.y + wB * rBX - vA.y - wA * rAX; - var Cdot2 = wB - wA; - var impulse = new b2Vec3(); - this.m_mass.Solve33(impulse, (-Cdot1X), (-Cdot1Y), (-Cdot2)); - this.m_impulse.Add(impulse); - vA.x -= mA * impulse.x; - vA.y -= mA * impulse.y; - wA -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); - vB.x += mB * impulse.x; - vB.y += mB * impulse.y; - wB += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); - bA.m_angularVelocity = wA; - bB.m_angularVelocity = wB; - } - b2WeldJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - var C1X = bB.m_sweep.c.x + rBX - bA.m_sweep.c.x - rAX; - var C1Y = bB.m_sweep.c.y + rBY - bA.m_sweep.c.y - rAY; - var C2 = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; - var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop; - var positionError = Math.sqrt(C1X * C1X + C1Y * C1Y); - var angularError = b2Math.Abs(C2); - if (positionError > k_allowedStretch) { - iA *= 1.0; - iB *= 1.0; - } - this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; - this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB; - this.m_mass.col3.x = (-rAY * iA) - rBY * iB; - this.m_mass.col1.y = this.m_mass.col2.x; - this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; - this.m_mass.col3.y = rAX * iA + rBX * iB; - this.m_mass.col1.z = this.m_mass.col3.x; - this.m_mass.col2.z = this.m_mass.col3.y; - this.m_mass.col3.z = iA + iB; - var impulse = new b2Vec3(); - this.m_mass.Solve33(impulse, (-C1X), (-C1Y), (-C2)); - bA.m_sweep.c.x -= mA * impulse.x; - bA.m_sweep.c.y -= mA * impulse.y; - bA.m_sweep.a -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); - bB.m_sweep.c.x += mB * impulse.x; - bB.m_sweep.c.y += mB * impulse.y; - bB.m_sweep.a += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; - } - helpers.inherit.call(b2WeldJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2WeldJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2WeldJointDef.b2WeldJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2WeldJointDef.prototype.b2WeldJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_weldJoint; - this.referenceAngle = 0.0; - } - b2WeldJointDef.prototype.Initialize = function (bA, bB, anchor) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); - this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)); - this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); - } -})(); -var Vector_a2j_Number = a2j.NVector; -//post-definitions -for (var i = 0; i < _A2J_postDefs.length; ++i) _A2J_postDefs[i]();(function() { - function b2DebugDraw() { - b2DebugDraw.b2DebugDraw.apply(this, arguments); - if (this.constructor === b2DebugDraw) this.b2DebugDraw.apply(this, arguments); - } - Box2D.Dynamics.b2DebugDraw = b2DebugDraw; -})(); -var _A2J_postDefs = []; -(function() { - var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; - b2DebugDraw.b2DebugDraw = function () { - this.m_drawScale = 1.0; - this.m_lineThickness = 1.0; - this.m_alpha = 1.0; - this.m_fillAlpha = 1.0; - this.m_xformScale = 1.0; - var __this = this; - //#WORKAROUND - this.m_sprite = {graphics: {clear: - function() {__this.m_ctx.clearRect(0,0,__this.m_ctx.canvas.width,__this.m_ctx.canvas.height)} - }}; - }; - b2DebugDraw.prototype._color = function(color, alpha) { - return "rgba("+ ((color & 0xFF0000) >> 16) +","+ ((color & 0xFF00) >> 8) +","+ - (color & 0xFF) +","+ alpha +")"; - }; - b2DebugDraw.prototype.b2DebugDraw = function () { - this.m_drawFlags = 0; - }; - b2DebugDraw.prototype.SetFlags = function (flags) { - if (flags === undefined) flags = 0; - this.m_drawFlags = flags; - }; - b2DebugDraw.prototype.GetFlags = function () { - return this.m_drawFlags; - }; - b2DebugDraw.prototype.AppendFlags = function (flags) { - if (flags === undefined) flags = 0; - this.m_drawFlags |= flags; - }; - b2DebugDraw.prototype.ClearFlags = function (flags) { - if (flags === undefined) flags = 0; - this.m_drawFlags &= ~flags; - }; - b2DebugDraw.prototype.SetSprite = function (sprite) { - this.m_ctx = sprite; - }; - b2DebugDraw.prototype.GetSprite = function () { - return this.m_ctx; - }; - b2DebugDraw.prototype.SetDrawScale = function (drawScale) { - if (drawScale === undefined) drawScale = 0; - this.m_drawScale = drawScale; - }; - b2DebugDraw.prototype.GetDrawScale = function () { - return this.m_drawScale; - }; - b2DebugDraw.prototype.SetLineThickness = function (lineThickness) { - if (lineThickness === undefined) lineThickness = 0; - this.m_lineThickness = lineThickness; - this.m_ctx.strokeWidth = lineThickness; - }; - b2DebugDraw.prototype.GetLineThickness = function () { - return this.m_lineThickness; - }; - b2DebugDraw.prototype.SetAlpha = function (alpha) { - if (alpha === undefined) alpha = 0; - this.m_alpha = alpha; - }; - b2DebugDraw.prototype.GetAlpha = function () { - return this.m_alpha; - }; - b2DebugDraw.prototype.SetFillAlpha = function (alpha) { - if (alpha === undefined) alpha = 0; - this.m_fillAlpha = alpha; - }; - b2DebugDraw.prototype.GetFillAlpha = function () { - return this.m_fillAlpha; - }; - b2DebugDraw.prototype.SetXFormScale = function (xformScale) { - if (xformScale === undefined) xformScale = 0; - this.m_xformScale = xformScale; - }; - b2DebugDraw.prototype.GetXFormScale = function () { - return this.m_xformScale; - }; - b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) { - if(!vertexCount) return; - var s = this.m_ctx; - var drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - for (var i = 1; i < vertexCount; i++) { - s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale); - } - s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - s.closePath(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) { - if(!vertexCount) return; - var s = this.m_ctx; - var drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.fillStyle = this._color(color.color, this.m_fillAlpha); - s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - for (var i = 1; i < vertexCount; i++) { - s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale); - } - s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - s.closePath(); - s.fill(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawCircle = function (center, radius, color) { - if(!radius) return; - var s = this.m_ctx; - var drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.arc(center.x * drawScale, center.y * drawScale, radius * drawScale, 0, Math.PI*2, true); - s.closePath(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) { - /*if (radius === undefined) radius = 0; - this.m_ctx.graphics.lineStyle(this.m_lineThickness, color.color, this.m_alpha); - this.m_ctx.graphics.moveTo(0, 0); - this.m_ctx.graphics.beginFill(color.color, this.m_fillAlpha); - this.m_ctx.graphics.drawCircle(center.x * this.m_drawScale, center.y * this.m_drawScale, radius * this.m_drawScale); - this.m_ctx.graphics.endFill(); - this.m_ctx.graphics.moveTo(center.x * this.m_drawScale, center.y * this.m_drawScale); - this.m_ctx.graphics.lineTo((center.x + axis.x * radius) * this.m_drawScale, (center.y + axis.y * radius) * this.m_drawScale); - */ - if(!radius) return; - var s = this.m_ctx - , drawScale = this.m_drawScale - , cx = center.x * drawScale - , cy = center.y * drawScale - ; - s.moveTo(0, 0); - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.fillStyle = this._color(color.color, this.m_fillAlpha); - s.arc(cx, cy, radius * drawScale, 0, Math.PI*2, true); - s.moveTo(cx, cy); - s.lineTo((center.x + axis.x * radius) * drawScale, (center.y + axis.y * radius) * drawScale); - s.closePath(); - s.fill(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) { - var s = this.m_ctx - , drawScale = this.m_drawScale - ; - s.strokeStyle = this._color(color.color, this.m_alpha); - s.beginPath(); - s.moveTo(p1.x * drawScale, p1.y * drawScale); - s.lineTo(p2.x * drawScale, p2.y * drawScale); - s.closePath(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawTransform = function (xf) { - var s = this.m_ctx - , drawScale = this.m_drawScale - ; - s.beginPath(); - s.strokeStyle = this._color(0xff0000, this.m_alpha); - s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale); - s.lineTo((xf.position.x + this.m_xformScale * xf.R.col1.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col1.y) * drawScale); - - s.strokeStyle = this._color(0xff00, this.m_alpha); - s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale); - s.lineTo((xf.position.x + this.m_xformScale * xf.R.col2.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col2.y) * drawScale); - s.closePath(); - s.stroke(); - }; - _A2J_postDefs.push(function () { - Box2D.Dynamics.b2DebugDraw.e_shapeBit = 0x0001; - Box2D.Dynamics.b2DebugDraw.prototype.e_shapeBit = Box2D.Dynamics.b2DebugDraw.e_shapeBit; - Box2D.Dynamics.b2DebugDraw.e_jointBit = 0x0002; - Box2D.Dynamics.b2DebugDraw.prototype.e_jointBit = Box2D.Dynamics.b2DebugDraw.e_jointBit; - Box2D.Dynamics.b2DebugDraw.e_aabbBit = 0x0004; - Box2D.Dynamics.b2DebugDraw.prototype.e_aabbBit = Box2D.Dynamics.b2DebugDraw.e_aabbBit; - Box2D.Dynamics.b2DebugDraw.e_pairBit = 0x0008; - Box2D.Dynamics.b2DebugDraw.prototype.e_pairBit = Box2D.Dynamics.b2DebugDraw.e_pairBit; - Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit = 0x0010; - Box2D.Dynamics.b2DebugDraw.prototype.e_centerOfMassBit = Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit; - Box2D.Dynamics.b2DebugDraw.e_controllerBit = 0x0020; - Box2D.Dynamics.b2DebugDraw.prototype.e_controllerBit = Box2D.Dynamics.b2DebugDraw.e_controllerBit; - }); -})(); - -//post-definitions -for (var i = 0; i < _A2J_postDefs.length; ++i) _A2J_postDefs[i](); - - -module.exports = Box2D + } + } + } + } + } + if(flags & b2DebugDraw.e_jointBit) { + for(j = this.m_jointList;j;j = j.m_next) { + this.DrawJoint(j) + } + } + if(flags & b2DebugDraw.e_controllerBit) { + for(var c = this.m_controllerList;c;c = c.m_next) { + c.Draw(this.m_debugDraw) + } + } + if(flags & b2DebugDraw.e_pairBit) { + color.Set(0.3, 0.9, 0.9); + for(var contact = this.m_contactManager.m_contactList;contact;contact = contact.GetNext()) { + var fixtureA = contact.GetFixtureA(); + var fixtureB = contact.GetFixtureB(); + var cA = fixtureA.GetAABB().GetCenter(); + var cB = fixtureB.GetAABB().GetCenter(); + this.m_debugDraw.DrawSegment(cA, cB, color) + } + } + if(flags & b2DebugDraw.e_aabbBit) { + bp = this.m_contactManager.m_broadPhase; + vs = [new b2Vec2, new b2Vec2, new b2Vec2, new b2Vec2]; + for(b = this.m_bodyList;b;b = b.GetNext()) { + if(b.IsActive() == false) { + continue + } + for(f = b.GetFixtureList();f;f = f.GetNext()) { + var aabb = bp.GetFatAABB(f.m_proxy); + vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y); + vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y); + vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); + vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); + this.m_debugDraw.DrawPolygon(vs, 4, color) + } + } + } + if(flags & b2DebugDraw.e_centerOfMassBit) { + for(b = this.m_bodyList;b;b = b.m_next) { + xf = b2World.s_xf; + xf.R = b.m_xf.R; + xf.position = b.GetWorldCenter(); + this.m_debugDraw.DrawTransform(xf) + } + } +}; +b2World.prototype.QueryAABB = function(callback, aabb) { + var broadPhase = this.m_contactManager.m_broadPhase; + function WorldQueryWrapper(proxy) { + return callback(broadPhase.GetUserData(proxy)) + } + broadPhase.Query(WorldQueryWrapper, aabb) +}; +b2World.prototype.QueryShape = function(callback, shape, transform) { + if(transform == null) { + transform = new b2Transform; + transform.SetIdentity() + } + var broadPhase = this.m_contactManager.m_broadPhase; + function WorldQueryWrapper(proxy) { + var fixture = broadPhase.GetUserData(proxy); + if(b2Shape.TestOverlap(shape, transform, fixture.GetShape(), fixture.GetBody().GetTransform())) { + return callback(fixture) + } + return true + } + var aabb = new b2AABB; + shape.ComputeAABB(aabb, transform); + broadPhase.Query(WorldQueryWrapper, aabb) +}; +b2World.prototype.QueryPoint = function(callback, p) { + var broadPhase = this.m_contactManager.m_broadPhase; + function WorldQueryWrapper(proxy) { + var fixture = broadPhase.GetUserData(proxy); + if(fixture.TestPoint(p)) { + return callback(fixture) + } + return true + } + var aabb = new b2AABB; + aabb.lowerBound.Set(p.x - b2Settings.b2_linearSlop, p.y - b2Settings.b2_linearSlop); + aabb.upperBound.Set(p.x + b2Settings.b2_linearSlop, p.y + b2Settings.b2_linearSlop); + broadPhase.Query(WorldQueryWrapper, aabb) +}; +b2World.prototype.RayCast = function(callback, point1, point2) { + var broadPhase = this.m_contactManager.m_broadPhase; + var output = new b2RayCastOutput; + function RayCastWrapper(input, proxy) { + var userData = broadPhase.GetUserData(proxy); + var fixture = userData; + var hit = fixture.RayCast(output, input); + if(hit) { + var fraction = output.fraction; + var point = new b2Vec2((1 - fraction) * point1.x + fraction * point2.x, (1 - fraction) * point1.y + fraction * point2.y); + return callback(fixture, point, output.normal, fraction) + } + return input.maxFraction + } + var input = new b2RayCastInput(point1, point2); + broadPhase.RayCast(RayCastWrapper, input) +}; +b2World.prototype.RayCastOne = function(point1, point2) { + var result; + function RayCastOneWrapper(fixture, point, normal, fraction) { + result = fixture; + return fraction + } + this.RayCast(RayCastOneWrapper, point1, point2); + return result +}; +b2World.prototype.RayCastAll = function(point1, point2) { + var result = new Array; + function RayCastAllWrapper(fixture, point, normal, fraction) { + result[result.length] = fixture; + return 1 + } + this.RayCast(RayCastAllWrapper, point1, point2); + return result +}; +b2World.prototype.GetBodyList = function() { + return this.m_bodyList +}; +b2World.prototype.GetJointList = function() { + return this.m_jointList +}; +b2World.prototype.GetContactList = function() { + return this.m_contactList +}; +b2World.prototype.IsLocked = function() { + return(this.m_flags & b2World.e_locked) > 0 +}; +b2World.prototype.s_stack = new Array; +b2World.prototype.m_flags = 0; +b2World.prototype.m_contactManager = new b2ContactManager; +b2World.prototype.m_contactSolver = new b2ContactSolver; +b2World.prototype.m_island = new b2Island; +b2World.prototype.m_bodyList = null; +b2World.prototype.m_jointList = null; +b2World.prototype.m_contactList = null; +b2World.prototype.m_bodyCount = 0; +b2World.prototype.m_contactCount = 0; +b2World.prototype.m_jointCount = 0; +b2World.prototype.m_controllerList = null; +b2World.prototype.m_controllerCount = 0; +b2World.prototype.m_gravity = null; +b2World.prototype.m_allowSleep = null; +b2World.prototype.m_groundBody = null; +b2World.prototype.m_destructionListener = null; +b2World.prototype.m_debugDraw = null; +b2World.prototype.m_inv_dt0 = null;if(typeof exports !== "undefined") { + exports.b2BoundValues = b2BoundValues; + exports.b2Math = b2Math; + exports.b2DistanceOutput = b2DistanceOutput; + exports.b2Mat33 = b2Mat33; + exports.b2ContactPoint = b2ContactPoint; + exports.b2PairManager = b2PairManager; + exports.b2PositionSolverManifold = b2PositionSolverManifold; + exports.b2OBB = b2OBB; + exports.b2CircleContact = b2CircleContact; + exports.b2PulleyJoint = b2PulleyJoint; + exports.b2Pair = b2Pair; + exports.b2TimeStep = b2TimeStep; + exports.b2FixtureDef = b2FixtureDef; + exports.b2World = b2World; + exports.b2PrismaticJoint = b2PrismaticJoint; + exports.b2Controller = b2Controller; + exports.b2ContactID = b2ContactID; + exports.b2RevoluteJoint = b2RevoluteJoint; + exports.b2JointDef = b2JointDef; + exports.b2Transform = b2Transform; + exports.b2GravityController = b2GravityController; + exports.b2EdgeAndCircleContact = b2EdgeAndCircleContact; + exports.b2EdgeShape = b2EdgeShape; + exports.b2BuoyancyController = b2BuoyancyController; + exports.b2LineJointDef = b2LineJointDef; + exports.b2Contact = b2Contact; + exports.b2DistanceJoint = b2DistanceJoint; + exports.b2Body = b2Body; + exports.b2DestructionListener = b2DestructionListener; + exports.b2PulleyJointDef = b2PulleyJointDef; + exports.b2ContactEdge = b2ContactEdge; + exports.b2ContactConstraint = b2ContactConstraint; + exports.b2ContactImpulse = b2ContactImpulse; + exports.b2DistanceJointDef = b2DistanceJointDef; + exports.b2ContactResult = b2ContactResult; + exports.b2EdgeChainDef = b2EdgeChainDef; + exports.b2Vec2 = b2Vec2; + exports.b2Vec3 = b2Vec3; + exports.b2DistanceProxy = b2DistanceProxy; + exports.b2FrictionJointDef = b2FrictionJointDef; + exports.b2PolygonContact = b2PolygonContact; + exports.b2TensorDampingController = b2TensorDampingController; + exports.b2ContactFactory = b2ContactFactory; + exports.b2WeldJointDef = b2WeldJointDef; + exports.b2ConstantAccelController = b2ConstantAccelController; + exports.b2GearJointDef = b2GearJointDef; + exports.ClipVertex = ClipVertex; + exports.b2SeparationFunction = b2SeparationFunction; + exports.b2ManifoldPoint = b2ManifoldPoint; + exports.b2Color = b2Color; + exports.b2PolygonShape = b2PolygonShape; + exports.b2DynamicTreePair = b2DynamicTreePair; + exports.b2ContactConstraintPoint = b2ContactConstraintPoint; + exports.b2FrictionJoint = b2FrictionJoint; + exports.b2ContactFilter = b2ContactFilter; + exports.b2ControllerEdge = b2ControllerEdge; + exports.b2Distance = b2Distance; + exports.b2Fixture = b2Fixture; + exports.b2DynamicTreeNode = b2DynamicTreeNode; + exports.b2MouseJoint = b2MouseJoint; + exports.b2DistanceInput = b2DistanceInput; + exports.b2BodyDef = b2BodyDef; + exports.b2DynamicTreeBroadPhase = b2DynamicTreeBroadPhase; + exports.b2Settings = b2Settings; + exports.b2Proxy = b2Proxy; + exports.b2Point = b2Point; + exports.b2BroadPhase = b2BroadPhase; + exports.b2Manifold = b2Manifold; + exports.b2WorldManifold = b2WorldManifold; + exports.b2PrismaticJointDef = b2PrismaticJointDef; + exports.b2RayCastOutput = b2RayCastOutput; + exports.b2ConstantForceController = b2ConstantForceController; + exports.b2TimeOfImpact = b2TimeOfImpact; + exports.b2CircleShape = b2CircleShape; + exports.b2MassData = b2MassData; + exports.b2Joint = b2Joint; + exports.b2GearJoint = b2GearJoint; + exports.b2DynamicTree = b2DynamicTree; + exports.b2JointEdge = b2JointEdge; + exports.b2LineJoint = b2LineJoint; + exports.b2NullContact = b2NullContact; + exports.b2ContactListener = b2ContactListener; + exports.b2RayCastInput = b2RayCastInput; + exports.b2TOIInput = b2TOIInput; + exports.Features = Features; + exports.b2FilterData = b2FilterData; + exports.b2Island = b2Island; + exports.b2ContactManager = b2ContactManager; + exports.b2ContactSolver = b2ContactSolver; + exports.b2Simplex = b2Simplex; + exports.b2AABB = b2AABB; + exports.b2Jacobian = b2Jacobian; + exports.b2Bound = b2Bound; + exports.b2RevoluteJointDef = b2RevoluteJointDef; + exports.b2PolyAndEdgeContact = b2PolyAndEdgeContact; + exports.b2SimplexVertex = b2SimplexVertex; + exports.b2WeldJoint = b2WeldJoint; + exports.b2Collision = b2Collision; + exports.b2Mat22 = b2Mat22; + exports.b2SimplexCache = b2SimplexCache; + exports.b2PolyAndCircleContact = b2PolyAndCircleContact; + exports.b2MouseJointDef = b2MouseJointDef; + exports.b2Shape = b2Shape; + exports.b2Segment = b2Segment; + exports.b2ContactRegister = b2ContactRegister; + exports.b2DebugDraw = b2DebugDraw; + exports.b2Sweep = b2Sweep +} +; From 939343fffaeb43c974e836620c2e82e20284c79d Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 22 Jan 2011 12:22:03 +1300 Subject: [PATCH 004/176] Refactored make script --- scripts/make.py | 245 ++++++++++++++++++++++++++++++---------------- scripts/module.js | 4 +- src/path.js | 2 +- 3 files changed, 161 insertions(+), 90 deletions(-) diff --git a/scripts/make.py b/scripts/make.py index b4ddc2e..fe9058b 100755 --- a/scripts/make.py +++ b/scripts/make.py @@ -2,117 +2,174 @@ from optparse import OptionParser from cStringIO import StringIO +from string import Template import re, os, base64, mimetypes, codecs try: import json except: import simplejson as json -TEXT_MIMETYPES = 'application/xml text/plain text/json application/json text/html'.split(' ') -CODE_MIMETYPES = 'text/javascript application/javascript application/x-javascript'.split(' ') - -IMAGE_RESOURCE_TEMPLATE = u'\nwindow.__resources__["%s"] = {meta: {mimetype: "%s"}, data: __imageResource("data:%s;base64,%s")};\n' -BINARY_RESOURCE_TEMPLATE = u'\nwindow.__resources__["%s"] = {meta: {mimetype: "%s"}, data: "%s"};\n' -TEXT_RESOURCE_TEMPLATE = u'\nwindow.__resources__["%s"] = {meta: {mimetype: "%s"}, data: %s};\n' -CODE_RESOURCE_TEMPLATE = u''' -window.__resources__['%s'] = {meta: {mimetype: "%s"}, data: function(exports, require, module, __filename, __dirname) { -%s -}}; -''' - mimetypes.add_type('application/xml', '.tmx') mimetypes.add_type('application/xml', '.tsx') mimetypes.add_type('application/xml', '.plist') -class Compiler: +TEXT_MIMETYPES = 'application/xml text/plain text/json application/json text/html'.split(' ') +CODE_MIMETYPES = 'text/javascript application/javascript application/x-javascript'.split(' ') + +RESOURCE_TEMPLATE = Template(u'__resources__["$resource"] = {meta: {mimetype: "$mimetype"}, data: $data};') + +class Compiler(object): config = None output = 'cocos2d.js' main_module = 'main' - header_code = u'' - footer_code = u'' - valid_extensions = None - - def __init__(self, config_file=None): - self.config = self.load_config(config_file) - - module_js = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'module.js') - self.footer_code = open(module_js).read() - self.header_code = u''' -if (!window.__resources__) { window.__resources__ = {}; } -if (!window.__imageResource) { window.__imageResource = function(data) { var img = new Image(); img.src = data; return img; }; } -var __main_module_name__ = %s -''' % json.dumps(self.main_module) - - def load_config(self, config_file): + extensions = ['js', 'tmx', 'tms', 'plist', 'gif', 'jpg', 'jpeg', 'png'] + header = u'' + footer = u'' + app_configs = ['cocos2d/src/libs/cocos2d/config.js', 'src/libs/cocos2d/config.js', 'libs/cocos2d/config.js', 'src/config.js'] + + def __init__(self, config='make.js'): + self.config = self.read_config(config) + print self.output + + def read_config(self, config_file): print "Loading config:", config_file - f = open(config_file, 'r') - config = json.loads(f.read()) + f = codecs.open(config_file, 'r', encoding='utf-8') + config = self.read_json_file(config_file) self.output = config['output'] self.main_module = config['main_module'] or 'main' - self.valid_extensions = config['extensions'] + self.extensions = config['extensions'] return config - + def make(self): - code = self.header_code + """ + Compile everything into a single script + """ + code = self.header + + # Prepend app globals needed for resources + code += '\n(function() {\n' + code += 'var __main_module_name__ = %s;\n' % json.dumps(self.main_module) + code += 'var __resources__ = [];\n' + code += 'function __imageResource(data) { var img = new Image(); img.src = data; return img; };\n' + for key, val in self.app_config().items(): + code += 'var %s = %s;\n' % (key.upper(), json.dumps(val)) + + + # Add all the code for source, dest in self.config['paths'].items(): - code += self.make_path(source, root_path=dest, include_header=False, include_footer=False) - code += self.footer_code + code += self.make_path(source, dest) + + + # Append module.js file -- this handles all the module loading + module_js_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'module.js') + code += codecs.open(module_js_path, 'r', encoding='utf-8').read() + + code += '\n})();\n' + + code += self.footer + return code - def make_path(self, source, strip_source=True, root_path='/', include_header=True, include_footer=False): - print "Building:", source - if not include_header: - code = '' - else: - code = self.header_code + def make_path(self, source_path, dest_path=None): + """ + Compile everything at a path and return the code + """ + if not dest_path: + dest_path = source_path + print 'Building Path:', source_path, ' => ', dest_path + + code = '' + files = self.scan_for_files(source_path) + for src_file in files: + if src_file in self.app_configs: + # Skip config files because they're JSON not JavaScript + continue + + dst_file = self.dst_for_src(src_file) + mimetype = mimetypes.guess_type(src_file)[0] + + print 'Building File:', src_file, ' => ', dst_file + code += '\n'; + code += RESOURCE_TEMPLATE.substitute({ + 'mimetype': mimetype, + 'resource': dst_file, + 'data': self.make_resource(src_file), + }) + + return code + + def dst_for_src(self, path): + for source, dest in self.config['paths'].items(): + if path.startswith(source): + return re.sub('\/+', '/', re.sub(r'^' + source.replace('/', '\\/'), dest, path)) + + return path - source = os.path.normpath(source) + def app_config(self): + """ + Reads all the app's config.js files and returns a dictionary of their values + """ + vals = {} + for config in self.app_configs: + if not os.path.exists(config): + continue - # If refrences to a single file we won't bother walking - if os.path.isfile(source): - f = source - if self.valid_extensions and os.path.splitext(f)[1][1:] not in self.valid_extensions: - print "Skipping:", f - return + data = self.read_json_file(config) + vals.update(data) - if strip_source: # Remove source path prefix - resource_name = '%s%s' % (root_path, f[len(source) +1:]) - else: - resource_name = '%s%s' % (root_path, f) - code += self.read_file(f, resource_name) + return vals + + def read_json_file(self, path): + j = codecs.open(path, 'r', encoding='utf-8').read() - else: # If it's a directory we'll include everything in it - for root, dirs, files in os.walk(source): - for f in files: - if f[0] == '.': - continue + # Strip comments + j = re.sub(r"\/\/.*", '', j) + j = re.sub(re.compile(r"\/\*.*?\*\/", re.DOTALL), '', j) - path = os.path.join(root, f) + # Fix unquoted keys + j = re.sub(r"{\s*(\w)", r'{"\1', j) + j = re.sub(r",\s*(\w)", r',"\1', j) + j = re.sub(r"(\w):", r'\1":', j) - if strip_source: # Remove source path prefix - resource_name = '%s%s' % (root_path, path[len(source) +1:]) - else: - resource_name = '%s%s' % (root_path, path) + # Fix trailing comma + j = re.sub(re.compile(r",\s+}", re.DOTALL), '}', j) - code += self.read_file(path, resource_name) + return json.loads(j) + def scan_for_files(self, path): + """ + Scan for files to build and return them as an array + """ + if os.path.isfile(path): + return [path] - if include_footer: - code += self.footer_code + found_files = [] - return code + for root, dirs, files in os.walk(path): + for f in files: + if f[0] == '.': + # Skip hidden files + continue - def read_file(self, filename, resource_name): - if self.valid_extensions and os.path.splitext(filename)[1][1:] not in self.valid_extensions: - print "Skipping:", filename - return '' + if self.extensions and os.path.splitext(f)[1][1:] not in self.extensions: + # Unwanted file extension + continue - resource_name = resource_name.replace('\\', '/') - print "Reading: '%s' --> '%s'" % (filename, resource_name) + full_path = os.path.join(root, f) + found_files.append(full_path) + + return found_files + + + + def make_resource(self, filename): + """ + Returns a resource string for adding to the __resources__ global + """ mimetype = mimetypes.guess_type(filename)[0] @@ -120,22 +177,36 @@ def read_file(self, filename, resource_name): is_text = (mimetype in TEXT_MIMETYPES) is_image = (mimetype.split('/')[0] == 'image') - data = StringIO() - if is_code: - file_code = codecs.open(filename, 'r', encoding='utf-8').read() - file_code = self.parse_supers(file_code) - code = CODE_RESOURCE_TEMPLATE % (resource_name, mimetype, file_code) + data = codecs.open(filename, 'r', encoding='utf-8').read() + data = self.parse_supers(data) + # Wrap code in function + data = "function(exports, require, module, __filename, __dirname) {\n%s\n}" % data elif is_text: - code = TEXT_RESOURCE_TEMPLATE % (resource_name, mimetype, json.dumps(open(filename, 'r').read())) + data = codecs.open(filename, 'r', encoding='utf-8').read() + # Escape text by converting to json + data = json.dumps(data) elif is_image: - base64.encode(open(filename, 'rb'), data) - code = IMAGE_RESOURCE_TEMPLATE % (resource_name, mimetype, mimetype, data.getvalue().replace('\n', '').replace('\r', '')) - else: # Binaries - base64.encode(open(filename, 'rb'), data) - code = BINARY_RESOURCE_TEMPLATE % (resource_name, mimetype, data.getvalue().replace('\n', '').replace('\r', '')) + data = open(filename, 'rb') + # Base64 encode image and create dataURL + data = self.b64(data) + data = '__imageResource("data:%s;base64,%s")' % (mimetype, data) + else: # is_binary + data = open(filename, 'rb') + data = self.b64(data) + data = '"%s"' % data + + return data + + def b64(self, data): + """ + Base 64 encode binary data + """ + output = StringIO() + data = base64.encode(data, output) - return code + # Remote whitespace from string + return re.sub('\s+', '', output.getvalue()) def parse_supers(self, code): """ @@ -168,7 +239,6 @@ def replace_super(matches): return code - def main(): parser = OptionParser(usage="Usage: cocos make [options]") parser.add_option("-c", "--config", dest="config", @@ -198,6 +268,7 @@ def main(): else: print code + if __name__ == "__main__": main() diff --git a/scripts/module.js b/scripts/module.js index 13ea1d7..9171671 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -1,5 +1,5 @@ function resource(path) { - return window.__resources__[path].data; + return __resources__[path].data; } (function() { @@ -103,7 +103,7 @@ function resource(path) { require.paths = modulePaths; require.main = process.mainModule; - window.__resources__[this.filename].data.apply(this.exports, [this.exports, require, this, this.filename, this.dirname]) + __resources__[this.filename].data.apply(this.exports, [this.exports, require, this, this.filename, this.dirname]) return this; } diff --git a/src/path.js b/src/path.js index 8931a0b..4b96c45 100644 --- a/src/path.js +++ b/src/path.js @@ -39,7 +39,7 @@ var path = { * @returns {Boolean} True if the path exists, false if not */ exists: function(path) { - return (window.__resources__[path] !== undefined); + return (__resources__[path] !== undefined); }, /** From 2720684d18e64439c2a57a133e6af3bb57de61af Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 22 Jan 2011 12:40:38 +1300 Subject: [PATCH 005/176] Added config option to invert Y axis --- src/libs/cocos2d/Director.js | 12 +++++++++++- src/libs/cocos2d/EventDispatcher.js | 6 ++++++ src/libs/cocos2d/TextureAtlas.js | 7 +++++++ src/libs/cocos2d/config.js | 7 +++++++ src/libs/cocos2d/nodes/Label.js | 13 +++++++++++++ src/libs/cocos2d/nodes/RenderTexture.js | 11 +++++++++-- src/libs/cocos2d/nodes/Sprite.js | 1 + src/libs/cocos2d/nodes/TMXLayer.js | 7 ++++++- 8 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/libs/cocos2d/config.js diff --git a/src/libs/cocos2d/Director.js b/src/libs/cocos2d/Director.js index c109a36..13db078 100644 --- a/src/libs/cocos2d/Director.js +++ b/src/libs/cocos2d/Director.js @@ -62,6 +62,11 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ var context = canvas.getContext('2d'); this.set('context', context); + if (FLIP_Y_AXIS) { + context.translate(0, view.clientHeight); + context.scale(1, -1); + } + view.appendChild(canvas); this.set('winSize', {width: view.clientWidth, height: view.clientHeight}); @@ -277,7 +282,12 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ y += o.offsetTop - o.scrollTop; } - return geo.ccpSub(evt.locationInWindow, ccp(x, y)); + var p = geo.ccpSub(evt.locationInWindow, ccp(x, y)); + if (FLIP_Y_AXIS) { + p.y = this.canvas.height - p.y; + } + + return p; }, showFPS: function() { diff --git a/src/libs/cocos2d/EventDispatcher.js b/src/libs/cocos2d/EventDispatcher.js index 10b7744..ab0a296 100644 --- a/src/libs/cocos2d/EventDispatcher.js +++ b/src/libs/cocos2d/EventDispatcher.js @@ -149,6 +149,9 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ if (this._previousMouseMovePosition) { evt.deltaX = evt.clientX - this._previousMouseMovePosition.x; evt.deltaY = evt.clientY - this._previousMouseMovePosition.y; + if (FLIP_Y_AXIS) { + evt.deltaY *= -1; + } } else { evt.deltaX = 0; evt.deltaY = 0; @@ -173,6 +176,9 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ if (this._previousMouseDragPosition) { evt.deltaX = evt.clientX - this._previousMouseDragPosition.x; evt.deltaY = evt.clientY - this._previousMouseDragPosition.y; + if (FLIP_Y_AXIS) { + evt.deltaY *= -1; + } } else { evt.deltaX = 0; evt.deltaY = 0; diff --git a/src/libs/cocos2d/TextureAtlas.js b/src/libs/cocos2d/TextureAtlas.js index ea92d15..a8ebbe9 100644 --- a/src/libs/cocos2d/TextureAtlas.js +++ b/src/libs/cocos2d/TextureAtlas.js @@ -75,8 +75,15 @@ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ dw = quad.drawRect.size.width, dh = quad.drawRect.size.height; + var scaleX = 1; var scaleY = 1; + + if (FLIP_Y_AXIS) { + dy -= dh; + dh *= -1; + } + if (dw < 0) { dw *= -1 diff --git a/src/libs/cocos2d/config.js b/src/libs/cocos2d/config.js new file mode 100644 index 0000000..fd86af5 --- /dev/null +++ b/src/libs/cocos2d/config.js @@ -0,0 +1,7 @@ +{ + // Invert the Y axis so origin is at the bottom left + FLIP_Y_AXIS: false, + + // No implemented yet + ENABLE_WEB_GL: false +} diff --git a/src/libs/cocos2d/nodes/Label.js b/src/libs/cocos2d/nodes/Label.js index cbe3559..655c282 100644 --- a/src/libs/cocos2d/nodes/Label.js +++ b/src/libs/cocos2d/nodes/Label.js @@ -46,6 +46,15 @@ var Label = Node.extend(/** @lends cocos.nodes.Label# */{ }, draw: function(context) { + if (FLIP_Y_AXIS) { + context.save(); + + // Flip Y axis + context.scale(1, -1); + context.translate(0, -this.get('fontSize')); + } + + context.fillStyle = this.get('fontColor'); context.font = this.get('font'); context.textBaseline = 'top'; @@ -54,6 +63,10 @@ var Label = Node.extend(/** @lends cocos.nodes.Label# */{ } else if (context.mozDrawText) { context.mozDrawText(this.get('string')); } + + if (FLIP_Y_AXIS) { + context.restore(); + } }, /** diff --git a/src/libs/cocos2d/nodes/RenderTexture.js b/src/libs/cocos2d/nodes/RenderTexture.js index 16117b1..f050f1d 100644 --- a/src/libs/cocos2d/nodes/RenderTexture.js +++ b/src/libs/cocos2d/nodes/RenderTexture.js @@ -40,8 +40,6 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ this.set('anchorPoint', ccp(0, 0)); this.sprite.set('anchorPoint', ccp(0, 0)); - - }, /** @@ -53,6 +51,11 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ canvas.width = size.width; canvas.height = size.height; + if (FLIP_Y_AXIS) { + this.context.scale(1, -1); + this.context.translate(0, -canvas.height); + } + var s = this.get('sprite'); if (s) { @@ -65,6 +68,10 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ */ clear: function() { this.canvas.width = this.canvas.width; + if (FLIP_Y_AXIS) { + this.context.scale(1, -1); + this.context.translate(0, -this.canvas.height); + } } }); diff --git a/src/libs/cocos2d/nodes/Sprite.js b/src/libs/cocos2d/nodes/Sprite.js index 83cd622..7a4b0e6 100644 --- a/src/libs/cocos2d/nodes/Sprite.js +++ b/src/libs/cocos2d/nodes/Sprite.js @@ -184,6 +184,7 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ this.quad.textureRect = util.copy(this.rect); this.quad.drawRect.origin = util.copy(offsetPosition); this.quad.drawRect.size = util.copy(this.rect.size); + if (this.flipX) { this.quad.drawRect.size.width *= -1; this.quad.drawRect.origin.x = -this.rect.size.width; diff --git a/src/libs/cocos2d/nodes/TMXLayer.js b/src/libs/cocos2d/nodes/TMXLayer.js index 39bfc7b..3f6b2f1 100644 --- a/src/libs/cocos2d/nodes/TMXLayer.js +++ b/src/libs/cocos2d/nodes/TMXLayer.js @@ -135,7 +135,12 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ positionForOrthoAt: function(pos) { var overlap = this.mapTileSize.height - this.tileset.tileSize.height; var x = Math.floor(pos.x * this.mapTileSize.width + 0.49); - var y = Math.floor(pos.y * this.mapTileSize.height + 0.49) + overlap; + var y; + if (FLIP_Y_AXIS) { + y = Math.floor((this.get('layerSize').height - pos.y -1) * this.mapTileSize.height + 0.49); + } else { + y = Math.floor(pos.y * this.mapTileSize.height + 0.49) + overlap; + } return ccp(x,y); }, From 82f6984a00746af8762d664641fe1cc0e56f996e Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 22 Jan 2011 18:52:41 +1300 Subject: [PATCH 006/176] Fixed dev server not unbinding HTTP port when exiting --- scripts/server.py | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/scripts/server.py b/scripts/server.py index 522e6b9..9f3a763 100755 --- a/scripts/server.py +++ b/scripts/server.py @@ -2,7 +2,7 @@ from optparse import OptionParser import SocketServer -import SimpleHTTPServer +import SimpleHTTPServer, BaseHTTPServer import urllib import threading from make import Compiler @@ -69,25 +69,17 @@ def main(): if options.config: CONFIG_FILE = options.config - httpd = SocketServer.TCPServer((host, port), Cocos2D) - httpd.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - httpd_thread = threading.Thread(target=httpd.serve_forever) - httpd_thread.setDaemon(True) - httpd_thread.start() + + httpd = BaseHTTPServer.HTTPServer((host, port), Cocos2D) print "Listening at http://%s:%d/" % (host, port) - - - running = True - while running: - try: - time.sleep(3600) - except (KeyboardInterrupt, SystemExit): - running = False - print "Shutting down" - httpd.shutdown() - httpd.server_close() - - return 0 + try: + httpd.serve_forever() + + except (KeyboardInterrupt, SystemExit): + print "Shutting down" + return 0 + + return 1 if __name__ == "__main__": From a7f2d6f11afaa9b075d58cdf3b10942bce68a9b0 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 22 Jan 2011 12:40:38 +1300 Subject: [PATCH 007/176] Added config option to invert Y axis --- src/libs/cocos2d/Director.js | 12 +++++++++++- src/libs/cocos2d/EventDispatcher.js | 6 ++++++ src/libs/cocos2d/TextureAtlas.js | 7 +++++++ src/libs/cocos2d/config.js | 7 +++++++ src/libs/cocos2d/nodes/Label.js | 13 +++++++++++++ src/libs/cocos2d/nodes/RenderTexture.js | 11 +++++++++-- src/libs/cocos2d/nodes/Sprite.js | 1 + src/libs/cocos2d/nodes/TMXLayer.js | 7 ++++++- 8 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/libs/cocos2d/config.js diff --git a/src/libs/cocos2d/Director.js b/src/libs/cocos2d/Director.js index c109a36..13db078 100644 --- a/src/libs/cocos2d/Director.js +++ b/src/libs/cocos2d/Director.js @@ -62,6 +62,11 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ var context = canvas.getContext('2d'); this.set('context', context); + if (FLIP_Y_AXIS) { + context.translate(0, view.clientHeight); + context.scale(1, -1); + } + view.appendChild(canvas); this.set('winSize', {width: view.clientWidth, height: view.clientHeight}); @@ -277,7 +282,12 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ y += o.offsetTop - o.scrollTop; } - return geo.ccpSub(evt.locationInWindow, ccp(x, y)); + var p = geo.ccpSub(evt.locationInWindow, ccp(x, y)); + if (FLIP_Y_AXIS) { + p.y = this.canvas.height - p.y; + } + + return p; }, showFPS: function() { diff --git a/src/libs/cocos2d/EventDispatcher.js b/src/libs/cocos2d/EventDispatcher.js index 10b7744..ab0a296 100644 --- a/src/libs/cocos2d/EventDispatcher.js +++ b/src/libs/cocos2d/EventDispatcher.js @@ -149,6 +149,9 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ if (this._previousMouseMovePosition) { evt.deltaX = evt.clientX - this._previousMouseMovePosition.x; evt.deltaY = evt.clientY - this._previousMouseMovePosition.y; + if (FLIP_Y_AXIS) { + evt.deltaY *= -1; + } } else { evt.deltaX = 0; evt.deltaY = 0; @@ -173,6 +176,9 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ if (this._previousMouseDragPosition) { evt.deltaX = evt.clientX - this._previousMouseDragPosition.x; evt.deltaY = evt.clientY - this._previousMouseDragPosition.y; + if (FLIP_Y_AXIS) { + evt.deltaY *= -1; + } } else { evt.deltaX = 0; evt.deltaY = 0; diff --git a/src/libs/cocos2d/TextureAtlas.js b/src/libs/cocos2d/TextureAtlas.js index ea92d15..a8ebbe9 100644 --- a/src/libs/cocos2d/TextureAtlas.js +++ b/src/libs/cocos2d/TextureAtlas.js @@ -75,8 +75,15 @@ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ dw = quad.drawRect.size.width, dh = quad.drawRect.size.height; + var scaleX = 1; var scaleY = 1; + + if (FLIP_Y_AXIS) { + dy -= dh; + dh *= -1; + } + if (dw < 0) { dw *= -1 diff --git a/src/libs/cocos2d/config.js b/src/libs/cocos2d/config.js new file mode 100644 index 0000000..fd86af5 --- /dev/null +++ b/src/libs/cocos2d/config.js @@ -0,0 +1,7 @@ +{ + // Invert the Y axis so origin is at the bottom left + FLIP_Y_AXIS: false, + + // No implemented yet + ENABLE_WEB_GL: false +} diff --git a/src/libs/cocos2d/nodes/Label.js b/src/libs/cocos2d/nodes/Label.js index cbe3559..655c282 100644 --- a/src/libs/cocos2d/nodes/Label.js +++ b/src/libs/cocos2d/nodes/Label.js @@ -46,6 +46,15 @@ var Label = Node.extend(/** @lends cocos.nodes.Label# */{ }, draw: function(context) { + if (FLIP_Y_AXIS) { + context.save(); + + // Flip Y axis + context.scale(1, -1); + context.translate(0, -this.get('fontSize')); + } + + context.fillStyle = this.get('fontColor'); context.font = this.get('font'); context.textBaseline = 'top'; @@ -54,6 +63,10 @@ var Label = Node.extend(/** @lends cocos.nodes.Label# */{ } else if (context.mozDrawText) { context.mozDrawText(this.get('string')); } + + if (FLIP_Y_AXIS) { + context.restore(); + } }, /** diff --git a/src/libs/cocos2d/nodes/RenderTexture.js b/src/libs/cocos2d/nodes/RenderTexture.js index 16117b1..f050f1d 100644 --- a/src/libs/cocos2d/nodes/RenderTexture.js +++ b/src/libs/cocos2d/nodes/RenderTexture.js @@ -40,8 +40,6 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ this.set('anchorPoint', ccp(0, 0)); this.sprite.set('anchorPoint', ccp(0, 0)); - - }, /** @@ -53,6 +51,11 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ canvas.width = size.width; canvas.height = size.height; + if (FLIP_Y_AXIS) { + this.context.scale(1, -1); + this.context.translate(0, -canvas.height); + } + var s = this.get('sprite'); if (s) { @@ -65,6 +68,10 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ */ clear: function() { this.canvas.width = this.canvas.width; + if (FLIP_Y_AXIS) { + this.context.scale(1, -1); + this.context.translate(0, -this.canvas.height); + } } }); diff --git a/src/libs/cocos2d/nodes/Sprite.js b/src/libs/cocos2d/nodes/Sprite.js index 83cd622..7a4b0e6 100644 --- a/src/libs/cocos2d/nodes/Sprite.js +++ b/src/libs/cocos2d/nodes/Sprite.js @@ -184,6 +184,7 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ this.quad.textureRect = util.copy(this.rect); this.quad.drawRect.origin = util.copy(offsetPosition); this.quad.drawRect.size = util.copy(this.rect.size); + if (this.flipX) { this.quad.drawRect.size.width *= -1; this.quad.drawRect.origin.x = -this.rect.size.width; diff --git a/src/libs/cocos2d/nodes/TMXLayer.js b/src/libs/cocos2d/nodes/TMXLayer.js index 39bfc7b..3f6b2f1 100644 --- a/src/libs/cocos2d/nodes/TMXLayer.js +++ b/src/libs/cocos2d/nodes/TMXLayer.js @@ -135,7 +135,12 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ positionForOrthoAt: function(pos) { var overlap = this.mapTileSize.height - this.tileset.tileSize.height; var x = Math.floor(pos.x * this.mapTileSize.width + 0.49); - var y = Math.floor(pos.y * this.mapTileSize.height + 0.49) + overlap; + var y; + if (FLIP_Y_AXIS) { + y = Math.floor((this.get('layerSize').height - pos.y -1) * this.mapTileSize.height + 0.49); + } else { + y = Math.floor(pos.y * this.mapTileSize.height + 0.49) + overlap; + } return ccp(x,y); }, From 57e9e4143d42c6b965616013b7a45caa55da6bf0 Mon Sep 17 00:00:00 2001 From: Szymon Pilkowski Date: Sun, 23 Jan 2011 02:30:02 +0100 Subject: [PATCH 008/176] Minor fixes: - scope leaks - duplicated declaration - typos etc --- src/global.js | 7 ++++--- src/libs/Plist.js | 1 - src/libs/base64.js | 2 +- src/libs/cocos2d/Scheduler.js | 16 +++++++++------- src/libs/cocos2d/SpriteFrameCache.js | 2 +- src/libs/cocos2d/TMXXMLParser.js | 7 ++++--- src/libs/cocos2d/TextureAtlas.js | 6 +++--- src/libs/cocos2d/nodes/Node.js | 4 ++-- src/libs/gzip.js | 4 ++-- src/libs/util.js | 9 ++++----- 10 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/global.js b/src/global.js index 6ca02ef..5e77733 100644 --- a/src/global.js +++ b/src/global.js @@ -239,7 +239,8 @@ BObject.create = function() { BObject.extend = function() { var newObj = function() {}, args = [], - i; + i, + x; // Copy 'class' methods for (x in this) { @@ -253,7 +254,7 @@ BObject.extend = function() { // Add given properties to the prototype - newObj.prototype = util.beget(this.prototype) + newObj.prototype = util.beget(this.prototype); args.push(newObj.prototype); for (i = 0; i 0 */{ - for (var i = 0, len = this.updatesPos.length; i < len; i++) { + for (i = 0, len = this.updatesPos.length; i < len; i++) { if (priority < this.updatesPos[i].priority) { this.updatesPos.splice(i, 0, entry); added = true; @@ -145,29 +146,30 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ }, tick: function(dt) { + var i; if (this.timeScale != 1.0) { dt *= this.timeScale; } var entry; - for (var i = 0, len = this.updatesNeg.length; i < len; i++) { + for (i = 0, len = this.updatesNeg.length; i < len; i++) { entry = this.updatesNeg[i]; if (!entry.paused) entry.target.update(dt); } - for (var i = 0, len = this.updates0.length; i < len; i++) { + for (i = 0, len = this.updates0.length; i < len; i++) { entry = this.updates0[i]; if (!entry.paused) entry.target.update(dt); } - for (var i = 0, len = this.updatesPos.length; i < len; i++) { + for (i = 0, len = this.updatesPos.length; i < len; i++) { entry = this.updatesPos[i]; if (!entry.paused) entry.target.update(dt); } for (var x in this.hashForMethods) { - var entry = this.hashForMethods[x]; - for (var i = 0, len = entry.timers.length; i < len; i++) { + entry = this.hashForMethods[x]; + for (i = 0, len = entry.timers.length; i < len; i++) { var timer = entry.timers[i]; timer.update(dt); } diff --git a/src/libs/cocos2d/SpriteFrameCache.js b/src/libs/cocos2d/SpriteFrameCache.js index 7349f70..64762fb 100644 --- a/src/libs/cocos2d/SpriteFrameCache.js +++ b/src/libs/cocos2d/SpriteFrameCache.js @@ -70,7 +70,7 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ switch (format) { case 0: - var x = frameDict.x + var x = frameDict.x, y = frameDict.y, w = frameDict.width, h = frameDict.height, diff --git a/src/libs/cocos2d/TMXXMLParser.js b/src/libs/cocos2d/TMXXMLParser.js index 6718a2e..a953ad4 100644 --- a/src/libs/cocos2d/TMXXMLParser.js +++ b/src/libs/cocos2d/TMXXMLParser.js @@ -67,6 +67,7 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ var tilesets = map.getElementsByTagName('tileset'); for (var i = 0, len = tilesets.length; i < len; i++) { var t = tilesets[i]; + var i, len, s; var tileset = TMXTilesetInfo.create(); tileset.set('name', t.getAttribute('name')); @@ -78,7 +79,7 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ tileset.set('margin', parseInt(t.getAttribute('margin'), 10)); } - var s = {}; + s = {}; s.width = parseInt(t.getAttribute('tilewidth'), 10) s.height = parseInt(t.getAttribute('tileheight'), 10) tileset.set('tileSize', s); @@ -93,7 +94,7 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ // PARSE var layers = map.getElementsByTagName('layer'); - for (var i = 0, len = layers.length; i < len; i++) { + for (i = 0, len = layers.length; i < len; i++) { var l = layers[i]; var data = l.getElementsByTagName('data')[0]; var layer = TMXLayerInfo.create(); @@ -105,7 +106,7 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ layer.set('visible', !!parseInt(l.getAttribute('visible'))); } - var s = {}; + s = {}; s.width = parseInt(l.getAttribute('width'), 10) s.height = parseInt(l.getAttribute('height'), 10) layer.set('layerSize', s); diff --git a/src/libs/cocos2d/TextureAtlas.js b/src/libs/cocos2d/TextureAtlas.js index a8ebbe9..831840c 100644 --- a/src/libs/cocos2d/TextureAtlas.js +++ b/src/libs/cocos2d/TextureAtlas.js @@ -35,7 +35,7 @@ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ // If we've been given a canvas element then we'll use that for our image this.imgElement = canvas; } else { - var texture = Texture2D.create({texture: texture, file: file, data: data}); + texture = Texture2D.create({texture: texture, file: file, data: data}); this.set('texture', texture); this.imgElement = texture.get('imgElement'); } @@ -86,12 +86,12 @@ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ if (dw < 0) { - dw *= -1 + dw *= -1; scaleX = -1; } if (dh < 0) { - dh *= -1 + dh *= -1; scaleY = -1; } diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index 81895f2..66c2fdc 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -214,8 +214,8 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ }, scheduleUpdate: function(opts) { - var opts = opts || {}, - priority = opts['priority'] || 0; + opts = opts || {}; + var priority = opts['priority'] || 0; Scheduler.get('sharedScheduler').scheduleUpdate({target: this, priority: priority, paused: !this.get('isRunning')}); }, diff --git a/src/libs/gzip.js b/src/libs/gzip.js index 9a4887f..21a781d 100644 --- a/src/libs/gzip.js +++ b/src/libs/gzip.js @@ -39,7 +39,7 @@ var gzip = { * @returns {Integer[]} Unpacked byte array */ unzipBase64AsArray: function(input, bytes) { - var bytes = bytes || 1; + bytes = bytes || 1; var dec = this.unzipBase64(input), ar = [], i, j, len; @@ -60,7 +60,7 @@ var gzip = { * @returns {Integer[]} Unpacked byte array */ unzipAsArray: function (input, bytes) { - var bytes = bytes || 1; + bytes = bytes || 1; var dec = this.unzip(input), ar = [], i, j, len; diff --git a/src/libs/util.js b/src/libs/util.js index dfc58c9..9fdc3aa 100644 --- a/src/libs/util.js +++ b/src/libs/util.js @@ -109,7 +109,7 @@ var util = { throw "You must provide at least a target and 1 object to extend from" } - var i, obj, key, val; + var i, j, obj, key, val; for (i = 1; i < arguments.length; i++) { obj = arguments[i]; @@ -145,9 +145,8 @@ var util = { } - var i; - for (i = 0; i Date: Thu, 27 Jan 2011 17:47:25 +1300 Subject: [PATCH 009/176] Fixed BObject.superclass --- src/global.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global.js b/src/global.js index 5e77733..629e7c2 100644 --- a/src/global.js +++ b/src/global.js @@ -261,7 +261,7 @@ BObject.extend = function() { } util.extend.apply(null, args); - newObj.superclass = this; + newObj.superclass = this.prototype; // Create new instance return newObj; }; From a98af0418bb6230f7c88a6574419b6fd26679ccc Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Jan 2011 17:48:13 +1300 Subject: [PATCH 010/176] Module code is now ECMAScript 5 strict --- scripts/module.js | 51 +++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/scripts/module.js b/scripts/module.js index 9171671..5784e09 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -1,8 +1,12 @@ +/*globals module exports resource require window Module __main_module_name__ __resources__*/ +/*jslint evil: true, undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + function resource(path) { return __resources__[path].data; } -(function() { +(function () { var process = {}; var modulePaths = ['/', '/libs']; @@ -62,6 +66,13 @@ function resource(path) { //console.log('Loading module: ', filename); var module = new Module(filename, parent); + + // Assign main module to process + if (request == __main_module_name__ && !process.mainModule) { + process.mainModule = module; + } + + // Run all the code in the module module._initialize(filename); return module; @@ -85,7 +96,7 @@ function resource(path) { this.dirname = null; } - Module.prototype._initialize = function(filename) { + Module.prototype._initialize = function (filename) { var module = this; function require(request) { return loadModule(request, module).exports; @@ -103,30 +114,32 @@ function resource(path) { require.paths = modulePaths; require.main = process.mainModule; - __resources__[this.filename].data.apply(this.exports, [this.exports, require, this, this.filename, this.dirname]) + __resources__[this.filename].data.apply(this.exports, [this.exports, require, this, this.filename, this.dirname]); return this; - } + }; // Manually load the path module because we need it to load other modules path = (new Module('path'))._initialize('/path.js').exports; - - // Populate globals - var globals = loadModule('global').exports; - for (var x in globals) { - window[x] = globals[x]; - } - var util = loadModule('util').exports; - util.ready(function() { + util.ready(function () { + // Populate globals + var globals = loadModule('global').exports; + for (var x in globals) { + if (globals.hasOwnProperty(x)) { + window[x] = globals[x]; + } + } + process.mainModule = loadModule(__main_module_name__); - }); - // Add a global require. Useful in the debug console. - window.require = function require(request, parent) { - return loadModule(request, parent).exports; - } - window.require.paths = modulePaths; - window.require.main = process.mainModule; + // Add a global require. Useful in the debug console. + window.require = function require(request, parent) { + return loadModule(request, parent).exports; + }; + window.require.main = process.mainModule; + window.require.paths = modulePaths; + + }); })(); From 11894cdea7d6f833cb3f8451ec9b40a7819f285f Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Jan 2011 17:48:31 +1300 Subject: [PATCH 011/176] Sprite and Tile test are now ECMAScript 5 strict --- tests/cocos2d/SpriteTest.js | 217 ++++++++++++++++++----------------- tests/cocos2d/TileMapTest.js | 46 ++++---- 2 files changed, 139 insertions(+), 124 deletions(-) diff --git a/tests/cocos2d/SpriteTest.js b/tests/cocos2d/SpriteTest.js index 22788c0..51fb912 100644 --- a/tests/cocos2d/SpriteTest.js +++ b/tests/cocos2d/SpriteTest.js @@ -1,3 +1,7 @@ +/*globals module exports resource require*/ +/*jslint evil: true, undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), Texture2D = require('cocos2d/Texture2D').Texture2D, cocos = require('cocos2d'), @@ -60,38 +64,38 @@ var SpriteDemo = nodes.Layer.extend({ title: 'No title', subtitle: null, - init: function() { - @super; + init: function () { + SpriteDemo.superclass.init.call(this); var s = cocos.Director.get('sharedDirector').get('winSize'); var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); - this.addChild({child: label, z:1}); + this.addChild({child: label, z: 1}); label.set('position', ccp(s.width / 2, 50)); var subtitle = this.get('subtitle'); if (subtitle) { - var l = nodes.Label.create({string:subtitle, fontName: "Thonburi", fontSize: 16}); - this.addChild({child: l, z:1}); - l.set('position', ccp(s.width/2, 80)); + var l = nodes.Label.create({string: subtitle, fontName: "Thonburi", fontSize: 16}); + this.addChild({child: l, z: 1}); + l.set('position', ccp(s.width / 2, 80)); } - var item1 = nodes.MenuItemImage.create({normalImage:__dirname + "/resources/b1.png", selectedImage:__dirname + "/resources/b2.png", callback:util.callback(this, 'backCallback')}); - var item2 = nodes.MenuItemImage.create({normalImage:__dirname + "/resources/r1.png", selectedImage:__dirname + "/resources/r2.png", callback:util.callback(this, 'restartCallback')}); - var item3 = nodes.MenuItemImage.create({normalImage:__dirname + "/resources/f1.png", selectedImage:__dirname + "/resources/f2.png", callback:util.callback(this, 'nextCallback')}); + var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); + var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); + var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); var menu = nodes.Menu.create({items: [item1, item2, item3]}); - menu.set('position', ccp(0,0)); - item1.set('position', ccp(s.width /2 -100, s.height -30)); - item2.set('position', ccp(s.width /2, s.height -30)); - item3.set('position', ccp(s.width /2 +100, s.height -30)); - this.addChild({child: menu, z:1}); + menu.set('position', ccp(0, 0)); + item1.set('position', ccp(s.width / 2 - 100, s.height - 30)); + item2.set('position', ccp(s.width / 2, s.height - 30)); + item3.set('position', ccp(s.width / 2 + 100, s.height - 30)); + this.addChild({child: menu, z: 1}); }, - restartCallback: function() { + restartCallback: function () { var director = cocos.Director.get('sharedDirector'); var scene = nodes.Scene.create(); @@ -100,7 +104,7 @@ var SpriteDemo = nodes.Layer.extend({ director.replaceScene(scene); }, - backCallback: function() { + backCallback: function () { var director = cocos.Director.get('sharedDirector'); var scene = nodes.Scene.create(); @@ -109,7 +113,7 @@ var SpriteDemo = nodes.Layer.extend({ director.replaceScene(scene); }, - nextCallback: function() { + nextCallback: function () { var director = cocos.Director.get('sharedDirector'); var scene = nodes.Scene.create(); @@ -128,38 +132,39 @@ var Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ title: 'Sprite', subtitle: 'Click screen', - init: function() { - @super; + init: function () { + Sprite1.superclass.init.call(this); + this.set('isMouseEnabled', true); var s = cocos.Director.get('sharedDirector').get('winSize'); - this.addNewSprite(ccp(s.width /2, s.height /2)); + this.addNewSprite(ccp(s.width / 2, s.height / 2)); }, - addNewSprite: function(point) { + addNewSprite: function (point) { var idx = Math.floor(Math.random() * 1400 / 100), - x = (idx%5) * 85, - y = (idx%3) * 121; + x = (idx % 5) * 85, + y = (idx % 3) * 121; - var sprite = nodes.Sprite.create({file: __dirname + "/resources/grossini_dance_atlas.png", rect:{origin:ccp(x, y), size:{width: 85, height: 121}}}) - this.addChild({child:sprite, z:0}); + var sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: new geo.Rect(x, y, 85, 121)}); + this.addChild({child: sprite, z: 0}); sprite.set('position', ccp(point.x, point.y)); var action, actionBack, seq; var rand = Math.random(); if (rand < 0.2) { - action = actions.ScaleBy.create({duration:3, scale:2}); + action = actions.ScaleBy.create({duration: 3, scale: 2}); } else if (rand < 0.4) { - action = actions.RotateBy.create({duration:3, angle:360}); + action = actions.RotateBy.create({duration: 3, angle: 360}); } else if (rand < 0.6) { - action = actions.ScaleBy.create({duration:3, scale:2}); + action = actions.ScaleBy.create({duration: 3, scale: 2}); //action = cocos.Blink.create({duration:3, scale:2}); } else if (rand < 0.8) { - action = actions.RotateBy.create({duration:3, angle:360}); + action = actions.RotateBy.create({duration: 3, angle: 360}); //action = cocos.TintBy.create({duration:3, scale:2}); } else { - action = actions.ScaleBy.create({duration:3, scale:2}); + action = actions.ScaleBy.create({duration: 3, scale: 2}); //action = cocos.FadeOut.create({duration:3, scale:2}); } @@ -167,11 +172,11 @@ var Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ actionBack = action.reverse(); - seq = actions.Sequence.create({actions:[action, actionBack]}); + seq = actions.Sequence.create({actions: [action, actionBack]}); sprite.runAction(actions.RepeatForever.create(seq)); }, - mouseUp: function(event) { + mouseUp: function (event) { var location = cocos.Director.get('sharedDirector').convertEventToCanvas(event); this.addNewSprite(location); @@ -189,26 +194,27 @@ var SpriteBatchNode1 = SpriteDemo.extend(/** @lends SpriteBatchNode1.prototype# title: 'SpriteBatchNode', subtitle: 'Click screen', - init: function() { - @super; + init: function () { + SpriteBatchNode1.superclass.init.call(this); + this.set('isMouseEnabled', true); - var batch = nodes.SpriteBatchNode.create({file: __dirname + "/resources/grossini_dance_atlas.png", size: geo.sizeMake(480, 320)}); + var batch = nodes.SpriteBatchNode.create({file: module.dirname + "/resources/grossini_dance_atlas.png", size: geo.sizeMake(480, 320)}); this.addChild({child: batch, z: 0, tag: kTagSpriteBatchNode}); var s = cocos.Director.get('sharedDirector').get('winSize'); - this.addNewSprite(ccp(s.width /2, s.height /2)); + this.addNewSprite(ccp(s.width / 2, s.height / 2)); }, - addNewSprite: function(point) { + addNewSprite: function (point) { var batch = this.getChild({tag: kTagSpriteBatchNode}); var idx = Math.floor(Math.random() * 1400 / 100), - x = (idx%5) * 85, - y = (idx%3) * 121; + x = (idx % 5) * 85, + y = (idx % 3) * 121; - var sprite = nodes.Sprite.create({textureAtlas: batch.get('textureAtlas'), rect:geo.rectMake(x, y, 85, 121)}) - batch.addChild({child:sprite}); + var sprite = nodes.Sprite.create({textureAtlas: batch.get('textureAtlas'), rect: geo.rectMake(x, y, 85, 121)}); + batch.addChild({child: sprite}); sprite.set('position', ccp(point.x, point.y)); @@ -216,25 +222,25 @@ var SpriteBatchNode1 = SpriteDemo.extend(/** @lends SpriteBatchNode1.prototype# var rand = Math.random(); if (rand < 0.2) { - action = actions.ScaleBy.create({duration:3, scale:2}); + action = actions.ScaleBy.create({duration: 3, scale: 2}); } else if (rand < 0.4) { - action = actions.RotateBy.create({duration:3, angle:360}); + action = actions.RotateBy.create({duration: 3, angle: 360}); } else if (rand < 0.6) { - action = actions.ScaleBy.create({duration:3, scale:2}); + action = actions.ScaleBy.create({duration: 3, scale: 2}); //action = cocos.Blink.create({duration:3, scale:2}); } else if (rand < 0.8) { - action = actions.RotateBy.create({duration:3, angle:360}); + action = actions.RotateBy.create({duration: 3, angle: 360}); //action = cocos.TintBy.create({duration:3, scale:2}); } else { - action = actions.ScaleBy.create({duration:3, scale:2}); - //action = cocos.FadeOut.create({duration:3, scale:2}); + action = actions.ScaleBy.create({duration: 3, scale: 2}); + //action = cocos.FadeOut.create({duration: 3, scale: 2}); } actionBack = action.reverse(); - seq = actions.Sequence.create({actions:[action, actionBack]}); + seq = actions.Sequence.create({actions: [action, actionBack]}); sprite.runAction(actions.RepeatForever.create(seq)); }, - mouseUp: function(event) { + mouseUp: function (event) { var location = cocos.Director.get('sharedDirector').convertEventToCanvas(event); this.addNewSprite(location); @@ -252,23 +258,23 @@ var SpriteBatchNode1 = SpriteDemo.extend(/** @lends SpriteBatchNode1.prototype# var SpriteAnimationFlip = SpriteDemo.extend(/** @lends SpriteAnimationFlip.prototype# */{ title: 'Sprite Animation + Flip', - init: function() { - @super; + init: function () { + SpriteAnimationFlip.superclass.init.call(this); var s = cocos.Director.get('sharedDirector').get('winSize'); - var texture = Texture2D.create({file: __dirname + "/resources/animations/dragon_animation.png"}); + var texture = Texture2D.create({file: module.dirname + "/resources/animations/dragon_animation.png"}); - var frame0 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132*0, 132*0, 132, 132)}), - frame1 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132*1, 132*0, 132, 132)}), - frame2 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132*2, 132*0, 132, 132)}), - frame3 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132*3, 132*0, 132, 132)}), - frame4 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132*0, 132*1, 132, 132)}), - frame5 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132*1, 132*1, 132, 132)}); + var frame0 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 0, 132 * 0, 132, 132)}), + frame1 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 1, 132 * 0, 132, 132)}), + frame2 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 2, 132 * 0, 132, 132)}), + frame3 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 3, 132 * 0, 132, 132)}), + frame4 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 0, 132 * 1, 132, 132)}), + frame5 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 1, 132 * 1, 132, 132)}); var sprite = nodes.Sprite.create({frame: frame0}); - sprite.set('position', ccp(s.width/2 - 80, s.height/2)); + sprite.set('position', ccp(s.width / 2 - 80, s.height / 2)); this.addChild(sprite); var animFrames = [ @@ -281,7 +287,7 @@ var SpriteAnimationFlip = SpriteDemo.extend(/** @lends SpriteAnimationFlip.proto ]; - var animation = cocos.Animation.create({frames: animFrames, delay:0.2}), + var animation = cocos.Animation.create({frames: animFrames, delay: 0.2}), animate = actions.Animate.create({animation: animation, restoreOriginalFrame: false}), seq = actions.Sequence.create({actions: [animate, actions.FlipX.create({flipX: true}), @@ -300,32 +306,32 @@ var SpriteAnimationFlip = SpriteDemo.extend(/** @lends SpriteAnimationFlip.proto var SpriteAnchorPoint = SpriteDemo.extend(/** @lends SpriteAnchorPoint.prototype# */{ title: 'Sprite Anchor Point', - init: function() { - @super; + init: function () { + SpriteAnchorPoint.superclass.init.call(this); var s = cocos.Director.get('sharedDirector').get('winSize'); var rotate = actions.RotateBy.create({duration: 10, angle: 360}); var action = actions.RepeatForever.create(rotate); - for (var i=0; i<3; i++) { - var sprite = nodes.Sprite.create({file: __dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85*i, 121*1, 85, 121)}); - sprite.position = ccp(s.width/4*(i+1), s.height/2); + for (var i = 0; i < 3; i++) { + var sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * i, 121 * 1, 85, 121)}); + sprite.position = ccp(s.width / 4 * (i + 1), s.height / 2); - var point = nodes.Sprite.create({file: __dirname + "/resources/r1.png"}); + var point = nodes.Sprite.create({file: module.dirname + "/resources/r1.png"}); point.set('scale', 0.25); point.set('position', sprite.get('position')); this.addChild({child: point, z: 10}); - switch(i) { - case 0: - sprite.set('anchorPoint', ccp(0, 0)); - break; - case 1: - sprite.set('anchorPoint', ccp(0.5, 0.5)); - break; - case 2: - sprite.set('anchorPoint', ccp(1, 1)); - break; + switch (i) { + case 0: + sprite.set('anchorPoint', ccp(0, 0)); + break; + case 1: + sprite.set('anchorPoint', ccp(0.5, 0.5)); + break; + case 2: + sprite.set('anchorPoint', ccp(1, 1)); + break; } point.set('position', sprite.get('position')); @@ -347,40 +353,44 @@ var SpriteZOrder = SpriteDemo.extend(/** @lends SpriteZOrder.prototype# */{ title: 'Sprite Z Order', dir: 1, - init: function() { - @super; + init: function () { + SpriteZOrder.superclass.init.call(this); var s = cocos.Director.get('sharedDirector').get('winSize'); + var i; var step = s.width / 11; - for (var i=0; i<5; i++) { - var sprite = nodes.Sprite.create({file: __dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85*0, 121*1, 85, 121)}); - sprite.set('position', ccp((i+1)*step, s.height/2)); + var sprite; + for (i = 0; i < 5; i++) { + sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 0, 121 * 1, 85, 121)}); + sprite.set('position', ccp((i + 1) * step, s.height / 2)); this.addChild({child: sprite, z: i}); } - for (var i=5; i<10; i++) { - var sprite = nodes.Sprite.create({file: __dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85*1, 121*0, 85, 121)}); - sprite.set('position', ccp((i+1)*step, s.height/2)); - this.addChild({child: sprite, z: 14-i}); + for (i = 5; i < 10; i++) { + sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 1, 121 * 0, 85, 121)}); + sprite.set('position', ccp((i + 1) * step, s.height / 2)); + this.addChild({child: sprite, z: 14 - i}); } - var sprite = nodes.Sprite.create({file: __dirname + "/resources/grossini_dance_atlas-red.png", rect: geo.rectMake(85*3, 121*0, 85, 121)}); + sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas-red.png", rect: geo.rectMake(85 * 3, 121 * 0, 85, 121)}); this.addChild({child: sprite, z: -1, tag: kTagSprite1}); - sprite.set('position', ccp(s.width/2, s.height/2 + 20)); + sprite.set('position', ccp(s.width / 2, s.height / 2 + 20)); sprite.set('scaleX', 6); cocos.Scheduler.get('sharedScheduler').schedule({target: this, method: this.reorderSprite, interval: 1}); }, - reorderSprite: function(dt) { + reorderSprite: function (dt) { var sprite = this.getChild({tag: kTagSprite1}); var z = sprite.get('zOrder'); - if (z < -1) + if (z < -1) { this.dir = 1; - if (z > 10) + } + if (z > 10) { this.dir = -1; + } z += this.dir * 3; @@ -397,26 +407,27 @@ var AnimationCache = SpriteDemo.extend(/** @lends AnimationCache.prototype# */{ title: 'AnimationCache', subtitle: 'Sprite should be animated', - init: function() { - @super; + init: function () { + AnimationCache.superclass.init.call(this); var frameCache = cocos.SpriteFrameCache.get('sharedSpriteFrameCache'), animCache = cocos.AnimationCache.get('sharedAnimationCache'); - frameCache.addSpriteFrames({file: __dirname + '/resources/animations/grossini.plist'}); - frameCache.addSpriteFrames({file: __dirname + '/resources/animations/grossini_gray.plist'}); - frameCache.addSpriteFrames({file: __dirname + '/resources/animations/grossini_blue.plist'}); + frameCache.addSpriteFrames({file: module.dirname + '/resources/animations/grossini.plist'}); + frameCache.addSpriteFrames({file: module.dirname + '/resources/animations/grossini_gray.plist'}); + frameCache.addSpriteFrames({file: module.dirname + '/resources/animations/grossini_blue.plist'}); // create "dance" animation var animFrames = [], - frame; - for (var i = 1; i < 15; i++) { + frame, + i; + for (i = 1; i < 15; i++) { frame = frameCache.getSpriteFrame({name: 'grossini_dance_' + (i >= 10 ? i : '0' + i) + '.png'}); animFrames.push(frame); } - var animation = cocos.Animation.create({frames: animFrames, delay:0.2}); + var animation = cocos.Animation.create({frames: animFrames, delay: 0.2}); // Add an animation to the Cache animCache.addAnimation({animation: animation, name: 'dance'}); @@ -424,12 +435,12 @@ var AnimationCache = SpriteDemo.extend(/** @lends AnimationCache.prototype# */{ // create animation "dance gray" animFrames = []; - for (var i = 1; i < 15; i++) { + for (i = 1; i < 15; i++) { frame = frameCache.getSpriteFrame({name: 'grossini_dance_gray_' + (i >= 10 ? i : '0' + i) + '.png'}); animFrames.push(frame); } - animation = cocos.Animation.create({frames: animFrames, delay:0.2}); + animation = cocos.Animation.create({frames: animFrames, delay: 0.2}); // Add an animation to the Cache animCache.addAnimation({animation: animation, name: 'dance_gray'}); @@ -437,12 +448,12 @@ var AnimationCache = SpriteDemo.extend(/** @lends AnimationCache.prototype# */{ // create animation "dance blue" animFrames = []; - for (var i = 1; i < 4; i++) { + for (i = 1; i < 4; i++) { frame = frameCache.getSpriteFrame({name: 'grossini_blue_0' + i + '.png'}); animFrames.push(frame); } - animation = cocos.Animation.create({frames: animFrames, delay:0.2}); + animation = cocos.Animation.create({frames: animFrames, delay: 0.2}); // Add an animation to the Cache animCache.addAnimation({animation: animation, name: 'dance_blue'}); @@ -463,7 +474,7 @@ var AnimationCache = SpriteDemo.extend(/** @lends AnimationCache.prototype# */{ var winSize = cocos.Director.get('sharedDirector').get('winSize'); - grossini.set('position', ccp(winSize.width/2, winSize.height/2)); + grossini.set('position', ccp(winSize.width / 2, winSize.height / 2)); this.addChild({child: grossini}); diff --git a/tests/cocos2d/TileMapTest.js b/tests/cocos2d/TileMapTest.js index 00a5ca9..d428ae5 100644 --- a/tests/cocos2d/TileMapTest.js +++ b/tests/cocos2d/TileMapTest.js @@ -1,3 +1,7 @@ +/*globals module exports resource require*/ +/*jslint evil: true, undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), Texture2D = require('cocos2d/Texture2D').Texture2D, cocos = require('cocos2d'), @@ -42,47 +46,47 @@ var TileDemo = nodes.Layer.extend({ title: 'No title', subtitle: null, - init: function() { - @super; + init: function () { + TileDemo.superclass.init.call(this); this.set('isMouseEnabled', true); var s = cocos.Director.get('sharedDirector').get('winSize'); var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); - this.addChild({child: label, z:1}); + this.addChild({child: label, z: 1}); label.set('position', ccp(s.width / 2, 50)); var subtitle = this.get('subtitle'); if (subtitle) { - var l = nodes.Label.create({string:subtitle, fontName: "Thonburi", fontSize: 16}); - this.addChild({child: l, z:1}); - l.set('position', ccp(s.width/2, 80)); + var l = nodes.Label.create({string: subtitle, fontName: "Thonburi", fontSize: 16}); + this.addChild({child: l, z: 1}); + l.set('position', ccp(s.width / 2, 80)); } - var item1 = nodes.MenuItemImage.create({normalImage:__dirname + "/resources/b1.png", selectedImage:__dirname + "/resources/b2.png", callback:util.callback(this, 'backCallback')}); - var item2 = nodes.MenuItemImage.create({normalImage:__dirname + "/resources/r1.png", selectedImage:__dirname + "/resources/r2.png", callback:util.callback(this, 'restartCallback')}); - var item3 = nodes.MenuItemImage.create({normalImage:__dirname + "/resources/f1.png", selectedImage:__dirname + "/resources/f2.png", callback:util.callback(this, 'nextCallback')}); + var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); + var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); + var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); var menu = nodes.Menu.create({items: [item1, item2, item3]}); - menu.set('position', ccp(0,0)); - item1.set('position', ccp(s.width /2 -100, s.height -30)); - item2.set('position', ccp(s.width /2, s.height -30)); - item3.set('position', ccp(s.width /2 +100, s.height -30)); - this.addChild({child: menu, z:1}); + menu.set('position', ccp(0, 0)); + item1.set('position', ccp(s.width / 2 - 100, s.height - 30)); + item2.set('position', ccp(s.width / 2, s.height - 30)); + item3.set('position', ccp(s.width / 2 + 100, s.height - 30)); + this.addChild({child: menu, z: 1}); }, - mouseDragged: function(event) { + mouseDragged: function (event) { var node = this.getChild({tag: kTagTileMap}); var currentPos = node.get('position'); node.set('position', geo.ccpAdd(currentPos, ccp(event.deltaX, event.deltaY))); return true; }, - restartCallback: function() { + restartCallback: function () { var director = cocos.Director.get('sharedDirector'); var scene = nodes.Scene.create(); @@ -91,7 +95,7 @@ var TileDemo = nodes.Layer.extend({ director.replaceScene(scene); }, - backCallback: function() { + backCallback: function () { var director = cocos.Director.get('sharedDirector'); var scene = nodes.Scene.create(); @@ -100,7 +104,7 @@ var TileDemo = nodes.Layer.extend({ director.replaceScene(scene); }, - nextCallback: function() { + nextCallback: function () { var director = cocos.Director.get('sharedDirector'); var scene = nodes.Scene.create(); @@ -115,10 +119,10 @@ var TMXOrthoTest2 = TileDemo.extend({ title: 'Tile Map Test', subtitle: 'drag screen', - init: function() { - @super; + init: function () { + TMXOrthoTest2.superclass.init.call(this); - var map = nodes.TMXTiledMap.create({file: __dirname + "/resources/TileMaps/orthogonal-test1.tmx"}); + var map = nodes.TMXTiledMap.create({file: module.dirname + "/resources/TileMaps/orthogonal-test1.tmx"}); this.addChild({child: map, z: 0, tag: kTagTileMap}); var s = cocos.Director.get('sharedDirector').get('winSize'); From 1f6853a25b3b61a72ff8783ba717e5f9b8707421 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Jan 2011 19:21:25 +1300 Subject: [PATCH 012/176] Removed evil usage of eval in tests --- scripts/module.js | 2 +- tests/cocos2d/SpriteTest.js | 37 ++++++++++++++++++------------------ tests/cocos2d/TileMapTest.js | 17 ++++++++--------- tests/commonjs.js | 8 ++++++-- tests/main.js | 16 +++++++++------- 5 files changed, 42 insertions(+), 38 deletions(-) diff --git a/scripts/module.js b/scripts/module.js index 5784e09..b6a30eb 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -1,5 +1,5 @@ /*globals module exports resource require window Module __main_module_name__ __resources__*/ -/*jslint evil: true, undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; function resource(path) { diff --git a/tests/cocos2d/SpriteTest.js b/tests/cocos2d/SpriteTest.js index 51fb912..1feff46 100644 --- a/tests/cocos2d/SpriteTest.js +++ b/tests/cocos2d/SpriteTest.js @@ -1,5 +1,5 @@ /*globals module exports resource require*/ -/*jslint evil: true, undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; var util = require('util'), @@ -20,6 +20,8 @@ var transitions = [ "AnimationCache" ]; +var tests = {}; + var kTagTileMap = 1, kTagSpriteBatchNode = 1, kTagNode = 2, @@ -41,8 +43,7 @@ function nextAction() { sceneIdx = sceneIdx % transitions.length; var r = transitions[sceneIdx]; - var c = eval('(' + r + ')'); - return c; + return tests[r]; } function backAction() { sceneIdx--; @@ -51,13 +52,11 @@ function backAction() { } var r = transitions[sceneIdx]; - var c = eval('(' + r + ')'); - return c; + return tests[r]; } function restartAction() { var r = transitions[sceneIdx]; - var c = eval('(' + r + ')'); - return c; + return tests[r]; } var SpriteDemo = nodes.Layer.extend({ @@ -128,12 +127,12 @@ var SpriteDemo = nodes.Layer.extend({ * * Example Sprite 1 */ -var Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ +tests.Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ title: 'Sprite', subtitle: 'Click screen', init: function () { - Sprite1.superclass.init.call(this); + tests.Sprite1.superclass.init.call(this); this.set('isMouseEnabled', true); @@ -190,12 +189,12 @@ var Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ * * Example SpriteBatchNode 1 */ -var SpriteBatchNode1 = SpriteDemo.extend(/** @lends SpriteBatchNode1.prototype# */{ +tests.SpriteBatchNode1 = SpriteDemo.extend(/** @lends SpriteBatchNode1.prototype# */{ title: 'SpriteBatchNode', subtitle: 'Click screen', init: function () { - SpriteBatchNode1.superclass.init.call(this); + tests.SpriteBatchNode1.superclass.init.call(this); this.set('isMouseEnabled', true); @@ -255,11 +254,11 @@ var SpriteBatchNode1 = SpriteDemo.extend(/** @lends SpriteBatchNode1.prototype# * * Example Sprite Animation and flip */ -var SpriteAnimationFlip = SpriteDemo.extend(/** @lends SpriteAnimationFlip.prototype# */{ +tests.SpriteAnimationFlip = SpriteDemo.extend(/** @lends SpriteAnimationFlip.prototype# */{ title: 'Sprite Animation + Flip', init: function () { - SpriteAnimationFlip.superclass.init.call(this); + tests.SpriteAnimationFlip.superclass.init.call(this); var s = cocos.Director.get('sharedDirector').get('winSize'); @@ -303,11 +302,11 @@ var SpriteAnimationFlip = SpriteDemo.extend(/** @lends SpriteAnimationFlip.proto * * Example Sprite Anchor Point */ -var SpriteAnchorPoint = SpriteDemo.extend(/** @lends SpriteAnchorPoint.prototype# */{ +tests.SpriteAnchorPoint = SpriteDemo.extend(/** @lends SpriteAnchorPoint.prototype# */{ title: 'Sprite Anchor Point', init: function () { - SpriteAnchorPoint.superclass.init.call(this); + tests.SpriteAnchorPoint.superclass.init.call(this); var s = cocos.Director.get('sharedDirector').get('winSize'); @@ -349,12 +348,12 @@ var SpriteAnchorPoint = SpriteDemo.extend(/** @lends SpriteAnchorPoint.prototype * * Example Sprite Z ORder */ -var SpriteZOrder = SpriteDemo.extend(/** @lends SpriteZOrder.prototype# */{ +tests.SpriteZOrder = SpriteDemo.extend(/** @lends SpriteZOrder.prototype# */{ title: 'Sprite Z Order', dir: 1, init: function () { - SpriteZOrder.superclass.init.call(this); + tests.SpriteZOrder.superclass.init.call(this); var s = cocos.Director.get('sharedDirector').get('winSize'); @@ -403,12 +402,12 @@ var SpriteZOrder = SpriteDemo.extend(/** @lends SpriteZOrder.prototype# */{ * * Example using AnimationCache and loading from a Zwoptex .plist file */ -var AnimationCache = SpriteDemo.extend(/** @lends AnimationCache.prototype# */{ +tests.AnimationCache = SpriteDemo.extend(/** @lends AnimationCache.prototype# */{ title: 'AnimationCache', subtitle: 'Sprite should be animated', init: function () { - AnimationCache.superclass.init.call(this); + tests.AnimationCache.superclass.init.call(this); var frameCache = cocos.SpriteFrameCache.get('sharedSpriteFrameCache'), animCache = cocos.AnimationCache.get('sharedAnimationCache'); diff --git a/tests/cocos2d/TileMapTest.js b/tests/cocos2d/TileMapTest.js index d428ae5..23b170f 100644 --- a/tests/cocos2d/TileMapTest.js +++ b/tests/cocos2d/TileMapTest.js @@ -1,5 +1,5 @@ /*globals module exports resource require*/ -/*jslint evil: true, undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; var util = require('util'), @@ -15,6 +15,8 @@ var transitions = [ "TMXOrthoTest2" ]; +var tests = {}; + var kTagTileMap = 1; @@ -23,8 +25,7 @@ function nextAction() { sceneIdx = sceneIdx % transitions.length; var r = transitions[sceneIdx]; - var c = eval('(' + r + ')'); - return c; + return tests[r]; } function backAction() { sceneIdx--; @@ -33,13 +34,11 @@ function backAction() { } var r = transitions[sceneIdx]; - var c = eval('(' + r + ')'); - return c; + return tests[r]; } function restartAction() { var r = transitions[sceneIdx]; - var c = eval('(' + r + ')'); - return c; + return tests[r]; } var TileDemo = nodes.Layer.extend({ @@ -115,12 +114,12 @@ var TileDemo = nodes.Layer.extend({ }); -var TMXOrthoTest2 = TileDemo.extend({ +tests.TMXOrthoTest2 = TileDemo.extend({ title: 'Tile Map Test', subtitle: 'drag screen', init: function () { - TMXOrthoTest2.superclass.init.call(this); + tests.TMXOrthoTest2.superclass.init.call(this); var map = nodes.TMXTiledMap.create({file: module.dirname + "/resources/TileMaps/orthogonal-test1.tmx"}); this.addChild({child: map, z: 0, tag: kTagTileMap}); diff --git a/tests/commonjs.js b/tests/commonjs.js index d368889..2697eba 100644 --- a/tests/commonjs.js +++ b/tests/commonjs.js @@ -1,15 +1,19 @@ +/*globals module exports resource require window*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var container = document.getElementById('cocos2d-tests'); container.className = 'logs'; var logNum = 0; -window.print = function(msg, tag) { +window.print = function (msg, tag) { logNum++; var div = document.createElement('div'); div.appendChild(document.createTextNode(logNum + '. ' + msg)); div.className = 'log ' + tag; container.appendChild(div); container.scrollTop = container.offsetHeight; -} +}; while (container.firstChild) { container.removeChild(container.firstChild); diff --git a/tests/main.js b/tests/main.js index 66bc35e..1b887b9 100644 --- a/tests/main.js +++ b/tests/main.js @@ -1,13 +1,15 @@ +/*globals module exports resource require window*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var params = window.location.search; if (params) { - var name = params.split('=')[1]; - require(name); + var mod = params.split('=')[1]; + require('./' + mod); } else { var c = document.getElementById('cocos2d-tests'); - with (c.style) { - textAlign = 'center'; - fontSize = '20pt'; - lineHeight = c.clientHeight + 'px'; - } + c.style.textAlign = 'center'; + c.style.fontSize = '20pt'; + c.style.lineHeight = c.clientHeight + 'px'; c.appendChild(document.createTextNode('Select a test to run')); } From 11b0dab8c75bafa46fbbac3284ec360863435920 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Jan 2011 19:51:04 +1300 Subject: [PATCH 013/176] Made modules in /libs take priority over modules in the root. --- scripts/module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/module.js b/scripts/module.js index b6a30eb..0fc3b57 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -8,7 +8,7 @@ function resource(path) { (function () { var process = {}; - var modulePaths = ['/', '/libs']; + var modulePaths = ['/libs', '/']; var path; // Will be loaded further down From 50e7274ef5a9b9e181a5a3d723856ba787df7a0d Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Jan 2011 19:52:40 +1300 Subject: [PATCH 014/176] Added QUnit module for unit testing. See: http://docs.jquery.com/Qunit --- make.js | 1 + public/index.html | 210 +++++- src/libs/qunit.js | 1415 +++++++++++++++++++++++++++++++++++++++ tests/cocos2d/config.js | 3 + tests/main.js | 3 + tests/qunit.js | 29 + 6 files changed, 1659 insertions(+), 2 deletions(-) create mode 100644 src/libs/qunit.js create mode 100644 tests/cocos2d/config.js create mode 100644 tests/qunit.js diff --git a/make.js b/make.js index 8bc143b..ff37bd6 100644 --- a/make.js +++ b/make.js @@ -9,6 +9,7 @@ "tests/commonjs/tests/" : "/commonjs/", "tests/cocos2d/" : "/cocos2d/", "tests/commonjs.js": "/commonjs.js", + "tests/qunit.js": "/qunit.js", "tests/main.js": "/main.js" } } diff --git a/public/index.html b/public/index.html index 2809892..ce661c7 100644 --- a/public/index.html +++ b/public/index.html @@ -23,7 +23,6 @@ background: #ccc; } #cocos2d-tests { - border: 1px solid #000; width: 480px; height: 320px; margin: 0 20px; @@ -32,6 +31,206 @@ overflow: auto; width: 800px !important; } + + + /** QUNIT */ + /** Font Family and Sizes */ + + #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial; + } + + #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } + #qunit-tests { font-size: smaller; } + + + /** Resets */ + + #qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult { + margin: 0; + padding: 0; + } + + + /** Header */ + + #qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699a4; + background-color: #0d3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: normal; + + border-radius: 15px 15px 0 0; + -moz-border-radius: 15px 15px 0 0; + -webkit-border-top-right-radius: 15px; + -webkit-border-top-left-radius: 15px; + } + + #qunit-header a { + text-decoration: none; + color: #c2ccd1; + } + + #qunit-header a:hover, + #qunit-header a:focus { + color: #fff; + } + + #qunit-banner { + height: 5px; + } + + #qunit-testrunner-toolbar { + padding: 0.5em 0 0.5em 2em; + color: #5E740B; + background-color: #eee; + } + + #qunit-userAgent { + padding: 0.5em 0 0.5em 2.5em; + background-color: #2b81af; + color: #fff; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; + } + + + /** Tests: Pass/Fail */ + + #qunit-tests { + list-style-position: inside; + } + + #qunit-tests li { + padding: 0.4em 0.5em 0.4em 2.5em; + border-bottom: 1px solid #fff; + list-style-position: inside; + } + + #qunit-tests li strong { + cursor: pointer; + } + + #qunit-tests ol { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #fff; + + border-radius: 15px; + -moz-border-radius: 15px; + -webkit-border-radius: 15px; + + box-shadow: inset 0px 2px 13px #999; + -moz-box-shadow: inset 0px 2px 13px #999; + -webkit-box-shadow: inset 0px 2px 13px #999; + } + + #qunit-tests table { + border-collapse: collapse; + margin-top: .2em; + } + + #qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 .5em 0 0; + } + + #qunit-tests td { + vertical-align: top; + } + + #qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; + } + + #qunit-tests del { + background-color: #e0f2be; + color: #374e0c; + text-decoration: none; + } + + #qunit-tests ins { + background-color: #ffcaca; + color: #500; + text-decoration: none; + } + + /*** Test Counts */ + + #qunit-tests b.counts { color: black; } + #qunit-tests b.passed { color: #5E740B; } + #qunit-tests b.failed { color: #710909; } + + #qunit-tests li li { + margin: 0.5em; + padding: 0.4em 0.5em 0.4em 0.5em; + background-color: #fff; + border-bottom: none; + list-style-position: inside; + } + + /*** Passing Styles */ + + #qunit-tests li li.pass { + color: #5E740B; + background-color: #fff; + border-left: 26px solid #C6E746; + } + + #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } + #qunit-tests .pass .test-name { color: #366097; } + + #qunit-tests .pass .test-actual, + #qunit-tests .pass .test-expected { color: #999999; } + + #qunit-banner.qunit-pass { background-color: #C6E746; } + + /*** Failing Styles */ + + #qunit-tests li li.fail { + color: #710909; + background-color: #fff; + border-left: 26px solid #EE5757; + } + + #qunit-tests .fail { color: #000000; background-color: #EE5757; } + #qunit-tests .fail .test-name, + #qunit-tests .fail .module-name { color: #000000; } + + #qunit-tests .fail .test-actual { color: #EE5757; } + #qunit-tests .fail .test-expected { color: green; } + + #qunit-banner.qunit-fail { background-color: #EE5757; } + + + /** Footer */ + + #qunit-testresult { + padding: 0.5em 0.5em 0.5em 2.5em; + + color: #2b81af; + background-color: #D2E0E6; + + border-radius: 0 0 15px 15px; + -moz-border-radius: 0 0 15px 15px; + -webkit-border-bottom-right-radius: 15px; + -webkit-border-bottom-left-radius: 15px; + } + + /** Fixture */ + + #qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; + } @@ -41,7 +240,14 @@

Tests

  • CommonJS
  • Sprites
  • Tile Maps
  • +
  • QUnit
  • -
    +
    +

    +
    +

    +
      +
      test markup, will be hidden
      +
      diff --git a/src/libs/qunit.js b/src/libs/qunit.js new file mode 100644 index 0000000..30e0395 --- /dev/null +++ b/src/libs/qunit.js @@ -0,0 +1,1415 @@ +/* + * QUnit - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +(function(window) { + +var defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + try { + return !!sessionStorage.getItem; + } catch(e){ + return false; + } + })() +} + +var testId = 0; + +var Test = function(name, testName, expected, testEnvironmentArg, async, callback) { + this.name = name; + this.testName = testName; + this.expected = expected; + this.testEnvironmentArg = testEnvironmentArg; + this.async = async; + this.callback = callback; + this.assertions = []; +}; +Test.prototype = { + init: function() { + var tests = id("qunit-tests"); + if (tests) { + var b = document.createElement("strong"); + b.innerHTML = "Running " + this.name; + var li = document.createElement("li"); + li.appendChild( b ); + li.id = this.id = "test-output" + testId++; + tests.appendChild( li ); + } + }, + setup: function() { + if (this.module != config.previousModule) { + if ( config.previousModule ) { + QUnit.moduleDone( { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + QUnit.moduleStart( { + name: this.module + } ); + } + + config.current = this; + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment); + if (this.testEnvironmentArg) { + extend(this.testEnvironment, this.testEnvironmentArg); + } + + QUnit.testStart( { + name: this.testName + } ); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + try { + if ( !config.pollution ) { + saveGlobal(); + } + + this.testEnvironment.setup.call(this.testEnvironment); + } catch(e) { + QUnit.ok( false, "Setup failed on " + this.testName + ": " + e.message ); + } + }, + run: function() { + if ( this.async ) { + QUnit.stop(); + } + + if ( config.notrycatch ) { + this.callback.call(this.testEnvironment); + return; + } + try { + this.callback.call(this.testEnvironment); + } catch(e) { + fail("Test " + this.testName + " died, exception and test follows", e, this.callback); + QUnit.ok( false, "Died on test #" + (this.assertions.length + 1) + ": " + e.message + " - " + QUnit.jsDump.parse(e) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + start(); + } + } + }, + teardown: function() { + try { + checkPollution(); + this.testEnvironment.teardown.call(this.testEnvironment); + } catch(e) { + QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message ); + } + }, + finish: function() { + if ( this.expected && this.expected != this.assertions.length ) { + QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" ); + } + + var good = 0, bad = 0, + tests = id("qunit-tests"); + + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + var ol = document.createElement("ol"); + + for ( var i = 0; i < this.assertions.length; i++ ) { + var assertion = this.assertions[i]; + + var li = document.createElement("li"); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed"); + ol.appendChild( li ); + + if ( assertion.result ) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + defined.sessionStorage && sessionStorage.setItem("qunit-" + this.testName, bad); + + if (bad == 0) { + ol.style.display = "none"; + } + + var b = document.createElement("strong"); + b.innerHTML = this.name + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + + addEvent(b, "click", function() { + var next = b.nextSibling, display = next.style.display; + next.style.display = display === "none" ? "block" : "none"; + }); + + addEvent(b, "dblclick", function(e) { + var target = e && e.target ? e.target : window.event.srcElement; + if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { + target = target.parentNode; + } + if ( window.location && target.nodeName.toLowerCase() === "strong" ) { + window.location.search = "?" + encodeURIComponent(getText([target]).replace(/\(.+\)$/, "").replace(/(^\s*|\s*$)/g, "")); + } + }); + + var li = id(this.id); + li.className = bad ? "fail" : "pass"; + li.style.display = resultDisplayStyle(!bad); + li.removeChild( li.firstChild ); + li.appendChild( b ); + li.appendChild( ol ); + + } else { + for ( var i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + try { + QUnit.reset(); + } catch(e) { + fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset); + } + + QUnit.testDone( { + name: this.testName, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length + } ); + }, + + queue: function() { + var test = this; + synchronize(function() { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function() { + test.setup(); + }); + synchronize(function() { + test.run(); + }); + synchronize(function() { + test.teardown(); + }); + synchronize(function() { + test.finish(); + }); + } + // defer when previous test run passed, if storage is available + var bad = defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.testName); + if (bad) { + run(); + } else { + synchronize(run); + }; + } + +} + +var QUnit = { + + // call on start of module test to prepend name to all tests + module: function(name, testEnvironment) { + config.currentModule = name; + config.currentModuleTestEnviroment = testEnvironment; + }, + + asyncTest: function(testName, expected, callback) { + if ( arguments.length === 2 ) { + callback = expected; + expected = 0; + } + + QUnit.test(testName, expected, callback, true); + }, + + test: function(testName, expected, callback, async) { + var name = '' + testName + '', testEnvironmentArg; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + // is 2nd argument a testEnvironment? + if ( expected && typeof expected === 'object') { + testEnvironmentArg = expected; + expected = null; + } + + if ( config.currentModule ) { + name = '' + config.currentModule + ": " + name; + } + + if ( !validTest(config.currentModule + ": " + testName) ) { + return; + } + + var test = new Test(name, testName, expected, testEnvironmentArg, async, callback); + test.module = config.currentModule; + test.moduleTestEnvironment = config.currentModuleTestEnviroment; + test.queue(); + }, + + /** + * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + */ + expect: function(asserts) { + config.current.expected = asserts; + }, + + /** + * Asserts true. + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function(a, msg) { + a = !!a; + var details = { + result: a, + message: msg + }; + msg = escapeHtml(msg); + QUnit.log(details); + config.current.assertions.push({ + result: a, + message: msg + }); + }, + + /** + * Checks that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * + * Prefered to ok( actual == expected, message ) + * + * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." ); + * + * @param Object actual + * @param Object expected + * @param String message (optional) + */ + equal: function(actual, expected, message) { + QUnit.push(expected == actual, actual, expected, message); + }, + + notEqual: function(actual, expected, message) { + QUnit.push(expected != actual, actual, expected, message); + }, + + deepEqual: function(actual, expected, message) { + QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); + }, + + notDeepEqual: function(actual, expected, message) { + QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message); + }, + + strictEqual: function(actual, expected, message) { + QUnit.push(expected === actual, actual, expected, message); + }, + + notStrictEqual: function(actual, expected, message) { + QUnit.push(expected !== actual, actual, expected, message); + }, + + raises: function(block, expected, message) { + var actual, ok = false; + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + if (actual) { + // we don't want to validate thrown error + if (!expected) { + ok = true; + // expected is a regexp + } else if (QUnit.objectType(expected) === "regexp") { + ok = expected.test(actual); + // expected is a constructor + } else if (actual instanceof expected) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if (expected.call({}, actual) === true) { + ok = true; + } + } + + QUnit.ok(ok, message); + }, + + start: function() { + config.semaphore--; + if (config.semaphore > 0) { + // don't start until equal number of stop-calls + return; + } + if (config.semaphore < 0) { + // ignore if start is called more often then stop + config.semaphore = 0; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if ( config.timeout ) { + clearTimeout(config.timeout); + } + + config.blocking = false; + process(); + }, 13); + } else { + config.blocking = false; + process(); + } + }, + + stop: function(timeout) { + config.semaphore++; + config.blocking = true; + + if ( timeout && defined.setTimeout ) { + clearTimeout(config.timeout); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + QUnit.start(); + }, timeout); + } + } + +}; + +// Backwards compatibility, deprecated +QUnit.equals = QUnit.equal; +QUnit.same = QUnit.deepEqual; + +// Maintain internal state +var config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true +}; + +// Load paramaters +(function() { + var location = window.location || { search: "", protocol: "file:" }, + GETParams = location.search.slice(1).split('&'); + + for ( var i = 0; i < GETParams.length; i++ ) { + GETParams[i] = decodeURIComponent( GETParams[i] ); + if ( GETParams[i] === "noglobals" ) { + GETParams.splice( i, 1 ); + i--; + config.noglobals = true; + } else if ( GETParams[i] === "notrycatch" ) { + GETParams.splice( i, 1 ); + i--; + config.notrycatch = true; + } else if ( GETParams[i].search('=') > -1 ) { + GETParams.splice( i, 1 ); + i--; + } + } + + // restrict modules/tests by get parameters + config.filters = GETParams; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = !!(location.protocol === 'file:'); +})(); + +// Expose the API as global variables, unless an 'exports' +// object exists, in that case we assume we're in CommonJS +if ( typeof exports === "undefined" || typeof require === "undefined" ) { + extend(window, QUnit); + window.QUnit = QUnit; +} else { + extend(exports, QUnit); + exports.QUnit = QUnit; +} + +// define these after exposing globals to keep them in these QUnit namespace only +extend(QUnit, { + config: config, + + // Initialize the configuration options + init: function() { + extend(config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date, + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filters: [], + queue: [], + semaphore: 0 + }); + + var tests = id("qunit-tests"), + banner = id("qunit-banner"), + result = id("qunit-testresult"); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + }, + + /** + * Resets the test setup. Useful for tests that modify the DOM. + * + * If jQuery is available, uses jQuery's html(), otherwise just innerHTML. + */ + reset: function() { + if ( window.jQuery ) { + jQuery( "#main, #qunit-fixture" ).html( config.fixture ); + } else { + var main = id( 'main' ) || id( 'qunit-fixture' ); + if ( main ) { + main.innerHTML = config.fixture; + } + } + }, + + /** + * Trigger an event on an element. + * + * @example triggerEvent( document.body, "click" ); + * + * @param DOMElement elem + * @param String type + */ + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent("MouseEvents"); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + elem.dispatchEvent( event ); + + } else if ( elem.fireEvent ) { + elem.fireEvent("on"+type); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) == type; + }, + + objectType: function( obj ) { + if (typeof obj === "undefined") { + return "undefined"; + + // consider: typeof null === object + } + if (obj === null) { + return "null"; + } + + var type = Object.prototype.toString.call( obj ) + .match(/^\[object\s(.*)\]$/)[1] || ''; + + switch (type) { + case 'Number': + if (isNaN(obj)) { + return "nan"; + } else { + return "number"; + } + case 'String': + case 'Boolean': + case 'Array': + case 'Date': + case 'RegExp': + case 'Function': + return type.toLowerCase(); + } + if (typeof obj === "object") { + return "object"; + } + return undefined; + }, + + push: function(result, actual, expected, message) { + var details = { + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeHtml(message) || (result ? "okay" : "failed"); + message = '' + message + ""; + expected = escapeHtml(QUnit.jsDump.parse(expected)); + actual = escapeHtml(QUnit.jsDump.parse(actual)); + var output = message + ''; + if (actual != expected) { + output += ''; + output += ''; + } + if (!result) { + var source = sourceFromStacktrace(); + if (source) { + details.source = source; + output += ''; + } + } + output += "
      Expected:
      ' + expected + '
      Result:
      ' + actual + '
      Diff:
      ' + QUnit.diff(expected, actual) +'
      Source:
      ' + source +'
      "; + + QUnit.log(details); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: function() {}, + // done: { failed, passed, total, runtime } + done: function() {}, + // log: { result, actual, expected, message } + log: function() {}, + // testStart: { name } + testStart: function() {}, + // testDone: { name, failed, passed, total } + testDone: function() {}, + // moduleStart: { name } + moduleStart: function() {}, + // moduleDone: { name, failed, passed, total } + moduleDone: function() {} +}); + +if ( typeof document === "undefined" || document.readyState === "complete" ) { + config.autorun = true; +} + +addEvent(window, "load", function() { + QUnit.begin({}); + + // Initialize the config, saving the execution queue + var oldconfig = extend({}, config); + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + var userAgent = id("qunit-userAgent"); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + var banner = id("qunit-header"); + if ( banner ) { + var paramsIndex = location.href.lastIndexOf(location.search); + if ( paramsIndex > -1 ) { + var mainPageLocation = location.href.slice(0, paramsIndex); + if ( mainPageLocation == location.href ) { + banner.innerHTML = ' ' + banner.innerHTML + ' '; + } else { + var testName = decodeURIComponent(location.search.slice(1)); + banner.innerHTML = '' + banner.innerHTML + '' + testName + ''; + } + } + } + + var toolbar = id("qunit-testrunner-toolbar"); + if ( toolbar ) { + var filter = document.createElement("input"); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + addEvent( filter, "click", function() { + var li = document.getElementsByTagName("li"); + for ( var i = 0; i < li.length; i++ ) { + if ( li[i].className.indexOf("pass") > -1 ) { + li[i].style.display = filter.checked ? "none" : ""; + } + } + if ( defined.sessionStorage ) { + sessionStorage.setItem("qunit-filter-passed-tests", filter.checked ? "true" : ""); + } + }); + if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { + filter.checked = true; + } + toolbar.appendChild( filter ); + + var label = document.createElement("label"); + label.setAttribute("for", "qunit-filter-pass"); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + } + + var main = id('main') || id('qunit-fixture'); + if ( main ) { + config.fixture = main.innerHTML; + } + + if (config.autostart) { + QUnit.start(); + } +}); + +function done() { + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + QUnit.moduleDone( { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + + var banner = id("qunit-banner"), + tests = id("qunit-tests"), + runtime = +new Date - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + 'Tests completed in ', + runtime, + ' milliseconds.
      ', + '', + passed, + ' tests of ', + config.stats.all, + ' passed, ', + config.stats.bad, + ' failed.' + ].join(''); + + if ( banner ) { + banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass"); + } + + if ( tests ) { + var result = id("qunit-testresult"); + + if ( !result ) { + result = document.createElement("p"); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests.nextSibling ); + } + + result.innerHTML = html; + } + + QUnit.done( { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + } ); +} + +function validTest( name ) { + var i = config.filters.length, + run = false; + + if ( !i ) { + return true; + } + + while ( i-- ) { + var filter = config.filters[i], + not = filter.charAt(0) == '!'; + + if ( not ) { + filter = filter.slice(1); + } + + if ( name.indexOf(filter) !== -1 ) { + return !not; + } + + if ( not ) { + run = true; + } + } + + return run; +} + +// so far supports only Firefox, Chrome and Opera (buggy) +// could be extended in the future to use something like https://github.com/csnover/TraceKit +function sourceFromStacktrace() { + try { + throw new Error(); + } catch ( e ) { + if (e.stacktrace) { + // Opera + return e.stacktrace.split("\n")[6]; + } else if (e.stack) { + // Firefox, Chrome + return e.stack.split("\n")[4]; + } + } +} + +function resultDisplayStyle(passed) { + return passed && id("qunit-filter-pass") && id("qunit-filter-pass").checked ? 'none' : ''; +} + +function escapeHtml(s) { + if (!s) { + return ""; + } + s = s + ""; + return s.replace(/[\&"<>\\]/g, function(s) { + switch(s) { + case "&": return "&"; + case "\\": return "\\\\"; + case '"': return '\"'; + case "<": return "<"; + case ">": return ">"; + default: return s; + } + }); +} + +function synchronize( callback ) { + config.queue.push( callback ); + + if ( config.autorun && !config.blocking ) { + process(); + } +} + +function process() { + var start = (new Date()).getTime(); + + while ( config.queue.length && !config.blocking ) { + if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) { + config.queue.shift()(); + } else { + window.setTimeout( process, 13 ); + break; + } + } + if (!config.blocking && !config.queue.length) { + done(); + } +} + +function saveGlobal() { + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + config.pollution.push( key ); + } + } +} + +function checkPollution( name ) { + var old = config.pollution; + saveGlobal(); + + var newGlobals = diff( old, config.pollution ); + if ( newGlobals.length > 0 ) { + ok( false, "Introduced global variable(s): " + newGlobals.join(", ") ); + config.current.expected++; + } + + var deletedGlobals = diff( config.pollution, old ); + if ( deletedGlobals.length > 0 ) { + ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") ); + config.current.expected++; + } +} + +// returns a new Array with the elements that are in a but not in b +function diff( a, b ) { + var result = a.slice(); + for ( var i = 0; i < result.length; i++ ) { + for ( var j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice(i, 1); + i--; + break; + } + } + } + return result; +} + +function fail(message, exception, callback) { + if ( typeof console !== "undefined" && console.error && console.warn ) { + console.error(message); + console.error(exception); + console.warn(callback.toString()); + + } else if ( window.opera && opera.postError ) { + opera.postError(message, exception, callback.toString); + } +} + +function extend(a, b) { + for ( var prop in b ) { + a[prop] = b[prop]; + } + + return a; +} + +function addEvent(elem, type, fn) { + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, fn ); + } else { + fn(); + } +} + +function id(name) { + return !!(typeof document !== "undefined" && document && document.getElementById) && + document.getElementById( name ); +} + +// Test for equality any JavaScript type. +// Discussions and reference: http://philrathe.com/articles/equiv +// Test suites: http://philrathe.com/tests/equiv +// Author: Philippe Rathé +QUnit.equiv = function () { + + var innerEquiv; // the real equiv function + var callers = []; // stack to decide between skip/abort functions + var parents = []; // stack to avoiding loops from circular referencing + + // Call the o related callback with the given arguments. + function bindCallbacks(o, callbacks, args) { + var prop = QUnit.objectType(o); + if (prop) { + if (QUnit.objectType(callbacks[prop]) === "function") { + return callbacks[prop].apply(callbacks, args); + } else { + return callbacks[prop]; // or undefined + } + } + } + + var callbacks = function () { + + // for string, boolean, number and null + function useStrictEquality(b, a) { + if (b instanceof a.constructor || a instanceof b.constructor) { + // to catch short annotaion VS 'new' annotation of a declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string": useStrictEquality, + "boolean": useStrictEquality, + "number": useStrictEquality, + "null": useStrictEquality, + "undefined": useStrictEquality, + + "nan": function (b) { + return isNaN(b); + }, + + "date": function (b, a) { + return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf(); + }, + + "regexp": function (b, a) { + return QUnit.objectType(b) === "regexp" && + a.source === b.source && // the regex itself + a.global === b.global && // and its modifers (gmi) ... + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function": function () { + var caller = callers[callers.length - 1]; + return caller !== Object && + typeof caller !== "undefined"; + }, + + "array": function (b, a) { + var i, j, loop; + var len; + + // b could be an object literal here + if ( ! (QUnit.objectType(b) === "array")) { + return false; + } + + len = a.length; + if (len !== b.length) { // safe and faster + return false; + } + + //track reference to avoid circular references + parents.push(a); + for (i = 0; i < len; i++) { + loop = false; + for(j=0;j= 0) { + type = "array"; + } else { + type = typeof obj; + } + return type; + }, + separator:function() { + return this.multiline ? this.HTML ? '
      ' : '\n' : this.HTML ? ' ' : ' '; + }, + indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + if ( !this.multiline ) + return ''; + var chr = this.indentChar; + if ( this.HTML ) + chr = chr.replace(/\t/g,' ').replace(/ /g,' '); + return Array( this._depth_ + (extra||0) ).join(chr); + }, + up:function( a ) { + this._depth_ += a || 1; + }, + down:function( a ) { + this._depth_ -= a || 1; + }, + setParser:function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote:quote, + literal:literal, + join:join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers:{ + window: '[Window]', + document: '[Document]', + error:'[ERROR]', //when no parser is found, shouldn't happen + unknown: '[Unknown]', + 'null':'null', + undefined:'undefined', + 'function':function( fn ) { + var ret = 'function', + name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE + if ( name ) + ret += ' ' + name; + ret += '('; + + ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join(''); + return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' ); + }, + array: array, + nodelist: array, + arguments: array, + object:function( map ) { + var ret = [ ]; + QUnit.jsDump.up(); + for ( var key in map ) + ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(map[key]) ); + QUnit.jsDump.down(); + return join( '{', ret, '}' ); + }, + node:function( node ) { + var open = QUnit.jsDump.HTML ? '<' : '<', + close = QUnit.jsDump.HTML ? '>' : '>'; + + var tag = node.nodeName.toLowerCase(), + ret = open + tag; + + for ( var a in QUnit.jsDump.DOMAttrs ) { + var val = node[QUnit.jsDump.DOMAttrs[a]]; + if ( val ) + ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' ); + } + return ret + close + open + '/' + tag + close; + }, + functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function + var l = fn.length; + if ( !l ) return ''; + + var args = Array(l); + while ( l-- ) + args[l] = String.fromCharCode(97+l);//97 is 'a' + return ' ' + args.join(', ') + ' '; + }, + key:quote, //object calls it internally, the key part of an item in a map + functionCode:'[code]', //function calls it internally, it's the content of the function + attribute:quote, //node calls it internally, it's an html attribute value + string:quote, + date:quote, + regexp:literal, //regex + number:literal, + 'boolean':literal + }, + DOMAttrs:{//attributes to dump from nodes, name=>realName + id:'id', + name:'name', + 'class':'className' + }, + HTML:false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar:' ',//indentation unit + multiline:true //if true, items in a collection, are separated by a \n, else just a space. + }; + + return jsDump; +})(); + +// from Sizzle.js +function getText( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += getText( elem.childNodes ); + } + } + + return ret; +}; + +/* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick brown fox jumped jumps over" + */ +QUnit.diff = (function() { + function diff(o, n){ + var ns = new Object(); + var os = new Object(); + + for (var i = 0; i < n.length; i++) { + if (ns[n[i]] == null) + ns[n[i]] = { + rows: new Array(), + o: null + }; + ns[n[i]].rows.push(i); + } + + for (var i = 0; i < o.length; i++) { + if (os[o[i]] == null) + os[o[i]] = { + rows: new Array(), + n: null + }; + os[o[i]].rows.push(i); + } + + for (var i in ns) { + if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { + n[ns[i].rows[0]] = { + text: n[ns[i].rows[0]], + row: os[i].rows[0] + }; + o[os[i].rows[0]] = { + text: o[os[i].rows[0]], + row: ns[i].rows[0] + }; + } + } + + for (var i = 0; i < n.length - 1; i++) { + if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && + n[i + 1] == o[n[i].row + 1]) { + n[i + 1] = { + text: n[i + 1], + row: n[i].row + 1 + }; + o[n[i].row + 1] = { + text: o[n[i].row + 1], + row: i + 1 + }; + } + } + + for (var i = n.length - 1; i > 0; i--) { + if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && + n[i - 1] == o[n[i].row - 1]) { + n[i - 1] = { + text: n[i - 1], + row: n[i].row - 1 + }; + o[n[i].row - 1] = { + text: o[n[i].row - 1], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function(o, n){ + o = o.replace(/\s+$/, ''); + n = n.replace(/\s+$/, ''); + var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)); + + var str = ""; + + var oSpace = o.match(/\s+/g); + if (oSpace == null) { + oSpace = [" "]; + } + else { + oSpace.push(" "); + } + var nSpace = n.match(/\s+/g); + if (nSpace == null) { + nSpace = [" "]; + } + else { + nSpace.push(" "); + } + + if (out.n.length == 0) { + for (var i = 0; i < out.o.length; i++) { + str += '' + out.o[i] + oSpace[i] + ""; + } + } + else { + if (out.n[0].text == null) { + for (n = 0; n < out.o.length && out.o[n].text == null; n++) { + str += '' + out.o[n] + oSpace[n] + ""; + } + } + + for (var i = 0; i < out.n.length; i++) { + if (out.n[i].text == null) { + str += '' + out.n[i] + nSpace[i] + ""; + } + else { + var pre = ""; + + for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { + pre += '' + out.o[n] + oSpace[n] + ""; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; +})(); + +})(this); diff --git a/tests/cocos2d/config.js b/tests/cocos2d/config.js new file mode 100644 index 0000000..8f9a2c1 --- /dev/null +++ b/tests/cocos2d/config.js @@ -0,0 +1,3 @@ +{ + "FLIP_Y_AXIS": false +} diff --git a/tests/main.js b/tests/main.js index 1b887b9..7ff6d77 100644 --- a/tests/main.js +++ b/tests/main.js @@ -11,5 +11,8 @@ if (params) { c.style.textAlign = 'center'; c.style.fontSize = '20pt'; c.style.lineHeight = c.clientHeight + 'px'; + while (c.firstChild) { + c.removeChild(c.firstChild); + } c.appendChild(document.createTextNode('Select a test to run')); } diff --git a/tests/qunit.js b/tests/qunit.js new file mode 100644 index 0000000..5eb8116 --- /dev/null +++ b/tests/qunit.js @@ -0,0 +1,29 @@ +/*globals module exports resource require*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + +var q = require('qunit'); + +q.test("a basic test example", function () { + q.ok(true, "this test is fine"); + var value = "hello"; + q.equals("hello", value, "We expect value to be hello"); +}); + +q.module("Module A"); + +q.test("first test within module", function () { + q.ok(true, "all pass"); +}); + +q.test("second test within module", function () { + q.ok(true, "all pass"); +}); + +q.module("Module B"); + +q.test("some other test", function () { + q.expect(2); + q.equals(true, false, "failing test"); + q.equals(true, true, "passing test"); +}); From 82d2fee06f8e8eb3de2ec30344c54f070dee7a1b Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Jan 2011 23:12:25 +1300 Subject: [PATCH 015/176] Big code cleanup. All code is ECMAScript 5 strict. All code validated with JSLint. Deprected use of @super, instead use: ClassName.superclass.foo.apply(this, arguments); --- src/libs/cocos2d/ActionManager.js | 50 ++++--- src/libs/cocos2d/Animation.js | 12 +- src/libs/cocos2d/AnimationCache.js | 24 +-- src/libs/cocos2d/Director.js | 54 +++---- src/libs/cocos2d/EventDispatcher.js | 70 ++++----- src/libs/cocos2d/Scheduler.js | 74 ++++++---- src/libs/cocos2d/SpriteFrame.js | 24 +-- src/libs/cocos2d/SpriteFrameCache.js | 26 ++-- src/libs/cocos2d/TMXOrientation.js | 4 + src/libs/cocos2d/TMXXMLParser.js | 161 +++++++++++---------- src/libs/cocos2d/Texture2D.js | 22 +-- src/libs/cocos2d/TextureAtlas.js | 36 +++-- src/libs/cocos2d/actions/Action.js | 39 ++--- src/libs/cocos2d/actions/ActionInstant.js | 47 +++--- src/libs/cocos2d/actions/ActionInterval.js | 135 ++++++++--------- src/libs/cocos2d/actions/index.js | 6 +- src/libs/cocos2d/config.js | 4 +- src/libs/cocos2d/index.js | 8 +- src/libs/cocos2d/nodes/BatchNode.js | 54 ++++--- src/libs/cocos2d/nodes/Label.js | 16 +- src/libs/cocos2d/nodes/Layer.js | 30 ++-- src/libs/cocos2d/nodes/Menu.js | 33 +++-- src/libs/cocos2d/nodes/MenuItem.js | 44 +++--- src/libs/cocos2d/nodes/Node.js | 131 +++++++++-------- src/libs/cocos2d/nodes/RenderTexture.js | 22 +-- src/libs/cocos2d/nodes/Scene.js | 8 +- src/libs/cocos2d/nodes/Sprite.js | 60 ++++---- src/libs/cocos2d/nodes/TMXLayer.js | 46 +++--- src/libs/cocos2d/nodes/TMXTiledMap.js | 37 +++-- src/libs/cocos2d/nodes/index.js | 8 +- 30 files changed, 715 insertions(+), 570 deletions(-) diff --git a/src/libs/cocos2d/ActionManager.js b/src/libs/cocos2d/ActionManager.js index e30cb7b..e924655 100644 --- a/src/libs/cocos2d/ActionManager.js +++ b/src/libs/cocos2d/ActionManager.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), console = require('system').console, Timer = require('./Scheduler').Timer, @@ -24,8 +28,8 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ * @extends BObject * @singleton */ - init: function() { - @super; + init: function () { + ActionManager.superclass.init.call(this); Scheduler.get('sharedScheduler').scheduleUpdate({target: this, priority: 0, paused: false}); this.targets = []; @@ -40,22 +44,22 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ * * @opt {cocos.nodes.Node} target Node to run the action on */ - addAction: function(opts) { + addAction: function (opts) { - var targetID = opts['target'].get('id'); + var targetID = opts.target.get('id'); var element = this.targets[targetID]; if (!element) { element = this.targets[targetID] = { paused: false, - target: opts['target'], + target: opts.target, actions: [] }; } - element.actions.push(opts['action']); + element.actions.push(opts.action); - opts['action'].startWithTarget(opts['target']); + opts.action.startWithTarget(opts.target); }, /** @@ -63,7 +67,7 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ * * @param {cocos.actions.Action} action Action to remove */ - removeAction: function(action) { + removeAction: function (action) { var targetID = action.originalTarget.get('id'), element = this.targets[targetID]; @@ -84,7 +88,7 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ element.actions[actionIndex] = null; element.actions.splice(actionIndex, 1); // Delete array item - if (element.actions.length == 0) { + if (element.actions.length === 0) { if (this.currentTarget == element) { this.set('currentTargetSalvaged', true); } @@ -97,7 +101,7 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ * * @param {cocos.nodes.Node} target Node to remove all actions for */ - removeAllActionsFromTarget: function(target) { + removeAllActionsFromTarget: function (target) { var targetID = target.get('id'); var element = this.targets[targetID]; @@ -106,22 +110,26 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ } // Delete everything in array but don't replace it incase something else has a reference - element.actions.splice(0, element.actions.length-1); + element.actions.splice(0, element.actions.length - 1); }, /** * @private */ - update: function(dt) { + update: function (dt) { var self = this; - util.each(this.targets, function(currentTarget, i) { + util.each(this.targets, function (currentTarget, i) { - if (!currentTarget) return; + if (!currentTarget) { + return; + } self.currentTarget = currentTarget; if (!currentTarget.paused) { - util.each(currentTarget.actions, function(currentAction, j) { - if (!currentAction) return; + util.each(currentTarget.actions, function (currentAction, j) { + if (!currentAction) { + return; + } currentTarget.currentAction = currentAction; currentTarget.currentActionSalvaged = false; @@ -141,19 +149,17 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ }); } - if (self.currentTargetSalvaged && currentTarget.actions.length == 0) { + if (self.currentTargetSalvaged && currentTarget.actions.length === 0) { self.targets[i] = null; delete self.targets[i]; } }); - - delete self; }, - pauseTarget: function(target) { + pauseTarget: function (target) { }, - resumeTarget: function(target) { + resumeTarget: function (target) { // TODO } }); @@ -164,7 +170,7 @@ util.extend(ActionManager, /** @lends cocos.ActionManager */{ * @getter sharedManager * @type cocos.ActionManager */ - get_sharedManager: function(key) { + get_sharedManager: function (key) { if (!this._instance) { this._instance = this.create(); } diff --git a/src/libs/cocos2d/Animation.js b/src/libs/cocos2d/Animation.js index 92a0f6e..822c124 100644 --- a/src/libs/cocos2d/Animation.js +++ b/src/libs/cocos2d/Animation.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'); var Animation = BObject.extend(/** @lends cocos.Animation# */{ @@ -22,11 +26,11 @@ var Animation = BObject.extend(/** @lends cocos.Animation# */{ * var animation = cocos.Animation.create({frames: [f1, f2, f3], delay: 0.1}); * sprite.runAction(cocos.actions.Animate.create({animation: animation})); */ - init: function(opts) { - @super; + init: function (opts) { + Animation.superclass.init.call(this, opts); - this.frames = opts['frames'] || []; - this.delay = opts['delay'] || 0.0; + this.frames = opts.frames || []; + this.delay = opts.delay || 0.0; } }); diff --git a/src/libs/cocos2d/AnimationCache.js b/src/libs/cocos2d/AnimationCache.js index 5d6259d..faeeaee 100644 --- a/src/libs/cocos2d/AnimationCache.js +++ b/src/libs/cocos2d/AnimationCache.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), Plist = require('Plist').Plist; @@ -14,8 +18,8 @@ var AnimationCache = BObject.extend(/** @lends cocos.AnimationCache# */{ * @extends BObject * @singleton */ - init: function() { - @super; + init: function () { + AnimationCache.superclass.init.call(this); this.set('animations', {}); }, @@ -26,9 +30,9 @@ var AnimationCache = BObject.extend(/** @lends cocos.AnimationCache# */{ * @opt {String} name Unique name of the animation * @opt {cocos.Animcation} animation Animation to cache */ - addAnimation: function(opts) { - var name = opts['name'], - animation = opts['animation']; + addAnimation: function (opts) { + var name = opts.name, + animation = opts.animation; this.get('animations')[name] = animation; }, @@ -38,8 +42,8 @@ var AnimationCache = BObject.extend(/** @lends cocos.AnimationCache# */{ * * @opt {String} name Unique name of the animation */ - removeAnimation: function(opts) { - var name = opts['name']; + removeAnimation: function (opts) { + var name = opts.name; delete this.get('animations')[name]; }, @@ -50,8 +54,8 @@ var AnimationCache = BObject.extend(/** @lends cocos.AnimationCache# */{ * @opt {String} name Unique name of the animation * @returns {cocos.Animation} Cached animation */ - getAnimation: function(opts) { - var name = opts['name']; + getAnimation: function (opts) { + var name = opts.name; return this.get('animations')[name]; } @@ -65,7 +69,7 @@ util.extend(AnimationCache, /** @lends cocos.AnimationCache */{ * @getter sharedAnimationCache * @type cocos.AnimationCache */ - get_sharedAnimationCache: function(key) { + get_sharedAnimationCache: function (key) { if (!this._instance) { this._instance = this.create(); } diff --git a/src/libs/cocos2d/Director.js b/src/libs/cocos2d/Director.js index 13db078..eda64f7 100644 --- a/src/libs/cocos2d/Director.js +++ b/src/libs/cocos2d/Director.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), geo = require('geometry'), ccp = geo.ccp, @@ -20,7 +24,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ nextDeltaTimeZero: false, lastUpdate: 0, - _nextScene:null, + _nextScene: null, /** *

      Creates and handles the main view and manages how and when to execute the @@ -34,8 +38,8 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * @extends BObject * @singleton */ - init: function() { - @super; + init: function () { + Director.superclass.init.call(this); this.set('sceneStack', []); }, @@ -45,7 +49,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * * @param {HTMLElement} view Any HTML element to add the application to */ - attachInView: function(view) { + attachInView: function (view) { if (!view.tagName) { throw "Director.attachInView must be given a HTML DOM Node"; } @@ -86,7 +90,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ evt.locationInCanvas = self.convertEventToCanvas(evt); eventDispatcher.mouseDragged(evt); - }; + } function mouseUp(evt) { evt.locationInWindow = ccp(evt.clientX, evt.clientY); evt.locationInCanvas = self.convertEventToCanvas(evt); @@ -96,7 +100,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ eventDispatcher.mouseUp(evt); - }; + } document.body.addEventListener('mousemove', mouseDragged, false); document.body.addEventListener('mouseup', mouseUp, false); @@ -115,10 +119,10 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ // Keyboard events function keyDown(evt) { this._keysDown = this._keysDown || {}; - eventDispatcher.keyDown(evt) + eventDispatcher.keyDown(evt); } function keyUp(evt) { - eventDispatcher.keyUp(evt) + eventDispatcher.keyUp(evt); } /* function keyPress(evt) { @@ -139,13 +143,13 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * * @param {cocos.Scene} scene The scene to start */ - runWithScene: function(scene) { + runWithScene: function (scene) { if (!(scene instanceof Scene)) { throw "Director.runWithScene must be given an instance of Scene"; } if (this._runningScene) { - throw "You can't run an scene if another Scene is running. Use replaceScene or pushScene instead" + throw "You can't run an scene if another Scene is running. Use replaceScene or pushScene instead"; } this.pushScene(scene); @@ -158,7 +162,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * * @param {cocos.Scene} scene The scene to replace with */ - replaceScene: function(scene) { + replaceScene: function (scene) { var index = this.sceneStack.length; this._sendCleanupToScene = true; @@ -173,7 +177,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * the stack the execution is terminated. ONLY call it if there is a * running scene. */ - popScene: function() { + popScene: function () { }, /** @@ -184,7 +188,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * * @param {cocos.Scene} scene The scene to add to the stack */ - pushScene: function(scene) { + pushScene: function (scene) { this._nextScene = scene; }, @@ -192,7 +196,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * The main loop is triggered again. Call this function only if * cocos.Directory#stopAnimation was called earlier. */ - startAnimation: function() { + startAnimation: function () { var animationInterval = 1.0 / this.get('maxFrameRate'); this._animationTimer = setInterval(util.callback(this, 'drawScene'), animationInterval * 1000); }, @@ -202,15 +206,15 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * triggered anymore. If you want to pause your animation call * cocos.Directory#pause instead. */ - stopAnimation: function() { + stopAnimation: function () { }, /** * Calculate time since last call * @private */ - calculateDeltaTime: function() { - var now = (new Date).getTime() /1000; + calculateDeltaTime: function () { + var now = (new Date()).getTime() / 1000; if (this.nextDeltaTimeZero) { this.dt = 0; @@ -226,7 +230,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * The main run loop * @private */ - drawScene: function() { + drawScene: function () { this.calculateDeltaTime(); if (!this.isPaused) { @@ -255,7 +259,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * Initialises the next scene * @private */ - setNextScene: function() { + setNextScene: function () { // TODO transitions if (this._runningScene) { @@ -272,12 +276,12 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ this._runningScene.onEnter(); }, - convertEventToCanvas: function(evt) { + convertEventToCanvas: function (evt) { var x = this.canvas.offsetLeft - document.documentElement.scrollLeft, y = this.canvas.offsetTop - document.documentElement.scrollTop; var o = this.canvas; - while (o = o.offsetParent) { + while ((o = o.offsetParent)) { x += o.offsetLeft - o.scrollLeft; y += o.offsetTop - o.scrollTop; } @@ -290,7 +294,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ return p; }, - showFPS: function() { + showFPS: function () { if (!this._fpsLabel) { var Label = require('./nodes/Label').Label; this._fpsLabel = Label.create({string: '', fontSize: 16}); @@ -303,12 +307,12 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ this._frames++; this._accumDt += this.get('dt'); - if (this._accumDt > 1.0/3.0) { + if (this._accumDt > 1.0 / 3.0) { var frameRate = this._frames / this._accumDt; this._frames = 0; this._accumDt = 0; - this._fpsLabel.set('string', 'FPS: ' + (Math.round(frameRate*100)/100).toString()); + this._fpsLabel.set('string', 'FPS: ' + (Math.round(frameRate * 100) / 100).toString()); } @@ -330,7 +334,7 @@ util.extend(Director, /** @lends cocos.Director */{ * @getter sharedDirector * @type cocos.Director */ - get_sharedDirector: function(key) { + get_sharedDirector: function (key) { if (!this._instance) { this._instance = this.create(); } diff --git a/src/libs/cocos2d/EventDispatcher.js b/src/libs/cocos2d/EventDispatcher.js index ab0a296..8ebd568 100644 --- a/src/libs/cocos2d/EventDispatcher.js +++ b/src/libs/cocos2d/EventDispatcher.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), geo = require('geometry'); @@ -15,8 +19,8 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ * @extends BObject * @singleton */ - init: function() { - @super; + init: function () { + EventDispatcher.superclass.init.call(this); this.keyboardDelegates = []; this.mouseDelegates = []; @@ -24,11 +28,11 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ this._keysDown = {}; }, - addDelegate: function(opts) { - var delegate = opts['delegate'], - priority = opts['priority'], - flags = opts['flags'], - list = opts['list']; + addDelegate: function (opts) { + var delegate = opts.delegate, + priority = opts.priority, + flags = opts.flags, + list = opts.list; var listElement = { delegate: delegate, @@ -53,9 +57,9 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ } }, - removeDelegate: function(opts) { - var delegate = opts['delegate'], - list = opts['list']; + removeDelegate: function (opts) { + var delegate = opts.delegate, + list = opts.list; var idx = -1, i; @@ -71,15 +75,15 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ } list.splice(idx, 1); }, - removeAllDelegates: function(opts) { - var list = opts['list']; + removeAllDelegates: function (opts) { + var list = opts.list; - list.splice(0, list.length -1); + list.splice(0, list.length - 1); }, - addMouseDelegate: function(opts) { - var delegate = opts['delegate'], - priority = opts['priority']; + addMouseDelegate: function (opts) { + var delegate = opts.delegate, + priority = opts.priority; var flags = 0; @@ -88,19 +92,19 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ this.addDelegate({delegate: delegate, priority: priority, flags: flags, list: this.mouseDelegates}); }, - removeMouseDelegate: function(opts) { - var delegate = opts['delegate']; + removeMouseDelegate: function (opts) { + var delegate = opts.delegate; this.removeDelegate({delegate: delegate, list: this.mouseDelegates}); }, - removeAllMouseDelegate: function() { + removeAllMouseDelegate: function () { this.removeAllDelegates({list: this.mouseDelegates}); }, - addKeyboardDelegate: function(opts) { - var delegate = opts['delegate'], - priority = opts['priority']; + addKeyboardDelegate: function (opts) { + var delegate = opts.delegate, + priority = opts.priority; var flags = 0; @@ -109,13 +113,13 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ this.addDelegate({delegate: delegate, priority: priority, flags: flags, list: this.keyboardDelegates}); }, - removeKeyboardDelegate: function(opts) { - var delegate = opts['delegate']; + removeKeyboardDelegate: function (opts) { + var delegate = opts.delegate; this.removeDelegate({delegate: delegate, list: this.keyboardDelegates}); }, - removeAllKeyboardDelegate: function() { + removeAllKeyboardDelegate: function () { this.removeAllDelegates({list: this.keyboardDelegates}); }, @@ -123,7 +127,7 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ // Mouse Events - mouseDown: function(evt) { + mouseDown: function (evt) { if (!this.dispatchEvents) { return; } @@ -141,7 +145,7 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ } } }, - mouseMoved: function(evt) { + mouseMoved: function (evt) { if (!this.dispatchEvents) { return; } @@ -168,7 +172,7 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ } } }, - mouseDragged: function(evt) { + mouseDragged: function (evt) { if (!this.dispatchEvents) { return; } @@ -193,9 +197,9 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ break; } } - }; + } }, - mouseUp: function(evt) { + mouseUp: function (evt) { if (!this.dispatchEvents) { return; } @@ -212,7 +216,7 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ }, // Keyboard events - keyDown: function(evt) { + keyDown: function (evt) { var kc = evt.keyCode; if (!this.dispatchEvents || this._keysDown[kc]) { return; @@ -231,7 +235,7 @@ var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ } }, - keyUp: function(evt) { + keyUp: function (evt) { if (!this.dispatchEvents) { return; } @@ -264,7 +268,7 @@ util.extend(EventDispatcher, /** @lends cocos.EventDispatcher */{ * @getter sharedDispatcher * @type cocos.EventDispatcher */ - get_sharedDispatcher: function(key) { + get_sharedDispatcher: function (key) { if (!this._instance) { this._instance = this.create(); } diff --git a/src/libs/cocos2d/Scheduler.js b/src/libs/cocos2d/Scheduler.js index f364516..bc0d008 100644 --- a/src/libs/cocos2d/Scheduler.js +++ b/src/libs/cocos2d/Scheduler.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'); /** @ignore */ @@ -33,18 +37,18 @@ var Timer = BObject.extend(/** @lends cocos.Timer# */{ * @opt {Function} callback The function to run at each interval * @opt {Float} interval Number of milliseconds to wait between each exectuion of callback */ - init: function(opts) { - @super; + init: function (opts) { + Timer.superclass.init(this, opts); - this.set('callback', opts['callback']); - this.set('interval', opts['interval'] || 0); + this.set('callback', opts.callback); + this.set('interval', opts.interval || 0); this.set('elapsed', -1); }, /** * @private */ - update: function(dt) { + update: function (dt) { if (this.elapsed == -1) { this.elapsed = 0; } else { @@ -76,7 +80,7 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ * @singleton * @private */ - init: function() { + init: function () { this.updates0 = []; this.updatesNeg = []; this.updatesPos = []; @@ -84,16 +88,16 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ this.hashForMethods = {}; }, - schedule: function(opts) { - var target = opts['target'], - method = opts['method'], - interval = opts['interval'], - paused = opts['paused'] || false; + schedule: function (opts) { + var target = opts.target, + method = opts.method, + interval = opts.interval, + paused = opts.paused || false; var element = this.hashForMethods[target.get('id')]; if (!element) { - element = new HashMethodEntry; + element = new HashMethodEntry(); this.hashForMethods[target.get('id')] = element; element.target = target; element.paused = paused; @@ -105,16 +109,16 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ element.timers.push(timer); }, - scheduleUpdate: function(opts) { - var target = opts['target'], - priority = opts['priority'], - paused = opts['paused']; + scheduleUpdate: function (opts) { + var target = opts.target, + priority = opts.priority, + paused = opts.paused; var i, len; var entry = {target: target, priority: priority, paused: paused}; var added = false; - if (priority == 0) { + if (priority === 0) { this.updates0.push(entry); } else if (priority < 0) { for (i = 0, len = this.updatesNeg.length; i < len; i++) { @@ -145,8 +149,8 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ this.hashForUpdates[target.get('id')] = entry; }, - tick: function(dt) { - var i; + tick: function (dt) { + var i, len, x; if (this.timeScale != 1.0) { dt *= this.timeScale; } @@ -154,33 +158,41 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ var entry; for (i = 0, len = this.updatesNeg.length; i < len; i++) { entry = this.updatesNeg[i]; - if (!entry.paused) entry.target.update(dt); + if (!entry.paused) { + entry.target.update(dt); + } } for (i = 0, len = this.updates0.length; i < len; i++) { entry = this.updates0[i]; - if (!entry.paused) entry.target.update(dt); + if (!entry.paused) { + entry.target.update(dt); + } } for (i = 0, len = this.updatesPos.length; i < len; i++) { entry = this.updatesPos[i]; - if (!entry.paused) entry.target.update(dt); + if (!entry.paused) { + entry.target.update(dt); + } } - for (var x in this.hashForMethods) { - entry = this.hashForMethods[x]; - for (i = 0, len = entry.timers.length; i < len; i++) { - var timer = entry.timers[i]; - timer.update(dt); + for (x in this.hashForMethods) { + if (this.hashForMethods.hasOwnProperty(x)) { + entry = this.hashForMethods[x]; + for (i = 0, len = entry.timers.length; i < len; i++) { + var timer = entry.timers[i]; + timer.update(dt); + } } } }, - unscheduleAllSelectorsForTarget: function(target) { + unscheduleAllSelectorsForTarget: function (target) { }, - pauseTarget: function(target) { + pauseTarget: function (target) { var element = this.hashForMethods[target.get('id')]; if (element) { element.paused = true; @@ -192,7 +204,7 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ } }, - resumeTarget: function(target) { + resumeTarget: function (target) { var element = this.hashForMethods[target.get('id')]; if (element) { element.paused = false; @@ -212,7 +224,7 @@ util.extend(Scheduler, /** @lends cocos.Scheduler */{ * @getter sharedScheduler * @type cocos.Scheduler */ - get_sharedScheduler: function(key) { + get_sharedScheduler: function (key) { if (!this._instance) { this._instance = this.create(); } diff --git a/src/libs/cocos2d/SpriteFrame.js b/src/libs/cocos2d/SpriteFrame.js index 0b327fc..f1d368d 100644 --- a/src/libs/cocos2d/SpriteFrame.js +++ b/src/libs/cocos2d/SpriteFrame.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), geo = require('geometry'), ccp = geo.ccp; @@ -28,20 +32,20 @@ var SpriteFrame = BObject.extend(/** @lends cocos.SpriteFrame# */{ * @opt {cocos.Texture2D} texture The texture to draw this frame using * @opt {geometry.Rect} rect The rectangle inside the texture to draw */ - init: function(opts) { - @super; - - this.texture = opts['texture']; - this.rect = opts['rect']; - this.rotated = !!opts['rotate']; - this.offset = opts['offset'] || ccp(0, 0); - this.originalSize = opts['originalSize'] || util.copy(this.rect.size); + init: function (opts) { + SpriteFrame.superclass.init(this, opts); + + this.texture = opts.texture; + this.rect = opts.rect; + this.rotated = !!opts.rotate; + this.offset = opts.offset || ccp(0, 0); + this.originalSize = opts.originalSize || util.copy(this.rect.size); }, /** * @ignore */ - toString: function() { + toString: function () { return "[object SpriteFrame | TextureName=" + this.texture.get('name') + ", Rect = (" + this.rect.origin.x + ", " + this.rect.origin.y + ", " + this.rect.size.width + ", " + this.rect.size.height + ")]"; }, @@ -50,7 +54,7 @@ var SpriteFrame = BObject.extend(/** @lends cocos.SpriteFrame# */{ * * @returns {cocos.SpriteFrame} Exact copy of this object */ - copy: function() { + copy: function () { return SpriteFrame.create({rect: this.rect, rotated: this.rotated, offset: this.offset, originalSize: this.originalSize, texture: this.texture}); } diff --git a/src/libs/cocos2d/SpriteFrameCache.js b/src/libs/cocos2d/SpriteFrameCache.js index 64762fb..1507aeb 100644 --- a/src/libs/cocos2d/SpriteFrameCache.js +++ b/src/libs/cocos2d/SpriteFrameCache.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), geo = require('geometry'), Plist = require('Plist').Plist, @@ -24,8 +28,8 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ * @constructs * @singleton */ - init: function() { - @super; + init: function () { + SpriteFrameCache.superclass.init.call(this); this.set('spriteFrames', {}); this.set('spriteFrameAliases', {}); @@ -36,8 +40,8 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ * * @param {String} opts.file The filename of a Zwoptex .plist containing the frame definiitons. */ - addSpriteFrames: function(opts) { - var plistPath = opts['file'], + addSpriteFrames: function (opts) { + var plistPath = opts.file, plist = Plist.create({file: plistPath}), plistData = plist.get('data'); @@ -48,10 +52,10 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ var format = 0, texturePath = null; - if (metaDataDict != null) { + if (metaDataDict) { format = metaDataDict.format; // Get texture path from meta data - texturePath = metaDataDict.textureFileName + texturePath = metaDataDict.textureFileName; } if (!texturePath) { @@ -80,7 +84,7 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ oh = frameDict.originalHeight; // check ow/oh - if(!ow || !oh) { + if (!ow || !oh) { //console.log("cocos2d: WARNING: originalWidth/Height not found on the CCSpriteFrame. AnchorPoint won't work as expected. Regenerate the .plist"); } @@ -135,7 +139,7 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ break; default: - throw "Unsupported Zwoptex format: " + format + throw "Unsupported Zwoptex format: " + format; } // Add sprite frame @@ -150,8 +154,8 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ * @param {String} opts.name The name of the sprite frame * @returns {cocos.SpriteFrame} The sprite frame */ - getSpriteFrame: function(opts) { - var name = opts['name']; + getSpriteFrame: function (opts) { + var name = opts.name; var frame = this.get('spriteFrames')[name]; @@ -181,7 +185,7 @@ util.extend(SpriteFrameCache, /** @lends cocos.SpriteFrameCache */{ * @name cocos.SpriteFrameCache.sharedSpriteFrameCache * @type cocos.SpriteFrameCache */ - get_sharedSpriteFrameCache: function(key) { + get_sharedSpriteFrameCache: function (key) { if (!this._instance) { this._instance = this.create(); } diff --git a/src/libs/cocos2d/TMXOrientation.js b/src/libs/cocos2d/TMXOrientation.js index 5da468b..523a7b4 100644 --- a/src/libs/cocos2d/TMXOrientation.js +++ b/src/libs/cocos2d/TMXOrientation.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + /** * @memberOf cocos * @namespace diff --git a/src/libs/cocos2d/TMXXMLParser.js b/src/libs/cocos2d/TMXXMLParser.js index a953ad4..fa3b9fa 100644 --- a/src/libs/cocos2d/TMXXMLParser.js +++ b/src/libs/cocos2d/TMXXMLParser.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray DOMParser*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), path = require('path'), ccp = require('geometry').ccp, @@ -7,6 +11,64 @@ var util = require('util'), TMXOrientationHex = require('./TMXOrientation').TMXOrientationHex, TMXOrientationIso = require('./TMXOrientation').TMXOrientationIso; +var TMXTilesetInfo = BObject.extend(/** @lends cocos.TMXTilesetInfo# */{ + name: '', + firstGID: 0, + tileSize: null, + spacing: 0, + margin: 0, + sourceImage: null, + + /** + * @memberOf cocos + * @constructs + * @extends BObject + */ + init: function () { + TMXTilesetInfo.superclass.init.call(this); + }, + + rectForGID: function (gid) { + var rect = {size: {}, origin: ccp(0, 0)}; + rect.size = util.copy(this.tileSize); + + gid = gid - this.firstGID; + + var imgSize = this.get('imageSize'); + + var maxX = Math.floor((imgSize.width - this.margin * 2 + this.spacing) / (this.tileSize.width + this.spacing)); + + rect.origin.x = (gid % maxX) * (this.tileSize.width + this.spacing) + this.margin; + rect.origin.y = Math.floor(gid / maxX) * (this.tileSize.height + this.spacing) + this.margin; + + return rect; + } +}); + +var TMXLayerInfo = BObject.extend(/** @lends cocos.TMXLayerInfo# */{ + name: '', + layerSize: null, + tiles: null, + visible: true, + opacity: 255, + minGID: 100000, + maxGID: 0, + properties: null, + offset: null, + + /** + * @memberOf cocos + * @constructs + * @extends BObject + */ + init: function () { + TMXLayerInfo.superclass.init.call(this); + + this.properties = {}; + this.offset = ccp(0, 0); + } +}); + var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ filename: '', orientation: 0, @@ -25,7 +87,9 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ * * @param {String} tmxFile The file path of the TMX file to load */ - init: function(tmxFile) { + init: function (tmxFile) { + TMXMapInfo.superclass.init.call(this, tmxFile); + this.tilesets = []; this.layers = []; this.objectGroups = []; @@ -36,7 +100,7 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ this.parseXMLFile(tmxFile); }, - parseXMLFile: function(xmlFile) { + parseXMLFile: function (xmlFile) { var parser = new DOMParser(), doc = parser.parseFromString(resource(xmlFile), 'text/xml'); @@ -48,26 +112,24 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ case 'orthogonal': this.orientation = TMXOrientationOrtho; break; - /* case 'isometric': this.orientation = TMXOrientationIso; break; case 'hexagonal': this.orientation = TMXOrientationHex; break; - */ default: throw "cocos2d: TMXFomat: Unsupported orientation: " + map.getAttribute('orientation'); } - this.mapSize = {width: parseInt(map.getAttribute('width'), 10), height: parseInt(map.getAttribute('height'), 10)} - this.tileSize = {width: parseInt(map.getAttribute('tilewidth'), 10), height: parseInt(map.getAttribute('tileheight'), 10)} + this.mapSize = {width: parseInt(map.getAttribute('width'), 10), height: parseInt(map.getAttribute('height'), 10)}; + this.tileSize = {width: parseInt(map.getAttribute('tilewidth'), 10), height: parseInt(map.getAttribute('tileheight'), 10)}; // PARSE var tilesets = map.getElementsByTagName('tileset'); - for (var i = 0, len = tilesets.length; i < len; i++) { + var i, len, s; + for (i = 0, len = tilesets.length; i < len; i++) { var t = tilesets[i]; - var i, len, s; var tileset = TMXTilesetInfo.create(); tileset.set('name', t.getAttribute('name')); @@ -80,8 +142,8 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ } s = {}; - s.width = parseInt(t.getAttribute('tilewidth'), 10) - s.height = parseInt(t.getAttribute('tileheight'), 10) + s.width = parseInt(t.getAttribute('tilewidth'), 10); + s.height = parseInt(t.getAttribute('tileheight'), 10); tileset.set('tileSize', s); // PARSE We assume there's only 1 @@ -89,7 +151,6 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ tileset.set('sourceImage', path.join(path.dirname(this.filename), image.getAttribute('source'))); this.tilesets.push(tileset); - delete tileset; } // PARSE @@ -100,19 +161,19 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ var layer = TMXLayerInfo.create(); layer.set('name', l.getAttribute('name')); - if (l.getAttribute('visible') == undefined) { + if (l.getAttribute('visible') !== false) { layer.set('visible', true); } else { - layer.set('visible', !!parseInt(l.getAttribute('visible'))); + layer.set('visible', !!parseInt(l.getAttribute('visible'), 10)); } s = {}; - s.width = parseInt(l.getAttribute('width'), 10) - s.height = parseInt(l.getAttribute('height'), 10) + s.width = parseInt(l.getAttribute('width'), 10); + s.height = parseInt(l.getAttribute('height'), 10); layer.set('layerSize', s); var opacity = l.getAttribute('opacity'); - if (opacity == undefined) { + if (opacity === undefined) { layer.set('opacity', 255); } else { layer.set('opacity', 255 * parseFloat(opacity)); @@ -120,8 +181,12 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ var x = parseInt(l.getAttribute('x'), 10), y = parseInt(l.getAttribute('y'), 10); - if (isNaN(x)) x = 0; - if (isNaN(y)) y = 0; + if (isNaN(x)) { + x = 0; + } + if (isNaN(y)) { + y = 0; + } layer.set('offset', ccp(x, y)); @@ -141,8 +206,6 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ } this.layers.push(layer); - delete layer; - } // TODO PARSE @@ -150,64 +213,6 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ } }); -var TMXLayerInfo = BObject.extend(/** @lends cocos.TMXLayerInfo# */{ - name: '', - layerSize: null, - tiles: null, - visible: true, - opacity: 255, - minGID: 100000, - maxGID: 0, - properties: null, - offset: null, - - /** - * @memberOf cocos - * @constructs - * @extends BObject - */ - init: function() { - @super; - - this.properties = {}; - this.offset = ccp(0, 0); - } -}); - -var TMXTilesetInfo = BObject.extend(/** @lends cocos.TMXTilesetInfo# */{ - name: '', - firstGID: 0, - tileSize: null, - spacing: 0, - margin: 0, - sourceImage: null, - - /** - * @memberOf cocos - * @constructs - * @extends BObject - */ - init: function() { - @super; - }, - - rectForGID: function(gid) { - var rect = {size:{}, origin:ccp(0,0)}; - rect.size = util.copy(this.tileSize); - - gid = gid - this.firstGID; - - var imgSize = this.get('imageSize'); - - var max_x = Math.floor((imgSize.width - this.margin*2 + this.spacing) / (this.tileSize.width + this.spacing)); - - rect.origin.x = (gid % max_x) * (this.tileSize.width + this.spacing) + this.margin; - rect.origin.y = Math.floor(gid / max_x) * (this.tileSize.height + this.spacing) + this.margin; - - return rect; - } -}); - exports.TMXMapInfo = TMXMapInfo; exports.TMXLayerInfo = TMXLayerInfo; exports.TMXTilesetInfo = TMXTilesetInfo; diff --git a/src/libs/cocos2d/Texture2D.js b/src/libs/cocos2d/Texture2D.js index 346491c..22c83a9 100644 --- a/src/libs/cocos2d/Texture2D.js +++ b/src/libs/cocos2d/Texture2D.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'); var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ @@ -13,10 +17,10 @@ var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ * @opt {String} [file] The file path of the image to use as a texture * @opt {Texture2D|HTMLImageElement} [data] Image data to read from */ - init: function(opts) { - var file = opts['file'], - data = opts['data'], - texture = opts['texture']; + init: function (opts) { + var file = opts.file, + data = opts.data, + texture = opts.texture; if (file) { this.name = file; @@ -29,13 +33,13 @@ var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ this.size = {width: 0, height: 0}; this.set('imgElement', data); - this.set('size', {width:this.imgElement.width, height: this.imgElement.height}); + this.set('size', {width: this.imgElement.width, height: this.imgElement.height}); }, - drawAtPoint: function(ctx, point) { + drawAtPoint: function (ctx, point) { ctx.drawImage(this.imgElement, point.x, point.y); }, - drawInRect: function(ctx, rect) { + drawInRect: function (ctx, rect) { ctx.drawImage(this.imgElement, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height @@ -46,7 +50,7 @@ var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ * @getter data * @type {String} Base64 encoded image data */ - get_data: function() { + get_data: function () { return this.imgElement ? this.imgElement.src : null; }, @@ -54,7 +58,7 @@ var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ * @getter contentSize * @type {geometry.Size} Size of the texture */ - get_contentSize: function() { + get_contentSize: function () { return this.size; } }); diff --git a/src/libs/cocos2d/TextureAtlas.js b/src/libs/cocos2d/TextureAtlas.js index 831840c..3b17d50 100644 --- a/src/libs/cocos2d/TextureAtlas.js +++ b/src/libs/cocos2d/TextureAtlas.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), Texture2D = require('./Texture2D').Texture2D; @@ -25,11 +29,11 @@ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ * @opt {Texture2D|HTMLImageElement} [data] Image data to read from * @opt {CanvasElement} [canvas] A canvas to use as a texture */ - init: function(opts) { - var file = opts['file'], - data = opts['data'], - texture = opts['texture'], - canvas = opts['canvas']; + init: function (opts) { + var file = opts.file, + data = opts.data, + texture = opts.texture, + canvas = opts.canvas; if (canvas) { // If we've been given a canvas element then we'll use that for our image @@ -43,28 +47,30 @@ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ this.quads = []; }, - insertQuad: function(opts) { - var quad = opts['quad'], - index = opts['index'] || 0; + insertQuad: function (opts) { + var quad = opts.quad, + index = opts.index || 0; this.quads.splice(index, 0, quad); }, - removeQuad: function(opts) { - var index = opts['index']; + removeQuad: function (opts) { + var index = opts.index; this.quads.splice(index, 1); }, - drawQuads: function(ctx) { - util.each(this.quads, util.callback(this, function(quad) { - if (!quad) return; + drawQuads: function (ctx) { + util.each(this.quads, util.callback(this, function (quad) { + if (!quad) { + return; + } this.drawQuad(ctx, quad); })); }, - drawQuad: function(ctx, quad) { + drawQuad: function (ctx, quad) { var sx = quad.textureRect.origin.x, sy = quad.textureRect.origin.y, sw = quad.textureRect.size.width, @@ -108,4 +114,4 @@ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ } }); -exports.TextureAtlas = TextureAtlas +exports.TextureAtlas = TextureAtlas; diff --git a/src/libs/cocos2d/actions/Action.js b/src/libs/cocos2d/actions/Action.js index 2655cc9..95a5a99 100644 --- a/src/libs/cocos2d/actions/Action.js +++ b/src/libs/cocos2d/actions/Action.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), console = require('system').console; @@ -20,7 +24,7 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ * * @param {Float} dt The delta time */ - step: function(dt) { + step: function (dt) { console.log('Action.step() Override me'); }, @@ -29,7 +33,7 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ * * @param {Float} time How much of the animation has played. 0.0 = just started, 1.0 just finished. */ - update: function(time) { + update: function (time) { console.log('Action.update() Override me'); }, @@ -38,7 +42,7 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ * * @param {cocos.nodes.Node} target The Node to run the action on */ - startWithTarget: function(target) { + startWithTarget: function (target) { this.target = this.originalTarget = target; }, @@ -47,7 +51,7 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ * Important: You should never call cocos.Action#stop manually. * Instead, use cocos.Node#stopAction(action) */ - stop: function() { + stop: function () { this.target = null; }, @@ -55,7 +59,7 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ * @getter isDone * @type {Boolean} */ - get_isDone: function(key) { + get_isDone: function (key) { return true; }, @@ -65,7 +69,7 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ * * @returns {cocos.actions.Action} A new Action in reverse */ - reverse: function() { + reverse: function () { } }); @@ -83,20 +87,19 @@ var RepeatForever = Action.extend(/** @lends cocos.actions.RepeatForever# */{ * @constructs * @param {cocos.actions.Action} action An action to repeat forever */ - init: function(action) { - - @super(); + init: function (action) { + RepeatForever.superclass.init(this, action); this.other = action; }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + RepeatForever.superclass.startWithTarget.call(this, target); this.other.startWithTarget(this.target); }, - step: function(dt) { + step: function (dt) { this.other.step(dt); if (this.other.get('isDone')) { var diff = dt - this.other.get('duration') - this.other.get('elapsed'); @@ -106,15 +109,15 @@ var RepeatForever = Action.extend(/** @lends cocos.actions.RepeatForever# */{ } }, - get_isDone: function() { + get_isDone: function () { return false; }, - reverse: function() { + reverse: function () { return RepeatForever.create(this.other.reverse()); }, - copy: function() { + copy: function () { return RepeatForever.create(this.other.copy()); } }); @@ -134,12 +137,12 @@ var FiniteTimeAction = Action.extend(/** @lends cocos.actions.FiniteTimeAction# * @constructs * @extends cocos.actions.Action */ - init: function() { - @super; + init: function () { + FiniteTimeAction.superclass.init.call(this); }, /** @ignore */ - reverse: function() { + reverse: function () { console.log('FiniteTimeAction.reverse() Override me'); } }); diff --git a/src/libs/cocos2d/actions/ActionInstant.js b/src/libs/cocos2d/actions/ActionInstant.js index 5860f55..da53538 100644 --- a/src/libs/cocos2d/actions/ActionInstant.js +++ b/src/libs/cocos2d/actions/ActionInstant.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), act = require('./Action'), ccp = require('geometry').ccp; @@ -10,20 +14,21 @@ var ActionInstant = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionI * @constructs * @extends cocos.actions.FiniteTimeAction */ - init: function(opts) { - @super; + init: function (opts) { + ActionInstant.superclass.init.call(this, opts); + this.duration = 0; }, - get_isDone: function() { + get_isDone: function () { return true; }, - step: function(dt) { + step: function (dt) { this.update(1); }, - update: function(t) { + update: function (t) { // ignore }, - reverse: function() { + reverse: function () { return this.copy(); } }); @@ -40,19 +45,20 @@ var FlipX = ActionInstant.extend(/** @lends cocos.actions.FlipX# */{ * * @opt {Boolean} flipX Should the sprite be flipped */ - init: function(opts) { - @super; + init: function (opts) { + FlipX.superclass.init.call(this, opts); - this.flipX = opts['flipX']; + this.flipX = opts.flipX; }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + FlipX.superclass.startWithTarget.call(this, target); + target.set('flipX', this.flipX); }, - reverse: function() { + reverse: function () { return FlipX.create({flipX: !this.flipX}); }, - copy: function() { + copy: function () { return FlipX.create({flipX: this.flipX}); } }); @@ -69,19 +75,20 @@ var FlipY = ActionInstant.extend(/** @lends cocos.actions.FlipY# */{ * * @opt {Boolean} flipY Should the sprite be flipped */ - init: function(opts) { - @super; + init: function (opts) { + FlipY.superclass.init.call(this, opts); - this.flipY = opts['flipY']; + this.flipY = opts.flipY; }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + FlipY.superclass.startWithTarget.call(this, target); + target.set('flipY', this.flipY); }, - reverse: function() { + reverse: function () { return FlipY.create({flipY: !this.flipY}); }, - copy: function() { + copy: function () { return FlipY.create({flipY: this.flipY}); } }); diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index 59b352b..f55f566 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), act = require('./Action'), ccp = require('geometry').ccp; @@ -25,11 +29,11 @@ var ActionInterval = act.FiniteTimeAction.extend(/** @lends cocos.actions.Action * * @opt {Float} duration Number of seconds to run action for */ - init: function(opts) { - @super; + init: function (opts) { + ActionInterval.superclass.init.call(this, opts); - var dur = opts['duration'] || 0; - if (dur == 0) { + var dur = opts.duration || 0; + if (dur === 0) { dur = 0.0000001; } @@ -38,11 +42,11 @@ var ActionInterval = act.FiniteTimeAction.extend(/** @lends cocos.actions.Action this._firstTick = true; }, - get_isDone: function() { + get_isDone: function () { return (this.elapsed >= this.duration); }, - step: function(dt) { + step: function (dt) { if (this._firstTick) { this._firstTick = false; this.elapsed = 0; @@ -50,18 +54,18 @@ var ActionInterval = act.FiniteTimeAction.extend(/** @lends cocos.actions.Action this.elapsed += dt; } - this.update(Math.min(1, this.elapsed/this.duration)); + this.update(Math.min(1, this.elapsed / this.duration)); }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + ActionInterval.superclass.startWithTarget.call(this, target); this.elapsed = 0.0; this._firstTick = true; }, - reverse: function() { - throw "Reverse Action not implemented" + reverse: function () { + throw "Reverse Action not implemented"; } }); @@ -128,21 +132,21 @@ var ScaleTo = ActionInterval.extend(/** @lends cocos.actions.ScaleTo# */{ * @opt {Float} [scaleX] Size to scale width of Node to * @opt {Float} [scaleY] Size to scale height of Node to */ - init: function(opts) { - @super; + init: function (opts) { + ScaleTo.superclass.init.call(this, opts); - if (opts['scale'] != undefined) { - this.endScaleX = this.endScaleY = opts['scale']; + if (opts.scale !== undefined) { + this.endScaleX = this.endScaleY = opts.scale; } else { - this.endScaleX = opts['scaleX']; - this.endScaleY = opts['scaleY']; + this.endScaleX = opts.scaleX; + this.endScaleY = opts.scaleY; } }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + ScaleTo.superclass.startWithTarget.call(this, target); this.startScaleX = this.target.get('scaleX'); this.startScaleY = this.target.get('scaleY'); @@ -150,7 +154,7 @@ var ScaleTo = ActionInterval.extend(/** @lends cocos.actions.ScaleTo# */{ this.deltaY = this.endScaleY - this.startScaleY; }, - update: function(t) { + update: function (t) { if (!this.target) { return; } @@ -173,19 +177,19 @@ var ScaleBy = ScaleTo.extend(/** @lends cocos.actions.ScaleBy# */{ * @opt {Float} [scaleX] Size to scale width of Node by * @opt {Float} [scaleY] Size to scale height of Node by */ - init: function() { - @super; + init: function (opts) { + ScaleBy.superclass.init.call(this, opts); }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + ScaleBy.superclass.startWithTarget.call(this, target); this.deltaX = this.startScaleX * this.endScaleX - this.startScaleX; this.deltaY = this.startScaleY * this.endScaleY - this.startScaleY; }, - reverse: function() { - return ScaleBy.create({duration: this.duration, scaleX:1/this.endScaleX, scaleY:1/this.endScaleY}); + reverse: function () { + return ScaleBy.create({duration: this.duration, scaleX: 1 / this.endScaleX, scaleY: 1 / this.endScaleY}); } }); @@ -220,14 +224,14 @@ var RotateTo = ActionInterval.extend(/** @lends cocos.actions.RotateTo# */{ * @opt {Float} duration Number of seconds to run action for * @opt {Float} angle Angle in degrees to rotate to */ - init: function(opts) { - @super; + init: function (opts) { + RotateTo.superclass.init.call(this, opts); - this.dstAngle = opts['angle']; + this.dstAngle = opts.angle; }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + RotateTo.superclass.startWithTarget.call(this, target); this.startAngle = target.get('rotation'); @@ -245,7 +249,7 @@ var RotateTo = ActionInterval.extend(/** @lends cocos.actions.RotateTo# */{ } }, - update: function(t) { + update: function (t) { this.target.set('rotation', this.startAngle + this.diffAngle * t); } }); @@ -268,27 +272,27 @@ var RotateBy = RotateTo.extend(/** @lends cocos.actions.RotateBy# */{ * @opt {Float} duration Number of seconds to run action for * @opt {Float} angle Angle in degrees to rotate by */ - init: function(opts) { - @super; + init: function (opts) { + RotateBy.superclass.init.call(this, opts); - this.angle = opts['angle']; + this.angle = opts.angle; }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + RotateBy.superclass.startWithTarget.call(this, target); this.startAngle = this.target.get('rotation'); }, - update: function(t) { - this.target.set('rotation', this.startAngle + this.angle *t); + update: function (t) { + this.target.set('rotation', this.startAngle + this.angle * t); }, - reverse: function() { + reverse: function () { return RotateBy.create({duration: this.duration, angle: -this.angle}); }, - copy: function() { + copy: function () { return RotateBy.create({duration: this.duration, angle: this.angle}); } }); @@ -324,33 +328,34 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ * @opt {Float} duration Number of seconds to run action for * @opt {cocos.actions.Action[]} Array of actions to run in sequence */ - init: function(opts) { - @super; + init: function (opts) { + Sequence.superclass.init.call(this, opts); - this.actions = util.copy(opts['actions']); + this.actions = util.copy(opts.actions); this.actionSequence = {}; - util.each(this.actions, util.callback(this, function(action) { + util.each(this.actions, util.callback(this, function (action) { this.duration += action.duration; })); }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + Sequence.superclass.startWithTarget.call(this, target); + this.currentActionIndex = 0; this.currentActionEndDuration = this.actions[0].get('duration'); this.actions[0].startWithTarget(this.target); }, - stop: function() { - util.each(this.actions, function(action) { + stop: function () { + util.each(this.actions, function (action) { action.stop(); }); - @super; + Sequence.superclass.stop.call(this); }, - step: function(dt) { + step: function (dt) { if (this._firstTick) { this._firstTick = false; this.elapsed = 0; @@ -359,10 +364,10 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ } this.actions[this.currentActionIndex].step(dt); - this.update(Math.min(1, this.elapsed/this.duration)); + this.update(Math.min(1, this.elapsed / this.duration)); }, - update: function(dt) { + update: function (dt) { // Action finished onto the next one if (this.elapsed > this.currentActionEndDuration) { var previousAction = this.actions[this.currentActionIndex]; @@ -399,38 +404,38 @@ var Animate = ActionInterval.extend(/** @lends cocos.actions.Animate# */{ * @opt {cocos.Animation} animation Animation to run * @opt {Boolean} [restoreOriginalFrame=true] Return to first frame when finished */ - init: function(opts) { - this.animation = opts['animation']; - this.restoreOriginalFrame = opts['restoreOriginalFrame'] !== false; - opts['duration'] = this.animation.frames.length * this.animation.delay; + init: function (opts) { + this.animation = opts.animation; + this.restoreOriginalFrame = opts.restoreOriginalFrame !== false; + opts.duration = this.animation.frames.length * this.animation.delay; - @super; + Animate.superclass.init.call(this, opts); }, - startWithTarget: function(target) { - @super; + startWithTarget: function (target) { + Animate.superclass.startWithTarget.call(this, target); if (this.restoreOriginalFrame) { this.set('origFrame', this.target.get('displayedFrame')); } }, - stop: function() { + stop: function () { if (this.target && this.restoreOriginalFrame) { var sprite = this.target; sprite.set('displayFrame', this.origFrame); } - @super; + Animate.superclass.stop.call(this); }, - update: function(t) { + update: function (t) { var frames = this.animation.get('frames'), numberOfFrames = frames.length, idx = Math.floor(t * numberOfFrames); if (idx >= numberOfFrames) { - idx = numberOfFrames -1; + idx = numberOfFrames - 1; } var sprite = this.target; @@ -439,7 +444,7 @@ var Animate = ActionInterval.extend(/** @lends cocos.actions.Animate# */{ } }, - copy: function() { + copy: function () { return Animate.create({animation: this.animation, restoreOriginalFrame: this.restoreOriginalFrame}); } diff --git a/src/libs/cocos2d/actions/index.js b/src/libs/cocos2d/actions/index.js index 9eef9d7..5925e1d 100644 --- a/src/libs/cocos2d/actions/index.js +++ b/src/libs/cocos2d/actions/index.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), path = require('path'); @@ -9,7 +13,7 @@ var modules = 'Action ActionInterval ActionInstant'.w(); */ var actions = {}; -util.each(modules, function(mod, i) { +util.each(modules, function (mod, i) { util.extend(actions, require('./' + mod)); }); diff --git a/src/libs/cocos2d/config.js b/src/libs/cocos2d/config.js index fd86af5..d25172e 100644 --- a/src/libs/cocos2d/config.js +++ b/src/libs/cocos2d/config.js @@ -1,7 +1,7 @@ { // Invert the Y axis so origin is at the bottom left - FLIP_Y_AXIS: false, + "FLIP_Y_AXIS": false, // No implemented yet - ENABLE_WEB_GL: false + "ENABLE_WEB_GL": false } diff --git a/src/libs/cocos2d/index.js b/src/libs/cocos2d/index.js index 7c2bf10..52340c4 100644 --- a/src/libs/cocos2d/index.js +++ b/src/libs/cocos2d/index.js @@ -1,7 +1,11 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), path = require('path'); -var modules = 'SpriteFrame SpriteFrameCache Director Animation AnimationCache Scheduler ActionManager TMXXMLParser'.w() +var modules = 'SpriteFrame SpriteFrameCache Director Animation AnimationCache Scheduler ActionManager TMXXMLParser'.w(); /** * @namespace All cocos2d objects live in this namespace @@ -11,7 +15,7 @@ var cocos = { actions: require('./actions') }; -util.each(modules, function(mod, i) { +util.each(modules, function (mod, i) { util.extend(cocos, require('./' + mod)); }); diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index 909152b..610b038 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -1,5 +1,9 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), - event = require('event'), + evt = require('event'), geo = require('geometry'), ccp = geo.ccp, TextureAtlas = require('../TextureAtlas').TextureAtlas, @@ -29,12 +33,12 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ * * @opt {geometry.Size} size The size of the in-memory canvas used for drawing to */ - init: function(opts) { - @super; + init: function (opts) { + BatchNode.superclass.init.call(this, opts); - var size = opts['size'] || geo.sizeMake(1, 1); + var size = opts.size || geo.sizeMake(1, 1); - event.addListener(this, 'contentsize_changed', util.callback(this, this._resizeCanvas)); + evt.addListener(this, 'contentsize_changed', util.callback(this, this._resizeCanvas)); this._dirtyRects = []; this.set('contentRect', geo.rectMake(0, 0, size.width, size.height)); @@ -43,11 +47,11 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ this.addChild({child: this.renderTexture}); }, - addChild: function(opts) { - @super; + addChild: function (opts) { + BatchNode.superclass.addChild.call(this, opts); - var child = opts['child'], - z = opts['z']; + var child = opts.child, + z = opts.z; if (child == this.renderTexture) { return; @@ -56,21 +60,25 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ // TODO handle texture resize // Watch for changes in child - event.addListener(child, 'istransformdirty_changed', util.callback(this, function() { this.set('dirty', true); })); - event.addListener(child, 'visible_changed', util.callback(this, function() { this.set('dirty', true); })); + evt.addListener(child, 'istransformdirty_changed', util.callback(this, function () { + this.set('dirty', true); + })); + evt.addListener(child, 'visible_changed', util.callback(this, function () { + this.set('dirty', true); + })); this.set('dirty', true); }, - removeChild: function(opts) { - @super; + removeChild: function (opts) { + BatchNode.superclass.removeChild.call(this, opts); // TODO remove istransformdirty_changed and visible_changed listeners this.set('dirty', true); }, - _resizeCanvas: function(oldSize) { + _resizeCanvas: function (oldSize) { var size = this.get('contentSize'); if (geo.sizeEqualToSize(size, oldSize)) { @@ -81,11 +89,11 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ this.set('dirty', true); }, - update: function() { + update: function () { }, - visit: function(context) { + visit: function (context) { if (!this.visible) { return; } @@ -114,7 +122,7 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ context.restore(); }, - draw: function(ctx) { + draw: function (ctx) { } }); @@ -132,12 +140,12 @@ var SpriteBatchNode = BatchNode.extend({ * @opt {Texture2D} texture (Optional) Texture to use as sprite atlas * @opt {cocos.TextureAtlas} textureAtlas (Optional) TextureAtlas to use as sprite atlas */ - init: function(opts) { - @super; + init: function (opts) { + SpriteBatchNode.superclass.init.call(this, opts); - var file = opts['file'], - textureAtlas = opts['textureAtlas'], - texture = opts['texture']; + var file = opts.file, + textureAtlas = opts.textureAtlas, + texture = opts.texture; if (file || texture) { textureAtlas = TextureAtlas.create({file: file, texture: texture}); @@ -150,7 +158,7 @@ var SpriteBatchNode = BatchNode.extend({ * @getter texture * @type cocos.Texture2D */ - get_texture: function() { + get_texture: function () { return this.textureAtlas ? this.textureAtlas.texture : null; } diff --git a/src/libs/cocos2d/nodes/Label.js b/src/libs/cocos2d/nodes/Label.js index 655c282..3e6e2ce 100644 --- a/src/libs/cocos2d/nodes/Label.js +++ b/src/libs/cocos2d/nodes/Label.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), console = require('system').console, Director = require('../Director').Director, @@ -21,10 +25,10 @@ var Label = Node.extend(/** @lends cocos.nodes.Label# */{ * @opt {String} [fontName="Helvetica"] The name of the font to use * @opt {String} [fontColor="white"] The color of the text */ - init: function(opts) { - @super; + init: function (opts) { + Label.superclass.init.call(this, opts); - util.each('fontSize fontName fontColor string'.w(), util.callback(this, function(name) { + util.each('fontSize fontName fontColor string'.w(), util.callback(this, function (name) { // Set property on init if (opts[name]) { this.set(name, opts[name]); @@ -41,11 +45,11 @@ var Label = Node.extend(/** @lends cocos.nodes.Label# */{ * @getter font * @type String */ - get_font: function(key) { + get_font: function (key) { return this.get('fontSize') + 'px ' + this.get('fontName'); }, - draw: function(context) { + draw: function (context) { if (FLIP_Y_AXIS) { context.save(); @@ -72,7 +76,7 @@ var Label = Node.extend(/** @lends cocos.nodes.Label# */{ /** * @private */ - _updateLabelContentSize: function() { + _updateLabelContentSize: function () { var ctx = Director.get('sharedDirector').get('context'); var size = {width: 0, height: this.get('fontSize')}; diff --git a/src/libs/cocos2d/nodes/Layer.js b/src/libs/cocos2d/nodes/Layer.js index 47dd0b7..c0d2d40 100644 --- a/src/libs/cocos2d/nodes/Layer.js +++ b/src/libs/cocos2d/nodes/Layer.js @@ -1,6 +1,10 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var Node = require('./Node').Node, util = require('util'), - event = require('event'), + evt = require('event'), Director = require('../Director').Director, ccp = require('geometry').ccp, EventDispatcher = require('../EventDispatcher').EventDispatcher; @@ -18,8 +22,8 @@ var Layer = Node.extend(/** @lends cocos.nodes.Layer# */{ * @constructs * @extends cocos.nodes.Node */ - init: function() { - @super; + init: function () { + Layer.superclass.init.call(this); var s = Director.get('sharedDirector').get('winSize'); @@ -27,10 +31,10 @@ var Layer = Node.extend(/** @lends cocos.nodes.Layer# */{ this.anchorPoint = ccp(0.5, 0.5); this.set('contentSize', s); - event.addListener(this, 'ismouseenabled_changed', util.callback(this, function() { + evt.addListener(this, 'ismouseenabled_changed', util.callback(this, function () { if (this.isRunning) { if (this.isMouseEnabled) { - EventDispatcher.get('sharedDispatcher').addMouseDelegate({delegate: this, priority:this.get('mouseDelegatePriority')}); + EventDispatcher.get('sharedDispatcher').addMouseDelegate({delegate: this, priority: this.get('mouseDelegatePriority')}); } else { EventDispatcher.get('sharedDispatcher').removeMouseDelegate({delegate: this}); } @@ -38,10 +42,10 @@ var Layer = Node.extend(/** @lends cocos.nodes.Layer# */{ })); - event.addListener(this, 'iskeyboardenabled_changed', util.callback(this, function() { + evt.addListener(this, 'iskeyboardenabled_changed', util.callback(this, function () { if (this.isRunning) { if (this.isKeyboardEnabled) { - EventDispatcher.get('sharedDispatcher').addKeyboardDelegate({delegate: this, priority:this.get('keyboardDelegatePriority')}); + EventDispatcher.get('sharedDispatcher').addKeyboardDelegate({delegate: this, priority: this.get('keyboardDelegatePriority')}); } else { EventDispatcher.get('sharedDispatcher').removeKeyboardDelegate({delegate: this}); } @@ -49,18 +53,18 @@ var Layer = Node.extend(/** @lends cocos.nodes.Layer# */{ })); }, - onEnter: function() { + onEnter: function () { if (this.isMouseEnabled) { - EventDispatcher.get('sharedDispatcher').addMouseDelegate({delegate: this, priority:this.get('mouseDelegatePriority')}); + EventDispatcher.get('sharedDispatcher').addMouseDelegate({delegate: this, priority: this.get('mouseDelegatePriority')}); } if (this.isKeyboardEnabled) { - EventDispatcher.get('sharedDispatcher').addKeyboardDelegate({delegate: this, priority:this.get('keyboardDelegatePriority')}); + EventDispatcher.get('sharedDispatcher').addKeyboardDelegate({delegate: this, priority: this.get('keyboardDelegatePriority')}); } - @super; + Layer.superclass.onEnter.call(this); }, - onExit: function() { + onExit: function () { if (this.isMouseEnabled) { EventDispatcher.get('sharedDispatcher').removeMouseDelegate({delegate: this}); } @@ -68,7 +72,7 @@ var Layer = Node.extend(/** @lends cocos.nodes.Layer# */{ EventDispatcher.get('sharedDispatcher').removeKeyboardDelegate({delegate: this}); } - @super; + Layer.superclass.onExit.call(this); } }); diff --git a/src/libs/cocos2d/nodes/Menu.js b/src/libs/cocos2d/nodes/Menu.js index 3b79424..b5cb487 100644 --- a/src/libs/cocos2d/nodes/Menu.js +++ b/src/libs/cocos2d/nodes/Menu.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), Layer = require('./Layer').Layer, Director = require('../Director').Director, @@ -14,7 +18,7 @@ var kMenuStateTrackingTouch = 1; var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ - mouseDelegatePriority: (-Number.MAX_VALUE +1), + mouseDelegatePriority: (-Number.MAX_VALUE + 1), state: kMenuStateWaiting, selectedItem: null, opacuty: 255, @@ -29,10 +33,10 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ * * @opt {cocos.nodes.MenuItem[]} items An array of MenuItems to draw on the menu */ - init: function(opts) { - @super; + init: function (opts) { + Menu.superclass.init.call(this, opts); - var items = opts['items']; + var items = opts.items; this.set('isMouseEnabled', true); @@ -42,28 +46,28 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ this.anchorPoint = ccp(0.5, 0.5); this.set('contentSize', s); - this.set('position', ccp(s.width /2, s.height /2)); + this.set('position', ccp(s.width / 2, s.height / 2)); if (items) { var z = 0; - util.each(items, util.callback(this, function(item) { - this.addChild({child: item, z:z++}); + util.each(items, util.callback(this, function (item) { + this.addChild({child: item, z: z++}); })); } }, - addChild: function(opts) { - if (!opts['child'] instanceof MenuItem) { + addChild: function (opts) { + if (!opts.child instanceof MenuItem) { throw "Menu only supports MenuItem objects as children"; } - return @super; + Menu.superclass.addChild.call(this, opts); }, - itemForMouseEvent: function(event) { + itemForMouseEvent: function (event) { var location = Director.get('sharedDirector').convertEventToCanvas(event); var children = this.get('children'); @@ -86,7 +90,7 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ return null; }, - mouseUp: function(event) { + mouseUp: function (event) { if (this.selectedItem) { this.selectedItem.set('isSelected', false); this.selectedItem.activate(); @@ -101,7 +105,7 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ return false; }, - mouseDown: function(event) { + mouseDown: function (event) { if (this.state != kMenuStateWaiting || !this.visible) { return false; } @@ -116,7 +120,8 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ return false; }, - mouseDragged: function(event) { + + mouseDragged: function (event) { var currentItem = this.itemForMouseEvent(event); if (currentItem != this.selectedItem) { diff --git a/src/libs/cocos2d/nodes/MenuItem.js b/src/libs/cocos2d/nodes/MenuItem.js index 62ed0f3..22d2eba 100644 --- a/src/libs/cocos2d/nodes/MenuItem.js +++ b/src/libs/cocos2d/nodes/MenuItem.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), Node = require('./Node').Node, Sprite = require('./Sprite').Sprite, @@ -18,16 +22,16 @@ var MenuItem = Node.extend(/** @lends cocos.nodes.MenuItem# */{ * * @opt {Function} callback Function to call when menu item is activated */ - init: function(opts) { - @super; + init: function (opts) { + MenuItem.superclass.init.call(this, opts); - var callback = opts['callback']; + var callback = opts.callback; this.set('anchorPoint', ccp(0.5, 0.5)); this.set('callback', callback); }, - activate: function() { + activate: function () { if (this.isEnabled && this.callback) { this.callback(this); } @@ -37,13 +41,13 @@ var MenuItem = Node.extend(/** @lends cocos.nodes.MenuItem# */{ * @getter rect * @type geometry.Rect */ - get_rect: function() { + get_rect: function () { return rectMake( this.position.x - this.contentSize.width * this.anchorPoint.x, this.position.y - this.contentSize.height * this.anchorPoint.y, this.contentSize.width, this.contentSize.height - ) + ); } }); @@ -63,12 +67,12 @@ var MenuItemSprite = MenuItem.extend(/** @lends cocos.nodes.MenuItemSprite# */{ * @opt {cocos.nodes.Node} selectedImage Node to draw when menu item is selected * @opt {cocos.nodes.Node} disabledImage Node to draw when menu item is disabled */ - init: function(opts) { - @super; + init: function (opts) { + MenuItemSprite.superclass.init.call(this, opts); - var normalImage = opts['normalImage'], - selectedImage = opts['selectedImage'], - disabledImage = opts['disabledImage']; + var normalImage = opts.normalImage, + selectedImage = opts.selectedImage, + disabledImage = opts.disabledImage; this.set('normalImage', normalImage); this.set('selectedImage', selectedImage); @@ -77,7 +81,7 @@ var MenuItemSprite = MenuItem.extend(/** @lends cocos.nodes.MenuItemSprite# */{ this.set('contentSize', normalImage.get('contentSize')); }, - draw: function(ctx) { + draw: function (ctx) { if (this.isEnabled) { if (this.isSelected) { this.selectedImage.draw(ctx); @@ -85,7 +89,7 @@ var MenuItemSprite = MenuItem.extend(/** @lends cocos.nodes.MenuItemSprite# */{ this.normalImage.draw(ctx); } } else { - if (this.disabledImage != null) { + if (this.disabledImage) { this.disabledImage.draw(ctx); } else { this.normalImage.draw(ctx); @@ -107,21 +111,21 @@ var MenuItemImage = MenuItemSprite.extend(/** @lends cocos.nodes.MenuItemImage# * @opt {String} selectedImage Image file to draw when menu item is selected * @opt {String} disabledImage Image file to draw when menu item is disabled */ - init: function(opts) { - var normalI = opts['normalImage'], - selectedI = opts['selectedImage'], - disabledI = opts['disabledImage'], - callback = opts['callback']; + init: function (opts) { + var normalI = opts.normalImage, + selectedI = opts.selectedImage, + disabledI = opts.disabledImage, + callback = opts.callback; var normalImage = Sprite.create({file: normalI}), selectedImage = Sprite.create({file: selectedI}), disabledImage = null; if (disabledI) { - disabledImage = Sprite.create({file: disabledI}) + disabledImage = Sprite.create({file: disabledI}); } - return @super({normalImage: normalImage, selectedImage: selectedImage, disabledImage: disabledImage, callback: callback}); + return MenuItemImage.superclass.init.call(this, {normalImage: normalImage, selectedImage: selectedImage, disabledImage: disabledImage, callback: callback}); } }); diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index 66c2fdc..cc4d0de 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -1,5 +1,9 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), - event = require('event'), + evt = require('event'), Scheduler = require('../Scheduler').Scheduler, ActionManager = require('../ActionManager').ActionManager, geom = require('geometry'), ccp = geom.ccp; @@ -37,18 +41,19 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * @constructs * @extends BObject */ - init: function() { + init: function () { + Node.superclass.init.call(this); this.set('contentSize', {width: 0, height: 0}); this.anchorPoint = ccp(0.5, 0.5); this.anchorPointInPixels = ccp(0, 0); - this.position = ccp(0,0); + this.position = ccp(0, 0); this.children = []; - util.each(['scaleX', 'scaleY', 'rotation', 'position', 'anchorPoint', 'contentSize', 'isRelativeAnchorPoint'], util.callback(this, function(key) { - event.addListener(this, key.toLowerCase() + '_changed', util.callback(this, this._dirtyTransform)); + util.each(['scaleX', 'scaleY', 'rotation', 'position', 'anchorPoint', 'contentSize', 'isRelativeAnchorPoint'], util.callback(this, function (key) { + evt.addListener(this, key.toLowerCase() + '_changed', util.callback(this, this._dirtyTransform)); })); - event.addListener(this, 'anchorpoint_changed', util.callback(this, this._updateAnchorPointInPixels)); - event.addListener(this, 'contentsize_changed', util.callback(this, this._updateAnchorPointInPixels)); + evt.addListener(this, 'anchorpoint_changed', util.callback(this, this._updateAnchorPointInPixels)); + evt.addListener(this, 'contentsize_changed', util.callback(this, this._updateAnchorPointInPixels)); }, /** @@ -56,7 +61,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * anchorPointInPixels property * @private */ - _updateAnchorPointInPixels: function() { + _updateAnchorPointInPixels: function () { var ap = this.get('anchorPoint'), cs = this.get('contentSize'); this.set('anchorPointInPixels', ccp(cs.width * ap.x, cs.height * ap.y)); @@ -70,16 +75,16 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * @opt {Integer|String} [tag] A tag to reference the child with * @returns {cocos.nodes.Node} The node the child was added to. i.e. 'this' */ - addChild: function(opts) { + addChild: function (opts) { if (opts.isCocosNode) { - return arguments.callee.call(this, {child:opts}); + return this.addChild({child: opts}); } - var child = opts['child'], - z = opts['z'], - tag = opts['tag']; + var child = opts.child, + z = opts.z, + tag = opts.tag; - if (z == undefined) { + if (z === undefined || z === null) { z = child.get('zOrder'); } @@ -110,8 +115,8 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ return this; }, - getChild: function(opts) { - var tag = opts['tag']; + getChild: function (opts) { + var tag = opts.tag; for (var i = 0; i < this.children.length; i++) { if (this.children[i].tag == tag) { @@ -122,7 +127,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ return null; }, - removeChild: function(opts) { + removeChild: function (opts) { var child = opts.child, cleanup = opts.cleanup; @@ -138,7 +143,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ } }, - detatchChild: function(opts) { + detatchChild: function (opts) { var child = opts.child, cleanup = opts.cleanup; @@ -158,9 +163,9 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ children.splice(idx, 1); }, - reorderChild: function(opts) { - var child = opts['child'], - z = opts['z']; + reorderChild: function (opts) { + var child = opts.child, + z = opts.z; var pos = this.children.indexOf(child); if (pos == -1) { @@ -188,7 +193,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ } }, - draw: function(context) { + draw: function (context) { // All draw code goes here }, @@ -196,9 +201,9 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * @getter scale * @type Float */ - get_scale: function() { + get_scale: function () { if (this.scaleX != this.scaleY) { - throw "scaleX and scaleY aren't identical" + throw "scaleX and scaleY aren't identical"; } return this.scaleX; @@ -208,14 +213,14 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * @setter scale * @type Float */ - set_scale: function(val) { + set_scale: function (val) { this.set('scaleX', val); this.set('scaleY', val); }, - scheduleUpdate: function(opts) { + scheduleUpdate: function (opts) { opts = opts || {}; - var priority = opts['priority'] || 0; + var priority = opts.priority || 0; Scheduler.get('sharedScheduler').scheduleUpdate({target: this, priority: priority, paused: !this.get('isRunning')}); }, @@ -225,8 +230,10 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * * @event */ - onEnter: function() { - util.each(this.children, function(child) { child.onEnter(); }); + onEnter: function () { + util.each(this.children, function (child) { + child.onEnter(); + }); this.resumeSchedulerAndActions(); this.set('isRunning', true); @@ -237,35 +244,39 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * * @event */ - onExit: function() { + onExit: function () { this.pauseSchedulerAndActions(); this.set('isRunning', false); - util.each(this.children, function(child) { child.onExit(); }); + util.each(this.children, function (child) { + child.onExit(); + }); }, - cleanup: function() { + cleanup: function () { this.stopAllActions(); this.unscheduleAllSelectors(); - util.each(this.children, function(child) { child.cleanup(); }); + util.each(this.children, function (child) { + child.cleanup(); + }); }, - resumeSchedulerAndActions: function() { + resumeSchedulerAndActions: function () { Scheduler.get('sharedScheduler').resumeTarget(this); ActionManager.get('sharedManager').resumeTarget(this); }, - pauseSchedulerAndActions: function() { + pauseSchedulerAndActions: function () { Scheduler.get('sharedScheduler').pauseTarget(this); ActionManager.get('sharedManager').pauseTarget(this); }, - unscheduleAllSelectors: function() { + unscheduleAllSelectors: function () { Scheduler.get('sharedScheduler').unscheduleAllSelectorsForTarget(this); }, - stopAllActions: function() { + stopAllActions: function () { ActionManager.get('sharedManager').removeAllActionsFromTarget(this); }, - visit: function(context) { + visit: function (context) { if (!this.visible) { return; } @@ -275,7 +286,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ this.transform(context); // Draw background nodes - util.each(this.children, function(child, i) { + util.each(this.children, function (child, i) { if (child.zOrder < 0) { child.visit(context); } @@ -284,7 +295,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ this.draw(context); // Draw foreground nodes - util.each(this.children, function(child, i) { + util.each(this.children, function (child, i) { if (child.zOrder >= 0) { child.visit(context); } @@ -292,13 +303,13 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ context.restore(); }, - transform: function(context) { + transform: function (context) { // Translate - if (this.isRelativeAnchorPoint && (this.anchorPointInPixels.x != 0 || this.anchorPointInPixels != 0)) { + if (this.isRelativeAnchorPoint && (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels !== 0)) { context.translate(Math.round(-this.anchorPointInPixels.x), Math.round(-this.anchorPointInPixels.y)); } - if (this.anchorPointInPixels.x != 0 || this.anchorPointInPixels != 0) { + if (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels !== 0) { context.translate(Math.round(this.position.x + this.anchorPointInPixels.x), Math.round(this.position.y + this.anchorPointInPixels.y)); } else { context.translate(Math.round(this.position.x), Math.round(this.position.y)); @@ -310,35 +321,35 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ // Scale context.scale(this.scaleX, this.scaleY); - if (this.anchorPointInPixels.x != 0 || this.anchorPointInPixels != 0) { + if (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels !== 0) { context.translate(Math.round(-this.anchorPointInPixels.x), Math.round(-this.anchorPointInPixels.y)); } }, - runAction: function(action) { + runAction: function (action) { ActionManager.get('sharedManager').addAction({action: action, target: this, paused: this.get('isRunning')}); }, - nodeToParentTransform: function() { + nodeToParentTransform: function () { if (this.isTransformDirty) { this.transformMatrix = geom.affineTransformIdentity(); - if (!this.isRelativeAnchorPoint && !geom.pointEqualToPoint(this.anchorPointInPixels, ccp(0,0))) { + if (!this.isRelativeAnchorPoint && !geom.pointEqualToPoint(this.anchorPointInPixels, ccp(0, 0))) { this.transformMatrix = geom.affineTransformTranslate(this.transformMatrix, this.anchorPointInPixels.x, this.anchorPointInPixels.y); } - if(!geom.pointEqualToPoint(this.position, ccp(0,0))) { + if (!geom.pointEqualToPoint(this.position, ccp(0, 0))) { this.transformMatrix = geom.affineTransformTranslate(this.transformMatrix, this.position.x, this.position.y); } - if(this.rotation != 0) { + if (this.rotation !== 0) { this.transformMatrix = geom.affineTransformRotate(this.transformMatrix, -geom.degreesToRadians(this.rotation)); } - if(!(this.scaleX == 1 && this.scaleY == 1)) { + if (!(this.scaleX == 1 && this.scaleY == 1)) { this.transformMatrix = geom.affineTransformScale(this.transformMatrix, this.scaleX, this.scaleY); } - if(!geom.pointEqualToPoint(this.anchorPointInPixels, ccp(0,0))) { + if (!geom.pointEqualToPoint(this.anchorPointInPixels, ccp(0, 0))) { this.transformMatrix = geom.affineTransformTranslate(this.transformMatrix, -this.anchorPointInPixels.x, -this.anchorPointInPixels.y); } @@ -349,11 +360,11 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ return this.transformMatrix; }, - parentToNodeTransform: function() { + parentToNodeTransform: function () { // TODO }, - nodeToWorldTransform: function() { + nodeToWorldTransform: function () { var t = this.nodeToParentTransform(); var p; @@ -364,11 +375,11 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ return t; }, - worldToNodeTransform: function() { + worldToNodeTransform: function () { return geom.affineTransformInvert(this.nodeToWorldTransform()); }, - convertToNodeSpace: function(worldPoint) { + convertToNodeSpace: function (worldPoint) { return geom.pointApplyAffineTransform(worldPoint, this.worldToNodeTransform()); }, @@ -376,7 +387,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * @getter acceptsFirstResponder * @type Boolean */ - get_acceptsFirstResponder: function() { + get_acceptsFirstResponder: function () { return false; }, @@ -384,7 +395,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * @getter becomeFirstResponder * @type Boolean */ - get_becomeFirstResponder: function() { + get_becomeFirstResponder: function () { return true; }, @@ -392,7 +403,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * @getter resignFirstResponder * @type Boolean */ - get_resignFirstResponder: function() { + get_resignFirstResponder: function () { return true; }, @@ -400,7 +411,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ * @getter boundingBox * @type geometry.Rect */ - get_boundingBox: function() { + get_boundingBox: function () { var cs = this.get('contentSize'); var rect = geom.rectMake(0, 0, cs.width, cs.height); return geom.rectApplyAffineTransform(rect, this.nodeToParentTransform()); @@ -409,7 +420,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ /** * @private */ - _dirtyTransform: function() { + _dirtyTransform: function () { this.set('isTransformDirty', true); } }); diff --git a/src/libs/cocos2d/nodes/RenderTexture.js b/src/libs/cocos2d/nodes/RenderTexture.js index f050f1d..6fe93f3 100644 --- a/src/libs/cocos2d/nodes/RenderTexture.js +++ b/src/libs/cocos2d/nodes/RenderTexture.js @@ -1,5 +1,9 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), - event = require('event'), + evt = require('event'), Node = require('./Node').Node, geo = require('geometry'), Sprite = require('./Sprite').Sprite, @@ -21,19 +25,19 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ * @opt {Integer} width The width of the canvas * @opt {Integer} height The height of the canvas */ - init: function(opts) { - @super; + init: function (opts) { + RenderTexture.superclass.init.call(this, opts); - var width = opts['width'], - height = opts['height']; + var width = opts.width, + height = opts.height; - event.addListener(this, 'contentsize_changed', util.callback(this, this._resizeCanvas)); + evt.addListener(this, 'contentsize_changed', util.callback(this, this._resizeCanvas)); this.canvas = document.createElement('canvas'); this.context = this.canvas.getContext('2d'); var atlas = TextureAtlas.create({canvas: this.canvas}); - this.sprite = Sprite.create({textureAtlas: atlas, rect: {origin: ccp(0,0), size: {width: width, height: height}}}); + this.sprite = Sprite.create({textureAtlas: atlas, rect: {origin: ccp(0, 0), size: {width: width, height: height}}}); this.set('contentSize', geo.sizeMake(width, height)); this.addChild(this.sprite); @@ -45,7 +49,7 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ /** * @private */ - _resizeCanvas: function() { + _resizeCanvas: function () { var size = this.get('contentSize'), canvas = this.get('canvas'); @@ -66,7 +70,7 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ /** * Clear the canvas */ - clear: function() { + clear: function () { this.canvas.width = this.canvas.width; if (FLIP_Y_AXIS) { this.context.scale(1, -1); diff --git a/src/libs/cocos2d/nodes/Scene.js b/src/libs/cocos2d/nodes/Scene.js index 319670f..65abc88 100644 --- a/src/libs/cocos2d/nodes/Scene.js +++ b/src/libs/cocos2d/nodes/Scene.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var Node = require('./Node').Node; var Scene = Node.extend(/** @lends cocos.nodes.Scene */{ @@ -8,8 +12,8 @@ var Scene = Node.extend(/** @lends cocos.nodes.Scene */{ * @constructs * @extends cocos.nodes.Node */ - init: function() { - @super; + init: function () { + Scene.superclass.init.call(this); } }); diff --git a/src/libs/cocos2d/nodes/Sprite.js b/src/libs/cocos2d/nodes/Sprite.js index 7a4b0e6..927c688 100644 --- a/src/libs/cocos2d/nodes/Sprite.js +++ b/src/libs/cocos2d/nodes/Sprite.js @@ -1,5 +1,9 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), - event = require('event'), + evt = require('event'), Director = require('../Director').Director, TextureAtlas = require('../TextureAtlas').TextureAtlas, Node = require('./Node').Node, @@ -28,17 +32,17 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ * @opt {String} file Path to image to use as sprite atlas * @opt {Rect} [rect] The rect in the sprite atlas image file to use as the sprite */ - init: function(opts) { - @super; + init: function (opts) { + Sprite.superclass.init.call(this, opts); opts = opts || {}; - var file = opts['file'], - textureAtlas = opts['textureAtlas'], - texture = opts['texture'], - frame = opts['frame'], - spritesheet = opts['spritesheet'], - rect = opts['rect']; + var file = opts.file, + textureAtlas = opts.textureAtlas, + texture = opts.texture, + frame = opts.frame, + spritesheet = opts.spritesheet, + rect = opts.rect; this.set('offsetPosition', ccp(0, 0)); this.set('unflippedOffsetPositionFromCenter', ccp(0, 0)); @@ -49,10 +53,10 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ rect = frame.get('rect'); } - util.each(['scale', 'scaleX', 'scaleY', 'rect', 'flipX', 'flipY'], util.callback(this, function(key) { - event.addListener(this, key.toLowerCase() + '_changed', util.callback(this, this._updateQuad)); + util.each(['scale', 'scaleX', 'scaleY', 'rect', 'flipX', 'flipY'], util.callback(this, function (key) { + evt.addListener(this, key.toLowerCase() + '_changed', util.callback(this, this._updateQuad)); })); - event.addListener(this, 'textureatlas_changed', util.callback(this, this._updateTextureQuad)); + evt.addListener(this, 'textureatlas_changed', util.callback(this, this._updateTextureQuad)); if (file || texture) { textureAtlas = TextureAtlas.create({file: file, texture: texture}); @@ -64,7 +68,7 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ } if (!rect && textureAtlas) { - rect = {origin: ccp(0,0), size:{width: textureAtlas.texture.size.width, height: textureAtlas.texture.size.height}}; + rect = {origin: ccp(0, 0), size: {width: textureAtlas.texture.size.width, height: textureAtlas.texture.size.height}}; } if (rect) { @@ -87,9 +91,9 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ /** * @private */ - _updateTextureQuad: function(obj, key, texture, oldTexture) { + _updateTextureQuad: function (obj, key, texture, oldTexture) { if (oldTexture) { - oldTexture.removeQuad({quad: this.get('quad')}) + oldTexture.removeQuad({quad: this.get('quad')}); } if (texture) { @@ -101,7 +105,7 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ * @setter textureCoords * @type geometry.Rect */ - set_textureCoords: function(rect) { + set_textureCoords: function (rect) { var quad = this.get('quad'); if (!quad) { quad = { @@ -119,10 +123,10 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ * @setter textureRect * @type geometry.Rect */ - set_textureRect: function(opts) { - var rect = opts['rect'], - rotated = !!opts['rotated'], - untrimmedSize = opts['untrimmedSize'] || rect.size; + set_textureRect: function (opts) { + var rect = opts.rect, + rotated = !!opts.rotated, + untrimmedSize = opts.untrimmedSize || rect.size; this.set('contentSize', untrimmedSize); this.set('rect', util.copy(rect)); @@ -160,7 +164,7 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ /** * @private */ - _updateQuad: function() { + _updateQuad: function () { if (!this.quad) { this.quad = { drawRect: geo.rectMake(0, 0, 0, 0), @@ -195,9 +199,9 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ } }, - updateTransform: function(ctx) { + updateTransform: function (ctx) { if (!this.useSpriteSheet) { - throw "updateTransform is only valid when Sprite is being rendered using a SpriteSheet" + throw "updateTransform is only valid when Sprite is being rendered using a SpriteSheet"; } if (!this.visible) { @@ -210,24 +214,24 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ this.quad.drawRect.origin = { x: this.position.x - this.anchorPointInPixels.x * this.scaleX, y: this.position.y - this.anchorPointInPixels.y * this.scaleY - } + }; this.quad.drawRect.size = { width: this.rect.size.width * this.scaleX, height: this.rect.size.height * this.scaleY - } + }; this.set('dirty', false); this.set('recursiveDirty', false); }, - draw: function(ctx) { + draw: function (ctx) { if (!this.quad) { return; } this.get('textureAtlas').drawQuad(ctx, this.quad); }, - isFrameDisplayed: function(frame) { + isFrameDisplayed: function (frame) { if (!this.rect || !this.textureAtlas) { return false; } @@ -239,7 +243,7 @@ var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ * @setter displayFrame * @type cocos.SpriteFrame */ - set_displayFrame: function(frame) { + set_displayFrame: function (frame) { if (!frame) { delete this.quad; return; diff --git a/src/libs/cocos2d/nodes/TMXLayer.js b/src/libs/cocos2d/nodes/TMXLayer.js index 3f6b2f1..9fbe1f7 100644 --- a/src/libs/cocos2d/nodes/TMXLayer.js +++ b/src/libs/cocos2d/nodes/TMXLayer.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), SpriteBatchNode = require('./BatchNode').SpriteBatchNode, Sprite = require('./Sprite').Sprite, @@ -28,10 +32,10 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ * @opt {cocos.TMXLayerInfo} layerInfo * @opt {cocos.TMXMapInfo} mapInfo */ - init: function(opts) { - var tilesetInfo = opts['tilesetInfo'], - layerInfo = opts['layerInfo'], - mapInfo = opts['mapInfo']; + init: function (opts) { + var tilesetInfo = opts.tilesetInfo, + layerInfo = opts.layerInfo, + mapInfo = opts.mapInfo; var size = layerInfo.get('layerSize'), totalNumberOfTiles = size.width * size.height; @@ -41,7 +45,7 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ tex = tilesetInfo.sourceImage; } - @super({file: tex}); + TMXLayer.superclass.init.call(this, {file: tex}); this.set('anchorPoint', ccp(0, 0)); @@ -63,7 +67,7 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ this.set('contentSize', geo.sizeMake(this.layerSize.width * this.mapTileSize.width, this.layerSize.height * this.mapTileSize.height)); }, - calculateLayerOffset: function(pos) { + calculateLayerOffset: function (pos) { var ret = ccp(0, 0); switch (this.layerOrientation) { @@ -81,18 +85,18 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ return ret; }, - setupTiles: function() { + setupTiles: function () { this.tileset.bindTo('imageSize', this.get('texture'), 'contentSize'); - for (var y=0; y < this.layerSize.height; y++) { - for (var x=0; x < this.layerSize.width; x++) { + for (var y = 0; y < this.layerSize.height; y++) { + for (var x = 0; x < this.layerSize.width; x++) { var pos = x + this.layerSize.width * y, gid = this.tiles[pos]; - if (gid != 0) { - this.appendTile({gid:gid, position:ccp(x,y)}); + if (gid !== 0) { + this.appendTile({gid: gid, position: ccp(x, y)}); // Optimization: update min and max GID rendered by the layer this.minGID = Math.min(gid, this.minGID); @@ -101,9 +105,9 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ } } }, - appendTile: function(opts) { - var gid = opts['gid'], - pos = opts['position']; + appendTile: function (opts) { + var gid = opts.gid, + pos = opts.position; var z = pos.x + pos.y * this.layerSize.width; @@ -115,7 +119,7 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ this.addChild({child: tile, z: 0, tag: z}); }, - positionAt: function(pos) { + positionAt: function (pos) { var ret = ccp(0, 0); switch (this.layerOrientation) { @@ -132,27 +136,27 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ return ret; }, - positionForOrthoAt: function(pos) { + positionForOrthoAt: function (pos) { var overlap = this.mapTileSize.height - this.tileset.tileSize.height; var x = Math.floor(pos.x * this.mapTileSize.width + 0.49); var y; if (FLIP_Y_AXIS) { - y = Math.floor((this.get('layerSize').height - pos.y -1) * this.mapTileSize.height + 0.49); + y = Math.floor((this.get('layerSize').height - pos.y - 1) * this.mapTileSize.height + 0.49); } else { y = Math.floor(pos.y * this.mapTileSize.height + 0.49) + overlap; } - return ccp(x,y); + return ccp(x, y); }, - tileGID: function(pos) { + tileGID: function (pos) { var tilesPerRow = this.get('layerSize').width, tilePos = pos.x + (pos.y * tilesPerRow); return this.tiles[tilePos]; }, - removeTile: function(pos) { + removeTile: function (pos) { var gid = this.tileGID(pos); - if (gid == 0) { + if (gid === 0) { // Tile is already blank return; } diff --git a/src/libs/cocos2d/nodes/TMXTiledMap.js b/src/libs/cocos2d/nodes/TMXTiledMap.js index 51bfd0e..c0591f5 100644 --- a/src/libs/cocos2d/nodes/TMXTiledMap.js +++ b/src/libs/cocos2d/nodes/TMXTiledMap.js @@ -1,3 +1,7 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), console = require('system').console, geo = require('geometry'), @@ -26,12 +30,12 @@ var TMXTiledMap = Node.extend(/** @lends cocos.nodes.TMXTiledMap# */{ * * @opt {String} file The file path of the TMX map to load */ - init: function(opts) { - @super; + init: function (opts) { + TMXTiledMap.superclass.init.call(this, opts); this.set('anchorPoint', ccp(0, 0)); - var mapInfo = TMXMapInfo.create(opts['file']); + var mapInfo = TMXMapInfo.create(opts.file); this.mapSize = mapInfo.get('mapSize'); this.tileSize = mapInfo.get('tileSize'); @@ -42,10 +46,10 @@ var TMXTiledMap = Node.extend(/** @lends cocos.nodes.TMXTiledMap# */{ // Add layers to map var idx = 0; - util.each(mapInfo.layers, util.callback(this, function(layerInfo) { + util.each(mapInfo.layers, util.callback(this, function (layerInfo) { if (layerInfo.get('visible')) { var child = this.parseLayer({layerInfo: layerInfo, mapInfo: mapInfo}); - this.addChild({child:child, z:idx, tag:idx}); + this.addChild({child: child, z: idx, tag: idx}); var childSize = child.get('contentSize'); var currentSize = this.get('contentSize'); @@ -58,37 +62,38 @@ var TMXTiledMap = Node.extend(/** @lends cocos.nodes.TMXTiledMap# */{ })); }, - parseLayer: function(opts) { + parseLayer: function (opts) { var tileset = this.tilesetForLayer(opts); - var layer = TMXLayer.create({tilesetInfo: tileset, layerInfo: opts['layerInfo'], mapInfo: opts['mapInfo']}); + var layer = TMXLayer.create({tilesetInfo: tileset, layerInfo: opts.layerInfo, mapInfo: opts.mapInfo}); layer.setupTiles(); return layer; }, - tilesetForLayer: function(opts) { - var layerInfo = opts['layerInfo'], - mapInfo = opts['mapInfo'], + tilesetForLayer: function (opts) { + var layerInfo = opts.layerInfo, + mapInfo = opts.mapInfo, size = layerInfo.get('layerSize'); // Reverse loop - for (var i = mapInfo.tilesets.length -1; i >= 0; i--) { - var tileset = mapInfo.tilesets[i]; + var tileset; + for (var i = mapInfo.tilesets.length - 1; i >= 0; i--) { + tileset = mapInfo.tilesets[i]; - for (var y=0; y < size.height; y++ ) { - for (var x=0; x < size.width; x++ ) { + for (var y = 0; y < size.height; y++) { + for (var x = 0; x < size.width; x++) { var pos = x + size.width * y, gid = layerInfo.tiles[pos]; - if (gid != 0 && gid >= tileset.firstGID) { + if (gid !== 0 && gid >= tileset.firstGID) { return tileset; } } // for (var x } // for (var y } // for (var i - console.warn("cocos2d: Warning: TMX Layer '%s' has no tiles", layerInfo.name) + console.warn("cocos2d: Warning: TMX Layer '%s' has no tiles", layerInfo.name); return tileset; } }); diff --git a/src/libs/cocos2d/nodes/index.js b/src/libs/cocos2d/nodes/index.js index fabe16f..1757c3c 100644 --- a/src/libs/cocos2d/nodes/index.js +++ b/src/libs/cocos2d/nodes/index.js @@ -1,7 +1,11 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), path = require('path'); -var modules = 'Node Layer Scene Label Sprite TMXTiledMap BatchNode RenderTexture Menu MenuItem'.w() +var modules = 'Node Layer Scene Label Sprite TMXTiledMap BatchNode RenderTexture Menu MenuItem'.w(); /** * @memberOf cocos @@ -9,7 +13,7 @@ var modules = 'Node Layer Scene Label Sprite TMXTiledMap BatchNode RenderTexture */ var nodes = {}; -util.each(modules, function(mod, i) { +util.each(modules, function (mod, i) { util.extend(nodes, require('./' + mod)); }); From 9dff80a4d82ea265a25d485ef4365444e84e7ddd Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Jan 2011 23:24:12 +1300 Subject: [PATCH 016/176] Fixed parsing of config files in 'make' script --- scripts/make.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/scripts/make.py b/scripts/make.py index fe9058b..0cd5097 100755 --- a/scripts/make.py +++ b/scripts/make.py @@ -25,11 +25,10 @@ class Compiler(object): extensions = ['js', 'tmx', 'tms', 'plist', 'gif', 'jpg', 'jpeg', 'png'] header = u'' footer = u'' - app_configs = ['cocos2d/src/libs/cocos2d/config.js', 'src/libs/cocos2d/config.js', 'libs/cocos2d/config.js', 'src/config.js'] def __init__(self, config='make.js'): self.config = self.read_config(config) - print self.output + print "Ouputting to: ", self.output def read_config(self, config_file): print "Loading config:", config_file @@ -52,7 +51,7 @@ def make(self): code += 'var __main_module_name__ = %s;\n' % json.dumps(self.main_module) code += 'var __resources__ = [];\n' code += 'function __imageResource(data) { var img = new Image(); img.src = data; return img; };\n' - for key, val in self.app_config().items(): + for key, val in self.app_config_dict().items(): code += 'var %s = %s;\n' % (key.upper(), json.dumps(val)) @@ -83,7 +82,7 @@ def make_path(self, source_path, dest_path=None): code = '' files = self.scan_for_files(source_path) for src_file in files: - if src_file in self.app_configs: + if src_file in self.app_configs(): # Skip config files because they're JSON not JavaScript continue @@ -107,15 +106,26 @@ def dst_for_src(self, path): return path - def app_config(self): + def app_configs(self): + """ + Returns an array of paths pointing to all the config.js files for the app + """ + configs = [u'src/libs/cocos2d/config.js'] + for source, dest in self.config['paths'].items(): + c = os.path.join(source, 'config.js') + if os.path.exists(c): + configs.append(c) + + return configs + + + + def app_config_dict(self): """ Reads all the app's config.js files and returns a dictionary of their values """ vals = {} - for config in self.app_configs: - if not os.path.exists(config): - continue - + for config in self.app_configs(): data = self.read_json_file(config) vals.update(data) From 3ed8cb6bc1446cd1573f3750e0e319c342a804a8 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 28 Jan 2011 19:47:24 +1300 Subject: [PATCH 017/176] Fixed menu items not highlighting onMouseDown --- src/libs/cocos2d/nodes/Menu.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/cocos2d/nodes/Menu.js b/src/libs/cocos2d/nodes/Menu.js index b5cb487..93f44b6 100644 --- a/src/libs/cocos2d/nodes/Menu.js +++ b/src/libs/cocos2d/nodes/Menu.js @@ -68,7 +68,7 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ }, itemForMouseEvent: function (event) { - var location = Director.get('sharedDirector').convertEventToCanvas(event); + var location = event.locationInCanvas; var children = this.get('children'); for (var i = 0, len = children.length; i < len; i++) { @@ -110,7 +110,8 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ return false; } - var selectedItem = this.set('selectedItem', this.itemForMouseEvent(event)); + var selectedItem = this.itemForMouseEvent(event); + this.set('selectedItem', selectedItem); if (selectedItem) { selectedItem.set('isSelected', true); this.set('state', kMenuStateTrackingTouch); From 09984dbbac1a24394d13b8365472c4251a1d88bb Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 28 Jan 2011 19:55:33 +1300 Subject: [PATCH 018/176] Fixed sprite frame offset when FLIP_Y_AXIS = true --- src/libs/cocos2d/SpriteFrameCache.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libs/cocos2d/SpriteFrameCache.js b/src/libs/cocos2d/SpriteFrameCache.js index 1507aeb..d83c654 100644 --- a/src/libs/cocos2d/SpriteFrameCache.js +++ b/src/libs/cocos2d/SpriteFrameCache.js @@ -1,4 +1,4 @@ -/*globals module exports resource require BObject BArray*/ +/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ /*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; @@ -88,6 +88,10 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ //console.log("cocos2d: WARNING: originalWidth/Height not found on the CCSpriteFrame. AnchorPoint won't work as expected. Regenerate the .plist"); } + if (FLIP_Y_AXIS) { + oy *= -1; + } + // abs ow/oh ow = Math.abs(ow); oh = Math.abs(oh); @@ -107,6 +111,10 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ offset = geo.pointFromString(frameDict.offset), sourceSize = geo.sizeFromString(frameDict.sourceSize); + if (FLIP_Y_AXIS) { + offset.y *= -1; + } + // create frame spriteFrame = SpriteFrame.create({texture: texture, @@ -123,6 +131,11 @@ var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ textureRect = geo.rectFromString(frameDict.textureRect), textureRotated = frameDict.textureRotated; + + if (FLIP_Y_AXIS) { + spriteOffset.y *= -1; + } + // get aliases var aliases = frameDict.aliases; for (var i = 0, len = aliases.length; i < len; i++) { From dfc323f9e9ccf65ffe6c4c2cd22b7cb8a5829057 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 28 Jan 2011 19:56:29 +1300 Subject: [PATCH 019/176] Set FLIP_Y_AXIS = true for tests so they match cocos2d-iphone --- tests/cocos2d/SpriteTest.js | 10 +++++----- tests/cocos2d/TileMapTest.js | 15 +++++---------- tests/cocos2d/config.js | 2 +- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/tests/cocos2d/SpriteTest.js b/tests/cocos2d/SpriteTest.js index 1feff46..e00dccf 100644 --- a/tests/cocos2d/SpriteTest.js +++ b/tests/cocos2d/SpriteTest.js @@ -70,14 +70,14 @@ var SpriteDemo = nodes.Layer.extend({ var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); this.addChild({child: label, z: 1}); - label.set('position', ccp(s.width / 2, 50)); + label.set('position', ccp(s.width / 2, s.height - 50)); var subtitle = this.get('subtitle'); if (subtitle) { var l = nodes.Label.create({string: subtitle, fontName: "Thonburi", fontSize: 16}); this.addChild({child: l, z: 1}); - l.set('position', ccp(s.width / 2, 80)); + l.set('position', ccp(s.width / 2, s.height - 80)); } @@ -88,9 +88,9 @@ var SpriteDemo = nodes.Layer.extend({ var menu = nodes.Menu.create({items: [item1, item2, item3]}); menu.set('position', ccp(0, 0)); - item1.set('position', ccp(s.width / 2 - 100, s.height - 30)); - item2.set('position', ccp(s.width / 2, s.height - 30)); - item3.set('position', ccp(s.width / 2 + 100, s.height - 30)); + item1.set('position', ccp(s.width / 2 - 100, 30)); + item2.set('position', ccp(s.width / 2, 30)); + item3.set('position', ccp(s.width / 2 + 100, 30)); this.addChild({child: menu, z: 1}); }, diff --git a/tests/cocos2d/TileMapTest.js b/tests/cocos2d/TileMapTest.js index 23b170f..cec1913 100644 --- a/tests/cocos2d/TileMapTest.js +++ b/tests/cocos2d/TileMapTest.js @@ -54,14 +54,14 @@ var TileDemo = nodes.Layer.extend({ var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); this.addChild({child: label, z: 1}); - label.set('position', ccp(s.width / 2, 50)); + label.set('position', ccp(s.width / 2, s.height - 50)); var subtitle = this.get('subtitle'); if (subtitle) { var l = nodes.Label.create({string: subtitle, fontName: "Thonburi", fontSize: 16}); this.addChild({child: l, z: 1}); - l.set('position', ccp(s.width / 2, 80)); + l.set('position', ccp(s.width / 2, s.height - 80)); } @@ -72,9 +72,9 @@ var TileDemo = nodes.Layer.extend({ var menu = nodes.Menu.create({items: [item1, item2, item3]}); menu.set('position', ccp(0, 0)); - item1.set('position', ccp(s.width / 2 - 100, s.height - 30)); - item2.set('position', ccp(s.width / 2, s.height - 30)); - item3.set('position', ccp(s.width / 2 + 100, s.height - 30)); + item1.set('position', ccp(s.width / 2 - 100, 30)); + item2.set('position', ccp(s.width / 2, 30)); + item3.set('position', ccp(s.width / 2 + 100, 30)); this.addChild({child: menu, z: 1}); }, @@ -126,11 +126,6 @@ tests.TMXOrthoTest2 = TileDemo.extend({ var s = cocos.Director.get('sharedDirector').get('winSize'); - // Adjust anchor and position to bottom left so it renders like cocos2d-iphone - map.set('anchorPoint', ccp(0, 1)); - - map.set('position', ccp(0, s.height)); - map.runAction(actions.ScaleBy.create({duration: 2, scale: 0.5})); } }); diff --git a/tests/cocos2d/config.js b/tests/cocos2d/config.js index 8f9a2c1..9778971 100644 --- a/tests/cocos2d/config.js +++ b/tests/cocos2d/config.js @@ -1,3 +1,3 @@ { - "FLIP_Y_AXIS": false + "FLIP_Y_AXIS": true } From 33020c316ebb45ef440d9c3306a453c92c060212 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 28 Jan 2011 21:50:30 +1300 Subject: [PATCH 020/176] Added support for Isometric TMX tile maps. --- src/libs/cocos2d/nodes/TMXLayer.js | 26 ++++++++++------ tests/cocos2d/TileMapTest.js | 28 +++++++++++++++++- tests/cocos2d/resources/TileMaps/iso-test.png | Bin 0 -> 8448 bytes tests/cocos2d/resources/TileMaps/iso-test.tmx | 17 +++++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 tests/cocos2d/resources/TileMaps/iso-test.png create mode 100644 tests/cocos2d/resources/TileMaps/iso-test.tmx diff --git a/src/libs/cocos2d/nodes/TMXLayer.js b/src/libs/cocos2d/nodes/TMXLayer.js index 9fbe1f7..f745fbe 100644 --- a/src/libs/cocos2d/nodes/TMXLayer.js +++ b/src/libs/cocos2d/nodes/TMXLayer.js @@ -120,21 +120,18 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ this.addChild({child: tile, z: 0, tag: z}); }, positionAt: function (pos) { - var ret = ccp(0, 0); - switch (this.layerOrientation) { case TMXOrientationOrtho: - ret = this.positionForOrthoAt(pos); - break; + return this.positionForOrthoAt(pos); case TMXOrientationIso: - // TODO - break; + return this.positionForIsoAt(pos); + /* case TMXOrientationHex: // TODO - break; + */ + default: + return ccp(0, 0); } - - return ret; }, positionForOrthoAt: function (pos) { var overlap = this.mapTileSize.height - this.tileset.tileSize.height; @@ -148,6 +145,17 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ return ccp(x, y); }, + positionForIsoAt: function (pos) { + var mapTileSize = this.get('mapTileSize'), + layerSize = this.get('layerSize'); + + return ccp( + mapTileSize.width / 2 * (layerSize.width + pos.x - pos.y - 1), + mapTileSize.height / 2 * ((layerSize.height * 2 - pos.x - pos.y) - 2) + ); + }, + + tileGID: function (pos) { var tilesPerRow = this.get('layerSize').width, tilePos = pos.x + (pos.y * tilesPerRow); diff --git a/tests/cocos2d/TileMapTest.js b/tests/cocos2d/TileMapTest.js index cec1913..2fe0fea 100644 --- a/tests/cocos2d/TileMapTest.js +++ b/tests/cocos2d/TileMapTest.js @@ -12,7 +12,8 @@ var util = require('util'), var sceneIdx = -1; var transitions = [ - "TMXOrthoTest2" + "TMXOrthoTest2", + "TMXIsoTest" ]; var tests = {}; @@ -130,6 +131,31 @@ tests.TMXOrthoTest2 = TileDemo.extend({ } }); + +tests.TMXIsoTest = TileDemo.extend({ + title: 'TMX Isometric test 0', + + init: function () { + tests.TMXIsoTest.superclass.init.call(this); + + /* + CCLayerColor *color = [CCLayerColor layerWithColor:ccc4(64,64,64,255)]; + [self addChild:color z:-1]; + */ + + var map = nodes.TMXTiledMap.create({file: module.dirname + "/resources/TileMaps/iso-test.tmx"}); + this.addChild({child: map, z: 0, tag: kTagTileMap}); + + // move map to the center of the screen + var ms = map.get('mapSize'), + ts = map.get('tileSize'); + + map.set('position', ccp(-ms.width * ts.width / 2, -ms.height * ts.height / 2)); + + //map.runAction(actions.MoveTo.create({duration: 1.0, position: ccp(-ms.width * ts.width / 2, -ms.height * ts.height / 2)})); + } +}); + // Initialise test var director = cocos.Director.get('sharedDirector'); diff --git a/tests/cocos2d/resources/TileMaps/iso-test.png b/tests/cocos2d/resources/TileMaps/iso-test.png new file mode 100644 index 0000000000000000000000000000000000000000..bb6327f47b524b69f2ae7d7e252a277e11a5ae6b GIT binary patch literal 8448 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 literal 0 HcmV?d00001 diff --git a/tests/cocos2d/resources/TileMaps/iso-test.tmx b/tests/cocos2d/resources/TileMaps/iso-test.tmx new file mode 100644 index 0000000..d46c585 --- /dev/null +++ b/tests/cocos2d/resources/TileMaps/iso-test.tmx @@ -0,0 +1,17 @@ + + + + + + + + + H4sIAAAAAAAAA+3DwQkAAAwDoYPsv3PH6EfBVVNVVVVVVVVVVVVVVVVVVVVfH73hYN0AQAAA + + + + + H4sIAAAAAAAAA+2Y2Y7DIAxFeeD/v3nEQ6UMYvGW4Gt8pKptAgnXZrFdSpLQqKcHkCTJJ9Tyf73X7js6vc6vdJ+27+3vP0m/5m4DQfubPkLxv+UYR/ssgg0sqN2nvz5rG4Gd5t42ddIuGhRtUWww0kDVFsEGKw1UG6AzswHFv4j6OWPe2QBN/26+c9YC4vrXrOlT+agVWn8h+vsHd+yaM8Er3LHP6k/ISG2APvdX/2d90OP9le8ixjVPqPnsqj8y1Hglao7PiekjrPURXBuUwfX+vmc4a3w3D3bv8GgPie8o9lrVBz3ZQbKfc2o9q3se7CA90yk5PkItSDpGS32n5wJXh1VeyG3zJhw/ScZKPSNOYrWnrWII7fvfRlvref7mxgoe9DcoedCs3+o5s3bUe18iqWFYtPOiv2G1z3PmgId9UArXr9J90ivSWJrzHFS0+RQ6nHwhov4Gcp3Agqi6qET2LRVNLh0BSf0wEpo6QgSeZ9xt2hvRzzgKN2tPkiRJEg1/QULzBABAAAA= + + + From 701cece83f905a523f0a856c35cc227cdaa6aee8 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 29 Jan 2011 12:48:51 +1300 Subject: [PATCH 021/176] Minor bug fixes for tilemaps --- src/libs/cocos2d/nodes/BatchNode.js | 1 + src/libs/cocos2d/nodes/RenderTexture.js | 3 +-- src/libs/cocos2d/nodes/TMXLayer.js | 14 +++++++++----- src/libs/cocos2d/nodes/TMXTiledMap.js | 3 +-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index 610b038..9639967 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -85,6 +85,7 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ return; // No change } + this.renderTexture.set('contentSize', size); this.set('dirty', true); }, diff --git a/src/libs/cocos2d/nodes/RenderTexture.js b/src/libs/cocos2d/nodes/RenderTexture.js index 6fe93f3..ea199a1 100644 --- a/src/libs/cocos2d/nodes/RenderTexture.js +++ b/src/libs/cocos2d/nodes/RenderTexture.js @@ -1,4 +1,4 @@ -/*globals module exports resource require BObject BArray*/ +/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ /*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; @@ -60,7 +60,6 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ this.context.translate(0, -canvas.height); } - var s = this.get('sprite'); if (s) { s.set('textureRect', {rect: geo.rectMake(0, 0, size.width, size.height)}); diff --git a/src/libs/cocos2d/nodes/TMXLayer.js b/src/libs/cocos2d/nodes/TMXLayer.js index f745fbe..694dfcb 100644 --- a/src/libs/cocos2d/nodes/TMXLayer.js +++ b/src/libs/cocos2d/nodes/TMXLayer.js @@ -64,7 +64,7 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ var offset = this.calculateLayerOffset(layerInfo.get('offset')); this.set('position', offset); - this.set('contentSize', geo.sizeMake(this.layerSize.width * this.mapTileSize.width, this.layerSize.height * this.mapTileSize.height)); + this.set('contentSize', geo.sizeMake(this.layerSize.width * this.mapTileSize.width, (this.layerSize.height * (this.mapTileSize.height - 1)) + this.tileset.tileSize.height)); }, calculateLayerOffset: function (pos) { @@ -149,10 +149,14 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ var mapTileSize = this.get('mapTileSize'), layerSize = this.get('layerSize'); - return ccp( - mapTileSize.width / 2 * (layerSize.width + pos.x - pos.y - 1), - mapTileSize.height / 2 * ((layerSize.height * 2 - pos.x - pos.y) - 2) - ); + if (FLIP_Y_AXIS) { + return ccp( + mapTileSize.width / 2 * (layerSize.width + pos.x - pos.y - 1), + mapTileSize.height / 2 * ((layerSize.height * 2 - pos.x - pos.y) - 2) + ); + } else { + throw "Isometric tiles without FLIP_Y_AXIS is currently unsupported"; + } }, diff --git a/src/libs/cocos2d/nodes/TMXTiledMap.js b/src/libs/cocos2d/nodes/TMXTiledMap.js index c0591f5..8d38cbd 100644 --- a/src/libs/cocos2d/nodes/TMXTiledMap.js +++ b/src/libs/cocos2d/nodes/TMXTiledMap.js @@ -3,7 +3,6 @@ "use strict"; var util = require('util'), - console = require('system').console, geo = require('geometry'), ccp = geo.ccp, Node = require('./Node').Node, @@ -93,7 +92,7 @@ var TMXTiledMap = Node.extend(/** @lends cocos.nodes.TMXTiledMap# */{ } // for (var y } // for (var i - console.warn("cocos2d: Warning: TMX Layer '%s' has no tiles", layerInfo.name); + //console.log("cocos2d: Warning: TMX Layer '%s' has no tiles", layerInfo.name); return tileset; } }); From ecf4e31d5585ec3e693c0c7ab0e1443783acc161 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 30 Jan 2011 18:46:41 +1300 Subject: [PATCH 022/176] Refactored Transform Matrix code --- src/libs/geometry.js | 375 ++++++++++++++++++++++--------------------- 1 file changed, 190 insertions(+), 185 deletions(-) diff --git a/src/libs/geometry.js b/src/libs/geometry.js index c923633..b02bf63 100644 --- a/src/libs/geometry.js +++ b/src/libs/geometry.js @@ -1,7 +1,11 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'); -var RE_PAIR = /{\s*([\d.-]+)\s*,\s*([\d.-]+)\s*}/, - RE_DOUBLE_PAIR = /{\s*({[\s\d,.-]+})\s*,\s*({[\s\d,.-]+})\s*}/; +var RE_PAIR = /\{\s*([\d.\-]+)\s*,\s*([\d.\-]+)\s*\}/, + RE_DOUBLE_PAIR = /\{\s*(\{[\s\d,.\-]+\})\s*,\s*(\{[\s\d,.\-]+\})\s*\}/; /** @namespace */ var geometry = { @@ -12,7 +16,7 @@ var geometry = { * @param {Float} x X value * @param {Float} y Y value */ - Point: function(x, y) { + Point: function (x, y) { /** * X coordinate * @type Float @@ -33,7 +37,7 @@ var geometry = { * @param {Float} w Width * @param {Float} h Height */ - Size: function(w, h) { + Size: function (w, h) { /** * Width * @type Float @@ -56,7 +60,7 @@ var geometry = { * @param {Float} w Width * @param {Float} h Height */ - Rect: function(x, y, w, h) { + Rect: function (x, y, w, h) { /** * Coordinate in 2D space * @type {geometry.Point} @@ -70,6 +74,18 @@ var geometry = { this.size = new geometry.Size(w, h); }, + /** + * Transform matrix + */ + TransformMatrix: function (a, b, c, d, tx, ty) { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.tx = tx; + this.ty = ty; + }, + /** * Creates a geometry.Point instance * @@ -77,7 +93,7 @@ var geometry = { * @param {Float} y Y coordinate * @returns {geometry.Point} */ - ccp: function(x, y) { + ccp: function (x, y) { return module.exports.pointMake(x, y); }, @@ -88,7 +104,7 @@ var geometry = { * @param {geometry.Point} p2 Second point * @returns {geometry.Point} New point */ - ccpAdd: function(p1, p2) { + ccpAdd: function (p1, p2) { return geometry.ccp(p1.x + p2.x, p1.y + p2.y); }, @@ -99,7 +115,7 @@ var geometry = { * @param {geometry.Point} p2 Second point * @returns {geometry.Point} New point */ - ccpSub: function(p1, p2) { + ccpSub: function (p1, p2) { return geometry.ccp(p1.x - p2.x, p1.y - p2.y); }, @@ -110,7 +126,7 @@ var geometry = { * @param {geometry.Point} p2 Second point * @returns {geometry.Point} New point */ - ccpMult: function(p1, p2) { + ccpMult: function (p1, p2) { return geometry.ccp(p1.x * p2.x, p1.y * p2.y); }, @@ -121,7 +137,7 @@ var geometry = { * @param {geometry.Point} p Point to invert * @returns {geometry.Point} New point */ - ccpNeg: function(p) { + ccpNeg: function (p) { return geometry.ccp(-p.x, -p.y); }, @@ -131,7 +147,7 @@ var geometry = { * @param {geometry.Point} p Point to round * @returns {geometry.Point} New point */ - ccpRound: function(p) { + ccpRound: function (p) { return geometry.ccp(Math.round(p.x), Math.round(p.y)); }, @@ -141,7 +157,7 @@ var geometry = { * @param {geometry.Point} p Point to round * @returns {geometry.Point} New point */ - ccpCeil: function(p) { + ccpCeil: function (p) { return geometry.ccp(Math.ceil(p.x), Math.ceil(p.y)); }, @@ -151,7 +167,7 @@ var geometry = { * @param {geometry.Point} p Point to round * @returns {geometry.Point} New point */ - ccpFloor: function(p) { + ccpFloor: function (p) { return geometry.ccp(Math.floor(p.x), Math.floor(p.y)); }, @@ -160,21 +176,21 @@ var geometry = { * * @returns {geometry.Point} New point at 0x0 */ - PointZero: function() { - return geometry.ccp(0,0); + PointZero: function () { + return geometry.ccp(0, 0); }, /** * @returns {geometry.Rect} */ - rectMake: function(x, y, w, h) { + rectMake: function (x, y, w, h) { return new geometry.Rect(x, y, w, h); }, /** * @returns {geometry.Rect} */ - rectFromString: function(str) { + rectFromString: function (str) { var matches = str.match(RE_DOUBLE_PAIR), p = geometry.pointFromString(matches[1]), s = geometry.sizeFromString(matches[2]); @@ -185,14 +201,14 @@ var geometry = { /** * @returns {geometry.Size} */ - sizeMake: function(w, h) { + sizeMake: function (w, h) { return new geometry.Size(w, h); }, /** * @returns {geometry.Size} */ - sizeFromString: function(str) { + sizeFromString: function (str) { var matches = str.match(RE_PAIR), w = parseFloat(matches[1]), h = parseFloat(matches[2]); @@ -203,14 +219,14 @@ var geometry = { /** * @returns {geometry.Point} */ - pointMake: function(x, y) { + pointMake: function (x, y) { return new geometry.Point(x, y); }, /** * @returns {geometry.Point} */ - pointFromString: function(str) { + pointFromString: function (str) { var matches = str.match(RE_PAIR), x = parseFloat(matches[1]), y = parseFloat(matches[2]); @@ -221,101 +237,147 @@ var geometry = { /** * @returns {Boolean} */ - rectContainsPoint: function(r, p) { - return ((p.x >= r.origin.x && p.x <= r.origin.x + r.size.width) - && (p.y >= r.origin.y && p.y <= r.origin.y + r.size.height)); + rectContainsPoint: function (r, p) { + return ((p.x >= r.origin.x && p.x <= r.origin.x + r.size.width) && + (p.y >= r.origin.y && p.y <= r.origin.y + r.size.height)); + }, + + /** + * Returns the smallest rectangle that contains the two source rectangles. + * + * @param {geometry.Rect} r1 + * @param {geometry.Rect} r2 + * @returns {geometry.Rect} + */ + rectUnion: function (r1, r2) { + var rect = new geometry.Rect(0, 0, 0, 0); + + rect.origin.x = Math.min(r1.origin.x, r2.origin.x); + rect.origin.y = Math.min(r1.origin.y, r2.origin.y); + rect.size.width = Math.max(r1.origin.x + r1.size.width, r2.origin.x + r2.size.width) - rect.origin.x; + rect.size.height = Math.max(r1.origin.y + r1.size.height, r2.origin.y + r2.size.height) - rect.origin.y; + + return rect; }, /** * @returns {Boolean} */ - rectOverlapsRect: function(r1, r2) { - if (r1.origin.x + r1.size.width < r2.origin.x) - return false - if (r2.origin.x + r2.size.width < r1.origin.x) - return false - if (r1.origin.y + r1.size.height < r2.origin.y) - return false - if (r2.origin.y + r2.size.height < r1.origin.y) - return false + rectOverlapsRect: function (r1, r2) { + if (r1.origin.x + r1.size.width < r2.origin.x) { + return false; + } + if (r2.origin.x + r2.size.width < r1.origin.x) { + return false; + } + if (r1.origin.y + r1.size.height < r2.origin.y) { + return false; + } + if (r2.origin.y + r2.size.height < r1.origin.y) { + return false; + } return true; }, + /** + * Returns the overlapping portion of 2 rectangles + */ + rectIntersection: function (lhsRect, rhsRect) { + + var intersection = new geometry.Rect( + Math.max(geometry.rectGetMinX(lhsRect), geometry.rectGetMinX(rhsRect)), + Math.max(geometry.rectGetMinY(lhsRect), geometry.rectGetMinY(rhsRect)), + 0, + 0 + ); + + intersection.size.width = Math.min(geometry.rectGetMaxX(lhsRect), geometry.rectGetMaxX(rhsRect)) - geometry.rectGetMinX(intersection); + intersection.size.height = Math.min(geometry.rectGetMaxY(lhsRect), geometry.rectGetMaxY(rhsRect)) - geometry.rectGetMinY(intersection); + + return intersection; + }, + /** * @returns {Boolean} */ - pointEqualToPoint: function(point1, point2) { + pointEqualToPoint: function (point1, point2) { return (point1.x == point2.x && point1.y == point2.y); }, /** * @returns {Boolean} */ - sizeEqualToSize: function(size1, size2) { + sizeEqualToSize: function (size1, size2) { return (size1.width == size2.width && size1.height == size2.height); }, /** * @returns {Boolean} */ - rectEqualToRect: function(rect1, rect2) { + rectEqualToRect: function (rect1, rect2) { return (module.exports.sizeEqualToSize(rect1.size, rect2.size) && module.exports.pointEqualToPoint(rect1.origin, rect2.origin)); }, /** * @returns {Float} */ - rectGetMinX: function(rect) { + rectGetMinX: function (rect) { return rect.origin.x; }, /** * @returns {Float} */ - rectGetMinY: function(rect) { + rectGetMinY: function (rect) { return rect.origin.y; }, /** * @returns {Float} */ - rectGetMaxX: function(rect) { + rectGetMaxX: function (rect) { return rect.origin.x + rect.size.width; }, /** * @returns {Float} */ - rectGetMaxY: function(rect) { + rectGetMaxY: function (rect) { return rect.origin.y + rect.size.height; }, - boundingRectMake: function(p1, p2, p3, p4) { - var minX = Math.min(p1.x, Math.min(p2.x, Math.min(p3.x, p4.x))); - var minY = Math.min(p1.y, Math.min(p2.y, Math.min(p3.y, p4.y))); - var maxX = Math.max(p1.x, Math.max(p2.x, Math.max(p3.x, p4.x))); - var maxY = Math.max(p1.y, Math.max(p2.y, Math.max(p3.y, p4.y))); + boundingRectMake: function (p1, p2, p3, p4) { + var minX = Math.min(p1.x, p2.x, p3.x, p4.x); + var minY = Math.min(p1.y, p2.y, p3.y, p4.y); + var maxX = Math.max(p1.x, p2.x, p3.x, p4.x); + var maxY = Math.max(p1.y, p2.y, p3.y, p4.y); - return geometry.rectMake(minX, minY, (maxX - minX), (maxY - minY)); + return new geometry.Rect(minX, minY, (maxX - minX), (maxY - minY)); }, /** * @returns {geometry.Point} */ - pointApplyAffineTransform: function(p, trans) { - var newPoint = geometry.ccp(0, 0); - - newPoint.x = p.x * trans[0][0] + p.y * trans[1][0] + trans[2][0]; - newPoint.y = p.x * trans[0][1] + p.y * trans[1][1] + trans[2][1]; + pointApplyAffineTransform: function (point, t) { + + /* + aPoint.x * aTransform.a + aPoint.y * aTransform.c + aTransform.tx, + aPoint.x * aTransform.b + aPoint.y * aTransform.d + aTransform.ty + */ + + return new geometry.Point(t.a * point.x + t.c * point.y + t.tx, t.b * point.x + t.d * point.y + t.ty); - return newPoint; }, /** - * @returns {geometry.Rect} + * Apply a transform matrix to a rectangle + * + * @param {geometry.Rect} rect Rectangle to transform + * @param {geometry.TransformMatrix} trans TransformMatrix to apply to rectangle + * @returns {geometry.Rect} A new transformed rectangle */ - rectApplyAffineTransform: function(rect, trans) { + rectApplyAffineTransform: function (rect, trans) { var p1 = geometry.ccp(geometry.rectGetMinX(rect), geometry.rectGetMinY(rect)); var p2 = geometry.ccp(geometry.rectGetMaxX(rect), geometry.rectGetMinY(rect)); @@ -331,169 +393,112 @@ var geometry = { }, /** - * @returns {Float} - */ - affineTransformDeterminant: function(trans) { - var det = 1, - t = util.copy(trans); - - var k, i, j, q, tkk; - for (k = 0; k < 3; k++) { - tkk = t[k][k]; - - if (tkk == 0) { - i = k; - while (t[i][k] == 0) { - if (i++ > 3) { - return 0; - } - } - - // Swap t[i] and t[k] - t[i] = t[i] + t[k]; t[k] = t[i] - t[k]; t[i] = t[i] - t[k]; - - tkk = t[k][k]; - - det *= -1; - } - - for (i = k+1; i < 3; i++) { - q = t[i][k] / tkk; - for (j = k+1; j < 3; j++) { - t[i][j] -= t[k][j] * q - } - } - - det *= tkk; - } - - return det; - }, - - /** - * @returns {Float[]} + * Inverts a transform matrix + * + * @param {geometry.TransformMatrix} trans TransformMatrix to invert + * @returns {geometry.TransformMatrix} New transform matrix */ - affineTransformInvert: function(trans) { - var newTrans = module.exports.affineTransformIdentity(); - - var t = util.copy(trans); + affineTransformInvert: function (trans) { + var determinant = 1 / (trans.a * trans.d - trans.b * trans.c); - var k, i, j, q, tkk; - for (k = 0; k < 3; k++) { - tkk = t[k][k]; - - if (tkk == 0) { - i = k; - do { - if (i++ > 3) { - throw "Matrix not regular size"; - } - } while (t[i][k] == 0); - - // Swap t[i] and t[k] - t[i] = t[i] + t[k]; - t[k] = t[i] - t[k]; - t[i] = t[i] - t[k]; - newTrans[i] = newTrans[i] + newTrans[k]; - newTrans[k] = newTrans[i] - newTrans[k]; - newTrans[i] = newTrans[i] - newTrans[k]; - - tkk = t[k][k]; - } - - for (i = 0; i < 3; i++) { - if (i == k) { - continue - } - - q = t[i][k] / tkk; - t[i][k] = 0; - - for (j = k+1; j < 3; j++) { - t[i][j] -= t[k][j] * q; - } - for (j = 0; j < 3; j++) { - newTrans[i][j] -= newTrans[k][j] * q; - } - } - - for (j = k+1; j < 3; j++) { - t[k][j] /= tkk; - } - for (j = 0; j < 3; j++) { - newTrans[k][j] /= tkk; - } - - } - - return newTrans; - + return new geometry.TransformMatrix( + determinant * trans.d, + -determinant * trans.b, + -determinant * trans.c, + determinant * trans.a, + determinant * (trans.c * trans.ty - trans.d * trans.tx), + determinant * (trans.b * trans.tx - trans.a * trans.ty) + ); }, /** - * Multiply 2 transform (3x3) matrices together - * @returns {Float[]} New transform matrix + * Multiply 2 transform matrices together + * @param {geometry.TransformMatrix} lhs Left matrix + * @param {geometry.TransformMatrix} rhs Right matrix + * @returns {geometry.TransformMatrix} New transform matrix */ - affineTransformConcat: function(trans1, trans2) { - var newTrans = module.exports.affineTransformIdentity(); - - var x, y, i; - for (x = 0; x < 3; x++) { - for (y = 0; y < 3; y++) { - newTrans[y][x] = 0; - for (i = 0; i < 3; i++) { - newTrans[y][x] += trans1[y][i] * trans2[i][x]; - } - } - } - - return newTrans; + affineTransformConcat: function (lhs, rhs) { + return new geometry.TransformMatrix( + lhs.a * rhs.a + lhs.b * rhs.c, + lhs.a * rhs.b + lhs.b * rhs.d, + lhs.c * rhs.a + lhs.d * rhs.c, + lhs.c * rhs.b + lhs.d * rhs.d, + lhs.tx * rhs.a + lhs.ty * rhs.c + rhs.tx, + lhs.tx * rhs.b + lhs.ty * rhs.d + rhs.ty + ); }, /** * @returns {Float} */ - degreesToRadians: function(angle) { + degreesToRadians: function (angle) { return angle / 180.0 * Math.PI; }, /** * @returns {Float} */ - radiansToDegrees: function(angle) { + radiansToDegrees: function (angle) { return angle * (180.0 / Math.PI); }, /** - * @returns {Float[]} + * Translate (move) a transform matrix + * + * @param {geometry.TransformMatrix} trans TransformMatrix to translate + * @param {Float} tx Amount to translate along X axis + * @param {Float} ty Amount to translate along Y axis + * @returns {geometry.TransformMatrix} A new TransformMatrix */ - affineTransformTranslate: function(trans, x, y) { - // tx = 6, ty = 7 - + affineTransformTranslate: function (trans, tx, ty) { var newTrans = util.copy(trans); - newTrans[2][0] += x; - newTrans[2][1] += y; - + newTrans.tx = trans.tx + trans.a * tx + trans.c * ty; + newTrans.ty = trans.ty + trans.b * tx + trans.d * ty; return newTrans; }, - affineTransformRotate: function(trans, angle) { - // TODO - return trans; + /** + * Rotate a transform matrix + * + * @param {geometry.TransformMatrix} trans TransformMatrix to rotate + * @param {Float} angle Angle in radians + * @returns {geometry.TransformMatrix} A new TransformMatrix + */ + affineTransformRotate: function (trans, angle) { + var sin = Math.sin(angle), + cos = Math.cos(angle); + + return new geometry.TransformMatrix( + trans.a * cos + trans.c * sin, + trans.b * cos + trans.d * sin, + trans.c * cos - trans.a * sin, + trans.d * cos - trans.b * sin, + trans.tx, + trans.ty + ); }, - affineTransformScale: function(trans, scale) { - // TODO - return trans; + /** + * Scale a transform matrix + * + * @param {geometry.TransformMatrix} trans TransformMatrix to scale + * @param {Float} sx X scale factor + * @param {Float} [sy=sx] Y scale factor + * @returns {geometry.TransformMatrix} A new TransformMatrix + */ + affineTransformScale: function (trans, sx, sy) { + if (sy === undefined) { + sy = sx; + } + + return new geometry.TransformMatrix(trans.a * sx, trans.b * sx, trans.c * sy, trans.d * sy, trans.tx, trans.ty); }, /** - * @returns {Float[]} 3x3 identity matrix + * @returns {geometry.TransformMatrix} identity matrix */ - affineTransformIdentity: function() { - return [[1, 0, 0], - [0, 1, 0], - [0, 0, 1]]; + affineTransformIdentity: function () { + return new geometry.TransformMatrix(1, 0, 0, 1, 0, 0); } }; From 41af169b45823856c14ed476bcfdeb3c0e8e2cae Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 30 Jan 2011 18:49:08 +1300 Subject: [PATCH 023/176] Added partial redraw support to BatchNode to improve performace of large tile maps --- src/libs/cocos2d/Director.js | 23 ++++++- src/libs/cocos2d/config.js | 4 +- src/libs/cocos2d/nodes/BatchNode.js | 77 +++++++++++++++++++--- src/libs/cocos2d/nodes/Node.js | 86 +++++++++++++++++++------ src/libs/cocos2d/nodes/RenderTexture.js | 14 ++-- 5 files changed, 167 insertions(+), 37 deletions(-) diff --git a/src/libs/cocos2d/Director.js b/src/libs/cocos2d/Director.js index eda64f7..c36c016 100644 --- a/src/libs/cocos2d/Director.js +++ b/src/libs/cocos2d/Director.js @@ -1,4 +1,4 @@ -/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ +/*globals module exports resource require BObject BArray FLIP_Y_AXIS SHOW_REDRAW_REGIONS*/ /*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; @@ -248,7 +248,26 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ this.setNextScene(); } - this._runningScene.visit(context); + var rect = new geo.Rect(0, 0, this.winSize.width, this.winSize.height); + + if (rect) { + context.beginPath(); + context.rect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + context.clip(); + context.closePath(); + } + + this._runningScene.visit(context, rect); + + if (SHOW_REDRAW_REGIONS) { + if (rect) { + context.beginPath(); + context.rect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + context.fillStyle = "rgba(255, 0, 0, 0.5)"; + //context.fill(); + context.closePath(); + } + } if (this.get('displayFPS')) { this.showFPS(); diff --git a/src/libs/cocos2d/config.js b/src/libs/cocos2d/config.js index d25172e..126b038 100644 --- a/src/libs/cocos2d/config.js +++ b/src/libs/cocos2d/config.js @@ -3,5 +3,7 @@ "FLIP_Y_AXIS": false, // No implemented yet - "ENABLE_WEB_GL": false + "ENABLE_WEB_GL": false, + + "SHOW_REDRAW_REGIONS": false } diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index 9639967..9836c18 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -1,4 +1,4 @@ -/*globals module exports resource require BObject BArray*/ +/*globals module exports resource require BObject BArray SHOW_REDRAW_REGIONS*/ /*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; @@ -14,6 +14,7 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ contentRect: null, renderTexture: null, dirty: true, + dirtyRegion: null, dynamicResize: false, /** @private @@ -61,13 +62,13 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ // Watch for changes in child evt.addListener(child, 'istransformdirty_changed', util.callback(this, function () { - this.set('dirty', true); + this.addDirtyRegion(child.get('boundingBox')); })); evt.addListener(child, 'visible_changed', util.callback(this, function () { - this.set('dirty', true); + this.addDirtyRegion(child.get('boundingBox')); })); - this.set('dirty', true); + this.addDirtyRegion(child.get('boundingBox')); }, removeChild: function (opts) { @@ -78,6 +79,18 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ this.set('dirty', true); }, + addDirtyRegion: function (rect) { + var region = this.get('dirtyRegion'); + if (!region) { + region = util.copy(rect); + } else { + region = geo.rectUnion(region, rect); + } + + this.set('dirtyRegion', region); + this.set('dirty', true); + }, + _resizeCanvas: function (oldSize) { var size = this.get('contentSize'); @@ -103,27 +116,75 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ this.transform(context); + var rect = this.get('dirtyRegion'); // Only redraw if something changed if (this.dirty) { - this.renderTexture.clear(); + + if (rect) { + // Clip region to visible area + var s = require('../Director').Director.get('sharedDirector').get('winSize'), + p = this.get('position'); + var r = new geo.Rect( + 0, 0, + s.width, s.height + ); + r = geo.rectApplyAffineTransform(r, this.worldToNodeTransform()); + rect = geo.rectIntersection(r, rect); + + this.renderTexture.clear(rect); + + this.renderTexture.context.save(); + this.renderTexture.context.beginPath(); + this.renderTexture.context.rect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + this.renderTexture.context.clip(); + this.renderTexture.context.closePath(); + } else { + this.renderTexture.clear(); + } + for (var i = 0, childLen = this.children.length; i < childLen; i++) { var c = this.children[i]; if (c == this.renderTexture) { continue; } - c.visit(this.renderTexture.context); + + // Draw children inside rect + if (!rect || geo.rectOverlapsRect(c.get('boundingBox'), rect)) { + c.visit(this.renderTexture.context, rect); + } } + + if (SHOW_REDRAW_REGIONS) { + if (rect) { + this.renderTexture.context.beginPath(); + this.renderTexture.context.rect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + this.renderTexture.context.fillStyle = "rgba(0, 0, 255, 0.5)"; + this.renderTexture.context.fill(); + this.renderTexture.context.closePath(); + } + } + + if (rect) { + this.renderTexture.context.restore(); + } + this.set('dirty', false); + this.set('dirtyRegion', null); } this.renderTexture.visit(context); - this.draw(context); - context.restore(); }, draw: function (ctx) { + }, + + onEnter: function () { + evt.addListener(this.get('parent'), 'istransformdirty_changed', util.callback(this, function () { + var box = this.get('visibleRect'); + this.addDirtyRegion(box); + })); } }); diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index cc4d0de..ec1ace7 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -6,7 +6,7 @@ var util = require('util'), evt = require('event'), Scheduler = require('../Scheduler').Scheduler, ActionManager = require('../ActionManager').ActionManager, - geom = require('geometry'), ccp = geom.ccp; + geo = require('geometry'), ccp = geo.ccp; var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ isCocosNode: true, @@ -193,7 +193,15 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ } }, - draw: function (context) { + /** + * Draws the node. Override to do custom drawing. If it's less efficient to + * draw only the area inside the rect then don't both. The result will be + * clipped to that area anyway. + * + * @param {CanvasRenderingContext2D|WebGLRenderingContext} context Canvas rendering context + * @param {geometry.Rect} rect Rectangular region that needs redrawing. Limit drawing to this area only if it's more efficient to do so. + */ + draw: function (context, rect) { // All draw code goes here }, @@ -276,7 +284,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ ActionManager.get('sharedManager').removeAllActionsFromTarget(this); }, - visit: function (context) { + visit: function (context, rect) { if (!this.visible) { return; } @@ -285,19 +293,25 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ this.transform(context); + // Adjust redraw region by nodes position + if (rect) { + var pos = this.get('position'); + rect = new geo.Rect(rect.origin.x - pos.x, rect.origin.y - pos.y, rect.size.width, rect.size.height); + } + // Draw background nodes util.each(this.children, function (child, i) { if (child.zOrder < 0) { - child.visit(context); + child.visit(context, rect); } }); - this.draw(context); + this.draw(context, rect); // Draw foreground nodes util.each(this.children, function (child, i) { if (child.zOrder >= 0) { - child.visit(context); + child.visit(context, rect); } }); @@ -316,7 +330,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ } // Rotate - context.rotate(geom.degreesToRadians(this.get('rotation'))); + context.rotate(geo.degreesToRadians(this.get('rotation'))); // Scale context.scale(this.scaleX, this.scaleY); @@ -332,25 +346,25 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ nodeToParentTransform: function () { if (this.isTransformDirty) { - this.transformMatrix = geom.affineTransformIdentity(); + this.transformMatrix = geo.affineTransformIdentity(); - if (!this.isRelativeAnchorPoint && !geom.pointEqualToPoint(this.anchorPointInPixels, ccp(0, 0))) { - this.transformMatrix = geom.affineTransformTranslate(this.transformMatrix, this.anchorPointInPixels.x, this.anchorPointInPixels.y); + if (!this.isRelativeAnchorPoint && !geo.pointEqualToPoint(this.anchorPointInPixels, ccp(0, 0))) { + this.transformMatrix = geo.affineTransformTranslate(this.transformMatrix, this.anchorPointInPixels.x, this.anchorPointInPixels.y); } - if (!geom.pointEqualToPoint(this.position, ccp(0, 0))) { - this.transformMatrix = geom.affineTransformTranslate(this.transformMatrix, this.position.x, this.position.y); + if (!geo.pointEqualToPoint(this.position, ccp(0, 0))) { + this.transformMatrix = geo.affineTransformTranslate(this.transformMatrix, this.position.x, this.position.y); } if (this.rotation !== 0) { - this.transformMatrix = geom.affineTransformRotate(this.transformMatrix, -geom.degreesToRadians(this.rotation)); + this.transformMatrix = geo.affineTransformRotate(this.transformMatrix, -geo.degreesToRadians(this.rotation)); } if (!(this.scaleX == 1 && this.scaleY == 1)) { - this.transformMatrix = geom.affineTransformScale(this.transformMatrix, this.scaleX, this.scaleY); + this.transformMatrix = geo.affineTransformScale(this.transformMatrix, this.scaleX, this.scaleY); } - if (!geom.pointEqualToPoint(this.anchorPointInPixels, ccp(0, 0))) { - this.transformMatrix = geom.affineTransformTranslate(this.transformMatrix, -this.anchorPointInPixels.x, -this.anchorPointInPixels.y); + if (!geo.pointEqualToPoint(this.anchorPointInPixels, ccp(0, 0))) { + this.transformMatrix = geo.affineTransformTranslate(this.transformMatrix, -this.anchorPointInPixels.x, -this.anchorPointInPixels.y); } this.set('isTransformDirty', false); @@ -369,18 +383,18 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ var p; for (p = this.get('parent'); p; p = p.get('parent')) { - t = geom.affineTransformConcat(t, p.nodeToParentTransform()); + t = geo.affineTransformConcat(t, p.nodeToParentTransform()); } return t; }, worldToNodeTransform: function () { - return geom.affineTransformInvert(this.nodeToWorldTransform()); + return geo.affineTransformInvert(this.nodeToWorldTransform()); }, convertToNodeSpace: function (worldPoint) { - return geom.pointApplyAffineTransform(worldPoint, this.worldToNodeTransform()); + return geo.pointApplyAffineTransform(worldPoint, this.worldToNodeTransform()); }, /** @@ -413,8 +427,38 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ */ get_boundingBox: function () { var cs = this.get('contentSize'); - var rect = geom.rectMake(0, 0, cs.width, cs.height); - return geom.rectApplyAffineTransform(rect, this.nodeToParentTransform()); + var rect = geo.rectMake(0, 0, cs.width, cs.height); + rect = geo.rectApplyAffineTransform(rect, this.nodeToParentTransform()); + return rect; + }, + + /** + * @getter worldBoundingBox + * @type geometry.Rect + */ + get_worldBoundingBox: function () { + var cs = this.get('contentSize'); + + var rect = geo.rectMake(0, 0, cs.width, cs.height); + rect = geo.rectApplyAffineTransform(rect, this.nodeToWorldTransform()); + return rect; + }, + + /** + * The area of the node currently visible on screen. Returns an rect even + * if visible is false. + * + * @getter visibleRect + * @type geometry.Rect + */ + get_visibleRect: function () { + var s = require('../Director').Director.get('sharedDirector').get('winSize'); + var rect = new geo.Rect( + 0, 0, + s.width, s.height + ); + + return geo.rectApplyAffineTransform(rect, this.worldToNodeTransform()); }, /** diff --git a/src/libs/cocos2d/nodes/RenderTexture.js b/src/libs/cocos2d/nodes/RenderTexture.js index ea199a1..c162d88 100644 --- a/src/libs/cocos2d/nodes/RenderTexture.js +++ b/src/libs/cocos2d/nodes/RenderTexture.js @@ -69,11 +69,15 @@ var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ /** * Clear the canvas */ - clear: function () { - this.canvas.width = this.canvas.width; - if (FLIP_Y_AXIS) { - this.context.scale(1, -1); - this.context.translate(0, -this.canvas.height); + clear: function (rect) { + if (rect) { + this.context.clearRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + } else { + this.canvas.width = this.canvas.width; + if (FLIP_Y_AXIS) { + this.context.scale(1, -1); + this.context.translate(0, -this.canvas.height); + } } } }); From 81c427c8b935d61fb964f97011c56ab39e3ec686 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 30 Jan 2011 23:09:01 +1300 Subject: [PATCH 024/176] Doc update --- src/libs/cocos2d/nodes/Node.js | 61 ++++++++++++++++++++++++++++++++-- src/libs/geometry.js | 12 +++++++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index ec1ace7..8a5969e 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -10,16 +10,71 @@ var util = require('util'), var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ isCocosNode: true, + + /** + * Is the node visible + * @type boolean + */ visible: true, + + /** + * Position relative to parent node + * @type geometry.Point + */ position: null, + + /** + * Parent node + * @type cocos.nodes.Node + */ parent: null, + + /** + * Unique tag to identify the node + * @type * + */ tag: null, + + /** + * Size of the node + * @type geometry.Size + */ contentSize: null, + + /** + * Nodes Z index. i.e. draw order + * @type Integer + */ zOrder: 0, + + /** + * Anchor point for scaling and rotation. 0x0 is top left and 1x1 is bottom right + * @type geometry.Point + */ anchorPoint: null, + + /** + * Anchor point for scaling and rotation in pixels from top left + * @type geometry.Point + */ anchorPointInPixels: null, + + /** + * Rotation angle in degrees + * @type Float + */ rotation: 0, + + /** + * X scale factor + * @type Float + */ scaleX: 1, + + /** + * Y scale factor + * @type Float + */ scaleY: 1, isRunning: false, isRelativeAnchorPoint: true, @@ -31,15 +86,15 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ /** * The child Nodes - * @type {cocos.nodes.Node[]} + * @type cocos.nodes.Node[] */ children: null, /** - * The base class all visual elements extend from * @memberOf cocos.nodes - * @constructs + * @class The base class all visual elements extend from * @extends BObject + * @constructs */ init: function () { Node.superclass.init.call(this); diff --git a/src/libs/geometry.js b/src/libs/geometry.js index b02bf63..2142b24 100644 --- a/src/libs/geometry.js +++ b/src/libs/geometry.js @@ -75,7 +75,15 @@ var geometry = { }, /** + * @class * Transform matrix + * + * @param {Float} a + * @param {Float} b + * @param {Float} c + * @param {Float} d + * @param {Float} tx + * @param {Float} ty */ TransformMatrix: function (a, b, c, d, tx, ty) { this.a = a; @@ -282,6 +290,10 @@ var geometry = { /** * Returns the overlapping portion of 2 rectangles + * + * @param {geometry.Rect} lhsRect First rectangle + * @param {geometry.Rect} rhsRect Second rectangle + * @returns {geometry.Rect} The overlapping portion of the 2 rectangles */ rectIntersection: function (lhsRect, rhsRect) { From ecf47cf080918f7eba79118cc1f3e9b48a082fef Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 30 Jan 2011 23:10:05 +1300 Subject: [PATCH 025/176] Removed redundent code --- src/libs/cocos2d/nodes/Node.js | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index 8a5969e..06cecb3 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -452,30 +452,6 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ return geo.pointApplyAffineTransform(worldPoint, this.worldToNodeTransform()); }, - /** - * @getter acceptsFirstResponder - * @type Boolean - */ - get_acceptsFirstResponder: function () { - return false; - }, - - /** - * @getter becomeFirstResponder - * @type Boolean - */ - get_becomeFirstResponder: function () { - return true; - }, - - /** - * @getter resignFirstResponder - * @type Boolean - */ - get_resignFirstResponder: function () { - return true; - }, - /** * @getter boundingBox * @type geometry.Rect From efbf0efdd6ea2eb0d59c45b1f09c85e00a1676a1 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 30 Jan 2011 23:40:09 +1300 Subject: [PATCH 026/176] Documentation update --- src/global.js | 28 ++++++++++++----------- src/libs/cocos2d/actions/Action.js | 15 +++++------- src/libs/cocos2d/actions/ActionInstant.js | 15 +++++------- src/libs/cocos2d/nodes/BatchNode.js | 7 +++--- src/libs/cocos2d/nodes/Node.js | 2 +- 5 files changed, 31 insertions(+), 36 deletions(-) diff --git a/src/global.js b/src/global.js index 629e7c2..5b10879 100644 --- a/src/global.js +++ b/src/global.js @@ -1,5 +1,9 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + var util = require('util'), - event = require('event'); + evt = require('event'); /** @@ -147,7 +151,7 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ * @private */ triggerChanged: function(key, oldVal) { - event.trigger(this, key.toLowerCase() + '_changed', oldVal); + evt.trigger(this, key.toLowerCase() + '_changed', oldVal); }, /** @@ -168,7 +172,7 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ var oldVal = this.get(key); // When bound property changes, trigger a 'changed' event on this one too - getBindings(this)[key] = event.addListener(target, targetKey.toLowerCase() + '_changed', function (oldVal) { + getBindings(this)[key] = evt.addListener(target, targetKey.toLowerCase() + '_changed', function (oldVal) { self.triggerChanged(key, oldVal); }); @@ -187,7 +191,7 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ } delete getBindings(this)[key]; - event.removeListener(binding); + evt.removeListener(binding); // Grab current value from bound property var val = this.get(key); delete getAccessors(this)[key]; @@ -211,6 +215,7 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ /** * Unique ID for this object * @getter id + * @type Integer */ get_id: function() { if (!this._id) { @@ -244,12 +249,9 @@ BObject.extend = function() { // Copy 'class' methods for (x in this) { - // Don't copy built-ins - if (!this.hasOwnProperty(x)) { - continue; + if (this.hasOwnProperty(x)) { + newObj[x] = this[x]; } - - newObj[x] = this[x]; } @@ -257,7 +259,7 @@ BObject.extend = function() { newObj.prototype = util.beget(this.prototype); args.push(newObj.prototype); for (i = 0; iImportant: You should never call cocos.Action#stop manually. - * Instead, use cocos.Node#stopAction(action) + * Important: You should never call cocos.actions.Action#stop manually. + * Instead, use cocos.nodes.Node#stopAction(action) */ stop: function () { this.target = null; @@ -73,19 +73,16 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ } }); -/** - * - * Repeats an action forever. To repeat the an action for a limited number of - * times use the cocos.Repeat action. - */ var RepeatForever = Action.extend(/** @lends cocos.actions.RepeatForever# */{ other: null, /** * @memberOf cocos.actions + * @class Repeats an action forever. To repeat the an action for a limited + * number of times use the cocos.Repeat action. * @extends cocos.actions.Action - * @constructs * @param {cocos.actions.Action} action An action to repeat forever + * @constructs */ init: function (action) { RepeatForever.superclass.init(this, action); diff --git a/src/libs/cocos2d/actions/ActionInstant.js b/src/libs/cocos2d/actions/ActionInstant.js index da53538..a4d10d0 100644 --- a/src/libs/cocos2d/actions/ActionInstant.js +++ b/src/libs/cocos2d/actions/ActionInstant.js @@ -8,11 +8,10 @@ var util = require('util'), var ActionInstant = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionInstant */{ /** - * Base class for actions that triggers instantly. They have no duration. - * * @memberOf cocos.actions - * @constructs + * @class Base class for actions that triggers instantly. They have no duration. * @extends cocos.actions.FiniteTimeAction + * @constructs */ init: function (opts) { ActionInstant.superclass.init.call(this, opts); @@ -37,11 +36,10 @@ var FlipX = ActionInstant.extend(/** @lends cocos.actions.FlipX# */{ flipX: false, /** - * Flips a sprite horizontally - * * @memberOf cocos.actions - * @constructs + * @class Flips a sprite horizontally * @extends cocos.actions.ActionInstant + * @constructs * * @opt {Boolean} flipX Should the sprite be flipped */ @@ -67,11 +65,10 @@ var FlipY = ActionInstant.extend(/** @lends cocos.actions.FlipY# */{ flipY: false, /** - * Flips a sprite vertically - * * @memberOf cocos.actions - * @constructs + * @class Flips a sprite vertically * @extends cocos.actions.ActionInstant + * @constructs * * @opt {Boolean} flipY Should the sprite be flipped */ diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index 9836c18..fd12265 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -188,15 +188,14 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ } }); -var SpriteBatchNode = BatchNode.extend({ +var SpriteBatchNode = BatchNode.extend(/** @lends cocos.nodes.SpriteBatchNode# */{ textureAtlas: null, /** - * A BatchNode that accepts only Sprite using the same texture - * * @memberOf cocos.nodes - * @constructs + * @class A BatchNode that accepts only Sprite using the same texture * @extends cocos.nodes.BatchNode + * @constructs * * @opt {String} file (Optional) Path to image to use as sprite atlas * @opt {Texture2D} texture (Optional) Texture to use as sprite atlas diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index 06cecb3..07947f6 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -250,7 +250,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ /** * Draws the node. Override to do custom drawing. If it's less efficient to - * draw only the area inside the rect then don't both. The result will be + * draw only the area inside the rect then don't bother. The result will be * clipped to that area anyway. * * @param {CanvasRenderingContext2D|WebGLRenderingContext} context Canvas rendering context From b493e331491a664d79cf547f3b7981f3e0001049 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 31 Jan 2011 09:50:26 +1300 Subject: [PATCH 027/176] Fixed error finding config.js in generated projects --- scripts/make.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/make.py b/scripts/make.py index 0cd5097..3ba0c41 100755 --- a/scripts/make.py +++ b/scripts/make.py @@ -110,7 +110,7 @@ def app_configs(self): """ Returns an array of paths pointing to all the config.js files for the app """ - configs = [u'src/libs/cocos2d/config.js'] + configs = [u'src/libs/cocos2d/config.js', u'cocos2d/src/libs/cocos2d/config.js'] for source, dest in self.config['paths'].items(): c = os.path.join(source, 'config.js') if os.path.exists(c): @@ -126,8 +126,9 @@ def app_config_dict(self): """ vals = {} for config in self.app_configs(): - data = self.read_json_file(config) - vals.update(data) + if os.path.exists(config): + data = self.read_json_file(config) + vals.update(data) return vals From 487740b02b498a5c20ed88ce0ef03e6c1ae47a28 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 5 Feb 2011 16:01:13 +1300 Subject: [PATCH 028/176] Fixed compatibility with Windows --- scripts/make.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/make.py b/scripts/make.py index 3ba0c41..b88f805 100755 --- a/scripts/make.py +++ b/scripts/make.py @@ -82,7 +82,7 @@ def make_path(self, source_path, dest_path=None): code = '' files = self.scan_for_files(source_path) for src_file in files: - if src_file in self.app_configs(): + if src_file.replace(os.sep, '/') in self.app_configs(): # Skip config files because they're JSON not JavaScript continue @@ -100,6 +100,7 @@ def make_path(self, source_path, dest_path=None): return code def dst_for_src(self, path): + path = path.replace(os.sep, '/') for source, dest in self.config['paths'].items(): if path.startswith(source): return re.sub('\/+', '/', re.sub(r'^' + source.replace('/', '\\/'), dest, path)) From 0243733f064dfb4c7802d4b76fc4ff5a1cafc355 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 5 Feb 2011 18:08:23 +1300 Subject: [PATCH 029/176] Added partialDraw flag to BatchNodes. Improves performace of small tilemaps --- src/libs/cocos2d/nodes/BatchNode.js | 38 +++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index fd12265..d802b3d 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -11,9 +11,15 @@ var util = require('util'), Node = require('./Node').Node; var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ + partialDraw: false, contentRect: null, renderTexture: null, dirty: true, + + /** + * Region to redraw + * @type geometry.Rect + */ dirtyRegion: null, dynamicResize: false, @@ -33,11 +39,13 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ * @extends cocos.nodes.Node * * @opt {geometry.Size} size The size of the in-memory canvas used for drawing to + * @opt {Boolean} [partialDraw=false] Draw only the area visible on screen. Small maps may be slower in some browsers if this is true. */ init: function (opts) { BatchNode.superclass.init.call(this, opts); var size = opts.size || geo.sizeMake(1, 1); + this.set('partialDraw', opts.partialDraw); evt.addListener(this, 'contentsize_changed', util.callback(this, this._resizeCanvas)); @@ -121,15 +129,17 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ if (this.dirty) { if (rect) { - // Clip region to visible area - var s = require('../Director').Director.get('sharedDirector').get('winSize'), - p = this.get('position'); - var r = new geo.Rect( - 0, 0, - s.width, s.height - ); - r = geo.rectApplyAffineTransform(r, this.worldToNodeTransform()); - rect = geo.rectIntersection(r, rect); + if (this.get('partialDraw')) { + // Clip region to visible area + var s = require('../Director').Director.get('sharedDirector').get('winSize'), + p = this.get('position'); + var r = new geo.Rect( + 0, 0, + s.width, s.height + ); + r = geo.rectApplyAffineTransform(r, this.worldToNodeTransform()); + rect = geo.rectIntersection(r, rect); + } this.renderTexture.clear(rect); @@ -181,10 +191,12 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ }, onEnter: function () { - evt.addListener(this.get('parent'), 'istransformdirty_changed', util.callback(this, function () { - var box = this.get('visibleRect'); - this.addDirtyRegion(box); - })); + if (this.get('partialDraw')) { + evt.addListener(this.get('parent'), 'istransformdirty_changed', util.callback(this, function () { + var box = this.get('visibleRect'); + this.addDirtyRegion(box); + })); + } } }); From 1d180f5c8af32ea013444d54588058921d824758 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 5 Feb 2011 18:14:53 +1300 Subject: [PATCH 030/176] Throw exception when encounting unsupported TMX Map compression --- src/libs/cocos2d/TMXXMLParser.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libs/cocos2d/TMXXMLParser.js b/src/libs/cocos2d/TMXXMLParser.js index fa3b9fa..3ce795d 100644 --- a/src/libs/cocos2d/TMXXMLParser.js +++ b/src/libs/cocos2d/TMXXMLParser.js @@ -199,10 +199,20 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ } // Unpack the tilemap data - if (data.getAttribute('compression') == 'gzip') { + var compression = data.getAttribute('compression'); + switch (compression) { + case 'gzip': layer.set('tiles', gzip.unzipBase64AsArray(nodeValue, 4)); - } else { + break; + + // Uncompressed + case null: + case '': layer.set('tiles', base64.decodeAsArray(nodeValue, 4)); + break; + + default: + throw "Unsupported TMX Tile Map compression: " + compression; } this.layers.push(layer); From c022b654feefc58eb9ff27ec672ddd8d2b5c2517 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 5 Feb 2011 19:03:55 +1300 Subject: [PATCH 031/176] Updated license --- LICENSE | 41 +++++++++++++++++------------------------ README.md | 2 +- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/LICENSE b/LICENSE index 6cd58c9..c2591cb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,27 +1,20 @@ -cocos2d-javascript is is released under the "Simplified BSD License": +Copyright (c) 2010-2011 Ryan Williams -Copyright 2010 Ryan Williams. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -Redistribution and use in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. - 1. Redistributions of source code must retain the above copyright notice, this list of - conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, this list - of conditions and the following disclaimer in the documentation and/or other materials - provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY RYAN WILLIAMS ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those of the -authors and should not be interpreted as representing official policies, either expressed -or implied, of Ryan Williams. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 054b294..dda7840 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Check the LICENSE file licensing details. +Cocos2d-javascript is released under the MIT license. This is in the early stages of development and could break backwards compatibility at any time. From a23e00126b3ce4c64443cab261aa9a16a4791464 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Feb 2011 10:55:29 +1300 Subject: [PATCH 032/176] Added command framework for running under node.js --- .gitmodules | 3 +++ bin/cocos-npm.js | 2 ++ bin/cocos.js | 18 ++++++++++++++++++ bin/cocos.sh | 30 ++++++++++++++++++++++++++++++ lib/cocos/commands/help.js | 22 ++++++++++++++++++++++ lib/cocos/commands/ide.js | 11 +++++++++++ lib/cocos/commands/index.js | 7 +++++++ lib/cocos/commands/make.js | 11 +++++++++++ lib/cocos/commands/new.js | 11 +++++++++++ lib/cocos/commands/server.js | 11 +++++++++++ lib/cocos/index.js | 22 ++++++++++++++++++++++ package.json | 21 +++++++++++++++++++++ support/node-builds | 1 + 13 files changed, 170 insertions(+) create mode 100644 bin/cocos-npm.js create mode 100644 bin/cocos.js create mode 100755 bin/cocos.sh create mode 100644 lib/cocos/commands/help.js create mode 100644 lib/cocos/commands/ide.js create mode 100644 lib/cocos/commands/index.js create mode 100644 lib/cocos/commands/make.js create mode 100644 lib/cocos/commands/new.js create mode 100644 lib/cocos/commands/server.js create mode 100644 lib/cocos/index.js create mode 100644 package.json create mode 160000 support/node-builds diff --git a/.gitmodules b/.gitmodules index e910533..e584d91 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "tests/commonjs"] path = tests/commonjs url = https://github.com/commonjs/commonjs.git +[submodule "support/node-builds"] + path = support/node-builds + url = https://github.com/ajaxorg/node-builds.git diff --git a/bin/cocos-npm.js b/bin/cocos-npm.js new file mode 100644 index 0000000..6e1a2e7 --- /dev/null +++ b/bin/cocos-npm.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +require("./cocos.js"); diff --git a/bin/cocos.js b/bin/cocos.js new file mode 100644 index 0000000..540d114 --- /dev/null +++ b/bin/cocos.js @@ -0,0 +1,18 @@ +#!/usr/bin/env node + +var sys = require('sys'), + fs = require('fs'), + path = require('path'); + +require.paths.unshift(path.join(__dirname, '../lib')); + +if (parseInt(process.version.split('.')[1], 10) < 2) { + sys.puts('ERROR: cocos2d requires node version 0.2.x or higher, but you are using ' + process.version); + process.exit(1); +} + +var version = JSON.parse(fs.readFileSync(__dirname + '/../package.json')).version; + +sys.puts('cocos2d-javascript version ' + version); + +require('cocos').main(); diff --git a/bin/cocos.sh b/bin/cocos.sh new file mode 100755 index 0000000..67f45aa --- /dev/null +++ b/bin/cocos.sh @@ -0,0 +1,30 @@ +#!/bin/sh -e +# lets check if we have the submodules initialized + +case `uname -a` in +Linux*x86_64*) echo "Linux 64 bit" + support/node-builds/lin64/node bin/cocos.js "$@" + ;; + +Linux*i686*) echo "Linux 32 bit" + support/node-builds/lin32/node bin/cocos.js "$@" + ;; + +Darwin*) echo "OSX" + support/node-builds/osx64/node bin/cocos.js "$@" + ;; + +CYGWIN*) echo "Cygwin" + support/node-builds/win32/node.exe bin/cocos.js "$@" + ;; + +MING*) echo "MingW" + support/node-builds/win32/node.exe bin/cocos.js "$@" + ;; + +*) echo "Unknown OS" + ;; +esac + + + diff --git a/lib/cocos/commands/help.js b/lib/cocos/commands/help.js new file mode 100644 index 0000000..e17b5e4 --- /dev/null +++ b/lib/cocos/commands/help.js @@ -0,0 +1,22 @@ +/*globals require module exports process console*/ +/*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ +"use strict"; + +var sys = require('sys'); + +exports.description = 'Show list of available commands'; +exports.run = function (opts) { + var commands = require('./'); + sys.puts('Available commands are:'); + for (var key in commands) { + if (commands.hasOwnProperty(key)) { + var command = 'cocos ' + key; + + var spaces = ''; + for (var i = 0; i < 8 - key.length; i++) { + spaces += ' '; + } + sys.puts(' ' + command + spaces + ' : ' + commands[key].description); + } + } +}; diff --git a/lib/cocos/commands/ide.js b/lib/cocos/commands/ide.js new file mode 100644 index 0000000..6df7d43 --- /dev/null +++ b/lib/cocos/commands/ide.js @@ -0,0 +1,11 @@ +/*globals require module exports process console*/ +/*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ +"use strict"; + +var sys = require('sys'); + +exports.description = 'Run the Cloud9 IDE'; +exports.run = function (opts) { + sys.puts('Not implemented yet'); + process.exit(1); +}; diff --git a/lib/cocos/commands/index.js b/lib/cocos/commands/index.js new file mode 100644 index 0000000..e575a33 --- /dev/null +++ b/lib/cocos/commands/index.js @@ -0,0 +1,7 @@ +module.exports = { + 'help': require('./help'), + 'new': require('./new'), + 'server': require('./server'), + 'make': require('./make'), + 'ide': require('./ide') +}; diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js new file mode 100644 index 0000000..51a363e --- /dev/null +++ b/lib/cocos/commands/make.js @@ -0,0 +1,11 @@ +/*globals require module exports process console*/ +/*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ +"use strict"; + +var sys = require('sys'); + +exports.description = 'Compile the cocos2d project into a single javascript file'; +exports.run = function (opts) { + sys.puts('Not implemented yet'); + process.exit(1); +}; diff --git a/lib/cocos/commands/new.js b/lib/cocos/commands/new.js new file mode 100644 index 0000000..4141143 --- /dev/null +++ b/lib/cocos/commands/new.js @@ -0,0 +1,11 @@ +/*globals require module exports process console*/ +/*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ +"use strict"; + +var sys = require('sys'); + +exports.description = 'Create a new cocos2d project'; +exports.run = function (opts) { + sys.puts('Not implemented yet'); + process.exit(1); +}; diff --git a/lib/cocos/commands/server.js b/lib/cocos/commands/server.js new file mode 100644 index 0000000..9dc00b5 --- /dev/null +++ b/lib/cocos/commands/server.js @@ -0,0 +1,11 @@ +/*globals require module exports process console*/ +/*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ +"use strict"; + +var sys = require('sys'); + +exports.description = 'Run the cocos2d development web server'; +exports.run = function (opts) { + sys.puts('Not implemented yet'); + process.exit(1); +}; diff --git a/lib/cocos/index.js b/lib/cocos/index.js new file mode 100644 index 0000000..ce7fe26 --- /dev/null +++ b/lib/cocos/index.js @@ -0,0 +1,22 @@ +/*globals require module exports process console*/ +/*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ +"use strict"; + +var sys = require('sys'), + commands = require('./commands'); + +exports.main = function (opts) { + var cmd = process.argv[2]; + + if (!cmd) { + cmd = 'help'; + } + + if (!commands[cmd]) { + sys.puts('Unknown command: ' + cmd); + sys.puts('Run "cocos help" for a list of available commands'); + process.exit(1); + } + + commands[cmd].run(process.argv.slice(3)); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..3d7f0d1 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "cocos2d", + "description": "Port of cocos2d-iphone for the Web", + "version": "0.0.1", + "homepage": "http://cocos2d-javascript.org/", + "engines": { + "node": ">= 0.2.0" + }, + "author": "Ryan Williams ", + "main": "bin/cocos", + "repository": "https://github.com/ryanwilliams/cocos2d-javascript.git", + "bin": { + "cocos": "./bin/cocos-npm.js" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/ryanwilliams/cocos2d-javascript/blob/master/LICENSE" + } + ] +} diff --git a/support/node-builds b/support/node-builds new file mode 160000 index 0000000..0fcee7d --- /dev/null +++ b/support/node-builds @@ -0,0 +1 @@ +Subproject commit 0fcee7d5f7fec359ad3c747cf86ba707548a039a From 4fc4c59f56e432bc008d9bb2aa93d160fd255bf3 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Feb 2011 15:24:06 +1300 Subject: [PATCH 033/176] Ported 'make' command from Python to Node.js --- lib/cocos/commands/make.js | 292 ++++- lib/cocos/commands/module_js | 145 +++ lib/cocos/mimetypes.js | 69 ++ lib/cocos/template.js | 21 + lib/mime.types | 1070 +++++++++++++++++++ make.js => make.json | 8 + src/libs/cocos2d/{config.js => config.json} | 0 tests/cocos2d/{config.js => config.json} | 0 8 files changed, 1601 insertions(+), 4 deletions(-) create mode 100644 lib/cocos/commands/module_js create mode 100644 lib/cocos/mimetypes.js create mode 100644 lib/cocos/template.js create mode 100644 lib/mime.types rename make.js => make.json (66%) rename src/libs/cocos2d/{config.js => config.json} (100%) rename tests/cocos2d/{config.js => config.json} (100%) diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index 51a363e..292ae94 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -1,11 +1,295 @@ -/*globals require module exports process console*/ +/*globals require module exports process console __dirname*/ /*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ "use strict"; -var sys = require('sys'); +var sys = require('sys'), + fs = require('fs'), + path = require('path'), + Template = require('../template').Template, + mimetypes = require('../mimetypes'); + +mimetypes.addType('application/xml', '.tmx'); +mimetypes.addType('application/xml', '.tsx'); +mimetypes.addType('application/xml', '.plist'); + +var RESOURCE_TEMPLATE = new Template('__resources__["$resource"] = {meta: {mimetype: "$mimetype"}, data: $data};'); +var TEXT_MIMETYPES = 'application/xml text/plain text/json application/json text/html'.split(' '); +var CODE_MIMETYPES = 'text/javascript application/javascript application/x-javascript'.split(' '); + +/** + * Merge an number of objects together and return the result as a new object + */ +function merge() { + var o = {}; + for (var i = 0, len = arguments.length; i < len; i++) { + var obj = arguments[i]; + for (var x in obj) { + if (obj.hasOwnProperty(x)) { + o[x] = obj[x]; + } + } + } + + return o; +} + +/** + * @memberOf cocos.commands.make + * @class Compile a cocos2d project into a single javascript file + * @param {String} [configFile=make.json] The project's config filename + */ +function Compiler(configFile) { + this.readConfig = function (configFile) { + sys.puts('Loading config: ' + configFile); + + var config = this.readJSONFile(configFile); + this.output = config.output; + this.mainModule = config.mainModule || config.main_module; + this.extensions = config.extensions; + + return config; + }; + + this.config = this.readConfig(configFile || 'make.json'); +} +(function () /** @lends cocos.commands.make.Compiler# */{ + + /** + * Read a JSON file and clean up any comments, unquoted keys and trailing + * commas before returning the object + * + * @param {String} filename Name of the JSON file to read + * @returns {Object} The JSON object + */ + this.readJSONFile = function (filename) { + var j = fs.readFileSync(filename, 'UTF-8'); + + // Strip comments + j = j.replace(/\/\/.*/g, ''); + j = j.replace(/\/\*(.|[\n\r])*?\*\//mg, ''); + + // Fix unquoted keys + j = j.replace(/\{\s*(\w)/g, '{"$1'); + j = j.replace(/,(\s*)(\w)/g, ',$1"$2'); + j = j.replace(/(\w):/g, '$1":'); + + // Fix trailing comma + j = j.replace(/,\s+\}/mg, '}'); + + return JSON.parse(j); + }; + + this.__defineGetter__('appConfigFiles', function () { + if (this.appConfigFiles_) { + return this.appConfigFiles_; + } + + var configs = ['src/libs/cocos2d/config.json', 'cocos2d/src/libs/cocos2d/config.json']; + + for (var source in this.config.paths) { + if (this.config.paths.hasOwnProperty(source)) { + var dest = this.config.paths[source]; + + var c = path.join(source, 'config.json'); + if (path.existsSync(c)) { + configs.push(c); + } + } + } + + this.appConfigFiles_ = configs; + + return this.appConfigFiles_; + }); + + /** + * Reads all the app's config.js files and returns an of object their + * values + */ + this.__defineGetter__('appConfig', function () { + if (this.appConfig_) { + return this.appConfig_; + } + + var vals = {}, data; + for (var i = 0, len = this.appConfigFiles.length; i < len; i++) { + var config = this.appConfigFiles[i]; + if (path.existsSync(config)) { + data = this.readJSONFile(config); + vals = merge(vals, data); + } + } + + this.appConfig_ = vals; + return this.appConfig_; + }); + + /** + * Compile everything into a single script + */ + this.make = function () { + var code = this.header || ''; + code += '\n(function() {\n'; + code += 'var __main_module_name__ = ' + JSON.stringify(this.mainModule) + ';\n'; + code += 'var __resources__ = [];\n'; + code += 'function __imageResource(data) { var img = new Image(); img.src = data; return img; };\n'; + + // Add config options + for (var key in this.appConfig) { + if (this.appConfig.hasOwnProperty(key)) { + code += 'var ' + key.toUpperCase() + ' = ' + JSON.stringify(this.appConfig[key]) + ';\n'; + } + } + + // Add all the code/images/etc + for (var source in this.config.paths) { + if (this.config.paths.hasOwnProperty(source)) { + var dest = this.config.paths[source]; + code += this.makePath(source, dest); + } + } + + var module_js = path.join(__dirname, 'module_js'); + code += fs.readFileSync(module_js, 'UTF-8'); + + code += '\n})();\n'; + + code += this.footer || ''; + + return code; + }; + + /** + * Compile everything at a path and return the code + * + * @param {String} source Path to compile + * @param {String} [dest=source] Output path + * @returns {String} Compiled javascript source code + */ + this.makePath = function (source, dest) { + sys.puts('Building Path: ' + source + ' => ' + dest); + + var code = ''; + var files = this.scanForFiles(source); + for (var i = 0, len = files.length; i < len; i++) { + var sourceFile = files[i]; + if (!!~this.appConfigFiles.indexOf(sourceFile)) { + continue; + } + + var destFile = this.destForSource(sourceFile), + mimetype = mimetypes.guessType(sourceFile); + + + sys.puts('Building File: ' + sourceFile + ' => ' + destFile); + code += '\n'; + code += RESOURCE_TEMPLATE.substitute({ + 'mimetype': mimetype, + 'resource': destFile, + 'data': this.makeResource(sourceFile) + }); + } + + + return code; + }; + + this.destForSource = function (path) { + for (var source in this.config.paths) { + if (this.config.paths.hasOwnProperty(source)) { + var dest = this.config.paths[source]; + + // Source starts with config path + if (path.indexOf(source) === 0) { + return path.replace(new RegExp(source), dest).replace(/\/+/, '/'); + } + } + } + + return source; + }; + + this.makeResource = function (filename) { + var mimetype = mimetypes.guessType(filename); + + var isCode = (!!~CODE_MIMETYPES.indexOf(mimetype)), + isText = (!!~TEXT_MIMETYPES.indexOf(mimetype)), + isImage = (mimetype.split('/')[0] == 'image'); + + var data; + if (isCode) { + data = fs.readFileSync(filename, 'UTF-8'); + data = "function(exports, require, module, __filename, __dirname) {\n" + data + "\n}"; + } else if (isText) { + data = JSON.stringify(fs.readFileSync(filename, 'UTF-8')); + } else if (isImage) { + data = fs.readFileSync(filename).toString('base64'); + data = '__imageResource("data:' + mimetype + ';base64,' + data + '")'; + } else /* isBinary */ { + data = JSON.stringify(fs.readFileSync(filename).toString('base64')); + } + + return data; + }; + + this.guessMimeType = function (filename) { + return 'image/png'; + }; + + /** + * Scan for files to build and return them as an array + * + * @param {String} source Path to scan + * @returns {String[]} List of filenames + */ + this.scanForFiles = function (source) { + + var foundFiles = []; + + // If given a file rather than a directory they just return that + if (fs.statSync(source).isFile()) { + return [source]; + } + + // Find all files in directory + var files = fs.readdirSync(source); + for (var i = 0, len = files.length; i < len; i++) { + var file = files[i]; + // Skip hidden files + if (file[0] == '.') { + continue; + } + + var fullPath = path.join(source, file); + + if (fs.statSync(fullPath).isFile()) { + // If extension isn't in our list then skip file + if (this.extensions && this.extensions.length && !~this.extensions.indexOf(path.extname(file).slice(1))) { + continue; + } + + foundFiles.push(fullPath); + } else { + // Directory + foundFiles = foundFiles.concat(this.scanForFiles(fullPath)); + } + + } + + return foundFiles; + }; +}).call(Compiler.prototype); + +exports.Compiler = Compiler; exports.description = 'Compile the cocos2d project into a single javascript file'; exports.run = function (opts) { - sys.puts('Not implemented yet'); - process.exit(1); + var compiler = new Compiler('make.json'); + var code = compiler.make(); + + var output = compiler.output; + if (output) { + sys.puts("Wrigint output to: " + output); + fs.writeFileSync(output, code, 'UTF-8'); + } }; diff --git a/lib/cocos/commands/module_js b/lib/cocos/commands/module_js new file mode 100644 index 0000000..0fc3b57 --- /dev/null +++ b/lib/cocos/commands/module_js @@ -0,0 +1,145 @@ +/*globals module exports resource require window Module __main_module_name__ __resources__*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + +function resource(path) { + return __resources__[path].data; +} + +(function () { + var process = {}; + var modulePaths = ['/libs', '/']; + + var path; // Will be loaded further down + + function resolveModulePath(request, parent) { + // If not a relative path then search the modulePaths for it + var start = request.substring(0, 2); + if (start !== "./" && start !== "..") { + return modulePaths; + } + + var parentIsIndex = path.basename(parent.filename).match(/^index\.js$/), + parentPath = parentIsIndex ? parent.id : path.dirname(parent.id); + + // Relative path so searching inside parent's directory + return [path.dirname(parent.filename)]; + } + + function findModulePath(id, dirs) { + if (id.charAt(0) === '/') { + dirs = ['']; + } + for (var i = 0; i < dirs.length; i++) { + var dir = dirs[i]; + var p = path.join(dir, id); + + // Check for index first + if (path.exists(path.join(p, 'index.js'))) { + return path.join(p, 'index.js'); + } else if (path.exists(p + '.js')) { + return p + '.js'; + } + } + + return false; + } + + function loadModule(request, parent) { + parent = parent || process.mainModule; + + var paths = resolveModulePath(request, parent), + filename = findModulePath(request, paths); + + if (filename === false) { + throw "Unable to find module: " + request; + } + + + if (parent) { + var cachedModule = parent.moduleCache[filename]; + if (cachedModule) { + return cachedModule; + } + } + + //console.log('Loading module: ', filename); + + var module = new Module(filename, parent); + + // Assign main module to process + if (request == __main_module_name__ && !process.mainModule) { + process.mainModule = module; + } + + // Run all the code in the module + module._initialize(filename); + + return module; + } + + function Module(id, parent) { + this.id = id; + this.parent = parent; + this.children = []; + this.exports = {}; + + if (parent) { + this.moduleCache = parent.moduleCache; + parent.children.push(this); + } else { + this.moduleCache = {}; + } + this.moduleCache[this.id] = this; + + this.filename = null; + this.dirname = null; + } + + Module.prototype._initialize = function (filename) { + var module = this; + function require(request) { + return loadModule(request, module).exports; + } + + this.filename = filename; + + // Work around incase this IS the path module + if (path) { + this.dirname = path.dirname(filename); + } else { + this.dirname = ''; + } + + require.paths = modulePaths; + require.main = process.mainModule; + + __resources__[this.filename].data.apply(this.exports, [this.exports, require, this, this.filename, this.dirname]); + + return this; + }; + + // Manually load the path module because we need it to load other modules + path = (new Module('path'))._initialize('/path.js').exports; + + var util = loadModule('util').exports; + util.ready(function () { + // Populate globals + var globals = loadModule('global').exports; + for (var x in globals) { + if (globals.hasOwnProperty(x)) { + window[x] = globals[x]; + } + } + + process.mainModule = loadModule(__main_module_name__); + + // Add a global require. Useful in the debug console. + window.require = function require(request, parent) { + return loadModule(request, parent).exports; + }; + window.require.main = process.mainModule; + window.require.paths = modulePaths; + + }); +})(); diff --git a/lib/cocos/mimetypes.js b/lib/cocos/mimetypes.js new file mode 100644 index 0000000..c1ac913 --- /dev/null +++ b/lib/cocos/mimetypes.js @@ -0,0 +1,69 @@ +var fs = require('fs'), + path = require('path'); + +var typesMap = {}, + typesMapInv = {}; + +exports.knowntypes = ['/etc/mime.types', + '/etc/httpd/mime.types', + '/etc/httpd/conf/mime.types', + '/etc/apache/mime.types', + '/etc/apache2/mime.types', + '/usr/local/etc/httpd/conf/mime.types', + '/usr/local/lib/netscape/mime.types', + '/usr/local/etc/httpd/conf/mime.types', + '/usr/local/etc/mime.types', + path.join(__dirname, 'mime.types')]; + +exports.guessType = function(url) { + return typesMap[path.extname(url)]; +}; + + +function addType(type, ext) { + typesMap[ext] = type.trim(); + if (!typesMapInv[type]) { + typesMapInv[type] = []; + } + if (!~typesMapInv[type].indexOf(ext)) { + typesMapInv[type].push(ext); + } +} + +exports.addType = addType; + +/** + * Read a single mime.types-format file + */ +function read(file) { + var data = fs.readFileSync(file, 'ascii'); + // Strip comments + data = data.replace(/#.*/g, ''); + var lines = data.split('\n'); + for (var i = 0, len = lines.length; i < len; i++) { + var line = lines[i].trim(); + if (!line) { + continue; + } + + var words = line.split(/\s/), + type = words.shift(), + suffixes = words; + + for (var j = 0, jen = suffixes.length; j < jen; j++) { + var suff = suffixes[j].trim(); + if (!suff) { + continue; + } + + addType(type, '.' + suff); + } + } +} + +for (var i = 0, len = exports.knowntypes.length; i < len; i++) { + var typeFile = exports.knowntypes[i]; + if (path.existsSync(typeFile)) { + read(typeFile); + } +} diff --git a/lib/cocos/template.js b/lib/cocos/template.js new file mode 100644 index 0000000..bfea049 --- /dev/null +++ b/lib/cocos/template.js @@ -0,0 +1,21 @@ +function Template(str) { + this.string = str; +} +(function() { + this.substitute = function (subs) { + var newStr = this.string; + for (var key in subs) { + if (subs.hasOwnProperty(key)) { + newStr = newStr.replace('$' + key, subs[key]); + } + } + + return newStr; + }; + + this.toString = function() { + return this.string; + }; +}).call(Template.prototype); + +exports.Template = Template; diff --git a/lib/mime.types b/lib/mime.types new file mode 100644 index 0000000..022fded --- /dev/null +++ b/lib/mime.types @@ -0,0 +1,1070 @@ +# This is a comment. I love comments. + +# This file controls what Internet media types are sent to the client for +# given file extension(s). Sending the correct media type to the client +# is important so they know how to handle the content of the file. +# Extra types can either be added here or by using an AddType directive +# in your config files. For more information about Internet media types, +# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type +# registry is at . + +# MIME type Extensions +application/activemessage +application/andrew-inset ez +application/applefile +application/atom+xml atom +application/atomcat+xml atomcat +application/atomicmail +application/atomsvc+xml atomsvc +application/auth-policy+xml +application/batch-smtp +application/beep+xml +application/cals-1840 +application/ccxml+xml ccxml +application/cellml+xml +application/cnrp+xml +application/commonground +application/conference-info+xml +application/cpl+xml +application/csta+xml +application/cstadata+xml +application/cybercash +application/davmount+xml davmount +application/dca-rft +application/dec-dx +application/dialog-info+xml +application/dicom +application/dns +application/dvcs +application/ecmascript ecma +application/edi-consent +application/edi-x12 +application/edifact +application/epp+xml +application/eshop +application/fastinfoset +application/fastsoap +application/fits +application/font-tdpfr pfr +application/h224 +application/http +application/hyperstudio stk +application/iges +application/im-iscomposing+xml +application/index +application/index.cmd +application/index.obj +application/index.response +application/index.vnd +application/iotp +application/ipp +application/isup +application/javascript js +application/json json +application/kpml-request+xml +application/kpml-response+xml +application/lost+xml lostxml +application/mac-binhex40 hqx +application/mac-compactpro cpt +application/macwriteii +application/marc mrc +application/mathematica ma nb mb +application/mathml+xml mathml +application/mbms-associated-procedure-description+xml +application/mbms-deregister+xml +application/mbms-envelope+xml +application/mbms-msk+xml +application/mbms-msk-response+xml +application/mbms-protection-description+xml +application/mbms-reception-report+xml +application/mbms-register+xml +application/mbms-register-response+xml +application/mbms-user-service-description+xml +application/mbox mbox +application/media_control+xml +application/mediaservercontrol+xml mscml +application/mikey +application/moss-keys +application/moss-signature +application/mosskey-data +application/mosskey-request +application/mp4 mp4s +application/mpeg4-generic +application/mpeg4-iod +application/mpeg4-iod-xmt +application/msword doc dot +application/mxf mxf +application/nasdata +application/news-transmission +application/nss +application/ocsp-request +application/ocsp-response +application/octet-stream bin dms lha lzh class so iso dmg dist distz pkg bpk dump elc scpt dmgpart +application/oda oda +application/oebps-package+xml +application/ogg ogx +application/parityfec +application/patch-ops-error+xml xer +application/pdf pdf +application/pgp-encrypted pgp +application/pgp-keys +application/pgp-signature asc sig +application/pics-rules prf +application/pidf+xml +application/pidf-diff+xml +application/pkcs10 p10 +application/pkcs7-mime p7m p7c +application/pkcs7-signature p7s +application/pkix-cert cer +application/pkix-crl crl +application/pkix-pkipath pkipath +application/pkixcmp pki +application/pls+xml pls +application/poc-settings+xml +application/postscript ai eps ps +application/prs.alvestrand.titrax-sheet +application/prs.cww cww +application/prs.nprend +application/prs.plucker +application/qsig +application/rdf+xml rdf +application/reginfo+xml rif +application/relax-ng-compact-syntax rnc +application/remote-printing +application/resource-lists+xml rl +application/resource-lists-diff+xml rld +application/riscos +application/rlmi+xml +application/rls-services+xml rs +application/rsd+xml rsd +application/rss+xml rss +application/rtf rtf +application/rtx +application/samlassertion+xml +application/samlmetadata+xml +application/sbml+xml sbml +application/scvp-cv-request scq +application/scvp-cv-response scs +application/scvp-vp-request spq +application/scvp-vp-response spp +application/sdp sdp +application/set-payment +application/set-payment-initiation setpay +application/set-registration +application/set-registration-initiation setreg +application/sgml +application/sgml-open-catalog +application/shf+xml shf +application/sieve +application/simple-filter+xml +application/simple-message-summary +application/simplesymbolcontainer +application/slate +application/smil +application/smil+xml smi smil +application/soap+fastinfoset +application/soap+xml +application/sparql-query rq +application/sparql-results+xml srx +application/spirits-event+xml +application/srgs gram +application/srgs+xml grxml +application/ssml+xml ssml +application/timestamp-query +application/timestamp-reply +application/tve-trigger +application/ulpfec +application/vemmi +application/vividence.scriptfile +application/vnd.3gpp.bsf+xml +application/vnd.3gpp.pic-bw-large plb +application/vnd.3gpp.pic-bw-small psb +application/vnd.3gpp.pic-bw-var pvb +application/vnd.3gpp.sms +application/vnd.3gpp2.bcmcsinfo+xml +application/vnd.3gpp2.sms +application/vnd.3gpp2.tcap tcap +application/vnd.3m.post-it-notes pwn +application/vnd.accpac.simply.aso aso +application/vnd.accpac.simply.imp imp +application/vnd.acucobol acu +application/vnd.acucorp atc acutc +application/vnd.adobe.xdp+xml xdp +application/vnd.adobe.xfdf xfdf +application/vnd.aether.imp +application/vnd.americandynamics.acc acc +application/vnd.amiga.ami ami +application/vnd.anser-web-certificate-issue-initiation cii +application/vnd.anser-web-funds-transfer-initiation fti +application/vnd.antix.game-component atx +application/vnd.apple.installer+xml mpkg +application/vnd.arastra.swi swi +application/vnd.audiograph aep +application/vnd.autopackage +application/vnd.avistar+xml +application/vnd.blueice.multipass mpm +application/vnd.bmi bmi +application/vnd.businessobjects rep +application/vnd.cab-jscript +application/vnd.canon-cpdl +application/vnd.canon-lips +application/vnd.cendio.thinlinc.clientconf +application/vnd.chemdraw+xml cdxml +application/vnd.chipnuts.karaoke-mmd mmd +application/vnd.cinderella cdy +application/vnd.cirpack.isdn-ext +application/vnd.claymore cla +application/vnd.clonk.c4group c4g c4d c4f c4p c4u +application/vnd.commerce-battelle +application/vnd.commonspace csp cst +application/vnd.contact.cmsg cdbcmsg +application/vnd.cosmocaller cmc +application/vnd.crick.clicker clkx +application/vnd.crick.clicker.keyboard clkk +application/vnd.crick.clicker.palette clkp +application/vnd.crick.clicker.template clkt +application/vnd.crick.clicker.wordbank clkw +application/vnd.criticaltools.wbs+xml wbs +application/vnd.ctc-posml pml +application/vnd.ctct.ws+xml +application/vnd.cups-pdf +application/vnd.cups-postscript +application/vnd.cups-ppd ppd +application/vnd.cups-raster +application/vnd.cups-raw +application/vnd.curl curl +application/vnd.cybank +application/vnd.data-vision.rdz rdz +application/vnd.denovo.fcselayout-link fe_launch +application/vnd.dna dna +application/vnd.dolby.mlp mlp +application/vnd.dpgraph dpg +application/vnd.dreamfactory dfac +application/vnd.dvb.esgcontainer +application/vnd.dvb.ipdcesgaccess +application/vnd.dvb.iptv.alfec-base +application/vnd.dvb.iptv.alfec-enhancement +application/vnd.dxr +application/vnd.ecdis-update +application/vnd.ecowin.chart mag +application/vnd.ecowin.filerequest +application/vnd.ecowin.fileupdate +application/vnd.ecowin.series +application/vnd.ecowin.seriesrequest +application/vnd.ecowin.seriesupdate +application/vnd.enliven nml +application/vnd.epson.esf esf +application/vnd.epson.msf msf +application/vnd.epson.quickanime qam +application/vnd.epson.salt slt +application/vnd.epson.ssf ssf +application/vnd.ericsson.quickcall +application/vnd.eszigno3+xml es3 et3 +application/vnd.eudora.data +application/vnd.ezpix-album ez2 +application/vnd.ezpix-package ez3 +application/vnd.fdf fdf +application/vnd.ffsns +application/vnd.fints +application/vnd.flographit gph +application/vnd.fluxtime.clip ftc +application/vnd.font-fontforge-sfd +application/vnd.framemaker fm frame maker +application/vnd.frogans.fnc fnc +application/vnd.frogans.ltf ltf +application/vnd.fsc.weblaunch fsc +application/vnd.fujitsu.oasys oas +application/vnd.fujitsu.oasys2 oa2 +application/vnd.fujitsu.oasys3 oa3 +application/vnd.fujitsu.oasysgp fg5 +application/vnd.fujitsu.oasysprs bh2 +application/vnd.fujixerox.art-ex +application/vnd.fujixerox.art4 +application/vnd.fujixerox.hbpl +application/vnd.fujixerox.ddd ddd +application/vnd.fujixerox.docuworks xdw +application/vnd.fujixerox.docuworks.binder xbd +application/vnd.fut-misnet +application/vnd.fuzzysheet fzs +application/vnd.genomatix.tuxedo txd +application/vnd.gmx gmx +application/vnd.google-earth.kml+xml kml +application/vnd.google-earth.kmz kmz +application/vnd.grafeq gqf gqs +application/vnd.gridmp +application/vnd.groove-account gac +application/vnd.groove-help ghf +application/vnd.groove-identity-message gim +application/vnd.groove-injector grv +application/vnd.groove-tool-message gtm +application/vnd.groove-tool-template tpl +application/vnd.groove-vcard vcg +application/vnd.handheld-entertainment+xml zmm +application/vnd.hbci hbci +application/vnd.hcl-bireports +application/vnd.hhe.lesson-player les +application/vnd.hp-hpgl hpgl +application/vnd.hp-hpid hpid +application/vnd.hp-hps hps +application/vnd.hp-jlyt jlt +application/vnd.hp-pcl pcl +application/vnd.hp-pclxl pclxl +application/vnd.httphone +application/vnd.hydrostatix.sof-data sfd-hdstx +application/vnd.hzn-3d-crossword x3d +application/vnd.ibm.afplinedata +application/vnd.ibm.electronic-media +application/vnd.ibm.minipay mpy +application/vnd.ibm.modcap afp listafp list3820 +application/vnd.ibm.rights-management irm +application/vnd.ibm.secure-container sc +application/vnd.iccprofile icc icm +application/vnd.igloader igl +application/vnd.immervision-ivp ivp +application/vnd.immervision-ivu ivu +application/vnd.informedcontrol.rms+xml +application/vnd.intercon.formnet xpw xpx +application/vnd.intertrust.digibox +application/vnd.intertrust.nncp +application/vnd.intu.qbo qbo +application/vnd.intu.qfx qfx +application/vnd.iptc.g2.conceptitem+xml +application/vnd.iptc.g2.knowledgeitem+xml +application/vnd.iptc.g2.newsitem+xml +application/vnd.iptc.g2.packageitem+xml +application/vnd.ipunplugged.rcprofile rcprofile +application/vnd.irepository.package+xml irp +application/vnd.is-xpr xpr +application/vnd.jam jam +application/vnd.japannet-directory-service +application/vnd.japannet-jpnstore-wakeup +application/vnd.japannet-payment-wakeup +application/vnd.japannet-registration +application/vnd.japannet-registration-wakeup +application/vnd.japannet-setstore-wakeup +application/vnd.japannet-verification +application/vnd.japannet-verification-wakeup +application/vnd.jcp.javame.midlet-rms rms +application/vnd.jisp jisp +application/vnd.joost.joda-archive joda +application/vnd.kahootz ktz ktr +application/vnd.kde.karbon karbon +application/vnd.kde.kchart chrt +application/vnd.kde.kformula kfo +application/vnd.kde.kivio flw +application/vnd.kde.kontour kon +application/vnd.kde.kpresenter kpr kpt +application/vnd.kde.kspread ksp +application/vnd.kde.kword kwd kwt +application/vnd.kenameaapp htke +application/vnd.kidspiration kia +application/vnd.kinar kne knp +application/vnd.koan skp skd skt skm +application/vnd.kodak-descriptor sse +application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop lbd +application/vnd.llamagraphics.life-balance.exchange+xml lbe +application/vnd.lotus-1-2-3 123 +application/vnd.lotus-approach apr +application/vnd.lotus-freelance pre +application/vnd.lotus-notes nsf +application/vnd.lotus-organizer org +application/vnd.lotus-screencam scm +application/vnd.lotus-wordpro lwp +application/vnd.macports.portpkg portpkg +application/vnd.marlin.drm.actiontoken+xml +application/vnd.marlin.drm.conftoken+xml +application/vnd.marlin.drm.license+xml +application/vnd.marlin.drm.mdcf +application/vnd.mcd mcd +application/vnd.medcalcdata mc1 +application/vnd.mediastation.cdkey cdkey +application/vnd.meridian-slingshot +application/vnd.mfer mwf +application/vnd.mfmp mfm +application/vnd.micrografx.flo flo +application/vnd.micrografx.igx igx +application/vnd.mif mif +application/vnd.minisoft-hp3000-save +application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf daf +application/vnd.mobius.dis dis +application/vnd.mobius.mbk mbk +application/vnd.mobius.mqy mqy +application/vnd.mobius.msl msl +application/vnd.mobius.plc plc +application/vnd.mobius.txf txf +application/vnd.mophun.application mpn +application/vnd.mophun.certificate mpc +application/vnd.motorola.flexsuite +application/vnd.motorola.flexsuite.adsi +application/vnd.motorola.flexsuite.fis +application/vnd.motorola.flexsuite.gotap +application/vnd.motorola.flexsuite.kmr +application/vnd.motorola.flexsuite.ttc +application/vnd.motorola.flexsuite.wem +application/vnd.motorola.iprm +application/vnd.mozilla.xul+xml xul +application/vnd.ms-artgalry cil +application/vnd.ms-asf asf +application/vnd.ms-cab-compressed cab +application/vnd.ms-excel xls xlm xla xlc xlt xlw +application/vnd.ms-fontobject eot +application/vnd.ms-htmlhelp chm +application/vnd.ms-ims ims +application/vnd.ms-lrm lrm +application/vnd.ms-playready.initiator+xml +application/vnd.ms-powerpoint ppt pps pot +application/vnd.ms-project mpp mpt +application/vnd.ms-tnef +application/vnd.ms-wmdrm.lic-chlg-req +application/vnd.ms-wmdrm.lic-resp +application/vnd.ms-wmdrm.meter-chlg-req +application/vnd.ms-wmdrm.meter-resp +application/vnd.ms-works wps wks wcm wdb +application/vnd.ms-wpl wpl +application/vnd.ms-xpsdocument xps +application/vnd.mseq mseq +application/vnd.msign +application/vnd.multiad.creator +application/vnd.multiad.creator.cif +application/vnd.music-niff +application/vnd.musician mus +application/vnd.muvee.style msty +application/vnd.ncd.control +application/vnd.ncd.reference +application/vnd.nervana +application/vnd.netfpx +application/vnd.neurolanguage.nlu nlu +application/vnd.noblenet-directory nnd +application/vnd.noblenet-sealer nns +application/vnd.noblenet-web nnw +application/vnd.nokia.catalogs +application/vnd.nokia.conml+wbxml +application/vnd.nokia.conml+xml +application/vnd.nokia.isds-radio-presets +application/vnd.nokia.iptv.config+xml +application/vnd.nokia.landmark+wbxml +application/vnd.nokia.landmark+xml +application/vnd.nokia.landmarkcollection+xml +application/vnd.nokia.n-gage.ac+xml +application/vnd.nokia.n-gage.data ngdat +application/vnd.nokia.n-gage.symbian.install n-gage +application/vnd.nokia.ncd +application/vnd.nokia.pcd+wbxml +application/vnd.nokia.pcd+xml +application/vnd.nokia.radio-preset rpst +application/vnd.nokia.radio-presets rpss +application/vnd.novadigm.edm edm +application/vnd.novadigm.edx edx +application/vnd.novadigm.ext ext +application/vnd.oasis.opendocument.chart odc +application/vnd.oasis.opendocument.chart-template otc +application/vnd.oasis.opendocument.formula odf +application/vnd.oasis.opendocument.formula-template otf +application/vnd.oasis.opendocument.graphics odg +application/vnd.oasis.opendocument.graphics-template otg +application/vnd.oasis.opendocument.image odi +application/vnd.oasis.opendocument.image-template oti +application/vnd.oasis.opendocument.presentation odp +application/vnd.oasis.opendocument.presentation-template otp +application/vnd.oasis.opendocument.spreadsheet ods +application/vnd.oasis.opendocument.spreadsheet-template ots +application/vnd.oasis.opendocument.text odt +application/vnd.oasis.opendocument.text-master otm +application/vnd.oasis.opendocument.text-template ott +application/vnd.oasis.opendocument.text-web oth +application/vnd.obn +application/vnd.olpc-sugar xo +application/vnd.oma-scws-config +application/vnd.oma-scws-http-request +application/vnd.oma-scws-http-response +application/vnd.oma.bcast.associated-procedure-parameter+xml +application/vnd.oma.bcast.drm-trigger+xml +application/vnd.oma.bcast.imd+xml +application/vnd.oma.bcast.ltkm +application/vnd.oma.bcast.notification+xml +application/vnd.oma.bcast.provisioningtrigger +application/vnd.oma.bcast.sgboot +application/vnd.oma.bcast.sgdd+xml +application/vnd.oma.bcast.sgdu +application/vnd.oma.bcast.simple-symbol-container +application/vnd.oma.bcast.smartcard-trigger+xml +application/vnd.oma.bcast.sprov+xml +application/vnd.oma.bcast.stkm +application/vnd.oma.dcd +application/vnd.oma.dcdc +application/vnd.oma.dd2+xml dd2 +application/vnd.oma.drm.risd+xml +application/vnd.oma.group-usage-list+xml +application/vnd.oma.poc.detailed-progress-report+xml +application/vnd.oma.poc.final-report+xml +application/vnd.oma.poc.groups+xml +application/vnd.oma.poc.invocation-descriptor+xml +application/vnd.oma.poc.optimized-progress-report+xml +application/vnd.oma.xcap-directory+xml +application/vnd.omads-email+xml +application/vnd.omads-file+xml +application/vnd.omads-folder+xml +application/vnd.omaloc-supl-init +application/vnd.openofficeorg.extension oxt +application/vnd.osa.netdeploy +application/vnd.osgi.dp dp +application/vnd.otps.ct-kip+xml +application/vnd.palm prc pdb pqa oprc +application/vnd.paos.xml +application/vnd.pg.format str +application/vnd.pg.osasli ei6 +application/vnd.piaccess.application-licence +application/vnd.picsel efif +application/vnd.poc.group-advertisement+xml +application/vnd.pocketlearn plf +application/vnd.powerbuilder6 pbd +application/vnd.powerbuilder6-s +application/vnd.powerbuilder7 +application/vnd.powerbuilder7-s +application/vnd.powerbuilder75 +application/vnd.powerbuilder75-s +application/vnd.preminet +application/vnd.previewsystems.box box +application/vnd.proteus.magazine mgz +application/vnd.publishare-delta-tree qps +application/vnd.pvi.ptid1 ptid +application/vnd.pwg-multiplexed +application/vnd.pwg-xhtml-print+xml +application/vnd.qualcomm.brew-app-res +application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb +application/vnd.rapid +application/vnd.recordare.musicxml mxl +application/vnd.recordare.musicxml+xml +application/vnd.renlearn.rlprint +application/vnd.rn-realmedia rm +application/vnd.route66.link66+xml link66 +application/vnd.ruckus.download +application/vnd.s3sms +application/vnd.sbm.mid2 +application/vnd.scribus +application/vnd.sealed.3df +application/vnd.sealed.csf +application/vnd.sealed.doc +application/vnd.sealed.eml +application/vnd.sealed.mht +application/vnd.sealed.net +application/vnd.sealed.ppt +application/vnd.sealed.tiff +application/vnd.sealed.xls +application/vnd.sealedmedia.softseal.html +application/vnd.sealedmedia.softseal.pdf +application/vnd.seemail see +application/vnd.sema sema +application/vnd.semd semd +application/vnd.semf semf +application/vnd.shana.informed.formdata ifm +application/vnd.shana.informed.formtemplate itp +application/vnd.shana.informed.interchange iif +application/vnd.shana.informed.package ipk +application/vnd.simtech-mindmapper twd twds +application/vnd.smaf mmf +application/vnd.software602.filler.form+xml +application/vnd.software602.filler.form-xml-zip +application/vnd.solent.sdkm+xml sdkm sdkd +application/vnd.spotfire.dxp dxp +application/vnd.spotfire.sfs sfs +application/vnd.sss-cod +application/vnd.sss-dtf +application/vnd.sss-ntf +application/vnd.street-stream +application/vnd.sun.wadl+xml +application/vnd.sus-calendar sus susp +application/vnd.svd svd +application/vnd.swiftview-ics +application/vnd.syncml+xml xsm +application/vnd.syncml.dm+wbxml bdm +application/vnd.syncml.dm+xml xdm +application/vnd.syncml.ds.notification +application/vnd.tao.intent-module-archive tao +application/vnd.tmobile-livetv tmo +application/vnd.trid.tpt tpt +application/vnd.triscape.mxs mxs +application/vnd.trueapp tra +application/vnd.truedoc +application/vnd.ufdl ufd ufdl +application/vnd.uiq.theme utz +application/vnd.umajin umj +application/vnd.unity unityweb +application/vnd.uoml+xml uoml +application/vnd.uplanet.alert +application/vnd.uplanet.alert-wbxml +application/vnd.uplanet.bearer-choice +application/vnd.uplanet.bearer-choice-wbxml +application/vnd.uplanet.cacheop +application/vnd.uplanet.cacheop-wbxml +application/vnd.uplanet.channel +application/vnd.uplanet.channel-wbxml +application/vnd.uplanet.list +application/vnd.uplanet.list-wbxml +application/vnd.uplanet.listcmd +application/vnd.uplanet.listcmd-wbxml +application/vnd.uplanet.signal +application/vnd.vcx vcx +application/vnd.vd-study +application/vnd.vectorworks +application/vnd.vidsoft.vidconference +application/vnd.visio vsd vst vss vsw +application/vnd.visionary vis +application/vnd.vividence.scriptfile +application/vnd.vsf vsf +application/vnd.wap.sic +application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo wtb +application/vnd.wfa.wsc +application/vnd.wmc +application/vnd.wmf.bootstrap +application/vnd.wordperfect wpd +application/vnd.wqd wqd +application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf stf +application/vnd.wv.csp+wbxml +application/vnd.wv.csp+xml +application/vnd.wv.ssp+xml +application/vnd.xara xar +application/vnd.xfdl xfdl +application/vnd.xmi+xml +application/vnd.xmpie.cpkg +application/vnd.xmpie.dpkg +application/vnd.xmpie.plan +application/vnd.xmpie.ppkg +application/vnd.xmpie.xlim +application/vnd.yamaha.hv-dic hvd +application/vnd.yamaha.hv-script hvs +application/vnd.yamaha.hv-voice hvp +application/vnd.yamaha.smaf-audio saf +application/vnd.yamaha.smaf-phrase spf +application/vnd.yellowriver-custom-menu cmp +application/vnd.zzazz.deck+xml zaz +application/voicexml+xml vxml +application/watcherinfo+xml +application/whoispp-query +application/whoispp-response +application/winhlp hlp +application/wita +application/wordperfect5.1 +application/wsdl+xml wsdl +application/wspolicy+xml wspolicy +application/x-ace-compressed ace +application/x-bcpio bcpio +application/x-bittorrent torrent +application/x-bzip bz +application/x-bzip2 bz2 boz +application/x-cdlink vcd +application/x-chat chat +application/x-chess-pgn pgn +application/x-compress +application/x-cpio cpio +application/x-csh csh +application/x-director dcr dir dxr fgd +application/x-dvi dvi +application/x-futuresplash spl +application/x-gtar gtar +application/x-gzip +application/x-hdf hdf +application/x-java-jnlp-file jnlp +application/x-latex latex +application/x-ms-wmd wmd +application/x-ms-wmz wmz +application/x-msaccess mdb +application/x-msbinder obd +application/x-mscardfile crd +application/x-msclip clp +application/x-msdownload exe dll com bat msi +application/x-msmediaview mvb m13 m14 +application/x-msmetafile wmf +application/x-msmoney mny +application/x-mspublisher pub +application/x-msschedule scd +application/x-msterminal trm +application/x-mswrite wri +application/x-netcdf nc cdf +application/x-pkcs12 p12 pfx +application/x-pkcs7-certificates p7b spc +application/x-pkcs7-certreqresp p7r +application/x-rar-compressed rar +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-stuffit sit +application/x-stuffitx sitx +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-texinfo texinfo texi +application/x-ustar ustar +application/x-wais-source src +application/x-x509-ca-cert der crt +application/x400-bp +application/xcap-att+xml +application/xcap-caps+xml +application/xcap-el+xml +application/xcap-error+xml +application/xcap-ns+xml +application/xenc+xml xenc +application/xhtml+xml xhtml xht +application/xml xml xsl +application/xml-dtd dtd +application/xml-external-parsed-entity +application/xmpp+xml +application/xop+xml xop +application/xslt+xml xslt +application/xspf+xml xspf +application/xv+xml mxml xhvml xvml xvm +application/zip zip +audio/32kadpcm +audio/3gpp +audio/3gpp2 +audio/ac3 +audio/amr +audio/amr-wb +audio/amr-wb+ +audio/asc +audio/basic au snd +audio/bv16 +audio/bv32 +audio/clearmode +audio/cn +audio/dat12 +audio/dls +audio/dsr-es201108 +audio/dsr-es202050 +audio/dsr-es202211 +audio/dsr-es202212 +audio/dvi4 +audio/eac3 +audio/evrc +audio/evrc-qcp +audio/evrc0 +audio/evrc1 +audio/evrcb +audio/evrcb0 +audio/evrcb1 +audio/evrcwb +audio/evrcwb0 +audio/evrcwb1 +audio/g722 +audio/g7221 +audio/g723 +audio/g726-16 +audio/g726-24 +audio/g726-32 +audio/g726-40 +audio/g728 +audio/g729 +audio/g7291 +audio/g729d +audio/g729e +audio/gsm +audio/gsm-efr +audio/ilbc +audio/l16 +audio/l20 +audio/l24 +audio/l8 +audio/lpc +audio/midi mid midi kar rmi +audio/mobile-xmf +audio/mp4 mp4a +audio/mp4a-latm m4a m4p +audio/mpa +audio/mpa-robust +audio/mpeg mpga mp2 mp2a mp3 m2a m3a +audio/mpeg4-generic +audio/ogg oga ogg spx +audio/parityfec +audio/pcma +audio/pcmu +audio/prs.sid +audio/qcelp +audio/red +audio/rtp-enc-aescm128 +audio/rtp-midi +audio/rtx +audio/smv +audio/smv0 +audio/smv-qcp +audio/sp-midi +audio/t140c +audio/t38 +audio/telephone-event +audio/tone +audio/ulpfec +audio/vdvi +audio/vmr-wb +audio/vnd.3gpp.iufp +audio/vnd.4sb +audio/vnd.audiokoz +audio/vnd.celp +audio/vnd.cisco.nse +audio/vnd.cmles.radio-events +audio/vnd.cns.anp1 +audio/vnd.cns.inf1 +audio/vnd.digital-winds eol +audio/vnd.dlna.adts +audio/vnd.dolby.mlp +audio/vnd.dts dts +audio/vnd.dts.hd dtshd +audio/vnd.everad.plj +audio/vnd.hns.audio +audio/vnd.lucent.voice lvp +audio/vnd.ms-playready.media.pya pya +audio/vnd.nokia.mobile-xmf +audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 ecelp4800 +audio/vnd.nuera.ecelp7470 ecelp7470 +audio/vnd.nuera.ecelp9600 ecelp9600 +audio/vnd.octel.sbc +audio/vnd.qcelp +audio/vnd.rhetorex.32kadpcm +audio/vnd.sealedmedia.softseal.mpeg +audio/vnd.vmx.cvsd +audio/vorbis +audio/vorbis-config +audio/wav wav +audio/x-aiff aif aiff aifc +audio/x-mpegurl m3u +audio/x-ms-wax wax +audio/x-ms-wma wma +audio/x-pn-realaudio ram ra +audio/x-pn-realaudio-plugin rmp +audio/x-wav wav +chemical/x-cdx cdx +chemical/x-cif cif +chemical/x-cmdf cmdf +chemical/x-cml cml +chemical/x-csml csml +chemical/x-pdb pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +image/fits +image/g3fax g3 +image/gif gif +image/ief ief +image/jp2 jp2 +image/jpeg jpeg jpg jpe +image/jpm +image/jpx +image/naplps +image/pict pict pic pct +image/png png +image/prs.btif btif +image/prs.pti +image/svg+xml svg svgz +image/t38 +image/tiff tiff tif +image/tiff-fx +image/vnd.adobe.photoshop psd +image/vnd.cns.inf2 +image/vnd.djvu djvu djv +image/vnd.dwg dwg +image/vnd.dxf dxf +image/vnd.fastbidsheet fbs +image/vnd.fpx fpx +image/vnd.fst fst +image/vnd.fujixerox.edmics-mmr mmr +image/vnd.fujixerox.edmics-rlc rlc +image/vnd.globalgraphics.pgb +image/vnd.microsoft.icon +image/vnd.mix +image/vnd.ms-modi mdi +image/vnd.net-fpx npx +image/vnd.sealed.png +image/vnd.sealedmedia.softseal.gif +image/vnd.sealedmedia.softseal.jpg +image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff xif +image/x-cmu-raster ras +image/x-cmx cmx +image/x-icon ico +image/x-macpaint pntg pnt mac +image/x-pcx pcx +image/x-pict pic pct +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-quicktime qtif qti +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +message/cpim +message/delivery-status +message/disposition-notification +message/external-body +message/global +message/global-delivery-status +message/global-disposition-notification +message/global-headers +message/http +message/news +message/partial +message/rfc822 eml mime +message/s-http +message/sip +message/sipfrag +message/tracking-status +message/vnd.si.simp +model/iges igs iges +model/mesh msh mesh silo +model/vnd.dwf dwf +model/vnd.flatland.3dml +model/vnd.gdl gdl +model/vnd.gs.gdl +model/vnd.gtw gtw +model/vnd.moml+xml +model/vnd.mts mts +model/vnd.parasolid.transmit.binary +model/vnd.parasolid.transmit.text +model/vnd.vtu vtu +model/vrml wrl vrml +multipart/alternative +multipart/appledouble +multipart/byteranges +multipart/digest +multipart/encrypted +multipart/form-data +multipart/header-set +multipart/mixed +multipart/parallel +multipart/related +multipart/report +multipart/signed +multipart/voice-message +text/calendar ics ifb +text/css css +text/csv csv +text/directory +text/dns +text/enriched +text/html html htm +text/parityfec +text/plain txt text conf def list log in +text/prs.fallenstein.rst +text/prs.lines.tag dsc +text/red +text/rfc822-headers +text/richtext rtx +text/rtf +text/rtp-enc-aescm128 +text/rtx +text/sgml sgml sgm +text/t140 +text/tab-separated-values tsv +text/troff t tr roff man me ms +text/ulpfec +text/uri-list uri uris urls +text/vnd.abc +text/vnd.curl +text/vnd.dmclientscript +text/vnd.esmertec.theme-descriptor +text/vnd.fly fly +text/vnd.fmi.flexstor flx +text/vnd.graphviz gv +text/vnd.in3d.3dml 3dml +text/vnd.in3d.spot spot +text/vnd.iptc.newsml +text/vnd.iptc.nitf +text/vnd.latex-z +text/vnd.motorola.reflex +text/vnd.ms-mediapackage +text/vnd.net2phone.commcenter.command +text/vnd.si.uricatalogue +text/vnd.sun.j2me.app-descriptor jad +text/vnd.trolltech.linguist +text/vnd.wap.si +text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-asm s asm +text/x-c c cc cxx cpp h hh dic +text/x-fortran f for f77 f90 +text/x-pascal p pas +text/x-java-source java +text/x-setext etx +text/x-uuencode uu +text/x-vcalendar vcs +text/x-vcard vcf +text/xml +text/xml-external-parsed-entity +video/3gpp 3gp +video/3gpp-tt +video/3gpp2 3g2 +video/bmpeg +video/bt656 +video/celb +video/dv +video/h261 h261 +video/h263 h263 +video/h263-1998 +video/h263-2000 +video/h264 h264 +video/jpeg jpgv +video/jpeg2000 +video/jpm jpm jpgm +video/mj2 mj2 mjp2 +video/mp1s +video/mp2p +video/mp2t +video/mp4 mp4 mp4v mpg4 m4v +video/mp4v-es +video/mpeg mpeg mpg mpe m1v m2v +video/mpeg4-generic +video/mpv +video/nv +video/ogg ogv +video/parityfec +video/pointer +video/quicktime qt mov +video/raw +video/rtp-enc-aescm128 +video/rtx +video/smpte292m +video/ulpfec +video/vc1 +video/vnd.cctv +video/vnd.dlna.mpeg-tts +video/vnd.fvt fvt +video/vnd.hns.video +video/vnd.iptvforum.1dparityfec-1010 +video/vnd.iptvforum.1dparityfec-2005 +video/vnd.iptvforum.2dparityfec-1010 +video/vnd.iptvforum.2dparityfec-2005 +video/vnd.iptvforum.ttsavc +video/vnd.iptvforum.ttsmpeg2 +video/vnd.motorola.video +video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.ms-playready.media.pyv pyv +video/vnd.nokia.interleaved-multimedia +video/vnd.nokia.videovoip +video/vnd.objectvideo +video/vnd.sealed.mpeg1 +video/vnd.sealed.mpeg4 +video/vnd.sealed.swf +video/vnd.sealedmedia.softseal.mov +video/vnd.vivo viv +video/x-dv dv dif +video/x-fli fli +video/x-ms-asf asf asx +video/x-ms-wm wm +video/x-ms-wmv wmv +video/x-ms-wmx wmx +video/x-ms-wvx wvx +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice diff --git a/make.js b/make.json similarity index 66% rename from make.js rename to make.json index ff37bd6..ac3af26 100644 --- a/make.js +++ b/make.json @@ -1,9 +1,17 @@ { + // Where to write the final file to "output": "public/tests.js", + + // Filetypes to embed into the javascript "extensions": ["js", "gif", "jpeg", "jpg", "png", "tmx", "tsx", "plist"], + + // Files to skip "ignore": null, + + // Module that run at startup "main_module": "main", + // Paths to the code that should be included in the application "paths": { "src" : "/", "tests/commonjs/tests/" : "/commonjs/", diff --git a/src/libs/cocos2d/config.js b/src/libs/cocos2d/config.json similarity index 100% rename from src/libs/cocos2d/config.js rename to src/libs/cocos2d/config.json diff --git a/tests/cocos2d/config.js b/tests/cocos2d/config.json similarity index 100% rename from tests/cocos2d/config.js rename to tests/cocos2d/config.json From 2f92fbd11877d5580cb444a573e94d9ecd3a4d2d Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Feb 2011 15:39:19 +1300 Subject: [PATCH 034/176] Fixed encoding --- lib/cocos/commands/make.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index 292ae94..99ecae5 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -62,7 +62,7 @@ function Compiler(configFile) { * @returns {Object} The JSON object */ this.readJSONFile = function (filename) { - var j = fs.readFileSync(filename, 'UTF-8'); + var j = fs.readFileSync(filename, 'utf8'); // Strip comments j = j.replace(/\/\/.*/g, ''); @@ -150,7 +150,7 @@ function Compiler(configFile) { } var module_js = path.join(__dirname, 'module_js'); - code += fs.readFileSync(module_js, 'UTF-8'); + code += fs.readFileSync(module_js, 'utf8'); code += '\n})();\n'; @@ -218,10 +218,10 @@ function Compiler(configFile) { var data; if (isCode) { - data = fs.readFileSync(filename, 'UTF-8'); + data = fs.readFileSync(filename, 'utf8'); data = "function(exports, require, module, __filename, __dirname) {\n" + data + "\n}"; } else if (isText) { - data = JSON.stringify(fs.readFileSync(filename, 'UTF-8')); + data = JSON.stringify(fs.readFileSync(filename, 'utf8')); } else if (isImage) { data = fs.readFileSync(filename).toString('base64'); data = '__imageResource("data:' + mimetype + ';base64,' + data + '")'; @@ -290,6 +290,6 @@ exports.run = function (opts) { var output = compiler.output; if (output) { sys.puts("Wrigint output to: " + output); - fs.writeFileSync(output, code, 'UTF-8'); + fs.writeFileSync(output, code, 'utf8'); } }; From 33304f454c51e722d808fb0c69aa0601b0ee478f Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Feb 2011 16:16:37 +1300 Subject: [PATCH 035/176] Fixed typo --- lib/cocos/commands/make.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index 99ecae5..18c69b3 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -289,7 +289,7 @@ exports.run = function (opts) { var output = compiler.output; if (output) { - sys.puts("Wrigint output to: " + output); + sys.puts("Writing output to: " + output); fs.writeFileSync(output, code, 'utf8'); } }; From 82e47a119b33532cb8cb6c10a0db1dbcd6c35487 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Feb 2011 16:17:08 +1300 Subject: [PATCH 036/176] Fixed location of mime.types file --- lib/{ => cocos}/mime.types | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{ => cocos}/mime.types (100%) diff --git a/lib/mime.types b/lib/cocos/mime.types similarity index 100% rename from lib/mime.types rename to lib/cocos/mime.types From faf1a0636c7e390f55cb7cfd20e818517adb01d4 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Feb 2011 16:27:54 +1300 Subject: [PATCH 037/176] Added Windows .bat file to launch cocos2d using Node.js --- bin/cocos.bat | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 bin/cocos.bat diff --git a/bin/cocos.bat b/bin/cocos.bat new file mode 100644 index 0000000..120e2de --- /dev/null +++ b/bin/cocos.bat @@ -0,0 +1,2 @@ +@echo off +start support\node-builds\win32\node bin/cocos.js From 28033e4a7fe72c0dea5960afbcf56965c71089d9 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Feb 2011 16:30:23 +1300 Subject: [PATCH 038/176] Fixed Windows .bat file launching in a new process --- bin/cocos.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cocos.bat b/bin/cocos.bat index 120e2de..64bac66 100644 --- a/bin/cocos.bat +++ b/bin/cocos.bat @@ -1,2 +1,2 @@ @echo off -start support\node-builds\win32\node bin/cocos.js +support\node-builds\win32\node bin/cocos.js From 992c3bad349d14e8001706268945f56bd3b16033 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Feb 2011 20:45:18 +1300 Subject: [PATCH 039/176] Indentation fix --- lib/cocos/commands/make.js | 402 ++++++++++++++++++------------------- 1 file changed, 201 insertions(+), 201 deletions(-) diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index 18c69b3..f18b410 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -3,10 +3,10 @@ "use strict"; var sys = require('sys'), - fs = require('fs'), - path = require('path'), - Template = require('../template').Template, - mimetypes = require('../mimetypes'); + fs = require('fs'), + path = require('path'), + Template = require('../template').Template, + mimetypes = require('../mimetypes'); mimetypes.addType('application/xml', '.tmx'); mimetypes.addType('application/xml', '.tsx'); @@ -20,17 +20,17 @@ var CODE_MIMETYPES = 'text/javascript application/javascript application/x-javas * Merge an number of objects together and return the result as a new object */ function merge() { - var o = {}; - for (var i = 0, len = arguments.length; i < len; i++) { - var obj = arguments[i]; - for (var x in obj) { - if (obj.hasOwnProperty(x)) { - o[x] = obj[x]; - } - } - } - - return o; + var o = {}; + for (var i = 0, len = arguments.length; i < len; i++) { + var obj = arguments[i]; + for (var x in obj) { + if (obj.hasOwnProperty(x)) { + o[x] = obj[x]; + } + } + } + + return o; } /** @@ -39,115 +39,115 @@ function merge() { * @param {String} [configFile=make.json] The project's config filename */ function Compiler(configFile) { - this.readConfig = function (configFile) { - sys.puts('Loading config: ' + configFile); + this.readConfig = function (configFile) { + sys.puts('Loading config: ' + configFile); - var config = this.readJSONFile(configFile); - this.output = config.output; - this.mainModule = config.mainModule || config.main_module; - this.extensions = config.extensions; + var config = this.readJSONFile(configFile); + this.output = config.output; + this.mainModule = config.mainModule || config.main_module; + this.extensions = config.extensions; - return config; - }; + return config; + }; - this.config = this.readConfig(configFile || 'make.json'); + this.config = this.readConfig(configFile || 'make.json'); } (function () /** @lends cocos.commands.make.Compiler# */{ - /** - * Read a JSON file and clean up any comments, unquoted keys and trailing - * commas before returning the object - * - * @param {String} filename Name of the JSON file to read - * @returns {Object} The JSON object - */ - this.readJSONFile = function (filename) { - var j = fs.readFileSync(filename, 'utf8'); + /** + * Read a JSON file and clean up any comments, unquoted keys and trailing + * commas before returning the object + * + * @param {String} filename Name of the JSON file to read + * @returns {Object} The JSON object + */ + this.readJSONFile = function (filename) { + var j = fs.readFileSync(filename, 'utf8'); // Strip comments - j = j.replace(/\/\/.*/g, ''); + j = j.replace(/\/\/.*/g, ''); j = j.replace(/\/\*(.|[\n\r])*?\*\//mg, ''); // Fix unquoted keys j = j.replace(/\{\s*(\w)/g, '{"$1'); - j = j.replace(/,(\s*)(\w)/g, ',$1"$2'); - j = j.replace(/(\w):/g, '$1":'); + j = j.replace(/,(\s*)(\w)/g, ',$1"$2'); + j = j.replace(/(\w):/g, '$1":'); // Fix trailing comma j = j.replace(/,\s+\}/mg, '}'); - return JSON.parse(j); - }; + return JSON.parse(j); + }; - this.__defineGetter__('appConfigFiles', function () { - if (this.appConfigFiles_) { - return this.appConfigFiles_; - } + this.__defineGetter__('appConfigFiles', function () { + if (this.appConfigFiles_) { + return this.appConfigFiles_; + } var configs = ['src/libs/cocos2d/config.json', 'cocos2d/src/libs/cocos2d/config.json']; - for (var source in this.config.paths) { - if (this.config.paths.hasOwnProperty(source)) { - var dest = this.config.paths[source]; - - var c = path.join(source, 'config.json'); - if (path.existsSync(c)) { - configs.push(c); - } - } - } - - this.appConfigFiles_ = configs; - - return this.appConfigFiles_; - }); - - /** - * Reads all the app's config.js files and returns an of object their - * values - */ - this.__defineGetter__('appConfig', function () { - if (this.appConfig_) { - return this.appConfig_; - } - - var vals = {}, data; - for (var i = 0, len = this.appConfigFiles.length; i < len; i++) { - var config = this.appConfigFiles[i]; - if (path.existsSync(config)) { - data = this.readJSONFile(config); - vals = merge(vals, data); - } - } - - this.appConfig_ = vals; - return this.appConfig_; - }); - - /** - * Compile everything into a single script - */ - this.make = function () { - var code = this.header || ''; + for (var source in this.config.paths) { + if (this.config.paths.hasOwnProperty(source)) { + var dest = this.config.paths[source]; + + var c = path.join(source, 'config.json'); + if (path.existsSync(c)) { + configs.push(c); + } + } + } + + this.appConfigFiles_ = configs; + + return this.appConfigFiles_; + }); + + /** + * Reads all the app's config.js files and returns an of object their + * values + */ + this.__defineGetter__('appConfig', function () { + if (this.appConfig_) { + return this.appConfig_; + } + + var vals = {}, data; + for (var i = 0, len = this.appConfigFiles.length; i < len; i++) { + var config = this.appConfigFiles[i]; + if (path.existsSync(config)) { + data = this.readJSONFile(config); + vals = merge(vals, data); + } + } + + this.appConfig_ = vals; + return this.appConfig_; + }); + + /** + * Compile everything into a single script + */ + this.make = function () { + var code = this.header || ''; code += '\n(function() {\n'; code += 'var __main_module_name__ = ' + JSON.stringify(this.mainModule) + ';\n'; - code += 'var __resources__ = [];\n'; + code += 'var __resources__ = {};\n'; code += 'function __imageResource(data) { var img = new Image(); img.src = data; return img; };\n'; // Add config options - for (var key in this.appConfig) { - if (this.appConfig.hasOwnProperty(key)) { - code += 'var ' + key.toUpperCase() + ' = ' + JSON.stringify(this.appConfig[key]) + ';\n'; - } - } + for (var key in this.appConfig) { + if (this.appConfig.hasOwnProperty(key)) { + code += 'var ' + key.toUpperCase() + ' = ' + JSON.stringify(this.appConfig[key]) + ';\n'; + } + } // Add all the code/images/etc - for (var source in this.config.paths) { - if (this.config.paths.hasOwnProperty(source)) { - var dest = this.config.paths[source]; - code += this.makePath(source, dest); - } - } + for (var source in this.config.paths) { + if (this.config.paths.hasOwnProperty(source)) { + var dest = this.config.paths[source]; + code += this.makePath(source, dest); + } + } var module_js = path.join(__dirname, 'module_js'); code += fs.readFileSync(module_js, 'utf8'); @@ -156,60 +156,60 @@ function Compiler(configFile) { code += this.footer || ''; - return code; - }; - - /** - * Compile everything at a path and return the code - * - * @param {String} source Path to compile - * @param {String} [dest=source] Output path - * @returns {String} Compiled javascript source code - */ - this.makePath = function (source, dest) { - sys.puts('Building Path: ' + source + ' => ' + dest); - - var code = ''; - var files = this.scanForFiles(source); - for (var i = 0, len = files.length; i < len; i++) { - var sourceFile = files[i]; - if (!!~this.appConfigFiles.indexOf(sourceFile)) { - continue; - } - - var destFile = this.destForSource(sourceFile), - mimetype = mimetypes.guessType(sourceFile); - - - sys.puts('Building File: ' + sourceFile + ' => ' + destFile); - code += '\n'; - code += RESOURCE_TEMPLATE.substitute({ - 'mimetype': mimetype, - 'resource': destFile, - 'data': this.makeResource(sourceFile) - }); - } - - - return code; - }; - - this.destForSource = function (path) { - for (var source in this.config.paths) { - if (this.config.paths.hasOwnProperty(source)) { - var dest = this.config.paths[source]; - - // Source starts with config path - if (path.indexOf(source) === 0) { - return path.replace(new RegExp(source), dest).replace(/\/+/, '/'); - } - } - } - - return source; - }; - - this.makeResource = function (filename) { + return code; + }; + + /** + * Compile everything at a path and return the code + * + * @param {String} source Path to compile + * @param {String} [dest=source] Output path + * @returns {String} Compiled javascript source code + */ + this.makePath = function (source, dest) { + sys.puts('Building Path: ' + source + ' => ' + dest); + + var code = ''; + var files = this.scanForFiles(source); + for (var i = 0, len = files.length; i < len; i++) { + var sourceFile = files[i]; + if (!!~this.appConfigFiles.indexOf(sourceFile)) { + continue; + } + + var destFile = this.destForSource(sourceFile), + mimetype = mimetypes.guessType(sourceFile); + + + sys.puts('Building File: ' + sourceFile + ' => ' + destFile); + code += '\n'; + code += RESOURCE_TEMPLATE.substitute({ + 'mimetype': mimetype, + 'resource': destFile, + 'data': this.makeResource(sourceFile) + }); + } + + + return code; + }; + + this.destForSource = function (path) { + for (var source in this.config.paths) { + if (this.config.paths.hasOwnProperty(source)) { + var dest = this.config.paths[source]; + + // Source starts with config path + if (path.indexOf(source) === 0) { + return path.replace(new RegExp(source), dest).replace(/\/+/, '/'); + } + } + } + + return source; + }; + + this.makeResource = function (filename) { var mimetype = mimetypes.guessType(filename); var isCode = (!!~CODE_MIMETYPES.indexOf(mimetype)), @@ -230,62 +230,62 @@ function Compiler(configFile) { } return data; - }; - - this.guessMimeType = function (filename) { - return 'image/png'; - }; - - /** - * Scan for files to build and return them as an array - * - * @param {String} source Path to scan - * @returns {String[]} List of filenames - */ - this.scanForFiles = function (source) { - - var foundFiles = []; - - // If given a file rather than a directory they just return that - if (fs.statSync(source).isFile()) { - return [source]; - } - - // Find all files in directory - var files = fs.readdirSync(source); - for (var i = 0, len = files.length; i < len; i++) { - var file = files[i]; - // Skip hidden files - if (file[0] == '.') { - continue; - } - - var fullPath = path.join(source, file); - - if (fs.statSync(fullPath).isFile()) { - // If extension isn't in our list then skip file - if (this.extensions && this.extensions.length && !~this.extensions.indexOf(path.extname(file).slice(1))) { - continue; - } - - foundFiles.push(fullPath); - } else { - // Directory - foundFiles = foundFiles.concat(this.scanForFiles(fullPath)); - } - - } - - return foundFiles; - }; + }; + + this.guessMimeType = function (filename) { + return 'image/png'; + }; + + /** + * Scan for files to build and return them as an array + * + * @param {String} source Path to scan + * @returns {String[]} List of filenames + */ + this.scanForFiles = function (source) { + + var foundFiles = []; + + // If given a file rather than a directory they just return that + if (fs.statSync(source).isFile()) { + return [source]; + } + + // Find all files in directory + var files = fs.readdirSync(source); + for (var i = 0, len = files.length; i < len; i++) { + var file = files[i]; + // Skip hidden files + if (file[0] == '.') { + continue; + } + + var fullPath = path.join(source, file); + + if (fs.statSync(fullPath).isFile()) { + // If extension isn't in our list then skip file + if (this.extensions && this.extensions.length && !~this.extensions.indexOf(path.extname(file).slice(1))) { + continue; + } + + foundFiles.push(fullPath); + } else { + // Directory + foundFiles = foundFiles.concat(this.scanForFiles(fullPath)); + } + + } + + return foundFiles; + }; }).call(Compiler.prototype); exports.Compiler = Compiler; exports.description = 'Compile the cocos2d project into a single javascript file'; exports.run = function (opts) { - var compiler = new Compiler('make.json'); - var code = compiler.make(); + var compiler = new Compiler('make.json'); + var code = compiler.make(); var output = compiler.output; if (output) { From ce99b5fbf1f2944d4fd2d876acec6509df63199e Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Feb 2011 20:45:42 +1300 Subject: [PATCH 040/176] Added Node.js development server --- lib/cocos/commands/server.js | 55 +++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/cocos/commands/server.js b/lib/cocos/commands/server.js index 9dc00b5..93e58da 100644 --- a/lib/cocos/commands/server.js +++ b/lib/cocos/commands/server.js @@ -2,10 +2,57 @@ /*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ "use strict"; -var sys = require('sys'); +var sys = require('sys'), + http = require('http'), + url = require('url'), + path = require('path'), + fs = require('fs'), + mimetypes = require('../mimetypes'), + Compiler = require('./make').Compiler; + +function parseOptions(args, defaults) { + return defaults; +} exports.description = 'Run the cocos2d development web server'; -exports.run = function (opts) { - sys.puts('Not implemented yet'); - process.exit(1); +exports.run = function () { + var options = parseOptions(arguments, { + host: 'localhost', + port: 4000, + config: 'make.json' + }); + + + var compiler = new Compiler(options.config); + + http.createServer(function (req, res) { + var uri = url.parse(req.url, true); + + if (uri.pathname == '/') { + uri.pathname = '/index.html'; + } + + + // Serve app code + if (uri.pathname == options.url) { + var code = compiler.make(); + res.writeHead(200, {'Content-Type': 'text/javascript'}); + res.end(code); + } else { + var filename = path.join(process.cwd(), 'public', uri.pathname); + sys.puts("Serving: " + filename); + if (path.existsSync(filename)) { + var mimetype = mimetypes.guessType(uri.pathname); + res.writeHead(200, {'Content-Type': mimetype}); + res.end(fs.readFileSync(filename)); + } else { + res.writeHead(404, 'File not found'); + res.end('File not found'); + } + } + + + + + }).listen(parseInt(options.port, 10), options.host); }; From a27c23878a57e5f5636bdd2fd198db5240dc5dc6 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 7 Feb 2011 18:17:59 +1300 Subject: [PATCH 041/176] Added command line options to Node.js server --- lib/cocos/commands/server.js | 49 ++++--- lib/cocos/opts.js | 276 +++++++++++++++++++++++++++++++++++ lib/cocos/template.js | 8 +- 3 files changed, 314 insertions(+), 19 deletions(-) create mode 100644 lib/cocos/opts.js diff --git a/lib/cocos/commands/server.js b/lib/cocos/commands/server.js index 93e58da..94d9da0 100644 --- a/lib/cocos/commands/server.js +++ b/lib/cocos/commands/server.js @@ -7,23 +7,41 @@ var sys = require('sys'), url = require('url'), path = require('path'), fs = require('fs'), + opts = require('../opts'), mimetypes = require('../mimetypes'), Compiler = require('./make').Compiler; -function parseOptions(args, defaults) { - return defaults; -} -exports.description = 'Run the cocos2d development web server'; -exports.run = function () { - var options = parseOptions(arguments, { - host: 'localhost', - port: 4000, - config: 'make.json' - }); +var rules = [ + { short: 'u', + long: 'url', + description: 'URL to serve the JavaScript as. Default is output defined in the config file', + value: true }, + + { short: 'c', + long: 'config', + description: 'Configuration file. Default is make.json', + value: true }, + { short: 'h', + long: 'host', + description: 'Hostname or IP address to listen on. Default is localhost', + value: true }, - var compiler = new Compiler(options.config); + { short: 'p', + long: 'port', + description: 'Port to listen on. Default is 4000', + value: true } +]; + +exports.description = 'Run the cocos2d development web server'; +exports.run = function () { + opts.parse(rules, true); + var host = opts.get('host') || 'localhost', + port = opts.get('port') || 4000, + config = opts.get('config') || 'make.json', + compiler = new Compiler(config), + output = opts.get('url') || compiler.output; http.createServer(function (req, res) { var uri = url.parse(req.url, true); @@ -32,9 +50,8 @@ exports.run = function () { uri.pathname = '/index.html'; } - // Serve app code - if (uri.pathname == options.url) { + if (uri.pathname == output) { var code = compiler.make(); res.writeHead(200, {'Content-Type': 'text/javascript'}); res.end(code); @@ -50,9 +67,7 @@ exports.run = function () { res.end('File not found'); } } + }).listen(parseInt(port, 10), host); - - - - }).listen(parseInt(options.port, 10), options.host); + sys.puts('Point your browser to http://' + host + ':' + port + '/'); }; diff --git a/lib/cocos/opts.js b/lib/cocos/opts.js new file mode 100644 index 0000000..ff16c1d --- /dev/null +++ b/lib/cocos/opts.js @@ -0,0 +1,276 @@ +/*************************************************************************** +Author : Joey Mazzarelli +Email : mazzarelli@gmail.com +Homepage : http://joey.mazzarelli.com/js-opts +Source : http://bitbucket.org/mazzarell/js-opts/ +License : Simplified BSD License +Version : 1.0 + +Copyright 2010 Joey Mazzarelli. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY JOEY MAZZARELLI 'AS IS' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL JOEY MAZZARELLI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of Joey Mazzarelli. +***************************************************************************/ + +var path = require('path'); + +var puts = console.log + , values = {} + , args = {} + , argv = [] + , errors = [] + , descriptors = {opts:[], args:[]}; + +/** + * Get some version info out of it + */ +exports.version = '1.2.1'; + +/** + * Add a set of option descriptors, not yet ready to be parsed. + * See exports.parse for description of options object + * + * Additionally, it takes a namespace as an argument, useful for + * building options for a library in addition to the main app. + */ +exports.add = function (options, namespace) { + for (var i=0; i or by including the option; + * { + * long : 'help', + * description : 'Show this help message', + * callback : require('./opts').help, + * } + * + * ===== Arguments Docs ===== + * Arguments are different than options, and simpler. They typically come + * after the options, but the library really doesn't care. Each argument + * can have the form of: + * { + * name : 'script', + * required : true, // default false + * callback : function (value) { ... }, + * } + */ +exports.parse = function (options, params, help) { + + if (params === true) { + help = true; + params = []; + } else if (!params) { + params = []; + } else { + for (var i=0; i Date: Mon, 7 Feb 2011 18:27:20 +1300 Subject: [PATCH 042/176] Added command line options to Node.js make command --- lib/cocos/commands/make.js | 36 ++++++++++++++++++++++++++++-------- lib/cocos/commands/server.js | 4 ++-- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index f18b410..e34854c 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -2,12 +2,26 @@ /*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ "use strict"; -var sys = require('sys'), - fs = require('fs'), - path = require('path'), - Template = require('../template').Template, +var sys = require('sys'), + opts = require('../opts'), + fs = require('fs'), + path = require('path'), + Template = require('../template').Template, mimetypes = require('../mimetypes'); +var options = [ + { short: 'f', + long: 'file', + description: 'File to write output to. Overrides config file', + value: true }, + + { short: 'c', + long: 'config', + description: 'Configuration file. Default is make.json', + value: true } + +]; + mimetypes.addType('application/xml', '.tmx'); mimetypes.addType('application/xml', '.tsx'); mimetypes.addType('application/xml', '.plist'); @@ -282,14 +296,20 @@ function Compiler(configFile) { exports.Compiler = Compiler; -exports.description = 'Compile the cocos2d project into a single javascript file'; -exports.run = function (opts) { - var compiler = new Compiler('make.json'); +exports.description = 'Compile a cocos2d project into a single javascript file'; +exports.run = function () { + opts.parse(options, true); + + var config = opts.get('config') || 'make.json', + compiler = new Compiler(config), + output = opts.get('file') || compiler.output; + var code = compiler.make(); - var output = compiler.output; if (output) { sys.puts("Writing output to: " + output); fs.writeFileSync(output, code, 'utf8'); + } else { + sys.puts(code); } }; diff --git a/lib/cocos/commands/server.js b/lib/cocos/commands/server.js index 94d9da0..ad83446 100644 --- a/lib/cocos/commands/server.js +++ b/lib/cocos/commands/server.js @@ -12,7 +12,7 @@ var sys = require('sys'), Compiler = require('./make').Compiler; -var rules = [ +var options = [ { short: 'u', long: 'url', description: 'URL to serve the JavaScript as. Default is output defined in the config file', @@ -36,7 +36,7 @@ var rules = [ exports.description = 'Run the cocos2d development web server'; exports.run = function () { - opts.parse(rules, true); + opts.parse(options, true); var host = opts.get('host') || 'localhost', port = opts.get('port') || 4000, config = opts.get('config') || 'make.json', From 729a028e0d564c47955297bc952b7a8ed5a3da5b Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 7 Feb 2011 18:32:31 +1300 Subject: [PATCH 043/176] Fixed passing arguments to Windows bat script --- bin/cocos.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cocos.bat b/bin/cocos.bat index 64bac66..cd5b6e3 100644 --- a/bin/cocos.bat +++ b/bin/cocos.bat @@ -1,2 +1,2 @@ @echo off -support\node-builds\win32\node bin/cocos.js +support\node-builds\win32\node bin/cocos.js "%@" From 2e6984a01c87ed523ca9c003169f64904939d32d Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 7 Feb 2011 18:35:28 +1300 Subject: [PATCH 044/176] Really fixed Windows .bat script --- bin/cocos.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cocos.bat b/bin/cocos.bat index cd5b6e3..143a1f9 100644 --- a/bin/cocos.bat +++ b/bin/cocos.bat @@ -1,2 +1,2 @@ @echo off -support\node-builds\win32\node bin/cocos.js "%@" +support\node-builds\win32\node bin/cocos.js %1 %2 %3 %4 %5 %6 %7 %8 %9 From c481d90652b9eb49299917eebd6774082cf1a2a0 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 7 Feb 2011 18:37:26 +1300 Subject: [PATCH 045/176] Removed some spaces from help output so it fits inside a Windows DOS prompt --- lib/cocos/commands/help.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cocos/commands/help.js b/lib/cocos/commands/help.js index e17b5e4..3c1ca85 100644 --- a/lib/cocos/commands/help.js +++ b/lib/cocos/commands/help.js @@ -16,7 +16,7 @@ exports.run = function (opts) { for (var i = 0; i < 8 - key.length; i++) { spaces += ' '; } - sys.puts(' ' + command + spaces + ' : ' + commands[key].description); + sys.puts(' ' + command + spaces + ': ' + commands[key].description); } } }; From b648f98a9a492131d46b9c581ef3545d1bc6e2e3 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 7 Feb 2011 18:41:03 +1300 Subject: [PATCH 046/176] Fixed Windows .bat script running from other directories --- bin/cocos.bat | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/cocos.bat b/bin/cocos.bat index 143a1f9..87992e0 100644 --- a/bin/cocos.bat +++ b/bin/cocos.bat @@ -1,2 +1,3 @@ @echo off +cd %~dp0.. support\node-builds\win32\node bin/cocos.js %1 %2 %3 %4 %5 %6 %7 %8 %9 From f6753367669f8a7abeafa16de6aac766320d8a5a Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 7 Feb 2011 19:47:56 +1300 Subject: [PATCH 047/176] Added Windows executables to run from Windows Explorer --- bin/Make.exe | Bin 0 -> 393216 bytes bin/Server.exe | Bin 0 -> 393216 bytes bin/cocos.bat | 6 +++--- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100755 bin/Make.exe create mode 100755 bin/Server.exe mode change 100644 => 100755 bin/cocos.bat diff --git a/bin/Make.exe b/bin/Make.exe new file mode 100755 index 0000000000000000000000000000000000000000..99884ac04fbaf42e6116a5708190e42e794ddfbe GIT binary patch literal 393216 zcmce+Q

      +&^7p!ZQE5{w$)`x{I5HZs01yBG0Q%2=egJ^hfB2vM{-5~&9sK@n!xOZ_0~(>Gh+2W9r-+oy%pD2s z9BfS;^sNaE^=)iyod^w#2_2km2+eH>h5slLTH6{K)4{<(lm4Hjdhf{J(VnTm6sz{}AvS_J8gD zTmCoK|2+K1{qKeU!T$^XO9C>vU;%{x>ikzXv;1GL|DQ}*PL1JzTK${tf9v{hp8u!$ z0RX%Ic#Qv(llvF{oBu!jfAN0*(6va#v~dOfb=qY%8p!RtB0W1E-IF}sY_1#q3Jc!c`u2F z>d>c@aK;&YNva1)d_4@;m~{Fi%i;D`8d%qKM2-95O=8=~dd$?2{>YPKwfL5JJ5!*; zT(}mOAvFpY3K0> zVN+EF|9Z>*)?D?sF7ps>-=ofE5Cb<=y;)tM(C&wfj`SmOOa!}@h+d{!7uenlN%I1Dv=AE9weCMLA1*P zQFPPG)e#nG;<{Sh!1ay_piOZ!<`XjZ%X&wD0ikUAuwYWiGqnjH3vl2Tm1KLX-})_o%Ew#i5hRZj#`&WFI8>U?7AQNKs;F_ZS{c*28Jy`r-Ez zt|cR$=0f3-bj~g8OBnl=gSyW)*v^=xEYAJ5#CztRH-Nl7l;?63<3)7tGKv_TdK1XT zU`eyGajP^>KRyd{Al`dzIz<@qtW2r(_ENrtttXb+i>&gR@C_O98-?W6WAxWzUrAFR zl(zRCFUgol9kxw9o?O*9&XK${T;_*bY(!L#0XkI3iVTv*&fyYDZ%IE0@U=re8Gr7u@QCw{Rs@qTGW zj0`%vqr<~qK!ZvkR-C;fPn!qY}P!5#<< zCh^0Ari4xV^^2z+JN{WyV^sckSB75=ITV*hW3|G1_EG2%F#WQANv|Q@A6R?|xobfX zF(q7Yq$-Ayw_s*MdTq%}&ENnZQg0d?^ephVNSW)(83pK1pc_c|)GFn%=X;ldl=!*q z=KJEw=r(dmMwAa;C5-nz=SBew84naIQwN@P3 zjV#Vi_WbKlQ_zPsttsPjGFHgSd;)1Bf@TyYG$cySZgf6N7$?-IxEAC#xcP>FZj*Q!YFp6 zU*j2w^P98&=lFx@M?HrSClGWWyaw`54>_ikZQLi;+2;iI&?|` zY?fI1{WKQm{J$pzwlYrwprm@PKl&1M-joZo3^ zactMwc=m76s0b+ovQRHMm}xdJ#R^q3=Cop+Wk>GFSmjV*ZNuAvtdww=bR z{P|*A7nxD7-;D}7ib|dtB!_$UseCr)j4p0F(cseMYwb9sGu0Oju!xuybAelpkB$1# zefZ4x;0_jGwCCnW-9BOit={pqMG_H#^~G=FhVsM?HVv_CP_cggm1PYOXfk2p`c>GY zWa-Ll50)9mJ-T~*1!I>?7x%=WX%2DYQ=p$pqhes=3Bo5c9PCfahe|-K7ED%_uc=tT zMY%WxQE(u%%LRK!ey0tTnIrgpsqe+OZ7)L%F0p>m1W-muaAtDkV-|@!rqev)1$L=P z#sj4G=V)q088a~*M;7{3}+gh_ZwA5UKFO7fMOR zj%amI*0r0)lClG%6zI{icXxtieS@d8T1D~=%%(Tcywrf39N)+*3^qeP>+5(rqa6<)dL=NN|gN6Q|PW?kyg!yuMR3E{J zwZ(O_GY?u4+nup*%mVCrKXmBKnxkq0ra@6(ue4n(dly%I&wrOa?~R(>$5GFWS#`O2 zw6hiST7t+1%8-X=t0(TdLEYUnyrZPZR-wG`#x+!89BuvT^eSEu+MVIVyqK|x?eaI5 zeOFMJubz;4U%C=?){%laI6=&sVv$HftVIfz%;qZV48ror^_r>`y4$^dciml^Ke+Q1 zZ|&@An3WAd;3c4l{JND_yEk+>J>4>Ppp z$v~@y?SjJaCwTMW;+R27ml){t%ZGZL)4`4cVNC>xH>$>4ciu(f6f*YdBnR+po1G5^ zlR{RK$>CLFH(L~@&VwtKc4VTN;!&~}LnGquY`Ln4f@4)E#s=`hUN4PONs|VD1H@X~ zY;83bjjJVzC1xuKBtLJC_!u zTBWg-y+oA-C3N^gCc2Pk>gXg31$1GDR%Xt6EpST|Ro&_I+QnUU6`Sp{bKRBgyEy99 zzh9_8R;(GZrrebWkF`#yldnaakn(y}@~SLe6T9g?7YSj_LDSj~6M#&kL$xVa zT9v`KF#aXD+K(vYkw{CK6}oVSG@a;9TSptZv2juw`JSVA90F+JR~>9ol&!TRE!V!A--8ZcNh8P z+;|RFX66*Ma+7ebu0P&`2XU#08yQ)I8!kz_%5NLlO4)+DaMz$$N#f~mJ9;zcw~ViQ zmbqsB;X2rW&)NPPv5c1xn|GJy(7YM@?WvLtGU=K$yDW=Wv_~3G+f(4gN0Il(9D*lC zYF?jW7&wYH%BjaVT>gGL3ygiTt--m`A8d(S6Srsqf~I7U`s-&qZ;7rYPn&-`8WUU@ zTKipuOn$-qy&Tl(tIxrsUkHdU}>n;TIb!qU&DT~EA27hm}UlkBd^VL(AJ|WHQ%0;w8s`rf#%jW{c%5@W$ z(N$Z^Xd*Pt!diy>9UegMZGnw3aOIVFwBmgMfA&QPTJ#v0CU}Os&}*MwYoJ8W3;cAyG!TfSZAcXY4iKo(92Rj9t>!&+DB7!58BW zKA9m696$C>67*pLCJ?n9ehcr4Sf+mzEL3OA12wq2xd*C_ z^;$4wSQr?^dqHhbot*g$D19|H3AgCnr11&^^M)Kdl3(G5TM*cs7@$`1DRz4U9lk*xWJruacjDyl#!dx!;AB zx4Rg{?QUd6QVHi$_VX6skwO+&IE*0*^y+bwXq>B>Kme~|fFkJaR}HwNm9IZAH0!ubfKFhr0&)Fd+d6Wr&@KzSi&9U9P6Q5^O{^LFHCNSc#RO|+J_K>ZD zTSbE9dAL!lXh-lh)ePkF^A13Wr{Q+S%P&4xgPyblb;GfGU;)%%6I{+Ld*>zraaWt$ z6)T2aA;ObAHAjXhZ?dvc$-_P8q8!8m=|zp5hE2I*<79A`$}M=Yn$Rd@Vdq?oPkxC) zju$ZI1)Z?Td-!mk1k!rs6?`=kU*7FJ>m!#=IO3{&cP8bBk@f%vX`RZQBrk5jw2u!7 z)v2}af{+*aZV*MzjeF+b^P!e2cHZ&vTH}Ljuu{O{MRL z#hL!N-;8;od7C*@4~ct4BUD(~eQ#{Jix{;Ao{`3&TAmeDpVt4;^0OsicR|kE2qS+m z*AK>Wjt8Dbup*1$32{w7{MC6wn0%l0A@Kz#j&--CZK8i3>F>R4s1#PXYE=E;jSY$UECKuMIlh9u@o*)q&BNUFt=dM>dk z)YXF`dPK<+NbPF9ucRGTuWP@feSpU90dDf^#ya?tAVxn{6667c_O~9n(lA%d%ncgI z@x=>hu4NX+d4OVOfscQ9F!3nQaf@g-xAqp6XBQGItYfD8)-mv4f7F^8@BB6_3vP>p z#j0)hVW~dq`qJ&I{p!&iRo*SeI}G-o_~y?Zhi*=;Mzys_Ux3TFjU5f_NavBK`a*Ye zm1?G$V4_^otUC_8LXl3PUAtdn{C4PR-^0&9ns5QN2-4fY06b^&RC>y#IK+1Q(F4Gd zOp41|l;**Oefjuh)lrbs*^cS5+Di0;;GIgTWPgA6gyS@*DRou~S>p;Avz21V#C-Q2 z3;z?(2U?lonV$>+%XM(m?QfPqNw=SGEC>E0-hv_FP@2S}RDFr6!Xu)isHJtc-Zy&b z&)QI~SHoX7?$Tf^vp`>-oUs)T@JRnf5=A*|^>u+BqsHhtt^ujJ1k>M(TP2^=zjHFyCJD}2N1%qGk%^I z>G#wKI<uewwv6Qj;dwBH)HP&PJdw*B1 zpK<$^_2-Hs@f8-=!lYDif6_f8-E^!wJ?8b%KUZr`nkok^iN1Q1ss-GoXXni2V5KzD z8TQcimMG%Jjg4c-n=-d9SmDbPslAhOcDTztKhtNxDmCuJ;qNV+0i&%e1U#y{dNS~W zdni7K{~EQK`0Iy1d-dUlXLW?9rnEG8@HyE#I?4yc=qqF7j`)Y7n38ZL6Pm}L;2l*n zN|8k*cX1)e!9T@Pd(v5Ue(wm0!zl5cbJOH*sLDI2lh_+9D1n7;3KkAig8Qp#oO7RG3ifcr+ZGu z8V(SO+cJx&UU=bWaTrt6JC@=aH1hRQ*ZZ(pL~xU0k&^qFZNZK_RwKaEqO2sIVWWc( zRkEaRRS3x#2Chu#f!)av6PJ+gCTHL#N_h+WHxma+ z%cHDjZ(a#%**3cL2Mlvv@KRZO28HiKgi&Q%9$f%U0Ls(z;Vyy3bNJBtr-&HNQM=1W zQ3-lgHX)vSCyA<#DD1WxyCXC^-ufC;d(wiz%QqX))T=}vpn7ZQLdF~HDu(n6zx0KX z%$~gHS9!!J7$GFh*;5pK^8tpInPZfPS0i^Pbl7S2sK^r4aw2

      zH+y&~+rl#A@nDhN$AyIpCw7IdQfeP6AEe6REVZ{y)b}wgNX4wuxayP+TlClb%eJEp z{tvwSs*2wdVkM2WfoMukVT}EhNlo_yLm6t~)^sXo)D(_UC`!g0z zcp`a5kim&W|0}R{xBs4?D%K5-&b2^BRs!p(B0AIRI>|JZjW#Z$AY4 zM^;#p1vqKu6nDkZT88x!ox(ci`u$=!Xfsz)LGD4PPw#!NRNgCRuhUKw%CY{)h?x%C z=gjtx@dOFsT>PCGR9lBWQShj{zMa{Ln0W;>0C=`%pYPf&;@er^C`l8VKKt5F)8>U8 z-44$8@7vcO0Sh8;iCfYX8b&%q_DaU-x#sZ2w@#^9!ZF{K)&y^v|T#LnVVK6{HKS_SAUYrzs&d_INjb3dTBxsB; z)SO*6SD>?&Jf1V@9-bsZC>AtRMs(c35*Dhn!d38uqwDyUz#fuKQNPZ=HVUtOTpX2n zk#(LizrkdTneE8=*(Y zf-`;tk0yFbMDdq;8XMks76z8enZP63sTXRFGPH(DPuaoLyYRn#4(tj&?-l<&%rjhYpxfu$Y&}<2wp)Q^$mBTHUt+T-gv_X?(Ki3nnox{4t z4%v)la#%n}QFRGGt)F^C6ecUOKrtbQsVvifjn}Fl&_)vj&X5rqv9gC_Iu^RGh@~oWW3^08cLT5v; z#U4K&gsV7rQH!wWh>VTuX1*6&-=uy<2dg)-WP&@f2E73~-=M(Z*xIbj^Cx51A5mB{_?O!T6mS zpxS5^V8@zuslm!cqoRIWAevk+S*fsUt3X~CYkmH$_{ysZG5pfJ=b)fL!N3!H4<-D20FG0} zDu`b$|5`=?z3%%=1i8%#Z=LUQfNEpmwVhj0?Yz4T9K(zaksa1xPy{&}>JlZX^T=0Jk{9{+szNIMbygN? z%u(ZcafB$I@iX2_!o&CW%WP6;@2i@1ob>jre{uvX_oAMAeyiK%AbYGYU4ox-dze8^ z>-Rj#zj-qmP|WN*6da`vhw8U}z5aRgjV{S^t{Z%m4v))~RaZ$i@x7ji9O$ns>?nw7 z_aYoDoRa(Iq}e%^fyzXsy}~29Jr-Q@!V}={dz7zN$>Wm!#V0Q8+Z(OG4KC{SA`no# z*v>@=wG&C+vZRn3O0n^sXn@cOeVb1WL_S+gn}zY4Y|G z-U0kw9SSgKUZny(ds@i~btHl>6@G# zfTeC;Ieg3KdVQuf!a!a%UUpn{&EZWnW7PnwPJNYJc? zVl9l4BPukR3hFJCCVTe=8%~@361MD42 z&yNPVH1zcxV6?v`QyHBJEPFKEGR!@>XWnzVN}qHdRE^DN_?Mli6~PqMg^Z>47x*KC zO=P9$Jip7XGU7ChQ&UZ{ z8L@M8=IG}ErCyF<#S_87?N16qxbSsp?-n}iqLO_+gpJz=RC$F6g+_SC5{}n5ocOV= z)jlGIK$snVo`{XQyBB}*=Rltt+5P}Iz+T7G5n$G8_Cx6TaZ$|~9@Z&wE|T%`PU+IR ziH6C_GxZCc(NQ(?B03pqt?He`G|woFA+X8ccUjeu>4DYRYaC=OOdh9J#yv00$Ggq1 zv8xTZ!|i=SCVUH)Yl<}lBS3bmrc}@ohEu&&-Of(ouO3KUP|A6n)mb#bj$&RXVRVCq zf|FIC*C!7uy9)sk)QU6d$)h@KNHE^9Bqeq6Gct}w*o$s>PzT6?D*iDSE!KJkHFuyo z2xG1@#{;Xt@*?_Rb4Sj|45TWBTA82OD((+h%deDqPOP)M8EtI&ZUl2CuQ&HNJ#rqS zq8i)*YMFA9)RJhX#p|*hYL2^YtX~0W{({29r1UOcwNY}!+%s|yy_-T80V1(>vI##4 z=Af=M#-Tezp4LrmjhjDz;U}%ZFSZe>6^GV**V(!0^fNuu`9<(x$psW8i;k=xwJIhB z<~zo)z%6Y)oXIRNV>+HcPZ7<|0bhZ~#q7=9lS=4WbMUBxFBsI{=?rwed<#kIUag-( zQdX>yB9QQ8;=##$<;2Km@UQ{i83w#H(kfLJM0d5%uS;|02TR<3D>D@VCEk_SJV01P zHB>T$L1F-j$ysfFYOmFLg+X|djtm_5R7r9;4>wVH!LsHuL0;V~kG*Kt;92J&AT!U= zNz9rt5;E7FfvJR1jAAiib>ro+GM4@5AvgDt?SZj^#Z5yg-cXs6-q|9+08@jY)wv>^ z1YQkZ-ksTr#fz{sKS1CnjP4zHux3i|=yy1%|Ju6gEeAYvN^i3HBg$-6bhu~_QLS^H zG0>fl4PIG4iZM}%vJFdD>bFy18)@dPi2*XwJV_OXeZ$N{Yi zfjcEF$i*!4lU#{vgC|5ED%5B3=4YceD32Wph#MFfhNT|NqGfl|EuD`W4Tu?4))EMk zw5HiwMMp4$>6q_@JEJ`q0XHd~RDyvv?gdnt@(3(%=UcCOJ%!z6K%qagE1z&^~?QdAm(sYjaGr_aJ82 z-{71<$q^<2VqYm*DG?t6_i<#b=x{)?OFXldZV5}@GKHzA@oIBdt6ya?D=84`=Kc~U z%*Zaq528n?>4O)24{xi*w}O0uNAGi`NvD>`1Sp4FZPRlc9}YN3C_Rd`Nq%CD z2@O8k3sX~%<)Re!rx)<1jt|i|H$fW;&%2_5_VF^`-8q#tKr2%FgoE}{-==*Ctgov2 z=DW(B-%_H4upn#bMga zUnd~#ma^E4MD$@q&v~vlwZ5k}VqjI$`&mdMoTNI8#m|}@vo@@Me?9>Ey}VVd9;yOd zqO$SElb4H=a^L#($dl+=1Lja7(gs#>q@J+`Ta6=h4urvL6jT2o%SqEHE2J&RS%+?m zTvI5`Sx4x4QAIy`+yF26J&+l-B**M)Ai^`NjGvRy)uNF5wxEe2lBZi=bTm{+hew2u z>uWuztfIJ~q2gkoAt$kHc-`%tAa;S7!s|%N2@GbtwX08N(Yz>SOxfFKA6|(WF8@fT zts(<{G7SW8XsMohr8tQZu-bb-m@B{#=2ZkHF4>hnl)`CaqxBT72KBmRv0|& zW1SPp3|SA^R-Nx6)*wX|x##vB!+ZI<7#aw#^Vx)yuKzQT1F*;okd|9AGX_gCthfj$ z;FT=seNN@d@UA{m+8Rsx`ZCybsz*X9`qf3C+r(oN5SCaO&E=KlwjVgnhw!mX((9-I zDp5JLEu+d-NMzBoTk|VUz`UT5>`F4S(zEb;jplYd%Y8^bGm<>za=nj8EH>d`>DbrB zTa+MN@jT+0+AiLP_0JSkvf;LeBMvn=y}y<8t=4<>n+lws?C2wesPpj>3N3vh+rn>@oU7<2fBVKF$e&u1<#Z*ysR zXPrNu%HFJuAuep?#wFR2CGLTf1zw)(3ct+mhGiZ}liy@rWfQb1%PmM>O)S@Q2p^=S z{2rk*WxSHcy!w!NHu-;|>3B`Z9`_dlNr$=M#q~@Z27bokQ<-z8SyMc;p19>YCjmC9 zjt~kU3TF$V&BI(eOtTUds3}Qy;f={}gOA)`Z@)K%K8&V?L!%vXQ=yK`CbjZT+$UQ- z$}u068k$~RaZl@t_b8+|x7=YYYq!+&1Kg`gKF-X2p92tKBm{3AL=RPv1ap#n!o zK6Xz6eKxo7!@Gfq6r7D3gyeTi=6`BZ)-I}{jP z1r!dDm-^6J#T6Qsv-HSmmb>RCGQ<$V`h)zms#TrW60a)x+VFS^84N> zQwt-D8Tq0tO5N`tptacWIg!PB*}6&6f$Om^yki)m(QQ61Lk&n>JM!V#AWrn+sN(OG zC%YDm(7SwoSZABE##4cjL#g#a7AnaUanv)jpY?`yGZoB1zx+9A+pn{_ zFjV?z(*LqB)SPX&dE7-Vs`u-URW3Q6M>*k)wmmceYJc#31A+V$*YP^zk!anWrYpG> z+=S^g=cLHtM-%0egIE}fys57aRG1coJuY>ij{`*tm- ze#R0PugO_5rWQQ4X(r#tFdcG%L&9&X{nRKv*YDL)9wAI21dAEsrgo>-FEn>{FD`>v zp-+kjNq~#Q05>A<>KekGNr{DLfDM{dA5d4J#;xO`TJNvnHF*o#YM+Eq#eu$Hw3 zpQ%O~C4CCn*<}C7OgVGj8y$?5nq$3vE`{D*()UMSJP47q790rE;@&0zJEvPT!C8L= z#yWvx!bVa+^-AN-U;L)5@{h&&pI(9pt=p1Yu~rhdmljGVIH}#RTR4W$!9TDFi15$L_S*_^ktj&PC?TyRH@xHS?_0{ zQaD6&vK1G_;DhCUu9hS+Trr7r&|wh%(d0!lh+R!Zw$z@ZqXg2V6}^t>TZ*g5va>)e zYJ(WsBM|mg2?37bWJD^`2~~46>1VxpFcf2WlCtDq>(2<8UTvK1<`=1h-*!-K#EhG< zqWu%x0H{NpWCa>mG2qIBSZ;cZL&u5}*UyI_C+dlKX9WHV|e60}fh7zrArmm3}C z)O}mI(6)k!=vH_vM3*V75g_MQq^bi}RYYdPS<;5%88LS|rfkWPfpoI#wVvE#qS{E? zwy!s4?b5b*jw&Ov26>sJi4=vgg6Gir7pg0`mz;>reO7;GZ&OG?X&t2c2 zDZ{c#^9Zacp1$9XdQR5c9*6tT#laaQzx&aDZ6S9jIj8;E%+|Z$LzN6{!l89!L7H}W z;OC$~?!ya|l6!;Eq4_JyM-Y-zu>u@~*3^$~R31=a5{eSEvMK}PhUKDwI`$;~6%<5h zHIQ)DGr-7=;K?ZKQL%=T)(i{}L|GuKKkOR555iQ~K#Mg!VE}mKd=tHn-!Nk|hy>F=k_bVW)M+E>6ORW~GA5KUZhZVv_bdVxm~8 z-*z%O^5lgf!u*UEOaCf~V0dSC7?w#qtl3{LZv!l%?Z`DsbKxGXV}r9J&$@0FztF$e zx3dje1oZ@hl7Dsc-w!s3qh2E36rGIuPy4vR93M05LbiX#2%0?zhMLOd9*oOz%@lp( zSQ&y}6s%GAJfoq@*|lJA{)Vw&%EISZCaoiu4;V

        HS!YQhKYMZdC9msF!FO+zM& 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 G9{B%+&_^r) literal 0 HcmV?d00001 diff --git a/bin/Server.exe b/bin/Server.exe new file mode 100755 index 0000000000000000000000000000000000000000..42d7418bda7c3b3e0925b4b4df82c391efebaca2 GIT binary patch literal 393216 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 Date: Mon, 7 Feb 2011 22:43:17 +1300 Subject: [PATCH 048/176] Improved serving code using dev server under Node.js --- lib/cocos/commands/make.js | 5 +++++ lib/cocos/commands/server.js | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index e34854c..2299bbb 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -258,6 +258,11 @@ function Compiler(configFile) { */ this.scanForFiles = function (source) { + if (!path.existsSync(source)) { + console.log('ERROR: Unable to find path: ', source); + return []; + } + var foundFiles = []; // If given a file rather than a directory they just return that diff --git a/lib/cocos/commands/server.js b/lib/cocos/commands/server.js index ad83446..16bbd35 100644 --- a/lib/cocos/commands/server.js +++ b/lib/cocos/commands/server.js @@ -49,9 +49,10 @@ exports.run = function () { if (uri.pathname == '/') { uri.pathname = '/index.html'; } + console.log(uri.pathname, output.replace(/^\/?public/, '')); // Serve app code - if (uri.pathname == output) { + if (uri.pathname == output.replace(/^\/?public/, '')) { var code = compiler.make(); res.writeHead(200, {'Content-Type': 'text/javascript'}); res.end(code); From 046ba75965eadb4009a68667a0132444c91ddc83 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 8 Feb 2011 18:34:43 +1300 Subject: [PATCH 049/176] Fixed cocos.sh script so it can run from any path --- bin/cocos.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bin/cocos.sh b/bin/cocos.sh index 67f45aa..b77bb7c 100755 --- a/bin/cocos.sh +++ b/bin/cocos.sh @@ -1,25 +1,27 @@ #!/bin/sh -e # lets check if we have the submodules initialized +DIR=`dirname $0` + case `uname -a` in Linux*x86_64*) echo "Linux 64 bit" - support/node-builds/lin64/node bin/cocos.js "$@" + "$DIR/../support/node-builds/lin64/node" "$DIR/cocos.js" "$@" ;; Linux*i686*) echo "Linux 32 bit" - support/node-builds/lin32/node bin/cocos.js "$@" + "$DIR/../support/node-builds/lin32/node" "$DIR/cocos.js" "$@" ;; Darwin*) echo "OSX" - support/node-builds/osx64/node bin/cocos.js "$@" + "$DIR/../support/node-builds/osx64/node" "$DIR/cocos.js" "$@" ;; CYGWIN*) echo "Cygwin" - support/node-builds/win32/node.exe bin/cocos.js "$@" + "$DIR/../support/node-builds/win32/node.exe" "$DIR/cocos.js" "$@" ;; MING*) echo "MingW" - support/node-builds/win32/node.exe bin/cocos.js "$@" + "$DIR/../support/node-builds/win32/node.exe" "$DIR/cocos.js" "$@" ;; *) echo "Unknown OS" From 81c3a5629f9dd504b23bba694f02e13366a41c31 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 8 Feb 2011 19:58:56 +1300 Subject: [PATCH 050/176] Updated Windows executable so they can be run from any path --- bin/Make.exe | Bin 393216 -> 419328 bytes bin/Server.exe | Bin 393216 -> 419328 bytes bin/cocos.bat | 36 +++++++++++++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/bin/Make.exe b/bin/Make.exe index 99884ac04fbaf42e6116a5708190e42e794ddfbe..41733e348c586eaccfc7ca3268eda9198ac15440 100755 GIT binary patch delta 45528 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 g3JYU_Z;4y19N2>XX2K0VD8j%K!iX delta 22641 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 K1irITtp5WK_`%Wu diff --git a/bin/Server.exe b/bin/Server.exe index 42d7418bda7c3b3e0925b4b4df82c391efebaca2..38b4424e97c6764c18b472584519c982befd1ce1 100755 GIT binary patch delta 45528 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%0D^v%*Wcltv?Im1k8S&NWv^`nbOy+pqoK`? zy0qNB9K{Kf;l1bxG2yT|V5S@g35dbJ6K%)jgEX8zj>F~u5eKRLI1mVfYWgS;QzX1_ zJfQ6G7^pd1N0~&G2&FsDUh@gc%q8mDkce)$bm2;v%Y~*NBQF> zfezzcvY!Vl70|QH2__NwPgnL6z*cAWFRSn<#>)xtL7;IQ0l$WejH$X>D8tOE1{RpL z7XU554hNkJhYZ8>K$K>h9`Mg%RD!rK<4jjy57GBeXJ=sc!zaa4%NuwA%(kwH7Tb0~ ze?as#59W1FH%#wKzktN}z))v*97>J@p9TZb*BXbtG6VKrqdz_wN?|TB3kFG7z(*LW zn1QgKmn6eS+;$Yi!x6Bw;hPF|O#a?^4wKQ#GM5?N4qqS91RM5O`a=rlYVMhP!Zf-I zgX|T@U$(cu53~<@_t88MJhLPHVCF=OuztW*8p#6s6BCdSRDbxc+l#z+Gn`&FXI}EB zcG@>~pTFW)npWd*Bw#!BNEG<9?jPzA|Li>K@1t*k;ylMGK25=lC4cKf>~&9#j(N!} zScy(mm2O|2=DpIJn;0#WqoKw=_r|?nO%<5L0W&%}R}#U-WR@vsbkT5E5@S3Q8ETx` z3q>Pbv5jEQsgk%wy-tjJdN97dPz*xQcckp#yV-oVy-)@MO!?Z?rXeIoHf zR$OBHRnw|%fJx6G^%8F~NhB5_VN!}ofa@1xfv0tChDZ8lKiJ11Nb6Pl^`X&>e5VpO z57;v?2?Nu^#~wP^Pu~}sP-ebwiO28^FbZo4gD+e?T9B2{qFQT$7HS!DgK21G1~Bsf zDDmi(3y<#UkLI-Rw0Jca$ey7CU{RRx|-2(%|x(r|tjQD~B z<{jR7pqDp_lI@6jJ27kydX#zwg7kY&C(N6}dhY-^M;AhYkV6>yTtJ%xExg9`xzOIA zQM+%4>Hl8ffc*>9I^yev-axlt01;#j=Uu5MTJlXGMRD8I;gP=Rm;pVgVEMO7272EZ z?~2Wa&i|&E1W@urOZ$!s2yn%uK(|eqfrW#mSh%NSt50H>HyA?OJO^$D{R@d=mCpQe zCaeGRYRfnp3+*tjcPl-1bc0*}qU)CN(J&_II6f@jrG;CXb1q|8f5BUePAH7)JLq8H zr7kVK!Uw2A7&Hbn1_0h;z?>MH<^(aLS1t2n99ibataa>NFoj90A~g&`0=W4Z>-()z z1u@~agPR4n{T@}21BYw@Hj#=0=7z$9$WQ^n6pp2b3Wte}M$lmlRf`=K8fxjG5@BI_ zy|o8*f$GxQm~yk*7=5GG#isU?MkOJb7dQ zm!l<8(q$q^PSI-RY4cTC959fsoygT`(u1_pRC!v8c4V4Ts!?mz z3Sy*Gofed$P4oSX&*h}0q$?G2Es@aC+awnb=e@0HnLM3P5?LVQaLA6Rd`AN^S_~(Q zO66LuS`(&`rYZ@!l+bAaR#Lz?%XoT98gwJnX&EW$S+UUZ6=~Emos^)TXQ_3Xu#60g zDv^}|s!NpVWBjk)w4jc$@#dQd{L9o!w7w8XnmT=CggTwjs8w1Ea5UpRJL3>HHg?d+|HTlk zqnoc%N~g)Q#Og(INc_05fn(>7^XL2fOQj0FOaXpKqz9KOC4GS|WdSfX+{zL}2h9A3 zz(0r)K`z0gY(+9jWUW5B*)_ox6T#i_It+bPCs`VXRe*r#B*d^<=r8LctA~D07uoO7 zU)@F44E=&GvKP=Vn&7&AhzA+$iuHhd5Zu0S2g5xTZgeGCTa~rVw6=O{yT;mXx3(qL zc3R}j*ht|RKVN}Rh(%0~i4dcXOr^r62%@b|F>whIGsV6#5~S0GkydG3RHV?R8y6)^ z3=>7u^Wx(oXIfR@^jvj{OsJf%Nzr75Vb~No0ktj-lgTu&Lg4?Flo~>pq5>IOChz-U zDwSILzBgGTmqUP&nMxHso1Te9rz;6d>Dej|!{X#b_@W54O0B`LG Date: Tue, 8 Feb 2011 23:39:07 +1300 Subject: [PATCH 051/176] Tweaked Node.js server to handle output not inside 'public' --- lib/cocos/commands/server.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/cocos/commands/server.js b/lib/cocos/commands/server.js index 16bbd35..114a130 100644 --- a/lib/cocos/commands/server.js +++ b/lib/cocos/commands/server.js @@ -49,10 +49,9 @@ exports.run = function () { if (uri.pathname == '/') { uri.pathname = '/index.html'; } - console.log(uri.pathname, output.replace(/^\/?public/, '')); // Serve app code - if (uri.pathname == output.replace(/^\/?public/, '')) { + if (uri.pathname == '/' + output || uri.pathname == output.replace(/^\/?public/, '')) { var code = compiler.make(); res.writeHead(200, {'Content-Type': 'text/javascript'}); res.end(code); From fe50f23a992d239e74dfe98cad9806acc9d9bbb5 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 9 Feb 2011 18:06:37 +1300 Subject: [PATCH 052/176] Restructured directory layout --- .gitmodules | 4 +- bin/Make.exe | Bin bin/Server.exe | Bin bin/cocos-npm.js | 2 - bin/cocos.bat | 0 bin/cocos.js | 0 bin/jsdoc.sh | 10 + cocos | 10 - cocos.bat | 22 -- jsdoc | 3 - jsdoc.conf | 28 -- lib/cocos/commands/make.js | 5 + package.json | 2 +- scripts/make.py | 286 ------------------ scripts/module.js | 145 --------- scripts/new.py | 163 ---------- scripts/server.py | 87 ------ support/Make.bat | 2 + support/Server.bat | 2 + make.json => tests/make.json | 9 +- {public => tests/public}/index.html | 0 tests/{ => src}/cocos2d/SpriteTest.js | 0 tests/{ => src}/cocos2d/TileMapTest.js | 0 tests/{ => src}/cocos2d/main.js | 0 .../resources/TileMaps/fixed-ortho-test2.png | Bin .../cocos2d/resources/TileMaps/iso-test.png | Bin .../cocos2d/resources/TileMaps/iso-test.tmx | 0 .../resources/TileMaps/ortho-test1.png | Bin .../resources/TileMaps/orthogonal-test1.tmx | 0 .../resources/TileMaps/orthogonal-test1.tsx | 0 .../resources/TileMaps/orthogonal-test2.tmx | 0 .../resources/TileMaps/orthogonal-test4.tmx | 0 .../resources/animations/dragon_animation.png | Bin .../resources/animations/grossini.plist | 0 .../cocos2d/resources/animations/grossini.png | Bin .../resources/animations/grossini_blue.plist | 0 .../resources/animations/grossini_blue.png | Bin .../resources/animations/grossini_gray.plist | 0 .../resources/animations/grossini_gray.png | Bin tests/{ => src}/cocos2d/resources/b1.png | Bin tests/{ => src}/cocos2d/resources/b2.png | Bin tests/{ => src}/cocos2d/resources/f1.png | Bin tests/{ => src}/cocos2d/resources/f2.png | Bin .../resources/grossini_dance_atlas-red.png | Bin .../resources/grossini_dance_atlas.png | Bin tests/{ => src}/cocos2d/resources/r1.png | Bin tests/{ => src}/cocos2d/resources/r2.png | Bin tests/{ => src}/commonjs | 0 tests/{ => src}/commonjs.js | 0 tests/{cocos2d => src}/config.json | 0 tests/{ => src}/main.js | 0 tests/{ => src}/qunit.js | 0 52 files changed, 25 insertions(+), 755 deletions(-) mode change 100755 => 100644 bin/Make.exe mode change 100755 => 100644 bin/Server.exe delete mode 100644 bin/cocos-npm.js mode change 100755 => 100644 bin/cocos.bat mode change 100644 => 100755 bin/cocos.js create mode 100755 bin/jsdoc.sh delete mode 100755 cocos delete mode 100644 cocos.bat delete mode 100755 jsdoc delete mode 100644 jsdoc.conf delete mode 100755 scripts/make.py delete mode 100644 scripts/module.js delete mode 100755 scripts/new.py delete mode 100755 scripts/server.py create mode 100755 support/Make.bat create mode 100755 support/Server.bat rename make.json => tests/make.json (63%) rename {public => tests/public}/index.html (100%) rename tests/{ => src}/cocos2d/SpriteTest.js (100%) rename tests/{ => src}/cocos2d/TileMapTest.js (100%) rename tests/{ => src}/cocos2d/main.js (100%) rename tests/{ => src}/cocos2d/resources/TileMaps/fixed-ortho-test2.png (100%) rename tests/{ => src}/cocos2d/resources/TileMaps/iso-test.png (100%) rename tests/{ => src}/cocos2d/resources/TileMaps/iso-test.tmx (100%) rename tests/{ => src}/cocos2d/resources/TileMaps/ortho-test1.png (100%) rename tests/{ => src}/cocos2d/resources/TileMaps/orthogonal-test1.tmx (100%) rename tests/{ => src}/cocos2d/resources/TileMaps/orthogonal-test1.tsx (100%) rename tests/{ => src}/cocos2d/resources/TileMaps/orthogonal-test2.tmx (100%) rename tests/{ => src}/cocos2d/resources/TileMaps/orthogonal-test4.tmx (100%) rename tests/{ => src}/cocos2d/resources/animations/dragon_animation.png (100%) rename tests/{ => src}/cocos2d/resources/animations/grossini.plist (100%) rename tests/{ => src}/cocos2d/resources/animations/grossini.png (100%) rename tests/{ => src}/cocos2d/resources/animations/grossini_blue.plist (100%) rename tests/{ => src}/cocos2d/resources/animations/grossini_blue.png (100%) rename tests/{ => src}/cocos2d/resources/animations/grossini_gray.plist (100%) rename tests/{ => src}/cocos2d/resources/animations/grossini_gray.png (100%) rename tests/{ => src}/cocos2d/resources/b1.png (100%) rename tests/{ => src}/cocos2d/resources/b2.png (100%) rename tests/{ => src}/cocos2d/resources/f1.png (100%) rename tests/{ => src}/cocos2d/resources/f2.png (100%) rename tests/{ => src}/cocos2d/resources/grossini_dance_atlas-red.png (100%) rename tests/{ => src}/cocos2d/resources/grossini_dance_atlas.png (100%) rename tests/{ => src}/cocos2d/resources/r1.png (100%) rename tests/{ => src}/cocos2d/resources/r2.png (100%) rename tests/{ => src}/commonjs (100%) rename tests/{ => src}/commonjs.js (100%) rename tests/{cocos2d => src}/config.json (100%) rename tests/{ => src}/main.js (100%) rename tests/{ => src}/qunit.js (100%) diff --git a/.gitmodules b/.gitmodules index e584d91..26c6397 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,5 +1,5 @@ -[submodule "tests/commonjs"] - path = tests/commonjs +[submodule "tests/src/commonjs"] + path = tests/src/commonjs url = https://github.com/commonjs/commonjs.git [submodule "support/node-builds"] path = support/node-builds diff --git a/bin/Make.exe b/bin/Make.exe old mode 100755 new mode 100644 diff --git a/bin/Server.exe b/bin/Server.exe old mode 100755 new mode 100644 diff --git a/bin/cocos-npm.js b/bin/cocos-npm.js deleted file mode 100644 index 6e1a2e7..0000000 --- a/bin/cocos-npm.js +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env node -require("./cocos.js"); diff --git a/bin/cocos.bat b/bin/cocos.bat old mode 100755 new mode 100644 diff --git a/bin/cocos.js b/bin/cocos.js old mode 100644 new mode 100755 diff --git a/bin/jsdoc.sh b/bin/jsdoc.sh new file mode 100755 index 0000000..f489244 --- /dev/null +++ b/bin/jsdoc.sh @@ -0,0 +1,10 @@ +#!/bin/sh +DIR=`dirname $0` + +java -jar "$JSDOC_HOME/jsrun.jar" "$JSDOC_HOME/app/run.js" \ + -t="$JSDOC_HOME/templates/jsdoc" \ + -r=10 \ + -v \ + -D="copyright:2011 Ryan Williams" \ + -d="docs" \ + "$DIR/../src/" diff --git a/cocos b/cocos deleted file mode 100755 index 287e810..0000000 --- a/cocos +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -if [ -f ./cocos2d/scripts/$1.py ]; then - python ./cocos2d/scripts/$1.py "$2" "$3" "$4" "$5" "$6" -elif [ -f ./scripts/$1.py ]; then - python ./scripts/$1.py "$2" "$3" "$4" "$5" "$6" -else - echo "Unknown command : $1" -fi - - diff --git a/cocos.bat b/cocos.bat deleted file mode 100644 index 83c37af..0000000 --- a/cocos.bat +++ /dev/null @@ -1,22 +0,0 @@ -@ECHO OFF - -IF EXIST ".\cocos2d\scripts\%1.py" GOTO USE_COCOS -IF EXIST ".\scripts\%1.py" GOTO USE_SCRIPTS -GOTO UNKNOWN - -:USE_COCOS -python ".\cocos2d\scripts\%1.py" "%2" "%3" "%4" "%5" "%6" - -GOTO END - -:USE_SCRIPTS -python ".\scripts\%1.py" "%2" "%3" "%4" "%5" "%6" - -GOTO END - -:UNKNOWN -ECHO "Unknown command : %1" - -GOTO END - -:END diff --git a/jsdoc b/jsdoc deleted file mode 100755 index 1069eb6..0000000 --- a/jsdoc +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -java -jar $JSDOC_HOME/jsrun.jar $JSDOC_HOME/app/run.js -t=$JSDOC_HOME/templates/jsdoc -c=jsdoc.conf -#java -jar $JSDOC_HOME/jsrun.jar $JSDOC_HOME/app/run.js -c=jsdoc.conf diff --git a/jsdoc.conf b/jsdoc.conf deleted file mode 100644 index f78ecb5..0000000 --- a/jsdoc.conf +++ /dev/null @@ -1,28 +0,0 @@ -{ - // Document the 'src' folder - _: ['src'], - - // Recursively scan to 10 levels deep - r: 10, - - // Include undocumented functions - //a: true, - - // Verbose output - v: true, - - // Include private items - //p: true, - - // Custom fields to add to documentation - D: {copyright: '2010 Ryan Williams'}, - - // Destination is 'docs' - d: 'docs', - - // Use our custom template - // XXX Moved to the cocos2d/jsdoc script - //t: '/usr/local/jsdoc-toolkit/templates/jsdoc', -} - -// vim:ft=javascript diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index 2299bbb..bbf80a2 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -104,10 +104,15 @@ function Compiler(configFile) { if (this.config.paths.hasOwnProperty(source)) { var dest = this.config.paths[source]; + var c = path.join(source, 'config.json'); if (path.existsSync(c)) { configs.push(c); } + c = path.join(source, 'libs/cocos2d/config.json'); + if (path.existsSync(c)) { + configs.push(c); + } } } diff --git a/package.json b/package.json index 3d7f0d1..cc1a301 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "main": "bin/cocos", "repository": "https://github.com/ryanwilliams/cocos2d-javascript.git", "bin": { - "cocos": "./bin/cocos-npm.js" + "cocos": "./bin/cocos.js" }, "licenses": [ { diff --git a/scripts/make.py b/scripts/make.py deleted file mode 100755 index b88f805..0000000 --- a/scripts/make.py +++ /dev/null @@ -1,286 +0,0 @@ -#!/usr/bin/env python - -from optparse import OptionParser -from cStringIO import StringIO -from string import Template -import re, os, base64, mimetypes, codecs -try: - import json -except: - import simplejson as json - -mimetypes.add_type('application/xml', '.tmx') -mimetypes.add_type('application/xml', '.tsx') -mimetypes.add_type('application/xml', '.plist') - -TEXT_MIMETYPES = 'application/xml text/plain text/json application/json text/html'.split(' ') -CODE_MIMETYPES = 'text/javascript application/javascript application/x-javascript'.split(' ') - -RESOURCE_TEMPLATE = Template(u'__resources__["$resource"] = {meta: {mimetype: "$mimetype"}, data: $data};') - -class Compiler(object): - config = None - output = 'cocos2d.js' - main_module = 'main' - extensions = ['js', 'tmx', 'tms', 'plist', 'gif', 'jpg', 'jpeg', 'png'] - header = u'' - footer = u'' - - def __init__(self, config='make.js'): - self.config = self.read_config(config) - print "Ouputting to: ", self.output - - def read_config(self, config_file): - print "Loading config:", config_file - f = codecs.open(config_file, 'r', encoding='utf-8') - config = self.read_json_file(config_file) - self.output = config['output'] - self.main_module = config['main_module'] or 'main' - self.extensions = config['extensions'] - - return config - - def make(self): - """ - Compile everything into a single script - """ - code = self.header - - # Prepend app globals needed for resources - code += '\n(function() {\n' - code += 'var __main_module_name__ = %s;\n' % json.dumps(self.main_module) - code += 'var __resources__ = [];\n' - code += 'function __imageResource(data) { var img = new Image(); img.src = data; return img; };\n' - for key, val in self.app_config_dict().items(): - code += 'var %s = %s;\n' % (key.upper(), json.dumps(val)) - - - # Add all the code - for source, dest in self.config['paths'].items(): - code += self.make_path(source, dest) - - - # Append module.js file -- this handles all the module loading - module_js_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'module.js') - code += codecs.open(module_js_path, 'r', encoding='utf-8').read() - - code += '\n})();\n' - - code += self.footer - - return code - - - def make_path(self, source_path, dest_path=None): - """ - Compile everything at a path and return the code - """ - if not dest_path: - dest_path = source_path - print 'Building Path:', source_path, ' => ', dest_path - - code = '' - files = self.scan_for_files(source_path) - for src_file in files: - if src_file.replace(os.sep, '/') in self.app_configs(): - # Skip config files because they're JSON not JavaScript - continue - - dst_file = self.dst_for_src(src_file) - mimetype = mimetypes.guess_type(src_file)[0] - - print 'Building File:', src_file, ' => ', dst_file - code += '\n'; - code += RESOURCE_TEMPLATE.substitute({ - 'mimetype': mimetype, - 'resource': dst_file, - 'data': self.make_resource(src_file), - }) - - return code - - def dst_for_src(self, path): - path = path.replace(os.sep, '/') - for source, dest in self.config['paths'].items(): - if path.startswith(source): - return re.sub('\/+', '/', re.sub(r'^' + source.replace('/', '\\/'), dest, path)) - - return path - - def app_configs(self): - """ - Returns an array of paths pointing to all the config.js files for the app - """ - configs = [u'src/libs/cocos2d/config.js', u'cocos2d/src/libs/cocos2d/config.js'] - for source, dest in self.config['paths'].items(): - c = os.path.join(source, 'config.js') - if os.path.exists(c): - configs.append(c) - - return configs - - - - def app_config_dict(self): - """ - Reads all the app's config.js files and returns a dictionary of their values - """ - vals = {} - for config in self.app_configs(): - if os.path.exists(config): - data = self.read_json_file(config) - vals.update(data) - - - return vals - - def read_json_file(self, path): - j = codecs.open(path, 'r', encoding='utf-8').read() - - # Strip comments - j = re.sub(r"\/\/.*", '', j) - j = re.sub(re.compile(r"\/\*.*?\*\/", re.DOTALL), '', j) - - # Fix unquoted keys - j = re.sub(r"{\s*(\w)", r'{"\1', j) - j = re.sub(r",\s*(\w)", r',"\1', j) - j = re.sub(r"(\w):", r'\1":', j) - - # Fix trailing comma - j = re.sub(re.compile(r",\s+}", re.DOTALL), '}', j) - - return json.loads(j) - - - def scan_for_files(self, path): - """ - Scan for files to build and return them as an array - """ - if os.path.isfile(path): - return [path] - - found_files = [] - - for root, dirs, files in os.walk(path): - for f in files: - if f[0] == '.': - # Skip hidden files - continue - - if self.extensions and os.path.splitext(f)[1][1:] not in self.extensions: - # Unwanted file extension - continue - - full_path = os.path.join(root, f) - found_files.append(full_path) - - return found_files - - - - def make_resource(self, filename): - """ - Returns a resource string for adding to the __resources__ global - """ - - mimetype = mimetypes.guess_type(filename)[0] - - is_code = (mimetype in CODE_MIMETYPES) - is_text = (mimetype in TEXT_MIMETYPES) - is_image = (mimetype.split('/')[0] == 'image') - - if is_code: - data = codecs.open(filename, 'r', encoding='utf-8').read() - data = self.parse_supers(data) - # Wrap code in function - data = "function(exports, require, module, __filename, __dirname) {\n%s\n}" % data - elif is_text: - data = codecs.open(filename, 'r', encoding='utf-8').read() - # Escape text by converting to json - data = json.dumps(data) - elif is_image: - data = open(filename, 'rb') - # Base64 encode image and create dataURL - data = self.b64(data) - data = '__imageResource("data:%s;base64,%s")' % (mimetype, data) - else: # is_binary - data = open(filename, 'rb') - data = self.b64(data) - data = '"%s"' % data - - return data - - def b64(self, data): - """ - Base 64 encode binary data - """ - output = StringIO() - data = base64.encode(data, output) - - # Remote whitespace from string - return re.sub('\s+', '', output.getvalue()) - - def parse_supers(self, code): - """ - Changes: - @super('foo', 'bar'); - @super() - @super - - Into: - arguments.callee.base.call(this, 'foo', 'bar'); - arguments.callee.base.call(this); - arguments.callee.base.apply(this, arguments); - """ - - def replace_super_apply(matches): - return '%sarguments.callee.base.apply(this, arguments);' % (matches.group('indent')) - - def replace_super(matches): - args = '' - if matches.group('args'): - args = ', %s' % matches.group('args') - - return '%sarguments.callee.base.call(this%s);' % (matches.group('indent'), args) - - super_re = re.compile('''(?P[ \t]*)@super\((?P.*)\)\s*;''') - code = super_re.sub(replace_super, code) - - super_re = re.compile('''(?P[ \t]*)@super\s*;''') - code = super_re.sub(replace_super_apply, code) - - return code - -def main(): - parser = OptionParser(usage="Usage: cocos make [options]") - parser.add_option("-c", "--config", dest="config", - help="configuration file. Default is make.js", metavar="CONFIG") - - parser.add_option("-f", "--file", dest="output", - help="write code to FILE. Overrides config file", metavar="FILE") - - parser.add_option("-s", "--source", dest="input", - help="compile everything in SRC. Config is ignored if specified", metavar="SRC") - - (options, args) = parser.parse_args() - - compiler = Compiler(options.config or 'make.js') - - if options.input: - code = compiler.make_path(options.input) - else: - code = compiler.make() - - output = options.output or compiler.output - if output: - print "Writing output to:", output - o = codecs.open(output, 'w', encoding='utf-8') - o.write(code) - o.close() - else: - print code - - -if __name__ == "__main__": - main() - diff --git a/scripts/module.js b/scripts/module.js deleted file mode 100644 index 0fc3b57..0000000 --- a/scripts/module.js +++ /dev/null @@ -1,145 +0,0 @@ -/*globals module exports resource require window Module __main_module_name__ __resources__*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -function resource(path) { - return __resources__[path].data; -} - -(function () { - var process = {}; - var modulePaths = ['/libs', '/']; - - var path; // Will be loaded further down - - function resolveModulePath(request, parent) { - // If not a relative path then search the modulePaths for it - var start = request.substring(0, 2); - if (start !== "./" && start !== "..") { - return modulePaths; - } - - var parentIsIndex = path.basename(parent.filename).match(/^index\.js$/), - parentPath = parentIsIndex ? parent.id : path.dirname(parent.id); - - // Relative path so searching inside parent's directory - return [path.dirname(parent.filename)]; - } - - function findModulePath(id, dirs) { - if (id.charAt(0) === '/') { - dirs = ['']; - } - for (var i = 0; i < dirs.length; i++) { - var dir = dirs[i]; - var p = path.join(dir, id); - - // Check for index first - if (path.exists(path.join(p, 'index.js'))) { - return path.join(p, 'index.js'); - } else if (path.exists(p + '.js')) { - return p + '.js'; - } - } - - return false; - } - - function loadModule(request, parent) { - parent = parent || process.mainModule; - - var paths = resolveModulePath(request, parent), - filename = findModulePath(request, paths); - - if (filename === false) { - throw "Unable to find module: " + request; - } - - - if (parent) { - var cachedModule = parent.moduleCache[filename]; - if (cachedModule) { - return cachedModule; - } - } - - //console.log('Loading module: ', filename); - - var module = new Module(filename, parent); - - // Assign main module to process - if (request == __main_module_name__ && !process.mainModule) { - process.mainModule = module; - } - - // Run all the code in the module - module._initialize(filename); - - return module; - } - - function Module(id, parent) { - this.id = id; - this.parent = parent; - this.children = []; - this.exports = {}; - - if (parent) { - this.moduleCache = parent.moduleCache; - parent.children.push(this); - } else { - this.moduleCache = {}; - } - this.moduleCache[this.id] = this; - - this.filename = null; - this.dirname = null; - } - - Module.prototype._initialize = function (filename) { - var module = this; - function require(request) { - return loadModule(request, module).exports; - } - - this.filename = filename; - - // Work around incase this IS the path module - if (path) { - this.dirname = path.dirname(filename); - } else { - this.dirname = ''; - } - - require.paths = modulePaths; - require.main = process.mainModule; - - __resources__[this.filename].data.apply(this.exports, [this.exports, require, this, this.filename, this.dirname]); - - return this; - }; - - // Manually load the path module because we need it to load other modules - path = (new Module('path'))._initialize('/path.js').exports; - - var util = loadModule('util').exports; - util.ready(function () { - // Populate globals - var globals = loadModule('global').exports; - for (var x in globals) { - if (globals.hasOwnProperty(x)) { - window[x] = globals[x]; - } - } - - process.mainModule = loadModule(__main_module_name__); - - // Add a global require. Useful in the debug console. - window.require = function require(request, parent) { - return loadModule(request, parent).exports; - }; - window.require.main = process.mainModule; - window.require.paths = modulePaths; - - }); -})(); diff --git a/scripts/new.py b/scripts/new.py deleted file mode 100755 index d758143..0000000 --- a/scripts/new.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python - -from optparse import OptionParser -import subprocess -import sys, re, os, base64, mimetypes, codecs, shutil - -INDEX_TEMPLATE = ''' - - - - - - {project_name} - - - -

        {project_name}

        -
        - - -''' - -MAKE_JS_TEMPLATE = ''' -{{ - "output": "public/{script_name}", - "extensions": ["js", "gif", "jpeg", "jpg", "png", "tmx", "tsx", "plist"], - "main_module": "main", - - "paths": {{ - "cocos2d/src" : "/", - "src" : "/" - }} -}} -''' - -MAIN_JS_TEMPLATE = ''' -// Import the cocos2d module -var cocos = require('cocos2d'), -// Import the geometry module - geo = require('geometry'); - -// Create a new layer -var {class_name} = cocos.nodes.Layer.extend({{ - init: function() {{ - // You must always call the super class version of init - @super; - - // Get size of canvas - var s = cocos.Director.get('sharedDirector').get('winSize'); - - // Create label - var label = cocos.nodes.Label.create({{string: '{project_name}', fontName: 'Arial', fontSize: 76}}); - - // Add label to layer - this.addChild({{child: label, z:1}}); - - // Position the label in the centre of the view - label.set('position', geo.ccp(s.width / 2, s.height / 2)); - }} -}}); - -// Initialise everything - -// Get director -var director = cocos.Director.get('sharedDirector'); - -// Attach director to our
        element -director.attachInView(document.getElementById('cocos2d-app')); - -// Create a scene -var scene = cocos.nodes.Scene.create(); - -// Add our layer to the scene -scene.addChild({{child: {class_name}.create()}}); - -// Run the scene -director.runWithScene(scene); -''' - - -def main(): - def removeNonAscii(s): - return "".join(i for i in s if ord(i) < 128) - - parser = OptionParser(usage="Usage: cocos new APP_PATH") - parser.add_option("-g", "--no-git", action="https://github.com/store_true", dest="nogit") - - (options, args) = parser.parse_args() - - if not str(args[0]).strip(): - print "Usage: cocos new APP_PATH" - return 1 - - - use_git = not options.nogit - project_path = os.path.abspath(args[0]) - project_name = os.path.basename(project_path) - script_name = removeNonAscii(project_name.lower().replace(' ', '_')) +'.js' - class_name = re.sub('(?:^| )(.)', lambda m: m.group(1).upper(), removeNonAscii(project_name.lower())) - - paths = ( - 'src', - 'src/resources', - 'public', - ) - - # Create initial folders - print "Creating cocos2d-javascript project in: %s" % project_path - for p in paths: - full_path = os.path.join(project_path, p) - if not os.path.exists(full_path): - print "Creating new directory : %s" % full_path - os.makedirs(full_path) - - subs = {'project_name': project_name, 'script_name': script_name, 'class_name': class_name} - - # Write out public/index.html - index = open(os.path.join(project_path, 'public/index.html'), 'w') - index.write(INDEX_TEMPLATE.format(**subs)) - index.close() - - # Write out make.js - make_js = open(os.path.join(project_path, 'make.js'), 'w') - make_js.write(MAKE_JS_TEMPLATE.format(**subs)) - make_js.close() - - # Write out src/main.js - main_js = open(os.path.join(project_path, 'src/main.js'), 'w') - main_js.write(MAIN_JS_TEMPLATE.format(**subs)) - main_js.close() - - - # Create cocos2d code - if use_git: - print "Creating cocos2d git submodule" - os.chdir(project_path) - subprocess.call(['git', 'init']) - subprocess.call(['git', 'submodule', 'add', 'git://github.com/ryanwilliams/cocos2d-javascript.git', 'cocos2d']) - else: - print "Copying cocos2d" - cocos_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) - shutil.copytree(cocos_path, os.path.join(project_path, 'cocos2d')) - os.chdir(project_path) - - shutil.copy2('cocos2d/cocos', './cocos') - shutil.copy2('cocos2d/cocos.bat', './cocos.bat') - - - - -if __name__ == "__main__": - main() diff --git a/scripts/server.py b/scripts/server.py deleted file mode 100755 index 9f3a763..0000000 --- a/scripts/server.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python - -from optparse import OptionParser -import SocketServer -import SimpleHTTPServer, BaseHTTPServer -import urllib -import threading -from make import Compiler -import os, sys, re, time, socket - -CODE_URL = None -CONFIG_FILE = 'make.js' - -class Cocos2D(SimpleHTTPServer.SimpleHTTPRequestHandler): - - def __init__(self, *args): - global CODE_URL, CONFIG_FILE - self.compiler = Compiler(CONFIG_FILE) - if not CODE_URL: - CODE_URL = re.sub('^/?public', '', self.compiler.output) - print "Serving as:", CODE_URL - SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, *args) - - - def do_GET(self): - self.path = self.path.split('?')[0] # Strip off params - if self.path == '/': - self.path = '/public/index.html' - return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) - else: - if CODE_URL == self.path: - print "Building code" - code = self.compiler.make() - - self.send_response(200) - self.send_header('Content-Type', 'text/javascript') - self.end_headers() - self.wfile.write(code.encode('utf-8')) - - else: - self.path = '/public' + os.path.normpath(self.path) - return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self) - -def main(): - global CODE_URL, CONFIG_FILE - parser = OptionParser(usage="Usage: cocos server [options]") - parser.add_option("-c", "--config", dest="config", - help="configuration file. Default is make.js", metavar="CONFIG") - - parser.add_option("-u", "--url", dest="url", - help="the URL to serve the JS as. Default is output defined in the config file", metavar="URL") - - parser.add_option("-l", "--host", dest="host", - help="the host/ip to listen on. Default is 127.0.0.1", metavar="HOST") - - parser.add_option("-p", "--port", dest="port", - help="the port to listen on. Default is 4000", metavar="PORT") - - (options, args) = parser.parse_args() - - if options.url and options.url[0] != '/': - options.url = '/' + options.url - - host = options.host or 'localhost' - port = int(options.port) if options.port else 4000 - - if options.url: - CODE_URL = options.url - if options.config: - CONFIG_FILE = options.config - - - httpd = BaseHTTPServer.HTTPServer((host, port), Cocos2D) - print "Listening at http://%s:%d/" % (host, port) - try: - httpd.serve_forever() - - except (KeyboardInterrupt, SystemExit): - print "Shutting down" - return 0 - - return 1 - - -if __name__ == "__main__": - sys.exit(main()) - diff --git a/support/Make.bat b/support/Make.bat new file mode 100755 index 0000000..155a4ff --- /dev/null +++ b/support/Make.bat @@ -0,0 +1,2 @@ +@echo off +"%~dp0\cocos.bat" make diff --git a/support/Server.bat b/support/Server.bat new file mode 100755 index 0000000..bc35ca8 --- /dev/null +++ b/support/Server.bat @@ -0,0 +1,2 @@ +@echo off +"%~dp0\cocos.bat" server diff --git a/make.json b/tests/make.json similarity index 63% rename from make.json rename to tests/make.json index ac3af26..505d6c7 100644 --- a/make.json +++ b/tests/make.json @@ -13,11 +13,8 @@ // Paths to the code that should be included in the application "paths": { - "src" : "/", - "tests/commonjs/tests/" : "/commonjs/", - "tests/cocos2d/" : "/cocos2d/", - "tests/commonjs.js": "/commonjs.js", - "tests/qunit.js": "/qunit.js", - "tests/main.js": "/main.js" + "../src" : "/", + "src/commonjs/tests/" : "/commonjs/", + "src/" : "/" } } diff --git a/public/index.html b/tests/public/index.html similarity index 100% rename from public/index.html rename to tests/public/index.html diff --git a/tests/cocos2d/SpriteTest.js b/tests/src/cocos2d/SpriteTest.js similarity index 100% rename from tests/cocos2d/SpriteTest.js rename to tests/src/cocos2d/SpriteTest.js diff --git a/tests/cocos2d/TileMapTest.js b/tests/src/cocos2d/TileMapTest.js similarity index 100% rename from tests/cocos2d/TileMapTest.js rename to tests/src/cocos2d/TileMapTest.js diff --git a/tests/cocos2d/main.js b/tests/src/cocos2d/main.js similarity index 100% rename from tests/cocos2d/main.js rename to tests/src/cocos2d/main.js diff --git a/tests/cocos2d/resources/TileMaps/fixed-ortho-test2.png b/tests/src/cocos2d/resources/TileMaps/fixed-ortho-test2.png similarity index 100% rename from tests/cocos2d/resources/TileMaps/fixed-ortho-test2.png rename to tests/src/cocos2d/resources/TileMaps/fixed-ortho-test2.png diff --git a/tests/cocos2d/resources/TileMaps/iso-test.png b/tests/src/cocos2d/resources/TileMaps/iso-test.png similarity index 100% rename from tests/cocos2d/resources/TileMaps/iso-test.png rename to tests/src/cocos2d/resources/TileMaps/iso-test.png diff --git a/tests/cocos2d/resources/TileMaps/iso-test.tmx b/tests/src/cocos2d/resources/TileMaps/iso-test.tmx similarity index 100% rename from tests/cocos2d/resources/TileMaps/iso-test.tmx rename to tests/src/cocos2d/resources/TileMaps/iso-test.tmx diff --git a/tests/cocos2d/resources/TileMaps/ortho-test1.png b/tests/src/cocos2d/resources/TileMaps/ortho-test1.png similarity index 100% rename from tests/cocos2d/resources/TileMaps/ortho-test1.png rename to tests/src/cocos2d/resources/TileMaps/ortho-test1.png diff --git a/tests/cocos2d/resources/TileMaps/orthogonal-test1.tmx b/tests/src/cocos2d/resources/TileMaps/orthogonal-test1.tmx similarity index 100% rename from tests/cocos2d/resources/TileMaps/orthogonal-test1.tmx rename to tests/src/cocos2d/resources/TileMaps/orthogonal-test1.tmx diff --git a/tests/cocos2d/resources/TileMaps/orthogonal-test1.tsx b/tests/src/cocos2d/resources/TileMaps/orthogonal-test1.tsx similarity index 100% rename from tests/cocos2d/resources/TileMaps/orthogonal-test1.tsx rename to tests/src/cocos2d/resources/TileMaps/orthogonal-test1.tsx diff --git a/tests/cocos2d/resources/TileMaps/orthogonal-test2.tmx b/tests/src/cocos2d/resources/TileMaps/orthogonal-test2.tmx similarity index 100% rename from tests/cocos2d/resources/TileMaps/orthogonal-test2.tmx rename to tests/src/cocos2d/resources/TileMaps/orthogonal-test2.tmx diff --git a/tests/cocos2d/resources/TileMaps/orthogonal-test4.tmx b/tests/src/cocos2d/resources/TileMaps/orthogonal-test4.tmx similarity index 100% rename from tests/cocos2d/resources/TileMaps/orthogonal-test4.tmx rename to tests/src/cocos2d/resources/TileMaps/orthogonal-test4.tmx diff --git a/tests/cocos2d/resources/animations/dragon_animation.png b/tests/src/cocos2d/resources/animations/dragon_animation.png similarity index 100% rename from tests/cocos2d/resources/animations/dragon_animation.png rename to tests/src/cocos2d/resources/animations/dragon_animation.png diff --git a/tests/cocos2d/resources/animations/grossini.plist b/tests/src/cocos2d/resources/animations/grossini.plist similarity index 100% rename from tests/cocos2d/resources/animations/grossini.plist rename to tests/src/cocos2d/resources/animations/grossini.plist diff --git a/tests/cocos2d/resources/animations/grossini.png b/tests/src/cocos2d/resources/animations/grossini.png similarity index 100% rename from tests/cocos2d/resources/animations/grossini.png rename to tests/src/cocos2d/resources/animations/grossini.png diff --git a/tests/cocos2d/resources/animations/grossini_blue.plist b/tests/src/cocos2d/resources/animations/grossini_blue.plist similarity index 100% rename from tests/cocos2d/resources/animations/grossini_blue.plist rename to tests/src/cocos2d/resources/animations/grossini_blue.plist diff --git a/tests/cocos2d/resources/animations/grossini_blue.png b/tests/src/cocos2d/resources/animations/grossini_blue.png similarity index 100% rename from tests/cocos2d/resources/animations/grossini_blue.png rename to tests/src/cocos2d/resources/animations/grossini_blue.png diff --git a/tests/cocos2d/resources/animations/grossini_gray.plist b/tests/src/cocos2d/resources/animations/grossini_gray.plist similarity index 100% rename from tests/cocos2d/resources/animations/grossini_gray.plist rename to tests/src/cocos2d/resources/animations/grossini_gray.plist diff --git a/tests/cocos2d/resources/animations/grossini_gray.png b/tests/src/cocos2d/resources/animations/grossini_gray.png similarity index 100% rename from tests/cocos2d/resources/animations/grossini_gray.png rename to tests/src/cocos2d/resources/animations/grossini_gray.png diff --git a/tests/cocos2d/resources/b1.png b/tests/src/cocos2d/resources/b1.png similarity index 100% rename from tests/cocos2d/resources/b1.png rename to tests/src/cocos2d/resources/b1.png diff --git a/tests/cocos2d/resources/b2.png b/tests/src/cocos2d/resources/b2.png similarity index 100% rename from tests/cocos2d/resources/b2.png rename to tests/src/cocos2d/resources/b2.png diff --git a/tests/cocos2d/resources/f1.png b/tests/src/cocos2d/resources/f1.png similarity index 100% rename from tests/cocos2d/resources/f1.png rename to tests/src/cocos2d/resources/f1.png diff --git a/tests/cocos2d/resources/f2.png b/tests/src/cocos2d/resources/f2.png similarity index 100% rename from tests/cocos2d/resources/f2.png rename to tests/src/cocos2d/resources/f2.png diff --git a/tests/cocos2d/resources/grossini_dance_atlas-red.png b/tests/src/cocos2d/resources/grossini_dance_atlas-red.png similarity index 100% rename from tests/cocos2d/resources/grossini_dance_atlas-red.png rename to tests/src/cocos2d/resources/grossini_dance_atlas-red.png diff --git a/tests/cocos2d/resources/grossini_dance_atlas.png b/tests/src/cocos2d/resources/grossini_dance_atlas.png similarity index 100% rename from tests/cocos2d/resources/grossini_dance_atlas.png rename to tests/src/cocos2d/resources/grossini_dance_atlas.png diff --git a/tests/cocos2d/resources/r1.png b/tests/src/cocos2d/resources/r1.png similarity index 100% rename from tests/cocos2d/resources/r1.png rename to tests/src/cocos2d/resources/r1.png diff --git a/tests/cocos2d/resources/r2.png b/tests/src/cocos2d/resources/r2.png similarity index 100% rename from tests/cocos2d/resources/r2.png rename to tests/src/cocos2d/resources/r2.png diff --git a/tests/commonjs b/tests/src/commonjs similarity index 100% rename from tests/commonjs rename to tests/src/commonjs diff --git a/tests/commonjs.js b/tests/src/commonjs.js similarity index 100% rename from tests/commonjs.js rename to tests/src/commonjs.js diff --git a/tests/cocos2d/config.json b/tests/src/config.json similarity index 100% rename from tests/cocos2d/config.json rename to tests/src/config.json diff --git a/tests/main.js b/tests/src/main.js similarity index 100% rename from tests/main.js rename to tests/src/main.js diff --git a/tests/qunit.js b/tests/src/qunit.js similarity index 100% rename from tests/qunit.js rename to tests/src/qunit.js From a8e0be5bd00d4c3275a1dd5a15139f92e27f2957 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 9 Feb 2011 18:22:10 +1300 Subject: [PATCH 053/176] Simplified make.json by making most things optional --- lib/cocos/commands/make.js | 28 ++++++++++++++++++++++++++-- tests/make.json | 10 ---------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index bbf80a2..9bf48c6 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -9,7 +9,7 @@ var sys = require('sys'), Template = require('../template').Template, mimetypes = require('../mimetypes'); -var options = [ +var OPTIONS = [ { short: 'f', long: 'file', description: 'File to write output to. Overrides config file', @@ -30,6 +30,16 @@ var RESOURCE_TEMPLATE = new Template('__resources__["$resource"] = {meta: {mimet var TEXT_MIMETYPES = 'application/xml text/plain text/json application/json text/html'.split(' '); var CODE_MIMETYPES = 'text/javascript application/javascript application/x-javascript'.split(' '); + +var DEFAULT_MAKE_JSON = { + output: "cocos2d-app.js", + extensions: ["js", "gif", "jpeg", "jpg", "png", "tmx", "tsx", "plist"], + ignore: null, + main_module: "main", + paths: {} +}; +DEFAULT_MAKE_JSON.paths[path.join(__dirname, '../../../src')] = '/'; + /** * Merge an number of objects together and return the result as a new object */ @@ -47,6 +57,19 @@ function merge() { return o; } +/** + * Merges 2 objects loaded from a make.json files or simiular. + * + * @param {Object} conf1 First config + * @param {Object} conf2 Second config. Will override conf1 + * @returns Object A new object + */ +function mergeMakeConfig(conf1, conf2) { + var o = merge(conf1, conf2); + o.paths = merge(conf1.paths, conf2.paths); + return o; +} + /** * @memberOf cocos.commands.make * @class Compile a cocos2d project into a single javascript file @@ -57,6 +80,7 @@ function Compiler(configFile) { sys.puts('Loading config: ' + configFile); var config = this.readJSONFile(configFile); + config = mergeMakeConfig(DEFAULT_MAKE_JSON, config); this.output = config.output; this.mainModule = config.mainModule || config.main_module; this.extensions = config.extensions; @@ -308,7 +332,7 @@ exports.Compiler = Compiler; exports.description = 'Compile a cocos2d project into a single javascript file'; exports.run = function () { - opts.parse(options, true); + opts.parse(OPTIONS, true); var config = opts.get('config') || 'make.json', compiler = new Compiler(config), diff --git a/tests/make.json b/tests/make.json index 505d6c7..dca353a 100644 --- a/tests/make.json +++ b/tests/make.json @@ -2,18 +2,8 @@ // Where to write the final file to "output": "public/tests.js", - // Filetypes to embed into the javascript - "extensions": ["js", "gif", "jpeg", "jpg", "png", "tmx", "tsx", "plist"], - - // Files to skip - "ignore": null, - - // Module that run at startup - "main_module": "main", - // Paths to the code that should be included in the application "paths": { - "../src" : "/", "src/commonjs/tests/" : "/commonjs/", "src/" : "/" } From f795145c136eefedb13765e35058d231ea16a441 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 9 Feb 2011 18:30:14 +1300 Subject: [PATCH 054/176] Moved mount point of builtin modules to avoid conflicts with user modules --- lib/cocos/commands/make.js | 2 +- lib/cocos/commands/module_js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index 9bf48c6..498a36a 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -38,7 +38,7 @@ var DEFAULT_MAKE_JSON = { main_module: "main", paths: {} }; -DEFAULT_MAKE_JSON.paths[path.join(__dirname, '../../../src')] = '/'; +DEFAULT_MAKE_JSON.paths[path.join(__dirname, '../../../src')] = '/__builtin__'; /** * Merge an number of objects together and return the result as a new object diff --git a/lib/cocos/commands/module_js b/lib/cocos/commands/module_js index 0fc3b57..8eac07d 100644 --- a/lib/cocos/commands/module_js +++ b/lib/cocos/commands/module_js @@ -8,7 +8,7 @@ function resource(path) { (function () { var process = {}; - var modulePaths = ['/libs', '/']; + var modulePaths = ['/__builtin__', '/__builtin__/libs', '/libs', '/']; var path; // Will be loaded further down @@ -120,7 +120,7 @@ function resource(path) { }; // Manually load the path module because we need it to load other modules - path = (new Module('path'))._initialize('/path.js').exports; + path = (new Module('path'))._initialize('/__builtin__/path.js').exports; var util = loadModule('util').exports; util.ready(function () { @@ -143,3 +143,5 @@ function resource(path) { }); })(); + +// vim:ft=javascript From 1d2f1da0aac91ab629f7c1196c17b718b948334f Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 9 Feb 2011 18:51:53 +1300 Subject: [PATCH 055/176] Removed platform echo inside cocos shell script --- bin/cocos.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/cocos.sh b/bin/cocos.sh index b77bb7c..4bb7d1e 100755 --- a/bin/cocos.sh +++ b/bin/cocos.sh @@ -4,23 +4,23 @@ DIR=`dirname $0` case `uname -a` in -Linux*x86_64*) echo "Linux 64 bit" +Linux*x86_64*) "$DIR/../support/node-builds/lin64/node" "$DIR/cocos.js" "$@" ;; -Linux*i686*) echo "Linux 32 bit" +Linux*i686*) "$DIR/../support/node-builds/lin32/node" "$DIR/cocos.js" "$@" ;; -Darwin*) echo "OSX" +Darwin*) "$DIR/../support/node-builds/osx64/node" "$DIR/cocos.js" "$@" ;; -CYGWIN*) echo "Cygwin" +CYGWIN*) "$DIR/../support/node-builds/win32/node.exe" "$DIR/cocos.js" "$@" ;; -MING*) echo "MingW" +MING*) "$DIR/../support/node-builds/win32/node.exe" "$DIR/cocos.js" "$@" ;; From 7f1496a55b2b1ec136a1e6ae83675d3ad442742e Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 9 Feb 2011 23:49:17 +1300 Subject: [PATCH 056/176] Added Node.js 'new' command script to create new cocos2d projects --- lib/cocos/commands/make.js | 2 +- lib/cocos/commands/new.js | 101 +++++++++++++++++++++++++-- lib/cocos/opts.js | 2 +- lib/cocos/skeleton/make.json | 6 ++ lib/cocos/skeleton/public/index.html | 34 +++++++++ lib/cocos/skeleton/src/main.js | 41 +++++++++++ lib/cocos/template.js | 2 +- 7 files changed, 180 insertions(+), 8 deletions(-) create mode 100644 lib/cocos/skeleton/make.json create mode 100644 lib/cocos/skeleton/public/index.html create mode 100644 lib/cocos/skeleton/src/main.js diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index 498a36a..52e3c57 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -26,7 +26,7 @@ mimetypes.addType('application/xml', '.tmx'); mimetypes.addType('application/xml', '.tsx'); mimetypes.addType('application/xml', '.plist'); -var RESOURCE_TEMPLATE = new Template('__resources__["$resource"] = {meta: {mimetype: "$mimetype"}, data: $data};'); +var RESOURCE_TEMPLATE = new Template('__resources__["$resource$"] = {meta: {mimetype: "$mimetype$"}, data: $data$};'); var TEXT_MIMETYPES = 'application/xml text/plain text/json application/json text/html'.split(' '); var CODE_MIMETYPES = 'text/javascript application/javascript application/x-javascript'.split(' '); diff --git a/lib/cocos/commands/new.js b/lib/cocos/commands/new.js index 4141143..bf8b503 100644 --- a/lib/cocos/commands/new.js +++ b/lib/cocos/commands/new.js @@ -1,11 +1,102 @@ -/*globals require module exports process console*/ +/*globals require module exports process console __dirname*/ /*jslint undef: true, strict: true, white: true, newcap: true, indent: 4 */ "use strict"; -var sys = require('sys'); +var sys = require('sys'), + opts = require('../opts'), + path = require('path'), + Template = require('../template').Template, + fs = require('fs'); + +var SKELETON_PATH = path.join(__dirname, '../skeleton'); + +var ARGS = [ + {name: 'APP_PATH', required: true} +]; + + +function camelCase(str, upperFirst) { + if (upperFirst) { + return str.replace(/(^.|[_\s]+[a-zA-Z])/g, function (s) { + return s.replace(/[_\s]/g, '').toUpperCase(); + }); + } else { + return str.replace(/_+[a-zA-Z]/g, function (s) { + return s.replace(/[_\s]/g, '').toUpperCase(); + }); + } +} +function snakeCase(str) { + str = str.replace(/([A-Z]+)([A-Z][a-z])/, '$1_$2'); + str = str.replace(/([a-z\d])([A-Z])/, '$1_$2'); + str = str.replace('-', '_'); + + return str.toLowerCase(); +} +function titleize(str) { + return str.replace(/(^.|_+[a-zA-Z])/g, function (s) { + return s.replace(/[_\s]/g, ' ').toUpperCase(); + }); +} + +function mkdir(dir, mode) { + mode = mode || 511; // Octal = 0777; + var paths = [dir]; + var d = dir; + while ((d = path.dirname(d)) && d != '/') { + paths.unshift(d); + } + + for (var i = 0, len = paths.length; i < len; i++) { + var p = paths[i]; + if (!path.existsSync(p)) { + fs.mkdirSync(p, mode); + } + } +} exports.description = 'Create a new cocos2d project'; -exports.run = function (opts) { - sys.puts('Not implemented yet'); - process.exit(1); +exports.run = function () { + opts.parse([], ARGS, true); + + var fullPath = path.normalize(path.join(process.cwd(), opts.arg('APP_PATH'))), + basename = path.basename(fullPath), + classname = camelCase(basename, true), + filename = snakeCase(classname), + appname = titleize(filename); + + mkdir(fullPath); + + sys.puts("Writing new project named '" + classname + "' to: " + fullPath); + + function copyTemplate(src, dst) { + if (fs.statSync(src).isDirectory()) { + mkdir(dst); + sys.puts("Created Directory: " + dst); + + var files = fs.readdirSync(src); + for (var i = 0, len = files.length; i < len; i++) { + var file = files[i]; + if (file[0] == '.') { + // Skip hidden files + continue; + } + + var dstFile = path.join(dst, path.basename(file)); + copyTemplate(path.join(src, file), dstFile); + } + } else { + var tmp = new Template(fs.readFileSync(src, 'utf8')); + var data = tmp.substitute({ + appname: appname, + classname: classname, + filename: filename, + basename: basename + }); + fs.writeFileSync(dst, data, 'utf8'); + sys.puts("Created File: " + dst); + } + } + + copyTemplate(SKELETON_PATH, fullPath); }; diff --git a/lib/cocos/opts.js b/lib/cocos/opts.js index ff16c1d..2559d3a 100644 --- a/lib/cocos/opts.js +++ b/lib/cocos/opts.js @@ -154,7 +154,7 @@ exports.parse = function (options, params, help) { if (options[i].long) checkDup(options[i], 'long'); } - for (var i=2; i + + + + + $appname$ + + + +

        $appname$

        +
        + + diff --git a/lib/cocos/skeleton/src/main.js b/lib/cocos/skeleton/src/main.js new file mode 100644 index 0000000..285134e --- /dev/null +++ b/lib/cocos/skeleton/src/main.js @@ -0,0 +1,41 @@ +// Import the cocos2d module +var cocos = require('cocos2d'), +// Import the geometry module + geo = require('geometry'); + +// Create a new layer +var $classname$ = cocos.nodes.Layer.extend({ + init: function() { + // You must always call the super class version of init + $classname$.superclass.init.call(this); + + // Get size of canvas + var s = cocos.Director.get('sharedDirector').get('winSize'); + + // Create label + var label = cocos.nodes.Label.create({string: '$appname$', fontName: 'Arial', fontSize: 76}); + + // Add label to layer + this.addChild({child: label, z:1}); + + // Position the label in the centre of the view + label.set('position', geo.ccp(s.width / 2, s.height / 2)); + } +}); + +// Initialise everything + +// Get director +var director = cocos.Director.get('sharedDirector'); + +// Attach director to our
        element +director.attachInView(document.getElementById('$filename$_app')); + +// Create a scene +var scene = cocos.nodes.Scene.create(); + +// Add our layer to the scene +scene.addChild({child: $classname$.create()}); + +// Run the scene +director.runWithScene(scene); diff --git a/lib/cocos/template.js b/lib/cocos/template.js index a52a718..bfabba0 100644 --- a/lib/cocos/template.js +++ b/lib/cocos/template.js @@ -10,7 +10,7 @@ function Template(str) { var newStr = this.string; for (var key in subs) { if (subs.hasOwnProperty(key)) { - newStr = newStr.replace('$' + key, subs[key]); + newStr = newStr.replace(new RegExp('\\$' + key + '\\$', 'g'), subs[key]); } } From 93c606d5c809d7f129397283e11f6aa89d08a8b8 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 10 Feb 2011 00:16:09 +1300 Subject: [PATCH 057/176] Allowed cocos.sh to be symlinked anywhere --- bin/cocos.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/cocos.sh b/bin/cocos.sh index 4bb7d1e..fc25373 100755 --- a/bin/cocos.sh +++ b/bin/cocos.sh @@ -1,7 +1,11 @@ #!/bin/sh -e # lets check if we have the submodules initialized -DIR=`dirname $0` +if [ -h $0 ]; then + DIR=$(dirname $(readlink $0)) +else + DIR=$(dirname $0) +fi case `uname -a` in Linux*x86_64*) From 43d2e4951d28c6e1facf042cd03bbdae6c7d64f1 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 10 Feb 2011 20:52:03 +1300 Subject: [PATCH 058/176] Added .npmignore to remove precompiled node.js binaries --- .npmignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..296b2cc --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +support/ From eb29b7d1622c9b2a802053bef68d972064487792 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 10 Feb 2011 20:52:55 +1300 Subject: [PATCH 059/176] Updated package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cc1a301..cab8aee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cocos2d", - "description": "Port of cocos2d-iphone for the Web", + "description": "Port of cocos2d for the Web", "version": "0.0.1", "homepage": "http://cocos2d-javascript.org/", "engines": { From 6184e6b5d96d63fb866612ea278267a6f591d747 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 10 Feb 2011 21:00:47 +1300 Subject: [PATCH 060/176] Updated package.json again --- package.json | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index cab8aee..a2c0384 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,26 @@ { - "name": "cocos2d", - "description": "Port of cocos2d for the Web", - "version": "0.0.1", - "homepage": "http://cocos2d-javascript.org/", - "engines": { - "node": ">= 0.2.0" - }, - "author": "Ryan Williams ", - "main": "bin/cocos", - "repository": "https://github.com/ryanwilliams/cocos2d-javascript.git", - "bin": { - "cocos": "./bin/cocos.js" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/ryanwilliams/cocos2d-javascript/blob/master/LICENSE" - } - ] + "name": "cocos2d", + "author": "Ryan Williams ", + "description": "Port of the cocos2d game engine for the Web", + "version": "0.0.1", + "homepage": "http://cocos2d-javascript.org/", + + "engines": { + "node": ">= 0.2.0" + }, + "main": "bin/cocos", + + "repository": { + "type" : "git" , + "url" : "https://github.com/ryanwilliams/cocos2d-javascript.git" + }, + + "bin": { + "cocos": "./bin/cocos.js" + }, + + "licenses": [{ + "type": "MIT", + "url": "https://github.com/ryanwilliams/cocos2d-javascript/blob/master/LICENSE" + }] } From 01bddbc18bdf68546571c7abd44dcbc49ea7f580 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 10 Feb 2011 21:59:01 +1300 Subject: [PATCH 061/176] Updated .npmignore --- .npmignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.npmignore b/.npmignore index 296b2cc..b166606 100644 --- a/.npmignore +++ b/.npmignore @@ -1 +1,3 @@ support/ +*~ +.* From c0fa98a1cba197c7f31f15f7f5bbdddd6b85dce7 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 12 Feb 2011 11:39:25 +1300 Subject: [PATCH 062/176] Updated make task so it always outputs to 'build/' --- lib/cocos/commands/make.js | 55 ++++++++++++++++++++++++++-- lib/cocos/skeleton/make.json | 2 +- lib/cocos/skeleton/public/index.html | 1 - 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index 52e3c57..3e9a8ec 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -19,7 +19,6 @@ var OPTIONS = [ long: 'config', description: 'Configuration file. Default is make.json', value: true } - ]; mimetypes.addType('application/xml', '.tmx'); @@ -330,19 +329,69 @@ function Compiler(configFile) { exports.Compiler = Compiler; +function mkdir(dir, mode) { + mode = mode || 511; // Octal = 0777; + + if (dir[0] != '/') { + dir = path.join(process.cwd(), dir); + } + + var paths = [dir]; + var d = dir; + while ((d = path.dirname(d)) && d != '/') { + console.log('foo', d); + paths.unshift(d); + } + + for (var i = 0, len = paths.length; i < len; i++) { + var p = paths[i]; + if (!path.existsSync(p)) { + fs.mkdirSync(p, mode); + } + } +} + + +function copyFolder(src, dst) { + if (fs.statSync(src).isDirectory()) { + mkdir(dst); + sys.puts("Created directory: " + dst); + + var files = fs.readdirSync(src); + for (var i = 0, len = files.length; i < len; i++) { + var file = files[i]; + if (file[0] == '.') { + // Skip hidden files + continue; + } + + var dstFile = path.join(dst, path.basename(file)); + copyFolder(path.join(src, file), dstFile); + } + } else { + var data = fs.readFileSync(src); + fs.writeFileSync(dst, data, 'utf8'); + sys.puts("Copied file: " + dst); + } +} + exports.description = 'Compile a cocos2d project into a single javascript file'; exports.run = function () { opts.parse(OPTIONS, true); var config = opts.get('config') || 'make.json', compiler = new Compiler(config), - output = opts.get('file') || compiler.output; + output = opts.get('file') || compiler.output, + outputDir = 'build/'; var code = compiler.make(); if (output) { sys.puts("Writing output to: " + output); - fs.writeFileSync(output, code, 'utf8'); + + copyFolder('public', 'build', true); + + fs.writeFileSync(path.join(outputDir, output), code, 'utf8'); } else { sys.puts(code); } diff --git a/lib/cocos/skeleton/make.json b/lib/cocos/skeleton/make.json index 2ec806b..d438fcc 100644 --- a/lib/cocos/skeleton/make.json +++ b/lib/cocos/skeleton/make.json @@ -1,5 +1,5 @@ { - "output": "$filename$.js", + "output": "$filename$.js", "paths": { "src" : "/" } diff --git a/lib/cocos/skeleton/public/index.html b/lib/cocos/skeleton/public/index.html index 8ed67d6..2b39fbf 100644 --- a/lib/cocos/skeleton/public/index.html +++ b/lib/cocos/skeleton/public/index.html @@ -1,4 +1,3 @@ - From 9e7ced93efe093232890a2f429d7ad15dcb356b3 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 12 Feb 2011 13:18:52 +1300 Subject: [PATCH 063/176] Added install.sh script for folks without node.js + npm --- install.sh | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100755 install.sh diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..6cdb094 --- /dev/null +++ b/install.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +if which npm &> /dev/null +then + echo "NPM is installed. You should probably install cocos2d-javascript as an npm package using this command instead:\n npm install .\n" + + read -p "Continue anyway? (y/n) : " yn + case $yn in + [Nn]* ) exit;; + [Yy]* ) break;; + * ) echo "Enter 'y' or 'n'" + esac +fi + +DIR=`dirname $0` + +read -p "Where should I install to? (/usr/local/cocos2d-javascript/) : " install_to + +if [ -z "$install_to" ] +then + install_to='/usr/local/cocos2d-javascript/' +fi + +echo "Installing to: $install_to" + +mkdir -p $install_to + +cd $DIR + +for file in `find * \( ! -regex '.*/\..*' \) -type f` +do + dst="$install_to/$file" + dst_dir=`dirname $dst` + if [ ! -d $dst_dir ] + then + mkdir -p $dst_dir + fi + + cp $file $dst +done + +cd - + +echo "All files copied." + +ln -s $install_to/bin/cocos.sh /usr/local/bin/cocos + +echo "Symlinked 'cocos' executable to /usr/local/bin/cocos\n" + +echo "Installation complete\n\n" + +echo "You should now be able to type 'cocos' and get a list of available commands." + + From 1dacf0a0854071189477cb972d8338acfa216f15 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 12 Feb 2011 16:09:21 +1300 Subject: [PATCH 064/176] Added NSIS script to generate MS Win installer --- .gitignore | 2 + support/win32/installer.nsi | 623 ++++++++++++++++++++++++++++++++++++ 2 files changed, 625 insertions(+) create mode 100755 support/win32/installer.nsi diff --git a/.gitignore b/.gitignore index 15205f4..423dcf4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ *.swp *.pyc +*~ jsdocs/ docs/ public/cocos2d.js public/tests.js +Cocos2D\ JavaScript*Setup.exe diff --git a/support/win32/installer.nsi b/support/win32/installer.nsi new file mode 100755 index 0000000..1948fa7 --- /dev/null +++ b/support/win32/installer.nsi @@ -0,0 +1,623 @@ +; Script generated by the HM NIS Edit Script Wizard. + +RequestExecutionLevel admin + +; HM NIS Edit Wizard helper defines +!define ROOT_PATH "..\.." +!define PRODUCT_NAME "Cocos2D JavaScript" +!define PRODUCT_VERSION "v0.0.1" +!define PRODUCT_WEB_SITE "http://cocos2d-javascript.org/" +!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\New Project.exe" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" +!define PRODUCT_UNINST_ROOT_KEY "HKLM" + +; MUI 1.67 compatible ------ +!include "MUI.nsh" + +; MUI Settings +!define MUI_ABORTWARNING +!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" + +; Welcome page +!insertmacro MUI_PAGE_WELCOME +; License page +!insertmacro MUI_PAGE_LICENSE "${ROOT_PATH}\LICENSE" +; Directory page +!insertmacro MUI_PAGE_DIRECTORY +; Instfiles page +!insertmacro MUI_PAGE_INSTFILES +; Finish page +!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt" +!insertmacro MUI_PAGE_FINISH + +; Uninstaller pages +!insertmacro MUI_UNPAGE_INSTFILES + +; Language files +!insertmacro MUI_LANGUAGE "English" + +; MUI end ------ + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +OutFile "${ROOT_PATH}\${PRODUCT_NAME} ${PRODUCT_VERSION} Setup.exe" +InstallDir "$PROGRAMFILES\Cocos2D JavaScript" +InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" +ShowInstDetails show +ShowUnInstDetails show + +Section "MainSection" SEC01 + SetOutPath "$INSTDIR\bin" + SetOverwrite ifnewer + File "${ROOT_PATH}\bin\New Project.exe" + CreateDirectory "$SMPROGRAMS\Cocos2D JavaScript" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Create new project.lnk" "$INSTDIR\bin\New Project.exe" + File "${ROOT_PATH}\bin\Compile Project.exe" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Compile project.lnk" "$INSTDIR\bin\Compile Project.exe" + File "${ROOT_PATH}\bin\Serve Project.exe" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Serve project.lnk" "$INSTDIR\bin\Serve Project.exe" + SetOverwrite try + File "${ROOT_PATH}\bin\cocos.bat" + File "${ROOT_PATH}\bin\cocos.js" + File "${ROOT_PATH}\bin\cocos.sh" + File "${ROOT_PATH}\bin\jsdoc.sh" + SetOutPath "$INSTDIR" + File "${ROOT_PATH}\install.sh" + SetOutPath "$INSTDIR\lib\cocos\commands" + File "${ROOT_PATH}\lib\cocos\commands\help.js" + File "${ROOT_PATH}\lib\cocos\commands\ide.js" + File "${ROOT_PATH}\lib\cocos\commands\index.js" + File "${ROOT_PATH}\lib\cocos\commands\make.js" + File "${ROOT_PATH}\lib\cocos\commands\module_js" + File "${ROOT_PATH}\lib\cocos\commands\new.js" + File "${ROOT_PATH}\lib\cocos\commands\server.js" + SetOutPath "$INSTDIR\lib\cocos" + File "${ROOT_PATH}\lib\cocos\index.js" + File "${ROOT_PATH}\lib\cocos\mime.types" + File "${ROOT_PATH}\lib\cocos\mimetypes.js" + File "${ROOT_PATH}\lib\cocos\opts.js" + SetOutPath "$INSTDIR\lib\cocos\skeleton" + File "${ROOT_PATH}\lib\cocos\skeleton\make.json" + SetOutPath "$INSTDIR\lib\cocos\skeleton\public" + File "${ROOT_PATH}\lib\cocos\skeleton\public\index.html" + SetOutPath "$INSTDIR\lib\cocos\skeleton\src" + File "${ROOT_PATH}\lib\cocos\skeleton\src\main.js" + SetOutPath "$INSTDIR\lib\cocos" + File "${ROOT_PATH}\lib\cocos\template.js" + SetOutPath "$INSTDIR" + File /oname=LICENSE.txt "${ROOT_PATH}\LICENSE" + File "${ROOT_PATH}\package.json" + SetOutPath "$INSTDIR" + File /oname=README.txt "${ROOT_PATH}\README.md" + SetOutPath "$INSTDIR\src" + File "${ROOT_PATH}\src\event.js" + File "${ROOT_PATH}\src\global.js" + SetOutPath "$INSTDIR\src\libs" + File "${ROOT_PATH}\src\libs\base64.js" + File "${ROOT_PATH}\src\libs\box2d.js" + SetOutPath "$INSTDIR\src\libs\cocos2d" + File "${ROOT_PATH}\src\libs\cocos2d\ActionManager.js" + SetOutPath "$INSTDIR\src\libs\cocos2d\actions" + File "${ROOT_PATH}\src\libs\cocos2d\actions\Action.js" + File "${ROOT_PATH}\src\libs\cocos2d\actions\ActionInstant.js" + File "${ROOT_PATH}\src\libs\cocos2d\actions\ActionInterval.js" + File "${ROOT_PATH}\src\libs\cocos2d\actions\index.js" + SetOutPath "$INSTDIR\src\libs\cocos2d" + File "${ROOT_PATH}\src\libs\cocos2d\Animation.js" + File "${ROOT_PATH}\src\libs\cocos2d\AnimationCache.js" + File "${ROOT_PATH}\src\libs\cocos2d\config.json" + File "${ROOT_PATH}\src\libs\cocos2d\Director.js" + File "${ROOT_PATH}\src\libs\cocos2d\EventDispatcher.js" + File "${ROOT_PATH}\src\libs\cocos2d\index.js" + SetOutPath "$INSTDIR\src\libs\cocos2d\nodes" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\BatchNode.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\index.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\Label.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\Layer.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\Menu.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\MenuItem.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\Node.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\RenderTexture.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\Scene.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\Sprite.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\TMXLayer.js" + File "${ROOT_PATH}\src\libs\cocos2d\nodes\TMXTiledMap.js" + SetOutPath "$INSTDIR\src\libs\cocos2d" + File "${ROOT_PATH}\src\libs\cocos2d\Scheduler.js" + File "${ROOT_PATH}\src\libs\cocos2d\SpriteFrame.js" + File "${ROOT_PATH}\src\libs\cocos2d\SpriteFrameCache.js" + File "${ROOT_PATH}\src\libs\cocos2d\Texture2D.js" + File "${ROOT_PATH}\src\libs\cocos2d\TextureAtlas.js" + File "${ROOT_PATH}\src\libs\cocos2d\TMXOrientation.js" + File "${ROOT_PATH}\src\libs\cocos2d\TMXXMLParser.js" + SetOutPath "$INSTDIR\src\libs" + File "${ROOT_PATH}\src\libs\geometry.js" + File "${ROOT_PATH}\src\libs\gzip.js" + File "${ROOT_PATH}\src\libs\JXGUtil.js" + File "${ROOT_PATH}\src\libs\Plist.js" + File "${ROOT_PATH}\src\libs\qunit.js" + File "${ROOT_PATH}\src\libs\util.js" + SetOutPath "$INSTDIR\src" + File "${ROOT_PATH}\src\path.js" + File "${ROOT_PATH}\src\system.js" + SetOutPath "$INSTDIR\support\node-builds\etc" + File "${ROOT_PATH}\support\node-builds\etc\resolv.conf" + File "${ROOT_PATH}\support\node-builds\etc\hosts" + SetOutPath "$INSTDIR\support\node-builds\tmp" + File "${ROOT_PATH}\support\node-builds\tmp\empty" + SetOutPath "$INSTDIR\support\node-builds\win32" + File "${ROOT_PATH}\support\node-builds\win32\cygcrypto-0.9.8.dll" + File "${ROOT_PATH}\support\node-builds\win32\cyggcc_s-1.dll" + File "${ROOT_PATH}\support\node-builds\win32\cygiconv-2.dll" + File "${ROOT_PATH}\support\node-builds\win32\cygssl-0.9.8.dll" + File "${ROOT_PATH}\support\node-builds\win32\cygstdc++-6.dll" + File "${ROOT_PATH}\support\node-builds\win32\cygwin1.dll" + File "${ROOT_PATH}\support\node-builds\win32\cygxml2-2.dll" + File "${ROOT_PATH}\support\node-builds\win32\cygz.dll" + File "${ROOT_PATH}\support\node-builds\win32\node-repl" + File "${ROOT_PATH}\support\node-builds\win32\node-waf" + File "${ROOT_PATH}\support\node-builds\win32\node.exe" + SetOutPath "$INSTDIR\tests" + File "${ROOT_PATH}\tests\make.json" + SetOutPath "$INSTDIR\tests\public" + File "${ROOT_PATH}\tests\public\index.html" + SetOutPath "$INSTDIR\tests\src\cocos2d" + File "${ROOT_PATH}\tests\src\cocos2d\main.js" + SetOutPath "$INSTDIR\tests\src\cocos2d\resources\animations" + File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\dragon_animation.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini.plist" + File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini_blue.plist" + File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini_blue.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini_gray.plist" + File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini_gray.png" + SetOutPath "$INSTDIR\tests\src\cocos2d\resources" + File "${ROOT_PATH}\tests\src\cocos2d\resources\b1.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\b2.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\f1.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\f2.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\grossini_dance_atlas-red.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\grossini_dance_atlas.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\r1.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\r2.png" + SetOutPath "$INSTDIR\tests\src\cocos2d\resources\TileMaps" + File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\fixed-ortho-test2.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\iso-test.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\iso-test.tmx" + File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\ortho-test1.png" + File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\orthogonal-test1.tmx" + File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\orthogonal-test1.tsx" + File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\orthogonal-test2.tmx" + File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\orthogonal-test4.tmx" + SetOutPath "$INSTDIR\tests\src\cocos2d" + File "${ROOT_PATH}\tests\src\cocos2d\SpriteTest.js" + File "${ROOT_PATH}\tests\src\cocos2d\TileMapTest.js" + SetOutPath "$INSTDIR\tests\src\commonjs" + File "${ROOT_PATH}\tests\src\commonjs\bootstrap.py" + SetOutPath "$INSTDIR\tests\src\commonjs\docs" + File "${ROOT_PATH}\tests\src\commonjs\docs\contributors.html.markdown" + SetOutPath "$INSTDIR\tests\src\commonjs\docs\css" + File "${ROOT_PATH}\tests\src\commonjs\docs\css\colorful.css" + File "${ROOT_PATH}\tests\src\commonjs\docs\css\default.css" + File "${ROOT_PATH}\tests\src\commonjs\docs\css\styles.css" + SetOutPath "$INSTDIR\tests\src\commonjs\docs" + File "${ROOT_PATH}\tests\src\commonjs\docs\history.html.markdown" + SetOutPath "$INSTDIR\tests\src\commonjs\docs\images" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_blue.jpg" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_gray.jpg" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_green.jpg" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_home.jpg" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_orange.jpg" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_red.jpg" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\content-wrapper_bg.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\content_bg.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\explosion.jpg" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\header_gradient.jpg" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\header_wrapper_bg.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\logo.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_browsers.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_browsers_on.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_commonjs.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_commonjs_on.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_div.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_js.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_js_on.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\news_bg-btm.png" + File "${ROOT_PATH}\tests\src\commonjs\docs\images\news_bg-top.png" + SetOutPath "$INSTDIR\tests\src\commonjs\docs\impl" + File "${ROOT_PATH}\tests\src\commonjs\docs\impl\flusspferd.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\impl\gpsee.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\impl\helma.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\impl\index.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\impl\narwhal.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\impl\persevere.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\impl\v8cgi.html.markdown" + SetOutPath "$INSTDIR\tests\src\commonjs\docs" + File "${ROOT_PATH}\tests\src\commonjs\docs\index.html.markdown" + SetOutPath "$INSTDIR\tests\src\commonjs\docs\interp" + File "${ROOT_PATH}\tests\src\commonjs\docs\interp\jsc.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\interp\mozilla.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\interp\rhino.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\interp\spidermonkey.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\interp\v8.html.markdown" + SetOutPath "$INSTDIR\tests\src\commonjs\docs" + File "${ROOT_PATH}\tests\src\commonjs\docs\license.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\process.html.markdown" + SetOutPath "$INSTDIR\tests\src\commonjs\docs\specs" + File "${ROOT_PATH}\tests\src\commonjs\docs\specs\0.1.html.markdown" + File "${ROOT_PATH}\tests\src\commonjs\docs\specs\0.5.html.markdown" + SetOutPath "$INSTDIR\tests\src\commonjs\docs\specs\modules" + File "${ROOT_PATH}\tests\src\commonjs\docs\specs\modules\1.0.html.markdown" + SetOutPath "$INSTDIR\tests\src\commonjs\docs\_hooks" + File "${ROOT_PATH}\tests\src\commonjs\docs\_hooks\extend_md.py" + File "${ROOT_PATH}\tests\src\commonjs\docs\_hooks\transformers.py" + SetOutPath "$INSTDIR\tests\src\commonjs\docs\_layout" + File "${ROOT_PATH}\tests\src\commonjs\docs\_layout\default.html" + SetOutPath "$INSTDIR\tests\src\commonjs" + File "${ROOT_PATH}\tests\src\commonjs\pavement.py" + File "${ROOT_PATH}\tests\src\commonjs\README.txt" + File "${ROOT_PATH}\tests\src\commonjs\requirements.txt" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\absolute\b.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\absolute\program.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\submodule" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\absolute\submodule\a.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\absolute\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\cyclic\a.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\cyclic\b.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\cyclic\program.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\cyclic\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\determinism\program.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\submodule" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\determinism\submodule\a.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\determinism\submodule\b.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\determinism\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\exactExports\a.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\exactExports\program.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\exactExports\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\hasOwnProperty.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\program.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\test.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\toString.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\method\a.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\method\program.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\method\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\missing" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\missing\program.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\missing\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\monkeys\a.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\monkeys\program.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\monkeys\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\a\b\c" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\nested\a\b\c\d.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\nested\program.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\nested\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\relative\program.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\submodule" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\relative\submodule\a.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\relative\submodule\b.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\relative\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\a.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\b.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\c.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\program.js" + File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\test.js" + SetOutPath "$INSTDIR\tests\src\commonjs\tests\unit-testing\1.0" + File "${ROOT_PATH}\tests\src\commonjs\tests\unit-testing\1.0\program.js" + SetOutPath "$INSTDIR\tests\src" + File "${ROOT_PATH}\tests\src\commonjs.js" + File "${ROOT_PATH}\tests\src\config.json" + File "${ROOT_PATH}\tests\src\main.js" + File "${ROOT_PATH}\tests\src\qunit.js" +SectionEnd + +Section -AdditionalIcons + SetOutPath $INSTDIR + WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Uninstall.lnk" "$INSTDIR\uninst.exe" +SectionEnd + +Section -Post + WriteUninstaller "$INSTDIR\uninst.exe" + WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\New Project.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\New Project.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" +SectionEnd + + +Function un.onUninstSuccess + HideWindow + MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." +FunctionEnd + +Function un.onInit + MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2 + Abort +FunctionEnd + +Section Uninstall + Delete "$INSTDIR\${PRODUCT_NAME}.url" + Delete "$INSTDIR\uninst.exe" + Delete "$INSTDIR\tests\src\qunit.js" + Delete "$INSTDIR\tests\src\main.js" + Delete "$INSTDIR\tests\src\config.json" + Delete "$INSTDIR\tests\src\commonjs.js" + Delete "$INSTDIR\tests\src\commonjs\tests\unit-testing\1.0\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\c.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\b.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\a.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\submodule\b.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\submodule\a.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\a\b\c\d.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys\a.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\missing\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\missing\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method\a.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\toString.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\hasOwnProperty.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports\a.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\submodule\b.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\submodule\a.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic\b.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic\a.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\test.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\submodule\a.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\program.js" + Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\b.js" + Delete "$INSTDIR\tests\src\commonjs\requirements.txt" + Delete "$INSTDIR\tests\src\commonjs\README.txt" + Delete "$INSTDIR\tests\src\commonjs\pavement.py" + Delete "$INSTDIR\tests\src\commonjs\docs\_layout\default.html" + Delete "$INSTDIR\tests\src\commonjs\docs\_hooks\transformers.py" + Delete "$INSTDIR\tests\src\commonjs\docs\_hooks\extend_md.py" + Delete "$INSTDIR\tests\src\commonjs\docs\specs\modules\1.0.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\specs\0.5.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\specs\0.1.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\process.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\license.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\interp\v8.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\interp\spidermonkey.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\interp\rhino.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\interp\mozilla.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\interp\jsc.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\index.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\impl\v8cgi.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\impl\persevere.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\impl\narwhal.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\impl\index.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\impl\helma.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\impl\gpsee.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\impl\flusspferd.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\images\news_bg-top.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\news_bg-btm.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_js_on.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_js.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_div.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_commonjs_on.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_commonjs.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_browsers_on.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_browsers.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\logo.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\header_wrapper_bg.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\header_gradient.jpg" + Delete "$INSTDIR\tests\src\commonjs\docs\images\explosion.jpg" + Delete "$INSTDIR\tests\src\commonjs\docs\images\content_bg.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\content-wrapper_bg.png" + Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_red.jpg" + Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_orange.jpg" + Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_home.jpg" + Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_green.jpg" + Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_gray.jpg" + Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_blue.jpg" + Delete "$INSTDIR\tests\src\commonjs\docs\history.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\docs\css\styles.css" + Delete "$INSTDIR\tests\src\commonjs\docs\css\default.css" + Delete "$INSTDIR\tests\src\commonjs\docs\css\colorful.css" + Delete "$INSTDIR\tests\src\commonjs\docs\contributors.html.markdown" + Delete "$INSTDIR\tests\src\commonjs\bootstrap.py" + Delete "$INSTDIR\tests\src\cocos2d\TileMapTest.js" + Delete "$INSTDIR\tests\src\cocos2d\SpriteTest.js" + Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\orthogonal-test4.tmx" + Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\orthogonal-test2.tmx" + Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\orthogonal-test1.tsx" + Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\orthogonal-test1.tmx" + Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\ortho-test1.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\iso-test.tmx" + Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\iso-test.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\fixed-ortho-test2.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\r2.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\r1.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\grossini_dance_atlas.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\grossini_dance_atlas-red.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\f2.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\f1.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\b2.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\b1.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini_gray.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini_gray.plist" + Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini_blue.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini_blue.plist" + Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini.png" + Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini.plist" + Delete "$INSTDIR\tests\src\cocos2d\resources\animations\dragon_animation.png" + Delete "$INSTDIR\tests\src\cocos2d\main.js" + Delete "$INSTDIR\tests\public\index.html" + Delete "$INSTDIR\tests\make.json" + Delete "$INSTDIR\support\node-builds\win32\node.exe" + Delete "$INSTDIR\support\node-builds\win32\node-waf" + Delete "$INSTDIR\support\node-builds\win32\node-repl" + Delete "$INSTDIR\support\node-builds\win32\cygz.dll" + Delete "$INSTDIR\support\node-builds\win32\cygxml2-2.dll" + Delete "$INSTDIR\support\node-builds\win32\cygwin1.dll" + Delete "$INSTDIR\support\node-builds\win32\cygstdc++-6.dll" + Delete "$INSTDIR\support\node-builds\win32\cygssl-0.9.8.dll" + Delete "$INSTDIR\support\node-builds\win32\cygiconv-2.dll" + Delete "$INSTDIR\support\node-builds\win32\cyggcc_s-1.dll" + Delete "$INSTDIR\support\node-builds\win32\cygcrypto-0.9.8.dll" + Delete "$INSTDIR\support\node-builds\tmp\empty" + Delete "$INSTDIR\support\node-builds\etc\resolv.conf" + Delete "$INSTDIR\support\node-builds\etc\hosts" + Delete "$INSTDIR\src\system.js" + Delete "$INSTDIR\src\path.js" + Delete "$INSTDIR\src\libs\util.js" + Delete "$INSTDIR\src\libs\qunit.js" + Delete "$INSTDIR\src\libs\Plist.js" + Delete "$INSTDIR\src\libs\JXGUtil.js" + Delete "$INSTDIR\src\libs\gzip.js" + Delete "$INSTDIR\src\libs\geometry.js" + Delete "$INSTDIR\src\libs\cocos2d\TMXXMLParser.js" + Delete "$INSTDIR\src\libs\cocos2d\TMXOrientation.js" + Delete "$INSTDIR\src\libs\cocos2d\TextureAtlas.js" + Delete "$INSTDIR\src\libs\cocos2d\Texture2D.js" + Delete "$INSTDIR\src\libs\cocos2d\SpriteFrameCache.js" + Delete "$INSTDIR\src\libs\cocos2d\SpriteFrame.js" + Delete "$INSTDIR\src\libs\cocos2d\Scheduler.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\TMXTiledMap.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\TMXLayer.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\Sprite.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\Scene.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\RenderTexture.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\Node.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\MenuItem.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\Menu.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\Layer.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\Label.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\index.js" + Delete "$INSTDIR\src\libs\cocos2d\nodes\BatchNode.js" + Delete "$INSTDIR\src\libs\cocos2d\index.js" + Delete "$INSTDIR\src\libs\cocos2d\EventDispatcher.js" + Delete "$INSTDIR\src\libs\cocos2d\Director.js" + Delete "$INSTDIR\src\libs\cocos2d\config.json" + Delete "$INSTDIR\src\libs\cocos2d\AnimationCache.js" + Delete "$INSTDIR\src\libs\cocos2d\Animation.js" + Delete "$INSTDIR\src\libs\cocos2d\actions\index.js" + Delete "$INSTDIR\src\libs\cocos2d\actions\ActionInterval.js" + Delete "$INSTDIR\src\libs\cocos2d\actions\ActionInstant.js" + Delete "$INSTDIR\src\libs\cocos2d\actions\Action.js" + Delete "$INSTDIR\src\libs\cocos2d\ActionManager.js" + Delete "$INSTDIR\src\libs\box2d.js" + Delete "$INSTDIR\src\libs\base64.js" + Delete "$INSTDIR\src\global.js" + Delete "$INSTDIR\src\event.js" + Delete "$INSTDIR\README.txt" + Delete "$INSTDIR\package.json" + Delete "$INSTDIR\LICENSE.txt" + Delete "$INSTDIR\lib\cocos\template.js" + Delete "$INSTDIR\lib\cocos\skeleton\src\main.js" + Delete "$INSTDIR\lib\cocos\skeleton\public\index.html" + Delete "$INSTDIR\lib\cocos\skeleton\make.json" + Delete "$INSTDIR\lib\cocos\opts.js" + Delete "$INSTDIR\lib\cocos\mimetypes.js" + Delete "$INSTDIR\lib\cocos\mime.types" + Delete "$INSTDIR\lib\cocos\index.js" + Delete "$INSTDIR\lib\cocos\commands\server.js" + Delete "$INSTDIR\lib\cocos\commands\new.js" + Delete "$INSTDIR\lib\cocos\commands\module_js" + Delete "$INSTDIR\lib\cocos\commands\make.js" + Delete "$INSTDIR\lib\cocos\commands\index.js" + Delete "$INSTDIR\lib\cocos\commands\ide.js" + Delete "$INSTDIR\lib\cocos\commands\help.js" + Delete "$INSTDIR\install.sh" + Delete "$INSTDIR\bin\jsdoc.sh" + Delete "$INSTDIR\bin\cocos.sh" + Delete "$INSTDIR\bin\cocos.js" + Delete "$INSTDIR\bin\cocos.bat" + Delete "$INSTDIR\bin\Serve Project.exe" + Delete "$INSTDIR\bin\Compile Project.exe" + Delete "$INSTDIR\bin\New Project.exe" + Delete "$SMPROGRAMS\Cocos2D JavaScript\Uninstall.lnk" + Delete "$SMPROGRAMS\Cocos2D JavaScript\Website.lnk" + Delete "$SMPROGRAMS\Cocos2D JavaScript\Serve project.lnk" + Delete "$SMPROGRAMS\Cocos2D JavaScript\Compile project.lnk" + Delete "$SMPROGRAMS\Cocos2D JavaScript\Create new project.lnk" + + RMDir "$SMPROGRAMS\Cocos2D JavaScript" + RMDir "$INSTDIR\tests\src\commonjs\tests\unit-testing\1.0" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\submodule" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\a\b\c" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\missing" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\submodule" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\submodule" + RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute" + RMDir "$INSTDIR\tests\src\commonjs\docs\specs\modules" + RMDir "$INSTDIR\tests\src\commonjs\docs\specs" + RMDir "$INSTDIR\tests\src\commonjs\docs\interp" + RMDir "$INSTDIR\tests\src\commonjs\docs\impl" + RMDir "$INSTDIR\tests\src\commonjs\docs\images" + RMDir "$INSTDIR\tests\src\commonjs\docs\css" + RMDir "$INSTDIR\tests\src\commonjs\docs\_layout" + RMDir "$INSTDIR\tests\src\commonjs\docs\_hooks" + RMDir "$INSTDIR\tests\src\commonjs\docs" + RMDir "$INSTDIR\tests\src\commonjs" + RMDir "$INSTDIR\tests\src\cocos2d\resources\TileMaps" + RMDir "$INSTDIR\tests\src\cocos2d\resources\animations" + RMDir "$INSTDIR\tests\src\cocos2d\resources" + RMDir "$INSTDIR\tests\src\cocos2d" + RMDir "$INSTDIR\tests\src" + RMDir "$INSTDIR\tests\public" + RMDir "$INSTDIR\tests" + RMDir "$INSTDIR\support\node-builds\win32" + RMDir "$INSTDIR\support\node-builds\tmp" + RMDir "$INSTDIR\support\node-builds\etc" + RMDir "$INSTDIR\support" + RMDir "$INSTDIR\src\libs\cocos2d\nodes" + RMDir "$INSTDIR\src\libs\cocos2d\actions" + RMDir "$INSTDIR\src\libs\cocos2d" + RMDir "$INSTDIR\src\libs" + RMDir "$INSTDIR\src" + RMDir "$INSTDIR\public" + RMDir "$INSTDIR\lib\cocos\skeleton\src" + RMDir "$INSTDIR\lib\cocos\skeleton\public" + RMDir "$INSTDIR\lib\cocos\skeleton" + RMDir "$INSTDIR\lib\cocos\commands" + RMDir "$INSTDIR\lib\cocos" + RMDir "$INSTDIR\bin" + RMDir "$INSTDIR" + + DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" + DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" + SetAutoClose true +SectionEnd From e3787ed28ebb642bf28cba48dc88f83bbce12559 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 13 Feb 2011 00:26:43 +1300 Subject: [PATCH 065/176] Added Windows executables for building/running cocos2d --- bin/Compile project.exe | Bin 0 -> 421376 bytes bin/Create project.exe | Bin 0 -> 421376 bytes bin/Make.exe | Bin 419328 -> 0 bytes bin/Serve project.exe | Bin 0 -> 421376 bytes lib/cocos/commands/make.js | 10 +- support/Make.bat | 2 - support/Server.bat | 2 - support/win32/installer.nsi | 24 +-- support/win32/utils/Cocos2D JavaScript.sln | 20 +++ support/win32/utils/Cocos2D JavaScript.suo | Bin 0 -> 25600 bytes .../win32/utils/Cocos2D JavaScript/Cocos.cs | 24 +++ .../Cocos2D JavaScript.csproj | 146 ++++++++++++++++++ .../Cocos2D JavaScript.csproj.user | 21 +++ .../win32/utils/Cocos2D JavaScript/Create.cs | 63 ++++++++ .../win32/utils/Cocos2D JavaScript/Make.cs | 44 ++++++ .../Properties/AssemblyInfo.cs | 36 +++++ .../Properties/Resources.Designer.cs | 63 ++++++++ .../Properties/Resources.resx | 117 ++++++++++++++ .../Properties/Settings.Designer.cs | 26 ++++ .../Properties/Settings.settings | 7 + .../win32/utils/Cocos2D JavaScript/Server.cs | 41 +++++ .../win32/utils/Cocos2D JavaScript/app.config | 3 + .../Cocos2D JavaScript/cocos2d - Happy.ico | Bin 419328 -> 370070 bytes 23 files changed, 628 insertions(+), 21 deletions(-) create mode 100755 bin/Compile project.exe create mode 100755 bin/Create project.exe delete mode 100644 bin/Make.exe create mode 100755 bin/Serve project.exe delete mode 100755 support/Make.bat delete mode 100755 support/Server.bat mode change 100755 => 100644 support/win32/installer.nsi create mode 100644 support/win32/utils/Cocos2D JavaScript.sln create mode 100644 support/win32/utils/Cocos2D JavaScript.suo create mode 100644 support/win32/utils/Cocos2D JavaScript/Cocos.cs create mode 100644 support/win32/utils/Cocos2D JavaScript/Cocos2D JavaScript.csproj create mode 100644 support/win32/utils/Cocos2D JavaScript/Cocos2D JavaScript.csproj.user create mode 100644 support/win32/utils/Cocos2D JavaScript/Create.cs create mode 100644 support/win32/utils/Cocos2D JavaScript/Make.cs create mode 100644 support/win32/utils/Cocos2D JavaScript/Properties/AssemblyInfo.cs create mode 100644 support/win32/utils/Cocos2D JavaScript/Properties/Resources.Designer.cs create mode 100644 support/win32/utils/Cocos2D JavaScript/Properties/Resources.resx create mode 100644 support/win32/utils/Cocos2D JavaScript/Properties/Settings.Designer.cs create mode 100644 support/win32/utils/Cocos2D JavaScript/Properties/Settings.settings create mode 100644 support/win32/utils/Cocos2D JavaScript/Server.cs create mode 100644 support/win32/utils/Cocos2D JavaScript/app.config rename bin/Server.exe => support/win32/utils/Cocos2D JavaScript/cocos2d - Happy.ico (88%) diff --git a/bin/Compile project.exe b/bin/Compile project.exe new file mode 100755 index 0000000000000000000000000000000000000000..1df23d85f56931da2b09ebaf88038a2dde51fb38 GIT binary patch literal 421376 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

        BxayoJ*ayD`< zbv+Nc0J#W$3GQXc71aMK_|?c3_;tt)$X58xxVIv|BhDT0yO4X3`;Z5ahmc2*-y@G9 zk0VbaPa)e$_bl=}@*@0Y+*gs;$?FaHo5z2|1X4v5E)CqBeAh3O^C;JBYlu0q#u%kegN(uWC$`0Nkc{;8Av9Q zh2+FCKap|Bg+-Sabro$X@;bg7VYe6EU39wBix9F)Ng?AxRdDCHl$l(o%d@-CiX3}`)A)Pm5GI-0y!y71>{Ceyt zv5@y~jug4#SG;qxg0~~qiUQF{%-<06Sl*L3jrV5G;0=j$cu(RyQeMcrF<0?E%#FMw zaU1Wy+|An(_wb&}y}U1RKkrIB$QvvV^Zv@CybAPa-(f|9UyB_H{;_Ws_-@}^@B@vX z_8pJ^pBiJ5y!Zzsm4F#ZD$WMiG~r#iRqG>YUS(Ih6X1P3Lr0Y_^r&^RSo#V^-5FInZVELmC7&L>vawoZpO zYFwY(KYDPL10VRi2OQd|uL}yq^3UG(E{DfE!$=f_7~;xXw2I z|CN)Nx#o2b5zl|>t+9Cg{B||ik5$y-SB%wLWGOIO zrb9?=v09D;=dw0iteO+R1-!+`yHC8oC|N%z;;-iYG|3xiCHR-{?xGZjf|gh+O7S12 z@o-AB#1Xu~D8(|+;w`m<@E-|UtmSAZ7ptCfRwynSeidTM70KlQT2Dr#i$9@|{7 znLWYceYS<*QIv0qASGL(l`<{fa6244hH@jo?kZM`wwfDbwPO zxZ{X(D`>Iv91s3Zbb`0@ew`)m5T}55ip|8i3$)moP6zK1XM*?g-krs}bmxK(v5#5o zQ5S%Zh>O5Sc@xhPkI@2)cc`uapP=rR*hZ}_@f7vtS5>L06x%^dJVQs94em&hshTyWjM(AlrMwn@>Otzd>zb?Z-ANdO)yKo4UU$7 zCVn=^7?$sWIr4olSAGEI$&bLX@?+wR11;WI-2vvy&%grtIXFRn2~Lz>gT?Y&utfd? zoFu;or^+9|Y4RuVK=})JkPMNV59F;jenZ+4Go%YFm$6`lj0Y>FTS_q#WTwbI;B1)$ zR>^+g!7>FrL=FHK%0VDETHq2n3_Mh(flK8G@GzMH)=Bk7U%ku%TVysl9|baQWe(UT z^S}-{4*l_U{&PUyFqHfTxA-k+i3@p`(h?U*S}!gJd23OYyv(6XKZW31=E zIO_#4!FmZyv|a)GTCai0)*r$C)}O#s>n(7g^$s}LdKVmO^?<{zzkuo1hu}!-uX3yy zWlaM|TL*$;EFYL_%>c(*72tSlCRkw22EEq7V39QkEVkx>ldJ{c6l)PU)mkja^UmcY z&}U5nXIN8tOLL}mC^*|X3_RF60-R$l2j^M80vA{{;38`!xY()(54Bc-hgoaDBdlM8 z%dH0RS5^~PW3_-Qtsq!$wSlXwb>JFn1Ndv}Xt2Th4cKHIE4?CUb%1Tw3E(>GL~w(3 zvMdt6vCaaIwax)MtlxqsSm%Q$S{H&RTNi_;T9<;SS(k%nSXY8)SzX{c)-~X7t!u&a zt?R)HtsB9Mt((A0ty{p$t=qsWt=na>xW+mayw*AmyxuxPP7*g+={#-RVvPiEv(y{= zw_BsYJFU^+-Mk?@N!)AYg7;fkSv+WQwJ#p#UDZkAQOgTEcJ%}HmePM+FA!b zV{HJRvyKK|uzmx+WE~5>Vs(J8Sto#hv`z&7WStDYWt|GXW1R-RYpLg-9_uXdFP3@^ z`YSn46Q7XtH1R1pPZNK$jt0N5egl3*&eOy<t1lA>weJVdJr7N+tde&(Y#H4pcup3)CY=O-lq16@s#Bg1(f9zUdr-` zBFgfKV#@M~NtERiQz*+Prc#zqOrtEHIFPb@!be#?F@v)BO9{&IiJ6q;6SFDHCl018 zpO`~gJ~5B7W{5?ucfrN39`I1tU%z_P*wvcCq2$E-oXd}-Gv5q_|cv|@@cr7S|D+^KK{39C0Uc=7_tAGe_J@9G;em zGeu2x}u780~@R&bOY;#$1fp~_{1>!kE7l;=KT_9c}bb)w<&_&{p zuHSNA{FCc^@GaMc;5)91!FOGkf<3Ow!N0h!6fqq|2+NU zXysFvFKOi;qguXbV{Oy&y5_p()}s35t?ex>&B3jO;_imM`)*_-kAJ%i9`T3R>z{s_Ojz_!Fc5Z6U7^9m&cHQgrmk@#3nX zQ-g~W^@-Dc*Ft<3+Ea03aJz70aqq{C!+i-i9`_SmoT!gIg3pNzWGBp4B&fu_KDNGl za4#jq)^A`5?)|a#w;$VE8;<|U$#!@o6wVKY^DDI-5uNhc@jN%ERz-i*-`on$yStBn z+8*L>*hBnxZ;BON?+dX;8PWN0J`$=AJc!gNgfA)_wf>Ag_v2x?7k+l%xXV8OY5ZlM zg~nd=*HF&6?}oC^cq5dx`BmgK{C^7N{`S4l*o!|7jlb+~Ar)7p38yW*`m0dkRiA`% zPJ2Ey)CQ0^Hog^Id94XHHbaZkY& zU;H%nmhVH;Z~rkg?Y8ej-m{+#CFlA=gS<;ai8+Ua5=PGs#f_X6N*p~kRCN9;I*y8~ z(x|k>jhfw)lKZOpu>5I_7{8^#QNee<%hpi5cC^D)jR& zzl3ghpgWY5F)@@j%dg|AG%D>uH+&tMd+(2-g%A838d|&{lv%PM^uRMOh33znAKHBS zS)sP0J3~!PO`!+3JsZlNLR(VPL*up0m&1Ypws< zeeJbRvZnpcvu6Fzw_2%VtW2ZslI37)qVMNC`?LFoZ%1$b!R9@4*v2pWo0YCm&6??( zrv1)!-!;lP-5TYbW=;B@ZRJ`Gvog&GS?bga?8Fy-cHi*rgol2#lb$ZXmex>@tw_v8%?P5PYW@-E#l%ZB`6y`A=wxo`M(($*jC)E5rhnSV5epRIZCDf;%j zfR8?BEAMlxPS?3srb%xrQ>B)j^3;zmF5mF&q;0|XXT5Ajn6c(DpRdgUK2<W;>qG0X@N?Bo zUn{L|T$&x1f2TV08zV3B^nCL>b;&oDw&EMrpS!H%qED^uZEst%E1tLd=WMjb2yq)2vjVQ}yh3dUuJH8*`;qntYShn7_mtocEA5 zzv_?H?v8h@)8fx9eZ_7|yYE{|T^i8fW!^zFrQiR9WvuzZGFN|NotJ%K9qxM9T3-E< zH9UWd)ttZBDo?q|$__fuN~UDkaiuF*i858JWW~BxvO*mzQM#h(2s}$_o^9oZUTBr4 z-fXo_SZa+f*lMk={gb6G_@{MV{-x6X)-shxXXQnnt%OCJyT9I(w&FYMx^|!S*m%%- zZdTZIK=t}Q>%Q)L%UZqLGM0a4b;n(3CCgT_QZ?IH<+h`&q5}1p57Y}u)tXt!@>Q+T z+?y?9#TV||?(2TA?2Y?fnxx%h(?ORPd6IYgg}d@HL{EN7neuxpU!$q=J=f}`Pqb=kM=Lk&se1hs)ybz@tu8ZNDATOJQLnoC zQTHXwst%uZbxc~MOCID!p5&drWRLZD;798tnGewWfe#;!hOW1~Y^BOqQ#*3HRjS+8 zdW{@!7vFNX-FWNmR5(>hkQaH9cb8>*tmoPvt^bw-Hu&LO8?yayG*s)*%j$LMdzwo&s=v9-^>;@V)9 z8+-A^7p+pg_SUG|T2p#y5qb8YyJ!!Go^^UqegVlCHxRj=R7u3odvc768)Sx5icrKVYx z#u@hf^Up`0Bqw{Eoy zFTBux{P9QI@cgSbXv!=rRlkdqgSMyIfEDk%bjgFf$dkOYSAJuIHtw~N47`eo}kZiJ$ zZSs?OHg4;8mQ<#K%bR{o<%VfC_o6@8vwwfr9(w2@$L~oeon&=VM_T4Jfv1Ol4c=Vu6Rex&QQ+YPz zogq!}X*3oN1M6H?!WOC)#*V&WL$mJ#9*)uby8oCsl4}{jS{L(j{&3 zATRPH?;-2HwTTb!vsq6bvg4o2vlE{G*?M2JO!!x{GL`E^)AziF^QV8=sOPCsJ*n4i zzEx^BI?6jTC|RzCjal@HOP93CgS^O-yoas-)+TS?Z*!hHWG6nKXD6#q+xK_N)CaC? zWhzy7eQ5G*-0Sp+tb;x&&&aPv`t%qY%d3CvWlul3M5%Ii{Nq2kbV-{$$csG5d&GwC zZ0aNX?f9p2?G(K~^+mIO7caNI7cI3m!)9Bpc0pghe)kitrs{h7wh;< zKiTKamGM%|R_QKH(j|}wd66f1k9zPso4#Yeo$ySqo%Z6-c82=ovo?HSr@!>GjlcVO zVNln}7x`D|Fg}`>&og|j*X@L8{-qmaT5^q6mNDxhmnP{F$b-Ddle|Z7{LW@Ry5CNE zHdpU|j`aT-0|euMx*fV{ED_`z=AC@KPWWrJj+0#ePVS{EY0)X!rrq~iOq%3DUgSyM z@%e}Q?%Yqf=Xontp@!Pua|-ZYx7+asF67@-mx=-y^6CYG=%Ld4qY`sqCZ-%vv2)X@@K47y-8cux1$^l zO*Ia5@|XT`1sC+5J_v38$QvGV`JVdBzF#GOWH5XEKdpTAdTuO6J=mnzX;J*?1C?n$ zP<_9e*6oBV3*^c7KE%s^)PvvJjFA5Mc!gc3uK25!t5(Nqw;yhm>Zdw+Q2xrc7^Hr1 zZA%?@N`diTd^$dV@+9w(8@|n(zGI)A_{<@dxjd(<@!y1h&shDY`eG?sRxRnuMWwbQ zT^-kP+^Ke^z7NNZzo$%*2YHbvc@JB+XU~*}_uBDK9n|=e{DU$W|84m9{B2)Y$>dU2 zz1;{aDZIO%bk!00_T`y8$csG5d+?gw8^&$<-i>2VRJr6mG$N-&VcM!URko9yo{x~O zC5jh*PMV}m9*mjElf3)i|8*D9kvmc2VV*-9@}Z7M6mrhF%Z@&iJjvS!Xh9x&w+FqD zZsw_O{8a*Jd0q1|_xXnB0{$EKuj}x*wJq~=X5J!AVU9v{-Xio~kKLcA-(Q>G_C=<~ z^oupW@P4bib{^E2K2PIIgQSTZctEHHQ7l+G{?z{k>nfIpcQsd~WUT zjs)&Cj~u*LoQ0ZCS)}hYzuaNTZkHBw5iZ2!^{t};TA&Hqpb=Wb^haoaq4nKgTYJTY z=1v;dr)mC%&}sQ@&A;rl)J30L`@283ws-u~THo}Ro5yL!JkBN0SfdLcvj*osZ1v93 zoaI>$YHoVH)j55g)j4CGyRUcFMyr4B7HfFHc5AG;o+g()XU(qqleN75HEVOrJJ#;b ze_4ln{%xs?zqC%8>q*m?&gHK;WoSW$&<2g-;e{{{@Z@M`-f3B6{%3{0U$#?oK%ZIr zyZ&WuZvMM9|HDhx_@YOx-kIw)7qir=%(%lUPQ1a&kNJa@9eJ6X6Dl+8VmAlG+)!-L zypZ0N8KJqMQI}hJ&A&50RBhG*t98u~pn)@jKX;$xTQ z=Ar3Z(Iy^5V}ysLV1Q16OZ!EVvEHX^Ua7OjbDi(oWob)4x752ou(r^C<@1^c+Ge#+ zS*bklvWgR~b96X*hiD#a@P(SoI>C}!X}+LV3p=htb$Mkakb{UZhOl*-uscIFZ)vT?ABb9Xj}Q6 zo7V#eXomKdw|}{?t#k|8nUBg?vsd#%8k1`-K691kC02Z8X^TF#4tKn5t*?8#|r5pDrRc_?w$yAfL_PS&} z^$Yu-p}Dl1MfcrSM>1i4t=VNyYt7_U>u~2kEN$^8*5$sPZXT}d13x&LGDRCSLMt>w zyXMZ`?;uRl?-RWbXe_TeCFZuWHOH0B{EFthx--Vt99q}ad$h*!m33bFZ|ii=`_|^_ z=dEJLfsStGs!G-AWM$QVijG~HYy76MiyKSm>gF-jr!7%RxTxPzHG8tPzvXY%>E3@S z%}*_J-K4m?ttYeelN{W z^x- z^br}8z=Mp?t?QBxT$(OzLU>)>m_ME`;v8Eqd3IH6AWg zrM@-Qe2DA!>smi!s+*Un-f5yW$UfOUuah~)Dz_i!c&gAw^P_R}g9-DLB}!FrJoH%p zQK5N43p7C+G(syhLwm6)ta@eTCLi;Pj=53=Ya>~dajK7OV#e+`qG?o6|H>R}Y-l;}dX?1@PS$Rm zS+#+sv~Fi--LSy!efSxB?O&hROMiOBQd3jid|;qc!FpS{>P;*qCB-hk`dT~Z>YHu! zyi=`q!^Uo2j&fbPQ4d#lH5fFnK)#L+(FASK2(8cz?deN)=XJaPJIh(W*ZN7n1_~$U zRtIk<9FANym%a9DORiAGDmCcnbOX6V`ycM#Z1+F;M>}{ZSIvpJb=I9bcUs-Lb=|yP zbIG20zl@9w`|i8%T%6p)dA9wPzw6sA*1l^GVIh5#Zh;SVaQda2qxnW@K$fBn8lkn@ z{oiZed3RoyrMvTbtomN_uzPKQ>XpIU4%txA&iZdSw3>B=mC#rtrRT{`cS=f6&bjFx zyK%z~`+nbkM_2gYb=RqVtDfTGCn@gRZ@(RWtvTvEyYGpY?1~i|txAoWR;q5A-*GZcER{?7WUz8$3b?4b`Ivf-Lr9sh7M?h#{OE9f@Wy% zwtP<>>-K|0|FCTbY?SyMqq*&|kL5+eVQZl|{3NZF`E_hZf4{*l??1oyp}q0O8;(D8 zw`$d@_Q3}q*!Jz)Em>=6)tY77^y$-`?r?Q|48>cwZk@5lzl2ZO{m<&Gy{+;!RAAXPxfn-iuXYROV%a%^wk3asnn;(b1bI(23 zt)rlWvwm}_TRTL5m?ti)`JI-MS=E-EZP=PmB5M(c9c|DEt#zRCFwLWn zmY$D)G}o;kFwZ~f39Vsl|IwA(nym-8dI$Z%9-?GYX@@)I_uC)$*{W5m?6S))b9BD? z>Z?||bQx>dZI0Twvs^iN^wCG%yIXI))#}x&XK%jwrakrAJ9f?5hb=v)uO(GYaqU}j zjn^4Sd9)9d22V8vYIi_fhfH3&p zR|DNw`$}8u18YLm8)x0Pz!p97oPDh|Daz$@&pl^#>ePu@m#ERQk2P-G*gpB>6WhCY zuN^vc$lm{ar(M795t}D_6xux2D`}5Q)k$^bcjERRls|MtXc0~D0*%lL&CuTK{ylkv zH~e6uw(hs_J2ap3M6O%on6C8&LeERrI{KUR3g+j7HYw=qpxa5MN?V)GU9HEEk=D6u zH{nvspf?vR3As%&v;wi)QwLgV8QKPWfD-C73yPCrgytv1{*DpfC_f0F3;G`Op1f;MP` zR%nLyeyhL98@}-e8~5;joATH}n<2bri*{^!2pwl$?AB1o-_O^29V+VT;)m84!f~;m zp{@+~sr@}z$j!7(f8_fp4bTBi&<2gr3eC{oUt#1X*$wI0w8u3s_Vi(`5#`xDt`)?v4{G+*mG^R>>@VZvFiznQH0(Mt6@I69mxMNd>u z3b}{wnw@7j`rVpSBo1qB%yU;womeRSj616|YNfo%KcImt>s`ke1u?o+ZyM)UV{KohhVjFvNoQGuF8%EI zN54@YqO9umoIvKH2fbkJr*78q8e^RmeeUR&tih*V_Y%6~b&4{*n z`DSZ9;RLNMu(m;bzkU;3{d(%pR;O)dbS>BG2|W1w zDE)Cdf?DmbNs=NLc{D+VsyuidzqJ$-j^y@LH49S1bJ(X zEShg*4I0{5zkyb0hW14CJN{qxIOrO>2V=$q^h3Q|&w}Z3;9+X%FcPvaZx_jOd*l zlx@WW2kf^!{mIo^y1x0O#ecN=X*o82!81|pUA_@L@b^bUe-yjWns4}7|BDto%)O0t zVY)=UioLRb=gMuQy~4JJxtOkVfA8cp?CK3#cRd`VGtvBhW&QE;XftGnlVAOeX;BPP za!!rjd!1>fHp|(BMC=mEr1W;}RKw1F?Ti-=MKSj2hIKW3UmW>U#$7rQ{W%N0FXWzQ zr#-u0_VwMZWT~>wevh`PR=c6j#xdMxA%AR&oX$7x=f;YaWs7&hBVPx3#py{@SL2?$ zb>H~%yZ)P?{*2T=uKwgZ%6~D!i95cw>P@vaq4JCkBDR?|T4JxK_E|Rf(2i}AYooA> zP-g&5%*_^rZD|M{i(h`^hegLgZlrl5!c}sk^PbGS;w#5q@8dm z=jcz;x(oJv4Ww7_QK{|dz@|gCq@^oXvB^tciDK;14(FHPKA>NHOUa-13!0&Q*t&1j z{{G;eouIZ2n|9ZJ6{0g?UGh9RtQ8j=>bB2vV>QNW%;_?ROaCaaLB)=%noVBvr=!vt zuS-GuCHkZ7?+@xfsQnroc)$Ud9<w z`@q$^7Rsi;=@WWI|LA1#N&Kk&NFfoY6&oggv zbeECcS^wYP=e{p0e*8P1kIxqxpaq)f_dp}GLNl~$ViLQRr78;FU` zFY+XBXn+=If;QwHPkWdTbc%98*`|IHzpjnb{vOqpJiv?R>qu9{ZKQ8Dw!B08 zb{Bl@?5(t4&e?%sFN56=d$nAUT^P1uF~PkfP7vD5Hp~Ut1z{W1e$lQXf{zn?b(1@KFG-E3U5AXs{@KzN6vI82ZczcAizK2fnfbE;?Y}l*Ui6DCeca_}) zHd-CEXQ<;+Y}dY)U776J7GnD*`?7mJwRQ_Wv9@=~&g{+)wNLs3YjgYi*7`QtoZb4K z_5>2%4FbOv+UQ-I+hyaWxNYy$zUl=Z%TDc6rS+L?9JB{-(O0r7ll|Hf*(oVcmp6L} z-5$k!+MpGhp&cIJ1)ksy9t)EJ&n2gW(k0V=N%t-GMb3UsHVT0ao$^|?TXt=-M_Vj< z?)|rH(mu4dw~PLp-n5q2{Z)G&Uv@Te*v4Tahpk-QGdEbB(;kq`*D7aYR`bLaR`Y~q z+LO3U_G=0!EH|FjI%%cVK6SOTwX1jbM(tPJDto*~WsmlhHNE0RYku{gt$%g*j? z?O}Z1+3=+<{7m~YWox(0+uF%SO}1xg5qmpifgIoo-rzA_1`(a#<9L_6us=km@SLta zm}%^j#0F1$CR6VbE_cB1-(_F+Cu?%))8bS1f@f`Tyj7obuT`0TyKK>JbbH&&jlR;^ zHY&TZK5BDQ(?*D`wM?D7%6<^sxV9 zKWNMA{vvt2B^=(j)O$aXt=^Zi>CrxV*$p~-J;?%I;E8epk4_IlWr4DRejp?Eow7eQ zO}2jN_bH7Pvfo?wm33P5Z|kt&U$O}l&ezKR4ZeS~)!EuX7d%&-c%5tz#qWqq13s}m z#6~X?N)0^UlCx%5Qu`rRQhP&7res>lCS5J5rS@ue8fB$=o*?_b-$vt?mOY@`$0~b8 z>>A6Dy~@cIyTMu~E|bjHTjL8KadN=NK)c)D5kA-}ex`l1J7s&Q{fyWwhGifgBV}PD z<$$`8`hhZno=~>259}gamM*Kl)pd_-jCNX@((HK82iE@fx2@InuUfOqWh?sIZO(T= zP3^6%DjUp76R!_!Fhl&88gzkp8!cPL=FUc44Up@XC%kH(Q^`i@PELV+W1tsN{wLq) z>?UiSxZLWWy}?p0+97+;7p%>Vf3xPjtJWuwr zr>%B-gR9NDQ}&QITIsY=cAWO;MtRkm2z!K?<7R!ZRK3m$;O*E?g4HIj`a_LuBOZhO<;0y|0Z-FeyPma+0{**AV8+c51F zUiYH{cAWd1J!j|pe{?*;D?E$$t0jk*kq6}i8DaOCwNAE@56Wf|o5e`LhSBXo);`T{ zYqdXF_KlhM@3bz%i7hG~-=gkI)t5~kd&!knQu!*@`usK4 zV?BGbwO3Sm2K%^waKPbjoIwdw75sc!D>0gjaZmciC>{rmEkNu67-J$ZoRh z#D|FIJ+S-4{xngLEg$lEaIe+qHYUJK^G; z^NLLyJUDw%bU-$*@CdK)4Dao++f{kUkR4#R2c%aU_FIn1OmFFqvw!uruSHzz4w&QU zDpkI^>^?N_E?#|L-ju!iT;aQR=4^M*Z`Q@jX)d07*76JEJN(S8QK=3^22G}3l5Znh z1a0sDFYp9!@CdK)4DZ;^rmLUVRpp|)>PhTsdkcH#dq9}?ll^Q_q0Q;{I(nG*PKnHO z!w>6n%v~}E>*@m8)v+JBVb-juY*=fjZg6%Dl3C5p)13_9Gr3l~Xgk5Yt(OCP__1*# z&9-MQE|NA!H+m}_fG2o^M|g#2XE!XL3tdznWUZ242$hdsiql7N`$=y24jO=uf&?LZ z$v?H<4I6lDakcg$9@vM-UUBHFm(tYj5g#^VzI7Wk+$vY0PA}o?n!J8cKd_F??}k}( z+}bbS#)cAZA9oq8c_0UDg|HoBAAjb}FD0Z8y5Rv{;0fN~5nkcBqj>MMNd7L=&+WGQ z2kW_B_JFcW?kC&&0kSa-?2hyOKZJcja9=ZXn4=RrM#sDCze`uBX{F1Svngj@;OqkL z-14No{=vWPfb4qr?Ac>u#sqaF_M~10=u7=BQ{7yBty;D0X4%$leeRET>w}Nl*|M$e zGkT&Wmn!Avze~%m6d8CM-?Ft+tnd0gqBRkn!ce@x6THDAyuvfQrzvErf7oM(;I9v(G+@M#dI;%S(TAX`ON1omQc8mB2<`ehiQSz6{Wl z`U7Sapf8_Z**l9Dc!D>0gjaZm_w>cP^0IWFt!KSA$R1H~25vnl+ilsnivOXqe=aQG zi-WxV`g_B!v)u2&vH`}H_GV%C-QI%s&@hJ$G#etPHKu6CU6Np5P50;T4|Yy~~nadEHiiYdP9m(^q|p z0h@oa!HPRnHojs1AKniLSA2nxCw5TYwgB7ovgIq-758m)v_AL7d!B_tuU)%#b$cgR zn?e_6%$QMVJRW|xcb~J-La|vOczQQTdn1O(9|$(if$jKVU1LMauoGRLHD&MU%P_L&*u9tI9Xj{? zus0z;yg2n#>AbLGZ4vr6Ze%!?`0v3N{^HU;5gTn}FTUZQz+P*fwLkgR0<^+|v)2|+ z@CJ|Y3eWJKDckdG-S^R0VSwzR2jlle`Z7Xti?=`L_ek08meRf#>R}z)z?r6tO-Tz^m`}e>9-S+R#FF)9~ zBiE}|JtP~CB)6Z8z9IVsN;mB0@-JPrwrq;!!y(RY9$w%H-rx~l;ThhsUGJ$eVqZNQ zv`O})vTGk9>_tYoIgZqbu=Rj@d8iq29NLx&+wkbz60I&*SK!*W|bes8704c zV`QU^&HOmoy@x}~iRU}ou<`Y}Py1CueUjdzCO8_gC8yrnuwjFX3olt&S$6#K$J^6S zKkfKw)25A;tI@=*v-AGRC!ciBX&XwH4*GaJA2)8Cd;a>r{vGANT!o6VGjHPf_iX@i z38gAll}+lND9!KyFYp9!@CdK)4Da2S@6PM3Js1Ntb{wjABegGJjN*>N_n_?mC&+d^ z9ICg$-bH=z?#D;@M-FAHHnheq+eB&nbk{fbkAM8bN|uz3v*LgK_1BIM_Pf0N^2_cS zcD&d=f#2_b_dECg-~ax%(~%Y}wD(ir4Hz)MJ>T)_n=b8(?q2Dh(?6u_W2Z~J=A%!u zjwjw=wdK>X-R#SwG{XbDz!SW|BfP>hy!TkKJFm~0?`)8s4cj7nSnVqqyW@~e&^OrX zW4rIec-d=~RG*8s8q7WZTx+)O@8~%7s#_hM8(;j3qZ{8y?0djZ5r2mdAGYjl&3!2i zzi$pbV4u^zefwM-?DsP>Gc8Hw96wG6)n~YE)8j7P5wnB3H)^LJssCGyIW0=(1ld-5 zn&AOn;0fN~5nkaL-m?|@J)kx82W7|hknCwyzm0$NkWG3#SH72Ir!D_WJ`7p(n&XlE zOkv)+$EG}4b3Jvmm+aD|>m03r{pZJyAO8>D@yP^UlzX2BeLtSz50gLoKnoTuh?f1w z{_>Vf@6sh}UD;>Pov-@?yS?MAVa~WHot|E<@BlCH1aI&NukZ}-J@3={wdO5`Zq!=5 z_5+M#?}hv!P1YWPsj^d_s{H~!WMA@tqq9n*E>YS&4_p}oFy3K59eatWtG4~=b^Bt^ zx6UV4zkX`F#V30N!ryUEABcBXTycfl6NVfPPCfhTx_M|g#2c<-gX8v}GdO#ZJ%tN$=wzOW`sUihV&F5dmV39e}; zTB;zmWm^Dxs-Ljat^EO?#_ZFX*RIc51d6ROq*~q4b~mj=s?!Zn?vLzhJrc zG~Q(+=bYryqRpkf^SpCqOvE=e+jWbfHA*-5i5GZ+H+Y0sc!u}h+WRp`dvHcyVG?Ala)I_DFnUI*u^k3CcPaCLT`!n&|; zct)Lqf2ZV#%?W(@Py(AP?eh)u9>agztSFtHUUwC4@B&Zp29NLx&+y)7mGE#L!@B&Zp29NLx&+y(?VTkTW>Dh$sKLvYd1#JacyLDhFYn z!}qKkK~Mk7ABfWF=?$*h>%o2-@dR)12(R!A?}HRZZv5UR=-E`go25AOY!kz@M(-msfG2o^M|g#2w{J}R zkJcW(Ne|;=>ws(oWiKdwIZ1L0_Fn~l67iJ?|JbxnU;9tXIpw@9=M5_p>j|`*V!H!UMd(6THDAyu$O4$iBHTx}U6P zGaow;>^)Q5ld&_^w|?IgSNP94>o)gn?zXQqZ89?&HzfNj!}}(}ar`~< z^7rvqd>MxMjlcI}zpNAf5JP8}X1Cu1&yV)ruZP6*?R+|_PGlTJ z*`KuR)hLagR)2*Dc!4K)gGYFU=b_>q+s1LapQ>lGA3qS-O)KuH&Tbm}W%;O#gwvio z7`^A&nA@Ll`IoL(yFmTTp4*DrFL1OxhvUcl^hOSDuaoxBGX7=WpknPt!9KYVot|E< z?3aU=lf_eDyL`a$3eV1_RQzL`if!$j2>;kR=i9!s_bE~M*=n^8=3m`jK-E`a`j6Dd z3&)MWcm970Y4_Z|YGKaWI@qUAIj0Evz%Hdp=R9%1*=Q3N zn|W;7qkESU?4QE7Cv-TUs2an?^O5Lxe7X1SosZ9cjd;Ch&Ko~R3}w1{!B=gVK=&-Wc@GsFEqWI^8`o`3w=d%j(M zEjkv-yWg|&pX8rBzyO~(tYi2!V9#fwD{UifU*I!2whg52i03_+=PBX#9o6d?jCp#U zRnVVpyuSXY@%Q5)d`q)8-`N9no_s_Z#M=fTAMfwY^Y82X3N`D+;5}>IyZ`I>M+O6ax5Q!P z_Hu^S2&n7g*9_wIf%7Xo-(20gmgfA>b^LCV{?Udb;_uu4V{HElqbF_h*-i$`X&VN=?8JAAq3+_2;zCB$<@-N=$0~Ol-sn5i>KAoevo}vBEE&5Gx zw9_x}Hc_0B5S}{?%YrsA%De1+oNq~$dFs`p$vZx-<6pecr-^U>;obFrp2Wi@G}kN$tKZxa6L{~jy;o(A@H7J!MCd0}(!4l+ za6JBgoa6TAM(jPC_a0-XKY#ESVGkYf059;Azjtw8WdEP$KG*Ki_)mVeLwhbcN6YvB zJuk<4g@;xHr#KnlM~`|Dd2mh(^@6vFbms)&PgU=JE#9Ho_y6I^^AE4^4DZ^Dm&?Aq z$q(;!`y1IO8QuG59dy>R}sJH^W;}3@H=1pF_7o;NY_D^t`z>k+J3{X zGu_;__p^pfy3DxX7nk=i4X*4<_Uz$>CwPNLc!g(p*M7#AwTDuEa5M&vYXe;wa60ho z=mBK`pIVF)>c|cje=+b)`%b?$O#3gn560_(?;c-K}z>~{Ndy$;Y0P*(Vk@6jLR=)>u{cR{*^Y>FFtoO+$(8NLZkvPanQI>)fM z-zSV0p~ut56`DQo@B&ZhH$1Wj8J^)?%j_kz*LWlH7^CxF@BuYl@raKepf|{Y`hz-@ z{rjYQEFqDKubv``8D?EGtBQof(=Lek(BqQ{Mvck92nc=BYo}&;!l{XoY5IhX;58_XzI?#e4rS@BUuT2O=BvgEB%r!MDz5fYPDgKtGYbGHL&> z3ZeOqpJirS)#p}H1xv;C^wx@lN%wDFSKtEAwx$%M@H%Xt|{3&y&|FsYq!v!=2{ds8h zeH-7#6~-ga)DHdM-~Y!Fcy^ZjMwHE01N=r@jy&`z>Ng_vo>%-O(x)Rm*Ph!Xg)Hqs z|Bd#au2Xoe#T{Sn)IQXo6msRaA-C0?J9Fj3;fO)|m~;Ps48@TRGDMb6rjji(cCwbt zk-ft}SR4tjU+cZ{YpQ&&*BQ&7iVnB`TJ&-LjN6aSeq@4ti74y}g8WzD!-6wj{x2L^ z2FS_DWHiJv!qkQqC#gU@o5njz-Uu z_>K3e!#;g??iy#W6)S|}>t4PdI&eOl4=xYRYKsr@eZd)Q1o`I)0_VAL&$T!q{yY8l z=@rP2{NWcrGr<{hoFfOlE*v%AVfn=Q2$FB0uwNi#j_knzUns6#5H?^0R$vBp$BH}O z>HAu$S9Z91-q-O_+@+Ub9>UvWi@%*9a6VZO0$)S^ci@MpBYSrV&i{~n5a}E~LU0}* zK3wF_g20)4k#qStn-Bj%&Oed!Q52lf$2ooN-MM_6&G(u1#1rJZ$cF|0mLH--;giTa zd>tu{|HfUF4(Tb7zVnGhUIgXeLFWWIdK_KyX(T#b@U(LtV1%bApN`)M?-BV#{W9q{ zvhs54xJ>sEd3yQc`-C!v>|=aH2^(J@1nt5XJHYT*bU@#=6!stFmw8{_L%5^oD$kC- z2;I)F)C%p(SLo!f_*}xL6F!*m;S>1faXz2$IVC?#9hb@v6n>|cAV2wrT7+Ej%k;Sd za+iOmyTR^bYj@X2&JR`FJLF$VeyE(UDd%@eKB#VfM?rpVbQWT(8|B~U#y70x4S&~} zhJ@Fx#dWWR!rycs4!jHExcGc`!y7Igm)=b}FOT$Z`G>W+_1%b%tM_&GB0jD@baVxN zu09F*x)S~31AbB?KCj@@@eAKB;IAf-3I03+IZ0;ts?xb~J|IgMylzM*kUhFkKo8Xa zqMi=wf-gP*%cIc&)gAQlKBt}cZ9MG`b&f0VQQRXw#K0L^g>w)Bzg6DXRvNyibY^9z zWxL#2lAK-HaS1ph8!-M()1erEmnlYyYbA9ACBOI;WCz zE}LF1pFKLaGUbwItntN9TBC~|cYd}S{&t7++123uZO->r{qr7@|1O1dwkT}YnV6fb z-r1qxo^5vT@bg7{e0K4D!{2OIT93GN8!LVCN%{TL@|X3T%fH!`FS&Cwn~Sa%*Z#$w zp9#It%{iKF#0UJeyHh@w#9#ZnKXLq~E|d>0@!wJU-cfqb8JoxlIi<lwa&*HzSi)&Rztq4s?S?w)#SIV+U&cn>dd>`d7}99sxs|1t4x@BtHLc- zdCDzTY0AyI67-vAF7W5V&2^`gftMS9ZY(r4wyN?lut4+majee)I;w0qyr1E0k2B(%~esp$|{V% z#-0Dlxv`v|iqE-nqb`%LwM(53H~i2!zjfYs9scVI3%rlS#rGTEmy^FXm!8rkeSEi( zALqT|8xI{qztFd8v+r@f?P{L5Ts{KtmruF1s%IXQ-aaHBYmYeonq2yf)9n^lzv6t} z;eW5qt?~mXeZcn}=hWi=4!Ln&EpkkgPr&r$I=5CbcE0Q)df;^-Xjg-F7>rz-Ak3Wa z$cPR^+5-9m3HyZf8R<6!ef*%@2iOO`1oN@SmtYVaP0;21>&bVa!(H{-qEE$#&Y4}H zdhgDE>ik;Og*SsabvWhw1?PLO@$ckw?Kj(0t~W*SzTf#&tUh<4^AG3B?v$JIaUL6B zj32qMFGA;ca43EV@wKOb&%Gh}KKqXSK9W`>-7?A}?BCGoh|`TLou5Rf7t+fr({7bc z-05_dvyE$?ywcSb^`#H^8*D6pcTFyN%K7|jq57ef{2#Wy>2-HjaeI{!d=#dtUOaE_JgbDEXveM%7e zpKYaM{52LwZz6gYuMets@ReCX^+ccxH@W(ObE#{neZt>i9r*^u&t^l_3;2C(a>iK6ZMPUGtx<;Pv+WEm~% zocHa{1CPkwVV}61gKtvD5%SL||9dr>*m33Lw@P+fOnVm$^1C6Ql_jb*w2}=wSyEe_ zsoZ^z{CHkaL_Okl;3A8y7u0TWCb{(1wH1?YaP5_=59Z$M{6E%FyN2J-hUaaG>Hueo zw^ZFoS!sLA8`fTBr^ABxt)tHUrc9+Rk&i~5|D7&*BlpfLC4bH)mk*qD7w8kvFN@Rz zZfp?vj0IELbk`0D>oETG4Vl+-^}g%x1#NzSeUKjM;!m_Q{zMhX6Th79Eb{wyIp3nt zhJVpci`0JIBj1{L34i$+ZFBSM(re)_KbQC$O}Y3ncXoP%b7};nyj?-4U)A*G(gA#{Msy%m zI)Ja)w$g#t@;BS^>OWfZE1tC`zt>pmw-0NarE%DqYu%agHRTtzy5vJSL0*+4H`lj| zw)ynuy#L`yTdz8xRKGJVsipjQ{aTn8T0cln|xeObPVB^$BA81N1xb9b7?m z7k-2*OP8xmzfHQW`d@Wit&^6k&Rgw#-ZuKpL#hh{?D0SAuvgh{C+s^!uaYNSTZJXbA`eftcCg2 z)B!5{>hpj3sm`u<{e9-{8RIjSaN|3rgD>6AtA3Q<)gWX(@T1PX|51KO3E%5pL4H^= zoi6N>UrPDcU7>nPdXTnQZI}G)rY?{k+#x-NKfK7()d`V)ei^mnNsYB{E#jN8=<;5|*ZqWsUn8Bp-i-;Wddyv$PkF!J z>3M^5H#xm;qB@Yeu*Fp`TI=hAGT-jD0QZjfyzl%Ur!D!n%Da3ZulUOO1I}C}U%kQ{ zStIwZ^8eLUevJb>lc|V)h}$V zwt+q$eMaj2PMTLhhe)T(>b=TC{wC#fGHdOA`QVlBLBe{1&K{R<;%@Rql_h$zYbSFj ze=qT@YpSZ}H{$AzU;ry)A z>DJf%Njm-)hc$k+Q}6nR`bPg$IrzZRmwYT=-=8}F*BL9naz3z;QPvvy{gz)JWQPoq zWq0{y?k=ByJ&-Xzyq(M=ezCzqn1Br!IX~gT4D7%VEL}SwY}*NAUk8A_^k7}6t1r=vDS-%_XGZyNpb*!S2dU(}lvHV1yGd-|(|l*-obPj$AAGbspXB%@7uMPMDJM7?Bj+H10a$=ZR0pUBgc;a@Ay_gdaCLw% z25T?}dxh7i``fAR@1Xjjqvns&)Mj*+e|6fCOz@}PmtNs}yodBGz@GetKR%ha$UirJ z${*4_!95GE`Sgl*_#nWO{5Lv(>(Xnd8}jAXU3FV`bRK!2AC!aDd#vgFTLb^Z1^Q+3 zCtRhGd}sA7fIDY;36;DXom-QfhTwa z;~pvp@Z3YZd;jlFCXx*@ayWypunx=8-8(ts4?Wk(9t^S-*XaQDa;OdfJJ%NwmS76D zU<}q^4)(2NPt;a@!uFgUp!%Vc>VEvHqc`|i@2Yx)HoyCNVXw5EKYi&N`Fh$C`;-s) zbC*u^iiF@hcvBGVInrx_Ccy` zm%l5A)W>QEzzD3s4D7(r)d9j3Y{3|;!5r*$cEC?WR*(FETWa$W&i4 zOJ%>C>XUHUcV`Mj@GlnjN90Aip?V`6y084gDzyrHbcW@MtdncCcm6Xf$qzlgr^4qU z`#q}uitm|UyX?p73H1+WW5m#@dZ2{%1GPSDSqxuc9)AtlIUS%Lj;jN}4D7%VEWs3P z!5FN;9PHcN^;K>=wFez!A4UC;u6dp=oFAg`B>F=?pYsMdcfpr^%59*d@<%Uhd&@Wd zuNk^6`^d`G3;d>rWm>X)4J)T}MJVTud&izf;qi{Y`tup$G5b&a4)(ysj~`1|%CyUV zRry3^?aEb9uYyTWUk3;)FatX<1WPal+n^1Q4TmrXdqVqru~}h#K7zmI52!b?BKY^v zc?;P}v#078>g!$+{5g{%O3SaL17KgaUh@KFsdTM2+G{t*?X`@@IMMG$5#NJhtPAr) z#(wpp{BwoBKhizEto)wuuv8`Vg_is3 z^3Q%G|67IWKp1Q9ql3NLRXa|M=?~zWk9H#7U&)cMPV^pMt|iM>E1<*mho1PW%gmh# zLfeTB(3cWMU)fLTv%=%@}bR^T1FaU?&Li7=0U&in&&5&66X^M;Map8KoG%*kFDxU+Gn zi>a6CM++-313NGTOE3jnFa~Qd2m5w+f1R7E`%Vsj%_pm!=&Eradczqr*=k2z*;l>d z&Qg+|1?B$N#lKFkz_&nHUd6>8-0(?^?{0^q@U75hgsao>!Q^odU+FWJZ#6us1K}}4 z?LvHZ#p7F?-^>>zX|6fU6Zg&MT>InR5BNGjSb-VXfuXAdn7^kFpgtg2gE`o@ zclfLB*Zg2-jS)TmoUhbF^+!*QCvr5d?4`a%Z}l_#D38ACcTo2GZ7uptrJ~MT3cqW0 z((MIgRFqFz&KjwcI?C{~jUN*H6nPoro1%2(dPaYtQTO?UV(;}J@L3V~C63pVnw@7v zb)z^~CyGs)5)Zw5W7A9Z=MqmYIU^RRX{5-y&fY0(|o!7(qk?Y?v=9dpY z<{^?QH+1uY{w$k#T|fu?*)E>WlBLR6hR(eDrSc1OASjQnUZxHJf9ik;{$L5FU<<}z z4d!6qL7|iS1L^7)WawR2#p$N@qKDdzY_%Ubsz-V$EzaHQtF-$G|9&d_oW}+2iOv)& z&hvho_gRI;?W1KE*_5eL-<>lT#)5m!Tf_g5mtXjrEMFv5Yu2`kRXCTd;CeoOI{f)g z@#*rLHXnaw@$cv}lx>uiaGtL~Ud&BYZ|=@>Dxd@Sd<>n1$+xAe*R!1aKl?>84D^S( zSUN!2q>R!>7iM4whF}S%U<=0S!XM1RJ~e`W=R)x3j4{qy>m7%G{|NpAej)zNrd|?* z7j<`GWwlP~NOvAZSl)FSrr5~YC)s(oE^_CyaYhB<^5q+B-bGhhx8A{d3gK_6x9C*> zV=$+zS5KP~^RB7-2mTy~a2mzB*P3CedR+>%AI>LMa=93utLpqQ&NM4dc_}oGtAAA% zX^%trgBjR?VLbj|4gO%Cdhge{Y1*U0vrP35v(!)QE?vpinr==6|2`U1^i|)I^!uyd zKR{)lkoc^+L}%FLKhIwDj{^06y#Haaq1@sh*UP;^rOGzxwDV#x2Y1e@diwQ$=!}x@ z+?hqPZLr55f80`1Qlj6IM)6D9qkt{tPU=!$o+G@t?!XFI5 z5=_AsjKLbr!M>wHy6(GZT+mgvL){dohwM6fg1^p~b+S(fg6OUk6M0VA*iGq3|gumn@E1!J%VbFlBUFu*?}f`50# z$yVGPebYk@?4A#(EhZ`>>f>nv{)kwPMxPJYa&?+mfB8Bot_;KRz`~VD zVFN~B1!iCehF}S%U<>|W4gO$H=&bupJ(*_ze}48=LTut+ zy!qyvG3U|Ir|_8jEA5ZZlk38T3*(b1@SF2sS3muy7}~C0v(-9f2WL#U^i+p2FC5kZ z=L5VHXa42)R~wHw^_b+z`L19BHbEVrwpy5h9TL75>`K(M|7q zMDXvWZ~8>=@2|85sE>nHc8Gm>rhG))Ormy8O;L4dq;W7P*mt7wtU&{Z> z@BFI(7Dsw;&N=5q^Jbh8&Xe{(sZ8L@4oo=Xu(*GmZ?^og7h`Dr!>TPto#pYx&wUtw z?)`a}J`QbN)=keHwGO!ReIxjT5mf3Rr@)*>nzReHNs!^g?(h7(pNS*{dLyvz%4p&ROjvn*z5dJdHYY3=jm{O+AQcOFv~hYlaM z+c!TELo;WHhU)!o%hA39&eiTG+r$Bz_NgAxIr2)2v((Wqcb>Y#KG#O-OzPr>wDXom z<&KbP~P)eD}8n zXr6KI#nC)D=Pthd^V^-15Sr`2zkJ^%?-WbE?tFX7WCVY(0yD4!L$Cx>umxj}KiCs= zezNH!X7a31yLI&0 z{rBIW@Y~|N;JoykHar?b_r;6WMAJV`YY~Ov&$IZxVEx{c%*(H+D_D$(;15P%1!iCe z{$L5FU<<}z4d!5%)IaR4Jv@EYU!>j`s58dVqoHa~VzJj*^eX$K zAImFN7`kDXJ7X_e?lk7}XGS4^AL#q}IF+hai;*FEuyn`s1t8!&_Q8Ym`|f;SLhHfP zrcH~ULmvK!`9PnC$G=>);9MS_KlWH+9eeAow`}Fgm9}ctD*N!m55vjE+%J3Vg#xrQ zZ|(CfBO69n<~bunYeLD@Tev+Y?hNQq-Ps>Gc&>G5aI&&#MxOqWOl;fi4l6 zb8vR#svp9<)a^F%h%yEXFaaAd0xK|cb$~DgOE3jn@CR!!2YZLV{C8w)A8{}B4~WxW z{e^-0X0W~;3jV530_+bdpWFa@TA*pKY`cyb=f8YD|mx`407-13Ufcj*Q1mzUWzzz(-5=_AsjKR8_Fn9Pb-Id#2 z_dO%{_thR8;tm4;Ey9260UNHgMoO$a?0?nbCB;tm3biTyjawHy2!RLG+s{@)JP5 z;rS-UhvB~!D^^6~$EWRozx;A+y|nh(S7PW!ck4E88cio${y7`or<3SfE3I#las~^h z1N6y+5mqm<@or9DP@ zjCE!Iu#FS;M+$xKdL@QGe_l`+_wc>5=Ze(ltnG*E0OtG;syzC?apT6tq>cQVHf?H8 zKKZ2W+O^BI)$#a;*MaJE49<1MrpU{F-n@A}d3T*YeY%y=9A1M4+6x?^EB<=L6<5T3 zvvB*fF?7R2h06J5z_6+e3a_a#nq7ebhhfr~PRI)n6Q}Z-zd!UwU-FMm~Hng8d=olWXIY-?+yQ+xRE) zju=u;ydg$zM><=SaiQmX+(~B@kmJ9;$e)|J^wLYCas4+>KmBwJ7C-&;Q}p*MujK0@ zYmR>1f%DA#_t*=B{}wM^?8Xc{d+DW@tZLPQHb&>4e}43n16qehPs4h9r2c<+AA9-Q zjjhAHtF2~gjyq$_(^b7qRzg{W1(<*h^({I8W?%<~U#KMD z6=#s*4$(Km^z8_xF-mETQJQ0w_BiD+UU`jIo)d)skwSy)u~FH=OT%t+qW%4Fx%cP3akzp7n1Br!ffbm69TGKgt_+c!}2CJr+%RpRPVYu!o9q+_`aW zzzyqn*bn>j%k;W+>tfb*=@SW( zI(6*FAAgL--|&3FzJF@>oai^nHCq=L|0l`+h^LF|s108hD%UX&eOu^rj|bR*5%_}{ z*nuHff+^TK{Dn36gMD{}p7JBrThIE*zr;Yr8LYU&^v#H^`=v(*Y>d)Euf{9w3Cd%l z!~U>MdNQxbFlv4NTpN5b&h|JLbq!VnuuQ*=M8ic7FSP z0a~#YOG-+PeiQEd`FWt^xbv_FEcjEAa*db!#3xi1DU-qmj9eWc%)kx|!4gct7L36f z%)y?Jqx(L3)?e=iZTP{4DDLnr`)s7X9j!FRDy?zCe}dAUs5~YquSv>tvhXh|^uBIK zlyBr(rEzAl@aKHp@cRGc)6Xv;*Ec_k#W)H=+zptG7=aC8fGzcWyseSf#qc};dX$%! z7n9nZci!pjh*DEi?X=TQvyVRdDEgjxKgOrwcAxuhaK-otJl54e##(~b9 zKWr&duJJMl3orp2Faj$u13NGTOE3jnFa~Qd2m2n&g}?lF^^uR60rF2koS~cc+6a9! zYTJI5{R1}ck%LaJCO&pZ`Q+MUhy7uj@>E`tA^qf=V)&}veps>a2aoWae5ul9Z2s@B ziIFX~U$nJF{V_K)ethiQ1N{q+cl@Ar6S|G|ngtPuQz zvY(It6y-Tp_!kwL5072%<=otOnJ4;9pA0)aFBf!R!YSv(=m6#G$=BYogR;Sj|D#Pv zON*6jl}5pMKT)1M59=NMg`({L$P+u1=iYd)0A1(Ye6N)c&H2*ChcOS|<4eTz$u<4t z8;g`{yv)HOjK8Y`;_wGkumyjx26M2_ULpMDW2&Eglnh+|y$#Vm%we1N+Q^6Yss7k+ zV;?zS<98f%dNt|sL&_)D0_+dlw5Rim47Jnp$JOxV$6H0oKm0C5XO1W1vs2&t&?>Eq zopi;GG4j4`)8qE!-`=(lzuaZ7zww5haKZ_$4fo%0t=usEh<#7;W^Sr%)mYn1?8Xip zI1sO5##-b9&&1mPp_3;)`Q>u%d4$wB! zMyn1GW?%<~UDOAr_!j3L9SGM0UQXDAVq@8R^hE17ZmMPW8*B}lwTS8CySQ3I zDQYiaVKg+A4S3idh;*1Y+Pvi<`)v0&_S(NbG3NN=$N9h4I$zF+ac*tE(|Mfw8}YWE zVeGlb-&{04c}+U6NV&$#94x>DY`_To!3^xc5G=tI{J|Lf!5r*+-nToqkNh_Fm*2iY z>K_i>_@j+be{q!h4P*7~c-12l)t*dJ-y$D-;jX%W#?wD14AVtZcuWn3g~_@&&u9y( zHt7}}7lvh3)P32i4T`k&FDh?zpnQ$|Ia{9(^SFJ+OtL9wUSRVtxz^@fc!iCebCPw) z$~N|)`FQTC{ej`R{&?K|Z@2azs^i*>KP#bJ3zIomOrtH1=m1!O8Q6g#Sb{0of-zWw zIoRh!@E;)mRIcq;oRR7;jMg{f^z8(tF-d9pvOi6E1lZ@<%x8X17$$7|B1RS!YPULO z{5?+W4WoSy?+b{Lw`7RzAbBNPWAbSg=gM3Kbw}79F+RUUzuE6urb(ZKb-u@*Yhm~o zCENISGpL8rflwU)W?%<~UK_bOoKcE9M&FFrw-c4d zWTiDl^~zM$FVmIB4COUbdCn64iNc6Qv9_L-8>anY{KJ?rMr8h;`DAQ}vE6TwIX&Up zQuy1Wy{8ST(l|qB-j|Kh>B6wb#y0P2Ck1%_Dj@AEUeE+YL z`hSV!TG(^2028nQBd`K9umeM|bbSC}>-vDg8qC4IcLe`IdNx$}k5HV^!hf8;nV@ec zDUB&gYnm(jxze-4Hp`X$Jew`-6NO%vu8G0FX6pgJYWe>qx)ApDaV+UHF2t`?e3?F) z-}sje*Cn0jU!72{g~@vsWzp3EYMX^WSb-VXfgxCeDcFKBSc5;<6Z-3(XT$Vvq~eST z;XhevOpV|_Lut9 z`tmV(H25AVE_=np_;)+&&V+I;Ox|DtCSU_b;16bC=kW(qumxkV26M3QbN}w#0rF8g z*yF!h_;1~(c4NQVkDqMHqX%u8#+2yQ%%^gtXNPT$!#>aEKKFCN(Dk%iVtA_CaZI%Q zSE}F9?d?q@-~aUUnq6i_X*rg>@Hy!*#dnmyKh|sfe&F7!JByNS{JS~Nsw}!XKy9-y za&>?(13NGTOE4WNY{4I_!5r+v_z%~+QHnEGaVO}TNg@1$vY#tG3-F(-Jm(4jL?M07 zWij~I?>yPbylz@xvr#j&_vTnI_$A-q7xH?Hj77^ecB5=P<7< z|FifJJJxdVzl*m49Dn~i3FTUtygeRZ14dv4W?%<~UHCt)VRUY$P+0V22&;Oh-be@vgo1}_TZqTZEnHOyh&DCbm5ksn%*#oD;(Tc;#6bE&f?N{?(hu z&T(Sr`Ah2HqVPG=yE_^3 z|K+OJDN?RpzTqoac>KW#tia6U50+v4!5YlLzQ4j?@Za#AjoS2sjg^i}kgiOAWWP;) z^e3DC_(7ZXWPtzNXL6O#Vbx8-Uf~3l|3o1ke{a_tZs+P}O#83Y0bop7umxkV z26M1?_^5E%<}=U||mS11SFy{738EIK`PLU6~@CnXYeVDvjAn zYp&9qr?lrQj}u(k&$E++f1*$v{EK4`R=>xIn$tZmDsM0MUwXwKG&)eR%_w)R(0arX z%RYI=`=S1&XG_G}e)Kr=)`T)mBx~>o6R-gzumUr%14FO`Q?LbNk3ZNCSiL)Ui0~gF z-$SD}|6t=4XVSyMe~0jYO!z->(B?c9;D7wH!v8tpul!C_NJJ0Mi-SLQp7H)4;&G*a z9q*enKF+cHjz1S5+!h>7dcN*B*7`qw&*!MSo-ITX^Nnz=ta~kdi7c^ z*UR6oARPn@^{)T#{nlEu*WPDl?>WgiISH5ZJl`|>>^if)@BP|ZGlOo?F}g--+IZtGw45MKkEL-AO5c^l39mT=l}S&UPDH^Q7aG3 zavh#a`$9$I&UM`J*?F%wir0Cc;knwlO6jtZh20xDfa6<2dZCiP|*Lu$|K*ceBw~m z7SZ<~p}ddZJW7}1D3V(Jb3Xgt7yQVrIq_?ipl9;!{qz1vm>Q@F>tJ z)UO+>dp=h??>Axn;f3Q_G|oI9_2GShIF+u@8M;G<=n|cxe{_tl(K))0`rq?w&$)e6 zAMF427wo-0_mlpWM;xMf0{e$c|3?JF2?;W|c`nzIqldw-edxV|&|ruT*@^SSt*+8EMYTj^*Z-mVuEP@jA7#G( zf8Ej2eUU`{#$9|ve9y*gH|6uue>7L` z@%@|&mc@SQ|6OvV6`aeRpb);;J-+Hfpvvxny|D*nAzVnk!-go4EFS#x~lXbmXXU!U$ zM*8D^Z;V}f-;RyV{~G;Pnb$YvenDLKE$#ad`_u7j&SP|ePS6cHiuy-)=n!3^Q*?`t z(KR|p_iL_~{%;EUr}jhtsu%gp!BPLJDf!ML{!RM7|8>(nzxh7#UnFxB|92RveCGQv z<-TXiemc)jHXkML8nCrG@b~Ljlf_(ockO#N*Zfw^wFAHLf;&j>eTVAC zcisDv@`zWIPrPbz3tvCznqOBPe}~T9 zORe4GI{ndq_MA{zQ?R-89)G9S7UMn@ZP7jVD2}h&y~Pvz-}{{V3dgEwjN|j@0-c~6 zbYwYzbcXKGA-Y7T=oTHLYjlq8TTB0ke&ex*$1`~P(kdG$x;B3tbGDYVh2CB7O{m+_ z@7$Qj{j`Q8>axt%&hgVV2e1RH`;zPYbm_UhJNo|D8je@gckQ;N^uM2M<1Mn0x5-xC zDVuq>Z0Atf&|$JA;>uC7t@p~t-X~jopKR_}@xLju`zg0q>7Q$Vl!@o8zr**|-m_z4 z^tiE~N$(%mNdM@Zdj;X=IoFHz!7=W!ov`~Mn>3E-0-c~6bYwYzbcXKGA-Y7T=oTFp z@xQtCf6NbGcRP&OxoRxx-KQtj)sTfpxlLWim407y9yfQ*N5{UEYnl)PYR~sy|CPJj zO#ka{c7Voc%Fg$c@fFR{YuWcUXU>Of{cz34$a_2P|C8MRrQ7!X z-23i-Ws}AcU7!4Vp`;L_wH0n8TYv*+)*PKc99v{E;il6_V*Z;BdU;W3;sPX}2uN6|OzefLa z@A#pMkIuENGV8yZb6?Qf{$A91-1ZqYd6RYjM&O@g*zdd_ROz4I*w6;o3Tve6yw~X? z(?2AKOJBz(8m<50n#F1FF^~E9T&EX22@|q zw?pTy?wvRNk2~gvueq+h#5ndIKBu9MigcIvd|dx)c|e2p#bx?^c8~Y2+h=^U&pS?A?6Bu}d~3gOy}dr| z!1rg*#n(1v`$p40W3l|B)#r~ho&%@u(_%Kzd-DDk^UJLJRF_k8w^sDF-Y)RMibc(VJ$FWC6=Hd8;q+MP1G_w28& ztN+@$d~9{y2{+{GxTV>DBkTW&Z$0g{8#JQI20HiXyIHRt(TIKP@hL||=TRo_bwsZ2 z(bdu4|5xE_yuLBgBK&JjKwHfJG&d#zJrGIRI>v`7G zALkp_d%etS^>TjZ^xJn&&fU;Hk=NJ8{34yTU(OyGm=o&K{ ze||AN!P*=z{lCL@L#p*IFC$1ZFW-7{`Y^e{#pCg zNN+9q`g`wt(G8kheXZnewrOYAeysK9!*y*AbTeR5^VbO1>+^T2xmG{FG2?9?-mK%0 zjww1Qt$*p()_(;3qx(Glzb&l)d3U=0XA96j$9?!cPr5!MC)MzmZv&mW@8CM>-a2{b zmlgH;IlsH;oW4#2CfEG#Hg3#{{k3+hW!6HadM*37k^a#k>wnNG>;IbQUu%GE{g-TF zzdQcv*MI80w*Iq9|F1Uj|C^itI3|bO@mJStaP^uY^8*vsRpor~UgEXa{~oFyLjRig zM*qRJfzmi1ANv}=U6uZa&RXH#_irz^8T*V!zW%jdKlp$2Z|gsU{?YN?k^i{CEhxGh@S zlc)Ou6Xv)hzw=z1>b|c2r8DAxp8jq9uXJ9${{PuT|1W0izu)uSm)+r8p#C}bcYW;- zIeuUpx4o{<%iKQK3rGLRcDm>Ah$Tlm)|hi$`r0+7yr1j2Mc(7qU!S9zd*aVw-+a8y zb>C3`(p|Rx`)*y+!`6T68gIAiT7TL3A5ZH1pQqhkU-SCs9Fezuv!ee)6aBNcJYE0W zR{o#kj)EWPt?NoeJ;yEAn&W!S9lM76ZfiYJryjmu@3zD6syG4vto?{OkK4R>za{BD zPygr$Uk$V9F4Mnsif-}o=o+1`y`F1-J*o5my#DvS{h#hYo&R@`-W$*V;yVu0cO9Yc zY^wjZ%X^~!*}`JKvD2E^0Qd8vR~T&~Zfko(^!aMf$IoqPy7&6`Yw_dyZ-4%W z&esh3ublrS{oDDUUjOJE-LJXM>wmp$!t4Keum5}gW#^97>ffLL^SV36&i~mm^v^gP zdGE81d@Sm!-j@5l#+dK@ezLAd*JG=_CJ*1WCF(xYzn%ZX+W&a|PmTViOPD_J>$qa=+O7Nos#|j_y}o^TaPy2U5uK`e;18&JN zARVKFuKK0x(RWalP6ti%*ZPWcdsg2i=i_<(w{vse{pmLC>!rt$_c&$0%J(Zz&&~Z} z?r*gpx&KoR-LJgn@f(!`T0Y=&z}g&u^FZswfN(D8mKF!%m{px$taGur?+Dj_wpg!o zaZ}!T+@Vt!x65a*+9LgZJf^67a`2e*F`By!!Ev>~ifB z77vIE{ygBCKCoQ}!1sY-9f%LedI6aYRIUjS_q8pz)P-ptz%}QY*JYh%NlrH>vxh@4r)h-z4^f%`59oTJiUHOKRvkzT zP_AfwfTRw{&IOOXfW!u3JwQA{h)rJNephcdhh2~ZqJJ{Z@}t9LG4WG2Tb+j}A4T^?b59-%8$})qT>b_5JAkO4sNd-7mlD@eZ{=jkE-3hbSPSxdu^u!(5UvZrewi%TRP-73-zSka0EB?<~yr|>6E!Uu1 zcjC=vuWhk^rGJyL3}YMhPP~V|O!rB@*J{2{^T(bKIt^?7$opacM0AhH4tA0~&IbjbSZ>aJ zYVL2v@rzqHGv0&V$@S1d^!ad)j+nnQ-G_b;y0rNoU-QHMm8tH{2VD8saQT22)f2Q@ z0ACT~zyVwrD9j6{Hb7m-Z?g~7oa~R;LhuXb8?cEg;TRI(m|8)mAN0{C`X9bvH~03N z|IjMGx6#Ltj)gt09xukwL}SX>GRBN`)H^z$&r_>=bVdx1exH6Hx<$v!rR!S#^S|uk zIPyZx3t4}dI8bW?_!aU2)|A-wLG|029Yk9Q_K?{`VjFf0@mN}MJ8<%XO#j`sAK+FV zf1Mw{R{YHtJGMApLD!5UJ|3OZ*Mqr=-u?O>bP|1js(at-wYk2S^Bu`919pCh`~W#2>&fs1-VXe=La{^kE7}A58O8QJ9z!c{-*xwMTJzIM`fumP z?RtoN$DNP+v1{euZOLPd;}*AZTp45Lbm5(`H-9f(pp)qHBlqYI9n$LyIp5vrxJduO z2KueI`tjf8*?{E(p*O&9VQt+d4mFj9Yj5 zy{-B?Eqx4ed~6%WEsi5&n&~{zdt{zGpSc@!gwJlGd+AiV?^jRv@ilTo*}&hU4KPQ8+aHS@cDqBBZ~0=JEKpyzxs;I zD>G;0ZJ}ZhW)tQkyq{p-5su?cX*vdReEe2prm}Oh4O*B$O*|EsSSxI*cWRE@H5^Y__f3MAN+#Z12&=cM$sxsrMj-5KD%i)HQalFfSb07Bab!#xTh?eW){Hr0j}FiU zI-!4uj?fi4Lw7}bZSM2>uA%zQEA`#18M5EPAK+_PONQU^e!=?&_Rs7h*amCP+4s7_ z@%>+r2IIh3p<~wR#&N{oqHo5Sv1ZH}dvuWK{Z({?u9~agvhTOtP`zW>!5=LyL|age zfeo@xj;7%LmIFos^&Uf+x{c^x`u4i_Du3+esD=H_^1b)NS= z{T6Xyx_$4e0#+0#Tj2Y{&cH=m7fG+ZMROUI&g}nLq<_Nqw0&kAMnFro5-D zCydwA>G<;=ch&NQ{;wnF>$NxK%`qslfqJ%MuT|SyJ=?7E5%LSQJ|X%8STH7F!!xqc zeZbb{xVhi2@2ap zs(6z55AP>x?K$%a(I15Tpvo7(if5)*b9viR-mm@NUUGuuxhCAld_ISH&wGXSYQ8Hv zogl_1Tv$(@((8#_q{nX<(Q#i?EAjZ^^Zd`_xQ)-3-Nw(wZTh+RT)O3P-v9CWt!$gx zjy=}#7uj2rcvFc><{J{9koto>Ur^%*o(l|Zzol^9Xg@}t@kl4_Gx5HXx-o(aqthF|1{;$SYRPr$I6Dt0ox>pmqh&==K z5UoD8+5ncs6l^u(uPtBKJ}#6zlpF7BxXBdx)Bn@Yg~#@p|LBl#v@EV z9)!o~|MB_9lK1Gj3;92YJ&w-1GHRqrY1HhX0#uC-(k2{-=qr2)-f99c14=M=0_Im7E~g5BNUe>#zoM zc`R=3=d>R?$tOLS#r%-#$DUrScWSwx5NoMC<^%6dVsqfS!s@f)Hb*YkbIp}p8xil9 zA@~$Aj+ouaUN4Oz`{l9OF}AGucZqC1vdrV`|CFPI(Tvr9h|7PtiB05DJ(tJ@dTjED zwmEXXo`S_T_PF{uI4+Zmv^5FGf3e1-N~*^$ z9anoC$2uGTs0XjBsHcjJ)cAJv++5p;@6WR}d(Qtx=1*#TM3w`}AJp{)Sx!*n2j~@2 z4^-C#55nH&<~{vA{r=u!KdbZ8m|vg!kRPRS-k48fd&YXgchrNnQ&YL(IXAUR^!gQv z*n6MRXDTv9kEdKNn~7qaN8XxmwQolbayfIm+38^pDxrl|Sh9TH!N#?yEds@cH;V zVasou)b5wOi#2-U;Y#dj1ocJZiA&kj|+QxCRt@js<=VbXu+cLgUOb^mQ)Q7fJ z`a*x1M7@S>(0OVP)sGX~F*~ZYuke3jgH=8y@e{Q^A#=_OBbM)n`ULi?V!qAGhdyZ5tFLfxxqS}v-fvgpcgA@Y-+uh3UHP1w zrsr+TV@b;WG}B#$`Ki)-mB>D(CNkx+$UC+qx#aOo%VAn#m-yUD@)5p6f{$ z{7rTpdB*1dBA%nbvDiV*`J+iSkG~g(|Idv->)~oS^MBm^J+VEyv+S$8@%r3Gy>09J`IfpEWj! z#^?MnR<`wHXk!`2)y5e=@kloIlP{JoOrmZc%XDTsM2{xYt@NAf+a6chgly%CD9_5a zykJw_wyJF{+Ff<*srC(-UkG_ZT0>O(0?)>TT0fw z-_h@#F82NU9rFE}IzP+x)yI$Xbk-}i{#NXzgjk>D-JW^lJ!75mk7NGN@L1cx`m`&9 zj@ZV>(%-a9hp?YAPfYN3P|UjQNA`r6UBNl_mI;i@HnGu+Y1yu98SzYe8#kMW0a!RI z@+(#{X5mVlohBwv`%REvyRoPK%8mK*e|q`SFWngAlwY{f$jSd9`MDc?67n;XQ71m= zGWp_9-6)fPcOy^mGAe9Gp70Yr*GR%=^c{SD)E9%Kzj2a&&we}X2m5o1_DjNk+WxZ7 zItGqq?5R4Y(-0k_{LeV~rsz)?i}7cA|KZ1pvGRUnf_#Se6&g?F8xxglL|-vUJ{28! zU;B6I2MKyYXF-3aOZn~0muLPU0eH9;db$<5BPj*tGHm z^9MD)Am0zDM_}`cu}_%z0QJ&gu2K&?LN0Ln=I{Z^H_nah=jZ!1F+Z#C^SJl9eKqre zcepo67&kwhuzn?adAgz->28{Ih)lg)z8*3CvVFp2%B70wmtqeo=frYi3icEDzCgBR zj0c;mVw)K4nf6@6^g|{VD~)B(vDrT?8^fNF(I@{*{J^Yd%QN{Sx6>CSpMSvZ^tm6p z5udx?jX3__+=$QqK=OSz{4>aXZuqCaXEN+l-*Lk}iQMake&XASe9H~}c#x0XqsNku z-EA^N+aj^|#P_nT5`ACt8~mpKZTg8vxvCHamo|I&?(enUQE-08oO{ML<^pY*=szs;92?&KB|&X$~m zfB0kOgYgmGH{c&67yixr2lRU}zTr{tG$Yh|pPFJ&wlyEvxLxal_5VZ6;BM?D0cz&$!b zU&gxhDZP4ucg6He&^rR_#0%_#JQLR8oERfJl08j4hu9sk^$xx0B2-{6#wdtJgg?An`UKyO51cl~2g* zMs|cPnN3CevUpSR0~Nc(MxQl1WjpPvXuHvtqc8B=%oij%L6skf{Q>-dSjv2W7)$Gc zS|0$Tt>FXoy+;?ZUzP7`U#Vd-_L&!>9~!yWHmm9BpEQZ-p8IrMV~n4E<M8{W|$dVJIb)~BH3i^RG(pL_v%qvC_HF3!&-R}Y+jRWSw5&m@*d&dFcN z#TA=mf5v#=dla!uwz|{j73VBg6QhaGVw)H#TOayy#oUj6(+x4E#f0&Eo7)j)BEzt2 z%)+49Jn9y^jhvwR2N`L6Tr`}vLdyX-@sL$oipPnY<8)V{LM z{f@X&$8eR7#`G@EmPWzR7^sl8u{K9{Ezi`&?Uu-z!cF!KjlEKB?VHGzpZ$n^tZzQBAy z^aD-nfgB%jbW8dG0IIgIpf2!1>%I_ zh3sSeSBU4b8F4=L%c^0&q&S03okV^v8#{q`q!_LkHR7}Pxe+i<><)Yn{g~pLY@mXqzYT^{Q>vckq4T`@`?` zJV3w8J{)+O?GyX8-CMPP2c6-19dxGlTl=p4@BNOmz3&Nr#C!*S10VJt`3%Mae-V7e z0Qo<1kAcVBkobt(%x@0<@SXAx-%u^{O&j~+pSstLkgpw~+GD5VzwbuM595!~+2|90 zB47Pe`Rt#$vGNP(79EdQzJShmKIxMFlx)jl z3jQGY0<*y@o|K*XIE0=0*rXUmtTKtdAju7)F9@;Ede#;TLytgpK_wUP`7=z#wFBe= ze(g}DCs5-9SR=5$C47LsXOv?9Gqx@{>Ge^E)Uuz(eC9lvE4TF-7W?5|qGP7V8d0>8Y^yL>;qpBZ>R9o|)I z$~G*oJn5%qGsZeKt8!7#y6Rim*|1N>SWa%Pyj+|Q`T+TFhJMBN^`+sdVv9oeMVgj)Ne_-(fU!d4waYQu(zF=zf1IjO_ zSzaJp40btPF$rJb#oKVj58w|{J5TEap9gzCAVvZ&^aqHalMwNg^#v~U^+28v$a;c) zZgAA5_yDobdHVkz*Y@CJ=sOg$uh`ETR$B`f*Jp)!^*Fzp#e0kOjEDRpaX$LX;6wcw zYCJ90Kdx=yKIZn8qY>-L>6O0`<1MF?567RME#ANS-(p^MA$eeo@zOi`A9G42zFWOX z?MZBx?F^R<4U;VqXDqIhvr~IpzD}-wy>eRO`BgrCDK{qv#&*e*J?CdDh7-Tf^s!qu zZ}A$&#Y7MB4I{8(Z0`ln3DaV^>mK3|+5IyW+3nM=tE7v`r(Bm^Yvq%AE|GPga9x@! z>F1j~4!^hCr))pimnvaj&EI$*Vm>MQ3;cxn2=5>4`0;bmKUgjiatP%;jGxsb${lui z_XQzmxYX(ld@QxafTOSVxq|#KdDr0MZkNvPbVJp17^d0_zfG<-;ouEFeHNE~keVgA8?9+d+USF8k&*HxJ z&(?3J?Aw}~Fb8LGKlV;)m}gv!{op^d96!c->M+H7i}T9K&;j{AtWpU$~7TX!qf#Y@BN;-?7%z!xZv zkVE>s;P-BFs1eKt$q8hWz*ULuhnygrQ)uD?;+j)!ZM{r> z9#GX2Ox6j)@W$i-`rN{_=1BEWnBdOPk?>>*Wo*F$gVtdBB@^{t67T0CF z-7Th*r-yh>EGHk|U3L!xF@8rjh_QK$!_?Z8dH#p{xNU165ceb9);v!A0>_x;6ETk< zf5^`nqEF~S4MYzkCPsc9U!XeS#2>3h_^IN>&*TSwAv^j{+0(Dx1oHzA$q)Qa`Q^j1J^2CI z;FJsgu-tPxOpb=K<8w!4KdAn#>LOo?zY@ zAs80R%{pgD@8=xe-`cr6O=^BWzYqJ7e>-n2IX}a%nfEb&8tW;NxF7Q%>y<>m82P7u zvhfo8mQ!gAskazggnrD0^lD*W{hD*-la=RB{3^X1&;Iz+74M}t^f%@dYI^#2;$HgQ z>3H&cxYrz%aj#mQxhm$ZK9F)x-<_Vj`t9`RV(m^(&hq(Cv&URsw%L7epU3<7uDU$t z?=X*jOSncq+MHE-YJ>+v;hb-d>9%on77Aov3FljI2W z9@KZB&tSEK?=4t=(|m#YkIJ|31LOwVr+I<=HFGAFI^jCy1o8vq1nL`DjSzBz5z7C( zAMiayVg)gS8gcBG)hkde8LybK^O?Vuop~QH@tps$*h38RKH$%0pVNXLAa3CUreFS8 zuxa@L#WoY!{fw9kWIn*>1gQ_OdVpHM`T?~*z}EsLpzIN>`Pze|-<;ZraE ztHzdmKV_e|ulfx3r5Aj(XFrMgCld436aL)y74y{-vbtVtVdx>NMjZShxK|I4IVsEW z#l7-K>)WN=tA}mezr}NJxji*J^?S%!t#;q@^PyfR&U@}F%wy*@d3-MKk(V;;m48pC z700?xOOJA$79Hj~&N--B=Dowerq?^~^3jlEl>hGfbx1s(xaE6!ED3%fZhdZ0;}5K# z5d8pkf_y>NV=nDkhOuQ6 zY&+vW_5{R0RV`4@2XO8JYi5%?zx(xq%AJ^@%e!tcH zT5rtvHL3X(|Lxij+6R9wocB+}etLbemjVC2@0o6&HveZnQ2fuh(&zotuXxKDcuH*cJU5ClLx%NBFbL|FUH9!>yFSBR z`=QfZhjGhY#~J&%PD_s52;UHoCvFq|gAd5~FRBl$Z}3?gU&cAkIb`z;v4^O>i|-SJ zx5*!qCVoIutKNX`|2Y1nS$1N0uP@e4h_s(!!ne%AAg`-zD4 z`m`^`KfcL}vCleOa{g?-!yhBZIYaplKF`F)0sb{6urHZ@1^g5L>8HqthS)z<|!$n=dJ6J6ZL97W*|1^cnSkKcznKCsgYj|F?^Otvw;6OAGyN~lU)o~d>}_8 zS0rZ~eZu{!1IPjXUHtz{{QpAys~;eHqu!jTz94aE@_9Z7fd5MT|C^g0`M=!P0iOLQ z+{~+F^H=%UKQnL-8#AvKABfn8f0JyjK``ru!=zs=pVPFDOMCH~dt>-(O_zt+qt?>GJrYQR6SpZ;Dw{+0V@?BfTT$$zKS zAGR1wJl>{Tug%AMJzv0U?K`-3I}CFj#x8Z879Y_JU$F7~v+lvy0a|aMJgf=-^4A&v z?-KuqIQOy zP7B_hdrXz%EWv+VTTq+-(*w}B`~1Js1K3XbA@NMs4 z#QqtVi~TG95!es*eYI@eMEqa#w3~H}I52rukH!Br&za0%8-0Mbz8>&vh`o382SLY=L(B`uFucCN^Fg9lh{wrFYZ}?;LqhD-&f3+*m=_797vzH$ah5_ z7LLc*x8w82IqO=s9J|IqJ^(*pw?N**vpe%5?|#vUIqNp+ad1H2DN z>wq!R;pi`D4VdKt^Z-={sNXXz_yDT|WDA326ImUQ^#QaNO*TXxS()!+tsd)cS!b&? zJk|%$+C15#t;dVGK$z>Rp3|?H=d&Cj*25M4J1soawI4RaZPTgSR>6FcU&?&J67?0E z__s<96ni60`hQv8U)}$UYYhDw0j({h?howy`M{9(+kD`~me&ms`vc|U2dVbY;=b4) zrd}|0A$H;O{`-91ul$iZl6n$*BER%;|F_or!|sfI#r-K4{mJL2ic#1p_KMvS^JgmN z&%Ek!H_Pn$Nwf7?ihHvH`!E0tv#)(lTQ4)Uoq6p)y)VEA82|s24@l1)2?at-@0(Q(Ym}#KPvx6^~g@3esfP9JEi5{x_0Q~^^D&zvx0vD+7A|EjMT=iiyAD~*` zD_YlintB1M*{I#91x9~S>%PbZ)Z5wVGn()Dl-7!>=QH%9T2uaEts|u$5OM+R#QFhN z4`{8A>c=L2;H`0;Pw)fQ6TlBB7eM3(Y|cMfzh}N6%L!_H!J3b`j??yb?RpQ{s+lkJ z1*#D^zRo(%SO+!X-QvA+r};~){uI@qKIbRq|HVyL zj_T`uaj&?A-D1PDu13WDHON!4f7$u9&q&04WFX@~tXvl)Ff;So=iLl(G(%j$*7U1% zE-|8bYv&GG9uU?ETQ8t8AHX`DtOnqE0hK<$!df37{;zBl`?K?SsXdH+&;4}m3;Sj4 zv#z)_eUS{)H$2I%<=Y#06{m*mHxjEM{7Kp|L(fF8uO#Hx1`U2!qSm#Tx^!dp3tpZNgu1HlKtB6WaWKOn6GigSRf>ja4XZdxZ~bADsxC&p== z?|9V?vFA5Y^NW6-pPnDF-{&60edAv2&$#A!#d~~}ws5awKxQM?zu@NF5JWy;j*fGV zwsW;b=G>q$K=1{@AK(+_n4f&g`%d$t@}G-Aj#STQC;5UA>H!ZYFVMX35X}t@ zQC=`ueIokB(FzM>$v?$*RkIO*J;2M*Lm=4lP<%TxKuh1oo~-~+Ht1q z)PIue*k_FE&}*1$-@Tt}*Qtm0uU*UUW2dgJ}-yhfdWIaFmmC33xV%~4;Un%Zk|7y=Z`xu#@b3Mlq zuS;(wZ;T2%}m1L9akL z;ZF2}WH69j0^EWRp#N0&|G;r8GB1o!WKY zL9Sho9a@H|b{)iNU)OPm(XP{=8LrESWv=V!H7zP#My+!Ah)(?{x(?e74L+gdT7pKs zM)`rxlh?YQit$#%XROEhJJ#{UwY@Q?r;n$c-sbV(J>>NX@3E#IDLsx-Za-QvevIaW z#>(f9Q(ceVcRp3jpDyNQ4-?Pw%ws20#5{Im%*&3jCzzih`!e1Y=drojiu1FTX^{?%VNLQ65>CY>&Kta?`OVYYEA5K!amHi-;%jE zdYN~Vwi32c=HINx2*)m&Z}Nhhf3w8Kg>j1Grmg%ZVq;2fa2@09eS-M|@&kPE70SV` zkWVHjlaHQ$DgHn;S{;8d@yuVz@2j_an*0Izfoy}gKz@MDjQ)b=f>;xx-tbP!8=Lq9 z<(7j#sPoTchx8GnU!dpI{|H?VgLMVUO?&P63D>dzs7>a+eV1P1eU$4wWUlKvYL^ye zy{zxR&vY6v*>a3+ly7Wmjnck*Z@2A|ciA}MN3+^Ji|f9A$M@oc@x?C>jEqX(3~APfLJDa@YUCr;{6V710m-;{E7swN|7VKo@39>7z8}JLNA4eW9zwjB= z4(cfm|D@&?=p~RZd_?D>%1(DY=33Wd+B&yQyY?H+NxLrFxsH9uE50vn6W;6k1^J-P zJI+#WFj(sWHq94w9yHeVf5++7j9bmF9=*-at8Uj=kNliCR}W|O35x5=+s2-xxGw#S z`;v0`7}w>~(WAxovwti7{+C!+d_Vtx#QOhJKK}>H>8D@vC$kIe13NK$xf0$LeSosC!{CwU2xctTw zO=G{U>t%l5*Zr~PH=jh!5_6WozHx8t!?~9Qx4z_}EWGt)hs6IE+$ujHS%}p5gasPE zio`qtzxq#;=nv)ve_%Qa`N1633vC8bZCJSVPDrN3(uJzG1)tpK~314cIvD+jn#wdXI3O zhb`Ljm@ld^qA%#Fwa2PWHYzV@-`;IEZ(rqFciT8x?hfP1$MCz2S$`q1PuXh1y4kbYJ@);QTX>s_;_2@ z3lNijU4Y^=>w>aA06Box@0_o5_LT#`IIP2bV1F_BK-TvQ=lJ-#pZisDe-*9iXP#gF zWxDnJn3H6F&-W*NkB_{c+9l@vitl2dn7;tgaV-eEFT73M-}Z`Il*!9_oF^~o`8ZC| zFZ@fsK~m!n7Rcu=!1r3N<$c2Z)IVo_LH=8P1Oy#d`~vly_Y1R#0mK5?2!0{@hUvr$ z`G#ro4O7iG{7(KsJtE}{lQaLIT2gUm)W>dh-AB*aDEn{Msk`f>o*i{}-MCxC;1=?H zmys*gd)#@W`vsl0ALND~b&-wdL~?e;a&j}qdx~;3eDhT0Z7_~brb{=|<-cP*M}L;T zOP4T?&-a`^CcP(|V-J?Y``AA3hQNEuy5bD>Wp;LpXB`_fTf`ob7`triZ5R7(V%xXN z))BM$SBwQ?!eXH~ffaIPg!mci0N8>t>HzBpsLyUbz~%)Nlf@>C!m6DoL=B+(F5a#6r7E6xK_*d?~v-ra|Q1kf=`#eP5;;c zKHvO;_YHGYLy$9IH`tHG3;Y9hq1l&WNyr_DFVkd;19m^gwd>fq+3dIL(o;RWXIm-9&?-t9A zap~6b_ou7kxy5w#ntWU*e~+9;JM!^7W4(%V>@a0rkE6|Mo7r<>+x9x|!R`YK#zf4A z;h%gt@}Kws>kDT5hdBZ2aO(wz9Dw=xm;;DmdU%!t*qY!_19<+A7XN2Z4~)~?faU%v z|7qVZ$^DK05c{p)Z}WTf_$#sB^Y4$r{8{8bjs1ap#$oa8uX+*pi!;&lcO+u(556;w zv3*~TPe}X%daLpcnNOgO@cPd3hL|(Nd{4FBJnB934df2;3n6bX+aitxA2IR7`&_qS z6PnLG@qXacjpn}l*j?Rr6Zdx8Pd(6WyYrqK{XIqOw&e57L2is6=r(kMn{>+kmZRa1 ztN5nAlTLiT?qfMRGl@BSO)U3}i*sT*_7Gw^c9P3Ed1w$H)3Lb_lZ<6=m&Q9bi%pyD zruH0cT(%x#UbPPh^|0};I>7i3bwJDkthY`M5PEJg2T1wnJi*9+)(2D#AhxX!DAuh9 zaMq(|DfZt+JrMi;6O<=RRK37Gqsjfb?ns*Z&(In_V*jip_pgrq^z@V1uVbi<{aM~0 z`1d}tW}Gq~Q2Trw*JNw{gE7b72A!C062FX(mQRS1={V+YY|*_*%o*4c3nb)!^csj0 z*b*Y!^74$^>Cn@a=XPlx`>O9d_8Hf#9)8aW>)j61-s%R-dAA#~=qNX0`3K#oRUa`K zvHSzBn|wh_^4eP8MV{l=7L=byY~Q7a8+GJ4#&u=vrGuc4s3X4(dK23V#dfCKRNs1x zJ(w*dwqZ76d3&@UZ&!VP2p*2T%e%AO4y1Q{FJe=KORnukwlMx^C}` zB=_exXR8M}M{5+|pZWcHs!!$z_7^B;p@vzgJZ7Q%*&^jOCdzjfBN?-=xFs5oB^tLD z5qin)N!WwD!&lzqN&Y9A2I8^-?;9| zOPgc6?K*a|xw0ajdMc0aH|w2l=;EW@$dw)o>7vJh?}YVe1Ga_rOj;-&71?7E|Jpa=r1i?E1IV9m_I*HNtLH!Z0N;Bn z;vaV5AC}V|z^1*k463`s6MdVU-7?+f9w1E_#bos*{VB=_>ZyQ$A5n;G4|K; z-=eX_?v)f6hNb-(UP+sQcSrtb63@dY)5t zO`mD%CHUN*YZK`FM4jK`*=G&EkNvFaov+%2wM+}Nwg(}1@o|zk8YIojgKm~e4@>Xd zx@5w~ZgB0JQR}mgp7r+8&e`^ww6ABrK~7(W{Xz2&tNQNrceb|2U3Oa0tX!Z&*B)-- zCvVy6Y{+chd{E+>tVSh2_PkikR9@rj0MC`J7i1l+nDcc2IRLddK7e^S&Cl6AHBA_*!T1NQ}@qp!oT0gT>h=L(y=DK+1TI8 z_#gEi_4&%ytBU!YPZJsJF>ZIu?ME#8K z!5fA7+T&pS+I22}{nDZPeq^ik0rmO!eZYm(0IZv*7ij!PACSX8^8j2oF!IkegOhoH zTK;#IFPNb9f%t~Wf&Z!cjP?EW9pn=;^_{ac$1qzt#vJ7uKKJ+h&$qt6a{tIbxxeNA zfqn8B`LwJ?Q|`aiWb4WMo5Mcq;Jc3A#pdIOEqPyy#rnv6+>%FhRsW!tn~nLOdBZI+ zk6;a92i6idI*%~CK6uY#wk{t){u}!gAwF6^I;{c3QkDY*{$bA70L;Hh=*Njo7==}< z0mLp0!!rECw)FtSI?P+_Kj$ACcsx~>iwhddnU76hn{w*E`J}gcK z{$VKc1Y0l$Ymt8#^ff@}0i^tMJ?JD*pd|Cx&av*c5<*q`yQ zzF+A574dKEr~GHJ{}s12@L!sJ)%x3wS?Pu?J*L&UhyNjq-dmSb<`IW4d%x`q^N8C` zYCJ!{93tPn~9eFFNu5PW%)D79SHGWa;KN&%KMjpean^UU;2J2_S<#nH0eU-Uh#{XFZ1%B~$Aw96q|w4E6PRs#n% zLVPr4=$Vl_vp&&$fNE=efLQZBz{lUT27pmmg;~o1tOvk4KCR~!+b|C6#{aq0{{Pru zwSOJ{eeU0gf4^^wbl(2f&i}lN9&(+wYrM7x_6N_ZW+vsQH6Fuc_i?*5VY1)McQlFl zdB4v*L=m6(kJ`^rJM@|Hw!+U8eOGHg&)VtsU3-`63l33Fa7&Ig#KIUCiIKiH?qg>@ z|MUUK0gCyD*?RoLJnXCY7x?$Rzp3gIR&swI|I^yPlKbo2Ig9_^7g^s=zG<=b{e0}N z#D9NGTSNR`a?>-e`;c)B?W!%^32uRc2UG;?Ye|0DnO0qFs#7hhNdX#HNS0m2->B+c`A z{vX>g!T2X9Q0}k#pqhVj2=)EcQ=Fsq{?r$9wbo#s&i9$GzQY3b{TFIY;v)4V7ioUd z*w>onC93KWr+eU9Y_dB4ePZpGKPJn1uA*W_(9*Q9#CHFAE~8@BN9OlnzV zP9dG|>offz#r%9;^B7K_E1El?ub93seN2C#h{d*gzBxW%=l5T_McUl*J724CAx5k( zP9DH~K;Q_b7K<(K1LOyoYZH4g2#YWYn=lHiFblg?Jpl0!(-<5#<$J5F|8 zdJc5$3)a2!Jg@V<9>eC^_5YZs=iJ|V-{0sp>WI7^V%h`D`;NX_Vl7ZI51^Mj^>cS^ zaXz3f|G@`rEdMYJ%hPl&0BplJti!yqFa9S5{-^4-X*yqMy52h@@INcW|GDxh^WeVO14}RkTQCM|Fb8`u2#YWYn=lHi#DCa@ ze^`cT*oJZVhxv)b{`16tSodeKAO4y5ga0`1ukSMcHODYtb%xLV#lPkt$U_!W_ecIM z_b=c-V_!aC3u1rqwf}Hk`smuV4f1|saLPg1$3x~G?0WPctGVlzy^jVxh+e~Hy5Wn9 zbM{92Xy*+lYY4a9xoHou_B+b1Ct&@qT_arAFm2ysfUf(qgVytIt8@IiIo3z>zulvR zdlw9xuInMJ*rfUbA5dn!aM%9B-J+}hw#E1WtAi6Za`|T-zV`?$9#bJ zXKha8KlA{Ne|iA$pY{O6zWM+a{xwHf>HSsa{pV<1;avF@z8n7eJ*0|%V!wJ6OPTYN zSnOBar}mFEzxg=L`K>Tf?El7=A^jKb(~$kH+YfDatxde|IcQSD?{4IG8of@9&}YoD zX769*x^_OX(RD`nT+w<0?n%(0*KlLJ(SGN>Zr3^IJn5SACCl~~%FYe;p1f4~=u2CK z4f;M<;KF)izDMT!WeyC_eJ`)M zRpP&`Wx@w8ZOCT_-J`3yF_!$isHV@e`<8gFORqtWzCz@>Ioq_Zuh#=izcah$h_2(q zd5&Dav?Y!seh2q8;(CE)*^lod?TEIR zYXJ4&Lp&xnNB&_Jc463R05J{QFisB;=864CJ^ttDeBw7M|BJ5plk3={SACmR&fc6k zerodWeMi>+&YU`t`eZT&0__zsf6R*9~oqWSxO@!xxIR5opaNjZvB1-HvAp-qtDporT0G`2j?#_FBt#N+YXuY4%e~kcBS^A z(ReiXb-R9IGjaj0xz^}6x(yoTmf!qro7!XKf^FmlcC3D;mJVFO7_3>%P4Ar^eB@tj z=J5~9Fb&%<4(l+V@vrlKr)q7m@vn9NGu8Vy{Rohl{la(bxVP zY@agzwQecnU+ewj@ubJtmh3OT<=KY)erk96cX{?-`&=3JyLRv4_I&q|g>gRRJU%|} z&hNSVe)*95{UeXNmtTEVw`;5X-FM%8ZtB#=@vZ;FT}vH9dQ5{C9$DB+958v$QhpBR zI(O}AIS&5r&`+J{K6>_L?$Z}vZ+`FN=U(YPc=`qI9mjpzt=#V*x07lfYM@4}+UvTH zVtQSrMtMMoZ3i~|-hoRF*z))nI~o6C3LlX1uXXmY2ZM_^2Z#6%|5*uecSKKNcL*#z-H(u2kd)ei#*IZl4PWyedp*{4Uu&xw0#KJ~#f70BA zvis{w$NOu)`(tCiLVNzBSLG8v^{G#}jvebxa^L#dZ%X@uw<|B`x8sn)v5k2` zhu*`>`2gkw8r+YRwL#cNTg0WdH(2x#ELbms@c8FVufN`eo3c;bfB*e;eE{o^8XZ&7>*NpZbRWLRT;6uyefM=w zJn=-s-QDo=EAIYZ|4%7DK<|^{tBf@pL^G`Jb)phRo4t z>hZrsImc4v9?O)2urJHCPb;)<-9x<` zhuY)(^Up7{dsXjw@uipDtv~#EsWCeGq%&=9wCK2ao^^(0Y5~?J)%zY^8+FiUH@j^{ zF4#t1V8`lbVrk$X#$e52F15E9gvEON!!k@q{$U;Fr;z)%3ICg)eS8hRy`Jt_mtW?5 zx*ca0_uq;8N1bqbDZBpa?cZ@vKKFbT7n}Oe<(FSxc#O>QA|S=b`f(`v9#~YP3d}^MvM~{j<&L19s7TSo8s# zlmDp~KE7d^t_d>zk|%XP<)@Ss9`Ul=g6tD-Iq3-o%&qZ^AUN0oz)Vb15i^_Tl+kFx$al$ za{%?=Z&oj!96)TsD6GOP?9LOzRs$&h!#0e=I?TiV{}ukxXRQsV{}boZxL5R;^Y_xv zrH_~IePAi}iFYj>_frm^dFB~M4?f+u_?TW`nH+$AVZHUsS6_W~`jeadnDM|Tmhk~Y z#}r?mr9-b_jdK9a33TkcbME-Wabi2>9bfoA!~cvB|7Xib%#p7s8~>Lp{;!ZPqAtNV zS?rge@^ybD{;yFE&{pxkVeHo&8RzH~F(03&7A|69=;(2!=k_1|`(vBTOQSESR|gE3 zv`52Z<-Ed_h4k_J-~awbKfh70;{(df6;caqw?onO+1hEX@Z3^9fcvtg$5s27wSkK- z{LN=we$& z=d5FmjMv*1F+qR&16sq|D0cDsz5nssjbfv@A7X95#EBDg?VEEM>m4WaA4T*0(-n}UH&tJ29Lwm)ZFZjlN?$y^`D>D5Sf4*K0 zP;YHxk)Oj?GRM%`f6Nay;-A-<8?24l@&8VPrj_ymtRsw{DcVlbx}esMRVn|lVm=`7 z4@;4&$Un@%9t<|(AC@EkFixz8`Dyh2;Q!($lovedW?d%!uXx(cz496B8_d5(@&DTA z+#>ms#Wy@3V*d;Fd&_TmQL$hA8~YpFD*2?<@=fgLE_ZtVE%xgejC~!`I{7y*uen_n z|2K#9pR-$C{g#dW^v&|@gLS=S*YdNDcXR%+4u>^4dHdaG?26nRU?*Mozi2(<`t|EK z%kHxd;>vp;Xy^l2A5gSbkaLmC%m?zGMs)z!f?j>|ldWp6>lFVZACZ^HkHu0kWj=r$ zn_64#$g@ijsJ^E@PB;?{*8U{Z|sYI%lpaw z#ec|a)_qg_n~43pTVIx3^qXAU&v+;q`^l9%_sHjH@$UOHv{PagYkJ$_@93kC&K-lI zbDR3@ye9YkjM*=K@r%uN2+RqTsRKB#Ak(MzF@4-g_X{fH1Gv^mqqTv>#j2Oogr0x@L*b0UGcxW*hP^_NPf^g!n&OzG04h#60;5pZh=S783sh|4UV0 zEW7Ciohzl-FQ2nQ@t-_om3$Gge;4f=`?&_OxKHeVCG%^$ihVDyx!uHnYs>IG-dkl4 zscrDM?3y@wgSDUKf9g-pV=0rXZp^ygmVoWvd+*KNch>VUms#5fz%S$->zXxdT4Hya z^&Q{%$uCQdE$0s9?K5$`4F9~x-(RrWf27~Znt;XU{H)b%*5|^Wk4hfk`LR4eOj%wn z#$XNRd=22^KTN_Vj9UB`v#`5B@gJ698n$7a_z&~2|3>A1&8^Qm)^n#itbIIK=kC`J)FN^hJA9`w)&$6C^|QQbC=TNWzMgt?|0j6w{7-Ac>4JlO635DefH#B z{cNNAh0^0Ifqce7`Hn^MA&ccp zmZ+w{w=56we}&@zO2z+GivO$Si*}JuS|i^?>|cv0{;wnUOLkTMkL;%S@8vbOyW)Rq z%H;Q*TVNC3$9L^LxXSiZ4r(74<^BhK@Dru@XN_B1{;gcOGIuO$uMsjp*EO&8k^JAg zckfp1`PUnp+kf;QrN+3Z4?tWm#lLa@yJk>L4N*HD(?5P~tJv*s>W4)>A}^62Sb{0b ztI4scwZ$Cl!5}PJP9EYvtimkp!Z0io|6v=(VIAgS-}t{I@PB#W|Eg!~GYhX3|JNn_ z8~gGBmivqUTgAWS{x$r6z3ut$HKzWYALp~xa-R1;bN;n9!2evohxKTU;{TU#y1U7_ z`}OR-HC{XJxZ`q@6?=S4!hhRs4V}y zufulr&pGU_YlW=40P$z47@_`@dlRW~F{}Rm#7`e#L)d|79Qh?;`d~V%)!5 z@!v$T|DM*9CFlM;*A}9Ea6U_!HE^&oaLQh}-^I1K%Gl*iKX|Z|oww$jF24BU++*m` zZ*&#^owv=u-XQacZTZJ_j~b0NYl5PFtGB8FnsHrm?kl*BYW?c(sO}3)c+Zzx+=yYKHKWRKMca6&jEaY4puGxNB-#n1pZ+>@(=rw|Jlk3cx|3? zgvkFQ`Hsc(XroVoqnD@bG_hry!gYS+W+B)A8ylQ zV9it`{&}5ir{*0e_ZDbQ4$!er@%m!EpKHdhz2(UkwO?Ngdp;sB7CQs~Fl9bK=O$BU z?;`$v4Uo@2%)%}VTMtnD!#0e=Ix#=;KTD5!Zf?TAul=j}r}kf=9Al;O|5YLWr~I$g zzSZ)-oA#gM*&W#o{O^9(ORjT+d-v8``x1GG+oEgvzWd`}C}orXc>1|EWrrVs=%I&l zx!@Xp@i@75X&yV&{%!rox`{IU7p({Cp!<(BhySkh0y}lj9gjFhqYwCKtMLyj<^#kI zKEV0_fqxjQ(W4=@A}^62Sb{0b0f@2G+F}m&V6c{dScO^GCH`9vu!#SQAKx(R zQpNwv6#uVK{(t4u>K6q5uX|R0MEu_n_?LfKaf{-=#r_wSe~5qW$C^88`2R-R@jq-$ zejJPX>pyX~Eaug+p7(#=b#FMwzl=RzdQbD$%KrGrKXxDc*vA|_`_ZFEyGfHKx!rc# z&7FMm$qtS;=C2I@T<8Dd}a0ODV@ zf0+B5ANWse|7GeYR>%H-ncwlT-}@uxCoJ|8_e1QDe#{?R8t-3s>%Z0Vvd1@HuABR_ zu9fwzd7S4x$D04lhLYZLp8)Vw5BS&AlbZPGI#eLwM`$G>swA6LB(%&t^ zKi55qzmsl{IO2%(tJ>^w*=q%H?WJ`8LY?|e$i3fK=fU~CpZJ~R z04p#1U5nWAp7*?-`I5*>zTCGLE7p+tLr$({ZFF&=r z>i#{b`6YX*wn5gb=J)ct+e`7krDgcq`nf-Id3kZZ=($bhpYzxn{c-)Qy4UZ{@juue z*Z27AU(2m4D%1aODgN;_MeB_sGhCyPH3`o@U;f%>KmFYwO7TBsetsTPbRR+PEf)8y zYAe4$-=M>G_3sPau0uz+N;$x$+VXnE|Hwz=CGrDHkt^#1h&AiCvF1(;!XiwT-i+j@Xv-FkrJ{%;`uyY?;C6}f-jdiNssTO$59;-BmE6rG<}Ws3zq0M5$% zm6`u<3I54riq;zE9S_$MC_A^v8p<;9f5y^PxjYx~&$WZ|_N_V34PJWS*317TPi&YI z=Kieqzv^kXD8&Dz>K`ssA7Q!r3HX#%@-3_7V|?uYmtw!~`>j(?a##7J-4y?KkFj4q zYfoaoWIeH8vX|n&m)G6iivKMs%g*`tx_T^ou21R@T08#J=WC9g<-M2ldm8-}{Z6|6 zkNbz`eSg{dpZ(aFJZ99WQKkABW%=h?40*>-ulBj+=ly(>?0GN6|Hwz= zCGxWeb7+Xzf-zWwIiCZl|4tvC96)TsD6GOP?7}edAEp^=Sc~o# zMxCGb0MhYk&f`G~)^Czc`})E25qXLHz*6LDH|EyFS}y<0%V`e4)&WHR#jx=&rt|op z9r&LopMY;zNc`7(m&j*C{#WR`eC^+q|8=VUcP0KO{Nt}8|LZps|9vJd%+8d{Ow%5-0eSqx4n6>uVh#}bhdJ0I2hZYv;NN-x3IDJR)36QW zuujZ}{gi*}{pmf66aJSghe-L~MZdAedVfCukNo@G|7F`x_H|F~v$3!Jk9p1Biv3<* zcl#**x0LL8$8)-7P4SxT=A7%7=Knly->F+JJ72i!wuV07@^AgHkpJtizdrYSYi+8` z|MmLm4?g%{{_n^qru~qOUH`{*23sPJX>^WJ*=vGLTa$7Gq>LW=PFcFq zHtlO+&qw4X@&ij2Q>_N@b#^WPFbSK)|Hwb=62svirs3aufHnNjl`ojD=Xh;V;D4z; zvrM0j{QKJf1^W$tYprUIb@DyC$_MQxUzGB{=Vs=A;fZ(U+jxlG%~|hX%Rg)6^K^gA zDQ7q2pX+=V{nfiRU*7ML!_!}5E}z`t)KgE*uJO%tMSsk}<$Yh5?J8^kIp%un|Le^& z6#AE(yeV%#;&aSr)cgD9Pk+^LyvfO!n~mR@ZaWWK*kt}M&IfiHn19}5`uVbt7oYmw zjq(AF_=hRW0hIs48qC2S48mgMf3^6x9)RLM?7}cC!#`}pIIP3GkNr<OMStVRkI(&`JfB!}{vWwY(I58#i2KjF1m^l#vlyRi&bHohl(`-t z{1>kO(OiGzy>{DqX#U!V=IncXFFC-**!4c@hetjlFOi@1Vu>8Ue1I5(HJI}`0CVun z#ryal`G?u%V%PW=%f`RhwjO|3hxs{|())X2!@R)1)&6?Vl53w)-|$)akLQ&82ma+( zcKO;1@-r`n*#9s2pAF`Rc87oM*B*C?f9)sxyZ&zRe-F98_z!viKHnDqCSw2ImXjTJ zF21jq&HL%xwnm&6y-trT>NefZSh}(l|3&Bj6|Kohe}l)YpQ-m(FZS1q&3X4bDDriz zIV}1kkD-Up8iVw&%sPPDV=X!st_ND?9$|&+f7^E|WIy_Xde{HkZp1{l{n+}~lSq$c z{^xFOwtf3r*z*y2iTuD)^Z_siYcS_?fDOt4d_E4FFlse`_=jB>hGm#0wp$N?b^Zb&plsQUos9dEyaa{!3zMSt||iuw=q1{$pe zO82j5J<#8ue7e+F7oPvqZHI>Z*Sq%Dj_U1WtGnO$cQ@<9m$@O!4se}x4sg2f>Em9b zrZ(HQea_(dh`dC8V98>tLi&Fmg+Kl`!J+1!r{mb6ZH;;$-T+#h+x$az}c>u0q%e`*% z{?0h#j6xfV_EZ!T^S&>A4knB41XdH6o!e{HPV_nw#C@-u$mc0TBnxw*jt) z{$a{;0L6b;gE`oPL0E*z82_yX5VNpL{Ez%E7TeYX2=O2G^Y~w?T!GK5&}Sq6yU3@k zQEstTIYu7;dupH7Yu}80?d#t1S^E(CCHpG>NA^?v_wu^iU;eZuWb&aWYq!?e%7loIFGW-I1d^=GI!t0T>qoqIzZ0zX=JN=C^wk%v8&v$ zl?OSlKha~yQ4K$ne&>GbhebXjFOeTuid?}MtmW|!n=lHi#BA7wVOWOgLjEs*QhmV? z|F3!4-n;Djg#VkLx9`mOm%rKd4#odF75^>vzhwKA@lWo*nfNC+%e8a*&oy&gMK<5) z`9U)d$o&nj0a)fb0O#HLJx2|j_Xpqg*38o9Z|)zpchOqBM(02kod?K1*6YvJ+ednW zg*rk{lA?PHaQ&1r?0@*oiwk~3*Z->1`-}B|qd9=xuK#nhcwX_<2b%T%hWrN~kn#Tw zdhYZ9n1f?3PCbB>e=(c!FP4pevF+yoRR4?l82{(%@xs9W61`{Hb>!L5LcOG$G-!DB@ zs{!OU^Ny9d#EtnIF=9mS_r>4fe&t1fW#|2huKm-#Tc3utKR%%Iko;@B$9*K%Zz-G2 z`yQVQcs?q5fahnQdwe|gIe^czVb13O>cNYDUjwK&FGh*~FbliHe^`cT*oJ>thxx6Y z|Mg#ctgc;cH)MK?@DCqF_x&aZD02@G?rpu{RWXeZDW}*G8MI z-8PE-(GPH4(Av-PKkEpan*-q6^1drRNBvXO_j~?dFFCHE)X2YbAF!f%zfS!pmg3*8 z`x$bPxNqrp?#HisL-IdQJ%9xv{x6nqSQ_I03i*tc@*S(?Lw1obStFmaPQGPV#sA%u zYwRwcvxnmUp2|Vi%NOmXx@2!%e`9ae{`)9b*;hVmKVrXRf7SiS0gC-zUUvs7{%@)* z{^A{VZHs$ZMVsE#Ej4rAwScgZNplxAv{7vMo(CJ(@=rYRgkw&P`*sl*5!Tmoo^Yc- za_Bt&!9KF@oX=Ed9Cnf zf9uTwPI=Esn{2Q3?EL_8;=o7bCGrDHFa=vM25T?}doT!#FbSJ53ac;+yD$vP#DCa^ zapFJB!~WLH|J1|3oUeD;7WUOB*Db?B`kvmyXBYln*?WOJ^q1ye`=ShQ)Cly@Iqp0u z>iMU~mp z!@2vhzAv+_cg@eS`yBg*ues%U zw^n^ce9La~F+TSHOa5m=i2X0Qz2%ekk#EXkzkJsI#D2*E#D2+v@^4;VcW+Vr-&7f{ zUTdD-?KygXo3QRDWg$MUcMovx1N@=WFKB49tYc~EYXTEzsS%3CqVu->nmrcvasYmd zxr=&#tQn>jp{8LC0PC2@X;@3x=(Ak!^P;=H-*7C+sfymwB=QoT0_F5-UG={@h zzHO83wVu5nsQ4fGh`dC8_7h7n2Y@kH+e_EE_BnuhaCiEA95!JTR$-R-55uqw)36QW zunzOEpUeOC3I8|$)4t32zfJt#UckSxpYZ=J@&9ddfAJsknghQh{!PUGcQ;*nYn?@r zzF5l|xoyd9zwxUJf3x3?LrTpD&8zULrsH ziKUGHyM3LV%fHxMCq^^=#csyGm@eXfp?tyO5dW9SN300^ua@uFCGfvaK4n*Z_wM?Q zJydV(DW9`m@qaJXA$!Xg;g|N+zU`|z1%I`__W1zVmqfqz7P0T;b@x{Bzp2u`bJs$B zZ98CmtMHF6Dawtpljit~VAcHhroi<-@Uy=#3DYc|zh>wVtm2A+?|OXLTZEC-;kCdPaYpq`u9gF#q?N!Wx@ zSS9|$E({a@VH&oH|F918G5&9j{O@t??+e+-Hd|udUlBLVkrka69DP8UT7b2IT-R=6 z{;02u&g*9%ko5XKMaRAI{kj`y&R9TcFXy^Xq(oAp zNQj~&R}v|9r4pxX+E%JmiOQr%kP<;~13LeIZ=Zg*`}O{M=DnF|urB+(H{JdE-9Fzr z=bm%!?e#J2{|@M=ogHBRmwY~a&TrDSKBGAB{$14s1?0&ok9Km)x$4@7O z)d2QJO<$P(F86Oy_Mc3Vttk6XM#(CfCA(ypEYtpzZ8A>#Pv*(~yobR5*Wmv@{HDqe zEPWLI|2HpT-0-%w>T&S@1o;2X@2z!={XGr;|GV)2;csku7XJVD;Qzz--})Tp|~Fgv0`b#~Y{L zX`TNB2 z)9y3ZD&JYU?O}1vem}P3e8x4xO3zu$r<5zRVaIFzq4|(;vhdUJLp`1*TV#x^kvSa$ zU=E(Sc*X#ko5wg^#Q>SJNA4aBlVvhZwp9)gtdn`NKi}qm5k6aj{2=#Pj(t}e{I9k7 z-+*&(#CPbi|9cpJT(QUg?<>6|{5PnvfBW)()AsOZe41<91o4~2=fiLGUvI{gBgUvG zw{hkRk%K>b@`o0md;g1n_&?U){@vfJoO>MZ`JJrs$;$4V{X>1qxzy(G^1kL8C1GoY zm_7n)pIF4d|HSD+73>;S$`_u`w zqo;*_N5l8uDNAO<W!SC%d%&QT#82E?8{a|7FM%I%9w2 z4|$Gt&?W2PQ|Q?LWot8hjV*{fZiVjI2LFFMe32dSNp|Aeiu`N#+l&99A-TVD*85A# z2;%`^F~Km|E%$GnpUm|;(_VX$H!%SSb{aeg#T5H{VD!2_Gj!5bBi|O+?$YR*o>M( z%|EY!*TQSk`l$i)eRrYeXBYB*dyw~M+lyKswtdiXx?QsxUoNlp9y}uOUd63*Pa^km z_GMmx>y3Ejraj*?&zWXz<2b)3Xdmi;pfwS^zm@#1Yix-f1EEi}vZ2Z1GZww)@_U~Z z`_vK9{Qq;=avLP~`(C={@FBbiKV*qaku4_<$a)*Fx0SW`ihslbz$O_bt7KNi0KqU> zRxv=uKk5J&0|fK)ANuVTQO9;o=o9AU-@xvz@-G4^kd{aIU79Q!lxFJpi0k2rBZ zn|;PE#E;Rwjp^@${fp__o*%pyDjP$m+}$CzFo+L6Yal9K<|oTZKC2rz%3_UP&^5I8 z=d2B2U15@I=9)=Uus$c(O<>&~=j?II_k3<&l#lQIu9~4!GO_#OA4Ky182B$kZo`h< z2YV>v1K~yZQE@=%fCjKttOYRZ02l+1IsotwR-G6i7*;Vrrv||0U)KOI_jhHH&HqyH zza0FpwE16yV>$L$zQ4_Xsqe4-5y$VxHSWf>ir>E%<9@OGjTrOmcFk%+Kc;P4aUZ<0 zV7}*gyuIZ=>imp9GB((&&!Et2HLp9)Yv$s{Oi%V4!>DUb`*;4v!I)zi=ejf9r)MuU zRu^uw+D7qDxl1dvQO9Y&K=UEIkR9p(vP7no4H3py$;4=mQt7Mk!l3^7C0Mlff zjMLVWd9vRb`Cs|q%b_wiX8N{@^Dj&>7SFLc$0TXv19kmJSVQ2`aE*RBZ#8YX#uBeF zQ^pZP@H-!$*WJ5*aoJ;iKb_GX`Cn+;|0U1~%b*)p*!F)l;)ZLXJ0$kE5jtfP;tN|4 zXV?l~V;lVc?a)0tFb>%XUDSZM|1RjJ-LU_ApsV&kXDQnc{ndzZKU)**zi!v8{jmRO z+roeSn6GSzyiAzWRF#~NS=QonO<}H0&~Nw@_|T)2k3c_xtuN-?F@Ha#evUQzj!mI! zbybrNpq}G1#A>m&sN9Dvw>^3fv}(uAY8UQB7ew*D4fa2+%tjs81pi<75MK6y9pwXX zEKQ%9V{0%**2o;$BZFj-Op;A9N>(KXNQTKWeR{G@#>qPEKiTh${LeWPyv7A(F77<{ zYT~D>TnqI8^;Tc#Hm<)`o(||?^+asHy}9q!{D1AYSC|i2ioAf1{a-@7@NJA6VE>Un zSpVejtqrItWL$CcGqC@tHPCs#E6_jh+qNI}pSGVlf5-O2{v+SN4^77XO&4MRRfFyS zar!p>p#L*%MAq7){-vw%*^$44c?qt;!W=~n?6=&Xur24{Gndcj^>R%fVY4H)QT0Df zFMU{++=j`#jt^))gcq`-Y65iR&bM49pU=B{_;>ji%C97nX?2=)!Or}?$ z28fK4bvp-$++UIZ5A?fbj=SH3^4jeg2r<@vqjL z0RGdq8#e{4Z42Aa`jn28@%+2)josf9=C!JI_Gr(^nzXucv(;SvIO}w_ryhvnKdrpR zIZlrcG#_L|=>Xe)?gjs3N{s=)m>vTZ`QHxy^%y|&PgaBYC*vmni@^U9+y3)!E1@G+ z+xCB*ZT~kym++ihpj*8BH$VsNf-ds%zYo`}Y=1lOf8Cnk`7azp=S-F|Sq(nX_<2V= z)Sf5R71hc=S@QBv=Exp>aFc&BN><4%?LQf&{U_68TlgpQWIu@iwK#^yZooOb{BK9R zVFz^1PJFlUzZ*Wu9_XgMu>bp@t9Z?gV84ltwjb>P?7wc;tb?%sY1^0?ivxYhtk(SP zYC2@Xg5#JMaG|2Qam?I9Rn33c{NKLA#-x_lIC6df@o?dTtf*KZZ6}(trSz#ewgzKl zP538+WRXnLHk=lzT6DUieKTTKW2fbRz?k~3$^X~2 z|Gx}#gP9*#1s`F}<8LdSvHm;S{%?XWu^D-Vt?(_jLC1*wZ-DOE1s`NLe33oSNqeE2 z9NQ23PustrjkX`{AndndO8CT-k)j_=QIlyVx!U{TPXZf7`vsLnX zhfHgzYW^8_42n$-ziC!#d5t6I2Vwt(53)jL$PO85R6s*6Xp~;{C^Mp!{6BP+!gr#;2+nq z`v>5kzW<8`|1W|6m&rbw?e`!2G5A*v?7xz}Q5Of@r-5T{_my$hs@3)zrgGGkWS~;t zP4Xo{=ObtD_x-$Fo|7IQw*K$+h&iW~*Eq*% zA3^g$KS0F-zz!KAOJs^{?F0Yxv-iN}l0EXj6Z~r*0J%9ZN><4%*(Jkdnf#M&GEUaX zJlXGz{0G^7e(pE-N3CUT*P>KnZg7?yr#%<>?{mYNc3B%F&NbC9#T||3mqo zI?rX}rYt$@nuF6_>jNbBHh%swSO3IeH;a9O7#}z9NY(Hk_WYmOM?POs{>hY|{U?KD zkxbGzr~N0ZwEtw6_Ma@1X|Me!`)teL3#>5w|1kb{;5)qh?}ab24?amFe3K^lD7@DF z@LA~lA7q0+)68c3|A!F!Yk~itwk6@;Z+_aOd6kWWWx-R@a|nMU?rf|G|D)$Lm)LmP ze*O-*wo2H1`A*gzg~`>TPd$`cUgO9)nGin6ii!n-9Wq3gluhN>8jO)OGDq8M@=rG7 z@K4ssyyE|1@c#(-$J$`J_U97fg|PqM!TA5l-yx2O@&9+uUTF_;+kS_`gW@(PZ5J3UmM($3rbYN#DZmleq>~&@*h>du`yPY<9%{ zlNOy){Pn+iV@3EMK67sg|KsN$uNwaACe91xf8Bq0xh$EDl6NveHdIqFa_Rua&KLvG z@igTFfH55d&~bM%NEUSr0Q^6z^K@jE?2=)!Or}?VOV{_2buzyM>@P)Ij@K*knacfP zpLN)G1CH5ja*TW~HF`@^|+f`9G%UxEI4U&SHzfq!NDac%n@+y9Ze{$^Z1_1Yme z#r{>LM-PMlv@MMP;WsQ%GUfIA&0|a*(Gl!b!*@)^I7n>WfPeY`WUC2`X&-<&clrR#!Rzrj z+1w6Bbqo+WJFrWJ$ugN<1GdRHSts*kzpL@jIjH2#&+iu<5LP2l4Xn1;H3YoR07+xCBxZU48z{%=QIVTW!1cftSP z4V|+Gx<`-w-S+>08vFa({}%WF)OB%mV$eRqvEP>b2l@T7KiA=CFUG3*y!~(5pg7|; z&ULb0n7O(7CFf%8A9POB_aNUqr@61nP59&nI#L(#nL#2S-fe&6n}cLAtIu_e!1j@S z>_3_E+JCY~2FW6sr2QwOWR=X){*z(ae=<$BRSYn|{+s-7#4$W}3(jHk-+=G%SEvs>5 zoJi4vKiMV2WI2@oZ(#iY*jq|BtbJVDe~164 z4gSA(*^1;}Y=4FLkGn4I=-cDjz&P^VS@sz=V~@ib$KyfQJ?@?(R^J=eTCB^6%f8uSWGd4d3`;T*MgD;_cf1G>QbMM){{}t$;_mv)MeDMQq`(J|n zcWnPh&|x3L?xVr(A7=ZBZq$iKUQORj-JJF{*WdEWVOM`Y>aK$h|KyQ50q<{SY(Q-9 z=s5>V{_fpB&U=adasHp*{;W%u@2teO_jM}*Z9nB}?uiG=lGix0P9}s8vZ8zeutSEL zFKT~U`2b*yI)Kb+9{@4<7xZ|XZ0-c3WR=X4T{5ifKbR)lWSp#%d9vSK`RBTOezKVK zvnk8YXL6pT-Xx1hcp@X{~+vtv-17@?SCtL zfNHS+)azM1H-oXUi3?8#%65>X(3{(ti=JNJLd z+6Z4^^ONr&_xC%*5#awn^RBfMF@;^juHFc2;ZX#KFEIfA_owYpl+g`qP_~U z|3}~hREz!RGrF>n?=g3`SVQ6CW^u0eKF8R5S|eHO$aRA1m!6Bfp7z!O1w2nE$Zx!D z+sO{&pKK@}z{maMSH!1F41^a09 zi;n#?eG9r*X+Gz3?aO73F#yV_Up&3sb7y_LUkt$Hi!}mSe`nbF7#}ddzoTFGp1d%S zeah3~PkyB=S&b{_WP)s{X6pgrhb#&I%`Y>@#xa17yOF_tKVU5$V*ob)i~$J$U|8`F zrn?*eHFbTg8I7L|y}!e*TabyovsT88r-#XWrT;eg_U(bpjfF4Mk=Ix0+P~V-(?aEA z$3y?UOY^_tkvFfbLOr0${bP;b4X6`jykHCJhMd?x>IoY#w{SP=i?r{LxWD83Yk$Ov z`(eIf3u=}a_fs)H_%h1hH)4LrUbU>_KTY4_+WC7E%TCgQ?Ks^RPEub?7KpgLb z??z(n#xR{Rc|rMWVsOk%-<9$7B(ZbuJ36CWn=lo%Rbv33m|IwmKI)ul|2|~e&Ol$J zBgO(fdIvwBdCau=9l}0!M9zPFe;|xy{;d`{n|arw0|KT?-%f#p97=SXH zBz{i$rw^Q#pR~t$^ZmST&cjW6zO=`A^N}6FynKgV^CS2fh0}MpIWiR2j;GzPQv9!k z53m}(z*_hO>){)0H2nWC3e~V|6ceQ`!MH-{{MdX9tSWN;UMCX&8ST{ zgxG%ze3ZlRRa)V*9HH-zb`<{1F*e5i(2m2`IRTxQwng#3@DpEjox91nV4Cj=IwmR>Dc9Cs+o?vP7oH78xUJWRC2SL9$3D$tL}OvPx#jE*Td8pKOzHvQFm7KI#CjupU71k2S)W zCs5;mJNKtz|0?%~@jvnlq5QMv#~J&Bf0gUA5<2>!vWlLN48fK(0;j4S?i4N#Zj zpMHPi6TkAkXR{7`I@AXkcKxD2R+BKsIslPj#@YR1d$fDh58RLbf0FZOxv!aft3>Y7 zZ%shyyN=lQ>@y@#CWcJD*;kIr!xuROozw!|RP_Bnh7UvE|Elft!|#WFW1~NG681lB3$p+8`-9H8>#N~o zfV%!8GU3o`)BIuq<~&@+zq4dI>A6_DSgADuD>?5cYV3d8mZO2P6eMHid`>2WkK^_@ zS@=1^8X6e`u(l4YkvXzQ|DP<9NwT>IjH(=fZU4zIStiqQ?SE(FpMHN-{|}jTQ=q=5 zP8mNZn{~0g&$%(@(wH`vHjedpNtw-Zf5sln>&x=oQRk{;>@RA)zg3@oEK;7L z-Xs?&{B!H)@AA1gS$tn-JBOc+H2bQ(Uxz*GXB6s1lCYb_zT}^5s4;-;|C1e#0qFme zDUPkl82x`TNA}1dStOJ6|H-Jz0f1SuOaGrNlWDR|#>qOFC;MUi@4&HM{u}WfCjZSg z|1G#CURx`!k=J?@*R0sb^>aLPf=#i1%{qzSdJ5zJw9T~t_4C#zI?sgJ;m>&(X|Eq# zE>Cgfn``2h`#qiY_)4z%6IJs+8?oZFvYGZcG9i4B6%_-Z?W7K{`6pXsjI5D=vS;#7 zHog3l;ZXh`h5g5TpmkUqRM-B({$sw-Hq0AP{67o(kNE`DDSI)$pb_&7bnFlIA9H_n z?C(S5CT;%3_ICjPbpwW22Vv8b^!aLx>rDOOecgM|=**aub+3YK8P~$>to)XH-G2U2 zP(Nk;d9M*Shswa#zqpu4rjp2C(7uuUgC`vWWQ`4d03CNHgZnuTPsISiKNwZ^AI$Cq zyNZ9XOr|$s4iFh9>tucv*k=pm{~6eS;U9iQB>$MFr0ag@`@{ZYJ`N9vm=>5+s4(P41@yfCJ42*Jl>P*LX#Mr-g{Sqe+>+ScR zeTN3#f7+B2uYQzRuF8>T9!n;K4;cptKV-?t0f4bc{=q73w&EWQ)0PMEzZ(3ng)UeR zoxu8_&Cn5Bp)0o2{^QsN@V^`9VqRe%bW0QLzaIO)kMW1L|1Ho(hoO^NacxE4|6}+t z^!=|Yzvd)-|C8XKjXLl&eskJJ{^|FpJ$~k%w!r((a}OAOb7poq%+F;FZfD{)t83-@ z!d@n`eqS?ag4KJ{f|Bp)J!L8GeQ?e1O{@2%maDY#$m7U_@Ih9T4zT$-2L7Ef02m`{ zWKQP*QG*NnuVVnH%>|<>2MA`#E*U1vWSVU28bGWA0OrYlXXKwcy7}o}r@l{3kG~em ze*w=5pS1!T4Y3}M!IT$?ou1xqRC*GPMk!8sVmcvqKJhp#;K9qhb zcUv<=Kg)-HzV}=``;Q8|?>%aISx0~L`?6&#jcn%jKmB+hO@D9t!t;T0z%c-Gf%V2S z>dNJ8)LjQkWU&(S{>uFw=WhtFaOk6DkhU;LiivnDh6QlLzc)C*&<_Pjm+sBAZl>HBAH}tj*O}tAjbb> zmkg&J|95r%dA~(Y{I-0SSXT8w^nU0 ze$)4FeeR8%e(g$sC;Adi|=Fn@qx-iwqi}pc~fxhpjuDhI#XtngPLnT(2QhtgvG07O(3j%niMN1&jeim-}s}F4|mC z_9=ro|CRFx;`jhVGOP#4imA?Y9zIJv3)cP4(WB4cP`>?`H$U6(Cr{=4cT@jg#vxHY zK#!g^)};CRS-G8wyK1@C_KN#QJ-gTB-0wB#f}H&Em7M=>&j0b3ejk|&7%=A6ZWXW3 zN_X%XzY})pd6=y&9|10PFi~Z+z(Yf$k0A*_YUHdwf4q)9O z>kiVgJP9?BX6Tf%*ysJ+{a61j=f4}r|4sf+|MVkk@c8ROWh%?{ z0n##=8U>73}BszdGzc z@57ou3SS?Day9an)nzl`$4Ps9HU)V`GDaPc$tp8q%Pzq}rY=e~u>P|w=FR{f&Rvu>y4-Q(JFvQK@%=Ygj28%#ZBJ`W*` z=OllNs^bs4ck(yZ`yT$@Z*u-~{!3(lV?vRWpzXkM(>je0VAkC+9$@n6eJ$*hN3LDs z{doY5q#d-qj!yb<~QpnGP1K4t#;lKU?DzY^O#|6e_00N(%GHnv3SfN`_R z9~&p(Deb;81`w8lo=s@7&wUxUPy3xb&Tr1MTtnI|=ku5xdtcM8dq4AgzwY0BJLf;I z{|l4>)`LdX1=sc)mg)S!a#)KxR>lD2&hOcTUiQmfn~cvr%X*!UsAqPNbB^f;jGPdv z1DNw?thW+&KIl7h`(Iu5pZ96$eP0fhBg)&5N!hIv6vc2kfA>CX&wTD6{dCuQyztq} zeJ1hvc}Fvi`*9tQs9gVu8>TC+qkOj+yUtb>`;@hu|LWtPHe$?e5w+!5E3h-v1aPjQ z*XJI4cZ+)dP`{hjyZ)BNx`d{`;r-q;?`sB*3)RK+`y0OU*NSV_^ZNPx^4Z?6{Y}n) zKL00{3{Y00#+03993bls2!D+4%WK)vXHSwR^z%uwUgN8F%=A#6$@QIk+noE!T29XC z6W+}&eS{z%ypo^i_P_e#%yZoQ?#2Qbzuhq28`LAC7DO*u%1yU!By|baJbwJcJ$^4#Go>T{A zo%8G2FL=!^(Zk!nbg_i#C2e0U(b@FlDm~9XNay7IS1@eeh<@){96icK4#)q2MTidV1ehc^9(ie-GyEnV(lg>G+G3TH2 zU;WIR_lU3Ke(UG1Jza^%x95i<@1X!%EIl^4zTW!hFGl7BDYK()TbIcgTX?IcZ6>xK&*$N@dc|)F z+NK%9b8Y8p&H0=1l-vK#sSBdk4W=yjsHwFk%xUV9Iv@+%@B7>?^qZ*%M%_Fs)|lU9 zsx!UL`R|5weP4kKspFRRvv&*h7X_c71E z`N8L7$NPk*&bH0@@4Wm|)|g+a?K>b+2e3Ynb~7!9eTPpe+mA^5-R5!S*7~XEb=K5H z_SZc}KG)^hr~Gt9{!hFb^!(3jUGkpBSv#2HfkES^r{w=#Dm;3)^$zszt|97k!Vb%wYpS>rx4xqju|7;^~UK#ti zG`yR~aJ|qd8}Ik`IP3TEx7>B`(`EH{XZ8~+!9Uq&Tl>v7tqqUAWo>%mZEMSuZ(G}* zdPl_!8rqS6<~us`{fc|-^kw7Z1(WE2dOVX?_-9=a-aMYt`jm6sFICh`4N30`^ zv#;zk3I2tjUmx~aT=uz!S9i+u`RSGR;-Bog_y^nc@#*Ua+JA%pozNYL`2TTk|NZW- ze75N9gATL8uHQC}4j40Si|br*YJ$lAfYCQ6u0bAj`?f^<*G*br6(ZK`=I`cnx~l0J zymFs9dYg!UFh*aSJ~w@D`r!1%>66npH|;;!CBu&W_v8OjbNqkF+G6v+{psJSV}<{{ zaqK^?O^pG({{K&}DxcC(W{$I~2PfXFK-p!^zo? zQP;~HKjWij-*ng4zWjrklW0=^cMMFCt)nscC#&??g@3Zlm>${Q^u(p2{RjK24gNRc zZ#n#IgI_C&_bslCa+$>wCiVS5p4TnxFqqHXFgH zWB(-_f^k zC^^2i?+{l_5Os%n&bYZkStl?o#wUM^%Rb|ujDwnekiXV*|D61v#Q#J5e=q-Jk>md` z{>ilBAB-pEfA{y_RXT;bMce-?R+0Y?tiy;!@S2X~ui}KaY>GARubY79BggRhbM}MnLlXN>#>g6(YkBDd75~%x zUvcqIW_KC(Kazjc0B#if|D@agyZC>B`TuDCbq#<$|2L2Sh3bVQI-vik8(s1HUVR2R zd<*A2Yx}A-2Tk_*H|mc#{Kw7p$IbEO><6VN$0zaRgsYv_*kKXH6q>VP=)0pyr5d|69u;MnN( zvqUd&yb#6z#Dyp0+5Pc|C&sAl$=MHQ-^;(${+u%W|1kc^pkx0{{=uxv{u}(0buv%( z75|U<^Uu6t!?St~0P??&{y)Bhc}9LGzxxn;5Xb+Q8bIhP&Hu+Lhrv9C{4VmZbwG5# z#NnnZ?Gv{~h&y*nj5!ZU3L_3IAl0Y?4v3s%rnhE*WMlZ>yJoFz@Am1N?v1 z2XWtRI3|pLRRe7DA5a4 z|8LuW;h+0DbAW97uWEpm{mSkLRSHF<0p2 zUfvI%xi@gk&u4M>>|dN~81}s!x8$`w$z&rA|1$Px?XNfYFSY+F_YXG7s9F0wEyEL`}t>DjyN}N>Y~kM=>WzGg>~Yn!+vS(FK+CgbAO!Jzft>FlKb1faL%8Xd%mBt^b>(=delvt zAM1IX)CKumo@CsM9Jp+MSnSW9`(x(*CH6=DCHC*+{zGzqM(v+P_R;t9U^s51g z%mLVSz=!j7Kr$a2ik!%H`TbvsT_a%H=%D!nL+;q&Yx~ujJu!0o{0`3F?`~`L%Ka#J z>*7B_?2oK@=lur7{(Wch-#~j!@gJ50z#IbF|Jdt*7(M`>UEr((59en{@0%#;1)55N8tUrP?a6$1#10mi8VjJ+0M?gJ#1pSW?s z{v)q<@y}de|C=|u`0ri6ICh+m{NJ(lXt!RkFX_GV?l0_@%=wGT`-jy1Ib;7g^L}*f z-y-{H4=Vm82Iw;nz>ERJt^`F!&<`YAs~ z`)_`B-(=rw`_-JkkeYwrykCItFKhnE*nbsRxA|YV?CY-&gbw(~H3r~XU{VKU*8wCM z132>mjWK}K0>sk+xi1ih8^!?WlbfuXulo+KSNzv6J!kd5X@eT`bG?opz4`_oV;;}f zd5k}N{1tVdOzuseKazc4+wYh6i|P9p*ZdOS|0A+*Syqo_55N9P83S-#0P2b2T%h9f z08}locReup0J0v4Yd)~}0EP}QbAe_q!0QJT^MXY^kjDl}<#6+Z&xdl%HN!ZkSFPWT z8vZ2yKH0xz-GMyLm%`sKGOx$^F77$*htKPb`CWd$uJ`vF_nY(moSHwdCviVj^J}m7 zLtCwCem%ZF*|zh37MUmeivO>_{y_XOfKdw&I3Lhh6F~U)$pu8|fFL~}{TrowyZYaw z)(;$i*FJ0b%sm$4`#t*(4b>H<-KS5nr0t8jzaNu*kw^EIwyPN9lbZJ^_FaBI*pa#Z zGVYgpe_iwEw*9*>S69~il=Z%Xe1F*f2MqpKV+^4D0>4^d*L+~(nII+gz{YdIq#lsh z&)lV~3+x>SC>>zb1^D>_(s%4nca!;(@wQz}AB>;5IFM;R6KM3DgI4Y6X^8I!j}c7n z`I@yw-F-?Jaeh2O6e6ZfnW&4rycgOv( z-WS&L;5go_`L*Nz7WiK+{4f3b>wV!5T#_+Bu@=al4~$wM_nN?NAHaMr7=07gCOYc^ z`HTbN=m19#81X?@e;T^gtrOh$BH7>K-0SMt=fuS;R!v=>K>lm64sgwY(Sd*Wa?ke@ zXD_!}p8btIC%rm;XL1(fTz5G#Qamtj6U$H@74 zZNGlj2cPv-obPM+{%?Z$-on2<26%}4Q$MV+=L5THfy^~Q93Q}EPLSaP&}VUCfm|Cb zzz>j^pr0>bj+5AzPBZv-`nwx_w(T!oPQ?DIAB!AkEKz!e7!^8vUn zh>8W+u|Ss&&}$W|aX_FBD9#a}4vFPf}U262ZqZ@)g>q7cr-to_8!avs;+Vq9z za_&vp2$CPq=W%4ywDls_w0Ald?q1ukl>K77pX@WvE`Gnc&PSB(x7YfWxW5I~@A2Wk z272M2%s3#A3-SRZ7a;S3S$|X<2N>&vVl2S<3ch{-VuFly7RLix519Ud^qJBH)CVzj zLacj(``KCdn>2TI+5As{zkleN|JP~zpz7|O$S1ZUx3bmDmvYawvRu#gbL_s&zA?w2 zF+cTuPq4<=8`+aJev2`GW1Vk1=g0B9?5<0@;^2{;;t&`zqgO`2FTQUmf$; z<9;98f3NWF-GcwY&<|V_K>& z@dw{4=ASly#_sdh(U&gg z?8Am5~>5t+@Qn+yn4X)2h^Ad z{X|`_uy!SKg_X+v{Y8+tC3p8Va zoKM93qSOS$(*cMH8hHWcGbKN$VuPk05TC%K3mo5oI>DnCT>T!QE6n@V8DG~87#z#~ z*Y@pi-E-nkt)my;SN>;b{H@h+&3>}w`b^{zTd`Ztmb}}{%NXC`Uitgl=F56s66ZJ9 z^z+(%7yDSFLvsCQt&fWNfn738mdUi2^Pu-jzxFS+@B#i;)HuM51%&GWi3w^Qpke}s zFQD=R9)Cdch3qrcs0*ZtK8@Ha9bw#?uJC@xfBr=*_9xC+W$pXcKWaVM#rmM5@1w(V zguID-n!G#A8)JOhdo|AY*nBtpI@TA)zBA^BEhhUxem_|z(?PuZeUAO-qbBew^@lkQ zP&EMqLKFc>YVF{P!6=+*naG=$a~JD2?`~UfKeJo7 zhYu`uJuZJAtoV)hO}kI#WXx~Y_^Wuo>Gy+Svh2rr)Mq%3>w_5M0DGNq#sWM!!7v@b zT&1cHKnz24fTIVPBVd$IXs%3&X|H_7qS z7cbgFmswo?<=j+hFH+_7{Ic47A z-uCtBC!023*w@?_b9@o(e>N`9Y4(F(@x>q=Ah|*2B1H$N@qmvnpvMHoaRJvAmOf$s zC|!W9PC2j~d7H~F?yf98D>zfT;tDQ7m{#jTc2%BRUY^Yy%G`K45%6;)D__l>Uf=f5pI@Z(^>Rz~XhUkubt95AJ4?+E4 z%8v8elrh7mi!7R~Q&vTOxur}i=9R6-T3z;9eI@o@jq~*!UYX0IYI^OOe$77S^kDqW zaX9O9Y@gp*&o3#@Y4(Q>XwxylVs4Pn5OZ<^DkdP~0i7R^xPVs=aIB;B0Q3R-#j6Wc z-x>aa^sA{C{9f~ZxSFjqocoo(S2{HB4{b}Fe(=bRpKO_*i9E_y?7JWHrmc64@$GsZ zbDS?VeJ+0=j1}2easI1hF%84z9%JVPE=i4$H!kS-0*F_*#soh8fW!$!7nJA&kAEP2 zE4slPKgfN^w{9Dh_eVDUq4>6ac$XZ~w%hidHjK7Rco#b_%scr!+uj$s7hhlJ_JaI< zGH2)bGL7>m)d|o6tPfB%LQ*SC{bc$AzIwnJ7wEZ!rcYq%0#hHDIzjcV_zKhwW|RA1 zZ@u>@f3JPfydT2*L9uMgk||^MYmq}Q>n87h%(He^#`pB|886fJ-iLda&DZmJ$Q;>A z%4>VK>>MygGq>>eUVGb8n;m zjcnA@dFy_C5JNV+^5lIla%gTvUMaguhUwdje{bjTC8p0@z9088&Np*=%I344AFPqN z_F%c3bK;ujLoca$gN`r2XNw!P0&YD}j1#gSBxj&>ff^&&`oM@CN`IPqLHgUfHSbCO zTIPzEf1mUCQqAQl zhwCKA+P=V9j!jHofNKy@4|vA~MW3Lk3nW&c^npE2Fm(cR2`ZmJy&z5c9a~3774WXdi+7Y5EFIe@nm9cknj&T^w)aE$@R^GT@OP zKN*wHL>~24%c{sMb9Z9n8ONuL3-c~p4<5*d5BHxVOF^7f`{%YEV6N~r@dt`y1D(r| z@qy$HWsD$wMgK_E6i_E1m!SI8)(O(j&X(gTyUCcseSfs>$Un>bA)X8rL zMqod!vHMN>Px{l`Qm=}RDC!C73cp5uoVUCWf@Hu?X7p#KjG4CFltqzK#kyUm=ko29 zoiF*K@cDmAM_>EjwU@02s6TAvt@B#Zl`~vZVlzv2iski~Rc72i33)Brh z`oZjf?`!iu<*$prXxhb5Fzl zx}3MX4}xUCD=+GOfP9%U2>;cP&o?epW^LJhjk2s{TFW+Nd?95%2_x;bFP;gL|I2$I z?}5Ar@*c>0An$>^2l5`sdm!(Dya)0g$a^5~fxHLu9>{wj?}5Ar@*c>0An$>^2l5`s zdm!(Dya)0g$a^5~fll57Gd^Ee*z5WYJqmS&Awvp<9)jrGu5_GSW_5*{n=X=)V^nM&Qr$K%dgVCT94m%9#?S!`?lbSY1n=Wtxz~v zn27Ui!0V&x3_R`}em8sbXyF+4EvO!He^!rQGXvK$6Tc{|m)K9d&dv7uc!zkM(r8+DThFwdJ$(Gk(S=iY z?pSrl-Bat^E;OGx+3g|%mnoQ-)s zcTQEu;k(;fTkbuN@3i0Jlk=^gxEI&idU(tE;3sjNr_{etQS-WF-N+DFLUYKaA`fll6_=?5D%ld zJyxq%zKP>OdJt7R4~}Km8=tPfaz%HX)+?_iN=_1@zy3esI#fmAGl+cWC{K?Nf4s#m zOHuRbiW7Yy8;F-?l>7Fy5T6!AJ{}=vN0`WO^KWQ__kRc=Ot+QxM1MR&)Z_eko=&(p_z!Pu7Wx%+lU6-s85LyGoz^XsybOBR`jJq;_elCERaXs z;>^fc*g4Ja_&{%hSVMpmA|(e%9Fju~5?dKtiHUJRG%d}Hu|(^vz>ouzRG~w*5GMOf z9S(_Wrd5eU4^Z_TG*w|-Gnm*XzIX^EJ|`X$+(stBSAiipiNqKu$#BH6WF0e3jIwet zcjCB1Rf%yqZv1WdtPVR^g_9<6+(2)Pm`s)=O*xht#th2ogTB~2NNVV zQ_aNIWFRrFLq*l`$5ClrF1hP+JG4i&zmq(u_3qj~R{p!~_mQd7{s+iJw|}T^fABGQ zeDGZ`r=O}SBRw%E1sFR{*KwdXUX+p?W2EE^K;Jx2#TW$8C0~ToS;1IKw77Bxqt|)# ziPyRGjVV?=kW!^!{>J=8{?_L9V4c6! z_!jwV>;1tAp2pU?=3ql$!Bf`W(AFOG&uH?uw*_k(CU_RK zuWSg^9pc}(xOuI=X~xPaQ)-LqiYEJtCl&g=Q;RcqEv&t%Ezsx>mtO5}V=$Y~g3@yJ zzpC@h>Vs!WHG}!6b!45YM3Hw&!4##56%An9Fd;Il+k%0n)vZd~16MO3b4j(RVS#+3 z0RPN}=9Pp^pKq_VnX{HumBZ)2A6!NFv5>aL7E$kCRZH`#np)dxo9g@`=on~jZIkgk z?HB868`}LVR*0poYZkRPHBr9uRtA~^t!w=C+Fu)Jz&A6{R2$q_*4)@q8}y6CEVE&M zd2L(m%Gy?cm{&FjRR^f7@GcDo+8l3bON+lr>lX(D)UD0GIM_~J4ymkdXpOKXt^RVm z9VWuuzy>NZuQ}LQ+aOdC^P3trirInsdViC!`$rtw+|b_W7v+JVzpkx0xKWe_>(&I; z`9*0%pte=0I%1Ai@>$ZfwyAl2)8dUSellxpURS%a!7nOx8H%_0MOpcx=0>rowy`|W zx>hU=G}Sk+Z>?-@U~oC*Ib^ZFv86ePeZqll^;J}Q}Dagv#c+ z_EtsbV(rGj(f;~~rgpw?b+lPUoD*pB+bL9^*d>*=RW#MlU&ToG*EZ@vN24RFKGhv-SZPCpP$LMlDb#xH zo7qs?v{unpQN1?MqCtn2H8eAdRQc5{{<=VIgWV;qT2;}sE)Z;PYVx81*-{7ZqRV+jdE|vscPJ_Q`b=w*-%TIF| zj=@@GS5+q+PgzcT^sw`bInApp)~PBnK}ze|0_&)asAj6L8nudw4gNZvwyZrEBvxc- z+dZ(8Qn#GB#n7_7Y9u;7H5whS8j;G&5MkwPWg$_lVncvw%^+Ru4>mI4sfSWmwl_4) zt7Td#QW{)MlbYIEg(^S7R9LycRgXNDS{)kARru`Ywzd9^I>_-VZB<=!)12nI+O}}A zT@;J_4TP@qFQ~<;D#_y7AdaT07Ex4%+B3DfZ6gy}1xIro-W*)Zn$+8pOLtbzX=XH5 z*Rpn~G^|I#^5(|ylu^`}L=g%*?-*dH%Nb zlv^HDOO!nvda2a#iB`0V()#)ZY!l>O*4)&@BBzXIr`%PqlJBBr#`xQuDenZTT%F}@ zm*~1hx`M4@W_zHaUR!+@S*S{D8$cG+sI2dMyOPp0PTXZs zTJ5oQWz8)cwN85+on9@Rh2CB|)NZJw&1Zu%WHtR9SrW|9)$N(%Z=(mbX{*;@I^9y0 zK!@r*NwG!E&5liV)Y5hA#cG?XZmDHoS1~Gs{wTJ%xvjRLnyo~K*?XbRTFrtes#9Vo zXVX-)+8<=GoY&sC(y3Qft6JYPj-rk;AWG;Pw%gy}ZubkU)49VscmhW+gu-56=2T}M^ehtI<;^)N^LP`EmnOcR43}_G^4i>jd`lu zS4Qs*ssr`(5~>$VTU9?g`_wGP5J#!{+F*S|qvAWqN>S0IdgahSYdhvw%Z{F7`askc zAVlT0hy@)Rv+Ov>8jQBS9Gf?<))lR0C#h@m+tZ5~y32B3y|Jlo4ZD{*DKO(#`I&Kb z{)(e0vsDdvWrNCKbK`7k>MTU17^rb2ha}bt)>n=qwZS&MEwQPzt86r+^n=>aiERHs*y|;SLj^yPOGAsX6rA5Zy^gV)?WK-_pGuh&R>CD!FD{d#>u zThbJ$Q)h>&`OH@i&w8CyHEv|&DMPiaY;Ch^+On!vjm4-Lw}Ov`b368^r6N%#q>I`^g66W zolJHa0Z~Va=o3V*(?hS5gFZFrzHPO;*x5!RTZj(Swv1Z!cG@-~TSjENh}s*}y5{T) zz4nCgeh^vtBdfkHmZ29p1Bj@VK6+W-Wl0Y!%yQmq!Pbj))Ix19($g7W?G63|Sqg#- zKUTM$AAQsjM=fvaiErnysK+8R(pou;t!2!r$f7E0>96AXj3)*4q(3LHQa$1crK(=z z=gCC*%95Tc6mz{&Cxxip2zf76!g#ax2V~0LxSd}lXPvzhBQjd; z@Ca8!EP5N=TQ8_F=ACMfF_P&4Zs!+fkwLsd2iT!zklRXCWO&p?C65}f;m}<(u_HzD zaYnPrW;Y{!=S-X^kvt+J#$*#w=@v!k&YA5TqGxPmH!&IRJm;hM&ROmfr1FfKs3y-S zovvjR-#O1+f^+UID&l#TQy(UgI^t~!o`HwVD;?h+?VAuM^^<_w{s(+R?OYS2ygx@ z-S!=ARnw~GaPnDPfz~#JpQO#<)oBlh;_zDRY~}jE8=V2wUftBpv8K*!_oB+Vq*3>O zPEL`oXFG_x!%<$Lwyec$2%>s%>EbmUbLt~&Xt+vIhlE`Ndl?}T?Cdjot>&>I&=6?b z7zqux(cX+OWMc~}Vo+^?0iJ|Jxa7q_F25UVgKHy6?YP?H>Tt3_`&uL6;iS6crl>N* z0a&xXy{>I{DOxrL1FP5UCP*L5BPqz6=Ogtn6w&R}q$+i*(cEHMG^;(Z8_TL?+j;Ja zY~nHug-muTukJ8Ki5CT z?0QF4_BY8QN$kpS{nOl}&UL-><0`qODymuPu*S(kIng=jgYaA)-u%Ic8XM|sY<2LC z(yIMN+in%N0#W*Ay#PcMPEnQZO?45aGw4*9^WbP#pTm=~3+LzFW>m)&zX*S`!Z!|l zQSn%{@bfi>U(|^<;X&5m_lQ-Z8ErlOAgmc42`huwA+4f7l%qdb)QWXTHQJyEh!&kw z3;t&DOOrDXTcVxV>xtRql+_FmqHV&hMO1m~kOtzmh(>&N%%%8N65fg%)G<`8R2{kU z<{P(YJ>S;M?_I+cyRBiqSfFdzqVsH{-ds46+am3%x&~>F(ut09|GzepGIt{;3Fxk( z$?irBwwCINRKM6jh%#9at_-3ysuM-O<(REqr>Ymrg&4eCcbwgM`GnQd5yC~xj^C8& z2#MpbxZ$Dx>c@E!G7cl`PqQ83wls`s&6Un#f(NrYNVX!V1 zzMTW2Qt(y3hzaqr)BaQWH1y6YMg_;{$b2_0Vmt~|wlV76jGfBedt~*!sI)(J)uof3 zETh}PSE0hri8mT{DWZ3%lcUbrZk*0c!=9|Or+S2|^RK7deJ%D zofz@yCdTR^VB;v&n8ntRr9r-5Xl|<5Q0H$^r!9^u9POkXDM32#(F~9xY0<{oCePA9 z17DGH4irPB7~niMdm`T^3Xvg2nz~%o8@{K&>+^Z`Go@W-t`uXYczwn7ll(<_Q>NC} z3twCR6IXicAFu|u^3Q%QfW10d>q?i;w zqlCXT&0pNy+(7(#+EGsb#*riYdOSc|KoRW!}`{N#%K7Z>hJe*jrRsP%u?zQLl%E zE<&ZNES^+UURL1CBZZfA<=(u~@|ne?EAtjsmKRMe_0Hsd3Mm#)5H)y8Cyz=wW$!87 zObGqerOKnk&OO*uyoEC-O)e@cu8bNMDoLTQ*jrfW_2$j2(1t6Ylvi3Xb*7V~d{U9O*lQ|F!M6SI z*uA5&@J_9)C?^}01vU5WD+}9(WMTT%WNJFt#IbuiiP>jv7Q?2DGT5Yj8te&PuhLB) z6dpRNN29VR+ItpRQh3y(d+)ogd^AyaQfh?QeS>FkxFFTdsvxI#7^C~>9kq(-x(?A< zL{)O;-YdCVGf@@2OsdKa)fwVZyMiuaSXg5(m;?MU$pA zs;b`7nT$auQbp0s$dGij|d>W%h_tbC;Am!dcj(z-?xX%B*Zk*`&&%QeWQG zsikzXo}V+z)bP~vdY8;T31?;xAeEWEuGbylWai!9%svfgW?K2zu*OvSv#`c4IciCA zN-NlVX^|RYiqFHD*`8f9o3!uD?A31mm=Wd*YwY=?YG1%wTwLz+<`vGI%Cf81nc^v>JFRY1 zt=k@0G2txi1(#xC!tw(Z-6@(jIFw_c2XWkJ{bkG?2`UooyqjChy-g z87;-g-89g?-qts|YI2)Cur2PCt14m-tw?z@_c2kTyU(6|k+l0-A2OvFwWqo|m%^&D z_6Lu>5=B*Z=RrPm9}|&0%)(%=M0==$eTQgYJVvik`!=-H1cVn+!_w3QN-M2Mt<5GaVOh(mq-;0r|n%fLr@~}U6>}66Nvv*fp_5FuE z5F^Ev?!!1_YL1;dubb><``U%VRW*i9(c2=q+UsUiMfTC|JxnjPeuPKtSSd1g)9#(V zNm9LPj#c)8t7_q$In!HEQN}J^S*Q+eyI{*>7MdohmqpM?o@f9`19P{k^F~FSU z?8)ua1&1Sp=v}4A@S_QPeLSSj=Gf%Y2 zmBq!(=ZaE}N!}^NdBsHqMR~=OeT8K_$`#I>QW!n3&2iSA)GCYpdq~;C^rv%reFv$= ziP;D3NgY*Nr_*>w*vGTCnhSfFbZR|}+|8@<%%R<02=b-K-9u0G`tCETBlgb(6lIR< zkDK*s($p#CrInRx%zG#06&9)|aBn&DfLn-yDe5Mov@H6e-!TW7nd7?sq#8B)_Ho59 zPKvDEw2;1td@1L&j$*zHKNZ-;I3wTP>pn6R6w zD^;ZKJ1;zDf7YdjmlIuR;naeH;?l~zih`+Sd4&Zti}Gg9EH22a@c9ZWCKt?P$!GXS z+Dg^G3Rm5JM2@QZKJH+~OEGpgRj1}rUs*@YZq5PrgLkA3yUvHweVSdZRn*<=>h`1i z{@1-gioD&_U8$lfzq8#{XX|qHLtEJHyRMl<-U{EO!l_g9CRh3@m;yy!)}NU?bWfQy zrKpGt%i?epeMwVWE8-EXhQd^HTr+YtI3vwt^y6kxVNvqu?^ z2{N0G(U>j5tlhTfUtjahifjro%c?2Ftbj&i76FsotY}7Kjyop9T{UKWmDuLC&ls4+ zELryH0F7A>>^}O6ix9cMc9`jYk9bt`0b$3`}Qr#2Qm{fO$HKud#3Tw>BtO;vOAI=SHOh3;F zYs{)`GPL`dK~jo}8k_4@)7{2`rrS(n({0A4CddqHQ&D46Q&D46Q&BTSOhwILGXv5L z8dF0vXiN=_#?;UZBeU|Dwa~0QX7HPJ*)+#2Ii@*gK{gt*e3<5#vP_drS*AIrEYloQ zmN9}U%VGFCI@Gqc1DEVBsgI%v#LGlOr}F}LgBGpo1VRr_rZ zyK4Iv{eQ(mfL+a`HuJ&^elstOrOi^XtI5p-G0UdusGS$d|Hy*(udQKbNi?24t&RWo zg17JH8Z(+R;jRPLj8ijmcO9^1k=$vV?%_U!N3EUyV32p!Xy&e~X1#6$LFU+KHXyU_ zn4QQN@I}4Fk?N(e=jE`+zE38|zVyXozLv4?O3|1Dsqy^Rs`0Olp}o}D^u4i{@fgDy zkFlWfm_cbgyYB90n>Thh9<#d}kKH9KF(uS2x@Y!T(SLCa{ogcd|F_QnRNJi@Z4LXJ z9I=i$CEJJNNPsyS+b7~kz^=V(`qDQ2{_O##XZAa~nOU!dr`W4uk9i*WFEr0o9M4{> zq{bU@%!+R|2lFUskI4NtfSuERN8eL<)XDzry>e!Fo5;qqmnQ9+$_!xR+4l@JQH^Jh zX-r+rvx|9TF;6Py$wZGA)hYIM`yNcW(>0wdZa`lo7s<2Y5?pa9(~%NnF>)BP9H~L- zkv3#QOk7IG84Au(aIu2R74#_hKn|2?GF6V~xS5|d>$oobwy^U@T08wkQ+`={Yg=>U z+}dF4np*yLs5L+Gr)7(qmH*IMeuaa-ND9YLKUCH`$-nbkX6mKtRZ~{^eDy`%+DWy% zHzwuCWNeEuJc6Hz)W1PDAXjPfRN#QTIN_4X$(HRT6Dt9+VmvZgd6Mx+4GA$GF(4<- zBL__ApO)ZpB_#Jx>z|hBiLpKX(}vSs!0#3)b7VOGj=JH4u2N}JC7VH%vKeYYrO4b_(^HOjkCnZeRQk86BY zCw^GhyyMw4x5pyel*3Y%JHC#Ktr*OU9Ysot@+HR!IUs9577MeLmKG23rF1+%@PHz1 zgaJi_&@vTm#(?4&K>+EL!i74Su2W5vDIJg4&hJ!};#3s}`1liz0euzZD#&x?(1|&8 zVvg#u9Nl9vIpl>h86`$0q~mRkcdG~;x1=e3o7Ox`v^4FzMJa0(EY$pQjj!qyv|S~9 zHZ3;Z8sJW5p1G~K4R$^*-1b=`jU=DHd89q%6ygUtN$^98%Iig{k;9O$ zP+UMnei~2fPry|_VOfrDAb$0`i;p3HMRp)6J;BZbzadd^-YgKQgR%$3iRoaXSTN`Z zG)uLnUTYHMQRp|JPZlQ(x^z&o_zjpSw)K4&d~VPi%AfdyNEDwB`i@Zd;1Pq9MIM+a ztiCF3(cn`2i#65^Rx$k=n=~Fj_&efUsqvA)ZxQoH?H@8k`6mxiq4PDa(b%c+(jm7E zp>&OJY0W=|sB-%b%^I344j8&X_5|shBb9S2PJb$YF^(?DW2NSYL59-wjvvTi8$iX-u+a^$ttbtjS?xG&{y&Ihvj6 zuzbxfcGxt{wm7VcIVi*}u(_15K(hxmOMt1;|Ey#7b=VgUTdBi-bXc=y3H?<)`-)?9 zF2i7RVJB#IVqeAjJ8Y~D8|1Kwnhkf@49zlOs&qe0h&+cK<*>_i*a;51QkSq>!xRb39D&XKr@b zR2^0({-$Hj(QKAt#B76&6o9F^c z?6A=~>`o_av<`dJ$#bd>d%_8us>5D(!e;2OH=VE;xTl zf)jRv4m-~YyFiCs<%C_J!|rp!Zq#8?bE|n+{7JXxDR_ z4$FWEYW<83o9Ki+qriM-yVO5zhF+~g(UNA!xPK=B5iK!D0?I;!p zfaMw&fD!#cTCZ?{ILPRa5M^lAXymsJjQ&J13;o#|F9pN-+#n7?f49cpYkUn1hrTc7 z6Z(n9Z#4d(QA(vx&^SQj2#p>vlD1l>Rrrli_=83%l|Mn_0F5Iwdcbhn@p36~rf4kH zI7{O^jf=rZ%w;;J!cwVlmd1G+7lYxL%jF6}f2naj7}3{jy~6df-sn$}0W@c7JRc0l zKSefay~6YHhxM1qRy12Q-l_3%jepSi5g3WNLB~{hr&Rd3#y@EM2%PO?LPlD?_W1ofTty<+7`>NIEW$HL# zZ^Brf9QJ{=(aWzfJM3>T^}?c^%lFt!ou6!GxuRH7g6r5wSW>F1(>ut-9Pc{K%Q4MK zH_>&TSN%S@olBAHO7BR+%3WK$>4qIim^P-awcmB4R~t;TCRdwxtckh7b%!_Guwz_x z-rO)t>WpTwXSwc+3cH;0)M-%HCFwfX!(JZbY!<6>$qzG~i(xvK2)m8COf)f-CA@|y zOZdVpR#{?_VagJd4O5nwW|*?Xbi+mUC()jsd_FnOx1IVVXB@>4O8_z+%Q#7e#V=Rs>GA&3u%ws|y=x5{3TrTIG_29E zyqG#~lVJx$v)I`&Gor#4#k54R6|iQLt}&*~+hW)z!j3ZRbi#s$T}D`|Vb>GJZz%9l zv;Pjl+70_XVe1Tg1-9O>4~V(Jux|+4XqXjS=RMl60kIpS*yz|6?(C8=6pWSFY;#fGU`Ut*Z5 z^`(ZXT3=?Es`cezrfYqLVXD^G7^Z4{onflh*Bhp4eY0Vz*0&j^YW*9-rpA5ey*agGo-ot>cducp|LzO3q{VUnjIh`haWTI8!(p+3xGmm?3|j|##IVy~ zzcuVa*zXLx2KJa?cfp=8?8&$m?~{hT5|`++zmQRD!Mm{SChQZ~(}sN)*U$HiVIqEr z?>WN~;z#;kFl<2l7~e~VWya_EUNI~m_L^Y_#6RqP-LP`l8-~q~pX7VXu)|>Q7*

        q|06NeSZxzy+3>&W=Utn*LlA%?85k#D0UU>OB41R*jI)< z5`U=gYr~$2U*`M9us7pteSb6TGuYn^`w{l7VeW($?{|g`OK9`{!?0|^zBg=gLY?;q z!)7I{j$*3Tk+5pg{b*t?C(oY@^Aq;7VXd%#8g_hw-xo6M^n_(TE(rLjmGAO|wLbMk zWwVSZ>`|K+sHImhs=o8K*w$we+*DuT%6KD8R!c32e zfnlb{#2~{icb(@mOvfBz!qn*DM>!n3sD6kr)epl=nCge&hN*rSVVLTNRKrw1q#36A zVWeTIANUoKsD4N{O!b4uFx3wcruremlm#P9^-4xKo$eL>B+xD)R`m*hQ0g$%E8ONg ztipY%Z)}+96^s|_oiMe6@!hAx)C!hom|DU3vn3}?tzi6hhQrhfHpwuxf)yF2RNrKY6UyUFtvh}8m3mTGQ-pgR$-W0!DbnzRjhtmvG{cxsX zsvpiaO!dQghN*tI*f7-(mpRO(`{9akm|Lv{5vF#MD@~Z%Nv<+X?Ic}>sh#9%!_-c4 zjbUmh*h|DE!_@7;*M_OvgTEW5ZV$dSOx+%Q zZ9Zxz+7K$S`$#V80;k>TkDCTF!2$+ZSP~eO5S3s`kYgrrH;8m}*}i z!&Li{3{&mvXP9bVieajKgA7yc8*G?r-!Q{e`$ib1+Lsn)x_zSzQ|(K4m_2qqCQLn3 zMwq(E$S`5*CS$Z=>Lw%8Fm;nL#xQl0k!6^=$rx*xy2;2kOxnJj)0Q~MFlC7nhuLF3%(l7JT}gzgyOPpyI=8wjnQ551D=9Nf-IbIZ zrtV5A!c3|go=U^iUCAMask@SShN-)f`G%>xlEsFpyOO1bsk@TH3{!U{hdaz}(eiMZ zZc&7(79DBAREvILm}=1q!&HlE3{x$t4Kv-Mm4>Mntu{=x=$D467Ogc*wW!4~)uL9z zREydSQ!Q$Dm_1rIm@swI9bxK@`si?&TitXUruU;Tvvb)Ljww|x5vFoECLE@7F-+$Y zW_B*>U+lDJvAR8vFm-$05e}0o&lAE-=V_SEGs13TmFje2+9jN5(y0<6OqFnQI82vt zYMAK~4AUhD26xFg5>9H(_f2oe^ew9-V2Jnn!0j%&v8q*(*wfsXWgP zr*o@3&j~Y~=edTdJb&FQ&oJBOR(IPGrtY@S3#W6dyY2H0Q+L}J7^d#FFEmWuZ5t-l z-L_)9y^*N!B#pNJ^u+%CE%g2SyTo}>`it>f;wr7bHc@!gSWxeO-0t`tjYo=y5>vbi zRcN=y-f>chvn^4A>#Y=zC7wx4@wmk6T0>eiA85_jU<@%MIsYTdFZ)FFv3*o-3N8Mb zTa}xge{58o{*Hh5sfI+w45zYV{x@r@TA^xg2~VFCuS?|Uc1@&3mYAgdQysruxBvY$ zw0k*X^BH~AxZ&g38>&=?MD@twQT{-bzfIdDoSRB@d>=LHPK%0jp^g(CIr}d6X5w4o z9zBY>!5Hy87%N`a`NV4b_c)=EcKv&)dXKa{)lIeQ-^>5sOJ&cdzc2zV@wFa@KRfn} zv==*5tKL>s8mq6eUbtPhCX&kP`|tbX$(dgq&^RJ0pZF+$R+K+K>=#lLJ84r`*?M%% zNA!*OXX!f6({Xm^PhllIqF1P`*?n6AI_Dth62A)9ftuU;6Se+yFh=}3D)bV^Z|B(y z^+f5V*=6o1%UrRW9QLGla??4h`ErAkHl@FG>@!cd!fy4v-Q;ZNpz_~Sd!xrd@7AeQ zy)}{CcGrqM)z;SUz0N9B+1xVLj+FKP#_FE>ZZBh%(Q>o4XYaA?^pPH!s(=5VZU1L% z8$B1IZN962*SY_nns9waowildY=r zzj9Vo@z-;(R3=k?PGZ{cSj@@ozi}r2&(>V!_CI-6{GZN0x)-ATs@#9?{Pypq+SjQs zx^B__|2_3oHQDtkZ&yw9)8g))`&2&riepJGKVq_`qOfd)PE6Z@pwG5IKxRunnQl!aB%9w?Jww5t+HoOY|!PFX& z2g47+KSxWUoCBYWe;$8xF;7gF^KtF}%H=|Qi^No9j;zLYi}mhOuUnkvzRi~+)Em7i zLfy*did)=wp}Eh^U9Nb_eZQ|%hgONV-H-T+wZB;Ga6j&=72ms`2Kyww>|2Qbb>DC? zEb$%RQTQL`eY*6-4}1ZUmG~(*Em6JIHY@Q<9p~@9jpDGx8RTD|_>*s|&hrki&HI4H z-)YTu?SBc}$Qws0^gWF`G=8P=dvFtPzNk>Q#uQK#3hh4pLZi1*0M}lkkm!T3E zk*h)VFH0rxk1ibrZs4EZN?>$u0z3FGfzfvoc&a!JJV%@jp3i>?;$m?Lc)7R|>=IkR zYsHP=jpA1D7I7zdySNX$pOKuvsDA_O7Vm(Mi}%5&#K+*X;xq77@iq8I@g4X!qc}nI z@V6=n;sbv9F@bn}z%Th3lmz}xWjy!~;RS^(0%PPfFhL#!_Lsi^2gy2cm|P>1#c&x% zZXVf)W{eDiIdVPdmA8V0@=kE7ybqi%9|lY0@4#}o4V)vN0T;*@!Nu}5@G$u%xLm#q z*2oXY|0EfY{hzSLg4?ZZdT*iYVeoL*qhPzM8$90id+-9+*|K$EwdiaaKkjxj)@b6>gi&sP<_?GAozAq+% zpNb;z8|GrZ_)#nbT`~ank*9+L-?KJD4h8s_1hyP@-PM!&-%8OzG=zkZ}K|W8%bQ1akm@5Ae zvl+dJ-Gbi@E|ZgDx1yOA+YOe*K8Ah{NY1g_(Hs-o1D+ha13a5QL#>t<$GX9*`5W45 zc~fkrRVVKPm&xCOsq(4VT=ZYZmViITmZ6V{D?{HWuF6^~i@<8REUpHukE&b6`C{RYrqTQ>s)p6N-$O42riQ^#|O~A z5#Is+IiBxRRfTy?v;5qIN@DlfC@EUg)c(Z#8G4BSK$#>ja(R}Fc20wRi2fuUo zfFf}R=uQ-|)p9_hD|VSo1zY84FjeLzy3toBdcft0nX#LsA54|!CFY`eB(VhCmRN@7 z1+Y$j54K8IpDOf;eQLmged-8J12@UaJ^?g=J{@4NPbV=qfpzi(Fjbz>XEXYH`*eZ7 z?Xv~VQ{X1~b)T(hhV<-zS94SnAyemj^dFX_7j&0~E< zT(x|bzx+>?uYs*H1lGy8Bscp0Ngi-`QfAyHIT}orvyyVr9FP0YBew`FRla|~8W+iu`$p>5IVPKtHk-QmwAh`<+CT}5h6SzrU zm%KG@t$Ye(oF{jK|44p}P}%P>(vI)99Zf;M9`JyE?-RcqOqC7&cA&YipNOxPSM_tn zGkW{E@xR>91HRQS7yO`K3HVvRviMf{Eto2Q2A9d~{#EGn``3U|`q#y8k|kiOT-85- z=A8Z=;3fS#iFpm!Dz}1+)&85&zuCVFe82w|G=Bv*$ss9Q(UhfhgL6_IL%#%UmB)c~ z^5m55=+95-0k24TpZM2?U;HU=O%- za3=a1aFaZ3a4wpM2bX|P3@#()^B|)atdpU^Rp{MAYQOd>cxn`Fh10GgwQbbv<> z=_F<+*ecHiQ|0;KGWqC`&4fNNqzin0$QJakgPWurx)n{~&~9+X(8ows3D(KEAS>t4 z?dVS$+5?_7^nElJft%#-hVDS~*-(*KEx#S=N?ayGV5^K9=1Q!SNg#C_<|edam3(Alz^v=sOq~`o(ERT2S?O^kBta`&yMII?Q3AQe0#)Z@WT;Z;O8T@ zg5QnkCRC($4)#y&K{FhrZmB!K+*FZ7-BR7)0jVCaJT(`bn_2=Mnp&Q;R<1~` z!hcd~4R}^+0K6!*1MEuO3~o*B0`E-S3O`V%lb~Ev*YYCT%Nt za#}ZdcG`CE;a-o;O=+TEwY)3M4L+Ra0iQ_A1)onV0bft60(;VGz#VA;@awb= z@W-^xV9dxaFlppgaLCARFn#29FlS^B=o`5MoHkPQ@04XAJNQU9SUu7ME+3f-`bU<4 zO(Uzo^&@M*j*$Uy^T-bH*CRKBmw{{LwIjRmKRt3Q_{zv`@a>V?!4F6FfS-@t0e&}9 zq%f*Sxk2|R4>({{E|@y11ROJ}3d|c-15O?l01q0~0nQ$^8C*E33p`@fR#|2RwGv4)BywVgPISC^vY?C=Ynes9f;oQ6=ErqpHA1M%94ZMg_nZMs0}2pGIv5W7B)U3j(AEeiSpQQ)DZ__)#Q2J&t!P5n%c(#HgJl$ZXXFE8-(*qWHc7O+Z z#NcW<%i{(Ycs$_Yo?LLHrvzN;)o z8C$_=8Qox6#&&Q{Mi00oV+Z()3^BA?uFi0SEg2qgV@57`LPiOAdPWs^ent&=MMeO; zKBEKtO~z*M{){g0cNts3r!%_2S2DJPZ-Z;)hZ#Ni`;6WJ4jL_nRm+j1-Qd{K9&qC5 zTyW~>60j8Pln0Nl!oP5I4S2-p09ZG=18f-GMQA(7$~?LoJZW?fc-Ck!oRw#^2kaVM z0&X2$1Kv5h1AJ(77x?(-Zt%I$J>VZkixI3mqdnlqqf5ZAMwgFRD}NYWgFh>?1I*9t z0;gnlgC&_gU{$6_<;Zti z67ZJH8t|UX4)D>;F7V0BZt%s-9`KD!F_Nc)Ob_^JW(oMW%o_0L%nmSaOc&U1OgA`e zOb?hbMvSVK0`=At(6sHYVbFV=>prwbc4r^=>bm}Bhs10V?5v`V@kkl z#?*i}kLdvK9@7OrGNv2cHl_!BVT|xFi^q7t_r{Fztd*aPDZ$@As~rFEtQ!0WWp#kF zv%0{AS>50fSv_D~mdKzESst)Gs{}kYs|GwJs{=eIs|&m&s~fx~s|UO}%QKofWR-xA zWYvJ%vO2&Qvbw-OW_5$_W%YocWQj~xk}MDSQ&tHWJGKT)9@_y99oq$Z#y+08R_2cF z!9RcO2lx*gE5>xnV?oBuSPyvC*c$Mnu^nL7*e-DE*lzI7u|42JV?`EYW~>K%Zfpto zhp{!_yJI`RkH>a_Uybbse;C^Xy0XRCYS}m20}jqE0Y_!mfZ5p{pf|egMud{o=AG1X+t3i$jOv)(%hvd|N={X%>PEHr-%jpKE<@A7MIi7K> z2010*60lSLBButwKc@?9%IOBz=k$ObIbuBfRE`JybxsL*SxyajZB7SxYfcw|TwtL2Hg9`MZE8t}s04)ChnF7U?OZt#xW9`M0jF_F_z zt_OTJw*-7Gw+4JCw*&krw+s9-w;TLE_wk8qr8TYxf8IFZW#1g<0S_8i1I`}T0WKWZ z1s*Z38>}1G12&8kK1TaE4|wdj67ZC9HQ+hpI>1ZDb%EE6>jrNg*8|=?P82ZO$9ceQ z<4V96#?^p-1Uuz><2vwvJgyu3YFrQa!#MukXz3d70sD?0Gij|HJiY{f>G&G(;PD+` z_4qDu`S@mAuK^zz-vR!9d>8o4_-^o3uv7kN zd=LH)#(Rp`4ab*&-;S>->Xadn9-Pnt_M6a!W*Er0n$QjAfSuAep$Gre31TvJo8SQt zo=^f-PbifW6S~32CWtBY&IAwm+JurRo$?)!)6Rq% z@bd{BXubohi|3RPApz4&&cb-e`nsc_#eva#{XVk5BN!*XBz8IUJ3Y9 zUJV$V-vK7)cY#CmyFpLBIDk6jd%%MH67Ych8n8US1Du=R1s2*_;wRo} zcmQ`T(ultq_b8+lX{XHf=r$sokYmsthkHEIiT@%HgzP{*MLt8mK)yo0LB2!2M}9

        t5#5oGL6=_G-BO8%T$T7%q$ni)gauRY1vKcuYITJY>ITtw(xd6F{ z{4T-04EGA$t8lNz-GX}q?#;+=kUNmOkb98(kOz=Qkl!MY5%&q)CvmsqzJU7@?i;vo z(XKzqlP10ke-C*d`3U_E^q(T1Azz^T3i$^4JMta!J@O;+GZG@cw2qq?Z_$rPKP1JX z577-qh9bk!rQ>GcX5wZMo^72pF&F=M{CW5%66QlDAw|d(q?qsnkW%85!Dk_dAal`G zBTMivMGi-nAx9!BkXob;@gu8|0J0WoM4FMKkXED}S&wW)Hj&>kxX0lhkK2iR67DIu zr{kWDoQGV1T!dVLT!vhMT#al&ZXoVf+?#Q4#k~vn9^6N8AH#hDc@qD2+-H#IkQb1b zkXMk`kk^qnkhhROA@3sZA@3s}A|D|;kWZ1%kT1yZE8K5z|Bm||?)SJq;)ZZtF6J5H zM*1L0NIxV68H@}?QeDSQ9EqEbn}M5+n~Uqioq}789DvL~4noS%SGbO!I18yl4na2; znU5?atQy@C*GUtX!VgE5Ax9!BkXpj)kO2Nh*IgntL}DgMuJzrg(p`3C>rk?-(- zkNYF#{ER<@$Qb%1=D3NmNPNuk6W#DWxJgJq{3*Btk-^B&n9hmA(WN3Ik#uw!xS2>6 z{%j-{|9IRy+=++}|0JXc{}kL}$~gf44CElB6e&Y0kXc9-atJaPnU5?)s*xqgQe+u& zB(egjMd}bgvKk2>Ymr8z8954RMcR?|$R^|%dj@$9c>(?s?kmV^10*evkZ!|7XHNh>WG*k=WRiCdT8skv>Qg(ho^NKM;2?G87q(q#`4cbR+}GM6zR< zpU8OR!h*{Sx(c=wcpcx3u-gmnF1TOoy9$0=@MOWW1uouoh~fKgzHa0FkOY2HHIesg z`tW{D694t%Tl4`Ug?Awa@TS8+ku>1#d^J75So(n7<YRV;x^uY zxtq5o?%_R`dwE~te%_UMkT+N!=KYmNc@^lBb)&8tosOR7#vFNfqEJ@?h{xjpu7TQ0FsS<3b(t2#xg` zTQsiMc%sI0H9nK5O21tDZ`JsGA63fz+W)x5mo&bkaew02rQ7+xpR|D7Hnu4#e!Cj%$0};^E5___>TlFR`pW+D?p3))ylv+-afQMJ+-rhpL$th6*aPWk8Lj4%${KJ zKHEa@D9X1)kdiIYN|_dKxE&52Lpc_E!;$2C9B7FXD8Uk!iCXXqO0amR%@1Bht`_gM z1;DG>SuAl4dyB=pZq4AelwgVL$lDUvi*|Cm0kqgz)`MHcM(`%yqqD@#lxgus+;POY z6|~rSjt74uI>Fm{zs?eOh*Q8j#b)B%1zPM(r-S#1Gr@a#@6O^~x^uyY*vBmPs0+YH z#6{qvyoqOt-_Zh#cc`uaAE)k?*hZ}_@g()-S5>L06x%^dJWWmcYfkED@%G)#;B(Z= z63OZ=Vk8ENvj-~jnMa3JqAS-gGs z1UOhe2@a9l!J+aQaF~1!94=p=lo24~Q@#YI$ydOU@-;ABz7A%{H^5B!7C1)!iTGI{ zV_3cmX3O`$9Qi(&D?bFs$&ZLL9<+F4bqAOyKLzvUXW&Hn1vp851s2M0z#{o~aI*Xk zoF=~qr^_F~1Le=)K{7;cB_MCL@f*^Xm?>RgnT!R?Wjt6R-BOB5keMR;fU{*1SS9;` z2g?-j5IGQBC3NDo+!NX)aSSQsRef2UEY>`>yd=$vImDymM%mq8- zc=X4Emgtmu;E9qe4BkKFp;w$N)lajX0$So!ISKz}&=RNdhNKjyYdk|vL35@oMspTu ziL>Pa_|E}(!%*@Y+~U`uB`)M$N=sZMX}!1@}b>Te1~=SGI#a zy#Fc1d!QvglpDdnNZzmzAAy$mR2~EVRUQX&>i~W(JHapHN#K|A6qzGF;jPge;@k~> zF7E}ul=p*Q%Ll=~@g8Z8_*Om&{zGjIo{t-!NpcRc&N1sJj_}H9%20wTy8ah zzp$FX8mk3dX$8T0s|{RbtpnFs8^B*$M}rO4ufQhjSm_l(s{?GaP5{?gCxRQSlVySU zm30<)taT39Vf`9B!8#v2(Yg>k*}51!)w&cs&AJ>s!@3eY%jyEpv91AsZCwkVZ(R>w zXx#{2Y~2K2YTW`}Zrui6Y27Xh#WmKc;I-Ci;PuuSaLrs2fW|H%Hlzbt9|h>@2XA~k6K=^+bRHmZ>cx@w^?oAQ`S20X=?-c ztaUW_y!9*aMeA7bWvc^x)j9$EgLNYKN9$zpP3u(fZR<4f9ZNm`^jK$sf40dAj(kbu{?7^(*j8a-J@}Cg$)CHcHIc}cijXIaNPn9a@__Faor9MbKMD! zaNP~2x$Xr=x$Xx&t_Q)ofxY*SL9_sotc$n)0@Cesmz~!!w!C$yO0c%`;1y{O02kTv5f~#C# zgKJ!W1ApoI7Hn|+gQw3H@+=oY@+=o^ zaRPakixbJST%1gv<>FNGEElJdXQepHH5)v~bujpAm--uz^Ih{e!(EJiwzw4iY;igI z+2Ts{2a9W53&3k#i@@t$i@_URhk`e`4g+s-9l<&8cH+ztcM@lgxSKe0#J$AfX_+{4 z#Dm0{CmwbE0Cu~60)OxNC-^vz`SZj!mn9d7rwLsko+WgFc%IM&;zdFih?fanB>v#~ zHRr`Yy3PmRbX^F(?YbCz$8{;#{9{zh7j3L+&)kR_-~tc3o|C zT`uufF0`lO#^840#^TObdwpzu_mEyn zh^^ni65RV^>u*1{w>BLA`@H@7xqCy519FjWVM1;d~@iA9xU{QHYYLaMb!U=G>2l=Un*ded90t?8gb0eHt2f z(O*K@=e`rlI^*?F=H^$BSMmQbl=JI%L*p*~C^X@+zlKy?l_s3lclDPc-&G%nvQK+1 zH1wC(hWac#ArzB8H{{AF4!K583&nUBg!(KxDKxC{hEUEKFNO-bJ_)HbkLf*5V2_@&0ga&(;h7z+62_=k~9f}(@J(M_RTBzXsmvtN!SEW&D z3(2SC_U}Vwcl{VT=%&v@gYssDGA1twRUNiEG_vUM(6FK-L!*5&L;Xfi4)w__4jp*? z4joseQE7{>{W3J`uJ1z!-}_T2yXNH3unAS6OK-b3^v{3(Gj!|;r-TkUbXDl5pMMVB z@IZGcDSc8Xb(UYpRcTb(gKqdLH22;gLJJ@GDKxBbK`5hWLFj>}UkuHkKR>kj^s_>3 zM|XyrnwmlnZhIz_HI=puNDGx+@{&%Y(pKE`RcOfrKZdIB_$)Lir#v*Wcx7l=LtE&A zi!KgLIPmb$_!)~B`OLN#lqZ<_Wy z*L~M0=X7h7bDA~jd$yHpHO$I1A7rUhFR&9|_}P8Kw-X-v(N22qu+4h#LmPJOW~-Yv z&gy2(bKjFUG&JdRmdm?z!z>%}hxK;aOXj}e+eur0v{PR=Y-j$_6n?hmy{G8g^8!Bl zoUOdiu{vGnTA3!jtxT0#cFI#fy10D9x0AL7-=Foe8DYknx2;ZxAuf%S-e)@6E4CSF zbsz0{|DNlJ>$g}fVNt*HWS4hk>CW6uA4R{7ey{w;Z}~p==-|~o6sN2q}x9MrK*1Z?=Eqw9~-;P-S&5l`*{p5Z_lMmA$c-NZsnPBrC-Wh%7 z-|;Qq=-cfBR_&_CRcRgc@<1jNHtlh;;XWn=G#~We9(SC{S^2Stx?dc3+*&G{$RG7i z6NNqszTR<-fqsYo%&Y{V`E6fzX?f>Y8(J^;dQY2scICCbcXwXfg}d|Gg~Po(FFLf- zcj0eHgS1GKw8?|Ke7;;&f6djqT-9gRarw8_X@$aa-7nc`9q#?i+TQtrwYvFjYjN#g zt?8A2w3JJqv&I)cWsNR+!W#YV3Ee-fXU|)+Km5sBT=$x_zU3d*?ye85!@|#1H+`+N zzHw=GT>hQv%x{dm$kX%9@6;vVSlWtjRDbTWj*C9Ewzs`)&8~Rf>YuaGs?S|$6(`+b zmwN8saxAYaeE$zN|^=U2A#uOV;rG zEmm{>VyismCM!GWJS&-!VaJuOU?s{_v62<*TFDA^tVHRGrX%nysd=`Q8+xHto_e#@ zI$^0bx?rody7o_&y5OJIdHI)0`&-LY9-WmJdA1T3ZSMYhPuhy_tn1o+)??#A>$zEB z(*f1%`>gxA?=5TfZp&EynbjS4p_MFK$x791W0l*EvWg1SV?IzXBvor>CCgW}Msshr zj1^zFZ@aJi!Lm2*cWIJ#k4*<%UgSyM?HBIK%Md+1HvDA0)E4x9NbN^B=vm!C$6J}I z4Xs}0tZ2PhL3Ii3QiawdqBKBD>69GFrn03>xkTw4icL%Dk_UN_CwX^NJDRonN6XoG z!1^eDKeb=s&}7Q*t$dB9%J*EWmp;*|sU5A{w5RIzQ&cCPZne71bfHYM{zkp(>POv| zEUP+v*3~g-kuG_V7kQF*`jS1?61~ z!_iQ!Loch_ag5by(c4DNJH^&M`-*FWRc`FX z7hkkW_1asbZgZ_q-+p%BzyZt4``LE9`i4zA`$9{q(#T3T%2qpD-}o$csG5 zyQ|81@AW_0pob2qJ58>n`&GSuGrM}tHrw^x4`dzvYnPg4RT^j5 z^UpsYeU^Lpu-(4-32T*>VP%^3wdCq8tjVa;qUn+cd66f1cf0Q!>$hRA4O2g2l=2>} z{sW=;_;ajAtG=%NYLS|5H*I*-@i=0{2pcT{-5s@=?bkDh4fU2=sD7%1$YwsBXS1I9+4^3!#VV@LK;Ayk zhl1BS9Y$K??33Jcp7EY5<)mzl=9Z+ghunR=Nd7&PKj{+4gS^O-yazt;t&Q8Z&!#_d z$mTqgXLHpj?Df0*9Ikabj*jN<=?GsN_c|lyef6{{k-mC8eZS3l>X4oIe4d@GK5gIMEmI%3vX!Y+ z-Swf#vvIG}BeD+qq&y?P8tKzxXe_V(v6nsl2e&b3qY{?r%E`dz%-`d+lu+663dI&_{2qzODb=MEzu+ zH&@0>HCv^-G)b309^^%yIC zCtu`WrNj7WUOvz8wO+RqqWPC@kZH*^T3N=di(HzdOCS&OB2V%jz41Gn`RIN->DgSp z|2fkCXABUG1L}6@rm;kjZF<-?(dN%L z?MKa5JCj);|5_QdtbUK6E~uR`+vN@BWvkY`6F+5$mM(LGy8s({E@-z_5ZZ;)$6&j81-P2UZ+Lzrw>%7`9Ssk zYFf7wt}Kuz-}?|R|4|QqYcoRn=i?Q2ox0+$R<2qdtKELMRjQxr+hUOV!L==Q z+$jadfAQ(~{K=ENM{f8wZ~BgXcH%RKROa%WuEu{8{yk&$o9c_DXj!$SD;Jg8j&yZg z$8o3Hnfg8)H~yY7MIPiup5#4j-JU&D9^PxmKXp*!OY#rOVEnh?-}AS9VI`AGS@m`! ztfcVne$rJ(a*OgvRc3`3+6T1#Hj{>ZroPgf$-(`n<5XJR>dAByI8_FY+XBAD{(!=-nRlLb{o! zy75;Dq~&$Z%iQN1o(uSI+`q2FFAe%lwB8q+V< z{KEUK?%H`!WBNReFBNvVxd-MS{^NnXlqY#Z1GGRBw0Sz?ug!1$qJrWqReb2Pc8m5{ z2hByKF4a82vQW^RLF&>ymZ~uubH5!He{CHW?bI0dD{HU$;P&@^;pU9n-SfG%yE_uN z*F19YUU3#`K4p=<)BJLWCA(c(%tg2mlh?P7255mMXoE&*4bvZ?{e{+de{Jm*7n(b1 zT%V@-8$ze$yEXr^(^40GZtd^>*xKIlPiuYCTW%hw8S^-oJY$V6e9Ri0|FG3NM{|~E zJ*c_q^;YNfbynw$b?(02SsShXxm&E^1>3E$=6af3_MA1l>QC14`q!+@E$>*nJO5=J z?)kT+F8*|==9HlY8A2O0iia1%JiwEqoq4Bak@=q$`hM9?%>jL8?eF@R zwYmB4*8C4IS>uZywR&f+*Idj}t1{ybt2prnD?jEBR(9lNZceDou#4Rs5OYJZLGwa- zS7wCfhDKd( zl^$}T$>eN>v-=+mcHyu(X(4~O`>h(cWzz} z9H1H6Ti*WV!nV>aXlFhuW6fU83u#QQx%kXgnwMDdm8C8E*gD+twzaECQ6V~9| zO;-El6;^Hb0;?<;mdQEZO4LwWtTFL%C6ZkKgYi~!jh1fQpH#V#nhpIDdscDi}Et`Gd+Xv!3A&A$VhJ?~qatDm=u z9S1tPnX4*Qr<0Xc|0z0lX|C~`#x8Cwp{tw6P@lF$DdD1iN7d}f*8Y~iS*Lsdr8Gaa z%#~kR)*8)aD6byMlf0n;TA&Hqpb=W38QR+{*m+RvHr7RaWv$z%Il2RuqxiivKh=wQ zGI!-(^Ho~s$yNeSp)Tf>3`SkG9#clG%pw)579?t zOac!wLbt9OrUyL-OQOVeC&rsmPQuMg%Idnt`z&ad!m z`t{FSQn^Z2T6*o~5;bmM>_A|Rg7HJu$QXuktiuBwLRfHLT5C8ZlFM3|T8*viz3&v6 zCp0mi3XRYT&CuRK^XQ#bKV=D*o?1ieB|iIXJ!E~i=2~CP(YX-1@3!b&OV)U}OqKf9 zRP!OO->+-^jHzy3qI#!^)*$<2_qz`A3E3 z2`$hBZO{m<&vn53kF)V7t^H~4RPp<7J6s_2+wzlDYSG1#%T{*d2F5SU z+m%QvWmRj|vTC(z>ps~%W1I&bjO)2F?k`olgX?2MFY^h>wc5M!hT|c*oK^{OW7%oU3oP(eqBV z+6^1Kc{$2;=|(+V-PK^wyaM?;Iz$t+K_j$6Gqk5K*`3$z{_iYj{a))Q{Te8om|GpZ zop3mE)m--4uPwPk6|2;sqtgxK4()%qf3w~H(+Jidd($! z=KV4#^#4&BN}s0jgI9Z#!f|MLX-i;m~T<6;?uHjg+1zJKZTMJvry5d+f#y zJM8;?`yE~3f7e~7_N{t~i=U*pZ@>L^__gM!^X$GSUa~7zY_uvhYFeqfX^w}IeZIhFNvi=G(j6QLMt>wd)H;V^K#aFZ~ZrF9&YOa8@~OJje7KOOvt|BDTgcL zee|K4>?F^6rO@wp(tw#d30T?C!hocE8_w=N&7dwzz7OZZ>b;JooIUpMJ8n zYuDPd&pzvZ?>~6ZuGM_@NtfSX$5D@p{^Xji9WP1cDr#Qv%NRPK4I2AvO$wT!z1#9V zd92$H68*!r9k5a2bByM;$3B)935TtP=J1oWR_52S9sT_VyS)GW-iP+a8*e!N(A}z4 ztJ()2d|=zRZ?|NvrB!Q|ZPTYuce=yX^)VE0-MV$g8Uyq3XI_7o#=)grn@2nD<1p8b z9RjpK6SP4iv_dnq_gJwfukYILZOA6g13Y}d#z=3*Kb}AT&pJTW7HOJ?ZtHZ%>5tZV z8Z>L+mMvR4c|ZR6<8FQ&`p!M~T(^#b z4$k_`rEcvI{b8QCtmb!GN@i7CcD7+_K8dVF9CoxpBeX&@v}fP9C$GQy8^bh@K3aM{ z{?S~we!x8cq$jk7vHeF^Zfmw4;OZUp2YZN;Nu?d`l;3ZE+-Iv+t+LB5yUfw~>Z`9> z>C$DaVYfMI?&O^PP76x<_oD>``d*Sg)i#E>$PhmEVcme^CC=5ursi!3#7(D>OrUulx7p4c_pB zjoP~3#_!O4&J($Ajbpmj7YIEsUF+y?(kqys589-luY+zUl`3s*I(M}mLq=NXuHA%7 zDTCf{Jnorit6jUc-J~_gC7ZU}xwqVF113(lWZ_h*PRD2;wNzbq*t$*Fywm0H>0r$T z+Mp3yp&8oytokNzsM_o?+xFWet;b9gpRA3{)cV9st&?P&c8l~UIa+qnp8x}0b>BGq z1g+2Yv#PSiso7?rTMLbkL;RrJ40mf8^gI1HfwkIjzo=Bbfc{CM-_zi(q6yld5n7=c z+WW2kCU5x0A8g#i`)$f&2W^J%nl0L~=^=ESd9hnVA%8z#>vgE8tBW66V+hB^eula- z+^6>UU?DftHvN(BqclJVG(j6QLMt>wdw+$In`AenXVV_nyx7x+wMLX@^RzxgXg~36 zxAt5weS%Sjp{uxoerOO^sp81+R}Wj@66XaQ-=v>x&CId=0_{l@8IZgvJ^d0Jt^cK zx@&fx;plg3PLVjQwK30KHFaX4^fT_P(x{d4CjWp2uB>-K8#F>IG(-E~2foQ0qx&gZ z2b%TdL7VsNVXcvAev~yTg$@(Xinb@%0EG1bTdeT!`1>lU6Eu#Q7+o{tJ$3@{7L~v1 z9IrcEnY&NP9vRKw(*aG;293}P&Cot%?KgR2xBO_+cKqbl)8;GANurxIwv)BSlp3MG zVdfym2W#0*?xMl3+3?$~DMe)L-`95Im$8mso;h6_5a3q66}E_x@o}UqP$rI3yOJ^Y z(&#!LG(Zb9K^tp+&A;y&Kc3>?V~dXD28le@Mp?&!JZ}a?||9rhW zMR8d3^lJtuKDsA*KlaY2oqXzc8XJ`-`pg*J%QyZS)){}#T!oi8S8QaMk0@DAHa0zm zMf3ACaD^slgGRr00PQ0bu;-ht^@J0&w!qp3@%{QuaP{k{KU5P9459P6S^7X&2*x2Y`cPE>Hm#lDWSMm8m6SP4iv_dnqkI)*!WaxkVC%4{mn&R+n zc%3PHKjzjQE+1@-66pue8>^4!^~~`HKMD=APl?eTH|}L#PI_OeTm{*a{t)D?HL_^F zku_*&WBmqNp&8l}(eLZj${_yx~Iv3L1K^uXUA4gFE@fE>(uL^~ z^(ywt{+%ngk@gDP8s=iU&i%cU)3B>IXx;U2jLt;!`<3;_%cISZ8BTunGp0o`NXa=h zdhd0nnc6I86B4mYD3j9LwNni{_q8)#I26U$ryJJQ@O^RQPZ@XVMD*t@^uCaLo}KpW ze%aS|x00pGI{Q7^rdsWWIvdAun}z(bDRMgBw4WO*R+cT^36FdoX zN$W1y^EHrO!AGUGqXU}`*^-v7Sj8qUeI<&qOFNujg8P7e^(`fT+AnB^_F?P3QTzLY zdv=1_Hf-8m`&Ed}gmuaDOqpq2J1#74-WBp2HjXOxrHo8TZ(m3HvKpq9dyN|y zI#A~R@A_Ym!*vZy9M`5_AbtL0x7A1Cas_XYV@QqI+{~DK< z&pSd7v_T_wV$h7O7(BoWJi%L0{L2n#pyKTj&iWoY#RIl)va?~YUMGU=4ct|B6WC~V z)SjV^OR-)1T6Sf!XIqHvo9xT(`PAAi_{7@YB|Eb_Kh!?y53J4Y?_2BJWOH`wd)gC7 zcsB_AR%oMlZEly1m*Td)Q~RnHd@MV)PnFhZvT@KJyhUHhu1xl8OJt{{JYC-GC3Jff z^J#-tXohxpfERdzH+U>e20WLX4oa6y`z77C*cUnbIoT)#Hgw8s*>2gj$sTR7=(+db zvPt{U+TJeuZ+g>OUiVk+d3@Q~#9Ptx3!1y zeP_d$y6`jY%apC%GH+`q8#URUrA6%RkOgvpCwPO$co{@=evji_^1}WQnZk3r_F$&5 zPZAqE?U_uyN4VSpzkio~*`KV*rB91b*$bYv!SPmo&b?M;`t7nsyV31!FE{#1XOmY} z_IB8*IXkyuzl+%B*#D*;m$S(Z8+3f`7>-P&i*J`#1Rh%~oe?2VL-7apHBdK@`6uE)Dp^_7EGr zNGLV%d`r%nVM*-Et!&OC7X1$q?X#N*=dxO>Uo0f|9%^dUt0EnZXc`c6|rk9 zKlUmoSL_CBow!UgUvG^se8kBC9|P@fe@FOWulSkv&F+-#q4qOkvly0vc#M>Vjg$lG zM(PL32zo-<#y+r%Y+1Uj`c~IHvN76eX-c!>Js(*6+uycU*S~7bE|;z7Z?`$$1vRy| zwyJC}D^0vUu)z%RUuw_=;%&5S8JjyBbu~b)U!L%)eNH7Cr8_wV_KksFMERe5qqCc= zb>ecXfA$7TxoC&%L0_;oH~!7q%U-b4LTnwskj>!NqWv4oSOp)laasAjE6eZ*ukZ}- z!v0$7Na_iA&$oTtYgw{S$_m*)X2=e)^U}{`=l6lLgKTr-U#x}lZgTOX*6=*p%bvE{ z?G3Ir>rUB2-e{%MM%i)NqZ{Q_Ya;9sW{#Wn!BX`)D~Q+Hnm4J|)YK%G6t|x@;`jLtO8SHP%QrlGtCeAGz&Ke+%p+#dqgrpIgStuVvr(jcmiTS9slz z3fOV(bM~B_@Bh*92(R!g-mjJ%UPd024`hVhXVyB|N+5ePitu(xb!JZlR3NkVSbCcFI8VQdF&-uT1n-rSnKoGSdaDW z&DLH~jneZ8ihjP|+!yQSRXZUf>Dd;1OQo8Qx{PnVYJ9L%P~^>><0!t`i?3 zp7+4+6Z_LdLAHFz=fS;JquZDOGtE1dZP3NdIbp}?=Z(4gJ!wVp9e(H5v#LdON$crN zXJ1o@U1}oQ@?`)|@CJ|Y3eVy_uif1{^E$HcTJ2@mH4)oY$qO4xY*+g@n@j926Ng^1 z!>OJz)bXBNuB!Z<1nbpdzPWE0ng3+Xw|d%Crw0|=jB;y#VV(=SXYVrm_t1q#azRLyt{byfq7H*>T`wf+L^Q6J-=BOFQ>V9?pez(jPLL>w??Hp6d5#`dP%;GY!S4< z1H8Z!yul;9!ZW;MJDaY4URRZi?y4uTtL-i9o$mo*-cR?Qxy zem893vBlNei+ErkB74Q5uU<-1w?}-~jQQ4W&~U3b1|xP9DZwB~^vuoc2~h<*H-H@}pSKIn!Ac!4K)gGYFU=Z@mN(<1r1P(QcZ>L0A< zdf5ZYF1ep<>j%ijG_X6)_x}*~1;KsI%wdjB>=+&Ivi~k!p{A8CTh6AOd4aPFymQNw z_WB3^wga;3-Lq$pjTsZvk=T=Z8K5uqyG(U+^|fl%vYTaFxAnO{+N}>hYG=!~w$JE^ zmRzcooBu8?yHaG}ZG6ktPO-l0_lVX+bP7Z90#EP;kMIi5@SdiSss3S)HL?TKyS{4E z`ag6~w%4*>j@m9`zZ@Gfu6f+?j%_A3*zm$0eds*p%A1`{=aL=I+uolJsGFJphh1c! zKHA%&a*VF<9d!n4F0EU)w$DEMEE*YG=q)e(&82n5b$42Y%2fgzdHFFw2KX{SPwEet zRe-*HdS&k{Uf>Dd;1OQo8Q#+u@5;;4eYT$U-XMEK#TmHuplr8g<0}4#%Ko{qfG-a6 z_UrEryUudI2g?Q+TiTn2-FJHn+C#$}Hqh9KdK(tjn39u|?X9=oit_Gn@?^`1pAToB zd&Q0JyCk)T@bC5)t6qVQ%&Q+Qlumen7kGjZ%tqIDF$r* z$p$O#P}%r~{eO5rAYAbULY~+`dD{YP)615xU{~C?(b4+c8}E4*3cYsi+SToyU~LLr zm@#8Uq49Y5-QIo9MiUvN_v+``L3~-ba-cpmv{Y!=%7)4wFia=+@BlCH1aI&NukZ}- z84BICC#u(4+2QHkAnlD9B7Y#*I0v@lhjon&DZ@^5dDfJ@qc6kAqGR`7j(6zX^TXbR z{P5z`Q>F95j7bxAZo6Em+)!MQtmJf$GyLotlCwPNLc!g(p$9BD^#)y6OY|tjz zlgh4rgs>kaxs6deW1P)6cH=?FzAmWu%GYQX#h&^P`469Uf}?T4)~6gRUwrX}Rje5F z-+5o7Mvds+jk$B@y0volAn@+}_uqHl{PB-}wCdF*Up>RV8k>0j-v0P=mo_q}RJEFH zjT$@b*@F{|83Ws$wsZavrPa}lEW`^u!5cinD?Gz{7W)o#-(Tap!JAcn6lawD_KlH^ zHa7F)WcMBpEhnDuXv4ptyQ3H3>OkDB0U#Fm_TYr}>OE-t)eWo6m%#~*J`KmD}h zr%jtSR<1@9x6aP{C!c)MJ*RCbT{`IF@qFC4aqju+|N3{7|8f;7%FeurC=( z274Fv!Mh(H!o@zY)3*gyX94=Y(xHqMIw_19lJKG^T_^2;x~XV~## z`viW!``z!{`+xuY-%dwbw9wv9eK%mh0QY>yt8corFS>iBdrtq5vX7lE@tTi5%{rcV zgVmN#$9A(XkJ1be@B&Zp29NLx&+y)3#qPX5YreBVdNyo}>|wR9VC;@VHbLKDtB>uz z594L8SyFv2+G;TO_;anfWfGex&|yG3K-=ofBkR?P-Pw zc!4K)gGYFUXL!$6==Xru&>xf?+e5OaRsA;p(L*-r@m%>{lAX5vFZnQJ(QA%J_A`Zf z=N_B#WX<)|(O$Akm#%ZP{`H?9JAV8>c*iFbcv0?s8ua~mhCfXH=mRZSupnCYAN$K& zF1<^ataW9dJ$JtD5A61ivxYh2qI7zCxxxdyz!SW|BfP>hy!X6M>(`pM7`jnw@!AhC zj=dN1hcsDx1g6SPeX8~g_>g_c1CGurjk-i>_dIZA48VAY{dDXlqORKZr`PR^J>NQ? zSpE8`?G~Tx5eR?BJ$)eFU2(+~Zci9;IFx(Xp7`6_E}hGkt+%G_QeC?P&z^tw9P(Wq z>Aj~j_9`D*;su`I4IbeYp5eWh_HGQ&{V@5z8m<1rc=^JbEP3IVYPxv$`zE-iop7zo z3tf+=-~UDi?5l*PDm7|ZlQ!+GX1$=FO4+H|W>BHu(uUH1<~#aEf4Joi`~8CD+S7QK zjhu6mON%y__RjOpl`#?D)NI!+hSn(E;3r<-3EtolUf~(udu#8ozTp{l z3jUpvBQ_`SB=IJirS)!5cinD?Gz{UxgvMAEjp#w*M6Dosr*M_IS+EUJrbf`Oq*c znB&5}kKp@%VcLs(kN@1F;xZ=!kIWBwUJJW2zlx4D&K?z|)6?txt3~#!;0u^NH}D9r z@C@($R`1Chy5V~pqh}NKZkpoEd@9%N5t--q-^i!$b3v$^7SuKDohVbOj@9ctsYo7* z;*U8GY*7=%VV<~L%c0J0xG=u`v(oi59sjLI%#YIP>2+7}z*1zMk2NJ6C%&*ek={9UtmN`1f@+`_mH9f28Nkh2p=Mc+7+OIRyV5 z^MUL;3ELWbp2Jr^57OoME2DIJdbz>_yucH@!6UrFGrSL6vnOwa?#FN4Yg5#}naSQI z`GY%N->}yPA9+4_{(YTPp?1px{QL2+=OfXTJt_E1WgioB;_>wXyz|W2xvLz6c@E#R zZUjC3FMl9Pr>8f#YOe?TZNwA2!6UrFGrSK{7`gF#o1kY?^=_8p%#%O5`SM+jZ$9?x z_z=%OUrjVDc|Am!}pYtc)Y{EecjK#Fz?SX{t6H90#EP;kMIi5Ln8a;#^`>sp3Qvh zK(O~raZkq1RNwl2Q(WOc=d9b@v$@;8(!5o2Fcwn%6{efI3*V6JuMF>-2*>gF$jjfy zU-4xa<~RP{kNvVv_(KexVVd23FY$7scw)~QJi;qHyM1@;8)V<3Y%6E!9s9!YTYn1n zwa#uAA9+E@oOfx&o;dj3tk-C#1N8O6v^)QYt%p0^4nIHId%qqM&$sjGs5+5x5M_VT zvR9)tdRqMz9^eI@;0+$(6`qHRcWfKS>3*u7&3^nqU^lI}r#ic7?3d-EG7?UE?qKwu zXJc-E!sTDOV(kL;H+ya?YQMnI@*IvI@6#JOxV=u=L(BM=d4r0z8wLC1LUek1xw2ml zUQQNIf$j1E$16NLn^N(QZ7R04b0Yj>>zr@<&fcd);b*JWI+%ZTdjVBnh3P+1A1@p? z{@(fjDWu(V`>KUGYwKX2KINPu=mWdJW*(m4A0FWqo`*+lY90TwrJwV}0cWF4Tx{mC zX^-w*O0a(l-=5Ine4=U$7tcqc-|^+%w|721`!(YAo;h#)9Fd<7Q}6p*ku<`C-}8Vi zI6Sg%!0|6zV)mZ=68=fQekXKMW6&bT#hx#Jg+JeSpv?^T|BwZJgLwY&XYcuT`L*a+ zB=3ID%72o7@&E&T;;@e4*ML2riLSJbw0(ik@-7lZe#b?^SK;~yCe_}vnRmD|f1 zS|gyYi(fN{*9Xq8@O*Q1>sp%gL)Y=UP5MV0j)=c+|Btc#D~z7B$!9wmFprm_Gci1$ ztalexH_&JH{5$_yNo8C*eJ{A@sQLDE70JJNrw>$U`=>q=-}-cp=6Z(qKey;N!O>2? zz}rM|MnZV*G%O3+z$ovs_i?@@RpzNzk0$T7ELZ2qS{fBqg|CJA9-~VH;nCt)i z0{)@lwC4_3lkUNMp|cBTcEquo0o3P)YOR_`&h` z`*DujpBu6FY~Fi}o&Nm6UxYn$zyrL%Q~ut?eUbftn)_V4N8>;F*$(ZwlGea4V>a+fFC{TMdZObEz}F%Ceob~gg;fi`?Yw7X5asZC(l2;!ZW;UFJ3PD@+LpL z*X?g)pJa6Juf|S{eU6oP{~dnlGiLtQ@dkec{FX6JrVrrk*&=q0?6W=N#oS+_gQ4!abZj!CpoDqR*3Gp}_Ba@y9@(&m&z2UAj{E2W$HcyUuiT z+uqL_GU+nof?r(T!!)?EFWIw)7oOk^9^n<9;a&R~U)CN<`N7c`IIazJWx(mcucHT) z1$=5TPN*Y0Sp3DnH|;z9+A!_EzK@CwiHK48_?*Qy-2J+=75pQ-sl zuLHgw4DTODrpFpMg9Cn(R2Oni0{0baHL!^bUp(eC<7tWCZw?P0dw7FK_7B6ec)z;e z%CFlGTC>~j%k?@yJ3v|CJHAJMkfRT$>)r+F7P2XB=yB?Gj%WBLG|3)e$Lk!!;(nhn zUW6V`A6IDhyu%ATq2KVx9%OiicP+D*&|c$>$YYGof58XTbj2e+dVt;_2kH;%Q1YQVc$R-G(syhLpwac3p~LaJi;qH!#hE8Xr!{RNAp3h zUL+o}LSL9KAq`|m`$6z~`ANUHVg6GGGg3>3C;)Ka-KehqaY%NyY;-nW7 zCqfT66QC8Ep&cIJ1>7UN9~AHX!@T=@Js*f{&=1N8^#tEKp8-mTegpkP`pTsJzbc3( zXoE)DcW8!ocz_ppir`-8{@0KU8c{Z=ANYoLg0_%JiKXGyQK0&;)JJ2(8cz z?eG9E@D#7}p69}@irb#{K{9)peggeOrRBy8e%vH|a`UImq5juGWDFP36!hnz)%R_D z8&?>QJX1ULe}DfUOW@gA@*7b$Uk&gZaXIqPqp07A(0g9-mq?$E^jv#xlN7SF2mLqN zf4WZLwH9}Lxl{X4e^SVm--g^)ckaxU4~HWL?PJdU|1lItHpmcJI+;qg$k@qRGDr3f z17UF_yne0s%CD*Ny@mI{T3c@+G3MD+uymfe#DLc=^9@WEmhU z7rgu=OD|XU{3B~*E}dZSw}FMjMA-aVILD{c?A9+*g#CRjZu=5lbomFEN3izT;$wxN zeaS%x{Fty;{fGg-Cr2B6x_syFqgU^Tg?Ik`Xs+Qj@#S(1^cD6^l)iBKvG@46Xt$6M zk)vdaFBr;Cpc{cs#OQ*s0VA-A$M0BwD=q5z^Q2?@RQKqNqewZYe1o}s4mcV;PvSS; zrw;q{-MMR=y;iIcj<0+9dg#FUY(BU=IIAr_$oB=)kU6pk1AL*ldO_HL5mUm$sM{$>4f_VsUk1hUog24G?K?r;e`QL#bqK@p{B{=^>@y)+7nNZ?;;--{9AsA5`|A9@9=e` zIQ|=VRXU`nK>E%n5_u7ne+Qit=;(2D$)}O%bivckd4Lg~qI^1jBfLlC6ZOla-^j|# zt>ZG?N95_{i|-T47_yJ?5hZMVeGs$@U+e(GW6=S9*HYMjkYDC~c@N=^o~t}N`XY2Y zzfvo-FJGaPyW(>RpHBE-!iP`bm&f^h!snFyFm+riKT!CcT7vxK8)^}9#V^z63dmjl zneGO=kFDKZA2~l%ZSRnODfyvtzNVbtDfytf`5guMwb5CKt!|WmpBvw>mN)!eXBrY- zw-(pE77BmUeK_zgh~wh(-3@QJbXAXDBzvUm+=GJ#3KCa%^*^BtN`q0r8___Kd ze!gUt4MTp3<3>otEu# zXGwB)WydApjBLR8Q=K&_xjB60hwBc>^)~qtldN0c43@$X{I310&U1X#n(LfO&be%Q zxqSBM+{%ey(rv8t$tUIaPs?A{b1wg8SH9%V&1^2ZT3q`VcYY@H zLO17Vwh3c`%J!fnpALNuKpI1(1Dlgs#SfToW zE~tKp(F0)wR`eHLT_6m>5=@Ju1CcuaJ&!&8c-O|ex;|XqDa(oQ7X9$yFc)7-;qgnI z4=0`%g0a7a5Smi0V zSfwd9>q^jXp1HvLTU~tj-Hbb2I#qS1Xf>V3S$*yz`7T@H@^e1k#;fA*Z}PYHhU2&G?eB_z`F@iekOy)>KF$Z6 zCo_?Oj z7yMz*xTan9es?EN~`L?Th;&S;2yk9=$)~cR)PXmkd58bK zHn++Tp!5OXcbrp;|2yQyd9}zfO+EqBm+RbG$=La_i|B#Zg`iyx+F>wqZGtd!z9S<# z5NQkO4vu~Ko}R+4oELj7&kDlK-=Nld&W16 zWdiKOxCdq4(SmNuPhpy9?6g>VD<6xgD(@Yn&+YE`hqb-sO=~T`e)wB#?s2~;g1h`< z)>R!^`{etqrph>Vw=3T&SFUW2Q`x3mt4t&7sP9RS^)cXFYQQ;Gs?TXws`n{D=zq4A zj`7!69KDI?S-d`|-oaO91=SOQF5Kkm2hOFgq4o)Xhjru|6hE5{RWIQ8vB@P*26}Lf z^x%5=!BjcH2PEYtRrNu~h4P2F_){m}bouWrr~|@2`?DluQ=gzHe zbJJ_m?>}3MtElInu@sg0Mk)jK&(XQ$r>~K}QR;WK-L7uGEvVO3zm^|&m6K((taIMC zI}bb}dxw4Eat^*p9Y@GNr~L2LXky2eliw=YZ87a#Fv#zQd{&mI*3e2e>|{x8b*6In zIr8IqK@s(c*MW;Hwq8)X!I|XJTh~@hy1}(qu0EK1uk-&{N9`JZKO3I6C8`6QDc(|b zBW0!SEpJ$Rm7NX?-nWiA_nR`6wnRP}b^dp{G z;4>CXY13UhAgsgq(>G*Z&(-^`zZbOm0ro+9q>De%&iE5mAW!^qy0ggd+vR+VLL2@? zJ1tWCb&q^&-X;9yXSB`DuS>6mzx-U{Z#3oN$K2WJ4bGvB56XUx`HO?HKSMrebp|uLDNg0lK<1^t(EG?Hu43Ee_H&Yrrs_5 zU46w)ltixVqzn!q}5W&8a>e93&!d|{` z@!#8JAVO0FZ}^L~Qd`$T`rhPX5;HFQCJDg5vvPgf^I`uSzljwdzNzO{&N#-hu631^GVUc-_V>$!7zld7aR z+r5&N>br9qosU+X?^1L+L48r8qRzPPG|I|JAE~2)vVM(p_IfuasOm9yZ9e7wey8UR z&fVnnzKQBU>cSRRy=bkk3(9=E+XCD>-t)fmf1I}D-zx9&fxO}?=MOk@m3;LIb7YO& zyUPDpSNSy#@Q^=D`NajJF2V{Q!D%b;5gW`8xH%$W>&ApZKj0IG{jFbQwp72cwb};y zeDoQq_d97`0UaWpF01z{5BZyv&&jN{`{jdIz6S~G2|9aRzKOfZ7gd(%$&x>stTpn( zDc{AJt9Dza{1|6Q7x1^7E?r1lsQ%2|>et+<{>^P~IKRiO)i&S*nR=m_^r4CLq45P< zt>L*Foy_WE+os^I8^2`$ESvn)S+dBEYldPT0o&3Q7 zOym=mAdE8C$Um?!b2>mhz#I{M0b%RrhJ-bk3;)a(T0@SO{e`S`Fegi2Pi=|HeHZ!J z&3GX2J)Na|y2<}Aewe%ChgQB=d&n1M5BVc>*9RlMrRCQcAI{y@L#zB(ua!Q?&ve(- z(g*pP&baSO$7AQEs@E2)Z*%Xzq!SwRM0BFv&9BK1xaLc)ec4)G^+LX0T>Plj9Q!+! z-(b&ZK}<>r^E&dklCJ%=#lyQOU2yNvhlW}1JnW)$p-kgctAFAmYx;YYYlri*PN!R6 z_b2K2UmVu>)lR+ZAL<+ZQ{~_TOJDM_e0_iF{9k9R{L1;jMn+j{CeUKe8M3&v< zm$|!q{`Ek{`0#czkNCv~3t<8_VC4LS3p20-L$Gx1fUs>RjC~yd_R@oOt?!cG_3>%VXbTqkK_sQrH~$rS9pk@=c0A?ZDS~#HV(|-?;Ou4IdGm z==Okg`T_BYUaZ;`)r$=2eizB4v;2amFZ$5Zq#K=7U$nmbaoO1SD7OpDW#H%hzOUrBSH9iFGrS`M z{IG*HvT?r8Retc%?tGHtmt0t9iKBS^m{&M>4^mdS7~l@9`eevjBVY7ykHU-Xj0p_$hx# z_XPJWxaQL<+Tnu$Px9aB{H;r`oo>jNUw74Q-O+jEfqqa9R`0Q<^KT9O6Bp>0$)9kQ zM)IB2w*c;(>5V@Yf1WTtc#4a2apK_zzeJh9KUi1?xUby4m!;qJwxb;$;02!G4UBuJ z9KdrA@$UVxI42cK-CGZ{+J~OYBoVNwN~wL7RE68P~B(^#r%9qV|_)7DdbxZwGU;2ZE9kwFA!FCTYJ=%+tlre6N8 z98w>v9RMS+0yD4!Lstg~Q?LbNum*Fm*VzF-wbi(gx*uQiX{skWtG>w4I3iPh$t;!q zZmLhhW#64C5W&A#*dLJ>>4xf!aOl4B3#-&B@X;BTE3!_m)!zBfs3br1_?`-%hwS&L z`YXO?e(ka!uP4+$oQ)Afr|N+c+7HzFtYtBLg?aonWao5%dN{5Q05h-yL$Cx>umxkV z26M1)bJth7?bIH0kbM;OL%Qa9x^RAo#*^p|{d~?F;M@gY_9?f4j>;dsu+O+Gwxc9Jkjp9^*v68%2B%hOsWp4;lN_ zi}KGE{{Be!__FeQzQelPaMYRZtdCz?UhZ5F*RBR_DHwqjn1MeS25mrqKNy2Gn1j9A z0pTzE8$Cx0RUldyItII$8 zk^FBJrUPNDy^jv|YFF(zF{VF&Z$8?Icz-2F!aC7=e7Tk^TdjZ&*B^S~uP!rpCJ1dO zIzV4a7=aa-fgSjRC76OO7=v}B50I;~V{$uaOh~(sE;}U7l*!cmZkF1OZaO!shvpcv zHRkN8aegoL(R!=wJM489M_-lszT1AC(Cfh;)ZPa^F!Rez39GI1(+k7)NYCnp&S%0u z4|}xzH|SEOcB7*@z*vEI=*E%!R3^ea{yFmx%thq$63iPm8hh@qCNn2{Vc^cjp)RIg zrXMY=zzpob5G=tIY{3|;!5r+{-TifLs_r{E{57AfcA~4sedrBm%w($_ab;iiiaSe5 zdKQ%XUl;#6y#n6?VR;o7dvL=iF}}MUj>5M>n-Q)~#|M+gJ$$9lSiaTps1Ah347CgK z*%gm(aegyjkfgchFi+e!pL6Z6rvnlET|MCI0AU4YU_kvv=C~n}6 zUL-~Qi-f-^{9b+)wO-daa-NsRJ$&UXKd|FGv+(oyegZzrlXYGX>qoAC$CzI}{FsMG zs@%}c3;MHc;&lNX@MpVtI!l%+V;MU0>X*td(1D;lx_X&90Q{)~BKU(Pn1U@BgEg3g zeFue3>JOx=Uyz}9T@|OB+KV1)H?q}!~kI$v?n@KtT@m6 zZQf@U8n=&@U1U?HN_}_ETo?=PId2XBLtcL2YqETiRIORtDpuiKvV!aR`04QHJH@BV zZ`yqPmBqiK&rr5eR>FC{0(mhvQN6i4b8;PWwb7AD`8u3pb_?*Hr;$uQ6#>SE~t zWs@>WA6=M%9TL2)X9KvZ7>t1VyrRsGl(0(|dSjpvLc&@7R$2ilhIOV0#IIjLxS)@G< z;SXkD2Zr(ZgEjbred@hm=cZ|o3ePgtKg?1;vAc97TWh*G5&ZjTOwm_;OVaPJe*XZK zeL~{1>Jpt{m;XF_(LV~*`|~+e_Sv33Y99`q|?re!5rKRl=T}|2 zWSyOM^=&qE`aG-GB-W=Xc_r6qSwIJz|IauZgQin1{zbC%cz{iy18S=os|$ZH1WPal zTQCM|FbDgN3hBD1NsDs_`wRa8%449zKGz26EWu+9 z{>(*>Yx$bZW6B>m)X&h|zx*cpI1QS$l6+ z8plcY4YOj~`WQXvqq865u%9qtf_?JIC(*Rgv4?dY&UNb^iJ@io1(#d3TCrn3f5u<9 zJ@CFTqcrJksmvRmJ7!tB^DQZp!Ul}M3e3O`48ami!4{0c8qC4I)4~A%j0pbS6(?J9 zbM#FwecMNA^i^8@mF57YJurg*poeuHVcc1g#r>UeP2g|a^UqmBjkANZLp>IZ=aOWP z>EoodY8yS1&|`o7`bX@YPd<<0lIZ5U@4mCPZQDlEDx>qbeOdSU`78eHe4d_JiG5e{VfyQS^ zQk?mh-(PJ!;?!f3C+E9@3D^X6fZA$d26kWwmS76DU<}q^4)$r_zf|~ZKSwvc>k+}f zm%ix}!N0%K8lXN3WuH6-yRv_5_-Fj#krdjKkvoalYB|$6kz~@eixE7P+3j&e`?PYIKV2m*YP(j05+T>ZeBKmX_ToMy_DL z;_(-avjva#@AJ<;w^BOS*vq?dkNop$=ok9u;qyI&_TsWO4@ zW76jA_jnzM_k~|ErM=Fr)%lJI&MPkLIaq)R*nkmOff?9=Ay|Sb*n&S;gE`ozD`aRN za#!u==&rLgv)2fJ*%$VaeM(>1==9fFy92lAyiuLI8(^>VN0r}D&SKShxj(t96x94b%45nGe|uaoSW_2dw>08=kDUdQXt;Yp@A=B(ytLZ_qUAZ41JzgUyW(> z(f|GFA0HH;wcmL4VU-u5usR@U2LgY&K3>}sZ#pWuf(4iic{nJaUJ}wcl+)6bIld&v~l^T$fvc>lk>ZG?%a7ySsXfi*lyqa zL=4TGAsVg&%ILh8_&T6;{fub-(2-oevJH6Pivnk0hh-VQ2MaI(8!!SZFatX<1b;9E zTQCM|kALUIU*~2@7rI68&rzJ-irZJ;^!NDdyyd~$4o0xo`Mb)G5PzO_QNM@iJm;ix z`Tco!?sVkbcwhFpR&LNSDvJ@3bC`X(=lbe<9~~1m{-YOOcp;iT=lzhUKf4;)_v+Ql zM?I!1a}Z&Axlhl@Z}XCCv?_o<`VenFlrrMvV$0X#F>HHKKEY}bXJiY1Fa%351zYe3 zYcL1C&b4-h1yQie}$_`)!mC=9|g0LhaVkXZPQK zf5LBz^MdozZ`$x^4BZzmS`$tGIITq#hCk2Z`-1g*PckpRqOM>uB7#2{ffbm69r%MK zn1U@BgEg3gea4bqxmnBiSP$*z%u)ZaxAyS#RezCsW1!9$M~{Z8J&DC$XVI(dkA5t# zSYhafUG9v%Xt~pv&z~8E{C%MB=i^kWS}jI~=)uw*&liAz^VkOu&hNYPeF?1xPn$L^ zdJcK`Bjy8r9v=U4)q-<*c>dU9iFNF)x8AaqD_7d8Rjcg74?hei8*{(xu@?%^&b+nH zw~TBUU76>M46O+zS8w6=n7A{bLw#S`$leS7azq(}#YpwVV{|~6xjH}?x;8+Vf-M+> zHJF2arb0K}XGiewqd5H(cYyF8q;JuqVM=Sb^lF6amyy!5QOawy@*E@lixWDZw=Bv# zGN=-F)}+UuIX^F>YPD(?km2g5bQnVDFE=;Wx^&TAU!_@C7(IG)D0XoB&O7f!<0fmr zD0!Ey7WnTcjc1;DrocDoSa{q(yppP)m?PM~e}94a>z{kI0PS@fH;LvOJ_ou)XwJde zk*j_P^HR6l$Ro-aEWiY8zzD3s%+&$H5G=tIY{4I_!5r)z{_@|Et$oD3)IT6jfAtpz z>YKs(b}0C(J_)ctq*2be`}?2NK^UPw%3@en zh27KN3;%82ygB*}xPyQB8qK25cpv^l$1*Zv`{&_&CQqImj_&RseBmzzXm8Y_RWy(A zzJ;W!vFlUewEcbW+g~bD&SQi{pabfYJra~tFatX<1WPalTQCOeZo=H*zjRk_cis1l z;NMq!aELny{I>}Itp{wl(i$nf8l|*H3xDz(^O*2|T=*X$jM;HWXDU{S@=l%GEM$x4 z%RX1;-HGiOHA^|Fe;UUJDLG2dKp!3EK8s>n|O`G)74 z7$1iJR;*YNjUS)3|NZjIvGvm0XJ3h-8{MtjxM?(&B-N%6cqikupi$ER4Vk%)kx|!4gct7K}aqV4t;Y zS8fmaamiWrt@Tm=u%Gs)4OD+|u)Z1k(0=LB0UP=7!3g$;luxdWQ-0$fKWyWl$U9<4 zJ@JMZxgF_jQO1Ry?{O!cRX~pa`XYaB=F&?qjmGugJpJ_3Fx{N zbqCHf^WS4H5dK@dc(EHZ@a(0RUb3oH3)&c+fByN=PY!4u8a)l`?UDNb;eG7oYd5wI z^RBjHJF1vAzSyo^sKMm^;euh ziaSK#4AZwGl*TBfHAZQURodf}$9Uy6UU^Os{znQ8vd2bc3oi}3&58E+!{y%J*J?K; z8oyPi&M|UCrrWgc?*CYmFITQyG(PF?-ko@Ec;du~(YV<5_&l*I^y5y_`17Ct?6W9v zz4FQ{qiJ|-mM>o(jrZ=qzbruWw6iaaepA@^zl6?L^l2q)j?Bw+^yWR*{gQRoWXN1A zSF?d-U$r&*&d1>j7GMH4U<6iR26kWwmS76DU<}q^4))zV{_-oqy8+<8ajy-PZQgKw zJ5p(k-X7pT?$JZaC)Xx`y~0H0eWXyXM*S#n*x@BwclTH{>3zET0KpzA#&PGywE;J* z-(f%O&o9&K)~$iKanXb?Vfy zAAkHY8h^v{1^fP~-E*SfB-d+l!W;1BlQ6?)2#RBt`&C;t)y6=$&G4%0Uyw(gf69k4M<3%wezv?nN!i4Ob2 zHtET{BEzWl`EzaX#W>sJT+}s;MZ1h{1ew@8{=%lH<<99G-=2yr)HHev)egaNkH^YOMuUKhjj0O(O(US3RU zciwrYvm;7PO|{cbJIy}&=%eU+=KUC-hTDDaGx`pS=3TOUtpa5q9Z0U#E*b|qbN;ZU zNV&$#94x>DY`_Stzzpob5G=tIY{3|;!5r*+EEoRr-_=JxW(LSV0dapsU{d{s<(*n9XgAHL#K#Oo*5 z%<~o%Dc5+pPkvHm(dmHdW?@7f0A^qZhF}S%U<<}z4d!4^=%xF<5&Q=$&agu856XT% z{!^6aRN-G#Xg)l4y_a)y<7J-cH+?ef^t@cqfeELa6Qcu^uP0x7#}3K{EB=o*AuTOd zu2mWZBqh%O6+6mmhBxCI9fd6rDMqjL%Me>qD!wE_Tut zH^#{OwoQ-QlYe{LKKyc*z5d1!?kk5^dt5?$(y;UvQ=YkGqD>xaNt0^ ziWzH>4?GiV`-e`ReC16Rp6_SB5Oe!s%)|HWEeg|`I{VThHJF2aPletQ{0BwwAFjBg^v#%ue^Nbiz$QfSpRBrnitwMRyrwD7 z>B7ILP@zu#+@@b^4dYv!dvqXN4|q9Y6N-&x@6i*j-?*uk*>A8lXx1X8kMH7Y4W+2P zgoV-2R5svYdmz$b-e~idhwQW6-`H#a`ox&yk00m%Uh8~0BgVP40Z->~>Tkr`eulB< z9)EMu_~bR|ydvcqFLST}6R-gz@CP%n14FO`Q}734@CS3S?|I+u+&=Q#*k6A82C08I zbmNaULjA>2>Nkwlx8qfhOjLU^Nqvia?1j7P{uxjIoG?rmP2n*$7#1e$;yj}*sM@4k zbX*vgRZ;h4t2QXo*1xE{(Sha?VNCAuHS1 zhvwtCtM&(m=lbJu_rKlRf2fXYGybfEaxF~eU@?uhIHCh!1!iCehF}S%U<<}z4d!5< z6TyFg{8PEMUvWmNzc5um*_&+*T=D>)3^}7Qt@T_Xnx~g zHe8ohxfUkxS(HUr2dHfp{$K@WU?;g9?Fj2fj&+E&_ z>u1(<*h7=b^Sft|-6Ou-h6!5YlLzR&%;a|g&r>0pol zX5qhepW2Q6YCnFmDUTksX&O_aS2Lf=m7X28IS%_goBQ0)2}9S@Zi(TkZpSgv@?WWb zN4K{(k$nHt&uey>8Kvb|^1|n&#}waD{{C36@%w>$tL`jHw(;-gJgc(k>HxLP!pPMD z!VK)d5G=uTq_72lum*Fm592>v??x%kSjC;7ZzhHC56XV7^en)CuJW8G{1b)rIhV!Y zU%&HYC-b^#fz3wE(B7M4!QhvCgJ0lZ(guWmgw@TO_lxmoPe8c*54rWpgmNuR-e3X# zU<3ZH4v63nhF}S%U<<}!{QFY=<%4?2`tNMS#vg37;*10T?fX@K{G@v1piO_`kj+&2 zpY?RE@;PkeM>t;iCkh4d?=so>=<;JXY_5I@hQH)ne1g{NRHJF2azg4?)2kL&Po{iMI zFD6qdJy&_mb7eoz=0E>)!q9ncZ24zxrBc0oUq59k z)%maCU$e^$=Nr5zjEj0#zSS^?d83?DEk%B4J&wnEjrR>T=kdJ>2tQjyGHs{r@xJIPXERDmndB+TK|`; zUZ+U8dijR0VBzrxBd`K9k3U$3@ds-#2mAgCgTa5pcQ$I%4>ndhGC{gB`H}rL_0gYf z`r`*}){_DLbDzmoK8IB|344VTRQ?l%c>KLxZ@8VSpE2#fQU`!BWtFo5JihpU!-xEl z?2{NfRBSsc>QB_Cb*yC{-*92s)a}?ap-dCW8Y}`GP}?kwz#q)O4h+E(Ou-h6!5YlL z-r>LY8yoKNe<&aSY5I0X1plDy=i2eYKfpfEPJH3#grQ4Z{U65N-&b#*6P3TmA^zGV z;?pz!`7im6uV3&g*J`Nq`|JC2#px5ECyljF#phqI+X=s@{FhG2w+%xsZAQ#bDAPpp zKH>SGJc14QgBAFL9T-OO7q;LJ)`NvP*bkumNAMr5cjFXiqI6}7bY{A~ovActE3LUo zbDq+kuRKn0Wk1hO68?!oaqusWJy`u7Cu&ajyr{gr+<)m6f6(Ya#WthdwLqA56dojKB)azzz(-5=_Asj6MEfKVbFl+#$k$gnSQ; z-u#1&SDZ-?3;!L$|1shJ#6g?$RDl2S&kFzNgun7TQ6UjMJTDIZ*m=hLe~8DG{&l=> z&iFXT@;m-qfN)!IH0k-e<5=te_&uMa?s~RJxfUjKun6h^wavl^{J{+Dzz{6|AA9Ek zZbwz_Z_*nffpk(yC%yMxNJ0x8#e#w~5iHmnDpC{>kluSonj$DFdJ*-CUcHvf_42nX zNCyE!z3cybzqQuvwfC9XdroprPQv9p&-cteyUwidd%w2U%%D?ri;mGXI!E`buYKy( zbvHg^&+Uc&?|i}D`&Q+RZ~xXy?wvvZDf?0PNB;1CU6IT>q&ok{xAht_+KpOyV3zCf zT-p~Z8h5Vaj?d0}y-~c*`wY+3#%=PtqW9K&o_hyutnT?7*OQI$kUZefZ$DQ!rbT0o zO_&WNJ^=lrJ9LOHP5;s@I!6EK9NkC#?{Uj>dQGuk?>SKYf`fwo4^|%eZsik)sYwx3_rBmqZq12bs~oTNpRU6%8fVztVQTgDIpce|es6r-oGo?} z@A<%W|C{sK^u5H5jn%);{rp;YY+#3-CKiro(Kz$G`2=$Dpnr6Q&d?qDN0;an-J)Z3 z9reGkls+&!TbW`KS-?1H`Fxh0f3&Iz*S~6#b)PbdAo@eboP+Uwh8&qxxX~ zufJgL^|_z)uRP)q#S_>+T>3vE=>I7B{`Wp0{TE28|K7vKxg)-}A$#x0rPb%{#q;pu zxaMu~v)$BpiTC{(w&WO%{aVLdOy2v;JjeB&;WxcEM48XU_teIa=GsEXK9%cE!2hbx zUY(6m(YWS4k1ntQbc2p84I75{r~HZ zmhOur>L0(q?}b0Edf%E8ZmNm_dDni8V;r|}tjXJn)iLhk8{&I5X1gh$kN%^%dXMkt zT(B(mOaJe>8wihgJg==zooTz;5yd>tz%B$~F#=jl5Ow zeY@%gKKpKcN7VljvaKU!WBk^8^_#W(k^Ud`Kl7cRZ1TP%?|aF0>6xtS)jDg|*fi1~ z_j_aP())I7Z2s5ix5~V}DfbKFx^HRUhuEKvUvnO#3v_~R&{5Psx_LdLjj#JV2 zrq81b1l^z`(?5Lx=^q`M{-smXKQ$owm(J1sTFLHuyw|PbU#}hbjThWOdha__H@@rM zmy}1mqI}|2iz`R!yN}Xu9If9v`hov-$LMk#MKbU36WjrpK3MqrLD&4c>i9c!?p|u` z9@puQ{=(*#F+=+*deOMPnSFM;GV>-Jm1O z0i-i@hYrytIz_kW7+s@tbl+O~KlB@qH9Vfd)0bA+K+(1Nz zyJb6v%7zY;EfH6al5M?LHugT*+WTa4$BO?=k=;+Zy-NRF`=d-eXZ;<%xAvYL8>7dK z{Y-lQxJLR%=iDm@KhL>dtPhTHkL`rr580$~L>K4;-Jm1O0i-i@hYrytIz_kWxQPGF zt^Z?w_`2I+#LiV?QSUxIsjh}BJj!kAII*#Q_Pfh@T{x99O@8{lk z|0|m`j_3lNpc`~#IRJAt(j7WPm*^DTqGNQ8&e45a>;IVhU)8+8sBC-~r@rG?w^?3a z#smH+BLZbp?4D0{7tTKzTppL@p- zU3_$|ZIxO7)tvi+*7oyrUFW?{ADR9k zIb8ZWHqmJP7uPIKdyjd{$LDI-^hcei+r`J8{-*wu9CGZc>a_uOFHrT_Qax?zW9!># z9*Gzp^G9?~Jvm@b{cF>u_Y{wM&f9XI$28|d=R53FeT|>?x-P(BcRlu|{uBKldgtF< z=kArYu#8*Y{ed>s2DYDipyhA$aF{AUv1_BHqX9z1P{+wX$= ztNh!@CF@&6_iq&c&v772KUldx3;O3eot*2P>S0qKGv8mUv%wAKk;|_0?lhqKdcGYx zcXjW)>3`fYKYYz~-EN1>26jK?wm0>kupjk*>;td69j8{GD`59))Li|h>OFp*HN~m^ zSqm6nE80e%k$$fBG3S4$*K);v7awz4rswf%-){Qv*1PW}*Zgt3*lz9hUwSM&hL?`X z8X?B9_wYFlbyTFgyyxTkU&{j;tS>Ip@3VWncileYn|q%x0qjM-6!Yz)Usatf9*9qJ8#>|z5CWb zRq6T2Z$D%AK{@EkUsOH6DZ1ygZ$$lbT%(rkRmGFtAAZ5cpSPL%0oLx6(Y z&gEmP>rS{KSH~^Q{u^2UM||sPx80x-RW{JMN8inQ?TAL~TaQmUDmsrcd9NdKb&sx& z{{FuTU*q+Skrv@!YXaJ0{-@FLzU8t9U5CzHvaw~1yZ0Sgw^rkvlA>$;raqw2W54dW zn0>D4*skUt&i%*FbVvW-rH#^Kqp>J@z1jMguA9vNY@zz+m{))1iYonM16z>Z5I7&{ZDJm|Hor!w55Min-Ag#isp(3Oy1LN zO8>ZCuaEon#aJJ=D?WB%o9Lc#YodSYiZvUB^Z$weUmMqdME|cfLb>Zda`eyIuSR-n z$=Ba|--~Y0Nx=pWtZ>HlqE{m;A8^*>vH{yFZ$?|IVo89AwjzkD0$)O`onQTNu#JHM=` z*U$OgMd$Q&8Zf!$cein4R_w2}TP?E|D%ES*$Bp!l4q5+$PFergME_a?Z0o;d6Z_rq zPrv?C@3r-xRr-ImiT~f+{Kqjlj8qkmif8T5~i_m2F>_1{_x#+uMV z{onVBJMsrxj{Z4rY@oI`fG_ToTvv|!jqn_OBkn7Oj)yNgQsN-+En*-^)H3>wl&5>h=H6Ci;IdTmSu@@4oB~-vaf|vA^qUf5`Cz z+qms@eO~7Fxn4N>N4C>Fhes?q+Ofu*>(bY*G3EVS&n@yExBmJZ)!Y+*4*TZgZLa%< z`j_sq_1|~vnjW_PTi1BIRoD8<&i{B)=l?wI_WGLFKj(~+i8}T0^?J7*hF8T2_-E}$)OpeP>hs zw_V;7_0JX-`;DE}#0I#Z7rnx06LDMH8=}uwdoEwPWw4FSM|2s?={AJ@As2+J-QxS?KOG$t}Rjbnf~qkAJ+cI^M7jeFI~d)fnV3PJ;gY> zHvLQYyGVAu@oBfGt_icx?a%2P(dTupu=v+!ICu1r?}&fp5l1MW#I~aT<2fK(LJVLW z5OVSH>+0VVoa+&!*PZ0rQqkYrIhr;1;zaiYC(bqdiodg^Y}4HTeRl3g(7$wr&d?n? zM3?9k-J)Z3jn2{i>T93auA7dzKH(gow^p44^m5&EfVL$4qZexN`8xNQdN9ui zbnP`bW8bgo^7A{a*=%34euK{spS#Aw``7jWbpBxd8eq$b0qNN6cFL`;Q@0*XY=HYn;rr9`h`B$PotGtjr#6Ex zY3uqvJ*L{n*m~36pU?f!S(f|7-cM5dqjPk>>Y68hp*qm=LFxkXLw^l`;v8^GjsfWy z9dy+%U5~zls&qPNn!napoZGYdE;%31>%X0w^X^Z#XJp#eGM({86zf2IK-LS$Y@l*YfVi)1xuq^l^8l_n&%7?{blY`Ju0Is~es^7a z`+$pnv_iZ_KADyH76<0kzTYf;-162&LKCtRQVt{f* z>jNZpKz1&8>;)t?5bFWr5khS868F1$yE*KF93bU;+rd*^SFXKKvtEn$44gF2asJ8X z*sr|bsOYzPoZ>jfagFgla({HF`K;%Y&G}aH{;ckkPOa}p-&eXu=jeX>DFN|p%TjIUX_dWOMg8CfYRQ3Ea_G8|!x?eg**V6f)(Y?HPrs2ksIJ|JEXCiDaKdleh-eF63w;Nt$gdG1H;DN`w295VJxptd>GkC4o#zHmU*-Ib8dG(?XFzicj~sSTlD@j-BCYy#l~`T?o)Gr zD~?~>!kO_N^iHma4x-P8dvwJ7o#{UGd(frL_xPG0_ODEJZ$9A4$A-%Xyr`a_)dKj6 z7zYmExBHqrm^1-rSo-~5MG z`Mr%khIB0KarJmHh9(+Q#+ET=tfSu10ezlY-J>&Nc=Y@9`_L^qUM^kN>Yx8*7srto zYF^0t!^DAF8^EuS53r`ht`Dl;&g>xCLa>L-CKB7QV~EGnirayc7i9YHw*3IN^7!lg z__gA1w%D=7@d~JJewQX8=IL*xg@30Y5uFYtEYuN8_NvR~02*v}}o@9`K~dHb%rpVOM3PSSrnH*VKM z+&k`k+>c!=|87ejV;r}*jpND~Gp7shjJ^4L=>nZZpC7qLcj%B_UHM#n|^4>r(m z#nq4hF3$!m9|*kxehYhxcEEapXbboS_7P!!O_ZCEJ0e_@tTkob>EG7*A!FRS)9-E7 z-)ZS%h~s11Fm7=i8PiPXiQXggrx{t4s8_EX$9&LcRLh=Ff z2y#j63tzx*Vh7k>v<23VW0NMqCa{ZCIF8noy|4JKd;2$@ZPnjsjr~u@C_aX(IG&6x zyfN01chh@__2>p2p(}KjaW7rg=KE3CMO)d*DA~Zn*nrOm{2Wn?2iO^X!u{1(WL}v$ zBX0{8doY_YAL0E3`;KrNZ%WfKh~wk88Z(U@V;J?#94=$bSTp8~JvvC4C(kF>Lucmm zr9*UCr006i<1dsC+(k}E?nrG&Ji)$LLx7+0{=lyt#{b|K%pR}_tv8Bx!G2c>$MU9B z#-Mh5f}U**HI`oA-p4aX%Ulj)?|r>z-eSFUgswt=_pY)&zsL^sd2+%JQa6|{(09`( z6Zb(ra^{*LMxocV4OQX3dcO7XAQV!&)-@j`s`RH?V(Z7r{1IbI!ik6^`%! zf;1Qh#tI#?PB)Gt{uX^R#*8&%&e)@aMDMSnBXreV{g!>d<%a4V%MSi%aUt4*Y7A_U zeIoZ@|Ds*6)*L%!-`|wRW58J1n1wO)y7u~JjLGZJIdiz^09{D$CpI_7E35Oo_vyEY z3)A)6$FYt;`|%6;g-0bD6n|`8vG&o{mur9RJ`>qCTz6W>V%ML3bL-E;%*H2-S6rXX zI5MV;Eo01BhqW8Wp#yZ0r=v2@X)ff=zc)wV%@KHW1l}BhH%H*j5%@ng0xuojew*bo=5E@?b(drziqZjUiVLE0Yz9l(w5s%XFk$n)R~VimK-fPLvq{bvmSjw@_We> zk{3sR^&c;e$&<77d?I7de(c4%a*keqQ{EhdA{%I6KdG(R;~bmBR?TL;?P9|ZVAH|2 zv2oe@BR$)axwic6QD;2TMY2wEmd4>18jn{sMlOmtcbS~6#}YB^bRfL@i*l?Wj$fM zo=(S~_qeN;C-i?EIbW~6DQ}KJkqy+d9eb_X-s;(Am5-2LsPzfaAHae!0UMr?jqU@s zHpk8VejQIQ$#Ih37cp|Mrp-B+oVBKIZc|%zNG|tXK10(dh&+ zKHU9>;BbzU(%BE^gD$#plv3kMsVI&u?Yh)OPH# zj=#v>n#7w*Tr%H~_=MCSqh%A@{C71X`hMrl^j3TKyY7=`RG%V zI9@&G-i9X1&YH-@dM=Zv^|-uD(tF!hp3?6l>3)R&b*%oiWXp3UWTN;_-QXS#}$OJq-l@{C?9mdTes z<62a-ACtqr_^tTJ_ATKTZZ4_$|6;LfJ|I3H|7TlAjPd04_`hwR5TAN2ljMKC^P=Q` zdz}8Cel9$=&m@oI|LOkmTlRlEj>g-{Sn0hQ7yd7lme!fRubz$g*Xr0<;^!*)+?Zd*i-{`RG#v z>lx=6L+GIavzO`hX37-3ze;2iQ*!0$CeKg4RJMv_HjDihh`5+sC}Qv8L^2*>^6?-% zPXCY3KbE{l&t1s>LF{pSE^K+OjAXwXe8>hHW^uCdYq?#)R>T<5Dzs z(J#cY4&$D$ryBj$>Not~TsyJ%*YQ71d`0jLS?(bF_Ble4FR0`MxqiU+315dbn9E~v zb3dp3*hxO=!7S#7TtD{oV!cz#{e)OcN3_k6 z^Yt9UYv=zxY{PT>-$cUu?D?F}T}3@rY^27wqvz(@Mtpyst=V(_H!^=x<0G;hQ2wB^Il$e)X`eYNCES61Vvy-djG5s%z_8skAEKG_bjwYG>UE7qy zzlq62&ikvID4AgL7dPQtV|&Y#=_$<9&E{-b})wyyj^uh$Bn(Q{wr`GU{K-w9iO z+oX2CY+tp%=OO+WvSZ`8vg5=rF%Dr&F4Q)TlWo1fU_2+wKiZb@jbeI`4x&D^t6W62CLftN8ZgKkdrr+%!FJ zTOLbN?x&gVD$Gxn-m66RF*T7Xmqp&OCCMd^XJU4DNwhy~^3hBtneED!FZ5hby5MiJ z>&P=U{}=Hb1&+lIa?T%3s(JjqIQ)NZ{8Ce-=?%^i#rOT<&F31Tjg^#vYz9Tqni_xz52 z?{u;6*YA+;*VOr0uCG3RoTsy1sr9#FFD1nKEbsQr8}AwGjDH;Se}>1}2G*xt8Fa)p zK9>HbWjciYlzC!;w}WEVWk0ef#Ow;rvA0ZMT(*ggW=zX=Wy^?X+S|Cjz(^n3Q(VL#ZPQ?y?a_S5#4ebzB> zEMrgAF`b6!80CM)$u~uR!dQ$y)B6uUPK=fJ8x!O+ysyxBD&Lr>TqF95N%E=a!28<2 zOFu}^6FLj}GhNDWXTCi12O(cbeZu962dTXTJHnnaiME#7VD>n*%@~h@KftDyFPJ~5 z@df#QKs^GRSB!na#0RLC4s(@y;1P0x(>I3?P`+_)WIsROuZj6teV@m@&+V(354^*@ zNy51K;e_=o(aX~n-AH%Sq(fxt6h&jCQ~j|OurO+NI55#6H~CC!1o2REn_^` zTov2IXwS6g8m1pIu~=y=dydWiVc8h=jEp|{XW|EDJzJj1AGw{rAo=_QZl}-v(2e-q z{cgnZ|K>(~_6L&hyWyWf?sLOG{XLUmpZbm)_DSSkH}n(VPUKr|=*NS6>>fRqeC%$M zA=(y+y(hkxZI$TzlHcGr{cr2{KlNR|PquH`KkcjSGy8u0{W_i>`eWj_bbKRE_^})L z#h>_NKT*C4KN9@Mm@mn9eEFAdZ1fxQ8RJg>jpVm(y!@p175{C%lyN7wm~gh_9Q?x{ zGarnP@V){6Ai3~w-anw*>r>14m@n?>gT}tS#rrhY`&uhw-Fzuy$=Jm)ea20AmrF|G4V&@jLY!{FePDzpZ^3gnZy@wqHAH|7>5i&+NM$gN}t`8uGDk z`eXdWw;acd4;dbO2mWou@juWQ{hRrVkzaVg#*Hz=M~;@SWNgQr@^g*#f7qChJ@r4m z4y23mUy*;1Zg!TAc2+KdZ}5KM_gpy<3E72gWU72ZW;e1U zY{_gY+Ly(fiXW)hB{ur3*(uv;S4G>6wj6zd-)6ob$qB0bK4CnGk+}B zEzT3$@!#-{{?Oy2Ca^vQ9bY8Y#rfn5$QuOYQ1K*>FWwOi7d=}fpNZI<(k1OVW^qX#oF)b#H=iA(lFcTSuU1Jso z#pY4hxPC`o?fM;YmFsu-6|V1LmrE{lecyAb>vQNOl8arRLoRYVy!*n6yz2tDgJk=I z&ku5*wvu-u=VsFT9p|`ONnfu#4xi;a_|A8oZ{N>v#NTBf`W&Ktv3d4ANjiZikOSwCx**MGNw&@gna9$FaFs3 z2l?F5r^r7<-*DQm$IEC#-A%>Yh$YNRI2dD{5#6hkf2=fKz1EL>j zS`Xy-fTLT|2Pm&tFZN$&ZDMWCUt!kJ9lgOiejRlto4ldrh# z-g3I@c_4DC>v@1=|1X_K)2|4yz&KfzVlfRxe381U=tH%84J_Yxg5J=Vy&<@owP z`b!_<8ArGeKGwF3v3xLc8UC0!?_>N_m^bbt^VEO%cjCL4H{Rv@;r-0O`|0qmT2r=R zdF4qzHJdTksachade&9n%Fc#;GRAUpbLHjYe9#BTez`+U)L-y1o>b>GWNxAk9e-PV7;B71($b<5;<*LBYz zdwkY)ZMGzz*Y|WYNxnb)Zg=g2N!Ta$uZQ-t$37>@&z$7_4t_+w$^3=V_C&*9ZuSZIc_=M4_ zCGh8CR7Z@Je;=oOZro}ADc}EVvx%LR^AQt>4fq3#7x)6j4vQnI8Sn*DqaRRyInD9{ z*557C0x#Z%D}DffklJ}#ANV}j`vEZ$c%eT){G5b{r>rkd_dL{^mBuw zHpK^sea_SW_qetPA4A`vkbT8|*09=IxVSzm%&W)w)hymytY63?&l@k_ZmIWV?Mp6oe4TQQvYeWs7yvU!Ww zFfJx~h;JBy6=QoZcutrW%U$;nhsf@qsmN}hc3mZ1Og`nh>{=_I)N_ff`-JP#TuDFQ zpAXZG2KbUyV!DTm-dmhkPKFN1??asTxxIWhHC~d}kC%_f z*BkTX^vVmfeExIf^VI7hzLUp)H01HtYoo^o?~3iRwHVjQTdn?1ShqZ#cn;^vi?_8{ z?&Elc^AlV*I1h2UDlUr~&$QUim<}AT(^k@19A~oj5zK2~Z-CW`N%O9IRkbfSe z9AQW02<8uzuaO@N`vm^r+o~778|sCBlP&yExq<2hasz4w)qma>{7P{{wF16CafBSw z=LNralS7SQHb_n&nb%o_Del!PR-7Mml5)QK zojg6nb7DF9`0lcM7>MyZvO$c^V;rW|rp)s{+{bNO`+&F~>9*!^>K8c1ET4#Z1o=aL z&JcY<4{9KK7$HxHy$1RWF-O=zzPQgJ7pmsEME%Fhy< zSe|FTKsGV*^Y{YQ2`BzoHNsC7FMcLJ@C(_|f6AVI?IxHXcu0QWcgimxmhH(8$Ofle z@FyROE+!v{en7RsW!?{vw|YO2)CSS+v#qZS{CuKkq&g3vjt+hRAJAlO!1o06)(F9{ zSZ>xiLwY~w@c!1$y`jG`r%=<=zZ3V;?@q^) z-^0D;pp1Lf^2}8+Z}owcd;0G5+|_TVKNo9vdUBS}hnhX+^0LkDd;2`z$9L7`F@J}7 z>|4@h*BIM92U#qSoEz8h6B%l2zRUc6y03Zr9$$~IX{+Nke`mfR^#j2dn4cs^p!cA@ z1APXo9ei)W`kUqp)PGdIg&!a{*gnk*Ll%3D~t?bPEfQje)kHsEhkoN(9Hv60w`~YzaA29v$$AV4E z4=A>o$nIyvTp;rSJ|{?hfYk%k0@e?x^#Q&X$a;dT84l|M;@SY~1t@LL17Gx{V*=ZzQzgP$@pEWoC=?M@n1Ez z$K=F*Ky84)iUoL{x!Ycd6$od9Habq*RMn3@x(3P%VSCK199tfgBpKe{ebl zy|R<q4(FJ`aUEjElTn_$}+ z|FI_^2C8a-dOm=27g#f!Fe z<87x^A95Y%AM83z-p#e&X`X90V4Q2$Ye%8HV*KwF@b%_^ef<>_)kAYJ~YJssTx<$zkF@v zKgNFJUpd;T>fL-vIorvq_p{iqd7#gz|NANRfj^;I-}t{>{A=wAIlt;d;sW(zKjr&< znU_`_>Fa!Y_{_hnC(RsP$oIF+`u1s!Pp>}4{m`GU;U7ECq>BBNjmE4KZ;9o``j9EE z-L`$pab1@GdhhGlMSfv~>o9te>p1fOhu^6m|BH@?V@}2+)&!XkNb&&V-}eYS|J8Yb zty>6r0KEbFGU$zZU$Nrgtd)SzHwfI29KKz?xYXwptAYZ_mI(h+?1EfA6rw*v(0Cm>}ihZut`CMG* zlg{;#_j5jit?#jZpZ7z4eqZd%H^sQ0t>FpBVBG7tW?ucQj*a7cT95GoPiZXhg~110 zi4TyUw3;dA|MH_3E2qM*UZ`FRxt7M;;y*c<;{OEcW9QSW`5y!S(%;C>iT}?A{y$0l zr`HGn%KdHbo^`U~|0waVK40JWMEhZ7KKVu(1&`kb2t^TmZ zVB+yM-Fj_4-s|}SUTfdMwcBBs>o9hy>$LcYX83}Q=bv>Cz7EiO1La{&_?N%V_w%VN)F*VwmW9sFbWFyO_r4#o&Y`|SsMVGtPO%y zYV{^{0N3Ia<3%}uUeh_fiv6`cKYbtHoAvwjJC(Ta^AhVf_;HCAgtL_-%mNfFmeFv_p_#+^*gL-XU)5O0JVSC>t`)3>+!T+M>VCbZF@_| z0TgSp9KhDT#5uj_1455KjsJCPe^_W5Cyn{(`?&UlCc15ulb6ol8!_98uTwXW8+2Om z?%ZRl9A^psTD0N+lIXFY&pG(Y(Mn=A(; z77!D#3+w|s@$CPba>xf{NB=H+deH0&`|`10`M>OL(z(A=EPB}N(X;<2%U7o<_b2wx zxLoXC@sGfMun7s=ny1~YYs7)cvwAH4uX)a72HWTZwDt9XUmI`dwFe)NtrN_v z15~%Cy}-~1$URqB>~np7?p0!Ie4E66a(;2o`U8J15Ba`gzQoRx4(CAnyhXk%`mk_3 z#=ae&Kh9a#vgOz{2J!*;0UMXh7mx>#H{nC+rBw2ODe|-C12p#dfJv&ud>-I^Kw1Zk zkq$?HL2JM)51;-^2o}3A8Ykkcgs3kt>Ljg zfY#>89&J5d%mu<+U-g`R%{-sw0I?pf@ZV|Sp|1U~8E%_S-L?wmi~LgN3zn#_*u=k8 za-i57Y1048^8V`nUtDA8*9d5BA$5OX-_Hkzyx-;nFSfjHfY=`>A3sR7e-`(}{xJ1| zsSB|SpZDMA^M2)z)REMa*c17skNdy1-XC^n>?`h1x#&+mKUIvvPO(?)mY6?NF@NS& zkGolB*H4*vMoB06M0$wJPAu$};ZK)C=SKVWnI$@)F>1zAo|;|tb&%ypc$w`o^>@M?yo_flKsohuYE=$<|6|c4`SuIAc2{g*FNuNh@%0~tk*9)lh0T$N!0P%liqu8IF$4l*D?0fE~YhTzeW1oG+ zcU||q*!D7;$2zXr*FPUbkL`b+d(O?djIq0+Rem6=34W-$PWiy+LtjAk-f-1@!#*D71dmf+fVx0)#q^1- zE}%CUeSu<1<_q4z`d-%X>)aP|0{Vki8-%=oxj}qESpVvK1grz{Hg5hvak1lsHEtW_ z%|-0Ip`O=#M8}<1yDqzY*w#D7v7mQib139bHT8Xu{lt7W&qt46JwD6vSs$!eFXmYv z4D)>tztrkDWBz^W^Tj$}dZo`tu5W$5PZRHz>wiw%D=t{BPp>cIUcJ7Q`*T$5pQm2m z`45}DO}*%k;{MNOhs1mAl6-$A+$-iA^U7&0rbXt>zMnOFpCh}UeLeR7Pd6uQXWtO` zxb6jU05hH+Sejve;Q7o4m>&o}02ZkO?D_#|9Z;MDR9z=P?03^TA)E6XD?c$#>wL$n zc8EQ{iJD*Z^ZfMui2XkIAnqIYVt>Xp&nw>JtF(oC9Ro5Ox&8$==Y}Bi0dsVmbF`hS zEi&f@jRAr$2>t+{FvtAlQ{H!)AC)gvE;aMYf4G^9H+dHMR`3PWq?4&xPN4iuzF^W< z)u)v&m>^y5tejxHa)NQ1&l!8N)_GAI$QO)KuXm(+K0C=5j8G4FIC+8Qg@I|*T)R#^w14edejht^bsfhob=`LTg!#xUr;qU+-eY{XdHpb_r@4K2 zx1Ro?7ulQ*eVYMCUFGw8)p0vg+Y{$)ZqN7jN65#c-;rW|lxjirKIV%*bYsQ*I5Cf1 zU?12C_A<$0y_mOHFXm-e*cZ%CzeMr=(!ZMhVTah`tg9X~+a%u44sjm)H9M9q&yBVn zY<;e_b8n3H4;yfx?Ts&r0nZHVM2==%`-1Tm8H?P(pq)D$&lO@$Ky!02OTXTFfnph^ zVcX{bk31#jv-1M($#dy>|CsYV#h+7EgK$_aO( zA0)fM9}H8zI8=24{$R%sX#I%d%0R^z?+<)_(C;vvvnHEt;uDxdq%WnpDeBa&^A2+D zdhF0LOttGEPW!r!JB)Un2F-9?Ml5q(N3Us7=`w1S!$)-LKhbsAZfNicCD#%(>NUy_ zbe_D{^;C?v8a`t^&fl?)C$8;{IX!(m<@7d>2k#-TPk4_t{YdF?lydvgit%GKA2e1z zf1K)i^uF_{V*Ye7FMF7HmS-M2nIh(~8)IH}ggwFh4B40Qt~ig)%~qVBtsH;0@>J~7 z+oW*Q)`s=-Fv%jm%Piy2|t?E?pa*-^*g>7AB-;^`ccJp)oq^jSjT_2 z65mfGzW*r1_Xo}2C=tHr#1j7tc8Fa@8;vo{>=)i|dfsf>+jg{dZDs#nHh3;>_FGsnc5d2W+vo>oi!I9s5+7i7 zK*#}LGg}v6Ie_Nu$N|JM`8;eB<6#}{d3iF;%&`_C~Uw`_3pZ+Xeh{~B8f+pqcm7wEB%G+fF~2~bptWEpD^HMJS>1qNQ2jXac=?6TsCH0K zarh@Sw?Hp}eBmQH7gct;<1yE|9@EyjZQ8ZpXinO7+0J$BJ6`d9X`Ap~*DuHib>4B7 za)ZHI53p&zp!1-yuKznuuV&n8cJ=6OeqMFE#(L!E#JPGnqfby=SKc=EB*k^G!|Hy5jr!|0CA_pYr)XSWZ9vl0TVUU?13t*~^vit{4yRW>4as zcym3hE52iQ!3ND1Z<0;I`OQd(W6^$ZksTwlYwSDPd&)rN@k_=E%)kx|MV?@5R`3Bc ztRHB-z+_E;*d>35WxpQ4*8s2%^YE{_zo%+~SI5dPFz4s%{>SAvo@g5T zZCx+(`@ZgvHNW{JYL=L@1on-4V;|1FEV%V07iHnCFFPduzu;E+0m(w7#wRS$_*Eq4 z3Ha52nnZsvFZct~QOFPGs9u(G0I>pX1H zmdAWijS+o8Ppv&xZL(2$LHqV@yLtO6*Sg!r(Ql?r&$-2^#RBMw0`G&owKhT0LEb*<^%hS$p^B&UpU9d*ZthDiu3e+S{nRco=U03e`^5YOh>mMP;CRNzcb|ihki= z@(q$2f3QG4cLBcFaxL!@=BNHS^9%Cd>LVcNxZ)S6=e%E-MGPPo$VTuB(Kk#dUdT60 zlW&-6zTtQB59$#qXPBJ%2i1~_JEJ~!tLr{`&PLgPyH4F*C-v;8yX(f?A_ljR=evwt zsovwx8{IGHwEZAA{HTj;JSUQ~E0&X+G2T;@tKplcDsO{vbTVDKnJ)hw<2m}X{9U?) zaeTh#{4wc0;T(Ig9Nx$Fc{c>!Q`Qw{urIT-TRiL7pxGk!h{V`sTW`DAZxh?TUAB&x z&A(zS7!wu?#R;sCDv|k*R@=;;6Wg}ec@K6USTH7HJ`Dfl z%aQ-Y2UuS)<3G#^P={MDFysKt&&M1<4AaB29KhBDhZ?~1f3)~NgL+_`<_0YHPx(*# zeo5|c{D;_Y{eGL@qsL!~{hoh+4Cc=w|7q+G+%pb~Z-3Q`xL=%!p1&gzdw=kqag6Qz za(qJK7tmXkZ^(QCb%fVkY5OSgV`2wB>0GlC*J3}4V%z> z?uqvUr*1U&-N)|gwwt)O+kWbSZrh#r-01HqVz(uqXAW{>{6M#%6WpXz?zbEbe_X{k z^__I$^K~D~(V0oi*=u6CXIz{U%dv+L)3K9W&dEcA_?V8(g_vY4d%HB=u~}@|Y&W&% zVB@m&81t%qK&Xd}f7JoTf2adu4q&}?a)8iti#b5bKj#TX{jY$%y42 zaNXn!T9Vh+`Y!SuzqX+KJYxGUJ=~}x&oQnmV=o;9eMBAkZP1(8UMRLR-KP51W9-3f zA+Zg!5zE`7{dl`tESt*Wc@^V{Ef(5sV#gNiDtT|@p-Bz^|1k$3rw;Q1)j5D_aIpxJ zu$k5XcFiC$49hSL+s1$B0T}ydJ^Js|{^RwW<^J%`oS*WBDK_V)b9t3dOxJaLXC%2l zzd2hy$T?c00RPPI&r^LeKd`?*ISVz+Lgg_F<$2Ky z%sSU=@_w%W?1PQ21u*qlCL{}l(j1@gVdb;5V5 zqxd-bd%vydxuSFIf#+enBAMOP*iehuD7GGaK*oWXFh3ADff?Ab-dU`r@d5PL#G1ui z*4Bx^3jgu}^yay)xYYofv!@RjYXGrrIY8(EjD`KP9(~y7{?)a=#eRKus`7}G|C!1& zEcU~{vHybY54nFe|9;=?I5PH$&8^ITT|ZLo52B7Uy;u2#XctXwCi;k3=l#ZYS6gdHy@yy zx`2OJ%zQwM|I7m<{7(|oRs&cMAmjguac4jJ-1u|;5&Hh(|3cm0{$kxDSJ(5Ls%!d8 zQ!l~i{#=_t=O^m?9?w2&_jJ#L*yWULJI_RC-u?=hh_? zK6Zm^-;7$Hb@Z&ak9N+s*Q9+t^9^$PGVBkUe^}Lbr@yncJ?^s8ie}{k9lG{#6F+&& zR%b(I^X7vR-()o^`LXB4Vy5yMUk7-uY`q}sXvLhb1IPiW#qj~m%V~bj?x~>~KuFR z_o&ZTwq8}t=X{#TV2^RTTW&vM*#}DJ^^N!+x$-#2_r~9Nqik7QTz35s`amyRTO5h@ zpVb_Ze^?2105Pvg*fUu;|w>jy75qFMEPBktqt^a|c6 z%-0?Vtq;UEOb+}{)n}~lr|%%2n5plar8$P#$}#3B*YLT&=YPKS{gwMi{>l9<{}1ew z&&a1`HJWn&r6yZX-rpSdSqI;B^e#3ZKWxeSS}fK_=Hr$;qO1A`wcKpX|I8b1iFpKT z2s^NrxY2op;q}3L9a6RNlGB;jw3eWj|GDCSp2dI9zh~da|3xAGFJ?YgzAGL_7XP=R z*gsKy{!+cZcJ17N$?G=@_c8YOoUm6u|BB=NXTPgSuYtM69^>ox3CR`W_v1TQYuHxt zzUX&54_l~fA(uP1VypB4IsC(t$7*|6zV-%l$q7 zlQb_d`JyM>6wMP%y;S^b-e9`w2iTvfYkAMsb$sXOx_)WyPwZcy>vpg|3vbaHIb(l= zxPM99BQMLJN$x<1_mVrkELYyY{Oen;O#jmNOR?XsLnk+I>OL7ak)PJw4w`ppE|>5+ zbV+f)Vc3#m95q1^TdW^U_nY;Gy{GJ7`2M2rY3=7(FI0Bz@St4|*`n>t7_b^Ruo2>; zF+<^xn);{(K+_W?fsrZoVJ!Ya&K4q!b1*70dQuh@ohSU3L9rS|{F2CMz+ z@b7c~M*RDITcq>$w|4&LUG$Lav|Z!1J+MD`Ry8vzKdtc?CcBT@tqGI;X1=3I%+LFM z<{^ss#DCO&hT5UejJFkjrs%s``+3$*x9{4!R9|q2dV*VWtRWW0xJZojy>TBq^ZBO_ zKn_sMKg`zSALe0Sy}!V}@BK|xpRkhq`}m*M{*~Nc=gwLD_rA#be)3I=t?%b!eREK)v|F8bIs!Vhs@H048ak&-4G- zh6%<$Ie~J2)d$u5lS8QQr=H>*t@o$Cn5(r0^K`z?eDxg`sPDf}YZ4c!C%H)Tlg7T* zEH6>rzf|iOO;pbq_v&*jN67n4UUMtHzU4`u*}5igqq!#4`>m1l!``rkhi6jDB6AAq zd|#jG2Px*~^P0zS`drc60e!{ved%NR14S&h)$`5q0Xx6{(k;^Fmf!hWg$praeR1*t z<^uvpFtu20c^@D@z+9WygF#q?N!Wx@ScO^Gt?B`Ye;D`tYb~JIpK$KuivNoJS|2<` z=LvcK(XlIU}O1*VOXA~a{*u*#$g@ijeYSyDeym4uT9hWLeur$8G-*I~?%cD#>pO0x8?kiL<{DW)RNG4+FUaFQeQrx! zBTzOE;Cz9(=lpVuu{-R4h2nq41v#=wg&$agDcFKBSc5s(gF#q?N!Wx@SS9|$F8sqX zOv5&e!#~VVB=(;t{=>RIi~aD=ydV6>d4GME@vk|C`KmK~?l1l|2SFaPn7TjmZ@GT~ z{~7!80b3CJi?98M>(WQpu5FO_6N6I@%03=4_h8qf|5(jkx9oj1=t1-vHq#AXT%5Bv z+DAKYI9Wru?aobmfVJOIc0B>>ckLSCx`t`{9s_jUpB=QGcUzs~*Uhm$n*Z${CEUAU z;B;LNVZ|oZ7x;iO>xH}aAMO@i^|vj?2Us1Pu#w9@^8n@p0{>#p*8t+5H8|!2#6N3u zBLATWX#CRyfd8}yAokSk8+}ukhXQ&+j2s{1f}tqgcwEpTuIn z;y$&1tohByY0htjiDLgZwhZaNaG!?kcinzyvukbQea}IY8h&>pztiY-YJ@&xmNk3- zBGtj|`%zxe>MY5ZFcK=D8FpSKRc_W+Im$)Wc*P5e*ST7enz z732-G6#r-IJLcx_zfk-yQv4?mS)zR*FIlR6TL$}*^b6t83a`Y7<*Uj0cb$z`aVEUceHAi$EAI@{+ z`lT PvB2uMyV^EX#g;A9+WaH9~{e9p2{lhyD8+IB-#w2ZY+0Iy!I#V^(L2IbQ>) z2Or`wu{rV&v#<-pRs)D>*oJX>fG|(&N9yrEN9Pm2QTbnV#h+Zq9=+<@taA3|%<)r` zckes0{&(io8SQn=`|bPncf-d`a3d#7wk`ih7Rqinc0Cd~J=Yq8A=VG3oY#BYd+h4c zYjMgRL+$&xUTEhb^P1%c$V1Ak6~_O!bqp%vpV(==vyJ2*b{p|OsSf|MWH5TEqP{cI30jKk9Lt_ZoRW>j`>KIiTTZ@pGG_ zwyF4nc6LuvYWx`I8*RC!a^>^+*BNc!sjHj&)t|MkEm|)u=Ed5^9H1osi>SrP0mNpd z2dFuF@ejjA@gMe)Dar+=DkmT}n4uhDrgDW@%Kvlu*II+f|6=9;OG5s?RQdlh4~@p7 zxv$&x6Pu9>aLu(wztL^bD7XCPXWP^sBNuEVFR)|vGqrT!3dUf~YHoV(^xz}^Vl$6_ zScYlXhH+Sj`HX*^_d8W_rcRIaPK(o({AN{2f3Y8^H2jdV%1*PeH7E{ zDmBUjI&3?z;r9+)a=@0yzu3w67gP9vjDM}Ohdmfv#5p*`fB4UO03rU1VdGy+&)|A~ z@GsV8G(9(6=Lql~__x@v&(77k1oOoIeDUvd{}=4{7V9^c=(m?@AC_ug zJo}3O#{SD8?!V$z=@=sStH1H8#@Nd)cfID?N_N`sqYdq$|Acj=xFHrciu;r1E|lG0 zS32Hb``sTK^A+0jAH6D{@TpII%605m=la?7FJ`~3)Ul*KAn!5kmzl#HIB=jl>69#g?2?e!=7V2Z?wJmn?G=We(cG7*y}ud_uY59ZMQA9Z{{yX zEb-^|*B(RJ|I4u7w{Kr}#u;b04I4Hz+1tN9{*?RH&wf+d7rb40LBAb`6pn4o6FT%B zUd{(FC(z)2q^u3XKH4HKwI%;kL;Rm1-!N10e^!Y9bLBhc$%o9BFIk}Yzfitq(Ty*d zze(f&vLycFr&c0X_gCWoYSlIAF}B4R^PBw}^!$kBtif-@#mE&O)Vkc_Yu1zd9`X4v zmty}*H-6Lo;8*|cUVr`dCft;L;{N;Zuj>O?f7Ixhie4vwXs7$|MdtFh`|i81d*X>F z8t(3fmtS%B|N4JQ`2l*L)CP^}f{uO0l=1qxI*mc={f3Kms z7LDGYC)@Vg-hD{5ZKHV4>*U6N{6}MM8iJ)a-~+nK@8s~8(x&r6Nb(I=g0bE8Ga#q+E)EK>`xHmTnC@Y<+@KD*g%GjhQ; z@&Y?nKNCv>|1bt?7IUe+#UL!!;~$n`I`R+eFh7OdzfJhx{Osdv@a^?<&$|3F=hN*t zv$+3G+&}7s(@WX)S8xB0d-A#GtGL+Ie=fiL^1@?eZnDhrrGB7$pAm)MN6kU)u_=GQ z`omw{X}8?daJ)Ww!8NufqELUz?K=;h-`EFetx}^k!ki~G|LmV_Rv)m7=EI^7*qr=N zz3}l3({xRc>6bjI`zb%AJmG2c6&Cxi*1Z*#LoB%NpUNwqcZ<|tT&x_!$Nm=;`xXB! z_HVG*zw&mir_{B6Rv{MmUvay9T@vE{n!8@rm?E#awcp&lGW|1OE41TiQ-h}O*DyyW z@2@wHNevHnm&gK64N)@%PA6&)Rr2%9lQO z#VvJx0M`U6vp%59utg1f0X;`fmF>Q?+3eKk!k&-F3+$|x_#A+mn%dgu*~@jmQlA5; z2Y<7A@#Fwv6GmYbW?^@p7`7Tf@gKHf9M)kT_W!T&k3MT{IQ^eEm&U!K$DF^HelC5y zeD4EGu}{2f>A0VA_{=lUIC}8uzQxD%0?Xt8^b6~)U%vY4tJ9y{% zgSC`@ScFN~gi%<9S=fbPVtFn9FmJiPYJkZ9Ecu2Q|L5s5jrdF`4IbGu-{vL%ZrNr;@{Zc;8w{et(I?MKXgu;_?5A&*XCJKVExVSVb-bJNk99b#$;sRAK4Vwp<^VhCy8lJ%8P~60zgc#l zbr4tH`#?hlxEA#4o1bh|dtImaANh#9M1CxmiYfB}(i+^KZ{9E2n?l1mB zUbF6-;@?E<-`)DM+_^_SM~ipgr=gt^t60<97Jo+{eRS>^6rJ1D zZ|60+?`O<@@rz$t!lGAzwmrS zUSJ1-C1NUUt=2V5d=Aine=*yTf3ZJJG9$$Q+42o@V(HpG&EdNt~avn>WTyt*=oJ^ucJ)&3*>PSyl0KIdnxX0tvQ_IyAHvhmzfdX%IP9}0=jvx0 z-7l0LUnw8Jx}Yxg&uOL?*jh2Gt@xiVA23tCV3vFWzF}^N{|n?Z7Rq-lk`GxdU$R6s z1-@l@i2o}T|5qyhuTuP9Enl>Ye9{{ECSw0uMDc$ev0t*Q@_%GE#eXlax!o22TT>># z@7w~L@IJn4@4;2JpK?(9xG48O=!2gq#XoD@+VXGZ%9XieQG1P$0lKbvt&imY-o1Ob zYR|vk*xdf3|0p%aMSTF`dMW;u1K2f#YHEnu@tFScYg@%`cT+zs@)3E7{J;`SSzb+! zO|32FU=Idi(Q@(-|6vtoVHbvBnfMReFb?Z55BtXdC4v9T1OHb&W1m@gt@yt#;osPo z53t-{{NF16E%&eC|Lbkff3Gq1=lnRIt(Nn=|C#fzwE_O;`aP^iYZU*#eAC@c&fTwP z@2&CLamO8(dkmbzkRJ1PgY(x&z3pvpYmMD1^_|pBjmDVQcYmkmEOXf9{y=5<=Y1Wv ztAEa6cU>!F-5oEqxDRN^znH4x|8`$@!{Caq`Fec$&CJcK2N?MmyD)70i)rIuj2r)A z9`jUw$Lyf9Z|ShuZ%I^EWH?o2yd(E%qz^8~ZQ&*nbzXUlQZ~-HQJv ziv9Pro-8@{=ef2J?Su1K%B+Edje%44%Ka{`#Z|^GZ~DQ5rR=;l-*oZC7v~;BkA9=8 z`0u=J{`Cf#M{LVKu6xvItXUHj^;^AF4bY71igRDVZB*-5e@As+V8VO8+~W4@>x#ff z?30O|b%=84weW8~!1vi!2mWCY7JUxj`*W~r@jvoU4Xn4&;2)q++XXZwU6r%%lke5F|XNO?0b35?IHeKOLp4p*t+`Le&m8G zyH8_a?c?4f=H!0Y>I2@<&?d3j|9JS%ZHbQkHtY2B?3wEY$K%Bx7S;X_Km2f;9s_Hp z8u8ETTst-IIJvh#b8>)=eTvr?^Zi^icI_=swy6F3TG;aud9m0T_=hR;0XjFCI(rxK z?`wd3{$Un&Vc2?r;vcqQ9M*~Xk^fnG%yV-S{(bFV%|EsO3gs9pmH)2_@jvB%t@f>! z|J}6z9MA5^X5fGKyIyjg8{E6M-rASQL);c!%lF+M|3WF7{KwPJwJAIN_(Kmpl*{>k5}tGA+g@5n*zw&-46}F{EInX126~2TpT?B*5;@O0RLhZb{C0Z<6lg}HjKkM%+C<}ngW}|XEv1dmir7C)X*034_x1->>oM$(xppte=qI>=iDE9=%J;qvz7jC8UDHM zQT&~Bd&Ch(q+iu$kIP;wh-)vU`yU^78MUg358&QHtP$$eZ$j?<#yStq@BPH@BnMb| z+3#A!miN5p^~{$z;Xcf0kRxGeSo9}fZ4PLAg04Ma{#a&<^bPN z{4Z#b`)@mNLTUE#2X-D@!hO^`_va}S|L=bA*QI#5`R1GJUbid$ZrlzTGQ?{7QeUn& zm8t*fiN^0wx5poUeA%C=df%^q{cFc($z7H$TV}#F0?$7CZ1?D+k5;|6%s*TQz08;w z^#HjiSZxi!wL-ShwZ!A`a{UmlAJBQwOc(t{`yTmoBJndrSHE+s=6{yrzxDp)6X*{t zkdIg>U$IzqLst9Cm#k1bwdPd>nHr1BbEB;45A}^62Sc+U(A3&^Gzl}9_Vh|Q#5;kEJR*C&<@!z#?v98Gd^VYi;vELH$zY+gjr>E%ryeeBP@BwgE=C92B ze@pOB9#gc|IPZA4mO$CLMb=Q3iT^W}uFB=Ph<~mfoVRbyd2aC11GirOFL`3aoG|xi zwf|L5yG0@XFIE3=nfeIJ)la~utdeh8Eg$1!|GyObecx}LdXl@!C+(*Azk7`R@>zQl z`z7m%{gS;D|Gm8K_E!9FNm+Kzzt`1c*>inTf6&_TpFUr6>@4rSoZr*vujqHu^?%$y zJn#F<*8l9s#^f=hMvW@f&nU}3*J8*!j-u-Wms#_h_kFd`EkEz)n`F;>DgH-3A}^7j zJ(xp7#1@Rf8qE0|K>c_6@ZhGiT^OYKx|tNKy!dFuQ|XCNE80A@%jH! z^$#=tE%z7y>NDo@Z@Itt5Bs{uH^sl^`;eH|?DZ}2ZzA@;-LkUtyS|XC_o%1l_WkR{ zf3EdaCKffi*3YKI{&-x})Q$c)cQ3v_-KOjRH>Ll-sd-G9>k5?Rf8o0IxyM>`zcA|j zvk5_S zzq$E;nR&jVeXf0e=~)kKv=7MRA9nBouoQEE$Un@%9yxdx{{#Ql14#IXWtfI-7>9LY zKJ2IbTklWrS)A~{TscI_|1SECHP-v{`G4f!=l(C-ezLE7YM+gL?SIT`_Ezlo^19nc z@xP^H&pV#eHEW93Y&Yjzzcl~nar;i)a@qO9Rkti2lIbNJ~8cwZ0!0!t~1yYc}$~ojLKdUY}%sy>ogVB|L|Yto*-rP(09txjkalD z3wu5yFOeTuvY2W$fUmP_`G-l^B>qSKVV4*V|1b^z)&s2Jf3AGNd_Bi&ivs^k^_gY* zY~~79_|62Z8BcG@HV@^4{ zA^%+GyXddpwfXXXj~t%<8gu#N4yT@aYIcopo-6ue4leKex@=cj`_D1gTmN5go}tjc zH-Gx8hT~06#@uZD&UD*(*up0Be{nvr)4=@m9@Ed4eZ2V8?{1V2 zXv9BESq`B5AJ$+F_FxbeBmb+#zx4nV|6vz~VHy5m8^&QB=6&pcV#8dm2b!;SLDUC} zuJ-YNsn!h{|2O{At-R^^(EAJg>-W~)F8;L!2|u)(?vt>)_Gu68TgJY8)?UPZ$=>Sw zA^Rx)dwJdMtN7niGWNia=IT7^EX{Lk`EK-o&mHsaX`jQ7EoG07Kl{&Ivxeoke~q@R z{mc6!?$bl3{x13(KYo1f@8tQ!qVxaARf_(&4?x_1)+I34&zi;fTywVdj-$-=0O7xI z{g3AQBk#4_&O`IpJ~U_F<9o>gHpZ^^Q9nHL5qXLHtQSk<0OkY47_7mZ&jFZ&XD;5y z|HwbgE*HDTzgRZ@#kTbT#5&B+xs=}D6C36Q{;l@cdzM`LjQWPp%6~kk+&}Oyzp~5M zUXY)8F~t6V$^UFHKeRjiYrpomOZ;m;+28edi~oDb{l$OC`}g^__%{*z_qLquuygT! zy=>l3=e9NCyy$g$WKp;2cE-|`rT8y8|F39GPWl@>X8laPzk0F1UTn_0-$9YDW6fdF zA9)NteAXDGe`VGI)E;Zmv2Z=mGWQ58T>sm?Qz84&7u37{-*zJ=y6wl-zn(;TEb~8i zYqRa!*TSBU$V=o0mZA@UF<65+p95@A4&d`~*o0B50mMJ-!Z0kuG_l=!0Ic(G!2hxu z{_!jI`1i5@WzW9&-%Ilev)EQ^_cbjsomr~-jwTZQB&uAXGh%!Fze!h7;#OI3cf6H~}8qEW64O{MYoA-Cd z8D|vQP_(C_n3(r{>2okybT44;VHS@q-Ev-Z{N37ZqyBvQ+v#K0_tbt@-v9M{%mcr9 zxZyaX2kyU?_uXaA|LxE-zt6+>5&vsr)xP(}y~5me1OU*e}^v`9HFs;=h;I-Tv~YEg_Q+JtLX-vHvC8r;LAc|INfdxmm8A(|@j+<0`WGM$ZqL zaX{{Ga1FpR*8w>1&hI&D*t|dZuD52EK7VunsJ)BU;x#%4s^~mG_OV`nuHHV<6D-sb zdXf~~TY&4QlwtqFXI@~{U1o5k~ruRhSM_c!D}_<)T6Z_sn6 z2f!R0b8+ecr2LE7jDN9g{EKZr2cY_2%*XgYUym0C{+H-I%dUIIEf4&!y6K;~_lf6! z?X52;_P-c%|9>g}*kFEWPwk6m-^YK?{ws?4#Qs+^zqbFquW3w>*WCf%X&LEOXU%_? zo&yWxTqEYw*O?pRzPWie%r$4q*yk^Q|Cd5UIOo6Ue!Vsm}p?o(*$82T%`Q{QDX}y?HT8{D)cCCH})QOv5((!#d1w?fkF* z+GBO?YP%uRTZDi3D7x=AIY60vfN*c?4KKe^WahR8o*X!@W}iBBYU%TRIlngAZ0)vD z?2mqc>w?yPmj78t*xVcd--rmetM=bVxyrusS^E+DCHt%HM-EWz_wu?sQ1O3LW$_p9 zsB2r?%PQLRrf#X3^R5MijZB)mu%V4&!}mPcxR!t7i6n`IqKOJ5V1I7^LCG!~t=?bqzFsFwrqTg+Y5 z`(w>8wFos0YXDfsL{7t6!bYFvdY>2F_5FrpNlsNX=f_xd9y-5S{I}OSfub=SzVdCG zY_Ij~{XoV4$VcQQ^0S{9M3 zhy7gsuTS{D`JeV(#{X^N|Mmj@js1lGZ;AhJllzPRkk=ge9r14>_P@L7(p&2+iuA== z*2ry3Zu^a2UHF^*b{tY_K7d}plg~Y051-PnQ7|FlE<~lK&@h^5W{>5|={|n^{7Kix1Og>^o;D5Dz$1Z{Yb@C~@>brN>Z|tFZ zV^8^<^@{&{sSep&z6igxul8+U)hYO^{k6{rz`i8TBBp z<6DJ)d`VGmjGZ*c2mJN%rwRxt_cUv38m%8-P2a})Kl%klJr9nR_};8(kVUDcmyx`~q%G3g^4dl9Z8}mnf zU36YQ`+%g^_bED-M$h*dyP|NM=>>2eQ%n7^PO4F_pV#U4bMNJNoV8od=S|~!*~cAs z7*+V4Jq8SaL-M~sHNc_}|Ch=)ED!O2m3#)iV~u>sTKSUy-`<%3$#I?ceSpO-?)$zM z;C#yf^Pv6tKGrQYhJ@!oRbWhLg_xtYmnlfd5 z4E?_YGHPcB=>H|351;d!bgj=Q4!nO?H9-M+a*jtnBY<(~IOF-@AN@RbOn~_}<^;TB z-us^Gon;mO=sRq3;P+7ma1LNO|5zKvwUXoX6+bh3>8il%>Cvlita=|mnGjY3*c&x{ zVfwq=zeVYPGDWtc^gkITt7Mk!l3}t;{ZF>ZIQ2i7C;Rgr0{>rw{r~WrDnGFFQP}_A zyad1DZEMxz;QtBm|DE4k>lpic8utHpVgJM4*z_#y|L?*6hwZ=hIoSWOOLm|px@h}< z2)m!Q|3|jX|1tVc+Er`s%jLD%XZ}2J43LG1cQ>cDd%dg&y&n-03lJV}oPMWu{tMA@ zL5}MuUj2o|XI=T#3NmKK`2tZopWmA$`~2-(J1MCCNq*-armPKO9E9tn#9^O$pSf1~ z&eClUi);4#u^ne0*9a>;XEC2r?wAcbUds>7hxp0DPs0zjKTWpC7+E88ItIWTJah4k z0WvoaKV8KDnX^ak9t@LZGEKHs4iK!9d9pv>=6@0PEkS;epIMI2t~B^xYxBPW=iZ3# z(7ykB@IS8DzW@75E(!k)%J*+y{%_hI{)|s^ZJQu|v)DiUM*sC@%yGmR6~}Fy`9kF2 z&z}6D#pmAt;vfEx^|ycb_bTTehkJe}YkacO`)2=8o^md=`MbQYxkgFYS|O&5z*?wR z{>R_Ps_$W+u*PcQ4dHVo_}tDooCkfTn)xSF!oRiwbli;$ZU+B427uVS%|DqH{>d_# zCfj73tdoDTAI1L~$dDxb(@x>F?t;wPP2G>S2XQ~Pz0m)|CiGy%nz>n@6~%i zyX$_F4P^&}_yQ&;%vE#k0InZ$@{j+_RXfOBHtX2=Y|+(w4qCJwSYK!!ANJaBO%L-r z%Y8i_bE%?a0Oiz|zx?IE+&*KTKlsJ}j5VKMYy$dG%&&(1_L_m?%3_}~p?37N(C=vY z{ySxj*|71x7x8f6LwFH>$P$@SJ^=K8T>i-}^?wxq3n2>@+xmYQ@`R4>kNhFeu@16i zJ!}dc`@d{$hOMy$amTHYJ=tMwsxwim^Y%KYV}2{xG*_BhI}Ed4|oXIn?~~8h9JdtMTRXTJOOl0`FDaI`<^wKF(*E7vOp$ z-f`2O@0sUJv$k=Z-xKs1%7CCX5xl>Z{H|+ki5&x>O|-J1$>K8>z31|KpB4L*5z+kr zbJ^oIXx#66>6*ib@FM(>B{D^}oH!usZNT1E*4``r5eER9WR$FuSrr2W!(>^-02TkJ z17Hjg%+G)5w^xw+yTW*&;vaK_87JgtRqT(kf7|zGZBfzpXWn0Ye{GLAaX*`V#xBH; z(YB3g?}Pn|>D!(kycaq)hEBP=Lv&#fAAHt8RJ_b@EGOAlH*l228oi)vXz%^34Paei zl56IgNmH;sC)Z72-5%%cam)97ZeNs*@BOZtp;I!^`(htN^8Xn4FJs(>9lH5sSf z_>Ve2V;FTgCYorWlK-Z%&^iZG51v{|IXcY#Of7FXyeME!SA$HD<~9 z{@)JSvjcv}PRODL#Qk?cHtmM~-ve2-2Qo|Pe#oyz`2B26(Eqw!v-U&(r)>-W^<%zc zL&nR5IZai`37KUrKGziH+64WEPk{|RO4$gs6WID<-W~JzL+a;Pqwm-hx>i>;$pFeZ zK0~Y)Ym3T#$a34G_du(5+^lxtUSvTO|J$Jd(~jAwQssG7-XXJm*ncy`pIOgKcbFU_Ty2`as z4p46Og>2*cYvsv+9#&7p_S>8LZq5JKetU)afThR_=-B@y#0%es-vIrO{K5Jse{XF- zO(Eloo1cOHN3DU*`(1(jdEeIk(Err^%=tUIANn8p{(WfT_cvXH{#OmU|HtXu^n?D- zw2`sa9`!F>h0l)s9n4E`4Ho7oYM{U6{)BBg2cNloKChQ+@(7z9v5l(#X?p3yvc_%L znAh0CV7B%@@N%#vL)OqR*?3e*6Rak6gb z0FnDE^1oc={{8viWb?lj-=S@PH~-4^$F|FmuPgMHnuSqH#>+IHin zfVFL*`&pmTkz+jnu6twm_k?+^YMnjmbFwC_Zrp4&S3k}=o$VumkM z5we8m+ydF+<-Y+kXcuIWm;ZgZW~KYvf&c5)1kZn=51lhv%49XzMC0cj?NEK5R8~|g z|76L_Kba$Yw82gO$tYPRv(*1&nEIbglWpOj%#-~f{@3Cd9=ieO@bbSM@rE6cIXm&) z!vAjABzqv6_Co*fgRJ5;H-h~pHtK$~1JM7vU9%2C|EFzZW-Jc0C9_)dx2wsJ2@8&6 zUciNl%EmEs4^=h)Ve^0c4jYqtyv7;l2M`YzKFErS1yXmSDP2mNn!Ys{BWuDx86=Bj zlDgUCpX`!hvfN$xXZ*aYv75#38GH9(Yto|A744f5vl=@s{{zOM2m>bOe zz$(}XYaV}F$&B^i(fWTAY>CatD{O^ru?;dt^nU|n&o0;?yJ3s$flS&9+2rVc=zr?| z{cP0zXa}MHb-QLYL;t631IPQXPtCXz*RBrYh0g&_yB1c^IXlaK^3PVu>m4$!p{n_3 z+%YINIsB$ssmE)aaeff`U-%#^WQOdJp+@@BY{~|JoekE=9N8m-qW{Sz86~S^minIz zQ~#4`vaNG~sP(7)5BAykx`h8H-ciT$9Gftw(Bc1k;2-wJj_0nx_6PsCj@>^1|Fr#I zH28lB{J%{0(QLc_;E%z-YGD7B^o_DO=spb`d%N!#XRTUozhNpzT}cKi_1$ED_?`QF z`=+C=Y2d9}eEIKp(|X_iN&WY7KOeUKAAQbp#%$EF+DFiQ&<{{?a|Fo^&$l!IZgZLjZNzd)d zVoj`$;w8)PA^!t!+gefn``)ZlW$7#<+{`=gprd`$siE~Z$OEHHZbL_lr;H{f2#wNY{EAc*T z{r_8cob8hQFY(d;YauJv+xmZ#t^c|9} zU2|}{Ykh#^-p0>A=IWm~>}K(qAjZedJ5n|Lhduvi_L0w5lz%eir~kO38pCA(ypER*Tg-_rGcWSz_}0sBkQmgDtG>{Gcvd}bX!y8*{+ z#Ic)kjx9Ksiv8i-JHfxU{jWg&yszRA`@p}_{kXRMj_&_RU4JvKpK|RGn_~Z}lB0*g zf7%wt|L_}@s4?ZW`^{ra8PO5!Rl|2oh94xlZt~)euLBr#`!?tMc^!lAD6Usl4f?-! z?467au`o9G>0A*bqnHcmL;n;6W{)6m(`8?O*XfMX9`Mmva+Mqb&HqLdjUYNPL z`X%RLeLm=%rtLw#c~0}QDmUSi8|X+`z-I=@`0#G~Bi|e}7PH!~V+6L1?4$q5lvn?g zJu*lZ$t3kZ86~S^minIzQ~#4`vaMo(0s7zMe)rhXrA%jS|C=Xw4-m2rvu}R@6Pg>VKeqPoY5Z-y6$oJ9I^V|u-0N-UKaBPN1*Od@r?R| ziHJjbzqcCde|ppgKVRUM%||QGzbykI`3Iw-|F?i$7yn>e=K$gVgL(S?%g|Qf^(yec z2KN6t^8du!N@i?+3i==C*alld+5R~9uIJvfZT~BfKkq9!)cE2DTKB&M{qN}hk08T7 zhTcbm-apLt6Wu5ikGz_`nX)tvqncUS(o?w;RROuBE%vh$go zC+YX5`8;cXOukGTfWH3F>ARf2XQlgjUfL40J%X;;{9g0=I_h=Z#Ct;dU;S^N>9YJU z_tF0wAS*V(XQ1rZ3K_E9*8dHL{@)9kvk&^e5q?OMq5ls;|2He!-(UZ?!Um`Y{ZF}` z#d9+l8=JWBWZ>8i8uOLdPg&(T zm9Pa?8}`5Oza@bGJ%~5@@qZB4Cj1|Q%|hG%FdKePE1P2fs&xdm&QaL^X>&an4+T*Z-!z&dRP~95IZ2UOQ`&+MDsP^VbXso=@7V?|{_fG|BiT z6T$~sQT{U6Awy(I_$OmJ2H@tOOw#`M@=u1n{F8Mu-`)8iIPQ*2bllMC4OS&;YLaj- zpB+B47y}Gqg0*_``Ht9fUQ*Dtbj1F!d4HpBo!hnfe+2sfQRx3~zGdhBFIgL5D{Ox9 z9pwIghd2W4|7YH{b|R**>-(3j-HsId<3pV21=(rmh-1h_4;xPtb^UoN7@DGL+|6sbi@n2Kd z$C}aj$>u@n4VYWF8}&un_D9^`vHi6@;>7(hU$F%> zON{%em>+BzW$zm?zhkdj*72XFZ*lefJtrTq4t)1Fq4zhd^*~11YuHFUJqbfm@v$W5 ziu2i^dOODbvZ(ioa}DyDO0NkTR`*N&arBjs${MS2$2pmB;)P&E#RC~Lr!T-bAnRzs zmc#+I4}e-g#|J+D(S;+yAWfcPi+v~WtKWhNMJlXH6{EwTt*tvHjv36sa z%$U5O{53J?Gt+iuJUvP5oSz+?QLasxirOk4z$fMwmZOh4XWG9HnYJ^~7U>9IphxfE z=QEF)HorsIr;Nz?k8clzvCO~KB4@Mj+rM(|-JI6Xh4MfA#$}na8_RKLh#{JNa!`3+gnU}Uj@xSmBUv!e%7REpAe!p`Mo)G-Z0G=-kAHd9I zDL(*fUIvYQS@WV_%(=Kh=P74D*WeJgDzPTOgas#@@0aW7$Zgp3emEwYzyF5sSn?ZR z12W2^&^G0Zr-Uu=(hkMe<^qy3-c{8@h1%)M12cj>n#p!8iw zYp z25E*ZatJc11+uAV`+p1@hPMAz+vbPe5BbJMd*~$ef7%wL|7rIJopaY$!+n6d{v$Hs z(5ut@VgcqnT*kk%WIE}&Si4xMH32I*?&}GCWMdUwx2Bg9AOQO z_yDY}18ZcC?9u)wi)4~)?g67J2Vm=eGEA1qbX@)48TqH(AJzXuCfyV$?#s254XZWf;<|71h?0Ji;4cIX4p{wGuPt;rbe ze=h2barJobk;y zam)Rl&U$<$*Zhg9`JatgaoVw&_Bb*je2^6t1EB7t46ykpTV#x^k$W=R7(yA$jx{=qVt z-h??oWSp#%`Bh+_Es+0bp#Oz`*cFldW1f<(`=RX*{g3%fY&zx-{r@xFXfK`mdHN>I zF8}mHiO+NF;uWjU;1QwsKdU&Px5mahj?HIal*?0RI=&-(|K9aWoII?z-+T5Q8hHPy zQ%=14QQ~n`&UogrWJ355KS1~)OHK{|j79PfR;jZU|6rK9Jc$3*;D0S-!FtF9)(35d zjMxfUv7P!K$2Nff-8dKX3i}{inxOx+@Bcph53T=OAd3z|Cbi<)injm9uwiKXUsZO^ zN!b1;!9N>i;A#Bkw2l1J?oWIC%sp*^_n+q;F#6`q^m3S;%NpFy#BEmB%Jqf4OlJMQ zX3zwy_oM|S-_v`_Qr!FCn%|pN?@K+d(vC+SM<#?1vZ7>w&CfCL@Av>G6?<{=Kl7ioo0as|zc9|Vz2!4e zw*T@^eWhY!l1vC6WJSdQY<|cRnIc>zTPj<<0TK~VR z^UwP&vXNhH14@7Pl3ovVgyJPL2`3yqgGOMjy_iO!LGjOcKf6u(v*O)*9^abY zp0!q=>sG-J2#@>I_OGNpn(P0{_yY^iJ{ZbBZGb5mb1E{RyYU~i?x2_BH1BmypMPGj zZu}f8s^+JXwm;=grTAa-*qc|@ed{gM1z*y&|4+V+dck*4H}pH?4}Xu`|GU;6toyBV z|L-BsctzzKn_qk%{>KL@57~+}iI1Qzk!vLuegBW)!_fD?>i9LMe-7UtjlcKoUsp#v z_QOk7Z{!pG?0?ypbsRwX0^P9gKWyFMG|ZdF)C>r=<9ZF5Vuh{q$8|oBJpV>T$E1=0 zHXjlP5PnX)s^e)Y1^~v$8ku7a02w5Ux(0x?`MOSr%#vL)OqR*?7O<`70N^>lV4m!E zcm64d=C=G{DF0dK0y>k;p4GLQYa^N5X7Rdi!rajNSAY*7vfOVwb3f za`&;Grw8h^{J4(0Z`$^g6=y%U|0`$vi~i?!(Yf$k0LRq$yY_V|8Nj+j)*Yl}c@kFk%XtpvvhH_$&Cn@jvCsRt`>+06&VM(K|C{`u{^>{7;PKamj;Soy2T03glHs&{TyTO!W=JOE3cuw-Ss5<_z zdnbQmz3<`g{U+x>=f7kO&?l5}60{vSZd#|Y0nEBP#sf?~y|0CR^2oJIynj#fUgi9K zo->++b?;|Y9dATFKj@yB`=`ubUvl3?{#Rm~=l`q62jKm`ZDUKM3>Y`7eBU?;Pia3Z zK7g+GKq0S=Q@(L_M>EoYSWtFmghu3}DWmvEEAP z`JnI2^?!Bgf8M91_kB5Z9C5r2nUvi+K~W5s^LOvF_RQxF(oT1+#|xXi+-DMxpLaCV zxF6T?h|2YkxM8~DI?8sNvFmJAvCpxV^Iv`ZQ%8)sEuyv@YXx?OngGr<^xE8G?`~1g zAL@70de`5wSeMYWH@x4Q=6%h;aiOx9c7MZH{#tR(dR{-9U-s?&+TY~-=ktGJjRB68 zD4(*k_yMx+fbhrozPy$#ZT2L2LO+`%>ovY=$4n39nOxtwx6QeqtmWjKKH=Tm(nbif z!7I5x*ZzOc2(h5szpBr~6HEay$TRcrc0#QRyZ z<*nhLc$fcko>=24_qCd~IsetmKgU+oT7i@aWAALJY8epqOftV`l_!-!S?BzE_6uIK zOXTqOFI_BQdP&TnWIO;CLg`NuzB;`4j&)z1I;s>6RZ z=KRg;&Gmohkp-+VlW`cdt=3q8`RvVd=k}R$AS>NpJMz}Zz8ybvajg11)^A7+XEo;h zbN)LI^X9$cYpxd`#J=qBJ8W_$F*TF3a$hsQM;)6b`&sG!x(RoqPs4qF@_gvKzmC-X za=-XI-)hbI%QbSF>;KLr3pjT)>e(Tb1Jza^%x95iW%G+H%0l-u&mUFa%l=Fn!&{B# z`BrPrKj*)5F>l^4zTW!hFGl7BIc7)Qwk{JNTX?IcZ6>-O&*$N@dc|%E+NSa0xwdn) z=KRg^laijJkPNET7+Gsx!UL`R|IgaZFj4bO}f_xV7udmwq_8mT@Y&#yr00&f3BB2L_Fwo|=C?i*(@F+fyHJGF;BVMQ)9<}`= z*}s12_AWV2{A`mm_On0vd|dPSpJb?F&;NX;yyyRRH~x8FlpWWeg&VSe8pW~JF zfrBSp7i|YX28@}$EfL2^MA*x5oUeR_}P16%K*v?^3OK%=9RIJOT)W)4A%>d z((!(OkF$Osf6HA5KV4RTcV;`G68w{Wwzc1U)7tR(Th^v0-nO8e|F7ceuKZYyYSDky6N9N8*83G5*bi8V3Z>RhEBP=-T5DJ zXJcaBuj+ex)Hv5EGRwQ=^A@Y^c^n-nV_f`$k#h2XWON@`-Shp+*6#1UYf*=n#{Wb3 z|BhS#@4`8FE}k>zKfTSu=S@YeA4o3Z$^fo6EFAUdS!1y_IF8=GYR&E zpIsleFE0CB!>c>x`TXQcd+|?pUHpS>+W55f1NFbb|4zt`MEw6a*Z+R^SN1JB`=GILYaoXgx%}xDJcFC}#|NZ!X)b#%^SzB!Ww?F+mb*%8eH;(?twJ9IK zYybcBsJ{4M7{y^SAt z{Kl05QS||Q?vN=1`V5^I$oAmLcd5?~PVl@!74u85p0CpTG1zB3RG!rpx6iur=Q@&q zGVa*_2LJ2f6Yy`Fz54%I?f)zN|NMJaQ$YN$_2P$0Hs$(1p8Vjv7L(n;*QgH|5s>5K zJOb}=V`h}r5)8j_sq;Dd4RQ27Ka=D+K1tZ`j`clZ@+&F-WX;e1C!396)Y1Q7m-fHt zf3i)+$-46Yz5IV$^S>3gf@A*&@PE(~|Ihi4$GtfYnD6%T8}#09-tXw!H{ZvPl0wjDIq%_y^-j z`QQEhca=<`Y|;AvidE$Q1M4ti5xk}&x&NPdY{&Km5HA}vVWx}iN%N1m*cQ%ZUIA;1 z=|jkV<_zQLeibLYWm7D_zitAaj~v71&)E;w4@vYt86#_CuH~fVN$8zaRgsYv_*kKXGha%78fa0pyr5d|69u;MnN(vqUb?Ux?y= z;=+^h^!|9n6Jyl&VM%v zI3Y7S|EF1U^gna|w*61`gnu$gHpwViRkeR$mkcwOx7Eu(nD_F(0ro%ZgZSBPI3|pL zRRe7DA5a4{cr1k;h&#% z<^b9HU)2CB{h!YPh`Oic{+;T;^WH7%d|$M&7g@n`{31kpUQpj%fDm$d-#u0`xia;r>OtQ zJ{#r%s(7HD16-^Dr2TKs0Z=hO%rDAofU+M4e&dL>@qF%uAJ0kmF<0p2UfvI%xi`?~ z=d-wb_Akyg4EtXCEqQHEvau0|fARfU`|Hj9OYOhP{ew+1YS#XeVc*(cFz@jHsODeQ z07?$fQv>A60je6nbU8rA0g5pIZU6X<{d}JuN1PisbCg7$^H4){wV%eJo3gnm;<2nzl(pw0L&Ud z#uJtPkIDfUH9*lhfbO*pKw6o`x$$@IZA&c!IOosHJ>O4R`ia0bJ?bXSkM%rG%7T0@ zPcrUh9Jq9USnSW9`(x(*CH6=DCHC*+{zGzqM(v+P_R;t9U^s51g%mLVSz=!j7 zKr;6YWt_-%`TbvsT_a%X=%D!nL+;q&tNYcOJu!0o{0`3F?`~`L%Ka#J>*7B_?2oK@ z=lur7{(Wch-#~j!@gJ50z#IbV|Jdt*7&ZW(UEr((! zxXC~31ibox^qgj2_InM#0d_`oevjwp8prwk{cLnU=fvpi<_V99&{pSb|8TwpE((#X0QyUvF4Z>|aE_4$+d`poTb_>-q{_A_SR z@%wGv@2dIriTnH7{+_(QYt2ur=kHVZOW&XTpF~@z`2U8%zls6)uLa_&0|@c~0_FmE zd-?p`p8ZCK$_>+&;5warzIht?lpmw*H$S~^vhUUX zYR+Fs&A)HnFTnPfHUGr-Uj^1}{ueI$`s)KB13q&309*@9>VWJzfFwSEGau0K0i+fn zo(#xsfjHbS20)wKWYv7#cX++xzkcaCtN%?Kl+VxgI(qc#8+eR)JYVNA{&4>*>OPs= zn>K$W`@Xv0FYg!A_AjpaCAR-ZWZ$x^9?Kqn{g>hca9se(iQ-(K;`0DhEwFbzFxUXH z9*Ao`u-E{G3@~$nW-h>M2Nd&yMLCei21>`_<_Dh-<(O-RaZayVzZ*6DN$h>Hf6KZ9 zd7LkWyJ>G#9tb$ou8-LLEY{rrA&zMoU`2lgcHr)qxf^?su=P?gu+E*I)d8srT14e{S8s z3v+d4y-!*1E6DbT?tj4Ge>HpnWf%C>0=wn|8_xtOsRuTm3nuk|ynf~`WnEyeAE0D_ zQ5WE63rOFwKiy5{PsZDJHF+?8=Hfu6`AneEa}HXyqo*OhAM7KT-19YSi@N*T+-{EJ zj4k)Ll=14?dUU?{`#Rod%=7cu{aokQtoJ);Kj(w>elFdQoWDEnhxNX&mIwWKv*y>1 z`&;0DweY|6>#z5PJ#a~UfMP9>Js%jgK<+hx-8O*vTrk=utW9**1@iF&;>Z9;4jA!4 zSAQC^)h!d;_afQf;@s=%_{@omSFD=4K7st#U>)F^0iy%|?&Y5EC(d4OwLJS9dro?F z{LbVo#<}it#z^tlpz-MJ=h*df&-ZqXUl99dzEAA_;#?o&IX_0u&#U|Ovp)E&ui|`P z!}fm@%=Z@lZ6Dwv@=y7&#-0!Css%FF1aWKtpE*H>4M3a4i3M_PumC$iVuF6Qfaxc( zFP&!a@AP*!+PCd5UQWceAMfVAS&g5xPQLn~GdHt4_Gwwa*%+JVn037_;l5PwJM4Sb z_@&+NulupipGWtbYkfJo->&%~Pn0Ng1nefkbhBkfSxtx1*Yy^!T&;B@L z)714cuBq>IEZn`eUn%>=ct6=^oL%gGbDfVU-EXh;D{+4dtl#6qe+}fqKbdhr9v5T- zNG?F;1+)IB=m!|V1OeNc7xPR1v;GHzw7nJ?v@Yh}5f>*wfwn|))BKVyFC`JP~nu{W|O zYy1{t{>D1rcFvFfyyX1B_-kJFDI;P}9bj*NpGaM;&ih?VrqlmpP`4 z*E0TswngUM+;f~eIXMH{f6Lj(d5)-g(0kH?%vY==eNS_Av zd3V^q<1c@fTKA8*e!8{mp&)t9Ww6a-h7Y0f6lZ4in#!HO`xm~Z2AFeZcwBQuw#NE z0}vB1Z2@Hu_{f4%c_95u*;;;U&#{s9xfh)ILSp`@^JnZnZykNNyS<~NK*PD9Z&Axk%uNm{>I-XMN%Y44%{K&S+y5DPjW+-d` zl?zlg!IBFwY6AHjA$}ii096-EKLE8y^hZKvfSDVVn1ELf*!F<(iO^4!l}cvXHj~-6 z=4+9)-C;XrL9+D#N8U8cYWS;PI{K(P^ig~NMsw_$ug$UQ=y{uY72h*#ec@i^_w8r- zsW?A4iDF-J{cgJ-`99|RWuBiq=6{K7`!Vm`htGY2Hh}U2?0JD^ERgewm|v8dfOs+h zF+n3QzAhnzdGaVx&eb@>Hpfk{jGaW{Hb;H z;`_?}?2Ny)8m`%IY`ONyc*Iupma`@AHuK`+JKQUKU+a8X&r9O`=9+$9z3*ZlYjjAi z->mgfF+Z?NhRHIS_HrKde(Bf#r4}~8|BCVh%veCU43Lm|v#(=)VeC6TKXftK53>8oGMNtI-ETiWKOZ%LS1CVCKS0$4z`tOOQTza2 zN0cwXyajWYPF&Eo1tdSfdO_L)k}Gs<0^2T7F%tBlBM%I@p!!>6gWoplzICF%FFgOH zQ2zT29&RoB^jAyuP$&A0v3YCn-{d!zuusODmva~EHt%j-Z$GnJxQ7iabv-V7AFTNK z`=;I}bK>)xHU28zZ`%D}m@NA-9<>k0aeWZO53tt>XDq;z6AY69%vGxT0K_mv1~_tn zIYKt{g{m9o)|3UdUEq=jlnEZWAo8KaZV)-qMYh*1Z3yK5#?||+1JAxuDkHndZ!eMk z9sIk@G3I(L^!053ca$xBM)dFm^Omb*LI&Px!}1U zU1?w6VWlrUfcP)p3mXl(D`JA zar9X18}UBz`6b>@cFAxM-*NWi_$fFK@&U#9f&3nc2kLbK{AGa74I(#yyny5e+_pfe zJs>p$5+f+F4JZ$6nNYM7ioS#UK4@9dRrc-t`ro;9KXZE1cHe6qeExSzCU%wIS^d95 z#+%K#q1%Od;a%eS9M2rvV&@C@T)R)%`d*!{YWwtjUdGnwUzgbYWZ$UqlUyHJC9`BV z4&zau!Fe|0e8pIRCnsRa0LBE(yZ~hYZI@zxQ0EB!W zYyqQAfHsaP2ee3NfRAAN7y`ZAYCxEGyIrX2PWdy^bLZSkVs2m3nLcRUH( zaX$+g@Y!$~plbwKAK;f8DB1#UpFre*OBTQ$k~o2qm+V6{u@7X+IZ?${w6RL>N$3CD zZ9C3cJ0JZ=mu=J)e`odors9~BaVT4kQPq@=*YkB~-$dpjmkg`tM z1n2|C2P94?u|nxD=|58@P%gM+gDqoCIic=_OJ<1d$hTUC=KT=V59Zi$UYldg(CIQ3 zP1ZS9W&Co>F|C+ax*ltF*=zNc=zHbo>p8qKmq*p~+BN-}eaz{B|4l!f^*Of9@2uyS zl;<>`hYV=bF~MSPkk1fvasw(RApU^P4@g|VD+lQ7C^-Omz<%+{0@ZhheIWg6$_2mI zydSP+%M9m!^5~m+LWJclr2sJ&)<I<^4f6)vB^#~zS4p~!*~dEl`Rq;EwwnEr#@hkWbS zL3w{<(;td&+lF_IL+W;0zf*@%mkIBp=Y@GEpJ(g)BKKnJ>)c+Dy-()s9ABn!{-iPi zGJy2~szyj^g(;s*TfkQiIDUbiOK92zrYtb!fhiMI--@k3*_|w7&P@-lg;Pd>%4K_LB129-qf`)WQb& z_wYlmmf8Y3EAgJCpp%(1L{^K}0#=^$UtNK~WY+tU$>F+fOiM0&@u}pFp`FP5K>MM@HnY^S;P%3@EN;oXNPe z$D$sSdR+{TRn=^}UTk}%=RM2|_bQ(UJD-e@6%Y4ZyW?y%>ii(tfa@KM_BpQ{;O|oL z0Uw({$pXnA8aYJvo0bXMMqq!Mwt~~&((kk#ybX32{jI#^eGqF5c*c+47?XW69`#m_ zRT;C)-HDE89G_!cn0M)V@IW?vxc?kk3gWEV_uF!Sxx&}P9w_<-I+r2-f#eRwN07dv zeWYp%C=-xNP4)b7w zY>*K@cDm9&{6?-TuoR8+30{RP_<;Q&c7fPIN{wj?}5Ar@*c>0An$>^2l5`sdm!(Dya)0g$a^5~fxHLu9>{wj z?}5Ar@*e2qJuu_*b%njI-_WB_R~Ry+Q0P&pFC6PtDD*7U*XwuR#NL|1j2ZU38w!P9 zg(XY$yPKC43blpLe8zs)hiBnGp5^BHUWML;|AcQ^QKNRM|E;K*jcr3=d*J~7zp}6m zuhtee7dGMjTKs<%Ui05ey)IqjdGx>HcCoz&m+1V}-c?wk_B9lm3+Hj3Ov7iU z6=te!p|D1MKYQzf`s^8;^OSM*%W-@w_VKUv_;u%T4JYur1$(Ap`zbX3J6M>A@7;iR zN7Wg4z31?|*_%fT$METb>LK^Odi`mSO4xU z>h~Nj+^c?%dC%hZ_iWYQ?(=wi-P`APt7DepzOv(A?J6div0*`|ELnGi?i}-h2McytbBOt*4vY?l^tC z<^0*Uvqvu6(Q@|myymvk)9#x&wf=PTnd3)V+b%Si--c7w*E=U$d${$?h2t0QcU{r6 z8N8}9&8PA88}DCw?%b*4EzK8jz0;b{otrvcpW(v!d)qFoJ#*x2%Lk;Bu0}3>y6f5(Om{i~A6PJ5 f?hxJ-?|J?zv_6K^>q-|OP30UMIO4Op1m#syiv>gK_Sdd4cw3Mf!r4~eB+7m$KkxtsN zhi$Yoqx19rbY@_1W*mlbI*L#bC2dLzf>0hK9b1xrG z)_$zL_S$Q&{aX9c2{Rm0lq5+8$t;D#l2i>h{j*8ERmYG0>Lh8KMe5RbQ`{$aSL?=q za(89r)S~$%)+NP@pDv#Jto2!EiEMpxp0(Jy$m(2FFt6A;ZT_Ov2Rp|n4*M~(|9{3g z?28gShNVv_zi#s-&*q8R5t`?ATRz!pd`h%d-Ng( ziEQKmr1Yvwb%7;zr&;Rvr zh&*q(jL6_>{19I*d^ZaLk0e4_opRm46hmQ;z4crC-%;h&Z83g*gl5f+Tc&su!M z^Go0e*+;yX8`bZ{2wKT~Z9HhYn z6(Zp@kQg(!M4m9gI%;w8!nunItoDNW^8Ce%tbeyYn4COx5dA)6b+xj+~_Zz&Xf$+Pno$x@5Cs;kdqlbBJ7XW0g3 zGb-Z@$|z%pFa)q{1RGhliPmct ze*XKIx8|qfo-Rse*~67_!%si|11bKSHt4iGu=@ng#r!%^`Yb?vZrl5?jY_!g(jP5FA>h>E{d^O5lV_g0%Gw2jUS6?N` z-;#Df=?aOrjHTzo7)Y6w%OB)Dpf;S|IUHLg8?^SDwJS z8>m3L8gvridh#ffQ7qP2T1%+xV+guI7li_BZH9l~9z~EJc!<@mC)VA2fa^YIP)~Vi^zDif7y$WTNGXqJk%zwU5#kC^edB}I`+9NjUU0te|H^5ism3u9S=i_gQ zct=DycY^=CX}OGh-nU3PX`;K{Q2M2Wxs@o5Malz3Jy2Ow`Efa!T~`(x-TMs6G811( zQh6KsG{nAzU*%46D~}qKp7qg`z2x>;m~ZyubExm2Jlu6BSd06Dg=Zlpt7jG^A(5ei zrzRSh!*r$A=#tgimyByeG9(LZwMk9}eM8(1ki46HcuQVoEgS#$KFe&8V zu4`tOSP-Gyz$Dh>KGWh3B&44*yFZg8i5;pr7o|Ux{^?Q!I~Ryz7uXT^Ig7iwMc;_B z2+oWSYloljHGf?VJQLCd9E$NLVv)F$I9xAP+_;ID5i^yZ? zzLF@`M3T2kQVtMJ4*qKpf*K7L_0b->L=Ejhj9Qc>M%JjGVRG*=Dl<&%bYL0V$)6{F zsnQmdem5xIAT2ebBUf=L4SG*@i0%Ik{}Pg84SYY^Uf_`ff%MD8@$9tw8;i2c7B@wwdr+hw#PwejqM zs`tMd4!2{Q%N_?;XgS>w8rYaOEz;uBA}IYVTWpd%;3kbPLE|jSaw|d{XzW91puzl6 ziSFKqs1uZzn77w^hVF!TC1xt8j?%n+x5xBvPsS&r2V7=gc?M;gK^c*D#Mxt;=u&I% zP7s*RSo3?LquU|+s#T%V@DuSmsd%As&AjD>-bvRyhG94RH~uoTC6EgN_GF@8Oxs_4 zAA5-U7KHWo{D!)}v?Ik)%KoGqNdiL=v4OkITe5m94ZIiXSg9}fIxT;u5?AP{Rl5p? zh1xumVw8!Y6t4(Z?o!4W8^)MKXIx_OjImOsc@lI=j#1Z^v|o9_M0K_#M9C{}mC<9j z3h_^E-xuNl2vI?3paJ>-&B7A!#m>md^ZFr(u=EU?SJ>@KF5B(=tLJx(tzh^-&AHAs zeq%Kv!iSpgRYwZhMLyxkjD6PQz385xQsL?+w`Jq6p(!?)9QR<^fL{QtjX&tI^jDfnw;b{%d9^V@sQI*|E zAtF_&TuVA8_w^W3Z&si-5}EliZdZF9cs04+ zQ_wtiej5(YnBI6~%ykB!Q-P@qSp5`<#u z4(X0)%`%!_px);3ASux3A)(UiLO| z{xZ>M;g4djrEr1A9u2*%Gnai0ZZO604AP~YGrxEmzDPM|-dfJoj^(75HuF-)mZp}p zi)d*hMND8vds#(Z@~TKa%j8T^hE7Uw@)T|cYcr-RyJ~opZdXb;snLBTe0R`O7DZLi zPt<@n*^_HXs$JH}oj9b;z0(l5tFls=Iwa(IUazc34kCzVAvdoHcU zBVzhqM!H4_Y5x@dHX6hX$n1bNq0uXjV7vJGqVga<`I*e-Se({9!c)vZ6k zYQ-d6_{tADqf))J7Sz@ma&Ok18fJQ9u_ZFEPZuF22DjJZyV(`Uv0?xTXz6qEFvs*+ zmEO#fKFZ=WvKhwo8K$MZSPMJl4j9-Sn1Jd}nYWCJ8rY=tLQ_PqovrA|;YE9Ndv)7J zKE6b0`@DwVr5q^z9PPhvjsH$h!f$o8$}ab=Co7yE;8y+xe<2jhB)INcA%^%QZ^561PNxYa)#cRR&B^22f6DXwpaxJUsK)IvR~ zdz|V8a=ploVTQYp??jKmeENDJvs`vQ2Ni^_OOlorq2qKu#d3{o%2~E6{lGE{n{C8@ zeNGGdlk@{6JrI|=TN&4~pbuQ`+Oty}e8UCIm+eOP@)kq!U2v2xZ>3eAvm4x3Y{4sX zoN!##$%a&KAht?3b2e6O_^G74^QN(Dtf@52FYfr6WZ{?>ig%g8bce zXLDH3RIg%h$xS`Te7s1*j!Hewd^6b>gcs>vzPGOIjDl~iKBBEF7sIEmD_g(r7?CF; zoIBl_n}91hdoIwH#kA5vr?eT^>nTb@Fux|+Cf3kp-~}X;)=_Nf@EeanM16z@E3xhr zsLcA6K?H;)wPf|t#1Q6MB-oZ6gp+#Q{fHz#!XH+tJ>-B#QYoipOAU{%X*NP9 zJez8z>>FXvgtMMp4g@|B{kQ)+^oz{Sv4*@N>CEMyt6n}$uw*VjDE!8HSNPEzVK59- z{y66MELa}ahHN`89ZpLavwNLJ%Zv4>VsCY?Y?aI}lcid)W8Pwma`VpV_SO|IP>x!&Yc4wTDu5OAs`Dyb9j#=Xf`%Ork3MB+=SOFUBzU_0 ztohe%C=~>$>J{|QQGGv>m)04uY;j~euOLln-3fHikg%tmB$>K4B`$4~Yyl+?B)JU&1P3P~Ja}5McZpGnO*1)2iknF_9sAjbfEo1xH~u$j6Ui zx=%SeUuLTfrC|xon9GY%%S;$U0>h}yTKMBC#rq-@OH68(G$|CMluaG!&NP%>CyR<~ zy2<5=_gxh@zpq1(CxL&`^E? zu7}rR-CZ7WTxV@c*>82zYC`~nO}^9INiUH z%)h>jXxE2=1!wQ-S1DVnS9XY(iHueDbgmBtHRq&yednxteS8)Z+}eO=6OyafTM<4O zpEV18wP1nw6H(RMi7IWA0DFi=mB{G=SoaT7lfV$6D>leI0t2dd5jt)906i=y1k$P- zDKJJ2Jf{XGLRP>2F3iS+xUn^F!@DQ)-z}Ip$lNbd52D3HRG|7Fz=nkWa z`l+!BZdLi03Q^HslUsOkt4<=DbPHebqe&AOj3JB%RMt zmLiK4hRQw&MH_?aIM6YtebwGpC21t>fX-XK1Y08W3aro0dvm zsi&MU-xmx46>J&6e%}GP{bb z*&-=N?Bu94O6EU553~zA5~C~y0|oP)&su3aVd323r{}5URmy@M$V<658J?grJRYef zDQ{Y;H}%Rk(tcOwjm)r6d&nt4isA=w87@gdy zP{|6xp7W)7O9R_g^O?b88e3XJNX)iyD=S8sj+UWj2S1 zzYrmw!wZP`>GV_1bIQZYQiE7jxHGqd4@vH}j-Z1(fCC#kd0d$rQQOc3{uG*=HXD(9 zX}pSQhJ#yFe41ErD?~+Q#JGA}xO>9i$R$Tz_EqWp(cnA9d)Y@elK61nnSTu*bCCyjT_2Vv{P->LpLB>fP`uLJ0MYZE-M|~>%9mJ^>&$9* zrV)l(NsecqGGDkmdCHDEJM&j4_3NkvDPVS8@3}1AyxC{o{Q4m93K#p7zXQpr_3v(8 z4LiI4?<6Y6l*xRmV1trM(`V#6b-om@ze$rL?VAimydp?r4#)3n&xqdvXX-(vl9FO( zN@Y%KlvCVSt;<%p{l?X?;Y82WA=s?LwpD-kRpY9z*tBzBwXBMvojYx}4jWpqU8Df* zU3}H}cHrBK?*P6N`26@<@l841-!obl^o)-Wp6)-n?Wp^6avNu~Z+)%!_VkDu*#BEK zB&~7TfuxVq8a)YJm+k^9lLZU91Mbg)Ne481F!=5C(<3N<^JZg3ywAMFSg6GN3Yl?@ zEefuRQBlwdgiwHi{02A+8MzA;;bAtt60eNX`>>ZN_8r}I!Kpk8%O5CNCv0S_H=+us z&+zeK2#a_ir<|1I^M6Ni(Pc*CC`CBiK35uPKAU6Sl5Hp~_5b^bY#v+a_D7YN*s<^- z))crS^?0C1X2QERNsi5Ieh;R3145!dcp4ReU4&T7j2@$5Ppu2)=)J{{O zhQiE$A1QvIF!Q}5%aRKFy?dlE^W7s(q=YGmwUl2`or&a>@4(i=bvFa5*WROo%!;HOi>exIc?U6(nINPS@CW zObd3`T2{24^pYL1{NO4_#rUYO`|}%Z$2K&+vg(=>Y<2&~5-D_HN*BIAzs~mh^a$O%RKk2$Y zP=4HXJ&}Hv%QIZp^W|LE^$bqW`Qc7c3q!atak;h zDzT-VT!F5x>(R>^UA}nG-Cfgch*15{jZd6WZB5ftt|$*`eYc+`2&5w^$IHDdCcvZ! zf2M>jEVHK+PNmlUd0&_ej&IEA@t{pQwHvD-`8f(T%O*8^LaG{WkmsTd$2Vr35dndm zwkAPn<(Tgixk^Na{x=bX8{|G6h+GYHIoWjlADxkNz;LqZ=!Ka+@I?Pyup_AdT(BCb z|JFv?REM-HI^w!!)LgbVO`6N$Gi$EI)^4iH_50UvS6$ZaAN5jQ{hzteM|E9|dd(_a zwk=uP?iDV}Uk>y8gloW8Wxv6c3LLdszkGi%xz?uq{qZxC_0gxMH}sVa+e#dUE5=!18~N#PIZdk1h8dX&P;lDmN~AaQUxa%*M%; zY4MNTUiA0JY|^@~_wKu+_RvJz+Oh=O+{x3+rr37C-;be8RlPFo*768p-!$8D!4K5h79_odxW+J1jesol0>acG|HkMA!T`1U_{ z{$alDKY!gH9@}?$?IGLxgg18H{*U**$sF1IlHaxa(QUtbd*p^5U#=dw?)J^yMm>{z zf10OlN%M+P$-6VognvI}%~zvdK6UjE*8{6IOwM}gfd#XAh3-4}LDteUdoLwDP*!^1 z=!5Z<$EEw<`cviT9vg!1SkCOMyEc0In^peUH`iP$uphqM7Wi!3^RMlAS)k+SOT(BYk>+>CSQwirVF+?Yy{Ds|k8C*Zx>oa+ z=$`0b6?@QQ4>=a-7Dz=sAF@eBQK)+U%M;W?J13-ibBivb!VAL51&X!7-bzE6$KLAj z*n^mFBh65x!3x;H#~?|ncgFPT1&XC8h%_S9icp__8G+v9 zjt-`TXzNwc{;^mOV6RF!!j>FP*}bOA$jfhG%1h%2YeJ`gA5!o*T3j^3M~f6Oj)=Hl z!-v3F#6mW1ZxbV${J0MLOb1s*^XK6ZbE4RHb<7x^93ndnb{LNQgFV)i;+{x8S1=feh#wr>|vJYWlK+B))dPXGrFuMj5>Z`sB;_;?TopNo{t3MSmQ^h(w0jV znNv~TX}`yo{=;llV|iHaY~Es?>~4sH+1XLBH$xh=lR zDU)-`4zAFL9jz$`J>wHC1+2HyOPOzM7-@(`ccF|l6)5pDG2r`2t~ebqh}ldSg1Ru{ zyQL0DH=n~q0@~=uDQ{*8PYHq-=0y)*+t-m4`N@o z>?^o%`ozS>CmKrA_Fem?i#$xMybQ%$N{dRHWAcL&bL7^h5j@N6|P$}2B%XB(n0uHzI=0lOmy!T}%s7f6nx zS!tO3V%-5|*^0#ee0_ItTZPOdWi9=(#YXnHq2WWw#aHP?1Lh;3UtnbOH>=j_BOym|NW7sPQrxqypf+1COf~^&aLwVot^DxN(HoyZV zLQV7AiH8Hc4O5d_vv=2FS6b~yY55nh`tKz^_x%?l1D^%hE9%H6L}JwHRql&j?uJo@ z3S@|;lgkzuDc?V0avDBBlq2b|R*SE0qC9?$7BpjO?zB7a_+dFYFeUT%gxOWj9Q-@N9Fi^HmMtd+Mhu3f+bcid z=9%(+fk9Qf0t2dc2kxu-BydmF{=i-E_pUk;xV>s$pj%Z_pi9-UKz!9v>`HtL+jH2w z*~_Mwc=5$>cy_G;WAQERN&zbol{Q184GzBiuxJeOF9|WkA0k5;s*JSwo{XDXJPVC0 zT{Os?1eVoPzVl{Nyav5dn$*U40dAIK;$5h*b~aFB-7QCj4^ZQ*K8oBKPCsBN`wqH4 zY#&12=#}lQ1uVV*M-q*w%oC_grO3Fx?ugpgryN{IPV~rqfR(ljyLl3DeJsv>H7py` zbk1*K!q-tfK&RI2QgJ7;JNLrHmK$io&^a?QVJJVos{3P#8YiDNVCahqe_DQgbs#cP z2qgH6p~3v0s9gRgs+b4x1Krg2dZ^EjWHOlz$2J2Nm-Z0l;%v_){rajNG!6`H%2M-E z^GUzH+TS6cc*@64`3$9e+-g1;3@RIjBsbny+P_dNmja0Z%hV_FG z%eO-4_0dD&l=yVe^PxMKmd7%BdgPu4HpakiXNI1-WBdy<2BUi8BxhjG>&x=D68KJtDyA%v|V-8Cc{uskq|2aSUrN2`o}P& zpLnkidx$I{tlr&hHg9$sm^<+HLa3NZlFJ6o$+HFm}ytW-)D%;~d z+2VxovOeKuRyJ%a?0VAWzdSx?cdd!$LX%yYqp7s=v_k9wzY9ae5odxs(+Zcgv{N-L zx5M3&@w-40O1|K(A}YdyZ+Y{1K38TUjTp|`FoFeAHzq-&LVOldD7E=h zaPEfZV|Q~#egOMhqk=C|-Z(CWTszP@79buG6Hhc&{Rn0iVWQuGy)n_@_Qt!LZ#ejB z1kNaI7#(#3EyQb_fdh~Ywjd@U5_D6X<)y+X`;{QCg8-DPN&|!*M~6)K2Pg&(sc}eI zNhfUZ5O>xi$G7iVA+XS1agMWyr6LresOsuwD=dKH}i|7%tOL=8=9O`y0=mZ}3 zEYg*J7mme7TK_znc~JkkEsXZd*CKz~9a~}c&=KDTwujF~P+$-{sXq?yAwCAu&cg;R zlEAk_!(U08(G-0@qLH~pl0+R(Q9j>F1?4?}IKx+&vKvyod&-D-xyOicI=SnJaZz%o z5##i7w7b?2;G;&3QVz^WI^d`BivFAM2Tv(XkC&~5=|Jv*UxVBQzcG}?7&z;$jZ*)M zln4C&P&Wq>e4$fpd858)#N|!FQ*8>Pc$1BLb^IF9R`DFag-Rc zM($(C4s0&lh9-m7DAew`5X%ect}VGQZJ*qO4~>E@wXlgHcAM@Rk4I%wJ@Gpc%=F6D z0QZl>(H)^bPZ6ahppnp?Qr@6E#i1NZ z3A6F9CScGsr5T+@Wj`Ak8W)I4@oJ%+^dmz{9#7lvj7kZQbDjg`9+)aWXQTK1ny5?vzf_omj0Us(5LTA=jazX? z+Od^=lMa>dUePP<=<2RIny(vq5i$vMO*t6&LOB`;h@g2GP-mijY3pIMSN>-Z6n#)K zG-%?A0crbI-d7%8bx+d8wEe5-WbRenC6A#8zarQ{B~A$?UE^d^po-G8DJ2YpXExJ= zt9#wcgF5G(ZjN&+aSo-KKZpIjd^#YY#{t}WEMEfsaSrWI;6!NsWTdYUeQ6i9FLg}ef8RsBCuE}apOmRd?LRSYAyV|19LxbHWp~b+aXM0Y zkK8q$t>_wqp?(akk*u5Arte2VXvAOrmC{57LK=6b1^qZoFyZdx@Kss(A5aFL`>JFv zYX-hUE48ve<=~o_HF>&>c)4FjC;1l{CV6s3XL(je7kO!h*<4lz%nK)@4h0Y|wc>_N8F`8K+}YyT+ig zb%81XB^IT634IyVh+B~_@syKSS{FnZPOiORk(>jIX!lFZURV~U>38o&RNcEeKAbwO z7KO|<&KN`~Sr(RMDXpVTKGZPvBN)r??2o!d^RcFvV1kfdVw9uPOH9sAuq*uzys}`x z$nL-qi)MC%HIQZ?9cu{~^Z4>zh;A`&z6<8_XxH^w&huj9fNXT7bsN#Akb2|>)ss6o zI#X0P7ITC(NQE;p?v*W)oKwaDf724i2w|{>f%STyEt5oUe&ub%QHafvr>4>S9QkWLX2uOfGjPG75%U7cHBb|;m7RyE}^(3cH50yC0_&B5gk z>6gH5(>Jj;DrmWb`23!*#sC8cl2ChOt9)i&@uGPPQy&~suy7#?AU!%y9=~|e(~h}v z(ZspW&KpT#q7IwE9y%9$NUM@F#4gOWJL<8DuwQ^NHRveng`41*`}Q1 zjoJPy7V7BYht$}6I>rudPy4=zHJ8)slNL%}kBcnF8tgn8fu3?=VjBsDzX}<7>>T#o z3&NhO#-Rp-kWYIyH{*+@A|DZ(r^Xtn5cT#;$V#*Qwjw`)kq8W*|05Wt1K)_!lO}2z z@V1>;6hwRMmmLfA{2)9I{uX{yued%W?x1aFz^ZHIWyu-uT6qEfL+z|PcnwhLpa`Mr zn*zGWTN-sw^TP_h*L&Hmd4SE6SV0i-`#s^dd}6A+of|w}3L1 z3)Jvi(_O~3tr6c#*E^E#!Fv0*8nypUW%ypIvzXkX^T0+SX%yBr+J(_}`}g?8Pt9F8 z4~HUtAWpN5cR(RqceN3?yl*oIcOQg42^;eHShm8Y_Eoqe$1=%_sm$H%QA7GpXYY07 zXOh6$M(HsvzIqy!Hkh48UvfW7#pL@A40J$FKnE71=p$$c2`xr+ZAZoQR^3|&Qm17P z3BuT4aIXwXavG^(j|mY~WV3_NhHwrH2CCWw;{8RKDe?doAJ85;Cnyp+slS{qY__aB zb+d|PJpuILXkU}b7yyItMnO1Y5Vje(j20XrUGyGekz0B+C3KqLL~+R-=(~;pTH5V6 zyPO+x#?~#^t3pF0EuOmzJMu> zPFguY+@)+ERj}-n_#TYV4t}u~rQF31V*|MhMzcUXt`g=L_yxF2>*z!ujS=B~{l)$c z%1Od2n-~#ZIJyce9OvL_+H~e4KZ6O77U6stxoF#)4~C1^orE_T<>T8h!)%uZ10A3L zekxaRHjTmIes7C>!u{UT;93p7DWGG4jYFfvcr6r+#!rqZyjU5@54$s6ShR;>MEsnz zZzM9qz=y_9TSz7~a1a6mCdWF$bclK4Oy8Q$=dq9%LAdaAUjbB>w9oJ>AO8aqYq*O9 z9a-mF*9vTm4YSpN2g7)Z?R)QfqK>|GATZXq5N-NdUx83WzNCUmN>l@k zZIm30eg};cbG2~4Y`uEFe6$8_8qCn(a19RCV6p}WX|TTr6E$enU>^fx?TO^f$sCa%~kbN_vgAn?;ZR+(A>eWYmCTI?|sz>Q{akTd4!oL7i127uku+WDX z)YMfy&F0XCP!7!R1lNovs_KH-W6)!?*a(v9{@%37;$m+7Hd@kg6H1NV6wApzi6~vP zxGRx^i^`nRIx;1&rXmAqif)a&h&dlSyp@9ZUm+og1y0Q_GdV|{xpFItLY-K0PDEMI z3-jKhfUQ_tqTbD~`P!9a7|^gS&2=cQ&;P=gC=ZH8TX&E(^p5O3qRC@=bCcqsYQt1C z?pH~VP}WW;!g3S=o1~AhL)8|FTizjVmKt|2;;a-mt3#YkjiVDo(QtZlgCItC$uKr~ zazng`oER&7{9PEN+WBr3dz%NlIe;I|sQqQN!|1~qt9gV!`jN9~DjNQ2*Lkj?^AI2ktxHf!)R4Sue{Ga5Xr z!7nuUr3Sy!AlIN@gXc6D(BOFueyza^8vI6sjT$_l!Gjt+q`|`){Er4d)!-2gHfivv z29Ig*xCT#X@T3M$Y4EfLy&A01V66sy8m!acP7T&;ut9^nG`L%XA8T-r2KQ?46AkXu z;C>BOY4G0~d{=|-X>gMU-`C(~4Q|n3wFb9pka{?(*AFzfU4tKL@FNZG0Gu_=M(QvA zb#zC<79rjQkI7<_e(DXJE+P?ic@nUxb;a42KQ(U&z1~vSAs>PEy&sCl)Jw7e{$KeF zTCTpe)5V@WZ|;(I(v{YH+xMv5>ZN$1z5Hj;HrXdR> z`adn>v5S_@T{ypB(vr%xKS7t`e=gllcB(ei-~57k!JnW@@jsVtoIN67=5@^aaXC=@ z&!ro0&!va{sOBo){t3DiPjr7yKV*hZ2>Ch|&tHVbZJ7PzJX1XN(?8aKM%p#$o1mSA zhqj<^Py7UJivPK^JKM7sFM=vZ+V%FIpiS{4lb_QcS?nX9dJ0c`<;`Eba4roh;JweB zAD0Wo|6KaanB*DuNmuGZ*46Ks}!Q3HlWObLn@n zk9-m@{LOtzRl-W!6F)8&ivRhv(N`Bz!%_RxH-CaQ#s6H|-RwDY3+KV?xbWt9y9w#L z>W2&)O4BKtR%L6@nDbmot~`HX3G+6oIKzJoht@tcGfTvW^(wnc_Ac@l!PaNs4Gy3w}=M6_!Bt{+0NGvQhB}(R_gAxm|7(2=%MD77enIFnu$k)r~4$HxVpxWXh_Z&Q5 z@JNzoz`!eFJ}$$U$T;?KlgyiE{UVH=sylGebtf-FWdgGcI|9SR3w^LX8Rd+bg!`VW zkFW+|4yJuJ@mK&Yv7bT>|3Ao%;n|ct-B!3(gZOF?Cj&+YUS^FDdnfKXo`Vw|up#35 zzbCh4iYK=fUl3miZy5X)t84IT54AlT#3d^`S8~r|e9 zD2}brF%{;;7T$09z>kqhy*O)*W0Oif9!A;opqCcwI9s6`nY2e~!%>!N%2AvXzx)^F zD4i333kSt#&Uu_{8I@^Zv7=;fa$oPe zH2QKqjRh#^A7vl^H(dWHQ~& zCy{}suD`G|vChpKu&tejo89bAan5M`}w$oa%Y?#iQAabPwuh-S0k0+Kzq=CFN`G!zC^)( z&zu{|Y+hmiDr2xS8lfjP@>M8R#t3J;GP@N4do~6>Q)V}RfC7axhB)I9RK1bU0FE;I zgyL+%J20=oGlR`;PTErvm2%v*@~gql_@s|Z47vl5`CBg@jkv3U4BdKwZ>2J z*jsoXP@gfKIh*{C!j*D7V}N{5MsjgxM%uEp`Nydb8HA&HUY!rw>o*3@=KGU@2i;7! z8&`J=+gsUelWTQ zL0Dy2Om^XJfHlZMReC5P8vJJX}-Ef!M3>S`Jd+h(CTrzLoPnGlrDov^J zIRD3&gAL5{6x59K@%cDhh20$LMrkJzhc?CD77^Fh#DkUhUNn7r0}tJ!2_If< z*$2z*5k4KQyWXJ3R!HQX6^tHex0Bff<8NL(AhwLfIXZ;3+s|96F;568Fo6a?pqU~W zLu=c|jZB(wtQ^!K1UUxPTqlG)<*hIjs|W0kgCleT0ZRv5)`aHFeA##rWc7r=Fgj?* z+dhRR(1E&7(XZgVLA%*HuLEJ~-(q=%N>U}Tss^cYTlt@mEMW1xMmZy7LMwj_qJzjt zVg@NM<;n&l4EQ+V6d!kRWlYuJwqt=9<5^i>(Y)ce4&@By8=FIavq_k8RNR&|7L$#y z<94t1Kek4{A?=Jam_J9mS9O?rbbDxREUL7^etm6>fY;VZfGFo$gYaKo8!h0a2K#x` zvs8T>eq2{2JnLdNxr0$FqpN9Dh9<0v7FwgA&Z^BgVB}h9i7M8Mr*iCv`D|dZmAGGT zKRlRj5F%+wZ>5GWL1NFQvAY&f%Q!DyO}PA4V6ew|#JqX7#dTdLk-HM)&R`06h4LDyRk62^BzM<`CRr2Kx zf!?C^j{+6B$A-^?1aGUT147|H$Q`>O5F|Vd4~7(P;4UA34Yc`-_*pX#I2hl@ir1cz zcGEy;toy0~-O%nT`bb}o`?h+#>(c$oULo@*I+~cdc%AA00$#|z#aU$4QJwzc${n+>AcFn zMJ^b&+I%U;*UY{wBrXJETr>O9Rkpnsx+@Lz$qkl{3YZ9h^(`L0X?&U*^m#>8N{-4$=H zIO9rJK@jliZ7B!qv-Fbx6L^mg8618@lID9Y6Y!Ko&|<^RztDM%|3^Qgew^QjlM*wJ zhM?)k|J8y<*mU%blPj;hQP^g`B8`;ej%}fq8MX&cJGtit{kAwzePhk&0bfnyMe6?>Q@?{!$Xn&We{-sN)wvXN|QU>t>k{!igf)$#r^6>r|YFj z%RAoyq@c8AUkCaYHe~5jD3d_K4$>bDsTUz6%NGk-9^NGi7S^0I7b^OSoG2fo(-C@IuzB@=#BL^e- z-%5|Yx4F4<$)&N-7x)g64{stVxo1y5+pJuxCQQr*;~}17n_m3tSv)8pKJC#kY<-c`|@Xm<7;>pUMwtJq~o-f(L?0tf+MEMB0%^8vT%lXlg|N|RiVB+G4h z`?2O+-vC6HaAGb|hMHgG6)Hzv1FBO^MF-38bx$>JYK&<^FF zmPB?a`R|Y+`f{2pNgwq`hrJ^oKe-D!(GA$G(%UwgPK zn(e0@OA`)11_J8PsO`7r;x5Yg&lX#{A$5~{PYdz| z8MpU4H`kYBEHLEpSAg#*s)Cew=p-gBWQnLg4|W?!g~M*IVVtvdfj*BH3dHk-cnFB? zoJJup;`Cv`DVWrq2qcun-@eD zTSJK77DvS>#T*Wrp%#PABB@0%|7sjESXT#jaeyDM2752lbvPVTpoh~ih7Ak!GjAS! zS9s8)@*RV$at|oBdGpk}!h9+;f%Lh7$CKtj&8{FMy=hgWKL#YlA&6=);}3#)K>{lt z^ZMv&bi^e?U>>OFJ23@B>%lbM!6t-6&~Kq2Y7^K5YWmqB{{|%ACdm*HxY$Z_9_|PG zSoC*e4cknJ;0jQ){4PSYL=c6xdR4@(K(rF#6F_wP^nv_s{UdmS;Oi=$8F)hpZ#WSQ zJg63Yx@;I^b#_6VjpF(sE&wr{SH&;^l?GD+#Gt1{DAhLz!8>9vQv+!+Vq{WRBq8lLCy4^E*^RIqvYM}7(=9iu`}2)RjLD3WH{gK6H4 zwLWyGwC-(8dbLgv$3XCmdwC;t0;f;9oWPlk51Zj3bY~y!9O?xqzJrw?CM3QFlVgbd z-i~qN>=e$!APODzOUN7Jav*NtA1H}3JLoAV67SC9-En4tHIDL>Uq*MMo&&jbAsqgo z(TVHJM9VZ^cwLv;@vn)$ooQ`>iv7*qBK|$>%&9j=pBcVLLE8EFA#I<&Taq+ zo53L%;tV5(gZ~m-d0wM30g6^E64gVE~V+bC^!HM>z18PH(hTto$+YTOz zB-A0UK4g4iQwq?#2Ix3m6#GM$;|lYzKe!So{4r1dQi0s8f`~ zv7nX5BGSR9-$YpuRrKak9CK^s=Z{j>qS~+A zo77|N+FdN@VT8c>9T5W5p*_4T(xFjb%yLbbu%k`Af?gi$M`XbZkU@L1$^<%fo!8O5 z`}|IvnM5bA=1z3Km%A9yJ7oRK_N+bA49F!{tRMyN@BDXawH=9bMK`%0(oTZ7H!SbS zJskD+KzWjY~(Gt*Qxv$5pj!PeU z@^#D#a3vDH?#y)ZP55AOPtJ!rc7=)t?o@^*!s=(hBL))d+z1VdM4v;nvcxof1`M>! zyPfinpQ>&Q`~U+vFgG{i$dL)3Wt{8W?Zw>!1MsHsQ5ZLp@E1!6-i=|xW7t_u^A!B~ z738Gacp3w-JR=Og8*^B#e*uJ}*$$ggqhvj7R%VCP9RsS0y5}NQ0po@VI)ZuKvoy4J zhH-dZCE6S>#7%3oRmFa`-p)HI&hz#5mQKpb)_Qvob#c~#d1Y?%x++3VC)5eeDD`k` z@$lj3*XSsfcAk9?^77c5xf3T^NgJO9^!dL+l?AwXVij{%pR$*36+SEZ|Al6u>XImr z2P@JV15Iks+#+|xJ9AaWuTyU0kQ;waq>>`H+NVcuwdV|urpxKM>aF&SY&koS+kUG( z6~p(Vkz4H#skhqui(Bot2OdywwfCc2?RN(5uG0Ie48E#pUsa5+D%MwJ^i{?Asyg|q zOunklzN#+1s@ugGTJ-cw!6#j7S1XC?U5qc4Pz9RDDdpr+$~TE$I@*XHmVVV++0U$q zR18cMxKrkSAwhDQsZv@<(g$e1FY3re-dcEBNl%Pc_GVo2GdcJZ|3R;WYb_Y6%;oPv zxwRqbII@8G=&XaELS@lI6u(C#lAu3FRDJn&{6>2OE1uT~d#kwLkN~A%S}3v1pZSUc zRPMbZC0%puM4D2*OZfMaUwOY#cn;$iWGN3^RPek;1zz_y@g76Gd&m#HSuz_T5)DU9 zff<6UR}oQP{yKi61?@M5pRSvN_FKa9Hbr{M36r$(H4^N)GNQeK=1Cs%M`*uwjcB*) zWHH3-5jDY2;fkQAocIvNLwz=B=(OvtU`<$`ZDBn5GeJ;M_p6|8VBQSrWu<5z{Bouf$oXIGsc-~iSVXYWs zuxqpKZ5sBDHUfJ>3rf>W-Oi^XF_wMZY0sVCi$M{SQ4G%^T*huMWCj=`BX9^Ezt6vP zJ4!-_K&iP^@>hb|!xwxfMYGOLYMVMt6OAjNzn=OX*0})kM7FbLA^0=}Q#Z7(3djvo z6FRhY1|T#@qmkFTy$DsODvD)YNT9s_Ji?6vWd&qjeHNVo>%JTTN>sIkNY?!=Akqs7 zUUw#CDarWr8i4gS6Sg(s5Kq|P{5iSt)VhX3P@s^5{{b@sptSRb`mqSkgoF4J4&q5T zh$G=3PRPOk^^TZEb>;PNIQUxp&fuRyEAV%%>K39+Hy9FMMU$DzcS5-^;Sv|_*1z>P zFo?c?{oAU;xPBuX?o0~TIW34X^`kSI>#Goel{);wS-lB<>=Gqxb%7}VCzP$Uj_5-U zw17#)V=;I?E(0^4S@g$?aAdo~0%7dCx`3UvO$_KJmS0(6F>f|u!(_L4eP>!e6bIP; zf%{77c(d!d=&|nIH%6B4b{gJ|3UtHDe|QHnQF!5}R(t13oDomO+c{!ciuV9~d^_E* z`E(qo(qjOtOx+!cjpg|W!v%~QTHoRzaU>!>hhKrJ4#YEAVlSq{`E%iq;90ReNJTe! z(7e98Sn^PQ1>9`T$u4s9P9_$i2_gYY0-ad$Z?pnLRDq;KGohT}Y;rbk~*wh-8o+zscaVVd_e z=Gm!N0t2wx83xPAtYNVOnu>d6RoKBjeO~iF#G>tnJ$z%2Gk|M+?i;3+odkOP=wY$W zdQ5cN&t1FgXczAzZxh-~OdRHp4Py*sU}_j6UOnY=ksB&LN{J~1xScf?;;DPRdCNg1 z&tTr-t>N+b<2rdC%__yxfaE3~N51@*Iqpo-Kf@}ss(IK)t{>A`7cegv$5#oGcwxO_ zOy>my_+riLtC(YgFk^Fh9HcT`vsQqWAO8pWh&*YcH`aMIhb9w`mPI;1-V3xi$NW1| z(b4?fZxE#HLsc}im(pgZ_6D8VH`u79d?o=Z;QnEOa?1W=$5i!|UjTs}7oxo&>FGEpTZgaH> zc>EYf4v+n?W9xE4wyMaz1oB}|ZWA9TkejM4g#1q+|9ix?yHu=4D6<5SS)*fXC8h7L z#vH{y70Yd`?n#N3iyZbkw!TRiNh-z`fw8x`4`Jj9j3B>;z8|Iueo4SxTDkkFDat8@ zeHY5z=`?8{rW^Lqwzol(&p>)iH{jhw-p2&FIxYFVYVt86c^#7PJtdMq;<0-*lxR#t zAoF_#iWewozZu4AQ8C9D>^#$?JzV>%?z1=7e@iqsEi8)g5naM5f`{DEa9c-Ca7@tR$WLCY z<|muRh-aS_xWoh8Bj~Ts2El&UE>m+C&6l(1mK2RFE}r{bPsGzdqD!#-I1&2f{^eL} zbecM0ae;H;ys?W47aM^?I(Q%6uZ;dy4&0VhRcplkxedG$G>-vnE`B#L1T(aH!)_XbLAGt80z{c}kcs(LUz0?Wa`wPry*sY-_2P<=m&i)#D{YzT+(?+tT zs1<(vtwIE>Kk+x3D$p-3=~gE`g}Zj-p~E~sa6fwV{E}zJ6wjNNvt;g5^X$uU)6Rld zvW={k{|S>7swZ}*s3F{xm;2Jf0Yy{!&r0CF9W+ByvJ%8?)6ZyKLS5Sm6kr9aRR$ai zxDb$LoCWx388{2@Ex@UO=kbllHwgaGfED;M=!1VKU^d_&Knq|ZU{An4fV%(_022UB zfE>^OxDYUeh3qWAR>1Rs=K-4l&jKa_o&eknco?t|a4%pp($)cP2iy*rkMK=^F9B`@ ztVH-*fOYWGV%-YZA7y0_0+0T^1b2lNUIF);T6h`UyEL~8Zm;HE0rw`& zy&Ud7T3Q+IBF()7?m7);A>327@FKY1)Z7JdzplAycS6?Ov*0#q?tHj|8l940qKg;Xh1%J^7ocV4rP*s~Ik_b->h&)>87NJDLo} z0t#G;!1fV#J>>55o6#3(_o7iB>UR+NpanF5Y*Rir6G>* zU#BkRbE*MH_rxv4RyATXBG}4SwjZX)L(Ob|+fkMqJan#8EzZ)>Nk=+V7i8T9txqvI zQB%2)3R{k)U#j^}bno+y!P70oRxhxHU5%HX$C%MBkUA6<<>4#dQ`wLKef|p@At0{J zx9R;8jIEon5;O_cx1u>p{C4Ej5N$+Jo|^pGmJbFZteSkxQd+z9xnY0AUl7E`*<;Rc zQje#8oq8pe7N=!EVun8un!aA&fN>UQk`P4iYBe7EoM7A0L%dTX{)kzNGE^YqFNEUA zA`OT}HhQCp(m@>XK_FA%|5ShN&^MhLSWsE9(S(;twhjVCY^$(w@p;2-`G!yk!P6dG#+5o-Q36pu6lD!~8u zT{O$B-*u3u2}DR41|i1h|LZ>>#}=%tDg_PxYmlUOVMv}W_)}3JljOi3dafdeMO}2@ z4}#|#m3;gflzb!WiN_r-wRu*gi-r(CIpKJ4d3$bChk3E0RVf5X^x=*vzwfV)RA;tyDv%hSZ9gfd8Sm{@m8mE2OS12w&?1 z|6lgr1H7s#YahR)5qd%m5Fqp<1h~DI0HL?gi-@!!AWe#bV?jYhK}A665PA_X3Myj5 zG9xoK#<4Jp4k}{ks3@Vt{eRze?zy=MDTp)Q_dWmLnp19%3*3#n;8=7g1Je?0W|iQzl63M+G4)YVg=clUjQS94#(JNpjvY7eiD@M?Q_ zI;$m}+M#qRq7b*?Ug&QT`jTD+znA0p!OVi+q341ZI}xAoD8>{|qHhhRGdL{0xvdG` zP_EkChw(!0*p-+ljINxWZipxji1IJdopL0~fS__`@Lpw;%$7yxT5*y4GyaWzH@XL6 zb3Vrf@fqdf*dAWwcAf)E^&&R+D_%KywGrPz8wrw^`yB5XagXyLb6e+q4!)+B$4nGA z?g!WYS*8skiiQC`w>A5ua?`u*>+&!XFziB+TIb`cA+F~5&fq$9F?Rbk)HZ*Yj3p?qt4k zSbt*{e&yZ=m2W(T*abHJ-**7%=RR}=F}p6a;ml)N_0*c_a6Eq_^NRxz?iYN7P(NJ8o_*Nf=mQbN>>zKvG*EskM^$ z`Vu|&vSDWVxp{HZ*Pe>FXJzg{q_>{zT0V}HH)_ZmIK2wqOA8KHdl8PTn1&^1tqykG z{|=s%$8#$n-(XpMjE+0^d;Fs>J|-}7O&_t)kL|0Bw{pk9f^xsa)BD(A9zv2t2t0I!IyA} zs{`w$iH=2)XXf6uAN-t0L@bm+v#KR#b*NikNi}o9Z-a6>p{NJtcEOXu!kdZ9aS)8qtkH(mJDc_GjNHC zl)(tb@c~LcAxZul)=RHciTq&BcJ9kEi)xvm*7NDi+`i;44wu2-`|&{VvNJD-$x~ij zE@&W+Nm;%M=HMT|2iOEYk`Nl%ZG)hYPLtuy?Ht}6(^il6;>X)3DsDs-`Wj=r+=Xb2 z`*rN!ADl~joPcoF*clV1Pn$4(=In7Qf5jF$3D9Gj3*{*uawH5m-6?=;%C`Oa|cd-Rjy2#39HeP>RdF@923QWimNlK3}rMv^i3hj^pO zY_Zzx4yUVK`wkf$JMp`+6hUr0Y9#o@-~3UShXxHEfH`ZBA#_OEf&(nXqqvs~IuFWY z{J?ZWEGQ0?07?QSgNz_2C>_)VlnELP8UY#ynhKf)ngf~-S_E1S$_8x%<$(5q4uB4V z4uKAXj)HPQ=RtWO!yx1j(krN5k#vLC4R;K9=U9{#M&W(;sqhr13*erQB zrOOLC_KA)sqT_SuI2t-Og^qurV@h0asN+PW4bk$`u@_d4(0-E%misuCeKyLezgE61 zLzYPbC>e7i+ZfNX!8Oax06K_gS$-^2mSG~|mg8O~o?V163HJ^mr0x%avO!aEkNBL6 z5LU+XnFx7S3lCRXj%y>HNd`GVhwwWa@8^POJ99wkxVI1CIE2d)4n{Z&vVu?J`zFAKxR;TP+!nQ&;y{w zplzVNpaY|D{%t_G8}tt76VP$cRZ#8ny!-gg8G8SfTn`xfF1{}1w9Ws0Qwko6vV&(mg|3}T&LiG^_epYu-Ji0BYpcr?Mx^$O6vKl-YyEPaZSnPW&%p5t9k`(-EHxWnD^C|GrfBfj%I!wXX zhrdOnOn`t*nKo(Ux|s>pVD*Y z#2Mq;@j}Sw2{+-1t$DR@){tymMhqplRc0Wbrw~446Dlm>ClSKtcr2&k$wk zJ7eO2$#)_dUXL6<9d0b6HEc=7f}?&j#%Q8k>jBe$;`Dx5GsNofEPml}{g;RquG=D| zQrHFy+f-qDBM-Bu&&Zn8GYd92T1uIE&778X2MeLV0=4V@Q+j7jLPSx2o$wMFG;;im zPE)4!8$bEhiCMizO~@KelPhXL{l?#wHDzqytm#u`P8-dFG(cP_`x)S5)XW)K(?tuo z+i~(8F!URv$N zZ_U&T+hRyF{{c(vG;`v_LT5jKhhk*MT^e48DPyu&6AEfU2_=H(3wcdZT-*!R=U@_2 zp?SA(ZQz|u))u_Onh{=-*VYt0mN|5sJabY996T_2%*bhab;EH3Sy~n06CKcy%+N&; z9cXt%WX7}c)GGph|M#y@3BtNSkZT=%2yMefb+=iDE%k7pqmKBzrmUk^5SiZOXWVvjKw8mQ-T1Q*wTI1|%?Az_R_6820 zW2xh$qpq`!^E0Qz)zjs1w{zd(zTdsjJNO>ysW zzu`XTspDpfd+vlfp&pTfw6(R0uKe&1x^Hh3S5Nmmm%F? zScIUiv4wG@$zeTfyJ-7|!{^L&)^$7F1Kd;Guetx_z7^V=<6Y!k<~`xP>~;Iv`TF^8 z_ub`t$oH5p)$j0k@OMMb!~K)|_xTt5SNb>jclbZ{U-efER0|{roPn-^p~(5Rz|_E< zfqMh<11kd?0y_fF2lfZv3j8hbao~%x*skT|RIkx$z6U%Mcwr#c? z+dkU?+dX;EXQ(3wquiHn`5UV$FbM3&+)3`fa4R#1;kIn_DCIm8=s3ajuE3sjeBWS+2WXb6oRW^Igkb`&?pf};-E-XY-1AWb7r8gN-*Lb1KIHzyeb{}( zebjx-o$EgBzUof&H1i~T(mY0w)#LPdJ?WkdPk+?ZyFGI}^E~rC3q6ZGOFhdyt35kC z?|VM+9QGXX9Q7RYUDa(-gIwz5()R{%7 zHOsxLz1iMP-hJM~s5{5Jx!%*>^WF<+hpu`JzM4L(&+AL~W%#=IdiXMZ{e6Rd!+cYH zi+szaZf){yL+#4(?e*>R9rB&`<@v7q4E`v8tiQ59&R^4?fEw3DT86>?VW@dy{Nwx+ z{Zml`H~Dw^bNqYJ!oBK0;D5(|(Eq;w2x>%BAU04r5ErN!NC+ebk^;?8I|idY850;6 zn27o@BQPs)cVJFnd0=1QK;WIg!NB{0LxE2MhXY3fM*|lEh7krsHtK6lW1=z1*vy!W zUc+d#O3#sLoNAn9yxTa(IL|oWxX`%BxYW4Zm}7j+_-ErM#&3)#j5STans->=u>Q^J zvit1q>>cf0?LF;%>;vpW>^Iv-+OzEA?UU@c+h^Km+wZY=g&kIRzU=zmb;k9JE8i9E zp5R{L-s|4ye${;dIxXk*qa7ITUmJKa@Jira)L<|+)nMQhM;-8IH{N7?%=oVH@5YP9 z8t9iYOp{FynD&_7G959UHKmxlnr}BBF~?g{EpAIc%P7mAEXyn(TehM{I&HmRZD?zY z`gjKIQ9JuEaCX_A0{j2T;dJ(P-tN55`H*w1b2IGvkn^1LBKoBcu92>Vu2rsQT@mgI z?rpHNU)|B3H$DIGH1M|dcJMyoec5}~oA0gcOZE*!`+2Kxl5d9ZUf*2bBfiIdOMNSR z>wH_F?dNAeBi|RkZ+)kH7k&A@Xn$3IJ%1zU+vInnz3bs$=zq$;7J7aG z`u(#%-(NqF5f~2LJr#Hjy_sQ-0rPPN!;|Q%BTVH@wM-37i%eTgADO-~<)M#AG`BUk zH+MIWHP1FbU|w&2*8HLQxcQtp(h_fJZs}mjvdpkNVA+g*?=#DB%USe#m8{9=xi46o z*?hLywwG*g+9uf-*mv7sxBu1tk^OV~5qo_{>rmS<%rU|-#xc$@(J|FA1MSG&jyaBb zj`@y-jz#DzmpfJ$)2_UO-syeEA+#@t9Y@el9dqP5PCL${waF`{y-9L5b0#~}(C#>$ zUT2203)-Ll(*CgZVcRpuInTKeqle|r)y_@9cIZ{KLTrORL9chzdCYm*dES}lyy}cX zd&Jg=ZBeo-&1H2t(H>=Bq>+hUaTvxMJX1Y)c^>pE^Sp*usDXF9cN^N0T<@>m2Iz

        QBI-^RZlJ#IvxQlM#|ZNMJr61XKW0d@M`z@osWKu%z<)aj#vV}abj zY1U@xd=pV$B8)YS^^J{;&5bF>wx~I7jQ(ymj>YKjZsS9!$t#VUjC+i4NNqY|JchcQ zXRK?on=(y0ftP0yKLG`#~W`_%NUDcAI?DaKsc9B*!HZe_NaJD|p8 znn#)^neQ>rGe2owW?p07Xnw`~w)wB-ugu?@Pns{7YgkN{o|d7O`z;GBYb~2BuUp=+ z9I||B`3^RC!BWmz&05pi#A>!Wtv+i{>mch$>lEuu>)qDJFyh&c9`-fs+t$BYKSCWo zXZ^)m$JWYbg}wH%jkHa(Jz-m6TW8y3+huzd)_chIt?e{w_iwgHdrfW7h%N)ihBaB9vj*#gM zMuCa~zj4&i8MTOpYw2#e(O(Ct|SnSn&G-ey4*!{eA1{7{f5|rT<=Z4hWxN@o_)J z(4Ir_>G%zHL%%ceduZ727(+ip2SZ;&S9}Qehc)#xbVS(S5NqgZXotJKKphOd5yHkm zOe+agPX6Pfn7?LE{!lmh=~FMYT6N}1+Nx73b=h&%^2x7N^M#+QrjPss^a-vHtK`N1 zQmM;-P-&}9D?ZD2^mk3`&nwfqT-EZ?4^*8An^dLD`&Cry?kcje6Xa4+ZF{Loedno! zNn2I&!b8f81L*k<(s-fGnzL8jJ1;6<&SmA@eNnYtcu-Ys;a4@=^ivgE_E53SyQr83 zE>)qaQ<)bZl4tlV-{HGfq?4X=Np;wBMFqB>R#lQrYQW&(s(beys(NCos@0%{>d~Wz z>e>tGH8LvymRxz3@9;YIRSA~fs*SscN@-(L4cuc?lMXXf(~Oxa z!8}-59UfJunN^jq(Li-r`FDAT?{?hrqZ;t?71j6IQ>tciM^(M4S0x1|%6kn1laR)A zmFS(I$|nU>RE-v@QKwOA@N4<<4&Uvz^CvY7aB98R{$15d=_2njPf~sNt-=Gt*k)Zo zomFGJKLU6@e24G$e)cCd>W!^x`v9C&Sj4Jegqx30~cT9bU>iXbLbsHf6 z_zvG4`25dm!rNEXWPn9Y{>yKwY5HK1S@KPvioB<)I`)yOd?UY#jjOFDynaER22+(RXpI;vq?K9OhmoV<^B_5Ahs8TNSeIaMn; zL)A48l)S4ob*NF#eiM2(^giXRgJo9CtcPS^| z;k!L{oPBBd%NON0dD3a<=Fe2q_Jh=@7fyxl>2Z9Q@8I1RGB%y6%MfW@(#wNo(tr0^ zDH~oFB8}%u`n&Wh|0Be9CJB@dDy^M?D_J>G(?vg6nlH(HrsY#7&m=E9m7lWwbbiW; z)A_04w4C=#r&PQb{tnY%T1=B^GY{sa=gSc7)kwr$LHniJtUIULW`ow@di4pFw)~h% zS@M-?@z|%T*~1^G#t-~OHM;jr)$mWRsRpxOQ4Q{T1=p|R-dn24+=Hsw{Et-2$3Iu8 zOTSiWE51itbP{Qul{DL|JC8QHPRUPt}s+F}yHMrw>)#BlUs`XP}DD%1>koGxcLmp=2#XMU;7s*ebJY&p0uk71? zQSM!rl=oTC?mV>PzbM!CAC+VCX=PdaovPh^67s36V(O%+YH58`<&@sicChUtm2ccm zMOAOEB4Vqm#9Cv8tMAQuPxXsE!>ws^-mGsMz?1 z(tlKGny#WNR##@TS+#H9UR8~&A^kx_g&L~y(0dD|#dMhm^J1RN+qC+Oa&P@vrK8L< z5Z@6vpE_9|IUs3QsNP83d+)t!=gys~UAuN_?%cWHp}C4eS(l59mVEEN`)-MQ=bd*{ zW@e^}jBf&cRZ(s4c{Y?D(`6pai+M6{%i1%_yX|MyAtz6D-g`xLdEsi1uBd9s4i(?n ztvYw^tS(%*pej|Wq_%C_rZ91dKB=~9;jOl>i+xhS8lgk{qoB%Dxq#Y z6_e;vF>wj1{k9XKbeRY9VxG*~j(Q&0@w4jmTps%GE2{fTSB2bBzCjnQ}M{VDl~sa#9qnl^2UYK=WV{rXA%QPrENM%~AS(q$gZ zi+M6{=lZj%{WBL-H;fy4A@AN8FOVAdo`}3NRISu5YR;TF>WL?wQ02;%Q`H)nL;awh zKSS~p8{bI9#l@*tUU@~zET*9cb+o?dC}Z6}C0*vhyqG8R_G~z-I_-xJ!4g(bA*bGjfL#xq%8D2^)Zb8n_(@>&A_T^s3IdHRZMI}85fj`jZ?MF z8LGvA>5?wRb6*qP<>v!qz1flRSkMIU-ij3BRXZ8mFpyf{}_xP`i07y z_c;a%&zskEY~U4bK~&9T(G}YRwo%>(o>c>ZSIe}S2lHZ{%sUZb>m=+&AS)QANJQ_-fl^kX)_Pz#XOmJm+j}&fW5z{;jdm+qu5`ZS^J1RNyVuV1>ZX@|RatLbQMUofa}vhjx9mEqCjR+1)otj_BJ%imVfmC%>Azr9f2-+S&!0$rZefh@iRRsF{-jBa1`QCQm*MCd?EQ4E~If8LeT~*gKK)%0|Fb320 zUei2Gm2Z+EV^YtA`Pbyh_jM{-{=IgdQ^UgSPk*ksaOnDvRE78iRl8MJX`kz~?j?Od zEbDp2TFN+R>NVecMbpvqXP(Tv=QHQ>Z+ht$HTI3msB`&Zt3}@l|2=HWr>bh*#>#-P zKwVRRRR!O$Y~xIWZ!a@%)+y$}yqG8R?za8RnZbK6sL`)o!uKTe*Xm$+o<*<6?EOJS zVB8m<(p~iJo%rZ=<;}F22lHZ{%)9fJ)6ewH`BA=G$D&>`o;^6r5`v0lJ=f3Z3t!i;mmy4ZjNW317BY zdg2nk;q&o52|6Wn4V-WIj}!Akp3Iv(kQeeq-gG{ThE1P1UJ1{v!Sm!#rLH`q(lGbX zdJX0U)`k)02wJZ>qgvw|jdQzct4^x4l_&7cnyXr2zPHu#<1#0ly6k(E`gD+Zjd@}% z9?z`6{K-nZhxy~Q)u$yb&OHbf%Ilo)Kwiibc_WYHHJtw-?{Bw!`lM=wXUTJ0e8(HJ z&k40%cN+68CsgZ|->X(nA5|%fzfdg~ej@WWO*n6J&l{@2td~{&8GBXT+n-elQ+8tR zd55Yqal5KBX}et4ow7^So0g*z?|4Bq#N1BOeQ&BJ^A4)!I7KD-@y}H1k|Qc@*|)0o zsvlHa%aB|r9e z)pYKkRm0i)RNcutF!!=XRU5WgRUYuDs+c)f#rC{U=77p~`xEAT?vi;Q&ixe7U5at# zdtff8*Bn)`?}IWQ6hHhaRqNLEm`~cR8r}V>YWC1yRmu~esI;fQR&7@wha9Ic_fDS9 zfj7ti9)mKhp$=$M)Jv&qy=wjRS1N_PKkydjefFr@<2R`I z;Y(HJ{_}+o;kV0d72SE3igFHD5m*B#7oVsMF_ok(=UB~9p_(dJtEq}iZm**K<1x=Q zD>$!px6FN2!5moi5zAD<#4RYF7ge(dF}Jno6V+z*qH;FxQ-ZNfZ6cCIq6JgU+bf2vx}|Ep?z&nv3_wB4%q zxNH@F%TuZ<=G0;wLshw|b>!R9fN#=>$_W_bHpBO3ihOfM#y7?|pa%Np2>D(vSF4GN z4cv;kv&X>q)2a^2g!5@l?t2|;BJZiRC7&zfs&ABK{Rx?Ovv2)Lc(Q>v@tPow#B4b6)U&*&ZQ+zXG45M9l!dR+=@ zHsmVD7R+5BFE{dJ-sFM2kSFp+9?2_tChy5low$T`8D)W7j_to-PA*UR@Vp=MQGU*g zNyux=PhlO$hj}s|=H6Q0zfVPB{lO3wt12{b${a%jtb1_mS;I6`e+6#FiZImr69VY04MH8oRJZ_xoZQ>E~8 zDEr8&iJAY2$xmJByY@XzWJdro@NM6Y^d2h4wbiS<1ZNt3Hu8UaP!(1tz@380U zHPjAsJCz!w$ah`Q7p5*V5M;=j^E?ts2Mb3fFn>SA_ zUc6W(BqT^#m#YxAor%Fppli!sSQn9vpyK3mYRpwA>TVuzLRlolF ztME)2zWeSwb>hScRkdnWsn5}M+Q_@cyLN=~4e>ykz#Dlaug;A>VxIYQzGcnneD|gw zG4FaoWuRT@yyvp&3f{TC8%|9J&64@jhMp|sQBLjM3v5#S(JsgvAi!0%YFO{Ub$kMBd0F zc_q)}-3sz#ln*tL~Uf?(tFqb=&hR=DTZSt-vVrmgM7$FTRlSA2Vi* z@WOj+4{NvTF1+&_x`1ZNIxp86c46M_`8?JAh0CfJP7(_z=e!prKej2HQ)k{EeDHxfdGchit{PMX z)}HEFhG5PEYv|xzn-2=R4$4!bMSHwoPSSYbfd^E6e!jZnjyte66DMsd`)%qXvV29= zdF%Iu_#kiOu>;ni$TN9&t~-;@b@@)9@aNzMu2{RT`$KD)rJr_P})~rcYvB zrvE{Kt%Tc+ehvSEkUhW zcq5PGl{}Mo&-yd@9WdVLhI#YeFXX9y`>x1b{y@y<4}1kWz%dh?6RDNbS;{vq$q~x4 zO5Ikl>uJT>OhZ3?Dhk_=ZddVb25PnrAB#}G27SofCVVcUE5{*kEq^V%Dm;-l^4RTJ z%&~)K^6uMkCZB#8JuvUy=fylVVE+|07;6Fa*&uaX`WNAswojX=XB{fKr{9M@&sEe` zct628TAnW&$KUa7!GCaU#4#Q1-4GEiJ|i-|!yL+h7cU@x@)6_(Jdro@NM6Y^dG~KT zli&H7pH#2se^vcn!u-uES7c4&Cafor+;?ph{yAT++X!u4zb+|^Z#xKcXcJ{Ep-G3r z_9OGT;p0+Vb4`3-pfjO4HL!8I20Mjpv4c_#1ao6hEUgt;6uW;JdsZKCTYG*7+Z_=WK`v z;RQUAH}Xhc$uoIxzxix__gz1!zI%UFgI~U+hCyGqfOq=rkXpn4hU>B9zcKou;_RWg zdn|u_4!LN&zP7E~Pa2dBb)vTI7HLDJ+>7wfb=G*y$!qy*Jn)+9TjY&Al2`If z-aBtSo1cm6!C3bh{^}*jeHH6rm=EQe6etz^>uo*zsc>7MuT}W(>$#?H7j;zy-v!}z zqhE`ELZELbf1MBVMBd0Fc_q)}z00<<`F(PJRzqL9DC=iq@XW2?n`>(0u%^_ikH&wJ zx0lEv{cNzjxh|;N4c994G7b+VK3KoQuS4s3Vdc;98{1KP*1XWV9(f=ysn@N2ti-$gZwYmLy;c)T+~2x~mxKgrWWjoEh&HWUkgKVPUF;yN?ecIoey z1m8C)|6*(@+w#f5uiHP{Q0lt(k~f0+YwM2Wg*=fr@%H+#CJ+ zWi<|Z;`8*`BUx|xlN$Nl_j28={Xi96As%I3uwKWuydu_!Shm+=KYWII)9pnM`8`a3 z$7p<;j(g+RQ2sg}%L3hkn*9A zr*0!G%POr3e(U%3Fx+PJYx%YhD}RoeqiQslF=!KiW+*?M2ZrQ{ypczJt$@7u0MTFX z7OWp+VJ(4c8GK$}uhBw%{q#4L(8?kHD^lLUG8fy?%fBr9L43s)Sj!LNpS~oVhoS9s zd0;E@*4Ajlc_2^ZjXaW9@=V@)U`=5V`QLw0)>m%BGkmY;+LHb|^U3{^55H4NvlrG4 z`lj+3_67R0nr~}?F9hdP^!6>LQZ+Th=iDp91mJS!nEo@~6$ymx^n!lcLpIo%gVQisfA;wYSKiw?EW_)K}ULh`wMEQPFBh z_6Mq7Tb~-Z^3NgNYqk@{18m~=@E_7$*cxy6y^eocD|)Y$(kWycx{c@|{T9O8sv4#t zp>~I3ecFwC+(S}MJs!yc@A-vnCY0a5*?#o0N$oyDz6I!auD3UheB(pcyr;K0^ljGt z5Mmnnq@QZ!>Wa34zSM>7Gu&pvudk>4S;zJCH2Jl(i(WI`+uppW>b3F024XSyIYQA+ z=#$QGGTml$8RVOVHV=Q!a?zDke501?)|by}c?H`GyquBbu$~ zdC*Qvxt;``!ui+QPmKM^e{hXjYyYn*J}Y`-J8&Jub^97k(nJq+;ZGL{SvXeZoHXsf za!Rit@6}XnwHj*ZhC?A8hwMYoCp_=4YmI-5Em8jLzsNIr@3#Fc`rn`AUKaW``m9U; zh4hNr%#>grqTeFdW1$E71o7LW9Og0U8%R46ACM$|r(@1Ku9l*&Msc=LlFjJ%wf+nI zhx*^2Fn+-JZQGek{c^CU0)9(e#~=UJRq<0`9wB||dMzWQUrftRL!@1)P$Nm~hI?7q zw^m7LguM!%|1O)6{DXCYeh%b~Jd#)POy05X{$=Lw^J?gezo?O~=3$=&{k<@Tpzgx- zcRhB*XC}UN34L36RV~S>%GbrWIM%#4<`}c*c;WQI(=P2AapZ+OkvH;4Udc0g@3{HY z3iuF+J<+Z>J{ku(`FzM*@SHyMI(eUbrA*3qD6#sV{vG2kSnGZE$Jip74lfKk>Cy=egTU zeYUuC^nCPu$pd*IPaOA8G*=bpd;lG#RJ|>WQ|-`ocQTantosBkYH2 z(Pg+A{#@>LJzr9q%#(SO2l7Im$UAu?ujHA$liF`MQ3=1_=6%XW{S18pzBZ^Qe2+xg zuZMcTNBDZ4E9)6OU-Cd+$P;-B^8Pk?*7*;UVGZ>{+hYA-9cSChciCTX%=$k;%!_$4 zZ}LE1$P;;ExfkUjmpJ+b75?eH`{5$+wO^=Kha`@=c}X$-MP8Qm?Dwyz&}j zKn??0=l&c1FO&oQw9-LyK)=UNOV=a(a9Y9t=HX_GbKixZ)EWAPw0w%B`A@;uC0{4a zk4yLG`kxE+{3X=+0*~aCJd=0IKv{IT$_nvp1H7}V`C{zDed?t6S7AS#_7qHLwf55J#|cY2%3S!7!C!4P{F0ETBl!Y=; zHp*CB8Sp;J=@M*7VLzn2OMfEqmxE7&<}-)9)}DqR8~o2!fuH5y!UyeZmGUI`U-%Ez zeEtX6)A+9Vz|j|uK5_JoOPKtOs&m^`_;_s+pR$@`vsKNkwb*mG7XE6WtaXa_YTdd) z)t<0feCz5?-G%*#&%^(2ANT!$Z>q(khu~NDDfTFSDL#9xR~*B>OZe8U z)qU&WlLlWiW6-~jWx;ZwOq7i>7A=FI&7Tq3QC{>nWSLTC6ZTjdxet;)ci0ozdKvVx znDYJ|{$vML(!H-kPWT5-c}8TbK4Q75cGHup%D@Gx5`5_@^nO5m@M7U#$Gw>1*Vc`G zc!jAv?uj2Bp5e3NiwFO`O8p)df4sPxm#7+}SD}11iBBH={kY$=`TX}$9-lxDU#iy2 zzkzSw5Afl^zIgZvihmx;g0fI1)(grgb`Vw@!cwm41S?#;!$~?@$eA zy(r~C%z)Go)xXE%05j zY&wVV419`CC?nErv+OI?>d8-4i$~s5P3FKi^v*qkMNkuaXXD^=S!KW@n$KmJ{LvY= z!#^rhcx)8{-{Ork@4q@wGZFwfl*{*myNq+e&SjLKDvQ!$o)s@f3vL&B$$dxYyw z+M*i3CzAe_+;5z+@I%cn5^|f@ey^+>PQst@EPTPR7kK;6Ao^|oBL17^jX#Twl$A0= z_6Jc8@3K5tKUhZe^K@*7Z{$w+NYY0!Nc35hJ;vCF>D-3>$M9#gZ9JhY>#$FH)lv9O zet|OiM5R9Vp{hIV5y%Qr4giyxS7vgjT2%Y$NEu zXy1x`)bPioPb2p~i*F_TyEGrmU`T&E_!|*tgL|bt@Oz;*-h+CJ@z!i(;s8R8Q@qP(UI zl!Y=;Hp)m@DKlkE~0{q88n549xT3d(>oQ8vm*St&DQ z&rf~&M1C9Yt44om-xBmyMS0PulD?|x;$ula%aX~5eTh|*we^x1?18Qi9}~_mH*{yo z{wvOXa!)MxzEQ5Y)&pd3BCokGU-xO{Z_eY!)VHAySfqWR9}4di^MgLrw1v8zv#y&r z${_xsv;p|IQbx*3nJIfK`st!RSmF2Q+zPvT=2zuIoe98p#NSo-buA%Gf9{g1>F6nZ zm9JV?e0J$e7F9vBTfHrl5WYY$arA+`Ny;Y<{z4UiOVb$Z<&_exvSw50d8z;9R79m( zntyLY*jI2ptwHZ81wOGQ@J1h9%0O8t6J?`}l$A15cKXViFwV21UbxUs(vLO(-3zt= zbl#pms-;lV;SY-J(U6z(!ra$R8LCvNqJ|6^qUO(^FZ_OH*HHA{Th^fHNxZ>nUCBIqC1V(g+)c@w^Ax3B@qMA;}K zWu?sGCk#vl3)%z6Cg47xe)#cBI-YHhaw8T{1~CXqAm@?~#rKo*$}&G5lw-n#3F_Rr zbLyLKz7gNxa&pr2uUn*syZ=x<6F$-qSoGEw&Nl8h{=kux6t5=I3 z;#+UMrJ6NsCeLzzw#@y)mYA>Q;nzy!k9<=G%0iha8)c-dl(`LLZ@UtB78vI`H~*x( zJK+BZKjilCrO$v*spjunfbXE=JZRw+6_@G}o@z8t5BYmP@x&7tRw?!2haal=_;`t@ zT%UgWse1Y4mj#nSm$^#)Hn5kPp)#QF?~x-%#DBDP>(+9=fB*hc24~LTJFAW6$IJ0T zbV6H+FJHZ$O5b_{yq3%-WuZ)zjWSYJ%1qgfARESq?k({9LR>raX&q3fJK~)JUuF6$ z7bfG~J0*YGJ9ST)`u6QBveSQA_gAJLE&two?>*J1Q6qVdZ8_Tr_6PL6su1QkN&nBh zygYUM_;JC9V7hD9u9Y+nA3iKT+8jr*O^mFn`Pe7;2VTQp0l)BXhAfncvQb9LN|`CU zY1OHG2d+K17kCE#hj^yr^OxYO4WCx{7I%fe^EHI~Rhw!)zr|X5Fz`wYAi4-MUG-{5N>;V0nh) zDemFrJ_o*Ine*JWe1dn%Kv^ggWuuIgl`>Oy%j#44&JE|34|{3aVN8+n>_ycX&vu1R zZ#ce(j`P9L`RMB!4^?VQJI+3jKHk(j|5#sjS%`b0U$dP{bPO*fd-&LZ>w|hfU$bV- zQ2hb0rliY%D_5?R^yp7V8_?IAE7olSALL&`xFI^fl!3BPCdx(`DJx~B>{gHqd!YQ= z;CF|(PB|A<7vO!+r&;qAzlyLh)o*{3@Ib5)@=rfPwr~31x8Hsnl3ABM24zJb?QnUE zyH04EDK?_N$B@4C`rn>Cdn9dQc2Is2_f_$^lrfK9!z*PF|7^%a*(f7rrOcGw248az zuG8_YkOBYa&ctZ8IQ_&ma^9aK`B$plBBaZTwY0wJhaY|r zte=R8h!F498dy+A3jDglLKH z+a$kQsa-?zYkLRaSI>Pv;6Wqe-(-ZIDNWYm;^?EK`Cu3HkCiJ|*7oqA?`PXb`NhX7 zlqc*0{x>~#o(%C!87K>7qHL6rvQlQs?pk*`KY%?K8TfYWinyNG2at(p`vOal{{H>p zD<4kP8f$HRBkaG?`6j+yf!u84W28^i4LT=z0{Q)1DE;!)#P%t_ zj@{F8&>hM$ZKbO3>#JIgoEPGmGEf%EMA;}KWu?rN-JN|pKYh!2)d}~y<-q?H`w05H zbXoPsJH-CsUICr@?)^#p2qNKIrSn=Rt%r=mbpGhmOP>`zzPPX`4o-2;@Lp)YWtg0L zJ`u6;@@>tz0^V!hXL5+oaK3p>Stt`_ql}c5GE;UBsQp%~neT+(+H>%qmAw*|)j;_4 z58{3UU?Az#ajCWj&h|{_nf}*0PsDx^Kcg~qTgN^s^uC@>aUt;*sbifu?$h_TaGr?% zkunyB{0#yFLVW7{GNcTYrQbf(X~;$yDJx~B?B4ZQug2U-*Iih9hyQ=lr^rAy%7K04_K*IbNP-dPL87Y_`R#w0X;1G41b5~UoQiZ7vDd! zF9u~J`>McGf+Zuwr_Qey0>=unP$tSo87V7ertE&~)yTkgH|&Azjr{}tfORzpeh*+^ z5eEy@yysZSt0=ZuN&J^|zb59wh0|QAWy2 znJIhvChXI}o}HdK@PXJ1|5fgFfxX;}Jq^RLH{%xW(FjsQUmua5-}xoUc0Kp0cgn=M zz>=QV@R17Yeo1AZ+kaiyzs_fPNEs*#Wuk19k+M=|%H9st1=qcBum1}dwY@UHwB??T z5!l;73^JYSnz_H$Abaw-?@Gt|DoKWt?sHE;Q7pEi&$5r8%n1xQeJRI<}$gQ{o;OkS>1%M;BG!(q8h__Er~+<=M6q`;c-|2JVBo(K6tBq5V{7 z>%!&cwYIM+3Ui2Y*h>X0#vq@C!eALtCdx(`DJx}`ePWQmH}>oe+)E6tJop5{KM?kE zE6PpVZ>8ZN5(}{o{8eKrS5w1xf2(}AYxo3Jv5p-sAHUnU-o-Ya_@3Nv5+471u8ZO` z7L{Kg`!;lS6RbuZvoSoR43vd3Q8vm*St)au;6AxbTo1y%n_te;_L|{YmS^~WE$)}1 z{2l(ZPWDiZ+>?v%yeOH&CLTk$TwLp8|Hi&cx8v~m>%G?3i;Bvv|K`3f+P?d?1=sBB zDzv`~vW$gH+@nSrDJx}`eRkX@$bF9Rr5uhp?gJyH{CN7)ik~hq@HBGW`k?H$(tmSL z7W1#&s#_uXse6v^NY^WCanF^6S0j6xVgKdu4aoe5Zu%s|qt2TiQU=OGnJ61&q^y*= zD`clHV_#ek!M$7d=V^Y@cy@yLNz-2$7?eSpNFV&L-+dOpCi!y?yr`b*d&bLN&f?^{ z-h0LECzicUnDgQMFJ-Tm*sKsw;r#KM`{O9fILM^=D(8u;lv#X8AwPXl=}S8zC_jCh z3w+(VXQU)To0y`_Q75#?yhhi5r0#P+uWskzVN|VFBDcOSZoB2KQuw3pG#`1&MENNr zWu?sBgFdt(KYZs$ypktA*?g8h^7LQV_F9DPdEzB_2^gj)uMgZ zpDk)XH7&!gk)QKn`Wi5GPvSWZ;rtZ6rVRQX2l{?fM(z_3`Qbavy(WJ|ex_gFtbK#( zYdX42rG;!G_449aH@rMp7IJ1ukv=c7n!bLd$#jv`q-A^JnCA%&yZNz;Wp1}`U+9s+^bXH=$GqucP#rqAwSE&GVBhGKVV!HwdHWx z^lSYr6V7pk>z?uKJHzFt-RtXI+(+AC7V)lQ)wuoV{?EvN+kuO!dK0Z}3hhM?tKYiZ z;bGYmtAk~iQyZr?-9Gc{y!%_%c0Y~8$?$Tz&~r?DwyZxcVPo( z!SAAS^Eb~Y3YT49*P^WtUibcW$*b!^56jfQ-v8fV|EK2@9_noY*G0qEJmZ^qN^Be0 zW>jre@U0g^Umsvb(C$0W*>pp)lc!SUhwK~!72E$|%*1!Y<+|SM$rwAd=%}sJ6C0$F zPh0n;{NdxI@OCmB3tr~*f__ep(f8dD4?3?RKV;#UrfC09*=76-jAMQL$Gu@P{`mv) zGjHy9Z0zkJ`V$;4?D?%{8Kij4`EtPm2WA}YUjJU8?elyty{%8n9DBn$C|3Tk@t=n4 zO!?1X{LlS)9RF+kBq=|~zc;FXJ@4Dz%u`K#8ommBA2?^q^_$8#&x&F6v#E zJ-N#;*@Ld9b)z9=pe&TBV6WmY!To-i``mU0-+#c-4%=hNbFuXC|BdFWzc=aa%POVo zaIpi9kJv7RrBPf;P|RC%tp!57~Vv|DgPoNtd6pQfA7Iy?0l*4{s2# zzPY!M`yxYoeevzYZy!Ca8x5%g`zT;kLT;V7HcsDIu5rcGvxWS=+w`5FCIfrmM)L}P zkGyk#Hg!pvC>v#@tdyDi4zZu`49}I|-bCV_j{=U6hAV&l-$3DcmUhjtTSTQdY`L*|C4|UF?|z?hU?yi}Zm~2gC;c zJ$Ar-?2(Y4^QN^i=I2>pv}6Vp0ZI! z?iZ%akp02-8&0`C~|)b=fHkWukpkM(#PL%#@@qUe~kNlU|``g8Wd=B=Sn0$vb7BEYy2Y_DhhxL%8hvHSTw0+0Z^%N7zpA zUBL)IIvh7}oXD{<)BZn2;EBAENA~aJnY>d5%0iifdM|eWYgidHVBKK*z<1bBu&?BJ zfnz3)l{t3iH`D(mB2VOvJd#)POx`I2WuZ((ZC;nTxDd~_V*h|Ldza$`juVlVd@tzV zO|U1KKjj?i{~86q;WVDK@jQ9e$2NK&SDcKzhkoe4fBz4c0C6JbP<~j#jo?I-WLNrq z?6HjmIk4w^Cia_d2Yu9R@ee1k@AM+*3UC^(v{-WD3NRbWBFM%4{W=utxGRj)uYXS%o+hzdZh*hy-U;y+ zo_^tLVp^oGAO*`2WlHQ9)*sC_G@B@73(yU9L|y&6>;P%8ou3XH`vq+e&M*qrbJlO_ z92f(_qb?KVEsCMTefe^(8qZd{E((7h*T8m2!@lMaNgh0lttbKOf@iFefXAZ|&uil~ z!|S1<@8P$e-Zl9#f67Z-8SRWXo)brYg?_i(;pI~V69`y9;W$7nbCx}IKoN2p1pSrd*DgHD$?nx zZ-F~h5`7blBeoHq(ch5}=`cMI(-#aR=0!sOX*dT^_z}Kf z_F(yhaG3C$Wu=!}o3*$OmZx66#5!ReW7!wNgo1AL_CV_wj=w}5-iQt0z2?yUR|R!m zukT@cr=6od3x7erHM}P5!_Ouz3qxWo5nqa!OT_HaaCijci5OGBU23xixKG5HTFvqU z7Su|XD{+{<2eI6N$MiIHcT}Y={g>cQr7Q-X6mX{mTS{=IfI0QpXCUC%;H<+I3xMad z;A7SN(ZA!&Lee4CZ2m`K^dYXpiE-L9@;u*r^kYd!(p!l0@RhIwX za9-nkswvK)lMJfBJVTS^!*VhL<4Vd5 z^+m`0D%Kuo3uqq-*#UG!U2(i9Z2@#hT~eplV*|l9|DU?wVy%QNQnKx&=mB z!@FKqiFdvTeLOEZN&qHVor&87Q;pba#96BWtg7mxR;qa5l*Qljw2HfVshk%|{H|(4 z7pbbGAy0rF$2pXbt15#Zlk+HfE%$g|;-8S`rOtj?HG-Wa-FpBSUch&o_bzPXJ;?VV@YOyRc~hP|4Ecfe zhH_weuv}O^g87E>(s18k57`CwK+G?mH>%l!-mV7wi(q@u3jKoCCtz%#_XnB{{IjgS z0P&I1-*cRYZwyWM94~8QI*#Mmhw1HWns)e*0*IAVP8Sz^8M{R+Tm zBW4}bW%|TwV}3l(l~{N@)0Fl_JBhz#nPAz~9J>yffE$4!w+-#gPT1{pz*KutX5_d*8{=#BUempX9ax}yVh3s@JdrQK(*sta=pF6a z%I_ct&XIiz?cS0va6T>C!pEp{w&ASbZwuC5!@Gd7HggZ^_3og)HwuPg^^q$C4^Hat z;DrTx?xX3LxOw5&gMu>{ehx4(_Ja6)e=KA=AY%T3$_H`#Xg^|Cv=On52Lu;U>;iUK zZRiuQi6vsQJiEB|xDC=))Pp?`U$7zY?UL?!O)&nNp?zopyu+3Y56M}?tx!jZN!S|g z0?Sd(C0+ykL)rn#*@QMB+zzCVkg=6EmKGb}_)u&h*cWg-z_|kGxVU}*cF~C64V+hC z-=X*S{J!D0jHdf=y=!$|c%f|qm(U0v+pdD$0#mUy>U$dOId$>pD&_HisFuL-Bfer& zUGKAldIuh60@~2p`DM!kW}|{X6s=-Eq2#_Kn54 z%Qvei`_KX+KBE_V|2j49VZB_vPa@BWIz9!&xUTXu;3;Ts@Y#{i3 z5F8Isx70CpUDO6(7wcuL&vsuQ>%o2sbg!k)d`vj+nr*%rIGTb*nGL%HmZotH+AHwc zW(E2)oP*tJ$v@>>>g0tV!M^{dn$2T7|AuOWI^O_wpx*5`cYNX&;ES?-N8c@N`y#Df zNBdf_?>s5XP+jMF-g4e|uI66 z$TmGybi0Ygrmy9x+d$EF0c`@$92cBZ^c4dimHtZFgOSSx@39X0HR60GPR|M10M86> zj<%6?CFSvtRV&n;w5PsQZE&tP>y&XdFd1>aw+ZFVayM^4`Sa{?VBVO7I40n@EZ7dn zw}FNcOP#V$mwo`c4%a`&hMd=vc3;MOTA#1!UQ3VZ5T{7?|{Bo3#XHIB2-i6u(j zh$q^1CHk*rz|vd_{R3At`LRQ=Yv>=imc$or^rx5QZ1noKvya#6evL7!w7NeG7_&HI zoOOpdvlWRm%f6g_a~b-NZa*1#tH4gG4qOeKfq7l}z7Crx2OOlxWj|Z6F8{VQ9i6EEH9pOFJrqi{kyrgu*7E*EUCi)U>Oi;M}=eUzt!IjW<5jVIhY`NM^ zi(uPm|Ix4f+hFE%XbUyn6K_^@kGh`<-KPb0-xh7DaW!-g>|53`%Z5`Z z@6*7)MY(SV)|2P~Isx{Z1^9Pnkcl{m&>3~dxf$w`-vlyO2pv<`(D{RG15o!d=KtY4 zoJ}v|ea_wU8=v2l@_mPNh@ETR^fPc)HL`8}8Ry#n4BS!DkGKW_cf}^Qa0)n-z|+k} zI|Vy1u0r1hT;0}B!44L~4j#vN_tE!N3-oo(VDF9Z#rHJIfMro1{Xt!{2X)48kT#Na zC7!l`u~bzV>j&F};5a|VHC&a8PrMGDmlMCV2%I%7IK4RYnD{y&!dY~YaY=%=CD=^Y z({{k$HL@A7Z@b(nZIo8mAA-$3BHsjYy3VD~XMNu&c3ywlZn66$w1I33o6UPiwVbcj z`P4<4-rFquQt*zAtG`8k2j+2huHgULHUXO#I%iq4-0i^ovIECh(+BV`frCpOS)eOo z0vk6F6IPoakU1jgR=x?falkjC`zMaunqyqp5`6>5d>k{f-EWI|1=VcTY$R>tYX`y)5-?iVk>Nc_{t{Of^h}L zGf!h&vjpRtMIQ^!aZB_K#5`uZ&;<671bb+B$MY(2+Ab-xgxfZ$+Nd`*(MQlGs`kD| zMb%9%Rqs3}PH;8r+d`O9;d?MjyXIa@V)Sw!uD%bwr1rpo@j`iH57_CG7~ieX`gV+E zwK~rJ{aNUHk6=kRx$iaA41GLpKl#!3fO~uhZR01Z_0q$@K0X56LSQ{Z=fqwnCbbQ9 z-430zJRQ)v17|=xw*%u2Wi4ec!qJ#Z1e@{!B@((`Y5oyzZ1M`>xNvx zyk;3WwgBfFI6f>pmLbd1wG(9uj6XNan3&yC=0O~6>H<2UZm1){1&7Y4JL-_SlzsrZ zO@)s2Hh{W^9c*v86gctAfR(;N$I0iM4*C?l%Ql7h(zGvK_wHT5p56_5R>Pt8>LIX5 ziJz@uiw7~ZgZSdawiY>pHsRa~o8AgJX&0MLh3vu#+qa-h%)kLRt^8UUVH<7HUL;Le zrJ`%pFIMmLIVNrt>+SXE^N&2kJ?h%Nz2e80@t#2{?TL>B%UpCUbsCuFkjYA1^YyvF z=>?WMWTxya1LCez*RG(hSysek7YuUZkVDrV;*yi3j9JbaQ3uoobrP}xwgb=^bw?di zm;5G>HUK)NuBmhC9`q60{#3O6X=oqXVE)L6KEn(=b@n4R>YwdC?21_9ZrGWod*%=Q z6N5Pic-+J#2OhDI+~a-5>%4+@%0Z$`z-ttIb=bAo2C(~FXxm)0d6oz51NFeR{F%5koe9ofnL2UgNs`dQ0m18s8 zZs-@XP$tSo9lKGVH60h=y-S&(Y*XtgDuBmhCz6Jb=QZOcL#j^s?KD0&KPaJjH4Kda2Xh+!RyLLeLNL%pp zVQKt0juIX>r} zd1A0|e;xOkh3~i2b*_iRs<;uo{+@T({zS$%zJ^!smu@uVUf4Y_%EM$UxGvD;jh3U> z0NddrZ2)yf-BE|sC3Q;OQpeOabxz$UFU`G@ivA!C{!wfnOql1fpuMo-dy@9UaX!x% z;5iF=-DkbkY!vwO&}{%%^#4vWE%>vFtXTD$^8EkUI}b3+iZcB(InTi4oOA5Sp(iJX zFbvGVkaGqR!x~WmQ4~=D$(bQXNg^U5=CJCYbzRqWSw&?P9g@TW8m#~O`>N{PI=64? zo*rg!>F4>LbNb$MPpJ2Mzf^Uq$kDoKZPxy*!?3)zxp$koE=5ytFFuy_9d-(H_^0-& z|H>n^R>Ny8+D6vi#w%}E!DL~y0m2H*zzz(-5=_C?`v8sM5awWyOuCFQEA-C?{8c}| zZp;n%FVOl5^*ZN5*%$1!>9cG(Yf!W#?wo5zDeU!bZI|Ko#`VbSTDHaWZQv*3JGm)# z_zu?VNIz@tKDk1vJfTnh2Dex-PfNF#tpj3y)%#K~0xK{Be=zhuz~c|bU=8MAFFzps zHU37Q)#~43_iYUo;a_R}l%{?+>np!##Cz6)=wCGF z1onQ&yd!OXs$E7daLmPx>^y9?)*o1Ab2JZIbdpQwSz`VP)|f|c(sj+j8T^^Yp_Fbg zCo6N&Q!8q-^9a?ChI!Fi?#xwAKEQl!slMP3;@s`29q2V@Pp#LXbvRhNqoo86;#<%G zVkuz+R$vBp;18By3btSj)*%LH&{{DKla&+V7p7|*5^KoJR(*G_{Kh=3leIuKhI-|k z3zg@a4U?TQ?6vmBGCc!pv9yFN*z_mYp?AKP*IMyCYsy5fv+hohp|i4eRnoRCwNI?j zR<*ufQ}@lq2sS50G8awP@oTed^wZpSmhWqAqE;PyH1a{Eu0tNeniX;WGSda=MDe^v z{I=hc1GR38)~slub^`-j3kN;GFB3-#D=-5)Fa%351zRu%YcL1$V%(Qqv9*(=XRJG8YY4Rv{!27(ard#z^A&xBQh7ApNoH$>#EPI;m*20TxZy@Vc8lsrLMtws7pkjP)Y~J9P_2>Ydlq0 zpDJrVVPJMxn1Br!ffbm69Tjlq?VNMYaliW2uWZetJ@?$R(YZJ$Ya5i}Jm+}u!3W*rk3VkfwHgQ&E#YJHPHzWRF26kXrj6Ya|KiE&XY;!}M-cjMR*@_S6Do&g)U8z@}?xKMIQsorO z6kBrs6^i>;iu*|Uwdu;OSy%Xc*5|*ic1ZhBS}EQ;*w$K1$L_Rg)5hI!!ws>CZTreA zTF*-B3a0JI{=$U|Z5=V}{{s&^;LbSX3^!zmUrVm|SpJV|I+psbU%!6tV;}pNV_hz6 z&UM#a=XTp|w?@~TJ$ts>ym@o({_q#*M|xh?voRgeTwrnjyZHU!-A~x6wv2dyjn@JB zYI1eq4~Ad~reF)kU=8MAKUFea`!kgn%+c7Pc{*l+#&s+Nf2}FU+Jc;mbp}@m|CPGN zD#O0Pt=8Is%@Nk^>pI-8w-noewPx`79lG_)wcF*FU!H4Q{CzR@=m<8s`0u{^?z8pl z;x*DO>++HF6JL^Rq~Ed6nw?-?{CC$~cQwLx=FFLH%a$#umyjx27j)f(h7o8z5gT%)kx|!4gct7L36f%)!16{I3@NdY@ySzFQFRU##CO z4fwCnxmF5)xX(3qHSRYL|0(akI){zTuP(b!jVHDx+Y?SWA=j4t^P?aAD0d9Ufpz?2 zomOfA>3QOQwKYo70b8@S=kSuh@7uSp<(2VTM;&!kqvP(p^UnBnw*B;{^K-+ownfwd zn;WyJ)->zW4>VZ^Y(3wAKNx`(n1MeSf+hHaEf|9}n1g-Y6`LDoYJX0^zh1{I(y>eQ z8`e}^u5+x^xmM|%t99;Oh5s5|tLz%O(#J;Y>c-Ecr(K5Rb8^<%qwV`n-XqtZKlp(b zCMo*6^wLXn$AIm+b?fXX@^E~1#5>*Ax<)JaVe6a>npW~W#2M$Fd#QtuLx|c0Kl5Z&cUYjkQ;` zer{7__E`_)+M-?Oo>^U?8hj_1OY_w@}9{4)`zEZ&_P;wa&#l%WHJ*-E@uJb**x1NXPY=OKtnk z&2zlZgk3W{SaU135p|wYe_!~*7qVmGv6Z&XU86VZ2)3zIZcy%;#CxUw_SmEF-1I4> z__H6^fQaX9-Jz4_wfjS(HLpvxDW8D_n1Br!ffbm69TFs9wM<0E3_It*v7UR$VjAu*F zJ!r)tHMeiXV|UhqHX9)PSrc3MgCSUgDcFKPSc5s(&rI;I*LREbUIFW9FW0!tm0x{D zc0}vO>s+jz&be*DZXX<|D=-&v2Cliol4?w>z%f4Q+Phbg-b5^MNRE% z>)FG}fInD)8Q6g#Sb{0of^ozj>=CUO?&eD;7V2H1#o({8xGMtwtS!Gr=h{u@WUcjx z|5~j*9@k;7W!rsZKBh|hV!@vF%b+<^B; z6?2x7_U+p{)`>6mchErxWxrueLgYWbzoYsE;{S|QNYCAG-kvqJF<9&w@CPHX0yD4! zf3O5oumxkV26M2Vb=A`ibFY2YEztX%ixeL&(K|fL6fa^oR%uOf^k_HvlRWlXdtTgM z_t0B4$%<=!n|rSIU3)j;r}giLwq?Ef;=f=1@|SMZs8PA|q-{mraM+@jS);O?4p1+o z|2VyFx<6>pAXmx;P?wI!weH+2!@I+XWj0=r_X*ndn`&!h6t4re==>j6ZDX)lt2iL1 z1H|jt0AXl8K$wCp7=tyKgZ*sDJnh#9{FmyOJ)#l*1E%kr;ZHl#e?#5%@fH0tFOAp9(ycz|8af$r~`4G-{R*=|6h3SBNf|uZ(-qeKrz|ZJx{?5?7$E#!4z!4 z7_8?BbHo4YryJ&Le__CXncl(S*wx^FkMO_mHMfV(wN`qym(IOT_;bCz9}@oG6#i9Y z?Y%F!R&D)yPdpPox>VcJ@0<3;uV263&6`(x{D-xT`hwVxNoWwQ@Bd`K9umeM|1XHjDllLr(TXFwiskUH!tsz=t zs3~}Di(@+gu6R_F)LC;e#13NGTOE3jnFa~Qd2YaMm`-}D2GJUr~$E?<|YxJAl_1isl zj=glQy`@+C=-lgdjSadM_p-0>uO@wpeE+b8CzQkv`=8bT<8!Cm4&4V>KT&h>9KI~S zo_BN4!|zz*Gs94Jobg?4dKCIE)BBG5=m_rCtO$Z=DOh z+Msjqt846M*uUvEe(SA@vgVp!=bj4;i*Xw`W24qsF2sjvJH-8+ht0|QiHd(;>;Jq5 zI$*wEm$KI1R64GBE#s8a?FMMtSxyb_ z_=ByjdD}kUx6AYKerWp6U~vvO?_<|jY}ev;-~U_UqUnHavoOL2fEn0Sm*}Vk*p8Ey-570Fa6#kWD=+ccjTzP-5T-&DadhmWmy2f_7-!$d( zf%A{EcYK@jn@Y#lg1_m20*jAI34fUmEqE?TnMpuh_1|Z4MSG{$>M;@CQ?{ z1%I#xbFiJ~h0KI}dgpdkk{J7N1mBPby(j>AUzYc&QwK*s#)X zOMREFX&&u(xvkF){J6AsdS|%!xZ?i*sYjhvv0aPX{lG_Li%kdc&G=~90AU7pUDY`_To!3^xc5G=tI{J|Lf!5r)tZhEF+spf55p?UjO zD?Z%qu9w`NiWm1%+^~;+yFqqjKlzi5iY*G*3wPQ6L%#iwvU0$KFK5rgb9L%DtjTR$ zD;BjJH)P>S*7n^e`S(f(Ngt@;^qz4@v+gUMTc8xCP5G=C|EY(cUbbCJwK-TEgf9*{ z09IfIc3=pWU<$Ti4Ax){_KO1kD>Xlr`FyRXi%QRj->KSHB^z@%oib1m4`a!jn*gG-zbsFyRfwwKv;u6*dxodze=C2QGBq6j@e7c?ycW!&~NwCIri7N z4v<|rQ1<0uUE>g4>rh?uFyUWL)_moAIsD1tYr$z-9Yf8YcfC^_2FyFAS@&eIiu5Qw z*VgP8<3COOFW0W6J_idh0UIy^D=-5)Fa%351zRu%YcL1<#n(U6uv~MsuDVV5%RlV# zRpBpxv5)eG4G#!^`H}tQPdM*E-xB`vHC*q|M}_})gnt=Xa%O(49`AH+D{N~$ZyK{P z-w!%b>u=NJQd_b$xX0gGKVstl>yAFFY`d0fZ?FIpumK~m0yD4!L$I_MK-gLgD6GL8 z?3V=mSL?Igg#Vs8W}Wa~uixye-)_`74$!#{GVV7>&)#&08Ta3EhYS01vfx8k=J?-t z;%?1q>$KgscE8WeLo?2j4>b3DgF`G4@!Q&M`+>7_Z8iHn=ap^OQtf>hTr?XX-z@yW z3e3O`48ami!4{0c8vMZ?S)qMC+g;zS)iHY~`0uZC92oFFMCU$K_#duo9j7Y#{$qI zgOpRESBE~*AU%829bwqN<&OOBKgvqo5vS+yA2?%w!{7X{-myyOb&B|G>n+#rs`&%A zwjY3bWg~vwT43Hd=8B2AAKR6myRU4!mTL1Oz9TN04UlgZMrH$q8Q6g#Sc2(VVGI6X z4d!5<;=hN!+e^pnqht5gZ#E|Qd+s+#&piG|>Y7Ih|8g?*pnSi7oXe@t1pjVk?{OPtQ-@w>8}7T+A02@u#jB_nW&d9{0QU(jS*?*HY~b7T^yy;BPh{;17mi38r8R z#wq^G;J@aeUUU23-JW;7=+^0&_2B=&tFj+kWJg|i2S5CVJ5>BX?Ar~x&YOkg57oI2*Ex?!@IPADEOjsOv&lvLXWU5NQ%M^dG26M1qA=wrD@A$jh>#HxieWWA%N>}#( z`m651Z)|Y~fAe*B*tb0XM@lb``p%oOO~PJstoUC}ChwQG|MB_K?e>TPw^nbMdzu<@ zj3HvbLgaE&x6BEXw#krryOnLza%~M3UI*lxg%S9J8Q6g#Sb{0of-zWwIoKQiw?60g zi1^=I!2clq_K<+T=YE4bTKIeH-*U%&{~u+g7W{jTUR>1&P;1#*%v$pIePug% z`$<<0kj@;e-yW)S9IkU6sdJiN(lw4X?!V=Z7yjjBN)7z4rB8@DO>_EZTN3m1T*dF2 zq&20ca-ZXQA0*}f(vMwTwoS{mHTZ+cF~SCnzzWR34h+E(Ou-h6BmQ8&@}_4R)(HPS z@BF*s!x!BK9kcOk!v8_x|B_;q*0BOd>wzoWS1yTV`BJ5EyWe)zmB{u&1mpO+Y* z+L%satiHk5ra0^<`#q-}uvPr$eX!UbY&Trl)`_&)P-*B zu7~EHxBs+4U9cRc-6rjm&D~ynO!ULWpTAxIr+o^|;eV?RJ+k&_)4r2C?mMrSZPRjX zjZT;jBsKv2!43?;((o6yU=03X4)ziMwRgUt@8tV+%>Jqu92D?BTyf-)iYJa%Zh?Kl z&K$3}k87T&DSFDu)FS)eR&!b$c*}pg)t|XDdtUUtYyXK={X4PtE>jzi1qAzkbB?U~ z`)#QUoyO+-6q}+0KK5&swMW0n^UJnpxpwArvkAoF0e`RpGq3}Humn@E1!J&|_^-bC z*@oSv3w*Xu!2bZ{3;gC#{q_i*<0zf$7@hN2*?#ow1YwVyq-&RxsT=e0fBk#Uvty5a z_$AHXU&wb_w{5RHu=0Bu_yF2X*q!+Ox3XhLE?J-HJT@TC0amH~draA2{rA*cIF5HY z(216Or=!yKOMSPswO`h%Onv|EU${SOqjK$9>T|F_2fzl5EDj_Fuo&<)9|H=1umxkV zt_AJ%$>exe+H}Kmdb&iPt@zSjmq+?v`Bwe%kKGOfE1^d7F z0~a+q?u18Q(>%Y0v7yZOT<*QV6u%g2#c@1r)9>Hz{dhmcxYqK&&Ha(s{sB|#8?{r~ zo|X2&0!+XLj3WME2Zmq?reF)kU=8MAzw0f+|Mq}CxgYo|U*tE3NBosja?azwC;YMF zx*qZ#@xPpa|DYL5^-QIYo4W6Na<*@m5euqfIb_kvIlj@C`*vd5{jb#a&pqy}vTa$ejpOGL53m6v!=E~U@CQS~Uzi&HumxkV26M3AR`{Rr$jeoqXYkDBxi(;IKsDUp9lWO< z>4&d&{I>c&)x(HsrLFbxYo2-L{K5{TbDebSH?(S7Rnmc$!hc`s#sSiigQY8nNoS6f z?i?*0I##-bUpY~_b&_=KJ!bp=;od9V+ZtJW?)^FZc}JwuJ3VEw|m zPtkq%962f17JX_QCrT{PlJE02MSqIpkZSn1(OQuaZ`Oio-8p$5P%+@fD}KD)@Zas$ zXB*bu@x1B+FSz~g6aOE0*&U*K@!{Xx;*R>(YwnnDzoD9BgZY({zW=8DjQB6yPWjP4 z+^IiyTP~VI!PoQ9; z_sV|tpPZlTkM*F+VYD@$6El{p88a>%d@G%wIV7t2dyDxrA5=Q8Q)BFRa)YKX*=p?J z&pX-v#~5Pcl|Rn;MQVcEVlHRu$m9<6DWy0w&V+Hj>1W0J#u#top>Y z@8X}tkmGmDj}7S1y}!oUHShi0V(jAo_;2v{?*RF8`?(?3RDCa`-<;aUdfA+gMe{!u z+c)|}PJHC0ckxf~KlXvYs$XE|T)fmv>##)ZT522L-|+p%N18o{`<3zuzKeCIirkmo zZ`~*8vH#HztoY~^xprcV81nWA~o!n6EwMPWi!`j{W%EzL$LWUHlX7NBoHe2dm#Gwi8>{-l#T4 zq!M<;-wj{-zFZ6!$MP2+m;O&*LpAJ~*DV-->o09T>8x`a3>;ZRajIy&bcBzYKexYt5NA z+4u8~Ju~-t)cxje{~6-{;%8s=$?I}$377g!@oNR9yln11e8%V3GPaztht;@WT<7W9 zXOKJop=WbAAOFyEn!CK6>38w-Zq5JyjQGjdez?la&TL&uT`^@KB z+=t(;b60opjsO0(@;>Ur+k(Hw|7?r?|M(2mw&cq(e@^wF*VttxF=m|^Uq5d89B;nX zSAKri;`us=_tu_!-*&;Cc58&cuwu+c+5Z2;{;!GSKcfBD7@?BmKT6=w*sp51wdD8j z`QGbp@XTe6>_G4Fjpq_#JUM#8y7J}hd%4dm)%nx0JW&r9zwi9FwH?wn1%sOL7q&M3 zBj6AArSLyEjQ=?@9sjcf;LmfP@bKSVpRrnBL)fNLN(UHA#ClPs#ubj(P}{x<$I;19<8ME=L|-x>?Xn9#ELKl+9{;k!Ey{aCeY6@1{;@GnI3p4zGDg15x zuQ1P#|Nnb}|0~(}?_(Z$-5s|B;vaQj=fU|kv%#CS<%!`~Z-oDm?t`aWO`uKtF1FrK zvF~S`L8<=TQrHuNob>1`+Z}t_pd$XlE*t;-pyu?j@!y)`?W>yWFMI#v8NL7WoZI^@ zk3a8-9Q^eH{zoVHGqyY(|GT~Hf6AkBz96m_*QP^PuLG*l5euLTrPd)UHIGZ%UisQ1 zza2Pj;SPg+Dg40*TMcKyF2i4#f-N>4tigQEEzJG(jNbqA_;0x9MYq4+|2s&>#`nKC z$FVxs@j7Q?{9CRMGsU#2`}C_6kFNnM<`_)p9ON^k*VyH`oS@Noe%5l-IQ@8h+`{`4 zzV*Tm!TZ=o`M{a-eY6` z2W+q3%YdAB~i19V{S9iZ1M zz5}!);UD#2@u}xIYH|_3blbVt$jtVqHD14tcZd~&pWt_l)7ut(cJW@fW}D()`rRM! z_wW9IDY-uwgEg3gz2t9t2gv$^$P4!?t^w%%!OA(nju8VCx8u6=9@Mz8!rWR>2jZNQ z)Onao1n%2BJVpI@96#%@kM2-DuJ{>?eZRf?6=FXy%VNJ+`$=+tFbDgUH$MHC@<59R z$qR@N{Tu-0W56BR2c&Iu=quz%#He>JeA9_b%PYhoEy-#oZQ{TTqzCVfmH2>@7+g9AL`9rI3dfNN} ze!;&7TvP|Pc>sJJDCU9KfUFjf=|EvlfK*qv*FNvoMeNyj+GVI?-VVm;wrZCjQ^NN< z4;|~U8QbfAD_s|UdGYyP9{WPv-ze{ow*NlWeG}gg=3u}4`pvUt2Q(k3e1O$~l?UPj z6f0UCAjt!=cfn&VAkl%C50Hx@_$Dv$zVq8k&)QPo@qSf`f49LiTzl49DH^ZEF~s;M zeDnG3hJ69wd^^Q1!<-LR^U3;r3vqvz_X$(0`%(85)?g0y%dX$tMtbn1 z`GA-QhCIOL0*QS=!3M-!kn6>K(Ck2%7l8XRT?jTIz3;bsf8yGsbNIJv(;@dixZ~^R zpK!M78LDXn-QD4~p-p4k;_rRD?|Bav%+ec`=s7$IbX>6W6cLl!bfXxeLwIM%7h}a;;2T>>9?(LEH{kaj>Q|w1C-{_9{ z`qQSbZ}+`5^?I>A!92rV?M>T*LB{*g*H6p`X4c;?45QyqxZeQg5&vKVHlY_52dFko zoEYmt<_G8#D6#_<4@mDaJxFu`-Ha0N`|aGWKJ(_1_;>2r&+Yo@Tdf`6&iiT3wPO3l zEj%;62i%GEz#!Uucn?PO-x>Cy-UF7_-{W(BxW6gI-fY08zYUWOcttfq%LT9%(GP57 zUZBt~nCbv|A=l;}$T_(m(}iFc%r>ACIpG-+;hDC9Oy1|DBK%vq@w*@Cj(p(hZF0S4 zKSSCUwx4e=+R#L8O54)Lv~|QC45;%IV-IHd@M!m`_kk@KFB8_q`18N?;)BG6>KC&5 zFn*v|2e2!|1B@xL`9XEPPqFv4UhC_NG5-fkVb5pMi#F1M2h9(tK7_wW zb->;aksTl=WIP$R!0UmZD-=ECzM?*GpHb}I<1=jI?Vf8`Gx?-)VcZ_rd~9qRo%I2RksN))!*F2f?@;{y_)&EWcs%Z%gTb z#RH)>z_rk~s0WM}h`NAX;2sg~*F>=iu_MBqWZP0!o^_Y&GhwdV=gMDf)9bYKGsO0> zZD_aHj%j($zzWPV-V4j(ct2uYZYy0GB^`Ji9q{ph?<0!-06n8lxS#5Z^efY6kjZKk%P4I|$4;nK#mHEmAYgF(u9;(TH~Ff*Gk48gJ-&XqpL zUML=TfS8cjk=zh}f_^cE06XLDfgd}J{lPAnKA;mCZxr={`_2i^@~#xxptyYk&en!% zOOLm=@$}KsmqXioTkknapcBD;dTgGV6*0eco4+dZXCe-i12&}*i?8@QV z)X#OUAv)(KotrU3b}j4ywuZ4}*d1>dylvqAOfQ0NFy@?luP8j<{{^Yi4zv{*Gfp?Q zBlZ@&X=B=&HmB{uAi=!>jKHd?_||&7#fGXKOAnqfzYujnIR-k&JrR3we^DxK3(}xQNU?JQ;+te7ZR?JHsr)%LCrt8`tWE_F+<1yKV zrzBhCe{5W_?$O4V>wayWiEJC@oz}D1{L}Al{d<^M`-Jw2nmeQ$%Xnnk+B#4?Ujmhk-mRd-fe?& zI#5M_QeCtC5;}>ln$CLNMTdWgP6ypa$EE9k>9(zTwWFSY)OmmDAlXfFf!g6QwMT>6 z$VCy)T_zW5Um{L>xk%d*GVbEd?p=Ae4c;ytD5Zn;Se&uIIuyxRubN(X|TCAydMCz<{5cA{9HGn)|YL5L4>wg9ep&h%(WF20@T z(*5ruIZN_FBi_e&z69qz-wRyN^SglQL~(rL<(1@FeV@n`+W)5!J@*yG5}z-A&j0Mk zZT!5}ZTwx_roW4yrCat({U1Mnhiy~cv3)&%Iely7Zwh|NY(rubQhQL!78Kcm7XpWN zc{{ngHP;$>-e213p7HmE7(eDf@V*k~qfJfxc)rcO4o#AtHIgg!StieEzjm3dW4Et7 ztLr1_eT4t@tp2-X%V#ynB=J8zF8!bVO8=+7E4$Ap%&$|{C-N%%0FMcb2WcQZv7v5Y|^#7IO zs@Z_}dHkPk1u>2%-^c%L`?UC}?=ngL=bTq0|J#20fBL(yZ@)?QskH2gugf5m*af2se$Vm&od5zLlw?mqwkw2Q+0e!q!Uw1 z%5#lApK`Ty70GlK{VgNn#gwul?p>Kk#z#20ISBjd|MBy`CCBKq%lSWu?Z?l;md|RD z?7HzfVH?lc=w8x$i}xC~;n^BJ|5a)e+AFq8xweaTA+~jB_tH2O;a7}r_`j)oV#imo zKaFffunk%4ApQ0+LOEMdhzUyC0beJ43$DSrrt)-K9IyKrA)EBG%;$$#Ki2eOzEjNm zi7}Td#reSZM!q@ly1>=Hi?=1@T7A}3DXAmk`!xtQMI1*=@1(C+N0I)rZ+eU_%l};^ zosV2*Kl?xBQNq!TtA7vx+CSppv5Ghqbfn0(gL6}L zBOYH$*X%QYjm(}D*@!F#ls%|u3$mD?$PQ2|Bp=A<1V4j&+k(@zo>SM~N8Hcy{M6@H z=6#5dQa^8;PkejE^@QIM2W_XNa@`AVT2A!+b&1%q&+9h@nX3J%*Ggxi7|$c$pB3jN zS3lE8rijZX(%C6F`J4WiME#EXE-p-tA|6dP`Lnhu5C2!3OyrU$-6Y9GlRvqM7bAbn z%SC^16D1R(T=<0FXIoKzukVY6-{`Zi@Ohcv$LoYG*ET7>FS}RW?sRuOpw)`9F!zQQ)z-gIx54NuH0t z6A%B#jlbaWyqy2vZhVyUe(T1W{Fk9QYrbhKCdSJcjLZX_&xiLuEBM~ zeT>&OyEpEe`_z`_@ScQ8&|!k=1B5MzO?F7TJP;9^U1yV|*Qy)TLTe*6yceo>yE#rmq_$9_7i zm0Eo()>4A6&*E;+dE3r zcVoWrOE2gAn;V0C{xLTi`P~1L{KAbs8~M4(sL%e)W%8MSb)!sv>PDXBWmMRXJnJX= zteS-1=p6ih)MtXE*En0(vulU@;C?=@`;u^d#;}8i-?|4_Gg@IQ?w_v z#rX5R{qXHXTY0-NQ8vTd3bm)=jY*0%qOF)Ln+gWr*8W-eAOR;Z3-}q9vfG(0&+I{n z7gC#Wt^7f%FF}vcr%a-*r8=1Hr@9&aQLqQ-wBiM`2Sv7^v>i~5!1@(qoiMQhs-?rZ zLO$>pVu3GJ<84cPuXy9)$o}!~9G`;z1b$y8-7<~`oy&0>AMH8qc@3w3V`9G2 zxa@gs`VW_l!=59fKlgL-2hMtKc~1Vwjrg?W%pbZDXZ*koKjZsu`03ws!$0+1$#>ka zPa==HVW0T6$}8#s}Ur%!Yn5s76{|qi3Rfcz+W8PYzdB+JBMt{S!KCTyr0zd$z{CH7w@Tq z#=5=v`_$L_Tr16h}SQwo|H}PrGSJPYkpLjj`bMP7;jGvXh z8>htq<8$OPJbpyn@%$YMw*vPDfA|46=tEy~gZ|}yH|T@+xq% zzn}YkJg2U~wd|T)TlX*kdEZ@jUjuc2cCWf;?%ke2&%!ee{>az;Gk)wL$Ma%Ch6US! zeH(uIchyGUGkY=e(?7I!qYbf_6VKM&8vJb*$f-st( zSOVMN?ZWRomS8GuC!1aPlQ4hMV~-9%1qI<9;sQ z*S(U%WZb7;jCyF~y|!6SPyM8kPxrh}+co<5>6@N&)7AddGkYwqo1e$GW53}$_<`e7 zCUAW!7+)c-i|11=BW{#`Fs_T|7Za-oo_|F?1)iUeFONJYekB%{Z<78Q#{<7d;mf3} zBhHkcGhdC5#y^YO_(BA0Bl*&-<`7A1>P%b1VEi`GF@%!91cMi@M&L6JVZKJNsJ?#HQyC?3e z`+>T@gU)k34mw}=t$Ww~?|kTm-u47LVzvXjfekxGHiNdnUIbgwPxg=4qyH(lCN|=3 zvzvqdT7<&w6qd)r-+3J6l&HlL?E4u); zU_4&&0+>&@;5Tk!unFkIB6ZBv>_M;vri0f#BR%zg z2tD<_Nj?f+WfE;c5*tKY5PYB2tj!mO8iDeHLM-6pXE+td4iF3Yu|tKLK#>h#jKI2L z9yjNIooAGM|MNC3IjQxLhZJ)^_4)L9(pPTdGtBqHdx@Tz8f)ab#rXO^+Dq@_X-9Y; zY^-f*W7%Nj8tgHC-uw7zaNc+yIZytFeaF9x^Tv1Ce)xWV;QN>0yK+tGhQ*a<|EuYY zah;r1v8d;|@>}WI(2qx7PHe8YTs$A}KH}fV^XR+r+u}Gr+c=o7{s^%8$9G=-%w7am;sw0JB_^_DIBp0qm@fw&&Mc_ z7%TfePVwBhFaA=t|5v6H6BP5|6Yve#1M?Ty0{IT}Bgz@D1=FG(P<&Zuae;I(=;d_z zBy52fufqj9fIUd{Jk1Y$9PI6YI1>0meE|PC84;hdy1?Z=A1Gx5vYMdp8ywXf&d1+~ z`@ES&V8$;cpEcfO68N+I0;o|tL(61i*S2KTazMl4wUBu5vdl_t~Z$q`G`TEV; z2HwZm-eNR-Ju$uFH+;Osbh6>t^9#lIul$!due^{rF#34m4*p|4U-0jiZ<2fB+oe0h zq(eicOZXY{>%{Ej-WIPDtKXuS7Jq)d_g{+5iGk5w;$+YB3+2P{-{*VZEuA-i4adca zF5)*Ffh)%Cz2S4hX>qyZTJaFs^OFVH;}fo+Nxx-3RxQ6YkaQjkh6YlcK%APMD4G_Q9SXI~VPP#S$TgP~1cNSw5oJq34m8g_z-L z%QLXCeQ;Bk&cIWDh1?^ti>1Q{+p`77$NbY*4TTb<#=ilf0hh?SSk7IYQL$5-~yafpEk6 zA8l+(7`GI7WOhK@s>ucv#s@G)sM+HL^;?bU_3!Ch|9;>;^#`lx-;LPvG+DQ@TX&2*uu%B6sAALP}nEbu@dBtR4KztwkypQc=yUFpAxPH8BJht9A zPfV}4FpKBUAf6{*5B{Av{=*@Tw^|!DHux^zE?tX$ow(KV?}Y0Xr{mAzx#Hrk=F7bw zFYx><*9o2nKb`Z-;*ICDxSer2@OU?ECGExIOxAqVwcp;7-cPchvp?}!uoIab3o%KI zD`X!muCW+L@dL4g*@e$r+|V7npg4&(#wL&-QQN@YQh(@u?A5~NI@eeB*zAGq^8m#N z0~I5fJy5(xd@%H5*n@8>Uw9nB~P*zE%4bzt^o<#}KHH}PJzV)^+oXDjymjOswiL(V)S8s@{15Nrc6-}^cpvGuXg{?JJYyD5#5jWZ zp>)g;Z9*4vAZi#PPKdPz>I^YP=qX#=>!{0>b6utSCrExPrq^#%?|uVcHp;)FCUlg$qq;d zr(X64?~AS^9*A~8xxqEw4iL9`JCNiCQSY;@&kKBiqUT6H4j_*Xb^sgDsBgg61WSz( zg2Uo+linH9@w~(PYkQZcQO@uC_u+ozzrDAXyr1F6%zK|-$9Rgw@5eaEY9-MwM*fpO zS$m257E`GW$+u`*gnG>7)N0|r>NOY3CM(XL^c8A3p8Mm!B!4g5z;Ddw$?2)ziTA>H z#OcKM@LqjT#(U-R^i|Ps^}dw%)ZMAMtKLq1F6QpkKIeU!drJJ4i@o~KO@5;+# z{0`^QZ%K#Uqi^>-$b5O^x$zqQL=J6le%EsS^j=Hdd;C6rr>&mX?48+y)D8q&V0Mxi zf!c%W4%8Vecks0Zt8bbuQ2kNy7IuKxV3#y5kiDkQq>v}vte8M{fS5pa1IrOYOfX#W zpSJ_PhKR4gXOJU~{eo%*@+ITtQzo4MYw4M{0h2EJZ}UC)Aa4WyX!=;QfX8!-La zzXhF^9guG`k>1aUu|Q@6d`ytq0Lur+1*{%WYy*5QkktekGaSYT#IXTZ3sC$nF8>Bj z*XsXu{QFDA{nYzxK8_^r&$wSI=GWL--*@MIf2`;GI4HD%aX+++abN9(?WFy#R!oIW zz4A%5E%AQJef+-iGq^8Yu+g6TiO>HmK3_HAGrl9AubPnM^%@I94Ouzjpbx-%)$r(( zvKU{yR~%_|yOj5;VH@uc@VvL!o*bV1J;bb*yYF>o$k*}np7#aLqvu6&d`Z4XzSP3K z3dgMeuxq#EMAvrCL9T7x-mdMGJzSg73oFZnRd$^Hrv7NxZpHgTyiwsgRdbN|JaNmp z*p~!55Vt-yD6$7uPl$GaJVCY~t1%K2_#A=yDg7inV+RzU?Q;0Vt{3@%*#Vy)^s{&X zJ3wyWYX#^5zF^qLzaii7u=M2H@)h6pd4YV#Sj7V4Vl1GVvBd)NHRv6_hxl{KrK$~B z9Doh@lj$pZiw>j9Cg^s?|5y_c2XeVUB^$uI3yhgf;sC1&(l7XIVSIo%8sh+RcIx(U z8BW*2e;voXJy!3xoL}ROIbWlkU;f|be$YMmcj3H!!uM0_i?s~+@9UoF_BpeEW&_3l z8Jm3EKmEGRZU*-98o2NIKkX{~zUMx6cFLuSyVT~BWq&7KNPSP-KQD4W`2Ejm%n0$m z`F-Mj`s=9aF%C}SQ55S(?)z9jeXr zdf;T&X8a1*cGdx|-O3L%!7jw-iQ9z#!3JdfFP9%!-QZK!zO-}fbIAG`VhvGs7hfj` zd4X(z&kL?7)CiQ*Ve7M4;DdL|7u+u!p!z_x0jC#i0CB)r#gXF_2ar=vzy>JCoP-UK z{t<%`i%yjdn5wvR>J=dlklxl^{b$o<&;P%<8RGwpO^Ek>wiW+pT(9^)+p>?)KOi2_ zS4d5OIKX0oz<=2Rd#{jOz{Up@`UJ9CK=Q5toQB)gY=Dl@7{5^S%hmf8_cNYfyq|#Kl*;-zhbm=Rl7MyG27>q?`OVW{Xm~o{r5E0fj_2P-}rxz_^+`i#Qe$+@eAaO zeH8Eare9ilq|fuI;nV-FnlycMA>Qwr)$P+9pIUwN`=LHx#DDZWlN|R`ZdB%ad-?UY z^A0sX4%c^T)2{j4-l_R^p;foOuJw>Qi!GWLC-BTkd&Ha|vjIsQVEp$r0?+?^9AM)X zLL5MCfVvF0kq`7#ov@es4t!nU8pD~|&H&YT2CB~hKQQ=1_qw6di(&E)#E8U-#EhfQ z`o8i2Vt}8D|34T19~1vo50Ji*Z%$HO5I;2K5+4J=|APPjUpGDS|5~31cc1@TENe$H0H#H}VYe|5JhgAIJYw z>x2J_{jKkwakAq7iQ>QNe7%o}{MVQ{#r?+rgR1Z!-%ow768{zZXWYjQG=cy4+qU@k z0h8QLZ98lizH9M_^4D$E+O^tcuxm4RiEFp$_!?t_=JTI%4?Yjjcmu^@jrcEno$>z& z@&Bk2{C}_bFZ-Y4zw~4HC&d5L#s4$EWBTLy|C1d5(Kr16Wa;0O!2hY2{a*U%`CoU{ zliv5shY`!7&!*Stw|pJ^NAKZ)7tek8VH|-cH@skWAld>S2ZV6~j1{CNfDK5-2Ea|m z2EkQw^+tIBb8(8}V3LS!SDOH#Ojsi^BLy^&%OP!=LpZ` zpD#WuTb>^~NPDPVXqy-d1RF5@8pQy#XRra-*r}ESs9*LX<^LB_`y&TnY?o^O=l(*q zKaKmc7(ipeKFt^q#_Xx?rx;);F@V+k8B@>r9mcdX=3O>`+&`=JGnSU|cp9&xoYKa& z9S~vw`I;;Su(2<(PcPblP~%Vif5qG%E)@BF{QUIwu65rrZl~65%5$$0FSpZo#0G7~ zEUsb;YT$nyTTmSTQv*=D`}n_51L!V%@cq+=CWHs0QA4>lkhCs-;E zP~M)_0z)037uN+AxIDm!a7Ky8l=n5;a^#{u33q54K~2?0O`U2=|q+XWOV?IMUxH@M;7|~7^}y)TgKUH43E_T zG&WEAXyfr>ED-wo@_qV6{d^V!#C+KEzun>!UF+d<+)nMgyrVc@EulSKXl6(?AiOgW#tOs9+}NP< zF~H-c{J*%rs$|}u`Tj7j-|~I=e7J98mZ?vK`_lbQzu`q6yWGhAOY|JGGI_y2=gr!h z$OZ&EF#D$G-0WZrW?>&K9w1&KcA|zVJ3u{vx(cxXxxi(ryT}Gixmb1B%myeI__D@z zeo?gmv<`2TpPA z>W|9uphkQ*f3Mi7$lu3!-*~TfhWFhzo}-#f%KMP-2cJ(K=Y9Tlvg@k(DaHfeL5lgz z=L>i6r|yqFpckVQ^Jh8#=VQ(G@61OT_uefs7C0%FRInXJ+2?lA9qO%@D8P*7WQ3E-@m1 zYwr$O91z9{TP>i_AHX=BEC*n|fI=OhzSstc|C_4${_H(oau4Ia=lyiu3-@K*=U%a0 zH@_rqdzsC?o@@3kF9p%Q{m*AFxH&h|7KqvfQTv#EOzgl+>H@@4!~?_vmJ?8GmF>M; zHuzH2V6X!hF>X^e0pXRi16fY+1Lbv!2hI$20p)wcl=lt&Xy_CCpy~qT1?nrNPHcGr zwZUi$N(W4lfC2lV_Q%=u|5>yr=tA6%f8}#*3UD#m`o)GWchp8DD=-=Uc^zYWMANusvw-4W~rhoJm z)@MWArr(Lz`}kgY+(2@B{Jiz;`P%+)*?90BDb9~lE(q>pKJx=NR-7Lv&Z8IT2YQ0O zOg3LH&YQ0n=cQNZ7o4AdmHhqHPn!Orhv?(1>;GoDiNBv6{5<+=dMsU@8+AMA`dn@2 z-WK&AZomU=Z+k@?@SK4=kw>#`dfE6DITm>b2kqVA_^uFr0_vNCv()RY7AP*mX}IlU zfWJH|&S&ohXn$A6`lbE-ajZ{P^OIefq8uZ}{l@)G;yv8I!E>K`jGUiy3(pbc)>p)H ziJoma$cE0j=~*|2wpA=OTXq1MrI-LQdtkOe z*kG4cBdDV$tGHk)c01UD$=HJP6wiH0_Fc8Y@rnz;f9%;B^Q9bNG-E%g6(}YgK|M%% zgFP6kcyWmG1nj}U_i6ly{7QfM7jF-Ie9-4uy|X5rY-AJYL!>UHzNxOef5^2NFup~2 zj~{Q-ZJ>BM*>xDYuqJ-jY6nUk*I~pmvng$N9^qPd=%Ht5)gsT)rq4*%dDVM;4xe#7 z_TMp%CywonF+FuW#q`#X2j4?npYT2A^dp7iD8=@p<>SYwKWMCM{y63J;6CA8asEr< zy!2tx1)lTh$y9M3y)n*9kI*MLKSTOue3zd`=Vr^#&sK~-TX8CS>2*|kDt(=M3!Ilo zhv(hqb=ve>oX_+=>i+F1FFa4?h%a+)eKq4yW($HHfOBwfx;R*{0rUwf4k#A`#PI-r zJkYK&2N3_y9TVz)neW$FLhJ{9{n!)g{q#3XEAst~xDV&KZ^_)-yv(~@TM64J^Y73; z!m~@}o4oAi-yyMfp`Bv8X)F7QSep_X+)O)rn_%{U_y8Mxono--WRr=>WTU5FjXh9~ zR>2-jI{)8g_f^~dqU-_jfpi1EKzxACjQ+Ixf*2E`+VBX)jg4%AV#`7A*ZXJEL+Xgp zE>Lsod%WhuU>xz`7rBm8R=b_lSGF}iAOGIA*EsXhr8xR_e%4{ca@VfkRN0^bdakYS zqi8>Jj_Y~Q7u8;j;iq1o`gNbbV|%f|*y14{mTyP@9|iyZGqd;D zefT~(@?CX&3AuBNn}6qPZvI_tC2a5V|1Z$Kmshn_n;>`4K2f|~pdG!)9^8gq zl|8r>JFEBr5e~C&QfzP|F&K3hVlu@B*n?}y(f(JMQmY9z;R^a}era0{5>RX_eK)moF zy^AV6?X~Wsu65U*&E|cp_T4O=?=XDHHuv$(wI3Zut#s}B*KM^eXw|NR>%RDK+0)w# z9JicZHG1oxSKh9+9(jg%t{Tqhv*gzmw~akpeqH#CJ4dm6^y{+e;Ap=6!e0yD{}k8d z-!J`das7W3&;Qny9pwG|e{hMVso^I^>ZCo$?`#$fFIltK?a+Vmg z1nwK}jr;K2%Yv`I=AzVp^>v5D{}+5!c0f{(6xoCYYQKWSI03u*qDiy|^MXAvj6!@c zNBP1WFa%3t1oAcEJM%hWE&EQKFhlm<;skO$Y=ZQIya9bNyFflDpAqfCMC^j}Z2TAg zHRKSg9mO0%IyqXkxVjsCm3soY1EGAlH8Iyd9SFEv7KK^oRM~mIzxZ*MFug}-<=ZfEDnITzu^{U^1Aj*$!q#Nwo|kVugW$^itNDx+1v%#UW>K7O_-nB z=gcn1eyfgvfN{Ytkk5I$Fbf}mFOZI47ou&Lj=zv?sFQ7&X13wCvJa{eDQ1|G*$34Y zzW8(3XU&PKnYC}a{;P)9w&y5Eu3e5_@1)N=3|p)k;xLV2YTJyqXybaXI?md25;41c zIk6e-Jyo$9wt1T3HaHF@(}m4++3)Dj!O!A%VF|~v`JU&06YdGm(Fcp+y>Fj)Yv6mz zb@>_e%k=C{&vkUrbP;_-qVKY;*Io3tk#653T}Mpk-!Lv1C(IX$Cvb&W8Nq*sJOFON zG4cSb2dK_&Ho*D?<&(utI0{$oJt1-ct;c9FKjqf{u9Li%=asP zDCGTqoDaUAy2H$j|Gvg=wZ6cA?ibsY@n625XNvwF?q~eJM|L2{B5gCdx52kj)=sg# zqD=_)z+wg8{)PA;#tPVkDEU~y+lFA%g}3344q)@mE_mB8M>zyB1A2r0n7_b2kQbVM z$(MxK0sk`gBX_wD@?A~N@!`E{_V~_s62EJ`S84^=wdUA?j)Nz-31@!Ob6d3>v&qWi zW+E1|i{IwQ#qYpzaGRre5BqMu+&C_5Eq;G4=g-ZjtJdWGI`MntdDJ8C&oi#)c#a;X zT-ScoS#2|YPITM8=NR-paKShc<6-zuyd3$T*Z`{wX8aF*0_5RV3k)#;{qr#f5QnMZ zSqxxff3~ z{ekzi!=if{yomRUGSTPvCSu12+Zo%~&R4=FBz6JZa<(C}3FHwT?<{VJF++^^l>#@k;s(<#{0MahMG7}yUR%V`{hmMedn>eyY7?MyI#`|bbV(Z z;RY@^&UKxzSCh|ED~DU+xaQh{)*U*#;m4eBF&g$b$8YjGVdCR;@5{l=B*yGTzT9(M zJja)#55cFSCnb4K92&&?baXEGB;&HzOXE8_i%y&FrurOoT)G~8Ufu?TeAxJ}Jiz!L z@_-lvSZ$pcAk^Gq43P4l_XH#VvpS%10CC&ufa1E<04{jy0{Q;C$p>QHf1=`qNy-;k zGn&|+c}LRNe}=~R;rnMLv47t8Q`1j;zn-Dk_h)f`;J>$#MeUT?fa1?%yCz$+AGA64 zHeh1dBz74aEt?P}!#KunY{A|n#tdxn1rp*vY7O`abP17eAu}%iwd*!+Zj*g}o38!U zH(y&#uk*M)+|EFjPziHEbh}x`aeTaP) zALwSw=f}3UZNMX94?ScQGdK%Es{=U{yfL=L>J5I zZKB8K>k4si2BXoP?Wc4q$TziNkOiPQz{Ef2aW%_b+(r zr{wG4--%3l-a#DBf9wWSo7&EmnIhR=c%`=)8-g2%~J@t|$D!Fek6+|AH(`?L^Rz zg=~XldK7HMq)*-N+IH*JB<|C1-+th%id^k7Zco>z>TBYf`CP`)bw{5Q8vf#F?oZ<@k5uK zQkCz;Hh}nlN8xmH?t`(0O{opE>D&$ODL<@9=d%e5>bwv;n^MR*wI07yiTLv<5IzY4L@h`DYTp|5fq*!3UuE*BS zd-Z407sj~S95=?Sv6z0qykp#mO>_Fxsg~elf9598`-ytL$8(=C z{NDF7rgy$_6UH(v(AXY?*v0!v{AiFgE)RBgiEvnQ-#bSZ-uArfHFvL?b#y1abHf<9 zlxN*1?c@5-J$kD+AGy!AXWfCh^QYH(C+@fFqgbE`;|T}tb&6Yj_m+2*9+}RY4N7d2 z<*3BRo-gJz71#JY!1Kz+3o?#Yob!1AF#x$ZHh_LP_0QRw8p;90T{sMv;WXTyc$vob zVFSc@xG&$og?NC^yzei^|5*3){3q|9+lc@E9!v7yaw|P+Vw;Wo?;!re{q7U$Yvz9I z&b_jCZ>ZJxo^gnB`KHJADc6hlhc154KNa_*y&_g(++(e|RqqAs-+49w-A`>mq zc>q2%&wt{80{`J4TrBWEsR0!6f3o-w$Bq9!2iVex|GBz<@c%ZSPYM3(eI@@s4|PBM zfAIaG?&s}S^!?fv`Tuv4?{6CSTWO5`7~^Hv3G2+)k6iJ=X2n5lElQXj)?#TauGYxvmT^MAh8{T2I1{uBFK{2#baJR_Ty zt2UjkUfv zg$<~``RR9#4X_v>`P$-sX&6!`?V;22zs{D*@+2M9HQl>f}f8TfBC0CC%LfWUv%0Jb0#E~(7_nezX$ zWK%NVpYdOHzfk)t$A9B~%Kyywzu|Ut{x81srJA|lu1jw>VD3@P;{AxFr@Eo_$2F3X z%NvjJi8g?7K;`(?Y0Pe}-<%_J_re&#a>vKdsU>j!VY;7g6ZfuqeEeO>?Woo2?^xVe znla8Xo}d1KR_(j~bJ>8D|8OJ30FgIk`ENErV{RC8Z#4k<#seeZ$!iCTB6?Okf(fQ8BhGGDu+#+s=OD8YZYWHCVS|Mm2< zCH#kraI%>Ha2F24WjIZ2AN@a^pJ1`S=l^8&3rxAg4>w}|(ziTB9svS*Te5&XU6J}=9J#j^W%Tp6;@ z`)lHU#~y>+@Cr43IN!f+z3bY4qJzt|*puqVw6ZaCa3>v8(0BIX7Q?4DC*5b9K$i+* z1mSynJo}}_71=yM8n0vT_co!QuHtjaCNR%fyM9v~98YapqkY+&HeLJG)RyFKi*J8^ zht@T?5P1Pdd~M8g$NNuwDKM7$Kks1 z|6+3gzizSIzXJb#>|c%l{@%F9cRK&aopO0ix&`-%-HSQH|Ja0{qqN>$huY%RirlC& z4=6sj$H@AMb|~KC(8Z^ej~yniEBPz~=N~IRuC{Ru{+<4&joEMVv&p8k=`kc{+e+F1 z-Yc%sHhhl_SaR1(JFX3AGXJRq5CfFwKb)<^e>e~KRr?G4_qD%isuLDsfA9a(+`ka} z>)ko?|K1i^-A}e@k=6aY?=Sd&Z`0lh{(t(}-_n@g>hG$T<37CKW#obu^z{|i-6_(2 za)};8XS$&ajw#9GXajhEs1ct+t**GAGTO1$?K;)OwOaUC`!TI7r=X5d?tX1)q0Ow(OWTpd|mP1r+jUd@9`X{y*}cIv_Ow)#A(M02;p+a{zJMasc)7dH(-x z%S7WpF@a)#y()rp;j9(c#o5IIGuw7%kD!0FT@e6 zi<1Y?9}sv1rxuA@-Ui4H(AOsJ!9lnPC*dX>g{yED?&fL$;y)aR>yz{@5Zs@5@n-pd z`F@QLo~rkRJpW}g$o;MMw-x;7{@)?|Uv|%HHP!mzcX6!`o^|fsj5$AQ@LP?z(1hRc zZW1|2xqgIQrtROzuhMU@!`QK+XQgJyeCDNMfm&_A=p)bB;cP%f{s$Y-T>ishxLl`q z0pKGnqAOmgDoS;eY%s@yg)2hc}7^c;_hX=c9kEjcRc5 zcU!aV-MhD|tE!f6^u5e;D^? zz90V6?+5>5zrW69{8t~teB~KF_80%v2SFUNh`c}Y-(vqV{Li>A8?Xa$fBIPuRo8jN z)NnoK&}{LoJL&WCy4pB*@7S@U+hdPC+uzt{L6<`$vu-jw%mv-8SF!}b05-`}3;$3OnDd;a<7%Ri95 zX=rG0zxvg$+_l$UYtO{*)AQA`&z$2O)elf?2WsgTXw$Kan{&a>cNiOBd2qswlKf{3 zjoE;}fBM=i2N3@mgJU*8{AX-V%Dy zu7~9KkMCEFVhMeI67&7^_u>0PZeuo1eSXVLj(n}S&QOlQb=k(K0ccVv-Zqhw)KOMUDb3^7A#wiV7tg!^W znx4DB*;7wF)qVf_->>DCD;|SAc<{jo-MV$_niLzb7DA)GLfHh~yGq->)PBdl!`z~q z|GGoyps#}kUIebd8DBT^aX{o19J4xG5&z8wh?~ZLs{zRWNB)-@2jFXf#{Vgy_E#tV zPuEz18L}0`4YTC`XX_kuOYpy5{9h>lPaLvX_d;BY`zA&qmchQAb=Fzg zeY4MJ#4m8XmcPdzf81h%a`#^Rc_|x!O|WrDMfHQ?-}aog!mYUXwe7BhJ_ioG5Jw_k zeBLboNgf?|1;;GUCg!#rKsET_kMYfs|8N%W!ePq+#A&z<$Eg9rd3--oiT`u-KJh;* z|EGQ8uBtq4*J&z9|o{ExN21+p>b`{JEN*^F2JQmII^w_;dJE%Q?#(Q|yn42ez)h*0^RtEE4~SWvE|l z%{9ndh#{)|5i?-tYPl9;2a9U~%q>{UJR;Ln58R%*2p0-*vEqOj1Jua>h2-MI0ODq$ z2BTs`wtTBg7Ha{;+Aa)CgH$ppgyG8py@h zE&ji4mmY56)&H|y^)d2-ZR88wvHY1_I`9gP!8Oad#XUHf@n765#ecXAr{OjnhwE@Y z2b1$X**SMvO{~GTf zpC^6B?aBSQ=l!JW7{89Y49RNc!_>cDZR|erZ7q2|ar&f5n%}C19D-xW2{vrlV1AG~ z0785*etgTUAzbTylsc}|z0pU}l)5CmuBF|mi&VF5t?XT*VjE!Vj#O#y?xSbAm8u17 zFTG5;5&5!0+{ySaPGJKw{%f2)+=GJ)c?Spo5C5|oK=A+Ku<>7nzn!ah3Fe9a^TmH3`@d}0Tcm3)*0q=D9+v1{yziI)H}1b4 z{QetmrJf-^+p4cMsC~Vxe&9{Fy`)E#x%%nn=Y8B*^Q$(t2kzHW2S#ZhU z$v0w4KJt-|)ND&q4!76)%Du;}XmbB0=YZqX^eX+4zmxB$*DSYB+(gZ@+TT-8X`PxX z@eOmUH|i76*ydX16&=3chqs$fMqaRue1SXI0E+|Qzu5pEXTv$T2M6Jzw*l&#vmAi2 zI`rA=ogH!5a)7{pI1bn0{FKY6{r%tK|D^X{T~#O3xWC`zJu4oM?$*M6xLOPMsioDD zL%@w!1Dia4Y1F7ux!PkT-V(dl^4zo|$5#7$;)y4!o{u@!i(>%R z9ctCCb44r}8#L>4k8Bqkus!)dE%^T#vJErk|7QjNKUcP6o@~f`*^&kF|Np3)xe_K{W<&Jh<1&6kL9rao1Xa4sU2a@ z?;kjPoags5Zbk{_l9L z?Awd;$2NYH-RAl0>+2oz9rZ`wg8IULP2OjW7cj>~i!Na9aMV0v%nR7~&|BTE157r^ zit+&r`%k9G)&`8Lr>{-sO#82V0I*3$$tsy8yJVR5pG=c&GEVzX=9TS-{pb2E*e3ih z!Mq_$ag2@sweUIC!S`4XAB5Mk0oSw<*CzaL0{`@18d=Cb%4YaBQkvlZcXye2_@9K! zjN3ls{2b!pc5j$Qr(u9bO;re7oXC`;x6aZICm ze{t5C0~DukpKTxV9d%CnGjaZyKWRG`=OPjA&1KE#8?DFjoD(-4>2}!^F1Qq4$c}11 z)0VpYlQFWUY%bg0V2~`@_$SL`TKFgHWPTof|FZDk{p?exGtO(1nPC&>dF<0h+H604 z+BkiD^!u&0%4L=P|51O;{fXPAHt&=1jPdi@yn7So{Y&06=P5CdjkC^J1=}J~e{9#p zIbYno3I1;Q`TBWtubcdHoqdJj$Laphg6+V*nZf5W&1mo?Qg&sx(3Yk zvx!C7{ZF0EPoubYzv@=ciAAoIYwym|Fy#enl)jj}X@Q)xCPagnm zl2NisX36eyFs#}Du>WM6jFWXTPxku){~I6t2gJDSIcglsV={2fnDE?swq@h^ytLPB zC!3rEtv56@SjC+=b8&oU|G8_2jM{D|w!gS-A-3`3{IM^> zf8X+%jQefBe6F3iDD*fvesa@^KEwY)*Zwboj#vs^5!e22fc@VHUBq??b(6CF&{MkI zpR@l>@BzwY|D$X_ZKOFyo^yKHWS?X4;{35sOJvEmWR6?VA9W1BvmG1u9s4Z9<|gyA z9`>1i14+jR@Os!r@sCrG`=c%kyJmBHSe?juWXZ8m=5hY@+DS`8bwG99RO_)k*V5m4 zrCW4>Y5&QJ@&R1?ui^mosSW#2=Exp>@HqCLOp|Tef3j}c|6AY-1o6KDzQaoR5Ub!z ztcFjq2EN5w_!#TpYpjRQ!QU4C8^Hf2m;XkWfBG*?EMy;L3w(cFt~kx`|GT4Xf)5wf z?q@%^$-uaq!{6^mI~+A;S7ej1F~2+peGY0%y!qyv4*i0l{iC)GpL|O}jNiP!BBd!hQUyTz&zChTq+&*OTENAnRA9lH{ zZeg3)>^cCBwAke*Ve4^8L{U5dIfKH;DaT zj$@+u-vItMLI*WK7YYB0eO&8iT(imlmNM}_`{eIhpD$y4{{ArA*xopCI+5GBee-_) z>HBh?44YgAeuo&pUza6eJ#1gj0myvFz~2NTVcXgE@sIam|6bVs=5`(%_mBRVd91nK ze_&lG|7;7?PFfOrteoe1^c!`xtupy1D@q5r{F5c&O86&pWRDC+@lTe8e=<&6Pv#de z_DBA|_a^*;x17b_2me2K+gbL*cU0V9#eJ~<_rHfZ)Zd3*`M|aPAFAKm@aSdOe(aykOkDY-L{r#h7H|E)XGQj!v z<=Oj}abwez-M9>!{8N_WjHmNomx}RYj6xX0#crpLX4rq>LwFH>lr05QN(a!#W?LKYr_eqC zd~mR+b%6HI$tsy8yJT3!0KqibCgWtC%q#x?I0pX@#^7JE5B?SV;9vRu^!>rV>(?|t z2mVz7`_FfMS@7liEpkz%+O}r9pNvq>ZFBm>>GPvZ^3N8VHszJ$>)58S#j?!({p%{m zA27dHvCIb@ujV|m*nI!B$!E4@*rs8QpKOa-#>oZJHSJi(L)1=QZuJ3FZeYZ_8OE*H z(WNr0{R_>9@IrQ2$P#TT*=po`1*#1Y!9SRdJR_Y$`kwh*{=07U>oPlad=7o z;`IH+VLWV~A?TwlHpcJ2|G1yi_6>yHOVIWt{D0#c-w1u)VR-<4U7+7>5+2WBEU@{R zkGn(%l#BmcpaT{`7c7QOpl(>^+W(c%8LOZ>RzruZfi78#HU)Ld2G{;?g#B-T?%4$U z-w6A^89J#6x{0=b3k&RjGi^Ug3;chUt+4;PTyeI+{&!`W+F~Ey&-Y{m$@TWIt+K-LxeIam%3l>B?!!T$pW|B8L+0Ok9G|Hr|<^8J1MKV4q_w>=8FJ8j=U!F~B+3Q6Msd={KTAncrB zV*&j3pP$)Z7a52SoA@rtA{a5UNqHX`P zwEZYz_n(LTR|U5Jg{~{}FWJZV4jwfl(DqZ#ZMm;zoIVc!rJm!5F@FCX$_t5 z2Eth5`wx=*F&8-OTzp?}5bHtP*jEsh8+={Imr5?bIu_>gA#pOW)64=NdJFkiIzY$S z8eRU$AX(HtfR4|RRb~H$f5re@{>ixTPxgiXCGZLO-E#N{!vAXMjx{*PTKE!S{A=I8 z)Ajv7R@d2#>(qX~=3o4pZD3!QE6#TC-&JMw0(;&J^LxVBC?)^Y7hy7)bUWW8>VNl0 z*gceMyUlk>dcVw_O7dsxS4_e`b%J^qg3li@ub=&ao9_KTC6!;@7S?Mw9=oxPIQxHkNMSzY)*Hd{+K-mFtT>zA#2g$-li{Iy}zgzh=(aZ;nk0 zyY@=hPTfjB#eWY;Kl}5BqI3asrow(BDgV>~{RY{`icV=f(q;UU6{Q2f4t0Qv1GxN? zF~-?U{>dVlB%5TEw%X*MEYqfwe=<(i$$S|9E3vQezZN=V9dyZhoYT*LBYcm|XoECC z7j3~c@!H6K3k!S}#XhcIv5$M&4*qqy;_QI^?}{?#?6*SYfbzk(nT->h4NKbor_9>N zs7C96a>n>=^Kdov`~SUUGQ1t} zaN$FE5q`)LnNmIgZ7kc`V2%(wj?DZQg@zt%_WpHQ}+cHg!AqQ|suGwuCVr}f3sm&PCdja6qe zuQ!ShTmL`j-HrQ4Um0+bJcc7W#tAP!)(0m!V`2B1wR+w21%>uw)lui}61x!(_!0m=q_ z`zR)C`G0X@(j527JfSdIjM}bZ{0loGuQTdCD&>3CHxTokNkMhPF;sEJ0odkQA=|>V zxn!*0-{0S_cBoTRKSR$Wj&}*N?=a}PWZU?atv#Cm#jyV>_6ME7_`pi&h*i)PYtU}+ z+Wycb8xdD%fN!x0I;Igh2b#^`B8SDZNt)v zHoq=coi^D2QkRi)Z1X`?IbnVNCMz5dAkWsn1=T@IVU_oY{d^Je(|ewNvm;=HFpf7Hpg zF_RqMW7>Uly=K()sjkPozR~m6^<4h{%QasIIL`nRwC<|{?Xa~tfx@FBbiKik=d#sap;7+E88+6O@V zopE^j0AQ1hl2tNGcF8d9Kbc+$wp9!OeSl;heSn=T1^nNq{r`1{AA0;N-yi%V&KStQ z^8LZTd#&4_1OMpnV-dfm?M3jf3fOjk$>Gkw~%d)wCbVbt^5bY0Q|of=QDkPVq{vk zg*6|-i||91gsZLWTLWu>{Ig#UeE=#CK==p4ihnR2#QzeP|K-pL)D5d>|FQ2{=nUb1 zBhIDU{)PNEqwU{9`)}}1eI@+2b`$@$c|O<|okafGM;P|Z>1Q&=$MqSaa$P-r--#>Fcr0@6E#~Ef){mtvz+*TMo8$=D=0y&R{h59M=LkxB9p-V%zxsG; z9T3Dn*`W>~OX33v|74Er(FgbJzstXh0T}#~Wim~+$v9c3%_sXN|0?!}ebyNKZ-5VB z^1m6s(WGL3+W!~+weSClx=vo}4qUThAJ;E_%}&^UU9LL2VE;>1HvZ9HS)bpq33C#2 zX3Jk`ZEa28w+Gqf*yD+d_9nijp3eW&wHG}86@QGcV{D$uP}23N`2_rZdM5X>UR{^I zkJ7x}x@+gBmTBD<)_e#r!Vg(eHdVC&bUWM6Kba((wEx0C*`*C9|74o{s~Dh<|7Fkx zE3l2)GYrycgcRAmDCV5R`jD;khHu&ek7%Zh)ntzrORoy;%&Q^x+@>|E~huiF0DXYKv(Aa3|B z^v8Sf{ayZ{S2jQPA@s~;*Y)QS-_{VkfdRw0d|1Z$@2mh|$zw0IN zuL{_IxpZZK<-J}>`u+Se%>MW=*-E;dF@FDCgZ|&^3!jI~-X6*%=jkh^Zy^7fgunl* zKnI{5;?Dyz&ovSD<%ZpNIb_@19=5*t?(Zj-Z|yT^K7<$Hhb)N>AY){W%xNE>6Fz|U z$H^ucRc!$9Pj<;LStir8?J5SqJpTy(*ZcUVUa|47ZT}~leemCgYu-urQADq`gMD4D zI=jJtDN5rX|3~XHshbi!&rclII6q+6GfuLdV+!N^USHT}*iCJr{F6(z*O`Ntq<(|; z?H>{M_v-+*6@t#gZIjltd$QVm@83ALT>O{Lgk@WunnA(WIb`B>&aM|e@s5cj=h_$6 zdg5*2o;$BZFj-Op5(iZ2&M!c4_~G|21G+#Qc|Ie};_FtE)&K}tRQj{6ZCqkba zpJST#Hs6<7tnc4{z+i`SWR{DwNvqD4?YC|BJYxRdNd6U*s&BwPFTbDDg3tX2IJFZO z$ND|nykE5Qab&dxzQID*HyBDE0Qw=$aolG&;$gyv@FM(>CE<#Uk+mTH$tD>ktF+l< zmkg6-G9AkQJ#Qf{=-U7L-d6jrf6(Cnkq^{4J^rC@T7Cli{}k-Mvi%>cYx4M~@83=Q zQ#Thpch^3UVVf)leaCTkws-%9{g%0%<6g@dg=*jz@nLn`QFc4*#E}Wc<52z~dkD5bHJo`{39YhZum# zKbZCS2g{0ou&w(5(EbPWV*giQeU;1qTI{p_fp?q@F8`Yze&1wT>(nC9NEt-98|26xc!sgTVf9C16JuhEDeXv}0I(}MwX@BmrHRqpsym951vAMMG zw=vmgj6Y3(L)`0(v)@$ovyWMn?493n&RdFom;)?q$6c19Z-8U@nR68On^Aedo4)&( zC6U=Mxz~C^^O5rdG(Wpu(DqdO0NT$cbJ_<$3?BUJHUMJtV3hWs%#vN&f3i%b$u{{X z>tw#C^Ur5uvgcoC9&a3(0QT9gWZ-o1sgZ zpi`QmTUucMx5C%h2A#7V_J0Tb|5oUtHndB2KF5M~KYW#T=&aqe{V03T?q}(M?bqe1 zvlsTi*s}1#A6lQ;#2D>w+WlhN`jneWit&$McG9Vv+up1Arw%Ad-vGuR@?Aecy2i#o zWvy6wwH@C!cva&D zitHN*Xxn0G1~Tj1pU+L+WwE7ozO|Upqo6~51qA#wjZT~wjX6L^qVeMoqe$X#g@@? z!{_@*8vA2@j*au6?>I)FoH70|jz=v#sO($V_vPGPEdNRm6wxi;z_)OB|xs)JJfzU@3E;UBD$*P7AP+41`ZXy0uy zK->HOCar2MiOhz{y>1(5K7<$HXE#{#_(yKBZUY4H4>p^@sK-Cp_4o(VVf?RxE?DE* z|Mk!j8(sbzp*uFa{5M0VwBX#^@EhCF-q-=1(+b_whIYtK=pyQ+cIG{!okD%J2iM#| z_EAKy?F0L|Ty^$?|6ttT+e^2Cp)4%wImH#wj{wVu=x1QhD zo1fW7SgE;n!mjW?8tnktRw>I;^RINklogTV1~{iD_q7$Fhm4z6R{qHp*^09N zWR$FuS+Yxp$ujLf*(T$(|74!*ue=BR{}BHFy}wrd0~;QI|NrB6&~A9w+59m0e-!*b z_JPyF*x!@z|9=AiAO6OUr{VuU1OFes|IX*&|HCiY%`p!i`=7$^r|+@eh{Ykm% z9Qavr<)-~#3Vl|5ZgFG(K{D-+1#nL8N{jIaUAJr#`#|rl8&$N-+GJk)4w?^XCksCvFX{F)*&<_Pjm+s7Ap79i7ta_V z`{vP3S1~~L*`x0s43lLtO}14ZAXq2!WPg>*|5|KYkN!dK(|~;&4gQ;5{g#QlJ_U~H$r>qU1W1qSA!a~}m!~#@|AMdkDd!BL}=kX7_7KugqFQ$yVVNvL_8dx`>By!BLgUk&q2gAkurpf=v1@N)d5t>u0OH}ohwvi&kR>vu+5j9^pkjd0{F7bU z|0w>~Ko_iY?f*vf6MAib^dIsZEzl)f;Zx|?|7E8YzD673jys`ycESH|hcB`l*R+S@ z9X$Ru`(4F9{V~zY{w3S*#qiV9k2Q1bueqTmlxy}644Jjf8H|0Vq5rcx?z_AAPorBZ zmw)u5x%`tcvPR~}9vLKyWRku)86~S^mh3ixVJ`*%wrT&#I+@q@|E!%Kk_uY$}pS|e!+mC*KmIKK3 zVL1pLr_1Ngp`WEM`(OAdlzr-gG<|>FA^Y9+8~!%-q?Kp$*q(uT`0D3%c(#%G!rgUk zbvN(!em4!HU3p9t|Ha5`)UgL&`P}0}coBZc5}6`fUL275HehcjbMF=Zhy#F4GD=p- ztcn4GVX~}ZfQoD zbGo;WAkO?Ba&6tcjO4!vnT?Y7gRqCvMi5?v9~B2=E)CeqFz;`#l!#(lU}@%s;; z-7j|k5Ze5@eC`}ZU8XIK-~O4Ef4;+4y? z`5eW6T6v9goc0eiAHoaSp$;HRWJ>t}5(iLi0Qvv{Z2+)JX2~uYRxtoDO}5E6Z9SPM z`#q8WRlj+!mH%S;{!Ll!sq0hM-d@1iu$x*7wlPl7-S^0NL#6QUzmC4h{~Fi+uZK?9 z2;H#Bwf{|s8#Y6CNbGMrbjl9I7upbK*a=@_7ySQr=$_qZhwOna>OkCYFLcvB*#G^| zRr{f{l z<-d+f`W(f7T6v9g++q0t!iVs35bP))fNg2|)NEUWF|tPH$Q~Iai)4~)l2NiMF+eg* zmg&=zZ8A>QY5&Q7Pvn38(XU$hk0Xb@eV?H>7TSB0wXsW%bvygaF)**8($@PV|37@I zll=i3&@Z54|L-7P_%7NFu>a^k*!uVf&Nk!}GOpPA6zo584RpU>C-l$9uI-2Yr|oB- zzi0bl|Iy!n5JlSkhhK&LR|U5J=jqFJTf*PZSBl)9-k=*K2RMkaYi4aNOI~15yCmrP z%C#+${~}~IO5SyhK=UEIkR6p1@KfzilPxkv);ieNu6zLY!RfwuvPnkCDw!p_WSA_I z=}pK1BI9J;?E^&LUylC<)%PFF{|=Y`o%jvy`{(noe1BXU{geaB_y0_@@A6OI<_Or= z<#XpK>N0Jawk|yPFX_1d-oSd$J;=LugIJody!-n5%xhyVV$k(e$~HaMXz<+PwL|Mu z%WE7t*KGvN2U$@%z_p(Tz(1K%Z2&N)+W?jw@BV(tO5t9v!#4hB==kYnWbxs9E8;zk^3k%lOAQX7WcrUu0XB<+A;}9?nTD*HMW}+dBZre_DBsbKFtH z!-WsBqGExxohZtd(x+zI8jO)O;hzkWMKVd-Z1PWb$uL>&P5kp&_;Y^cGsou#*&c4= zxcy2WyB~J#X|^->-{h>Ewx8E;i%FQ*S*~^4{2$}tbH?E~?LKAW|3}*Y--xln>>t<+ zA7RVG?<$?K^)YS#cfgluMZdyM_!hgMW5oV>^w zKN+U|C(~qG_W>f;pZ-7CXW@DQ|Bt?>j^#OaU`(OM|1;np{>JX-I^p|+e_Y4D7r{S$ z|CbH^UjhF=Bl{?>-+%1q;9nK6|BLiRY<oiF(| z<%;>6brjSdA&a(m0*A5M72Ep{9vNy^W}?rj7@3VaR{IT_54HnToE+?sp+jKF;~$La zHh_-1kwLPkV*m#KVAkUwEQj&G4*YKb{|&JJjj;bsuKjPpG25U!wuApxoU08wWfycy zJNVaaf6c$P{hzqD|5N7>bQJZ~VO%rWKg#0T{o`O?m(QIO;6H5%;$F4|&BIThpJRf# zPuhpo$1?}IJ+p7B4gz~@e zknIw{Bcgn+R}WO*9qD6a(m2VS=+lzqz1nlIl|R{qIUko_lvWRXnLH>dq4 ztF-@Qm-e45lWD*GC;KcL;R|ds{C^w&yYU--{tv(xIS8NR5PXxv@KJcJN8q#2_dmu0 zf95!g>;IoX?C&J}|1>3v|FL+NkI1*__Y41Arg$vT-={ND@y z?*sps8%*c^yn}cl?EhnE|3Cgd;)rPf|KvkA_J0}e4Db(q)A2m){|m7HxQ+uafqz`r zp`U_(&-R1=SIIt#wEKSn9e~32(8)hbSCa70`Fc(6WxcPD4^GN%DfX|QwBeP_e43lLt-Sm*o?<4DEem&UVfYN~VMr>1kf7qu5`)qp@ofKR>iUo4`l;7WuqgJgDm{7% z{HG~EtLu8h-9 z5I)F?@&#x+sRO`2eE_m`7>sEjfPL=t0oVtx+v8-j9gON2Ao}dUE*U1vWO@tOCgWtC z%#;1z$Upu5+M&LApyBt6E*~=XhKzss-QA_X{IUNbv$y5tVO0YE)gxwj@*#2}%Yk*H zyOe$Eh)Up}@quROh^?;u-{IQ-ov{Dyh%4-N?f+i*|NEeG_CxpRwtv3;KdRdP!S??o zd;s2ST)pVuZ(j`i&ptqTc0tQ*j8ONnPaQLP^{sjS{Y2k^ApQ@d{eJ|$$x-+yyw+pzS?K$pV8Q*IWKry2bxwi*)6jWoN)-QfQ!q9l#P2tC zK^6n-J{@54EipgS_wdhGYHO!=)pud<4x-FlyK!$SSxq9}WJ35LE2_N=cE}J}QZ|)s zYcNLE*yi^0Pc}{d$u1ct%U1sHNBjT5x0P;aepuUokN+nP{-3$*MDj1TzpMCv*xvsa zhkZWN@$=fc&HpuJy)Ujy-aq~RpgaU~zVfc(JL-%>?|9q_U(4m(<(YF5;*niLVe+C_P1$G|=cK;O1pXoxqc;>ZqWq%a^MmyhphW>T> z34M{pa@@0u{UP2z1vx-LzhCZm0t}qCHk5tJO~cn7Of9c*<(y0iA7n-O0$_&>9e-8( z)5-?`W7Gj;PWu3e!M~u}<79IW7$vJ@mh6&YW&go6*(T#;oy?Q{zRG{?(6NEC7$l#z zZ9(?TwtrvyPUie#{!iGwmwQg|0epwJ#cu5S{(tDT{5J&H|839}JJ4pJ?$`+(((c;- z4#WN*fX+Dx`+o@Ski&-kKL-1MT>1XN_Wv||fJ(6ceBQ;pBUEHr^4H{Zw#<(!Ok8YRbEa~A%8 znsT5-{y(22IiVf%5s|h%f|nGu>TLh{{Q%Gx9|TQXFGg_*2mvN z-{1R)Bf$TE>O*G_VhVeoz3l9RjuHER2)@T*_#j8%iyTEvg1U)%iux+d{-1#lP?Y_D zBqIKAX~+57c%{k%7{BZU-lw-G<3B}CQP{Y^INX+EpMlplgtAY0S$6Il-NrxJP(DC_ z{m=OT>|=)y0OrUZ8Kf^xCdnolC97nX?2=)!Os2O!qVs#mI+1&gw6G$NGFn&Rkm( zX8C@tVVK{lukl;#{f=F7w5y^G2`cf75-x?%a%gK-Kq;IfAz#Pmu9~HslR? zv47+fc3^DbKI9i^-yd;*&-d5*Sz_Ez#r)vQD1YCG`JH>sanApFx^n1| z|83=2eEfdZHO{Vo{Y&TY<9}z}e^C9Tk}xZC+oqXgZ#v$`T`WgE_4so4{r4X-HdH?9 zCe2JOr%C0TOn7kvu%hAtjG417z&IfDXu+1m0d*Syxqx090C@mx1AtMox*N<&9{^ca zF+i~0!nysK0|4g9esAS}{=Q4zvm0ZXFP!>f+Uj#f^C$D|U&Ht6CE$7Ly4#&{yo;++ z^u@57+RAGG`&HM5@;|d-uO~xEc}}{2#(zA2AddZ~-+%g*PVd<*KJnGiXH5P_-LSD} z{>hWPW0(1^armO1U~b%$HMhmuKh8OO+CJs%`x_WB=f|o$zU|3SQl69UUoQR|;R7_m z7ifl0uob?+cEkVQh5Uit$RpSTUt+K8{~v&laS&sU=>H#q?{O4k5so1qc^tV3ClLET z2_NMYe3jGiSz|B<{S&-ekkYR>)Z1=KhlUD#tSFeSef2Q;xcFolFQHWQEKKKV*qa zku5St*2o;$BZFj-Op;Cd|74ZSl3g+^{y*6!<7A!8lYQg?bTS`6@sBye*iWF^|8C!( ziv6p;KeYeRzhLE`IX_<8AN;GnJ~!TP#QdonZ~cpO< zKzmM}Da(AnHv0v_7?QXb=fn@&r?+n}ckJKxzK;Qehr(uk7AQ+;W!H8bneh4xz>4Y* zaQQjSel&>zFc-+izv=@7|6tbZ18{SIR39K1SN!W7pkBp4{r)pQ>kNEmi;n)5mH$%p z127jzY#G}FLE{5B4o3Fj*tg!!dD#7pUU<-}2dR(lT=uIO94Zr2mo){-k&WSEzN;ku zTM_@?37yf7`~m8a4(JjU`-g5h2p{7Re2v4d|9=cV$Z_~0C!mu~LO11n|10oe==)!F zeSY};=<{cxA9Wk-f0}YQ#QxLo-}{5V4m~HolfHqVW$lpBCE<{5c~ge#=XK=y_w@D6 zm=|-0!uaUz+lSBHl~-40y><2az^TD=LyBxHN8V2w`AmBZnGinCyX|D*=L~abqz%B_ zIQ(Jl&2_pOY(ije>{I6$o`L>Io~;t zwpvtuFFXBp>oYIacmR%hGa2VP#|Tm8`3_F=yEx-xg81p_+sd8y+y9#I`5|kE*2j{k zD0xfreYyDGjQHOc!~$9n6WoT_zz)R!+Tbhfa{d23@c;L^{{I2j|33_0;|P3?qwqcG zgPd^v|5L92e@4arwf}$4=l|bYr2l`!=l@6f{pK?``h-0fsDI5s%=J{7TpZ~OG+8g$ zhFD=w=Q!>4n{$Ghb<`c}>Rlg}`F^fj-yUg8Ot~t>I{7CXstw@!|73@40Q&!AifwB$ zM*pA8kv%d<7Re<2e=@520KhESrTy*U$FMtt^WD&z;+FuNTn%PgDH-FNNQq3@GvTKSIi zP798EPka8Jew-O6?GEP6--w#)f8&?Gmq@0P$Y0pLWJ35LD=G#++esbZ@=vzN7+E9# zWY6TEZ2I{p!&d$ufc?jKpcc#xs&ju~|1n-@7sd@J{-1{Z$9Mwjlmi%Fa0ufJbnFlI zA7g)X?C(?bO}hMx?e7NuM_)hRxfOnYSe*uKZ~E;At^5xhKCWa;s{Vb;yDaMFwwLU; zdYV26dl#_DX;-aR*G;v`z_BO)E|E+H$yw5Ek^F-v9Rp;J4SfI|cPE2KI1W$60Kq>P zRrVju?g6`sf3QrZcVG+<87J#xelyr-3FZGO*ni<4enlkz7^kH3e(3wd{$o57i;nrj z{{Mw8^p`IDn{?&KW4ixe`Talq>%`|d_iCpz2=loI*?!qJY01HoaLKuWBp)D1mV@TP z?P(mRx!&$*``1ockr!t%>)+PzH}cv!iDfFSEStxX3E@N90m2Vi^7;V4SS0^ol{Q=P z4~A*W!}xCk|IN?^TcHz}AJhsRu@kzYo%SEcc7XqVI2ZdB4nnsahW*!V|BuoB(Dwf% zbkQm3q|>;zobP`HJ`8>TtIDsr4Zi*+ z<@-Twb6cD5z)8bVPd&!WlQg+3<$C|YBOLbe`OitcAbLJ%x%k*`rIxES@+`-Y3E_jR zC>`MPa}NA_Z2&Mv*2tXh14Irk?7xlyAU79`sy;w4OLoaHStiqDTju~`9sn>;_In!t ztS|cgx4rgR>gRM6J_P-Tpy#i);r#(qS4HRV#^F!*_qP_vA?1=WusG-FZTm#Ei~P(c z{aia~iF&p*qh=MpEf&2bb(a-4GwXIe;sGC~4 z`N37bpPLtK$}-=3)!W#Px*xuq&DJI|>nH7c|G^{Gv!xH?N584iU-S$8G6%M)W|D%XC9z&bsINJa0hd70{$Z51m z&Y*2_7V-ach*h3Po8?xv{ZZJSxxk{@{+~OyqpfoXbY8g&+Y$2YgO+@cpzvFY<;Vs5 zJz1p8_r*Cw{dG`E_IWPaeDhfj7&p(W^C;hcCu~BwWRgq>A7n+v09<~^5}6`fWQ?ql zIo$_{92~GnCK;O}qpA-O?SHaMhSRqHdprM|e(Rn*Suy2?>&yo##XAB-cQ6)Uwta2m z1Lc_Bwj45Ro5y3R*_U>|`5dc zU+_KT4ZV;4!w=B+|Dm%V^M32T|Bukm*s1y(kH7pe+8>{&e#q09llTns63_nPGo$T) z1#K9%{jYlMn%n;k+WsiK-;2MjjB?x0I~~S-O`p-fUTPnJtg|i97nnEivCDk_>oz;K zcX(8fnBi2x5AZ)%`8;&Y7r|H*$GA7J?8Tl$>6PRh7#|E}`=*}qq1nZs9Xylr^^dF18xM>G3h z-u6J04^YLNz?FS3U&qFD-0#@d>8kNQ%D0CNxAATJj(x!8W}m;G@n2s4=>xDGXp@y8 zV`la^AAtFGaXIa({U)tC=k>vrGUl)5@9x*%`pj(4liyMAXZ-iw_@DXg8~>3#AAs^Q zVPQwvc}l`5=N&3$jv?mj6&tJUsX2yRXj{lqd-~Q*HIioQC z(X{S!$1CS_W1!22N*hTcF}Ak;i#B>&9R5nZIdbWr*9H?|zLKDSEg^Ec%!v;UQ;3#Ke-u*wpB$%%{hdMpW3m9|uK5rcba18_-3 zgW~gH?Sr`Y#2Dj{*(Dt3AH(lwJWu-aTmIQ2q0g+6`usEgE0cNixg34ub*H*^P^dhS z|DMtg7~*^Pn5he7z5eFiMeDMl_n*o6(=2Q1F@6vAY%9#&lIM2*l@CIn*~|^?-hQ%w zB`h=hU%9$q)%kB&Wsh<>Y{J~4xru9E)9%MyKpTII3zT9`BLDkOZNC}you0SD?)T4F zwY7lhFu!fbH=i!pH{(Cc|Fy{g`-!9G3ZxDgcXMUG&nwCIkCUU`py9GukwOc7nd)W*0#qvZu*8VgxdcR z^Gg%MsGqkd^f#hxz5n~_q4s%MsB=xf-{gtyHh+7e62|$P*J!S1{8u*rd{!&Ye7!)X z{4zFZ#FV0A=W$q0yH8LIVCapliE@L(emf|}=w~|a=K*8qM%HyyTfT1c%)E0P!h0i3 z<|=7D&Uau%=0Nlo1fQFs(hc?sjHkS%lo-m z$MoeT-XF#>?Y-#dv9lLdEc?9vjQ`5#pU;VY<$%FMJ-HJ3%3ETtkV+jV%y$lo4Q8J| z+v`bnNYMTqUnu7-W~tizwGs6T{y9!7jC$IsEgv-LPqIq?`^MHm>4g0g~%iO7@lQ4|uO;jt>|%K6)JLu!%R9%*Lj%%l>1?eW`qYId>^+ zzZ%yUF_#x@Ion@Jm}CxjrS|!o_mT16v-sz;+xPu{7uhFB-*xot#){Gb!fh#*rLg@2 zr>~DSpGR0TDXh<%+s-Dk`@&UES!VqAO#Uff9Cud0yib0a8#HCbiK6@f&Octt_mLLMekuC< ztA|gDtUKmja(?EX!g8AH%=quQ{L{yblOH_bnvu@*wdwoYIM+ZW+wb|L)c7Q(t8K_gwz@{3xRwgBs-r462*tT)XiLsr>-v7gj>Q;?%Vlit6vHowx{f zWgpkWeCs&<{AuiMr5)27`M>qGu=js{-YfMv=bnigBS8HyWb6&8`vvQ#Ep>*DzbUo; zDAwnfUiO|nB}BZ=TqDMxUqir+jkXfm3ZDR;~xyC ze*bUAe<~TgdFRpAtz-}fo@DLWbey@!83&$xX8)B#E74XK;L*jW{F+v`)u5z^Ry&gq->J-%_q@-x4W zIaQ`E?JMi$;=k#^w>n$G-v5{R|3%3n?O4=1g_R$G{GcQ{fcvWBpaVwFYUnl}VDzFx zsr>%x`sh4q#!V~feO%qGcgn#(*=K3~@voh255Mi~c=TPT?eTY=T~EBHVg?;u$Upl# zy1S0c@q2uiP@I0jssuWK?;aEWInJ;eOm$IkJWKXy+1^b_agE1x>2fA*$@5*@%?B4Mb0`qD1<0qQU>aH94; z`uu7}&+@KOt~F>GcRX)7*zAtq%;O)76x07lMh}A3{m))@_C52VLmOTg|F`h}Sib$= zi*xW?JZHv#dY^@PEOBxJ;_86mljeJD_3K~lOkEZHPA`8upT0xV{G+IOLxc1}oUy#r z1st2(6UOIsr5@-i{>g40|6rRwK7IXA`)}~S2f8B>|3A;{zfDf~UW!ubfU$G7di;~4 zI5|PgA5PkD$e3T!cX6@GO zpX`!h&;AGT|A5*4f5&Na`EP&neRZtxe;|(i$F-?8fZzZB^Q+3IxxJ72|E5kzq65ax z-4^QC)86}iX88y7$I~B4bil~#RtIuDY{Hy8{;3Pb&C7oW3EAg( z1JM(cmmLi}m!Exp9yVuZZ2sf2-&gZ{!r15br2Lb$Apf6i9s;AD{Rg}B|Hb~3Z8A>Q zRr}x1|0A0Jo$wVr|38HPW4`!*#(zBSO*u%S12|s5|4!a9Hx}j?`g4Lf|Cq4PIS7I{ z584*=UeKU8AGal8pZ%d`9c1gp^G_Dp{!v;npt7l=8)q5PvC!E65;{2y2O zKf(4th=1la^u_!idCs536*=J5a-<@c? z_rCs}$-m_OTrlGQHvY+=Xa7z9!EB!WH~1&(WS;CR{vQnHpZ$g%PwP1V$p1n5|M(5| zGx9h2+b7_Ic>cfS0774B{;#M$4EAHleUX2y1ME7nFUkbx4j2Bl1(y7R#omF*d@b^`S*N(-`syOa{r>o{^aaG*=NBxKot+vV}Nrxfb{>( zF#swC2pyB<0400I!gSIl^JAwhZivNQ824&B+6m16^|$x=ne%xKpSvrx%|CG38mHfY z!ajze-(y~1()V*Et&`rie;od$?a$m_w*5nMf50XgHFJN-aA58)nD_X9K=ZG10HqJm zmjjg72dHuY)Aa$eeUpm;X#LmQo@puXhhyXBY(H6)4j4FmLLmF(f9#TDq3qXATIy6) z*T(woET=cQP0;KY#{S~Q{yFx?i~Sq9e+7Mi!MQ(*|4sM3`5wjqDEptsKiUgs4j|)+ z%Kk_70T?+z(R~1YYaW1N^uo&X--w+jlHFD6cF2ZG8Y3LqPkl`T%0a0OO1UVmlz~2TbNS9=iWO#d`0! z$-kK|D0*Pzg8c>TGsYiho=!P8+a-N{?v60FqqgU<&zuEF!70J1hfl&tu_KlA*X z&ZJw`#j??yD_oeD<-`@I3)!Ex*6CLpJvYCwzwG2!yWHRL-*<2N?B`#&$o2bQRXKFR zzv=tu=luta`+=ePqZ@Bl3C%7(s0C_P0TMRHx9$@Ub05ctsRJP;B1(_ct z+;ho!JO^LjoX3Cd#Kp1Wd>pIP_>b<%*iY&6^EnIq-khIe`>`bdGUtcN`vpVvrIqcs ztxM1BjgmWW)iP!{p5cYViSBFG)G*>-*1Zzs>3g zjGvc#M+ozO{qOFn8O1p|qsQ;j?lU);Im&&#&WpK!%|3NNt{+TnzZv%@Gh+Lr=KKlE z`|-E^x8}zEF!oRWzm0Mm+5yZ3&b0yDJYatwkbf?)WNmjC_{&qm71Cr@Lz9&z7 z@}MQ>`xN_czOP&5^9>zmJ=Q#5-Q?@C@w-LXeCmuK_Put$Yx}kR_vQS%{r-hxeqG<+ z*YBS<=O^a#56Jsv+n@a3hO$QSf4{-MiU9=A1(KHs5Y`3=84D2T17td&D0|9$JCjp$ zo#Oy8F8^yb{^*Ti&;g(2wE;L6nB)Puc>qb;0N!{&qYWUr0P%Eyjt6AEfZZ2huAQG% z^E2lNC;wB{+~y3rev4}J4;XV(?0$WoD~s{lpFxyfGr2c?e$(y;vLDdrA2i=@Y~MdO z=a=~YpOJmXar$k%_l>`jHUQ@Zpq|K$1UZ@m=Oo@|}HO z_*`<#>vnz~_hw%oWS+8b#{9$D{eIg|=Gf;iaX*#w>(2K>Tdl|Z;C2_XCj^aVuefG|BE_1o8F@5Yv+R{p21I<0d1YbPyn`e9BW zzkUe&%r-^)cVErekJ;WAdCXtZcIDz*66eaZ`vL6d`TYUyesivWzwO_P@qRMjr_A>i z=KI6;f79T<32gx77X;-3=Zyz8-U(8W4{W>_O!5K!^8)(Y0ZIoLeF8zgfYcr9GryQI zmFV@}rZ0w1m>$YB=LR1+zr(4n=RWb``_u>H=Pc{pfXx@5pYosA z-{f0OXP;YV)_hClF*v;lIt zK<;>88o?SMEsz|#Z1c7f;ubLp@D^q=EA>&n>Yx1w5%8mCmeE(mA`GLZ}+XlFY{8K+{amNGaHvue2KfSJy|FI6669O;p>13K$%9t@h3Pm; z_UkwQ(}%sj*g#qCLv@?#{tekQWj1fUfO}(nzn^{I9KZDYgKaV1FAiw)0XQbW9T%u#fq6PW_gkoTK&TGLWy?Q#q zcm{#ndXWszZ97{M{>RQ<A2MdLv;AAoW!%S=55HWwpGE${mO1A0xzDrt%WBg%b zUG`;;ABp*yxxPB)uiO0rw*QO5yMGD(>!2SvCxFry1#tkx6D21&H#dk83pCmR)K#39 zG*Aa1Cg}AGNKC->1%h=!&M%NU4Xg9Mu)XD(;kBC!hJ17k}yt_0=8sC~}!w zQf74_@4`IgJJ04r{$)-t`pDtz>%RUlzhC^L&T5&*rN>KE=L%pO?((Z_evYyPwZ~{uo~~ z=Er$FCD)hz`O@b{woTT9*0IkB_yDReP~`+mUx1Ml$oB~G_viztykNEikb9IjM@Wzk zF#852Cg9ftM!UeT3ryd@tmAOqVCsq9vp!~4{(JqRV*In3k2uGl{s+$Wt8jeY_4XG;H|iVd22Kzst9F7WgL{R6{C$g6Xy zdo1Od^rq#h7vGIN58$xz)12+U|6;GKhwgl)Ve;i|7kR{zGMZP&yUV<^@jdPhn=kWu zNu1xD)6Z}B^Vr869n#lt=K83ZpPTDTmdUiA^RUkwe)y{a@B#iyR6D?o1=w|f#00et zP%#0+7f}5JK7T;^3t4BXP!~w?*Kx>ar6Y`I(;GgweDm2z-=Der^Y`B6oO<~~ttWd~ z9d!3|%;Pyk*3>?(e44y_%p*fmi7RnC$?S6M*&wV~o-c;B`c`1=u&poJB7t;Q9j6KfruJ`U6TAKrebef$JBj z7zygo(+7rLQ1vakA!uoPWhUqP~jZ6a@e z&huDzdH0xCw%&bbw{Q<1Sn_)E{C%(z)ZRDkKADp?znSB&;{B%I4~EHd5aUtXa2)3c zG1>v{JmHK5`1%BGI)HtZDnG!833z&deS|Ei3zav_rKt;CzaUQ^P$&5Gg6M|=zd`gw zFIi4lur`qYn!!VyW#@j^IrY=dLLJ#l?!7?wck_LjGM2Y4^5`xptE#wmUd`9%GOzr6 z;ofNH=lT2Kgv>CWE`9uV_H%8174J9welQ%xdD!>he;|AZ&Jn150GT65#R9x|U_3uS z=>WHXFy9w&`w6A5(60-8`hfm{=_7b`?bf-{3%=*kTecm4;eDsNws0KZm)z1NA%s!8$H}9NBHV~k3Hi)MBZG^4cjiv3-1!or#w@(#m^V+ zIfhsH`hJ_Qa{KgnUdGngzAo_jjj?@XQu_MHDw!p_aTt%<2j^+U`Es!UU!Q=f0~ixD z`vs^2=)2_l2laadg7g6A6J))Zx*$*=&_{6nguHfx=!RapTzLFz9{)2pA9fBs`Kw%; zsh8ff@KlLQ#W?C+$)d<4mSo-JJ&$?FH{)PI-0#QyU8cWJc7%O0MYb4oQ|d;ud*fbAPo59oG*_6bZ~p!I=n zCx{L;^@7y5Ed9@;w|t(oc(XHX;&o2*@4ZwYbG_vrEBQV|zWhs5CiQyGjww5DG9O^? z&33+ww4d2~z>}$@UXWsSv$lh>IJ@Xz!-tsy3 zSoe5G&aTV5>Elz*Df1rpuCGr&*|hn>zUDsH#}~o=Z^z|1&3^DJz7wVcq;HUYk)i`s zdmz9U&~1WTyMXfwOP#QOlrF$h`VClrsxDEV^qsU1CBBr_4b%@oI>OW!*?OVOW_1#; zPDH-cQu*+P{E>4hlvNbUF8l9Ao<+VX>*D9r-iL9Y^Y?S?lQG8L0_{H7Ov7~2W8epT z)6@aFUqJT_^7=Stm@xtB0ggwY{^A^BY{QuSgw%D)CqNxAJ|J;Ii4{tHN&T5RLDj8W z&q_C#>+&3orPdjuJF;a~A9fk=STOG z^Ys{B8Ox(`dfl9U%|6ETp#9BuIP-JJBAHCeaWVVj_b%y}V6JbF?-29)22@Ny+5@_O zK;i;^J;1h((gV;3tQWs7P<3bc2U4%5UI<#J?#(OmoU*01O<6qz*Mm=Pf@I6wCh{mt zvF}05o3=i$jqm33nC*PY>C5x?!B~!c73aT77K>py?XhmZz&ny7O=AE`tW&jNZan(ciJ%8GT~k9yfE+e z=ehPi$G!Oadfv`3f1k{`eS9U2^C#5>&;iU3P&q=9D@^@l`T~J^z-t%iv4o~iVCn)> zADB8p)vfpn)D32l=in~=&nWw>ebKBQ?De2nHf70_F?U_$(9gQbdl2)?-Iew|{d~sD zw7n1DKF{W>_jZwe=Ju4Ne?KYn{{3+s1K@*v3+<4rg}#7}3$Wc%s0VU!LLDQ>*9D9f z>_XlH^?_d}uulEDfpzXL)W4C1dO9n8uMT3!hF_lipG6MMrN}E~SIIDad-3nxK75Jk zvoAl0duiwAa(Z0una>Z_$ef?Ua(~7(t%6=s;|4unfbSMJas~4BKrT+mdXPQ?r3+LW z!PN&w>`>~{)C*GI{-ya$vURO5vwBEg4}Q7we>OR%d@;tj@e_pT>N~^ zz0T#^40a^O=lc5`$Cqj>Pj~4C*B7|Rwu$Kra1J8s0e`z7=M&^~fy4@wK5*L!rcPjA zg6dD8UXUX7j-{s~vh}PkN+<)0YmqaNJ69I9OzL?tD66Wte!cki%Fg?k7w%Pm9{hYV zLRNg-bMB6dm1y(B^a`%G4(029J;3`?@qqxJK^gU7aBH>@C@za*MPn@}G~^ z9oe?59^%PBPM(xp1<0MqqmoTmR>h|m8Kz7N?~=PiJ80T^a^d>F;y@dN& z0X^_t#0h`x*9DF6dBiV}HUjHui(79}e^Q_3l6qBiL{3joR|FO68S?0n9@_m~G0WP^+ZvD2Hj;T}1!zy=hKCwL9I;1kw^_yytz zDgB80QgH(=-TWe@7pNNo^n+Rd{&n*?W$QU#G^>mJy70?Q*k{_NJXz!zT(=Fc+VQmS zig)eTi*N5T{|RMZF#s0GL~mj|$-STshCm0bK{=1YIfou;xbMxsKs~*V^8ZjSqwb9I z)@9VIS5ViN1IvTh?kjj+m$Q=9L6{8q5s56^p-x24wo1%1pQ_jkC5-cp6%Zov^3u-t&< zS#>R^tM0_I758*Emim6H-Mbu!{g30GzKH+t!gUP7FPuhA+~sWe{Ab{mV)^ct85Lr&nE%ZS|;|OZdlqbKji7QLHV>$vE|U`fS`z z8JmvtUc~;>apV_qg?Hi;kLUiA)vt3e^S9392=0Bn>I}X)sjlh*w(y$o#xuHzBkOTR zm#}TNTF%89Yn9K4*Ltez#;W1C+7sC4Zu}argjdjr^}E#Xufw+|)%Ed?_$+v*7qDmU z&bU4uTTbEMT{yGe^LkwCboE=jB3=unk-s}jUCXShd05w1cM*3GdUlS56<9yiq4nb6vpQ+K8^H+J);QGXtRS`8+6{GY#^1Ceozu=MFrlLQSZz zQ#63S7s~Zlz_tG>!}rzocM8AtW&FlPa73OplPA>YJ8+$sz}7J6YV%v(IiEl6#ZWLb zAKz0iiuTYtW;mXv)_l1dVcn8fYN%!`&1ZVX-J5!rzc32c?;`$Dk5CtUMO_^krv8(? zFI9~+eurdGUuuGRZ+GCVTK7uLPgfS_D>yT+gV(K>`p)INgJB=f<2>Z-46d2ac1*!F z({A!w`6N$bPqJ~Rs;hc+JoTnnDE=<*;WyR(7eT}>bzdZrPyHO0n(JIm>RO_Va4*Wd zpZVzp*QB+9DL*+)$m9K5a2o25`XlU!Q@97)eT<7Z-haj8Blg$w!Mhc`_Q-!&Hvj*w zefoh5ztjG!FZ|nGfBPG!jx4>q<(J?6#qW$h^xn6QK5@@CcHc7juTCsnxa07+-+Jgj zPx>Ew=UiM_bK##)8urMj6|ev4{Hm&c@V@Hnxr9EfQOoK2(~q&Wf7OBo?x*YNL9Jh} vKh54)1)t_?UvobV>IZ81$Ft0yUW0SCZD`xDX;br#rhWU|mF#oz_3{4!=$J_E^jj`H*f@zSk! zS&EuZSDfez*+9H>qujTrh4{1}^6>~UJHkXkn}0(ay#K=hVY;ofC;H(+zkcIx;TZq&zzK?;KYhGrtFx(e#7Y$FlYOQP zgTyt{s>C4&sQM0^qA;!*Ozab1Iv5h48xIL?Ba`53z~J0OVvLn!IQ%%Wju|UPTDh1z zaqOY0#JF5H{x*D8haIfKNs~BsfHy`=B1@8{97hdf2IlrbU+O^@{3Ch4M2MA(855hS zW@2kHkQmpYqU!i#skAPa+;zDf+N0XvNgmXCckLe||I_vtlBv`F2gyXYe~4~>@Nsy2 z@I5fMpQ07&BJaaey~ol#v``q~xZeZyumx3pc3z z>sDiX|~QYV#h@BB06leyY{-t@jvVDW65-<%J$72LJh_^R(Oc4gMR>Q zD}2a&Za4RF?^#7WPKMgR9WR@5XisVmwvBoGGm zMgH1)e{j5~v9+!_*brDb-gBrw*cxbVnqE}kRsW6ml(#puwFmvvoBZuX!M6mulBbwn9XNFS%vyv z)paP?fw-j#M0I^i`tu-C|`MJ2ATq`Yy9=vUmIw^HzUwg8{Aml+}KhZ^ozwTvtfTl zZCmZi+E#y<&uk8=4p3R)T^bCuIo`6C7Jrl0FAfH%TbqAzu${adGPAa!HNuv(`YY^q zmq;<=3rxOgHT1xZ)(^mW(Vr){Y}E|A8}}NLwloNR0M+ly0+%vMo|{5TN7C4 z7iA5B+E$_Jh&fuxXGzoArsnlci#N9T$*i$?UG2&SznH1ZP`u4A$}1K%H;P5IjTM2` zwPI&)f`2A5NwLl*lRTbhH|Cmh&TUqzML>gTt&DW@_RRHme=e&yOtnAu#{ z-m2(atlbzm+Fu{h)Na^GV<(x{9ElQ66xNkD*EP2mRjfF;c3o|CT`?lVjy9`^a{^6%JB8{KyQH$V%BK4Hs~GA2+D0AdXmn)Nr@CVeD{E*FY6M|6g<7wD zGa71})+*X6s@DcuH0aRshGs^QD!;nLUl*utu)CyHt16q;1%k~@jsB)K!EhG~np@gi zL^+jd^P9R?ZfKz`QBlM5a*=5#gd@QY4A6#Zd)T}`Drf0 zF<7hYs_LZUDa&b(9(H~)r+IbdI#nemNLgK5U>&s))l3yuqgGM5!C$A-mbV9k#EJ}U zy9ahs>XtLN7+SVhjYP+%Mx*0ZBT{)8BCMRPEF_9mZU``~8KjH-!A2%L^-$`W?F|j{ zYMEAwlm%DQq^7o3p~{ai6;|PI)gzCkR){dO0u{%h@+{hMHE$`_DrpA+sK4g!O>iYHwV|UCiS-D(w&uani-AN zwX7W~4eL>`qPa0VWfV0gQ3OM-VxiP=)hg5878PNBaCL1{;Ap#rDz|C|GxM)yp1*B9 z~1*H)iJ7OK+P29O1{YHZqbEv%b~J;MGOY!G38<%TwYliH5Min5ih zED>$Gd&4@lq-wt|hJo42h*LR+y?PmTNVqm?#;G{kwbyAhy%qvt&sZJH@!ApRHm~z* zt@hZu^5&L}TBkjZPOlcuLT@h}YB$u;=Ci>WvYLL5ED2`l>h{d>x6y;zwAE`coo=a0 zphNYZq}Zb7X2+&FYS}vWVzo_Gx74z)s~9tb{wTJ%xvjRLnyo~K*?XbRTFrtes#9Vo zXVX-)+8<=GoY&sC(y3Qft6JYPj-rk;AWG;Pw%gy}ZubkU)49VscmhW+gu-56=2T}M^ehNI<;^)N^LP`EmnOcR43}_G^4i>jd`lu zS4Qs*ssr`(5~>%=T2((f`_wGP5J#!{+F*S|qvAWqN>SOQdgahSYdhvw%Z{F7`askc zAVlT0hy@)Rv+Ov>8jQBS0-HCl))lR0C#h@m+tZ5~y32B3y|Jlo4ZD{*DKO(#`I&Kb z{>q~$vsDdvWrLZ)=Em97)LDqiFi_)44oR#PtgjqJYJ+WhTVhjbSLZSlLz&hr!sKQa zN8PPUYXc0#pxPf)@?Gl2v9rLx!7o^rTkSKYsB_K)>q#o?BL^qb);0xZlPG8K*V5`> zD_agv?)HwZdoy~`R>jY6TIA=*&aukReo^1LxLIk%;y@dXRU?tKYehAW^}5D~s)Mbl z!sZ)9b33D7^SKO}+STlDdjC)xuF$#YomNFN&DMz`yPFP+s<`58VWiU$)sCfSgVGz1 z>f!RndL3go+e;nuP3@}oX;XWbwA3@^!+VL@WERx6wz5yus{=I?-&vz|3O(8Et!M#< zFKr2-m1^13E2izytC!K~I@-fudwZ{u)%t;orLvVVV((h>*ZK8XUayh%O03IQ`t|yR zwxlUgr_K&l^O>(4p7lDZYTU@kQ-*3;+1h5;v}IMT8jDdg%9+6W!3BfZ<0X9T3?Dh| z1D<`F?0u4qK1KFw3g@S&GoN!V+hzDt7j2+9% zI+^S;0-}x-(I<#rr-xoA2YqVLecNhxv9patwh$etZ5g%d?X+z~wv5Pj5w$m{b#na z&y$Jrl{Yu2bz7an6pbEjCSp+}%|ttvI@7DzxX##Hv0`pj#hew66KGqtBCx)7O>^T4 zuh&}$6i(JYCnx7IOO@ap4|Ra!x650yXpZh7^*pAxqM(1Szimx(y?LP4tApt%v9~IC zRp}ZEMOD-gsnT5^Z3KHPn1RU7!iuDIoi*Xscsm0h1>Z>a@N^9F(RYY z4v%m(#G<#+z4d|`W8NwD7$cb;;C6mt78%4VbbuXd2Dzm2Odl?wr}qA$rC}b`z7~&T~GB@0{f>K`PIviE8qU z(&<`8@tyPBB}mtkmBnPHuMjxvaKUMB=FVlN^T=1A_Gm_!9(FT=+;Q=!YadMQs}HWz z)G?K9nQKM0mNYgug(KK^uvPPgJ^0m;DqKu>4OY*7&V5+{b97Z;bvrjAYQ@}LjPT~q z(rw?-RyD0^4kw?*6=-ck_(|FvUY+)EC=Rd1&Q`7uywMp@?bS`q9Bb;#b}y=&OB!|m z=j0UWdbWe8I~?T|YRg*8h9IgJmn~kyF{eJVhK8#Ybx7DXu$K`c!OlLT*J>Uc0u6z- zjgioB8|}>qLpHXsA_mnK7~n}rgiBr=fZi4i|Jd%REc|KAPLlNChO{!A28qF=HMYGxiyRocVww>p$ zNKO_0mF=rntB0_NuChMBwVNK#y#q`ib7|Yet%W+SHt<-}q%P|G_3GRg$;Cvj_jCPY z%&vD-Wq*?_lEkhI*FVio>Ri`5KdzEns-l{u4r`n&loOqUJ_yg{;mse6sIj5G##RUK zD6QIWwCz@LD-fk`)(b#H;S@Eqy{RsubOxOYa~>S+>T`HfcH#Wo+l=bC;uqm>R`|w& zFDf3d7Jk0Q@QXUpCOpU*{2sANG^4G@AA~i-BVpz6I;2$;i3;=wi(0V`sYV+V0nws! zYQf(uer@dC`MqnnVz)Ic5DRn-TXddn)SC-Oa$BTbRo5WxQ999a-v8G|Qs!>NBmv!3 zG}+yV!PZhek>(d02vH^r!j(akMs=d-w;Z#z>s0k(xe$Yv>yEQKuYj;xIzqUJ+40+Q zom?qYQq@QGj>Y#iI_!RkjE^RASWnvCz3_iKPSn`ql0w%H1H{{<2p9hB<&3@X$nao{ z=#dvT$G&1U(Bid1LMnfMD%y>fbz$vZzB0NJ(`MyISkgt zqHyPcs1$tFFJeM`?6m(g1?%wi~B2)37J&?5Q5%>iqlZc3+FVR9(Fku(RzV4O5|f zOeaQsx{0xR2-rAMHD<9jcxjOD7n++YH`MuC)M<;O3P(F>M@o>+do-z1BrV!l+vHgq zXy7YS&Vgcx6sgW*vnTRxq7a!nJ2~Q$=<@!`icIM{K-@5 z>+*}IloaQeuB=^|zjDgTVt+|tv3KIC622yvB3^w_Us&L!%~HR06XiKvibLiG>VnO! z&8yl9!q=|t^?~LBd$(#W2%juDhXq!%u^UA-8(V|E#Bz4-=3qjheknkerHyF{^hq%> zd`1a>Yg(|lxw(P-+qj8c-LO&ZoAu!%tNwb#AB-=y-!gEr3+LHCNB5uWa5mniYeuV`IVCkr{otFme0(eQaZ6B-|H>&mX~@ zu+T-QbTdmQmQ<7%73Pz|OS%egep$tgQqq-si)U7pOeyou;C%`y7Elm1cv>fqN;!G& zDcwv6{ne$)!)NEA78{+X;*khZnU?N7Q|e)VbTgdFspLh)Gb&5UCVKNLD`r-z))eK> zD4jTw))ab+XH1+_QeHYUYFMZw#f7Eb;$p8ie@3M?T*buvvZ5(7oFo+!OT49CQ&|eO z?T5$i9hHT5%FN0NvQb%3^TK^)VcU=_Ouw2;O$VDec26fU`^?Q^*pyKQo48MdJ<01; zy6FSMLr3*!R2C(B&mvn2k9u_PeYaJBChAT~jS#zU@C*tUq`FxZbRWH=Rxw@I z!8(hmO3v7OC3kBks-l-kRk{j+sqi1S^4Dhi8D*e z3iGE-DWjA1{G3s)hNqs_yJYrhI5T?ysm%0sz3u=fGw=Rp_E|VH)5^bvHKx*^hc$M| zQA?6jTG8H1i_{QPd=bvf_UxM3#C>OGuQp`%WjM2!bVo*6vt;kNIK`@(nap_EtVZ|N z%Q~~DD7%=qc<;GWGxjGtvsZLxXsoctj4)SNW6vj5`y$rj(uzWFe({VcEW3K0DVtofOfnr@D1mt8Q4Rb(9XQH6RdiYLyj^cLpN^p>gts5h2k zZ+HMkHWt$;omAvYk-MAqB65csefMcE5Bt@;Xk$fcX^*uT`zC*Mx9;4T&eH+6p%J$+EF~*F2Ou(pS zMNMzjc4}=~cC-{3yRlcVd-mws?%Nu+aVfxFCZlS*@5M+}&25G*dDtI3_A;rC*}JQ) z`u@Wnh>_yT_F)_{HOJ1K*G+b_eeFWwsv5(l=xvc)?R7J%BKv6f9;TOCKf)t+j1-x> zY4=XwB&l9C$0~clRkiTWnBgs|EN7RVS*#9iyI|-6C$HNCb`|yOO*KAgqPA)1hDz2y~$*-8~ zEz2*S$Z>Z{S#eQ*>6Bv5X!P;S89Xe|cC{vwfjKqVQ+dxv!Kg2R^z_)j!!;$CQqqiaFIi+Zyb}*;6$QrqSwHPl&&Te{CsdTfVzeQ0-G3!rcMwgWoPnj{LvN*q_ z5aSk4nxyulqT>9Dva-So^*Aan zehe@tIeT(Db;04tAbM9RGW=-5ULOysvpIL#^L&C7V|P<|+nCW`+x;hPFlSGDHal(5 zle%=`%$cR7%;(B7j!E9hrTL{LMJ4&AlM0K=d6X-jF}XN;V4LHtJ*ia|`}dHthv`q} z^!g4`jT5sE+LJn}woa$gk++AQ==I%aR7dQe z2`I`O*Pk%!)x;^2E6QfhRAb&dF~7K2J%M{GmS)psk%}{>b~>BWAR*SeZa*SNRec|KFyo{cvzw|@^Qf<^BW5?}0Q?y9qOx%#0kZ1-K)%o1;9;l$!8Q}QRxEUaV-lz3Tx zX7JEGdE(@f5-u!DOSrM5{^m@WpmUC@|30oc_H6s8ul6Ih*SV_#?T<6$9mDThe`oZU z@4XwM>mNCRJ8Ab(|Gn5hssVenf226)=B;p_H*c!t)Y$BPdp+i>VPM{d(C3)_yWyh% zvkjU(%6LqW*>sG?Y!PPdwmtv;nr~KQQ;1nsO(A9lG#axAnB-37v*{1_EW<9VkAjbUrM|pGKV4utx&Q7W3F2x+D%`?8a`*fn3r*r$P9Ld96 zl$fKh89L^uYI@cjIqeSJL$5ib%6WTFjYeZYV<*hUhah7ovqsow9fIr+o>#+{N2Y4# zGRKT8V~}Wa?{%lBt~;o2CV3BpM^_I+)D( zHAXVS%NWUQ7O#cPW(;XO#@NOLCdg>)%14@Ks%2_y`p&e%^)`BHG|lg&e+Eo+@4p_BQ7KSFmDXy32RJ)GQ%44<%YQ{H$~WY<>YLN z7!gioKdTZnGOV$mInmsqk0^M|R~dJPH73RVF(b1ktTBB! zH>@%JJSVI%tG3C|?q>!`87gXQu3Jra8w;9lGl@;N8Jn6QGptQTjZIBOjZIBO%@8pa zHG|CzNHb_m4b7l2H8dJiLo+V}_cEV+N>+WBT1x-po=H z$BYCM$BYDfXzlkdWCphVI6+%Y)${;Y`q;GG^q=vV{xjWX_tqXB6?gMexN5bry6IT61erC&EI4L0Fyq~HqnT}H zBAVG|rj(gUrW?&XHmj~#Y|R>LmR7T(nuXM?pQg@cFq%4>p=X+7hNoEo&G0Y{^vqNJ zHDgf#tbzx_;ww0yAD3H zdfQ#K-}bPpwtvz8S1bhB)l6zLFU;UK^TJr#ECsuo+)NO&Y?_YRd6E1tS@8b7HOwrD z#nGWK058gn2up8v6G{Ci_)FEuuO zZ|r3}#&E`CENDDtP#Vv!ySv%ujoppM?C!>6cL__3kD5jI%swmnZ;qk=n?~*b*7;x6 zcB@8P!#*cRtYc2e_Te}ZV2;N2i8vClYww!Av`xQ%dw}Vg{f=&C)~n$u_FC9uo(KL1 znrAAGXRlRKANh@Uvze*N5L0cK%3fr@v?_ zC~t3VYi^ud8*E)u%ij*Q7DWEEY;m*lA6m<=aPSvN;TY#+!l_qeS7 z>B_Zm`=`e#t#V}Q33Es+Ql`ZcyW^cco>-!*C@NIdFj)uOLq7N^#!6PHI&QU{=WOQ@ z%0~GJ9jObn?6ej&BGY8c>f?z~o|MC^l;w7MRlSrpo%tg)I9>a0RmvKwFH>riccC(a zrGuW(_?k}qh^~3ZbLno6MYbu2r7U-R9hX=!m=`;WloaJljuSF9J2jhy*-B53hZLrC zJVl8Y2iGol>|^C)0JRi87_*QQP^ws#2V)Vrn6OqLJEHL7swq zS1z5HODE>49?R7|7L!X}D3eiQWI{UL(Rh!F&~aDM!`bOpV0W4 zPC?sM!spUsP8GV{!B#U;nY%hbI1cvo_2Y3g)zrO5QSco#8}=J)2ph%Fg)9?b9Z|S$<>Z!nwJZbX}vCEelzC(6uhUbQI!8IZ^OKipuLn zs*%HxuTfk`M1C4i>rcd0KVeycZUBDuyNiz_e?xX4Dm}r@0>2?qao#KtX#;Zx#))ZQ zqF6BSM>I>dre13jYT&3~RL2ncDC+#0RSotRnR-yAXuF=@3 z@v_0U52kdDZ)?pz2di@X4#^&pEDjj5Xh@>?^$?ZA$wO34t{tM{-=*=XAu7*zwg2xL z`wms1BQzEb{ZX7DD)?=}WKlgdo1c#q;;+dH)z;V{`-?A=ze^sWnSi3`8N`#S7Phpp6MKRK*fvxNSt zo_)o!I+vlaxvJE^Z?{T((&hYfVt1kHvyY`SJyFjcxACPco&j&j)LI_yM;U8PId ztkdO-TQs{wvtpRarCY~5z+q22tXqe@<*+9-`_y4i>0G{o%@qfTH#KvmD0UD`Eym7k}3==V&%dF=DpCMu8-<`0!RQnd|bcc(e4m;8b3+k|- z6Lz8wJJAU{QHP!Hgk7k^u6DvM)M58KVK?cpXPmH`bl6)?*!?=}BPZ;B9rm*mwoQj6 z53uXGO^0Q|1hsxvhfQ$8p4DMhPS{I2>{m|MOFAs*guS7|PH@8B&|z0NVejg&yPU9h zb=Wp1>_Z*)x)b)H4*SXp`&5U;4Ycd|sSXHSb=5o1$&|hm@4@UI$TCZ@utT*~oWdO}t z8ZQ9D@lTaaTCeZ|{9*m&vK7r1jdy8$LgODbehfxpZqP9m-X#@2q4AFzKL%%e*jD(J z;C!pd%O6l^c2Po+HN|U*r!_le=z-RB*h`w7H?+bkgMFe|rxW&-X6GjyVpS40B~$P@ zKVgM+FwEz$wbp#tY|ZTQT;d(gE)wglCEgg}9i`IQ<;9CBn%Obq#n3DjcAhxiTFx(B ztB@66}lfyo=HhTFrW{3S9re0XIbNKS~ELRjuN^l()2}??Ib$SPynB!ch zdpV{#=_a_&_p09~w{t0RUF98NScPkgH^ZkLo{V37=ug66J>7>-vMY!m!6& z&v<7U_KfQlZ&jG-9y`P^RnIwLrt3M+FjdcmhN*fkF-+BSsbQ*~ha0Bq$%2!BmKwV;ij9hG@oq9gau(8hMfpI!LajTCmMDgtTW7FZ;SoR zdy-*~#@^)JY}iY&$9c~*>@UPT%dqc>`5VLf#U1Cp(6BLaZQhH*EJ@Y+V#8FeFELEj z`clJGtuHf7)%tS7RIRTFGhOQ|4O6wg)-YA;>kU)2zQHh6>st&{wZ7djRqNjxHYM(R z?;T;5q(IzFARHDOh}+_Q*syi5 zM-4k2_B+Eag8kmGYhjNYb~o%v!=8$3@jhkPt8s~i_7^g0EqD*M-GqG#d&aQuhGoU)7rts(0qk|d4v2rm`-Wi^us02xA3w41ZNm6n8}m>NC&D2HPg)ejM-`eCREQ~fZ^Fx3yk4O9J) zW|-=Sbi-6Xj4({~1HU2?)ejklsebSnruremR6j(RvS5U%Udarn)4jr<1llFUs$Ss_ zN*$(ph1-0GRk|-L91~`G1>?nfCrqtieD~=vwSwgvrdBZiY{>~zD;R&B;V`v=O*Blc zU?qmB6>PF$Y6UAbOs!y34O1)F0fwm+Y?@(e1)FY|TEPx7Os!yLhN%^-+%UC*RT`#N zuvvzw6|BlIwSpaDm|DT+8m3mT1%{~=tlBU&T9+86Rxo}|#j(qw?&}JFW!M_`7H_S? z;`9?yT{z6Gb`ry+>WBJpm{k3++A!4*0mD>3tTjyaL!)7;ADRtQ{cx0FsvlYnQ~l6p znCgdi!&E=4Gfefvdc#ydY&1;u!zRO2KOAeA>WAYEQ~hv)VX7ZG4O9JavSF$pPBl#R z!|8^pemKi8)eq+wruyN0!&E<9VwmcO%N^#@{cvSC%&pdf2va-BRVGaBBv%`zc9Jf` z)J}4ZVQMG2)-bh`Y%xsjB-a_Hc9QE2Q#;8GhN+$8M#I!ja+6_dCkZpV4Pmy;t@cgB zq)@>>omvNPGfb_6w;QI`!QUFD*1TG(f?>+?5vD93VajF^ruyNUD_xjvbE_Mk2vava5vFc< zB23-z7$(&XPlTx(o_E6KNp-{XXT#JD&%1`H8=m(JQ#U+4hN&B#_YG4wJby7v-SC8& zy$6KZHn+Ovh%j|~@PSFEZaF?OOx+%QVwk!;_?uzs_TUS{)a}7nhN;_wZwynn2mdfk z-5z{rn7Tdq!7z1u@RMQc_TZN=bF15fkYVcfzb%7RPBo~ zOtmlGFx9?3hN<=?8K&CT&oI@#6vI^e1{$W?H^?y6zM+Px_6;{owJ$x)bo)jcrrMX` zFnjEJOqhD6j4*YRk!ixzO~xq0)J;Z~Vd^Ghv|;KdBik@_lQG6Hb(4`}n7YYO|9YW5 z-MiIIMxJ5niFT}E>WOxoVd^GhykY7lBf`{8M!pGCHyH(CCe=;G1jE#mFc-DDblVbP zw#}_95n;*_h2eB=Wr-rglqDt_rYuoxn6gBPVagJd3{#evY?!jd6vLDyN)1z%m};1^ z!~upWOH4CNSt7!eC8nD&Wr+jBOk3h0!;~d_4ztI6m~C^byOIb~cO_-vbZ&K5GQ%)+ zS5j`6x+|$LOx=}KhM811JTnbbcO{1yrtV7S8K&+^<{PH&N){WY?n;&#rtV4(Gfdr; z9PTi?Ma#osxZ8M9ZgtabnBI@V%+6&~IHpv&M3~Cu z*l?K6#W0;qnAy3gf3ee^#p?Dv!qn|~M>tHXJWmWWou^?s&j`DnRjSj8X_s)4NvBGP zFjc}S;V@moXIFie*aVXB19y-GOUq*Jp$!qogb!-T2%cV?LBd32UxY95{KFuT@a zX0Ip_rt&-|oX)NCJU7gAp63~+^88J&Ji~08TitC(n7Z3OKb+33?zS&5OxvezsCuUwCg`h)qAAvscx!W|5^V3St@%r{gn}D ziEs2c{Kc_nq`lagTJ^T7(pY_!^}_A4HIYqH zsL)Ftzny0<)DxwbW|z66EOX^@TjyS;sF-^?2^+nda3b1bwm(r+ ziatnRFG>Z?(-z{7T39N8v_sSmJc@uTT8B zaI4PqPO#1UpvK>8&35g78QjPlM=JDvjXN}ct?>tN6K}q#P`AbuP!tUV?7CGd|f9R+USpWaGfbZ!DW_%DIccQSaII2}A!oC99Ke+l9e zaVdC(xC-nNTfpnYP2f%9Ht<$)7kG!bAAEq3oWQ7m6YLi6f=`GKz^BD0;B(@0@HO!b z_$To__zt5uLG?tkn-PH}A;Q9l2q3a3oQr9-> zbG_?n{99eme6Tr_z3HU8@u|WJJ7J@Dr0Q<-@zyWd#m?pP^S@KnIob0ix#6-EnsuKsu zZ@_Xn#}z=c(AA0N2=EYjIan^cT$@F;yxz4Hyxp}Oyx+A0>~^{2GPxa0lP~cXjn(o; zmq$J>TrpW_62N7$C?*emX-qkq8DO1k0GG*iF;(b~jj6+b3Rox40@LKhF#+_ykLe(v zXJR@DeGyEPe~j6TUc_#}?*^C2iLqPJOpWaZ%VQr$KL;e|*zIVJjqL$XiQNI7!=Is6 z%S&S2;5GaWZMD2PHp{A$cZ191@4+(8)$5){_Grk7AFuu-JC$9q2 zMloL4%W$o!8EzpU4{NQcMW)|I{=>R?f@@!Zw9Y*cY(LKw-EClaG8A9y%o(z z?r!i4_jd4mcMm8McYy9h5nC-&6J4>(WE$8iM}cWFFVT&@I?)3zPt1zlB>iBTJU=lH z&7+Ava9d(Inis)3`2*N0U45$1C-$iU2lS~UG#%U|XZ8u83H0dzgMB)Qxe2V3CxU76 z%s!jZ-`A%L{9T_dXr2Z)$#42>MKic>H<;1)aZ=@ib#eljCQJKnM_<>s2W;s30rA_x zGl_9WB#wEGY_fPVG!;-S%Hpx+7nw*uChvujxA9!?9 zIhszeRo({H$$OHj&_9+`13r~hN2-^=H2Fe4gNFvaYALk$4NV`-*z-b{d&Ly`h7tB3NTGJ^xJ{v zqJAR2T3+4H70>AH=f?j^KM(kJzdZ26em?N?e&zA4@;fk1{sJzOIsL297xb?IC-<+5 z-z0rtnq1XCfacu(9pI(?JBfKM*ebVzjMe^|(ZAKd3;dw}7BqhYH_5>%ThWxKbc1tJ z9!I|fY?a4@b@G&y?dUH^=>e}y`GEL0fQ*xr9cX??5ee1ON_8c)%0A#SnF`j)VPKlf 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 literal 0 HcmV?d00001 diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index 3e9a8ec..cacb380 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -339,7 +339,6 @@ function mkdir(dir, mode) { var paths = [dir]; var d = dir; while ((d = path.dirname(d)) && d != '/') { - console.log('foo', d); paths.unshift(d); } @@ -369,8 +368,7 @@ function copyFolder(src, dst) { copyFolder(path.join(src, file), dstFile); } } else { - var data = fs.readFileSync(src); - fs.writeFileSync(dst, data, 'utf8'); + sys.pump(fs.createReadStream(src), fs.createWriteStream(dst)); sys.puts("Copied file: " + dst); } } @@ -389,9 +387,11 @@ exports.run = function () { if (output) { sys.puts("Writing output to: " + output); - copyFolder('public', 'build', true); + copyFolder('public', 'build'); - fs.writeFileSync(path.join(outputDir, output), code, 'utf8'); + var outputPath = path.join(outputDir, output); + mkdir(path.dirname(outputPath)); + fs.writeFileSync(outputPath, code, 'utf8'); } else { sys.puts(code); } diff --git a/support/Make.bat b/support/Make.bat deleted file mode 100755 index 155a4ff..0000000 --- a/support/Make.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -"%~dp0\cocos.bat" make diff --git a/support/Server.bat b/support/Server.bat deleted file mode 100755 index bc35ca8..0000000 --- a/support/Server.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -"%~dp0\cocos.bat" server diff --git a/support/win32/installer.nsi b/support/win32/installer.nsi old mode 100755 new mode 100644 index 1948fa7..28c0984 --- a/support/win32/installer.nsi +++ b/support/win32/installer.nsi @@ -7,7 +7,7 @@ RequestExecutionLevel admin !define PRODUCT_NAME "Cocos2D JavaScript" !define PRODUCT_VERSION "v0.0.1" !define PRODUCT_WEB_SITE "http://cocos2d-javascript.org/" -!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\New Project.exe" +!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\Create project.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" @@ -49,13 +49,13 @@ ShowUnInstDetails show Section "MainSection" SEC01 SetOutPath "$INSTDIR\bin" SetOverwrite ifnewer - File "${ROOT_PATH}\bin\New Project.exe" + File "${ROOT_PATH}\bin\Create project.exe" CreateDirectory "$SMPROGRAMS\Cocos2D JavaScript" - CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Create new project.lnk" "$INSTDIR\bin\New Project.exe" - File "${ROOT_PATH}\bin\Compile Project.exe" - CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Compile project.lnk" "$INSTDIR\bin\Compile Project.exe" - File "${ROOT_PATH}\bin\Serve Project.exe" - CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Serve project.lnk" "$INSTDIR\bin\Serve Project.exe" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Create new project.lnk" "$INSTDIR\bin\Create project.exe" + File "${ROOT_PATH}\bin\Compile project.exe" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Compile project.lnk" "$INSTDIR\bin\Compile project.exe" + File "${ROOT_PATH}\bin\Serve project.exe" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Serve project.lnk" "$INSTDIR\bin\Serve project.exe" SetOverwrite try File "${ROOT_PATH}\bin\cocos.bat" File "${ROOT_PATH}\bin\cocos.js" @@ -332,10 +332,10 @@ SectionEnd Section -Post WriteUninstaller "$INSTDIR\uninst.exe" - WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\New Project.exe" + WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\Create project.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\New Project.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\Create project.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" SectionEnd @@ -556,9 +556,9 @@ Section Uninstall Delete "$INSTDIR\bin\cocos.sh" Delete "$INSTDIR\bin\cocos.js" Delete "$INSTDIR\bin\cocos.bat" - Delete "$INSTDIR\bin\Serve Project.exe" - Delete "$INSTDIR\bin\Compile Project.exe" - Delete "$INSTDIR\bin\New Project.exe" + Delete "$INSTDIR\bin\Serve project.exe" + Delete "$INSTDIR\bin\Compile project.exe" + Delete "$INSTDIR\bin\Create project.exe" Delete "$SMPROGRAMS\Cocos2D JavaScript\Uninstall.lnk" Delete "$SMPROGRAMS\Cocos2D JavaScript\Website.lnk" Delete "$SMPROGRAMS\Cocos2D JavaScript\Serve project.lnk" diff --git a/support/win32/utils/Cocos2D JavaScript.sln b/support/win32/utils/Cocos2D JavaScript.sln new file mode 100644 index 0000000..650017b --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C# Express 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cocos2D JavaScript", "Cocos2D JavaScript\Cocos2D JavaScript.csproj", "{65C64718-5117-408E-9E12-B20453E56E84}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {65C64718-5117-408E-9E12-B20453E56E84}.Debug|x86.ActiveCfg = Debug|x86 + {65C64718-5117-408E-9E12-B20453E56E84}.Debug|x86.Build.0 = Debug|x86 + {65C64718-5117-408E-9E12-B20453E56E84}.Release|x86.ActiveCfg = Release|x86 + {65C64718-5117-408E-9E12-B20453E56E84}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/support/win32/utils/Cocos2D JavaScript.suo b/support/win32/utils/Cocos2D JavaScript.suo new file mode 100644 index 0000000000000000000000000000000000000000..2a10e0b1d53a33f88ca609250c982f8ffc60553b GIT binary patch literal 25600 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 + + + Debug + x86 + 8.0.30703 + 2.0 + {65C64718-5117-408E-9E12-B20453E56E84} + WinExe + Properties + Cocos2D_JavaScript + Serve project + v2.0 + + + 512 + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + Cocos2D_JavaScript.Server + + + cocos2d - Happy.ico + + + + + + + + + + + + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + False + Microsoft .NET Framework 4 Client Profile %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + + + + + + + {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} + 1 + 0 + 0 + tlbimp + False + True + True + + + + + "c:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe" /out:"$(TargetDir)\tmp.exe" "$(TargetPath)" "$(TargetDir)\Interop.IWshRuntimeLibrary.dll" +del "$(TargetPath)" +rename "$(TargetDir)\tmp.exe" "$(TargetFileName)" + + + \ No newline at end of file diff --git a/support/win32/utils/Cocos2D JavaScript/Cocos2D JavaScript.csproj.user b/support/win32/utils/Cocos2D JavaScript/Cocos2D JavaScript.csproj.user new file mode 100644 index 0000000..53c4be7 --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/Cocos2D JavaScript.csproj.user @@ -0,0 +1,21 @@ + + + + publish\ + + + + + + en-US + false + + + + + + + + + + \ No newline at end of file diff --git a/support/win32/utils/Cocos2D JavaScript/Create.cs b/support/win32/utils/Cocos2D JavaScript/Create.cs new file mode 100644 index 0000000..bc8fa74 --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/Create.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using IWshRuntimeLibrary; + +namespace Cocos2D_JavaScript +{ + static class Create + { + ///

        + /// The main entry point for the application. + /// + [STAThread] + static void Main(String[] args) + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + FolderBrowserDialog dialog = new FolderBrowserDialog(); + dialog.Description = "Create and select the folder for the new Cocos2D JavaScript project you want to create."; + String filename; + + if (args.Length > 0) + { + filename = args[0]; + } + else + { + filename = (dialog.ShowDialog() == DialogResult.OK) ? dialog.SelectedPath : null; + } + + if (filename != null) + { + String exeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + + String oldDir = System.IO.Directory.GetCurrentDirectory(); + System.IO.Directory.SetCurrentDirectory(filename); + Cocos.Command("new", ".", true); + + // Create shortcuts + Create.Shortcut(exeDir + @"\Serve project.exe", filename + @"\Serve project.lnk"); + Create.Shortcut(exeDir + @"\Compile project.exe", filename + @"\Compile project.lnk"); + + Process.Start(new ProcessStartInfo("explorer.exe", filename)); + } + } + + static void Shortcut(String source, String dest, String description="") + { + WshShell wsh = new WshShellClass(); + + IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)wsh.CreateShortcut(dest); + shortcut.Arguments = "."; + shortcut.TargetPath = source; + + shortcut.Save(); + } + + } +} diff --git a/support/win32/utils/Cocos2D JavaScript/Make.cs b/support/win32/utils/Cocos2D JavaScript/Make.cs new file mode 100644 index 0000000..de7f6a0 --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/Make.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +namespace Cocos2D_JavaScript +{ + static class Make + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(String[] args) + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + FolderBrowserDialog dialog = new FolderBrowserDialog(); + dialog.Description = "Select the folder of the Cocos2D JavaScript project you want to compile."; + + String filename; + if (args.Length > 0) + { + filename = args[0]; + } + else + { + filename = (dialog.ShowDialog() == DialogResult.OK) ? dialog.SelectedPath : null; + } + + if (filename != null) + { + System.IO.Directory.SetCurrentDirectory(filename); + Cocos.Command("make", "", true); + Process.Start(new ProcessStartInfo("explorer.exe ", filename + "\\build\\")); + } + + + } + } +} diff --git a/support/win32/utils/Cocos2D JavaScript/Properties/AssemblyInfo.cs b/support/win32/utils/Cocos2D JavaScript/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8df484f --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Cocos2D JavaScript")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Ryan Williams")] +[assembly: AssemblyProduct("Cocos2D JavaScript")] +[assembly: AssemblyCopyright("Copyright 2011 Ryan Williams")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7019d3e5-78dc-4854-9bab-b8b4e51403f5")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.0.1.0")] +[assembly: AssemblyFileVersion("0.0.1.0")] diff --git a/support/win32/utils/Cocos2D JavaScript/Properties/Resources.Designer.cs b/support/win32/utils/Cocos2D JavaScript/Properties/Resources.Designer.cs new file mode 100644 index 0000000..08ab5a8 --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Cocos2D_JavaScript.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Cocos2D_JavaScript.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/support/win32/utils/Cocos2D JavaScript/Properties/Resources.resx b/support/win32/utils/Cocos2D JavaScript/Properties/Resources.resx new file mode 100644 index 0000000..ffecec8 --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/support/win32/utils/Cocos2D JavaScript/Properties/Settings.Designer.cs b/support/win32/utils/Cocos2D JavaScript/Properties/Settings.Designer.cs new file mode 100644 index 0000000..9aff387 --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Cocos2D_JavaScript.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/support/win32/utils/Cocos2D JavaScript/Properties/Settings.settings b/support/win32/utils/Cocos2D JavaScript/Properties/Settings.settings new file mode 100644 index 0000000..abf36c5 --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/support/win32/utils/Cocos2D JavaScript/Server.cs b/support/win32/utils/Cocos2D JavaScript/Server.cs new file mode 100644 index 0000000..0d26a9f --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/Server.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +namespace Cocos2D_JavaScript +{ + static class Server + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(String[] args) + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + FolderBrowserDialog dialog = new FolderBrowserDialog(); + dialog.Description = "Select the folder of the Cocos2D JavaScript project you want to run a development Web server for."; + + String filename; + if (args.Length > 0) + { + filename = args[0]; + } + else + { + filename = (dialog.ShowDialog() == DialogResult.OK) ? dialog.SelectedPath : null; + } + + if (filename != null) + { + System.IO.Directory.SetCurrentDirectory(filename); + Cocos.Command("server"); + } + } + } +} diff --git a/support/win32/utils/Cocos2D JavaScript/app.config b/support/win32/utils/Cocos2D JavaScript/app.config new file mode 100644 index 0000000..8494f72 --- /dev/null +++ b/support/win32/utils/Cocos2D JavaScript/app.config @@ -0,0 +1,3 @@ + + + diff --git a/bin/Server.exe b/support/win32/utils/Cocos2D JavaScript/cocos2d - Happy.ico similarity index 88% rename from bin/Server.exe rename to support/win32/utils/Cocos2D JavaScript/cocos2d - Happy.ico index 38b4424e97c6764c18b472584519c982befd1ce1..c1a268c567699acd7d2264dd51a498d458254d6d 100644 GIT binary patch delta 209 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 L{C*YnYv8{DgHA`F From 04b8e914eede01af315b37d383477148e56d16eb Mon Sep 17 00:00:00 2001 From: Hackfrag Date: Sat, 12 Feb 2011 15:51:27 +0100 Subject: [PATCH 066/176] Added TMXObjectGroup support. --- src/libs/cocos2d/TMXXMLParser.js | 104 ++++++++++++++++++ src/libs/cocos2d/nodes/TMXTiledMap.js | 21 ++++ .../resources/TileMaps/orthogonal-test1.tmx | 21 +++- 3 files changed, 145 insertions(+), 1 deletion(-) diff --git a/src/libs/cocos2d/TMXXMLParser.js b/src/libs/cocos2d/TMXXMLParser.js index 3ce795d..194fba2 100644 --- a/src/libs/cocos2d/TMXXMLParser.js +++ b/src/libs/cocos2d/TMXXMLParser.js @@ -69,6 +69,59 @@ var TMXLayerInfo = BObject.extend(/** @lends cocos.TMXLayerInfo# */{ } }); +var TMXObjectGroup = BObject.extend(/** @lends cocos.TMXObjectGroup# */{ + name: '', + properties: null, + offset: null, + objects: null, + + /** + * @memberOf cocos + * @constructs + * @extends BObject + */ + init: function () { + TMXObjectGroup.superclass.init.call(this); + + this.properties = {}; + this.objects = {}; + this.offset = ccp(0, 0); + }, + + /** + * return the value for the specific property name + * + * @opt {String} name Property name + * @returns {String} Property value + */ + propertyNamed: function(opts) { + var propertyName = opts.name + return this.properties[propertyName]; + }, + + /** + * Return the object for the specific object name. It will return the 1st + * object found on the array for the given name. + * + * @opt {String} name Object name + * @returns {Object} Object + */ + objectNamed: function(opts) { + var objectName = opts.name; + var object = null; + + this.objects.forEach(function(item) { + + if(item.name == objectName) { + object = item; + } + }); + if(object != null) { + return object; + } + } +}); + var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ filename: '', orientation: 0, @@ -220,9 +273,60 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ // TODO PARSE + // PARSE + var objectgroups = map.getElementsByTagName('objectgroup'); + for (i = 0, len = objectgroups.length; i < len; i++) { + var g = objectgroups[i], + objectGroup = TMXObjectGroup.create(); + + objectGroup.set('name', g.getAttribute('name')); + + var properties = g.querySelectorAll('objectgroup > properties property'), + propertiesValue = {}; + + for(j = 0; j < properties.length; j++) { + var property = properties[j]; + if(property.getAttribute('name')) { + propertiesValue[property.getAttribute('name')] = property.getAttribute('value'); + } + } + + objectGroup.set('properties', propertiesValue); + + var objectsArray = [], + objects = g.querySelectorAll('object'); + + for(j = 0; j < objects.length; j++) { + var object = objects[j]; + var objectValue = { + x : object.getAttribute('x'), + y : object.getAttribute('y'), + width : object.getAttribute('width'), + height : object.getAttribute('height') + }; + if(object.getAttribute('name')) { + objectValue.name = object.getAttribute('name'); + } + if(object.getAttribute('type')) { + objectValue.name = object.getAttribute('type'); + } + properties = object.querySelectorAll('property'); + for(var k = 0; k < properties.length; k++) { + property = properties[k]; + if(property.getAttribute('name')) { + objectValue[property.getAttribute('name')] = property.getAttribute('value'); + } + } + objectsArray.push(objectValue); + + } + objectGroup.set('objects', objectsArray); + this.objectGroups.push(objectGroup); + } } }); exports.TMXMapInfo = TMXMapInfo; exports.TMXLayerInfo = TMXLayerInfo; exports.TMXTilesetInfo = TMXTilesetInfo; +exports.TMXObjectGroup = TMXObjectGroup; \ No newline at end of file diff --git a/src/libs/cocos2d/nodes/TMXTiledMap.js b/src/libs/cocos2d/nodes/TMXTiledMap.js index 8d38cbd..99e3138 100644 --- a/src/libs/cocos2d/nodes/TMXTiledMap.js +++ b/src/libs/cocos2d/nodes/TMXTiledMap.js @@ -94,6 +94,27 @@ var TMXTiledMap = Node.extend(/** @lends cocos.nodes.TMXTiledMap# */{ //console.log("cocos2d: Warning: TMX Layer '%s' has no tiles", layerInfo.name); return tileset; + }, + + /** + * Return the ObjectGroup for the secific group + * + * @opt {String} name The object group name + * @returns {cocos.TMXObjectGroup} The object group + */ + objectGroupNamed: function(opts) { + var objectGroupName = opts.name, + objectGroup = null; + + this.objectGroups.forEach(function(item) { + + if(item.name == objectGroupName) { + objectGroup = item; + } + }); + if(objectGroup != null) { + return objectGroup; + } } }); diff --git a/tests/cocos2d/resources/TileMaps/orthogonal-test1.tmx b/tests/cocos2d/resources/TileMaps/orthogonal-test1.tmx index db2e170..d8c693b 100644 --- a/tests/cocos2d/resources/TileMaps/orthogonal-test1.tmx +++ b/tests/cocos2d/resources/TileMaps/orthogonal-test1.tmx @@ -1,6 +1,5 @@ - @@ -9,4 +8,24 @@ H4sIAAAAAAAAA9XMzQpAQBhG4cnfwsK/sJVBuf/7c9Sn3o0aWXnrSTNz4ty/N4iQTSJkBUpUdp4futa+m4gRIUGKTNq7X7Fbr2usud48Frv3osaBER166/OX/Zf/n+tha6FAAgAA + + + + + + + + + + + + + + + + + + + + From 95fd33732158778539ac0a497807d53ee203c528 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 13 Feb 2011 10:55:13 +1300 Subject: [PATCH 067/176] Fixed compilation on Windows --- bin/cocos.bat | 2 +- lib/cocos/commands/make.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 bin/cocos.bat diff --git a/bin/cocos.bat b/bin/cocos.bat old mode 100644 new mode 100755 index de3ffa5..405050d --- a/bin/cocos.bat +++ b/bin/cocos.bat @@ -30,4 +30,4 @@ set UNIX_COCOS_DIR=%UNIX_COCOS_DIR:X:=/cygdrive/x% set UNIX_COCOS_DIR=%UNIX_COCOS_DIR:Y:=/cygdrive/y% set UNIX_COCOS_DIR=%UNIX_COCOS_DIR:Z:=/cygdrive/z% -%COCOS_DIR%\support\node-builds\win32\node %UNIX_COCOS_DIR%/bin/cocos.js %1 %2 %3 %4 %5 %6 %7 %8 %9 +"%COCOS_DIR%\support\node-builds\win32\node" "%UNIX_COCOS_DIR%/bin/cocos.js" %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/lib/cocos/commands/make.js b/lib/cocos/commands/make.js index cacb380..ffa9468 100644 --- a/lib/cocos/commands/make.js +++ b/lib/cocos/commands/make.js @@ -243,7 +243,7 @@ function Compiler(configFile) { // Source starts with config path if (path.indexOf(source) === 0) { - return path.replace(new RegExp(source), dest).replace(/\/+/, '/'); + return path.replace(source, dest).replace(/\/+/, '/'); } } } From 3a8166eba0abdc8c397be3af151f36af972fbfa0 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 13 Feb 2011 19:26:12 +1300 Subject: [PATCH 068/176] Renamed Node.js module to 'cocos2d' --- bin/cocos.js | 2 +- lib/{cocos => cocos2d}/commands/help.js | 0 lib/{cocos => cocos2d}/commands/ide.js | 0 lib/{cocos => cocos2d}/commands/index.js | 0 lib/{cocos => cocos2d}/commands/make.js | 0 lib/{cocos => cocos2d}/commands/module_js | 0 lib/{cocos => cocos2d}/commands/new.js | 0 lib/{cocos => cocos2d}/commands/server.js | 0 lib/{cocos => cocos2d}/index.js | 0 lib/{cocos => cocos2d}/mime.types | 0 lib/{cocos => cocos2d}/mimetypes.js | 0 lib/{cocos => cocos2d}/opts.js | 0 lib/{cocos => cocos2d}/skeleton/make.json | 0 lib/{cocos => cocos2d}/skeleton/public/index.html | 0 lib/{cocos => cocos2d}/skeleton/src/main.js | 0 lib/{cocos => cocos2d}/template.js | 0 16 files changed, 1 insertion(+), 1 deletion(-) rename lib/{cocos => cocos2d}/commands/help.js (100%) rename lib/{cocos => cocos2d}/commands/ide.js (100%) rename lib/{cocos => cocos2d}/commands/index.js (100%) rename lib/{cocos => cocos2d}/commands/make.js (100%) rename lib/{cocos => cocos2d}/commands/module_js (100%) rename lib/{cocos => cocos2d}/commands/new.js (100%) rename lib/{cocos => cocos2d}/commands/server.js (100%) rename lib/{cocos => cocos2d}/index.js (100%) rename lib/{cocos => cocos2d}/mime.types (100%) rename lib/{cocos => cocos2d}/mimetypes.js (100%) rename lib/{cocos => cocos2d}/opts.js (100%) rename lib/{cocos => cocos2d}/skeleton/make.json (100%) rename lib/{cocos => cocos2d}/skeleton/public/index.html (100%) rename lib/{cocos => cocos2d}/skeleton/src/main.js (100%) rename lib/{cocos => cocos2d}/template.js (100%) diff --git a/bin/cocos.js b/bin/cocos.js index 540d114..01495fb 100755 --- a/bin/cocos.js +++ b/bin/cocos.js @@ -15,4 +15,4 @@ var version = JSON.parse(fs.readFileSync(__dirname + '/../package.json')).versio sys.puts('cocos2d-javascript version ' + version); -require('cocos').main(); +require('cocos2d').main(); diff --git a/lib/cocos/commands/help.js b/lib/cocos2d/commands/help.js similarity index 100% rename from lib/cocos/commands/help.js rename to lib/cocos2d/commands/help.js diff --git a/lib/cocos/commands/ide.js b/lib/cocos2d/commands/ide.js similarity index 100% rename from lib/cocos/commands/ide.js rename to lib/cocos2d/commands/ide.js diff --git a/lib/cocos/commands/index.js b/lib/cocos2d/commands/index.js similarity index 100% rename from lib/cocos/commands/index.js rename to lib/cocos2d/commands/index.js diff --git a/lib/cocos/commands/make.js b/lib/cocos2d/commands/make.js similarity index 100% rename from lib/cocos/commands/make.js rename to lib/cocos2d/commands/make.js diff --git a/lib/cocos/commands/module_js b/lib/cocos2d/commands/module_js similarity index 100% rename from lib/cocos/commands/module_js rename to lib/cocos2d/commands/module_js diff --git a/lib/cocos/commands/new.js b/lib/cocos2d/commands/new.js similarity index 100% rename from lib/cocos/commands/new.js rename to lib/cocos2d/commands/new.js diff --git a/lib/cocos/commands/server.js b/lib/cocos2d/commands/server.js similarity index 100% rename from lib/cocos/commands/server.js rename to lib/cocos2d/commands/server.js diff --git a/lib/cocos/index.js b/lib/cocos2d/index.js similarity index 100% rename from lib/cocos/index.js rename to lib/cocos2d/index.js diff --git a/lib/cocos/mime.types b/lib/cocos2d/mime.types similarity index 100% rename from lib/cocos/mime.types rename to lib/cocos2d/mime.types diff --git a/lib/cocos/mimetypes.js b/lib/cocos2d/mimetypes.js similarity index 100% rename from lib/cocos/mimetypes.js rename to lib/cocos2d/mimetypes.js diff --git a/lib/cocos/opts.js b/lib/cocos2d/opts.js similarity index 100% rename from lib/cocos/opts.js rename to lib/cocos2d/opts.js diff --git a/lib/cocos/skeleton/make.json b/lib/cocos2d/skeleton/make.json similarity index 100% rename from lib/cocos/skeleton/make.json rename to lib/cocos2d/skeleton/make.json diff --git a/lib/cocos/skeleton/public/index.html b/lib/cocos2d/skeleton/public/index.html similarity index 100% rename from lib/cocos/skeleton/public/index.html rename to lib/cocos2d/skeleton/public/index.html diff --git a/lib/cocos/skeleton/src/main.js b/lib/cocos2d/skeleton/src/main.js similarity index 100% rename from lib/cocos/skeleton/src/main.js rename to lib/cocos2d/skeleton/src/main.js diff --git a/lib/cocos/template.js b/lib/cocos2d/template.js similarity index 100% rename from lib/cocos/template.js rename to lib/cocos2d/template.js From 4870b79a2ee7b9c864f711dc765f80044ec95ffb Mon Sep 17 00:00:00 2001 From: Hackfrag Date: Sun, 13 Feb 2011 19:03:50 +0100 Subject: [PATCH 069/176] transform the object values to integer --- src/libs/cocos2d/TMXXMLParser.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/cocos2d/TMXXMLParser.js b/src/libs/cocos2d/TMXXMLParser.js index 194fba2..6f4b7e0 100644 --- a/src/libs/cocos2d/TMXXMLParser.js +++ b/src/libs/cocos2d/TMXXMLParser.js @@ -299,10 +299,10 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ for(j = 0; j < objects.length; j++) { var object = objects[j]; var objectValue = { - x : object.getAttribute('x'), - y : object.getAttribute('y'), - width : object.getAttribute('width'), - height : object.getAttribute('height') + x : parseInt(object.getAttribute('x'), 10), + y : parseInt(object.getAttribute('y'), 10), + width : parseInt(object.getAttribute('width'), 10), + height : parseInt(object.getAttribute('height'), 10) }; if(object.getAttribute('name')) { objectValue.name = object.getAttribute('name'); From a40d6490c9f74616baa93fbc82b5bb8ef52d45ec Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 14 Feb 2011 20:10:12 +1300 Subject: [PATCH 070/176] Fixed installation script's handling of spaces. --- install.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/install.sh b/install.sh index 6cdb094..37f017d 100755 --- a/install.sh +++ b/install.sh @@ -23,27 +23,28 @@ fi echo "Installing to: $install_to" -mkdir -p $install_to +mkdir -p "$install_to" cd $DIR +IFS=$'\n' for file in `find * \( ! -regex '.*/\..*' \) -type f` do dst="$install_to/$file" - dst_dir=`dirname $dst` - if [ ! -d $dst_dir ] + dst_dir=`dirname "$dst"` + if [ ! -d "$dst_dir" ] then - mkdir -p $dst_dir + mkdir -p "$dst_dir" fi - cp $file $dst + cp "$file" "$dst" done cd - echo "All files copied." -ln -s $install_to/bin/cocos.sh /usr/local/bin/cocos +ln -s "$install_to/bin/cocos.sh" "/usr/local/bin/cocos" echo "Symlinked 'cocos' executable to /usr/local/bin/cocos\n" From 5f7d2af68f44395bb8167d36f656ae88b2e981b1 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 14 Feb 2011 20:11:12 +1300 Subject: [PATCH 071/176] Added script to generate Windows installer and Unix .tar.gz --- .gitignore | 1 + .npmignore | 10 +- LICENSE | 40 +-- README.md | 174 ++++----- support/installer_nsi.template | 94 +++++ support/package.js | 184 ++++++++++ support/win32/installer.nsi | 623 --------------------------------- 7 files changed, 395 insertions(+), 731 deletions(-) create mode 100644 support/installer_nsi.template create mode 100755 support/package.js delete mode 100644 support/win32/installer.nsi diff --git a/.gitignore b/.gitignore index 423dcf4..3ffc54a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ docs/ public/cocos2d.js public/tests.js Cocos2D\ JavaScript*Setup.exe +Cocos2D-JavaScript*.tar.gz diff --git a/.npmignore b/.npmignore index b166606..ff8cf1f 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1,11 @@ support/ -*~ .* +*.swp +*.pyc +*~ +jsdocs/ +docs/ +public/cocos2d.js +public/tests.js +Cocos2D\ JavaScript*Setup.exe +Cocos2D-JavaScript*.tar.gz diff --git a/LICENSE b/LICENSE index c2591cb..ef9e8f2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,20 +1,20 @@ -Copyright (c) 2010-2011 Ryan Williams - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Copyright (c) 2010-2011 Ryan Williams + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index dda7840..1eea5a2 100644 --- a/README.md +++ b/README.md @@ -1,87 +1,87 @@ -Cocos2d-javascript is released under the MIT license. - -This is in the early stages of development and could break backwards compatibility at any time. - -* You can find me on Twitter: @cocos2djs -* Email: -* Website: -* Documentation: -* Forum: - -Creating a new project ----------------------- - -To create a new project you first need to get a copy of cocos2d-javascript. Grab the latest using git - - git clone git://github.com/ryanwilliams/cocos2d-javascript.git - -To create your initial project simply navigate to the cocos2d-javascript directory and run - - ./cocos new ~/Projects/MyApp - -This will create a new directory at that path with everything you need to -get started. It will also add cocos2d-javascript as a git submodule. If you -prefer to just copy the cocos2d-javascript code instead of using a git -submodule then use - - ./cocos new ~/Projects/MyApp -g - -Getting things running ----------------------- - -To get your project running simply navigate to the newly created directory run -the development web server - - ./cocos server - -And visit . There you will see a simple application -outputting your application name. - -Developing ----------- - -Everything you write will be in separate JavaScript files. These will be -compiled into a single file which also includes all your other resources -including images, sound files, map files, etc. - -The entry point for the code is path defined as "main.js" inside the in "make.js" file. - -In the public/index.html you will see <script src="https://github.com/appname.js"> tag to include the code. - -The web server will compile your code each time it is requested. This makes -development a lot easier. - -Run ./cocos server -h for help. - -Compiling your application --------------------------- - -To compile your code you run ./cocos make. Which reads the make.js file -to work out what you want to build. - -When built the resulting .js file will contain all your code aswell as all your -images and map files. This means you only need to update a single file and only -a single HTTP request is needed to serve everything. - -Run ./cocos make -h for help. - -Browser Support ---------------- - -I intend for this to work in Firefox, Chrome, Safari, Opera and IE9. I -mostly develop using Chrome so that's likely to have the best compatibility -until I get close to a proper release. - -Documentation -------------- - -Download JsDoc 2.3 (or 2.4) from . - -Copy that to /usr/local/jsdoc-toolkit or wherever you like and then run: - - JSDOC_HOME=/usr/local/jsdoc-toolkit ./jsdoc - -The documentation will appear in the 'docs' directory. - -© 2010 Ryan Williams - +Cocos2d-javascript is released under the MIT license. + +This is in the early stages of development and could break backwards compatibility at any time. + +* You can find me on Twitter: @cocos2djs +* Email: +* Website: +* Documentation: +* Forum: + +Creating a new project +---------------------- + +To create a new project you first need to get a copy of cocos2d-javascript. Grab the latest using git + + git clone git://github.com/ryanwilliams/cocos2d-javascript.git + +To create your initial project simply navigate to the cocos2d-javascript directory and run + + ./cocos new ~/Projects/MyApp + +This will create a new directory at that path with everything you need to +get started. It will also add cocos2d-javascript as a git submodule. If you +prefer to just copy the cocos2d-javascript code instead of using a git +submodule then use + + ./cocos new ~/Projects/MyApp -g + +Getting things running +---------------------- + +To get your project running simply navigate to the newly created directory run +the development web server + + ./cocos server + +And visit . There you will see a simple application +outputting your application name. + +Developing +---------- + +Everything you write will be in separate JavaScript files. These will be +compiled into a single file which also includes all your other resources +including images, sound files, map files, etc. + +The entry point for the code is path defined as "main.js" inside the in "make.js" file. + +In the public/index.html you will see <script src="https://github.com/appname.js"> tag to include the code. + +The web server will compile your code each time it is requested. This makes +development a lot easier. + +Run ./cocos server -h for help. + +Compiling your application +-------------------------- + +To compile your code you run ./cocos make. Which reads the make.js file +to work out what you want to build. + +When built the resulting .js file will contain all your code aswell as all your +images and map files. This means you only need to update a single file and only +a single HTTP request is needed to serve everything. + +Run ./cocos make -h for help. + +Browser Support +--------------- + +I intend for this to work in Firefox, Chrome, Safari, Opera and IE9. I +mostly develop using Chrome so that's likely to have the best compatibility +until I get close to a proper release. + +Documentation +------------- + +Download JsDoc 2.3 (or 2.4) from . + +Copy that to /usr/local/jsdoc-toolkit or wherever you like and then run: + + JSDOC_HOME=/usr/local/jsdoc-toolkit ./jsdoc + +The documentation will appear in the 'docs' directory. + +© 2010 Ryan Williams + diff --git a/support/installer_nsi.template b/support/installer_nsi.template new file mode 100644 index 0000000..a4a25fe --- /dev/null +++ b/support/installer_nsi.template @@ -0,0 +1,94 @@ +; vim:ft=nsis + +RequestExecutionLevel admin + +!define ROOT_PATH "$root_path$" +!define PRODUCT_NAME "Cocos2D JavaScript" +!define PRODUCT_VERSION "$version$" +!define PRODUCT_WEB_SITE "http://cocos2d-javascript.org/" +!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\Create project.exe" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" +!define PRODUCT_UNINST_ROOT_KEY "HKLM" + +; MUI 1.67 compatible ------ +!include "MUI.nsh" + +; MUI Settings +!define MUI_ABORTWARNING +!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" + +; Welcome page +!insertmacro MUI_PAGE_WELCOME +; License page +!insertmacro MUI_PAGE_LICENSE "${ROOT_PATH}\LICENSE" +; Directory page +!insertmacro MUI_PAGE_DIRECTORY +; Instfiles page +!insertmacro MUI_PAGE_INSTFILES +; Finish page +!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt" +!insertmacro MUI_PAGE_FINISH + +; Uninstaller pages +!insertmacro MUI_UNPAGE_INSTFILES + +; Language files +!insertmacro MUI_LANGUAGE "English" + +; MUI end ------ + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +OutFile "${ROOT_PATH}\${PRODUCT_NAME} ${PRODUCT_VERSION} Setup.exe" +InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" +InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" +ShowInstDetails show +ShowUnInstDetails show + +Section "MainSection" SEC01 +$install_file_list$ + + ; Start menu shortcuts + SetOverwrite ifnewer + CreateDirectory "$SMPROGRAMS\Cocos2D JavaScript" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Create new project.lnk" "$INSTDIR\bin\Create project.exe" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Compile project.lnk" "$INSTDIR\bin\Compile project.exe" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Serve project.lnk" "$INSTDIR\bin\Serve project.exe" +SectionEnd + +Section -AdditionalIcons + SetOutPath $INSTDIR + WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" + CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Uninstall.lnk" "$INSTDIR\uninst.exe" +SectionEnd + +Section -Post + WriteUninstaller "$INSTDIR\uninst.exe" + WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\Create project.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\Create project.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" +SectionEnd + + +Function un.onUninstSuccess + HideWindow + MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." +FunctionEnd + +Function un.onInit + MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2 + Abort +FunctionEnd + +Section Uninstall + RMDir /r "$SMPROGRAMS\Cocos2D JavaScript" + RMDir /r "$INSTDIR" + + DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" + DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" + SetAutoClose true +SectionEnd diff --git a/support/package.js b/support/package.js new file mode 100755 index 0000000..1d43145 --- /dev/null +++ b/support/package.js @@ -0,0 +1,184 @@ +#!/usr/bin/env node + +/** + * @fileOverview Generates a Windows installer .exe and a .zip + */ + +var sys = require('sys'), + fs = require('fs'), + path = require('path'), + spawn = require('child_process').spawn; + +// Include cocos2d because it has some useful modules +require.paths.unshift(path.join(__dirname, '../lib')); + +var Template = require('cocos2d/Template').Template; + +var VERSION = JSON.parse(fs.readFileSync(__dirname + '/../package.json')).version; + +sys.puts('Packaging Cocos2D JavaScript version ' + VERSION); + +/** + * Generates an NSIS installer script to install the contents of a given + * directory and returns it as a string. + * + * @param {String} dir The directory that will be installed + * @returns String The contents of the NSIS script + */ +function generateNSISScript(files, callback) { + sys.puts('Generating NSIS script'); + var installFileList = ' SetOverwrite try\n', + removeFileList = '', + removeDirList = ''; + + // Generate the install and remove lists + var prevDirname, i, len; + for (i = 0, len = files.length; i < len; i++) { + var file = files[i]; + var dirname = path.dirname(file); + + if (dirname != prevDirname) { + prevDirname = dirname; + installFileList += ' SetOutPath "$INSTDIR\\' + dirname.replace(/\//g, '\\') + '"\n'; + removeDirList += ' RMDir "$INSTDIR\\' + dirname.replace(/\//g, '\\') + '"\n'; + } + + var m; + if ((m = file.match(/\/?(README|LICENSE)(.md)?$/))) { + // Rename README and LICENSE so they end in .txt + installFileList += ' File /oname=' + m[1] + '.txt "${ROOT_PATH}\\' + file.replace(/\//g, '\\') + '"\n'; + } else { + installFileList += ' File "${ROOT_PATH}\\' + file.replace(/\//g, '\\') + '"\n'; + } + removeFileList += ' Delete "$INSTDIR\\' + file.replace(/\//g, '\\') + '"\n'; + } + + + var tmp = new Template(fs.readFileSync(path.join(__dirname, 'installer_nsi.template'), 'utf8')); + var data = tmp.substitute({ + root_path: '..', + version: 'v' + VERSION, + install_file_list: installFileList, + remove_file_list: removeFileList, + remove_dir_list: removeDirList + }); + + callback(data); +} + +/** + * Uses git to find the files we want to install. If a file isn't commited, + * then it won't be installed. + * + * @param {String} dir The directory that will be installed + * @returns String[] Array of file paths + */ +function findFilesToPackage(dir, callback) { + var cwd = process.cwd(); + process.chdir(dir); + + var gitls = spawn('git', ['ls-files']), + // This gets the full path to each file in each submodule + subls = spawn('git', ['submodule', 'foreach', 'for file in `git ls-files`; do echo "$path/$file"; done']) + + + var mainFileList = ''; + gitls.stdout.on('data', function (data) { + mainFileList += data; + }); + gitls.on('exit', returnFileList); + + var subFileList = ''; + subls.stdout.on('data', function (data) { + subFileList += data; + }); + subls.on('exit', returnFileList); + + var lsCount = 0; + function returnFileList(code) { + lsCount++; + if (lsCount < 2) { + return; + } + process.chdir(cwd); + + // Convert \n separated list of filenames into a sorted array + var fileList = (mainFileList.trim() + subFileList.trim()).split('\n').filter(function(file) { + // Ignore entering submodule messages + if (file.indexOf('Entering ') === 0) { + return; + } + + // Ignore hidden and backup files + if (file.split('/').pop()[0] == '.' || file[file.length - 1] == '~') { + return; + } + + // Ignore node-builds for other platforms + if (~file.indexOf('node-builds') && !~file.indexOf('win32')) { + return; + } + + + // Submodules appear in ls-files but aren't files. Skip them + if (fs.statSync(path.join(dir, file)).isDirectory()) { + return; + } + + + return file; + }).sort() + + callback(fileList); + } + +} + +function generateZip(files, zipName) { + sys.puts('Generating .tar.gz archive : ' + zipName); + if (path.exists(zipName)) { + fs.unlink(zipName); + } + + var tar = spawn('tar', ['-czf', zipName + '.tar.gz'].concat(files)); + + tar.stderr.on('data', function(data) { + sys.print(data); + }); + + tar.on('exit', function() { + sys.puts('Generated .tar.gz archive'); + }); +} + + +(function main() { + var dir = path.join(__dirname, '../') + findFilesToPackage(dir, function(filesToPackage) { + generateNSISScript(filesToPackage, function(nsis) { + + // Write out installer file + var output = path.join(__dirname, 'windows-installer.nsi'); + fs.writeFileSync(output, nsis); + + // Generate installer + sys.puts('Generating windows installer .EXE'); + var makensis = spawn('makensis', [output]); + makensis.stderr.on('data', function (data) { + sys.print(data); + }); + makensis.on('exit', function (data) { + sys.puts('Windows installer generated'); + + fs.unlink(output); + + + var cwd = process.cwd(); + process.chdir(dir); + // Generate zip archive + generateZip(filesToPackage, 'Cocos2D-JavaScript-v' + VERSION); + }); + }); + }); +})(); + diff --git a/support/win32/installer.nsi b/support/win32/installer.nsi deleted file mode 100644 index 28c0984..0000000 --- a/support/win32/installer.nsi +++ /dev/null @@ -1,623 +0,0 @@ -; Script generated by the HM NIS Edit Script Wizard. - -RequestExecutionLevel admin - -; HM NIS Edit Wizard helper defines -!define ROOT_PATH "..\.." -!define PRODUCT_NAME "Cocos2D JavaScript" -!define PRODUCT_VERSION "v0.0.1" -!define PRODUCT_WEB_SITE "http://cocos2d-javascript.org/" -!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\Create project.exe" -!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" -!define PRODUCT_UNINST_ROOT_KEY "HKLM" - -; MUI 1.67 compatible ------ -!include "MUI.nsh" - -; MUI Settings -!define MUI_ABORTWARNING -!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" - -; Welcome page -!insertmacro MUI_PAGE_WELCOME -; License page -!insertmacro MUI_PAGE_LICENSE "${ROOT_PATH}\LICENSE" -; Directory page -!insertmacro MUI_PAGE_DIRECTORY -; Instfiles page -!insertmacro MUI_PAGE_INSTFILES -; Finish page -!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt" -!insertmacro MUI_PAGE_FINISH - -; Uninstaller pages -!insertmacro MUI_UNPAGE_INSTFILES - -; Language files -!insertmacro MUI_LANGUAGE "English" - -; MUI end ------ - -Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" -OutFile "${ROOT_PATH}\${PRODUCT_NAME} ${PRODUCT_VERSION} Setup.exe" -InstallDir "$PROGRAMFILES\Cocos2D JavaScript" -InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" -ShowInstDetails show -ShowUnInstDetails show - -Section "MainSection" SEC01 - SetOutPath "$INSTDIR\bin" - SetOverwrite ifnewer - File "${ROOT_PATH}\bin\Create project.exe" - CreateDirectory "$SMPROGRAMS\Cocos2D JavaScript" - CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Create new project.lnk" "$INSTDIR\bin\Create project.exe" - File "${ROOT_PATH}\bin\Compile project.exe" - CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Compile project.lnk" "$INSTDIR\bin\Compile project.exe" - File "${ROOT_PATH}\bin\Serve project.exe" - CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Serve project.lnk" "$INSTDIR\bin\Serve project.exe" - SetOverwrite try - File "${ROOT_PATH}\bin\cocos.bat" - File "${ROOT_PATH}\bin\cocos.js" - File "${ROOT_PATH}\bin\cocos.sh" - File "${ROOT_PATH}\bin\jsdoc.sh" - SetOutPath "$INSTDIR" - File "${ROOT_PATH}\install.sh" - SetOutPath "$INSTDIR\lib\cocos\commands" - File "${ROOT_PATH}\lib\cocos\commands\help.js" - File "${ROOT_PATH}\lib\cocos\commands\ide.js" - File "${ROOT_PATH}\lib\cocos\commands\index.js" - File "${ROOT_PATH}\lib\cocos\commands\make.js" - File "${ROOT_PATH}\lib\cocos\commands\module_js" - File "${ROOT_PATH}\lib\cocos\commands\new.js" - File "${ROOT_PATH}\lib\cocos\commands\server.js" - SetOutPath "$INSTDIR\lib\cocos" - File "${ROOT_PATH}\lib\cocos\index.js" - File "${ROOT_PATH}\lib\cocos\mime.types" - File "${ROOT_PATH}\lib\cocos\mimetypes.js" - File "${ROOT_PATH}\lib\cocos\opts.js" - SetOutPath "$INSTDIR\lib\cocos\skeleton" - File "${ROOT_PATH}\lib\cocos\skeleton\make.json" - SetOutPath "$INSTDIR\lib\cocos\skeleton\public" - File "${ROOT_PATH}\lib\cocos\skeleton\public\index.html" - SetOutPath "$INSTDIR\lib\cocos\skeleton\src" - File "${ROOT_PATH}\lib\cocos\skeleton\src\main.js" - SetOutPath "$INSTDIR\lib\cocos" - File "${ROOT_PATH}\lib\cocos\template.js" - SetOutPath "$INSTDIR" - File /oname=LICENSE.txt "${ROOT_PATH}\LICENSE" - File "${ROOT_PATH}\package.json" - SetOutPath "$INSTDIR" - File /oname=README.txt "${ROOT_PATH}\README.md" - SetOutPath "$INSTDIR\src" - File "${ROOT_PATH}\src\event.js" - File "${ROOT_PATH}\src\global.js" - SetOutPath "$INSTDIR\src\libs" - File "${ROOT_PATH}\src\libs\base64.js" - File "${ROOT_PATH}\src\libs\box2d.js" - SetOutPath "$INSTDIR\src\libs\cocos2d" - File "${ROOT_PATH}\src\libs\cocos2d\ActionManager.js" - SetOutPath "$INSTDIR\src\libs\cocos2d\actions" - File "${ROOT_PATH}\src\libs\cocos2d\actions\Action.js" - File "${ROOT_PATH}\src\libs\cocos2d\actions\ActionInstant.js" - File "${ROOT_PATH}\src\libs\cocos2d\actions\ActionInterval.js" - File "${ROOT_PATH}\src\libs\cocos2d\actions\index.js" - SetOutPath "$INSTDIR\src\libs\cocos2d" - File "${ROOT_PATH}\src\libs\cocos2d\Animation.js" - File "${ROOT_PATH}\src\libs\cocos2d\AnimationCache.js" - File "${ROOT_PATH}\src\libs\cocos2d\config.json" - File "${ROOT_PATH}\src\libs\cocos2d\Director.js" - File "${ROOT_PATH}\src\libs\cocos2d\EventDispatcher.js" - File "${ROOT_PATH}\src\libs\cocos2d\index.js" - SetOutPath "$INSTDIR\src\libs\cocos2d\nodes" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\BatchNode.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\index.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\Label.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\Layer.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\Menu.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\MenuItem.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\Node.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\RenderTexture.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\Scene.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\Sprite.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\TMXLayer.js" - File "${ROOT_PATH}\src\libs\cocos2d\nodes\TMXTiledMap.js" - SetOutPath "$INSTDIR\src\libs\cocos2d" - File "${ROOT_PATH}\src\libs\cocos2d\Scheduler.js" - File "${ROOT_PATH}\src\libs\cocos2d\SpriteFrame.js" - File "${ROOT_PATH}\src\libs\cocos2d\SpriteFrameCache.js" - File "${ROOT_PATH}\src\libs\cocos2d\Texture2D.js" - File "${ROOT_PATH}\src\libs\cocos2d\TextureAtlas.js" - File "${ROOT_PATH}\src\libs\cocos2d\TMXOrientation.js" - File "${ROOT_PATH}\src\libs\cocos2d\TMXXMLParser.js" - SetOutPath "$INSTDIR\src\libs" - File "${ROOT_PATH}\src\libs\geometry.js" - File "${ROOT_PATH}\src\libs\gzip.js" - File "${ROOT_PATH}\src\libs\JXGUtil.js" - File "${ROOT_PATH}\src\libs\Plist.js" - File "${ROOT_PATH}\src\libs\qunit.js" - File "${ROOT_PATH}\src\libs\util.js" - SetOutPath "$INSTDIR\src" - File "${ROOT_PATH}\src\path.js" - File "${ROOT_PATH}\src\system.js" - SetOutPath "$INSTDIR\support\node-builds\etc" - File "${ROOT_PATH}\support\node-builds\etc\resolv.conf" - File "${ROOT_PATH}\support\node-builds\etc\hosts" - SetOutPath "$INSTDIR\support\node-builds\tmp" - File "${ROOT_PATH}\support\node-builds\tmp\empty" - SetOutPath "$INSTDIR\support\node-builds\win32" - File "${ROOT_PATH}\support\node-builds\win32\cygcrypto-0.9.8.dll" - File "${ROOT_PATH}\support\node-builds\win32\cyggcc_s-1.dll" - File "${ROOT_PATH}\support\node-builds\win32\cygiconv-2.dll" - File "${ROOT_PATH}\support\node-builds\win32\cygssl-0.9.8.dll" - File "${ROOT_PATH}\support\node-builds\win32\cygstdc++-6.dll" - File "${ROOT_PATH}\support\node-builds\win32\cygwin1.dll" - File "${ROOT_PATH}\support\node-builds\win32\cygxml2-2.dll" - File "${ROOT_PATH}\support\node-builds\win32\cygz.dll" - File "${ROOT_PATH}\support\node-builds\win32\node-repl" - File "${ROOT_PATH}\support\node-builds\win32\node-waf" - File "${ROOT_PATH}\support\node-builds\win32\node.exe" - SetOutPath "$INSTDIR\tests" - File "${ROOT_PATH}\tests\make.json" - SetOutPath "$INSTDIR\tests\public" - File "${ROOT_PATH}\tests\public\index.html" - SetOutPath "$INSTDIR\tests\src\cocos2d" - File "${ROOT_PATH}\tests\src\cocos2d\main.js" - SetOutPath "$INSTDIR\tests\src\cocos2d\resources\animations" - File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\dragon_animation.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini.plist" - File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini_blue.plist" - File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini_blue.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini_gray.plist" - File "${ROOT_PATH}\tests\src\cocos2d\resources\animations\grossini_gray.png" - SetOutPath "$INSTDIR\tests\src\cocos2d\resources" - File "${ROOT_PATH}\tests\src\cocos2d\resources\b1.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\b2.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\f1.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\f2.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\grossini_dance_atlas-red.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\grossini_dance_atlas.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\r1.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\r2.png" - SetOutPath "$INSTDIR\tests\src\cocos2d\resources\TileMaps" - File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\fixed-ortho-test2.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\iso-test.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\iso-test.tmx" - File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\ortho-test1.png" - File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\orthogonal-test1.tmx" - File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\orthogonal-test1.tsx" - File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\orthogonal-test2.tmx" - File "${ROOT_PATH}\tests\src\cocos2d\resources\TileMaps\orthogonal-test4.tmx" - SetOutPath "$INSTDIR\tests\src\cocos2d" - File "${ROOT_PATH}\tests\src\cocos2d\SpriteTest.js" - File "${ROOT_PATH}\tests\src\cocos2d\TileMapTest.js" - SetOutPath "$INSTDIR\tests\src\commonjs" - File "${ROOT_PATH}\tests\src\commonjs\bootstrap.py" - SetOutPath "$INSTDIR\tests\src\commonjs\docs" - File "${ROOT_PATH}\tests\src\commonjs\docs\contributors.html.markdown" - SetOutPath "$INSTDIR\tests\src\commonjs\docs\css" - File "${ROOT_PATH}\tests\src\commonjs\docs\css\colorful.css" - File "${ROOT_PATH}\tests\src\commonjs\docs\css\default.css" - File "${ROOT_PATH}\tests\src\commonjs\docs\css\styles.css" - SetOutPath "$INSTDIR\tests\src\commonjs\docs" - File "${ROOT_PATH}\tests\src\commonjs\docs\history.html.markdown" - SetOutPath "$INSTDIR\tests\src\commonjs\docs\images" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_blue.jpg" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_gray.jpg" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_green.jpg" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_home.jpg" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_orange.jpg" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\banner_red.jpg" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\content-wrapper_bg.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\content_bg.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\explosion.jpg" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\header_gradient.jpg" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\header_wrapper_bg.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\logo.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_browsers.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_browsers_on.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_commonjs.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_commonjs_on.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_div.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_js.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\nav_js_on.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\news_bg-btm.png" - File "${ROOT_PATH}\tests\src\commonjs\docs\images\news_bg-top.png" - SetOutPath "$INSTDIR\tests\src\commonjs\docs\impl" - File "${ROOT_PATH}\tests\src\commonjs\docs\impl\flusspferd.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\impl\gpsee.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\impl\helma.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\impl\index.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\impl\narwhal.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\impl\persevere.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\impl\v8cgi.html.markdown" - SetOutPath "$INSTDIR\tests\src\commonjs\docs" - File "${ROOT_PATH}\tests\src\commonjs\docs\index.html.markdown" - SetOutPath "$INSTDIR\tests\src\commonjs\docs\interp" - File "${ROOT_PATH}\tests\src\commonjs\docs\interp\jsc.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\interp\mozilla.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\interp\rhino.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\interp\spidermonkey.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\interp\v8.html.markdown" - SetOutPath "$INSTDIR\tests\src\commonjs\docs" - File "${ROOT_PATH}\tests\src\commonjs\docs\license.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\process.html.markdown" - SetOutPath "$INSTDIR\tests\src\commonjs\docs\specs" - File "${ROOT_PATH}\tests\src\commonjs\docs\specs\0.1.html.markdown" - File "${ROOT_PATH}\tests\src\commonjs\docs\specs\0.5.html.markdown" - SetOutPath "$INSTDIR\tests\src\commonjs\docs\specs\modules" - File "${ROOT_PATH}\tests\src\commonjs\docs\specs\modules\1.0.html.markdown" - SetOutPath "$INSTDIR\tests\src\commonjs\docs\_hooks" - File "${ROOT_PATH}\tests\src\commonjs\docs\_hooks\extend_md.py" - File "${ROOT_PATH}\tests\src\commonjs\docs\_hooks\transformers.py" - SetOutPath "$INSTDIR\tests\src\commonjs\docs\_layout" - File "${ROOT_PATH}\tests\src\commonjs\docs\_layout\default.html" - SetOutPath "$INSTDIR\tests\src\commonjs" - File "${ROOT_PATH}\tests\src\commonjs\pavement.py" - File "${ROOT_PATH}\tests\src\commonjs\README.txt" - File "${ROOT_PATH}\tests\src\commonjs\requirements.txt" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\absolute\b.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\absolute\program.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\submodule" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\absolute\submodule\a.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\absolute\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\cyclic\a.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\cyclic\b.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\cyclic\program.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\cyclic\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\determinism\program.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\submodule" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\determinism\submodule\a.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\determinism\submodule\b.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\determinism\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\exactExports\a.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\exactExports\program.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\exactExports\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\hasOwnProperty.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\program.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\test.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\toString.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\method\a.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\method\program.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\method\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\missing" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\missing\program.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\missing\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\monkeys\a.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\monkeys\program.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\monkeys\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\a\b\c" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\nested\a\b\c\d.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\nested\program.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\nested\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\relative\program.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\submodule" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\relative\submodule\a.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\relative\submodule\b.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\relative\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\a.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\b.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\c.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\program.js" - File "${ROOT_PATH}\tests\src\commonjs\tests\modules\1.0\transitive\test.js" - SetOutPath "$INSTDIR\tests\src\commonjs\tests\unit-testing\1.0" - File "${ROOT_PATH}\tests\src\commonjs\tests\unit-testing\1.0\program.js" - SetOutPath "$INSTDIR\tests\src" - File "${ROOT_PATH}\tests\src\commonjs.js" - File "${ROOT_PATH}\tests\src\config.json" - File "${ROOT_PATH}\tests\src\main.js" - File "${ROOT_PATH}\tests\src\qunit.js" -SectionEnd - -Section -AdditionalIcons - SetOutPath $INSTDIR - WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" - CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" - CreateShortCut "$SMPROGRAMS\Cocos2D JavaScript\Uninstall.lnk" "$INSTDIR\uninst.exe" -SectionEnd - -Section -Post - WriteUninstaller "$INSTDIR\uninst.exe" - WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\Create project.exe" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\Create project.exe" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" - WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" -SectionEnd - - -Function un.onUninstSuccess - HideWindow - MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." -FunctionEnd - -Function un.onInit - MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2 - Abort -FunctionEnd - -Section Uninstall - Delete "$INSTDIR\${PRODUCT_NAME}.url" - Delete "$INSTDIR\uninst.exe" - Delete "$INSTDIR\tests\src\qunit.js" - Delete "$INSTDIR\tests\src\main.js" - Delete "$INSTDIR\tests\src\config.json" - Delete "$INSTDIR\tests\src\commonjs.js" - Delete "$INSTDIR\tests\src\commonjs\tests\unit-testing\1.0\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\c.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\b.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive\a.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\submodule\b.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\submodule\a.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\a\b\c\d.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys\a.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\missing\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\missing\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method\a.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\toString.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty\hasOwnProperty.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports\a.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\submodule\b.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\submodule\a.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic\b.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic\a.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\test.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\submodule\a.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\program.js" - Delete "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\b.js" - Delete "$INSTDIR\tests\src\commonjs\requirements.txt" - Delete "$INSTDIR\tests\src\commonjs\README.txt" - Delete "$INSTDIR\tests\src\commonjs\pavement.py" - Delete "$INSTDIR\tests\src\commonjs\docs\_layout\default.html" - Delete "$INSTDIR\tests\src\commonjs\docs\_hooks\transformers.py" - Delete "$INSTDIR\tests\src\commonjs\docs\_hooks\extend_md.py" - Delete "$INSTDIR\tests\src\commonjs\docs\specs\modules\1.0.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\specs\0.5.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\specs\0.1.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\process.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\license.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\interp\v8.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\interp\spidermonkey.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\interp\rhino.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\interp\mozilla.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\interp\jsc.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\index.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\impl\v8cgi.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\impl\persevere.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\impl\narwhal.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\impl\index.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\impl\helma.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\impl\gpsee.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\impl\flusspferd.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\images\news_bg-top.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\news_bg-btm.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_js_on.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_js.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_div.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_commonjs_on.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_commonjs.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_browsers_on.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\nav_browsers.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\logo.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\header_wrapper_bg.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\header_gradient.jpg" - Delete "$INSTDIR\tests\src\commonjs\docs\images\explosion.jpg" - Delete "$INSTDIR\tests\src\commonjs\docs\images\content_bg.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\content-wrapper_bg.png" - Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_red.jpg" - Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_orange.jpg" - Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_home.jpg" - Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_green.jpg" - Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_gray.jpg" - Delete "$INSTDIR\tests\src\commonjs\docs\images\banner_blue.jpg" - Delete "$INSTDIR\tests\src\commonjs\docs\history.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\docs\css\styles.css" - Delete "$INSTDIR\tests\src\commonjs\docs\css\default.css" - Delete "$INSTDIR\tests\src\commonjs\docs\css\colorful.css" - Delete "$INSTDIR\tests\src\commonjs\docs\contributors.html.markdown" - Delete "$INSTDIR\tests\src\commonjs\bootstrap.py" - Delete "$INSTDIR\tests\src\cocos2d\TileMapTest.js" - Delete "$INSTDIR\tests\src\cocos2d\SpriteTest.js" - Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\orthogonal-test4.tmx" - Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\orthogonal-test2.tmx" - Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\orthogonal-test1.tsx" - Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\orthogonal-test1.tmx" - Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\ortho-test1.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\iso-test.tmx" - Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\iso-test.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\TileMaps\fixed-ortho-test2.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\r2.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\r1.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\grossini_dance_atlas.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\grossini_dance_atlas-red.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\f2.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\f1.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\b2.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\b1.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini_gray.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini_gray.plist" - Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini_blue.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini_blue.plist" - Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini.png" - Delete "$INSTDIR\tests\src\cocos2d\resources\animations\grossini.plist" - Delete "$INSTDIR\tests\src\cocos2d\resources\animations\dragon_animation.png" - Delete "$INSTDIR\tests\src\cocos2d\main.js" - Delete "$INSTDIR\tests\public\index.html" - Delete "$INSTDIR\tests\make.json" - Delete "$INSTDIR\support\node-builds\win32\node.exe" - Delete "$INSTDIR\support\node-builds\win32\node-waf" - Delete "$INSTDIR\support\node-builds\win32\node-repl" - Delete "$INSTDIR\support\node-builds\win32\cygz.dll" - Delete "$INSTDIR\support\node-builds\win32\cygxml2-2.dll" - Delete "$INSTDIR\support\node-builds\win32\cygwin1.dll" - Delete "$INSTDIR\support\node-builds\win32\cygstdc++-6.dll" - Delete "$INSTDIR\support\node-builds\win32\cygssl-0.9.8.dll" - Delete "$INSTDIR\support\node-builds\win32\cygiconv-2.dll" - Delete "$INSTDIR\support\node-builds\win32\cyggcc_s-1.dll" - Delete "$INSTDIR\support\node-builds\win32\cygcrypto-0.9.8.dll" - Delete "$INSTDIR\support\node-builds\tmp\empty" - Delete "$INSTDIR\support\node-builds\etc\resolv.conf" - Delete "$INSTDIR\support\node-builds\etc\hosts" - Delete "$INSTDIR\src\system.js" - Delete "$INSTDIR\src\path.js" - Delete "$INSTDIR\src\libs\util.js" - Delete "$INSTDIR\src\libs\qunit.js" - Delete "$INSTDIR\src\libs\Plist.js" - Delete "$INSTDIR\src\libs\JXGUtil.js" - Delete "$INSTDIR\src\libs\gzip.js" - Delete "$INSTDIR\src\libs\geometry.js" - Delete "$INSTDIR\src\libs\cocos2d\TMXXMLParser.js" - Delete "$INSTDIR\src\libs\cocos2d\TMXOrientation.js" - Delete "$INSTDIR\src\libs\cocos2d\TextureAtlas.js" - Delete "$INSTDIR\src\libs\cocos2d\Texture2D.js" - Delete "$INSTDIR\src\libs\cocos2d\SpriteFrameCache.js" - Delete "$INSTDIR\src\libs\cocos2d\SpriteFrame.js" - Delete "$INSTDIR\src\libs\cocos2d\Scheduler.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\TMXTiledMap.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\TMXLayer.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\Sprite.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\Scene.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\RenderTexture.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\Node.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\MenuItem.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\Menu.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\Layer.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\Label.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\index.js" - Delete "$INSTDIR\src\libs\cocos2d\nodes\BatchNode.js" - Delete "$INSTDIR\src\libs\cocos2d\index.js" - Delete "$INSTDIR\src\libs\cocos2d\EventDispatcher.js" - Delete "$INSTDIR\src\libs\cocos2d\Director.js" - Delete "$INSTDIR\src\libs\cocos2d\config.json" - Delete "$INSTDIR\src\libs\cocos2d\AnimationCache.js" - Delete "$INSTDIR\src\libs\cocos2d\Animation.js" - Delete "$INSTDIR\src\libs\cocos2d\actions\index.js" - Delete "$INSTDIR\src\libs\cocos2d\actions\ActionInterval.js" - Delete "$INSTDIR\src\libs\cocos2d\actions\ActionInstant.js" - Delete "$INSTDIR\src\libs\cocos2d\actions\Action.js" - Delete "$INSTDIR\src\libs\cocos2d\ActionManager.js" - Delete "$INSTDIR\src\libs\box2d.js" - Delete "$INSTDIR\src\libs\base64.js" - Delete "$INSTDIR\src\global.js" - Delete "$INSTDIR\src\event.js" - Delete "$INSTDIR\README.txt" - Delete "$INSTDIR\package.json" - Delete "$INSTDIR\LICENSE.txt" - Delete "$INSTDIR\lib\cocos\template.js" - Delete "$INSTDIR\lib\cocos\skeleton\src\main.js" - Delete "$INSTDIR\lib\cocos\skeleton\public\index.html" - Delete "$INSTDIR\lib\cocos\skeleton\make.json" - Delete "$INSTDIR\lib\cocos\opts.js" - Delete "$INSTDIR\lib\cocos\mimetypes.js" - Delete "$INSTDIR\lib\cocos\mime.types" - Delete "$INSTDIR\lib\cocos\index.js" - Delete "$INSTDIR\lib\cocos\commands\server.js" - Delete "$INSTDIR\lib\cocos\commands\new.js" - Delete "$INSTDIR\lib\cocos\commands\module_js" - Delete "$INSTDIR\lib\cocos\commands\make.js" - Delete "$INSTDIR\lib\cocos\commands\index.js" - Delete "$INSTDIR\lib\cocos\commands\ide.js" - Delete "$INSTDIR\lib\cocos\commands\help.js" - Delete "$INSTDIR\install.sh" - Delete "$INSTDIR\bin\jsdoc.sh" - Delete "$INSTDIR\bin\cocos.sh" - Delete "$INSTDIR\bin\cocos.js" - Delete "$INSTDIR\bin\cocos.bat" - Delete "$INSTDIR\bin\Serve project.exe" - Delete "$INSTDIR\bin\Compile project.exe" - Delete "$INSTDIR\bin\Create project.exe" - Delete "$SMPROGRAMS\Cocos2D JavaScript\Uninstall.lnk" - Delete "$SMPROGRAMS\Cocos2D JavaScript\Website.lnk" - Delete "$SMPROGRAMS\Cocos2D JavaScript\Serve project.lnk" - Delete "$SMPROGRAMS\Cocos2D JavaScript\Compile project.lnk" - Delete "$SMPROGRAMS\Cocos2D JavaScript\Create new project.lnk" - - RMDir "$SMPROGRAMS\Cocos2D JavaScript" - RMDir "$INSTDIR\tests\src\commonjs\tests\unit-testing\1.0" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\transitive" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative\submodule" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\relative" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested\a\b\c" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\nested" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\monkeys" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\missing" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\method" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\hasOwnProperty" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\exactExports" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism\submodule" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\determinism" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\cyclic" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute\submodule" - RMDir "$INSTDIR\tests\src\commonjs\tests\modules\1.0\absolute" - RMDir "$INSTDIR\tests\src\commonjs\docs\specs\modules" - RMDir "$INSTDIR\tests\src\commonjs\docs\specs" - RMDir "$INSTDIR\tests\src\commonjs\docs\interp" - RMDir "$INSTDIR\tests\src\commonjs\docs\impl" - RMDir "$INSTDIR\tests\src\commonjs\docs\images" - RMDir "$INSTDIR\tests\src\commonjs\docs\css" - RMDir "$INSTDIR\tests\src\commonjs\docs\_layout" - RMDir "$INSTDIR\tests\src\commonjs\docs\_hooks" - RMDir "$INSTDIR\tests\src\commonjs\docs" - RMDir "$INSTDIR\tests\src\commonjs" - RMDir "$INSTDIR\tests\src\cocos2d\resources\TileMaps" - RMDir "$INSTDIR\tests\src\cocos2d\resources\animations" - RMDir "$INSTDIR\tests\src\cocos2d\resources" - RMDir "$INSTDIR\tests\src\cocos2d" - RMDir "$INSTDIR\tests\src" - RMDir "$INSTDIR\tests\public" - RMDir "$INSTDIR\tests" - RMDir "$INSTDIR\support\node-builds\win32" - RMDir "$INSTDIR\support\node-builds\tmp" - RMDir "$INSTDIR\support\node-builds\etc" - RMDir "$INSTDIR\support" - RMDir "$INSTDIR\src\libs\cocos2d\nodes" - RMDir "$INSTDIR\src\libs\cocos2d\actions" - RMDir "$INSTDIR\src\libs\cocos2d" - RMDir "$INSTDIR\src\libs" - RMDir "$INSTDIR\src" - RMDir "$INSTDIR\public" - RMDir "$INSTDIR\lib\cocos\skeleton\src" - RMDir "$INSTDIR\lib\cocos\skeleton\public" - RMDir "$INSTDIR\lib\cocos\skeleton" - RMDir "$INSTDIR\lib\cocos\commands" - RMDir "$INSTDIR\lib\cocos" - RMDir "$INSTDIR\bin" - RMDir "$INSTDIR" - - DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" - DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" - SetAutoClose true -SectionEnd From 916cf330caa7d4d82a3a7d781b0a471c1a087a16 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 14 Feb 2011 21:43:08 +1300 Subject: [PATCH 072/176] Updated .tar generation so it actually includes node.js for all platforms --- support/package.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/support/package.js b/support/package.js index 1d43145..524a777 100755 --- a/support/package.js +++ b/support/package.js @@ -31,6 +31,16 @@ function generateNSISScript(files, callback) { removeFileList = '', removeDirList = ''; + files = files.filter(function(file) { + // Ignore node-builds for other platforms + if (~file.indexOf('node-builds') && !~file.indexOf('win32')) { + return; + } + + return file; + }); + + // Generate the install and remove lists var prevDirname, i, len; for (i = 0, len = files.length; i < len; i++) { @@ -103,7 +113,7 @@ function findFilesToPackage(dir, callback) { process.chdir(cwd); // Convert \n separated list of filenames into a sorted array - var fileList = (mainFileList.trim() + subFileList.trim()).split('\n').filter(function(file) { + var fileList = (mainFileList.trim() + '\n' + subFileList.trim()).split('\n').filter(function(file) { // Ignore entering submodule messages if (file.indexOf('Entering ') === 0) { return; @@ -114,12 +124,6 @@ function findFilesToPackage(dir, callback) { return; } - // Ignore node-builds for other platforms - if (~file.indexOf('node-builds') && !~file.indexOf('win32')) { - return; - } - - // Submodules appear in ls-files but aren't files. Skip them if (fs.statSync(path.join(dir, file)).isDirectory()) { return; From 0bfc0b3df2765170843fadd5b688bd74927c048b Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 14 Feb 2011 21:59:36 +1300 Subject: [PATCH 073/176] Fixed class name generation --- lib/cocos2d/commands/new.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cocos2d/commands/new.js b/lib/cocos2d/commands/new.js index bf8b503..42df0a1 100644 --- a/lib/cocos2d/commands/new.js +++ b/lib/cocos2d/commands/new.js @@ -27,8 +27,8 @@ function camelCase(str, upperFirst) { } } function snakeCase(str) { - str = str.replace(/([A-Z]+)([A-Z][a-z])/, '$1_$2'); - str = str.replace(/([a-z\d])([A-Z])/, '$1_$2'); + str = str.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2'); + str = str.replace(/([a-z\d])([A-Z])/g, '$1_$2'); str = str.replace('-', '_'); return str.toLowerCase(); From 779626f8c08dcb985275ad1c996532f3509372f8 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Feb 2011 16:26:58 +1300 Subject: [PATCH 074/176] Use system Node.js build if it's available. --- bin/cocos.sh | 58 ++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/bin/cocos.sh b/bin/cocos.sh index fc25373..edf545e 100755 --- a/bin/cocos.sh +++ b/bin/cocos.sh @@ -7,30 +7,34 @@ else DIR=$(dirname $0) fi -case `uname -a` in -Linux*x86_64*) - "$DIR/../support/node-builds/lin64/node" "$DIR/cocos.js" "$@" - ;; - -Linux*i686*) - "$DIR/../support/node-builds/lin32/node" "$DIR/cocos.js" "$@" - ;; - -Darwin*) - "$DIR/../support/node-builds/osx64/node" "$DIR/cocos.js" "$@" - ;; - -CYGWIN*) - "$DIR/../support/node-builds/win32/node.exe" "$DIR/cocos.js" "$@" - ;; - -MING*) - "$DIR/../support/node-builds/win32/node.exe" "$DIR/cocos.js" "$@" - ;; - -*) echo "Unknown OS" - ;; -esac - - - +if which node &> /dev/null +then + # User has node installed, use that + node "$DIR/cocos.js" "$@" +else + # User doesn't have node installed, fallback to precompiled binaries + case `uname -a` in + Linux*x86_64*) + "$DIR/../support/node-builds/lin64/node" "$DIR/cocos.js" "$@" + ;; + + Linux*i686*) + "$DIR/../support/node-builds/lin32/node" "$DIR/cocos.js" "$@" + ;; + + Darwin*) + "$DIR/../support/node-builds/osx64/node" "$DIR/cocos.js" "$@" + ;; + + CYGWIN*) + "$DIR/../support/node-builds/win32/node.exe" "$DIR/cocos.js" "$@" + ;; + + MING*) + "$DIR/../support/node-builds/win32/node.exe" "$DIR/cocos.js" "$@" + ;; + + *) echo "Unknown OS and Node isn't installed. Can't continue." + ;; + esac +fi From ea152abecdbb7cb448e01c9389eec9ccac61fbbf Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Feb 2011 16:27:37 +1300 Subject: [PATCH 075/176] Updated README --- README.md | 147 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 1eea5a2..156b5eb 100644 --- a/README.md +++ b/README.md @@ -1,87 +1,144 @@ -Cocos2d-javascript is released under the MIT license. - -This is in the early stages of development and could break backwards compatibility at any time. - -* You can find me on Twitter: @cocos2djs -* Email: +* Twitter: [@cocos2djs](http://twitter.com/cocos2djs) * Website: * Documentation: * Forum: +* Email: + +Installation +============ + +Follow the instructions for your given platform or skip ahead to 'manual +installation' if you want to install from git. + +Windows +------- + +Download and launch the installer. + + + +Linux or Mac OS X using npm +--------------------------- + +If you have [Node.js][nodejs] and [npm][npm] installed you can install Cocos2D +JavaScript as a package. + + npm install cocos2d + +Linux or Mac OS X using ZIP archive +----------------------------------- + +If you don't have, or don't want to use npm, you can install by downloading the +latest ZIP. -Creating a new project ----------------------- + -To create a new project you first need to get a copy of cocos2d-javascript. Grab the latest using git +The above file is a few megabytes because it includes precompiled builds +of Node.js for every platform. If you have Node installed and want a smaller +download use this link. - git clone git://github.com/ryanwilliams/cocos2d-javascript.git + -To create your initial project simply navigate to the cocos2d-javascript directory and run +Then from your terminal run `sudo ./install.sh`. This script will copy Cocos2D +JavaScript to a global location of your choice and symlink the executable to +/usr/local/bin/cocos - ./cocos new ~/Projects/MyApp +Manual Installation (all platforms) +----------------------------------- -This will create a new directory at that path with everything you need to -get started. It will also add cocos2d-javascript as a git submodule. If you -prefer to just copy the cocos2d-javascript code instead of using a git -submodule then use +You don't need to use the installer if you don't want to. You can download the +latest ZIP or checkout the latest version from github. - ./cocos new ~/Projects/MyApp -g +If you checkout from github and don't have Node.js installed, be sure to also +get the submodules as they include precompiled Node.js binaries. -Getting things running ----------------------- + git submodule update --init -To get your project running simply navigate to the newly created directory run -the development web server +With all the code read you can copy it to any place you want and from there use +the 'cocos.sh', 'cocos.bat' or .EXEs in _bin/_ as you would normally. - ./cocos server +Creating your first project +=========================== -And visit . There you will see a simple application -outputting your application name. +On Windows use the 'Create project' shortcut from your start menu to create and +select a location for your new project. + +On Linux and Mac OS X open your terminal and run: + + cocos new ~/my_first_project + +This will create a barebones project which simply draws the project name in the +centre of the screen. + +To test that it's working, on Windows double click the 'Serve project' shortcut +in your project's folder. + +On Linux and Mac OS X from your terminal run: + + cd ~/my_first_project + cocos server + +Now visit http://localhost:4000 and with a bit of luck you'll have something showing. Developing ----------- +========== Everything you write will be in separate JavaScript files. These will be compiled into a single file which also includes all your other resources including images, sound files, map files, etc. -The entry point for the code is path defined as "main.js" inside the in "make.js" file. +The entry point for the code is the file _src/main.js_ which has an +`exports.main` function that is called on startup. -In the public/index.html you will see <script src="https://github.com/appname.js"> tag to include the code. +The HTML for your page is in _public/index.html_. -The web server will compile your code each time it is requested. This makes -development a lot easier. +Compiling your application +========================== -Run ./cocos server -h for help. +You should never use the development server in production. It's very slow and +insecure. Instead you will compile your application into a single JavaScript +file. This file includes everything, you don't need to worry about hosting any +external resources such as images and tilemaps. -Compiling your application --------------------------- +To do this, on Windows double click the 'Compile project' shortcut in your +project's folder. -To compile your code you run ./cocos make. Which reads the make.js file -to work out what you want to build. +On Linux and Mac OS X in your terminal run: -When built the resulting .js file will contain all your code aswell as all your -images and map files. This means you only need to update a single file and only -a single HTTP request is needed to serve everything. + cd ~/my_first_project + cocos make -Run ./cocos make -h for help. +The file will be written to _build/_. You can run this through a JavaScript +minifier if you so choose. You will get a very good reduction in size if your +Web server is configured to gzip JavaScript files. Browser Support ---------------- +=============== -I intend for this to work in Firefox, Chrome, Safari, Opera and IE9. I -mostly develop using Chrome so that's likely to have the best compatibility -until I get close to a proper release. +Everything should work in Firefox 3, Chrome, Safari, Opera and IE9. If that is +not the case then please file a bug report. Documentation -------------- +============= + +Documentation can be viewed online at http://cocos2d-javascript.org/documentation + +If you wish to generate the documentation yourself you need to follow these steps. Download JsDoc 2.3 (or 2.4) from . Copy that to /usr/local/jsdoc-toolkit or wherever you like and then run: - JSDOC_HOME=/usr/local/jsdoc-toolkit ./jsdoc + JSDOC_HOME=/usr/local/jsdoc-toolkit ./bin/jsdoc The documentation will appear in the 'docs' directory. -© 2010 Ryan Williams +License +======= + +Cocos2D JavaScript is released under the MIT license. See LICENSE for more details. + +© 2010-2011 Ryan Williams +[nodejs]: http://nodejs.org +[npm]: http://npmjs.org From ab1cc60509119a58d4745cb2ff1d371cf351cf9e Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Feb 2011 16:30:58 +1300 Subject: [PATCH 076/176] Updated README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 156b5eb..dd0a552 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ download use this link. -Then from your terminal run `sudo ./install.sh`. This script will copy Cocos2D +Then from your terminal run `sudo ./install.sh`. The script will copy Cocos2D JavaScript to a global location of your choice and symlink the executable to /usr/local/bin/cocos @@ -121,7 +121,7 @@ not the case then please file a bug report. Documentation ============= -Documentation can be viewed online at http://cocos2d-javascript.org/documentation +Documentation can be viewed online at If you wish to generate the documentation yourself you need to follow these steps. From 31815810b3a281ed140ec71b8319c375cb514c76 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Feb 2011 16:36:29 +1300 Subject: [PATCH 077/176] Initialise by calling 'main()' in the mainModule --- lib/cocos2d/commands/module_js | 3 +++ lib/cocos2d/skeleton/src/main.js | 24 +++++++++++++----------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/cocos2d/commands/module_js b/lib/cocos2d/commands/module_js index 8eac07d..caeca87 100644 --- a/lib/cocos2d/commands/module_js +++ b/lib/cocos2d/commands/module_js @@ -133,6 +133,9 @@ function resource(path) { } process.mainModule = loadModule(__main_module_name__); + if (process.mainModule.exports.main) { + process.mainModule.exports.main(); + } // Add a global require. Useful in the debug console. window.require = function require(request, parent) { diff --git a/lib/cocos2d/skeleton/src/main.js b/lib/cocos2d/skeleton/src/main.js index 285134e..ac04e93 100644 --- a/lib/cocos2d/skeleton/src/main.js +++ b/lib/cocos2d/skeleton/src/main.js @@ -23,19 +23,21 @@ var $classname$ = cocos.nodes.Layer.extend({ } }); -// Initialise everything +exports.main = function() { + // Initialise application -// Get director -var director = cocos.Director.get('sharedDirector'); + // Get director + var director = cocos.Director.get('sharedDirector'); -// Attach director to our
        element -director.attachInView(document.getElementById('$filename$_app')); + // Attach director to our
        element + director.attachInView(document.getElementById('$filename$_app')); -// Create a scene -var scene = cocos.nodes.Scene.create(); + // Create a scene + var scene = cocos.nodes.Scene.create(); -// Add our layer to the scene -scene.addChild({child: $classname$.create()}); + // Add our layer to the scene + scene.addChild({child: $classname$.create()}); -// Run the scene -director.runWithScene(scene); + // Run the scene + director.runWithScene(scene); +}; From 4d8a12158f460c7d86ad42a19d7572ad55688811 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Feb 2011 17:54:32 +1300 Subject: [PATCH 078/176] Added support for Solaris (yes, really!) --- bin/cocos.sh | 4 ++++ support/node-builds | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/cocos.sh b/bin/cocos.sh index edf545e..984bf3a 100755 --- a/bin/cocos.sh +++ b/bin/cocos.sh @@ -25,6 +25,10 @@ else Darwin*) "$DIR/../support/node-builds/osx64/node" "$DIR/cocos.js" "$@" ;; + + SunOS*) + "$DIR/../support/node-builds/sol32/node" "$DIR/cocos.js" "$@" + ;; CYGWIN*) "$DIR/../support/node-builds/win32/node.exe" "$DIR/cocos.js" "$@" diff --git a/support/node-builds b/support/node-builds index 0fcee7d..bbbdd1c 160000 --- a/support/node-builds +++ b/support/node-builds @@ -1 +1 @@ -Subproject commit 0fcee7d5f7fec359ad3c747cf86ba707548a039a +Subproject commit bbbdd1c721538286ec2466191c28f3cc6667a53b From 0b755fc9c69460b88e4beeb01326a07255486283 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Feb 2011 18:03:56 +1300 Subject: [PATCH 079/176] Updaged package details --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a2c0384..f734c77 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "cocos2d", "author": "Ryan Williams ", - "description": "Port of the cocos2d game engine for the Web", - "version": "0.0.1", + "description": "Port of the Cocos2D graphics engine to HTML5", + "version": "0.1.0", "homepage": "http://cocos2d-javascript.org/", "engines": { From 1c7d51c2fd2a0332a005029d8ef53a64d4eea98f Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Feb 2011 18:24:37 +1300 Subject: [PATCH 080/176] Updated packager to produce archives for separate platforms --- .gitignore | 5 ++-- .npmignore | 5 ++-- support/installer_nsi.template | 2 +- support/package.js | 52 ++++++++++++++++++++++++++++++---- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 3ffc54a..26e7c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,6 @@ jsdocs/ docs/ public/cocos2d.js public/tests.js -Cocos2D\ JavaScript*Setup.exe -Cocos2D-JavaScript*.tar.gz +cocos2d-*.exe +cocos2d-*.gz +cocos2d-*.zip diff --git a/.npmignore b/.npmignore index ff8cf1f..363579a 100644 --- a/.npmignore +++ b/.npmignore @@ -7,5 +7,6 @@ jsdocs/ docs/ public/cocos2d.js public/tests.js -Cocos2D\ JavaScript*Setup.exe -Cocos2D-JavaScript*.tar.gz +cocos2d-*.exe +cocos2d-*.gz +cocos2d-*.zip diff --git a/support/installer_nsi.template b/support/installer_nsi.template index a4a25fe..740f390 100644 --- a/support/installer_nsi.template +++ b/support/installer_nsi.template @@ -39,7 +39,7 @@ RequestExecutionLevel admin ; MUI end ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" -OutFile "${ROOT_PATH}\${PRODUCT_NAME} ${PRODUCT_VERSION} Setup.exe" +OutFile "${ROOT_PATH}\cocos2d-javascript-${PRODUCT_VERSION}-windows.exe" InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" ShowInstDetails show diff --git a/support/package.js b/support/package.js index 524a777..b40e291 100755 --- a/support/package.js +++ b/support/package.js @@ -33,7 +33,7 @@ function generateNSISScript(files, callback) { files = files.filter(function(file) { // Ignore node-builds for other platforms - if (~file.indexOf('node-builds') && !~file.indexOf('win32')) { + if (~file.indexOf('node-builds') && !~file.indexOf('win')) { return; } @@ -139,19 +139,38 @@ function findFilesToPackage(dir, callback) { } function generateZip(files, zipName) { + zipName += '.zip'; + + sys.puts('Generating .zip archive : ' + zipName); + if (path.exists(zipName)) { + fs.unlink(zipName); + } + + var tar = spawn('zip', ['-9', zipName].concat(files)); + + tar.stderr.on('data', function(data) { + sys.print(data); + }); + + tar.on('exit', function() { + sys.puts('Generated ' + zipName + ' archive'); + }); +} +function generateGZip(files, zipName) { + zipName += '.tar.gz'; sys.puts('Generating .tar.gz archive : ' + zipName); if (path.exists(zipName)) { fs.unlink(zipName); } - var tar = spawn('tar', ['-czf', zipName + '.tar.gz'].concat(files)); + var tar = spawn('tar', ['-czf', zipName].concat(files)); tar.stderr.on('data', function(data) { sys.print(data); }); tar.on('exit', function() { - sys.puts('Generated .tar.gz archive'); + sys.puts('Generated ' + zipName + ' archive'); }); } @@ -179,8 +198,31 @@ function generateZip(files, zipName) { var cwd = process.cwd(); process.chdir(dir); - // Generate zip archive - generateZip(filesToPackage, 'Cocos2D-JavaScript-v' + VERSION); + + // Generate zip archives for all platforms + generateGZip(filesToPackage, 'cocos2d-javascript-v' + VERSION + '-all'); + + function removeNodeBuilds(files, platform) { + return files.filter(function(file) { + if (~file.indexOf('node-builds') && !~file.indexOf(platform) && !~file.indexOf('tmp') && !~file.indexOf('etc')) { + return; + } + + return file; + }); + } + + // Mac OS X + generateGZip(removeNodeBuilds(filesToPackage, 'osx'), 'cocos2d-javascript-v' + VERSION + '-mac'); + + // Linux + generateGZip(removeNodeBuilds(filesToPackage, 'lin'), 'cocos2d-javascript-v' + VERSION + '-linux'); + + // Windows + generateZip(removeNodeBuilds(filesToPackage, 'win'), 'cocos2d-javascript-v' + VERSION + '-windows'); + + // Solaris + generateGZip(removeNodeBuilds(filesToPackage, 'sol'), 'cocos2d-javascript-v' + VERSION + '-solaris'); }); }); }); From 1cacbde34e2e0397839ff2366e5ef9be3a6032a2 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Feb 2011 19:20:52 +1300 Subject: [PATCH 081/176] Updated windows installer filename --- support/installer_nsi.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support/installer_nsi.template b/support/installer_nsi.template index 740f390..9e1dcf8 100644 --- a/support/installer_nsi.template +++ b/support/installer_nsi.template @@ -39,7 +39,7 @@ RequestExecutionLevel admin ; MUI end ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" -OutFile "${ROOT_PATH}\cocos2d-javascript-${PRODUCT_VERSION}-windows.exe" +OutFile "${ROOT_PATH}\cocos2d-javascript-${PRODUCT_VERSION}-windows-installer.exe" InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" ShowInstDetails show From 4965c18d4f1cc154861818bfbc0ab10fcfa60e84 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 15 Feb 2011 20:23:27 +1300 Subject: [PATCH 082/176] Updated README --- README.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dd0a552..444cec9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Windows Download and launch the installer. - + Linux or Mac OS X using npm --------------------------- @@ -31,13 +31,7 @@ Linux or Mac OS X using ZIP archive If you don't have, or don't want to use npm, you can install by downloading the latest ZIP. - - -The above file is a few megabytes because it includes precompiled builds -of Node.js for every platform. If you have Node installed and want a smaller -download use this link. - - + Then from your terminal run `sudo ./install.sh`. The script will copy Cocos2D JavaScript to a global location of your choice and symlink the executable to From 2e3d83c2f4ae92a689515548aff74850976fab8e Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 16 Feb 2011 08:37:53 +1300 Subject: [PATCH 083/176] Updated README --- README.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 444cec9..0da9280 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ -* Twitter: [@cocos2djs](http://twitter.com/cocos2djs) -* Website: -* Documentation: -* Forum: -* Email: +Overview +======== + +Cocos2D JavaScript is an HTML5 port of the popular iPhone 2D graphics engine Cocos2D. It allows rapid development of 2D games and graphical applications which can run in any modern Web browser. Installation ============ @@ -134,5 +133,15 @@ Cocos2D JavaScript is released under the MIT license. See LICENSE for more detai © 2010-2011 Ryan Williams +Links +===== + +* Twitter: [@cocos2djs](http://twitter.com/cocos2djs) +* Website: +* Documentation: +* Forum: +* Email: + + [nodejs]: http://nodejs.org [npm]: http://npmjs.org From fcc46d4ddad07353cf77fbbbbaf04f3073726cfe Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 16 Feb 2011 19:58:03 +1300 Subject: [PATCH 084/176] Renamed 'event' module to 'events' to avoid conflicts with browser globals --- src/{event.js => events.js} | 31 ++++++++++++------------- src/global.js | 22 +++++++++--------- src/libs/cocos2d/nodes/BatchNode.js | 2 +- src/libs/cocos2d/nodes/Layer.js | 2 +- src/libs/cocos2d/nodes/Node.js | 2 +- src/libs/cocos2d/nodes/RenderTexture.js | 2 +- src/libs/cocos2d/nodes/Sprite.js | 2 +- 7 files changed, 31 insertions(+), 32 deletions(-) rename src/{event.js => events.js} (80%) diff --git a/src/event.js b/src/events.js similarity index 80% rename from src/event.js rename to src/events.js index 357c040..6ec63f2 100644 --- a/src/event.js +++ b/src/events.js @@ -1,12 +1,11 @@ /*global module exports require*/ /*jslint white: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true*/ - /** * @namespace * Support for listening for and triggering events */ -var event = {}; +var events = {}; /** * @private @@ -39,7 +38,7 @@ var eventID = 0; /** * @class * Represents an event being listened to. You should not create instances of - * this directly, it is instead returned by event.addListener + * this directly, it is instead returned by events.addListener * * @extends Object * @@ -47,7 +46,7 @@ var eventID = 0; * @param {String} eventName Name of the event to listen for * @param {Function} handler Callback to fire when the event triggers */ -event.EventListener = function (source, eventName, handler) { +events.EventListener = function (source, eventName, handler) { /** * Object to listen to for an event * @type Object @@ -82,10 +81,10 @@ event.EventListener = function (source, eventName, handler) { * @param {String} eventName Name of the event to listen for * @param {Function} handler Callback to fire when the event triggers * - * @returns {event.EventListener} The event listener. Pass to removeListener to destroy it. + * @returns {events.EventListener} The event listener. Pass to removeListener to destroy it. */ -event.addListener = function (source, eventName, handler) { - return new event.EventListener(source, eventName, handler); +events.addListener = function (source, eventName, handler) { + return new events.EventListener(source, eventName, handler); }; /** @@ -94,7 +93,7 @@ event.addListener = function (source, eventName, handler) { * @param {Object} source Object to trigger the event on * @param {String} eventName Name of the event to trigger */ -event.trigger = function (source, eventName) { +events.trigger = function (source, eventName) { var listeners = getListeners(source, eventName), args = Array.prototype.slice.call(arguments, 2), eventID, @@ -113,9 +112,9 @@ event.trigger = function (source, eventName) { /** * Remove a previously registered event listener * - * @param {event.EventListener} listener EventListener to remove, as returned by event.addListener + * @param {events.EventListener} listener EventListener to remove, as returned by events.addListener */ -event.removeListener = function (listener) { +events.removeListener = function (listener) { delete getListeners(listener.source, listener.eventName)[listener.eventID]; }; @@ -125,7 +124,7 @@ event.removeListener = function (listener) { * @param {Object} source Object to remove listeners from * @param {String} eventName Name of event to remove listeners from */ -event.clearListeners = function (source, eventName) { +events.clearListeners = function (source, eventName) { var listeners = getListeners(source, eventName), eventID; @@ -134,7 +133,7 @@ event.clearListeners = function (source, eventName) { if (listeners.hasOwnProperty(eventID)) { var l = listeners[eventID]; if (l) { - event.removeListener(l); + events.removeListener(l); } } } @@ -145,18 +144,18 @@ event.clearListeners = function (source, eventName) { * * @param {Object} source Object to remove listeners from */ -event.clearInstanceListeners = function (source, eventName) { +events.clearInstanceListeners = function (source) { var listeners = getListeners(source), eventID; - for (eventName in listeners) { + for (var eventName in listeners) { if (listeners.hasOwnProperty(eventName)) { var el = listeners[eventName]; for (eventID in el) { if (el.hasOwnProperty(eventID)) { var l = el[eventID]; if (l) { - event.removeListener(l); + events.removeListener(l); } } } @@ -164,4 +163,4 @@ event.clearInstanceListeners = function (source, eventName) { } }; -module.exports = event; +module.exports = events; diff --git a/src/global.js b/src/global.js index 5b10879..5c84e76 100644 --- a/src/global.js +++ b/src/global.js @@ -1,9 +1,9 @@ -/*globals module exports resource require BObject BArray*/ +/*globals module exports resource require*/ /*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; var util = require('util'), - evt = require('event'); + events = require('events'); /** @@ -150,8 +150,8 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ /** * @private */ - triggerChanged: function(key, oldVal) { - evt.trigger(this, key.toLowerCase() + '_changed', oldVal); + triggerChanged: function (key, oldVal) { + events.trigger(this, key.toLowerCase() + '_changed', oldVal); }, /** @@ -172,7 +172,7 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ var oldVal = this.get(key); // When bound property changes, trigger a 'changed' event on this one too - getBindings(this)[key] = evt.addListener(target, targetKey.toLowerCase() + '_changed', function (oldVal) { + getBindings(this)[key] = events.addListener(target, targetKey.toLowerCase() + '_changed', function (oldVal) { self.triggerChanged(key, oldVal); }); @@ -191,7 +191,7 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ } delete getBindings(this)[key]; - evt.removeListener(binding); + events.removeListener(binding); // Grab current value from bound property var val = this.get(key); delete getAccessors(this)[key]; @@ -217,7 +217,7 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ * @getter id * @type Integer */ - get_id: function() { + get_id: function () { if (!this._id) { this._id = ++objectID; } @@ -231,7 +231,7 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ * Create a new instance of this object * @returns {BObject} New instance of this object */ -BObject.create = function() { +BObject.create = function () { var ret = new this(); ret.init.apply(ret, arguments); return ret; @@ -324,7 +324,7 @@ var BArray = BObject.extend(/** @lends BArray# */{ var oldVal = this.array[i]; this.array[i] = value; - evt.trigger(this, 'set_at', i, oldVal); + events.trigger(this, 'set_at', i, oldVal); }, /** @@ -336,7 +336,7 @@ var BArray = BObject.extend(/** @lends BArray# */{ insertAt: function (i, value) { this.array.splice(i, 0, value); this.set('length', this.array.length); - evt.trigger(this, 'insert_at', i); + events.trigger(this, 'insert_at', i); }, /** @@ -349,7 +349,7 @@ var BArray = BObject.extend(/** @lends BArray# */{ var oldVal = this.array[i]; this.array.splice(i, 1); this.set('length', this.array.length); - evt.trigger(this, 'remove_at', i, oldVal); + events.trigger(this, 'remove_at', i, oldVal); return oldVal; }, diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index d802b3d..08345d8 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -3,7 +3,7 @@ "use strict"; var util = require('util'), - evt = require('event'), + evt = require('events'), geo = require('geometry'), ccp = geo.ccp, TextureAtlas = require('../TextureAtlas').TextureAtlas, diff --git a/src/libs/cocos2d/nodes/Layer.js b/src/libs/cocos2d/nodes/Layer.js index c0d2d40..4f080ae 100644 --- a/src/libs/cocos2d/nodes/Layer.js +++ b/src/libs/cocos2d/nodes/Layer.js @@ -4,7 +4,7 @@ var Node = require('./Node').Node, util = require('util'), - evt = require('event'), + evt = require('events'), Director = require('../Director').Director, ccp = require('geometry').ccp, EventDispatcher = require('../EventDispatcher').EventDispatcher; diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index 07947f6..8da05f5 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -3,7 +3,7 @@ "use strict"; var util = require('util'), - evt = require('event'), + evt = require('events'), Scheduler = require('../Scheduler').Scheduler, ActionManager = require('../ActionManager').ActionManager, geo = require('geometry'), ccp = geo.ccp; diff --git a/src/libs/cocos2d/nodes/RenderTexture.js b/src/libs/cocos2d/nodes/RenderTexture.js index c162d88..86789af 100644 --- a/src/libs/cocos2d/nodes/RenderTexture.js +++ b/src/libs/cocos2d/nodes/RenderTexture.js @@ -3,7 +3,7 @@ "use strict"; var util = require('util'), - evt = require('event'), + evt = require('events'), Node = require('./Node').Node, geo = require('geometry'), Sprite = require('./Sprite').Sprite, diff --git a/src/libs/cocos2d/nodes/Sprite.js b/src/libs/cocos2d/nodes/Sprite.js index 927c688..dcb3a03 100644 --- a/src/libs/cocos2d/nodes/Sprite.js +++ b/src/libs/cocos2d/nodes/Sprite.js @@ -3,7 +3,7 @@ "use strict"; var util = require('util'), - evt = require('event'), + evt = require('events'), Director = require('../Director').Director, TextureAtlas = require('../TextureAtlas').TextureAtlas, Node = require('./Node').Node, From 10caf02b4247a4b7268963a45a400d239f66f566 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 16 Feb 2011 20:57:02 +1300 Subject: [PATCH 085/176] Refactored Module so global 'require' is available before init --- lib/cocos2d/commands/module_js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/cocos2d/commands/module_js b/lib/cocos2d/commands/module_js index caeca87..dc67201 100644 --- a/lib/cocos2d/commands/module_js +++ b/lib/cocos2d/commands/module_js @@ -132,18 +132,20 @@ function resource(path) { } } - process.mainModule = loadModule(__main_module_name__); - if (process.mainModule.exports.main) { - process.mainModule.exports.main(); - } - // Add a global require. Useful in the debug console. window.require = function require(request, parent) { return loadModule(request, parent).exports; }; - window.require.main = process.mainModule; window.require.paths = modulePaths; + process.mainModule = loadModule(__main_module_name__); + + window.require.main = process.mainModule; + + if (process.mainModule.exports.main) { + process.mainModule.exports.main(); + } + }); })(); From 9322dc1ab707539a8b1c62c9c4e8b6d8e37f3595 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 17 Feb 2011 17:41:29 +1300 Subject: [PATCH 086/176] Fixed packager generating broken Windows installer builds --- support/package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support/package.js b/support/package.js index b40e291..2e7ee40 100755 --- a/support/package.js +++ b/support/package.js @@ -33,7 +33,7 @@ function generateNSISScript(files, callback) { files = files.filter(function(file) { // Ignore node-builds for other platforms - if (~file.indexOf('node-builds') && !~file.indexOf('win')) { + if (~file.indexOf('node-builds') && !~file.indexOf('win') && !~file.indexOf('tmp') && !~file.indexOf('etc')) { return; } From 44307c81ba383440f5b14a2fb1856ae99163c3ee Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 17 Feb 2011 17:52:02 +1300 Subject: [PATCH 087/176] Fixed packaged so reinstalling doesn't go to \bin\ folder --- support/installer_nsi.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support/installer_nsi.template b/support/installer_nsi.template index 9e1dcf8..c1aecce 100644 --- a/support/installer_nsi.template +++ b/support/installer_nsi.template @@ -65,7 +65,7 @@ SectionEnd Section -Post WriteUninstaller "$INSTDIR\uninst.exe" - WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\bin\Create project.exe" + WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\bin\Create project.exe" From 4ac67122e8bd57e43ee869707528562663fa3bf9 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 19 Feb 2011 15:31:19 +1300 Subject: [PATCH 088/176] Bumped version number --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index f734c77..ebb18eb 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,12 @@ "name": "cocos2d", "author": "Ryan Williams ", "description": "Port of the Cocos2D graphics engine to HTML5", - "version": "0.1.0", + "version": "0.1.1", "homepage": "http://cocos2d-javascript.org/", "engines": { "node": ">= 0.2.0" }, - "main": "bin/cocos", "repository": { "type" : "git" , From 10ea4188d2a6c1503c72a2ee9d3df7543cd3bd28 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 19 Feb 2011 15:48:36 +1300 Subject: [PATCH 089/176] Cleaned up some TMX code --- src/libs/cocos2d/TMXXMLParser.js | 60 +++++++++++++++++---------- src/libs/cocos2d/nodes/TMXLayer.js | 2 +- src/libs/cocos2d/nodes/TMXTiledMap.js | 19 ++++++--- 3 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/libs/cocos2d/TMXXMLParser.js b/src/libs/cocos2d/TMXXMLParser.js index 6f4b7e0..c64e4f7 100644 --- a/src/libs/cocos2d/TMXXMLParser.js +++ b/src/libs/cocos2d/TMXXMLParser.js @@ -1,4 +1,4 @@ -/*globals module exports resource require BObject BArray DOMParser*/ +/*globals module exports resource require BObject BArray DOMParser console*/ /*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; @@ -89,36 +89,51 @@ var TMXObjectGroup = BObject.extend(/** @lends cocos.TMXObjectGroup# */{ }, /** - * return the value for the specific property name + * Get the value for the specific property name * * @opt {String} name Property name * @returns {String} Property value */ - propertyNamed: function(opts) { - var propertyName = opts.name + getProperty: function (opts) { + var propertyName = opts.name; return this.properties[propertyName]; }, /** - * Return the object for the specific object name. It will return the 1st + * @deprected Since v0.2. You should now use cocos.TMXObjectGroup#getProperty + */ + propertyNamed: function (opts) { + console.warn('TMXObjectGroup#propertyNamed is deprected. Use TMXTiledMap#getProperty instread'); + return this.getProperty(opts); + }, + + /** + * Get the object for the specific object name. It will return the 1st * object found on the array for the given name. * * @opt {String} name Object name * @returns {Object} Object */ - objectNamed: function(opts) { + getObject: function (opts) { var objectName = opts.name; var object = null; - this.objects.forEach(function(item) { - - if(item.name == objectName) { + this.objects.forEach(function (item) { + if (item.name == objectName) { object = item; } }); - if(object != null) { + if (object !== null) { return object; } + }, + + /** + * @deprected Since v0.2. You should now use cocos.TMXObjectGroup#getProperty + */ + objectNamed: function (opts) { + console.warn('TMXObjectGroup#objectNamed is deprected. Use TMXObjectGroup#getObject instread'); + return this.getObject(opts); } }); @@ -180,7 +195,7 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ // PARSE var tilesets = map.getElementsByTagName('tileset'); - var i, len, s; + var i, j, len, jen, s; for (i = 0, len = tilesets.length; i < len; i++) { var t = tilesets[i]; @@ -247,7 +262,7 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ // nodes up into multiple nodes. So, we'll stitch them back // together. var nodeValue = ''; - for (var j = 0, jen = data.childNodes.length; j < jen; j++) { + for (j = 0, jen = data.childNodes.length; j < jen; j++) { nodeValue += data.childNodes[j].nodeValue; } @@ -282,11 +297,12 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ objectGroup.set('name', g.getAttribute('name')); var properties = g.querySelectorAll('objectgroup > properties property'), - propertiesValue = {}; + propertiesValue = {}, + property; - for(j = 0; j < properties.length; j++) { - var property = properties[j]; - if(property.getAttribute('name')) { + for (j = 0; j < properties.length; j++) { + property = properties[j]; + if (property.getAttribute('name')) { propertiesValue[property.getAttribute('name')] = property.getAttribute('value'); } } @@ -296,7 +312,7 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ var objectsArray = [], objects = g.querySelectorAll('object'); - for(j = 0; j < objects.length; j++) { + for (j = 0; j < objects.length; j++) { var object = objects[j]; var objectValue = { x : parseInt(object.getAttribute('x'), 10), @@ -304,16 +320,16 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ width : parseInt(object.getAttribute('width'), 10), height : parseInt(object.getAttribute('height'), 10) }; - if(object.getAttribute('name')) { + if (object.getAttribute('name')) { objectValue.name = object.getAttribute('name'); } - if(object.getAttribute('type')) { + if (object.getAttribute('type')) { objectValue.name = object.getAttribute('type'); } properties = object.querySelectorAll('property'); - for(var k = 0; k < properties.length; k++) { + for (var k = 0; k < properties.length; k++) { property = properties[k]; - if(property.getAttribute('name')) { + if (property.getAttribute('name')) { objectValue[property.getAttribute('name')] = property.getAttribute('value'); } } @@ -329,4 +345,4 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ exports.TMXMapInfo = TMXMapInfo; exports.TMXLayerInfo = TMXLayerInfo; exports.TMXTilesetInfo = TMXTilesetInfo; -exports.TMXObjectGroup = TMXObjectGroup; \ No newline at end of file +exports.TMXObjectGroup = TMXObjectGroup; diff --git a/src/libs/cocos2d/nodes/TMXLayer.js b/src/libs/cocos2d/nodes/TMXLayer.js index 694dfcb..f81847b 100644 --- a/src/libs/cocos2d/nodes/TMXLayer.js +++ b/src/libs/cocos2d/nodes/TMXLayer.js @@ -47,7 +47,7 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ TMXLayer.superclass.init.call(this, {file: tex}); - this.set('anchorPoint', ccp(0, 0)); + this.set('anchorPoint', ccp(0, 0)); this.layerName = layerInfo.get('name'); this.layerSize = layerInfo.get('layerSize'); diff --git a/src/libs/cocos2d/nodes/TMXTiledMap.js b/src/libs/cocos2d/nodes/TMXTiledMap.js index 99e3138..4395613 100644 --- a/src/libs/cocos2d/nodes/TMXTiledMap.js +++ b/src/libs/cocos2d/nodes/TMXTiledMap.js @@ -1,4 +1,4 @@ -/*globals module exports resource require BObject BArray*/ +/*globals module exports resource require BObject BArray console*/ /*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; @@ -102,19 +102,26 @@ var TMXTiledMap = Node.extend(/** @lends cocos.nodes.TMXTiledMap# */{ * @opt {String} name The object group name * @returns {cocos.TMXObjectGroup} The object group */ - objectGroupNamed: function(opts) { + getObjectGroup: function (opts) { var objectGroupName = opts.name, objectGroup = null; - this.objectGroups.forEach(function(item) { - - if(item.name == objectGroupName) { + this.objectGroups.forEach(function (item) { + if (item.name == objectGroupName) { objectGroup = item; } }); - if(objectGroup != null) { + if (objectGroup !== null) { return objectGroup; } + }, + + /** + * @deprected Since v0.2. You should now use cocos.TMXTiledMap#getObjectGroup. + */ + objectGroupNamed: function (opts) { + console.warn('TMXTiledMap#objectGroupNamed is deprected. Use TMXTiledMap#getObjectGroup instread'); + return this.getObjectGroup(opts); } }); From 89edc21b018926c94b09dc69ad8c16c68f0742a0 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 19 Feb 2011 15:50:06 +1300 Subject: [PATCH 090/176] Fixed indentation --- src/libs/cocos2d/ActionManager.js | 6 +- src/libs/cocos2d/Director.js | 2 +- src/libs/cocos2d/Scheduler.js | 6 +- src/libs/cocos2d/TMXOrientation.js | 6 +- src/libs/cocos2d/Texture2D.js | 52 +++++------ src/libs/cocos2d/TextureAtlas.js | 74 ++++++++-------- src/libs/cocos2d/nodes/BatchNode.js | 18 ++-- src/libs/cocos2d/nodes/Menu.js | 52 +++++------ src/libs/cocos2d/nodes/MenuItem.js | 132 ++++++++++++++-------------- 9 files changed, 174 insertions(+), 174 deletions(-) diff --git a/src/libs/cocos2d/ActionManager.js b/src/libs/cocos2d/ActionManager.js index e924655..1318517 100644 --- a/src/libs/cocos2d/ActionManager.js +++ b/src/libs/cocos2d/ActionManager.js @@ -159,9 +159,9 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ pauseTarget: function (target) { }, - resumeTarget: function (target) { - // TODO - } + resumeTarget: function (target) { + // TODO + } }); util.extend(ActionManager, /** @lends cocos.ActionManager */{ diff --git a/src/libs/cocos2d/Director.js b/src/libs/cocos2d/Director.js index c36c016..b1b77df 100644 --- a/src/libs/cocos2d/Director.js +++ b/src/libs/cocos2d/Director.js @@ -333,7 +333,7 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ this._fpsLabel.set('string', 'FPS: ' + (Math.round(frameRate * 100) / 100).toString()); } - + var s = this.get('winSize'); this._fpsLabel.set('position', ccp(10, s.height - 10)); diff --git a/src/libs/cocos2d/Scheduler.js b/src/libs/cocos2d/Scheduler.js index bc0d008..5c45c97 100644 --- a/src/libs/cocos2d/Scheduler.js +++ b/src/libs/cocos2d/Scheduler.js @@ -187,7 +187,7 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ } } - }, + }, unscheduleAllSelectorsForTarget: function (target) { }, @@ -204,7 +204,7 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ } }, - resumeTarget: function (target) { + resumeTarget: function (target) { var element = this.hashForMethods[target.get('id')]; if (element) { element.paused = false; @@ -215,7 +215,7 @@ var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ if (elementUpdate) { elementUpdate.paused = false; } - } + } }); util.extend(Scheduler, /** @lends cocos.Scheduler */{ diff --git a/src/libs/cocos2d/TMXOrientation.js b/src/libs/cocos2d/TMXOrientation.js index 523a7b4..347b85a 100644 --- a/src/libs/cocos2d/TMXOrientation.js +++ b/src/libs/cocos2d/TMXOrientation.js @@ -11,19 +11,19 @@ var TMXOrientation = /** @lends cocos.TMXOrientation */{ * Orthogonal orientation * @constant */ - TMXOrientationOrtho: 1, + TMXOrientationOrtho: 1, /** * Hexagonal orientation * @constant */ - TMXOrientationHex: 2, + TMXOrientationHex: 2, /** * Isometric orientation * @constant */ - TMXOrientationIso: 3 + TMXOrientationIso: 3 }; module.exports = TMXOrientation; diff --git a/src/libs/cocos2d/Texture2D.js b/src/libs/cocos2d/Texture2D.js index 22c83a9..92716df 100644 --- a/src/libs/cocos2d/Texture2D.js +++ b/src/libs/cocos2d/Texture2D.js @@ -5,8 +5,8 @@ var util = require('util'); var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ - imgElement: null, - size: null, + imgElement: null, + size: null, name: null, /** @@ -17,34 +17,34 @@ var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ * @opt {String} [file] The file path of the image to use as a texture * @opt {Texture2D|HTMLImageElement} [data] Image data to read from */ - init: function (opts) { - var file = opts.file, - data = opts.data, - texture = opts.texture; + init: function (opts) { + var file = opts.file, + data = opts.data, + texture = opts.texture; - if (file) { + if (file) { this.name = file; - data = resource(file); - } else if (texture) { + data = resource(file); + } else if (texture) { this.name = texture.get('name'); - data = texture.get('imgElement'); - } + data = texture.get('imgElement'); + } - this.size = {width: 0, height: 0}; + this.size = {width: 0, height: 0}; - this.set('imgElement', data); - this.set('size', {width: this.imgElement.width, height: this.imgElement.height}); - }, + this.set('imgElement', data); + this.set('size', {width: this.imgElement.width, height: this.imgElement.height}); + }, - drawAtPoint: function (ctx, point) { - ctx.drawImage(this.imgElement, point.x, point.y); - }, - drawInRect: function (ctx, rect) { - ctx.drawImage(this.imgElement, - rect.origin.x, rect.origin.y, - rect.size.width, rect.size.height - ); - }, + drawAtPoint: function (ctx, point) { + ctx.drawImage(this.imgElement, point.x, point.y); + }, + drawInRect: function (ctx, rect) { + ctx.drawImage(this.imgElement, + rect.origin.x, rect.origin.y, + rect.size.width, rect.size.height + ); + }, /** * @getter data @@ -52,14 +52,14 @@ var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ */ get_data: function () { return this.imgElement ? this.imgElement.src : null; - }, + }, /** * @getter contentSize * @type {geometry.Size} Size of the texture */ get_contentSize: function () { - return this.size; + return this.size; } }); diff --git a/src/libs/cocos2d/TextureAtlas.js b/src/libs/cocos2d/TextureAtlas.js index 3b17d50..3a53b13 100644 --- a/src/libs/cocos2d/TextureAtlas.js +++ b/src/libs/cocos2d/TextureAtlas.js @@ -3,20 +3,20 @@ "use strict"; var util = require('util'), - Texture2D = require('./Texture2D').Texture2D; + Texture2D = require('./Texture2D').Texture2D; /* QUAD STRUCTURE quad = { - drawRect: , // Where the quad is drawn to - textureRect: // The slice of the texture to draw in drawRect + drawRect: , // Where the quad is drawn to + textureRect: // The slice of the texture to draw in drawRect } */ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ - quads: null, - imgElement: null, - texture: null, + quads: null, + imgElement: null, + texture: null, /** * A single texture that can represent lots of smaller images @@ -29,48 +29,48 @@ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ * @opt {Texture2D|HTMLImageElement} [data] Image data to read from * @opt {CanvasElement} [canvas] A canvas to use as a texture */ - init: function (opts) { - var file = opts.file, - data = opts.data, - texture = opts.texture, - canvas = opts.canvas; + init: function (opts) { + var file = opts.file, + data = opts.data, + texture = opts.texture, + canvas = opts.canvas; if (canvas) { // If we've been given a canvas element then we'll use that for our image this.imgElement = canvas; } else { texture = Texture2D.create({texture: texture, file: file, data: data}); - this.set('texture', texture); - this.imgElement = texture.get('imgElement'); + this.set('texture', texture); + this.imgElement = texture.get('imgElement'); } - this.quads = []; - }, + this.quads = []; + }, - insertQuad: function (opts) { - var quad = opts.quad, - index = opts.index || 0; + insertQuad: function (opts) { + var quad = opts.quad, + index = opts.index || 0; - this.quads.splice(index, 0, quad); - }, - removeQuad: function (opts) { - var index = opts.index; + this.quads.splice(index, 0, quad); + }, + removeQuad: function (opts) { + var index = opts.index; - this.quads.splice(index, 1); - }, + this.quads.splice(index, 1); + }, - drawQuads: function (ctx) { - util.each(this.quads, util.callback(this, function (quad) { + drawQuads: function (ctx) { + util.each(this.quads, util.callback(this, function (quad) { if (!quad) { return; } - this.drawQuad(ctx, quad); - })); - }, + this.drawQuad(ctx, quad); + })); + }, - drawQuad: function (ctx, quad) { + drawQuad: function (ctx, quad) { var sx = quad.textureRect.origin.x, sy = quad.textureRect.origin.y, sw = quad.textureRect.size.width, @@ -104,14 +104,14 @@ var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ ctx.scale(scaleX, scaleY); var img = this.get('imgElement'); - ctx.drawImage(img, - sx, sy, // Draw slice from x,y - sw, sh, // Draw slice size - dx, dy, // Draw at 0, 0 - dw, dh // Draw size - ); + ctx.drawImage(img, + sx, sy, // Draw slice from x,y + sw, sh, // Draw slice size + dx, dy, // Draw at 0, 0 + dw, dh // Draw size + ); ctx.scale(1, 1); - } + } }); exports.TextureAtlas = TextureAtlas; diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index 08345d8..d202afe 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -8,7 +8,7 @@ var util = require('util'), ccp = geo.ccp, TextureAtlas = require('../TextureAtlas').TextureAtlas, RenderTexture = require('./RenderTexture').RenderTexture, - Node = require('./Node').Node; + Node = require('./Node').Node; var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ partialDraw: false, @@ -41,20 +41,20 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ * @opt {geometry.Size} size The size of the in-memory canvas used for drawing to * @opt {Boolean} [partialDraw=false] Draw only the area visible on screen. Small maps may be slower in some browsers if this is true. */ - init: function (opts) { - BatchNode.superclass.init.call(this, opts); + init: function (opts) { + BatchNode.superclass.init.call(this, opts); var size = opts.size || geo.sizeMake(1, 1); this.set('partialDraw', opts.partialDraw); evt.addListener(this, 'contentsize_changed', util.callback(this, this._resizeCanvas)); - this._dirtyRects = []; + this._dirtyRects = []; this.set('contentRect', geo.rectMake(0, 0, size.width, size.height)); this.renderTexture = RenderTexture.create(size); this.renderTexture.sprite.set('isRelativeAnchorPoint', false); this.addChild({child: this.renderTexture}); - }, + }, addChild: function (opts) { BatchNode.superclass.addChild.call(this, opts); @@ -185,9 +185,9 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ this.renderTexture.visit(context); context.restore(); - }, + }, - draw: function (ctx) { + draw: function (ctx) { }, onEnter: function () { @@ -232,8 +232,8 @@ var SpriteBatchNode = BatchNode.extend(/** @lends cocos.nodes.SpriteBatchNode# * * @type cocos.Texture2D */ get_texture: function () { - return this.textureAtlas ? this.textureAtlas.texture : null; - } + return this.textureAtlas ? this.textureAtlas.texture : null; + } }); diff --git a/src/libs/cocos2d/nodes/Menu.js b/src/libs/cocos2d/nodes/Menu.js index 93f44b6..bfc4be0 100644 --- a/src/libs/cocos2d/nodes/Menu.js +++ b/src/libs/cocos2d/nodes/Menu.js @@ -15,14 +15,14 @@ var kMenuStateWaiting = 0; /** @private * @constant */ var kMenuStateTrackingTouch = 1; - + var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ - mouseDelegatePriority: (-Number.MAX_VALUE + 1), - state: kMenuStateWaiting, - selectedItem: null, - opacuty: 255, - color: null, + mouseDelegatePriority: (-Number.MAX_VALUE + 1), + state: kMenuStateWaiting, + selectedItem: null, + opacuty: 255, + color: null, /** * A fullscreen node used to render a selection of menu options @@ -33,36 +33,36 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ * * @opt {cocos.nodes.MenuItem[]} items An array of MenuItems to draw on the menu */ - init: function (opts) { - Menu.superclass.init.call(this, opts); + init: function (opts) { + Menu.superclass.init.call(this, opts); - var items = opts.items; + var items = opts.items; - this.set('isMouseEnabled', true); - + this.set('isMouseEnabled', true); + var s = Director.get('sharedDirector').get('winSize'); - this.set('isRelativeAnchorPoint', false); - this.anchorPoint = ccp(0.5, 0.5); - this.set('contentSize', s); + this.set('isRelativeAnchorPoint', false); + this.anchorPoint = ccp(0.5, 0.5); + this.set('contentSize', s); - this.set('position', ccp(s.width / 2, s.height / 2)); + this.set('position', ccp(s.width / 2, s.height / 2)); - if (items) { - var z = 0; - util.each(items, util.callback(this, function (item) { - this.addChild({child: item, z: z++}); - })); - } + if (items) { + var z = 0; + util.each(items, util.callback(this, function (item) { + this.addChild({child: item, z: z++}); + })); + } - }, + }, - addChild: function (opts) { - if (!opts.child instanceof MenuItem) { - throw "Menu only supports MenuItem objects as children"; - } + addChild: function (opts) { + if (!opts.child instanceof MenuItem) { + throw "Menu only supports MenuItem objects as children"; + } Menu.superclass.addChild.call(this, opts); }, diff --git a/src/libs/cocos2d/nodes/MenuItem.js b/src/libs/cocos2d/nodes/MenuItem.js index 22d2eba..5743c88 100644 --- a/src/libs/cocos2d/nodes/MenuItem.js +++ b/src/libs/cocos2d/nodes/MenuItem.js @@ -9,9 +9,9 @@ var util = require('util'), ccp = require('geometry').ccp; var MenuItem = Node.extend(/** @lends cocos.nodes.MenuItem# */{ - isEnabled: true, - isSelected: false, - callback: null, + isEnabled: true, + isSelected: false, + callback: null, /** * Base class for any buttons or options in a menu @@ -22,39 +22,39 @@ var MenuItem = Node.extend(/** @lends cocos.nodes.MenuItem# */{ * * @opt {Function} callback Function to call when menu item is activated */ - init: function (opts) { - MenuItem.superclass.init.call(this, opts); + init: function (opts) { + MenuItem.superclass.init.call(this, opts); - var callback = opts.callback; + var callback = opts.callback; - this.set('anchorPoint', ccp(0.5, 0.5)); - this.set('callback', callback); - }, + this.set('anchorPoint', ccp(0.5, 0.5)); + this.set('callback', callback); + }, - activate: function () { - if (this.isEnabled && this.callback) { - this.callback(this); - } - }, + activate: function () { + if (this.isEnabled && this.callback) { + this.callback(this); + } + }, /** * @getter rect * @type geometry.Rect */ - get_rect: function () { - return rectMake( - this.position.x - this.contentSize.width * this.anchorPoint.x, - this.position.y - this.contentSize.height * this.anchorPoint.y, - this.contentSize.width, - this.contentSize.height - ); - } + get_rect: function () { + return rectMake( + this.position.x - this.contentSize.width * this.anchorPoint.x, + this.position.y - this.contentSize.height * this.anchorPoint.y, + this.contentSize.width, + this.contentSize.height + ); + } }); var MenuItemSprite = MenuItem.extend(/** @lends cocos.nodes.MenuItemSprite# */{ - normalImage: null, - selectedImage: null, - disabledImage: null, + normalImage: null, + selectedImage: null, + disabledImage: null, /** * A menu item that accepts any cocos.nodes.Node @@ -67,35 +67,35 @@ var MenuItemSprite = MenuItem.extend(/** @lends cocos.nodes.MenuItemSprite# */{ * @opt {cocos.nodes.Node} selectedImage Node to draw when menu item is selected * @opt {cocos.nodes.Node} disabledImage Node to draw when menu item is disabled */ - init: function (opts) { - MenuItemSprite.superclass.init.call(this, opts); - - var normalImage = opts.normalImage, - selectedImage = opts.selectedImage, - disabledImage = opts.disabledImage; - - this.set('normalImage', normalImage); - this.set('selectedImage', selectedImage); - this.set('disabledImage', disabledImage); - - this.set('contentSize', normalImage.get('contentSize')); - }, - - draw: function (ctx) { - if (this.isEnabled) { - if (this.isSelected) { - this.selectedImage.draw(ctx); - } else { - this.normalImage.draw(ctx); - } - } else { - if (this.disabledImage) { - this.disabledImage.draw(ctx); - } else { - this.normalImage.draw(ctx); - } - } - } + init: function (opts) { + MenuItemSprite.superclass.init.call(this, opts); + + var normalImage = opts.normalImage, + selectedImage = opts.selectedImage, + disabledImage = opts.disabledImage; + + this.set('normalImage', normalImage); + this.set('selectedImage', selectedImage); + this.set('disabledImage', disabledImage); + + this.set('contentSize', normalImage.get('contentSize')); + }, + + draw: function (ctx) { + if (this.isEnabled) { + if (this.isSelected) { + this.selectedImage.draw(ctx); + } else { + this.normalImage.draw(ctx); + } + } else { + if (this.disabledImage) { + this.disabledImage.draw(ctx); + } else { + this.normalImage.draw(ctx); + } + } + } }); var MenuItemImage = MenuItemSprite.extend(/** @lends cocos.nodes.MenuItemImage# */{ @@ -111,21 +111,21 @@ var MenuItemImage = MenuItemSprite.extend(/** @lends cocos.nodes.MenuItemImage# * @opt {String} selectedImage Image file to draw when menu item is selected * @opt {String} disabledImage Image file to draw when menu item is disabled */ - init: function (opts) { - var normalI = opts.normalImage, - selectedI = opts.selectedImage, - disabledI = opts.disabledImage, - callback = opts.callback; + init: function (opts) { + var normalI = opts.normalImage, + selectedI = opts.selectedImage, + disabledI = opts.disabledImage, + callback = opts.callback; - var normalImage = Sprite.create({file: normalI}), - selectedImage = Sprite.create({file: selectedI}), - disabledImage = null; + var normalImage = Sprite.create({file: normalI}), + selectedImage = Sprite.create({file: selectedI}), + disabledImage = null; - if (disabledI) { - disabledImage = Sprite.create({file: disabledI}); - } + if (disabledI) { + disabledImage = Sprite.create({file: disabledI}); + } - return MenuItemImage.superclass.init.call(this, {normalImage: normalImage, selectedImage: selectedImage, disabledImage: disabledImage, callback: callback}); + return MenuItemImage.superclass.init.call(this, {normalImage: normalImage, selectedImage: selectedImage, disabledImage: disabledImage, callback: callback}); } }); From 2df437366b12ac3bed09618f8475fd240af05c24 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 19 Feb 2011 16:22:00 +1300 Subject: [PATCH 091/176] Added test for TMX orthographic object groups --- tests/src/cocos2d/TileMapTest.js | 65 ++++++++++++++++++- .../resources/TileMaps/ortho-objects.tmx | 21 ++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests/src/cocos2d/resources/TileMaps/ortho-objects.tmx diff --git a/tests/src/cocos2d/TileMapTest.js b/tests/src/cocos2d/TileMapTest.js index 2fe0fea..d93ef89 100644 --- a/tests/src/cocos2d/TileMapTest.js +++ b/tests/src/cocos2d/TileMapTest.js @@ -1,4 +1,4 @@ -/*globals module exports resource require*/ +/*globals module exports resource require FLIP_Y_AXIS console*/ /*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ "use strict"; @@ -13,6 +13,7 @@ var util = require('util'), var sceneIdx = -1; var transitions = [ "TMXOrthoTest2", + "TMXOrthoObjectsTest", "TMXIsoTest" ]; @@ -156,6 +157,68 @@ tests.TMXIsoTest = TileDemo.extend({ } }); +tests.TMXOrthoObjectsTest = TileDemo.extend({ + title: 'TMX Ortho object test', + subtitle: 'You should see a white box around the 3 platforms', + + init: function () { + tests.TMXOrthoObjectsTest.superclass.init.call(this); + + var map = nodes.TMXTiledMap.create({file: module.dirname + "/resources/TileMaps/ortho-objects.tmx"}); + this.addChild({child: map, z: -1, tag: kTagTileMap}); + + var s = map.get('contentSize'); + + console.log("ContentSize: %f, %f", s.width, s.height); + console.log("----> Iterating over all the group objects"); + + var group = map.getObjectGroup({name: 'Object Group 1'}), + objs = group.get('objects'); + for (var i = 0, len = objs.length; i < len; i++) { + var obj = objs[i]; + console.log("Object: ", obj); + } + + console.log("----> Fetching 1 object by name"); + var platform = group.getObject({name: "platform"}); + console.log("platform: ", platform); + }, + + draw: function (ctx) { + var map = this.getChild({tag: kTagTileMap}), + group = map.getObjectGroup({name: 'Object Group 1'}), + objs = group.get('objects'); + + ctx.save(); + ctx.strokeStyle = '#fff'; + ctx.lineWidth = 3; + ctx.beginPath(); + + if (FLIP_Y_AXIS) { + ctx.scale(1, -1); + ctx.translate(0, -1024); + } + + for (var i = 0, len = objs.length; i < len; i++) { + var obj = objs[i]; + + var x = obj.x, + y = obj.y, + width = obj.width, + height = obj.height; + + ctx.moveTo(x, y); + ctx.lineTo(x + width, y); + ctx.lineTo(x + width, y + height); + ctx.lineTo(x, y + height); + ctx.lineTo(x, y); + } + ctx.closePath(); + ctx.stroke(); + ctx.restore(); + } +}); + // Initialise test var director = cocos.Director.get('sharedDirector'); diff --git a/tests/src/cocos2d/resources/TileMaps/ortho-objects.tmx b/tests/src/cocos2d/resources/TileMaps/ortho-objects.tmx new file mode 100644 index 0000000..17fec3d --- /dev/null +++ b/tests/src/cocos2d/resources/TileMaps/ortho-objects.tmx @@ -0,0 +1,21 @@ + + + + + + + + + H4sIAAAAAAAAA+3DsQkAIAwAsAriY/7/k6NQXBx00AQSAQAA8Iea3tZTprb4mrLxhAFhdCAKABAAAA== + + + + + + + + + + + + From 5cab7e842b72f723419190e6d8811ed63e798b42 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 20 Feb 2011 13:52:32 +1300 Subject: [PATCH 092/176] Allowed adding multiple event listeners in a single call --- src/events.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/events.js b/src/events.js index 6ec63f2..ea7a6dd 100644 --- a/src/events.js +++ b/src/events.js @@ -78,13 +78,21 @@ events.EventListener = function (source, eventName, handler) { * Register an event listener * * @param {Object} source Object to listen to for an event - * @param {String} eventName Name of the event to listen for + * @param {String|Stringp[} eventName Name or Array of names of the event(s) to listen for * @param {Function} handler Callback to fire when the event triggers * - * @returns {events.EventListener} The event listener. Pass to removeListener to destroy it. + * @returns {events.EventListener|events.EventListener[]} The event listener(s). Pass to removeListener to destroy it. */ events.addListener = function (source, eventName, handler) { - return new events.EventListener(source, eventName, handler); + if (eventName instanceof Array) { + var listeners = []; + for (var i = 0, len = eventName.length; i < len; i++) { + listeners.push(new events.EventListener(source, eventName[i], handler)); + } + return listeners; + } else { + return new events.EventListener(source, eventName, handler); + } }; /** From 0057340c2ea93c52f7232c6ca7b39b5356aeb3c7 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 20 Feb 2011 13:52:52 +1300 Subject: [PATCH 093/176] Added *_before_changed event --- src/global.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/global.js b/src/global.js index 5c84e76..419bc61 100644 --- a/src/global.js +++ b/src/global.js @@ -100,9 +100,14 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ set: function (key, value) { var accessor = getAccessors(this)[key], oldVal = this.get(key); + + + this.triggerBeforeChanged(key, oldVal); + if (accessor) { accessor.target.set(accessor.key, value); } else { + if (this['set_' + key]) { this['set_' + key](value); } else { @@ -147,6 +152,13 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ } }, + /** + * @private + */ + triggerBeforeChanged: function (key, oldVal) { + events.trigger(this, key.toLowerCase() + '_before_changed', oldVal); + }, + /** * @private */ From 034bb6b369c4811f5c802a7f09db7efdc3e75b96 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 20 Feb 2011 13:53:08 +1300 Subject: [PATCH 094/176] Added MoveTo and MoveBy actions --- src/libs/cocos2d/actions/ActionInterval.js | 70 +++++++++++++++++++++- src/libs/cocos2d/nodes/BatchNode.js | 12 ++-- 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index f55f566..b2e79c0 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -4,7 +4,8 @@ var util = require('util'), act = require('./Action'), - ccp = require('geometry').ccp; + geo = require('geometry'), + ccp = geo.ccp; var ActionInterval = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionInterval# */{ /** @@ -214,7 +215,7 @@ var RotateTo = ActionInterval.extend(/** @lends cocos.actions.RotateTo# */{ diffAngle: 0, /** - * Rotates a cocos.Node object to a certain angle by modifying its rotation + * @class Rotates a cocos.Node object to a certain angle by modifying its rotation * attribute. The direction will be decided by the shortest angle. * * @memberOf cocos.actions @@ -297,6 +298,65 @@ var RotateBy = RotateTo.extend(/** @lends cocos.actions.RotateBy# */{ } }); +var MoveTo = ActionInterval.extend(/** @lends cocos.actions.MoveTo# */{ + delta: null, + startPosition: null, + endPosition: null, + + /** + * @class Animates moving a cocos.nodes.Node object to a another point. + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.ActionInterval + * + * @opt {Float} duration Number of seconds to run action for + * @opt {geometry.Point} position Destination poisition + */ + init: function (opts) { + MoveTo.superclass.init.call(this, opts); + + this.set('endPosition', util.copy(opts.position)); + }, + + startWithTarget: function (target) { + MoveTo.superclass.startWithTarget.call(this, target); + + this.set('startPosition', util.copy(target.get('position'))); + this.set('delta', geo.ccpSub(this.get('endPosition'), this.get('startPosition'))); + }, + + update: function (t) { + var startPosition = this.get('startPosition'), + delta = this.get('delta'); + this.target.set('position', ccp(startPosition.x + delta.x * t, startPosition.y + delta.y * t)); + } +}); + +var MoveBy = MoveTo.extend(/** @lends cocos.actions.MoveBy# */{ + /** + * Animates moving a cocos.node.Node object by a given number of pixels + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.MoveTo + * + * @opt {Float} duration Number of seconds to run action for + * @opt {geometry.Point} position Number of pixels to move by + */ + init: function (opts) { + MoveBy.superclass.init.call(this, opts); + + this.set('delta', util.copy(opts.position)); + }, + + startWithTarget: function (target) { + var dTmp = this.get('delta'); + MoveBy.superclass.startWithTarget.call(this, target); + this.set('delta', dTmp); + } +}); + var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ @@ -384,6 +444,10 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ this.currentActionEndDuration += currentAction.duration; } } + }, + + copy: function () { + return Sequence.create({actions: this.get('actions')}); } }); @@ -455,5 +519,7 @@ exports.ScaleTo = ScaleTo; exports.ScaleBy = ScaleBy; exports.RotateTo = RotateTo; exports.RotateBy = RotateBy; +exports.MoveTo = MoveTo; +exports.MoveBy = MoveBy; exports.Sequence = Sequence; exports.Animate = Animate; diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index d202afe..de2381c 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -69,10 +69,14 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ // TODO handle texture resize // Watch for changes in child - evt.addListener(child, 'istransformdirty_changed', util.callback(this, function () { - this.addDirtyRegion(child.get('boundingBox')); - })); - evt.addListener(child, 'visible_changed', util.callback(this, function () { + var watchEvents = ['position_before_changed', + 'scalex_before_changed', + 'scaley_before_changed', + 'rotation_before_changed', + 'anchorpoint_before_changed', + 'opacity_before_changed', + 'visible_before_changed']; + evt.addListener(child, watchEvents, util.callback(this, function () { this.addDirtyRegion(child.get('boundingBox')); })); From c980ff61f138d17003fc53641aad49eb3cfc9208 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 20 Feb 2011 13:53:43 +1300 Subject: [PATCH 095/176] Added method TMXTiledMap#getLayer --- src/libs/cocos2d/nodes/TMXTiledMap.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libs/cocos2d/nodes/TMXTiledMap.js b/src/libs/cocos2d/nodes/TMXTiledMap.js index 4395613..152d107 100644 --- a/src/libs/cocos2d/nodes/TMXTiledMap.js +++ b/src/libs/cocos2d/nodes/TMXTiledMap.js @@ -95,6 +95,26 @@ var TMXTiledMap = Node.extend(/** @lends cocos.nodes.TMXTiledMap# */{ //console.log("cocos2d: Warning: TMX Layer '%s' has no tiles", layerInfo.name); return tileset; }, + + /** + * Get a layer + * + * @opt {String} name The name of the layer to get + * @returns {cocos.nodes.TMXLayer} The layer requested + */ + getLayer: function (opts) { + var layerName = opts.name, + layer = null; + + this.get('children').forEach(function (item) { + if (item instanceof TMXLayer && item.layerName == layerName) { + layer = item; + } + }); + if (layer !== null) { + return layer; + } + }, /** * Return the ObjectGroup for the secific group From ce83ec66e04738b61bfec47602dd46b8bd53ccea Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 20 Feb 2011 13:54:06 +1300 Subject: [PATCH 096/176] Added TMXLayer#tileAt method --- src/libs/cocos2d/nodes/TMXLayer.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/libs/cocos2d/nodes/TMXLayer.js b/src/libs/cocos2d/nodes/TMXLayer.js index f81847b..87bddb2 100644 --- a/src/libs/cocos2d/nodes/TMXLayer.js +++ b/src/libs/cocos2d/nodes/TMXLayer.js @@ -159,6 +159,32 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ } }, + /** + * Get the tile at a specifix tile coordinate + * + * @param {geometry.Point} pos Position of tile to get in tile coordinates (not pixels) + * @returns {cocos.nodes.Sprite} The tile + */ + tileAt: function (pos) { + var layerSize = this.get('layerSize'), + tiles = this.get('tiles'); + + if (pos.x < 0 || pos.y < 0 || pos.x >= layerSize.width || pos.y >= layerSize.height) { + throw "TMX Layer: Invalid position"; + } + + var tile, + gid = this.tileGIDAt(pos); + + // if GID is 0 then no tile exists at that point + if (gid) { + var z = pos.x + pos.y * layerSize.width; + tile = this.getChild({tag: z}); + } + + return tile; + }, + tileGID: function (pos) { var tilesPerRow = this.get('layerSize').width, @@ -166,6 +192,10 @@ var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ return this.tiles[tilePos]; }, + tileGIDAt: function (pos) { + return this.tileGID(pos); + }, + removeTile: function (pos) { var gid = this.tileGID(pos); if (gid === 0) { From 14b60ee5c9270840eff94cdd510a4de9e544fcdd Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 22 Feb 2011 17:55:27 +1300 Subject: [PATCH 097/176] Added buffer around dirty regions in BatchNode to account for aliasing artifacts --- src/libs/cocos2d/nodes/BatchNode.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index de2381c..7b32e49 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -92,9 +92,16 @@ var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ }, addDirtyRegion: function (rect) { + // Increase rect slightly to compensate for subpixel artifacts + rect = util.copy(rect); + rect.origin.x -= 2; + rect.origin.y -= 2; + rect.size.width += 4; + rect.size.height += 4; + var region = this.get('dirtyRegion'); if (!region) { - region = util.copy(rect); + region = rect; } else { region = geo.rectUnion(region, rect); } From 43f8ade9139ce9f161d705947d39c7446b8681dc Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 22 Feb 2011 17:55:42 +1300 Subject: [PATCH 098/176] Updated tilemap test --- tests/src/cocos2d/TileMapTest.js | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/src/cocos2d/TileMapTest.js b/tests/src/cocos2d/TileMapTest.js index d93ef89..fb4ba37 100644 --- a/tests/src/cocos2d/TileMapTest.js +++ b/tests/src/cocos2d/TileMapTest.js @@ -12,6 +12,7 @@ var util = require('util'), var sceneIdx = -1; var transitions = [ + "TMXReadWriteTest", "TMXOrthoTest2", "TMXOrthoObjectsTest", "TMXIsoTest" @@ -219,6 +220,46 @@ tests.TMXOrthoObjectsTest = TileDemo.extend({ } }); +tests.TMXReadWriteTest = TileDemo.extend({ + title: 'TMX Read/Write test', + + init: function () { + tests.TMXReadWriteTest.superclass.init.call(this); + + var map = nodes.TMXTiledMap.create({file: module.dirname + "/resources/TileMaps/orthogonal-test2.tmx"}); + this.addChild({child: map, z: 0, tag: kTagTileMap}); + + + var s = map.get('contentSize'); + console.log("ContentSize: %f, %f", s.width, s.height); + + + var layer = map.getLayer({name: "Layer 0"}); + var tile0 = layer.tileAt(ccp(1, 63)), + tile1 = layer.tileAt(ccp(2, 63)), + tile2 = layer.tileAt(ccp(2, 62)); + + + tile0.set('anchorPoint', ccp(0.5, 0.5)); + tile1.set('anchorPoint', ccp(0.5, 0.5)); + tile2.set('anchorPoint', ccp(0.5, 0.5)); + + var move = actions.MoveBy.create({duration: 0.5, position: ccp(0, 160)}), + rotate = actions.RotateBy.create({duration: 2.0, angle: 360}), + scale = actions.ScaleBy.create({duration: 2.0, scale: 5}); + + + var seq0 = actions.Sequence.create({actions: [move, rotate, scale]}), /*, scale, opacity, fadein, scaleback, finish, nil];*/ + seq1 = seq0.copy(), + seq2 = seq0.copy(); + + tile0.runAction(seq0); + tile1.runAction(seq1); + tile2.runAction(seq2); + + } +}); + // Initialise test var director = cocos.Director.get('sharedDirector'); From 64fdcf6130f8277feeaf52cc5dd290f4c9655dfe Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Mar 2011 17:41:43 +1300 Subject: [PATCH 099/176] Fixed incorrect anchor checks in Node#transform --- src/libs/cocos2d/nodes/Node.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index 8da05f5..15204f6 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -374,11 +374,11 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ }, transform: function (context) { // Translate - if (this.isRelativeAnchorPoint && (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels !== 0)) { + if (this.isRelativeAnchorPoint && (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels.y !== 0)) { context.translate(Math.round(-this.anchorPointInPixels.x), Math.round(-this.anchorPointInPixels.y)); } - if (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels !== 0) { + if (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels.y !== 0) { context.translate(Math.round(this.position.x + this.anchorPointInPixels.x), Math.round(this.position.y + this.anchorPointInPixels.y)); } else { context.translate(Math.round(this.position.x), Math.round(this.position.y)); @@ -390,7 +390,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ // Scale context.scale(this.scaleX, this.scaleY); - if (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels !== 0) { + if (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels.y !== 0) { context.translate(Math.round(-this.anchorPointInPixels.x), Math.round(-this.anchorPointInPixels.y)); } }, From b376a9b9f2942e8657a90a1c2a1eab14105541d6 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 6 Mar 2011 17:53:03 +1300 Subject: [PATCH 100/176] Default new projects to 'defer' JavaScript execution --- lib/cocos2d/skeleton/public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cocos2d/skeleton/public/index.html b/lib/cocos2d/skeleton/public/index.html index 2b39fbf..7a41acf 100644 --- a/lib/cocos2d/skeleton/public/index.html +++ b/lib/cocos2d/skeleton/public/index.html @@ -2,7 +2,7 @@ - + $appname$ - - -

        Tests

        -

        Select a test suite to run:

        - -
        -

        -
        -

        -
          -
          test markup, will be hidden
          -
          - - diff --git a/tests/build/resources/__builtin__/libs/cocos2d/resources/progress-bar-empty.png b/tests/build/resources/__builtin__/libs/cocos2d/resources/progress-bar-empty.png deleted file mode 100644 index 27bb5a95a9f92d72a4cf53cb168822385e07f357..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 866 zcmV-o1D*VdP)Q542+T%`R6EI1Sk zfJ4!3xiEb-9hi>BHIOH!4b!^m5j6!U9UarY>7(iVe+=ZA z>6K|EjOoU2reo8o>CE)Qzxze40q!IZOw*=0)4XZP|NoV6&!OqP|NsAKAbM4Kllr}m z%xBXlf209``;A%_FHFzFn0g~`{nh411CjH*3+AE6mR-|c>Ni^epd4s&q;A?w{dPt+ zk=OA_BpQfr`Vd}QzMHm9U#KNOX<0LEnVyE%nV0@>ktV{88^JuzF%JN657W><=iZRqD{9$5w8C`NzfeO& zvn@1C0U*+KZ^%tkdB&^^M9b6j3R87gnW_bV>o`b*85nuSq6{Ri_c*3T08l{mhy@u) zH4L0m9{?yIdPG$QG7|>Qs1E=X5Itf>3(0<`!Iu1oiG3{qa5LIF^V2_fC#VMijEfB9 zGF(qn5&$S5dc>s+q#Xw4s1E=X5Iv$T18IhVdFlfI1w@Z%%0L=nV2SzwKmpMs8Zr14j(=8+ zS)FD12G@sp^d=#Y{m&Q;7yEz+FaR s$=Z>xO|{w=r(TCvr?*D=@gD&O0Jmqh;UCbc+W-In07*qoM6N<$f`)&C;{X5v diff --git a/tests/build/resources/__builtin__/libs/cocos2d/resources/progress-bar-full.png b/tests/build/resources/__builtin__/libs/cocos2d/resources/progress-bar-full.png deleted file mode 100644 index 306f398f42c7a4d6b8e4fdd6b04814d03a1ad8e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1015 zcmVYCdVqg#k zf`db%lYc;Ha0nbOlBpk}twU?jP9-llRA3dz=P$$%D$YawcuA2w0ggjS%B&=>dn5cCMT z;XY^X+B<(4$TR4Hn|a)K=E3hFCR9hDZpB=Px}^v$g)DJeawan4W+Km_hio)jM}Npx zTOxDLJTBX3%`2IQ5Oq(tjrD08`@y_m&OI|~o^fm-Oq#@{S|&{A-OPhCkx9i>h@_ab zu^(4s=FJ;|c|{=_2zQtc+7FzvaJ3~SOvhv%LL_Y>W7a-0Z-}2Y^o&*-2)C!l9j45# z#-&;&Oh*($A(Cdqydao2#1$BNMh^|d@Ap`B?SY`2hY+dLZC-GaM|9CZ+Fi$nYxgO3 zLWnXi@E*}l18H#`+pgWAxCtT3yuf=z3-^Ki4*8M%3n4$(@;zvim=Ge{Y<9`oJUjE# z+DDCwjS!+*Xds8~?`GHDRd|FDWnSPt;*bWi=Q`S4dsA@}LX>%d_lP|j$d>EqbnO+z zO$bru1>PgJXdvsZqt~^0DzB*636V5K^MaE+Vx0!U0;>Dg!FnJCYx79&lHw;s(kzAi zcz?k>BA92a(Lh*zIaV3s!5LN}ip#n@(mSgd3XvqU<^jPxVL0T6>*yIfaT%9;+z+hH zGG^n}=E0d6nTQZcn#WAY56_K-eYK^hKj?C8AyVQ@F4r!H#g|z>mAMgCF=HX3rjTzs6GGG;TpZzvd>*Rh lxj5!JxI2BPl9&GoFaTgi^1Va&t9bwb002ovPDHLkV1mFu)42cu diff --git a/tests/build/resources/cocos2d/resources/TileMaps/fixed-ortho-test2.png b/tests/build/resources/cocos2d/resources/TileMaps/fixed-ortho-test2.png deleted file mode 100644 index 137ddbe796f5349f09d79946ec1e0d16be4648e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32551 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 diff --git a/tests/build/resources/cocos2d/resources/TileMaps/iso-test.png b/tests/build/resources/cocos2d/resources/TileMaps/iso-test.png deleted file mode 100644 index bb6327f47b524b69f2ae7d7e252a277e11a5ae6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8448 zcmeHt_gfQdwDlweLg<2uq7;>41uTGykbnq8x`H55Md|g>YXXSaQBXm;qM#s6>5wKz z5v3~x2q95=35h}yN=WW-?q6`9@7FIp3Cuk6&bzbA+H39MuC2A1q?m#j005F`bCXK| z00sYq0HPw`ug{Nre726lFPRwwRXuy>zyp!%7G@@ZVC$zCSC$2yL4=xL4F>>mxve(@ z$j#pco`grBtuDYvp>o?0r^+*$&I5o7fHpC*j~Qi9F@X*~g|t7tyJhcMYI}5El(?u8 zVCEcs;^X(gJIPn(#B}%n&g|lmh+@0^PW|{MnvcEsmYY%j&`)R7HT%PfRHM>L(<7f# z#oGPR6ZdN_nNfTfa+Kv7vL3h~mfKApp^uGtc&9!^+X$MHqgfb})Z7YZyt{vIi*0s)jbDl_L^3#zVHS&e%|SNT0w)iJCe-k89w zGs#VOh$=wjNo5w8#jBzVLh6u5iw4{1ilrejCphTEj$AtO&u3Q}Qxysz0BtRyo9bEp z_@YhYJ$cW4m#4eGd4F8qT%I=-4#`7IhVRG}4XqS{DwQCxqd#&--aoXmXe;uO!=`Jl z!iADvjuRM_fiE0R77X_mj~9?VjNp5ubd-!-932^Q`GTIdv^0m;^xB-$(=%@l64@!0RSlfVWI2J z=@Ss^^@X#re11}-62neC%kEf)$iJ1pGsO5LC5%%waz0jWh3Cp|6q-i&LSmd!G2kTu z-XDj8Mqe}z&{QF5hXIi)svS2^-#@HG#WAz-5^{Ktv^XCf&$GLG-pL_3mP-7Ba^V8U zg#mjjdzOvt>cf}eiS=X62Zt$A;{337URnwgJDCFo$|sE*Xk>~_0DV+365nsgY(Pjo z|Fgq+)BWIT{CTPDIIk?oHvl3F6syO5<#6yq!x zPdYc2@enb_O13Kcj)HLL73O{fU=CnM#rdUBmCnPMJOuBUq&S0-jN6vBrog*jxt1aJ zR~-S!JY3T*{zM`y``S#-3yeF7UndjmPaR#M8b(z021?jl6wS4rK;@mmX?1@^Ingun zmI(=KAFeRZ{)#sMzmO?_Ek9l%c&3f0F@spLxCJ|h@n%AKQ5Q!&qu}qOu;FibS!9snzbUa! zeHkq_Eav$a-5-vK`yX0OSA(X#ACKH$U8cN~)gH(9M5A8bg2qg0nx2B#;ygwS&OITw z+Q_Y@qEj6doa9ItO_FY43`TQ#J=qVa!T{KNaI|A)d{V^dvHInbA64by&czjD2<$i+ ztd8d9)8pQRvU`~3>^K~kGqhl})T1N0{Oi<(;>BS&@YVy{b>qbRxzVh0o|a_zjZhsa z#Nmj)g$66kmMRxLE+;NN9!FVZK9StLe0rl6U8aCF+Yta@#bB7r93N|*#dZ2i7mj~n%@+Y**r5^);&TE~ISJ_%Y=p8?;x-rMm zSVuqG63~UQq&RYwYiwt-A}1uS#?EtSryWbcyVCB10-vxrcJ4gjJ_4+Z!-4p-@y>v<_g#Qj{L zh?>XMn7;h;?sK3hOdAT=Yy2{-UE_|aibJj`?DW6!7jLT0TCC;kmd!E8@K5=8;q!G3HV9P-d|oLrXWzH{%Hn(ifW+q=Cj z0o zh0bPha>Aiw{u-NU)0?SA=K`Oq1oM$cSK(&r1BFLLL3@j5>BwtY)k9t0m6W<4;=HI3 z!$2owWsR87$AdM-aFJ$x@~N21K)9l?xxTE-UXC<}U)hYQN(7MzwU$ai@YGM|F*!*B z^+Poo8&(Kz^=+c9 zA;XDc4hZ}5!^I&nm%;)dvciJznJExlqvMAKK4qYKo5!lMik!&dvtoU*bsB?GSW;nP zjzUJa#|@Q^C?1v480{O$m4Fav~612Y6?5T_ED;n@7Q5a ze?H2)FUo%=5%Wk@Pu^F94JP@xIV!g#hT72ZbsI2a@*xqHLMl=OAV?`8=(oKxA4lHb z?qNHuT&PGmRpaGGUg0xzAn&+t&o9m1|Z~vGT}>Z@a2& z`A z8_g28fQbo5AHtA|Mnq2g&i{VV#rD*2+x; zew7O=wQ%1eAfrzX5q-N#r;-gg&u#!zrq7T92Vr{hnR3Fk%vJ@c+^ot`hr zA8L03#S$_HubwFA_NE%&Ust0S* z9F=RsWd8f|Yq9%MFRpP%s7rB%^QxmIOIlM@BKZ7XU16dEfRzSp2k1z$Tih1L%ZlMl zYi@;tHO;B?d;i6Unhk@cRB6$(%el(WWng;y#L$LK{A3t_3QMlq-ny|vY%FIH5;CEwk=;s&f72As%8n~?{`xM zX{7C_iOSpfnEjEm9?C11@4@yTUCoXOpx2Seky>p3xqx&v^baP(hG)$2`c#;$3V=)e z)sJiE3146c+nOKBkS$bP*P5y?&M98d^y4L33CgwPe+qnkUa5M3ixV@NPyWFe7v=r$ z!u=561%f7eyq4H-iOXVOmB(JxNG$V%#||agkvMr4*{y`l?p8is$sDTbj$e#7)L-3W zle7@O-Z2+eW`ahr%vVLM0DJY-BISai=g;GU{N6cQv>PX$U3+6#z#9zQ z$o32I+86K;TXARZUbDFzuNq&36d*S%3`1g&RWl(QjF9m`y=+bCjmFc{5u~O>7}ji? z4+Kz?TJh8aX={)8(z7br8foQurNX|SpHF)834vwM(m79zA;0{AA8wdC%=o0BbS1131duQTYPi2IAng_s;2r4O1a~`0g$gk>Gftt=#D83b z_RmmK1E7m(SoInTZtdpx>^YhseM}TJOzR5jC44yIB>ca5|Mw9z$AKMxt;m`OGt(Ti zj`%lZl&+lpz=^`Y^82IvL4-B}%b%_uWy5J}LbSw1H$GWlW75WMoyq;cZ5h= zIrvSM-X%>sl&pFHijH3l%gFw_urX0s@nC~rW(|Fy;eO^VVXYzx!*XvJ<8IIj6CDMA z-FYUDCVWRed|}P34RKc}T-u`q#T4WgoapS<*54fYo$_&HUT@Am1*cQ9*`%8B?79u& z{Y6>UH_U(N$ z3=hAkd9&L{y9{{V%0~`fn62$tX{Bvyo>&#kfTrMdfX~Ha(jFiM{A!LGE=8hqU?f$c zOw4!srQjXsz)spi8?&1~jD2MWslwAL{`7XRf8W>gPvC_gbH{gWC^d*+$G1%XX~|-q z8$DUgf!34?m1hE{E23lXvn^%m7oC+3F6+nqHo#Fi&LnyWQW>!&g6vgSeNOCVbGg|J z;cs@jPNZ$vf6*wGhYI@10RV>a2tF+#dN8b5GaZy{5tE-7XOLTxV?5kmd)1=ZDkUX( zBv59Os?<er0x4CKq;Y?VFJSzQ$TGL04X|8RzSRw?Z;kQszRN#McRYMDwwZg?WU!`EQ z5ltY?=dTsvG|+ex?1I97-kQx*1_k3rN?d58p}uH#TrSaCBvAdhDBe4CgHGQlbXA$P zFK0BBLO}7{CdTLJ5|`ibwC;|`lJ42VkH#$Nzf)ojNGIh-Q_Rvi;RZsNu4|w?q(~TA zZ_=*?1LRT78yiOkZrhQNN56JlWsOCzuphdU|LwUAGA-iyLLkRM;3tQ@L|(~u7M7O$ zs|Kjgy7Q)b?_U(#CA=k>4-Z*XVf-v!?O2Tpt-Pte+SKIqK)1`4ei^FmgPrV!`^CYFxFkcTw*Y#%e3>M+%mjf||S+3bowW`VzZ^fr|xzrKRP$ zk>TOh42Q1bfa}6q43z#Yoc!e_jYD;l)wT?b_9_O1YLG{NiYCZ6sslza?C zP!H}^L1uTkglMh=chKWDxcQYwR67$ni??|M0~6o$wLz)gI2Sy?g7Zb}`4g=d^R(->|_VYB3|S%G&kn-UMFz8Y_q?g)2yT* zU2O-+#1quu%;RC5CZRbrrFrRA0$OJABW#g7kUJ9CBLomdiDU8c;-(7`|9t7^oON{9 z>-C*)&pUf&!q>(-ZRdj_bY=s&dH$?nd3Byoo05k)v$voccYV}zygoIn+k1I>!Qz?3 zb_KON&H*xd12tf)q~+rc6g*5tEi+lh?Q)|7mx{P<-N?bAJ1&|5h5ncP7O#c6BNfR z)h8B`v%O9hH4*W(e(3o~C^%wT%>+8aKm}QN;38>Fz!I?o^ee63BDm|s3 zhZh9fr<^-&(g543Z9r@K(D5d>-a;zfb(l%zT?GAH9qp4s!sWTgBBK|BhbC7w#+M87 z!|G;HOTTHyo5q!-s^*lm8LZIyc2I;(5Arn7B8wX@+@f>cHeE8s7QVWhW&T(*ZIz#N z4{|H-(HmuyUXKZj&G^M;1 z^zLCsFbCTH>RCp7JE@n?ibYoiOC-Mc@tL`;_6|(fdR;wh{d4CS^cx?q>XnS0#oA~P zR;F1$o-#mQpAeWkS(0;W-z45zH}7FZ`N0_haw%m7f0^U9Zh>5_eJ4T>RVg+;0F3(w zoosB~a{D99Z}#sl?WL6dv&Wp*nz+QEily}=X}8(N%9e_FJ;DH(2^}B2;yCHO@kn?a zMrYfKZ+d!_Vt$}*gLQwUUO z%%EN)1@v?y9+{)p7|)z`98cT$($|4!MoIVa6TvJS&FbuC4}qcQMu-1mf;qOeHRyfk zh~hI&>Q{PRdW`<+4}@zR-lpvyb>gw=adR&Vi^Tp6>Tun^PuaEFQmC*40D8V51Q$Md zturXjtCZ}cIjY#2r`9PByFG_k>U`e^mQU71QH(+BBWm}k+l+tzw+`IQ>@fAc!HXT^ ztgtupU;NU|S`-uRV%OH+m$}YJ^G!hg1xlyg%$}$eZO7>|_paXZjXM6m;gXa96X8oZ z13k^;sQSQxjF#5{Kqff|w7-JFZ;3TktoTQsd)aY*Wl_3_Tp3+8|FeZz&YyZVdL`Pi zIZ-FX@X&z%<4QL8=T`%$Bc7@TuoHrB5f}IG z8a!$9-Ox(Adx9J^dgvWBiSVotdN6j4HY${UAPZX$m#Sd*?N;okeUt)n7DQ3UBPosJ z&GQTFW4pRtSHMs%EHFmoBbQsRvV(f1$;Q;vAcE!)!6D5NG)S|qa9Oup$b)PBev#5P zAZa%a+9dDTd+4C)A?x`)XUQ|0=QfgXT%>Zm!0;M(CNVK$`K0UVnzSS59-n|5^rJSs zpjBdG-!P3aUb9{yyN1WSHF;Y&0>=4lyiyXJA62Y)T}bdmyfM*8XV+VI z-~V>P-6)Qa`D6jThnOu*&<;#3GVc0fIDH(nYY4n@s-=ozaL(>zfY3dvNDOoCS6g+> z69^z|3VgF`Gynl3Qc-!Z!675`Yt+QObIqynXjlTqfa0FN^_>cKYx-5B(Pig)Q8W;od!C87e)Xk^%?TTTC6C z{V_LlRXsu$eoR@z#H0lOwO1*AfTLl_fotU1JA6Yf&6~4<-0aU<6cc@I4kU!P_A2u6 zASAyBk(p^6pxHLv>RK4NP*8yv4^N_UQXOcfo8OP%#08zZI~>)oRFU<>+xPEG@0Y4e zB~LJw3PTwlyCwKhA>%*SC>?weHP67wg6kksv zY*H02uu1{T5f2x-(u=n0lLs!lv9ezy-B;w-moH#mf>jQJSbd0935cIB!67f6ir6Av zpl`+-@SwVm?Yy%VeM=4Y=1SF?0L(+=>dl3u&1wR_Qq_;`UY)60xi%5tGL;NNU@up; zFuX>N2UUmT#4$QxwZTXCy;sb?>S-`t?9nG3ycPguy*hxIWl#4$u#D~C=2jn&58i+Z zxJk=p3JDmK%u^A+yxfgFcPiu_OG@uy`^~x(fmZzrS`J7dj3oEjOAr6pt&Y$Zj9+B) zEp+^AqNYxc_j-#FRUts8734JMvEQ48hSo1q(*x*UMk;}k_MiieQ@^q2n(%Ki|{1HE&5 ziZ--`T~1L)EA~%`qHp@aD7u6?gtH%|4^Ys_h$SwEpSr}@gyS|U1=EQy zD2tSCuSHd2lAC^~sP%<9aBQBrBmONxEDwCN@Od53>O7t3v{gG9!Aa^t)ZSCTV_gVK zvu%%IXz(I(VHR{3IVf6DxzdRm^=|$Pn7PeLzvhn5jK8!i16$zu=U)B`5J`TI?h7;_ zhVAw7`XS2*N^}P2_=5vA+95C^Z+r+tm8Z9tN`I2Q?P1(EgfTcZ442Yc)O8y>~NiOKnmuW5XP?4;iakyI@3cox&BB|?GYF_?B1RQ++y>W z6cyOhw=1qT2DxEuyg#R6!+d`>NBjPKGU+;NF-X~p-Rry9tAX;CBEN5MObki?YhWFx zO%s66(Q;@1Xq*AQK4p)%ziGn^a3PO@*L$UO#oL2%;r0HJ6p#drr@57N>Q7V^B7KACufpZGLxq!H_#YpsMiwY#HB^Px zx1J#cx5d7R?q34iuGdIyN+jj-M3HZA`3^TK=iL#0OVG)cvB(7bvj)=<1xn(Qs?UtU zo$SC~7{Qq%{ULcf;BnOIxqeC>$6VT<+r7!4!n^kqoQr7EB9l#?JXMnZoHOL|VbNlf z13)eA?TMj>8kH1l=Wh;GZrWfiZCBW)O~|ku@4a@a>CKyQ3mMBAy;k;%jofNy<{x;# zW-41?mw{+?ALvNO8KME(+c1@KxYK;gpXQ+;#|jP0Eo1Itai*ZYdlj|tu~E5Dt782J zXBcAN<24m`{iAjl&kYlm+FGgU_+jwobV6PcS96||M(}JV1XEzrAf>9>^y)D{yQZ6# z#24t?0;4Ua2F-kZM-JZJuvpM5zjtF2{}1x{I;NP&F1w`l6QrCBFiT1*kGRC+uVg;D z86I9Q`JKQRjHJk~Uv}KNuufRNRvE*!`3vn#I1ic^wpbFAdX3Z5fw9)9KBL202N0;f zk3M=$rGX3M-PH*%A(JE1RFn^YNlr2G#nFXLbU diff --git a/tests/build/resources/cocos2d/resources/TileMaps/iso-test.tmx b/tests/build/resources/cocos2d/resources/TileMaps/iso-test.tmx deleted file mode 100644 index d46c585..0000000 --- a/tests/build/resources/cocos2d/resources/TileMaps/iso-test.tmx +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - H4sIAAAAAAAAA+3DwQkAAAwDoYPsv3PH6EfBVVNVVVVVVVVVVVVVVVVVVVVfH73hYN0AQAAA - - - - - H4sIAAAAAAAAA+2Y2Y7DIAxFeeD/v3nEQ6UMYvGW4Gt8pKptAgnXZrFdSpLQqKcHkCTJJ9Tyf73X7js6vc6vdJ+27+3vP0m/5m4DQfubPkLxv+UYR/ssgg0sqN2nvz5rG4Gd5t42ddIuGhRtUWww0kDVFsEGKw1UG6AzswHFv4j6OWPe2QBN/26+c9YC4vrXrOlT+agVWn8h+vsHd+yaM8Er3LHP6k/ISG2APvdX/2d90OP9le8ixjVPqPnsqj8y1Hglao7PiekjrPURXBuUwfX+vmc4a3w3D3bv8GgPie8o9lrVBz3ZQbKfc2o9q3se7CA90yk5PkItSDpGS32n5wJXh1VeyG3zJhw/ScZKPSNOYrWnrWII7fvfRlvref7mxgoe9DcoedCs3+o5s3bUe18iqWFYtPOiv2G1z3PmgId9UArXr9J90ivSWJrzHFS0+RQ6nHwhov4Gcp3Agqi6qET2LRVNLh0BSf0wEpo6QgSeZ9xt2hvRzzgKN2tPkiRJEg1/QULzBABAAAA= - - - diff --git a/tests/build/resources/cocos2d/resources/TileMaps/ortho-objects.tmx b/tests/build/resources/cocos2d/resources/TileMaps/ortho-objects.tmx deleted file mode 100644 index 17fec3d..0000000 --- a/tests/build/resources/cocos2d/resources/TileMaps/ortho-objects.tmx +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - H4sIAAAAAAAAA+3DsQkAIAwAsAriY/7/k6NQXBx00AQSAQAA8Iea3tZTprb4mrLxhAFhdCAKABAAAA== - - - - - - - - - - - - diff --git a/tests/build/resources/cocos2d/resources/TileMaps/ortho-test1.png b/tests/build/resources/cocos2d/resources/TileMaps/ortho-test1.png deleted file mode 100644 index d13ddb0931c1772127b38010990140adce837bc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 421976 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 !G$-kY(Es$pCzIkBCDJ_HRYRGc&H`5 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�pc{D}`1F^gR0H$=%QcP=RWMQDp5Jkp z;;!!tILWfn0+=Q9I6~36&hf^-v;e@8dh9e?iClCeZ)3s}>vX5Yvvv)UTD5OP;n|f# zxPa1jNO-XPFPBAE}$eWGbqDD2jpH?2#H+l}BeOtHi z?UJP(|Ke|Jstlsq`>hS_T-|8@@mft;Sud+pYDXGLx7YRQC$hZ|eKIG&V#PBt!~?~c z-HXAlQKPmGB$Cdxq&B z6^XL~$D*q*Oz-_kEgs#gi0*t%+QU?!)bM@N&<+GBO zH{|WtCj6yn!N&hqZuc8Vb}4nGBgxo--%zM9e&omCVLg%wm)P= zKXSU1D)6EY!N|w>VH>|}o^Hdzxe&ZItVEMuhXSMelU#+TvG-JFGt22hSnv>v4XEUo zKW^*r!`C+^0-=w#WLp_X+4JI#TUd_+Un9<;{^AeMHV{+g8@?!X@9pYnuLNSr5NWC- zr>^{-aX<~ySvv^@>j+2oN|T;dq7cdn0}r)zRgAx_2Hjq0r=Wi+ zr4`>w2gowi48NwD0*4OY)P>@Y+Gn{AZ~vMPLixcMhN#Rd(sTdFBt@cmbXGyjTGeq2&rcD1 z=;-XhQkHqahl%oQZoV>5AUS7$gZBOSo{peTlt0|BKoeM1VEC4dUCAr?`eqt7cE5p~ z<0rA64Sz*2b7WYCIHvSk0qZ(~Rj1Mx*Vm@>VN>o# z5bx|j=-KvFEzTH@6_N)TD#NJ#%-)xAsQEU?b-Ci0sNqevzOq;ob4b2@%)ub}d7#Y} zrsW$36|iKIrpLN6>V+|&FFW^QHpk?)@TCH~rE99hZPbQ+6k`@~uO+m%pSEaid8o(Ml~a8K@-09SfM+Hz;_B1K*;Y4+!OJo&oTm zMFXPG#cGqK?}tO?4_*>;H%gj)q~39^8vO#{gU|s1&;OdT^OmE7LM~;pn?K? zOSEoG!=Q9du_3Vkw^3HKpJl`M&Ztuqt(ifqL2DQlV@M|9Psr{H{0f1CqgDzr^nHZR zaNXx|OyxU8hC@#WXjrBRq%_QYIwKrp4PFk7r(q_U4d^o{l{2ADVx(=z9=v$@r2|b~ z2y;V2VgKH)l}%Qak_Cu41B#a7ZS6RcN|*XxS%TX%l2{9Pz-(Q@F9?$^)iZy#)O;N5bn zR*~(E)Q@b3JVOT=8x&5RMZOK*TRPoP;J;8MuIizmwja6vb$O{e;ljBvEXP@4&9d7% zFN14+g&KSVqPpYU3NxxNWQ`5yp{gm)m=r0tQ1Xa;~{ zeBdNzc{avn^f6{LNc*cxvVKA}9tkeAA~%r*aC%lssOH5&-H(2Yp3X z$PEb#4S%KF4`mnmJ@_aj&~23)mgGgm?1A!d&e}`AaCyJB?s}q8T^qsz4trn~sK575 zo;2bng7^LnuN2*-j4E#GM(8lOEG|lQR&sE{l<;Z?l2Buc5>uNB1pXx?KjPI&Jhx^o08-2gV5wM zEh?usNr*|em$Dzi$!(@8={`9FC0j%r++J$vs_A43$$9&)4OL&*epUrrc+$~CkVR2m ztH{c!1#=_?!lJGWH-a- zxPJ4!>dl6hot>*oEIOf$?;GYID{IHWy3@sY!AI~&nw^~y*V-1ta)!!Gt5-o1Qjeyt z)Q>X2OP3$J0St!k4a=%4lHH*A?EQ-mLwElV^Ogu@Lqa}V9%IYjhh?(k!;?V8yPQ%| zy;$$+Nu60S?`Op_X`-0sz~TK1+9|DS#$X!1*#@ zjFkW?YU~19qc{KQsLx}e^s-X?Dc~zOgoj{yKmF{?bT|}3)8h$AEZjc*a4ZtnA3rvf z_gamEozOg~r|Y^Q8>F!cRF~-Zd=yJ)Ejm(B;6)xNwG9MGT$R&!A;dh0+CHgzKHLq8 zbVP@i7BLGP2qO%(H!#evc8>w~fcDbLw)|gPTXp5nKd9wM==(1lLT)bi!)I`dZp@xl zqB~$OxSLlju989bZ*13*Mu92Lz@d^38H8|-Kaq5MCu$X2!wWIa+mg0RvQgMHK=L{0 z$65TTNy)`Xz*ghbH3{JTYx8Ciraw7&^e-vxRIhO;)hX}tlpad*7{j@Gvct(c(4bAf zT;DU)1;*1wOCOMW(fQNXb?fLeya!rl^u-oGuI%G+plC3kywTxz0=u6xoYkwR>6`IkK^>*LTe#S-j_m+n0RXrIc z{j-mM)E!iH?>`j7rq{aW-`GD1E2%JA!iNhn^KE0Q$`CLg3;Xk)t@+bII7&~hk&5&0 z13zE@iH5=bs2CL>4*cYWTs0frukPY3%!2e5n6voCx`Xe8PFt7D$*+1Q+CZ`)T5@P; zBB>5Qcf3}fxj4KC!-CvqyVU(Du^_J2IP zFD|VQTc7YKVTIxr`_{2zvAjUqHmv+%=|mf&tS!=Z(_Hoxc$*hWcBo6hz@ zL#Q2(n6Ov1+QnRDrTTh}7ff*22^saU#b>dwS z8nx^ppQEQvK)`anxlXN|#WL=tQ>xqx^}=Os;%IIXccNMJ>wD+-uX6+{E)hGLcy^TsewzaLLP4>c6%=iKO8(7B8x)$!)w3lrF90iU!$H5 zWD|jlVbaJGLQhzjpz;QgVd6K1JcCGhu&FhuFarWu^i9fa%+e@-EKI?*!Iu3{BWC7& za_}vbnLIcq>on^~pE@$mUeeXE^I^Sr>^t6pPaaKFwYsaH!pNb8vE5Q(m$xZwxMn=Y z9q$?wjnZEzVkVZ8&N6g`4(-F3=*TM&Q{!SvQ%cb67h0G-0Oub6g5#qm=8{*JKX|&_ zahh~~+b)p@keAv9nq|xG9RInC#yaoQ@u74iX8{J78AzLTrbBm4-I8JIk-zH{TjM3s zD%}g-$!5B7-$X-jk!EFRL|h;~86^Kh6X^eU9C}lQMO*OW$2_bY#u|BxRM}#+X*Wne>clxkwUREFc9)n7ts z9_P(Y7S4EJQLwR;)EkFMKgOp&D!O3ypr^EGvKJBaWkq!Pu4XVgFyo*Wob{-Y(RG2g zIaQ?sy-At3N_&>n*P}<$st-3_B;<(a$AQ0dco#MGveYYQFShsTqH-4qq3Ks1kjDfjIuo z(Rj!8yW@FIF@>IM20BK$j&~=lbUByzrqvI~URo|=T;d12En|Nfgw809HHS4~i|-1S zaBvO*V>iHdKf8(Q7RiUs&|P!m{wnuR};9cSaks^PkkID@l$QwEXh z$)1E9@qhub9AQ6L2IB5aet(3mc;$W(`i{u;36xmi$_B%hxH7891{_#XCR?a|n1Bjb zvG>sOc*VBgXiqD#x2st5y>9fSrqb578JW9#VWz`!+dbj{hvpE>8+IP}m*EqG?PmOo z{I*hz6h<;;B(j(wwq-gA+C^qIx3{TOmKbeM0^c@-1_yeR^SwU&!A92^%jsW{9_u=P zf8-ALiU>rOFW$NV3U(+IC@*J(YUXsh)^l{+m1QYHsMwNV5rQ0b1UH+I!Q`mZKgPD5 z+(zqu&j>pXLMi`4w>bEOx3Bg2r>~MJu1B}={N6!tKwFU51;JuGt8dr1yGcD>Hcg(% zap&8T-2xP}?%9GkKt=U#K^|DQ{g>?NCwVhNbKoEU>pInMySDQiBAOc5RaWqtEM!&C zNDaaSJi#2b+IlHAeWO8!|GV<8d{8>jg*i{;Gx;jQ=##_X%H){s+j?j(phOa$X+;VdpqV8~#E5RCC)b}>Lp0;dV%r`?Fr7|g!7?>uKlQYq{gdB17x z{OI6!aQ}Mb4%@ndsEinBB_KmQZ^Us%^K(~idz5c+AE~>ztOviWKTyn!5?YqaJURWL zfxiFHwy>m5>==a*03SjX7-BkCTcoehRi4~R=ZdALjx$nCA$9E~t7MEPKVdSet+Jck zAbL>*h9n15T%e+^`#trVDy$dKRR<$v*5&KZ85aZ~oyb+65bv>E{Om>#V&u%Tm_vRn)EnFRye7k@YCHPWj zO7Ol%Cz(&v5s~EZzuNlN^YKP7-{ALUG8luv&~NvGmQ;X@*#D2Gw`_4s;0Ik(gOF>a8Y~_5S|04&kT0_({ejJ9As3?huRWiC5+B zH|O~xj5f=|yAkM3dLg2HS_^!tvi)uAh;iW)e&9MekCZR`u&_l1V~pdeC3{*3sB3eG zKUNgat(Y9sCF>J2k?Rx=Hzlr_HeSP^uDk1^aC@Qnm$0&5a~BbqW<+vnB#lzdF2e=0 zHrBDVeKfzg1QK#tf+Rf_Zjo-q0;wdp zK8HL*PUXm5(CFsAQ=)+qp;hthXwkK&k+CCSiC|N#qayT$HR%l#)B_-@?4ZI$jgT^+ z?sS709xHRg3$yS)20T%u3~0~;Mx>y>ZC!^3Sogl|u{~bNcoDcAW4_L8Nm=AGb3mnc%{lQb*??=A6iw2Ut%+4aG(8+I)Q@#=#HUDCN)!h^< z!JXUR9_<-R8Mxp~ zV!7x)|1BNcz2Ei7MQy?behI;p1`cW6@_b5yFotRdP4Ru(M#i8?8APCDFCoT#%?L-t ziU%ckpT3bT`OK*QOX~73tQLuO;+g*Vj8A~ner{c=q(JtCl8#2EIr!$}iJ#`|B4DR) ze0&6LuQJr-&%Jsa+hM=9{L|u*sFXMoEg@A7Ph4E?{A6I5GB7+%=IubN2C;ahrzeJX zQQrr8n%W=dIKcOMgJ~p6X4j@P;8@-AtSDjFv9!^liFaioRtD0=cZw}6ZOB&%Crba^ z#+(`?h=t{Q?iqq^;4ZO27fW$@U@QoE%p%8!YMa`cBi}vuUU*9C+)~{MX<<#$wQr|*H4G>E>Bd?w`{ThiR&gxS0X)?6T|S5Cv~t6!|D=8UXP%(n zw>i6>aGzLB3fRb{c~>sS-3FT&VL*)0_hDC@yMnxWNj6MH;nXCDre zP%ZjKU+Z%x07*3q7d>BXG{2M9VfU&;&kQ|&Ht$re0xMa{f{$H2l@gjG9NTu>q^+)owy;en}c2y{D2Z*dYApZ)nLgx~(;s*rR9$LyQYd4{f zcYP7PQ)f3#Im@VnEm$L*=1((y!^R5UfEt7?DOKF&A8Q1|0={8{t?LC?n{et89)GT#k+DSr=N{HmAV30mVTk~g z1~C~e7Js51q-mene~m4yG6>?jG_KS;q50t+ej$YQgaNigr}TYu|C*WO^VqT5x4u4u zx4UAH{o(8ms{)mWJ=0+`5wVA%qzBpwf%>VSfj=4|e}_*E%})k2#)+NdO!QlYkp=Xh zTL-*zCwqU@!UM`CYWY8uGB=~(OMG9;o5|EWw3mx=Tr8$UPHcb9?*P5HQFeZ)Kp2LK zl@QpS2oa_N*qTlYUY~zyO2IB57N!&k7w)od57!} zxMvwjo}$0LY^A)l_t@Oy@*@LE06HT&do2Ju&2dQb*6l0Q1MT2?3VGH7x91ie}=y!0KumG^qj z_r+x*zEF1f8L>nmYHp)MgsU(_WH4oSyyn-3il?M=_u?-)+&h~F-Qmg=Qd{f~+)_ye zs{ELSr8p_E-z}G5!9NcJBiaKyA$TRRfC!oV4c!oRm*1xi%)NYYK&vJMeLw}Dy{M4W zDK=0W@K*K|+e*_F7=ZrJ(&2wj@`DK`=&8`_h^MQui94=GmHA1ZH7j>(O)YI>0j$uG z79jn9Q_vxYSqO&T+=q$Wa9M3I5jBa9*9c{@GdKM6JIRdO{(HlsKLB~i2T z7>18o%~V4Ww7NZUYU>K4@Vmdc4;Yzumv4107*1zK4nOYs# z#LXV-y?lMLX6*WQ>cb~6^U#hGYf%d0wS*fyup@$3QDq(jOC6ilK4P~4i(rBXP&*xF zg2#eDw6m2GzEA20tPNzG*tJ!WBcMQXDNLl4fM$K^u3?S*8QV+!Sm+(TIc>s(WI`Kj zeobiH&_lXLK=J{Aa-tNA+hbe_%)mH;SEr2GXpNM=amVfwfc6)V$pkc>0VS&;IMID^ z2qZTylIX=?OYm1r{;Iplkv^b5 zz5-ur@9l&y3xRllXtZx(eI^G&nvq#hdj{V>DFFIVV&|K_a)+TkzFT&vyVNXs@1lgN zLRGgu2s$a92tM5_RZ#?EG3XcV2S|e(drdHgDIH>$GwkF)M~)cChzI^+w#0g$Nwxr|CRy& z%AnSEKo%w#z5b{GOCMvvknd)?W16uef|0kEY;zqO-r*%s8N;Ytov&AMdu^*q@VLH~ z9ZemfKxAlW*{y9Sj{16i^z4BG&{M5_Y+kH4skLD^Rkd`ZR-75mHq0&61jn{q_tSE; z#w0-}V$q1jMO}SsdmARQ5b*fa**~jY!L4b#^DN&})AC`Z6Q%W)tLt*enIMd=v0iJ_ z;1K}7!ALTORlbwYxkOscXGURjCKJi?&6w~L=OT(;p5Z(ED=ItU_}BB?w5U}j?w9$tv|59hJ`M`^`svnbY zXDgnD;SjmN-7ZR20GI+Aq%AF>U72cZrn?Q%#F^B|Jt-*wiTj!k=plS8xyqB zcvx)_Y~C<13=ZcIcQpzRP{Ym7!8LBXr!Fh#?#V{L5Hw|X3#t@kb?26YwkVvsZSTt; zuucu3S`SG<%;3dHAa_mZB*PDg>Jo3nF5y*V(&FK_m_8#eIZYX^3H&#>H2^!#eo>~> zqMgRs*v*qCC8^Ei*-48g(O-wT6OgLZF1S;y_|$HFG|F+nSl1HPKSFh z2(rw?bVM`k9pTew@5@*jpTO9XCXJ>pMf9B1lK%eiGQyH(NjiNWu_XPBn2D2WnL_d$ zV8tc*=Qz0bLnvX2j#xs_$B=SE`y4i98+Iyap`c02Gw(S1q-_P=n)OBumvimmEkMwDdYWOtwx>+bMwbS7cED z`c~HZhLE?6rVxj!h`j%G|2qHu@W)z-OPPRG5zIf4_oBx0feyC5={aHa(mV{)S{Y-K z<%1J5Mz?=O#{D+5i^~BM#4F3y^q<+RthulJ)*3l>2SWx{7#UIbC8uj}c_ks*$;8^J zLBHw*>pJAMCy!Om1J@cbnu zeDs8@5+nj^Cla$%;O@R_v3;zkRL{vmM?R|#7&sv_cCj-J&qTjHD*8L-L63|nGerw~s`~BF@N=s`I zQZeSlIEcg}F6&~V%TUn(a4z{wfcFP$c480CQhv-B;cqN( ztNMkvowS=(1C_V?f8khBAK&rxU*>Y(Djz}mQbOLdoGD479RxlMa^`1PTOVsDR_O`` zvT9#4(OpeV?fnA&>UlA-k)HaUs#D#m{pl@C_UQZNR~N@)wDB67^I302Bo@C4=~~Bc z)VI4nWA3rjdTAegQj+yS7z&OYgVg8LC@9bBbjcS>eIwB`m{;Xsh&E1|^wQhWXT*i6 z0?A!u%u`+~PF8V(x9DZ2(? zN(y*J2%-2H(kd8I{Gy@=Cdc?{Jm9gOgVR#mVwGoxP$SbNGq{amS`U1Jq*P&yB9hrLPzCT z(KKLn`t6`)g$WdnsN-YC%&`xE250)mZphjq0%+rg;qq?@He21;lRJ$Y5U_oIJ0B0q}tUc(J!!ml^+TL*dY6P{}QKR6jIY%s%i* zbMk+57rrHFCZwM=*Z=Ao(Cis%d&pNtRm~tCA;~tnCDjiSFsa~;=qB1});t5liV%-T!{D3JL1DKE? zheaK<>22OL0$qQSL^Qi&L|X*xB_2xvOWXnhL>IjFv6kpuIg!+QWOjj;5 zydz^;qZE`1@-hV~9BQvo2s!&_T5OaMd*Sz@=Ev}KYMuyd#hofQTQv}zKF-%ieQY3G z>LB?}^n3<}3L>vn01!;pW-RucBVKL42mA0(1v>)J(*6R1DUt@@=8VJuTzT@`Ofykx zupqU)_mEDb?iH=&7v?MwaEpoNdDDOpVBZY*IUxYb+8%Lw*{CD(uaSI)`EQNr{U_2` z*rR{EMIj3bHkn~B2_3KVR91*H_v`*TC!YNPdgztq??YYAt8q)6px3+oLL05XqYmNrr?zC!4v_5w6XWv& zZ;KsF!oNc$!q|@Ntrf(ojq`#fJIHV^m+w5^voMUs3@#&{-ISNT2@NWM(N-blbtT8~ z+RSm=JBy%)P9{lXl?5rJnEsQr+`hdVB8c=D{w^Hb%1y?Aa1Z(Hfd}8!0(A=;wJ2-V;3YjmQ1uDeBaQ4|K~(=!yIB?dain zpdo1}?m+jLm7DOdbI8(h#25SkZNh${`YC?Yf|S;kNaP?jaE$Mb1r<&JqQQK=@^aJ>w1}ahVIxJy z+MYy4>s)B=66}W6RHLv4q(AQo(W6{;D-$WReX}|kK2HNPnT>`cetEFP- zmH~i=JfKEe3WWsod#cIvub{zrbO;{^;;n@f*$pBgB&P&Hu;O(=i~wb+ffGyux&xxI zjP6@*DHXamff-jm<|^K&(C1^);sx(`n;=cbPeoIZRPKD8qM4>ZcOTNVv!|V$oYVVn zJ>ME;Y%ZTD*8|DzW8`ho_$N2*{CPHo@(&0+l_$M?m_!a%V{)Ve#XQWd9uSRpUNKV3 zkR_{t#gw}CPzsa_3dfOih+)`WNTbaorP_ z{ga|xb>x@i6%{A+#V<%6?qoHW8&dneGB?sw*~Meh0IS*NEU2US zLYvU4Mfy4HaTN-A66`xqFNBy9!asqLwZBp?eZj!K8(I}A#N|scAQ|w&5M|uELcpZO zq7A}jc-L`WXTax#C~7g;?00#)dLa;$-RYFSfD^k(O)G^{d!4qp6Qoh}NG(h3!qKEB z_Pinb=OqMc^+#E?{pN-MundJ?>YILPdKpMEhVW8=gMqejp(Up1Zx!f<(DLu7d#08q z6#%MEy?Am{E&Sk1aSs5{et|1MD3gJ#YYoy#75wY53goH9O>1Wc&MrF1jOtazE2~4D z`3>aE0enfAuMQqBTXRy^RN=WN3N#<;w0tmI&PO@Y-ub5T@?q}-&>*58L8hz#@rpr?46AwWl7>5th_ZZOd-xnJ6 zKQaw-hGNTvT?t}I6s6I8to($?^XV9qOC;y)3Z~dpV3u`{3)}q3Eav*Z$B`KZth_h# zlf*V0H?P0e<|;ekcL_@x(_(JYUY`TjTol;ie^bFGCV&x$Y~aY@c2SNJ0!_#z{vc+N zykD~_GzAjSjeq}s4(9b(qV-sRn&{#iPkx(~dgvDy?>Oo0`0(%Sq z_5{ha2K-K)_ywSbYIk~QZR1SWssM{Dd{^Y?taB890mM_stbI+f9wrc}ky3#eW1-}X zqbO`TtR>&aMCKt;yM3J2Y%%0ea8(~bAE5v32Vm*rpp4}NQwFIkkIct-sY9{DR-BKt zbceF+inH-j2RyxEd*2>(<9}irpl}&e|GVsXO?&8NOtb6g=P(-U>LzG*ZY}%k^D`~| zz(@)Wp0;u3$hgu2W5R9NjnAF4+PR^=Ix+kOr7M2GSv|?pW0Np_)5$65*Z8MZrWHQI zM--iF4w_ZHmYAF()@$PS-4Dxzwf2(h=QoidU;vve2wcdEeuEDKG=+PZh^x<)Iaka< zt~n%5B^-EU8=n}1d6SogR*X_UvUBih`QF}reIHBQUU2EV!v1fUwG#Qyv1jnSOWhXt zNsuEbS|)EF8?MVE0Mey&v(|y(i(w?uh1_i{Nw^~WiS@vaY@FNX#Nvbxp|*g_M%E=U zx7eq$?QZ#}0f2$+_TyBC{bzeb%9DTD&U3F^#i6DeBX;BjTiy0ME1|Q*gjgRLrTLCR ziwMlP77(bLIc16wWkmc)cU%`&9E|7KjRV?>QsyzX$%crG!cvZqJZeXRF86ytYdu~5 z1Fp8brb?kbRxSn;S0iD+_p?(ffK>o8sOo!&G{f7a zfcV8k71!%S$FSA2y?w(7j_n;epc(>)Sb*ql5)>9p2s%0DwU>l?_<}b%-%zghM#rg4 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�# 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

          _b0lT<^`J(Rr*sJBUqV?v0BB=Z5 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

        1. ^v5k+E_HO4}O+=FEj>r1qGv5vUz<+GO%hZToagW&{FN>zbU;^TWQ!MG*d zQdVV&!C_MxXfySB&Z+TfA5Mk@ob*$0ro{X!wVK1Yv%B57JbDb{vw)xdU1k=x5>_Y^ z0Sm}77;h)zZnrgB^`Clgc+rO@S_Udd*e_2tTK)N=fQ1)l|s{nD#jPF{Vx4oHVAY3d03hwq;gzZiy8Io3N0 zLnvy^OyNJ1i?$0PzlSIm#d8o()NFiiSKN4!GmPgH6@;w#!4YLEUheKp)T~w1+RraK zX;^jo^7ma2UH_`Op@dYvBK_~lR`~YOhre5$_Qt(XrckRTL}4N{Id2C#@3F(+(Z|WQ zhL-TBNTVqcue9`-T2Y|qi3`DESK#XUR4%;K9Av(=r*|QSb@CkxYuY6il_sO!nga{= z292O&jA0d!OfvAe^`KHL!}1wa=RPA_H7yr79RTnNe-;UjE+^a1(hN@IB=4(&F_te^ zlspYBmAcBGPGOq!%<_2JFv7O*sjMqZ{%wp+;DKw0)x@sVfUJ_QuEqjO{_hCu&m4EsdST7aZLi zTbZ<|5z13IxPv7Kv+pA0B7c4F-QOi6em(wi69e#6Ri`*}CNOPmA`{RzCf7)n(f(rV zquGj+`%59{Z+0Pw{owXb>8QXwz}d4WrO&GcS~zBxOT?&xCL#8$GS=$usCrK__9F}c z>Lp%8IoY;bO8b2|k)@4f0zk%v=|K_dz{igHJg#Hx*v^lAWRW?SMPmI?f|s>&fl5dK*Ox_l|()@X0VuEn$*QrDOfL#0igb6^J zp=K;_J@DFSWC+P+wft=4ta|W$vVS3Sm4t9=M5aFYA^>Hf**O4bpOUotQqsPJ_XLLW zQ#vXXT<6D*@xBv_KS#b+gDP%QbQC;1c+XbCn0BsxOEA;Q_FxS2_Nn)u7W*vD0R_KN z)BNn77$d7#CdrbN55Z?eR##w#TAm>Z1_|}h9J$9q`8?MTkp~zq!d(6SS#%mpIGmkQ zFXeY14GotQN)9?9vwH!cI(h+qPZiy(q6Ptae}8)O1f3WJ=~7jJ$uK5ykbenj2qC^< zdb{OM_bY_*?Z&#*#kn8zO%KYVl&?rK!6x?a<}KYkLCLKh@ZK}aAPm)KUH)^o)c8|C7J{V7z~6*K zKJGoYI$PjdYpmV;!R1d>{o8vnf*uJ^R|moSXP-R-et#YP!qH7eD^yTF*OjQ8QypC} zeFLV{!1u%Jy07+WcDeE%DGoC^h=JGE-o>IIeDv;GMQrB1Us7v1A93`UZ| zx_JA!J|yHbnCLup_#K_UJo9ZycxeOvO3oo-suOcp-8WCj-OvyTDPq{ykWo^p)ic{+ zf{;l;u?>TVOJs|D4Y2p}1FH%+peihn3v+Ie}~L0 zX@9+fKDSxDh~Qf%{o9?SOyAc$h;>fRttRLWGV6FjIc;(KWSzE)^bpk6ssIV94&^A) z4JB8%0v(Q_q5ucOdNT4U#gMx7~Elx=iWuV;UIDc_3Tci6!Dzr|xJ(G9l!$+i2j?dR&x87l)-jOW9JA z>Etjjq3vATwcJsZ0WJ0&UH1bXXm(rJ0gwv7?X8h6$9HME{s9@jHabCm`$b$=1U$ZG z%%)>`fNp!?l$AakqpCwfxAiuxwb?7B_DHz!upD7mb&&HXh>H&*`pwVLUSq{4i{3#d-U6)|mFt&srAwcIi4KS=T zHg=QkzAtIcj`KV{j1A%6yRYct#@M}GoaEA{0rpe381?*|xf>nB-`^)`drQ)mxg>(v zGj_G-f&N-jqz7O?*d3f3B~Fw>tTIZ#V3_>E(kN(E{jFmUC|V{>rBmH57=(31ZR2|;6ma&F3c=*ZM`e5}%!$A8WL!}r z`~Q+&ax~CwjS89Bc6I>@>GbDm^1rn{Ul0wPilcu{?ZT^4#bq*<-=9DAdRl!f?0ei9 zb^9sLg31$`MObz4Q zp^C=<1_e4Pz#@tqEdcWn0n(*|(NKM_KgwKRKMKHrnbvhKc*7ScyL5HA+rEj8w-!OS z+@9dehVI4&e`qZTf-wD{z~9JVqF~E96l9m_vtA(SDph|ZwCE`pV$w=9#g8R_=k{m()v+A&j>(em#w` zs>-Bg%rwOKr@#*mvnS|hc*Au;2r03k)B@9BYNR609SbGiy13q=Qx(Fa@aYo)4tI@0 z|9~b-7^!UN-<~rWv3k>-$gzAEkElS};Y+QIs&e$aKYBBA4C)*c)xS`|$Vf_%w2MrZ z`ycS)`lmkLt8;u0AwO*xk`#U(FcIKSz%UU>Uq@k-5sgFyV7yB#3k0lo`@_9U&krco zgzI#{qT@kMrgZNI71pT^T5PW58%v_*eaLXycOrE|krJ_#K8OGH%fQ}(_z(uj2~;=~J`Ej$5{ej}oshn89nm>(G3bMY0revuU9z-kCmjLD9^plQXj=lMR}tA@NKm>-??OoW*2kKI@M!z=TsaSuYC^;am8!No-;2t-_UFa%V`G7W zbcw@1Fl)cEE#7Kd#bBIOSRAOdAvmVD2b2P80;O2Zlm9*Wx$1Y=v-D9U$gicRyBjv; z7SO71!c7exW38TNQ!fAbe7WzW78szhBPc|+x#b^~lT*tau`f48q?Yul^r4JxNO{=%@GG*vV&+b;_ZO=rZL8uX*_?P?r<-pe0K>z6*D%eCM+XRYy zBZ94tzn5b4{=7rbYlrLq{JjRRaYTe-{t7J?V`qZ1Su7z4$b0k$#O>k4!^G{io)WUU ziR<0mD!KK1Ekg4t<0u@Aik{15vNM60Kq-j4B%y4y=>Fd!P7uW7&`A;ru&?THX?tFF zh`=3>S58(MlVrhGXuKyfy*+z$V{JX~I-UXI#ILs?=T8tmbhU=v`Ms1#Adhw2)l1Vv z4RP$Q(V5`dBrdxLdwh#@?s8m;pk)H7(Hs^Gky4a*D@2#3*-iHN1a+uJ5;U#V8Z zXu!BroOMUcvWV~B*9TG_oyhzJ(axQY(ExUkeWmb0-eC-Z?bO6Ydx6Yyw4-)}ZTv&` z5KG}A7y$D}NwskEWCwz?Gd?kC<;upq1BAsglYm4FZ*f}$qiw@4zV?EKQH!_N;*w?b z8N2Fuinf?AW6DWmfk?4S+EAAn8|U?Ty>A$)-~^v7)eDp*IG9mgSdW`!kJFZ*{Z?b| z1u(=CbyCAK*NZ}+TU%uU%{WAk+fv%{=(uf-1HPI30QlSjHl@(?I*{?qOpNR?6qUAa z6kjwQl+)U?Aw{xC#XDLOfgd9o{L4D4Pi4@sEL0+wUYgU#$}_$O#qAHGia_*?HE-c# z{h!_noWVO&cVm9R1PJGJ7Y1=4L9f^BP4D8&6IxW%MxKX_W7gXlUlzM=eoMc0oIRUz9S_ZgJIr#MQaYKTrJW*3h7B4jhjGP1_#EDG!`q$46>ejgJj=gjNe@`O) z;Nm^FVLf*#q_sXrl>J@CFg+e{!74F~9CFJ9zLPsgn6_L3SD~D((qTnzTELt(1~Dx1 zWV5~s>kjb*4!3j5zY+KHanW2Cvuum>VTJoXP=El2Kifa)o(Hy>%;wN9>j_GfCS*F(a2ccs9tl2v_!7>e8-dD-K3GGCdg11c>1 zOLhz0?s_o%H*e?FMo`??R;*JHx~o*s=gKO4g>iL4a;JGedB&tk330{^bC&_nj$X5F zXvrj(LI#sVyf4ZKtN+6mu}`-wp=_vcz_fZ2!aja&(3Giqmk8a2D&lQci&UjR=9F2gY_Pr1(`;e1Pq$RMvU5<+hg2g` zee&moF~9#!+VTwCR%8evJ*#PqOYz%(zm2>XV;Rbu@(^~vSr5|NE*SmTahuFv$>-q&@Txw_8l!vSNPIvYncPIvH_}w~ z^7~7N&N@g_Qe5zOak`eD`FMsQNTqgZ>9s`+X$wJ-HBKxB$dF16zzEH$-d}%gl5D8; z!Y*TXHUVJM2#e%?^w;U+0#6BLvwk1E^8eG&DZG97Kqk^i#xyiEzVG&C8;y$ua(De} zrvIrhgLhiVtrC9qE5N`(fV<-8YVH#-aRpJd4h-&hJ# z>fZd?`>FMYJp!)MsiTLjD0iG%JBQ4CJZ8=Aq4Q`1&0mnv%DMQ*;qp8DolBslj*pc1 z8Z8HtMMPD^UHMy>e8iLg=Qk;_5xeelA* z^5MpmS9<`+|*Mtd_``Qh|7QnyFgJY7MoPs?%i7x{dj<&3{lF>6VW}n_E zr_@^_IT!Yc#UXqH+oMe*jm#ras*C@f&}ZQZ<72lUrPm@<2MVPyReSxN|1sbe|BKg)+rTRSRsMSbhkw6#S8 zpXp0FWh$Ry8oAy%e7wGBH2-8+5=Z{kJZ{i2os#mz?P)7sC4GiX@+G0r;dy8&;=L{Z zjV~@*UFCv&$oNyi137Q+F3@d$A(PbMvwm-%NauI>J>Y3S zg-OCgEn-W8)?WAd?4K8Ea*#FN+A zo?U)tTVIQD-#=^4>Lkg;YQ}qjHy<3nDVZcwyj{6=t4iLuN}~9rFTD`k!~7ANXJDXU zdTwQA&RbdCx}}X$|Bd8lGu|(*#^dA&$to2od?B=#k!!L7%76_l{iVSz{++HnB=Vr~ z8-8@@*u*z7^t=ptveW1|R4k@g;!5ei$WJYQ#iK4#h*@Z4j2lzB-B04FJV;vaH33Wn z1EY{{*Ij9oE_Z9c;#Hy1ms~YI+cXB{sGhohe#z7FnEV`zeE zznArEu*gu|y4SUbi8a6<&MQYTW_0xUk%)`D;)2SS@fdEgx>)DPN|kiDmN&K2S`go# zofnVNyGEo}Rx-D4O)}>-NA&2~Q~z#*z1h;xhbTU-?n81`)H14T)wImTHJS6E#hmp& zFm2rKBHg1*vo5B(qL3(vDqoVSkOd6_?r0SGAwJ@k*2nqvhKA&^ z=CWz$EZeJ5*FcG^bqa)y9*4WY`SrlNKYPaKU5aft|F%^a%q}sZH|00C}`w^{Z-&Nnvtn%*obZ};d|3rZYhwMttr{Ej7t^Ea+W!>oVlnxxuIdU-wQ@J6FF>M=%w-Hnq>ljtPQ zz~I|(`aiSYn@+lTI2A6HoOFyC@JblqQDQf09~^`Ay`b>k&*=GscKrwj|FO`KiXar; z@bbTbLf(JqwIhqADrQ@=CRs>}b=K(*KxUhjdhMfhokTEE2smM*5y70LFWAK$2RRdb#vMYTkS!*!5imX~S~hMTzsGe< zyjF{)yC6Vn-qtBtE-G657KddFnoHV& zo}0I(1f1?+IgF|e+^*WJq~YSy&L3|IVmm`_{= z76?dUN@^=>rz*vBUD`yk^3bm3pF42?;hK13uBw0LVGNUawvSPxs;Xs^<-LuR9Fs+uKNgqTivU2D)#AGx)1>Lx3pZZ_F#KxA-Q*RXjCC-{Z3#o>-)MRXPRItm z;8dFzSRnSPMuMDgne^tGa(HLnQ)3TM}3FBlW0aXFF} zfQfhvH(&@elmEfLd5FA?Z$;CJrc2}TjE+lJfIrTupq73w1LfuQ@ zB3$D1quHh$Yx(*mNN+W&2X3XmDCaItx#Q!QFJnBb@W23r5m4iSOhJwAIb)|S-lMp9 z(bJvZw$(M9xEU3a=i+d9Q6n}loY1+-CAz2vT*XBYJTw=2~xbU%(UK615DbfRwgw&FZkA*MI}mWrViYdvL_BYh#9*`#3d1S_eXvK+| zV*y|a!)YKK`=Vb4C=bC%T?z^Jl(E%o<#^bWa543^(8k?UUYDP}zX!eaNt1spal&(@WtUa~AfJp>s;AF?Pcy_4JA1WRsY4~7K(ibz=w@Z6(?dcWcP`6F=}JJXhUInXcHWa z_|WnlnM=|VjeD~PX;FnMd<>^`jk7zS(`=-&skk2NlQe`2p{}}t5>t*T6W%T<{&QgC z!nUMJKwxk@7J`lh>H>_dv=G$M(V}z#6wwe1yQFf1Qz!%^rizlKOHqb?_}f}vTy(?>bgHlZkYMUiH;=>h;^O;CBw9}={b1wX=F$TPvu&X zTUMh~IzEKqt8eb{Y1;Hv+uU^o<$3BJzKAYT6HKuFS}8%D_>315bH<5ezxnIA?)LM) z-6+%&8TUb4z!%YDS#R?r7CvaT*m4@mqD_CR%ETP0;j{cEFT=l7ul5ImfA2d*+j3C& z&ouUj9Yycm_+oMh0;s!f=4*3opzh|p;Mf>XZu6wDo4t+}l&cOtEdSNQ2S@K^ax7GU z$`MW0`l(+Y#`VKvBR$DB{&O-j>cIDA8cO4= z!Ns5kqM~VN6F}6YiHGGI?hqz*F>~L3?Y7^O=o!L=m+d+sK*`$L+THiD#{1?aM;$Gi z9KY%T|NSrA@4R+A;CVZ~Lq$AeqlNd(2Bumg5DUX*ETFTKbe7@ z3HZDIfeIQhDw%?EF~M|q7ujzcP*goqX1&5%1=> zt-L?~sGpA77wJKbYzp~hw!4f^^u{Mz@PP*rqDdRGOIc;P#{EX7w>R{vBd*Um>bnJ^ zWPNA&Jo4kq%PiJoKVjn`(T4Y&~Hyxez^aMo-5lQ z0auo+vP?6RBLn&_u*NtK8b@?L<69C`-@Qts!;%%k{{5_^W~lcknF(96_BLJz*lUO>T?I0n(uI(PAeKU<25#>6OK|l+rWGLGfUxWX1 z<9QV#%qzaw&q=Z#me7gZ@b~%OQtA95#bN?_PMW~+s0fQ*Oz_}zKUX3?f=S^s&^rN= zuP<1EA3=9LNND~ZCR%3jpRv%)ic`P-AfS(Q#!rq@A=hZUBef2Vm?oiumuz?)PGgk^sVBz=%7JRR(5>;icLak9Nr4}&DGF!N_Gaw?Y3WZ@J{cSlHGMc>g4OtL|roa9D?-S!`QI*41D ze0N?8syDx&psDtvQpo?Tq6>kc83`B7n4|r61t1Alg1kYcqmxrianlj9F7$5+s)P=3 zcjMy`ZN$0dg#9Ly{30k>@^z8^mL6*Vvi}vXIb;(gII)7eVb2Tu_L?5PNxCDE_K29p zmwPzuK}9wrM6cq;Jh2taeLlHXbCz-m51QWH_2)PVqEXNv4O(d-rRwoUZGp+F@C>+$ zsSV*gOg9I9H@hW06!>4u%<#2xq%dJ8ONNZLmCWFxkb!VJaq~|}g#)60@yKYgP@=5A3ie=%RdqQd47dFAoOrZy6|Hk5s zdMF`PMB86}6vF*4p9mG-yq`rvB^wF0LIYwB@+c}A{_B1RI{@z-ON%p|#KFZ?r@67-q{fEBv` zL^bI&uXhuAjobF?=nUIfEokF3N4E~^2{-8rJpeU|+goOQrW3k?|D`1!M9QF72yCH( zq?*T7BbrQ7#ZHV&dwx8jq29dOCwq@-(_zbnbGY#a8#TCBnL>_=ix%kv19RcsmqOO~ z<5;)q;*E_ZJ4Ex6@0YvzK~Yq#s6j_W`INx=MYxl8AHltv0}MJ3!|@2=eR~66x%((d zN*FRa3iw-UNjaHq#;%gd(L4Fx%Rc#5Id-S%L5b>8XtuY>&Up{`EkE9;?g`2JK_+-I z%Tjsb&AYv-wPlTr=Q)1{swsQT%K{8T`G^sA&n!W~sX=JLU^tIZ@Lz|6IzS(L%5RPLoJtW0RC zgR`Cm5vGN1)@xlNAyxz_@>hRumGfW7;NquC z42{Q+v%DscE`oN>9y2Bf`v)^7)J%FMy$&aJ#DfzT&Ns)A6=*>FcfhQrU|0)OG7U>l zhNLygD`9CyqG%}n=JIlXb7#i_23sAnT||6?lDPW=RY2*G1eX(ymcPhuyY8$R{av^q z^F;zgrr2b?_ls;OhfHiW004HBFJ|mwZJQ#io7aY138n5ULVJ2`Ib|xUBoGK=qk61> z!<>Mq?Asn{nYMG17sZHO*4tbRn9njiQZDT}-m|Gh`9CtYp_1#X-Ya00Jnn}e|KOW6 z^|y=8K$Ta*}fxo zshG65TgaOheBVv2&N+d`VhVp zeG3&Q02iau0JZIjj~>$|@==*j@lJNoYHHXo?S0adMh;%J(iwV#F&aw$q7`RC>SfsK{; z?Ox;LxdEp$e`5^MlU+sQ2LvdVoy=5YJ*hUl{ll$cP)BW*VoYgP#m)VZdra&xc~$!o zwFF{{X|Ch?Dp%ra)w{ea^D=_|UY%9$u%5%jJuhQ;*VFGAJbgbe_HDTZ+9#Z)qEOR5 zSF?**`OKca_v?<;`8kGkPMO==kT$*+bNLy-=e|11ZVKn@9pi9<*7lLVt zc$T%uk&u=inAo*5bMCQ$ML_9cJ_^H)!y`{ zzVEP{O1}}u=TP{4F6i!FJiQSfmcqUQKm0d2UHQL_Uu=7IB<(jw6P`TLzv%Pvf}5l} z7y$qMJ55~MO2Xu`*G)!@$4@~%9Fn0IliFpmotKrTPeZfv4g~o1wrfP`waR`TWbs=_ zm?Bq4b+O-OF}*1;e+y&xwfUz`^(9PQmR_PBFi>K1>6I?1lpLO9h0~gWj)E3V*ZhKo z$wzeahkh)LM}&HF?>fL~I}y=ezYrWbGOa|$p!dU3DRN#yH#;MU%0j`sUS>lj~c^rHsnz;cB zm^NtAl9{+EB(;~Mr0c}3f&qMp8kPAUY|>pL??^s=UYB1TmnHQDczcP@BuA;*pRvmL zxx8HCt)FLP=6A~;4ymXGnaC?klm}!*N@%{AXG#)d1E6LPDR(_X+cf=v9k*6Jvzu)o z4ZC$cjsDZYm3>sm=aX}B`c89*^*&Mez`;**1`0PU_3u2ePr^IfytAf1H5GpXfi=*F zF&Eto8^Ps#-bvY))w^XN!>9eMnlQ-a2ww8cL>xb0dfLuUq}2NNa!F-u-a7n5g+kZ@ zKJw%AdF|THY^eL)X;Q)ue@lfA+$GarOg(-;3gYl4dt*9N4Lyk*Ban6+zRtgR1Vp{q zOPW41_DeJXwq@V)72K5i^PHNWvnoM;{`4*Q8Z>opH&#fvry&(K11))rfs}{w5#h(_ z2e^?v^ySL@iWY4{BCY55{PjcbzFRdh%~Zs;0NXV9fT1xRnW+uB(<#jiq#;B_mDC?L z8yk508lMV`ufSAgdBR3O-7$gi%=;9$^z4$_kwF1^MnE$eTsk1oge2@tO{xOEbt6}i z56!{SJ&R`3bvZq%D|(zgGV}1bvHk|bc1;XDVfz33_JrdKCnk(}%(Jn~FxFnIX3^BC zuD>SW-|8JURb2sf1d%>PwTD@>NK`R%Ibw*(FLqko0hd?xJ&VROUXNmm{`d;g3nEWP z^vY+;W@U=U9^XH-`5km2H}6@=TG`H{483;-BvLuYv@b9sgb2pypb9<~Q01NNh6M?0 z%&F06wwh8(bd$34wepL-ER&zDaiIj35`I@98js}&Vv)y5^iADAs_&kD&t(S9JrI@! z6v7qroDyfb2F6j_BNwdN^4WK;C4(d2Y-!r9>}%IfEr=6eskTp~|9~1aL`7PHgSXer zUB>T!emWk}U*9aHxOg}g==6I6<*8wZ=bqJC+>V{%mm+zB6$e{~X^T+h(x>0u31%0t z{4HR;MGz~`57JJzj|f7%v~~kPfL{^`9<^Ts^d0g-bK%X8apwX8uU*1gCVd2URgwEL z1&76}70wfL>wtKsA-~J0{ABfOv;tPLhr(Yb9ass;1FCr8pKsT=O_awz;GGT(>z$Y|8Fb#uXsj@D1JHD7MU7y>8FwQ7Ic zNZO>opbB|@xMX70kp99T{~=T!bEtH%?C71MA)^^{v&%e8Ot|(AJC6R}kN(4IB1Rh7 zrHu2Nl$D~1szoMp=M1~D^jt(SHZiZdUsX7*{Wmw3-Y@st!yZY|S&<^~FC)VCAav*Y z8?lEv+W`DF+7KZ$n=5QEA5s{Wd@;hXPqE;KjQ0<-iShK-^w5vWYzD~5OlmDC&yfI(0>Pd!~ZRMgNeVq3iSoA3mr?WkNR%$`b1r1Otp@lFn}4oX&6w8n5~uGhN6LQ zSuPp;qo4XcRPrq|*SlCQ3B_kUWI*TL#^`30rhnEzch00nkG>myRZHcpOuJfp%N%T? z8iufk0Zib8F%i3<0Z0!isOXa26$xhat4;8aFJkC1KCA(ul-G8;kx5!r4so0}1e8Z< zFvG$g+w30D{SbFx4{w~*!bvnQjEM}f3JJ`c$b5Q8VTqg=mFA#Q@NoY{^eCm5$c~Ec zVxG-i?T@L4O}z`S$3lr8=8}?7qu-fOQ8mjFL*>?M zO*@F%OBT=qU&_Aj$)hidn#R}J4BArjkf;l3n6%oU{5&X312H_(mzTNEair(A ze-GY4Rc1Ts|1M2lPl=SwUlaHpNj8RyQEX87>$yaJ-S2l*eY-sS^j%&@x8;Y4>1yAF?q3>s=+i*{PA4Ig>CVs- zF&$kZYqwyVlvGm+qV?x(5;8@|W+pl`c)FCZufj8bbUPF(X!z-`-(Zdp#tMJt6gg&t z0ZT9}Qau!=E+RqjFuMvdU4SoZeL-9ra~o?+xLI1-b-ujW-uttE)4SD$lT$!z?-#c8 z<#<&L2QdX%2&3U$?_e6c8RBg+!t|gU#EcWLV>rHYUBgH>8IhuM&xewi2s(PQJdX+v z?h57pOt0aJ4h0*)i_5_@GBft!YH2Hq=WeUs zn6KepWDZMtL3cQxc_RE1;M2>wYSQPZ0u8P*H2%DjpTYcog^ z8wO8IlIWf&U16pW8u2x0;>&~}`)0tu_TV7JYTB_&Yi_yX&;wgWA&QNc$b^chdO;y< zyUgO$cGipgI#oA2UJ|;+Cgv|?>YGT)^y(`v@eG|=F*8e_+KJ%S*Sx0NIow~#))lBd z!ZAS$I94D=4waNR>wsO%X6DdE;q1>;#VjnIY4%hk;VxWp?{2FDVgdz5dNbsAA9E;= zt*a|etZJ$lLT~d5ew(yMwJYRdEB}zBTCuW}Q*7`_e%Z$5!Vb?<4GE1J4vq^IKf(xY zO$NF{D@$l=2vRNDg?J+SnfN!RfdEUyy{`Zl!dYPTFty8lT>T*(t0HdvsxmvrY)3#@ zihlH;_91PQw`GhqFSqjW1W9;69nh;12p#tp1YMl-t#NT|tF1Ighuv#K`ljs4#9-xYP5HQ~?9UEY9;oqtf(^e$_ zEqJziUtDO6%K{&e9Fmpo?l}_;6W&ze$QQnxY<=f*Ine0>yI$#y~;Px z|I-tAK>Q%WEj@=NG?HwGGt_WuCFaTQ&ihZT>>(?<%Yd8WH@JI7+j|-9owe06;0KhB? zURi=vRm4d-7w!l*j4?{8pft6xsh!?j`Cpr`PZ^{vjEQf7;1Nthd`Tf}1W}7~L+s=s zasY@nvY}6Yo<)kmbsULspi!M~c{wK7gT5E5|Y2|uaL)cZ2-j(5lWU`s9 zKM!=S;i#@!TpzoGm$b;e^p_QAGgM$R2R71>RIqxA2J$EGUqi4qq-lE#sznt$vYu<2Cg> z0gtd-*4QP=Q&`8Qce_{AaqM-^GCJoz^@PRZHIYGz!`~^VSN8b9$H=_BKhtNcTUQ0E zB09%O)jh*jyRRUh|42Un7k<-7!qipT#0u7+B|<~HgsR zaCrP0(UE+&i>{{ya|Eet7jE)-tgYl&053LIxV?cEe{bO7ALb_Y^k&ImoE#M0lba{ylQ;KU_tuH$5d zEi|4wp89*wKSg9ZlDMXBuT+dv@#nafXfd}3cn>3`mAx-dI=sZcR%6iLRvRIXGHtw| ztkM;vg&B~)uwfk1ezzaW1FE&c>RzvIj^kX(HtTL5T*`3s_lL6+y&^F668{DPJ1emz zMY+cU90aM2uSXEs6yz(rO|%#i@%;f>c!l@!L`airT&rSG*TCr0ZUPC%=uytbCW5+8 z?`A-QYrS?15B5LaS%0H^t9~d#b z%JC((Lg&K!hUDm8ElzlO{k3xtxv$OwwVf&CV;gkh6kyq=GdXe4Wsc2*M** z8VN56rOGvgLBF5Y_uuMF!w2*P5gocd1s|E~PtOf;8{ zkG$bSX*kZuH0W_~=%J?kXe|{Nu0A`+j}@LCP6(zuMtskNQ$zaD`b#mRnH;j{>wNGJ z1gdwiL3J3TL<2Y?W`^Wsb{jNF9YmAgd%3L_Y&$$1-t&se&aFS7E&ma7!`|7gVE=LS*ANzpMft_%EwACmE zc|rQG6kL}%amCmWu_MUk`!H?Ga2|?a(mhQHFQK9Wc`XVG(g>SY=1M-(ibh#bULJ+n zNeg2W%wanPdEu%?IRi|Hvy_xsD=7cV{+^mEdgoi{x6jys+0Q@7dPrTL2)MmXddy6k ztdm>x|JF;@uN^!05)WF=RH5%RE`)0fgOpdeztl#5_6#_~2| z&s@O40A8|SpPAwPF;gg^@lb19XTAw9r8Du*Zz*=Qh=rv6OQ|wSSuHbCSieqkf748F zA`4-OPOMlH-cwEB`@;&6kv}1#N2Q3n>zlZWefX`WA6Dx~T)M92$l28;?Zw$3XQv3D zIeF$;oYQs;D!ivb0^MGPH5v+xI? zhL(jew?(m;A+!2e849U-76rm5v+1g=p!XfaR&`S^U)}2`h3?`;KU6D%Ij)fp-Cd~i)I2xw=9T=!_GBz)>fF%#+uAU1hTGulO8U9)vok;QUH8PZ#w znvO|fO6B`?@v@|&e>j7hvQ8qu9Ldp#lsPe|t`fd>so=fdk7t!~et`8`tY^*X^>dWG zBEj~D2^iyl@^3=}$5}~2vAgByJiRvoGC#Z(kn0io0V}2itH`n2D6~>^sggPTI4drD zS6nz#i_u!z#e|i2V=l>;U-x|`|N52DBcOJGldQ}V%tqR7Rvrnv$&;*dREqPVv4r|o*zz& zS7^fGxMPZgxO>kV%d?&(IAiguvBNtKrP=MsExc2{BkIvcd>LqNhyDuH2}x&b1mVp+ z?B|Ov76`WV?G@?gB0}}ohDvpqTSmWmiH~yTsd6e4e7&NT|9a1fMotAVEVK%$b8+!B z6*Nl-lLlkT>ogn4pT~3m6~wRBz|`j)Rx8qqd$5QxUH0H1z|)cq{&kAKWb?I60(JX# zl`AlAB?ydgFaV^Gf^G}|VleNW;;#vKJR@S@w*kils@-Z<6){9>T>-OmI6!@Jb6#a| z@$>saL{u?*f832?TYBLaX@>zEaZZP@&i!_-6_gBGhHfQl%7RUKOC_uUMFK1%P9h(7Uqryj|Vi+4(o{@#3e~Z6HByAWNBErui?04<0`6 zFxj*8NRi&)gJd!B-{2ENw%keb1) zS}s@`d~B5pmC1ijGyJO*Vs}G(N&;RFf6-MBI3^y5@%KiXfT|V7mOt1Jm$4>y>z~pK z3fFY>IBKDkG?*xhr!9**$bjC)l`fd0;Ho8of4*T1D(A}CsX18R6-_e>OcPfNB)uDY?EZg~XhoHR3s`74g7 zbyrCREW=|40gs$B&J2^Jp?PK~gQPnTvn3vI-_CTvGYWln_bnv(lwXu=3<*(BqgUg0 z;WuGucbNNV2Bo+6w%!(xgc=GO_?zH^huh}zidoosEVaY=uJZrm?XBP9>XxX%?xt~R zEWsUu1SeSV;2~%rA-EHQ6WqFScL>4V-4nEN2*CpccXxMs`n~VHGvCY~Fu$GW^wZC- zv(G-YYgesWOYV7HSZ@;z$pCXd>8!(R`TVf2=NwPCiWl0@cPs&FXyXdnXn-;1zMqBM z1#V}ndTiJ$4PW7DYkf>K`cL_9u!&9k9}#P0wKD^maX@Cy?II(@_Xl8JEFcr>h8f9}8Fc+g%!U z!&n+l@%T#Q*^2A199jJ$`l}FUZPb~PdRVelr93YVuz8)J5(F6fJOE2o=MO0`0{g99 z2gf9u3cqcKDsq*qgnR#dr_>zEZ#K)h8|N%()TWTK^xP~qv?@%NOwM=z$CClo2Sbt= z6ubk`J$>3}7FTTeyLMs>fCNEPRQehgHCKY_J^uWF7r`}KEilOl}{0mA2KJ zD)rgO@dH7A2V2$ls8eWoi*Jygry!_(eV6yLfm;}U@{R$G}sB4gCZM~rPaWs>GVw8Jv z*@wGMY*D0(k!x&0>+_y5nGS`GsvFOs8+E!8MMQ-OSEl!chG}Bd>Cq$eD>tUOMk#%_ zm<~)B6^)T~YKO&>p!Wmn|A`7ZSahEZ=6IG*OWf)AaV5h&sujJe7kH`ZmrXATEWnIv zYRROwiLtDsPylKH&7HJgwuD2cqs7jB_$Ipn00zEL);3UsN>G4pBz)A$y^Aj1%41bH zb}fC?mQl6=k22vNtx6&ipl3I=Qzi$D>XuFF6o4;GYfq;j^fyi@yb)U&=44p!;lyb2 zn@2i@u4d5LAyvj*HI3CM7P6pP_sl>LbtUH)Q^N5`>wHz<##g5|_*E}kd?;x5Op3Nv zMwMV@v;fIM9{`*b0-&Xg!TNjqY$*fUb8bl#W8{?F8eetWvU8q=gW?@SS&VrkRujSa zL;>3G|430umjFn>0k#*!aRim10>-wdlC&Hpa`?IP*2ar_)wJE@nxfJj%ow-TBYW z1-xZLkkCRQ>cab(bY7v{=kx3hf<2LhRB&tnV@Kx0AP!Er?%$ViCwb%0OAw# z2CA>BM`b+jGyqc5>;}2aZBiUG(hVrY{Qmvy77LQ?Lxm)wH=vdsI(qBQ)kJ80sAAR7 ziLZuITr^qYdAp`%AX?i@iY)x(C%!lqE0Y%X{_rgO@7`ziP==Ze6j*QtU~OU620-f+ z-b!T{S2w4%to-%1&_;9^DHyp=6@%m=<&51m5qd-CfA?5s5}fzJp{wnI#_7McSLJ^Q zWPIxOr>)4zWxsSs5z!Np_)0@{o=jDfexYKp$o|oyt59?e?)Du{4MfBL63ZK6#_?(C z)bn6b(B7gk60oB6y;%9=qMuUqZG?IUu4?)P>wAV5eEjrF()P}D+zLM`b>d}RLovAI z{evi1v^}KJM{iCKHpH4A*F<<%`~7RMAoLD@2*Y|&{!OO zdO$wE?)c{9`n?n@O(Xcd!Ni0f@a)}@>wL}I>u;~YXsTTzha{WS_1mH*jM>ci7uFF8 zd00&m<`cGmBzlVG(X#B(gs5-{oM5rq4qEpjAjA$!ENKTy%#=US>PzEp_R@hqu*W(Q;u4Q-M#TTn;~Zm@Zao_(CMr-D?@$Y22^kD{+`gP<>9 z8w)Bf0F5V!)y00{yO8I3tK1S^pgv|X&1wIX?k3*I0+73KvhJ)*zkv`)68A=i*6!BJ zmE86ia**iK(Y*LrTA*3SKVZN&802F&CVK`&TPUr_Wq8Y7xd_RPZrJf<`0-(vca^#6 z-0^lK*m33Td&hEj;ljwoDJ-|*lEtnA<4KLkMqXmdUOuFfTcp~w`uu8?2bH!k4ug=+ zsLS*f4_5HQRcmn1{V2%T$p2}Vh^S9JX7;4GYjF`Ma|9&tUZoDj94C#?$T!Lekas3Te0{sZ=nGunBa5}TpP2^>5lV&v z(H`G9lZt(-h9<-VQc+fB&LGpnRN{vEQhDXDh}ZosY>+W=5F*EGA?p*5;}^ne!Fsu! zSboChpN#7{`?lxXVEPd5!XM%xv&)P&-Ij7P>PW6OmR z+ts<}OSaN3v?T4)q6p9)u6I4KbrmBkJ53P4%lX3ULgz&9d!=t+tbAxGYkSk=>V7o? z7tjYFR-Kh;Ss@!oQZ*;H({FiUE}pggO8NYfQrO-56Z><$+Rft?5cxh&i% z>1d%_zCBek zd_-gsoJ4f0y-llC#etSUVY%~VN zsTWM4#C!e+K*auWop`uVcHZ&P(mZ&|HEPuG_{8zdPi(~i&pBer;yKAFW(`Rm;HJl? zH{--B)E;_%qCk+oe{k!DDUWj_xu`d=DVHvI#<{+*zB3#W1_(t*$oj|7-MWoybyG^t@Jn%q?nD$L6Ly?tI< zxi3QB>=T8SY=n=08<7|{qjYhtcwQ|N{#@`Q$w_7vrU8FQ&2D5VC~urp`8@Qp+l_Ja zcIgjrra@cc3Fbx-S&C&}wM+>(oSZ2Cpv~FQ>4JBAbH+G9qw>l3f7L{LWGc<~AQ0b3 ze@f7nZH{IYfe7@@xH2X)hWGVOcaz(Z^6F$YALa#1RD56 z&>JPn;sp5o?2}vX1N0ChuiSjvkov$ii`Mx|-1Tb}}YTb|_^C#;Z|MdJ0~+ zxBi8!naOkUG19E)kC>rKNm4H}`O3YEmQJFndn{|>Z(NKy`xlSS2~22q z3;r4|sagpZm;8+;ypX3V&d>HovY5zAr7eX2RJRQ0rE{dTy>FdjB0t&xal%UT@d zPd#xy*kb+|N-g9-C2uKne}fhu3l7nntv4tU%N5UE9H{fU+8?V^o*{RRlCs8W9ti|c z)NfuV;|syOHQ;xq6hvtGtYF|@3*XmtdI0IAREO6Kkh=&yQ;p}GD&1s0*r+dGxhR~m z%Zm>zAAE)vfdGBqbqoF!mX^}g%^o2yx(E*9l~u1(n<2|@DFJZP>+sFdW%UUdBp8FE2542+Wc>tW&S zROkj6eHNedR+y6_mSq)oPUhF|j_`57`4w-|-cQ2I0PvMSX`AyS9V2SG4oB4B_K&5; zgkpleJyCoEzsAQAb|<<8$0(>}kgoK`ZKAbIs^0d61-f%bu|-imm?NYI$V!ch_g&^muAr4r$49AC0c z4+9NgL+J~JN^mOYupo5}Hy1S(r`EikvQ-g~#c$9d)RPtP4aLZFPy2}sAFxo*Of&e) zCq~IqFM2ZHQ6U8}!s;#zPQT!&h9YG2elm*vP+;P#ctul-DB*MRMLxSv4S{?J#=43+N^zRZ2EaTKLiC&}6P+Hnrv;{R}qa&MC}FwMA| zc(3MKC1g^8HemNtIudNaYM6KSPN=1#)9$q!$P+VcU?fYCk}ZsD&TEb5u(g;UBLp;u zx`RfJz!hJGEPqP}}Q7h%(qYTEF9^`RX5JykRz z3n9TdQl)D<=ntBMEB1QkSSJ6Ed&ihU;q++p0*)=EcQt_xsyl!Deh9Gv@g|@C2i}jK z{HGYKSeK>&Y!bVK)zhjV$>&;4Xn{<@zmPNDQou)Af9RA((sG3R) z{JW~@VMT+M&_)qFm~^-Mb8;9Vd>aFcZt>v#5fmfL>7}5%ngR!c<>ONj0NVJp_L|si z;A)_vrIc7wf;@^l<((v>B(yllnn_iaJaP zcnko#=*M?#>*VFVHPDsvj&@=(I|Yb~)5jEJgex)D!!^VJas;sLXY1$56sn>M{w`>34y}vLg&<2uL=@Zu%_wx>sJoC24E!qt+MGj& zKpDhrjWOX#vMIV7F6&Fhc(m#^OJqqTve%yB(fn8Pqx~!ldXhrAUUcdCXjh}{ovu=J zY*{x;mM&gX{-Mn2r=E#;7PNTZ(|L%##ka!&qz;PU++TqQqy*eAP%Z)7vu}KByBU#<=xtgw1d=acsML1~6d#&p zKBM&H`*L%W4+6M&x)H4phTk3~U}EQ^@(whA00kF@K>9qI7v7IgFu^Lr&Wah=%)5m$ z!yh(Kf3|R9me+K`KfPe-fYCEJj(9fdSJ~y51!b=E59I)pIiY7gPd9`p{0QDk_G@1 z4iuX}7@I;Q_mC6&))3yCcR(f_foH&sYzoo8N!E8^J02xKgcCdbcb00=`?mSRql~XK zS4fWq-JdcLh}TMzK4(aht@)&}bDTbI0{Ur|q-K2p4`o2(F>De7qu+eHE;1-jM(M;LM_WL!oE|gn zuyLFQs?Mk~NSG5<^5WySEQkx%4-~(z52$~<`V6%dxA7g8X;%&&C}n*@I-jf?5)3ee zJVnMX$IRdV8O&C;VX8x)nQp|c&z1cn=YF}PDiA+ka&?#sa1sexYI-D~k~HCq_Bq}$ znAU}LC*bG*%)mzAjFLeXSd)CW7jC$|5>AMJ{m=F?D{IO z<|sFz7D30evGuA>Se+t}e_O!h&iQh-y|Ex*i9vDlPq9E#u^@#^bTFnY+f{^Q`iQg~ zF)itdrR94m0(Dnq+Dc5uU5T~wHMK;Nf~dnu<1iXQ0%f!90Vp*tX_HNkZfc=0#}Hw{ zAUJP)=iFWNNeH=k)HZCHk$gF$UdW(p+xfK^@=$3Qx^q$DGB>y$WWv#YW69CU>e1E= zFYCN#{x?4|Ai9LUvrlgsqY*m^K~62 zxD&Q9>tzy_ehG*;XC0AHjb(e}OB5m!7Ji`?g)+`vyetLU`E_B!l1oLkKsw0xW5pg^!;6-duh`#M_(xL z;lF3OL6vSv93Q@fN{tBm9}GPoFN%aOe*Lt}_kDw^Axof(@=Dp_x3PdFxw;UY47=>WKcp)DlK%j6QZgTS(g03Szx7ZMNEu1e>%!Uq5 z0IB#+_|pnyGeU&K92!UEQ{eer)r+%O7m@_Q4Sjo8c*!K&q-Jaf$&I*gs3;WRKwE5g zvmF#8DKsE{zOged-7{-2OIIM0Ae6zKz*{qO_NNA$m_u) zPXdaO7DtQbx)Kip;F&xnj=?GLa(q)6r`_YZpgIYFyBJNuzv8aP3U zIYYQ`U%}&#;ZDI5+apVHxV$W(@Zof0NXq*z5Z#pS)!L|-(wJM%HZey6Y*E1HhtGgp z(KCAI`)vWMzu|;w4yd=ydYva;#*yH5+#qJ=u0XV_r|2X=ZlFvL)i<`jncUAZ0a)zI7J_{By z^hxeDapcb$wa-tS(ckPySdKq_1v<=6$oj?n-Jm@Pn#n>1YqxxYuVJ(RnD6c2Be%-qh{?#M%-J64VYpnAaR(`@_JpZ9>X zWd+VCi}%k%^>YN1`wwDHUBG0RV@|QN@icsY^O5~kpeJroAyg8BZ&Eqcvra&9`mXFT z_sV4V?_#U9%|`EY08s4}R43ss2LmWU^s*Eh*4x)8lAr9|yMrN{5mawq1KiRgNZv9S zKtC>we!NPK2GHFk=Rz@n?VB$`(Ig3Rjfh9DELwWIZGwpwv&WWb9j7JwtWsnp1*YRh zpSwd|v{iab%lAxjSkbR$#XP4{9EaZQLEw2aOlP#B{6c|2m?+2(D{&;OT#^p5-9u+O zWZI2FpC_5NnrrLw9y7UfZ#$&YZ0m~&>83RRok}h=%V4p_$3|Ph{zlgurjP`?j zRG=CH{;=#7vp(nux$&B%QNI8KF8IE!i?15R1d`@0p{)@p$i`agl}YX5bhf18(bf z4as&28Weheawv~3Bu0Mf6VEv=80RwS5@r_n)W|4_p8be-6?qsMg>hlcq{K^7(W5{NAOmt6bY2RE4T!|;_Ui4ZT?Bb$xNZ=>aT?!?^lyS2pQ2ka&=vF z4@jsfjq&?$IZ{qULKEC@95OGk035#VsAZhs(VEQvmVD*Vw0nKXO)98S;ax}K?Qoq# z<~E{;eTFma+PBuADq`2!Q;WEF+IMJkVtD&}X4b~FO`F{={j1oILwx#XCi;unr)#C) zb%sA8v0z%7XoOCX!IfV7zwRJI8QCs_A0(jxRUxO4oe%mb{zi2?;wHHLP0SdB^Q299 zeo*SK@ZuCsnehAy=M(`ybZ%P7V19C3<2DaIZzf5EP|YPoXVThl5{q>PM`vsoDSFZOgy(`E0Tcm6zG!epogG(D?A{a*pxOH7M=Cl%F1eR&erGfQ@rjTd zc)iE)z45B37Z^z=BgUP#d<;F=-xfQrTJvRjzPY%C8|Nrd)%ULH^OgtVVRmP5yMz)` zHZlPeckIn=UKh(CJc|GcJJUX8{VEDZJq=^6?OKgcrzQ?7S zw%*haNMuV~@NpFc`%%9i1n9yZHl>w5Q8y&saF z7@8ZfZ;ctNNST^{>79>xOV(@#XfC@bv07)%XshY=l}4Yd2TS^_)oxK8y(@edG9B4)o@IipU5 z>$Tu?^yP?krapCc-y)(dE^|+7v3(LyI^%r(Or8mKL0wXWX@R*fiz*=Ww5FtbX<@DZ zj@hD)D3%Jrob$~Y#E9v}wu(+`)j6}i%x(prAmsGJF^*q%LK7l@B@V^viJ1vvgpu9t z6}f;un*eb7WG1i!rlGxvv~5Z*7$Y_zA7_V8f5;w}2`xp@dN4N~t@;TDK^kPsN!ISh zW3@l;~)d}r68Q}pM7mtTAMmd3}ZKbpT#s0~u0pseZ|Lz6%p z2FaTHJqk*=X8}mX?f20}1aTVq*A=gS9bq_hRi?h~*jEH#t?o_|6?`DsNmCYAu$+7( zZe&>e+FZGj@B&@3`Rn@H3Vs)G>|QDd3rluqd6^K5XQu`SEa*_rWfKMkCJV2wH4l?S zmAN6poLuxN>?8t>?y)#9A}b!NnCB0#hT8WKUm9{Zox+fTqCnPY$Ju~|#4jlO&2RCRe`kS&k`B!4PYR4C_MQ6h=j`K z{ku=F}rl8Vct?bP{I=*h(jzN=|YMNK>wpG^)a%+ui8IziW%o zScp7Vo3pyT5!CH<{i)K0ym_BsB^CU7q`niNjP)UZ1Mewa62LJwt~r+aN&n{`rV5wK zQeyR!S(it_X94LuHxPHkn@0&03CouXH-fZ!dUz+iK3#St-hEPWKv@f|+wcH#niOpE zpi`1_^B(ffa(?>#gNo(~4>y!Fw5r1euy^D`j)FeEAKFigN&dJ$6Gh@yRZi$Ml;z6{ zOF)3i=!?J0^I_;Hl=!s1X3f6J2N4t`nA5H*F5VnN^zP+sRnh;IjU>CjbG`?hMeqY-MqKm0ti zsO(2a`&!0G`{j(F;N%>v7S*QyDw~|gaC6Aoy_L+^rQlX+=@FjT)n&r*`AOF6zrY?b zdm^OHOw08ub|bwXvVV$IF8qc-llV$CC(!=^!g&1v46oOGZZ0FeikBF^Ma+;0F30}s z)=m}PwwTc-LPrNASj%*&t#2&(;;693EVUfRcX}O28RwFNb z;oBTrU~X-ox>kb)4SIoQZ}uBCA~qkxQaq3(*f*-f>O}s5{c8t7cHSY#@S`v%7ncK+ z!S#{mixP`{Cca$#pHzFUAg)Zhgjle0ac>WEVWJf z8rAiFV#bIt&ob_nxL_aXi%s-{IL;jBlrf3|dMJ3=%d>-I@e|#{xK0|{?s2_eg>nuf z@iQ`jP1D`OJ5)!;DEn!v`{0u_%K(-M8AGhuV5pMf7);o8 z#;SbcN><{@8m-Z0U;2&o$aFor^n2D%UJoB>b8!H_OcDgbc4)~=V#QktT6|GOy7j$> zs-Awb!!BRG^P!4kyNq9fi=5x(xMO*v)oRJi1C zwb`ug8&ju;fLSIm0__b&bMLvu0S%?bFDW_HCx=7}hAM7BT#yMPTT61ZGW}Z}#3D5v z-W>_+!V8FD#ENc#-o)#WHl9N|Dm&e@o?1W=rZ&cnZS60#?>d1wSw#{rK_~lfb5LS0 z<)YkLdGz#{_j(w@uRu|k<|14`= zsI$SBnMjFFZ?>Z$z@8b9A)6%}{k21gqB2M9_~tZD0pinra9s*a1NL?SjW}{W3yzZsiF$Bu_c(! zM+nG9KW4n2aDGUIbMtxev-q}wAV*lf&;D4^a*QI&6+f%|1I^{V;Q7}nY2&-9XUo@o z9SGJWRw=Mn%9bdZ%qNIT&`6X1hoe!R;}-YI?$%=s1LfM=_$vM_`Y$5{e1kWqynfe; z2lP5Z%A(C7`gqN@)L?Ob!Kl|A#D9K;vx&VDe7E#sY~<$BWLObW{~=U+R*A z5z=86j^x}cZnC`PfR&0ZK6p3|79FCHLrD6r!fuUO*O%1CBy8d|-p0SEe?chw{oPk* zcfU;+ZT<3PK=Y6-w?UfJBF;I5AZMN}rg^xU9_L&OJGz#C%AOicA_slnXqXg~n3-=! zly-xkb)6;*3FFQy)0gZ(Rdc<-TN&!R+V9J2&=jwxN-TKM@&HX4>83uGI9?G_!OqSa z1bu>cSneY+XcSR$Uu|t|T|GQfhKH3K8X9_+mJIM7+|Kk7Lecgc{5hD9Rg7fqw>8Ul zcXe)vPhXvfT)($8^_aV>RC%dT%Chj^Z8qD!W$er>#RunA;y60@#yq<6ydY}Uzx#i! z{f@f2SsF!Cj$qoTB+ZL8*$c>tniwlM++131r!xT&B?$3HUgU?wuZ+_`{YW4a(n_=? z^nVM7N0kLy&P5Mm%%rWX%ksw_(=9A5zomHaRUfyd2j3KR!gU(sh4h@XO;0}5gZEbE~n4&j1A<_ej47gP!Qmv zS@uu??N5H0w^Cqww!?Eob|4p?aLnPHgc5jW)zyNDe^rqu=HEZQr{fUHo!1W!LbY?_ zmdNrWPe4Hpkpf$m2aw*|tj)ee!BFTzE28@$vl0*9@}P&h4T1nBW&qeofrds9ee3=V zr4+t@XPg;+LV)cfy&1sB;jLe9RE{5)NPZ?~S8|7x$7X&_~1rnDw100vw!KCVRgko zzm^+2w231-6_L{0GDcK4X*W{PeIRg}cSki1|NW6IX=0F{{z>q^jWrn^;eXVK`#O#n zQg%$Rk_Zx|uxH;Mm>aRt&~|ktPFfqU60zUoJpc9_MZnMeJ9BmQqAPjto0K=-%pJ*G zXKb9JW$k!VB%W8sKl^P(=!EcDz!ns|ei#{^yBh!eYEPa2d9Bwo|0m1$btz#u!QHEJ zqFcQqDlwApvdPj?hhZte0KxlvYty=x`+-GaQD^kYw9&okBrx5UE)r?EI!gjpeB5s< z4OV^~&koVYY~3CkiShJXZ^Xzr=ZjUKZl?_tR-G5Y=n*+kgvYTek1Fy@sT@RL=zz}6 z>Einb&Dg4d@UV7G{-R9cU&Oy(L1+d7m??ojb1XEE{bm+Y-kuwyeKFb+tLy#bN>VC8 zsCQ3$c=8hPI|00k#VH19QCKj^alF63sJgs8*4FCRvT~mjOZA>>PXoc1mg*zT!*h#C zcC5U`gr7FkpXW0t+kKpUv-b_5k)TLXGVjmB>^QfJnQri)E|NU1xdVWGa79C+AFN7t z%abzOJ@21PTUj4Z+g31Tmw-PY#Be`L&2Uqux3zW|g=HFF&1X^T;q=G;?Pd91?~1U5 zG$%=1IFk*n(i#(?L5vrRYIfcx4ee_>61W&fFX&OUIF-?%Z%O0uyX61H>~^#|TTwfY!!UxU_(WZ)TcP-c$QW=E7ir z!`y#NLUthj$8_X#a?=9lb|pFo23R--`g>_#c8Qs2_jbme4&m;H5CosMsdin7FgUXQ@xC+_Qg zQL=v=_Wzxve@4Oz#zT&d#0~!+!%MoYAhiSgdV1=4|H=hR8EQrP1!aWzg#|_Vg{36< zAxW9&>kx>?;gjQIn&4##aU?1ol@c*$xaAkl0Wj7oSr-gSv361N= zNy)^L6zNzz7l>3jUY6(}eL~zvMgEGkJUuPSg%OC~z?1He$vzx)TstEtf|pTO;QtxlpYET9@(+M|UJR>C56Qrp7tYQEtU-1757bPT${8=AKz z#I#{vNvnn;oCf&0iN2WEGZRPz*+&sh-xj4$I%kiSXZZLo-WCbKp{W4mtU*6PB@EsNAjfwvTgU)yP z-wk$w2dj&l7;VLnf+*lwgMnm=4rE2v^MmTj+TOGL=D#^X@}}TqwzpssmsrF+HJ8~a zg4!4$DI?QS4}!60pyBe7<`i)NM8))I1c9#?F-pb0p5nQ9z>fN_Y2k{v$BaL`c(RPz z7NG|Tom_*-R%f*YthnavkyN>HSW_kLBD)=^taE)rB7XLa7>c#Cq-l#h_DW~~85tSq z5!QcZ^RE<^za-K?#HvtXG!vTLZ!dShE9z`MmvFmr;2t#r2Yn|azy7-jme^UatW>N0 ztr7LP#fRf<0F0;a?+m^=2$181<{}tsgc)|FL5|(Z#K^8o-qw0btmP; z)Pe61u%XK&Zg^Bmh)&2C)bM_Z`FU5#^Bju&qe!M>VaGI5X3fPTkclzBY$b$e@7(G{ zz^XhG+C}QM?8;;4ANyvXjKI93eY9gz=UA%Vua8r=Lb%850QJB4n*|X&5Dz}u%CbS- zfwXZ%C>te=K~k!pAp31TWl*%2TEPmIGpkb|CCG}Yo*mo3>xFDB23S8)lE-kpYx3`+ z=qn8X@~t_(S3Wben>IQNrD<~oxaxXPc;>zdlto7EzUZygNboHOR z@8A^X_3l-=wP83~8~*zREGQup_QXNR^i4u+A(Ofqvopg1^p9*ch)qo?O{T<SkT0GGX-4mac~Y)YnW?s za_;Ej&DVwZi4>_2tkXo5f$%S%r)JO!aNkDZ-b=WAh>2UFq7%w>1KVR>`9S>yc10gh z&U+QS780H@B_F-Rc^dA3T6(>UH@<%^BKLIeqAYP_dVlx(>?(TeHX-DK3aWxcAeSVc6@|lH$7;D1dN(2?;w>baX zEExyjPm3HwrskhqIQyDf>B(B7^;<5ztb_;kmxzouPN#w4&IsSkW-?E{FK)i$Q>BwI z4w7=(K!Kx0gKNW0A0VI;bs{jJ?)qNa%phOBMpA#nm(FA+abQ~HyOc?)Rh7nK#Cm}BnE`Nl|D#8Wp}8QCRIX%k7AM~g3b8HOy2w7!2eAP zF8;*p;>JN+kx)q`^!rZgfnYY33zfG0>dGAjbCsfMzR|7iA&VazVL}Da1>&c1Pfs21 z15})pRMh(DWg(At$p$Sk?b0~XhoUX;wVKjU@*$`>1Z5rT51q?CV+{SUsI%UPc%39aUl1uD^WV>DHj8;dGZO zLf1q75Nc7!oESgOtZ>#rP=H}9|9x5pqsHdnI>=%TRyQruj~H^z1)|+Oam^N}DgLRG zHmOz))?oScG^!}yyNY*g27-l#s;Hw}&Hd(58RcN9*nhl4Gc`{J?>xXp^zo_PZj5D8 zQM@JEQHO1vR~l`&F{ zD-WU!_}++XBAG8w zUkD*qBvPkFkhb4$s&u}4|(cEK=5JL@RU%mfu#;|z^%Vqwi1KdkeIg50NOzOHT!&_ z?ks!v{7~mC$6Asfbg$|}+JXFckm7kqQyadYrY3;RY`}%PkbnaBytGTx#Uebug;sM$i-W9)aJf;a@SfQOflJjUOT|uSAnw5p(wV3xQA0 zegchcXn*<|D+7or@6Mlv>Y(bYr8-@6hJ}jH@FLnWfn%f2Am=V&oN{lhKJ6K#LRHA&mN4Ve4LEBfghCTz0|FC{nkvyViZzZ5CkO#WZQUi}t+HUicQH;kAu2&Jd}j*H06jn0LYhA>MAW^YpY$AfaV~VBe&t;{;%M z?t{u4Cg9bDX#7D(>;)$ACWGp~_AYkfbvxvj0>d5TifcyXjuI{gtv8 zD)Fas_Q*Q4dshgKuLdGxvXHMC@{^)<9i*>b+Q}OHAl}>)Ksc|9qXoGgZfS_jcmUu= z1a1csGj557j=(}kz$A6j!ihT+-$oJ#E6wt@-^19*sRA|W-7wCiFTXe|r_4o`iih?!8c7kEg$9*Q9W ztbKP@lV*ty>wgl!80YJgn*q{tmZ$6T0B;iQfs(kik_-Pzj4bjXeK@|%cowZN4=Q># z?zM#a=k@6Si>j}RY6DujPJ(-IcQ5Yl?o!;XNby2(2`5n^;!bgg;*y{H z-QI`)A&*&ED`#fT%szYe##@OB0uctK3`iudP73vZeCPW`pXIHYERH_r=P;VC%3C{m zkk5;Q1P*!kcMxAE)mtl_J1Qx=+$DksOX>Y#+)D><;oSfXLP%bMJ#Gx+wD?r77rR^m z`&3j_V(0(!y4j$HoTVEsA!#NS{>xpgAV2K7mZ_rRsVy{_TLa*Z9s-l;K2Q; zvQYBP`vHZj_}2W~1b_I7hJ_1jZpL!Q?2Ofa+C7mB^Hy&kvm=IbV@B!Lth(#oss|8| zFAe#H^}}u-9q6H*VU2N|8~DtI66JAGUe!L4_hgK>|C1P@e>LWy#cgi}4iX3#szh7p zOZ+c)8vau&AzNY!E6oP(*h73SZtk}n{$NvCFg`sa1L8S=O86t`dbO zK0hPiKO;`ZC4)^j<3Y)}--NSGpvy@#*Ow(Qv3*L^rS|5w$h1J^uj|96wG2di>?D3F z4xUOzC#y~x;*WizGECywDIe#fJ1aBQSSEg_jZ>86_2l|psEodkib73lMEtp4v_SeF1BF$K4rHoH=?t{xO> z@p+?TO3L>f0K^$f=4Noei0k8$sM%OJT{`71=r72&b4zB)E(he-Dm9v22GC%HXAtH- z1kDP{T4JvwP2YGuo$hUbfE>VnO8#&fEzJ3en3t_-C*sHlzrn=P5JQBl)Y)`>MU@LY z5JM--g<73KDJ4YF|MuU%`8I}$gTuB0S0RnjU=3zr$R_1qiuFZmL_AFy)G<2=FRxe5*)ihh;;*SsysnbXVjTGK zZn&EqAUebZ@e60xBj0f;{oiWmVe|f)w6B=jH7?Ul2IOPWNxK%3%@Yd0xYF&pJ|jio zxhW$)P0_QbJld!M0e>H$D9s3pzq|e~`~SZwzi$#*AFGaHcsT#NA`e`hpD^h z|19YvmysG9wzUC;qMn>6qXwiEqE^NAShc$z!#%{6axD68iAb411Ys}`uwn2KPzI0h z98fm`o3a5dI*y0~$2A-Xhh`MuowyTkRpAr3fzlxHqM5IaMkZRXqH4gAkj z+r69fKtHFu-^UzFViaN?jzu`@{hs7J%1 z^|Z;N!-Qi%lb85@r)<{IEV@Djh&&nkkc|!)_33dk{v!Vl``PSNY>Yp1z*myOoQCL3 z_BdodX5}Ri0bm_vM7L_fGvde2eklNFriG;{C0OL+<;8Vv3p*qg}_veV9gDBs?2v0o^k>pDvy4>$y2jphwWm1*vwdjs@*EL6@JEQ9 zdAxR)5-KRm83@hHDHu`gb2*HYG3#FGec5Xjo&oTa4eFl35X6S-tqeAIK4f5hz@viyh$lxUH0Un5CEQN$(cm&lQskR@d)I^+|*ANB24oIR~+ z0N`!%4Ckj)<=I$}3m%EdF{Opz3YsXoYP_7<7ZrUK0$9@y*P5?zC0?d`&dDbHYk=y> zi<=S;A@Mh0$nyo-%Yo-8vMnSFASfFDq(YSbcS305K}nt9-aWUAn>fDMjy2G>F>Di!b|>Mtg9b+6reLL5S^eQ z2@#{Q2ZXgxyrEiehqc6k)h~`Sa_MZ!Or4~~FeX#pqV)-gP^4W>B0hmc(qCSvLE-&` zW6i0>nZYsnL~7Qx=KT~%1W0*wYdWRy$X{o~_9DZTiVl$&*4&Pp%R7@DFK%LPeY$>O zpU&U~9a^J$(XdNX3?6HX#+{zBH30H~;{GIDJASU^EBkQb(tWk7bSnlJ5`%ICkCBC& zHGn>Ebnzb_`4USb(q}q!YxD`E;$7c5ApMen@b%x$zsfW#KGpuqfCjX;iwf>XU>s=@ zSPg)d^@I8+P>LNDmjw;?Z*?DHGfpI~B-RRt3|R7wS_Tn6SV#77+jt!X0xSa^I*#K3 zZ$jT*Nh+A8Q7u!{dg*xOiD+ME z(A(&t(kufRP`DsoGHbwxJ4#@hi?K4Ae2*pyzDPkX0fC&p%DoD77(Z=vbU(y5_Ay+& z)b|pK!mj=;A`337U|PNns;#-)3h%3-W^gx_in*D&d!SnVlna;b=0-{|k^#s3aXmi1 zmChI2a?ki*zDPK|9mU%%hs8%}2SPZI5f_o|uy*cO>9mQM8_RXYhex6zssL%%WT;&& z8_wLvo}vNvUkeuYUMy{#iFr)s6fenfHK%Dl5c3qh^Fvp1h^DE*#8vN*2P`roK`w-O zPcT|lwJFp`%48I~P17KMEV%&X!SsODIt?z1NnP@%tR~w$#LoigIw1cAPIS^L?LZED zsHINN5pe{W%AEpW^)F3-CNqzfRF42W+h}fUCgf0*Sn#fInk|dV#P1c34B+Cl{=Z@` z@ivg4!u{BQS3LgtEsJc(*BjR6?R-(h3AIRmhE4yeSw^$JTA{-O5L}n()z1_P;mOdy zR6FCr?VF2L6T+V1pfQo$g!DS80ZJtxa?xb;WXJ&+?VQBF&x}m9%E{U;T^9IVtk6JH zT_(6SNpOy%@mVh{6lDvuXPTVlSGHe~8N=d1kXsS}fCIi5M<>vxGUaB5xRf8}576h+ z_udMwkBwqhmOT1)HqS2`q$25QGxyLE>V;*gr5w z<;?Xtuo!@$pkLiUD&54_rPo&ATSR@Nj99yDTyAB=zexr5@$6l&4XA4}z`R*x`6Kid zNkBfX)5dC-8H|IaKTwEAR+hbZcc2HWfGPN8ckI>?r~Fh&b-=bJoHz#Bvj>g6HkwDK za1>PRy@BXGMojmAg<5Kf18!YncxC&5(<=gjmOVAEO!_C;c&X?RyL9u(ng6yRCvOl^-4I#aF(nFc&f2WxORc`UlJCO-_N@;- ziR7XRtvXM6HyQqxFz?n{hOLy8jU-&2s{?a6;Fkz({!HuEK+TVNEYkEU(S$u%ftr&b zc=4{8GzexUH2#PxAf!o!k*Ll+__(V4P<9h&5o3!>@eFo#nf4zJ=YZ^W?_(3oW<3h= z-~D`Rk>6_O%Kv)0BpwM#pZJ~BPqu~5DDne}**9}nfEp0j zL{^TVYp|JQp9S&>Tj;NES%5d2p^m`!B~Hsg1;x<%(;cG}^V!s9S!-ClnD6KI5z#g< zQZc~+Zc8om)3F@dx=&GKO9Ex_k?#T}o+bove~5awaBw54r^E~Y!)!#}_RPSt8zbxa zW>JVgDV7e)`6bG24~*OQz%F3)gm4&jeNiATW5q!}fH{AN3Uc~EIfzm^F*P{!b1!7DDW`83HFcow-AH9ujraW5>n>1WjR@_dm>hM&u6kr8J)nFF z^q`0BV)!HR@@eI#;m)T2-@w0mN&9TfhmWj~O1gR2cNOw%=WXz1D{{3kop21bo_z6l zcv^xJVp7r!iUmc`vpXH45RX1PPUVd86E~Qa1M+tz&%aYY_#7Lje7e7S5yxzdpntOm zB}k5z7gI=*mHL?{PY{kEK6CxejQZeqUpxIv7W35G&Psdqj#nUAhe1!CU4`B7{y;fh z@UVs5Chq@*Uk-;7j08Ar<7_?01~Ef6s~Frbi?V{q8+^(FEUI`xd!;axaj2c2CO4zC z%`#&gV^nbR^k6*yR>_+B^OB=pj$07R$fXNtUxl?oKT;SdSU9gZLhW zf6(ms;`vD2p?(?JJm+2$HUTttWpM<(ykP4^{X=6$T93sQiGmC6&1|;B$OVmo}(!w6&Iy+ zu9`T1MtCCb)kts6w0gPDl8ZEPPLGUx&Ejv2yaz)b3YLMJXaKSqhd0vee^NEOOHoP! zEI#9uMnfd2E-e$1Z&rcFi^t1ru%;u_&vu3I9P|vSiKKV{2uUzyaTngV$1fRw$&$8I zwxsy}0mFfBn7v*|XlDC00TcvsO(o;Cq%W)R!n&l%9DQ0J&oS9o_#w+>%#+syWi`Fp z@0`96n1XpS`7PE`nFWAU0vBpt4G|i&-PaG>p!RU3#hH#;ENy+Tbs6 z`~8Apzw=ozMv2qSX(-qQzCq`c423zz%L(pJ+okE!lE_*$aAZ^y3FmD2@|0 zvl?Y*F=qhntS4^!jbDDA06TQsu)J^y3}y90P7MB`P3w3)o9W7-P{R9Bf(COhq>nkg zZ}Q`Gj_;n9CIB%wf0W=DK;XyaSe-%y{e!*wJ4=smrr`W3r<2?R_4hTy*`paZSaFr9 zqR7!oKQ!-GZrlC>?CJY3e^2KfVBdCDnRw}yJ7l}RkBYaf{b9x#O8-;tSZo&wkP=TC zv9n11O@^?PYYnXrk0Y(&3};gr9~1ClsJCC8tI+{&Wf}cDRUzh^1BZ?MC6v%<$<|8+ ze97WkR}2}0V{LP2kDyP`q{y7t<-Q2R{1pReQMjw>1 z9MzHP^Y$W1lDNXe2v9olIklQ3Ani2k`o;1|5|}S|+{zZ(4!`TTV@^5&-o{qQOYj^vt^9kHfHOB2-9Hp2o(hyy*ra z4&t5O;sNXg_y7D+5?Khu^mV`YWKV0;TEW1JSF{kDMQ_Q8dEQv&6YH<>fb@|%zirG ztPi-~Rl5S1)irf%*&44~QAYv-sA|6`04PPCE7c0PrbPp35O>Zc#nW;Nn%wP9)~9&Y zOuju?rlY>no@|^M8S7s>1A1|PM%U*5dar6j&g%YXPe~hTam6fC<*q=p)YULNn?Bm2 zu?-9133JO@K%A!qkdOo*Z2Y&4$`Ns%RmTb6uzXr}J!yRaCoa=zRu-bmXpySG!%B6^ zM5!<8Y1}=>_vM)ZE0|G9#hJAk0}HSuwcq4gB@1~IhB{I)q`q=Tje}An6Y_@VQ~m#7 zEOqW5clV+JP+^@S88Vew1q=-_%n0Cx<1u4LC_*8nNIxPE(71N4GzUI+@r%~-)6<)p zoSu?u)j4PbAd!kyRdzO(mZVJMw3CMBp;84LLjHzitO3oK#`X2zzUi&5`FpaZPoRYb zUp@GZx7J)OFFRJ()lue{NC@Xbz_TCnN>XfjkINTkT)gfpl%>(R;#sxRs0tfDgf(<{ zBa{+`I~s}#wJa|b9(OKoK-E{*1ELL1PXr+2;^K;kHQ7_5(sao|oEmhDA28(P@*0}1 z_uh2uJb%=MB8CQn{8krC$N};_=OR8Q-bNPTT$wMUzk60Jn~gAPt>z3Jnb$eNU&6y# z059TwH@_h7fSvG&VU#JyyuegQ0x}}5tvft2^hF#Zx$_ku-Iral?X)~(_r5O`6*p!g zF7$&v*LzoN@I`N-J?K06N1!q%;$JxjONZ6$FA~4q-2-! z-n-JtS+D25S6*A-Jv}N3)J`lZUafIPTs}xZL7MMz4ffuA?_DH%UpYV9I{fPt>g9i5 z(~KwnPeT2Aj6benZO+xJ9ZvgO5;qEO>avXI3k12P`rRcOE_q)Z=?j96{D(E%`lCW6 zUM)yys29#VvWn$R;pYtVtszJG{K86G?OpjI!WC+JYwp~RyVYYM5m<4eP3uN(5dr<+ z<4zZ2gq4*Q1{@N-v^Tpp#De_hz|YB=5{%fjLdY{+5Wn@?+uP@eo;(NJ;lhxrbT*4Q zZVExnuY>tK_2!*s1a1y72SkXQ-O!6&%MK&>eUeUAcAn2Dxt>U0(-6rt{!k14S+tp* zGykfq&cKg2Xxm`o%={_0d9am5>)k?sq%><*(6JuO#@2Gw(?+Zjeq|rv?Os-pme7i# zdX^N?hFWwwZH}8>loyL6Qu(43wM9OR#M{t($R(L-|iY zppX?LrB9$BVS)yF@Amc2TBDgb)4J~K?6>!&2%2}V-dS7Ms<5(*s3IsVQaZV9&Kua- z)fCoMO%|W|%OdzSXcSepKj4jW6l)#c^irWp0irzh!6YjE6rsgP6!|H)NVPEy(-p)a z1s~w>r83?IuUqW*aTVh7d6GZ7#DD4+*=j|_w0O6r ztse6mt2lU~R+?G+BXa<}Si(K!Gx~hkwyYwibhY|{Y&CAEj$@W;lIq@!8%HvCOVsaQ z2L0Jn4xEEILFQ)y`|HV4AV|um4xO&|xjEfaV`Buh$BnJ6-*+d{0fnW91ZkuNTJJR9 z;Wju%D1N|N`0NcmL&JBI`+Z?bnG@qyBsl)uO_Zse=F>erGJ+62+#uGe%Ep<=je_F2 zwBDNewGvd{^O~67Jt2Qqe!PLPq#W%)HyrYi#VwMoxQh(t4P#<*&dfjz3%&&e6}^|M z;gu_3pPrtko1N88OEZ~aX6+$>hd%Fnd7VD&(^s{T!F(Ww3V7i5v2J==df$SV7Muty)m4q&Gn-1tlfGC%`Ih9p9zilLk5 z(66d}>7{B_H4UgiN0ii(k&WQ(L>tDDs5{wj8}qBeA3e{s^rGwNWFD-;ST{;d9V zI4}IYDIH0ATW~pmhuSmGg|@7uOi z#zN+Y9q=p#V>!s;DaWh>x64ficgx&_1FlfJ*9mWLmwS0iL5fox1V;S?A^pGcNlrF; z$|*iTxU&j3pfL>5KhEzos*Ka6)egt-S7X*IUZ)|`YWJnnXEyGO^`=0={-f4e;`x!97HjvwlhUAtQ zy=$Ne3WQ^&M`;Zlh5{-SzcrCK=kn}%)?4OUUa+ku(nW$H` z+Ev9CRLO6G{TU+nA^5vYq`RPGTGMh6D(0BrUUC87(8Qb4SQ8qi?CZK!uy`mFyjLb? zz0P2{K(z)%%7ZL{d>F|~d_QoSkiW~evoL{epxo;5c*f4mj1F2Us`tK?bqzE(*4D*e(?Kxvi~`BEeA-I{0huzo!)Fara|Bz}J1{pB2?{GE`{M)~hs zJ-znNwJ26ig!2o!6~B*GYmJ1i`PV#>*VfQt2vvgEk*#f*s%vVtJJH`K+c0cm;amyK z_XHLgWt#i?hCDo6j>SW^`F!V53jI%zlZ|HF+EEW5}_tu^E`*ntrHmp$&D)cbPM9qrq>K-L30rI+WR4nJa8)COVC_7lY z^B!g~62Hx2DC4@^yNsx&ySy4ea@0b=$df4lh`_hI}$3&n^ZTW;)+yF~hUtg6ltR!Lw} zT);FEl0!2h!=lVM9e;I4K}KG!i6RMjkCpLC4?j~YeWICJx_kO^{Oj={M7efM!jUN_ z>s5Gn!c7WRyjL~ZAyqN}RP_BRUdX-hnuqhH#tQh3_DMAVYXIL-Y{o^3JtAkLpp=za z;B7yYv|;9WJbQs1Cs>?8RbR6f_tuu%x8mg&)=8p8M9dM#_nF_ zc(>`6Wd0x?qzo`^lxsBp&adqwrTLCk)>N3}P|thSPtSwu)fie&cE6xlaZ2=6Rt83J zStg)=RKJ}6YdOPvJG>mq(6q{_5Z~#wSd2FsUxFhe%m~vQz-o{o`wJ|2X7Oz_aMb{o zqTSi8k=}h$DC}>$;7*F(KVM|IT7}7`CIj~-11nhoqkxDAIe;>qw?Ez{$5`B9^Iw13Du1QZJ3erC8Vr~5 zf5lzzqMr!^)AxTr^GNl)UgYrmd%+FxwtMRQTo$ItoyoGDv+xt3bx2A9$`OfW9rqWX zlt#+Hc(1i~J{(khg7)amaq`!P(6k5rGU)3GF`Dd4&b`pFz!QhHOX3zteq4moN>`Fk zI*BijtT&G8a%-u`(>Y!A%^8WT$Cmu$?EG^wcX;~IpX;h~Xlj08Qc&ra9z}&1yY>BW zFahdgvjKcdxR*(3*KOIN3JCY%fMrcx%%5Ag4@x^EL zgw;(_N#g7&_1({z%iUA5i+-B>Kk0_8!!!WMFn!EHwG&GKV$y99MPv)=pPxQc_x@_E zZo81{tT>jx^z-={I5dnkX*e<}jjdU9+{Vcw23-fe_AP7(PW3LnGD-DmMHCTQQ1_9rGeE~tU&?fL*R~Dn89;iG zwqLU_hlRgOxwByYAeKN3N@(QQ;a236K+L5O_6n@HRY44z^r4%#Tsw+2V3Me&b=8Vf z&@{I!e;vnL`0{U>HdcAlD8zYPe_o7}XOFDRs$Id=Y}2Y7B84yuNVg;MZ31dKkAaoZ zipF;o6cQ;zWWM3U&qE&7V4{e^a5bXw+eI>a;nqE0=k+@x(;$4gqv;9s&7U~_P%KIJ zqFhuxnBh+K%9WlC?nri;0Zavdj~X>Lu_osn!@mJ|^m*Atuk#X#&s6#0BYG{%{FsX> zmU6E@8Q{Z#o?-o6{+QpOrH3z`N}RDwcA%kDv7kKoDbC|vj0I-j>1y!+UGZ2qc_2*^ z1>A)Pz$#3l)L{{b8B4(4`RMj+$l1v+_S}$qe#2o)$tvpS7yoyPEWp3_HJas1X44~9 zl?p$<4S-{@F9V9wwnKst@|&)zLv#B5ngswHr!Eqd={0aR{H(=`R6Iwn=AjARL6HSu z-cVS@9KN6xnvlzg%B1|YFYfqgv`E8G=rRsTQ--TDZOjjY z59Rj)?=WcLxnq}h!djAa{)(7-+1s&oWY4PMT|ZS!{veqSAA<=mbmPi9!9(|cWrXvS zF#S`&Agr#~Z>B+k30W$Q>xnw+tl;Z}$99mf^)mh@E3cU_Bk-!`{&?9CB^-S41Ko1& zE3hD%zjC3sG}~9gwisBQm52JhH|owumY~MmB=Q#>CS{tR>gGaE!IPSYTbpim)c8aYPo@t>^~BjXlCbn^8%p=5bKa&;skRaMAMm`~YyY8xk!zegGVb*Pv*0X+ErK zNeka3dt{;9N#y|w$L4B^vgo3r>A|p>?tQYiooyrc#g|-B#F}|{4IGIIC$4WmrIeLc z&UTCXeC&zVxMDG1(_B&3Oq=*^J{$kP&_uNvL@x+52JqX<=lP5Y^2D~W{***U(-wbb z6p?T|wDIA73G@L@8RPgQQ02ZG8888W=(GPyL>%hvkVXLlv?-I~#+0ZKfg5!D*qf;U zEzZ4-Ptw0IWB2gF@cLRX`%^rImBbMRgZhqj^T?)iNdgZ()IKwnH$i=StUmg9`lN_0 zG|jN>g+y7P!0ID<^WZ7_?+8!0WSp6{lP_uFUC`?t2+tkqqF{fV#TS%IA`5-|44^bL z#@>1MBZ~ozV=q^_gf4!9d+(5B2{4mCh|W)uFk#5ZZOzGw!KN7}NY1FIW@X6Q|6V~u z+#m1t4W)?lWW61C-LcUVyMz^#883?@FP}l>wn6uFc7~7jSoS{UWC&@|7o#~2jr?Ry zQZSQc@zdx>U+swAyxL0Y6!Yh?%4vr{`zz7xVi!!F6()Qk%cWZS(w-LO< z@IP*wv54A=I6=S}Ypbhhv}RNVBJX#}h_iArU`q+}^OqR;4-yvCVlYu!IZPbveR<`A zl(4Dqmirr%=cXUxww}p6u;kuJmuO!xw|>ZB$(v5w*!Rx6%VA(qE<$v}ktzROi8y$1 ziJt|0RwD%1jCWy#%t?F4u^$g(p1{F~J^b?T%8_4MHt^FE8oajhjnH)gWgMFnpBrXv zUr)k`%azroV>61qZJbndk3KRXM9uMT>ShK@Jo(!)^L&DZXhYGE!0xoHfkXF%s2A2d zgx|8+_@SK$B2gyQ%DRAlbZj6K&7Yj0imM?^* zDn!k14YGfl;!SUSxnU>q-dhWKY=O5Y4MY_xe#O=?sog$W`Tg_Jq=?Juq&g%eN1!ym zn7rRvc$DIh`hm0``-=0Hj3e&I6-*zN1=(it6%T#Rh?) zwE=g+#^orI{m98MdN40@Y5Ew|7SHMdvE%T&u4N`fgqhbpC{T%@|GZb zFbTinSER#;q$@Mp2X{>ylY^f^A@hisz?g=_N5Vm4EMy+Q-bNvPn5NYegEb(fU3~98 zYm6D~+Vjsw-<#p`e_m>g-`Z$#693+7Xn4Y=CIL7#0gUxAA};d*o^-k61@SM;1!nY+ zoEZ$BH7|VeBy(hmlDLLYu?h)Ood3Qh|B9!MCZ-l_&>wwz{WSm9bDD{n*Y3NIYCOj1 zC3Iy!7sc!DUS#PB;w@o=0*gd-kR%Z!WllWO0feLGbTpa;im#uLa66=6N6ir^x}E~s zp%d`d!~kBzuWoI>PecP6^pnR)dINkKJFX9c+yamPE=@$_tPF2J zeS=;_yI!n_2U>NP`6M!5Sn52k14B0%le`c|-&Vh7y$~C#-=Wvj)Wqm3-sP$GWxyqt zM8f;CTTdlG^9fB%*IzLxRZ_YF51qkij~B!&{7&jJFoI6%-lWQfz-L3pMH7H%4n$4@Jd08IQKqj%8k5!i$8hlNyeje%_uv#uh047m18U8eM8;?#;v+nKH=6PRrcbi&X12bAY_BwS=3PB9_da|Z{9?7#WNQC)>CAtaD&>L-cr(pZIfJ(^qFsJZBZoHw!m2c znOW7$k8NNJ9>G}SK*d751mqq|UWet1UY+x;+ks6|T3AHtsDR>4S5O))R5>|t)OAK*>afW}_KMdUNaMJ){wt|FZHG{%aB>Vtl2@ z)?EY{)nDOfyhW&aX#RqfUq6`)eD3kUou5}OO!|BNKYwt>nxhIBVGfM5f`k&K<`!tk zf6So&u)~C?!d8-~Z6f*I>zEqYpU^RI?QKb$DQC?85*ecBt3b)rHc5L7X~mGq7v(!k~jds3(>oV zNnQTH7l{EtqIreLY!RF3f3Hnl%-3Olhm2ckz*DTUJvv!WAa?ahfr+8{Xle12Rjdf% zQqLO>b*7F1IqNOcsWP*-C$6f>Q)f+AXU2L$ z2SEc)DfV3g7WV3~NE|B+U_NS11xnIyeytq32wg@F%;H2WhW^C0k|tt_i#_KpJ+{`P z>S&rt{DEXtJGNZ@3m_8IJMH%gLP-O1QnqP$bi!bScQ1$dn+;wX9T3TJ%9yi1?(JTw zy!~#D{Tg(xP`gXBd2d#M+WpeGO|acydh=(_v0iTZ>g$#FwbY^Ztzm0Qh2ls8lMM%l z2K*T#CvUp<&AAo+ zjh`yl;6Z%fF$*-1>vz7sD@sNjik6(y4Cj-zUynR!Jja*)}ltUs$OYnlFdO}@TaU9{y1Unt3$pPmrnbGrODe9wL1s31$7V9@L= zkAq{&kB{CL!p`T6{t23eCSp%=HJNe9#VLzxYhjM@r-3fPs`TP520)j49)L+e&yt_Z z;o8yny|oVcEYIOo)OTl;fFIPb2=EJ-wx>Tx7&~A6UOX(>kS;#%Obbi461aY~NRfFV zhiHN13ml^u=-VFLT}t|NV6+U0wBx9tn> zr2q3~*rIff0FWr=@QLglLRf-h-vwwK6rIH6bDD%igKTlB6hA&NVxlT*G?J!}N?A)6 znA+yev34K4uHQL)K}nr@$_cb{(~_%R)jJL)>V58?4s6(&`2?kYF!l!aHIq+Gn`4O#NehS=L z5=*`O;0KOy1jW(AguERB_}>4LeT0s+K zxljAq=dQ@0KDx^dvRuUy)X^nV0Vvey_MD%#y0*6e`j#GWAE2&&Hh6KKgO83KTz~)Z zL3Z$Ns<56$p6(C%@JZnE+q(NCD77(6N2ppxG|=nuM(3s9iWwyAyxL>a>_v(!&PhLH z3ZS8+lrRGWEQVA?#yhfdFKLFvv>)@fhp(otH3+7|1$}66DWk6nk<~x%oNltP>5gYy zG(qN#%3;-E)$230$KL_pHV29POwia5P_H3=aS})FYy1P%PUq%RE*Eca>p6J#r{a84 zAItd=0qy)eM)osdO-gx08JQih8-Mfli+Jj91 z)7U*uK?dCiM*{;lVK(+kMWV+Ms78z(m7=^n;agFdZ|}FQ=bw=-)*?9qq2p#RyF1f& zG*6~#Yw#mwqxQn|ag&aH2le8xw^TI<-tJ}vSeRz}1s~~=MhFP7&lJ;wUM-?(aA<~U z-ZP>!PZawm;f1D9RETpf-x`bQ1QZHt9cG=*YXC^$E`_% z@;>`VhK7}%;#17m^Ur#%D4HHR!2Cf#N)zRrIV8WUVTWP}XUZBHswBK6=HI(e4CQat z1mUKudz7pDIinVJ7r0pkD9r~VY_ol`r)o2?1s+hNQdCJXQS}Z`2^42o{#;6PAmz(ug#n3+9c`Bnag<*VP3U&K~~wcv`mPaI$0uh3C#fTkkfs{Cp#VjlDt-OiN3%Yq{N> zxf}4gwAng)^X-$@h-S=M)R&NwSA|AMY>JtItZv<+4MeO?ErmbSOm6siAFf93wc=V2 zE9&eaSR!hPZQ=)V=}>hr$6wt!TzxJ~4txi6xf>t$U>HxGD|O2+jsE@O;B<^BT|jlp z#U8z~Cp&QObr2FT2qvaziQWs}9ULBie59SyMa+Rw?_Sa?Vwc{tzsi>xT?Y&thtqQ_=3EgosEI3C*yr|kUY0MQJ9DvBDlvMnGjwDTF{){C?yg7h zXK3PxV8o!t?{IMe^m)mnk;{Swb92|7=a=bOp?6vfaVq2`KZ$mJG$^RHef;+3E`9)t z;jK!K&l8;7iKyEP^3ZviVfVNAI$ZX}t*=f2&~Dy3>mhM`W(KZN|L9!(=X--^72!S! ztI9Q`L%=}QyG|N6*o;5&<6M>PE?c&Fg0@pH4{t1klo_ayeK83D@am}_y3C|5>34#6 z-!wY_h&v9r=e8_dZ?QS~P@OM4naG%Ks zO~`}ko@s^j*N?>#-u)6q5dqb6jWg%Pfry|D_>A7UnddK8g@IHiCu-oizIPNT*C^f4 zT?fdoH#;jaro=04Xo1OrLqkzS4ty)>YhdVgS0ZUpJKLt7eyrc|mf^T!2R?`6jiPkN0g zU}I@2O8E0xlCM}E$DF)r5j7lPXxzqcv&;G{83x|Jf8Jw!XnQV z>s2OyX-u&|Myn%#H(o`S(Y(up>cw;mTkVI^4@*jMx7F{3;!U#R-i8=7*H$>Gme#O1 z;gI>@ikKyE+6LzBtNQ!<1-j$;le}SNvcDCM+@{B}ZZ_j^dpb?#=lQ`?u`4Y#A5)BK zJa}Q!-94Um-XPW1=~3bd=C(aMp8Z9!Nlh=Yj*iK?-t%g*;oQDI3o?D)YOSOA&4{cw zp#`+A!Ls1gPt?C)1*-b*k3(}2jj#}IL`Vl$V zI+G93@5R!y>DuWFhM1wv-FW@=!`;@5S|R5n23VHT{=DwkDaG+E?kH6EjD|=%asq`~kV-Wz0NmO*0n+ zHRTK3I;K5VeR{D!mps{3NnSxyp1KBO1ncM%)kkiUW^{^@ z=4(%i>!s;u6omW%Y>*cZDInd+w?cBbL1RkgoSQQ<=?Hk!T)-oqsR5p+flq*axO2+- z-EX=o8GQFppYnFP!Ebf*>+6&Y)JpH7f11U_GI4H6&{x(Xzyb4N3h#GY78K z!_)kt4V3<7r4dE@#bbkZZ7`hH0UYU}K^df_{Vv$7O?n5cTZGr@}97ahF_a$ zj@sCcW@3SBq47D#ZN~FV4?!G9#w&MXdwW1S89^eEf^8G0d67Nc8=gY%mfAEV_+@)=8gBI&_$<=t&%dFjr=;)gA|6sl3R|9&D zK5T!#+bgOBTP!Wkk=61LOoTUpq+}KA37B}Bso6}Qc3@H(_)_*viszzZu(SCKR-k#d z;7mtPKlr|Sp}rd(=dK}>v8}b&zk)9lc<}CR;cXYW&|T<}ZF9Wo z!|is9A%5jZWF;kMTHk z*-0!WfYY~FGg4zfO#E4{u1m7dVZ2ZCa5{FAaD` zE4FlV|AsNoyEpSi_W6XYBt)d|wtZBgGLe6Ibc^BY`M8EF4nG~iyPDfA7nM*Q#m*Ie zYt^(kjs3nil^3w~NAolstooZ}s+$E5e-RnZhV`53&Z9FiR|)6tw~42ax2I)Qw>wq; z>s_^ArXtmd__FQeit_NDzz_cUDpMQxf}a!6s8E=+7Q>+eJ)(@%oaP{=|Yft=1!_@ zPe}SZQXGFPzuH4g`W^s~(<4y}zB6qKXKrw{_2h1N^xW#+R66SV`dzZqB;MB;t7OTJ zVJO35iQvoWErgWN|7s(S$NZXo1$v(YZRmQ18QMq;9%z;dP~7eWZ6x2Dy!-X1ltxoB zTMr8^inDwOi=OfDXxhFBFG%7%K=$|SeruYGT5@@SSRix?f?I)?aC3Wy4p)z`f69Xz z6A7rL&p>M|!W^{%(L|{bV}IyP^Ov>B6^#j?KOMUGw%^EUYIPSx^UGi3GXrYE-#eCK z5+eG5z!B6~dNfAZD@+zI`XHMePBr}3e;Y9>Z>fh9o|h?P`X6H*oD~&J?TY-5n8a2z zJr8J8=&wkUk)H?Qk&txcp8-Q4yy|5clrM@}CHab}lF_z3eY76+B5xegdV&=$)tE>u zUAQ?9?K@)>^P^p!{ADB_$u`k|1W|3}n2hQ}SX>)R8%vD2WjZQHhOTa9g-O&Z(I z#A&R?R+GkPoXq_5?EUQbJ&yS}U)QnL@4C6&k7Yv+y~2&(Jh^I3#Q^Zr&3&A4NfjL#H`TwdpmtmJJyRw!KF9NB(<$50=Z7 znW}$R{F`h#jva$*i^?#b^RNklP^T^Mm=*nI_)l;Pul3Qta zH)R$D*A6CByX3knEsvPZYbTA@E4pb=Qm^yvpC#ozXkuk9T>Xyv-EJ#iVkc7#hj~}t zm*3w|VO5wrYrUh=1tqO35$+%=3U#eMW|`>+&NfNXwV?HifSZEF@H|gDLsk6O*F?G@ z_aDl__s8COt+PkIx9=E%{R(AzgIZU+TA9KO64D-ghLImk+<{wrX$>nr$Los**Z?`+ zfl50tk*oiucYkO9#MH?oYJjoO+aF?Q1D+HdRl*s4Jq9=LIz^#u;C>GY@G^4C8P(@J z0wFHNcgph1-3)F@RIfiJ7FZ9zUYv+OxLOr=Z2ae8n$CVHP~O z|GRq5F)4{Scssk#a{7*6N;Ikv@7pX#B zP(zs15-0xyTVA9wAgC}}O&=hSqm9b)ckYN(NJ5XF=M#xh|&+uc$Ylc6Z^QJV>tN|S@@)q61u>=#1(+|o}2&fhklYYTN*@T zLF40DiPSj?q)S`5;q6t)-Djba^r|7y7|O|lVgeA%!9IY(P;ACpbPOa4I-JS~l*!O) z8d{57nvw!}qNGcAQ&ayl*>YPMJ*UZzX2Hzk7m}&Fr-JM6U~#hGvtY)1NfWO}fdZwZ zg7L3LyrP6feIF16A?XITuD9+Q^YzjeO`ayNkzQhbAeVDd_?9`5jr`)-3djTzZtO zzwQSz=RgJtNL_g7#U_RZx^^x~Rb#D*pstS>@AK=xp!+j!aL(1I`Q`5x$ksFJW!aZa zyST#I=RS9Mc-Dl~CengnNa|PF3iNL~3aJz;0_kpXS4s|i+zJ8?s4Nn1av~(cJ|Uf~ z`G{7Xry}9w$bmKnrEYlX8+&FcBvA*f6?AB^Zxj?-`}?HvKe_RO(-tWAL21PIo-qcw zrgnd*s{0aBu2>uzcWUo_?hz*O+7BTDEiVrurs6J~T33ZS11`JsM(l4_u5g$23|>0B zBC$zy|9OtFCYT@8khJ@N3s!ZEvY8TX7HwMLUOSU{>lRNUCn268-{%kOxHEP6NZigh z;i%iW6UEmt-zE6~fd2lT;izjvfo7%((KaSrJEuXb-ky`Zf)2zeF9d*Lel#>hJAy`Qjh2m~waKA0O=kY8%%3oG7A zkA!cg>LEwJuD$D?o+*GD$Aq8*mtmpNapu+b$XNe&Px+ZiLtM8h8VhzH`-2R|nq*BG-Q%_=rkj~x zXWdy{DPfP8#acH;xaJv7;Yk|<89rnF?~3Du6Okm|c#yHC^4t{+^X;#fd*39G43H_ON8gs4L%HT-g$m>$WU8dM;w*3I8z(B*|6e0(g) z#dQUhzX6Xn9_jQ1ap~or8npY@z{LJsIq?0MX+|oe%-kbBVc*m_dJ%hNg|A}qkl{wj z$Ns+NG>kbvOLFI1xO;o_|j*olqEczEN#_{L_Nj0_Kb zb4JT`_XX|QZ9%aJ8~FQ=bmZV!q@Ckt3*_g%teg9SXu<}ruE4g$XqO;&1b-hkNX9g}Nc& zV;UD$Va)v7IqU3R@7Ub5_#$=fstlusoo0G7h3Qvk^>la$M8!v7U7NLzL!`utIyPC` zm$+enae4n*b`I7HSh55(34KsI>^YGXCA?THsoo(x%Z@6#psy6j=U;LheGPIR3THI@4<>=!&mI77=ibi#P8DNkZgD5-=Ep^AkbAOx zo7Lr?QTv*j0{ViWOD-3+URTd{3AYL|Im{J(jq^)!$3ML-Yt#;D9o=kG5Ay8qjjRG~ z{cu0-Ipvkngg_KLc7~5lKq0xm6Hmozlrc|@F*&X1|7MAGZ9x%J^1UFF0dL@A`JbA) z6QAQ_-&PE+jws|(Fi_C3RMq^i*k@1v_V@apIlCcf2n=|T@JdAXfVdxx zbs$0LWM$a}wYF~l{de#txs>YU_;sC|v;DLQo_V3z=8jb9*t;3jHVKQcIv##1#pXEZ z7h8`temqg1s9am>wmL%d)1|1ySW0C@RsbH0GeeBw9k zJyPpcz1ZlicRlB1jPWa-gM+Csx91VwS!6ixX}zenv+M$a@uhHK(mB`m=l}J&6ig)& zO5#NTyFK0tiIb?c*bq!b(6CIhUX0b-C^(J;)x9LxhU0ssL>3=9l2OkzN|PVibt zG}b%=o(L3X>hzjx5_3R}nd)}`h%40>=meF(3AeUQCT&mVZjkzku(cBOjp}-iO`T20 z>e}{4fzw(=AHh}@3K}(SR3AC0cYA**!u?R9PmR|7k3wD^H!2U$>AW3h76vWyFu7k} zvQ(+ip^A#iqkms=V2}v40P%yqEtf5qHt{o1SxzS>Fqz7)W*(5e`4=dSFLK*O3xKkh zy)=UhwiPjf#mnZ)16=uaY2^Cl^C^7JOD)1j5)xLcSijLupXWFIG);drO0Z2AywPJtlzDQxFz` z%m@7~$1SP1i9lA9e47J2WEnMCj(@lRlF#`AhFC1?s{TgM78cHbB!oNJA+XEiAQ7k~ z{XJ6)MN^VD$)^0?1C-wLeU>|*522M#N@VJ&LFahNiXLhdaI9Y5)L8Plj#YC;=a<{HCE-A-*QEL7>JO8- zmebM>(oEg3hczR#F<6!9mMtZzE~2gD$%j&sx8pa-ZBODva3pG~sK-{EVV6kU$y1M+ zEXb)=!5M76#E>*xy8c~+t+B899SW9?vJHo{_9Imen7J%TKf8K z-;DD%D8qd&ABfQkIqOuL_TH5A#2j7J=i%CaBqt-;g|nAYEis&Y<3eK3)@q#dGW+i~ zta9GItn+)*%oFg-^ZS`*YhlNNK9?M&G+|Q7=qwT{=2JJ5qyiNA0!#jF4$05kkwB(~ zIPHz`qeqXp;NYpb!a^uO`pKX6CL>GpJ~{4uINt94pFn=;De9rZ2G$idI$5J_ff?)F z_t80i?#!zbU@UXc>CKh>oGPF=1PJ0UXI@`7&i2Q2hs-wBz2+2wKujJwwP+joF zQ1}MQl)zI~Wl$ZIp;XhRE}r@&qdD5Zh8cx7^_}`XZEhOLbOx@%oVtmvhV?=kziIbc z86Zmq=XMSD=19_2nGUsz-^*avY5RgpoX!4Tkt466i24#N4^Jdh9^sCYQ!5+S?s0N` z9)5#|&o6t+{r`tGlAp`R_iIsoUir{O#7bnEpF&=JW&^aWSaO44_ZQ4(xK7tU0|`(> z^b1HB+#@6d2(H!P;UbK-Fs=#?+~?z0v&d1pK(ijjMY)9Efn~R~D=p^>wboWaySwKT zbMa9o=B2YB5b?HC(pv%XQ)0LMCL)9@Q4-Lx(aPPtJ5R_RlDsGY4GGFq65527%+&78mnA^2nktS)~hD_a&Z% zkKY=gKWEU3a208k2&8f)q`zae2@!$>PceT)C-=ioxFlnYqO@Y#aFSES!wdOt910EQ z89VHX-LMA3BXjo$gz-a(_vE>;g9&^Y8g&yFgcOTh1HU7k7_%i{hnvbc6`)o^krIVj zEa?la#fyahYY817I2+9#z~({dZVE}Ha3cLxuo}!~P3thLVs*qPts_YzPA6k#ZA+Ou zybo_J_Ql`upb~Kioo2@Co^qqWJn-X^N%j(r5?XuLFF|e@$%~3v#T6eD5QQ-d)?S3j zo8dFXNY?+w*n1D+)R1kq3fiH3`#=p{In)>ITQo4Rj?kb;pjy8PSKY|VeTi~K`Kqav z`+-!Itd^2M+z(4nxo+PVeE5aC{@V57;cM%o&_kMk{_4}rD|LKtwAY5OVn-hRD9`a! zUPsoLWvJXX9FWsj3VaGE6EFE0@}(r>vW`~9|I(J97TcH0BA@9hrzTKYu8)N{@4>R8 zQ}bjtj7AH2jF*~v{wjW=ITW;aS3ZamnvI*spZz_&#ZZqwL)zE_RtIZH+7@EZ!k|$V zsS~U$mx-$`YW2!NwB-4nld9*aG#s@wq4d^M$c=I+F>?ErjQW z;wLFHfG*xM7qdSjyEgJI@( ziI^6`+sQdTcl)nVZ}TE^)&Lqw6pF+d|2x&~_e6s)@1L;HC+Aq8oU|!{Hx|U+KJEo_ z=(e4*v(*$i(4xV}_Y?gdtqBB>*Z`raM>_WA>2Yarzrd4iI1+MsVo*O$_Y#e{rYgcS zV5JQAr(#meU8GQB&fN=K3tVTy4Fqj-_8DavHOOmf5+a|~uffG8u;v#Q8oa$*@}Ate zP50)Tf`1+vWtJ&eA-#U=;Jg4-G_i4U8(64*Y+k;XdNG*u6{umsNUHWOpTYKg8xsPZ zt>YT|r`)esekUL~Rz8r~jw9#c`jKyJ#ZeFONZ&}pkS4K$bzD}xwWVFjHFf>_st}j=-pEvw9RZ#lP6z6vmKI0P-9?Ul zpkq1ht>mK%+gpo1B9zgdxUbupysP;$-t z*|lf3N1snY6u~5X7|o!~sJxuSROG_$@&^Tm*`@ycE(Qc28U$(-RA7N3i=Jt#(WXcj zV#8wj4wDY^iE-d}9w7kn!@ng|w35ZD7bE{}#3)+D2BqU1e?w2gzITF@{kKLuZX;STnH`yq%UM@EYs9N9-hDTzay57?zm2w}eIs<|E(ZBl{MO z1go;M9Npr-S@0C~J5EJkh>N#i(C~9wsEU(5YBNPG+G~#j<*3;%4{--d?iK#Y@aT_N zN#jdzmQZ|a^R1m78taRsPQA)<7JV>d|9oizgosr$-pRo{HudizrLdMyyY^P9)J z&-Z5RE`rd<9c>{o?*Strp<_hxU3kIhEl-Ij`uTsQ;Gb#D=4Y25uqzoub`#@B$1Be$ z6zi%#58#{BEAt94Jc79U77)Soh6l4Di7N@E*X-1bV%?oh#;DnRPAYX4fl4~9QXDxS z518QvznloG!0g=%bhi8pVrq4iFEmaWi@i49N@_f5p}c>|zxCMyYOiwo3Yqf>k|zoq zzD_mAGfY*UM+y`L-1&G9?i)oJ^mde2?iMOzMpl6l){XCzxqOGAA2F23g7KM#IddAM2PF` zlYfXkvxPu^9a!8A!=|YrHbi+fzRW9%XmqZ1H)%J-s8_B+W0S0bM#|5N)mUkr^*taV z!dQGw$iOnfqFF(+?Z^X@`~n+yB^lUS+D1_4A;jX|MYGZ6bo~j2-z$J`b68M=J`ckE z0NR=}cF9E55@Id_dI7}|#h&fBh8)qNw&2+PPXb?66W>+=lr*tgnIIZ0lH zKK21l8ETet7_8>|HoX}hp%RwNlC|OzcuI1YT#3;m$uLgVsfXN!g=mdW09E-@6+(hi zRA`iJ9I*F-Ys~J)Wd$;w-OWp-!7pk1=?eOeiU7|b6O$%%b{%Y|N!}9wi9_f+Ki?hW zhsm%RYfRrIxf^}prXI>FgL-T{r5%>i)Rog6doVBSV<{(Yp{qFZB$W(nWfG}>kDkr8 z26r2%){}dbeb*HsBW@Mg3)s&`J@mTdYT6njei7y^GnlDbS*7`!mN5Hx@gX((&-!~pGcQ>c6Ud%YO^wLHJr!U3-_dS@pDS;IU zyvjU^yXf*$%O;S4AmsYl{0ma;1`Dh45Bl02ngGJ}KqO49X%3x^CC2z|JacMUW_MnM z9s%zoMb0EkV|I(GZrNF8kEZ7=xX2x}vk2%^tf>LSvtnsm9PX|Ru}IKHsJT&hvE(Rp z2@7>+4uNm?lSPegJowBx`0U2IXm57gX%M@-ok!N!!v%m{#bu7OcOmF)<`E~>2v5Si zYk-$ToSP`b+NOdJZw=_+CQUBmylTDT8;Vd@G`YdRaZIEye=t%Hu*H5zQpCgE+=iG} z?dw9?s=^^%3PafHap zS~R{Xf6M)lpt9-fvqQi+9bos1ik)aC&p{uZPODm@0+w=xrlw*s(HNYKmWKcQxlSb8 z-aIW6&9Ct7YRG7c@I}Y4Am5j_TWgZ$E6*4Il9VwOs$2v8S}y3>4lDSl?WZIs;WzN# zq+xZ;YGy!q+OC%Tl~M#+(dyjvN$%2Zuo50iUikLO;2nOwx#D8W86AmR z#f2+a6OH-*Dn=ZD!s463BPLEGm@b3yOn*JF8cIeB!jgz z%JZBSZo-~nw+}*adhFF+@Hgd&RNjw1^VB$m^W%6QaQL!4JiuN~A;mOd2v6R2n!jL} z;U~pSzw{+Q^V-Z4H7IXh2A7%jQ#MEW&rh>1NqT)H-J*XQ2n(8chq(nI*xTzcTmO4f zj_wYl*QYj;2IyFLrdRs7U-z&kmN5K<-Gq)S7U@RbpWF8O68Lg|kYL`Q@X#kEnY)u8 z`sDLHK0QyGHFGRED^aPDaQ`Gn$^&bk$y3OgZo zb>7kZ)&^du3BT>H=sF?lE3`{rW+uTnim*({o}})n<{IF-_Ze`euTW1|r@MD%MVOs) zmxb>{0qSVOx3UHv^6Rfga@h3Q3YzzMnUdySfWO_!fg9@2vCkRw`(`iuIO?0}IS%7(GoxQRbd3 z85?FF#1Vd%xv&BMU>~RvY;nMAEU#fw z_&ggy$XrGF(>#%vUGF|CLh2ju1y;C!o5;cIB|{v`7=y4EaU#-NjS$}}dl8dx8>l}> z_Q+oztan#Pf{q1>{CWO11G;5{OYJ1T324C%ToVR`Ga(g|!#)3hSdEpSF zCjkKA&9RKaa0)39QSC4Hxgt0Gt(u3b6BtO$Y{=UNGZD00MT34%i`mCs#DbtG=@7 zWjsGZi_V`E$!&X4(p zNPMfIEMt*jMw2lk%Vy4uhl_0D7}1@?)MVEnxQ2wkmx)~0|J+l8d2gnXX|*tdQ&bct zyg4BOViw^F@B}8kJzcZtD^IShP?S))W=16``?_3zJOsSmY_k#kfc`Lw#Y~;_EnmX6 z^BGtlE=oDD!T`ugJHqJyjke1;ETEi>6euV}w-$FWywa$hvaEcTuiBsx{p@#Iwercz zgF?*D+E<=zF7N+S4Y@t9mO_C@cAOz{+qRLY?obiCeW_l0txaY3hGL4GkvQ*4fbp%= zJ6lAKOL^(uKe^iaWa74{u@8Rwr$vU{6RBP0@`_e{+y$|m9cZD<+}=HgFO|&UWx!idfyM>a4hIjU_EUchW?vg zj8~OmDFqeET-!v+&q{{0-W+Ep44FTmF8k|nmvI8056_jwbI0>;$6|_DubC!3?pv^_*hgHSwK~9;_(`6H z^Lem#wlP5ejAv(mM3DsCFWs9#^nnHijxckHqs6{dOWizfr ztz3Rhr~a6Rp`xI-WkErw)_0iiYMfaU3Gf%3oNu#)V-I7|8@sI@Qo&2LR%|+|yyLFj zdm*vDt$1n-;y9Lj6Tnj7%XOh1(%*spMP<5g;UWx?dPG_X8E(*0<}Q^x^d>!!B9N4~BkW{`N7T{`w}V zCa(G$`3`VS3XLpQ1|?_jTK|=vBKLbhWm_oPs9=>2MhT3Xt7Dv0FalN=tHAWP%!K1w zof1iOdd0A@64wkBy<`rt7)o_mY$<5DFwah|F5+_jcr$TJLYG_$WYx)UkkTY1E*>5t z7|`!V8qs_7kdvX!&rvF<@P`myoQF4o+-XZm1juM?=6K<`%u)!{%qQ=Tz0?C&K3Nm@ zEk#0Lr`kl|jJ1sG zfmzzpLal%;!QMF>KpmE9W#_ikA29RdromKa`qKSNRM7a>LEwM0PQ|26jZZqp{kqMZ zdKQ^{1A+sq63r5V&?_3ou+dZ*3=j?h1vBY1hUwlx>D-cm0Q}+5NF%TbB9f%odQI7Z z7O4|!F#*@6ru>IL(G`F;FFa}(v`vgBg%Xc%g-^ZKC=fR$>h3-~l=9?UksW#G+YL5J zg2c*eYj|u0#I9Z^S16BueefJAna3sAd#Z`icbpPJSN+;hkADuf+@sqn-Jv<(dyQ}3 z({Rj>MwY=&gdzvUH}nHRD5u7~k*_{b9b1s|iPb%9k-gRQt97@={=#k_EAgH9&eVGR z4M?%hbRhX=@E;tD@8m!(!C&6O?^gn|#QbN>PRyD@&pjveL9O2X#H`c;b#x6{5P{Di zzdkEs1qWAKiTu%GmnA6!&dlE0apufwjS>yWIY$x|S=k?jVo(u&B_=$$4>?DPdzP|y z%s+IQL%Oghe^3@?eVxensAlFwFQyx*A3yz_+{MgmNVJG_4|D3A07wXS{uMk)A0=s$ z`nHL@65mKZ)|+&T3q*7dzz7X|?S6X?IoTV3qSBr-+}QZInCkQ13B1Q%X%9SaIyh3W zdudaPEfI@9rj`4qT26o=B*_aExfZD zt;u4n5u3koP3HOU6QP0_sycozJOL@X{BcGxY-^_ZQvsz4xItsXSTJAd>*hza$^NEs zy{kHM>F0`-?I7ul&--uuc39daI+b|3v9Dc5W)U-MDLkiLB3FV?CoH;(!9w>3ExrHl z)(g1X(~x?MFK#!F>2ZxZTOSezR*5FV)jK7<_R40rTvf0T>ezuDbV4e;e&=FVj5FAD$Ge*VQuwJ%6&;^M^dt z;ChQ_c(dunQmXK4P04^}705Gj!9J-B7dS=_-3@d1E7O0cxqYClgU?X&e^Sk<&w>5t zH(~d~=%Iqbk&bA4xYPjTJ>(8qlf~EG(5zoj7Ab~Yy`P6M8O~%TQ&23ndGH&d1*X3M zdq53R+?mr;{J6})KMuJ#?}lARN=ii1twMFPD&dxWHt@!fZ^v7^9% z|8=)+dqv!K6ywww2J{uGxQ1r$yG9x?U2UE?DGuT|h=s{saMrIkkpnC=w0p$_ZJ!UZ zqpmb%80r&kV1y_!T@>_kdD4Ldf(YNk7kfXAx?c_rI{CrG5a`qtgk6knML!G|f&s}4 zMK_X?q$plrjEJFZQ@{zq3@HT@?+^ln+vn4KrOC7jX%Q&Hr@l~-kJrc1LNr~+SJ`F# zNr%?@hi7w$v#`K#vQOpF7N7==D8LMM%Fc3CmGRJLvi^{`5aWR^+#YI$x_O_dkuDPI z_kO-_VDH5nko3?ISkMi6qNC3a$&lBOMk7xm2y3$( zc~mN$yoKr7nu7}y_)pi@H+#cLfb4k8{;jX~AJ^j?#8xw--ivTF`IIC7@MrDkNKR11 z?A0jO2r1*^O{h51J`g^C$0Y(het{mzf-|VN_h&u0%1ZU4-A$gNT-`_`r)^xcd=pi1 zx9>|4&DRzz+Y|FG_R}1)z;XxmmR>)2{aw=*|2&~ z>}O`$ThvFonv|em)T=YR5AP6P=?{{}GD1)pXq4o4th?Ru?Yf9IBKJ(GB?@Wa46&TEoj%f|9YzvW{=9X zwGUtHqK|?3FO;gcwOV;a`=qM9tEjDD{t7zTKUW^n)MroCA{m&2Lb*4J;Cvg{jbEB}1gmxYF&Ur$-Lsw%F0b zN_-MPAT(Y*49sEBD~A=i;dpq`UeJ<`)dOtD-S2yZ@p58afFJWI6Nl^xe$I%$6LcZ} zaOnhNVf0CO?qpqOM(c0Iz1xW0nTfsJdjCE7~Ek`7HG#lTC7QBOS>0$lZ>so-JBD)+GC5qIEf>85I9 zh4_d{GN&F01_1<)#74Fbp-7o@P5IpYTF;oCAEA$DAmJNo&LSuZ9a~G#WO{I;&Eq(Bm@mbE(x! zh*ObRY-v*Vu$Vf15_(PyM;Dd$q3E~E&;wt)LU%*7DZOuvGss*V7Xw`Z} z$LT->c+M>&Is3XC<$o8r5+tke0bCXS@6nj~&%F}?)Yse=yi{;#d_f?k2*9ojkCjc&0L6Ju^8DK(OE~Cv z*WWjTn_?+F6?@=@<4S?-ioH%u>HvTI+?%_2IIw zva+X14euIEHYcO2O`zS>9)zP)V_bqQNyhWET$EDg@j+!098#v5n?IMh_o@fh$%uN> zbfEaEdp#I}{o6-mAf5QcMK%Zi3fxp8ZWSO@t3R??a+92zoUrozsQwl;&KdQj)e(RR ze7;(pdpOh|#=kCFCjq&04LI-4f_h(O2D5~BUOwIk-&WTP{zxdtc~LeVi~dDO3ts&t zV1+drUhBkt?C3^HxGCAFZN~T*z3~`9m!Y__&QGfMQ~%ojecNZ5dfgUD<=u+;-r8>mhYGCxb*Q9p@8Q<(Xsy zYXd~uIdJf^c{dQ6{{rPNymWg z&R8?awVZ4aqS)dza}AG758rDL0j(?mdMzEpgAi?D!6#sDOwlRtDLTF3@ab?8jPtwL zaW{{TDngWV=7;SpiER59YKJczjhZX|4_nm6qsvlH3TMfWLE?j}xKv=L0ThJuXu(w4G>}#SDVU z;20s5=@+}s-+MONrDMlMd{)R#)dIN)lfmRF8MD@@?XI%ybtL?=p=S(SJ^%!yKjADg z?ujrsX!gb7vt^0l@7Gw^?aiq5n#XbLx(*=Edx#u{0^B=(-`n?e^g6?HL83l;Ul7L; z_VyUa`^i%X3-UrF2p$lP4I_e!rE=$Yv#Y~X2m2Uwq5rR;^Rxvk$L#fIaW%?)+R)9`e%gywpI5>+)Ec~&<@94X(-DEHW z?i^Xu4IFRkYrE>{T}P*mGZPV%F$zH?&>0yvjNEMC6`ns8xrZH`D?S*b9aW((y`O15 z3Cf!>u7cMxYZ2|&f#DXmIU5|6^AOB5*L&Ww`IQk49C5`-?HJKcG?fLhyB!*24BGcb z+e2y6%KYMoP&nPSPQ*d-9}7k$z0wd|ut?$X=k$(YxFH`;B8*sB--dmol4DD2a&-$E zS-yMKrd;SeUEb?O)+T4Ddnt^s{;3z;5BU%+tiNp z#Kj0VcoNr&{NQocf>>zQb9+8R+wKk%4l;5uTyyPP+djAmucgVk5*$6XB5$0FO{JK5 z6B#rd1d6*E`GUGTJ8yd@lm>Sk#OT1lVzEA+bNxBprEfpQuqk_5#&wn+>i}fa1x{j& zFd0@ytZgMm`44+Qbr^?IKqpG8-}RNj#WkP1(<$PoX%=^?JHd0{pZGO9*INoj#|EBC zaVl7--nF|ty834xKaVdLEriYjB(iAmjbQo_J@pSEl@k^QeQC`eGDm>f9;*=L;s;p) zFl?zr8~@)hzS!exd=@AA009TdSN)XNq@)B$$QHE}YtzD3;-BD})h&*wVTHQYR{Za^ z{NJYi-;P%5WWTC!UL2>grQwn2$#U0?>W_Pf^JCJ6-Cc6Q9QHZdJ_RK(PyXNX&3`D! z&jX^qjN9RSOA!{Cf~K2-0%>jOt&MCQK-k?a%9;7iKY2odvDbRGIzIs?WV=b;)PCkgJkGAEc3<$ zGoWW`D8Z3%wg@qV)Tp?niqH zhY(5GBkyjGnR0PjIig+jP7c|j=AAVw8uv29w0^(&m@5L~*}l9k3q&}va} zIFMDoQ6Fa8GKh?jLsLFU1rseYi4bem9CPlTA0*|M{k0tkd=Krz)#l%f1v?T=Ri?rifrBB(#tABd`JO)b9Ol9aLXM;&3*`y&7v$-oQe0Rxll;{G$`; zo!_MjoHS_zii=qfl%^Lo8oAtwGbT`^ydu84X$a^LE-QxQPa#`R-1Bq~U zvHB0MA6XA@NkixLOv3frmU~mKU+p%Cp^>yMSB}(K>*rMr@(sYr>YQr)v zQy@x+<8H>Cg94w#;`~7O9n7fZ@XvoH3Mvk#-(NpUqw=TAwYmRc*U8KC&fW+qapU17 zASHg2btS`~I8>da;l#Vm*XH!GLEG_5kW}F#HR5R?xKf7o5QGp&rWa2*sITGql9^c6 zV&?LVV(>>8^?isMEvz0*pFOn|bn7oZWMR1o3AoJqpH;|`bvC^v9zw8Ua;AnRxpr3; zxh0QSp3@i1aiJp=Jlifp!iPH(e>3H^MnfeF-Jkvm387Vxv;tdO3&8p-C@+#A(I+wL z5D$PCocLz*Kqkyz6EVJg7QR;Z=keyU3AnQZ?zb?&GG8ct^;R|fj>O+FmwHcV^>Ytsuz6-~=!p|e_h3%oo^Tp?b z?px0(UQF^Lf71xr;dsI82kS_{4;qR?ULamRRYHVrd~ZbUfI0Z$rGD|WEF>x0`DeLq zJ3gYoy2W);8@2p&#D#Uv*?9?N&8m64?p_$~?Z52bRN~fu$cbvVO~;NU_8cW@WYH9n z33$sKO`Sn1=VXfyYD32i`Qy0RmpO1zixy;K8|T47>G;J(zVXu&;krXPZEWbw44EA5yYBi&Lk{568OYmFK$^bA{k97W z!RH>!M~n8$@}_|TucHuxg%fS%a)v)0?5P$!>xzW-e5&wkSeUcS>mQdH4ac#3m>mU- z=eY>lEZF6K5m@vQr3VWzcso0p6QV`B??d#@=ljZz2aU%MXGpLo)`ka|@v;4s8f2QD zHad0L6VtR&M$hKRlrZsf_zZI)L8NASvhheZKELQqsVe32mzn@N}Cpc>8K<8`*ec&GDuTOWc8 z*D0Ys416%mu5Zm;BrLs=bR#H938SX}JND!PW<))q(#}s_O?R4R6t;N<)(_rdd(-a^ z@)rnffjP#05;6z!K9~68pC9m)4nE^> zrUQL3Mp(Z+h!xVlX+gHS>s%vf^Z_v)2}NcxglI&R8b5JFkP4pGQk_OTdj^{61i3W_db{6W9Xsq@^isK27iItBQ-SiGFEs#2B}w*Ll>jkrPZ1U5PwVd-=fgB zEmu?wCym7gOa%UMh*%ii7$6bJi{0LyuwV6{5vBKR8kqDA1ve4Q^Tc3%q1?$xJ70x; zRh!g{yq%ny9gLCG*(tysKzdEFAg|jVerap&9crhG@QQtYd$~YycZfjHN_v^y_|nYZ zR%^2Ct^4v>zl=ej+AlV7)un5sI=dx|{C-m7{FT!!uJ8QpRkI<}oM=;Z&92?oKmS{V zG;Wmk`@glF`9$M5aQerm&hkIR?1Iz(yu5PO4V^DqWpi`6Mzi7dD8fGlp=!=P$gjk` z0PSAneU#4QZd{qIU^+ufuU*V~2N?|I?L`@4f&tkC2cl2SE#Pw_#YWqoad|k9dCbyx#jyL-NUq zdib55RBkzPBxZMyzH_Tqp?z$!v<6l#MVHaW)at|_`pxOdf$ALMeW|!WZ7+EFL#y;i zQJjGWLlJsAJ<-+)%C_jRW0>~s+FONQB)Hm;b&NX%;)GOdhex$!^27V*r2nhq&4_js z#*RvD39ME*fT04Skq6cV>@?(KhbO=sv&2QRg|jxqQgF1R&busw4kn)lXH7f_2dux{ zPu%Di@bmTLeSiPUXk16;<7*I|sk7{*bhBr5{Ndbt6Z!+b_^5X`J=Ohd+5?{srEXhV zLG*J56E_WBq2Hk~^i^cR;_Y&ml)^)=aijwzg4oO4R|KV@?9qVEVgMg-R|qRX=X|J{pdn`dK$~2RF5sUG|Tss`;Q!>y*Y;)6!Je0=AHx;Kl+cHd6^x)lP z$zk0b(f%zM&4`fc>)K)#nEv)ja|OVVftJ3)#)(hq!j?hQH_uu5vLmH%?Ult}kd69A z!kRbps~PFb=d2IzvQ->|GFuFj`o5Co6IU!*OpzT<=o}4W7TTYf4jlFdlJtIocX8tj zWh>bXcxmavZw}PNN2U@GybJfQgQQ)0)tjC88%<%?V3Afk%+)U#C+%hlt9G$C-!vlOc(TZP% zvN+Hk9IIhU1~y!b^nSdEW80dvY|ddaD3+zTHj=th*t9{X+)2}?aL(@$9Yu_0`&#Cf z->EScQ4zz`oj_0ArN&M7!)g!hHpo(DWrX(jU;O~rYk*}5N;0wbjP`%Ihdj@nmoX(n zyhiiu-?BtJ0!K5kp=Y63sqxc8_$6b;*7Wz(UW8%x{3eY5FIIN@pIG@R$zn=L;X*-9 zPH}2}b|4g+UWa{{Fd2^atsg?4xTIIK<3g8ZxY3R*JQ(3ejQMz`hv&7WYlCA~qCAyi zLOm0hBn2Kg;&yw|@2RitP8z=5OR4RS9DsPxx^i&wbF#m{fD zPMBh{Nne{l#qHY0tyTF%S8U=!Gf!fp~vTh+rj9_Q-qBTkRNfOq!n=tuvSl_3>B6h z#A!^i-5^AW!JwJ=fpZ~9`$QZ>T)zs8Yyf_A8f!T<{JIpU?mQIeb?49Ppg~;Ks8xj4 zSV^;4o2fQA#ZAcUy&=U#T_4mSugKlknS)|xZKdF^8JrfQspb_gt>EQK4I&$5`)e!? zvYz^XO#M|*Ty58d3pb5haCdiicXtgC+%3U9&}eXXcS3M?cXxLQ65Jj7=lS>h?b_8x zebiN}>t1uMG3K~ND865*vGisN@GDAUAIDh#huqm$9s-G2@Lc#`C(Zxb0ExegY*`+E}^A&bKm#qlyHLZy))!3BI+ew(jYeDe|X+U1?zJR#<) zBD6fP6XE5c(&@(wHbQNXRA}O-PaCC9s3057NRXzNbM-vZfgR$Fm}8slSI5U;3CY6n zGZc*V%<-~0VghSli(8r^|5fa2=XL`@M!e)cqX=-f7(Xaw+v*1PL6r>pCQ7Ml7-v( zj2xHC)<=8&kZ86jX$hDh;Uz-@Za(}@DNr=1j_p_Hy3gC)t;2?wPwcs0T@%{E=N+3# zMLEam&V0<8(_RzSCgZaJkjCprHKFT>%eY{@{Wd~CFf7U!LmPlGcY6ofyhUl)`8&y! z@aAKVZ@{(f1IZX{kpY~p+R~%VqWmCquk63oQ|!Lozkw)Qr)Hax7GOxKffA|*B|On$ zm}8mqqbhmh43CtZjE!oF7uP^2hVA6Q?18v}jG*7+kzMLhjcP`8mk*$ZTwkKF=Zk$X zE9%vGb#4bn*t_Mf(2-UBYXNQ~@VaIZ(G$FtX+Z+3w#fD472DJ10Bi_lM#>(s?xg#w zyZlIEj%K(M>or2TyfMj%W*pVPm6MpYgB*mgIP{g6&!segI=7kz%%ywzW0|2hpdIba z^eeVmzJR{`(a6?cWzTUb{?ofBdOsB@sws%TMk& z?iL>V`_<<3a{`V!umi#Me8N`eXvS1-pDB>C#CF&-yAW7B-s5%1m#v(e>7*%N+g{)A zu2MT{df6B_f80a37 z+7)mEb1kqh>)o!Gt!cTy=K1#yZp$a??coGlWP5Mhf7W$W)mJq->T#v#mY zyU8AGT#6?+c$kZs6AEn3 z;O#K;`M;dOfJHuF{-5VQC5LaHid$}atBcS1+8+&h)aTL&QLK}Q@7gsxG^p;3PXvrQ zu0|igFpB{d<6a;cnYL^IG+M;M5UtYbP_)^R-^7Fo+w!#xx_VfGX!Sc z=fCSH+uZ&bn|@g9`~Esy4*$a-&W);~Hw{|zR7~d@!o3*<4#IxkG!tHqqH-0Ci_gH4 zbZ=62s>fF-I)q~2F%7%*ZPJ<&t%69)iE+W}ta~w#D~<|dMg;j|8u(#WEV_&3K0(ic z_+aJV1uPyyI=A5xJqYRkG9}`ltj-{REt-C{Gki7bA-nR%aySk0yL{br0KKaIk|{(^ zvwSr1s+_!-BHKbt#t57{{zU~xNQlX61j&rzh1RkqXVZl4chRi;smCkIE#?sg|4P9d zJqV95wF>ra4ybGFp3L^xE$!pvI>3DTs<8tiKFjs1Y{}mxq7rnTjg64^)Rr`on=qdq zDhTvn)pLDW@Zwj$y87p$z2yywmhVzHI5p++qlp7wT8EY> zwi8ueWK{%UyIOE-ojD*WDO51yGcveKm5232%1ebS$6JBW5W_+CN%=h&*(|itsB1to zi|n~_6g^rhIury9E01LNPiCKZh_ooMjq&_dc>nkCzI8Z$wq2ffyKC-#(?C~Q`zQKC z25?PF=sYUEHPM%eXhnl->I(vnky?xHm(}lUDZUMs#LgcEWwG)Aif@amSBfsj47;_G zDU_HK=v8tUpwCnC({0cTS*1-9X;<%s|Pft+C+5c&CIw!cp?gWk`RyUUP8*#zy}XOHFp=qV&&&lcarXl_>M{yQmPb9$_3RClH&$4FdM#(F>fa9IJP;Jp#PPRz4ksY;~4^v|KH*K zZ{g=NR#nzDIe4D#gg(v|qZ%AWPDV+|Z34-H<~1r&Gof&WAY0*y6r5B83jquW>oq>u zV{PuzUY;&!3vC)Uiw!r|d1Ca@n>X0Z_$U0IX|%kwt3<7F!%24G(egTUAPuEl;xcC* zf#$%5oVR{n)7;$N;Gkiy18ahtg{$jEEL}(@hWg($>lPH+J6t+^J`z+ozV|-6*fPY# z5S%u%vdRn!k`S%!^mVB;s}8c7&f!R(SRx1Sg#A6*_Pq<&J`tM_aEM)~cUv)}5@%zm zNd&S?gzv#s?`z=pYF-?uCGF6KSTCP0kjvWnY%C+ab|DHw?#)0yP{GJAmcnj$J-_5O zfD4?nKUAy9-zK@OVAHUfoY(YD%h3E4a(BbPm&3ojE`YOvET6_`GxQ>Q9hsNeY1cK8ppls*W2hOS_OyY^bc z;e0)&8JJf1DW_~@IiI4ZTirHQ^CWA!sU;ommE&de8j^0&I}!(sn%h2TM*Qr$f4!A^ zzh;ZZTlU48{Wi9y28R8S1>$CkHmuHS1K9PPj&RyRb{{C?<+T?F7UyPV79e;KB;`#Hhi{K=#r6t+)VkVl4 zMnMuaPfFEqJZa+a+KH&doi=iRXv9`I+4?BfDAew4sU&iIZ_moF#Fa(Fj5=fpQDv_#O9{H) zzQtn6WA5*>X(iXLZWf_0iwy+Q$bxN9@ zg+Tj*e3+`8l3Q9{s{{OG3V#U~1{j5I*?1dFR;r11?3z_x?P-mc*OJLGBrLG2Fw9lx z5$>H){L%OeChzNzNAJ|f1w2Nzu)$?5PI5~bl1*l9it+@vS7GWn^)@QiLuh-v6HwX= za{fsX(fQ;DskYcKSTPlaP(!scIwO2zC@LEdO*Y)WH>P)56-cTyKCzp728sFXt#Ez# zy!}rT8IQq``8SR zNk|yT5@!1f+vRno50%5_%w*(|e3^BNw#kc|7Oz?0x8Hg||J9XkXXk{OOK-xBmG%Y7 zcSFf;tMj|zezKrm<8#jp%P48HJ!RN!H@<3mH7n@(0`r8amGySN5?s__wB{e14MJg7 z##SEnJ)d7+U)u>uy7#ZH!g_adLxOL2`a|L0{U&;Qh2_}!!QpycToFeubKS~sso^g% zaAElqc6F}5M2<-V>@b{dvPhJYw>Sqj=3u_%ZxMMe;fd}e^*lTY*!ortp7P<%vQFfk z_8K-b0n;>0MH86IKWdck*15q=1bG$6pq!*Aj&`2Tb@Gond>q!pnV$L3lTeTpJ4-~R z-EQKR`yKhX-ByQu>1=700-;-J!+9mQ&K?OYV-u5}L1qrcQx)Uo^Pkzgtf3nqjcs$iG5*9}Rm6i!@> z4`CQBi5>GF=3?|rfoNtf@%Hm|qGl`s@a6cyLjc9_?cwD$74+r?zW8dy7zjbL4?N%t zyT9DCp7cy`;bmI=VnRvg5R{Quv2tU8FxwQ8_ow91cW|B4=r1=QtT3*vgwZM~xp(%9 z(6B{X)Kx!V`|;BOlDrZmAb;#)rRDI*M3#zb?M=xX)IOq~XK!3efY_|C7P??hrZm#=ZI;+}fCB#9>T zY@~a+c5jUYZ+}?Ix-?2Q%Jm|I`EA z6twNV=b|m@)6U)3ExI`^FoMqvck6fPp{~Fo-T#9v{%@mILrX~LI|_!1V0Z|rS}?#O zKu3Tf2O_*?pUTr;wgb=sw95g8ht$J-A_FLah^BveV^}^{T3vKpr@73Y0}p5ejqsJG zU1K%N%Km78Ti@KMmx*ItIwZMaaUx%;#WSd(l5qEvbS}@&%`AGCqJ?eN_?ArtVh!<+ zsrqg=yGLK%liMI~ueK5`z*D3sFa#QEJ)Y3z@0H*BIo3N7KHp#7rnC>;73oH=vF86X}xIh@`|rEx$LcLH??33l3DACSRiIq?#@0A7ZQ5R-Kx z$^_>04-+pWwG1@A3)=g^O}ScfK@Iec^-jwVPdtlOJ^ zJ_Yc#l6Tc;n?BKdEira~i|k+LNrFU#@}EkP&JC6R}NCE*d)^cQDwMp7>@)k+fNKL62TWHCJ#%?TVwm`V_$Il+*375+cqMWzdag!=a zW@y5abMS&;baFYpMOWHQMsAejRQx@E#p805$j^agz?*07HM^bUHGc8PEky=5&_sb( zc#2PP^H0Rqa_H^q7Y+#}-731TjW#bLqF!HMdn{gW_-D+!xx~V7X(*?dv6wQFXtAZl zbPX>Wg2Sg|>S@rjeC~CmFNJKJ+luAdiTbdV>gC*xfA5!A{48T-PIAg`DGc}aXm3)f z2O>vL5be@1bvNPRu$S5%98;<@E#EL2Cv)snAVH)H*Du{i%Xd4L^?&~?t?D#t1Eb60 zWC5aY6&BaHr?X6O$lnx{93HTptL!Hl8<#Abz7r*bm*2aU7iRhjY0QUARF# z>{>*&4q7sHLxUPCe3!LZ(+Q1i^75B{WoM%W_3msaLWB{3mZuyu;Yu%qt{M>Eq{1M> zG|Lcp_sza|IKy~2>mSo(oJfXM1%61vgh@K@bo$^~q0U!9{UBsGJL>)XnuXJ? zHC?f*uruTX2HA9ZmD+or1%VONG>5rp5}_lhn@qEiU)t@`zTqAsknsB+ex#x4ObN9{ zQ!2pGwWsD(%R&TbSa=z2=y5^c^(W~xwTP6MqeurA;+IPpS(sq<9?~-9QSqnk@s$$l z!T+*$fc(ihXH5i8Tp98kmTXOn!BAOaFchW`xs3LD%Q($!jI3;=SDHpZi}mg8{75Bd zGfBzs-Kh@cOyp&EYq`Gg@b|QE*R-`NDP4K>TxvDEI031w0&4%}#7wZix)X1nb|5X; zj>f6K%@qV@ZW9YG+^!!~k!c~o}Aii#O z`Y=TCCAZsB^@|!m4DkDA#V=>-diBmfxJWLp$W0ATmI1UVLli^113_4UF_faJ2*sSV z5;pAY-);sALj}G3Mt-uH8O!`J2&2^U@T6kgwb~zG(&=gC2yImDG39ld1>W^`75HojH=?g@w4SL#+M%=Y z?}W4{xc!m1t-~s{mjzw7#{0A~dJkCgGffWqPD|w z?(aD{wJeA}mh4m^oKO(z)#f%yI{ULkpUl&X(^L+7wX^#o&BFWq*Y5;Jhm4avO3F+u z`StTsg?JrU6^$#K=K*1=U31gYOJBioMznt6`lY{|CJ>~9RA;Ub<4jKxg zd#$tbW_j7}{X*m0zZ!MaD zWW_tjk0y*wz3-7IxiGRAD1#khQPH89r@36aPSF4AUzd%T76^Ly4N}bR?nzNnb0#uM!Zr*1CPVH)=%cH&7$hu-JZf zI9Zf=E$m3r2#USQ{L?QgK=mj@C5#?nxrP@7`w*F)7yR8ppWfkYxho^iIjy2L1hc-M z*XVL|5cakoo;pJZu;WMBSBaTlmuu$iNdrXr0%BZJBxg=_9iw*#hq1TC7N9X;QIR2> zYJM$a7M8#VV=lq(VA{eQzhJKSLoLy$>hi=}>AyYl5s`S-zV9xZy)+6%Pnc z49BV=KAF}sNDl~EMIcG-VEk50F5i?lpW-mANdoByHx3cBStg<9u*&%pIcJdL#i z`bY1kY9ct6=MI21>o6S9hi92#t+Vo1v+H->cutFQ?mK_dt#Nagu|ABFz4?N+VA!M{ zO%hJ=5D`PrQjn9g(shF~Js)zTyzUmJv!}f*dz)}CWHdImH`^bx8*lcPb3a_^;;q65 zh0z~6P>cv;hX`Y-Z@vBWy3djP-vXA~m$FnOmWrGlqBfq2bI}0jrQm-^{;UrzM#LOv z*c%^?HM9*atktsT30FoR+pzPtkH72h)X^rVSXvoG^->hcxrzeV#*RpOQBacP;)*H# z6V?`1I}9|%g8W_=sTzTAJi!I^kE_ET&C8b^(=H4xaQI1FNB;)G!dNRQHtT|>H?dxb z#;wss=jzR<4u*zH!w>?(xL~RwqUG~bO2;IjQIKR~*0O@&r9446lp+ldydq9dglc;b@;UkYy(~1amX~xVpl}BgmS(+xs83|Ar6aT}|TKch4kvtcr zHI{>bCOyo>#_fKP&<&46`0@4fwSyb<9T#%bF7hP>eAmgEDYznZ zPH{A40=}VKl)M0g&U$k14&;v*FdWLVlCX^Uvup5R=YJ8Y{~8!oQH41CisTS%1Lr8| zT|-t>Dcxo5+bkzVYDz?U0#W?2jCx|2(MWpA7*alo_^MJQ^h^zZ&O0*fP$GTaU4SM*cq4 zVNX-ZR6~x0K56*br0*HSLm0~jRs@VAF-}+vF#zH(KF{|$l3x1NM@2JOU(B$EPZQ0X zMgpmmqXlWh0nHvpxh>E*j+n=geI6fUY0FpF_f)6hWAAz~44`4OGx@vUil9G054HxA zV^PWkd|j>$tuMnMi%J=f|58uQM&AEQ5)>K}~gFDO|7V45{VOgP~Cf`}2?&yBzE=skxGFp?XCK(Yrz z;b%b?$eZ5swb0~)rMW_BIcSH@I0lv9f{D65qdBr!_I zJ$(E_eB?mpG=HCa`i>8{k7FdYKf&>UCNr}l@x<~{3WUC}Xd0ua4<<+WFmdQKr$KTZ z?0$DRU%Z_>8QzuGa8^u4E?aAEY-5g@mV*Lw4DRmJ=QzbABsjh4SWPHrTtZz^vM^Rn z$*W|`7+x2N#&wU{`t~4pK2foq=YK3H0Fg~^U%~pMX!5sdzVl_Q6f)rNwPn+mi#v85 z$(eJQQq2v9_&qU41iJ){AsL>ZOC3?%0dU$9O_=bxa4ZOc3s){KO*yZ1 zK-Hw=y@*l_7-w`6<6{?16w%Npq1Wrw`8pGTGVk>c!E|KXtkJmoDBx|=H_3vL|Leb-A^v~xzz4{YO{m}pCbckXK zc?`wuL(x#>E77CILK|E|kYd}f)Lx{3tVR4)j%jKRQC9lOD&kiH7s^UC8*J1Cluf7g zu{mPSseM)T1`5AMm|7&na}?rD^F40(sHg(o-nnsubqp^Iy}Q%Rjp#z01Unopf(sfm zxCX9|_jUmpOS)GuXhOnUltkj?8uhF1<9SAKqCMz9S{eXh34Zf8EDUsj!WZ+4Af&Go z6wv;7&;YcVyRjY6R#W?S?urs#T-E3qC?UJ?J53>GP(PY$0prXB3O7<75h}kDDIwb) zWp!HIW;JSqba3M`Nv^LW6t|JEH(0^>4oAU(2V%qP_W9Wxow|IYq+Si80eiy?9uU0@db7bPAPLe>>`}5C>Rm?FGAfvT5QTQojE7>|9}gQw z*IO_0OaCfzdlMN5G%kbLK|jVBAXR|lEbEzn#lP$t(Y;~;*p$m_>Ib+tyC0A`A1qEr z!)8C6B!)h!-s`&-54oF&s{_mC7%>M$lWcjR7KFmjS*6E-T?)9=QIdAF+!elrUuMDX zVR?sS_xcsC1S|ZwreNB>EkhFiMYxo8SuBawu4L_yF$l|_(Q`uy%oEfQ>Bh9#qT-~4 zQI5^^!GqeHQQeeJU6GdaL8@y>(JqudP?j2N(*rtisOdFdh}j6yQN{7oIRs|(0+alW zAxzl}M%4LR7EesAJYd~G5P9rzf1rg63XdhxZ_3W-Zz1*9e{z)lxy{BXYM9vJ!yx`p zT0*3;hCPa$&!&V&ddQUk@Z$aPeMyTM{#7eXSY*vPMwz9CGWlT%vx1%+;1qDy7>naV zGmmn6!UnZ&c+7Dc8OaDS;Z}l#bkf&^#;y{$6lEyFviNHb%p+f(6+RvdDipLo;B0MGr=w1U$9E%9sDy^%vAyyI-z&c8d4J zarOzf{_nxepz{ZY80v@R<&sC&6U`_zAu0knIW#&-oM!$GylSAeC!8mMnCy-dGfDPN z7SojzQxlB}T?7Hbe*9suYvcUO;8yi_RAq8fwUX=XX~XOvUz=}zIc}9~9>;3I|8j_n zG4(xeLLAW#y@&%z{nham5F0V@>eX^3juc);pnBdjtG59wo^3v_2u^o|BjJGVgM4x+ z>bI{@@4!SV2qbA-0jCzL}lnNbcRGdQdmX#PuW59{pJU4V5P*Zy=gc3@km9Kew z^NTHP&s3sEGq=t)H-`}JG|-V@ME#W}3CuTZ@860Ig;sRXiw*NM+>d*rfpcPplX3|4 zmU+jWKPhZR0M!H_WO-Ap^@;Co2`Lrl^oeAvnfz{kzz7K+SEDnk&u00)!sKr{$5@;ylMx+d0eA~+ib=!CpbJHC^Aby(V|4jx ziof3f`^62O2pe%d&mbEtUUZ$cZ97JxIC~V=c+HIfyLqifqPKC%2c0Al~nhMmH5ywl{p7 zuayOLec0A;vm!%d8l(M=Lk+B6PG3G!;EZYE^XQ;Q6sYR@Mr)Dp!Q))uMq+^L7(_;S zMR1V2efz`))^aTrl%f^Y&`b@$dx+JMkQUz*4j*Dl{7gJDVKeq0`)>JI1xpQ@>JxI}GhbJ5CW2x$Y(w5;ix{ z5sh95)57zR*!@vr*}oI2D(j?{ukmRE77Ls$RJU1O8cNHqHAAvQEDFG9C0!l&dbiEJ z#gUfut)Bsu9vYcn9dr&4xR`G?2EO9M&A{Lu!vUIf0LUD9&~W;~26go;KQq#kce;sb zeCYo1n$~S?W1GLGcXvVx-Wif?h7p4~0cM{VMvsf$#&65vp@?zc4Sn(L8oT*9>Lwxr z`xK<2E8A>Q*KSJ@tmP=hFOp3t6|=~0`3PvdC#+nC3e&3Pe(|bYAj)IOlXq}IK$ULA zbJT3rQ`!Wi++%)NItiZ8fy17xc}{J7$m_~+8Fpk4PlxxXCoMq6c`m1#l?S`33>OP_AcSRX-pBv+H0?57v3}j~heu>Y-`pwQB7;&fvEQwjw@Hg&=p7Qm|MGmamgeP_8;^G{=ivM| z-ocqC><88B{}z${8xfy7e698E%Jz(CbZ`ZfP-?2ApZX;h`n0GwaR5%9B5VgTGM0fn zJ|$Ezkc^!2Xt>+X$HS7=(xcN5)+CQqQg~8!izJ%!q3Tk|YN|C3*&mE%8H03WWOBLq z@Pqwu(8jK2i(h%wt0AB?V!!+LELR0M65-eDu|IeOZ3oSul%4=i9Tvv|U^Iyk2)rk0 z3+zrU-AueqdA}d#Hp0@qujEl#WxwNw6=0V|F=>bJ=Ly1iJHM?-XZN!R>D#=Ds>vtk z2=T28=7uqU&?+9Lu$8>h?e5bwAMq4xOnoOmX$|b->WVwElJ?En^{}oCllS3J zfsJ$RMCn_3l7uxIc`z1J+WF8Mxi1;gIVQUMbFbXPAE+wmV{fpFF02MnJ;QRt9+DV8 z@-VBaU~+OZLw^koOuP)VR{hgUM4&GrQ54rUK?zjEc|YLv54SPSCj=00DSExrncFWa zUgwqr+hib5qWwwdXp5J!UE1|Vg%s$f`I~CjFaYet}e=Aw7$b{!nkw%dNnFg-or0ZiG?{++v zOAyQ$3z)eX{Lt9CSGR$n=(4Ej)dEn{l2*Nvf9^v6V&Kmgzbe)Icm?q7t$Z{DA?HaO zE6>EyGD%4kdTQ;H7IjUF*uM;pE{!poou{FCMU^)16B6uqFI#b6Ik^7ts2NGC%Lw|3z1|Tt2;7ujY|Cd*Q8S6g#QjegW2 zLn4U8bXqgMI66?qm4n4JPqt)ts=(2$Z>JMAaHoIfOa%(&yG0!~#|QK?i!4};jTCCo z8WRwRQ}=d>I817^FeUH2eLhEESA~rY3cxcL#X*ZlM*DE~*ePQ`hbwluJTkIIpl|U@QIB zuv*}Jna=5PQ3`O8(i=JrBX8GH+vb({Qcn%34(5a`udD&p{z@mh*efE4(aNDaQYSz6 zfYbJiI6hYi44adB0F=QHLEH4++~#xk)*8dy~>7!X(2uC}>4Y*5sB;TBq2086cKf zK|od5j6D)VZlE+qJ)^*LdnKRA&$AY|f1P#fW34rWeBGsEmV_DW&*qLtTGxIphy7P? zMgf2&gsL=uGs;1e!Pf9)u)o;ehHGN10Ib!=24dD1k^dzbMt>}bqWB`+5x0{?K!_T~Wu9)%y>39bw(s-{J`Oo4F2S;P zGt}Kf!2q;q^d1Whn3^UB8=Z|tt}8&^S!^v!X&Ldscn~vcvxB-J-^GBA4QevlE!;TJ z0C}ccqoub?SA@3oy3Ql7+dnGZMaq#;wBXarwhejMoF!7 zE+ex_hxPt=PP#kqGI_%ab1T6oUsdG-GSN&spLJ$DvW6S81Dldc;`jHEkt0c3Wh@7w zq0}g}YEKHzY%({r<=O?b!aIuO?jsa$P zA|ctznHxA~4-cY@$f+~-Qzm2mpr}U4AyO!4D2BeJ=I@$s^ZQe?+baQ>$H>kIA%1=x zbLAtr`0@F>j2BRlWZ(^3Dh-h75)y?+DBg6U2dm1wxU+eb4+yH>g6LK3P(PUMIiL`u zsX^}nMADM#t5`Lwa_)C7w)jKvkagEv=c8KPH#*~wwk8NI?fcqQjD;8|#b>R(>tQP~ zh%iyxfayZ@e14GwSy&03Ama~J4D#f{P8RAaDwL|$jsB>!MI2pFz!9zIk7f;he=vu2 zH@~y8q@#A=w)f{U&Iz_|zx|r%w3_GvKZl{6d@P&LPq-#4&L$R z!4NakOb}U>T2)HM6({nKP&Gs@x;K{QHOmx|M2Q?z-5p% z%-uil@7^b^QU*-DD>TR4t35%_kLM&uc0F&DB;yU{>`cFDV0Q#}>6?V0jZToRNT6N^ z5dd|;jZLvD@~+VN|6;Odf#tdSJ2HDHd0m3G$f7jwE;~Pwp;a3J{K1GC#Pni#PYTmQ zsW2qwL~-b2`vlGR_d-97wnLQ9?n7CyQ z(deO`b{_dNu%M8xkF=RgNJM2Yl7_{|m58I3tlLg1VrcSwQ3A+i(~W;y)zm4eR#kH& z(YJ8&M1Nbh%!l**cwi{t9co@gj#6ou;paK|$s`8yCji#GGl&b>=NZ}sN_PLvO+uHi z>jpv@WmhKnLXh4q&NeQCDGDKFk635C8S6yyHylpwX`yuN#Ps^t5}yg4#K`P69m>$f z$Dk z%1q2HcKzA*kj1SA2?teBpWb8uEE{0p+HO)Ud`Sm7|B?(zFlvEnC{u9-=N$hniZfRL zr$^|^Lzuf8bt`W}KJxjKHX;^lQSTGY+5hztP5uYd2iAswsqR4t$C~yZP^by3i%f!+Y;m`GhP_D;SBEhPtQ+qk4zxM~jTsH@<=q z$@ZF?MLw6rx~tkD4SJC|nNBTFR7Fy#<_ z-^gk{8mC}C6Q<#>B0^-EY$j_?WSF;}vg~aT`r)u!{~QBLyl=~6FNL|Ds?TpdKyPR5 z0wm`IlRsEur7+5BDt^qsEGk_xb~IDW&To$`k}_xk43TuPwY|Za=Av+YiGM85_U3Zo z-?VyT!nZaC9ST%p&N*k6rSm5fvaI6)G+mjQFl|C9c_1e#a$}Wf&jE`E6a-?h;ht}g zt$Xw?MkN=*``~i3@LR9#{bVW+i(xp~FW}X`ovrDw+g_&#+)!OIy_&4nF5&mq)#MNb;5NY$PyggzA+mI=#r!I z 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 diff --git a/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test1.tmx b/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test1.tmx deleted file mode 100644 index d8c693b..0000000 --- a/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test1.tmx +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - H4sIAAAAAAAAA9XMzQpAQBhG4cnfwsK/sJVBuf/7c9Sn3o0aWXnrSTNz4ty/N4iQTSJkBUpUdp4futa+m4gRIUGKTNq7X7Fbr2usud48Frv3osaBER166/OX/Zf/n+tha6FAAgAA - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test1.tsx b/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test1.tsx deleted file mode 100644 index ce744aa..0000000 --- a/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test1.tsx +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test2.tmx b/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test2.tmx deleted file mode 100644 index 619e74b..0000000 --- a/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test2.tmx +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - H4sIAAAAAAAAA+2bS2/UMBDHDSyUHpBgOZVXV0ALEqKwS8sRhLj0CILyBeAAJ7gARygPiSLBhcciwZX3Q3CCG3w0ZtS1mJixM7GdxFHyk/7aJHKS+cePOLZXqY6Ojo7/WQM9rjuIGvkN+lN3ECXTA20WqldTjB3VMGsIGRlClgwhQ0bIgFGqzDLHRsz2EpNuaNkfqLQ9U8rwrxmo9J9F28t/RwfHNCNkm6G2QP1T6P4T0NNqwqkcif8qKftZu8o/Req/aWVj2nI8z/95h5qEr//DDjWJEP8nVNb3omqmf5/3X5Py/xPoM9GXCNfUXi8Rpeq/DHzz/z7oQbmhJc1P0K+6g5jgWy/2gPaC9nncMyX/viyAjoGO56T7CvpmHHuvmu8fuSBIw40xp57/30E/VP78wBljfztoB9mndYvWq9T9a2zzA3rsSOf/YPK7H3RAcF30/yEksBLY6pA0HZeeI8X8l77LXemkfZ9noOegF4xeBvrwxeXnImhFZft3If6blv8uf2OPe6XoX6PbfgljoiKk7F/KmJGUOtv/66AbgdfgvBd5BnXmP/Y9Yz372OW/inHDt6B3ka7VxPqP/m3vXono+7lK/yHfm5QU85/Op9qQfm/mEdO/C1xPs6Wg8pB8b+ZRlf8y8PF/B3SXaBV0T3BekX5QVcTI/5jfHj59XxebGFFilv+PnqqTGP5129tG/xsM+fivem53Y46KUMSnbv9Syv9QfMt82/3rMt9W/23J/z7Z1vM2If5d85x1rJGR+r+m/o394/6IpFkscL/Y37mhYzcS/z1G+G0ypdbH9m3/EbgMugK6So6hf66v+ZA5vy+IP/R5uto17X+OaOfkVzK+fRN0C3TbES9X5vWxg4L4Y/s3hTGg33mVfQ7S8f1Hlngldf2kIH7J83Shfc6AdoF2q6x/jGGOkfZ9SGX9m/en/kckXm7dvXnuMtk2v1m1VlWc/D8COg06qrL+l+2niqD+pxi5KFr/R66EFqjXU4pv/0JA/68m20XnxfLqv7lOxWcNV55/SRuEvAa9YY7T/Ee/8ypbd1xg3VtT5f4fMc+/pA1C6LoAur5F+8dxkSL5j2so+4pfb+BTzjnwfyzU6zm13i6Z9X9guTfGqPs+NE66bea/1L/vmgLuf0omQ+H1Y2llIts8OqezAvnG8xeas1zUAEAAAA== - - - diff --git a/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test4.tmx b/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test4.tmx deleted file mode 100644 index 8960918..0000000 --- a/tests/build/resources/cocos2d/resources/TileMaps/orthogonal-test4.tmx +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - H4sIAAAAAAAAAFNjYGCQIxFrQGlGIGYCYmYglgRiKSiWRpJjQlID088JxFxAzA3EikCsAsSqQKwMlRMBYiEgFoWqwaVPB4h1kfRxI6nDpw/dPmL1odsnA/WbLJo+Qaj7hYFYE4i1oFgbSU4ISQ1Ijz4Z8WAAxADxIVkbwAEAAA== - - - diff --git a/tests/build/resources/cocos2d/resources/animations/dragon_animation.png b/tests/build/resources/cocos2d/resources/animations/dragon_animation.png deleted file mode 100644 index 064fda0b8b8e9c65eccf153120d760b1305051f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4198 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 b&sqSfIchb-;3!zFErA~OaIHIh;nu$atmEDc diff --git a/tests/build/resources/cocos2d/resources/animations/grossini.plist b/tests/build/resources/cocos2d/resources/animations/grossini.plist deleted file mode 100644 index 97236c4..0000000 --- a/tests/build/resources/cocos2d/resources/animations/grossini.plist +++ /dev/null @@ -1,254 +0,0 @@ - - - - - frames - - grossini_dance_01.png - - frame - {{2, 2}, {51, 109}} - offset - {0, -1} - rotated - - sourceColorRect - {{17, 7}, {51, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_15.png - - - grossini_dance_02.png - - frame - {{55, 2}, {63, 109}} - offset - {-6, -1} - rotated - - sourceColorRect - {{5, 7}, {63, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_16.png - - - grossini_dance_03.png - - frame - {{120, 2}, {63, 109}} - offset - {-6, -1} - rotated - - sourceColorRect - {{5, 7}, {63, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_17.png - - - grossini_dance_04.png - - frame - {{185, 2}, {74, 109}} - offset - {-0.5, -1} - rotated - - sourceColorRect - {{5, 7}, {74, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_18.png - - - grossini_dance_05.png - - frame - {{261, 2}, {74, 109}} - offset - {-0.5, -1} - rotated - - sourceColorRect - {{5, 7}, {74, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_19.png - - - grossini_dance_06.png - - frame - {{337, 2}, {63, 109}} - offset - {-6, -1} - rotated - - sourceColorRect - {{5, 7}, {63, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_20.png - - - grossini_dance_07.png - - frame - {{402, 2}, {63, 109}} - offset - {-6, -1} - rotated - - sourceColorRect - {{5, 7}, {63, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_21.png - - - grossini_dance_08.png - - frame - {{2, 113}, {51, 109}} - offset - {0, -1} - rotated - - sourceColorRect - {{17, 7}, {51, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_22.png - - - grossini_dance_09.png - - frame - {{55, 113}, {51, 109}} - offset - {0, -1} - rotated - - sourceColorRect - {{17, 7}, {51, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_23.png - - - grossini_dance_10.png - - frame - {{108, 113}, {62, 109}} - offset - {5.5, -1} - rotated - - sourceColorRect - {{17, 7}, {62, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_24.png - - - grossini_dance_11.png - - frame - {{172, 113}, {62, 109}} - offset - {5.5, -1} - rotated - - sourceColorRect - {{17, 7}, {62, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_25.png - - - grossini_dance_12.png - - frame - {{236, 113}, {51, 106}} - offset - {0, -2.5} - rotated - - sourceColorRect - {{17, 10}, {51, 106}} - sourceSize - {85, 121} - aliases - - grossini_dance_26.png - - - grossini_dance_13.png - - frame - {{289, 113}, {51, 109}} - offset - {0, -1} - rotated - - sourceColorRect - {{17, 7}, {51, 109}} - sourceSize - {85, 121} - aliases - - grossini_dance_27.png - - - grossini_dance_14.png - - frame - {{342, 113}, {51, 106}} - offset - {0, -2.5} - rotated - - sourceColorRect - {{17, 10}, {51, 106}} - sourceSize - {85, 121} - aliases - - grossini_dance_28.png - - - - metadata - - format - 2 - size - {512, 256} - - - diff --git a/tests/build/resources/cocos2d/resources/animations/grossini.png b/tests/build/resources/cocos2d/resources/animations/grossini.png deleted file mode 100644 index 5672efb11950761b182d46699f67f8ae46328cd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14188 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 N>ZPh&k&N-@{|E7uT^9fV diff --git a/tests/build/resources/cocos2d/resources/animations/grossini_blue.plist b/tests/build/resources/cocos2d/resources/animations/grossini_blue.plist deleted file mode 100644 index 7e39687..0000000 --- a/tests/build/resources/cocos2d/resources/animations/grossini_blue.plist +++ /dev/null @@ -1,92 +0,0 @@ - - - - - texture - - width - 256 - height - 128 - - frames - - grossini_blue_01.png - - x - 76 - y - 1 - width - 51 - height - 109 - offsetX - 0 - offsetY - -1 - originalWidth - 85 - originalHeight - 121 - - grossini_blue_02.png - - x - 128 - y - 1 - width - 63 - height - 109 - offsetX - -6 - offsetY - -1 - originalWidth - 85 - originalHeight - 121 - - grossini_blue_03.png - - x - 192 - y - 1 - width - 63 - height - 109 - offsetX - -6 - offsetY - -1 - originalWidth - 85 - originalHeight - 121 - - grossini_blue_04.png - - x - 1 - y - 1 - width - 74 - height - 109 - offsetX - -0.5 - offsetY - -1 - originalWidth - 85 - originalHeight - 121 - - - - diff --git a/tests/build/resources/cocos2d/resources/animations/grossini_blue.png b/tests/build/resources/cocos2d/resources/animations/grossini_blue.png deleted file mode 100644 index 302cafe2913701ee4c1ee3b54692e8fa783f1da1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1534 zcmZuxX;f236rMyN5gLfH#Dky+$5skTZA(Bj29Xdz6hthGDQorAT3HM>q*30hTU5jp zcLfc&fFgo=kPx>-Ww8nbl|^YF7$^Y+1fH0c_xggT|2lJK&YkZrGxy%P_fXV2HpSZ6 z8UR2E3k{A2fPj+#CR^cq{~d{$LEuKSgFt1A%MgCBN?pSa2AFvkKPWqnBQrBY|#DzQsrA4k0P9s3SD|&OFa{ zW>D!pfhZ>i{Q{DyctALh~@4Ti#TC1~Ytv)duzS$q%u$1nO4CelhPjWY6SA5*~VnrvIW&yNgt{GHE_?>xtOI z1=q!<+EJ6&q(b1BOwk{3UT}Lkc6f?wXLP9p_)_*B3Nj&uw55|P*T}UxP zK8!N9>~P#!wdCM%i)<;DeiWd)&gc*kpCVUxnoN7G;QA`PoX9Wq!`+wQ-XOf37n&+cTgt@!$r>M5W&EgV@hUo+Z33F8_HS?%>>UMYm(| z(Gas=3ozwo!l&)iFrw&oN)}JUt1#tG!ZUi%Pk34kno*mmQgc2tUNeP@5Y=C(?up!spqMg4&H%16;y5#Ha>0911pImJd3($w)3G0 zii?3`HWLPD?u<4vqn0f;j-kRgmi|9@F&EeEPGgjwShqD|w@IX5p&jHZpbp#Olf+%# zb=pHYoJmfcO+ld;i@-`=)nm)Z9SmBJq`B*>n3^+X=s7WFj1#udF#fOHmXI3<-~kO& zP_bH@hxM=o;X_0Gh)6|R-hyJi-pBdA|JSyW?Ci6X&jsfMDAEuRA>QRVbA~sXvAXv~XSq~A4L1gGyyTbX z%yPoY_6t7cw#wqj6>m(7TNv2pwB}bfZgXkLg`%i(Ox?6?m4pk`$%ImkEVF{&b$M=C zQX9D1%`hm1lZsf?jp*56TzN^c+aG&!z65sbWa=7ITaiGH#dI}&uGr6ob*zY}cxyeRnR!d$d_(4!zQ z*#bnR8li`^y!Yz?paO7LX`RnwEHUy&O@d6H0lW+N6V14Vxz7epi~L8{K3W9e!8|Nm za|wXfG;kzewvvZ-xBJDekelR4g19JA**vvF=#F0mdzkgz97qcR{gOfCEtvsaru#PD cdH;6|KY^HZ54-KuFoT&N##$F#8I-)|UwrxVtN;K2 diff --git a/tests/build/resources/cocos2d/resources/animations/grossini_gray.plist b/tests/build/resources/cocos2d/resources/animations/grossini_gray.plist deleted file mode 100644 index cf9bb58..0000000 --- a/tests/build/resources/cocos2d/resources/animations/grossini_gray.plist +++ /dev/null @@ -1,282 +0,0 @@ - - - - - texture - - width - 512 - height - 256 - - frames - - grossini_dance_gray_01.png - - x - 347 - y - 1 - width - 51 - height - 109 - offsetX - 0 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_02.png - - x - 215 - y - 111 - width - 63 - height - 109 - offsetX - -6 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_03.png - - x - 151 - y - 111 - width - 63 - height - 109 - offsetX - -6 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_04.png - - x - 1 - y - 111 - width - 74 - height - 109 - offsetX - -0.5 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_05.png - - x - 76 - y - 111 - width - 74 - height - 109 - offsetX - -0.5 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_06.png - - x - 399 - y - 1 - width - 63 - height - 109 - offsetX - -6 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_07.png - - x - 105 - y - 1 - width - 63 - height - 109 - offsetX - -6 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_08.png - - x - 1 - y - 1 - width - 51 - height - 109 - offsetX - 0 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_09.png - - x - 295 - y - 1 - width - 51 - height - 109 - offsetX - 0 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_10.png - - x - 232 - y - 1 - width - 62 - height - 109 - offsetX - 5.5 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_11.png - - x - 169 - y - 1 - width - 62 - height - 109 - offsetX - 5.5 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_12.png - - x - 279 - y - 111 - width - 51 - height - 106 - offsetX - 0 - offsetY - -2.5 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_13.png - - x - 53 - y - 1 - width - 51 - height - 109 - offsetX - 0 - offsetY - -1 - originalWidth - 85 - originalHeight - -121 - - grossini_dance_gray_14.png - - x - 331 - y - 111 - width - 51 - height - 106 - offsetX - 0 - offsetY - -2.5 - originalWidth - 85 - originalHeight - -121 - - - - diff --git a/tests/build/resources/cocos2d/resources/animations/grossini_gray.png b/tests/build/resources/cocos2d/resources/animations/grossini_gray.png deleted file mode 100644 index 897c0ee96622c2dfde78ed3b587d811096b72cc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6062 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 Z{vWZ$MDj2umy7@a002ovPDHLkV1lhaiZuWL diff --git a/tests/build/resources/cocos2d/resources/f2.png b/tests/build/resources/cocos2d/resources/f2.png deleted file mode 100644 index e752eda24dd55e19813ef79fb93213234ad5db04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4046 zcmV;<4>9nGP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2iXD; z4k|dF%en*r01r+{L_t(&-sPKZj8xZo$N$ec_ujelwl9NOFIm96>@LI@OpF5wF?M5I zyOv`TRaW|;iK?uW05VBmVp~yD#ZsG8xUCeoajK}2RVj6&HIW?FRWSfA^ zi!m6yunW5^u(LCB=f0iu^uyk}T<*>cFUGD-uXHt+*_nIK`JMm&d7g9509^YAMdwvN z#Qy_$5`ghR02HYax@M02fjl<6{yGWE$^gg$up*FjHAf|REw2@LUmy4%n}Ba*)~)+Q z_3+`KJ~X5gf9B}CYVd3TnFcZ9W2wkh8#ZK!=#kD`?&}?Q-Z_gpI!>S2xwDo6_r3ti zFKpX(OW(ji$LZa>l{+%hmQWyloMYn3_3KRlUo?qUc39Su?j=iZ$=-XfaE=`tsSgkP z35Zt=Q1%ZDe42pgXWVno%KU-_(kK?CJ3P$V_v1h-BZ%VTq{3C}*GmHK5JW2kk+7xg zn%&v?`JTJ)UM_CBX|z5(T=hmq)cb)b`v(SW0P8FvK3$wQZ%uLe@+C8Gzx@-^ww=m> z13s9|2wYl`A8Bi^TEAWhqLl=!i5n-0s9+egub(q#W&WE`woD{kvvx9+C={Q0P#I8g_)rG4Ls)YwRoAF0f}dcy_~a1($( zkVFtfh+ZipM0=NQ-#mNOs%1`B*P+V6gB9gCmkm(%4Gee$ECH}O?lb|0DMV*Jms>oe zzyH4L)~&m3#%Dj<)4pt3yICw6?#Yv+eLn-hj7k6_p-h=bI?3ciA12g$zWGgr%yR|N z9|91P2qnuxr)9y_8Uir$hB0^HjW^zDty{-IwR&=5|Nf*3FRA**7q)Ht8h{@HXt#tw z&M;63g7jxOWG+`+_n<#Me!w|;bpOz^&%SYH$Br=oUUUWkLI6Gh6*WR7MwC;d%c=6= zsvZyR+4K7Veh#1{0Cd?lmbJHI)bsFOtp-Oa06?I1`IPHE_tImJ{oT+r&m0HfM1A3l zmMV(}267DC4WML8iDm8WxP9hKNFq#xAv7}t5g9~w&NOEii^ZkwbLM=ed+pk_-48sl ze8%e4*ULx%~Ql-`eGS8v?dC4hS+QHdh!&a!Qk zEDJL%3n4S=VF-iBE}G`z*{fI24;L*udhWH?##Oz3QFsOb5YYiJj|!mIR|=XLvvWE0 z77B2b!hwki9Ie$b=KGik0%&GK5_Q;8cC?jBy(pFL>tC@VmSe@C^Ig&KI{A3mB|FLY<;bv zm=WspA?J$= z!|;T6?%c3DIyzK2aA2^!XV0myR&$l(_{#GFjeN^hm@5aX;+y1R@{c?Qw?(xL4 zFH~N1>=FPI5mmzw)i8u&o~BpL43h|^VW4OjSdh=d*Ba#@z-iCJS>H!F2vAoFZZy)& zEG;2&0CE6OFpSwVGMS}RC_v7g3*34u)K|XZc}ksilp3vu;aEKg&V|+LnV?)A3#!$s zs?};ix$LM~%?m0OHy9tUyQfdP?(lHk865Pq=cN;rc8(wKL8;V{^t7k-v*{OjzGf1LT{J@@=HtW=!H9n;}SqJ8moT`2@w!%+%Gq@G5(n-g%` zOcQOUiFwR$l|oG^IAMr#5TF`{s3`?kDTK^W%#&H+yfR@DWlY1E)n=NrrfkvK3Cx+p z4ETZ8wSd`SW;bAV6?0urzPf?dj<2;-SE?F1PBpAnYeA(_EzX^LgDFI}jEG7iF!Lnc zluP1&wVNi02Ll4uIL zNQDLfN|#Dg3KT?APA*4HIff@KIb8^e>ztGjmW6TpHY#G!YB(mO2Ln=Rb=@fp>EAQ zb-x%KO^>hV-%C8Rq7*t!6LWI8slT_XLv-Yji7*5+!_#{A!Aj*Xo?5l)H;rN*2skQ; zR!0F7b)}FIq9K$Pi+8+JKLxLygXo5XcBIHE6oYU?GwmlB@VWJtM&f$u-@ z&O6`T)Z14vQr{b+D3AwQ!_yk70VHlB^H!tDE$(x%_w*%(209-nVMUHnse5~ACT*oAy?#-}=msTCx^Y(mywUr78PCuy;&1Xf zaY#^FBZ#hjtr0RK&>E%?m}T3@8wLny126#Kzl_w)&x*ti!zh@?7HZVUW?5G^u!l~K zXshq)wCz)aHO2 z+vv9KDUkyB5rEB``uZj=%(g_+HZ6iwXOayJBS?N?6ywh81}bc(EN<`&ZV_jj#i>@% z_#)O$ClE=5>oS=nI7LKHG4o@a`uZAV+eDTV3A^Y--4n+FKM@PnMHm7 zaI=L05Ku_gS&A89v_Q}>12#z<+@g`K?Ab~k&6Gw&$QuT7Qo<4fb`;oS2W6!M5lzM0 zW*MECA&D?Elfk@vKIy<074!Gf;HJR?&=ZT#AiAJHZU(K9(k=$=Qj$Qcm?nu}2!WiG z$VSjoQ?)uxu40S0-qS6haRhs2CWHC;JPaWqCKql0Qv(k*0ykZGL_NuX`B8utf8QiR zMoMIafE}#_H<-_kF|boHziJRY2%twqNic0sPEF;yG8yz13UR*~z;gh;^I&i9k(SHw zi4M<-p%GC_dtPqlypnik62XqtWfH+kSu*N4Gw?10&nf1uu2Q=XSF5A9mP&sNphqNE zOq&$**V{H0;Uk{#unfjDQ{8IwjU-mkx+bWMUx0JvRwk20x%9>STXNZT0cAH z`#URPSUo&4;%&eGe*VG!{as>m(`hO`roly9VqQKUuUiHHwgUL`jSE|Yy8zyr z7hlW@V3ADB4;xwRa_rd(nuvC@tf;K8gn%Tv09dLWW14v%1A8>{_K7fjj9t#pRoI&(%p!H@A z{OrNrUgt`mXBb4+0aybdpRS>rfMWr;0M2OU5db3qPATT&8W;?I}uSl_@68m(Pi7Q+5q5pA@g5W!*J`vix-FQ=XnMJ^8wt3l#(J? zJ~NMM;241SSnFd9yrY>Z1L>Cy;XJ<$65 ziuo5I^RYkc?^jnnOyJr%mK#Jf0E~ppFS$zn;DwVX4{pidp>gX66l1R;c)b9&Yvx~6 z!*J_Eixy3M;0fwlAt#7lBH-8GSg>&D!wN?K3$&ZsSXgD>_5c6?07*qoM6N<$f?MRD ANdN!< diff --git a/tests/build/resources/cocos2d/resources/grossini_dance_atlas-red.png b/tests/build/resources/cocos2d/resources/grossini_dance_atlas-red.png deleted file mode 100644 index 6de48393a2be6c72df4be5c4d49e38bb567c7ddf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8078 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 diff --git a/tests/build/resources/cocos2d/resources/r1.png b/tests/build/resources/cocos2d/resources/r1.png deleted file mode 100644 index 827a77226e2bb127b40591db58fd55475bd91e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1956 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 j{cQ5l+68f8Uo!j;y-bQt_= 0; --j){ - ar[i] += dec.charCodeAt((i *bytes) +j) << (j *8); - } - } - return ar; - }, - - /** - * Encode a binary string into base64 - * - * @param {String} input Binary string - * @returns {String} Base64 encoded data - */ - encode: function(input) { - return JXG.Util.Base64.encode(input); - } -}; - -module.exports = base64; - -}}; -__resources__["/__builtin__/libs/box2d.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -function extend(a, b) { - for(var c in b) { - a[c] = b[c] - } -} -function isInstanceOf(obj, _constructor) { - while(typeof obj === "object") { - if(obj.constructor === _constructor) { - return true - } - obj = obj._super - } - return false -} -;var b2BoundValues = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2BoundValues.prototype.__constructor = function() { - this.lowerValues = new Array; - this.lowerValues[0] = 0; - this.lowerValues[1] = 0; - this.upperValues = new Array; - this.upperValues[0] = 0; - this.upperValues[1] = 0 -}; -b2BoundValues.prototype.__varz = function() { -}; -b2BoundValues.prototype.lowerValues = null; -b2BoundValues.prototype.upperValues = null;var b2PairManager = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2PairManager.prototype.__constructor = function() { - this.m_pairs = new Array; - this.m_pairBuffer = new Array; - this.m_pairCount = 0; - this.m_pairBufferCount = 0; - this.m_freePair = null -}; -b2PairManager.prototype.__varz = function() { -}; -b2PairManager.prototype.AddPair = function(proxy1, proxy2) { - var pair = proxy1.pairs[proxy2]; - if(pair != null) { - return pair - } - if(this.m_freePair == null) { - this.m_freePair = new b2Pair; - this.m_pairs.push(this.m_freePair) - } - pair = this.m_freePair; - this.m_freePair = pair.next; - pair.proxy1 = proxy1; - pair.proxy2 = proxy2; - pair.status = 0; - pair.userData = null; - pair.next = null; - proxy1.pairs[proxy2] = pair; - proxy2.pairs[proxy1] = pair; - ++this.m_pairCount; - return pair -}; -b2PairManager.prototype.RemovePair = function(proxy1, proxy2) { - var pair = proxy1.pairs[proxy2]; - if(pair == null) { - return null - } - var userData = pair.userData; - delete proxy1.pairs[proxy2]; - delete proxy2.pairs[proxy1]; - pair.next = this.m_freePair; - pair.proxy1 = null; - pair.proxy2 = null; - pair.userData = null; - pair.status = 0; - this.m_freePair = pair; - --this.m_pairCount; - return userData -}; -b2PairManager.prototype.Find = function(proxy1, proxy2) { - return proxy1.pairs[proxy2] -}; -b2PairManager.prototype.ValidateBuffer = function() { -}; -b2PairManager.prototype.ValidateTable = function() { -}; -b2PairManager.prototype.Initialize = function(broadPhase) { - this.m_broadPhase = broadPhase -}; -b2PairManager.prototype.AddBufferedPair = function(proxy1, proxy2) { - var pair = this.AddPair(proxy1, proxy2); - if(pair.IsBuffered() == false) { - pair.SetBuffered(); - this.m_pairBuffer[this.m_pairBufferCount] = pair; - ++this.m_pairBufferCount - } - pair.ClearRemoved(); - if(b2BroadPhase.s_validate) { - this.ValidateBuffer() - } -}; -b2PairManager.prototype.RemoveBufferedPair = function(proxy1, proxy2) { - var pair = this.Find(proxy1, proxy2); - if(pair == null) { - return - } - if(pair.IsBuffered() == false) { - pair.SetBuffered(); - this.m_pairBuffer[this.m_pairBufferCount] = pair; - ++this.m_pairBufferCount - } - pair.SetRemoved(); - if(b2BroadPhase.s_validate) { - this.ValidateBuffer() - } -}; -b2PairManager.prototype.Commit = function(callback) { - var i = 0; - var removeCount = 0; - for(i = 0;i < this.m_pairBufferCount;++i) { - var pair = this.m_pairBuffer[i]; - pair.ClearBuffered(); - var proxy1 = pair.proxy1; - var proxy2 = pair.proxy2; - if(pair.IsRemoved()) { - }else { - if(pair.IsFinal() == false) { - callback(proxy1.userData, proxy2.userData) - } - } - } - this.m_pairBufferCount = 0; - if(b2BroadPhase.s_validate) { - this.ValidateTable() - } -}; -b2PairManager.prototype.m_broadPhase = null; -b2PairManager.prototype.m_pairs = null; -b2PairManager.prototype.m_freePair = null; -b2PairManager.prototype.m_pairCount = 0; -b2PairManager.prototype.m_pairBuffer = null; -b2PairManager.prototype.m_pairBufferCount = 0;var b2TimeStep = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2TimeStep.prototype.__constructor = function() { -}; -b2TimeStep.prototype.__varz = function() { -}; -b2TimeStep.prototype.Set = function(step) { - this.dt = step.dt; - this.inv_dt = step.inv_dt; - this.positionIterations = step.positionIterations; - this.velocityIterations = step.velocityIterations; - this.warmStarting = step.warmStarting -}; -b2TimeStep.prototype.dt = null; -b2TimeStep.prototype.inv_dt = null; -b2TimeStep.prototype.dtRatio = null; -b2TimeStep.prototype.velocityIterations = 0; -b2TimeStep.prototype.positionIterations = 0; -b2TimeStep.prototype.warmStarting = null;var b2Controller = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Controller.prototype.__constructor = function() { -}; -b2Controller.prototype.__varz = function() { -}; -b2Controller.prototype.Step = function(step) { -}; -b2Controller.prototype.Draw = function(debugDraw) { -}; -b2Controller.prototype.AddBody = function(body) { - var edge = new b2ControllerEdge; - edge.controller = this; - edge.body = body; - edge.nextBody = m_bodyList; - edge.prevBody = null; - m_bodyList = edge; - if(edge.nextBody) { - edge.nextBody.prevBody = edge - } - m_bodyCount++; - edge.nextController = body.m_controllerList; - edge.prevController = null; - body.m_controllerList = edge; - if(edge.nextController) { - edge.nextController.prevController = edge - } - body.m_controllerCount++ -}; -b2Controller.prototype.RemoveBody = function(body) { - var edge = body.m_controllerList; - while(edge && edge.controller != this) { - edge = edge.nextController - } - if(edge.prevBody) { - edge.prevBody.nextBody = edge.nextBody - } - if(edge.nextBody) { - edge.nextBody.prevBody = edge.prevBody - } - if(edge.nextController) { - edge.nextController.prevController = edge.prevController - } - if(edge.prevController) { - edge.prevController.nextController = edge.nextController - } - if(m_bodyList == edge) { - m_bodyList = edge.nextBody - } - if(body.m_controllerList == edge) { - body.m_controllerList = edge.nextController - } - body.m_controllerCount--; - m_bodyCount-- -}; -b2Controller.prototype.Clear = function() { - while(m_bodyList) { - this.RemoveBody(m_bodyList.body) - } -}; -b2Controller.prototype.GetNext = function() { - return this.m_next -}; -b2Controller.prototype.GetWorld = function() { - return this.m_world -}; -b2Controller.prototype.GetBodyList = function() { - return m_bodyList -}; -b2Controller.prototype.m_next = null; -b2Controller.prototype.m_prev = null; -b2Controller.prototype.m_world = null;var b2GravityController = function() { - b2Controller.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2GravityController.prototype, b2Controller.prototype); -b2GravityController.prototype._super = b2Controller.prototype; -b2GravityController.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2GravityController.prototype.__varz = function() { -}; -b2GravityController.prototype.Step = function(step) { - var i = null; - var body1 = null; - var p1 = null; - var mass1 = 0; - var j = null; - var body2 = null; - var p2 = null; - var dx = 0; - var dy = 0; - var r2 = 0; - var f = null; - if(this.invSqr) { - for(i = m_bodyList;i;i = i.nextBody) { - body1 = i.body; - p1 = body1.GetWorldCenter(); - mass1 = body1.GetMass(); - for(j = m_bodyList;j != i;j = j.nextBody) { - body2 = j.body; - p2 = body2.GetWorldCenter(); - dx = p2.x - p1.x; - dy = p2.y - p1.y; - r2 = dx * dx + dy * dy; - if(r2 < Number.MIN_VALUE) { - continue - } - f = new b2Vec2(dx, dy); - f.Multiply(this.G / r2 / Math.sqrt(r2) * mass1 * body2.GetMass()); - if(body1.IsAwake()) { - body1.ApplyForce(f, p1) - } - f.Multiply(-1); - if(body2.IsAwake()) { - body2.ApplyForce(f, p2) - } - } - } - }else { - for(i = m_bodyList;i;i = i.nextBody) { - body1 = i.body; - p1 = body1.GetWorldCenter(); - mass1 = body1.GetMass(); - for(j = m_bodyList;j != i;j = j.nextBody) { - body2 = j.body; - p2 = body2.GetWorldCenter(); - dx = p2.x - p1.x; - dy = p2.y - p1.y; - r2 = dx * dx + dy * dy; - if(r2 < Number.MIN_VALUE) { - continue - } - f = new b2Vec2(dx, dy); - f.Multiply(this.G / r2 * mass1 * body2.GetMass()); - if(body1.IsAwake()) { - body1.ApplyForce(f, p1) - } - f.Multiply(-1); - if(body2.IsAwake()) { - body2.ApplyForce(f, p2) - } - } - } - } -}; -b2GravityController.prototype.G = 1; -b2GravityController.prototype.invSqr = true;var b2DestructionListener = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2DestructionListener.prototype.__constructor = function() { -}; -b2DestructionListener.prototype.__varz = function() { -}; -b2DestructionListener.prototype.SayGoodbyeJoint = function(joint) { -}; -b2DestructionListener.prototype.SayGoodbyeFixture = function(fixture) { -};var b2ContactEdge = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactEdge.prototype.__constructor = function() { -}; -b2ContactEdge.prototype.__varz = function() { -}; -b2ContactEdge.prototype.other = null; -b2ContactEdge.prototype.contact = null; -b2ContactEdge.prototype.prev = null; -b2ContactEdge.prototype.next = null;var b2EdgeChainDef = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2EdgeChainDef.prototype.__constructor = function() { - this.vertexCount = 0; - this.isALoop = true; - this.vertices = [] -}; -b2EdgeChainDef.prototype.__varz = function() { -}; -b2EdgeChainDef.prototype.vertices = null; -b2EdgeChainDef.prototype.vertexCount = null; -b2EdgeChainDef.prototype.isALoop = null;var b2Vec2 = function(x_, y_) { - if(arguments.length == 2) { - this.x = x_; - this.y = y_ - } -}; -b2Vec2.Make = function(x_, y_) { - return new b2Vec2(x_, y_) -}; -b2Vec2.prototype.SetZero = function() { - this.x = 0; - this.y = 0 -}; -b2Vec2.prototype.Set = function(x_, y_) { - this.x = x_; - this.y = y_ -}; -b2Vec2.prototype.SetV = function(v) { - this.x = v.x; - this.y = v.y -}; -b2Vec2.prototype.GetNegative = function() { - return new b2Vec2(-this.x, -this.y) -}; -b2Vec2.prototype.NegativeSelf = function() { - this.x = -this.x; - this.y = -this.y -}; -b2Vec2.prototype.Copy = function() { - return new b2Vec2(this.x, this.y) -}; -b2Vec2.prototype.Add = function(v) { - this.x += v.x; - this.y += v.y -}; -b2Vec2.prototype.Subtract = function(v) { - this.x -= v.x; - this.y -= v.y -}; -b2Vec2.prototype.Multiply = function(a) { - this.x *= a; - this.y *= a -}; -b2Vec2.prototype.MulM = function(A) { - var tX = this.x; - this.x = A.col1.x * tX + A.col2.x * this.y; - this.y = A.col1.y * tX + A.col2.y * this.y -}; -b2Vec2.prototype.MulTM = function(A) { - var tX = b2Math.Dot(this, A.col1); - this.y = b2Math.Dot(this, A.col2); - this.x = tX -}; -b2Vec2.prototype.CrossVF = function(s) { - var tX = this.x; - this.x = s * this.y; - this.y = -s * tX -}; -b2Vec2.prototype.CrossFV = function(s) { - var tX = this.x; - this.x = -s * this.y; - this.y = s * tX -}; -b2Vec2.prototype.MinV = function(b) { - this.x = this.x < b.x ? this.x : b.x; - this.y = this.y < b.y ? this.y : b.y -}; -b2Vec2.prototype.MaxV = function(b) { - this.x = this.x > b.x ? this.x : b.x; - this.y = this.y > b.y ? this.y : b.y -}; -b2Vec2.prototype.Abs = function() { - if(this.x < 0) { - this.x = -this.x - } - if(this.y < 0) { - this.y = -this.y - } -}; -b2Vec2.prototype.Length = function() { - return Math.sqrt(this.x * this.x + this.y * this.y) -}; -b2Vec2.prototype.LengthSquared = function() { - return this.x * this.x + this.y * this.y -}; -b2Vec2.prototype.Normalize = function() { - var length = Math.sqrt(this.x * this.x + this.y * this.y); - if(length < Number.MIN_VALUE) { - return 0 - } - var invLength = 1 / length; - this.x *= invLength; - this.y *= invLength; - return length -}; -b2Vec2.prototype.IsValid = function() { - return b2Math.IsValid(this.x) && b2Math.IsValid(this.y) -}; -b2Vec2.prototype.x = 0; -b2Vec2.prototype.y = 0;var b2Vec3 = function(x, y, z) { - if(arguments.length == 3) { - this.x = x; - this.y = y; - this.z = z - } -}; -b2Vec3.prototype.SetZero = function() { - this.x = this.y = this.z = 0 -}; -b2Vec3.prototype.Set = function(x, y, z) { - this.x = x; - this.y = y; - this.z = z -}; -b2Vec3.prototype.SetV = function(v) { - this.x = v.x; - this.y = v.y; - this.z = v.z -}; -b2Vec3.prototype.GetNegative = function() { - return new b2Vec3(-this.x, -this.y, -this.z) -}; -b2Vec3.prototype.NegativeSelf = function() { - this.x = -this.x; - this.y = -this.y; - this.z = -this.z -}; -b2Vec3.prototype.Copy = function() { - return new b2Vec3(this.x, this.y, this.z) -}; -b2Vec3.prototype.Add = function(v) { - this.x += v.x; - this.y += v.y; - this.z += v.z -}; -b2Vec3.prototype.Subtract = function(v) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z -}; -b2Vec3.prototype.Multiply = function(a) { - this.x *= a; - this.y *= a; - this.z *= a -}; -b2Vec3.prototype.x = 0; -b2Vec3.prototype.y = 0; -b2Vec3.prototype.z = 0;var b2DistanceProxy = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2DistanceProxy.prototype.__constructor = function() { -}; -b2DistanceProxy.prototype.__varz = function() { -}; -b2DistanceProxy.prototype.Set = function(shape) { - switch(shape.GetType()) { - case b2Shape.e_circleShape: - var circle = shape; - this.m_vertices = new Array(1); - this.m_vertices[0] = circle.m_p; - this.m_count = 1; - this.m_radius = circle.m_radius; - break; - case b2Shape.e_polygonShape: - var polygon = shape; - this.m_vertices = polygon.m_vertices; - this.m_count = polygon.m_vertexCount; - this.m_radius = polygon.m_radius; - break; - default: - b2Settings.b2Assert(false) - } -}; -b2DistanceProxy.prototype.GetSupport = function(d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for(var i = 1;i < this.m_count;++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if(value > bestValue) { - bestIndex = i; - bestValue = value - } - } - return bestIndex -}; -b2DistanceProxy.prototype.GetSupportVertex = function(d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for(var i = 1;i < this.m_count;++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if(value > bestValue) { - bestIndex = i; - bestValue = value - } - } - return this.m_vertices[bestIndex] -}; -b2DistanceProxy.prototype.GetVertexCount = function() { - return this.m_count -}; -b2DistanceProxy.prototype.GetVertex = function(index) { - b2Settings.b2Assert(0 <= index && index < this.m_count); - return this.m_vertices[index] -}; -b2DistanceProxy.prototype.m_vertices = null; -b2DistanceProxy.prototype.m_count = 0; -b2DistanceProxy.prototype.m_radius = null;var b2ContactFactory = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactFactory.prototype.__constructor = function() { -}; -b2ContactFactory.prototype.__varz = function() { - this.InitializeRegisters() -}; -b2ContactFactory.prototype.AddType = function(createFcn, destroyFcn, type1, type2) { - this.m_registers[type1][type2].createFcn = createFcn; - this.m_registers[type1][type2].destroyFcn = destroyFcn; - this.m_registers[type1][type2].primary = true; - if(type1 != type2) { - this.m_registers[type2][type1].createFcn = createFcn; - this.m_registers[type2][type1].destroyFcn = destroyFcn; - this.m_registers[type2][type1].primary = false - } -}; -b2ContactFactory.prototype.InitializeRegisters = function() { - this.m_registers = new Array(b2Shape.e_shapeTypeCount); - for(var i = 0;i < b2Shape.e_shapeTypeCount;i++) { - this.m_registers[i] = new Array(b2Shape.e_shapeTypeCount); - for(var j = 0;j < b2Shape.e_shapeTypeCount;j++) { - this.m_registers[i][j] = new b2ContactRegister - } - } - this.AddType(b2CircleContact.Create, b2CircleContact.Destroy, b2Shape.e_circleShape, b2Shape.e_circleShape); - this.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_circleShape); - this.AddType(b2PolygonContact.Create, b2PolygonContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_polygonShape); - this.AddType(b2EdgeAndCircleContact.Create, b2EdgeAndCircleContact.Destroy, b2Shape.e_edgeShape, b2Shape.e_circleShape); - this.AddType(b2PolyAndEdgeContact.Create, b2PolyAndEdgeContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_edgeShape) -}; -b2ContactFactory.prototype.Create = function(fixtureA, fixtureB) { - var type1 = fixtureA.GetType(); - var type2 = fixtureB.GetType(); - var reg = this.m_registers[type1][type2]; - var c; - if(reg.pool) { - c = reg.pool; - reg.pool = c.m_next; - reg.poolCount--; - c.Reset(fixtureA, fixtureB); - return c - } - var createFcn = reg.createFcn; - if(createFcn != null) { - if(reg.primary) { - c = createFcn(this.m_allocator); - c.Reset(fixtureA, fixtureB); - return c - }else { - c = createFcn(this.m_allocator); - c.Reset(fixtureB, fixtureA); - return c - } - }else { - return null - } -}; -b2ContactFactory.prototype.Destroy = function(contact) { - if(contact.m_manifold.m_pointCount > 0) { - contact.m_fixtureA.m_body.SetAwake(true); - contact.m_fixtureB.m_body.SetAwake(true) - } - var type1 = contact.m_fixtureA.GetType(); - var type2 = contact.m_fixtureB.GetType(); - var reg = this.m_registers[type1][type2]; - if(true) { - reg.poolCount++; - contact.m_next = reg.pool; - reg.pool = contact - } - var destroyFcn = reg.destroyFcn; - destroyFcn(contact, this.m_allocator) -}; -b2ContactFactory.prototype.m_registers = null; -b2ContactFactory.prototype.m_allocator = null;var b2ConstantAccelController = function() { - b2Controller.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2ConstantAccelController.prototype, b2Controller.prototype); -b2ConstantAccelController.prototype._super = b2Controller.prototype; -b2ConstantAccelController.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2ConstantAccelController.prototype.__varz = function() { - this.A = new b2Vec2(0, 0) -}; -b2ConstantAccelController.prototype.Step = function(step) { - var smallA = new b2Vec2(this.A.x * step.dt, this.A.y * step.dt); - for(var i = m_bodyList;i;i = i.nextBody) { - var body = i.body; - if(!body.IsAwake()) { - continue - } - body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + smallA.x, body.GetLinearVelocity().y + smallA.y)) - } -}; -b2ConstantAccelController.prototype.A = new b2Vec2(0, 0);var b2SeparationFunction = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2SeparationFunction.prototype.__constructor = function() { -}; -b2SeparationFunction.prototype.__varz = function() { - this.m_localPoint = new b2Vec2; - this.m_axis = new b2Vec2 -}; -b2SeparationFunction.e_points = 1; -b2SeparationFunction.e_faceA = 2; -b2SeparationFunction.e_faceB = 4; -b2SeparationFunction.prototype.Initialize = function(cache, proxyA, transformA, proxyB, transformB) { - this.m_proxyA = proxyA; - this.m_proxyB = proxyB; - var count = cache.count; - b2Settings.b2Assert(0 < count && count < 3); - var localPointA; - var localPointA1; - var localPointA2; - var localPointB; - var localPointB1; - var localPointB2; - var pointAX; - var pointAY; - var pointBX; - var pointBY; - var normalX; - var normalY; - var tMat; - var tVec; - var s; - var sgn; - if(count == 1) { - this.m_type = b2SeparationFunction.e_points; - localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); - localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); - tVec = localPointA; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointB; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_axis.x = pointBX - pointAX; - this.m_axis.y = pointBY - pointAY; - this.m_axis.Normalize() - }else { - if(cache.indexB[0] == cache.indexB[1]) { - this.m_type = b2SeparationFunction.e_faceA; - localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); - localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); - localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); - this.m_localPoint.x = 0.5 * (localPointA1.x + localPointA2.x); - this.m_localPoint.y = 0.5 * (localPointA1.y + localPointA2.y); - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1); - this.m_axis.Normalize(); - tVec = this.m_axis; - tMat = transformA.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointB; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - s = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; - if(s < 0) { - this.m_axis.NegativeSelf() - } - }else { - if(cache.indexA[0] == cache.indexA[0]) { - this.m_type = b2SeparationFunction.e_faceB; - localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); - localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); - localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); - this.m_localPoint.x = 0.5 * (localPointB1.x + localPointB2.x); - this.m_localPoint.y = 0.5 * (localPointB1.y + localPointB2.y); - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1); - this.m_axis.Normalize(); - tVec = this.m_axis; - tMat = transformB.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointA; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - s = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; - if(s < 0) { - this.m_axis.NegativeSelf() - } - }else { - localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); - localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); - localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); - localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); - var pA = b2Math.MulX(transformA, localPointA); - var dA = b2Math.MulMV(transformA.R, b2Math.SubtractVV(localPointA2, localPointA1)); - var pB = b2Math.MulX(transformB, localPointB); - var dB = b2Math.MulMV(transformB.R, b2Math.SubtractVV(localPointB2, localPointB1)); - var a = dA.x * dA.x + dA.y * dA.y; - var e = dB.x * dB.x + dB.y * dB.y; - var r = b2Math.SubtractVV(dB, dA); - var c = dA.x * r.x + dA.y * r.y; - var f = dB.x * r.x + dB.y * r.y; - var b = dA.x * dB.x + dA.y * dB.y; - var denom = a * e - b * b; - s = 0; - if(denom != 0) { - s = b2Math.Clamp((b * f - c * e) / denom, 0, 1) - } - var t = (b * s + f) / e; - if(t < 0) { - t = 0; - s = b2Math.Clamp((b - c) / a, 0, 1) - } - localPointA = new b2Vec2; - localPointA.x = localPointA1.x + s * (localPointA2.x - localPointA1.x); - localPointA.y = localPointA1.y + s * (localPointA2.y - localPointA1.y); - localPointB = new b2Vec2; - localPointB.x = localPointB1.x + s * (localPointB2.x - localPointB1.x); - localPointB.y = localPointB1.y + s * (localPointB2.y - localPointB1.y); - if(s == 0 || s == 1) { - this.m_type = b2SeparationFunction.e_faceB; - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1); - this.m_axis.Normalize(); - this.m_localPoint = localPointB; - tVec = this.m_axis; - tMat = transformB.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointA; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - sgn = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; - if(s < 0) { - this.m_axis.NegativeSelf() - } - }else { - this.m_type = b2SeparationFunction.e_faceA; - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1); - this.m_localPoint = localPointA; - tVec = this.m_axis; - tMat = transformA.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointB; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - sgn = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; - if(s < 0) { - this.m_axis.NegativeSelf() - } - } - } - } - } -}; -b2SeparationFunction.prototype.Evaluate = function(transformA, transformB) { - var axisA; - var axisB; - var localPointA; - var localPointB; - var pointA; - var pointB; - var seperation; - var normal; - switch(this.m_type) { - case b2SeparationFunction.e_points: - axisA = b2Math.MulTMV(transformA.R, this.m_axis); - axisB = b2Math.MulTMV(transformB.R, this.m_axis.GetNegative()); - localPointA = this.m_proxyA.GetSupportVertex(axisA); - localPointB = this.m_proxyB.GetSupportVertex(axisB); - pointA = b2Math.MulX(transformA, localPointA); - pointB = b2Math.MulX(transformB, localPointB); - seperation = (pointB.x - pointA.x) * this.m_axis.x + (pointB.y - pointA.y) * this.m_axis.y; - return seperation; - case b2SeparationFunction.e_faceA: - normal = b2Math.MulMV(transformA.R, this.m_axis); - pointA = b2Math.MulX(transformA, this.m_localPoint); - axisB = b2Math.MulTMV(transformB.R, normal.GetNegative()); - localPointB = this.m_proxyB.GetSupportVertex(axisB); - pointB = b2Math.MulX(transformB, localPointB); - seperation = (pointB.x - pointA.x) * normal.x + (pointB.y - pointA.y) * normal.y; - return seperation; - case b2SeparationFunction.e_faceB: - normal = b2Math.MulMV(transformB.R, this.m_axis); - pointB = b2Math.MulX(transformB, this.m_localPoint); - axisA = b2Math.MulTMV(transformA.R, normal.GetNegative()); - localPointA = this.m_proxyA.GetSupportVertex(axisA); - pointA = b2Math.MulX(transformA, localPointA); - seperation = (pointA.x - pointB.x) * normal.x + (pointA.y - pointB.y) * normal.y; - return seperation; - default: - b2Settings.b2Assert(false); - return 0 - } -}; -b2SeparationFunction.prototype.m_proxyA = null; -b2SeparationFunction.prototype.m_proxyB = null; -b2SeparationFunction.prototype.m_type = 0; -b2SeparationFunction.prototype.m_localPoint = new b2Vec2; -b2SeparationFunction.prototype.m_axis = new b2Vec2;var b2DynamicTreePair = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2DynamicTreePair.prototype.__constructor = function() { -}; -b2DynamicTreePair.prototype.__varz = function() { -}; -b2DynamicTreePair.prototype.proxyA = null; -b2DynamicTreePair.prototype.proxyB = null;var b2ContactConstraintPoint = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactConstraintPoint.prototype.__constructor = function() { -}; -b2ContactConstraintPoint.prototype.__varz = function() { - this.localPoint = new b2Vec2; - this.rA = new b2Vec2; - this.rB = new b2Vec2 -}; -b2ContactConstraintPoint.prototype.localPoint = new b2Vec2; -b2ContactConstraintPoint.prototype.rA = new b2Vec2; -b2ContactConstraintPoint.prototype.rB = new b2Vec2; -b2ContactConstraintPoint.prototype.normalImpulse = null; -b2ContactConstraintPoint.prototype.tangentImpulse = null; -b2ContactConstraintPoint.prototype.normalMass = null; -b2ContactConstraintPoint.prototype.tangentMass = null; -b2ContactConstraintPoint.prototype.equalizedMass = null; -b2ContactConstraintPoint.prototype.velocityBias = null;var b2ControllerEdge = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ControllerEdge.prototype.__constructor = function() { -}; -b2ControllerEdge.prototype.__varz = function() { -}; -b2ControllerEdge.prototype.controller = null; -b2ControllerEdge.prototype.body = null; -b2ControllerEdge.prototype.prevBody = null; -b2ControllerEdge.prototype.nextBody = null; -b2ControllerEdge.prototype.prevController = null; -b2ControllerEdge.prototype.nextController = null;var b2DistanceInput = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2DistanceInput.prototype.__constructor = function() { -}; -b2DistanceInput.prototype.__varz = function() { -}; -b2DistanceInput.prototype.proxyA = null; -b2DistanceInput.prototype.proxyB = null; -b2DistanceInput.prototype.transformA = null; -b2DistanceInput.prototype.transformB = null; -b2DistanceInput.prototype.useRadii = null;var b2Settings = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Settings.prototype.__constructor = function() { -}; -b2Settings.prototype.__varz = function() { -}; -b2Settings.b2MixFriction = function(friction1, friction2) { - return Math.sqrt(friction1 * friction2) -}; -b2Settings.b2MixRestitution = function(restitution1, restitution2) { - return restitution1 > restitution2 ? restitution1 : restitution2 -}; -b2Settings.b2Assert = function(a) { - if(!a) { - throw"Assertion Failed"; - } -}; -b2Settings.VERSION = "2.1alpha"; -b2Settings.USHRT_MAX = 65535; -b2Settings.b2_pi = Math.PI; -b2Settings.b2_maxManifoldPoints = 2; -b2Settings.b2_aabbExtension = 0.1; -b2Settings.b2_aabbMultiplier = 2; -b2Settings.b2_polygonRadius = 2 * b2Settings.b2_linearSlop; -b2Settings.b2_linearSlop = 0.0050; -b2Settings.b2_angularSlop = 2 / 180 * b2Settings.b2_pi; -b2Settings.b2_toiSlop = 8 * b2Settings.b2_linearSlop; -b2Settings.b2_maxTOIContactsPerIsland = 32; -b2Settings.b2_maxTOIJointsPerIsland = 32; -b2Settings.b2_velocityThreshold = 1; -b2Settings.b2_maxLinearCorrection = 0.2; -b2Settings.b2_maxAngularCorrection = 8 / 180 * b2Settings.b2_pi; -b2Settings.b2_maxTranslation = 2; -b2Settings.b2_maxTranslationSquared = b2Settings.b2_maxTranslation * b2Settings.b2_maxTranslation; -b2Settings.b2_maxRotation = 0.5 * b2Settings.b2_pi; -b2Settings.b2_maxRotationSquared = b2Settings.b2_maxRotation * b2Settings.b2_maxRotation; -b2Settings.b2_contactBaumgarte = 0.2; -b2Settings.b2_timeToSleep = 0.5; -b2Settings.b2_linearSleepTolerance = 0.01; -b2Settings.b2_angularSleepTolerance = 2 / 180 * b2Settings.b2_pi;var b2Proxy = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Proxy.prototype.__constructor = function() { -}; -b2Proxy.prototype.__varz = function() { - this.lowerBounds = new Array(2); - this.upperBounds = new Array(2); - this.pairs = new Object -}; -b2Proxy.prototype.IsValid = function() { - return this.overlapCount != b2BroadPhase.b2_invalid -}; -b2Proxy.prototype.lowerBounds = new Array(2); -b2Proxy.prototype.upperBounds = new Array(2); -b2Proxy.prototype.overlapCount = 0; -b2Proxy.prototype.timeStamp = 0; -b2Proxy.prototype.pairs = new Object; -b2Proxy.prototype.next = null; -b2Proxy.prototype.userData = null;var b2Point = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Point.prototype.__constructor = function() { -}; -b2Point.prototype.__varz = function() { - this.p = new b2Vec2 -}; -b2Point.prototype.Support = function(xf, vX, vY) { - return this.p -}; -b2Point.prototype.GetFirstVertex = function(xf) { - return this.p -}; -b2Point.prototype.p = new b2Vec2;var b2WorldManifold = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2WorldManifold.prototype.__constructor = function() { - this.m_points = new Array(b2Settings.b2_maxManifoldPoints); - for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { - this.m_points[i] = new b2Vec2 - } -}; -b2WorldManifold.prototype.__varz = function() { - this.m_normal = new b2Vec2 -}; -b2WorldManifold.prototype.Initialize = function(manifold, xfA, radiusA, xfB, radiusB) { - if(manifold.m_pointCount == 0) { - return - } - var i = 0; - var tVec; - var tMat; - var normalX; - var normalY; - var planePointX; - var planePointY; - var clipPointX; - var clipPointY; - switch(manifold.m_type) { - case b2Manifold.e_circles: - tMat = xfA.R; - tVec = manifold.m_localPoint; - var pointAX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - var pointAY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xfB.R; - tVec = manifold.m_points[0].m_localPoint; - var pointBX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - var pointBY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - var dX = pointBX - pointAX; - var dY = pointBY - pointAY; - var d2 = dX * dX + dY * dY; - if(d2 > Number.MIN_VALUE * Number.MIN_VALUE) { - var d = Math.sqrt(d2); - this.m_normal.x = dX / d; - this.m_normal.y = dY / d - }else { - this.m_normal.x = 1; - this.m_normal.y = 0 - } - var cAX = pointAX + radiusA * this.m_normal.x; - var cAY = pointAY + radiusA * this.m_normal.y; - var cBX = pointBX - radiusB * this.m_normal.x; - var cBY = pointBY - radiusB * this.m_normal.y; - this.m_points[0].x = 0.5 * (cAX + cBX); - this.m_points[0].y = 0.5 * (cAY + cBY); - break; - case b2Manifold.e_faceA: - tMat = xfA.R; - tVec = manifold.m_localPlaneNormal; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xfA.R; - tVec = manifold.m_localPoint; - planePointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - planePointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_normal.x = normalX; - this.m_normal.y = normalY; - for(i = 0;i < manifold.m_pointCount;i++) { - tMat = xfB.R; - tVec = manifold.m_points[i].m_localPoint; - clipPointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - clipPointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_points[i].x = clipPointX + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalX; - this.m_points[i].y = clipPointY + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalY - } - break; - case b2Manifold.e_faceB: - tMat = xfB.R; - tVec = manifold.m_localPlaneNormal; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xfB.R; - tVec = manifold.m_localPoint; - planePointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - planePointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_normal.x = -normalX; - this.m_normal.y = -normalY; - for(i = 0;i < manifold.m_pointCount;i++) { - tMat = xfA.R; - tVec = manifold.m_points[i].m_localPoint; - clipPointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - clipPointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_points[i].x = clipPointX + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalX; - this.m_points[i].y = clipPointY + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalY - } - break - } -}; -b2WorldManifold.prototype.m_normal = new b2Vec2; -b2WorldManifold.prototype.m_points = null;var b2RayCastOutput = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2RayCastOutput.prototype.__constructor = function() { -}; -b2RayCastOutput.prototype.__varz = function() { - this.normal = new b2Vec2 -}; -b2RayCastOutput.prototype.normal = new b2Vec2; -b2RayCastOutput.prototype.fraction = null;var b2ConstantForceController = function() { - b2Controller.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2ConstantForceController.prototype, b2Controller.prototype); -b2ConstantForceController.prototype._super = b2Controller.prototype; -b2ConstantForceController.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2ConstantForceController.prototype.__varz = function() { - this.F = new b2Vec2(0, 0) -}; -b2ConstantForceController.prototype.Step = function(step) { - for(var i = m_bodyList;i;i = i.nextBody) { - var body = i.body; - if(!body.IsAwake()) { - continue - } - body.ApplyForce(this.F, body.GetWorldCenter()) - } -}; -b2ConstantForceController.prototype.F = new b2Vec2(0, 0);var b2MassData = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2MassData.prototype.__constructor = function() { -}; -b2MassData.prototype.__varz = function() { - this.center = new b2Vec2(0, 0) -}; -b2MassData.prototype.mass = 0; -b2MassData.prototype.center = new b2Vec2(0, 0); -b2MassData.prototype.I = 0;var b2DynamicTree = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2DynamicTree.prototype.__constructor = function() { - this.m_root = null; - this.m_freeList = null; - this.m_path = 0; - this.m_insertionCount = 0 -}; -b2DynamicTree.prototype.__varz = function() { -}; -b2DynamicTree.prototype.AllocateNode = function() { - if(this.m_freeList) { - var node = this.m_freeList; - this.m_freeList = node.parent; - node.parent = null; - node.child1 = null; - node.child2 = null; - return node - } - return new b2DynamicTreeNode -}; -b2DynamicTree.prototype.FreeNode = function(node) { - node.parent = this.m_freeList; - this.m_freeList = node -}; -b2DynamicTree.prototype.InsertLeaf = function(leaf) { - ++this.m_insertionCount; - if(this.m_root == null) { - this.m_root = leaf; - this.m_root.parent = null; - return - } - var center = leaf.aabb.GetCenter(); - var sibling = this.m_root; - if(sibling.IsLeaf() == false) { - do { - var child1 = sibling.child1; - var child2 = sibling.child2; - var norm1 = Math.abs((child1.aabb.lowerBound.x + child1.aabb.upperBound.x) / 2 - center.x) + Math.abs((child1.aabb.lowerBound.y + child1.aabb.upperBound.y) / 2 - center.y); - var norm2 = Math.abs((child2.aabb.lowerBound.x + child2.aabb.upperBound.x) / 2 - center.x) + Math.abs((child2.aabb.lowerBound.y + child2.aabb.upperBound.y) / 2 - center.y); - if(norm1 < norm2) { - sibling = child1 - }else { - sibling = child2 - } - }while(sibling.IsLeaf() == false) - } - var node1 = sibling.parent; - var node2 = this.AllocateNode(); - node2.parent = node1; - node2.userData = null; - node2.aabb.Combine(leaf.aabb, sibling.aabb); - if(node1) { - if(sibling.parent.child1 == sibling) { - node1.child1 = node2 - }else { - node1.child2 = node2 - } - node2.child1 = sibling; - node2.child2 = leaf; - sibling.parent = node2; - leaf.parent = node2; - do { - if(node1.aabb.Contains(node2.aabb)) { - break - } - node1.aabb.Combine(node1.child1.aabb, node1.child2.aabb); - node2 = node1; - node1 = node1.parent - }while(node1) - }else { - node2.child1 = sibling; - node2.child2 = leaf; - sibling.parent = node2; - leaf.parent = node2; - this.m_root = node2 - } -}; -b2DynamicTree.prototype.RemoveLeaf = function(leaf) { - if(leaf == this.m_root) { - this.m_root = null; - return - } - var node2 = leaf.parent; - var node1 = node2.parent; - var sibling; - if(node2.child1 == leaf) { - sibling = node2.child2 - }else { - sibling = node2.child1 - } - if(node1) { - if(node1.child1 == node2) { - node1.child1 = sibling - }else { - node1.child2 = sibling - } - sibling.parent = node1; - this.FreeNode(node2); - while(node1) { - var oldAABB = node1.aabb; - node1.aabb = b2AABB.Combine(node1.child1.aabb, node1.child2.aabb); - if(oldAABB.Contains(node1.aabb)) { - break - } - node1 = node1.parent - } - }else { - this.m_root = sibling; - sibling.parent = null; - this.FreeNode(node2) - } -}; -b2DynamicTree.prototype.CreateProxy = function(aabb, userData) { - var node = this.AllocateNode(); - var extendX = b2Settings.b2_aabbExtension; - var extendY = b2Settings.b2_aabbExtension; - node.aabb.lowerBound.x = aabb.lowerBound.x - extendX; - node.aabb.lowerBound.y = aabb.lowerBound.y - extendY; - node.aabb.upperBound.x = aabb.upperBound.x + extendX; - node.aabb.upperBound.y = aabb.upperBound.y + extendY; - node.userData = userData; - this.InsertLeaf(node); - return node -}; -b2DynamicTree.prototype.DestroyProxy = function(proxy) { - this.RemoveLeaf(proxy); - this.FreeNode(proxy) -}; -b2DynamicTree.prototype.MoveProxy = function(proxy, aabb, displacement) { - b2Settings.b2Assert(proxy.IsLeaf()); - if(proxy.aabb.Contains(aabb)) { - return false - } - this.RemoveLeaf(proxy); - var extendX = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.x > 0 ? displacement.x : -displacement.x); - var extendY = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.y > 0 ? displacement.y : -displacement.y); - proxy.aabb.lowerBound.x = aabb.lowerBound.x - extendX; - proxy.aabb.lowerBound.y = aabb.lowerBound.y - extendY; - proxy.aabb.upperBound.x = aabb.upperBound.x + extendX; - proxy.aabb.upperBound.y = aabb.upperBound.y + extendY; - this.InsertLeaf(proxy); - return true -}; -b2DynamicTree.prototype.Rebalance = function(iterations) { - if(this.m_root == null) { - return - } - for(var i = 0;i < iterations;i++) { - var node = this.m_root; - var bit = 0; - while(node.IsLeaf() == false) { - node = this.m_path >> bit & 1 ? node.child2 : node.child1; - bit = bit + 1 & 31 - } - ++this.m_path; - this.RemoveLeaf(node); - this.InsertLeaf(node) - } -}; -b2DynamicTree.prototype.GetFatAABB = function(proxy) { - return proxy.aabb -}; -b2DynamicTree.prototype.GetUserData = function(proxy) { - return proxy.userData -}; -b2DynamicTree.prototype.Query = function(callback, aabb) { - if(this.m_root == null) { - return - } - var stack = new Array; - var count = 0; - stack[count++] = this.m_root; - while(count > 0) { - var node = stack[--count]; - if(node.aabb.TestOverlap(aabb)) { - if(node.IsLeaf()) { - var proceed = callback(node); - if(!proceed) { - return - } - }else { - stack[count++] = node.child1; - stack[count++] = node.child2 - } - } - } -}; -b2DynamicTree.prototype.RayCast = function(callback, input) { - if(this.m_root == null) { - return - } - var p1 = input.p1; - var p2 = input.p2; - var r = b2Math.SubtractVV(p1, p2); - r.Normalize(); - var v = b2Math.CrossFV(1, r); - var abs_v = b2Math.AbsV(v); - var maxFraction = input.maxFraction; - var segmentAABB = new b2AABB; - var tX; - var tY; - tX = p1.x + maxFraction * (p2.x - p1.x); - tY = p1.y + maxFraction * (p2.y - p1.y); - segmentAABB.lowerBound.x = Math.min(p1.x, tX); - segmentAABB.lowerBound.y = Math.min(p1.y, tY); - segmentAABB.upperBound.x = Math.max(p1.x, tX); - segmentAABB.upperBound.y = Math.max(p1.y, tY); - var stack = new Array; - var count = 0; - stack[count++] = this.m_root; - while(count > 0) { - var node = stack[--count]; - if(node.aabb.TestOverlap(segmentAABB) == false) { - continue - } - var c = node.aabb.GetCenter(); - var h = node.aabb.GetExtents(); - var separation = Math.abs(v.x * (p1.x - c.x) + v.y * (p1.y - c.y)) - abs_v.x * h.x - abs_v.y * h.y; - if(separation > 0) { - continue - } - if(node.IsLeaf()) { - var subInput = new b2RayCastInput; - subInput.p1 = input.p1; - subInput.p2 = input.p2; - subInput.maxFraction = input.maxFraction; - maxFraction = callback(subInput, node); - if(maxFraction == 0) { - return - } - tX = p1.x + maxFraction * (p2.x - p1.x); - tY = p1.y + maxFraction * (p2.y - p1.y); - segmentAABB.lowerBound.x = Math.min(p1.x, tX); - segmentAABB.lowerBound.y = Math.min(p1.y, tY); - segmentAABB.upperBound.x = Math.max(p1.x, tX); - segmentAABB.upperBound.y = Math.max(p1.y, tY) - }else { - stack[count++] = node.child1; - stack[count++] = node.child2 - } - } -}; -b2DynamicTree.prototype.m_root = null; -b2DynamicTree.prototype.m_freeList = null; -b2DynamicTree.prototype.m_path = 0; -b2DynamicTree.prototype.m_insertionCount = 0;var b2JointEdge = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2JointEdge.prototype.__constructor = function() { -}; -b2JointEdge.prototype.__varz = function() { -}; -b2JointEdge.prototype.other = null; -b2JointEdge.prototype.joint = null; -b2JointEdge.prototype.prev = null; -b2JointEdge.prototype.next = null;var b2RayCastInput = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2RayCastInput.prototype.__constructor = function() { -}; -b2RayCastInput.prototype.__varz = function() { - this.p1 = new b2Vec2; - this.p2 = new b2Vec2 -}; -b2RayCastInput.prototype.p1 = new b2Vec2; -b2RayCastInput.prototype.p2 = new b2Vec2; -b2RayCastInput.prototype.maxFraction = null;var Features = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -Features.prototype.__constructor = function() { -}; -Features.prototype.__varz = function() { -}; -Features.prototype.__defineGetter__("referenceEdge", function() { - return this._referenceEdge -}); -Features.prototype.__defineSetter__("referenceEdge", function(value) { - this._referenceEdge = value; - this._m_id._key = this._m_id._key & 4294967040 | this._referenceEdge & 255 -}); -Features.prototype.__defineGetter__("incidentEdge", function() { - return this._incidentEdge -}); -Features.prototype.__defineSetter__("incidentEdge", function(value) { - this._incidentEdge = value; - this._m_id._key = this._m_id._key & 4294902015 | this._incidentEdge << 8 & 65280 -}); -Features.prototype.__defineGetter__("incidentVertex", function() { - return this._incidentVertex -}); -Features.prototype.__defineSetter__("incidentVertex", function(value) { - this._incidentVertex = value; - this._m_id._key = this._m_id._key & 4278255615 | this._incidentVertex << 16 & 16711680 -}); -Features.prototype.__defineGetter__("flip", function() { - return this._flip -}); -Features.prototype.__defineSetter__("flip", function(value) { - this._flip = value; - this._m_id._key = this._m_id._key & 16777215 | this._flip << 24 & 4278190080 -}); -Features.prototype._referenceEdge = 0; -Features.prototype._incidentEdge = 0; -Features.prototype._incidentVertex = 0; -Features.prototype._flip = 0; -Features.prototype._m_id = null;var b2FilterData = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2FilterData.prototype.__constructor = function() { -}; -b2FilterData.prototype.__varz = function() { - this.categoryBits = 1; - this.maskBits = 65535 -}; -b2FilterData.prototype.Copy = function() { - var copy = new b2FilterData; - copy.categoryBits = this.categoryBits; - copy.maskBits = this.maskBits; - copy.groupIndex = this.groupIndex; - return copy -}; -b2FilterData.prototype.categoryBits = 1; -b2FilterData.prototype.maskBits = 65535; -b2FilterData.prototype.groupIndex = 0;var b2AABB = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2AABB.prototype.__constructor = function() { -}; -b2AABB.prototype.__varz = function() { - this.lowerBound = new b2Vec2; - this.upperBound = new b2Vec2 -}; -b2AABB.Combine = function(aabb1, aabb2) { - var aabb = new b2AABB; - aabb.Combine(aabb1, aabb2); - return aabb -}; -b2AABB.prototype.IsValid = function() { - var dX = this.upperBound.x - this.lowerBound.x; - var dY = this.upperBound.y - this.lowerBound.y; - var valid = dX >= 0 && dY >= 0; - valid = valid && this.lowerBound.IsValid() && this.upperBound.IsValid(); - return valid -}; -b2AABB.prototype.GetCenter = function() { - return new b2Vec2((this.lowerBound.x + this.upperBound.x) / 2, (this.lowerBound.y + this.upperBound.y) / 2) -}; -b2AABB.prototype.GetExtents = function() { - return new b2Vec2((this.upperBound.x - this.lowerBound.x) / 2, (this.upperBound.y - this.lowerBound.y) / 2) -}; -b2AABB.prototype.Contains = function(aabb) { - var result = true && this.lowerBound.x <= aabb.lowerBound.x && this.lowerBound.y <= aabb.lowerBound.y && aabb.upperBound.x <= this.upperBound.x && aabb.upperBound.y <= this.upperBound.y; - return result -}; -b2AABB.prototype.RayCast = function(output, input) { - var tmin = -Number.MAX_VALUE; - var tmax = Number.MAX_VALUE; - var pX = input.p1.x; - var pY = input.p1.y; - var dX = input.p2.x - input.p1.x; - var dY = input.p2.y - input.p1.y; - var absDX = Math.abs(dX); - var absDY = Math.abs(dY); - var normal = output.normal; - var inv_d; - var t1; - var t2; - var t3; - var s; - if(absDX < Number.MIN_VALUE) { - if(pX < this.lowerBound.x || this.upperBound.x < pX) { - return false - } - }else { - inv_d = 1 / dX; - t1 = (this.lowerBound.x - pX) * inv_d; - t2 = (this.upperBound.x - pX) * inv_d; - s = -1; - if(t1 > t2) { - t3 = t1; - t1 = t2; - t2 = t3; - s = 1 - } - if(t1 > tmin) { - normal.x = s; - normal.y = 0; - tmin = t1 - } - tmax = Math.min(tmax, t2); - if(tmin > tmax) { - return false - } - } - if(absDY < Number.MIN_VALUE) { - if(pY < this.lowerBound.y || this.upperBound.y < pY) { - return false - } - }else { - inv_d = 1 / dY; - t1 = (this.lowerBound.y - pY) * inv_d; - t2 = (this.upperBound.y - pY) * inv_d; - s = -1; - if(t1 > t2) { - t3 = t1; - t1 = t2; - t2 = t3; - s = 1 - } - if(t1 > tmin) { - normal.y = s; - normal.x = 0; - tmin = t1 - } - tmax = Math.min(tmax, t2); - if(tmin > tmax) { - return false - } - } - output.fraction = tmin; - return true -}; -b2AABB.prototype.TestOverlap = function(other) { - var d1X = other.lowerBound.x - this.upperBound.x; - var d1Y = other.lowerBound.y - this.upperBound.y; - var d2X = this.lowerBound.x - other.upperBound.x; - var d2Y = this.lowerBound.y - other.upperBound.y; - if(d1X > 0 || d1Y > 0) { - return false - } - if(d2X > 0 || d2Y > 0) { - return false - } - return true -}; -b2AABB.prototype.Combine = function(aabb1, aabb2) { - this.lowerBound.x = Math.min(aabb1.lowerBound.x, aabb2.lowerBound.x); - this.lowerBound.y = Math.min(aabb1.lowerBound.y, aabb2.lowerBound.y); - this.upperBound.x = Math.max(aabb1.upperBound.x, aabb2.upperBound.x); - this.upperBound.y = Math.max(aabb1.upperBound.y, aabb2.upperBound.y) -}; -b2AABB.prototype.lowerBound = new b2Vec2; -b2AABB.prototype.upperBound = new b2Vec2;var b2Jacobian = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Jacobian.prototype.__constructor = function() { -}; -b2Jacobian.prototype.__varz = function() { - this.linearA = new b2Vec2; - this.linearB = new b2Vec2 -}; -b2Jacobian.prototype.SetZero = function() { - this.linearA.SetZero(); - this.angularA = 0; - this.linearB.SetZero(); - this.angularB = 0 -}; -b2Jacobian.prototype.Set = function(x1, a1, x2, a2) { - this.linearA.SetV(x1); - this.angularA = a1; - this.linearB.SetV(x2); - this.angularB = a2 -}; -b2Jacobian.prototype.Compute = function(x1, a1, x2, a2) { - return this.linearA.x * x1.x + this.linearA.y * x1.y + this.angularA * a1 + (this.linearB.x * x2.x + this.linearB.y * x2.y) + this.angularB * a2 -}; -b2Jacobian.prototype.linearA = new b2Vec2; -b2Jacobian.prototype.angularA = null; -b2Jacobian.prototype.linearB = new b2Vec2; -b2Jacobian.prototype.angularB = null;var b2Bound = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Bound.prototype.__constructor = function() { -}; -b2Bound.prototype.__varz = function() { -}; -b2Bound.prototype.IsLower = function() { - return(this.value & 1) == 0 -}; -b2Bound.prototype.IsUpper = function() { - return(this.value & 1) == 1 -}; -b2Bound.prototype.Swap = function(b) { - var tempValue = this.value; - var tempProxy = this.proxy; - var tempStabbingCount = this.stabbingCount; - this.value = b.value; - this.proxy = b.proxy; - this.stabbingCount = b.stabbingCount; - b.value = tempValue; - b.proxy = tempProxy; - b.stabbingCount = tempStabbingCount -}; -b2Bound.prototype.value = 0; -b2Bound.prototype.proxy = null; -b2Bound.prototype.stabbingCount = 0;var b2SimplexVertex = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2SimplexVertex.prototype.__constructor = function() { -}; -b2SimplexVertex.prototype.__varz = function() { -}; -b2SimplexVertex.prototype.Set = function(other) { - this.wA.SetV(other.wA); - this.wB.SetV(other.wB); - this.w.SetV(other.w); - this.a = other.a; - this.indexA = other.indexA; - this.indexB = other.indexB -}; -b2SimplexVertex.prototype.wA = null; -b2SimplexVertex.prototype.wB = null; -b2SimplexVertex.prototype.w = null; -b2SimplexVertex.prototype.a = null; -b2SimplexVertex.prototype.indexA = 0; -b2SimplexVertex.prototype.indexB = 0;var b2Mat22 = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Mat22.prototype.__constructor = function() { - this.col1.x = this.col2.y = 1 -}; -b2Mat22.prototype.__varz = function() { - this.col1 = new b2Vec2; - this.col2 = new b2Vec2 -}; -b2Mat22.FromAngle = function(angle) { - var mat = new b2Mat22; - mat.Set(angle); - return mat -}; -b2Mat22.FromVV = function(c1, c2) { - var mat = new b2Mat22; - mat.SetVV(c1, c2); - return mat -}; -b2Mat22.prototype.Set = function(angle) { - var c = Math.cos(angle); - var s = Math.sin(angle); - this.col1.x = c; - this.col2.x = -s; - this.col1.y = s; - this.col2.y = c -}; -b2Mat22.prototype.SetVV = function(c1, c2) { - this.col1.SetV(c1); - this.col2.SetV(c2) -}; -b2Mat22.prototype.Copy = function() { - var mat = new b2Mat22; - mat.SetM(this); - return mat -}; -b2Mat22.prototype.SetM = function(m) { - this.col1.SetV(m.col1); - this.col2.SetV(m.col2) -}; -b2Mat22.prototype.AddM = function(m) { - this.col1.x += m.col1.x; - this.col1.y += m.col1.y; - this.col2.x += m.col2.x; - this.col2.y += m.col2.y -}; -b2Mat22.prototype.SetIdentity = function() { - this.col1.x = 1; - this.col2.x = 0; - this.col1.y = 0; - this.col2.y = 1 -}; -b2Mat22.prototype.SetZero = function() { - this.col1.x = 0; - this.col2.x = 0; - this.col1.y = 0; - this.col2.y = 0 -}; -b2Mat22.prototype.GetAngle = function() { - return Math.atan2(this.col1.y, this.col1.x) -}; -b2Mat22.prototype.GetInverse = function(out) { - var a = this.col1.x; - var b = this.col2.x; - var c = this.col1.y; - var d = this.col2.y; - var det = a * d - b * c; - if(det != 0) { - det = 1 / det - } - out.col1.x = det * d; - out.col2.x = -det * b; - out.col1.y = -det * c; - out.col2.y = det * a; - return out -}; -b2Mat22.prototype.Solve = function(out, bX, bY) { - var a11 = this.col1.x; - var a12 = this.col2.x; - var a21 = this.col1.y; - var a22 = this.col2.y; - var det = a11 * a22 - a12 * a21; - if(det != 0) { - det = 1 / det - } - out.x = det * (a22 * bX - a12 * bY); - out.y = det * (a11 * bY - a21 * bX); - return out -}; -b2Mat22.prototype.Abs = function() { - this.col1.Abs(); - this.col2.Abs() -}; -b2Mat22.prototype.col1 = new b2Vec2; -b2Mat22.prototype.col2 = new b2Vec2;var b2SimplexCache = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2SimplexCache.prototype.__constructor = function() { -}; -b2SimplexCache.prototype.__varz = function() { - this.indexA = new Array(3); - this.indexB = new Array(3) -}; -b2SimplexCache.prototype.metric = null; -b2SimplexCache.prototype.count = 0; -b2SimplexCache.prototype.indexA = new Array(3); -b2SimplexCache.prototype.indexB = new Array(3);var b2Shape = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Shape.prototype.__constructor = function() { - this.m_type = b2Shape.e_unknownShape; - this.m_radius = b2Settings.b2_linearSlop -}; -b2Shape.prototype.__varz = function() { -}; -b2Shape.TestOverlap = function(shape1, transform1, shape2, transform2) { - var input = new b2DistanceInput; - input.proxyA = new b2DistanceProxy; - input.proxyA.Set(shape1); - input.proxyB = new b2DistanceProxy; - input.proxyB.Set(shape2); - input.transformA = transform1; - input.transformB = transform2; - input.useRadii = true; - var simplexCache = new b2SimplexCache; - simplexCache.count = 0; - var output = new b2DistanceOutput; - b2Distance.Distance(output, simplexCache, input); - return output.distance < 10 * Number.MIN_VALUE -}; -b2Shape.e_hitCollide = 1; -b2Shape.e_missCollide = 0; -b2Shape.e_startsInsideCollide = -1; -b2Shape.e_unknownShape = -1; -b2Shape.e_circleShape = 0; -b2Shape.e_polygonShape = 1; -b2Shape.e_edgeShape = 2; -b2Shape.e_shapeTypeCount = 3; -b2Shape.prototype.Copy = function() { - return null -}; -b2Shape.prototype.Set = function(other) { - this.m_radius = other.m_radius -}; -b2Shape.prototype.GetType = function() { - return this.m_type -}; -b2Shape.prototype.TestPoint = function(xf, p) { - return false -}; -b2Shape.prototype.RayCast = function(output, input, transform) { - return false -}; -b2Shape.prototype.ComputeAABB = function(aabb, xf) { -}; -b2Shape.prototype.ComputeMass = function(massData, density) { -}; -b2Shape.prototype.ComputeSubmergedArea = function(normal, offset, xf, c) { - return 0 -}; -b2Shape.prototype.m_type = 0; -b2Shape.prototype.m_radius = null;var b2Segment = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Segment.prototype.__constructor = function() { -}; -b2Segment.prototype.__varz = function() { - this.p1 = new b2Vec2; - this.p2 = new b2Vec2 -}; -b2Segment.prototype.TestSegment = function(lambda, normal, segment, maxLambda) { - var s = segment.p1; - var rX = segment.p2.x - s.x; - var rY = segment.p2.y - s.y; - var dX = this.p2.x - this.p1.x; - var dY = this.p2.y - this.p1.y; - var nX = dY; - var nY = -dX; - var k_slop = 100 * Number.MIN_VALUE; - var denom = -(rX * nX + rY * nY); - if(denom > k_slop) { - var bX = s.x - this.p1.x; - var bY = s.y - this.p1.y; - var a = bX * nX + bY * nY; - if(0 <= a && a <= maxLambda * denom) { - var mu2 = -rX * bY + rY * bX; - if(-k_slop * denom <= mu2 && mu2 <= denom * (1 + k_slop)) { - a /= denom; - var nLen = Math.sqrt(nX * nX + nY * nY); - nX /= nLen; - nY /= nLen; - lambda[0] = a; - normal.Set(nX, nY); - return true - } - } - } - return false -}; -b2Segment.prototype.Extend = function(aabb) { - this.ExtendForward(aabb); - this.ExtendBackward(aabb) -}; -b2Segment.prototype.ExtendForward = function(aabb) { - var dX = this.p2.x - this.p1.x; - var dY = this.p2.y - this.p1.y; - var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p1.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p1.x) / dX : Number.POSITIVE_INFINITY, dY > 0 ? (aabb.upperBound.y - this.p1.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p1.y) / dY : Number.POSITIVE_INFINITY); - this.p2.x = this.p1.x + dX * lambda; - this.p2.y = this.p1.y + dY * lambda -}; -b2Segment.prototype.ExtendBackward = function(aabb) { - var dX = -this.p2.x + this.p1.x; - var dY = -this.p2.y + this.p1.y; - var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p2.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p2.x) / dX : Number.POSITIVE_INFINITY, dY > 0 ? (aabb.upperBound.y - this.p2.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p2.y) / dY : Number.POSITIVE_INFINITY); - this.p1.x = this.p2.x + dX * lambda; - this.p1.y = this.p2.y + dY * lambda -}; -b2Segment.prototype.p1 = new b2Vec2; -b2Segment.prototype.p2 = new b2Vec2;var b2ContactRegister = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactRegister.prototype.__constructor = function() { -}; -b2ContactRegister.prototype.__varz = function() { -}; -b2ContactRegister.prototype.createFcn = null; -b2ContactRegister.prototype.destroyFcn = null; -b2ContactRegister.prototype.primary = null; -b2ContactRegister.prototype.pool = null; -b2ContactRegister.prototype.poolCount = 0;var b2DebugDraw = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2DebugDraw.prototype.__constructor = function() { - this.m_drawFlags = 0 -}; -b2DebugDraw.prototype.__varz = function() { -}; -b2DebugDraw.e_shapeBit = 1; -b2DebugDraw.e_jointBit = 2; -b2DebugDraw.e_aabbBit = 4; -b2DebugDraw.e_pairBit = 8; -b2DebugDraw.e_centerOfMassBit = 16; -b2DebugDraw.e_controllerBit = 32; -b2DebugDraw.prototype.SetFlags = function(flags) { - this.m_drawFlags = flags -}; -b2DebugDraw.prototype.GetFlags = function() { - return this.m_drawFlags -}; -b2DebugDraw.prototype.AppendFlags = function(flags) { - this.m_drawFlags |= flags -}; -b2DebugDraw.prototype.ClearFlags = function(flags) { - this.m_drawFlags &= ~flags -}; -b2DebugDraw.prototype.SetSprite = function(sprite) { - this.m_sprite = sprite -}; -b2DebugDraw.prototype.GetSprite = function() { - return this.m_sprite -}; -b2DebugDraw.prototype.SetDrawScale = function(drawScale) { - this.m_drawScale = drawScale -}; -b2DebugDraw.prototype.GetDrawScale = function() { - return this.m_drawScale -}; -b2DebugDraw.prototype.SetLineThickness = function(lineThickness) { - this.m_lineThickness = lineThickness -}; -b2DebugDraw.prototype.GetLineThickness = function() { - return this.m_lineThickness -}; -b2DebugDraw.prototype.SetAlpha = function(alpha) { - this.m_alpha = alpha -}; -b2DebugDraw.prototype.GetAlpha = function() { - return this.m_alpha -}; -b2DebugDraw.prototype.SetFillAlpha = function(alpha) { - this.m_fillAlpha = alpha -}; -b2DebugDraw.prototype.GetFillAlpha = function() { - return this.m_fillAlpha -}; -b2DebugDraw.prototype.SetXFormScale = function(xformScale) { - this.m_xformScale = xformScale -}; -b2DebugDraw.prototype.GetXFormScale = function() { - return this.m_xformScale -}; -b2DebugDraw.prototype.Clear = function() { - this.m_sprite.clearRect(0, 0, this.m_sprite.canvas.width, this.m_sprite.canvas.height) -}; -b2DebugDraw.prototype.Y = function(y) { - return this.m_sprite.canvas.height - y -}; -b2DebugDraw.prototype.ToWorldPoint = function(localPoint) { - return new b2Vec2(localPoint.x / this.m_drawScale, this.Y(localPoint.y) / this.m_drawScale) -}; -b2DebugDraw.prototype.ColorStyle = function(color, alpha) { - return"rgba(" + color.r + ", " + color.g + ", " + color.b + ", " + alpha + ")" -}; -b2DebugDraw.prototype.DrawPolygon = function(vertices, vertexCount, color) { - this.m_sprite.graphics.lineStyle(this.m_lineThickness, color.color, this.m_alpha); - this.m_sprite.graphics.moveTo(vertices[0].x * this.m_drawScale, vertices[0].y * this.m_drawScale); - for(var i = 1;i < vertexCount;i++) { - this.m_sprite.graphics.lineTo(vertices[i].x * this.m_drawScale, vertices[i].y * this.m_drawScale) - } - this.m_sprite.graphics.lineTo(vertices[0].x * this.m_drawScale, vertices[0].y * this.m_drawScale) -}; -b2DebugDraw.prototype.DrawSolidPolygon = function(vertices, vertexCount, color) { - this.m_sprite.strokeSyle = this.ColorStyle(color, this.m_alpha); - this.m_sprite.lineWidth = this.m_lineThickness; - this.m_sprite.fillStyle = this.ColorStyle(color, this.m_fillAlpha); - this.m_sprite.beginPath(); - this.m_sprite.moveTo(vertices[0].x * this.m_drawScale, this.Y(vertices[0].y * this.m_drawScale)); - for(var i = 1;i < vertexCount;i++) { - this.m_sprite.lineTo(vertices[i].x * this.m_drawScale, this.Y(vertices[i].y * this.m_drawScale)) - } - this.m_sprite.lineTo(vertices[0].x * this.m_drawScale, this.Y(vertices[0].y * this.m_drawScale)); - this.m_sprite.fill(); - this.m_sprite.stroke(); - this.m_sprite.closePath() -}; -b2DebugDraw.prototype.DrawCircle = function(center, radius, color) { - this.m_sprite.graphics.lineStyle(this.m_lineThickness, color.color, this.m_alpha); - this.m_sprite.graphics.drawCircle(center.x * this.m_drawScale, center.y * this.m_drawScale, radius * this.m_drawScale) -}; -b2DebugDraw.prototype.DrawSolidCircle = function(center, radius, axis, color) { - this.m_sprite.strokeSyle = this.ColorStyle(color, this.m_alpha); - this.m_sprite.lineWidth = this.m_lineThickness; - this.m_sprite.fillStyle = this.ColorStyle(color, this.m_fillAlpha); - this.m_sprite.beginPath(); - this.m_sprite.arc(center.x * this.m_drawScale, this.Y(center.y * this.m_drawScale), radius * this.m_drawScale, 0, Math.PI * 2, true); - this.m_sprite.fill(); - this.m_sprite.stroke(); - this.m_sprite.closePath() -}; -b2DebugDraw.prototype.DrawSegment = function(p1, p2, color) { - this.m_sprite.lineWidth = this.m_lineThickness; - this.m_sprite.strokeSyle = this.ColorStyle(color, this.m_alpha); - this.m_sprite.beginPath(); - this.m_sprite.moveTo(p1.x * this.m_drawScale, this.Y(p1.y * this.m_drawScale)); - this.m_sprite.lineTo(p2.x * this.m_drawScale, this.Y(p2.y * this.m_drawScale)); - this.m_sprite.stroke(); - this.m_sprite.closePath() -}; -b2DebugDraw.prototype.DrawTransform = function(xf) { - this.m_sprite.lineWidth = this.m_lineThickness; - this.m_sprite.strokeSyle = this.ColorStyle(new b2Color(255, 0, 0), this.m_alpha); - this.m_sprite.beginPath(); - this.m_sprite.moveTo(xf.position.x * this.m_drawScale, this.Y(xf.position.y * this.m_drawScale)); - this.m_sprite.lineTo((xf.position.x + this.m_xformScale * xf.R.col1.x) * this.m_drawScale, this.Y((xf.position.y + this.m_xformScale * xf.R.col1.y) * this.m_drawScale)); - this.m_sprite.stroke(); - this.m_sprite.closePath(); - this.m_sprite.strokeSyle = this.ColorStyle(new b2Color(0, 255, 0), this.m_alpha); - this.m_sprite.beginPath(); - this.m_sprite.moveTo(xf.position.x * this.m_drawScale, this.Y(xf.position.y * this.m_drawScale)); - this.m_sprite.lineTo((xf.position.x + this.m_xformScale * xf.R.col2.x) * this.m_drawScale, this.Y((xf.position.y + this.m_xformScale * xf.R.col2.y) * this.m_drawScale)); - this.m_sprite.stroke(); - this.m_sprite.closePath() -}; -b2DebugDraw.prototype.m_drawFlags = 0; -b2DebugDraw.prototype.m_sprite = null; -b2DebugDraw.prototype.m_drawScale = 1; -b2DebugDraw.prototype.m_lineThickness = 1; -b2DebugDraw.prototype.m_alpha = 1; -b2DebugDraw.prototype.m_fillAlpha = 1; -b2DebugDraw.prototype.m_xformScale = 1;var b2Sweep = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Sweep.prototype.__constructor = function() { -}; -b2Sweep.prototype.__varz = function() { - this.localCenter = new b2Vec2; - this.c0 = new b2Vec2; - this.c = new b2Vec2 -}; -b2Sweep.prototype.Set = function(other) { - this.localCenter.SetV(other.localCenter); - this.c0.SetV(other.c0); - this.c.SetV(other.c); - this.a0 = other.a0; - this.a = other.a; - this.t0 = other.t0 -}; -b2Sweep.prototype.Copy = function() { - var copy = new b2Sweep; - copy.localCenter.SetV(this.localCenter); - copy.c0.SetV(this.c0); - copy.c.SetV(this.c); - copy.a0 = this.a0; - copy.a = this.a; - copy.t0 = this.t0; - return copy -}; -b2Sweep.prototype.GetTransform = function(xf, alpha) { - xf.position.x = (1 - alpha) * this.c0.x + alpha * this.c.x; - xf.position.y = (1 - alpha) * this.c0.y + alpha * this.c.y; - var angle = (1 - alpha) * this.a0 + alpha * this.a; - xf.R.Set(angle); - var tMat = xf.R; - xf.position.x -= tMat.col1.x * this.localCenter.x + tMat.col2.x * this.localCenter.y; - xf.position.y -= tMat.col1.y * this.localCenter.x + tMat.col2.y * this.localCenter.y -}; -b2Sweep.prototype.Advance = function(t) { - if(this.t0 < t && 1 - this.t0 > Number.MIN_VALUE) { - var alpha = (t - this.t0) / (1 - this.t0); - this.c0.x = (1 - alpha) * this.c0.x + alpha * this.c.x; - this.c0.y = (1 - alpha) * this.c0.y + alpha * this.c.y; - this.a0 = (1 - alpha) * this.a0 + alpha * this.a; - this.t0 = t - } -}; -b2Sweep.prototype.localCenter = new b2Vec2; -b2Sweep.prototype.c0 = new b2Vec2; -b2Sweep.prototype.c = new b2Vec2; -b2Sweep.prototype.a0 = null; -b2Sweep.prototype.a = null; -b2Sweep.prototype.t0 = null;var b2DistanceOutput = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2DistanceOutput.prototype.__constructor = function() { -}; -b2DistanceOutput.prototype.__varz = function() { - this.pointA = new b2Vec2; - this.pointB = new b2Vec2 -}; -b2DistanceOutput.prototype.pointA = new b2Vec2; -b2DistanceOutput.prototype.pointB = new b2Vec2; -b2DistanceOutput.prototype.distance = null; -b2DistanceOutput.prototype.iterations = 0;var b2Mat33 = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Mat33.prototype.__constructor = function(c1, c2, c3) { - if(!c1 && !c2 && !c3) { - this.col1.SetZero(); - this.col2.SetZero(); - this.col3.SetZero() - }else { - this.col1.SetV(c1); - this.col2.SetV(c2); - this.col3.SetV(c3) - } -}; -b2Mat33.prototype.__varz = function() { - this.col1 = new b2Vec3; - this.col2 = new b2Vec3; - this.col3 = new b2Vec3 -}; -b2Mat33.prototype.SetVVV = function(c1, c2, c3) { - this.col1.SetV(c1); - this.col2.SetV(c2); - this.col3.SetV(c3) -}; -b2Mat33.prototype.Copy = function() { - return new b2Mat33(this.col1, this.col2, this.col3) -}; -b2Mat33.prototype.SetM = function(m) { - this.col1.SetV(m.col1); - this.col2.SetV(m.col2); - this.col3.SetV(m.col3) -}; -b2Mat33.prototype.AddM = function(m) { - this.col1.x += m.col1.x; - this.col1.y += m.col1.y; - this.col1.z += m.col1.z; - this.col2.x += m.col2.x; - this.col2.y += m.col2.y; - this.col2.z += m.col2.z; - this.col3.x += m.col3.x; - this.col3.y += m.col3.y; - this.col3.z += m.col3.z -}; -b2Mat33.prototype.SetIdentity = function() { - this.col1.x = 1; - this.col2.x = 0; - this.col3.x = 0; - this.col1.y = 0; - this.col2.y = 1; - this.col3.y = 0; - this.col1.z = 0; - this.col2.z = 0; - this.col3.z = 1 -}; -b2Mat33.prototype.SetZero = function() { - this.col1.x = 0; - this.col2.x = 0; - this.col3.x = 0; - this.col1.y = 0; - this.col2.y = 0; - this.col3.y = 0; - this.col1.z = 0; - this.col2.z = 0; - this.col3.z = 0 -}; -b2Mat33.prototype.Solve22 = function(out, bX, bY) { - var a11 = this.col1.x; - var a12 = this.col2.x; - var a21 = this.col1.y; - var a22 = this.col2.y; - var det = a11 * a22 - a12 * a21; - if(det != 0) { - det = 1 / det - } - out.x = det * (a22 * bX - a12 * bY); - out.y = det * (a11 * bY - a21 * bX); - return out -}; -b2Mat33.prototype.Solve33 = function(out, bX, bY, bZ) { - var a11 = this.col1.x; - var a21 = this.col1.y; - var a31 = this.col1.z; - var a12 = this.col2.x; - var a22 = this.col2.y; - var a32 = this.col2.z; - var a13 = this.col3.x; - var a23 = this.col3.y; - var a33 = this.col3.z; - var det = a11 * (a22 * a33 - a32 * a23) + a21 * (a32 * a13 - a12 * a33) + a31 * (a12 * a23 - a22 * a13); - if(det != 0) { - det = 1 / det - } - out.x = det * (bX * (a22 * a33 - a32 * a23) + bY * (a32 * a13 - a12 * a33) + bZ * (a12 * a23 - a22 * a13)); - out.y = det * (a11 * (bY * a33 - bZ * a23) + a21 * (bZ * a13 - bX * a33) + a31 * (bX * a23 - bY * a13)); - out.z = det * (a11 * (a22 * bZ - a32 * bY) + a21 * (a32 * bX - a12 * bZ) + a31 * (a12 * bY - a22 * bX)); - return out -}; -b2Mat33.prototype.col1 = new b2Vec3; -b2Mat33.prototype.col2 = new b2Vec3; -b2Mat33.prototype.col3 = new b2Vec3;var b2PositionSolverManifold = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2PositionSolverManifold.prototype.__constructor = function() { - this.m_normal = new b2Vec2; - this.m_separations = new Array(b2Settings.b2_maxManifoldPoints); - this.m_points = new Array(b2Settings.b2_maxManifoldPoints); - for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { - this.m_points[i] = new b2Vec2 - } -}; -b2PositionSolverManifold.prototype.__varz = function() { -}; -b2PositionSolverManifold.circlePointA = new b2Vec2; -b2PositionSolverManifold.circlePointB = new b2Vec2; -b2PositionSolverManifold.prototype.Initialize = function(cc) { - b2Settings.b2Assert(cc.pointCount > 0); - var i = 0; - var clipPointX; - var clipPointY; - var tMat; - var tVec; - var planePointX; - var planePointY; - switch(cc.type) { - case b2Manifold.e_circles: - tMat = cc.bodyA.m_xf.R; - tVec = cc.localPoint; - var pointAX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var pointAY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = cc.bodyB.m_xf.R; - tVec = cc.points[0].localPoint; - var pointBX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var pointBY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var dX = pointBX - pointAX; - var dY = pointBY - pointAY; - var d2 = dX * dX + dY * dY; - if(d2 > Number.MIN_VALUE * Number.MIN_VALUE) { - var d = Math.sqrt(d2); - this.m_normal.x = dX / d; - this.m_normal.y = dY / d - }else { - this.m_normal.x = 1; - this.m_normal.y = 0 - } - this.m_points[0].x = 0.5 * (pointAX + pointBX); - this.m_points[0].y = 0.5 * (pointAY + pointBY); - this.m_separations[0] = dX * this.m_normal.x + dY * this.m_normal.y - cc.radius; - break; - case b2Manifold.e_faceA: - tMat = cc.bodyA.m_xf.R; - tVec = cc.localPlaneNormal; - this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = cc.bodyA.m_xf.R; - tVec = cc.localPoint; - planePointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - planePointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = cc.bodyB.m_xf.R; - for(i = 0;i < cc.pointCount;++i) { - tVec = cc.points[i].localPoint; - clipPointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - clipPointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; - this.m_points[i].x = clipPointX; - this.m_points[i].y = clipPointY - } - break; - case b2Manifold.e_faceB: - tMat = cc.bodyB.m_xf.R; - tVec = cc.localPlaneNormal; - this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = cc.bodyB.m_xf.R; - tVec = cc.localPoint; - planePointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - planePointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = cc.bodyA.m_xf.R; - for(i = 0;i < cc.pointCount;++i) { - tVec = cc.points[i].localPoint; - clipPointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - clipPointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; - this.m_points[i].Set(clipPointX, clipPointY) - } - this.m_normal.x *= -1; - this.m_normal.y *= -1; - break - } -}; -b2PositionSolverManifold.prototype.m_normal = null; -b2PositionSolverManifold.prototype.m_points = null; -b2PositionSolverManifold.prototype.m_separations = null;var b2OBB = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2OBB.prototype.__constructor = function() { -}; -b2OBB.prototype.__varz = function() { - this.R = new b2Mat22; - this.center = new b2Vec2; - this.extents = new b2Vec2 -}; -b2OBB.prototype.R = new b2Mat22; -b2OBB.prototype.center = new b2Vec2; -b2OBB.prototype.extents = new b2Vec2;var b2Pair = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Pair.prototype.__constructor = function() { -}; -b2Pair.prototype.__varz = function() { -}; -b2Pair.b2_nullProxy = b2Settings.USHRT_MAX; -b2Pair.e_pairBuffered = 1; -b2Pair.e_pairRemoved = 2; -b2Pair.e_pairFinal = 4; -b2Pair.prototype.SetBuffered = function() { - this.status |= b2Pair.e_pairBuffered -}; -b2Pair.prototype.ClearBuffered = function() { - this.status &= ~b2Pair.e_pairBuffered -}; -b2Pair.prototype.IsBuffered = function() { - return(this.status & b2Pair.e_pairBuffered) == b2Pair.e_pairBuffered -}; -b2Pair.prototype.SetRemoved = function() { - this.status |= b2Pair.e_pairRemoved -}; -b2Pair.prototype.ClearRemoved = function() { - this.status &= ~b2Pair.e_pairRemoved -}; -b2Pair.prototype.IsRemoved = function() { - return(this.status & b2Pair.e_pairRemoved) == b2Pair.e_pairRemoved -}; -b2Pair.prototype.SetFinal = function() { - this.status |= b2Pair.e_pairFinal -}; -b2Pair.prototype.IsFinal = function() { - return(this.status & b2Pair.e_pairFinal) == b2Pair.e_pairFinal -}; -b2Pair.prototype.userData = null; -b2Pair.prototype.proxy1 = null; -b2Pair.prototype.proxy2 = null; -b2Pair.prototype.next = null; -b2Pair.prototype.status = 0;var b2FixtureDef = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2FixtureDef.prototype.__constructor = function() { - this.shape = null; - this.userData = null; - this.friction = 0.2; - this.restitution = 0; - this.density = 0; - this.filter.categoryBits = 1; - this.filter.maskBits = 65535; - this.filter.groupIndex = 0; - this.isSensor = false -}; -b2FixtureDef.prototype.__varz = function() { - this.filter = new b2FilterData -}; -b2FixtureDef.prototype.shape = null; -b2FixtureDef.prototype.userData = null; -b2FixtureDef.prototype.friction = null; -b2FixtureDef.prototype.restitution = null; -b2FixtureDef.prototype.density = null; -b2FixtureDef.prototype.isSensor = null; -b2FixtureDef.prototype.filter = new b2FilterData;var b2ContactID = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactID.prototype.__constructor = function() { - this.features._m_id = this -}; -b2ContactID.prototype.__varz = function() { - this.features = new Features -}; -b2ContactID.prototype.Set = function(id) { - key = id._key -}; -b2ContactID.prototype.Copy = function() { - var id = new b2ContactID; - id.key = key; - return id -}; -b2ContactID.prototype.__defineSetter__("key", function() { - return this._key -}); -b2ContactID.prototype.__defineSetter__("key", function(value) { - this._key = value; - this.features._referenceEdge = this._key & 255; - this.features._incidentEdge = (this._key & 65280) >> 8 & 255; - this.features._incidentVertex = (this._key & 16711680) >> 16 & 255; - this.features._flip = (this._key & 4278190080) >> 24 & 255 -}); -b2ContactID.prototype._key = 0; -b2ContactID.prototype.features = new Features;var b2Transform = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Transform.prototype.__constructor = function(pos, r) { - if(pos) { - this.position.SetV(pos); - this.R.SetM(r) - } -}; -b2Transform.prototype.__varz = function() { - this.position = new b2Vec2; - this.R = new b2Mat22 -}; -b2Transform.prototype.Initialize = function(pos, r) { - this.position.SetV(pos); - this.R.SetM(r) -}; -b2Transform.prototype.SetIdentity = function() { - this.position.SetZero(); - this.R.SetIdentity() -}; -b2Transform.prototype.Set = function(x) { - this.position.SetV(x.position); - this.R.SetM(x.R) -}; -b2Transform.prototype.GetAngle = function() { - return Math.atan2(this.R.col1.y, this.R.col1.x) -}; -b2Transform.prototype.position = new b2Vec2; -b2Transform.prototype.R = new b2Mat22;var b2EdgeShape = function() { - b2Shape.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2EdgeShape.prototype, b2Shape.prototype); -b2EdgeShape.prototype._super = b2Shape.prototype; -b2EdgeShape.prototype.__constructor = function(v1, v2) { - this._super.__constructor.apply(this, []); - this.m_type = b2Shape.e_edgeShape; - this.m_prevEdge = null; - this.m_nextEdge = null; - this.m_v1 = v1; - this.m_v2 = v2; - this.m_direction.Set(this.m_v2.x - this.m_v1.x, this.m_v2.y - this.m_v1.y); - this.m_length = this.m_direction.Normalize(); - this.m_normal.Set(this.m_direction.y, -this.m_direction.x); - this.m_coreV1.Set(-b2Settings.b2_toiSlop * (this.m_normal.x - this.m_direction.x) + this.m_v1.x, -b2Settings.b2_toiSlop * (this.m_normal.y - this.m_direction.y) + this.m_v1.y); - this.m_coreV2.Set(-b2Settings.b2_toiSlop * (this.m_normal.x + this.m_direction.x) + this.m_v2.x, -b2Settings.b2_toiSlop * (this.m_normal.y + this.m_direction.y) + this.m_v2.y); - this.m_cornerDir1 = this.m_normal; - this.m_cornerDir2.Set(-this.m_normal.x, -this.m_normal.y) -}; -b2EdgeShape.prototype.__varz = function() { - this.s_supportVec = new b2Vec2; - this.m_v1 = new b2Vec2; - this.m_v2 = new b2Vec2; - this.m_coreV1 = new b2Vec2; - this.m_coreV2 = new b2Vec2; - this.m_normal = new b2Vec2; - this.m_direction = new b2Vec2; - this.m_cornerDir1 = new b2Vec2; - this.m_cornerDir2 = new b2Vec2 -}; -b2EdgeShape.prototype.SetPrevEdge = function(edge, core, cornerDir, convex) { - this.m_prevEdge = edge; - this.m_coreV1 = core; - this.m_cornerDir1 = cornerDir; - this.m_cornerConvex1 = convex -}; -b2EdgeShape.prototype.SetNextEdge = function(edge, core, cornerDir, convex) { - this.m_nextEdge = edge; - this.m_coreV2 = core; - this.m_cornerDir2 = cornerDir; - this.m_cornerConvex2 = convex -}; -b2EdgeShape.prototype.TestPoint = function(transform, p) { - return false -}; -b2EdgeShape.prototype.RayCast = function(output, input, transform) { - var tMat; - var rX = input.p2.x - input.p1.x; - var rY = input.p2.y - input.p1.y; - tMat = transform.R; - var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); - var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); - var nX = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y) - v1Y; - var nY = -(transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y) - v1X); - var k_slop = 100 * Number.MIN_VALUE; - var denom = -(rX * nX + rY * nY); - if(denom > k_slop) { - var bX = input.p1.x - v1X; - var bY = input.p1.y - v1Y; - var a = bX * nX + bY * nY; - if(0 <= a && a <= input.maxFraction * denom) { - var mu2 = -rX * bY + rY * bX; - if(-k_slop * denom <= mu2 && mu2 <= denom * (1 + k_slop)) { - a /= denom; - output.fraction = a; - var nLen = Math.sqrt(nX * nX + nY * nY); - output.normal.x = nX / nLen; - output.normal.y = nY / nLen; - return true - } - } - } - return false -}; -b2EdgeShape.prototype.ComputeAABB = function(aabb, transform) { - var tMat = transform.R; - var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); - var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); - var v2X = transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y); - var v2Y = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y); - if(v1X < v2X) { - aabb.lowerBound.x = v1X; - aabb.upperBound.x = v2X - }else { - aabb.lowerBound.x = v2X; - aabb.upperBound.x = v1X - } - if(v1Y < v2Y) { - aabb.lowerBound.y = v1Y; - aabb.upperBound.y = v2Y - }else { - aabb.lowerBound.y = v2Y; - aabb.upperBound.y = v1Y - } -}; -b2EdgeShape.prototype.ComputeMass = function(massData, density) { - massData.mass = 0; - massData.center.SetV(this.m_v1); - massData.I = 0 -}; -b2EdgeShape.prototype.ComputeSubmergedArea = function(normal, offset, xf, c) { - var v0 = new b2Vec2(normal.x * offset, normal.y * offset); - var v1 = b2Math.MulX(xf, this.m_v1); - var v2 = b2Math.MulX(xf, this.m_v2); - var d1 = b2Math.Dot(normal, v1) - offset; - var d2 = b2Math.Dot(normal, v2) - offset; - if(d1 > 0) { - if(d2 > 0) { - return 0 - }else { - v1.x = -d2 / (d1 - d2) * v1.x + d1 / (d1 - d2) * v2.x; - v1.y = -d2 / (d1 - d2) * v1.y + d1 / (d1 - d2) * v2.y - } - }else { - if(d2 > 0) { - v2.x = -d2 / (d1 - d2) * v1.x + d1 / (d1 - d2) * v2.x; - v2.y = -d2 / (d1 - d2) * v1.y + d1 / (d1 - d2) * v2.y - }else { - } - } - c.x = (v0.x + v1.x + v2.x) / 3; - c.y = (v0.y + v1.y + v2.y) / 3; - return 0.5 * ((v1.x - v0.x) * (v2.y - v0.y) - (v1.y - v0.y) * (v2.x - v0.x)) -}; -b2EdgeShape.prototype.GetLength = function() { - return this.m_length -}; -b2EdgeShape.prototype.GetVertex1 = function() { - return this.m_v1 -}; -b2EdgeShape.prototype.GetVertex2 = function() { - return this.m_v2 -}; -b2EdgeShape.prototype.GetCoreVertex1 = function() { - return this.m_coreV1 -}; -b2EdgeShape.prototype.GetCoreVertex2 = function() { - return this.m_coreV2 -}; -b2EdgeShape.prototype.GetNormalVector = function() { - return this.m_normal -}; -b2EdgeShape.prototype.GetDirectionVector = function() { - return this.m_direction -}; -b2EdgeShape.prototype.GetCorner1Vector = function() { - return this.m_cornerDir1 -}; -b2EdgeShape.prototype.GetCorner2Vector = function() { - return this.m_cornerDir2 -}; -b2EdgeShape.prototype.Corner1IsConvex = function() { - return this.m_cornerConvex1 -}; -b2EdgeShape.prototype.Corner2IsConvex = function() { - return this.m_cornerConvex2 -}; -b2EdgeShape.prototype.GetFirstVertex = function(xf) { - var tMat = xf.R; - return new b2Vec2(xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y), xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y)) -}; -b2EdgeShape.prototype.GetNextEdge = function() { - return this.m_nextEdge -}; -b2EdgeShape.prototype.GetPrevEdge = function() { - return this.m_prevEdge -}; -b2EdgeShape.prototype.Support = function(xf, dX, dY) { - var tMat = xf.R; - var v1X = xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y); - var v1Y = xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y); - var v2X = xf.position.x + (tMat.col1.x * this.m_coreV2.x + tMat.col2.x * this.m_coreV2.y); - var v2Y = xf.position.y + (tMat.col1.y * this.m_coreV2.x + tMat.col2.y * this.m_coreV2.y); - if(v1X * dX + v1Y * dY > v2X * dX + v2Y * dY) { - this.s_supportVec.x = v1X; - this.s_supportVec.y = v1Y - }else { - this.s_supportVec.x = v2X; - this.s_supportVec.y = v2Y - } - return this.s_supportVec -}; -b2EdgeShape.prototype.s_supportVec = new b2Vec2; -b2EdgeShape.prototype.m_v1 = new b2Vec2; -b2EdgeShape.prototype.m_v2 = new b2Vec2; -b2EdgeShape.prototype.m_coreV1 = new b2Vec2; -b2EdgeShape.prototype.m_coreV2 = new b2Vec2; -b2EdgeShape.prototype.m_length = null; -b2EdgeShape.prototype.m_normal = new b2Vec2; -b2EdgeShape.prototype.m_direction = new b2Vec2; -b2EdgeShape.prototype.m_cornerDir1 = new b2Vec2; -b2EdgeShape.prototype.m_cornerDir2 = new b2Vec2; -b2EdgeShape.prototype.m_cornerConvex1 = null; -b2EdgeShape.prototype.m_cornerConvex2 = null; -b2EdgeShape.prototype.m_nextEdge = null; -b2EdgeShape.prototype.m_prevEdge = null;var b2BuoyancyController = function() { - b2Controller.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2BuoyancyController.prototype, b2Controller.prototype); -b2BuoyancyController.prototype._super = b2Controller.prototype; -b2BuoyancyController.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2BuoyancyController.prototype.__varz = function() { - this.normal = new b2Vec2(0, -1); - this.velocity = new b2Vec2(0, 0) -}; -b2BuoyancyController.prototype.Step = function(step) { - if(!m_bodyList) { - return - } - if(this.useWorldGravity) { - this.gravity = this.GetWorld().GetGravity().Copy() - } - for(var i = m_bodyList;i;i = i.nextBody) { - var body = i.body; - if(body.IsAwake() == false) { - continue - } - var areac = new b2Vec2; - var massc = new b2Vec2; - var area = 0; - var mass = 0; - for(var fixture = body.GetFixtureList();fixture;fixture = fixture.GetNext()) { - var sc = new b2Vec2; - var sarea = fixture.GetShape().ComputeSubmergedArea(this.normal, this.offset, body.GetTransform(), sc); - area += sarea; - areac.x += sarea * sc.x; - areac.y += sarea * sc.y; - var shapeDensity; - if(this.useDensity) { - shapeDensity = 1 - }else { - shapeDensity = 1 - } - mass += sarea * shapeDensity; - massc.x += sarea * sc.x * shapeDensity; - massc.y += sarea * sc.y * shapeDensity - } - areac.x /= area; - areac.y /= area; - massc.x /= mass; - massc.y /= mass; - if(area < Number.MIN_VALUE) { - continue - } - var buoyancyForce = this.gravity.GetNegative(); - buoyancyForce.Multiply(this.density * area); - body.ApplyForce(buoyancyForce, massc); - var dragForce = body.GetLinearVelocityFromWorldPoint(areac); - dragForce.Subtract(this.velocity); - dragForce.Multiply(-this.linearDrag * area); - body.ApplyForce(dragForce, areac); - body.ApplyTorque(-body.GetInertia() / body.GetMass() * area * body.GetAngularVelocity() * this.angularDrag) - } -}; -b2BuoyancyController.prototype.Draw = function(debugDraw) { - var r = 1E3; - var p1 = new b2Vec2; - var p2 = new b2Vec2; - p1.x = this.normal.x * this.offset + this.normal.y * r; - p1.y = this.normal.y * this.offset - this.normal.x * r; - p2.x = this.normal.x * this.offset - this.normal.y * r; - p2.y = this.normal.y * this.offset + this.normal.x * r; - var color = new b2Color(0, 0, 1); - debugDraw.DrawSegment(p1, p2, color) -}; -b2BuoyancyController.prototype.normal = new b2Vec2(0, -1); -b2BuoyancyController.prototype.offset = 0; -b2BuoyancyController.prototype.density = 0; -b2BuoyancyController.prototype.velocity = new b2Vec2(0, 0); -b2BuoyancyController.prototype.linearDrag = 2; -b2BuoyancyController.prototype.angularDrag = 1; -b2BuoyancyController.prototype.useDensity = false; -b2BuoyancyController.prototype.useWorldGravity = true; -b2BuoyancyController.prototype.gravity = null;var b2Body = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Body.prototype.__constructor = function(bd, world) { - this.m_flags = 0; - if(bd.bullet) { - this.m_flags |= b2Body.e_bulletFlag - } - if(bd.fixedRotation) { - this.m_flags |= b2Body.e_fixedRotationFlag - } - if(bd.allowSleep) { - this.m_flags |= b2Body.e_allowSleepFlag - } - if(bd.awake) { - this.m_flags |= b2Body.e_awakeFlag - } - if(bd.active) { - this.m_flags |= b2Body.e_activeFlag - } - this.m_world = world; - this.m_xf.position.SetV(bd.position); - this.m_xf.R.Set(bd.angle); - this.m_sweep.localCenter.SetZero(); - this.m_sweep.t0 = 1; - this.m_sweep.a0 = this.m_sweep.a = bd.angle; - var tMat = this.m_xf.R; - var tVec = this.m_sweep.localCenter; - this.m_sweep.c.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - this.m_sweep.c.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_sweep.c.x += this.m_xf.position.x; - this.m_sweep.c.y += this.m_xf.position.y; - this.m_sweep.c0.SetV(this.m_sweep.c); - this.m_jointList = null; - this.m_controllerList = null; - this.m_contactList = null; - this.m_controllerCount = 0; - this.m_prev = null; - this.m_next = null; - this.m_linearVelocity.SetV(bd.linearVelocity); - this.m_angularVelocity = bd.angularVelocity; - this.m_linearDamping = bd.linearDamping; - this.m_angularDamping = bd.angularDamping; - this.m_force.Set(0, 0); - this.m_torque = 0; - this.m_sleepTime = 0; - this.m_type = bd.type; - if(this.m_type == b2Body.b2_dynamicBody) { - this.m_mass = 1; - this.m_invMass = 1 - }else { - this.m_mass = 0; - this.m_invMass = 0 - } - this.m_I = 0; - this.m_invI = 0; - this.m_inertiaScale = bd.inertiaScale; - this.m_userData = bd.userData; - this.m_fixtureList = null; - this.m_fixtureCount = 0 -}; -b2Body.prototype.__varz = function() { - this.m_xf = new b2Transform; - this.m_sweep = new b2Sweep; - this.m_linearVelocity = new b2Vec2; - this.m_force = new b2Vec2 -}; -b2Body.b2_staticBody = 0; -b2Body.b2_kinematicBody = 1; -b2Body.b2_dynamicBody = 2; -b2Body.s_xf1 = new b2Transform; -b2Body.e_islandFlag = 1; -b2Body.e_awakeFlag = 2; -b2Body.e_allowSleepFlag = 4; -b2Body.e_bulletFlag = 8; -b2Body.e_fixedRotationFlag = 16; -b2Body.e_activeFlag = 32; -b2Body.prototype.connectEdges = function(s1, s2, angle1) { - var angle2 = Math.atan2(s2.GetDirectionVector().y, s2.GetDirectionVector().x); - var coreOffset = Math.tan((angle2 - angle1) * 0.5); - var core = b2Math.MulFV(coreOffset, s2.GetDirectionVector()); - core = b2Math.SubtractVV(core, s2.GetNormalVector()); - core = b2Math.MulFV(b2Settings.b2_toiSlop, core); - core = b2Math.AddVV(core, s2.GetVertex1()); - var cornerDir = b2Math.AddVV(s1.GetDirectionVector(), s2.GetDirectionVector()); - cornerDir.Normalize(); - var convex = b2Math.Dot(s1.GetDirectionVector(), s2.GetNormalVector()) > 0; - s1.SetNextEdge(s2, core, cornerDir, convex); - s2.SetPrevEdge(s1, core, cornerDir, convex); - return angle2 -}; -b2Body.prototype.SynchronizeFixtures = function() { - var xf1 = b2Body.s_xf1; - xf1.R.Set(this.m_sweep.a0); - var tMat = xf1.R; - var tVec = this.m_sweep.localCenter; - xf1.position.x = this.m_sweep.c0.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - xf1.position.y = this.m_sweep.c0.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var f; - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - for(f = this.m_fixtureList;f;f = f.m_next) { - f.Synchronize(broadPhase, xf1, this.m_xf) - } -}; -b2Body.prototype.SynchronizeTransform = function() { - this.m_xf.R.Set(this.m_sweep.a); - var tMat = this.m_xf.R; - var tVec = this.m_sweep.localCenter; - this.m_xf.position.x = this.m_sweep.c.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - this.m_xf.position.y = this.m_sweep.c.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y) -}; -b2Body.prototype.ShouldCollide = function(other) { - if(this.m_type != b2Body.b2_dynamicBody && other.m_type != b2Body.b2_dynamicBody) { - return false - } - for(var jn = this.m_jointList;jn;jn = jn.next) { - if(jn.other == other) { - if(jn.joint.m_collideConnected == false) { - return false - } - } - } - return true -}; -b2Body.prototype.Advance = function(t) { - this.m_sweep.Advance(t); - this.m_sweep.c.SetV(this.m_sweep.c0); - this.m_sweep.a = this.m_sweep.a0; - this.SynchronizeTransform() -}; -b2Body.prototype.CreateFixture = function(def) { - if(this.m_world.IsLocked() == true) { - return null - } - var fixture = new b2Fixture; - fixture.Create(this, this.m_xf, def); - if(this.m_flags & b2Body.e_activeFlag) { - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - fixture.CreateProxy(broadPhase, this.m_xf) - } - fixture.m_next = this.m_fixtureList; - this.m_fixtureList = fixture; - ++this.m_fixtureCount; - fixture.m_body = this; - if(fixture.m_density > 0) { - this.ResetMassData() - } - this.m_world.m_flags |= b2World.e_newFixture; - return fixture -}; -b2Body.prototype.CreateFixture2 = function(shape, density) { - var def = new b2FixtureDef; - def.shape = shape; - def.density = density; - return this.CreateFixture(def) -}; -b2Body.prototype.DestroyFixture = function(fixture) { - if(this.m_world.IsLocked() == true) { - return - } - var node = this.m_fixtureList; - var ppF = null; - var found = false; - while(node != null) { - if(node == fixture) { - if(ppF) { - ppF.m_next = fixture.m_next - }else { - this.m_fixtureList = fixture.m_next - } - found = true; - break - } - ppF = node; - node = node.m_next - } - var edge = this.m_contactList; - while(edge) { - var c = edge.contact; - edge = edge.next; - var fixtureA = c.GetFixtureA(); - var fixtureB = c.GetFixtureB(); - if(fixture == fixtureA || fixture == fixtureB) { - this.m_world.m_contactManager.Destroy(c) - } - } - if(this.m_flags & b2Body.e_activeFlag) { - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - fixture.DestroyProxy(broadPhase) - }else { - } - fixture.Destroy(); - fixture.m_body = null; - fixture.m_next = null; - --this.m_fixtureCount; - this.ResetMassData() -}; -b2Body.prototype.SetPositionAndAngle = function(position, angle) { - var f; - if(this.m_world.IsLocked() == true) { - return - } - this.m_xf.R.Set(angle); - this.m_xf.position.SetV(position); - var tMat = this.m_xf.R; - var tVec = this.m_sweep.localCenter; - this.m_sweep.c.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - this.m_sweep.c.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_sweep.c.x += this.m_xf.position.x; - this.m_sweep.c.y += this.m_xf.position.y; - this.m_sweep.c0.SetV(this.m_sweep.c); - this.m_sweep.a0 = this.m_sweep.a = angle; - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - for(f = this.m_fixtureList;f;f = f.m_next) { - f.Synchronize(broadPhase, this.m_xf, this.m_xf) - } - this.m_world.m_contactManager.FindNewContacts() -}; -b2Body.prototype.SetTransform = function(xf) { - this.SetPositionAndAngle(xf.position, xf.GetAngle()) -}; -b2Body.prototype.GetTransform = function() { - return this.m_xf -}; -b2Body.prototype.GetPosition = function() { - return this.m_xf.position -}; -b2Body.prototype.SetPosition = function(position) { - this.SetPositionAndAngle(position, this.GetAngle()) -}; -b2Body.prototype.GetAngle = function() { - return this.m_sweep.a -}; -b2Body.prototype.SetAngle = function(angle) { - this.SetPositionAndAngle(this.GetPosition(), angle) -}; -b2Body.prototype.GetWorldCenter = function() { - return this.m_sweep.c -}; -b2Body.prototype.GetLocalCenter = function() { - return this.m_sweep.localCenter -}; -b2Body.prototype.SetLinearVelocity = function(v) { - if(this.m_type == b2Body.b2_staticBody) { - return - } - this.m_linearVelocity.SetV(v) -}; -b2Body.prototype.GetLinearVelocity = function() { - return this.m_linearVelocity -}; -b2Body.prototype.SetAngularVelocity = function(omega) { - if(this.m_type == b2Body.b2_staticBody) { - return - } - this.m_angularVelocity = omega -}; -b2Body.prototype.GetAngularVelocity = function() { - return this.m_angularVelocity -}; -b2Body.prototype.GetDefinition = function() { - var bd = new b2BodyDef; - bd.type = this.GetType(); - bd.allowSleep = (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag; - bd.angle = this.GetAngle(); - bd.angularDamping = this.m_angularDamping; - bd.angularVelocity = this.m_angularVelocity; - bd.fixedRotation = (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag; - bd.bullet = (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag; - bd.awake = (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag; - bd.linearDamping = this.m_linearDamping; - bd.linearVelocity.SetV(this.GetLinearVelocity()); - bd.position = this.GetPosition(); - bd.userData = this.GetUserData(); - return bd -}; -b2Body.prototype.ApplyForce = function(force, point) { - if(this.m_type != b2Body.b2_dynamicBody) { - return - } - if(this.IsAwake() == false) { - this.SetAwake(true) - } - this.m_force.x += force.x; - this.m_force.y += force.y; - this.m_torque += (point.x - this.m_sweep.c.x) * force.y - (point.y - this.m_sweep.c.y) * force.x -}; -b2Body.prototype.ApplyTorque = function(torque) { - if(this.m_type != b2Body.b2_dynamicBody) { - return - } - if(this.IsAwake() == false) { - this.SetAwake(true) - } - this.m_torque += torque -}; -b2Body.prototype.ApplyImpulse = function(impulse, point) { - if(this.m_type != b2Body.b2_dynamicBody) { - return - } - if(this.IsAwake() == false) { - this.SetAwake(true) - } - this.m_linearVelocity.x += this.m_invMass * impulse.x; - this.m_linearVelocity.y += this.m_invMass * impulse.y; - this.m_angularVelocity += this.m_invI * ((point.x - this.m_sweep.c.x) * impulse.y - (point.y - this.m_sweep.c.y) * impulse.x) -}; -b2Body.prototype.Split = function(callback) { - var linearVelocity = this.GetLinearVelocity().Copy(); - var angularVelocity = this.GetAngularVelocity(); - var center = this.GetWorldCenter(); - var body1 = this; - var body2 = this.m_world.CreateBody(this.GetDefinition()); - var prev; - for(var f = body1.m_fixtureList;f;) { - if(callback(f)) { - var next = f.m_next; - if(prev) { - prev.m_next = next - }else { - body1.m_fixtureList = next - } - body1.m_fixtureCount--; - f.m_next = body2.m_fixtureList; - body2.m_fixtureList = f; - body2.m_fixtureCount++; - f.m_body = body2; - f = next - }else { - prev = f; - f = f.m_next - } - } - body1.ResetMassData(); - body2.ResetMassData(); - var center1 = body1.GetWorldCenter(); - var center2 = body2.GetWorldCenter(); - var velocity1 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center1, center))); - var velocity2 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center2, center))); - body1.SetLinearVelocity(velocity1); - body2.SetLinearVelocity(velocity2); - body1.SetAngularVelocity(angularVelocity); - body2.SetAngularVelocity(angularVelocity); - body1.SynchronizeFixtures(); - body2.SynchronizeFixtures(); - return body2 -}; -b2Body.prototype.Merge = function(other) { - var f; - for(f = other.m_fixtureList;f;) { - var next = f.m_next; - other.m_fixtureCount--; - f.m_next = this.m_fixtureList; - this.m_fixtureList = f; - this.m_fixtureCount++; - f.m_body = body2; - f = next - } - body1.m_fixtureCount = 0; - var body1 = this; - var body2 = other; - var center1 = body1.GetWorldCenter(); - var center2 = body2.GetWorldCenter(); - var velocity1 = body1.GetLinearVelocity().Copy(); - var velocity2 = body2.GetLinearVelocity().Copy(); - var angular1 = body1.GetAngularVelocity(); - var angular = body2.GetAngularVelocity(); - body1.ResetMassData(); - this.SynchronizeFixtures() -}; -b2Body.prototype.GetMass = function() { - return this.m_mass -}; -b2Body.prototype.GetInertia = function() { - return this.m_I -}; -b2Body.prototype.GetMassData = function(data) { - data.mass = this.m_mass; - data.I = this.m_I; - data.center.SetV(this.m_sweep.localCenter) -}; -b2Body.prototype.SetMassData = function(massData) { - b2Settings.b2Assert(this.m_world.IsLocked() == false); - if(this.m_world.IsLocked() == true) { - return - } - if(this.m_type != b2Body.b2_dynamicBody) { - return - } - this.m_invMass = 0; - this.m_I = 0; - this.m_invI = 0; - this.m_mass = massData.mass; - if(this.m_mass <= 0) { - this.m_mass = 1 - } - this.m_invMass = 1 / this.m_mass; - if(massData.I > 0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { - this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y); - this.m_invI = 1 / this.m_I - } - var oldCenter = this.m_sweep.c.Copy(); - this.m_sweep.localCenter.SetV(massData.center); - this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); - this.m_sweep.c.SetV(this.m_sweep.c0); - this.m_linearVelocity.x += this.m_angularVelocity * -(this.m_sweep.c.y - oldCenter.y); - this.m_linearVelocity.y += this.m_angularVelocity * +(this.m_sweep.c.x - oldCenter.x) -}; -b2Body.prototype.ResetMassData = function() { - this.m_mass = 0; - this.m_invMass = 0; - this.m_I = 0; - this.m_invI = 0; - this.m_sweep.localCenter.SetZero(); - if(this.m_type == b2Body.b2_staticBody || this.m_type == b2Body.b2_kinematicBody) { - return - } - var center = b2Vec2.Make(0, 0); - for(var f = this.m_fixtureList;f;f = f.m_next) { - if(f.m_density == 0) { - continue - } - var massData = f.GetMassData(); - this.m_mass += massData.mass; - center.x += massData.center.x * massData.mass; - center.y += massData.center.y * massData.mass; - this.m_I += massData.I - } - if(this.m_mass > 0) { - this.m_invMass = 1 / this.m_mass; - center.x *= this.m_invMass; - center.y *= this.m_invMass - }else { - this.m_mass = 1; - this.m_invMass = 1 - } - if(this.m_I > 0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { - this.m_I -= this.m_mass * (center.x * center.x + center.y * center.y); - this.m_I *= this.m_inertiaScale; - b2Settings.b2Assert(this.m_I > 0); - this.m_invI = 1 / this.m_I - }else { - this.m_I = 0; - this.m_invI = 0 - } - var oldCenter = this.m_sweep.c.Copy(); - this.m_sweep.localCenter.SetV(center); - this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); - this.m_sweep.c.SetV(this.m_sweep.c0); - this.m_linearVelocity.x += this.m_angularVelocity * -(this.m_sweep.c.y - oldCenter.y); - this.m_linearVelocity.y += this.m_angularVelocity * +(this.m_sweep.c.x - oldCenter.x) -}; -b2Body.prototype.GetWorldPoint = function(localPoint) { - var A = this.m_xf.R; - var u = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); - u.x += this.m_xf.position.x; - u.y += this.m_xf.position.y; - return u -}; -b2Body.prototype.GetWorldVector = function(localVector) { - return b2Math.MulMV(this.m_xf.R, localVector) -}; -b2Body.prototype.GetLocalPoint = function(worldPoint) { - return b2Math.MulXT(this.m_xf, worldPoint) -}; -b2Body.prototype.GetLocalVector = function(worldVector) { - return b2Math.MulTMV(this.m_xf.R, worldVector) -}; -b2Body.prototype.GetLinearVelocityFromWorldPoint = function(worldPoint) { - return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)) -}; -b2Body.prototype.GetLinearVelocityFromLocalPoint = function(localPoint) { - var A = this.m_xf.R; - var worldPoint = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); - worldPoint.x += this.m_xf.position.x; - worldPoint.y += this.m_xf.position.y; - return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)) -}; -b2Body.prototype.GetLinearDamping = function() { - return this.m_linearDamping -}; -b2Body.prototype.SetLinearDamping = function(linearDamping) { - this.m_linearDamping = linearDamping -}; -b2Body.prototype.GetAngularDamping = function() { - return this.m_angularDamping -}; -b2Body.prototype.SetAngularDamping = function(angularDamping) { - this.m_angularDamping = angularDamping -}; -b2Body.prototype.SetType = function(type) { - if(this.m_type == type) { - return - } - this.m_type = type; - this.ResetMassData(); - if(this.m_type == b2Body.b2_staticBody) { - this.m_linearVelocity.SetZero(); - this.m_angularVelocity = 0 - } - this.SetAwake(true); - this.m_force.SetZero(); - this.m_torque = 0; - for(var ce = this.m_contactList;ce;ce = ce.next) { - ce.contact.FlagForFiltering() - } -}; -b2Body.prototype.GetType = function() { - return this.m_type -}; -b2Body.prototype.SetBullet = function(flag) { - if(flag) { - this.m_flags |= b2Body.e_bulletFlag - }else { - this.m_flags &= ~b2Body.e_bulletFlag - } -}; -b2Body.prototype.IsBullet = function() { - return(this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag -}; -b2Body.prototype.SetSleepingAllowed = function(flag) { - if(flag) { - this.m_flags |= b2Body.e_allowSleepFlag - }else { - this.m_flags &= ~b2Body.e_allowSleepFlag; - this.SetAwake(true) - } -}; -b2Body.prototype.SetAwake = function(flag) { - if(flag) { - this.m_flags |= b2Body.e_awakeFlag; - this.m_sleepTime = 0 - }else { - this.m_flags &= ~b2Body.e_awakeFlag; - this.m_sleepTime = 0; - this.m_linearVelocity.SetZero(); - this.m_angularVelocity = 0; - this.m_force.SetZero(); - this.m_torque = 0 - } -}; -b2Body.prototype.IsAwake = function() { - return(this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag -}; -b2Body.prototype.SetFixedRotation = function(fixed) { - if(fixed) { - this.m_flags |= b2Body.e_fixedRotationFlag - }else { - this.m_flags &= ~b2Body.e_fixedRotationFlag - } - this.ResetMassData() -}; -b2Body.prototype.IsFixedRotation = function() { - return(this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag -}; -b2Body.prototype.SetActive = function(flag) { - if(flag == this.IsActive()) { - return - } - var broadPhase; - var f; - if(flag) { - this.m_flags |= b2Body.e_activeFlag; - broadPhase = this.m_world.m_contactManager.m_broadPhase; - for(f = this.m_fixtureList;f;f = f.m_next) { - f.CreateProxy(broadPhase, this.m_xf) - } - }else { - this.m_flags &= ~b2Body.e_activeFlag; - broadPhase = this.m_world.m_contactManager.m_broadPhase; - for(f = this.m_fixtureList;f;f = f.m_next) { - f.DestroyProxy(broadPhase) - } - var ce = this.m_contactList; - while(ce) { - var ce0 = ce; - ce = ce.next; - this.m_world.m_contactManager.Destroy(ce0.contact) - } - this.m_contactList = null - } -}; -b2Body.prototype.IsActive = function() { - return(this.m_flags & b2Body.e_activeFlag) == b2Body.e_activeFlag -}; -b2Body.prototype.IsSleepingAllowed = function() { - return(this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag -}; -b2Body.prototype.GetFixtureList = function() { - return this.m_fixtureList -}; -b2Body.prototype.GetJointList = function() { - return this.m_jointList -}; -b2Body.prototype.GetControllerList = function() { - return this.m_controllerList -}; -b2Body.prototype.GetContactList = function() { - return this.m_contactList -}; -b2Body.prototype.GetNext = function() { - return this.m_next -}; -b2Body.prototype.GetUserData = function() { - return this.m_userData -}; -b2Body.prototype.SetUserData = function(data) { - this.m_userData = data -}; -b2Body.prototype.GetWorld = function() { - return this.m_world -}; -b2Body.prototype.m_flags = 0; -b2Body.prototype.m_type = 0; -b2Body.prototype.m_islandIndex = 0; -b2Body.prototype.m_xf = new b2Transform; -b2Body.prototype.m_sweep = new b2Sweep; -b2Body.prototype.m_linearVelocity = new b2Vec2; -b2Body.prototype.m_angularVelocity = null; -b2Body.prototype.m_force = new b2Vec2; -b2Body.prototype.m_torque = null; -b2Body.prototype.m_world = null; -b2Body.prototype.m_prev = null; -b2Body.prototype.m_next = null; -b2Body.prototype.m_fixtureList = null; -b2Body.prototype.m_fixtureCount = 0; -b2Body.prototype.m_controllerList = null; -b2Body.prototype.m_controllerCount = 0; -b2Body.prototype.m_jointList = null; -b2Body.prototype.m_contactList = null; -b2Body.prototype.m_mass = null; -b2Body.prototype.m_invMass = null; -b2Body.prototype.m_I = null; -b2Body.prototype.m_invI = null; -b2Body.prototype.m_inertiaScale = null; -b2Body.prototype.m_linearDamping = null; -b2Body.prototype.m_angularDamping = null; -b2Body.prototype.m_sleepTime = null; -b2Body.prototype.m_userData = null;var b2ContactImpulse = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactImpulse.prototype.__constructor = function() { -}; -b2ContactImpulse.prototype.__varz = function() { - this.normalImpulses = new Array(b2Settings.b2_maxManifoldPoints); - this.tangentImpulses = new Array(b2Settings.b2_maxManifoldPoints) -}; -b2ContactImpulse.prototype.normalImpulses = new Array(b2Settings.b2_maxManifoldPoints); -b2ContactImpulse.prototype.tangentImpulses = new Array(b2Settings.b2_maxManifoldPoints);var b2TensorDampingController = function() { - b2Controller.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2TensorDampingController.prototype, b2Controller.prototype); -b2TensorDampingController.prototype._super = b2Controller.prototype; -b2TensorDampingController.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2TensorDampingController.prototype.__varz = function() { - this.T = new b2Mat22 -}; -b2TensorDampingController.prototype.SetAxisAligned = function(xDamping, yDamping) { - this.T.col1.x = -xDamping; - this.T.col1.y = 0; - this.T.col2.x = 0; - this.T.col2.y = -yDamping; - if(xDamping > 0 || yDamping > 0) { - this.maxTimestep = 1 / Math.max(xDamping, yDamping) - }else { - this.maxTimestep = 0 - } -}; -b2TensorDampingController.prototype.Step = function(step) { - var timestep = step.dt; - if(timestep <= Number.MIN_VALUE) { - return - } - if(timestep > this.maxTimestep && this.maxTimestep > 0) { - timestep = this.maxTimestep - } - for(var i = m_bodyList;i;i = i.nextBody) { - var body = i.body; - if(!body.IsAwake()) { - continue - } - var damping = body.GetWorldVector(b2Math.MulMV(this.T, body.GetLocalVector(body.GetLinearVelocity()))); - body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + damping.x * timestep, body.GetLinearVelocity().y + damping.y * timestep)) - } -}; -b2TensorDampingController.prototype.T = new b2Mat22; -b2TensorDampingController.prototype.maxTimestep = 0;var b2ManifoldPoint = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ManifoldPoint.prototype.__constructor = function() { - this.Reset() -}; -b2ManifoldPoint.prototype.__varz = function() { - this.m_localPoint = new b2Vec2; - this.m_id = new b2ContactID -}; -b2ManifoldPoint.prototype.Reset = function() { - this.m_localPoint.SetZero(); - this.m_normalImpulse = 0; - this.m_tangentImpulse = 0; - this.m_id.key = 0 -}; -b2ManifoldPoint.prototype.Set = function(m) { - this.m_localPoint.SetV(m.m_localPoint); - this.m_normalImpulse = m.m_normalImpulse; - this.m_tangentImpulse = m.m_tangentImpulse; - this.m_id.Set(m.m_id) -}; -b2ManifoldPoint.prototype.m_localPoint = new b2Vec2; -b2ManifoldPoint.prototype.m_normalImpulse = null; -b2ManifoldPoint.prototype.m_tangentImpulse = null; -b2ManifoldPoint.prototype.m_id = new b2ContactID;var b2PolygonShape = function() { - b2Shape.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2PolygonShape.prototype, b2Shape.prototype); -b2PolygonShape.prototype._super = b2Shape.prototype; -b2PolygonShape.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.m_type = b2Shape.e_polygonShape; - this.m_centroid = new b2Vec2; - this.m_vertices = new Array; - this.m_normals = new Array -}; -b2PolygonShape.prototype.__varz = function() { -}; -b2PolygonShape.AsArray = function(vertices, vertexCount) { - var polygonShape = new b2PolygonShape; - polygonShape.SetAsArray(vertices, vertexCount); - return polygonShape -}; -b2PolygonShape.AsVector = function(vertices, vertexCount) { - var polygonShape = new b2PolygonShape; - polygonShape.SetAsVector(vertices, vertexCount); - return polygonShape -}; -b2PolygonShape.AsBox = function(hx, hy) { - var polygonShape = new b2PolygonShape; - polygonShape.SetAsBox(hx, hy); - return polygonShape -}; -b2PolygonShape.AsOrientedBox = function(hx, hy, center, angle) { - var polygonShape = new b2PolygonShape; - polygonShape.SetAsOrientedBox(hx, hy, center, angle); - return polygonShape -}; -b2PolygonShape.AsEdge = function(v1, v2) { - var polygonShape = new b2PolygonShape; - polygonShape.SetAsEdge(v1, v2); - return polygonShape -}; -b2PolygonShape.ComputeCentroid = function(vs, count) { - var c = new b2Vec2; - var area = 0; - var p1X = 0; - var p1Y = 0; - var inv3 = 1 / 3; - for(var i = 0;i < count;++i) { - var p2 = vs[i]; - var p3 = i + 1 < count ? vs[parseInt(i + 1)] : vs[0]; - var e1X = p2.x - p1X; - var e1Y = p2.y - p1Y; - var e2X = p3.x - p1X; - var e2Y = p3.y - p1Y; - var D = e1X * e2Y - e1Y * e2X; - var triangleArea = 0.5 * D; - area += triangleArea; - c.x += triangleArea * inv3 * (p1X + p2.x + p3.x); - c.y += triangleArea * inv3 * (p1Y + p2.y + p3.y) - } - c.x *= 1 / area; - c.y *= 1 / area; - return c -}; -b2PolygonShape.ComputeOBB = function(obb, vs, count) { - var i = 0; - var p = new Array(count + 1); - for(i = 0;i < count;++i) { - p[i] = vs[i] - } - p[count] = p[0]; - var minArea = Number.MAX_VALUE; - for(i = 1;i <= count;++i) { - var root = p[parseInt(i - 1)]; - var uxX = p[i].x - root.x; - var uxY = p[i].y - root.y; - var length = Math.sqrt(uxX * uxX + uxY * uxY); - uxX /= length; - uxY /= length; - var uyX = -uxY; - var uyY = uxX; - var lowerX = Number.MAX_VALUE; - var lowerY = Number.MAX_VALUE; - var upperX = -Number.MAX_VALUE; - var upperY = -Number.MAX_VALUE; - for(var j = 0;j < count;++j) { - var dX = p[j].x - root.x; - var dY = p[j].y - root.y; - var rX = uxX * dX + uxY * dY; - var rY = uyX * dX + uyY * dY; - if(rX < lowerX) { - lowerX = rX - } - if(rY < lowerY) { - lowerY = rY - } - if(rX > upperX) { - upperX = rX - } - if(rY > upperY) { - upperY = rY - } - } - var area = (upperX - lowerX) * (upperY - lowerY); - if(area < 0.95 * minArea) { - minArea = area; - obb.R.col1.x = uxX; - obb.R.col1.y = uxY; - obb.R.col2.x = uyX; - obb.R.col2.y = uyY; - var centerX = 0.5 * (lowerX + upperX); - var centerY = 0.5 * (lowerY + upperY); - var tMat = obb.R; - obb.center.x = root.x + (tMat.col1.x * centerX + tMat.col2.x * centerY); - obb.center.y = root.y + (tMat.col1.y * centerX + tMat.col2.y * centerY); - obb.extents.x = 0.5 * (upperX - lowerX); - obb.extents.y = 0.5 * (upperY - lowerY) - } - } -}; -b2PolygonShape.s_mat = new b2Mat22; -b2PolygonShape.prototype.Validate = function() { - return false -}; -b2PolygonShape.prototype.Reserve = function(count) { - for(var i = this.m_vertices.length;i < count;i++) { - this.m_vertices[i] = new b2Vec2; - this.m_normals[i] = new b2Vec2 - } -}; -b2PolygonShape.prototype.Copy = function() { - var s = new b2PolygonShape; - s.Set(this); - return s -}; -b2PolygonShape.prototype.Set = function(other) { - this._super.Set.apply(this, [other]); - if(isInstanceOf(other, b2PolygonShape)) { - var other2 = other; - this.m_centroid.SetV(other2.m_centroid); - this.m_vertexCount = other2.m_vertexCount; - this.Reserve(this.m_vertexCount); - for(var i = 0;i < this.m_vertexCount;i++) { - this.m_vertices[i].SetV(other2.m_vertices[i]); - this.m_normals[i].SetV(other2.m_normals[i]) - } - } -}; -b2PolygonShape.prototype.SetAsArray = function(vertices, vertexCount) { - var v = new Array; - for(var i = 0, tVec = null;i < vertices.length, tVec = vertices[i];i++) { - v.push(tVec) - } - this.SetAsVector(v, vertexCount) -}; -b2PolygonShape.prototype.SetAsVector = function(vertices, vertexCount) { - if(typeof vertexCount == "undefined") { - vertexCount = vertices.length - } - b2Settings.b2Assert(2 <= vertexCount); - this.m_vertexCount = vertexCount; - this.Reserve(vertexCount); - var i = 0; - for(i = 0;i < this.m_vertexCount;i++) { - this.m_vertices[i].SetV(vertices[i]) - } - for(i = 0;i < this.m_vertexCount;++i) { - var i1 = i; - var i2 = i + 1 < this.m_vertexCount ? i + 1 : 0; - var edge = b2Math.SubtractVV(this.m_vertices[i2], this.m_vertices[i1]); - b2Settings.b2Assert(edge.LengthSquared() > Number.MIN_VALUE); - this.m_normals[i].SetV(b2Math.CrossVF(edge, 1)); - this.m_normals[i].Normalize() - } - this.m_centroid = b2PolygonShape.ComputeCentroid(this.m_vertices, this.m_vertexCount) -}; -b2PolygonShape.prototype.SetAsBox = function(hx, hy) { - this.m_vertexCount = 4; - this.Reserve(4); - this.m_vertices[0].Set(-hx, -hy); - this.m_vertices[1].Set(hx, -hy); - this.m_vertices[2].Set(hx, hy); - this.m_vertices[3].Set(-hx, hy); - this.m_normals[0].Set(0, -1); - this.m_normals[1].Set(1, 0); - this.m_normals[2].Set(0, 1); - this.m_normals[3].Set(-1, 0); - this.m_centroid.SetZero() -}; -b2PolygonShape.prototype.SetAsOrientedBox = function(hx, hy, center, angle) { - this.m_vertexCount = 4; - this.Reserve(4); - this.m_vertices[0].Set(-hx, -hy); - this.m_vertices[1].Set(hx, -hy); - this.m_vertices[2].Set(hx, hy); - this.m_vertices[3].Set(-hx, hy); - this.m_normals[0].Set(0, -1); - this.m_normals[1].Set(1, 0); - this.m_normals[2].Set(0, 1); - this.m_normals[3].Set(-1, 0); - this.m_centroid = center; - var xf = new b2Transform; - xf.position = center; - xf.R.Set(angle); - for(var i = 0;i < this.m_vertexCount;++i) { - this.m_vertices[i] = b2Math.MulX(xf, this.m_vertices[i]); - this.m_normals[i] = b2Math.MulMV(xf.R, this.m_normals[i]) - } -}; -b2PolygonShape.prototype.SetAsEdge = function(v1, v2) { - this.m_vertexCount = 2; - this.Reserve(2); - this.m_vertices[0].SetV(v1); - this.m_vertices[1].SetV(v2); - this.m_centroid.x = 0.5 * (v1.x + v2.x); - this.m_centroid.y = 0.5 * (v1.y + v2.y); - this.m_normals[0] = b2Math.CrossVF(b2Math.SubtractVV(v2, v1), 1); - this.m_normals[0].Normalize(); - this.m_normals[1].x = -this.m_normals[0].x; - this.m_normals[1].y = -this.m_normals[0].y -}; -b2PolygonShape.prototype.TestPoint = function(xf, p) { - var tVec; - var tMat = xf.R; - var tX = p.x - xf.position.x; - var tY = p.y - xf.position.y; - var pLocalX = tX * tMat.col1.x + tY * tMat.col1.y; - var pLocalY = tX * tMat.col2.x + tY * tMat.col2.y; - for(var i = 0;i < this.m_vertexCount;++i) { - tVec = this.m_vertices[i]; - tX = pLocalX - tVec.x; - tY = pLocalY - tVec.y; - tVec = this.m_normals[i]; - var dot = tVec.x * tX + tVec.y * tY; - if(dot > 0) { - return false - } - } - return true -}; -b2PolygonShape.prototype.RayCast = function(output, input, transform) { - var lower = 0; - var upper = input.maxFraction; - var tX; - var tY; - var tMat; - var tVec; - tX = input.p1.x - transform.position.x; - tY = input.p1.y - transform.position.y; - tMat = transform.R; - var p1X = tX * tMat.col1.x + tY * tMat.col1.y; - var p1Y = tX * tMat.col2.x + tY * tMat.col2.y; - tX = input.p2.x - transform.position.x; - tY = input.p2.y - transform.position.y; - tMat = transform.R; - var p2X = tX * tMat.col1.x + tY * tMat.col1.y; - var p2Y = tX * tMat.col2.x + tY * tMat.col2.y; - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var index = -1; - for(var i = 0;i < this.m_vertexCount;++i) { - tVec = this.m_vertices[i]; - tX = tVec.x - p1X; - tY = tVec.y - p1Y; - tVec = this.m_normals[i]; - var numerator = tVec.x * tX + tVec.y * tY; - var denominator = tVec.x * dX + tVec.y * dY; - if(denominator == 0) { - if(numerator < 0) { - return false - } - }else { - if(denominator < 0 && numerator < lower * denominator) { - lower = numerator / denominator; - index = i - }else { - if(denominator > 0 && numerator < upper * denominator) { - upper = numerator / denominator - } - } - } - if(upper < lower - Number.MIN_VALUE) { - return false - } - } - if(index >= 0) { - output.fraction = lower; - tMat = transform.R; - tVec = this.m_normals[index]; - output.normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - output.normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - return true - } - return false -}; -b2PolygonShape.prototype.ComputeAABB = function(aabb, xf) { - var tMat = xf.R; - var tVec = this.m_vertices[0]; - var lowerX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var lowerY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var upperX = lowerX; - var upperY = lowerY; - for(var i = 1;i < this.m_vertexCount;++i) { - tVec = this.m_vertices[i]; - var vX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var vY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - lowerX = lowerX < vX ? lowerX : vX; - lowerY = lowerY < vY ? lowerY : vY; - upperX = upperX > vX ? upperX : vX; - upperY = upperY > vY ? upperY : vY - } - aabb.lowerBound.x = lowerX - this.m_radius; - aabb.lowerBound.y = lowerY - this.m_radius; - aabb.upperBound.x = upperX + this.m_radius; - aabb.upperBound.y = upperY + this.m_radius -}; -b2PolygonShape.prototype.ComputeMass = function(massData, density) { - if(this.m_vertexCount == 2) { - massData.center.x = 0.5 * (this.m_vertices[0].x + this.m_vertices[1].x); - massData.center.y = 0.5 * (this.m_vertices[0].y + this.m_vertices[1].y); - massData.mass = 0; - massData.I = 0; - return - } - var centerX = 0; - var centerY = 0; - var area = 0; - var I = 0; - var p1X = 0; - var p1Y = 0; - var k_inv3 = 1 / 3; - for(var i = 0;i < this.m_vertexCount;++i) { - var p2 = this.m_vertices[i]; - var p3 = i + 1 < this.m_vertexCount ? this.m_vertices[parseInt(i + 1)] : this.m_vertices[0]; - var e1X = p2.x - p1X; - var e1Y = p2.y - p1Y; - var e2X = p3.x - p1X; - var e2Y = p3.y - p1Y; - var D = e1X * e2Y - e1Y * e2X; - var triangleArea = 0.5 * D; - area += triangleArea; - centerX += triangleArea * k_inv3 * (p1X + p2.x + p3.x); - centerY += triangleArea * k_inv3 * (p1Y + p2.y + p3.y); - var px = p1X; - var py = p1Y; - var ex1 = e1X; - var ey1 = e1Y; - var ex2 = e2X; - var ey2 = e2Y; - var intx2 = k_inv3 * (0.25 * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5 * px * px; - var inty2 = k_inv3 * (0.25 * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5 * py * py; - I += D * (intx2 + inty2) - } - massData.mass = density * area; - centerX *= 1 / area; - centerY *= 1 / area; - massData.center.Set(centerX, centerY); - massData.I = density * I -}; -b2PolygonShape.prototype.ComputeSubmergedArea = function(normal, offset, xf, c) { - var normalL = b2Math.MulTMV(xf.R, normal); - var offsetL = offset - b2Math.Dot(normal, xf.position); - var depths = new Array; - var diveCount = 0; - var intoIndex = -1; - var outoIndex = -1; - var lastSubmerged = false; - var i = 0; - for(i = 0;i < this.m_vertexCount;++i) { - depths[i] = b2Math.Dot(normalL, this.m_vertices[i]) - offsetL; - var isSubmerged = depths[i] < -Number.MIN_VALUE; - if(i > 0) { - if(isSubmerged) { - if(!lastSubmerged) { - intoIndex = i - 1; - diveCount++ - } - }else { - if(lastSubmerged) { - outoIndex = i - 1; - diveCount++ - } - } - } - lastSubmerged = isSubmerged - } - switch(diveCount) { - case 0: - if(lastSubmerged) { - var md = new b2MassData; - this.ComputeMass(md, 1); - c.SetV(b2Math.MulX(xf, md.center)); - return md.mass - }else { - return 0 - } - break; - case 1: - if(intoIndex == -1) { - intoIndex = this.m_vertexCount - 1 - }else { - outoIndex = this.m_vertexCount - 1 - } - break - } - var intoIndex2 = (intoIndex + 1) % this.m_vertexCount; - var outoIndex2 = (outoIndex + 1) % this.m_vertexCount; - var intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]); - var outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]); - var intoVec = new b2Vec2(this.m_vertices[intoIndex].x * (1 - intoLamdda) + this.m_vertices[intoIndex2].x * intoLamdda, this.m_vertices[intoIndex].y * (1 - intoLamdda) + this.m_vertices[intoIndex2].y * intoLamdda); - var outoVec = new b2Vec2(this.m_vertices[outoIndex].x * (1 - outoLamdda) + this.m_vertices[outoIndex2].x * outoLamdda, this.m_vertices[outoIndex].y * (1 - outoLamdda) + this.m_vertices[outoIndex2].y * outoLamdda); - var area = 0; - var center = new b2Vec2; - var p2 = this.m_vertices[intoIndex2]; - var p3; - i = intoIndex2; - while(i != outoIndex2) { - i = (i + 1) % this.m_vertexCount; - if(i == outoIndex2) { - p3 = outoVec - }else { - p3 = this.m_vertices[i] - } - var triangleArea = 0.5 * ((p2.x - intoVec.x) * (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x)); - area += triangleArea; - center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3; - center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3; - p2 = p3 - } - center.Multiply(1 / area); - c.SetV(b2Math.MulX(xf, center)); - return area -}; -b2PolygonShape.prototype.GetVertexCount = function() { - return this.m_vertexCount -}; -b2PolygonShape.prototype.GetVertices = function() { - return this.m_vertices -}; -b2PolygonShape.prototype.GetNormals = function() { - return this.m_normals -}; -b2PolygonShape.prototype.GetSupport = function(d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for(var i = 1;i < this.m_vertexCount;++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if(value > bestValue) { - bestIndex = i; - bestValue = value - } - } - return bestIndex -}; -b2PolygonShape.prototype.GetSupportVertex = function(d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for(var i = 1;i < this.m_vertexCount;++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if(value > bestValue) { - bestIndex = i; - bestValue = value - } - } - return this.m_vertices[bestIndex] -}; -b2PolygonShape.prototype.m_centroid = null; -b2PolygonShape.prototype.m_vertices = null; -b2PolygonShape.prototype.m_normals = null; -b2PolygonShape.prototype.m_vertexCount = 0;var b2Fixture = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Fixture.prototype.__constructor = function() { - this.m_aabb = new b2AABB; - this.m_userData = null; - this.m_body = null; - this.m_next = null; - this.m_shape = null; - this.m_density = 0; - this.m_friction = 0; - this.m_restitution = 0 -}; -b2Fixture.prototype.__varz = function() { - this.m_filter = new b2FilterData -}; -b2Fixture.prototype.Create = function(body, xf, def) { - this.m_userData = def.userData; - this.m_friction = def.friction; - this.m_restitution = def.restitution; - this.m_body = body; - this.m_next = null; - this.m_filter = def.filter.Copy(); - this.m_isSensor = def.isSensor; - this.m_shape = def.shape.Copy(); - this.m_density = def.density -}; -b2Fixture.prototype.Destroy = function() { - this.m_shape = null -}; -b2Fixture.prototype.CreateProxy = function(broadPhase, xf) { - this.m_shape.ComputeAABB(this.m_aabb, xf); - this.m_proxy = broadPhase.CreateProxy(this.m_aabb, this) -}; -b2Fixture.prototype.DestroyProxy = function(broadPhase) { - if(this.m_proxy == null) { - return - } - broadPhase.DestroyProxy(this.m_proxy); - this.m_proxy = null -}; -b2Fixture.prototype.Synchronize = function(broadPhase, transform1, transform2) { - if(!this.m_proxy) { - return - } - var aabb1 = new b2AABB; - var aabb2 = new b2AABB; - this.m_shape.ComputeAABB(aabb1, transform1); - this.m_shape.ComputeAABB(aabb2, transform2); - this.m_aabb.Combine(aabb1, aabb2); - var displacement = b2Math.SubtractVV(transform2.position, transform1.position); - broadPhase.MoveProxy(this.m_proxy, this.m_aabb, displacement) -}; -b2Fixture.prototype.GetType = function() { - return this.m_shape.GetType() -}; -b2Fixture.prototype.GetShape = function() { - return this.m_shape -}; -b2Fixture.prototype.SetSensor = function(sensor) { - if(this.m_isSensor == sensor) { - return - } - this.m_isSensor = sensor; - if(this.m_body == null) { - return - } - var edge = this.m_body.GetContactList(); - while(edge) { - var contact = edge.contact; - var fixtureA = contact.GetFixtureA(); - var fixtureB = contact.GetFixtureB(); - if(fixtureA == this || fixtureB == this) { - contact.SetSensor(fixtureA.IsSensor() || fixtureB.IsSensor()) - } - edge = edge.next - } -}; -b2Fixture.prototype.IsSensor = function() { - return this.m_isSensor -}; -b2Fixture.prototype.SetFilterData = function(filter) { - this.m_filter = filter.Copy(); - if(this.m_body) { - return - } - var edge = this.m_body.GetContactList(); - while(edge) { - var contact = edge.contact; - var fixtureA = contact.GetFixtureA(); - var fixtureB = contact.GetFixtureB(); - if(fixtureA == this || fixtureB == this) { - contact.FlagForFiltering() - } - edge = edge.next - } -}; -b2Fixture.prototype.GetFilterData = function() { - return this.m_filter.Copy() -}; -b2Fixture.prototype.GetBody = function() { - return this.m_body -}; -b2Fixture.prototype.GetNext = function() { - return this.m_next -}; -b2Fixture.prototype.GetUserData = function() { - return this.m_userData -}; -b2Fixture.prototype.SetUserData = function(data) { - this.m_userData = data -}; -b2Fixture.prototype.TestPoint = function(p) { - return this.m_shape.TestPoint(this.m_body.GetTransform(), p) -}; -b2Fixture.prototype.RayCast = function(output, input) { - return this.m_shape.RayCast(output, input, this.m_body.GetTransform()) -}; -b2Fixture.prototype.GetMassData = function(massData) { - if(massData == null) { - massData = new b2MassData - } - this.m_shape.ComputeMass(massData, this.m_density); - return massData -}; -b2Fixture.prototype.SetDensity = function(density) { - this.m_density = density -}; -b2Fixture.prototype.GetDensity = function() { - return this.m_density -}; -b2Fixture.prototype.GetFriction = function() { - return this.m_friction -}; -b2Fixture.prototype.SetFriction = function(friction) { - this.m_friction = friction -}; -b2Fixture.prototype.GetRestitution = function() { - return this.m_restitution -}; -b2Fixture.prototype.SetRestitution = function(restitution) { - this.m_restitution = restitution -}; -b2Fixture.prototype.GetAABB = function() { - return this.m_aabb -}; -b2Fixture.prototype.m_massData = null; -b2Fixture.prototype.m_aabb = null; -b2Fixture.prototype.m_density = null; -b2Fixture.prototype.m_next = null; -b2Fixture.prototype.m_body = null; -b2Fixture.prototype.m_shape = null; -b2Fixture.prototype.m_friction = null; -b2Fixture.prototype.m_restitution = null; -b2Fixture.prototype.m_proxy = null; -b2Fixture.prototype.m_filter = new b2FilterData; -b2Fixture.prototype.m_isSensor = null; -b2Fixture.prototype.m_userData = null;var b2DynamicTreeNode = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2DynamicTreeNode.prototype.__constructor = function() { -}; -b2DynamicTreeNode.prototype.__varz = function() { - this.aabb = new b2AABB -}; -b2DynamicTreeNode.prototype.IsLeaf = function() { - return this.child1 == null -}; -b2DynamicTreeNode.prototype.userData = null; -b2DynamicTreeNode.prototype.aabb = new b2AABB; -b2DynamicTreeNode.prototype.parent = null; -b2DynamicTreeNode.prototype.child1 = null; -b2DynamicTreeNode.prototype.child2 = null;var b2BodyDef = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2BodyDef.prototype.__constructor = function() { - this.userData = null; - this.position.Set(0, 0); - this.angle = 0; - this.linearVelocity.Set(0, 0); - this.angularVelocity = 0; - this.linearDamping = 0; - this.angularDamping = 0; - this.allowSleep = true; - this.awake = true; - this.fixedRotation = false; - this.bullet = false; - this.type = b2Body.b2_staticBody; - this.active = true; - this.inertiaScale = 1 -}; -b2BodyDef.prototype.__varz = function() { - this.position = new b2Vec2; - this.linearVelocity = new b2Vec2 -}; -b2BodyDef.prototype.type = 0; -b2BodyDef.prototype.position = new b2Vec2; -b2BodyDef.prototype.angle = null; -b2BodyDef.prototype.linearVelocity = new b2Vec2; -b2BodyDef.prototype.angularVelocity = null; -b2BodyDef.prototype.linearDamping = null; -b2BodyDef.prototype.angularDamping = null; -b2BodyDef.prototype.allowSleep = null; -b2BodyDef.prototype.awake = null; -b2BodyDef.prototype.fixedRotation = null; -b2BodyDef.prototype.bullet = null; -b2BodyDef.prototype.active = null; -b2BodyDef.prototype.userData = null; -b2BodyDef.prototype.inertiaScale = null;var b2DynamicTreeBroadPhase = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2DynamicTreeBroadPhase.prototype.__constructor = function() { -}; -b2DynamicTreeBroadPhase.prototype.__varz = function() { - this.m_tree = new b2DynamicTree; - this.m_moveBuffer = new Array; - this.m_pairBuffer = new Array -}; -b2DynamicTreeBroadPhase.prototype.BufferMove = function(proxy) { - this.m_moveBuffer[this.m_moveBuffer.length] = proxy -}; -b2DynamicTreeBroadPhase.prototype.UnBufferMove = function(proxy) { - var i = this.m_moveBuffer.indexOf(proxy); - this.m_moveBuffer.splice(i, 1) -}; -b2DynamicTreeBroadPhase.prototype.ComparePairs = function(pair1, pair2) { - return 0 -}; -b2DynamicTreeBroadPhase.prototype.CreateProxy = function(aabb, userData) { - var proxy = this.m_tree.CreateProxy(aabb, userData); - ++this.m_proxyCount; - this.BufferMove(proxy); - return proxy -}; -b2DynamicTreeBroadPhase.prototype.DestroyProxy = function(proxy) { - this.UnBufferMove(proxy); - --this.m_proxyCount; - this.m_tree.DestroyProxy(proxy) -}; -b2DynamicTreeBroadPhase.prototype.MoveProxy = function(proxy, aabb, displacement) { - var buffer = this.m_tree.MoveProxy(proxy, aabb, displacement); - if(buffer) { - this.BufferMove(proxy) - } -}; -b2DynamicTreeBroadPhase.prototype.TestOverlap = function(proxyA, proxyB) { - var aabbA = this.m_tree.GetFatAABB(proxyA); - var aabbB = this.m_tree.GetFatAABB(proxyB); - return aabbA.TestOverlap(aabbB) -}; -b2DynamicTreeBroadPhase.prototype.GetUserData = function(proxy) { - return this.m_tree.GetUserData(proxy) -}; -b2DynamicTreeBroadPhase.prototype.GetFatAABB = function(proxy) { - return this.m_tree.GetFatAABB(proxy) -}; -b2DynamicTreeBroadPhase.prototype.GetProxyCount = function() { - return this.m_proxyCount -}; -b2DynamicTreeBroadPhase.prototype.UpdatePairs = function(callback) { - this.m_pairCount = 0; - for(var i = 0, queryProxy = null;i < this.m_moveBuffer.length, queryProxy = this.m_moveBuffer[i];i++) { - var that = this; - function QueryCallback(proxy) { - if(proxy == queryProxy) { - return true - } - if(that.m_pairCount == that.m_pairBuffer.length) { - that.m_pairBuffer[that.m_pairCount] = new b2DynamicTreePair - } - var pair = that.m_pairBuffer[that.m_pairCount]; - pair.proxyA = proxy < queryProxy ? proxy : queryProxy; - pair.proxyB = proxy >= queryProxy ? proxy : queryProxy; - ++that.m_pairCount; - return true - } - var fatAABB = this.m_tree.GetFatAABB(queryProxy); - this.m_tree.Query(QueryCallback, fatAABB) - } - this.m_moveBuffer.length = 0; - for(var i = 0;i < this.m_pairCount;) { - var primaryPair = this.m_pairBuffer[i]; - var userDataA = this.m_tree.GetUserData(primaryPair.proxyA); - var userDataB = this.m_tree.GetUserData(primaryPair.proxyB); - callback(userDataA, userDataB); - ++i; - while(i < this.m_pairCount) { - var pair = this.m_pairBuffer[i]; - if(pair.proxyA != primaryPair.proxyA || pair.proxyB != primaryPair.proxyB) { - break - } - ++i - } - } -}; -b2DynamicTreeBroadPhase.prototype.Query = function(callback, aabb) { - this.m_tree.Query(callback, aabb) -}; -b2DynamicTreeBroadPhase.prototype.RayCast = function(callback, input) { - this.m_tree.RayCast(callback, input) -}; -b2DynamicTreeBroadPhase.prototype.Validate = function() { -}; -b2DynamicTreeBroadPhase.prototype.Rebalance = function(iterations) { - this.m_tree.Rebalance(iterations) -}; -b2DynamicTreeBroadPhase.prototype.m_tree = new b2DynamicTree; -b2DynamicTreeBroadPhase.prototype.m_proxyCount = 0; -b2DynamicTreeBroadPhase.prototype.m_moveBuffer = new Array; -b2DynamicTreeBroadPhase.prototype.m_pairBuffer = new Array; -b2DynamicTreeBroadPhase.prototype.m_pairCount = 0;var b2BroadPhase = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2BroadPhase.prototype.__constructor = function(worldAABB) { - var i = 0; - this.m_pairManager.Initialize(this); - this.m_worldAABB = worldAABB; - this.m_proxyCount = 0; - this.m_bounds = new Array; - for(i = 0;i < 2;i++) { - this.m_bounds[i] = new Array - } - var dX = worldAABB.upperBound.x - worldAABB.lowerBound.x; - var dY = worldAABB.upperBound.y - worldAABB.lowerBound.y; - this.m_quantizationFactor.x = b2Settings.USHRT_MAX / dX; - this.m_quantizationFactor.y = b2Settings.USHRT_MAX / dY; - this.m_timeStamp = 1; - this.m_queryResultCount = 0 -}; -b2BroadPhase.prototype.__varz = function() { - this.m_pairManager = new b2PairManager; - this.m_proxyPool = new Array; - this.m_querySortKeys = new Array; - this.m_queryResults = new Array; - this.m_quantizationFactor = new b2Vec2 -}; -b2BroadPhase.BinarySearch = function(bounds, count, value) { - var low = 0; - var high = count - 1; - while(low <= high) { - var mid = Math.round((low + high) / 2); - var bound = bounds[mid]; - if(bound.value > value) { - high = mid - 1 - }else { - if(bound.value < value) { - low = mid + 1 - }else { - return parseInt(mid) - } - } - } - return parseInt(low) -}; -b2BroadPhase.s_validate = false; -b2BroadPhase.b2_invalid = b2Settings.USHRT_MAX; -b2BroadPhase.b2_nullEdge = b2Settings.USHRT_MAX; -b2BroadPhase.prototype.ComputeBounds = function(lowerValues, upperValues, aabb) { - var minVertexX = aabb.lowerBound.x; - var minVertexY = aabb.lowerBound.y; - minVertexX = b2Math.Min(minVertexX, this.m_worldAABB.upperBound.x); - minVertexY = b2Math.Min(minVertexY, this.m_worldAABB.upperBound.y); - minVertexX = b2Math.Max(minVertexX, this.m_worldAABB.lowerBound.x); - minVertexY = b2Math.Max(minVertexY, this.m_worldAABB.lowerBound.y); - var maxVertexX = aabb.upperBound.x; - var maxVertexY = aabb.upperBound.y; - maxVertexX = b2Math.Min(maxVertexX, this.m_worldAABB.upperBound.x); - maxVertexY = b2Math.Min(maxVertexY, this.m_worldAABB.upperBound.y); - maxVertexX = b2Math.Max(maxVertexX, this.m_worldAABB.lowerBound.x); - maxVertexY = b2Math.Max(maxVertexY, this.m_worldAABB.lowerBound.y); - lowerValues[0] = parseInt(this.m_quantizationFactor.x * (minVertexX - this.m_worldAABB.lowerBound.x)) & b2Settings.USHRT_MAX - 1; - upperValues[0] = parseInt(this.m_quantizationFactor.x * (maxVertexX - this.m_worldAABB.lowerBound.x)) % 65535 | 1; - lowerValues[1] = parseInt(this.m_quantizationFactor.y * (minVertexY - this.m_worldAABB.lowerBound.y)) & b2Settings.USHRT_MAX - 1; - upperValues[1] = parseInt(this.m_quantizationFactor.y * (maxVertexY - this.m_worldAABB.lowerBound.y)) % 65535 | 1 -}; -b2BroadPhase.prototype.TestOverlapValidate = function(p1, p2) { - for(var axis = 0;axis < 2;++axis) { - var bounds = this.m_bounds[axis]; - var bound1 = bounds[p1.lowerBounds[axis]]; - var bound2 = bounds[p2.upperBounds[axis]]; - if(bound1.value > bound2.value) { - return false - } - bound1 = bounds[p1.upperBounds[axis]]; - bound2 = bounds[p2.lowerBounds[axis]]; - if(bound1.value < bound2.value) { - return false - } - } - return true -}; -b2BroadPhase.prototype.QueryAxis = function(lowerQueryOut, upperQueryOut, lowerValue, upperValue, bounds, boundCount, axis) { - var lowerQuery = b2BroadPhase.BinarySearch(bounds, boundCount, lowerValue); - var upperQuery = b2BroadPhase.BinarySearch(bounds, boundCount, upperValue); - var bound; - for(var j = lowerQuery;j < upperQuery;++j) { - bound = bounds[j]; - if(bound.IsLower()) { - this.IncrementOverlapCount(bound.proxy) - } - } - if(lowerQuery > 0) { - var i = lowerQuery - 1; - bound = bounds[i]; - var s = bound.stabbingCount; - while(s) { - bound = bounds[i]; - if(bound.IsLower()) { - var proxy = bound.proxy; - if(lowerQuery <= proxy.upperBounds[axis]) { - this.IncrementOverlapCount(bound.proxy); - --s - } - } - --i - } - } - lowerQueryOut[0] = lowerQuery; - upperQueryOut[0] = upperQuery -}; -b2BroadPhase.prototype.IncrementOverlapCount = function(proxy) { - if(proxy.timeStamp < this.m_timeStamp) { - proxy.timeStamp = this.m_timeStamp; - proxy.overlapCount = 1 - }else { - proxy.overlapCount = 2; - this.m_queryResults[this.m_queryResultCount] = proxy; - ++this.m_queryResultCount - } -}; -b2BroadPhase.prototype.IncrementTimeStamp = function() { - if(this.m_timeStamp == b2Settings.USHRT_MAX) { - for(var i = 0;i < this.m_proxyPool.length;++i) { - this.m_proxyPool[i].timeStamp = 0 - } - this.m_timeStamp = 1 - }else { - ++this.m_timeStamp - } -}; -b2BroadPhase.prototype.InRange = function(aabb) { - var dX; - var dY; - var d2X; - var d2Y; - dX = aabb.lowerBound.x; - dY = aabb.lowerBound.y; - dX -= this.m_worldAABB.upperBound.x; - dY -= this.m_worldAABB.upperBound.y; - d2X = this.m_worldAABB.lowerBound.x; - d2Y = this.m_worldAABB.lowerBound.y; - d2X -= aabb.upperBound.x; - d2Y -= aabb.upperBound.y; - dX = b2Math.Max(dX, d2X); - dY = b2Math.Max(dY, d2Y); - return b2Math.Max(dX, dY) < 0 -}; -b2BroadPhase.prototype.CreateProxy = function(aabb, userData) { - var index = 0; - var proxy; - var i = 0; - var j = 0; - if(!this.m_freeProxy) { - this.m_freeProxy = this.m_proxyPool[this.m_proxyCount] = new b2Proxy; - this.m_freeProxy.next = null; - this.m_freeProxy.timeStamp = 0; - this.m_freeProxy.overlapCount = b2BroadPhase.b2_invalid; - this.m_freeProxy.userData = null; - for(i = 0;i < 2;i++) { - j = this.m_proxyCount * 2; - this.m_bounds[i][j++] = new b2Bound; - this.m_bounds[i][j] = new b2Bound - } - } - proxy = this.m_freeProxy; - this.m_freeProxy = proxy.next; - proxy.overlapCount = 0; - proxy.userData = userData; - var boundCount = 2 * this.m_proxyCount; - var lowerValues = new Array; - var upperValues = new Array; - this.ComputeBounds(lowerValues, upperValues, aabb); - for(var axis = 0;axis < 2;++axis) { - var bounds = this.m_bounds[axis]; - var lowerIndex = 0; - var upperIndex = 0; - var lowerIndexOut = new Array; - lowerIndexOut.push(lowerIndex); - var upperIndexOut = new Array; - upperIndexOut.push(upperIndex); - this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[axis], upperValues[axis], bounds, boundCount, axis); - lowerIndex = lowerIndexOut[0]; - upperIndex = upperIndexOut[0]; - bounds.splice(upperIndex, 0, bounds[bounds.length - 1]); - bounds.length--; - bounds.splice(lowerIndex, 0, bounds[bounds.length - 1]); - bounds.length--; - ++upperIndex; - var tBound1 = bounds[lowerIndex]; - var tBound2 = bounds[upperIndex]; - tBound1.value = lowerValues[axis]; - tBound1.proxy = proxy; - tBound2.value = upperValues[axis]; - tBound2.proxy = proxy; - var tBoundAS3 = bounds[parseInt(lowerIndex - 1)]; - tBound1.stabbingCount = lowerIndex == 0 ? 0 : tBoundAS3.stabbingCount; - tBoundAS3 = bounds[parseInt(upperIndex - 1)]; - tBound2.stabbingCount = tBoundAS3.stabbingCount; - for(index = lowerIndex;index < upperIndex;++index) { - tBoundAS3 = bounds[index]; - tBoundAS3.stabbingCount++ - } - for(index = lowerIndex;index < boundCount + 2;++index) { - tBound1 = bounds[index]; - var proxy2 = tBound1.proxy; - if(tBound1.IsLower()) { - proxy2.lowerBounds[axis] = index - }else { - proxy2.upperBounds[axis] = index - } - } - } - ++this.m_proxyCount; - for(i = 0;i < this.m_queryResultCount;++i) { - this.m_pairManager.AddBufferedPair(proxy, this.m_queryResults[i]) - } - this.m_queryResultCount = 0; - this.IncrementTimeStamp(); - return proxy -}; -b2BroadPhase.prototype.DestroyProxy = function(proxy_) { - var proxy = proxy_; - var tBound1; - var tBound2; - var boundCount = 2 * this.m_proxyCount; - for(var axis = 0;axis < 2;++axis) { - var bounds = this.m_bounds[axis]; - var lowerIndex = proxy.lowerBounds[axis]; - var upperIndex = proxy.upperBounds[axis]; - tBound1 = bounds[lowerIndex]; - var lowerValue = tBound1.value; - tBound2 = bounds[upperIndex]; - var upperValue = tBound2.value; - bounds.splice(upperIndex, 1); - bounds.splice(lowerIndex, 1); - bounds.push(tBound1); - bounds.push(tBound2); - var tEnd = boundCount - 2; - for(var index = lowerIndex;index < tEnd;++index) { - tBound1 = bounds[index]; - var proxy2 = tBound1.proxy; - if(tBound1.IsLower()) { - proxy2.lowerBounds[axis] = index - }else { - proxy2.upperBounds[axis] = index - } - } - tEnd = upperIndex - 1; - for(var index2 = lowerIndex;index2 < tEnd;++index2) { - tBound1 = bounds[index2]; - tBound1.stabbingCount-- - } - var ignore = new Array; - this.QueryAxis(ignore, ignore, lowerValue, upperValue, bounds, boundCount - 2, axis) - } - for(var i = 0;i < this.m_queryResultCount;++i) { - this.m_pairManager.RemoveBufferedPair(proxy, this.m_queryResults[i]) - } - this.m_queryResultCount = 0; - this.IncrementTimeStamp(); - proxy.userData = null; - proxy.overlapCount = b2BroadPhase.b2_invalid; - proxy.lowerBounds[0] = b2BroadPhase.b2_invalid; - proxy.lowerBounds[1] = b2BroadPhase.b2_invalid; - proxy.upperBounds[0] = b2BroadPhase.b2_invalid; - proxy.upperBounds[1] = b2BroadPhase.b2_invalid; - proxy.next = this.m_freeProxy; - this.m_freeProxy = proxy; - --this.m_proxyCount -}; -b2BroadPhase.prototype.MoveProxy = function(proxy_, aabb, displacement) { - var proxy = proxy_; - var as3arr; - var as3int = 0; - var axis = 0; - var index = 0; - var bound; - var prevBound; - var nextBound; - var nextProxyId = 0; - var nextProxy; - if(proxy == null) { - return - } - if(aabb.IsValid() == false) { - return - } - var boundCount = 2 * this.m_proxyCount; - var newValues = new b2BoundValues; - this.ComputeBounds(newValues.lowerValues, newValues.upperValues, aabb); - var oldValues = new b2BoundValues; - for(axis = 0;axis < 2;++axis) { - bound = this.m_bounds[axis][proxy.lowerBounds[axis]]; - oldValues.lowerValues[axis] = bound.value; - bound = this.m_bounds[axis][proxy.upperBounds[axis]]; - oldValues.upperValues[axis] = bound.value - } - for(axis = 0;axis < 2;++axis) { - var bounds = this.m_bounds[axis]; - var lowerIndex = proxy.lowerBounds[axis]; - var upperIndex = proxy.upperBounds[axis]; - var lowerValue = newValues.lowerValues[axis]; - var upperValue = newValues.upperValues[axis]; - bound = bounds[lowerIndex]; - var deltaLower = lowerValue - bound.value; - bound.value = lowerValue; - bound = bounds[upperIndex]; - var deltaUpper = upperValue - bound.value; - bound.value = upperValue; - if(deltaLower < 0) { - index = lowerIndex; - while(index > 0 && lowerValue < bounds[parseInt(index - 1)].value) { - bound = bounds[index]; - prevBound = bounds[parseInt(index - 1)]; - var prevProxy = prevBound.proxy; - prevBound.stabbingCount++; - if(prevBound.IsUpper() == true) { - if(this.TestOverlapBound(newValues, prevProxy)) { - this.m_pairManager.AddBufferedPair(proxy, prevProxy) - } - as3arr = prevProxy.upperBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.stabbingCount++ - }else { - as3arr = prevProxy.lowerBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.stabbingCount-- - } - as3arr = proxy.lowerBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.Swap(prevBound); - --index - } - } - if(deltaUpper > 0) { - index = upperIndex; - while(index < boundCount - 1 && bounds[parseInt(index + 1)].value <= upperValue) { - bound = bounds[index]; - nextBound = bounds[parseInt(index + 1)]; - nextProxy = nextBound.proxy; - nextBound.stabbingCount++; - if(nextBound.IsLower() == true) { - if(this.TestOverlapBound(newValues, nextProxy)) { - this.m_pairManager.AddBufferedPair(proxy, nextProxy) - } - as3arr = nextProxy.lowerBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.stabbingCount++ - }else { - as3arr = nextProxy.upperBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.stabbingCount-- - } - as3arr = proxy.upperBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.Swap(nextBound); - index++ - } - } - if(deltaLower > 0) { - index = lowerIndex; - while(index < boundCount - 1 && bounds[parseInt(index + 1)].value <= lowerValue) { - bound = bounds[index]; - nextBound = bounds[parseInt(index + 1)]; - nextProxy = nextBound.proxy; - nextBound.stabbingCount--; - if(nextBound.IsUpper()) { - if(this.TestOverlapBound(oldValues, nextProxy)) { - this.m_pairManager.RemoveBufferedPair(proxy, nextProxy) - } - as3arr = nextProxy.upperBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.stabbingCount-- - }else { - as3arr = nextProxy.lowerBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.stabbingCount++ - } - as3arr = proxy.lowerBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.Swap(nextBound); - index++ - } - } - if(deltaUpper < 0) { - index = upperIndex; - while(index > 0 && upperValue < bounds[parseInt(index - 1)].value) { - bound = bounds[index]; - prevBound = bounds[parseInt(index - 1)]; - prevProxy = prevBound.proxy; - prevBound.stabbingCount--; - if(prevBound.IsLower() == true) { - if(this.TestOverlapBound(oldValues, prevProxy)) { - this.m_pairManager.RemoveBufferedPair(proxy, prevProxy) - } - as3arr = prevProxy.lowerBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.stabbingCount-- - }else { - as3arr = prevProxy.upperBounds; - as3int = as3arr[axis]; - as3int++; - as3arr[axis] = as3int; - bound.stabbingCount++ - } - as3arr = proxy.upperBounds; - as3int = as3arr[axis]; - as3int--; - as3arr[axis] = as3int; - bound.Swap(prevBound); - index-- - } - } - } -}; -b2BroadPhase.prototype.UpdatePairs = function(callback) { - this.m_pairManager.Commit(callback) -}; -b2BroadPhase.prototype.TestOverlap = function(proxyA, proxyB) { - var proxyA_ = proxyA; - var proxyB_ = proxyB; - if(proxyA_.lowerBounds[0] > proxyB_.upperBounds[0]) { - return false - } - if(proxyB_.lowerBounds[0] > proxyA_.upperBounds[0]) { - return false - } - if(proxyA_.lowerBounds[1] > proxyB_.upperBounds[1]) { - return false - } - if(proxyB_.lowerBounds[1] > proxyA_.upperBounds[1]) { - return false - } - return true -}; -b2BroadPhase.prototype.GetUserData = function(proxy) { - return proxy.userData -}; -b2BroadPhase.prototype.GetFatAABB = function(proxy_) { - var aabb = new b2AABB; - var proxy = proxy_; - aabb.lowerBound.x = this.m_worldAABB.lowerBound.x + this.m_bounds[0][proxy.lowerBounds[0]].value / this.m_quantizationFactor.x; - aabb.lowerBound.y = this.m_worldAABB.lowerBound.y + this.m_bounds[1][proxy.lowerBounds[1]].value / this.m_quantizationFactor.y; - aabb.upperBound.x = this.m_worldAABB.lowerBound.x + this.m_bounds[0][proxy.upperBounds[0]].value / this.m_quantizationFactor.x; - aabb.upperBound.y = this.m_worldAABB.lowerBound.y + this.m_bounds[1][proxy.upperBounds[1]].value / this.m_quantizationFactor.y; - return aabb -}; -b2BroadPhase.prototype.GetProxyCount = function() { - return this.m_proxyCount -}; -b2BroadPhase.prototype.Query = function(callback, aabb) { - var lowerValues = new Array; - var upperValues = new Array; - this.ComputeBounds(lowerValues, upperValues, aabb); - var lowerIndex = 0; - var upperIndex = 0; - var lowerIndexOut = new Array; - lowerIndexOut.push(lowerIndex); - var upperIndexOut = new Array; - upperIndexOut.push(upperIndex); - this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[0], upperValues[0], this.m_bounds[0], 2 * this.m_proxyCount, 0); - this.QueryAxis(lowerIndexOut, upperIndexOut, lowerValues[1], upperValues[1], this.m_bounds[1], 2 * this.m_proxyCount, 1); - for(var i = 0;i < this.m_queryResultCount;++i) { - var proxy = this.m_queryResults[i]; - if(!callback(proxy)) { - break - } - } - this.m_queryResultCount = 0; - this.IncrementTimeStamp() -}; -b2BroadPhase.prototype.Validate = function() { - var pair; - var proxy1; - var proxy2; - var overlap; - for(var axis = 0;axis < 2;++axis) { - var bounds = this.m_bounds[axis]; - var boundCount = 2 * this.m_proxyCount; - var stabbingCount = 0; - for(var i = 0;i < boundCount;++i) { - var bound = bounds[i]; - if(bound.IsLower() == true) { - stabbingCount++ - }else { - stabbingCount-- - } - } - } -}; -b2BroadPhase.prototype.Rebalance = function(iterations) { -}; -b2BroadPhase.prototype.RayCast = function(callback, input) { - var subInput = new b2RayCastInput; - subInput.p1.SetV(input.p1); - subInput.p2.SetV(input.p2); - subInput.maxFraction = input.maxFraction; - var dx = (input.p2.x - input.p1.x) * this.m_quantizationFactor.x; - var dy = (input.p2.y - input.p1.y) * this.m_quantizationFactor.y; - var sx = dx < -Number.MIN_VALUE ? -1 : dx > Number.MIN_VALUE ? 1 : 0; - var sy = dy < -Number.MIN_VALUE ? -1 : dy > Number.MIN_VALUE ? 1 : 0; - var p1x = this.m_quantizationFactor.x * (input.p1.x - this.m_worldAABB.lowerBound.x); - var p1y = this.m_quantizationFactor.y * (input.p1.y - this.m_worldAABB.lowerBound.y); - var startValues = new Array; - var startValues2 = new Array; - startValues[0] = parseInt(p1x) & b2Settings.USHRT_MAX - 1; - startValues[1] = parseInt(p1y) & b2Settings.USHRT_MAX - 1; - startValues2[0] = startValues[0] + 1; - startValues2[1] = startValues[1] + 1; - var startIndices = new Array; - var xIndex = 0; - var yIndex = 0; - var proxy; - var lowerIndex = 0; - var upperIndex = 0; - var lowerIndexOut = new Array; - lowerIndexOut.push(lowerIndex); - var upperIndexOut = new Array; - upperIndexOut.push(upperIndex); - this.QueryAxis(lowerIndexOut, upperIndexOut, startValues[0], startValues2[0], this.m_bounds[0], 2 * this.m_proxyCount, 0); - if(sx >= 0) { - xIndex = upperIndexOut[0] - 1 - }else { - xIndex = lowerIndexOut[0] - } - this.QueryAxis(lowerIndexOut, upperIndexOut, startValues[1], startValues2[1], this.m_bounds[1], 2 * this.m_proxyCount, 1); - if(sy >= 0) { - yIndex = upperIndexOut[0] - 1 - }else { - yIndex = lowerIndexOut[0] - } - for(var i = 0;i < this.m_queryResultCount;i++) { - subInput.maxFraction = callback(this.m_queryResults[i], subInput) - } - for(;;) { - var xProgress = 0; - var yProgress = 0; - xIndex += sx >= 0 ? 1 : -1; - if(xIndex < 0 || xIndex >= this.m_proxyCount * 2) { - break - } - if(sx != 0) { - xProgress = (this.m_bounds[0][xIndex].value - p1x) / dx - } - yIndex += sy >= 0 ? 1 : -1; - if(yIndex < 0 || yIndex >= this.m_proxyCount * 2) { - break - } - if(sy != 0) { - yProgress = (this.m_bounds[1][yIndex].value - p1y) / dy - } - for(;;) { - if(sy == 0 || sx != 0 && xProgress < yProgress) { - if(xProgress > subInput.maxFraction) { - break - } - if(sx > 0 ? this.m_bounds[0][xIndex].IsLower() : this.m_bounds[0][xIndex].IsUpper()) { - proxy = this.m_bounds[0][xIndex].proxy; - if(sy >= 0) { - if(proxy.lowerBounds[1] <= yIndex - 1 && proxy.upperBounds[1] >= yIndex) { - subInput.maxFraction = callback(proxy, subInput) - } - }else { - if(proxy.lowerBounds[1] <= yIndex && proxy.upperBounds[1] >= yIndex + 1) { - subInput.maxFraction = callback(proxy, subInput) - } - } - } - if(subInput.maxFraction == 0) { - break - } - if(sx > 0) { - xIndex++; - if(xIndex == this.m_proxyCount * 2) { - break - } - }else { - xIndex--; - if(xIndex < 0) { - break - } - } - xProgress = (this.m_bounds[0][xIndex].value - p1x) / dx - }else { - if(yProgress > subInput.maxFraction) { - break - } - if(sy > 0 ? this.m_bounds[1][yIndex].IsLower() : this.m_bounds[1][yIndex].IsUpper()) { - proxy = this.m_bounds[1][yIndex].proxy; - if(sx >= 0) { - if(proxy.lowerBounds[0] <= xIndex - 1 && proxy.upperBounds[0] >= xIndex) { - subInput.maxFraction = callback(proxy, subInput) - } - }else { - if(proxy.lowerBounds[0] <= xIndex && proxy.upperBounds[0] >= xIndex + 1) { - subInput.maxFraction = callback(proxy, subInput) - } - } - } - if(subInput.maxFraction == 0) { - break - } - if(sy > 0) { - yIndex++; - if(yIndex == this.m_proxyCount * 2) { - break - } - }else { - yIndex--; - if(yIndex < 0) { - break - } - } - yProgress = (this.m_bounds[1][yIndex].value - p1y) / dy - } - } - break - } - this.m_queryResultCount = 0; - this.IncrementTimeStamp(); - return -}; -b2BroadPhase.prototype.TestOverlapBound = function(b, p) { - for(var axis = 0;axis < 2;++axis) { - var bounds = this.m_bounds[axis]; - var bound = bounds[p.upperBounds[axis]]; - if(b.lowerValues[axis] > bound.value) { - return false - } - bound = bounds[p.lowerBounds[axis]]; - if(b.upperValues[axis] < bound.value) { - return false - } - } - return true -}; -b2BroadPhase.prototype.m_pairManager = new b2PairManager; -b2BroadPhase.prototype.m_proxyPool = new Array; -b2BroadPhase.prototype.m_freeProxy = null; -b2BroadPhase.prototype.m_bounds = null; -b2BroadPhase.prototype.m_querySortKeys = new Array; -b2BroadPhase.prototype.m_queryResults = new Array; -b2BroadPhase.prototype.m_queryResultCount = 0; -b2BroadPhase.prototype.m_worldAABB = null; -b2BroadPhase.prototype.m_quantizationFactor = new b2Vec2; -b2BroadPhase.prototype.m_proxyCount = 0; -b2BroadPhase.prototype.m_timeStamp = 0;var b2Manifold = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Manifold.prototype.__constructor = function() { - this.m_points = new Array(b2Settings.b2_maxManifoldPoints); - for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { - this.m_points[i] = new b2ManifoldPoint - } - this.m_localPlaneNormal = new b2Vec2; - this.m_localPoint = new b2Vec2 -}; -b2Manifold.prototype.__varz = function() { -}; -b2Manifold.e_circles = 1; -b2Manifold.e_faceA = 2; -b2Manifold.e_faceB = 4; -b2Manifold.prototype.Reset = function() { - for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { - this.m_points[i].Reset() - } - this.m_localPlaneNormal.SetZero(); - this.m_localPoint.SetZero(); - this.m_type = 0; - this.m_pointCount = 0 -}; -b2Manifold.prototype.Set = function(m) { - this.m_pointCount = m.m_pointCount; - for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { - this.m_points[i].Set(m.m_points[i]) - } - this.m_localPlaneNormal.SetV(m.m_localPlaneNormal); - this.m_localPoint.SetV(m.m_localPoint); - this.m_type = m.m_type -}; -b2Manifold.prototype.Copy = function() { - var copy = new b2Manifold; - copy.Set(this); - return copy -}; -b2Manifold.prototype.m_points = null; -b2Manifold.prototype.m_localPlaneNormal = null; -b2Manifold.prototype.m_localPoint = null; -b2Manifold.prototype.m_type = 0; -b2Manifold.prototype.m_pointCount = 0;var b2CircleShape = function() { - b2Shape.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2CircleShape.prototype, b2Shape.prototype); -b2CircleShape.prototype._super = b2Shape.prototype; -b2CircleShape.prototype.__constructor = function(radius) { - this._super.__constructor.apply(this, []); - this.m_type = b2Shape.e_circleShape; - this.m_radius = radius -}; -b2CircleShape.prototype.__varz = function() { - this.m_p = new b2Vec2 -}; -b2CircleShape.prototype.Copy = function() { - var s = new b2CircleShape; - s.Set(this); - return s -}; -b2CircleShape.prototype.Set = function(other) { - this._super.Set.apply(this, [other]); - if(isInstanceOf(other, b2CircleShape)) { - var other2 = other; - this.m_p.SetV(other2.m_p) - } -}; -b2CircleShape.prototype.TestPoint = function(transform, p) { - var tMat = transform.R; - var dX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); - var dY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); - dX = p.x - dX; - dY = p.y - dY; - return dX * dX + dY * dY <= this.m_radius * this.m_radius -}; -b2CircleShape.prototype.RayCast = function(output, input, transform) { - var tMat = transform.R; - var positionX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); - var positionY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); - var sX = input.p1.x - positionX; - var sY = input.p1.y - positionY; - var b = sX * sX + sY * sY - this.m_radius * this.m_radius; - var rX = input.p2.x - input.p1.x; - var rY = input.p2.y - input.p1.y; - var c = sX * rX + sY * rY; - var rr = rX * rX + rY * rY; - var sigma = c * c - rr * b; - if(sigma < 0 || rr < Number.MIN_VALUE) { - return false - } - var a = -(c + Math.sqrt(sigma)); - if(0 <= a && a <= input.maxFraction * rr) { - a /= rr; - output.fraction = a; - output.normal.x = sX + a * rX; - output.normal.y = sY + a * rY; - output.normal.Normalize(); - return true - } - return false -}; -b2CircleShape.prototype.ComputeAABB = function(aabb, transform) { - var tMat = transform.R; - var pX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); - var pY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); - aabb.lowerBound.Set(pX - this.m_radius, pY - this.m_radius); - aabb.upperBound.Set(pX + this.m_radius, pY + this.m_radius) -}; -b2CircleShape.prototype.ComputeMass = function(massData, density) { - massData.mass = density * b2Settings.b2_pi * this.m_radius * this.m_radius; - massData.center.SetV(this.m_p); - massData.I = massData.mass * (0.5 * this.m_radius * this.m_radius + (this.m_p.x * this.m_p.x + this.m_p.y * this.m_p.y)) -}; -b2CircleShape.prototype.ComputeSubmergedArea = function(normal, offset, xf, c) { - var p = b2Math.MulX(xf, this.m_p); - var l = -(b2Math.Dot(normal, p) - offset); - if(l < -this.m_radius + Number.MIN_VALUE) { - return 0 - } - if(l > this.m_radius) { - c.SetV(p); - return Math.PI * this.m_radius * this.m_radius - } - var r2 = this.m_radius * this.m_radius; - var l2 = l * l; - var area = r2 * (Math.asin(l / this.m_radius) + Math.PI / 2) + l * Math.sqrt(r2 - l2); - var com = -2 / 3 * Math.pow(r2 - l2, 1.5) / area; - c.x = p.x + normal.x * com; - c.y = p.y + normal.y * com; - return area -}; -b2CircleShape.prototype.GetLocalPosition = function() { - return this.m_p -}; -b2CircleShape.prototype.SetLocalPosition = function(position) { - this.m_p.SetV(position) -}; -b2CircleShape.prototype.GetRadius = function() { - return this.m_radius -}; -b2CircleShape.prototype.SetRadius = function(radius) { - this.m_radius = radius -}; -b2CircleShape.prototype.m_p = new b2Vec2;var b2Joint = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Joint.prototype.__constructor = function(def) { - b2Settings.b2Assert(def.bodyA != def.bodyB); - this.m_type = def.type; - this.m_prev = null; - this.m_next = null; - this.m_bodyA = def.bodyA; - this.m_bodyB = def.bodyB; - this.m_collideConnected = def.collideConnected; - this.m_islandFlag = false; - this.m_userData = def.userData -}; -b2Joint.prototype.__varz = function() { - this.m_edgeA = new b2JointEdge; - this.m_edgeB = new b2JointEdge; - this.m_localCenterA = new b2Vec2; - this.m_localCenterB = new b2Vec2 -}; -b2Joint.Create = function(def, allocator) { - var joint = null; - switch(def.type) { - case b2Joint.e_distanceJoint: - joint = new b2DistanceJoint(def); - break; - case b2Joint.e_mouseJoint: - joint = new b2MouseJoint(def); - break; - case b2Joint.e_prismaticJoint: - joint = new b2PrismaticJoint(def); - break; - case b2Joint.e_revoluteJoint: - joint = new b2RevoluteJoint(def); - break; - case b2Joint.e_pulleyJoint: - joint = new b2PulleyJoint(def); - break; - case b2Joint.e_gearJoint: - joint = new b2GearJoint(def); - break; - case b2Joint.e_lineJoint: - joint = new b2LineJoint(def); - break; - case b2Joint.e_weldJoint: - joint = new b2WeldJoint(def); - break; - case b2Joint.e_frictionJoint: - joint = new b2FrictionJoint(def); - break; - default: - break - } - return joint -}; -b2Joint.Destroy = function(joint, allocator) { -}; -b2Joint.e_unknownJoint = 0; -b2Joint.e_revoluteJoint = 1; -b2Joint.e_prismaticJoint = 2; -b2Joint.e_distanceJoint = 3; -b2Joint.e_pulleyJoint = 4; -b2Joint.e_mouseJoint = 5; -b2Joint.e_gearJoint = 6; -b2Joint.e_lineJoint = 7; -b2Joint.e_weldJoint = 8; -b2Joint.e_frictionJoint = 9; -b2Joint.e_inactiveLimit = 0; -b2Joint.e_atLowerLimit = 1; -b2Joint.e_atUpperLimit = 2; -b2Joint.e_equalLimits = 3; -b2Joint.prototype.InitVelocityConstraints = function(step) { -}; -b2Joint.prototype.SolveVelocityConstraints = function(step) { -}; -b2Joint.prototype.FinalizeVelocityConstraints = function() { -}; -b2Joint.prototype.SolvePositionConstraints = function(baumgarte) { - return false -}; -b2Joint.prototype.GetType = function() { - return this.m_type -}; -b2Joint.prototype.GetAnchorA = function() { - return null -}; -b2Joint.prototype.GetAnchorB = function() { - return null -}; -b2Joint.prototype.GetReactionForce = function(inv_dt) { - return null -}; -b2Joint.prototype.GetReactionTorque = function(inv_dt) { - return 0 -}; -b2Joint.prototype.GetBodyA = function() { - return this.m_bodyA -}; -b2Joint.prototype.GetBodyB = function() { - return this.m_bodyB -}; -b2Joint.prototype.GetNext = function() { - return this.m_next -}; -b2Joint.prototype.GetUserData = function() { - return this.m_userData -}; -b2Joint.prototype.SetUserData = function(data) { - this.m_userData = data -}; -b2Joint.prototype.IsActive = function() { - return this.m_bodyA.IsActive() && this.m_bodyB.IsActive() -}; -b2Joint.prototype.m_type = 0; -b2Joint.prototype.m_prev = null; -b2Joint.prototype.m_next = null; -b2Joint.prototype.m_edgeA = new b2JointEdge; -b2Joint.prototype.m_edgeB = new b2JointEdge; -b2Joint.prototype.m_bodyA = null; -b2Joint.prototype.m_bodyB = null; -b2Joint.prototype.m_islandFlag = null; -b2Joint.prototype.m_collideConnected = null; -b2Joint.prototype.m_userData = null; -b2Joint.prototype.m_localCenterA = new b2Vec2; -b2Joint.prototype.m_localCenterB = new b2Vec2; -b2Joint.prototype.m_invMassA = null; -b2Joint.prototype.m_invMassB = null; -b2Joint.prototype.m_invIA = null; -b2Joint.prototype.m_invIB = null;var b2LineJoint = function() { - b2Joint.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2LineJoint.prototype, b2Joint.prototype); -b2LineJoint.prototype._super = b2Joint.prototype; -b2LineJoint.prototype.__constructor = function(def) { - this._super.__constructor.apply(this, [def]); - var tMat; - var tX; - var tY; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_localXAxis1.SetV(def.localAxisA); - this.m_localYAxis1.x = -this.m_localXAxis1.y; - this.m_localYAxis1.y = this.m_localXAxis1.x; - this.m_impulse.SetZero(); - this.m_motorMass = 0; - this.m_motorImpulse = 0; - this.m_lowerTranslation = def.lowerTranslation; - this.m_upperTranslation = def.upperTranslation; - this.m_maxMotorForce = def.maxMotorForce; - this.m_motorSpeed = def.motorSpeed; - this.m_enableLimit = def.enableLimit; - this.m_enableMotor = def.enableMotor; - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_axis.SetZero(); - this.m_perp.SetZero() -}; -b2LineJoint.prototype.__varz = function() { - this.m_localAnchor1 = new b2Vec2; - this.m_localAnchor2 = new b2Vec2; - this.m_localXAxis1 = new b2Vec2; - this.m_localYAxis1 = new b2Vec2; - this.m_axis = new b2Vec2; - this.m_perp = new b2Vec2; - this.m_K = new b2Mat22; - this.m_impulse = new b2Vec2 -}; -b2LineJoint.prototype.InitVelocityConstraints = function(step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX; - this.m_localCenterA.SetV(bA.GetLocalCenter()); - this.m_localCenterB.SetV(bB.GetLocalCenter()); - var xf1 = bA.GetTransform(); - var xf2 = bB.GetTransform(); - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - this.m_invMassA = bA.m_invMass; - this.m_invMassB = bB.m_invMass; - this.m_invIA = bA.m_invI; - this.m_invIB = bB.m_invI; - this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; - this.m_motorMass = this.m_motorMass > Number.MIN_VALUE ? 1 / this.m_motorMass : 0; - this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var m1 = this.m_invMassA; - var m2 = this.m_invMassB; - var i1 = this.m_invIA; - var i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - if(this.m_enableLimit) { - var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; - if(b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2 * b2Settings.b2_linearSlop) { - this.m_limitState = b2Joint.e_equalLimits - }else { - if(jointTransition <= this.m_lowerTranslation) { - if(this.m_limitState != b2Joint.e_atLowerLimit) { - this.m_limitState = b2Joint.e_atLowerLimit; - this.m_impulse.y = 0 - } - }else { - if(jointTransition >= this.m_upperTranslation) { - if(this.m_limitState != b2Joint.e_atUpperLimit) { - this.m_limitState = b2Joint.e_atUpperLimit; - this.m_impulse.y = 0 - } - }else { - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_impulse.y = 0 - } - } - } - }else { - this.m_limitState = b2Joint.e_inactiveLimit - } - if(this.m_enableMotor == false) { - this.m_motorImpulse = 0 - } - if(step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_motorImpulse *= step.dtRatio; - var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x; - var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y; - var L1 = this.m_impulse.x * this.m_s1 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a1; - var L2 = this.m_impulse.x * this.m_s2 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a2; - bA.m_linearVelocity.x -= this.m_invMassA * PX; - bA.m_linearVelocity.y -= this.m_invMassA * PY; - bA.m_angularVelocity -= this.m_invIA * L1; - bB.m_linearVelocity.x += this.m_invMassB * PX; - bB.m_linearVelocity.y += this.m_invMassB * PY; - bB.m_angularVelocity += this.m_invIB * L2 - }else { - this.m_impulse.SetZero(); - this.m_motorImpulse = 0 - } -}; -b2LineJoint.prototype.SolveVelocityConstraints = function(step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var v1 = bA.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var v2 = bB.m_linearVelocity; - var w2 = bB.m_angularVelocity; - var PX; - var PY; - var L1; - var L2; - if(this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) { - var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); - var oldImpulse = this.m_motorImpulse; - var maxImpulse = step.dt * this.m_maxMotorForce; - this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, -maxImpulse, maxImpulse); - impulse = this.m_motorImpulse - oldImpulse; - PX = impulse * this.m_axis.x; - PY = impulse * this.m_axis.y; - L1 = impulse * this.m_a1; - L2 = impulse * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2 - } - var Cdot1 = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; - if(this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { - var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var f1 = this.m_impulse.Copy(); - var df = this.m_K.Solve(new b2Vec2, -Cdot1, -Cdot2); - this.m_impulse.Add(df); - if(this.m_limitState == b2Joint.e_atLowerLimit) { - this.m_impulse.y = b2Math.Max(this.m_impulse.y, 0) - }else { - if(this.m_limitState == b2Joint.e_atUpperLimit) { - this.m_impulse.y = b2Math.Min(this.m_impulse.y, 0) - } - } - var b = -Cdot1 - (this.m_impulse.y - f1.y) * this.m_K.col2.x; - var f2r; - if(this.m_K.col1.x != 0) { - f2r = b / this.m_K.col1.x + f1.x - }else { - f2r = f1.x - } - this.m_impulse.x = f2r; - df.x = this.m_impulse.x - f1.x; - df.y = this.m_impulse.y - f1.y; - PX = df.x * this.m_perp.x + df.y * this.m_axis.x; - PY = df.x * this.m_perp.y + df.y * this.m_axis.y; - L1 = df.x * this.m_s1 + df.y * this.m_a1; - L2 = df.x * this.m_s2 + df.y * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2 - }else { - var df2; - if(this.m_K.col1.x != 0) { - df2 = -Cdot1 / this.m_K.col1.x - }else { - df2 = 0 - } - this.m_impulse.x += df2; - PX = df2 * this.m_perp.x; - PY = df2 * this.m_perp.y; - L1 = df2 * this.m_s1; - L2 = df2 * this.m_s2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2 - } - bA.m_linearVelocity.SetV(v1); - bA.m_angularVelocity = w1; - bB.m_linearVelocity.SetV(v2); - bB.m_angularVelocity = w2 -}; -b2LineJoint.prototype.SolvePositionConstraints = function(baumgarte) { - var limitC; - var oldLimitImpulse; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var c1 = bA.m_sweep.c; - var a1 = bA.m_sweep.a; - var c2 = bB.m_sweep.c; - var a2 = bB.m_sweep.a; - var tMat; - var tX; - var m1; - var m2; - var i1; - var i2; - var linearError = 0; - var angularError = 0; - var active = false; - var C2 = 0; - var R1 = b2Mat22.FromAngle(a1); - var R2 = b2Mat22.FromAngle(a2); - tMat = R1; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = R2; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var dX = c2.x + r2X - c1.x - r1X; - var dY = c2.y + r2Y - c1.y - r1Y; - if(this.m_enableLimit) { - this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - var translation = this.m_axis.x * dX + this.m_axis.y * dY; - if(b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2 * b2Settings.b2_linearSlop) { - C2 = b2Math.Clamp(translation, -b2Settings.b2_maxLinearCorrection, b2Settings.b2_maxLinearCorrection); - linearError = b2Math.Abs(translation); - active = true - }else { - if(translation <= this.m_lowerTranslation) { - C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); - linearError = this.m_lowerTranslation - translation; - active = true - }else { - if(translation >= this.m_upperTranslation) { - C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0, b2Settings.b2_maxLinearCorrection); - linearError = translation - this.m_upperTranslation; - active = true - } - } - } - } - this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var impulse = new b2Vec2; - var C1 = this.m_perp.x * dX + this.m_perp.y * dY; - linearError = b2Math.Max(linearError, b2Math.Abs(C1)); - angularError = 0; - if(active) { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - this.m_K.Solve(impulse, -C1, -C2) - }else { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - var impulse1; - if(k11 != 0) { - impulse1 = -C1 / k11 - }else { - impulse1 = 0 - } - impulse.x = impulse1; - impulse.y = 0 - } - var PX = impulse.x * this.m_perp.x + impulse.y * this.m_axis.x; - var PY = impulse.x * this.m_perp.y + impulse.y * this.m_axis.y; - var L1 = impulse.x * this.m_s1 + impulse.y * this.m_a1; - var L2 = impulse.x * this.m_s2 + impulse.y * this.m_a2; - c1.x -= this.m_invMassA * PX; - c1.y -= this.m_invMassA * PY; - a1 -= this.m_invIA * L1; - c2.x += this.m_invMassB * PX; - c2.y += this.m_invMassB * PY; - a2 += this.m_invIB * L2; - bA.m_sweep.a = a1; - bB.m_sweep.a = a2; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop -}; -b2LineJoint.prototype.GetAnchorA = function() { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) -}; -b2LineJoint.prototype.GetAnchorB = function() { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) -}; -b2LineJoint.prototype.GetReactionForce = function(inv_dt) { - return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y)) -}; -b2LineJoint.prototype.GetReactionTorque = function(inv_dt) { - return inv_dt * this.m_impulse.y -}; -b2LineJoint.prototype.GetJointTranslation = function() { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var p1 = bA.GetWorldPoint(this.m_localAnchor1); - var p2 = bB.GetWorldPoint(this.m_localAnchor2); - var dX = p2.x - p1.x; - var dY = p2.y - p1.y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var translation = axis.x * dX + axis.y * dY; - return translation -}; -b2LineJoint.prototype.GetJointSpeed = function() { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var p1X = bA.m_sweep.c.x + r1X; - var p1Y = bA.m_sweep.c.y + r1Y; - var p2X = bB.m_sweep.c.x + r2X; - var p2Y = bB.m_sweep.c.y + r2Y; - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var v1 = bA.m_linearVelocity; - var v2 = bB.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var w2 = bB.m_angularVelocity; - var speed = dX * -w1 * axis.y + dY * w1 * axis.x + (axis.x * (v2.x + -w2 * r2Y - v1.x - -w1 * r1Y) + axis.y * (v2.y + w2 * r2X - v1.y - w1 * r1X)); - return speed -}; -b2LineJoint.prototype.IsLimitEnabled = function() { - return this.m_enableLimit -}; -b2LineJoint.prototype.EnableLimit = function(flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableLimit = flag -}; -b2LineJoint.prototype.GetLowerLimit = function() { - return this.m_lowerTranslation -}; -b2LineJoint.prototype.GetUpperLimit = function() { - return this.m_upperTranslation -}; -b2LineJoint.prototype.SetLimits = function(lower, upper) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_lowerTranslation = lower; - this.m_upperTranslation = upper -}; -b2LineJoint.prototype.IsMotorEnabled = function() { - return this.m_enableMotor -}; -b2LineJoint.prototype.EnableMotor = function(flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableMotor = flag -}; -b2LineJoint.prototype.SetMotorSpeed = function(speed) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_motorSpeed = speed -}; -b2LineJoint.prototype.GetMotorSpeed = function() { - return this.m_motorSpeed -}; -b2LineJoint.prototype.SetMaxMotorForce = function(force) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_maxMotorForce = force -}; -b2LineJoint.prototype.GetMaxMotorForce = function() { - return this.m_maxMotorForce -}; -b2LineJoint.prototype.GetMotorForce = function() { - return this.m_motorImpulse -}; -b2LineJoint.prototype.m_localAnchor1 = new b2Vec2; -b2LineJoint.prototype.m_localAnchor2 = new b2Vec2; -b2LineJoint.prototype.m_localXAxis1 = new b2Vec2; -b2LineJoint.prototype.m_localYAxis1 = new b2Vec2; -b2LineJoint.prototype.m_axis = new b2Vec2; -b2LineJoint.prototype.m_perp = new b2Vec2; -b2LineJoint.prototype.m_s1 = null; -b2LineJoint.prototype.m_s2 = null; -b2LineJoint.prototype.m_a1 = null; -b2LineJoint.prototype.m_a2 = null; -b2LineJoint.prototype.m_K = new b2Mat22; -b2LineJoint.prototype.m_impulse = new b2Vec2; -b2LineJoint.prototype.m_motorMass = null; -b2LineJoint.prototype.m_motorImpulse = null; -b2LineJoint.prototype.m_lowerTranslation = null; -b2LineJoint.prototype.m_upperTranslation = null; -b2LineJoint.prototype.m_maxMotorForce = null; -b2LineJoint.prototype.m_motorSpeed = null; -b2LineJoint.prototype.m_enableLimit = null; -b2LineJoint.prototype.m_enableMotor = null; -b2LineJoint.prototype.m_limitState = 0;var b2ContactSolver = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactSolver.prototype.__constructor = function() { -}; -b2ContactSolver.prototype.__varz = function() { - this.m_step = new b2TimeStep; - this.m_constraints = new Array -}; -b2ContactSolver.s_worldManifold = new b2WorldManifold; -b2ContactSolver.s_psm = new b2PositionSolverManifold; -b2ContactSolver.prototype.Initialize = function(step, contacts, contactCount, allocator) { - var contact; - this.m_step.Set(step); - this.m_allocator = allocator; - var i = 0; - var tVec; - var tMat; - this.m_constraintCount = contactCount; - while(this.m_constraints.length < this.m_constraintCount) { - this.m_constraints[this.m_constraints.length] = new b2ContactConstraint - } - for(i = 0;i < contactCount;++i) { - contact = contacts[i]; - var fixtureA = contact.m_fixtureA; - var fixtureB = contact.m_fixtureB; - var shapeA = fixtureA.m_shape; - var shapeB = fixtureB.m_shape; - var radiusA = shapeA.m_radius; - var radiusB = shapeB.m_radius; - var bodyA = fixtureA.m_body; - var bodyB = fixtureB.m_body; - var manifold = contact.GetManifold(); - var friction = b2Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction()); - var restitution = b2Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution()); - var vAX = bodyA.m_linearVelocity.x; - var vAY = bodyA.m_linearVelocity.y; - var vBX = bodyB.m_linearVelocity.x; - var vBY = bodyB.m_linearVelocity.y; - var wA = bodyA.m_angularVelocity; - var wB = bodyB.m_angularVelocity; - b2Settings.b2Assert(manifold.m_pointCount > 0); - b2ContactSolver.s_worldManifold.Initialize(manifold, bodyA.m_xf, radiusA, bodyB.m_xf, radiusB); - var normalX = b2ContactSolver.s_worldManifold.m_normal.x; - var normalY = b2ContactSolver.s_worldManifold.m_normal.y; - var cc = this.m_constraints[i]; - cc.bodyA = bodyA; - cc.bodyB = bodyB; - cc.manifold = manifold; - cc.normal.x = normalX; - cc.normal.y = normalY; - cc.pointCount = manifold.m_pointCount; - cc.friction = friction; - cc.restitution = restitution; - cc.localPlaneNormal.x = manifold.m_localPlaneNormal.x; - cc.localPlaneNormal.y = manifold.m_localPlaneNormal.y; - cc.localPoint.x = manifold.m_localPoint.x; - cc.localPoint.y = manifold.m_localPoint.y; - cc.radius = radiusA + radiusB; - cc.type = manifold.m_type; - for(var k = 0;k < cc.pointCount;++k) { - var cp = manifold.m_points[k]; - var ccp = cc.points[k]; - ccp.normalImpulse = cp.m_normalImpulse; - ccp.tangentImpulse = cp.m_tangentImpulse; - ccp.localPoint.SetV(cp.m_localPoint); - var rAX = ccp.rA.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyA.m_sweep.c.x; - var rAY = ccp.rA.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyA.m_sweep.c.y; - var rBX = ccp.rB.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyB.m_sweep.c.x; - var rBY = ccp.rB.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyB.m_sweep.c.y; - var rnA = rAX * normalY - rAY * normalX; - var rnB = rBX * normalY - rBY * normalX; - rnA *= rnA; - rnB *= rnB; - var kNormal = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rnA + bodyB.m_invI * rnB; - ccp.normalMass = 1 / kNormal; - var kEqualized = bodyA.m_mass * bodyA.m_invMass + bodyB.m_mass * bodyB.m_invMass; - kEqualized += bodyA.m_mass * bodyA.m_invI * rnA + bodyB.m_mass * bodyB.m_invI * rnB; - ccp.equalizedMass = 1 / kEqualized; - var tangentX = normalY; - var tangentY = -normalX; - var rtA = rAX * tangentY - rAY * tangentX; - var rtB = rBX * tangentY - rBY * tangentX; - rtA *= rtA; - rtB *= rtB; - var kTangent = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rtA + bodyB.m_invI * rtB; - ccp.tangentMass = 1 / kTangent; - ccp.velocityBias = 0; - var tX = vBX + -wB * rBY - vAX - -wA * rAY; - var tY = vBY + wB * rBX - vAY - wA * rAX; - var vRel = cc.normal.x * tX + cc.normal.y * tY; - if(vRel < -b2Settings.b2_velocityThreshold) { - ccp.velocityBias += -cc.restitution * vRel - } - } - if(cc.pointCount == 2) { - var ccp1 = cc.points[0]; - var ccp2 = cc.points[1]; - var invMassA = bodyA.m_invMass; - var invIA = bodyA.m_invI; - var invMassB = bodyB.m_invMass; - var invIB = bodyB.m_invI; - var rn1A = ccp1.rA.x * normalY - ccp1.rA.y * normalX; - var rn1B = ccp1.rB.x * normalY - ccp1.rB.y * normalX; - var rn2A = ccp2.rA.x * normalY - ccp2.rA.y * normalX; - var rn2B = ccp2.rB.x * normalY - ccp2.rB.y * normalX; - var k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B; - var k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B; - var k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B; - var k_maxConditionNumber = 100; - if(k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { - cc.K.col1.Set(k11, k12); - cc.K.col2.Set(k12, k22); - cc.K.GetInverse(cc.normalMass) - }else { - cc.pointCount = 1 - } - } - } -}; -b2ContactSolver.prototype.InitVelocityConstraints = function(step) { - var tVec; - var tVec2; - var tMat; - for(var i = 0;i < this.m_constraintCount;++i) { - var c = this.m_constraints[i]; - var bodyA = c.bodyA; - var bodyB = c.bodyB; - var invMassA = bodyA.m_invMass; - var invIA = bodyA.m_invI; - var invMassB = bodyB.m_invMass; - var invIB = bodyB.m_invI; - var normalX = c.normal.x; - var normalY = c.normal.y; - var tangentX = normalY; - var tangentY = -normalX; - var tX; - var j = 0; - var tCount = 0; - if(step.warmStarting) { - tCount = c.pointCount; - for(j = 0;j < tCount;++j) { - var ccp = c.points[j]; - ccp.normalImpulse *= step.dtRatio; - ccp.tangentImpulse *= step.dtRatio; - var PX = ccp.normalImpulse * normalX + ccp.tangentImpulse * tangentX; - var PY = ccp.normalImpulse * normalY + ccp.tangentImpulse * tangentY; - bodyA.m_angularVelocity -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); - bodyA.m_linearVelocity.x -= invMassA * PX; - bodyA.m_linearVelocity.y -= invMassA * PY; - bodyB.m_angularVelocity += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); - bodyB.m_linearVelocity.x += invMassB * PX; - bodyB.m_linearVelocity.y += invMassB * PY - } - }else { - tCount = c.pointCount; - for(j = 0;j < tCount;++j) { - var ccp2 = c.points[j]; - ccp2.normalImpulse = 0; - ccp2.tangentImpulse = 0 - } - } - } -}; -b2ContactSolver.prototype.SolveVelocityConstraints = function() { - var j = 0; - var ccp; - var rAX; - var rAY; - var rBX; - var rBY; - var dvX; - var dvY; - var vn; - var vt; - var lambda; - var maxFriction; - var newImpulse; - var PX; - var PY; - var dX; - var dY; - var P1X; - var P1Y; - var P2X; - var P2Y; - var tMat; - var tVec; - for(var i = 0;i < this.m_constraintCount;++i) { - var c = this.m_constraints[i]; - var bodyA = c.bodyA; - var bodyB = c.bodyB; - var wA = bodyA.m_angularVelocity; - var wB = bodyB.m_angularVelocity; - var vA = bodyA.m_linearVelocity; - var vB = bodyB.m_linearVelocity; - var invMassA = bodyA.m_invMass; - var invIA = bodyA.m_invI; - var invMassB = bodyB.m_invMass; - var invIB = bodyB.m_invI; - var normalX = c.normal.x; - var normalY = c.normal.y; - var tangentX = normalY; - var tangentY = -normalX; - var friction = c.friction; - var tX; - for(j = 0;j < c.pointCount;j++) { - ccp = c.points[j]; - dvX = vB.x - wB * ccp.rB.y - vA.x + wA * ccp.rA.y; - dvY = vB.y + wB * ccp.rB.x - vA.y - wA * ccp.rA.x; - vt = dvX * tangentX + dvY * tangentY; - lambda = ccp.tangentMass * -vt; - maxFriction = friction * ccp.normalImpulse; - newImpulse = b2Math.Clamp(ccp.tangentImpulse + lambda, -maxFriction, maxFriction); - lambda = newImpulse - ccp.tangentImpulse; - PX = lambda * tangentX; - PY = lambda * tangentY; - vA.x -= invMassA * PX; - vA.y -= invMassA * PY; - wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); - vB.x += invMassB * PX; - vB.y += invMassB * PY; - wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); - ccp.tangentImpulse = newImpulse - } - var tCount = c.pointCount; - if(c.pointCount == 1) { - ccp = c.points[0]; - dvX = vB.x + -wB * ccp.rB.y - vA.x - -wA * ccp.rA.y; - dvY = vB.y + wB * ccp.rB.x - vA.y - wA * ccp.rA.x; - vn = dvX * normalX + dvY * normalY; - lambda = -ccp.normalMass * (vn - ccp.velocityBias); - newImpulse = ccp.normalImpulse + lambda; - newImpulse = newImpulse > 0 ? newImpulse : 0; - lambda = newImpulse - ccp.normalImpulse; - PX = lambda * normalX; - PY = lambda * normalY; - vA.x -= invMassA * PX; - vA.y -= invMassA * PY; - wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); - vB.x += invMassB * PX; - vB.y += invMassB * PY; - wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); - ccp.normalImpulse = newImpulse - }else { - var cp1 = c.points[0]; - var cp2 = c.points[1]; - var aX = cp1.normalImpulse; - var aY = cp2.normalImpulse; - var dv1X = vB.x - wB * cp1.rB.y - vA.x + wA * cp1.rA.y; - var dv1Y = vB.y + wB * cp1.rB.x - vA.y - wA * cp1.rA.x; - var dv2X = vB.x - wB * cp2.rB.y - vA.x + wA * cp2.rA.y; - var dv2Y = vB.y + wB * cp2.rB.x - vA.y - wA * cp2.rA.x; - var vn1 = dv1X * normalX + dv1Y * normalY; - var vn2 = dv2X * normalX + dv2Y * normalY; - var bX = vn1 - cp1.velocityBias; - var bY = vn2 - cp2.velocityBias; - tMat = c.K; - bX -= tMat.col1.x * aX + tMat.col2.x * aY; - bY -= tMat.col1.y * aX + tMat.col2.y * aY; - var k_errorTol = 0.0010; - for(;;) { - tMat = c.normalMass; - var xX = -(tMat.col1.x * bX + tMat.col2.x * bY); - var xY = -(tMat.col1.y * bX + tMat.col2.y * bY); - if(xX >= 0 && xY >= 0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break - } - xX = -cp1.normalMass * bX; - xY = 0; - vn1 = 0; - vn2 = c.K.col1.y * xX + bY; - if(xX >= 0 && vn2 >= 0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break - } - xX = 0; - xY = -cp2.normalMass * bY; - vn1 = c.K.col2.x * xY + bX; - vn2 = 0; - if(xY >= 0 && vn1 >= 0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break - } - xX = 0; - xY = 0; - vn1 = bX; - vn2 = bY; - if(vn1 >= 0 && vn2 >= 0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break - } - break - } - } - bodyA.m_angularVelocity = wA; - bodyB.m_angularVelocity = wB - } -}; -b2ContactSolver.prototype.FinalizeVelocityConstraints = function() { - for(var i = 0;i < this.m_constraintCount;++i) { - var c = this.m_constraints[i]; - var m = c.manifold; - for(var j = 0;j < c.pointCount;++j) { - var point1 = m.m_points[j]; - var point2 = c.points[j]; - point1.m_normalImpulse = point2.normalImpulse; - point1.m_tangentImpulse = point2.tangentImpulse - } - } -}; -b2ContactSolver.prototype.SolvePositionConstraints = function(baumgarte) { - var minSeparation = 0; - for(var i = 0;i < this.m_constraintCount;i++) { - var c = this.m_constraints[i]; - var bodyA = c.bodyA; - var bodyB = c.bodyB; - var invMassA = bodyA.m_mass * bodyA.m_invMass; - var invIA = bodyA.m_mass * bodyA.m_invI; - var invMassB = bodyB.m_mass * bodyB.m_invMass; - var invIB = bodyB.m_mass * bodyB.m_invI; - b2ContactSolver.s_psm.Initialize(c); - var normal = b2ContactSolver.s_psm.m_normal; - for(var j = 0;j < c.pointCount;j++) { - var ccp = c.points[j]; - var point = b2ContactSolver.s_psm.m_points[j]; - var separation = b2ContactSolver.s_psm.m_separations[j]; - var rAX = point.x - bodyA.m_sweep.c.x; - var rAY = point.y - bodyA.m_sweep.c.y; - var rBX = point.x - bodyB.m_sweep.c.x; - var rBY = point.y - bodyB.m_sweep.c.y; - minSeparation = minSeparation < separation ? minSeparation : separation; - var C = b2Math.Clamp(baumgarte * (separation + b2Settings.b2_linearSlop), -b2Settings.b2_maxLinearCorrection, 0); - var impulse = -ccp.equalizedMass * C; - var PX = impulse * normal.x; - var PY = impulse * normal.y; - bodyA.m_sweep.c.x -= invMassA * PX; - bodyA.m_sweep.c.y -= invMassA * PY; - bodyA.m_sweep.a -= invIA * (rAX * PY - rAY * PX); - bodyA.SynchronizeTransform(); - bodyB.m_sweep.c.x += invMassB * PX; - bodyB.m_sweep.c.y += invMassB * PY; - bodyB.m_sweep.a += invIB * (rBX * PY - rBY * PX); - bodyB.SynchronizeTransform() - } - } - return minSeparation > -1.5 * b2Settings.b2_linearSlop -}; -b2ContactSolver.prototype.m_step = new b2TimeStep; -b2ContactSolver.prototype.m_allocator = null; -b2ContactSolver.prototype.m_constraints = new Array; -b2ContactSolver.prototype.m_constraintCount = 0;var b2Simplex = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Simplex.prototype.__constructor = function() { - this.m_vertices[0] = this.m_v1; - this.m_vertices[1] = this.m_v2; - this.m_vertices[2] = this.m_v3 -}; -b2Simplex.prototype.__varz = function() { - this.m_v1 = new b2SimplexVertex; - this.m_v2 = new b2SimplexVertex; - this.m_v3 = new b2SimplexVertex; - this.m_vertices = new Array(3) -}; -b2Simplex.prototype.ReadCache = function(cache, proxyA, transformA, proxyB, transformB) { - b2Settings.b2Assert(0 <= cache.count && cache.count <= 3); - var wALocal; - var wBLocal; - this.m_count = cache.count; - var vertices = this.m_vertices; - for(var i = 0;i < this.m_count;i++) { - var v = vertices[i]; - v.indexA = cache.indexA[i]; - v.indexB = cache.indexB[i]; - wALocal = proxyA.GetVertex(v.indexA); - wBLocal = proxyB.GetVertex(v.indexB); - v.wA = b2Math.MulX(transformA, wALocal); - v.wB = b2Math.MulX(transformB, wBLocal); - v.w = b2Math.SubtractVV(v.wB, v.wA); - v.a = 0 - } - if(this.m_count > 1) { - var metric1 = cache.metric; - var metric2 = this.GetMetric(); - if(metric2 < 0.5 * metric1 || 2 * metric1 < metric2 || metric2 < Number.MIN_VALUE) { - this.m_count = 0 - } - } - if(this.m_count == 0) { - v = vertices[0]; - v.indexA = 0; - v.indexB = 0; - wALocal = proxyA.GetVertex(0); - wBLocal = proxyB.GetVertex(0); - v.wA = b2Math.MulX(transformA, wALocal); - v.wB = b2Math.MulX(transformB, wBLocal); - v.w = b2Math.SubtractVV(v.wB, v.wA); - this.m_count = 1 - } -}; -b2Simplex.prototype.WriteCache = function(cache) { - cache.metric = this.GetMetric(); - cache.count = parseInt(this.m_count); - var vertices = this.m_vertices; - for(var i = 0;i < this.m_count;i++) { - cache.indexA[i] = parseInt(vertices[i].indexA); - cache.indexB[i] = parseInt(vertices[i].indexB) - } -}; -b2Simplex.prototype.GetSearchDirection = function() { - switch(this.m_count) { - case 1: - return this.m_v1.w.GetNegative(); - case 2: - var e12 = b2Math.SubtractVV(this.m_v2.w, this.m_v1.w); - var sgn = b2Math.CrossVV(e12, this.m_v1.w.GetNegative()); - if(sgn > 0) { - return b2Math.CrossFV(1, e12) - }else { - return b2Math.CrossVF(e12, 1) - } - ; - default: - b2Settings.b2Assert(false); - return new b2Vec2 - } -}; -b2Simplex.prototype.GetClosestPoint = function() { - switch(this.m_count) { - case 0: - b2Settings.b2Assert(false); - return new b2Vec2; - case 1: - return this.m_v1.w; - case 2: - return new b2Vec2(this.m_v1.a * this.m_v1.w.x + this.m_v2.a * this.m_v2.w.x, this.m_v1.a * this.m_v1.w.y + this.m_v2.a * this.m_v2.w.y); - default: - b2Settings.b2Assert(false); - return new b2Vec2 - } -}; -b2Simplex.prototype.GetWitnessPoints = function(pA, pB) { - switch(this.m_count) { - case 0: - b2Settings.b2Assert(false); - break; - case 1: - pA.SetV(this.m_v1.wA); - pB.SetV(this.m_v1.wB); - break; - case 2: - pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x; - pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y; - pB.x = this.m_v1.a * this.m_v1.wB.x + this.m_v2.a * this.m_v2.wB.x; - pB.y = this.m_v1.a * this.m_v1.wB.y + this.m_v2.a * this.m_v2.wB.y; - break; - case 3: - pB.x = pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x + this.m_v3.a * this.m_v3.wA.x; - pB.y = pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y + this.m_v3.a * this.m_v3.wA.y; - break; - default: - b2Settings.b2Assert(false); - break - } -}; -b2Simplex.prototype.GetMetric = function() { - switch(this.m_count) { - case 0: - b2Settings.b2Assert(false); - return 0; - case 1: - return 0; - case 2: - return b2Math.SubtractVV(this.m_v1.w, this.m_v2.w).Length(); - case 3: - return b2Math.CrossVV(b2Math.SubtractVV(this.m_v2.w, this.m_v1.w), b2Math.SubtractVV(this.m_v3.w, this.m_v1.w)); - default: - b2Settings.b2Assert(false); - return 0 - } -}; -b2Simplex.prototype.Solve2 = function() { - var w1 = this.m_v1.w; - var w2 = this.m_v2.w; - var e12 = b2Math.SubtractVV(w2, w1); - var d12_2 = -(w1.x * e12.x + w1.y * e12.y); - if(d12_2 <= 0) { - this.m_v1.a = 1; - this.m_count = 1; - return - } - var d12_1 = w2.x * e12.x + w2.y * e12.y; - if(d12_1 <= 0) { - this.m_v2.a = 1; - this.m_count = 1; - this.m_v1.Set(this.m_v2); - return - } - var inv_d12 = 1 / (d12_1 + d12_2); - this.m_v1.a = d12_1 * inv_d12; - this.m_v2.a = d12_2 * inv_d12; - this.m_count = 2 -}; -b2Simplex.prototype.Solve3 = function() { - var w1 = this.m_v1.w; - var w2 = this.m_v2.w; - var w3 = this.m_v3.w; - var e12 = b2Math.SubtractVV(w2, w1); - var w1e12 = b2Math.Dot(w1, e12); - var w2e12 = b2Math.Dot(w2, e12); - var d12_1 = w2e12; - var d12_2 = -w1e12; - var e13 = b2Math.SubtractVV(w3, w1); - var w1e13 = b2Math.Dot(w1, e13); - var w3e13 = b2Math.Dot(w3, e13); - var d13_1 = w3e13; - var d13_2 = -w1e13; - var e23 = b2Math.SubtractVV(w3, w2); - var w2e23 = b2Math.Dot(w2, e23); - var w3e23 = b2Math.Dot(w3, e23); - var d23_1 = w3e23; - var d23_2 = -w2e23; - var n123 = b2Math.CrossVV(e12, e13); - var d123_1 = n123 * b2Math.CrossVV(w2, w3); - var d123_2 = n123 * b2Math.CrossVV(w3, w1); - var d123_3 = n123 * b2Math.CrossVV(w1, w2); - if(d12_2 <= 0 && d13_2 <= 0) { - this.m_v1.a = 1; - this.m_count = 1; - return - } - if(d12_1 > 0 && d12_2 > 0 && d123_3 <= 0) { - var inv_d12 = 1 / (d12_1 + d12_2); - this.m_v1.a = d12_1 * inv_d12; - this.m_v2.a = d12_2 * inv_d12; - this.m_count = 2; - return - } - if(d13_1 > 0 && d13_2 > 0 && d123_2 <= 0) { - var inv_d13 = 1 / (d13_1 + d13_2); - this.m_v1.a = d13_1 * inv_d13; - this.m_v3.a = d13_2 * inv_d13; - this.m_count = 2; - this.m_v2.Set(this.m_v3); - return - } - if(d12_1 <= 0 && d23_2 <= 0) { - this.m_v2.a = 1; - this.m_count = 1; - this.m_v1.Set(this.m_v2); - return - } - if(d13_1 <= 0 && d23_1 <= 0) { - this.m_v3.a = 1; - this.m_count = 1; - this.m_v1.Set(this.m_v3); - return - } - if(d23_1 > 0 && d23_2 > 0 && d123_1 <= 0) { - var inv_d23 = 1 / (d23_1 + d23_2); - this.m_v2.a = d23_1 * inv_d23; - this.m_v3.a = d23_2 * inv_d23; - this.m_count = 2; - this.m_v1.Set(this.m_v3); - return - } - var inv_d123 = 1 / (d123_1 + d123_2 + d123_3); - this.m_v1.a = d123_1 * inv_d123; - this.m_v2.a = d123_2 * inv_d123; - this.m_v3.a = d123_3 * inv_d123; - this.m_count = 3 -}; -b2Simplex.prototype.m_v1 = new b2SimplexVertex; -b2Simplex.prototype.m_v2 = new b2SimplexVertex; -b2Simplex.prototype.m_v3 = new b2SimplexVertex; -b2Simplex.prototype.m_vertices = new Array(3); -b2Simplex.prototype.m_count = 0;var b2WeldJoint = function() { - b2Joint.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2WeldJoint.prototype, b2Joint.prototype); -b2WeldJoint.prototype._super = b2Joint.prototype; -b2WeldJoint.prototype.__constructor = function(def) { - this._super.__constructor.apply(this, [def]); - this.m_localAnchorA.SetV(def.localAnchorA); - this.m_localAnchorB.SetV(def.localAnchorB); - this.m_referenceAngle = def.referenceAngle; - this.m_impulse.SetZero(); - this.m_mass = new b2Mat33 -}; -b2WeldJoint.prototype.__varz = function() { - this.m_localAnchorA = new b2Vec2; - this.m_localAnchorB = new b2Vec2; - this.m_impulse = new b2Vec3; - this.m_mass = new b2Mat33 -}; -b2WeldJoint.prototype.InitVelocityConstraints = function(step) { - var tMat; - var tX; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * rAX + tMat.col2.x * rAY; - rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * rBX + tMat.col2.x * rBY; - rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; - rBX = tX; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; - this.m_mass.col2.x = -rAY * rAX * iA - rBY * rBX * iB; - this.m_mass.col3.x = -rAY * iA - rBY * iB; - this.m_mass.col1.y = this.m_mass.col2.x; - this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; - this.m_mass.col3.y = rAX * iA + rBX * iB; - this.m_mass.col1.z = this.m_mass.col3.x; - this.m_mass.col2.z = this.m_mass.col3.y; - this.m_mass.col3.z = iA + iB; - if(step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_impulse.z *= step.dtRatio; - bA.m_linearVelocity.x -= mA * this.m_impulse.x; - bA.m_linearVelocity.y -= mA * this.m_impulse.y; - bA.m_angularVelocity -= iA * (rAX * this.m_impulse.y - rAY * this.m_impulse.x + this.m_impulse.z); - bB.m_linearVelocity.x += mB * this.m_impulse.x; - bB.m_linearVelocity.y += mB * this.m_impulse.y; - bB.m_angularVelocity += iB * (rBX * this.m_impulse.y - rBY * this.m_impulse.x + this.m_impulse.z) - }else { - this.m_impulse.SetZero() - } -}; -b2WeldJoint.prototype.SolveVelocityConstraints = function(step) { - var tMat; - var tX; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var vA = bA.m_linearVelocity; - var wA = bA.m_angularVelocity; - var vB = bB.m_linearVelocity; - var wB = bB.m_angularVelocity; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * rAX + tMat.col2.x * rAY; - rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * rBX + tMat.col2.x * rBY; - rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; - rBX = tX; - var Cdot1X = vB.x - wB * rBY - vA.x + wA * rAY; - var Cdot1Y = vB.y + wB * rBX - vA.y - wA * rAX; - var Cdot2 = wB - wA; - var impulse = new b2Vec3; - this.m_mass.Solve33(impulse, -Cdot1X, -Cdot1Y, -Cdot2); - this.m_impulse.Add(impulse); - vA.x -= mA * impulse.x; - vA.y -= mA * impulse.y; - wA -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); - vB.x += mB * impulse.x; - vB.y += mB * impulse.y; - wB += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); - bA.m_angularVelocity = wA; - bB.m_angularVelocity = wB -}; -b2WeldJoint.prototype.SolvePositionConstraints = function(baumgarte) { - var tMat; - var tX; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * rAX + tMat.col2.x * rAY; - rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * rBX + tMat.col2.x * rBY; - rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; - rBX = tX; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - var C1X = bB.m_sweep.c.x + rBX - bA.m_sweep.c.x - rAX; - var C1Y = bB.m_sweep.c.y + rBY - bA.m_sweep.c.y - rAY; - var C2 = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; - var k_allowedStretch = 10 * b2Settings.b2_linearSlop; - var positionError = Math.sqrt(C1X * C1X + C1Y * C1Y); - var angularError = b2Math.Abs(C2); - if(positionError > k_allowedStretch) { - iA *= 1; - iB *= 1 - } - this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; - this.m_mass.col2.x = -rAY * rAX * iA - rBY * rBX * iB; - this.m_mass.col3.x = -rAY * iA - rBY * iB; - this.m_mass.col1.y = this.m_mass.col2.x; - this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; - this.m_mass.col3.y = rAX * iA + rBX * iB; - this.m_mass.col1.z = this.m_mass.col3.x; - this.m_mass.col2.z = this.m_mass.col3.y; - this.m_mass.col3.z = iA + iB; - var impulse = new b2Vec3; - this.m_mass.Solve33(impulse, -C1X, -C1Y, -C2); - bA.m_sweep.c.x -= mA * impulse.x; - bA.m_sweep.c.y -= mA * impulse.y; - bA.m_sweep.a -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); - bB.m_sweep.c.x += mB * impulse.x; - bB.m_sweep.c.y += mB * impulse.y; - bB.m_sweep.a += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop -}; -b2WeldJoint.prototype.GetAnchorA = function() { - return this.m_bodyA.GetWorldPoint(this.m_localAnchorA) -}; -b2WeldJoint.prototype.GetAnchorB = function() { - return this.m_bodyB.GetWorldPoint(this.m_localAnchorB) -}; -b2WeldJoint.prototype.GetReactionForce = function(inv_dt) { - return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y) -}; -b2WeldJoint.prototype.GetReactionTorque = function(inv_dt) { - return inv_dt * this.m_impulse.z -}; -b2WeldJoint.prototype.m_localAnchorA = new b2Vec2; -b2WeldJoint.prototype.m_localAnchorB = new b2Vec2; -b2WeldJoint.prototype.m_referenceAngle = null; -b2WeldJoint.prototype.m_impulse = new b2Vec3; -b2WeldJoint.prototype.m_mass = new b2Mat33;var b2Math = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Math.prototype.__constructor = function() { -}; -b2Math.prototype.__varz = function() { -}; -b2Math.IsValid = function(x) { - return isFinite(x) -}; -b2Math.Dot = function(a, b) { - return a.x * b.x + a.y * b.y -}; -b2Math.CrossVV = function(a, b) { - return a.x * b.y - a.y * b.x -}; -b2Math.CrossVF = function(a, s) { - var v = new b2Vec2(s * a.y, -s * a.x); - return v -}; -b2Math.CrossFV = function(s, a) { - var v = new b2Vec2(-s * a.y, s * a.x); - return v -}; -b2Math.MulMV = function(A, v) { - var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y); - return u -}; -b2Math.MulTMV = function(A, v) { - var u = new b2Vec2(b2Math.Dot(v, A.col1), b2Math.Dot(v, A.col2)); - return u -}; -b2Math.MulX = function(T, v) { - var a = b2Math.MulMV(T.R, v); - a.x += T.position.x; - a.y += T.position.y; - return a -}; -b2Math.MulXT = function(T, v) { - var a = b2Math.SubtractVV(v, T.position); - var tX = a.x * T.R.col1.x + a.y * T.R.col1.y; - a.y = a.x * T.R.col2.x + a.y * T.R.col2.y; - a.x = tX; - return a -}; -b2Math.AddVV = function(a, b) { - var v = new b2Vec2(a.x + b.x, a.y + b.y); - return v -}; -b2Math.SubtractVV = function(a, b) { - var v = new b2Vec2(a.x - b.x, a.y - b.y); - return v -}; -b2Math.Distance = function(a, b) { - var cX = a.x - b.x; - var cY = a.y - b.y; - return Math.sqrt(cX * cX + cY * cY) -}; -b2Math.DistanceSquared = function(a, b) { - var cX = a.x - b.x; - var cY = a.y - b.y; - return cX * cX + cY * cY -}; -b2Math.MulFV = function(s, a) { - var v = new b2Vec2(s * a.x, s * a.y); - return v -}; -b2Math.AddMM = function(A, B) { - var C = b2Mat22.FromVV(b2Math.AddVV(A.col1, B.col1), b2Math.AddVV(A.col2, B.col2)); - return C -}; -b2Math.MulMM = function(A, B) { - var C = b2Mat22.FromVV(b2Math.MulMV(A, B.col1), b2Math.MulMV(A, B.col2)); - return C -}; -b2Math.MulTMM = function(A, B) { - var c1 = new b2Vec2(b2Math.Dot(A.col1, B.col1), b2Math.Dot(A.col2, B.col1)); - var c2 = new b2Vec2(b2Math.Dot(A.col1, B.col2), b2Math.Dot(A.col2, B.col2)); - var C = b2Mat22.FromVV(c1, c2); - return C -}; -b2Math.Abs = function(a) { - return a > 0 ? a : -a -}; -b2Math.AbsV = function(a) { - var b = new b2Vec2(b2Math.Abs(a.x), b2Math.Abs(a.y)); - return b -}; -b2Math.AbsM = function(A) { - var B = b2Mat22.FromVV(b2Math.AbsV(A.col1), b2Math.AbsV(A.col2)); - return B -}; -b2Math.Min = function(a, b) { - return a < b ? a : b -}; -b2Math.MinV = function(a, b) { - var c = new b2Vec2(b2Math.Min(a.x, b.x), b2Math.Min(a.y, b.y)); - return c -}; -b2Math.Max = function(a, b) { - return a > b ? a : b -}; -b2Math.MaxV = function(a, b) { - var c = new b2Vec2(b2Math.Max(a.x, b.x), b2Math.Max(a.y, b.y)); - return c -}; -b2Math.Clamp = function(a, low, high) { - return a < low ? low : a > high ? high : a -}; -b2Math.ClampV = function(a, low, high) { - return b2Math.MaxV(low, b2Math.MinV(a, high)) -}; -b2Math.Swap = function(a, b) { - var tmp = a[0]; - a[0] = b[0]; - b[0] = tmp -}; -b2Math.Random = function() { - return Math.random() * 2 - 1 -}; -b2Math.RandomRange = function(lo, hi) { - var r = Math.random(); - r = (hi - lo) * r + lo; - return r -}; -b2Math.NextPowerOfTwo = function(x) { - x |= x >> 1 & 2147483647; - x |= x >> 2 & 1073741823; - x |= x >> 4 & 268435455; - x |= x >> 8 & 16777215; - x |= x >> 16 & 65535; - return x + 1 -}; -b2Math.IsPowerOfTwo = function(x) { - var result = x > 0 && (x & x - 1) == 0; - return result -}; -b2Math.b2Vec2_zero = new b2Vec2(0, 0); -b2Math.b2Mat22_identity = b2Mat22.FromVV(new b2Vec2(1, 0), new b2Vec2(0, 1)); -b2Math.b2Transform_identity = new b2Transform(b2Math.b2Vec2_zero, b2Math.b2Mat22_identity);var b2PulleyJoint = function() { - b2Joint.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2PulleyJoint.prototype, b2Joint.prototype); -b2PulleyJoint.prototype._super = b2Joint.prototype; -b2PulleyJoint.prototype.__constructor = function(def) { - this._super.__constructor.apply(this, [def]); - var tMat; - var tX; - var tY; - this.m_ground = this.m_bodyA.m_world.m_groundBody; - this.m_groundAnchor1.x = def.groundAnchorA.x - this.m_ground.m_xf.position.x; - this.m_groundAnchor1.y = def.groundAnchorA.y - this.m_ground.m_xf.position.y; - this.m_groundAnchor2.x = def.groundAnchorB.x - this.m_ground.m_xf.position.x; - this.m_groundAnchor2.y = def.groundAnchorB.y - this.m_ground.m_xf.position.y; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_ratio = def.ratio; - this.m_constant = def.lengthA + this.m_ratio * def.lengthB; - this.m_maxLength1 = b2Math.Min(def.maxLengthA, this.m_constant - this.m_ratio * b2PulleyJoint.b2_minPulleyLength); - this.m_maxLength2 = b2Math.Min(def.maxLengthB, (this.m_constant - b2PulleyJoint.b2_minPulleyLength) / this.m_ratio); - this.m_impulse = 0; - this.m_limitImpulse1 = 0; - this.m_limitImpulse2 = 0 -}; -b2PulleyJoint.prototype.__varz = function() { - this.m_groundAnchor1 = new b2Vec2; - this.m_groundAnchor2 = new b2Vec2; - this.m_localAnchor1 = new b2Vec2; - this.m_localAnchor2 = new b2Vec2; - this.m_u1 = new b2Vec2; - this.m_u2 = new b2Vec2 -}; -b2PulleyJoint.b2_minPulleyLength = 2; -b2PulleyJoint.prototype.InitVelocityConstraints = function(step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var p1X = bA.m_sweep.c.x + r1X; - var p1Y = bA.m_sweep.c.y + r1Y; - var p2X = bB.m_sweep.c.x + r2X; - var p2Y = bB.m_sweep.c.y + r2Y; - var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; - var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; - var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; - var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; - this.m_u1.Set(p1X - s1X, p1Y - s1Y); - this.m_u2.Set(p2X - s2X, p2Y - s2Y); - var length1 = this.m_u1.Length(); - var length2 = this.m_u2.Length(); - if(length1 > b2Settings.b2_linearSlop) { - this.m_u1.Multiply(1 / length1) - }else { - this.m_u1.SetZero() - } - if(length2 > b2Settings.b2_linearSlop) { - this.m_u2.Multiply(1 / length2) - }else { - this.m_u2.SetZero() - } - var C = this.m_constant - length1 - this.m_ratio * length2; - if(C > 0) { - this.m_state = b2Joint.e_inactiveLimit; - this.m_impulse = 0 - }else { - this.m_state = b2Joint.e_atUpperLimit - } - if(length1 < this.m_maxLength1) { - this.m_limitState1 = b2Joint.e_inactiveLimit; - this.m_limitImpulse1 = 0 - }else { - this.m_limitState1 = b2Joint.e_atUpperLimit - } - if(length2 < this.m_maxLength2) { - this.m_limitState2 = b2Joint.e_inactiveLimit; - this.m_limitImpulse2 = 0 - }else { - this.m_limitState2 = b2Joint.e_atUpperLimit - } - var cr1u1 = r1X * this.m_u1.y - r1Y * this.m_u1.x; - var cr2u2 = r2X * this.m_u2.y - r2Y * this.m_u2.x; - this.m_limitMass1 = bA.m_invMass + bA.m_invI * cr1u1 * cr1u1; - this.m_limitMass2 = bB.m_invMass + bB.m_invI * cr2u2 * cr2u2; - this.m_pulleyMass = this.m_limitMass1 + this.m_ratio * this.m_ratio * this.m_limitMass2; - this.m_limitMass1 = 1 / this.m_limitMass1; - this.m_limitMass2 = 1 / this.m_limitMass2; - this.m_pulleyMass = 1 / this.m_pulleyMass; - if(step.warmStarting) { - this.m_impulse *= step.dtRatio; - this.m_limitImpulse1 *= step.dtRatio; - this.m_limitImpulse2 *= step.dtRatio; - var P1X = (-this.m_impulse - this.m_limitImpulse1) * this.m_u1.x; - var P1Y = (-this.m_impulse - this.m_limitImpulse1) * this.m_u1.y; - var P2X = (-this.m_ratio * this.m_impulse - this.m_limitImpulse2) * this.m_u2.x; - var P2Y = (-this.m_ratio * this.m_impulse - this.m_limitImpulse2) * this.m_u2.y; - bA.m_linearVelocity.x += bA.m_invMass * P1X; - bA.m_linearVelocity.y += bA.m_invMass * P1Y; - bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); - bB.m_linearVelocity.x += bB.m_invMass * P2X; - bB.m_linearVelocity.y += bB.m_invMass * P2Y; - bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X) - }else { - this.m_impulse = 0; - this.m_limitImpulse1 = 0; - this.m_limitImpulse2 = 0 - } -}; -b2PulleyJoint.prototype.SolveVelocityConstraints = function(step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var v1X; - var v1Y; - var v2X; - var v2Y; - var P1X; - var P1Y; - var P2X; - var P2Y; - var Cdot; - var impulse; - var oldImpulse; - if(this.m_state == b2Joint.e_atUpperLimit) { - v1X = bA.m_linearVelocity.x + -bA.m_angularVelocity * r1Y; - v1Y = bA.m_linearVelocity.y + bA.m_angularVelocity * r1X; - v2X = bB.m_linearVelocity.x + -bB.m_angularVelocity * r2Y; - v2Y = bB.m_linearVelocity.y + bB.m_angularVelocity * r2X; - Cdot = -(this.m_u1.x * v1X + this.m_u1.y * v1Y) - this.m_ratio * (this.m_u2.x * v2X + this.m_u2.y * v2Y); - impulse = this.m_pulleyMass * -Cdot; - oldImpulse = this.m_impulse; - this.m_impulse = b2Math.Max(0, this.m_impulse + impulse); - impulse = this.m_impulse - oldImpulse; - P1X = -impulse * this.m_u1.x; - P1Y = -impulse * this.m_u1.y; - P2X = -this.m_ratio * impulse * this.m_u2.x; - P2Y = -this.m_ratio * impulse * this.m_u2.y; - bA.m_linearVelocity.x += bA.m_invMass * P1X; - bA.m_linearVelocity.y += bA.m_invMass * P1Y; - bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); - bB.m_linearVelocity.x += bB.m_invMass * P2X; - bB.m_linearVelocity.y += bB.m_invMass * P2Y; - bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X) - } - if(this.m_limitState1 == b2Joint.e_atUpperLimit) { - v1X = bA.m_linearVelocity.x + -bA.m_angularVelocity * r1Y; - v1Y = bA.m_linearVelocity.y + bA.m_angularVelocity * r1X; - Cdot = -(this.m_u1.x * v1X + this.m_u1.y * v1Y); - impulse = -this.m_limitMass1 * Cdot; - oldImpulse = this.m_limitImpulse1; - this.m_limitImpulse1 = b2Math.Max(0, this.m_limitImpulse1 + impulse); - impulse = this.m_limitImpulse1 - oldImpulse; - P1X = -impulse * this.m_u1.x; - P1Y = -impulse * this.m_u1.y; - bA.m_linearVelocity.x += bA.m_invMass * P1X; - bA.m_linearVelocity.y += bA.m_invMass * P1Y; - bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X) - } - if(this.m_limitState2 == b2Joint.e_atUpperLimit) { - v2X = bB.m_linearVelocity.x + -bB.m_angularVelocity * r2Y; - v2Y = bB.m_linearVelocity.y + bB.m_angularVelocity * r2X; - Cdot = -(this.m_u2.x * v2X + this.m_u2.y * v2Y); - impulse = -this.m_limitMass2 * Cdot; - oldImpulse = this.m_limitImpulse2; - this.m_limitImpulse2 = b2Math.Max(0, this.m_limitImpulse2 + impulse); - impulse = this.m_limitImpulse2 - oldImpulse; - P2X = -impulse * this.m_u2.x; - P2Y = -impulse * this.m_u2.y; - bB.m_linearVelocity.x += bB.m_invMass * P2X; - bB.m_linearVelocity.y += bB.m_invMass * P2Y; - bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X) - } -}; -b2PulleyJoint.prototype.SolvePositionConstraints = function(baumgarte) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; - var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; - var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; - var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; - var r1X; - var r1Y; - var r2X; - var r2Y; - var p1X; - var p1Y; - var p2X; - var p2Y; - var length1; - var length2; - var C; - var impulse; - var oldImpulse; - var oldLimitPositionImpulse; - var tX; - var linearError = 0; - if(this.m_state == b2Joint.e_atUpperLimit) { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - p1X = bA.m_sweep.c.x + r1X; - p1Y = bA.m_sweep.c.y + r1Y; - p2X = bB.m_sweep.c.x + r2X; - p2Y = bB.m_sweep.c.y + r2Y; - this.m_u1.Set(p1X - s1X, p1Y - s1Y); - this.m_u2.Set(p2X - s2X, p2Y - s2Y); - length1 = this.m_u1.Length(); - length2 = this.m_u2.Length(); - if(length1 > b2Settings.b2_linearSlop) { - this.m_u1.Multiply(1 / length1) - }else { - this.m_u1.SetZero() - } - if(length2 > b2Settings.b2_linearSlop) { - this.m_u2.Multiply(1 / length2) - }else { - this.m_u2.SetZero() - } - C = this.m_constant - length1 - this.m_ratio * length2; - linearError = b2Math.Max(linearError, -C); - C = b2Math.Clamp(C + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); - impulse = -this.m_pulleyMass * C; - p1X = -impulse * this.m_u1.x; - p1Y = -impulse * this.m_u1.y; - p2X = -this.m_ratio * impulse * this.m_u2.x; - p2Y = -this.m_ratio * impulse * this.m_u2.y; - bA.m_sweep.c.x += bA.m_invMass * p1X; - bA.m_sweep.c.y += bA.m_invMass * p1Y; - bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); - bB.m_sweep.c.x += bB.m_invMass * p2X; - bB.m_sweep.c.y += bB.m_invMass * p2Y; - bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); - bA.SynchronizeTransform(); - bB.SynchronizeTransform() - } - if(this.m_limitState1 == b2Joint.e_atUpperLimit) { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - p1X = bA.m_sweep.c.x + r1X; - p1Y = bA.m_sweep.c.y + r1Y; - this.m_u1.Set(p1X - s1X, p1Y - s1Y); - length1 = this.m_u1.Length(); - if(length1 > b2Settings.b2_linearSlop) { - this.m_u1.x *= 1 / length1; - this.m_u1.y *= 1 / length1 - }else { - this.m_u1.SetZero() - } - C = this.m_maxLength1 - length1; - linearError = b2Math.Max(linearError, -C); - C = b2Math.Clamp(C + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); - impulse = -this.m_limitMass1 * C; - p1X = -impulse * this.m_u1.x; - p1Y = -impulse * this.m_u1.y; - bA.m_sweep.c.x += bA.m_invMass * p1X; - bA.m_sweep.c.y += bA.m_invMass * p1Y; - bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); - bA.SynchronizeTransform() - } - if(this.m_limitState2 == b2Joint.e_atUpperLimit) { - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - p2X = bB.m_sweep.c.x + r2X; - p2Y = bB.m_sweep.c.y + r2Y; - this.m_u2.Set(p2X - s2X, p2Y - s2Y); - length2 = this.m_u2.Length(); - if(length2 > b2Settings.b2_linearSlop) { - this.m_u2.x *= 1 / length2; - this.m_u2.y *= 1 / length2 - }else { - this.m_u2.SetZero() - } - C = this.m_maxLength2 - length2; - linearError = b2Math.Max(linearError, -C); - C = b2Math.Clamp(C + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); - impulse = -this.m_limitMass2 * C; - p2X = -impulse * this.m_u2.x; - p2Y = -impulse * this.m_u2.y; - bB.m_sweep.c.x += bB.m_invMass * p2X; - bB.m_sweep.c.y += bB.m_invMass * p2Y; - bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); - bB.SynchronizeTransform() - } - return linearError < b2Settings.b2_linearSlop -}; -b2PulleyJoint.prototype.GetAnchorA = function() { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) -}; -b2PulleyJoint.prototype.GetAnchorB = function() { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) -}; -b2PulleyJoint.prototype.GetReactionForce = function(inv_dt) { - return new b2Vec2(inv_dt * this.m_impulse * this.m_u2.x, inv_dt * this.m_impulse * this.m_u2.y) -}; -b2PulleyJoint.prototype.GetReactionTorque = function(inv_dt) { - return 0 -}; -b2PulleyJoint.prototype.GetGroundAnchorA = function() { - var a = this.m_ground.m_xf.position.Copy(); - a.Add(this.m_groundAnchor1); - return a -}; -b2PulleyJoint.prototype.GetGroundAnchorB = function() { - var a = this.m_ground.m_xf.position.Copy(); - a.Add(this.m_groundAnchor2); - return a -}; -b2PulleyJoint.prototype.GetLength1 = function() { - var p = this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; - var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; - var dX = p.x - sX; - var dY = p.y - sY; - return Math.sqrt(dX * dX + dY * dY) -}; -b2PulleyJoint.prototype.GetLength2 = function() { - var p = this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; - var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; - var dX = p.x - sX; - var dY = p.y - sY; - return Math.sqrt(dX * dX + dY * dY) -}; -b2PulleyJoint.prototype.GetRatio = function() { - return this.m_ratio -}; -b2PulleyJoint.prototype.m_ground = null; -b2PulleyJoint.prototype.m_groundAnchor1 = new b2Vec2; -b2PulleyJoint.prototype.m_groundAnchor2 = new b2Vec2; -b2PulleyJoint.prototype.m_localAnchor1 = new b2Vec2; -b2PulleyJoint.prototype.m_localAnchor2 = new b2Vec2; -b2PulleyJoint.prototype.m_u1 = new b2Vec2; -b2PulleyJoint.prototype.m_u2 = new b2Vec2; -b2PulleyJoint.prototype.m_constant = null; -b2PulleyJoint.prototype.m_ratio = null; -b2PulleyJoint.prototype.m_maxLength1 = null; -b2PulleyJoint.prototype.m_maxLength2 = null; -b2PulleyJoint.prototype.m_pulleyMass = null; -b2PulleyJoint.prototype.m_limitMass1 = null; -b2PulleyJoint.prototype.m_limitMass2 = null; -b2PulleyJoint.prototype.m_impulse = null; -b2PulleyJoint.prototype.m_limitImpulse1 = null; -b2PulleyJoint.prototype.m_limitImpulse2 = null; -b2PulleyJoint.prototype.m_state = 0; -b2PulleyJoint.prototype.m_limitState1 = 0; -b2PulleyJoint.prototype.m_limitState2 = 0;var b2PrismaticJoint = function() { - b2Joint.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2PrismaticJoint.prototype, b2Joint.prototype); -b2PrismaticJoint.prototype._super = b2Joint.prototype; -b2PrismaticJoint.prototype.__constructor = function(def) { - this._super.__constructor.apply(this, [def]); - var tMat; - var tX; - var tY; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_localXAxis1.SetV(def.localAxisA); - this.m_localYAxis1.x = -this.m_localXAxis1.y; - this.m_localYAxis1.y = this.m_localXAxis1.x; - this.m_refAngle = def.referenceAngle; - this.m_impulse.SetZero(); - this.m_motorMass = 0; - this.m_motorImpulse = 0; - this.m_lowerTranslation = def.lowerTranslation; - this.m_upperTranslation = def.upperTranslation; - this.m_maxMotorForce = def.maxMotorForce; - this.m_motorSpeed = def.motorSpeed; - this.m_enableLimit = def.enableLimit; - this.m_enableMotor = def.enableMotor; - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_axis.SetZero(); - this.m_perp.SetZero() -}; -b2PrismaticJoint.prototype.__varz = function() { - this.m_localAnchor1 = new b2Vec2; - this.m_localAnchor2 = new b2Vec2; - this.m_localXAxis1 = new b2Vec2; - this.m_localYAxis1 = new b2Vec2; - this.m_axis = new b2Vec2; - this.m_perp = new b2Vec2; - this.m_K = new b2Mat33; - this.m_impulse = new b2Vec3 -}; -b2PrismaticJoint.prototype.InitVelocityConstraints = function(step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX; - this.m_localCenterA.SetV(bA.GetLocalCenter()); - this.m_localCenterB.SetV(bB.GetLocalCenter()); - var xf1 = bA.GetTransform(); - var xf2 = bB.GetTransform(); - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - this.m_invMassA = bA.m_invMass; - this.m_invMassB = bB.m_invMass; - this.m_invIA = bA.m_invI; - this.m_invIB = bB.m_invI; - this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; - if(this.m_motorMass > Number.MIN_VALUE) { - this.m_motorMass = 1 / this.m_motorMass - } - this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var m1 = this.m_invMassA; - var m2 = this.m_invMassB; - var i1 = this.m_invIA; - var i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; - this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = i1 + i2; - this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; - this.m_K.col3.x = this.m_K.col1.z; - this.m_K.col3.y = this.m_K.col2.z; - this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - if(this.m_enableLimit) { - var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; - if(b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2 * b2Settings.b2_linearSlop) { - this.m_limitState = b2Joint.e_equalLimits - }else { - if(jointTransition <= this.m_lowerTranslation) { - if(this.m_limitState != b2Joint.e_atLowerLimit) { - this.m_limitState = b2Joint.e_atLowerLimit; - this.m_impulse.z = 0 - } - }else { - if(jointTransition >= this.m_upperTranslation) { - if(this.m_limitState != b2Joint.e_atUpperLimit) { - this.m_limitState = b2Joint.e_atUpperLimit; - this.m_impulse.z = 0 - } - }else { - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_impulse.z = 0 - } - } - } - }else { - this.m_limitState = b2Joint.e_inactiveLimit - } - if(this.m_enableMotor == false) { - this.m_motorImpulse = 0 - } - if(step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_motorImpulse *= step.dtRatio; - var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x; - var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y; - var L1 = this.m_impulse.x * this.m_s1 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a1; - var L2 = this.m_impulse.x * this.m_s2 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a2; - bA.m_linearVelocity.x -= this.m_invMassA * PX; - bA.m_linearVelocity.y -= this.m_invMassA * PY; - bA.m_angularVelocity -= this.m_invIA * L1; - bB.m_linearVelocity.x += this.m_invMassB * PX; - bB.m_linearVelocity.y += this.m_invMassB * PY; - bB.m_angularVelocity += this.m_invIB * L2 - }else { - this.m_impulse.SetZero(); - this.m_motorImpulse = 0 - } -}; -b2PrismaticJoint.prototype.SolveVelocityConstraints = function(step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var v1 = bA.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var v2 = bB.m_linearVelocity; - var w2 = bB.m_angularVelocity; - var PX; - var PY; - var L1; - var L2; - if(this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) { - var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); - var oldImpulse = this.m_motorImpulse; - var maxImpulse = step.dt * this.m_maxMotorForce; - this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, -maxImpulse, maxImpulse); - impulse = this.m_motorImpulse - oldImpulse; - PX = impulse * this.m_axis.x; - PY = impulse * this.m_axis.y; - L1 = impulse * this.m_a1; - L2 = impulse * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2 - } - var Cdot1X = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; - var Cdot1Y = w2 - w1; - if(this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { - var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var f1 = this.m_impulse.Copy(); - var df = this.m_K.Solve33(new b2Vec3, -Cdot1X, -Cdot1Y, -Cdot2); - this.m_impulse.Add(df); - if(this.m_limitState == b2Joint.e_atLowerLimit) { - this.m_impulse.z = b2Math.Max(this.m_impulse.z, 0) - }else { - if(this.m_limitState == b2Joint.e_atUpperLimit) { - this.m_impulse.z = b2Math.Min(this.m_impulse.z, 0) - } - } - var bX = -Cdot1X - (this.m_impulse.z - f1.z) * this.m_K.col3.x; - var bY = -Cdot1Y - (this.m_impulse.z - f1.z) * this.m_K.col3.y; - var f2r = this.m_K.Solve22(new b2Vec2, bX, bY); - f2r.x += f1.x; - f2r.y += f1.y; - this.m_impulse.x = f2r.x; - this.m_impulse.y = f2r.y; - df.x = this.m_impulse.x - f1.x; - df.y = this.m_impulse.y - f1.y; - df.z = this.m_impulse.z - f1.z; - PX = df.x * this.m_perp.x + df.z * this.m_axis.x; - PY = df.x * this.m_perp.y + df.z * this.m_axis.y; - L1 = df.x * this.m_s1 + df.y + df.z * this.m_a1; - L2 = df.x * this.m_s2 + df.y + df.z * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2 - }else { - var df2 = this.m_K.Solve22(new b2Vec2, -Cdot1X, -Cdot1Y); - this.m_impulse.x += df2.x; - this.m_impulse.y += df2.y; - PX = df2.x * this.m_perp.x; - PY = df2.x * this.m_perp.y; - L1 = df2.x * this.m_s1 + df2.y; - L2 = df2.x * this.m_s2 + df2.y; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2 - } - bA.m_linearVelocity.SetV(v1); - bA.m_angularVelocity = w1; - bB.m_linearVelocity.SetV(v2); - bB.m_angularVelocity = w2 -}; -b2PrismaticJoint.prototype.SolvePositionConstraints = function(baumgarte) { - var limitC; - var oldLimitImpulse; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var c1 = bA.m_sweep.c; - var a1 = bA.m_sweep.a; - var c2 = bB.m_sweep.c; - var a2 = bB.m_sweep.a; - var tMat; - var tX; - var m1; - var m2; - var i1; - var i2; - var linearError = 0; - var angularError = 0; - var active = false; - var C2 = 0; - var R1 = b2Mat22.FromAngle(a1); - var R2 = b2Mat22.FromAngle(a2); - tMat = R1; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = R2; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var dX = c2.x + r2X - c1.x - r1X; - var dY = c2.y + r2Y - c1.y - r1Y; - if(this.m_enableLimit) { - this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - var translation = this.m_axis.x * dX + this.m_axis.y * dY; - if(b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2 * b2Settings.b2_linearSlop) { - C2 = b2Math.Clamp(translation, -b2Settings.b2_maxLinearCorrection, b2Settings.b2_maxLinearCorrection); - linearError = b2Math.Abs(translation); - active = true - }else { - if(translation <= this.m_lowerTranslation) { - C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0); - linearError = this.m_lowerTranslation - translation; - active = true - }else { - if(translation >= this.m_upperTranslation) { - C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0, b2Settings.b2_maxLinearCorrection); - linearError = translation - this.m_upperTranslation; - active = true - } - } - } - } - this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var impulse = new b2Vec3; - var C1X = this.m_perp.x * dX + this.m_perp.y * dY; - var C1Y = a2 - a1 - this.m_refAngle; - linearError = b2Math.Max(linearError, b2Math.Abs(C1X)); - angularError = b2Math.Abs(C1Y); - if(active) { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; - this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = i1 + i2; - this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; - this.m_K.col3.x = this.m_K.col1.z; - this.m_K.col3.y = this.m_K.col2.z; - this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - this.m_K.Solve33(impulse, -C1X, -C1Y, -C2) - }else { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - var k12 = i1 * this.m_s1 + i2 * this.m_s2; - var k22 = i1 + i2; - this.m_K.col1.Set(k11, k12, 0); - this.m_K.col2.Set(k12, k22, 0); - var impulse1 = this.m_K.Solve22(new b2Vec2, -C1X, -C1Y); - impulse.x = impulse1.x; - impulse.y = impulse1.y; - impulse.z = 0 - } - var PX = impulse.x * this.m_perp.x + impulse.z * this.m_axis.x; - var PY = impulse.x * this.m_perp.y + impulse.z * this.m_axis.y; - var L1 = impulse.x * this.m_s1 + impulse.y + impulse.z * this.m_a1; - var L2 = impulse.x * this.m_s2 + impulse.y + impulse.z * this.m_a2; - c1.x -= this.m_invMassA * PX; - c1.y -= this.m_invMassA * PY; - a1 -= this.m_invIA * L1; - c2.x += this.m_invMassB * PX; - c2.y += this.m_invMassB * PY; - a2 += this.m_invIB * L2; - bA.m_sweep.a = a1; - bB.m_sweep.a = a2; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop -}; -b2PrismaticJoint.prototype.GetAnchorA = function() { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) -}; -b2PrismaticJoint.prototype.GetAnchorB = function() { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) -}; -b2PrismaticJoint.prototype.GetReactionForce = function(inv_dt) { - return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y)) -}; -b2PrismaticJoint.prototype.GetReactionTorque = function(inv_dt) { - return inv_dt * this.m_impulse.y -}; -b2PrismaticJoint.prototype.GetJointTranslation = function() { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var p1 = bA.GetWorldPoint(this.m_localAnchor1); - var p2 = bB.GetWorldPoint(this.m_localAnchor2); - var dX = p2.x - p1.x; - var dY = p2.y - p1.y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var translation = axis.x * dX + axis.y * dY; - return translation -}; -b2PrismaticJoint.prototype.GetJointSpeed = function() { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var p1X = bA.m_sweep.c.x + r1X; - var p1Y = bA.m_sweep.c.y + r1Y; - var p2X = bB.m_sweep.c.x + r2X; - var p2Y = bB.m_sweep.c.y + r2Y; - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var v1 = bA.m_linearVelocity; - var v2 = bB.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var w2 = bB.m_angularVelocity; - var speed = dX * -w1 * axis.y + dY * w1 * axis.x + (axis.x * (v2.x + -w2 * r2Y - v1.x - -w1 * r1Y) + axis.y * (v2.y + w2 * r2X - v1.y - w1 * r1X)); - return speed -}; -b2PrismaticJoint.prototype.IsLimitEnabled = function() { - return this.m_enableLimit -}; -b2PrismaticJoint.prototype.EnableLimit = function(flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableLimit = flag -}; -b2PrismaticJoint.prototype.GetLowerLimit = function() { - return this.m_lowerTranslation -}; -b2PrismaticJoint.prototype.GetUpperLimit = function() { - return this.m_upperTranslation -}; -b2PrismaticJoint.prototype.SetLimits = function(lower, upper) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_lowerTranslation = lower; - this.m_upperTranslation = upper -}; -b2PrismaticJoint.prototype.IsMotorEnabled = function() { - return this.m_enableMotor -}; -b2PrismaticJoint.prototype.EnableMotor = function(flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableMotor = flag -}; -b2PrismaticJoint.prototype.SetMotorSpeed = function(speed) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_motorSpeed = speed -}; -b2PrismaticJoint.prototype.GetMotorSpeed = function() { - return this.m_motorSpeed -}; -b2PrismaticJoint.prototype.SetMaxMotorForce = function(force) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_maxMotorForce = force -}; -b2PrismaticJoint.prototype.GetMotorForce = function() { - return this.m_motorImpulse -}; -b2PrismaticJoint.prototype.m_localAnchor1 = new b2Vec2; -b2PrismaticJoint.prototype.m_localAnchor2 = new b2Vec2; -b2PrismaticJoint.prototype.m_localXAxis1 = new b2Vec2; -b2PrismaticJoint.prototype.m_localYAxis1 = new b2Vec2; -b2PrismaticJoint.prototype.m_refAngle = null; -b2PrismaticJoint.prototype.m_axis = new b2Vec2; -b2PrismaticJoint.prototype.m_perp = new b2Vec2; -b2PrismaticJoint.prototype.m_s1 = null; -b2PrismaticJoint.prototype.m_s2 = null; -b2PrismaticJoint.prototype.m_a1 = null; -b2PrismaticJoint.prototype.m_a2 = null; -b2PrismaticJoint.prototype.m_K = new b2Mat33; -b2PrismaticJoint.prototype.m_impulse = new b2Vec3; -b2PrismaticJoint.prototype.m_motorMass = null; -b2PrismaticJoint.prototype.m_motorImpulse = null; -b2PrismaticJoint.prototype.m_lowerTranslation = null; -b2PrismaticJoint.prototype.m_upperTranslation = null; -b2PrismaticJoint.prototype.m_maxMotorForce = null; -b2PrismaticJoint.prototype.m_motorSpeed = null; -b2PrismaticJoint.prototype.m_enableLimit = null; -b2PrismaticJoint.prototype.m_enableMotor = null; -b2PrismaticJoint.prototype.m_limitState = 0;var b2RevoluteJoint = function() { - b2Joint.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2RevoluteJoint.prototype, b2Joint.prototype); -b2RevoluteJoint.prototype._super = b2Joint.prototype; -b2RevoluteJoint.prototype.__constructor = function(def) { - this._super.__constructor.apply(this, [def]); - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_referenceAngle = def.referenceAngle; - this.m_impulse.SetZero(); - this.m_motorImpulse = 0; - this.m_lowerAngle = def.lowerAngle; - this.m_upperAngle = def.upperAngle; - this.m_maxMotorTorque = def.maxMotorTorque; - this.m_motorSpeed = def.motorSpeed; - this.m_enableLimit = def.enableLimit; - this.m_enableMotor = def.enableMotor; - this.m_limitState = b2Joint.e_inactiveLimit -}; -b2RevoluteJoint.prototype.__varz = function() { - this.K = new b2Mat22; - this.K1 = new b2Mat22; - this.K2 = new b2Mat22; - this.K3 = new b2Mat22; - this.impulse3 = new b2Vec3; - this.impulse2 = new b2Vec2; - this.reduced = new b2Vec2; - this.m_localAnchor1 = new b2Vec2; - this.m_localAnchor2 = new b2Vec2; - this.m_impulse = new b2Vec3; - this.m_mass = new b2Mat33 -}; -b2RevoluteJoint.tImpulse = new b2Vec2; -b2RevoluteJoint.prototype.InitVelocityConstraints = function(step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX; - if(this.m_enableMotor || this.m_enableLimit) { - } - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var m1 = bA.m_invMass; - var m2 = bB.m_invMass; - var i1 = bA.m_invI; - var i2 = bB.m_invI; - this.m_mass.col1.x = m1 + m2 + r1Y * r1Y * i1 + r2Y * r2Y * i2; - this.m_mass.col2.x = -r1Y * r1X * i1 - r2Y * r2X * i2; - this.m_mass.col3.x = -r1Y * i1 - r2Y * i2; - this.m_mass.col1.y = this.m_mass.col2.x; - this.m_mass.col2.y = m1 + m2 + r1X * r1X * i1 + r2X * r2X * i2; - this.m_mass.col3.y = r1X * i1 + r2X * i2; - this.m_mass.col1.z = this.m_mass.col3.x; - this.m_mass.col2.z = this.m_mass.col3.y; - this.m_mass.col3.z = i1 + i2; - this.m_motorMass = 1 / (i1 + i2); - if(this.m_enableMotor == false) { - this.m_motorImpulse = 0 - } - if(this.m_enableLimit) { - var jointAngle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; - if(b2Math.Abs(this.m_upperAngle - this.m_lowerAngle) < 2 * b2Settings.b2_angularSlop) { - this.m_limitState = b2Joint.e_equalLimits - }else { - if(jointAngle <= this.m_lowerAngle) { - if(this.m_limitState != b2Joint.e_atLowerLimit) { - this.m_impulse.z = 0 - } - this.m_limitState = b2Joint.e_atLowerLimit - }else { - if(jointAngle >= this.m_upperAngle) { - if(this.m_limitState != b2Joint.e_atUpperLimit) { - this.m_impulse.z = 0 - } - this.m_limitState = b2Joint.e_atUpperLimit - }else { - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_impulse.z = 0 - } - } - } - }else { - this.m_limitState = b2Joint.e_inactiveLimit - } - if(step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_motorImpulse *= step.dtRatio; - var PX = this.m_impulse.x; - var PY = this.m_impulse.y; - bA.m_linearVelocity.x -= m1 * PX; - bA.m_linearVelocity.y -= m1 * PY; - bA.m_angularVelocity -= i1 * (r1X * PY - r1Y * PX + this.m_motorImpulse + this.m_impulse.z); - bB.m_linearVelocity.x += m2 * PX; - bB.m_linearVelocity.y += m2 * PY; - bB.m_angularVelocity += i2 * (r2X * PY - r2Y * PX + this.m_motorImpulse + this.m_impulse.z) - }else { - this.m_impulse.SetZero(); - this.m_motorImpulse = 0 - } -}; -b2RevoluteJoint.prototype.SolveVelocityConstraints = function(step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX; - var newImpulse; - var r1X; - var r1Y; - var r2X; - var r2Y; - var v1 = bA.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var v2 = bB.m_linearVelocity; - var w2 = bB.m_angularVelocity; - var m1 = bA.m_invMass; - var m2 = bB.m_invMass; - var i1 = bA.m_invI; - var i2 = bB.m_invI; - if(this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) { - var Cdot = w2 - w1 - this.m_motorSpeed; - var impulse = this.m_motorMass * -Cdot; - var oldImpulse = this.m_motorImpulse; - var maxImpulse = step.dt * this.m_maxMotorTorque; - this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, -maxImpulse, maxImpulse); - impulse = this.m_motorImpulse - oldImpulse; - w1 -= i1 * impulse; - w2 += i2 * impulse - } - if(this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var Cdot1X = v2.x + -w2 * r2Y - v1.x - -w1 * r1Y; - var Cdot1Y = v2.y + w2 * r2X - v1.y - w1 * r1X; - var Cdot2 = w2 - w1; - this.m_mass.Solve33(this.impulse3, -Cdot1X, -Cdot1Y, -Cdot2); - if(this.m_limitState == b2Joint.e_equalLimits) { - this.m_impulse.Add(this.impulse3) - }else { - if(this.m_limitState == b2Joint.e_atLowerLimit) { - newImpulse = this.m_impulse.z + this.impulse3.z; - if(newImpulse < 0) { - this.m_mass.Solve22(this.reduced, -Cdot1X, -Cdot1Y); - this.impulse3.x = this.reduced.x; - this.impulse3.y = this.reduced.y; - this.impulse3.z = -this.m_impulse.z; - this.m_impulse.x += this.reduced.x; - this.m_impulse.y += this.reduced.y; - this.m_impulse.z = 0 - } - }else { - if(this.m_limitState == b2Joint.e_atUpperLimit) { - newImpulse = this.m_impulse.z + this.impulse3.z; - if(newImpulse > 0) { - this.m_mass.Solve22(this.reduced, -Cdot1X, -Cdot1Y); - this.impulse3.x = this.reduced.x; - this.impulse3.y = this.reduced.y; - this.impulse3.z = -this.m_impulse.z; - this.m_impulse.x += this.reduced.x; - this.m_impulse.y += this.reduced.y; - this.m_impulse.z = 0 - } - } - } - } - v1.x -= m1 * this.impulse3.x; - v1.y -= m1 * this.impulse3.y; - w1 -= i1 * (r1X * this.impulse3.y - r1Y * this.impulse3.x + this.impulse3.z); - v2.x += m2 * this.impulse3.x; - v2.y += m2 * this.impulse3.y; - w2 += i2 * (r2X * this.impulse3.y - r2Y * this.impulse3.x + this.impulse3.z) - }else { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var CdotX = v2.x + -w2 * r2Y - v1.x - -w1 * r1Y; - var CdotY = v2.y + w2 * r2X - v1.y - w1 * r1X; - this.m_mass.Solve22(this.impulse2, -CdotX, -CdotY); - this.m_impulse.x += this.impulse2.x; - this.m_impulse.y += this.impulse2.y; - v1.x -= m1 * this.impulse2.x; - v1.y -= m1 * this.impulse2.y; - w1 -= i1 * (r1X * this.impulse2.y - r1Y * this.impulse2.x); - v2.x += m2 * this.impulse2.x; - v2.y += m2 * this.impulse2.y; - w2 += i2 * (r2X * this.impulse2.y - r2Y * this.impulse2.x) - } - bA.m_linearVelocity.SetV(v1); - bA.m_angularVelocity = w1; - bB.m_linearVelocity.SetV(v2); - bB.m_angularVelocity = w2 -}; -b2RevoluteJoint.prototype.SolvePositionConstraints = function(baumgarte) { - var oldLimitImpulse; - var C; - var tMat; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var angularError = 0; - var positionError = 0; - var tX; - var impulseX; - var impulseY; - if(this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { - var angle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; - var limitImpulse = 0; - if(this.m_limitState == b2Joint.e_equalLimits) { - C = b2Math.Clamp(angle - this.m_lowerAngle, -b2Settings.b2_maxAngularCorrection, b2Settings.b2_maxAngularCorrection); - limitImpulse = -this.m_motorMass * C; - angularError = b2Math.Abs(C) - }else { - if(this.m_limitState == b2Joint.e_atLowerLimit) { - C = angle - this.m_lowerAngle; - angularError = -C; - C = b2Math.Clamp(C + b2Settings.b2_angularSlop, -b2Settings.b2_maxAngularCorrection, 0); - limitImpulse = -this.m_motorMass * C - }else { - if(this.m_limitState == b2Joint.e_atUpperLimit) { - C = angle - this.m_upperAngle; - angularError = C; - C = b2Math.Clamp(C - b2Settings.b2_angularSlop, 0, b2Settings.b2_maxAngularCorrection); - limitImpulse = -this.m_motorMass * C - } - } - } - bA.m_sweep.a -= bA.m_invI * limitImpulse; - bB.m_sweep.a += bB.m_invI * limitImpulse; - bA.SynchronizeTransform(); - bB.SynchronizeTransform() - } - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - var CLengthSquared = CX * CX + CY * CY; - var CLength = Math.sqrt(CLengthSquared); - positionError = CLength; - var invMass1 = bA.m_invMass; - var invMass2 = bB.m_invMass; - var invI1 = bA.m_invI; - var invI2 = bB.m_invI; - var k_allowedStretch = 10 * b2Settings.b2_linearSlop; - if(CLengthSquared > k_allowedStretch * k_allowedStretch) { - var uX = CX / CLength; - var uY = CY / CLength; - var k = invMass1 + invMass2; - var m = 1 / k; - impulseX = m * -CX; - impulseY = m * -CY; - var k_beta = 0.5; - bA.m_sweep.c.x -= k_beta * invMass1 * impulseX; - bA.m_sweep.c.y -= k_beta * invMass1 * impulseY; - bB.m_sweep.c.x += k_beta * invMass2 * impulseX; - bB.m_sweep.c.y += k_beta * invMass2 * impulseY; - CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y - } - this.K1.col1.x = invMass1 + invMass2; - this.K1.col2.x = 0; - this.K1.col1.y = 0; - this.K1.col2.y = invMass1 + invMass2; - this.K2.col1.x = invI1 * r1Y * r1Y; - this.K2.col2.x = -invI1 * r1X * r1Y; - this.K2.col1.y = -invI1 * r1X * r1Y; - this.K2.col2.y = invI1 * r1X * r1X; - this.K3.col1.x = invI2 * r2Y * r2Y; - this.K3.col2.x = -invI2 * r2X * r2Y; - this.K3.col1.y = -invI2 * r2X * r2Y; - this.K3.col2.y = invI2 * r2X * r2X; - this.K.SetM(this.K1); - this.K.AddM(this.K2); - this.K.AddM(this.K3); - this.K.Solve(b2RevoluteJoint.tImpulse, -CX, -CY); - impulseX = b2RevoluteJoint.tImpulse.x; - impulseY = b2RevoluteJoint.tImpulse.y; - bA.m_sweep.c.x -= bA.m_invMass * impulseX; - bA.m_sweep.c.y -= bA.m_invMass * impulseY; - bA.m_sweep.a -= bA.m_invI * (r1X * impulseY - r1Y * impulseX); - bB.m_sweep.c.x += bB.m_invMass * impulseX; - bB.m_sweep.c.y += bB.m_invMass * impulseY; - bB.m_sweep.a += bB.m_invI * (r2X * impulseY - r2Y * impulseX); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop -}; -b2RevoluteJoint.prototype.GetAnchorA = function() { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) -}; -b2RevoluteJoint.prototype.GetAnchorB = function() { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) -}; -b2RevoluteJoint.prototype.GetReactionForce = function(inv_dt) { - return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y) -}; -b2RevoluteJoint.prototype.GetReactionTorque = function(inv_dt) { - return inv_dt * this.m_impulse.z -}; -b2RevoluteJoint.prototype.GetJointAngle = function() { - return this.m_bodyB.m_sweep.a - this.m_bodyA.m_sweep.a - this.m_referenceAngle -}; -b2RevoluteJoint.prototype.GetJointSpeed = function() { - return this.m_bodyB.m_angularVelocity - this.m_bodyA.m_angularVelocity -}; -b2RevoluteJoint.prototype.IsLimitEnabled = function() { - return this.m_enableLimit -}; -b2RevoluteJoint.prototype.EnableLimit = function(flag) { - this.m_enableLimit = flag -}; -b2RevoluteJoint.prototype.GetLowerLimit = function() { - return this.m_lowerAngle -}; -b2RevoluteJoint.prototype.GetUpperLimit = function() { - return this.m_upperAngle -}; -b2RevoluteJoint.prototype.SetLimits = function(lower, upper) { - this.m_lowerAngle = lower; - this.m_upperAngle = upper -}; -b2RevoluteJoint.prototype.IsMotorEnabled = function() { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - return this.m_enableMotor -}; -b2RevoluteJoint.prototype.EnableMotor = function(flag) { - this.m_enableMotor = flag -}; -b2RevoluteJoint.prototype.SetMotorSpeed = function(speed) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_motorSpeed = speed -}; -b2RevoluteJoint.prototype.GetMotorSpeed = function() { - return this.m_motorSpeed -}; -b2RevoluteJoint.prototype.SetMaxMotorTorque = function(torque) { - this.m_maxMotorTorque = torque -}; -b2RevoluteJoint.prototype.GetMotorTorque = function() { - return this.m_maxMotorTorque -}; -b2RevoluteJoint.prototype.K = new b2Mat22; -b2RevoluteJoint.prototype.K1 = new b2Mat22; -b2RevoluteJoint.prototype.K2 = new b2Mat22; -b2RevoluteJoint.prototype.K3 = new b2Mat22; -b2RevoluteJoint.prototype.impulse3 = new b2Vec3; -b2RevoluteJoint.prototype.impulse2 = new b2Vec2; -b2RevoluteJoint.prototype.reduced = new b2Vec2; -b2RevoluteJoint.prototype.m_localAnchor1 = new b2Vec2; -b2RevoluteJoint.prototype.m_localAnchor2 = new b2Vec2; -b2RevoluteJoint.prototype.m_impulse = new b2Vec3; -b2RevoluteJoint.prototype.m_motorImpulse = null; -b2RevoluteJoint.prototype.m_mass = new b2Mat33; -b2RevoluteJoint.prototype.m_motorMass = null; -b2RevoluteJoint.prototype.m_enableMotor = null; -b2RevoluteJoint.prototype.m_maxMotorTorque = null; -b2RevoluteJoint.prototype.m_motorSpeed = null; -b2RevoluteJoint.prototype.m_enableLimit = null; -b2RevoluteJoint.prototype.m_referenceAngle = null; -b2RevoluteJoint.prototype.m_lowerAngle = null; -b2RevoluteJoint.prototype.m_upperAngle = null; -b2RevoluteJoint.prototype.m_limitState = 0;var b2JointDef = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2JointDef.prototype.__constructor = function() { - this.type = b2Joint.e_unknownJoint; - this.userData = null; - this.bodyA = null; - this.bodyB = null; - this.collideConnected = false -}; -b2JointDef.prototype.__varz = function() { -}; -b2JointDef.prototype.type = 0; -b2JointDef.prototype.userData = null; -b2JointDef.prototype.bodyA = null; -b2JointDef.prototype.bodyB = null; -b2JointDef.prototype.collideConnected = null;var b2LineJointDef = function() { - b2JointDef.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2LineJointDef.prototype, b2JointDef.prototype); -b2LineJointDef.prototype._super = b2JointDef.prototype; -b2LineJointDef.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.type = b2Joint.e_lineJoint; - this.localAxisA.Set(1, 0); - this.enableLimit = false; - this.lowerTranslation = 0; - this.upperTranslation = 0; - this.enableMotor = false; - this.maxMotorForce = 0; - this.motorSpeed = 0 -}; -b2LineJointDef.prototype.__varz = function() { - this.localAnchorA = new b2Vec2; - this.localAnchorB = new b2Vec2; - this.localAxisA = new b2Vec2 -}; -b2LineJointDef.prototype.Initialize = function(bA, bB, anchor, axis) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA = this.bodyA.GetLocalPoint(anchor); - this.localAnchorB = this.bodyB.GetLocalPoint(anchor); - this.localAxisA = this.bodyA.GetLocalVector(axis) -}; -b2LineJointDef.prototype.localAnchorA = new b2Vec2; -b2LineJointDef.prototype.localAnchorB = new b2Vec2; -b2LineJointDef.prototype.localAxisA = new b2Vec2; -b2LineJointDef.prototype.enableLimit = null; -b2LineJointDef.prototype.lowerTranslation = null; -b2LineJointDef.prototype.upperTranslation = null; -b2LineJointDef.prototype.enableMotor = null; -b2LineJointDef.prototype.maxMotorForce = null; -b2LineJointDef.prototype.motorSpeed = null;var b2DistanceJoint = function() { - b2Joint.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2DistanceJoint.prototype, b2Joint.prototype); -b2DistanceJoint.prototype._super = b2Joint.prototype; -b2DistanceJoint.prototype.__constructor = function(def) { - this._super.__constructor.apply(this, [def]); - var tMat; - var tX; - var tY; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_length = def.length; - this.m_frequencyHz = def.frequencyHz; - this.m_dampingRatio = def.dampingRatio; - this.m_impulse = 0; - this.m_gamma = 0; - this.m_bias = 0 -}; -b2DistanceJoint.prototype.__varz = function() { - this.m_localAnchor1 = new b2Vec2; - this.m_localAnchor2 = new b2Vec2; - this.m_u = new b2Vec2 -}; -b2DistanceJoint.prototype.InitVelocityConstraints = function(step) { - var tMat; - var tX; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - this.m_u.x = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - this.m_u.y = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - var length = Math.sqrt(this.m_u.x * this.m_u.x + this.m_u.y * this.m_u.y); - if(length > b2Settings.b2_linearSlop) { - this.m_u.Multiply(1 / length) - }else { - this.m_u.SetZero() - } - var cr1u = r1X * this.m_u.y - r1Y * this.m_u.x; - var cr2u = r2X * this.m_u.y - r2Y * this.m_u.x; - var invMass = bA.m_invMass + bA.m_invI * cr1u * cr1u + bB.m_invMass + bB.m_invI * cr2u * cr2u; - this.m_mass = invMass != 0 ? 1 / invMass : 0; - if(this.m_frequencyHz > 0) { - var C = length - this.m_length; - var omega = 2 * Math.PI * this.m_frequencyHz; - var d = 2 * this.m_mass * this.m_dampingRatio * omega; - var k = this.m_mass * omega * omega; - this.m_gamma = step.dt * (d + step.dt * k); - this.m_gamma = this.m_gamma != 0 ? 1 / this.m_gamma : 0; - this.m_bias = C * step.dt * k * this.m_gamma; - this.m_mass = invMass + this.m_gamma; - this.m_mass = this.m_mass != 0 ? 1 / this.m_mass : 0 - } - if(step.warmStarting) { - this.m_impulse *= step.dtRatio; - var PX = this.m_impulse * this.m_u.x; - var PY = this.m_impulse * this.m_u.y; - bA.m_linearVelocity.x -= bA.m_invMass * PX; - bA.m_linearVelocity.y -= bA.m_invMass * PY; - bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); - bB.m_linearVelocity.x += bB.m_invMass * PX; - bB.m_linearVelocity.y += bB.m_invMass * PY; - bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX) - }else { - this.m_impulse = 0 - } -}; -b2DistanceJoint.prototype.SolveVelocityConstraints = function(step) { - var tMat; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var v1X = bA.m_linearVelocity.x + -bA.m_angularVelocity * r1Y; - var v1Y = bA.m_linearVelocity.y + bA.m_angularVelocity * r1X; - var v2X = bB.m_linearVelocity.x + -bB.m_angularVelocity * r2Y; - var v2Y = bB.m_linearVelocity.y + bB.m_angularVelocity * r2X; - var Cdot = this.m_u.x * (v2X - v1X) + this.m_u.y * (v2Y - v1Y); - var impulse = -this.m_mass * (Cdot + this.m_bias + this.m_gamma * this.m_impulse); - this.m_impulse += impulse; - var PX = impulse * this.m_u.x; - var PY = impulse * this.m_u.y; - bA.m_linearVelocity.x -= bA.m_invMass * PX; - bA.m_linearVelocity.y -= bA.m_invMass * PY; - bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); - bB.m_linearVelocity.x += bB.m_invMass * PX; - bB.m_linearVelocity.y += bB.m_invMass * PY; - bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX) -}; -b2DistanceJoint.prototype.SolvePositionConstraints = function(baumgarte) { - var tMat; - if(this.m_frequencyHz > 0) { - return true - } - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = tMat.col1.x * r1X + tMat.col2.x * r1Y; - r1Y = tMat.col1.y * r1X + tMat.col2.y * r1Y; - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * r2X + tMat.col2.x * r2Y; - r2Y = tMat.col1.y * r2X + tMat.col2.y * r2Y; - r2X = tX; - var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - var length = Math.sqrt(dX * dX + dY * dY); - dX /= length; - dY /= length; - var C = length - this.m_length; - C = b2Math.Clamp(C, -b2Settings.b2_maxLinearCorrection, b2Settings.b2_maxLinearCorrection); - var impulse = -this.m_mass * C; - this.m_u.Set(dX, dY); - var PX = impulse * this.m_u.x; - var PY = impulse * this.m_u.y; - bA.m_sweep.c.x -= bA.m_invMass * PX; - bA.m_sweep.c.y -= bA.m_invMass * PY; - bA.m_sweep.a -= bA.m_invI * (r1X * PY - r1Y * PX); - bB.m_sweep.c.x += bB.m_invMass * PX; - bB.m_sweep.c.y += bB.m_invMass * PY; - bB.m_sweep.a += bB.m_invI * (r2X * PY - r2Y * PX); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return b2Math.Abs(C) < b2Settings.b2_linearSlop -}; -b2DistanceJoint.prototype.GetAnchorA = function() { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) -}; -b2DistanceJoint.prototype.GetAnchorB = function() { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) -}; -b2DistanceJoint.prototype.GetReactionForce = function(inv_dt) { - return new b2Vec2(inv_dt * this.m_impulse * this.m_u.x, inv_dt * this.m_impulse * this.m_u.y) -}; -b2DistanceJoint.prototype.GetReactionTorque = function(inv_dt) { - return 0 -}; -b2DistanceJoint.prototype.GetLength = function() { - return this.m_length -}; -b2DistanceJoint.prototype.SetLength = function(length) { - this.m_length = length -}; -b2DistanceJoint.prototype.GetFrequency = function() { - return this.m_frequencyHz -}; -b2DistanceJoint.prototype.SetFrequency = function(hz) { - this.m_frequencyHz = hz -}; -b2DistanceJoint.prototype.GetDampingRatio = function() { - return this.m_dampingRatio -}; -b2DistanceJoint.prototype.SetDampingRatio = function(ratio) { - this.m_dampingRatio = ratio -}; -b2DistanceJoint.prototype.m_localAnchor1 = new b2Vec2; -b2DistanceJoint.prototype.m_localAnchor2 = new b2Vec2; -b2DistanceJoint.prototype.m_u = new b2Vec2; -b2DistanceJoint.prototype.m_frequencyHz = null; -b2DistanceJoint.prototype.m_dampingRatio = null; -b2DistanceJoint.prototype.m_gamma = null; -b2DistanceJoint.prototype.m_bias = null; -b2DistanceJoint.prototype.m_impulse = null; -b2DistanceJoint.prototype.m_mass = null; -b2DistanceJoint.prototype.m_length = null;var b2PulleyJointDef = function() { - b2JointDef.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2PulleyJointDef.prototype, b2JointDef.prototype); -b2PulleyJointDef.prototype._super = b2JointDef.prototype; -b2PulleyJointDef.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.type = b2Joint.e_pulleyJoint; - this.groundAnchorA.Set(-1, 1); - this.groundAnchorB.Set(1, 1); - this.localAnchorA.Set(-1, 0); - this.localAnchorB.Set(1, 0); - this.lengthA = 0; - this.maxLengthA = 0; - this.lengthB = 0; - this.maxLengthB = 0; - this.ratio = 1; - this.collideConnected = true -}; -b2PulleyJointDef.prototype.__varz = function() { - this.groundAnchorA = new b2Vec2; - this.groundAnchorB = new b2Vec2; - this.localAnchorA = new b2Vec2; - this.localAnchorB = new b2Vec2 -}; -b2PulleyJointDef.prototype.Initialize = function(bA, bB, gaA, gaB, anchorA, anchorB, r) { - this.bodyA = bA; - this.bodyB = bB; - this.groundAnchorA.SetV(gaA); - this.groundAnchorB.SetV(gaB); - this.localAnchorA = this.bodyA.GetLocalPoint(anchorA); - this.localAnchorB = this.bodyB.GetLocalPoint(anchorB); - var d1X = anchorA.x - gaA.x; - var d1Y = anchorA.y - gaA.y; - this.lengthA = Math.sqrt(d1X * d1X + d1Y * d1Y); - var d2X = anchorB.x - gaB.x; - var d2Y = anchorB.y - gaB.y; - this.lengthB = Math.sqrt(d2X * d2X + d2Y * d2Y); - this.ratio = r; - var C = this.lengthA + this.ratio * this.lengthB; - this.maxLengthA = C - this.ratio * b2PulleyJoint.b2_minPulleyLength; - this.maxLengthB = (C - b2PulleyJoint.b2_minPulleyLength) / this.ratio -}; -b2PulleyJointDef.prototype.groundAnchorA = new b2Vec2; -b2PulleyJointDef.prototype.groundAnchorB = new b2Vec2; -b2PulleyJointDef.prototype.localAnchorA = new b2Vec2; -b2PulleyJointDef.prototype.localAnchorB = new b2Vec2; -b2PulleyJointDef.prototype.lengthA = null; -b2PulleyJointDef.prototype.maxLengthA = null; -b2PulleyJointDef.prototype.lengthB = null; -b2PulleyJointDef.prototype.maxLengthB = null; -b2PulleyJointDef.prototype.ratio = null;var b2DistanceJointDef = function() { - b2JointDef.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2DistanceJointDef.prototype, b2JointDef.prototype); -b2DistanceJointDef.prototype._super = b2JointDef.prototype; -b2DistanceJointDef.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.type = b2Joint.e_distanceJoint; - this.length = 1; - this.frequencyHz = 0; - this.dampingRatio = 0 -}; -b2DistanceJointDef.prototype.__varz = function() { - this.localAnchorA = new b2Vec2; - this.localAnchorB = new b2Vec2 -}; -b2DistanceJointDef.prototype.Initialize = function(bA, bB, anchorA, anchorB) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchorA)); - this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchorB)); - var dX = anchorB.x - anchorA.x; - var dY = anchorB.y - anchorA.y; - this.length = Math.sqrt(dX * dX + dY * dY); - this.frequencyHz = 0; - this.dampingRatio = 0 -}; -b2DistanceJointDef.prototype.localAnchorA = new b2Vec2; -b2DistanceJointDef.prototype.localAnchorB = new b2Vec2; -b2DistanceJointDef.prototype.length = null; -b2DistanceJointDef.prototype.frequencyHz = null; -b2DistanceJointDef.prototype.dampingRatio = null;var b2FrictionJointDef = function() { - b2JointDef.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2FrictionJointDef.prototype, b2JointDef.prototype); -b2FrictionJointDef.prototype._super = b2JointDef.prototype; -b2FrictionJointDef.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.type = b2Joint.e_frictionJoint; - this.maxForce = 0; - this.maxTorque = 0 -}; -b2FrictionJointDef.prototype.__varz = function() { - this.localAnchorA = new b2Vec2; - this.localAnchorB = new b2Vec2 -}; -b2FrictionJointDef.prototype.Initialize = function(bA, bB, anchor) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); - this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)) -}; -b2FrictionJointDef.prototype.localAnchorA = new b2Vec2; -b2FrictionJointDef.prototype.localAnchorB = new b2Vec2; -b2FrictionJointDef.prototype.maxForce = null; -b2FrictionJointDef.prototype.maxTorque = null;var b2WeldJointDef = function() { - b2JointDef.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2WeldJointDef.prototype, b2JointDef.prototype); -b2WeldJointDef.prototype._super = b2JointDef.prototype; -b2WeldJointDef.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.type = b2Joint.e_weldJoint; - this.referenceAngle = 0 -}; -b2WeldJointDef.prototype.__varz = function() { - this.localAnchorA = new b2Vec2; - this.localAnchorB = new b2Vec2 -}; -b2WeldJointDef.prototype.Initialize = function(bA, bB, anchor) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); - this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)); - this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle() -}; -b2WeldJointDef.prototype.localAnchorA = new b2Vec2; -b2WeldJointDef.prototype.localAnchorB = new b2Vec2; -b2WeldJointDef.prototype.referenceAngle = null;var b2GearJointDef = function() { - b2JointDef.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2GearJointDef.prototype, b2JointDef.prototype); -b2GearJointDef.prototype._super = b2JointDef.prototype; -b2GearJointDef.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.type = b2Joint.e_gearJoint; - this.joint1 = null; - this.joint2 = null; - this.ratio = 1 -}; -b2GearJointDef.prototype.__varz = function() { -}; -b2GearJointDef.prototype.joint1 = null; -b2GearJointDef.prototype.joint2 = null; -b2GearJointDef.prototype.ratio = null;var b2Color = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Color.prototype.__constructor = function(rr, gg, bb) { - this._r = parseInt(255 * b2Math.Clamp(rr, 0, 1)); - this._g = parseInt(255 * b2Math.Clamp(gg, 0, 1)); - this._b = parseInt(255 * b2Math.Clamp(bb, 0, 1)) -}; -b2Color.prototype.__varz = function() { -}; -b2Color.prototype.Set = function(rr, gg, bb) { - this._r = parseInt(255 * b2Math.Clamp(rr, 0, 1)); - this._g = parseInt(255 * b2Math.Clamp(gg, 0, 1)); - this._b = parseInt(255 * b2Math.Clamp(bb, 0, 1)) -}; -b2Color.prototype.__defineGetter__("r", function() { - return this._r -}); -b2Color.prototype.__defineSetter__("r", function(rr) { - this._r = parseInt(255 * b2Math.Clamp(rr, 0, 1)) -}); -b2Color.prototype.__defineGetter__("g", function() { - return this._g -}); -b2Color.prototype.__defineSetter__("g", function(gg) { - this._g = parseInt(255 * b2Math.Clamp(gg, 0, 1)) -}); -b2Color.prototype.__defineGetter__("b", function() { - return this._g -}); -b2Color.prototype.__defineSetter__("b", function(bb) { - this._b = parseInt(255 * b2Math.Clamp(bb, 0, 1)) -}); -b2Color.prototype.__defineGetter__("color", function() { - return this._r << 16 | this._g << 8 | this._b -}); -b2Color.prototype._r = 0; -b2Color.prototype._g = 0; -b2Color.prototype._b = 0;var b2FrictionJoint = function() { - b2Joint.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2FrictionJoint.prototype, b2Joint.prototype); -b2FrictionJoint.prototype._super = b2Joint.prototype; -b2FrictionJoint.prototype.__constructor = function(def) { - this._super.__constructor.apply(this, [def]); - this.m_localAnchorA.SetV(def.localAnchorA); - this.m_localAnchorB.SetV(def.localAnchorB); - this.m_linearMass.SetZero(); - this.m_angularMass = 0; - this.m_linearImpulse.SetZero(); - this.m_angularImpulse = 0; - this.m_maxForce = def.maxForce; - this.m_maxTorque = def.maxTorque -}; -b2FrictionJoint.prototype.__varz = function() { - this.m_localAnchorA = new b2Vec2; - this.m_localAnchorB = new b2Vec2; - this.m_linearImpulse = new b2Vec2; - this.m_linearMass = new b2Mat22 -}; -b2FrictionJoint.prototype.InitVelocityConstraints = function(step) { - var tMat; - var tX; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * rAX + tMat.col2.x * rAY; - rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * rBX + tMat.col2.x * rBY; - rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; - rBX = tX; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - var K = new b2Mat22; - K.col1.x = mA + mB; - K.col2.x = 0; - K.col1.y = 0; - K.col2.y = mA + mB; - K.col1.x += iA * rAY * rAY; - K.col2.x += -iA * rAX * rAY; - K.col1.y += -iA * rAX * rAY; - K.col2.y += iA * rAX * rAX; - K.col1.x += iB * rBY * rBY; - K.col2.x += -iB * rBX * rBY; - K.col1.y += -iB * rBX * rBY; - K.col2.y += iB * rBX * rBX; - K.GetInverse(this.m_linearMass); - this.m_angularMass = iA + iB; - if(this.m_angularMass > 0) { - this.m_angularMass = 1 / this.m_angularMass - } - if(step.warmStarting) { - this.m_linearImpulse.x *= step.dtRatio; - this.m_linearImpulse.y *= step.dtRatio; - this.m_angularImpulse *= step.dtRatio; - var P = this.m_linearImpulse; - bA.m_linearVelocity.x -= mA * P.x; - bA.m_linearVelocity.y -= mA * P.y; - bA.m_angularVelocity -= iA * (rAX * P.y - rAY * P.x + this.m_angularImpulse); - bB.m_linearVelocity.x += mB * P.x; - bB.m_linearVelocity.y += mB * P.y; - bB.m_angularVelocity += iB * (rBX * P.y - rBY * P.x + this.m_angularImpulse) - }else { - this.m_linearImpulse.SetZero(); - this.m_angularImpulse = 0 - } -}; -b2FrictionJoint.prototype.SolveVelocityConstraints = function(step) { - var tMat; - var tX; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var vA = bA.m_linearVelocity; - var wA = bA.m_angularVelocity; - var vB = bB.m_linearVelocity; - var wB = bB.m_angularVelocity; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * rAX + tMat.col2.x * rAY; - rAY = tMat.col1.y * rAX + tMat.col2.y * rAY; - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * rBX + tMat.col2.x * rBY; - rBY = tMat.col1.y * rBX + tMat.col2.y * rBY; - rBX = tX; - var maxImpulse; - var Cdot = wB - wA; - var impulse = -this.m_angularMass * Cdot; - var oldImpulse = this.m_angularImpulse; - maxImpulse = step.dt * this.m_maxTorque; - this.m_angularImpulse = b2Math.Clamp(this.m_angularImpulse + impulse, -maxImpulse, maxImpulse); - impulse = this.m_angularImpulse - oldImpulse; - wA -= iA * impulse; - wB += iB * impulse; - var CdotX = vB.x - wB * rBY - vA.x + wA * rAY; - var CdotY = vB.y + wB * rBX - vA.y - wA * rAX; - var impulseV = b2Math.MulMV(this.m_linearMass, new b2Vec2(-CdotX, -CdotY)); - var oldImpulseV = this.m_linearImpulse.Copy(); - this.m_linearImpulse.Add(impulseV); - maxImpulse = step.dt * this.m_maxForce; - if(this.m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) { - this.m_linearImpulse.Normalize(); - this.m_linearImpulse.Multiply(maxImpulse) - } - impulseV = b2Math.SubtractVV(this.m_linearImpulse, oldImpulseV); - vA.x -= mA * impulseV.x; - vA.y -= mA * impulseV.y; - wA -= iA * (rAX * impulseV.y - rAY * impulseV.x); - vB.x += mB * impulseV.x; - vB.y += mB * impulseV.y; - wB += iB * (rBX * impulseV.y - rBY * impulseV.x); - bA.m_angularVelocity = wA; - bB.m_angularVelocity = wB -}; -b2FrictionJoint.prototype.SolvePositionConstraints = function(baumgarte) { - return true -}; -b2FrictionJoint.prototype.GetAnchorA = function() { - return this.m_bodyA.GetWorldPoint(this.m_localAnchorA) -}; -b2FrictionJoint.prototype.GetAnchorB = function() { - return this.m_bodyB.GetWorldPoint(this.m_localAnchorB) -}; -b2FrictionJoint.prototype.GetReactionForce = function(inv_dt) { - return new b2Vec2(inv_dt * this.m_linearImpulse.x, inv_dt * this.m_linearImpulse.y) -}; -b2FrictionJoint.prototype.GetReactionTorque = function(inv_dt) { - return inv_dt * this.m_angularImpulse -}; -b2FrictionJoint.prototype.SetMaxForce = function(force) { - this.m_maxForce = force -}; -b2FrictionJoint.prototype.GetMaxForce = function() { - return this.m_maxForce -}; -b2FrictionJoint.prototype.SetMaxTorque = function(torque) { - this.m_maxTorque = torque -}; -b2FrictionJoint.prototype.GetMaxTorque = function() { - return this.m_maxTorque -}; -b2FrictionJoint.prototype.m_localAnchorA = new b2Vec2; -b2FrictionJoint.prototype.m_localAnchorB = new b2Vec2; -b2FrictionJoint.prototype.m_linearImpulse = new b2Vec2; -b2FrictionJoint.prototype.m_angularImpulse = null; -b2FrictionJoint.prototype.m_maxForce = null; -b2FrictionJoint.prototype.m_maxTorque = null; -b2FrictionJoint.prototype.m_linearMass = new b2Mat22; -b2FrictionJoint.prototype.m_angularMass = null;var b2Distance = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Distance.prototype.__constructor = function() { -}; -b2Distance.prototype.__varz = function() { -}; -b2Distance.Distance = function(output, cache, input) { - ++b2Distance.b2_gjkCalls; - var proxyA = input.proxyA; - var proxyB = input.proxyB; - var transformA = input.transformA; - var transformB = input.transformB; - var simplex = b2Distance.s_simplex; - simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB); - var vertices = simplex.m_vertices; - var k_maxIters = 20; - var saveA = b2Distance.s_saveA; - var saveB = b2Distance.s_saveB; - var saveCount = 0; - var closestPoint = simplex.GetClosestPoint(); - var distanceSqr1 = closestPoint.LengthSquared(); - var distanceSqr2 = distanceSqr1; - var i = 0; - var p; - var iter = 0; - while(iter < k_maxIters) { - saveCount = simplex.m_count; - for(i = 0;i < saveCount;i++) { - saveA[i] = vertices[i].indexA; - saveB[i] = vertices[i].indexB - } - switch(simplex.m_count) { - case 1: - break; - case 2: - simplex.Solve2(); - break; - case 3: - simplex.Solve3(); - break; - default: - b2Settings.b2Assert(false) - } - if(simplex.m_count == 3) { - break - } - p = simplex.GetClosestPoint(); - distanceSqr2 = p.LengthSquared(); - if(distanceSqr2 > distanceSqr1) { - } - distanceSqr1 = distanceSqr2; - var d = simplex.GetSearchDirection(); - if(d.LengthSquared() < Number.MIN_VALUE * Number.MIN_VALUE) { - break - } - var vertex = vertices[simplex.m_count]; - vertex.indexA = proxyA.GetSupport(b2Math.MulTMV(transformA.R, d.GetNegative())); - vertex.wA = b2Math.MulX(transformA, proxyA.GetVertex(vertex.indexA)); - vertex.indexB = proxyB.GetSupport(b2Math.MulTMV(transformB.R, d)); - vertex.wB = b2Math.MulX(transformB, proxyB.GetVertex(vertex.indexB)); - vertex.w = b2Math.SubtractVV(vertex.wB, vertex.wA); - ++iter; - ++b2Distance.b2_gjkIters; - var duplicate = false; - for(i = 0;i < saveCount;i++) { - if(vertex.indexA == saveA[i] && vertex.indexB == saveB[i]) { - duplicate = true; - break - } - } - if(duplicate) { - break - } - ++simplex.m_count - } - b2Distance.b2_gjkMaxIters = b2Math.Max(b2Distance.b2_gjkMaxIters, iter); - simplex.GetWitnessPoints(output.pointA, output.pointB); - output.distance = b2Math.SubtractVV(output.pointA, output.pointB).Length(); - output.iterations = iter; - simplex.WriteCache(cache); - if(input.useRadii) { - var rA = proxyA.m_radius; - var rB = proxyB.m_radius; - if(output.distance > rA + rB && output.distance > Number.MIN_VALUE) { - output.distance -= rA + rB; - var normal = b2Math.SubtractVV(output.pointB, output.pointA); - normal.Normalize(); - output.pointA.x += rA * normal.x; - output.pointA.y += rA * normal.y; - output.pointB.x -= rB * normal.x; - output.pointB.y -= rB * normal.y - }else { - p = new b2Vec2; - p.x = 0.5 * (output.pointA.x + output.pointB.x); - p.y = 0.5 * (output.pointA.y + output.pointB.y); - output.pointA.x = output.pointB.x = p.x; - output.pointA.y = output.pointB.y = p.y; - output.distance = 0 - } - } -}; -b2Distance.b2_gjkCalls = 0; -b2Distance.b2_gjkIters = 0; -b2Distance.b2_gjkMaxIters = 0; -b2Distance.s_simplex = new b2Simplex; -b2Distance.s_saveA = new Array(3); -b2Distance.s_saveB = new Array(3);var b2MouseJoint = function() { - b2Joint.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2MouseJoint.prototype, b2Joint.prototype); -b2MouseJoint.prototype._super = b2Joint.prototype; -b2MouseJoint.prototype.__constructor = function(def) { - this._super.__constructor.apply(this, [def]); - this.m_target.SetV(def.target); - var tX = this.m_target.x - this.m_bodyB.m_xf.position.x; - var tY = this.m_target.y - this.m_bodyB.m_xf.position.y; - var tMat = this.m_bodyB.m_xf.R; - this.m_localAnchor.x = tX * tMat.col1.x + tY * tMat.col1.y; - this.m_localAnchor.y = tX * tMat.col2.x + tY * tMat.col2.y; - this.m_maxForce = def.maxForce; - this.m_impulse.SetZero(); - this.m_frequencyHz = def.frequencyHz; - this.m_dampingRatio = def.dampingRatio; - this.m_beta = 0; - this.m_gamma = 0 -}; -b2MouseJoint.prototype.__varz = function() { - this.K = new b2Mat22; - this.K1 = new b2Mat22; - this.K2 = new b2Mat22; - this.m_localAnchor = new b2Vec2; - this.m_target = new b2Vec2; - this.m_impulse = new b2Vec2; - this.m_mass = new b2Mat22; - this.m_C = new b2Vec2 -}; -b2MouseJoint.prototype.InitVelocityConstraints = function(step) { - var b = this.m_bodyB; - var mass = b.GetMass(); - var omega = 2 * Math.PI * this.m_frequencyHz; - var d = 2 * mass * this.m_dampingRatio * omega; - var k = mass * omega * omega; - this.m_gamma = step.dt * (d + step.dt * k); - this.m_gamma = this.m_gamma != 0 ? 1 / this.m_gamma : 0; - this.m_beta = step.dt * k * this.m_gamma; - var tMat; - tMat = b.m_xf.R; - var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; - var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; - var tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - var invMass = b.m_invMass; - var invI = b.m_invI; - this.K1.col1.x = invMass; - this.K1.col2.x = 0; - this.K1.col1.y = 0; - this.K1.col2.y = invMass; - this.K2.col1.x = invI * rY * rY; - this.K2.col2.x = -invI * rX * rY; - this.K2.col1.y = -invI * rX * rY; - this.K2.col2.y = invI * rX * rX; - this.K.SetM(this.K1); - this.K.AddM(this.K2); - this.K.col1.x += this.m_gamma; - this.K.col2.y += this.m_gamma; - this.K.GetInverse(this.m_mass); - this.m_C.x = b.m_sweep.c.x + rX - this.m_target.x; - this.m_C.y = b.m_sweep.c.y + rY - this.m_target.y; - b.m_angularVelocity *= 0.98; - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - b.m_linearVelocity.x += invMass * this.m_impulse.x; - b.m_linearVelocity.y += invMass * this.m_impulse.y; - b.m_angularVelocity += invI * (rX * this.m_impulse.y - rY * this.m_impulse.x) -}; -b2MouseJoint.prototype.SolveVelocityConstraints = function(step) { - var b = this.m_bodyB; - var tMat; - var tX; - var tY; - tMat = b.m_xf.R; - var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; - var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; - tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - var CdotX = b.m_linearVelocity.x + -b.m_angularVelocity * rY; - var CdotY = b.m_linearVelocity.y + b.m_angularVelocity * rX; - tMat = this.m_mass; - tX = CdotX + this.m_beta * this.m_C.x + this.m_gamma * this.m_impulse.x; - tY = CdotY + this.m_beta * this.m_C.y + this.m_gamma * this.m_impulse.y; - var impulseX = -(tMat.col1.x * tX + tMat.col2.x * tY); - var impulseY = -(tMat.col1.y * tX + tMat.col2.y * tY); - var oldImpulseX = this.m_impulse.x; - var oldImpulseY = this.m_impulse.y; - this.m_impulse.x += impulseX; - this.m_impulse.y += impulseY; - var maxImpulse = step.dt * this.m_maxForce; - if(this.m_impulse.LengthSquared() > maxImpulse * maxImpulse) { - this.m_impulse.Multiply(maxImpulse / this.m_impulse.Length()) - } - impulseX = this.m_impulse.x - oldImpulseX; - impulseY = this.m_impulse.y - oldImpulseY; - b.m_linearVelocity.x += b.m_invMass * impulseX; - b.m_linearVelocity.y += b.m_invMass * impulseY; - b.m_angularVelocity += b.m_invI * (rX * impulseY - rY * impulseX) -}; -b2MouseJoint.prototype.SolvePositionConstraints = function(baumgarte) { - return true -}; -b2MouseJoint.prototype.GetAnchorA = function() { - return this.m_target -}; -b2MouseJoint.prototype.GetAnchorB = function() { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor) -}; -b2MouseJoint.prototype.GetReactionForce = function(inv_dt) { - return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y) -}; -b2MouseJoint.prototype.GetReactionTorque = function(inv_dt) { - return 0 -}; -b2MouseJoint.prototype.GetTarget = function() { - return this.m_target -}; -b2MouseJoint.prototype.SetTarget = function(target) { - if(this.m_bodyB.IsAwake() == false) { - this.m_bodyB.SetAwake(true) - } - this.m_target = target -}; -b2MouseJoint.prototype.GetMaxForce = function() { - return this.m_maxForce -}; -b2MouseJoint.prototype.SetMaxForce = function(maxForce) { - this.m_maxForce = maxForce -}; -b2MouseJoint.prototype.GetFrequency = function() { - return this.m_frequencyHz -}; -b2MouseJoint.prototype.SetFrequency = function(hz) { - this.m_frequencyHz = hz -}; -b2MouseJoint.prototype.GetDampingRatio = function() { - return this.m_dampingRatio -}; -b2MouseJoint.prototype.SetDampingRatio = function(ratio) { - this.m_dampingRatio = ratio -}; -b2MouseJoint.prototype.K = new b2Mat22; -b2MouseJoint.prototype.K1 = new b2Mat22; -b2MouseJoint.prototype.K2 = new b2Mat22; -b2MouseJoint.prototype.m_localAnchor = new b2Vec2; -b2MouseJoint.prototype.m_target = new b2Vec2; -b2MouseJoint.prototype.m_impulse = new b2Vec2; -b2MouseJoint.prototype.m_mass = new b2Mat22; -b2MouseJoint.prototype.m_C = new b2Vec2; -b2MouseJoint.prototype.m_maxForce = null; -b2MouseJoint.prototype.m_frequencyHz = null; -b2MouseJoint.prototype.m_dampingRatio = null; -b2MouseJoint.prototype.m_beta = null; -b2MouseJoint.prototype.m_gamma = null;var b2PrismaticJointDef = function() { - b2JointDef.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2PrismaticJointDef.prototype, b2JointDef.prototype); -b2PrismaticJointDef.prototype._super = b2JointDef.prototype; -b2PrismaticJointDef.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.type = b2Joint.e_prismaticJoint; - this.localAxisA.Set(1, 0); - this.referenceAngle = 0; - this.enableLimit = false; - this.lowerTranslation = 0; - this.upperTranslation = 0; - this.enableMotor = false; - this.maxMotorForce = 0; - this.motorSpeed = 0 -}; -b2PrismaticJointDef.prototype.__varz = function() { - this.localAnchorA = new b2Vec2; - this.localAnchorB = new b2Vec2; - this.localAxisA = new b2Vec2 -}; -b2PrismaticJointDef.prototype.Initialize = function(bA, bB, anchor, axis) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA = this.bodyA.GetLocalPoint(anchor); - this.localAnchorB = this.bodyB.GetLocalPoint(anchor); - this.localAxisA = this.bodyA.GetLocalVector(axis); - this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle() -}; -b2PrismaticJointDef.prototype.localAnchorA = new b2Vec2; -b2PrismaticJointDef.prototype.localAnchorB = new b2Vec2; -b2PrismaticJointDef.prototype.localAxisA = new b2Vec2; -b2PrismaticJointDef.prototype.referenceAngle = null; -b2PrismaticJointDef.prototype.enableLimit = null; -b2PrismaticJointDef.prototype.lowerTranslation = null; -b2PrismaticJointDef.prototype.upperTranslation = null; -b2PrismaticJointDef.prototype.enableMotor = null; -b2PrismaticJointDef.prototype.maxMotorForce = null; -b2PrismaticJointDef.prototype.motorSpeed = null;var b2TimeOfImpact = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2TimeOfImpact.prototype.__constructor = function() { -}; -b2TimeOfImpact.prototype.__varz = function() { -}; -b2TimeOfImpact.TimeOfImpact = function(input) { - ++b2TimeOfImpact.b2_toiCalls; - var proxyA = input.proxyA; - var proxyB = input.proxyB; - var sweepA = input.sweepA; - var sweepB = input.sweepB; - b2Settings.b2Assert(sweepA.t0 == sweepB.t0); - b2Settings.b2Assert(1 - sweepA.t0 > Number.MIN_VALUE); - var radius = proxyA.m_radius + proxyB.m_radius; - var tolerance = input.tolerance; - var alpha = 0; - var k_maxIterations = 1E3; - var iter = 0; - var target = 0; - b2TimeOfImpact.s_cache.count = 0; - b2TimeOfImpact.s_distanceInput.useRadii = false; - for(;;) { - sweepA.GetTransform(b2TimeOfImpact.s_xfA, alpha); - sweepB.GetTransform(b2TimeOfImpact.s_xfB, alpha); - b2TimeOfImpact.s_distanceInput.proxyA = proxyA; - b2TimeOfImpact.s_distanceInput.proxyB = proxyB; - b2TimeOfImpact.s_distanceInput.transformA = b2TimeOfImpact.s_xfA; - b2TimeOfImpact.s_distanceInput.transformB = b2TimeOfImpact.s_xfB; - b2Distance.Distance(b2TimeOfImpact.s_distanceOutput, b2TimeOfImpact.s_cache, b2TimeOfImpact.s_distanceInput); - if(b2TimeOfImpact.s_distanceOutput.distance <= 0) { - alpha = 1; - break - } - b2TimeOfImpact.s_fcn.Initialize(b2TimeOfImpact.s_cache, proxyA, b2TimeOfImpact.s_xfA, proxyB, b2TimeOfImpact.s_xfB); - var separation = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); - if(separation <= 0) { - alpha = 1; - break - } - if(iter == 0) { - if(separation > radius) { - target = b2Math.Max(radius - tolerance, 0.75 * radius) - }else { - target = b2Math.Max(separation - tolerance, 0.02 * radius) - } - } - if(separation - target < 0.5 * tolerance) { - if(iter == 0) { - alpha = 1; - break - } - break - } - var newAlpha = alpha; - var x1 = alpha; - var x2 = 1; - var f1 = separation; - sweepA.GetTransform(b2TimeOfImpact.s_xfA, x2); - sweepB.GetTransform(b2TimeOfImpact.s_xfB, x2); - var f2 = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); - if(f2 >= target) { - alpha = 1; - break - } - var rootIterCount = 0; - for(;;) { - var x; - if(rootIterCount & 1) { - x = x1 + (target - f1) * (x2 - x1) / (f2 - f1) - }else { - x = 0.5 * (x1 + x2) - } - sweepA.GetTransform(b2TimeOfImpact.s_xfA, x); - sweepB.GetTransform(b2TimeOfImpact.s_xfB, x); - var f = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); - if(b2Math.Abs(f - target) < 0.025 * tolerance) { - newAlpha = x; - break - } - if(f > target) { - x1 = x; - f1 = f - }else { - x2 = x; - f2 = f - } - ++rootIterCount; - ++b2TimeOfImpact.b2_toiRootIters; - if(rootIterCount == 50) { - break - } - } - b2TimeOfImpact.b2_toiMaxRootIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxRootIters, rootIterCount); - if(newAlpha < (1 + 100 * Number.MIN_VALUE) * alpha) { - break - } - alpha = newAlpha; - iter++; - ++b2TimeOfImpact.b2_toiIters; - if(iter == k_maxIterations) { - break - } - } - b2TimeOfImpact.b2_toiMaxIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxIters, iter); - return alpha -}; -b2TimeOfImpact.b2_toiCalls = 0; -b2TimeOfImpact.b2_toiIters = 0; -b2TimeOfImpact.b2_toiMaxIters = 0; -b2TimeOfImpact.b2_toiRootIters = 0; -b2TimeOfImpact.b2_toiMaxRootIters = 0; -b2TimeOfImpact.s_cache = new b2SimplexCache; -b2TimeOfImpact.s_distanceInput = new b2DistanceInput; -b2TimeOfImpact.s_xfA = new b2Transform; -b2TimeOfImpact.s_xfB = new b2Transform; -b2TimeOfImpact.s_fcn = new b2SeparationFunction; -b2TimeOfImpact.s_distanceOutput = new b2DistanceOutput;var b2GearJoint = function() { - b2Joint.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2GearJoint.prototype, b2Joint.prototype); -b2GearJoint.prototype._super = b2Joint.prototype; -b2GearJoint.prototype.__constructor = function(def) { - this._super.__constructor.apply(this, [def]); - var type1 = def.joint1.m_type; - var type2 = def.joint2.m_type; - this.m_revolute1 = null; - this.m_prismatic1 = null; - this.m_revolute2 = null; - this.m_prismatic2 = null; - var coordinate1; - var coordinate2; - this.m_ground1 = def.joint1.GetBodyA(); - this.m_bodyA = def.joint1.GetBodyB(); - if(type1 == b2Joint.e_revoluteJoint) { - this.m_revolute1 = def.joint1; - this.m_groundAnchor1.SetV(this.m_revolute1.m_localAnchor1); - this.m_localAnchor1.SetV(this.m_revolute1.m_localAnchor2); - coordinate1 = this.m_revolute1.GetJointAngle() - }else { - this.m_prismatic1 = def.joint1; - this.m_groundAnchor1.SetV(this.m_prismatic1.m_localAnchor1); - this.m_localAnchor1.SetV(this.m_prismatic1.m_localAnchor2); - coordinate1 = this.m_prismatic1.GetJointTranslation() - } - this.m_ground2 = def.joint2.GetBodyA(); - this.m_bodyB = def.joint2.GetBodyB(); - if(type2 == b2Joint.e_revoluteJoint) { - this.m_revolute2 = def.joint2; - this.m_groundAnchor2.SetV(this.m_revolute2.m_localAnchor1); - this.m_localAnchor2.SetV(this.m_revolute2.m_localAnchor2); - coordinate2 = this.m_revolute2.GetJointAngle() - }else { - this.m_prismatic2 = def.joint2; - this.m_groundAnchor2.SetV(this.m_prismatic2.m_localAnchor1); - this.m_localAnchor2.SetV(this.m_prismatic2.m_localAnchor2); - coordinate2 = this.m_prismatic2.GetJointTranslation() - } - this.m_ratio = def.ratio; - this.m_constant = coordinate1 + this.m_ratio * coordinate2; - this.m_impulse = 0 -}; -b2GearJoint.prototype.__varz = function() { - this.m_groundAnchor1 = new b2Vec2; - this.m_groundAnchor2 = new b2Vec2; - this.m_localAnchor1 = new b2Vec2; - this.m_localAnchor2 = new b2Vec2; - this.m_J = new b2Jacobian -}; -b2GearJoint.prototype.InitVelocityConstraints = function(step) { - var g1 = this.m_ground1; - var g2 = this.m_ground2; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var ugX; - var ugY; - var rX; - var rY; - var tMat; - var tVec; - var crug; - var tX; - var K = 0; - this.m_J.SetZero(); - if(this.m_revolute1) { - this.m_J.angularA = -1; - K += bA.m_invI - }else { - tMat = g1.m_xf.R; - tVec = this.m_prismatic1.m_localXAxis1; - ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = bA.m_xf.R; - rX = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - rY = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - crug = rX * ugY - rY * ugX; - this.m_J.linearA.Set(-ugX, -ugY); - this.m_J.angularA = -crug; - K += bA.m_invMass + bA.m_invI * crug * crug - } - if(this.m_revolute2) { - this.m_J.angularB = -this.m_ratio; - K += this.m_ratio * this.m_ratio * bB.m_invI - }else { - tMat = g2.m_xf.R; - tVec = this.m_prismatic2.m_localXAxis1; - ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = bB.m_xf.R; - rX = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - rY = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - crug = rX * ugY - rY * ugX; - this.m_J.linearB.Set(-this.m_ratio * ugX, -this.m_ratio * ugY); - this.m_J.angularB = -this.m_ratio * crug; - K += this.m_ratio * this.m_ratio * (bB.m_invMass + bB.m_invI * crug * crug) - } - this.m_mass = K > 0 ? 1 / K : 0; - if(step.warmStarting) { - bA.m_linearVelocity.x += bA.m_invMass * this.m_impulse * this.m_J.linearA.x; - bA.m_linearVelocity.y += bA.m_invMass * this.m_impulse * this.m_J.linearA.y; - bA.m_angularVelocity += bA.m_invI * this.m_impulse * this.m_J.angularA; - bB.m_linearVelocity.x += bB.m_invMass * this.m_impulse * this.m_J.linearB.x; - bB.m_linearVelocity.y += bB.m_invMass * this.m_impulse * this.m_J.linearB.y; - bB.m_angularVelocity += bB.m_invI * this.m_impulse * this.m_J.angularB - }else { - this.m_impulse = 0 - } -}; -b2GearJoint.prototype.SolveVelocityConstraints = function(step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var Cdot = this.m_J.Compute(bA.m_linearVelocity, bA.m_angularVelocity, bB.m_linearVelocity, bB.m_angularVelocity); - var impulse = -this.m_mass * Cdot; - this.m_impulse += impulse; - bA.m_linearVelocity.x += bA.m_invMass * impulse * this.m_J.linearA.x; - bA.m_linearVelocity.y += bA.m_invMass * impulse * this.m_J.linearA.y; - bA.m_angularVelocity += bA.m_invI * impulse * this.m_J.angularA; - bB.m_linearVelocity.x += bB.m_invMass * impulse * this.m_J.linearB.x; - bB.m_linearVelocity.y += bB.m_invMass * impulse * this.m_J.linearB.y; - bB.m_angularVelocity += bB.m_invI * impulse * this.m_J.angularB -}; -b2GearJoint.prototype.SolvePositionConstraints = function(baumgarte) { - var linearError = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var coordinate1; - var coordinate2; - if(this.m_revolute1) { - coordinate1 = this.m_revolute1.GetJointAngle() - }else { - coordinate1 = this.m_prismatic1.GetJointTranslation() - } - if(this.m_revolute2) { - coordinate2 = this.m_revolute2.GetJointAngle() - }else { - coordinate2 = this.m_prismatic2.GetJointTranslation() - } - var C = this.m_constant - (coordinate1 + this.m_ratio * coordinate2); - var impulse = -this.m_mass * C; - bA.m_sweep.c.x += bA.m_invMass * impulse * this.m_J.linearA.x; - bA.m_sweep.c.y += bA.m_invMass * impulse * this.m_J.linearA.y; - bA.m_sweep.a += bA.m_invI * impulse * this.m_J.angularA; - bB.m_sweep.c.x += bB.m_invMass * impulse * this.m_J.linearB.x; - bB.m_sweep.c.y += bB.m_invMass * impulse * this.m_J.linearB.y; - bB.m_sweep.a += bB.m_invI * impulse * this.m_J.angularB; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return linearError < b2Settings.b2_linearSlop -}; -b2GearJoint.prototype.GetAnchorA = function() { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1) -}; -b2GearJoint.prototype.GetAnchorB = function() { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2) -}; -b2GearJoint.prototype.GetReactionForce = function(inv_dt) { - return new b2Vec2(inv_dt * this.m_impulse * this.m_J.linearB.x, inv_dt * this.m_impulse * this.m_J.linearB.y) -}; -b2GearJoint.prototype.GetReactionTorque = function(inv_dt) { - var tMat = this.m_bodyB.m_xf.R; - var rX = this.m_localAnchor1.x - this.m_bodyB.m_sweep.localCenter.x; - var rY = this.m_localAnchor1.y - this.m_bodyB.m_sweep.localCenter.y; - var tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - var PX = this.m_impulse * this.m_J.linearB.x; - var PY = this.m_impulse * this.m_J.linearB.y; - return inv_dt * (this.m_impulse * this.m_J.angularB - rX * PY + rY * PX) -}; -b2GearJoint.prototype.GetRatio = function() { - return this.m_ratio -}; -b2GearJoint.prototype.SetRatio = function(ratio) { - this.m_ratio = ratio -}; -b2GearJoint.prototype.m_ground1 = null; -b2GearJoint.prototype.m_ground2 = null; -b2GearJoint.prototype.m_revolute1 = null; -b2GearJoint.prototype.m_prismatic1 = null; -b2GearJoint.prototype.m_revolute2 = null; -b2GearJoint.prototype.m_prismatic2 = null; -b2GearJoint.prototype.m_groundAnchor1 = new b2Vec2; -b2GearJoint.prototype.m_groundAnchor2 = new b2Vec2; -b2GearJoint.prototype.m_localAnchor1 = new b2Vec2; -b2GearJoint.prototype.m_localAnchor2 = new b2Vec2; -b2GearJoint.prototype.m_J = new b2Jacobian; -b2GearJoint.prototype.m_constant = null; -b2GearJoint.prototype.m_ratio = null; -b2GearJoint.prototype.m_mass = null; -b2GearJoint.prototype.m_impulse = null;var b2TOIInput = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2TOIInput.prototype.__constructor = function() { -}; -b2TOIInput.prototype.__varz = function() { - this.proxyA = new b2DistanceProxy; - this.proxyB = new b2DistanceProxy; - this.sweepA = new b2Sweep; - this.sweepB = new b2Sweep -}; -b2TOIInput.prototype.proxyA = new b2DistanceProxy; -b2TOIInput.prototype.proxyB = new b2DistanceProxy; -b2TOIInput.prototype.sweepA = new b2Sweep; -b2TOIInput.prototype.sweepB = new b2Sweep; -b2TOIInput.prototype.tolerance = null;var b2RevoluteJointDef = function() { - b2JointDef.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2RevoluteJointDef.prototype, b2JointDef.prototype); -b2RevoluteJointDef.prototype._super = b2JointDef.prototype; -b2RevoluteJointDef.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.type = b2Joint.e_revoluteJoint; - this.localAnchorA.Set(0, 0); - this.localAnchorB.Set(0, 0); - this.referenceAngle = 0; - this.lowerAngle = 0; - this.upperAngle = 0; - this.maxMotorTorque = 0; - this.motorSpeed = 0; - this.enableLimit = false; - this.enableMotor = false -}; -b2RevoluteJointDef.prototype.__varz = function() { - this.localAnchorA = new b2Vec2; - this.localAnchorB = new b2Vec2 -}; -b2RevoluteJointDef.prototype.Initialize = function(bA, bB, anchor) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA = this.bodyA.GetLocalPoint(anchor); - this.localAnchorB = this.bodyB.GetLocalPoint(anchor); - this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle() -}; -b2RevoluteJointDef.prototype.localAnchorA = new b2Vec2; -b2RevoluteJointDef.prototype.localAnchorB = new b2Vec2; -b2RevoluteJointDef.prototype.referenceAngle = null; -b2RevoluteJointDef.prototype.enableLimit = null; -b2RevoluteJointDef.prototype.lowerAngle = null; -b2RevoluteJointDef.prototype.upperAngle = null; -b2RevoluteJointDef.prototype.enableMotor = null; -b2RevoluteJointDef.prototype.motorSpeed = null; -b2RevoluteJointDef.prototype.maxMotorTorque = null;var b2MouseJointDef = function() { - b2JointDef.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2MouseJointDef.prototype, b2JointDef.prototype); -b2MouseJointDef.prototype._super = b2JointDef.prototype; -b2MouseJointDef.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments); - this.type = b2Joint.e_mouseJoint; - this.maxForce = 0; - this.frequencyHz = 5; - this.dampingRatio = 0.7 -}; -b2MouseJointDef.prototype.__varz = function() { - this.target = new b2Vec2 -}; -b2MouseJointDef.prototype.target = new b2Vec2; -b2MouseJointDef.prototype.maxForce = null; -b2MouseJointDef.prototype.frequencyHz = null; -b2MouseJointDef.prototype.dampingRatio = null;var b2Contact = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Contact.prototype.__constructor = function() { -}; -b2Contact.prototype.__varz = function() { - this.m_nodeA = new b2ContactEdge; - this.m_nodeB = new b2ContactEdge; - this.m_manifold = new b2Manifold; - this.m_oldManifold = new b2Manifold -}; -b2Contact.s_input = new b2TOIInput; -b2Contact.e_sensorFlag = 1; -b2Contact.e_continuousFlag = 2; -b2Contact.e_islandFlag = 4; -b2Contact.e_toiFlag = 8; -b2Contact.e_touchingFlag = 16; -b2Contact.e_enabledFlag = 32; -b2Contact.e_filterFlag = 64; -b2Contact.prototype.Reset = function(fixtureA, fixtureB) { - this.m_flags = b2Contact.e_enabledFlag; - if(!fixtureA || !fixtureB) { - this.m_fixtureA = null; - this.m_fixtureB = null; - return - } - if(fixtureA.IsSensor() || fixtureB.IsSensor()) { - this.m_flags |= b2Contact.e_sensorFlag - } - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if(bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { - this.m_flags |= b2Contact.e_continuousFlag - } - this.m_fixtureA = fixtureA; - this.m_fixtureB = fixtureB; - this.m_manifold.m_pointCount = 0; - this.m_prev = null; - this.m_next = null; - this.m_nodeA.contact = null; - this.m_nodeA.prev = null; - this.m_nodeA.next = null; - this.m_nodeA.other = null; - this.m_nodeB.contact = null; - this.m_nodeB.prev = null; - this.m_nodeB.next = null; - this.m_nodeB.other = null -}; -b2Contact.prototype.Update = function(listener) { - var tManifold = this.m_oldManifold; - this.m_oldManifold = this.m_manifold; - this.m_manifold = tManifold; - this.m_flags |= b2Contact.e_enabledFlag; - var touching = false; - var wasTouching = (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag; - var bodyA = this.m_fixtureA.m_body; - var bodyB = this.m_fixtureB.m_body; - var aabbOverlap = this.m_fixtureA.m_aabb.TestOverlap(this.m_fixtureB.m_aabb); - if(this.m_flags & b2Contact.e_sensorFlag) { - if(aabbOverlap) { - var shapeA = this.m_fixtureA.GetShape(); - var shapeB = this.m_fixtureB.GetShape(); - var xfA = bodyA.GetTransform(); - var xfB = bodyB.GetTransform(); - touching = b2Shape.TestOverlap(shapeA, xfA, shapeB, xfB) - } - this.m_manifold.m_pointCount = 0 - }else { - if(bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { - this.m_flags |= b2Contact.e_continuousFlag - }else { - this.m_flags &= ~b2Contact.e_continuousFlag - } - if(aabbOverlap) { - this.Evaluate(); - touching = this.m_manifold.m_pointCount > 0; - for(var i = 0;i < this.m_manifold.m_pointCount;++i) { - var mp2 = this.m_manifold.m_points[i]; - mp2.m_normalImpulse = 0; - mp2.m_tangentImpulse = 0; - var id2 = mp2.m_id; - for(var j = 0;j < this.m_oldManifold.m_pointCount;++j) { - var mp1 = this.m_oldManifold.m_points[j]; - if(mp1.m_id.key == id2.key) { - mp2.m_normalImpulse = mp1.m_normalImpulse; - mp2.m_tangentImpulse = mp1.m_tangentImpulse; - break - } - } - } - }else { - this.m_manifold.m_pointCount = 0 - } - if(touching != wasTouching) { - bodyA.SetAwake(true); - bodyB.SetAwake(true) - } - } - if(touching) { - this.m_flags |= b2Contact.e_touchingFlag - }else { - this.m_flags &= ~b2Contact.e_touchingFlag - } - if(wasTouching == false && touching == true) { - listener.BeginContact(this) - } - if(wasTouching == true && touching == false) { - listener.EndContact(this) - } - if((this.m_flags & b2Contact.e_sensorFlag) == 0) { - listener.PreSolve(this, this.m_oldManifold) - } -}; -b2Contact.prototype.Evaluate = function() { -}; -b2Contact.prototype.ComputeTOI = function(sweepA, sweepB) { - b2Contact.s_input.proxyA.Set(this.m_fixtureA.GetShape()); - b2Contact.s_input.proxyB.Set(this.m_fixtureB.GetShape()); - b2Contact.s_input.sweepA = sweepA; - b2Contact.s_input.sweepB = sweepB; - b2Contact.s_input.tolerance = b2Settings.b2_linearSlop; - return b2TimeOfImpact.TimeOfImpact(b2Contact.s_input) -}; -b2Contact.prototype.GetManifold = function() { - return this.m_manifold -}; -b2Contact.prototype.GetWorldManifold = function(worldManifold) { - var bodyA = this.m_fixtureA.GetBody(); - var bodyB = this.m_fixtureB.GetBody(); - var shapeA = this.m_fixtureA.GetShape(); - var shapeB = this.m_fixtureB.GetShape(); - worldManifold.Initialize(this.m_manifold, bodyA.GetTransform(), shapeA.m_radius, bodyB.GetTransform(), shapeB.m_radius) -}; -b2Contact.prototype.IsTouching = function() { - return(this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag -}; -b2Contact.prototype.IsContinuous = function() { - return(this.m_flags & b2Contact.e_continuousFlag) == b2Contact.e_continuousFlag -}; -b2Contact.prototype.SetSensor = function(sensor) { - if(sensor) { - this.m_flags |= b2Contact.e_sensorFlag - }else { - this.m_flags &= ~b2Contact.e_sensorFlag - } -}; -b2Contact.prototype.IsSensor = function() { - return(this.m_flags & b2Contact.e_sensorFlag) == b2Contact.e_sensorFlag -}; -b2Contact.prototype.SetEnabled = function(flag) { - if(flag) { - this.m_flags |= b2Contact.e_enabledFlag - }else { - this.m_flags &= ~b2Contact.e_enabledFlag - } -}; -b2Contact.prototype.IsEnabled = function() { - return(this.m_flags & b2Contact.e_enabledFlag) == b2Contact.e_enabledFlag -}; -b2Contact.prototype.GetNext = function() { - return this.m_next -}; -b2Contact.prototype.GetFixtureA = function() { - return this.m_fixtureA -}; -b2Contact.prototype.GetFixtureB = function() { - return this.m_fixtureB -}; -b2Contact.prototype.FlagForFiltering = function() { - this.m_flags |= b2Contact.e_filterFlag -}; -b2Contact.prototype.m_flags = 0; -b2Contact.prototype.m_prev = null; -b2Contact.prototype.m_next = null; -b2Contact.prototype.m_nodeA = new b2ContactEdge; -b2Contact.prototype.m_nodeB = new b2ContactEdge; -b2Contact.prototype.m_fixtureA = null; -b2Contact.prototype.m_fixtureB = null; -b2Contact.prototype.m_manifold = new b2Manifold; -b2Contact.prototype.m_oldManifold = new b2Manifold; -b2Contact.prototype.m_toi = null;var b2ContactConstraint = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactConstraint.prototype.__constructor = function() { - this.points = new Array(b2Settings.b2_maxManifoldPoints); - for(var i = 0;i < b2Settings.b2_maxManifoldPoints;i++) { - this.points[i] = new b2ContactConstraintPoint - } -}; -b2ContactConstraint.prototype.__varz = function() { - this.localPlaneNormal = new b2Vec2; - this.localPoint = new b2Vec2; - this.normal = new b2Vec2; - this.normalMass = new b2Mat22; - this.K = new b2Mat22 -}; -b2ContactConstraint.prototype.points = null; -b2ContactConstraint.prototype.localPlaneNormal = new b2Vec2; -b2ContactConstraint.prototype.localPoint = new b2Vec2; -b2ContactConstraint.prototype.normal = new b2Vec2; -b2ContactConstraint.prototype.normalMass = new b2Mat22; -b2ContactConstraint.prototype.K = new b2Mat22; -b2ContactConstraint.prototype.bodyA = null; -b2ContactConstraint.prototype.bodyB = null; -b2ContactConstraint.prototype.type = 0; -b2ContactConstraint.prototype.radius = null; -b2ContactConstraint.prototype.friction = null; -b2ContactConstraint.prototype.restitution = null; -b2ContactConstraint.prototype.pointCount = 0; -b2ContactConstraint.prototype.manifold = null;var b2ContactResult = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactResult.prototype.__constructor = function() { -}; -b2ContactResult.prototype.__varz = function() { - this.position = new b2Vec2; - this.normal = new b2Vec2; - this.id = new b2ContactID -}; -b2ContactResult.prototype.shape1 = null; -b2ContactResult.prototype.shape2 = null; -b2ContactResult.prototype.position = new b2Vec2; -b2ContactResult.prototype.normal = new b2Vec2; -b2ContactResult.prototype.normalImpulse = null; -b2ContactResult.prototype.tangentImpulse = null; -b2ContactResult.prototype.id = new b2ContactID;var b2PolygonContact = function() { - b2Contact.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2PolygonContact.prototype, b2Contact.prototype); -b2PolygonContact.prototype._super = b2Contact.prototype; -b2PolygonContact.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2PolygonContact.prototype.__varz = function() { -}; -b2PolygonContact.Create = function(allocator) { - return new b2PolygonContact -}; -b2PolygonContact.Destroy = function(contact, allocator) { -}; -b2PolygonContact.prototype.Evaluate = function() { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - b2Collision.CollidePolygons(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) -}; -b2PolygonContact.prototype.Reset = function(fixtureA, fixtureB) { - this._super.Reset.apply(this, [fixtureA, fixtureB]) -};var ClipVertex = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -ClipVertex.prototype.__constructor = function() { -}; -ClipVertex.prototype.__varz = function() { - this.v = new b2Vec2; - this.id = new b2ContactID -}; -ClipVertex.prototype.Set = function(other) { - this.v.SetV(other.v); - this.id.Set(other.id) -}; -ClipVertex.prototype.v = new b2Vec2; -ClipVertex.prototype.id = new b2ContactID;var b2ContactFilter = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactFilter.prototype.__constructor = function() { -}; -b2ContactFilter.prototype.__varz = function() { -}; -b2ContactFilter.b2_defaultFilter = new b2ContactFilter; -b2ContactFilter.prototype.ShouldCollide = function(fixtureA, fixtureB) { - var filter1 = fixtureA.GetFilterData(); - var filter2 = fixtureB.GetFilterData(); - if(filter1.groupIndex == filter2.groupIndex && filter1.groupIndex != 0) { - return filter1.groupIndex > 0 - } - var collide = (filter1.maskBits & filter2.categoryBits) != 0 && (filter1.categoryBits & filter2.maskBits) != 0; - return collide -}; -b2ContactFilter.prototype.RayCollide = function(userData, fixture) { - if(!userData) { - return true - } - return this.ShouldCollide(userData, fixture) -};var b2NullContact = function() { - b2Contact.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2NullContact.prototype, b2Contact.prototype); -b2NullContact.prototype._super = b2Contact.prototype; -b2NullContact.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2NullContact.prototype.__varz = function() { -}; -b2NullContact.prototype.Evaluate = function() { -};var b2ContactListener = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactListener.prototype.__constructor = function() { -}; -b2ContactListener.prototype.__varz = function() { -}; -b2ContactListener.b2_defaultListener = new b2ContactListener; -b2ContactListener.prototype.BeginContact = function(contact) { -}; -b2ContactListener.prototype.EndContact = function(contact) { -}; -b2ContactListener.prototype.PreSolve = function(contact, oldManifold) { -}; -b2ContactListener.prototype.PostSolve = function(contact, impulse) { -};var b2Island = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Island.prototype.__constructor = function() { - this.m_bodies = new Array; - this.m_contacts = new Array; - this.m_joints = new Array -}; -b2Island.prototype.__varz = function() { -}; -b2Island.s_impulse = new b2ContactImpulse; -b2Island.prototype.Initialize = function(bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) { - var i = 0; - this.m_bodyCapacity = bodyCapacity; - this.m_contactCapacity = contactCapacity; - this.m_jointCapacity = jointCapacity; - this.m_bodyCount = 0; - this.m_contactCount = 0; - this.m_jointCount = 0; - this.m_allocator = allocator; - this.m_listener = listener; - this.m_contactSolver = contactSolver; - for(i = this.m_bodies.length;i < bodyCapacity;i++) { - this.m_bodies[i] = null - } - for(i = this.m_contacts.length;i < contactCapacity;i++) { - this.m_contacts[i] = null - } - for(i = this.m_joints.length;i < jointCapacity;i++) { - this.m_joints[i] = null - } -}; -b2Island.prototype.Clear = function() { - this.m_bodyCount = 0; - this.m_contactCount = 0; - this.m_jointCount = 0 -}; -b2Island.prototype.Solve = function(step, gravity, allowSleep) { - var i = 0; - var j = 0; - var b; - var joint; - for(i = 0;i < this.m_bodyCount;++i) { - b = this.m_bodies[i]; - if(b.GetType() != b2Body.b2_dynamicBody) { - continue - } - b.m_linearVelocity.x += step.dt * (gravity.x + b.m_invMass * b.m_force.x); - b.m_linearVelocity.y += step.dt * (gravity.y + b.m_invMass * b.m_force.y); - b.m_angularVelocity += step.dt * b.m_invI * b.m_torque; - b.m_linearVelocity.Multiply(b2Math.Clamp(1 - step.dt * b.m_linearDamping, 0, 1)); - b.m_angularVelocity *= b2Math.Clamp(1 - step.dt * b.m_angularDamping, 0, 1) - } - this.m_contactSolver.Initialize(step, this.m_contacts, this.m_contactCount, this.m_allocator); - var contactSolver = this.m_contactSolver; - contactSolver.InitVelocityConstraints(step); - for(i = 0;i < this.m_jointCount;++i) { - joint = this.m_joints[i]; - joint.InitVelocityConstraints(step) - } - for(i = 0;i < step.velocityIterations;++i) { - for(j = 0;j < this.m_jointCount;++j) { - joint = this.m_joints[j]; - joint.SolveVelocityConstraints(step) - } - contactSolver.SolveVelocityConstraints() - } - for(i = 0;i < this.m_jointCount;++i) { - joint = this.m_joints[i]; - joint.FinalizeVelocityConstraints() - } - contactSolver.FinalizeVelocityConstraints(); - for(i = 0;i < this.m_bodyCount;++i) { - b = this.m_bodies[i]; - if(b.GetType() == b2Body.b2_staticBody) { - continue - } - var translationX = step.dt * b.m_linearVelocity.x; - var translationY = step.dt * b.m_linearVelocity.y; - if(translationX * translationX + translationY * translationY > b2Settings.b2_maxTranslationSquared) { - b.m_linearVelocity.Normalize(); - b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * step.inv_dt; - b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * step.inv_dt - } - var rotation = step.dt * b.m_angularVelocity; - if(rotation * rotation > b2Settings.b2_maxRotationSquared) { - if(b.m_angularVelocity < 0) { - b.m_angularVelocity = -b2Settings.b2_maxRotation * step.inv_dt - }else { - b.m_angularVelocity = b2Settings.b2_maxRotation * step.inv_dt - } - } - b.m_sweep.c0.SetV(b.m_sweep.c); - b.m_sweep.a0 = b.m_sweep.a; - b.m_sweep.c.x += step.dt * b.m_linearVelocity.x; - b.m_sweep.c.y += step.dt * b.m_linearVelocity.y; - b.m_sweep.a += step.dt * b.m_angularVelocity; - b.SynchronizeTransform() - } - for(i = 0;i < step.positionIterations;++i) { - var contactsOkay = contactSolver.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); - var jointsOkay = true; - for(j = 0;j < this.m_jointCount;++j) { - joint = this.m_joints[j]; - var jointOkay = joint.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); - jointsOkay = jointsOkay && jointOkay - } - if(contactsOkay && jointsOkay) { - break - } - } - this.Report(contactSolver.m_constraints); - if(allowSleep) { - var minSleepTime = Number.MAX_VALUE; - var linTolSqr = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance; - var angTolSqr = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance; - for(i = 0;i < this.m_bodyCount;++i) { - b = this.m_bodies[i]; - if(b.GetType() == b2Body.b2_staticBody) { - continue - } - if((b.m_flags & b2Body.e_allowSleepFlag) == 0) { - b.m_sleepTime = 0; - minSleepTime = 0 - } - if((b.m_flags & b2Body.e_allowSleepFlag) == 0 || b.m_angularVelocity * b.m_angularVelocity > angTolSqr || b2Math.Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr) { - b.m_sleepTime = 0; - minSleepTime = 0 - }else { - b.m_sleepTime += step.dt; - minSleepTime = b2Math.Min(minSleepTime, b.m_sleepTime) - } - } - if(minSleepTime >= b2Settings.b2_timeToSleep) { - for(i = 0;i < this.m_bodyCount;++i) { - b = this.m_bodies[i]; - b.SetAwake(false) - } - } - } -}; -b2Island.prototype.SolveTOI = function(subStep) { - var i = 0; - var j = 0; - this.m_contactSolver.Initialize(subStep, this.m_contacts, this.m_contactCount, this.m_allocator); - var contactSolver = this.m_contactSolver; - for(i = 0;i < this.m_jointCount;++i) { - this.m_joints[i].InitVelocityConstraints(subStep) - } - for(i = 0;i < subStep.velocityIterations;++i) { - contactSolver.SolveVelocityConstraints(); - for(j = 0;j < this.m_jointCount;++j) { - this.m_joints[j].SolveVelocityConstraints(subStep) - } - } - for(i = 0;i < this.m_bodyCount;++i) { - var b = this.m_bodies[i]; - if(b.GetType() == b2Body.b2_staticBody) { - continue - } - var translationX = subStep.dt * b.m_linearVelocity.x; - var translationY = subStep.dt * b.m_linearVelocity.y; - if(translationX * translationX + translationY * translationY > b2Settings.b2_maxTranslationSquared) { - b.m_linearVelocity.Normalize(); - b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * subStep.inv_dt; - b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * subStep.inv_dt - } - var rotation = subStep.dt * b.m_angularVelocity; - if(rotation * rotation > b2Settings.b2_maxRotationSquared) { - if(b.m_angularVelocity < 0) { - b.m_angularVelocity = -b2Settings.b2_maxRotation * subStep.inv_dt - }else { - b.m_angularVelocity = b2Settings.b2_maxRotation * subStep.inv_dt - } - } - b.m_sweep.c0.SetV(b.m_sweep.c); - b.m_sweep.a0 = b.m_sweep.a; - b.m_sweep.c.x += subStep.dt * b.m_linearVelocity.x; - b.m_sweep.c.y += subStep.dt * b.m_linearVelocity.y; - b.m_sweep.a += subStep.dt * b.m_angularVelocity; - b.SynchronizeTransform() - } - var k_toiBaumgarte = 0.75; - for(i = 0;i < subStep.positionIterations;++i) { - var contactsOkay = contactSolver.SolvePositionConstraints(k_toiBaumgarte); - var jointsOkay = true; - for(j = 0;j < this.m_jointCount;++j) { - var jointOkay = this.m_joints[j].SolvePositionConstraints(b2Settings.b2_contactBaumgarte); - jointsOkay = jointsOkay && jointOkay - } - if(contactsOkay && jointsOkay) { - break - } - } - this.Report(contactSolver.m_constraints) -}; -b2Island.prototype.Report = function(constraints) { - if(this.m_listener == null) { - return - } - for(var i = 0;i < this.m_contactCount;++i) { - var c = this.m_contacts[i]; - var cc = constraints[i]; - for(var j = 0;j < cc.pointCount;++j) { - b2Island.s_impulse.normalImpulses[j] = cc.points[j].normalImpulse; - b2Island.s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse - } - this.m_listener.PostSolve(c, b2Island.s_impulse) - } -}; -b2Island.prototype.AddBody = function(body) { - body.m_islandIndex = this.m_bodyCount; - this.m_bodies[this.m_bodyCount++] = body -}; -b2Island.prototype.AddContact = function(contact) { - this.m_contacts[this.m_contactCount++] = contact -}; -b2Island.prototype.AddJoint = function(joint) { - this.m_joints[this.m_jointCount++] = joint -}; -b2Island.prototype.m_allocator = null; -b2Island.prototype.m_listener = null; -b2Island.prototype.m_contactSolver = null; -b2Island.prototype.m_bodies = null; -b2Island.prototype.m_contacts = null; -b2Island.prototype.m_joints = null; -b2Island.prototype.m_bodyCount = 0; -b2Island.prototype.m_jointCount = 0; -b2Island.prototype.m_contactCount = 0; -b2Island.prototype.m_bodyCapacity = 0; -b2Island.prototype.m_contactCapacity = 0; -b2Island.prototype.m_jointCapacity = 0;var b2PolyAndEdgeContact = function() { - b2Contact.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2PolyAndEdgeContact.prototype, b2Contact.prototype); -b2PolyAndEdgeContact.prototype._super = b2Contact.prototype; -b2PolyAndEdgeContact.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2PolyAndEdgeContact.prototype.__varz = function() { -}; -b2PolyAndEdgeContact.Create = function(allocator) { - return new b2PolyAndEdgeContact -}; -b2PolyAndEdgeContact.Destroy = function(contact, allocator) { -}; -b2PolyAndEdgeContact.prototype.Evaluate = function() { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - this.b2CollidePolyAndEdge(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) -}; -b2PolyAndEdgeContact.prototype.b2CollidePolyAndEdge = function(manifold, polygon, xf1, edge, xf2) { -}; -b2PolyAndEdgeContact.prototype.Reset = function(fixtureA, fixtureB) { - this._super.Reset.apply(this, [fixtureA, fixtureB]); - b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); - b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_edgeShape) -};var b2Collision = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2Collision.prototype.__constructor = function() { -}; -b2Collision.prototype.__varz = function() { -}; -b2Collision.MakeClipPointVector = function() { - var r = new Array(2); - r[0] = new ClipVertex; - r[1] = new ClipVertex; - return r -}; -b2Collision.ClipSegmentToLine = function(vOut, vIn, normal, offset) { - var cv; - var numOut = 0; - cv = vIn[0]; - var vIn0 = cv.v; - cv = vIn[1]; - var vIn1 = cv.v; - var distance0 = normal.x * vIn0.x + normal.y * vIn0.y - offset; - var distance1 = normal.x * vIn1.x + normal.y * vIn1.y - offset; - if(distance0 <= 0) { - vOut[numOut++].Set(vIn[0]) - } - if(distance1 <= 0) { - vOut[numOut++].Set(vIn[1]) - } - if(distance0 * distance1 < 0) { - var interp = distance0 / (distance0 - distance1); - cv = vOut[numOut]; - var tVec = cv.v; - tVec.x = vIn0.x + interp * (vIn1.x - vIn0.x); - tVec.y = vIn0.y + interp * (vIn1.y - vIn0.y); - cv = vOut[numOut]; - var cv2; - if(distance0 > 0) { - cv2 = vIn[0]; - cv.id = cv2.id - }else { - cv2 = vIn[1]; - cv.id = cv2.id - } - ++numOut - } - return numOut -}; -b2Collision.EdgeSeparation = function(poly1, xf1, edge1, poly2, xf2) { - var count1 = poly1.m_vertexCount; - var vertices1 = poly1.m_vertices; - var normals1 = poly1.m_normals; - var count2 = poly2.m_vertexCount; - var vertices2 = poly2.m_vertices; - var tMat; - var tVec; - tMat = xf1.R; - tVec = normals1[edge1]; - var normal1WorldX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - var normal1WorldY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xf2.R; - var normal1X = tMat.col1.x * normal1WorldX + tMat.col1.y * normal1WorldY; - var normal1Y = tMat.col2.x * normal1WorldX + tMat.col2.y * normal1WorldY; - var index = 0; - var minDot = Number.MAX_VALUE; - for(var i = 0;i < count2;++i) { - tVec = vertices2[i]; - var dot = tVec.x * normal1X + tVec.y * normal1Y; - if(dot < minDot) { - minDot = dot; - index = i - } - } - tVec = vertices1[edge1]; - tMat = xf1.R; - var v1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var v1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = vertices2[index]; - tMat = xf2.R; - var v2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var v2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - v2X -= v1X; - v2Y -= v1Y; - var separation = v2X * normal1WorldX + v2Y * normal1WorldY; - return separation -}; -b2Collision.FindMaxSeparation = function(edgeIndex, poly1, xf1, poly2, xf2) { - var count1 = poly1.m_vertexCount; - var normals1 = poly1.m_normals; - var tVec; - var tMat; - tMat = xf2.R; - tVec = poly2.m_centroid; - var dX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var dY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf1.R; - tVec = poly1.m_centroid; - dX -= xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - dY -= xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var dLocal1X = dX * xf1.R.col1.x + dY * xf1.R.col1.y; - var dLocal1Y = dX * xf1.R.col2.x + dY * xf1.R.col2.y; - var edge = 0; - var maxDot = -Number.MAX_VALUE; - for(var i = 0;i < count1;++i) { - tVec = normals1[i]; - var dot = tVec.x * dLocal1X + tVec.y * dLocal1Y; - if(dot > maxDot) { - maxDot = dot; - edge = i - } - } - var s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2); - var prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1; - var sPrev = b2Collision.EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2); - var nextEdge = edge + 1 < count1 ? edge + 1 : 0; - var sNext = b2Collision.EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2); - var bestEdge = 0; - var bestSeparation; - var increment = 0; - if(sPrev > s && sPrev > sNext) { - increment = -1; - bestEdge = prevEdge; - bestSeparation = sPrev - }else { - if(sNext > s) { - increment = 1; - bestEdge = nextEdge; - bestSeparation = sNext - }else { - edgeIndex[0] = edge; - return s - } - } - while(true) { - if(increment == -1) { - edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1 - }else { - edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0 - } - s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2); - if(s > bestSeparation) { - bestEdge = edge; - bestSeparation = s - }else { - break - } - } - edgeIndex[0] = bestEdge; - return bestSeparation -}; -b2Collision.FindIncidentEdge = function(c, poly1, xf1, edge1, poly2, xf2) { - var count1 = poly1.m_vertexCount; - var normals1 = poly1.m_normals; - var count2 = poly2.m_vertexCount; - var vertices2 = poly2.m_vertices; - var normals2 = poly2.m_normals; - var tMat; - var tVec; - tMat = xf1.R; - tVec = normals1[edge1]; - var normal1X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - var normal1Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xf2.R; - var tX = tMat.col1.x * normal1X + tMat.col1.y * normal1Y; - normal1Y = tMat.col2.x * normal1X + tMat.col2.y * normal1Y; - normal1X = tX; - var index = 0; - var minDot = Number.MAX_VALUE; - for(var i = 0;i < count2;++i) { - tVec = normals2[i]; - var dot = normal1X * tVec.x + normal1Y * tVec.y; - if(dot < minDot) { - minDot = dot; - index = i - } - } - var tClip; - var i1 = index; - var i2 = i1 + 1 < count2 ? i1 + 1 : 0; - tClip = c[0]; - tVec = vertices2[i1]; - tMat = xf2.R; - tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tClip.id.features.referenceEdge = edge1; - tClip.id.features.incidentEdge = i1; - tClip.id.features.incidentVertex = 0; - tClip = c[1]; - tVec = vertices2[i2]; - tMat = xf2.R; - tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tClip.id.features.referenceEdge = edge1; - tClip.id.features.incidentEdge = i2; - tClip.id.features.incidentVertex = 1 -}; -b2Collision.CollidePolygons = function(manifold, polyA, xfA, polyB, xfB) { - var cv; - manifold.m_pointCount = 0; - var totalRadius = polyA.m_radius + polyB.m_radius; - var edgeA = 0; - b2Collision.s_edgeAO[0] = edgeA; - var separationA = b2Collision.FindMaxSeparation(b2Collision.s_edgeAO, polyA, xfA, polyB, xfB); - edgeA = b2Collision.s_edgeAO[0]; - if(separationA > totalRadius) { - return - } - var edgeB = 0; - b2Collision.s_edgeBO[0] = edgeB; - var separationB = b2Collision.FindMaxSeparation(b2Collision.s_edgeBO, polyB, xfB, polyA, xfA); - edgeB = b2Collision.s_edgeBO[0]; - if(separationB > totalRadius) { - return - } - var poly1; - var poly2; - var xf1; - var xf2; - var edge1 = 0; - var flip = 0; - var k_relativeTol = 0.98; - var k_absoluteTol = 0.0010; - var tMat; - if(separationB > k_relativeTol * separationA + k_absoluteTol) { - poly1 = polyB; - poly2 = polyA; - xf1 = xfB; - xf2 = xfA; - edge1 = edgeB; - manifold.m_type = b2Manifold.e_faceB; - flip = 1 - }else { - poly1 = polyA; - poly2 = polyB; - xf1 = xfA; - xf2 = xfB; - edge1 = edgeA; - manifold.m_type = b2Manifold.e_faceA; - flip = 0 - } - var incidentEdge = b2Collision.s_incidentEdge; - b2Collision.FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); - var count1 = poly1.m_vertexCount; - var vertices1 = poly1.m_vertices; - var local_v11 = vertices1[edge1]; - var local_v12; - if(edge1 + 1 < count1) { - local_v12 = vertices1[parseInt(edge1 + 1)] - }else { - local_v12 = vertices1[0] - } - var localTangent = b2Collision.s_localTangent; - localTangent.Set(local_v12.x - local_v11.x, local_v12.y - local_v11.y); - localTangent.Normalize(); - var localNormal = b2Collision.s_localNormal; - localNormal.x = localTangent.y; - localNormal.y = -localTangent.x; - var planePoint = b2Collision.s_planePoint; - planePoint.Set(0.5 * (local_v11.x + local_v12.x), 0.5 * (local_v11.y + local_v12.y)); - var tangent = b2Collision.s_tangent; - tMat = xf1.R; - tangent.x = tMat.col1.x * localTangent.x + tMat.col2.x * localTangent.y; - tangent.y = tMat.col1.y * localTangent.x + tMat.col2.y * localTangent.y; - var tangent2 = b2Collision.s_tangent2; - tangent2.x = -tangent.x; - tangent2.y = -tangent.y; - var normal = b2Collision.s_normal; - normal.x = tangent.y; - normal.y = -tangent.x; - var v11 = b2Collision.s_v11; - var v12 = b2Collision.s_v12; - v11.x = xf1.position.x + (tMat.col1.x * local_v11.x + tMat.col2.x * local_v11.y); - v11.y = xf1.position.y + (tMat.col1.y * local_v11.x + tMat.col2.y * local_v11.y); - v12.x = xf1.position.x + (tMat.col1.x * local_v12.x + tMat.col2.x * local_v12.y); - v12.y = xf1.position.y + (tMat.col1.y * local_v12.x + tMat.col2.y * local_v12.y); - var frontOffset = normal.x * v11.x + normal.y * v11.y; - var sideOffset1 = -tangent.x * v11.x - tangent.y * v11.y + totalRadius; - var sideOffset2 = tangent.x * v12.x + tangent.y * v12.y + totalRadius; - var clipPoints1 = b2Collision.s_clipPoints1; - var clipPoints2 = b2Collision.s_clipPoints2; - var np = 0; - np = b2Collision.ClipSegmentToLine(clipPoints1, incidentEdge, tangent2, sideOffset1); - if(np < 2) { - return - } - np = b2Collision.ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2); - if(np < 2) { - return - } - manifold.m_localPlaneNormal.SetV(localNormal); - manifold.m_localPoint.SetV(planePoint); - var pointCount = 0; - for(var i = 0;i < b2Settings.b2_maxManifoldPoints;++i) { - cv = clipPoints2[i]; - var separation = normal.x * cv.v.x + normal.y * cv.v.y - frontOffset; - if(separation <= totalRadius) { - var cp = manifold.m_points[pointCount]; - tMat = xf2.R; - var tX = cv.v.x - xf2.position.x; - var tY = cv.v.y - xf2.position.y; - cp.m_localPoint.x = tX * tMat.col1.x + tY * tMat.col1.y; - cp.m_localPoint.y = tX * tMat.col2.x + tY * tMat.col2.y; - cp.m_id.Set(cv.id); - cp.m_id.features.flip = flip; - ++pointCount - } - } - manifold.m_pointCount = pointCount -}; -b2Collision.CollideCircles = function(manifold, circle1, xf1, circle2, xf2) { - manifold.m_pointCount = 0; - var tMat; - var tVec; - tMat = xf1.R; - tVec = circle1.m_p; - var p1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var p1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf2.R; - tVec = circle2.m_p; - var p2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var p2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var distSqr = dX * dX + dY * dY; - var radius = circle1.m_radius + circle2.m_radius; - if(distSqr > radius * radius) { - return - } - manifold.m_type = b2Manifold.e_circles; - manifold.m_localPoint.SetV(circle1.m_p); - manifold.m_localPlaneNormal.SetZero(); - manifold.m_pointCount = 1; - manifold.m_points[0].m_localPoint.SetV(circle2.m_p); - manifold.m_points[0].m_id.key = 0 -}; -b2Collision.CollidePolygonAndCircle = function(manifold, polygon, xf1, circle, xf2) { - manifold.m_pointCount = 0; - var tPoint; - var dX; - var dY; - var positionX; - var positionY; - var tVec; - var tMat; - tMat = xf2.R; - tVec = circle.m_p; - var cX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var cY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - dX = cX - xf1.position.x; - dY = cY - xf1.position.y; - tMat = xf1.R; - var cLocalX = dX * tMat.col1.x + dY * tMat.col1.y; - var cLocalY = dX * tMat.col2.x + dY * tMat.col2.y; - var dist; - var normalIndex = 0; - var separation = -Number.MAX_VALUE; - var radius = polygon.m_radius + circle.m_radius; - var vertexCount = polygon.m_vertexCount; - var vertices = polygon.m_vertices; - var normals = polygon.m_normals; - for(var i = 0;i < vertexCount;++i) { - tVec = vertices[i]; - dX = cLocalX - tVec.x; - dY = cLocalY - tVec.y; - tVec = normals[i]; - var s = tVec.x * dX + tVec.y * dY; - if(s > radius) { - return - } - if(s > separation) { - separation = s; - normalIndex = i - } - } - var vertIndex1 = normalIndex; - var vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0; - var v1 = vertices[vertIndex1]; - var v2 = vertices[vertIndex2]; - if(separation < Number.MIN_VALUE) { - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.SetV(normals[normalIndex]); - manifold.m_localPoint.x = 0.5 * (v1.x + v2.x); - manifold.m_localPoint.y = 0.5 * (v1.y + v2.y); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0; - return - } - var u1 = (cLocalX - v1.x) * (v2.x - v1.x) + (cLocalY - v1.y) * (v2.y - v1.y); - var u2 = (cLocalX - v2.x) * (v1.x - v2.x) + (cLocalY - v2.y) * (v1.y - v2.y); - if(u1 <= 0) { - if((cLocalX - v1.x) * (cLocalX - v1.x) + (cLocalY - v1.y) * (cLocalY - v1.y) > radius * radius) { - return - } - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.x = cLocalX - v1.x; - manifold.m_localPlaneNormal.y = cLocalY - v1.y; - manifold.m_localPlaneNormal.Normalize(); - manifold.m_localPoint.SetV(v1); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0 - }else { - if(u2 <= 0) { - if((cLocalX - v2.x) * (cLocalX - v2.x) + (cLocalY - v2.y) * (cLocalY - v2.y) > radius * radius) { - return - } - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.x = cLocalX - v2.x; - manifold.m_localPlaneNormal.y = cLocalY - v2.y; - manifold.m_localPlaneNormal.Normalize(); - manifold.m_localPoint.SetV(v2); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0 - }else { - var faceCenterX = 0.5 * (v1.x + v2.x); - var faceCenterY = 0.5 * (v1.y + v2.y); - separation = (cLocalX - faceCenterX) * normals[vertIndex1].x + (cLocalY - faceCenterY) * normals[vertIndex1].y; - if(separation > radius) { - return - } - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.x = normals[vertIndex1].x; - manifold.m_localPlaneNormal.y = normals[vertIndex1].y; - manifold.m_localPlaneNormal.Normalize(); - manifold.m_localPoint.Set(faceCenterX, faceCenterY); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0 - } - } -}; -b2Collision.TestOverlap = function(a, b) { - var t1 = b.lowerBound; - var t2 = a.upperBound; - var d1X = t1.x - t2.x; - var d1Y = t1.y - t2.y; - t1 = a.lowerBound; - t2 = b.upperBound; - var d2X = t1.x - t2.x; - var d2Y = t1.y - t2.y; - if(d1X > 0 || d1Y > 0) { - return false - } - if(d2X > 0 || d2Y > 0) { - return false - } - return true -}; -b2Collision.b2_nullFeature = 255; -b2Collision.s_incidentEdge = b2Collision.MakeClipPointVector(); -b2Collision.s_clipPoints1 = b2Collision.MakeClipPointVector(); -b2Collision.s_clipPoints2 = b2Collision.MakeClipPointVector(); -b2Collision.s_edgeAO = new Array(1); -b2Collision.s_edgeBO = new Array(1); -b2Collision.s_localTangent = new b2Vec2; -b2Collision.s_localNormal = new b2Vec2; -b2Collision.s_planePoint = new b2Vec2; -b2Collision.s_normal = new b2Vec2; -b2Collision.s_tangent = new b2Vec2; -b2Collision.s_tangent2 = new b2Vec2; -b2Collision.s_v11 = new b2Vec2; -b2Collision.s_v12 = new b2Vec2; -b2Collision.b2CollidePolyTempVec = new b2Vec2;var b2PolyAndCircleContact = function() { - b2Contact.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2PolyAndCircleContact.prototype, b2Contact.prototype); -b2PolyAndCircleContact.prototype._super = b2Contact.prototype; -b2PolyAndCircleContact.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2PolyAndCircleContact.prototype.__varz = function() { -}; -b2PolyAndCircleContact.Create = function(allocator) { - return new b2PolyAndCircleContact -}; -b2PolyAndCircleContact.Destroy = function(contact, allocator) { -}; -b2PolyAndCircleContact.prototype.Evaluate = function() { - var bA = this.m_fixtureA.m_body; - var bB = this.m_fixtureB.m_body; - b2Collision.CollidePolygonAndCircle(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) -}; -b2PolyAndCircleContact.prototype.Reset = function(fixtureA, fixtureB) { - this._super.Reset.apply(this, [fixtureA, fixtureB]); - b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); - b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_circleShape) -};var b2ContactPoint = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactPoint.prototype.__constructor = function() { -}; -b2ContactPoint.prototype.__varz = function() { - this.position = new b2Vec2; - this.velocity = new b2Vec2; - this.normal = new b2Vec2; - this.id = new b2ContactID -}; -b2ContactPoint.prototype.shape1 = null; -b2ContactPoint.prototype.shape2 = null; -b2ContactPoint.prototype.position = new b2Vec2; -b2ContactPoint.prototype.velocity = new b2Vec2; -b2ContactPoint.prototype.normal = new b2Vec2; -b2ContactPoint.prototype.separation = null; -b2ContactPoint.prototype.friction = null; -b2ContactPoint.prototype.restitution = null; -b2ContactPoint.prototype.id = new b2ContactID;var b2CircleContact = function() { - b2Contact.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2CircleContact.prototype, b2Contact.prototype); -b2CircleContact.prototype._super = b2Contact.prototype; -b2CircleContact.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2CircleContact.prototype.__varz = function() { -}; -b2CircleContact.Create = function(allocator) { - return new b2CircleContact -}; -b2CircleContact.Destroy = function(contact, allocator) { -}; -b2CircleContact.prototype.Evaluate = function() { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - b2Collision.CollideCircles(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) -}; -b2CircleContact.prototype.Reset = function(fixtureA, fixtureB) { - this._super.Reset.apply(this, [fixtureA, fixtureB]) -};var b2EdgeAndCircleContact = function() { - b2Contact.prototype.__varz.call(this); - this.__varz(); - this.__constructor.apply(this, arguments) -}; -extend(b2EdgeAndCircleContact.prototype, b2Contact.prototype); -b2EdgeAndCircleContact.prototype._super = b2Contact.prototype; -b2EdgeAndCircleContact.prototype.__constructor = function() { - this._super.__constructor.apply(this, arguments) -}; -b2EdgeAndCircleContact.prototype.__varz = function() { -}; -b2EdgeAndCircleContact.Create = function(allocator) { - return new b2EdgeAndCircleContact -}; -b2EdgeAndCircleContact.Destroy = function(contact, allocator) { -}; -b2EdgeAndCircleContact.prototype.Evaluate = function() { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - this.b2CollideEdgeAndCircle(this.m_manifold, this.m_fixtureA.GetShape(), bA.m_xf, this.m_fixtureB.GetShape(), bB.m_xf) -}; -b2EdgeAndCircleContact.prototype.b2CollideEdgeAndCircle = function(manifold, edge, xf1, circle, xf2) { -}; -b2EdgeAndCircleContact.prototype.Reset = function(fixtureA, fixtureB) { - this._super.Reset.apply(this, [fixtureA, fixtureB]) -};var b2ContactManager = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2ContactManager.prototype.__constructor = function() { - this.m_world = null; - this.m_contactCount = 0; - this.m_contactFilter = b2ContactFilter.b2_defaultFilter; - this.m_contactListener = b2ContactListener.b2_defaultListener; - this.m_contactFactory = new b2ContactFactory(this.m_allocator); - this.m_broadPhase = new b2DynamicTreeBroadPhase -}; -b2ContactManager.prototype.__varz = function() { -}; -b2ContactManager.s_evalCP = new b2ContactPoint; -b2ContactManager.prototype.AddPair = function(proxyUserDataA, proxyUserDataB) { - var fixtureA = proxyUserDataA; - var fixtureB = proxyUserDataB; - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if(bodyA == bodyB) { - return - } - var edge = bodyB.GetContactList(); - while(edge) { - if(edge.other == bodyA) { - var fA = edge.contact.GetFixtureA(); - var fB = edge.contact.GetFixtureB(); - if(fA == fixtureA && fB == fixtureB) { - return - } - if(fA == fixtureB && fB == fixtureA) { - return - } - } - edge = edge.next - } - if(bodyB.ShouldCollide(bodyA) == false) { - return - } - if(this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { - return - } - var c = this.m_contactFactory.Create(fixtureA, fixtureB); - fixtureA = c.GetFixtureA(); - fixtureB = c.GetFixtureB(); - bodyA = fixtureA.m_body; - bodyB = fixtureB.m_body; - c.m_prev = null; - c.m_next = this.m_world.m_contactList; - if(this.m_world.m_contactList != null) { - this.m_world.m_contactList.m_prev = c - } - this.m_world.m_contactList = c; - c.m_nodeA.contact = c; - c.m_nodeA.other = bodyB; - c.m_nodeA.prev = null; - c.m_nodeA.next = bodyA.m_contactList; - if(bodyA.m_contactList != null) { - bodyA.m_contactList.prev = c.m_nodeA - } - bodyA.m_contactList = c.m_nodeA; - c.m_nodeB.contact = c; - c.m_nodeB.other = bodyA; - c.m_nodeB.prev = null; - c.m_nodeB.next = bodyB.m_contactList; - if(bodyB.m_contactList != null) { - bodyB.m_contactList.prev = c.m_nodeB - } - bodyB.m_contactList = c.m_nodeB; - ++this.m_world.m_contactCount; - return -}; -b2ContactManager.prototype.FindNewContacts = function() { - var that = this; - this.m_broadPhase.UpdatePairs(function(a, b) { - return that.AddPair(a, b) - }) -}; -b2ContactManager.prototype.Destroy = function(c) { - var fixtureA = c.GetFixtureA(); - var fixtureB = c.GetFixtureB(); - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if(c.IsTouching()) { - this.m_contactListener.EndContact(c) - } - if(c.m_prev) { - c.m_prev.m_next = c.m_next - } - if(c.m_next) { - c.m_next.m_prev = c.m_prev - } - if(c == this.m_world.m_contactList) { - this.m_world.m_contactList = c.m_next - } - if(c.m_nodeA.prev) { - c.m_nodeA.prev.next = c.m_nodeA.next - } - if(c.m_nodeA.next) { - c.m_nodeA.next.prev = c.m_nodeA.prev - } - if(c.m_nodeA == bodyA.m_contactList) { - bodyA.m_contactList = c.m_nodeA.next - } - if(c.m_nodeB.prev) { - c.m_nodeB.prev.next = c.m_nodeB.next - } - if(c.m_nodeB.next) { - c.m_nodeB.next.prev = c.m_nodeB.prev - } - if(c.m_nodeB == bodyB.m_contactList) { - bodyB.m_contactList = c.m_nodeB.next - } - this.m_contactFactory.Destroy(c); - --this.m_contactCount -}; -b2ContactManager.prototype.Collide = function() { - var c = this.m_world.m_contactList; - while(c) { - var fixtureA = c.GetFixtureA(); - var fixtureB = c.GetFixtureB(); - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if(bodyA.IsAwake() == false && bodyB.IsAwake() == false) { - c = c.GetNext(); - continue - } - if(c.m_flags & b2Contact.e_filterFlag) { - if(bodyB.ShouldCollide(bodyA) == false) { - var cNuke = c; - c = cNuke.GetNext(); - this.Destroy(cNuke); - continue - } - if(this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { - cNuke = c; - c = cNuke.GetNext(); - this.Destroy(cNuke); - continue - } - c.m_flags &= ~b2Contact.e_filterFlag - } - var proxyA = fixtureA.m_proxy; - var proxyB = fixtureB.m_proxy; - var overlap = this.m_broadPhase.TestOverlap(proxyA, proxyB); - if(overlap == false) { - cNuke = c; - c = cNuke.GetNext(); - this.Destroy(cNuke); - continue - } - c.Update(this.m_contactListener); - c = c.GetNext() - } -}; -b2ContactManager.prototype.m_world = null; -b2ContactManager.prototype.m_broadPhase = null; -b2ContactManager.prototype.m_contactList = null; -b2ContactManager.prototype.m_contactCount = 0; -b2ContactManager.prototype.m_contactFilter = null; -b2ContactManager.prototype.m_contactListener = null; -b2ContactManager.prototype.m_contactFactory = null; -b2ContactManager.prototype.m_allocator = null;var b2World = function() { - this.__varz(); - this.__constructor.apply(this, arguments) -}; -b2World.prototype.__constructor = function(gravity, doSleep) { - this.m_destructionListener = null; - this.m_debugDraw = null; - this.m_bodyList = null; - this.m_contactList = null; - this.m_jointList = null; - this.m_controllerList = null; - this.m_bodyCount = 0; - this.m_contactCount = 0; - this.m_jointCount = 0; - this.m_controllerCount = 0; - b2World.m_warmStarting = true; - b2World.m_continuousPhysics = true; - this.m_allowSleep = doSleep; - this.m_gravity = gravity; - this.m_inv_dt0 = 0; - this.m_contactManager.m_world = this; - var bd = new b2BodyDef; - this.m_groundBody = this.CreateBody(bd) -}; -b2World.prototype.__varz = function() { - this.s_stack = new Array; - this.m_contactManager = new b2ContactManager; - this.m_contactSolver = new b2ContactSolver; - this.m_island = new b2Island -}; -b2World.s_timestep2 = new b2TimeStep; -b2World.s_backupA = new b2Sweep; -b2World.s_backupB = new b2Sweep; -b2World.s_timestep = new b2TimeStep; -b2World.s_queue = new Array; -b2World.e_newFixture = 1; -b2World.e_locked = 2; -b2World.s_xf = new b2Transform; -b2World.s_jointColor = new b2Color(0.5, 0.8, 0.8); -b2World.m_warmStarting = null; -b2World.m_continuousPhysics = null; -b2World.prototype.Solve = function(step) { - var b; - for(var controller = this.m_controllerList;controller;controller = controller.m_next) { - controller.Step(step) - } - var island = this.m_island; - island.Initialize(this.m_bodyCount, this.m_contactCount, this.m_jointCount, null, this.m_contactManager.m_contactListener, this.m_contactSolver); - for(b = this.m_bodyList;b;b = b.m_next) { - b.m_flags &= ~b2Body.e_islandFlag - } - for(var c = this.m_contactList;c;c = c.m_next) { - c.m_flags &= ~b2Contact.e_islandFlag - } - for(var j = this.m_jointList;j;j = j.m_next) { - j.m_islandFlag = false - } - var stackSize = this.m_bodyCount; - var stack = this.s_stack; - for(var seed = this.m_bodyList;seed;seed = seed.m_next) { - if(seed.m_flags & b2Body.e_islandFlag) { - continue - } - if(seed.IsAwake() == false || seed.IsActive() == false) { - continue - } - if(seed.GetType() == b2Body.b2_staticBody) { - continue - } - island.Clear(); - var stackCount = 0; - stack[stackCount++] = seed; - seed.m_flags |= b2Body.e_islandFlag; - while(stackCount > 0) { - b = stack[--stackCount]; - island.AddBody(b); - if(b.IsAwake() == false) { - b.SetAwake(true) - } - if(b.GetType() == b2Body.b2_staticBody) { - continue - } - var other; - for(var ce = b.m_contactList;ce;ce = ce.next) { - if(ce.contact.m_flags & b2Contact.e_islandFlag) { - continue - } - if(ce.contact.IsSensor() == true || ce.contact.IsEnabled() == false || ce.contact.IsTouching() == false) { - continue - } - island.AddContact(ce.contact); - ce.contact.m_flags |= b2Contact.e_islandFlag; - other = ce.other; - if(other.m_flags & b2Body.e_islandFlag) { - continue - } - stack[stackCount++] = other; - other.m_flags |= b2Body.e_islandFlag - } - for(var jn = b.m_jointList;jn;jn = jn.next) { - if(jn.joint.m_islandFlag == true) { - continue - } - other = jn.other; - if(other.IsActive() == false) { - continue - } - island.AddJoint(jn.joint); - jn.joint.m_islandFlag = true; - if(other.m_flags & b2Body.e_islandFlag) { - continue - } - stack[stackCount++] = other; - other.m_flags |= b2Body.e_islandFlag - } - } - island.Solve(step, this.m_gravity, this.m_allowSleep); - for(var i = 0;i < island.m_bodyCount;++i) { - b = island.m_bodies[i]; - if(b.GetType() == b2Body.b2_staticBody) { - b.m_flags &= ~b2Body.e_islandFlag - } - } - } - for(i = 0;i < stack.length;++i) { - if(!stack[i]) { - break - } - stack[i] = null - } - for(b = this.m_bodyList;b;b = b.m_next) { - if(b.IsAwake() == false || b.IsActive() == false) { - continue - } - if(b.GetType() == b2Body.b2_staticBody) { - continue - } - b.SynchronizeFixtures() - } - this.m_contactManager.FindNewContacts() -}; -b2World.prototype.SolveTOI = function(step) { - var b; - var fA; - var fB; - var bA; - var bB; - var cEdge; - var j; - var island = this.m_island; - island.Initialize(this.m_bodyCount, b2Settings.b2_maxTOIContactsPerIsland, b2Settings.b2_maxTOIJointsPerIsland, null, this.m_contactManager.m_contactListener, this.m_contactSolver); - var queue = b2World.s_queue; - for(b = this.m_bodyList;b;b = b.m_next) { - b.m_flags &= ~b2Body.e_islandFlag; - b.m_sweep.t0 = 0 - } - var c; - for(c = this.m_contactList;c;c = c.m_next) { - c.m_flags &= ~(b2Contact.e_toiFlag | b2Contact.e_islandFlag) - } - for(j = this.m_jointList;j;j = j.m_next) { - j.m_islandFlag = false - } - for(;;) { - var minContact = null; - var minTOI = 1; - for(c = this.m_contactList;c;c = c.m_next) { - if(c.IsSensor() == true || c.IsEnabled() == false || c.IsContinuous() == false) { - continue - } - var toi = 1; - if(c.m_flags & b2Contact.e_toiFlag) { - toi = c.m_toi - }else { - fA = c.m_fixtureA; - fB = c.m_fixtureB; - bA = fA.m_body; - bB = fB.m_body; - if((bA.GetType() != b2Body.b2_dynamicBody || bA.IsAwake() == false) && (bB.GetType() != b2Body.b2_dynamicBody || bB.IsAwake() == false)) { - continue - } - var t0 = bA.m_sweep.t0; - if(bA.m_sweep.t0 < bB.m_sweep.t0) { - t0 = bB.m_sweep.t0; - bA.m_sweep.Advance(t0) - }else { - if(bB.m_sweep.t0 < bA.m_sweep.t0) { - t0 = bA.m_sweep.t0; - bB.m_sweep.Advance(t0) - } - } - toi = c.ComputeTOI(bA.m_sweep, bB.m_sweep); - b2Settings.b2Assert(0 <= toi && toi <= 1); - if(toi > 0 && toi < 1) { - toi = (1 - toi) * t0 + toi; - if(toi > 1) { - toi = 1 - } - } - c.m_toi = toi; - c.m_flags |= b2Contact.e_toiFlag - } - if(Number.MIN_VALUE < toi && toi < minTOI) { - minContact = c; - minTOI = toi - } - } - if(minContact == null || 1 - 100 * Number.MIN_VALUE < minTOI) { - break - } - fA = minContact.m_fixtureA; - fB = minContact.m_fixtureB; - bA = fA.m_body; - bB = fB.m_body; - b2World.s_backupA.Set(bA.m_sweep); - b2World.s_backupB.Set(bB.m_sweep); - bA.Advance(minTOI); - bB.Advance(minTOI); - minContact.Update(this.m_contactManager.m_contactListener); - minContact.m_flags &= ~b2Contact.e_toiFlag; - if(minContact.IsSensor() == true || minContact.IsEnabled() == false) { - bA.m_sweep.Set(b2World.s_backupA); - bB.m_sweep.Set(b2World.s_backupB); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - continue - } - if(minContact.IsTouching() == false) { - continue - } - var seed = bA; - if(seed.GetType() != b2Body.b2_dynamicBody) { - seed = bB - } - island.Clear(); - var queueStart = 0; - var queueSize = 0; - queue[queueStart + queueSize++] = seed; - seed.m_flags |= b2Body.e_islandFlag; - while(queueSize > 0) { - b = queue[queueStart++]; - --queueSize; - island.AddBody(b); - if(b.IsAwake() == false) { - b.SetAwake(true) - } - if(b.GetType() != b2Body.b2_dynamicBody) { - continue - } - for(cEdge = b.m_contactList;cEdge;cEdge = cEdge.next) { - if(island.m_contactCount == island.m_contactCapacity) { - break - } - if(cEdge.contact.m_flags & b2Contact.e_islandFlag) { - continue - } - if(cEdge.contact.IsSensor() == true || cEdge.contact.IsEnabled() == false || cEdge.contact.IsTouching() == false) { - continue - } - island.AddContact(cEdge.contact); - cEdge.contact.m_flags |= b2Contact.e_islandFlag; - var other = cEdge.other; - if(other.m_flags & b2Body.e_islandFlag) { - continue - } - if(other.GetType() != b2Body.b2_staticBody) { - other.Advance(minTOI); - other.SetAwake(true) - } - queue[queueStart + queueSize] = other; - ++queueSize; - other.m_flags |= b2Body.e_islandFlag - } - for(var jEdge = b.m_jointList;jEdge;jEdge = jEdge.next) { - if(island.m_jointCount == island.m_jointCapacity) { - continue - } - if(jEdge.joint.m_islandFlag == true) { - continue - } - other = jEdge.other; - if(other.IsActive() == false) { - continue - } - island.AddJoint(jEdge.joint); - jEdge.joint.m_islandFlag = true; - if(other.m_flags & b2Body.e_islandFlag) { - continue - } - if(other.GetType() != b2Body.b2_staticBody) { - other.Advance(minTOI); - other.SetAwake(true) - } - queue[queueStart + queueSize] = other; - ++queueSize; - other.m_flags |= b2Body.e_islandFlag - } - } - var subStep = b2World.s_timestep; - subStep.warmStarting = false; - subStep.dt = (1 - minTOI) * step.dt; - subStep.inv_dt = 1 / subStep.dt; - subStep.dtRatio = 0; - subStep.velocityIterations = step.velocityIterations; - subStep.positionIterations = step.positionIterations; - island.SolveTOI(subStep); - var i = 0; - for(i = 0;i < island.m_bodyCount;++i) { - b = island.m_bodies[i]; - b.m_flags &= ~b2Body.e_islandFlag; - if(b.IsAwake() == false) { - continue - } - if(b.GetType() != b2Body.b2_dynamicBody) { - continue - } - b.SynchronizeFixtures(); - for(cEdge = b.m_contactList;cEdge;cEdge = cEdge.next) { - cEdge.contact.m_flags &= ~b2Contact.e_toiFlag - } - } - for(i = 0;i < island.m_contactCount;++i) { - c = island.m_contacts[i]; - c.m_flags &= ~(b2Contact.e_toiFlag | b2Contact.e_islandFlag) - } - for(i = 0;i < island.m_jointCount;++i) { - j = island.m_joints[i]; - j.m_islandFlag = false - } - this.m_contactManager.FindNewContacts() - } -}; -b2World.prototype.DrawJoint = function(joint) { - var b1 = joint.GetBodyA(); - var b2 = joint.GetBodyB(); - var xf1 = b1.m_xf; - var xf2 = b2.m_xf; - var x1 = xf1.position; - var x2 = xf2.position; - var p1 = joint.GetAnchorA(); - var p2 = joint.GetAnchorB(); - var color = b2World.s_jointColor; - switch(joint.m_type) { - case b2Joint.e_distanceJoint: - this.m_debugDraw.DrawSegment(p1, p2, color); - break; - case b2Joint.e_pulleyJoint: - var pulley = joint; - var s1 = pulley.GetGroundAnchorA(); - var s2 = pulley.GetGroundAnchorB(); - this.m_debugDraw.DrawSegment(s1, p1, color); - this.m_debugDraw.DrawSegment(s2, p2, color); - this.m_debugDraw.DrawSegment(s1, s2, color); - break; - case b2Joint.e_mouseJoint: - this.m_debugDraw.DrawSegment(p1, p2, color); - break; - default: - if(b1 != this.m_groundBody) { - this.m_debugDraw.DrawSegment(x1, p1, color) - } - this.m_debugDraw.DrawSegment(p1, p2, color); - if(b2 != this.m_groundBody) { - this.m_debugDraw.DrawSegment(x2, p2, color) - } - } -}; -b2World.prototype.DrawShape = function(shape, xf, color) { - switch(shape.m_type) { - case b2Shape.e_circleShape: - var circle = shape; - var center = b2Math.MulX(xf, circle.m_p); - var radius = circle.m_radius; - var axis = xf.R.col1; - this.m_debugDraw.DrawSolidCircle(center, radius, axis, color); - break; - case b2Shape.e_polygonShape: - var i = 0; - var poly = shape; - var vertexCount = poly.GetVertexCount(); - var localVertices = poly.GetVertices(); - var vertices = new Array(vertexCount); - for(i = 0;i < vertexCount;++i) { - vertices[i] = b2Math.MulX(xf, localVertices[i]) - } - this.m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color); - break; - case b2Shape.e_edgeShape: - var edge = shape; - this.m_debugDraw.DrawSegment(b2Math.MulX(xf, edge.GetVertex1()), b2Math.MulX(xf, edge.GetVertex2()), color); - break - } -}; -b2World.prototype.SetDestructionListener = function(listener) { - this.m_destructionListener = listener -}; -b2World.prototype.SetContactFilter = function(filter) { - this.m_contactManager.m_contactFilter = filter -}; -b2World.prototype.SetContactListener = function(listener) { - this.m_contactManager.m_contactListener = listener -}; -b2World.prototype.SetDebugDraw = function(debugDraw) { - this.m_debugDraw = debugDraw -}; -b2World.prototype.SetBroadPhase = function(broadPhase) { - var oldBroadPhase = this.m_contactManager.m_broadPhase; - this.m_contactManager.m_broadPhase = broadPhase; - for(var b = this.m_bodyList;b;b = b.m_next) { - for(var f = b.m_fixtureList;f;f = f.m_next) { - f.m_proxy = broadPhase.CreateProxy(oldBroadPhase.GetFatAABB(f.m_proxy), f) - } - } -}; -b2World.prototype.Validate = function() { - this.m_contactManager.m_broadPhase.Validate() -}; -b2World.prototype.GetProxyCount = function() { - return this.m_contactManager.m_broadPhase.GetProxyCount() -}; -b2World.prototype.CreateBody = function(def) { - if(this.IsLocked() == true) { - return null - } - var b = new b2Body(def, this); - b.m_prev = null; - b.m_next = this.m_bodyList; - if(this.m_bodyList) { - this.m_bodyList.m_prev = b - } - this.m_bodyList = b; - ++this.m_bodyCount; - return b -}; -b2World.prototype.DestroyBody = function(b) { - if(this.IsLocked() == true) { - return - } - var jn = b.m_jointList; - while(jn) { - var jn0 = jn; - jn = jn.next; - if(this.m_destructionListener) { - this.m_destructionListener.SayGoodbyeJoint(jn0.joint) - } - this.DestroyJoint(jn0.joint) - } - var coe = b.m_controllerList; - while(coe) { - var coe0 = coe; - coe = coe.nextController; - coe0.controller.RemoveBody(b) - } - var ce = b.m_contactList; - while(ce) { - var ce0 = ce; - ce = ce.next; - this.m_contactManager.Destroy(ce0.contact) - } - b.m_contactList = null; - var f = b.m_fixtureList; - while(f) { - var f0 = f; - f = f.m_next; - if(this.m_destructionListener) { - this.m_destructionListener.SayGoodbyeFixture(f0) - } - f0.DestroyProxy(this.m_contactManager.m_broadPhase); - f0.Destroy() - } - b.m_fixtureList = null; - b.m_fixtureCount = 0; - if(b.m_prev) { - b.m_prev.m_next = b.m_next - } - if(b.m_next) { - b.m_next.m_prev = b.m_prev - } - if(b == this.m_bodyList) { - this.m_bodyList = b.m_next - } - --this.m_bodyCount -}; -b2World.prototype.CreateJoint = function(def) { - var j = b2Joint.Create(def, null); - j.m_prev = null; - j.m_next = this.m_jointList; - if(this.m_jointList) { - this.m_jointList.m_prev = j - } - this.m_jointList = j; - ++this.m_jointCount; - j.m_edgeA.joint = j; - j.m_edgeA.other = j.m_bodyB; - j.m_edgeA.prev = null; - j.m_edgeA.next = j.m_bodyA.m_jointList; - if(j.m_bodyA.m_jointList) { - j.m_bodyA.m_jointList.prev = j.m_edgeA - } - j.m_bodyA.m_jointList = j.m_edgeA; - j.m_edgeB.joint = j; - j.m_edgeB.other = j.m_bodyA; - j.m_edgeB.prev = null; - j.m_edgeB.next = j.m_bodyB.m_jointList; - if(j.m_bodyB.m_jointList) { - j.m_bodyB.m_jointList.prev = j.m_edgeB - } - j.m_bodyB.m_jointList = j.m_edgeB; - var bodyA = def.bodyA; - var bodyB = def.bodyB; - if(def.collideConnected == false) { - var edge = bodyB.GetContactList(); - while(edge) { - if(edge.other == bodyA) { - edge.contact.FlagForFiltering() - } - edge = edge.next - } - } - return j -}; -b2World.prototype.DestroyJoint = function(j) { - var collideConnected = j.m_collideConnected; - if(j.m_prev) { - j.m_prev.m_next = j.m_next - } - if(j.m_next) { - j.m_next.m_prev = j.m_prev - } - if(j == this.m_jointList) { - this.m_jointList = j.m_next - } - var bodyA = j.m_bodyA; - var bodyB = j.m_bodyB; - bodyA.SetAwake(true); - bodyB.SetAwake(true); - if(j.m_edgeA.prev) { - j.m_edgeA.prev.next = j.m_edgeA.next - } - if(j.m_edgeA.next) { - j.m_edgeA.next.prev = j.m_edgeA.prev - } - if(j.m_edgeA == bodyA.m_jointList) { - bodyA.m_jointList = j.m_edgeA.next - } - j.m_edgeA.prev = null; - j.m_edgeA.next = null; - if(j.m_edgeB.prev) { - j.m_edgeB.prev.next = j.m_edgeB.next - } - if(j.m_edgeB.next) { - j.m_edgeB.next.prev = j.m_edgeB.prev - } - if(j.m_edgeB == bodyB.m_jointList) { - bodyB.m_jointList = j.m_edgeB.next - } - j.m_edgeB.prev = null; - j.m_edgeB.next = null; - b2Joint.Destroy(j, null); - --this.m_jointCount; - if(collideConnected == false) { - var edge = bodyB.GetContactList(); - while(edge) { - if(edge.other == bodyA) { - edge.contact.FlagForFiltering() - } - edge = edge.next - } - } -}; -b2World.prototype.AddController = function(c) { - c.m_next = this.m_controllerList; - c.m_prev = null; - this.m_controllerList = c; - c.m_world = this; - this.m_controllerCount++; - return c -}; -b2World.prototype.RemoveController = function(c) { - if(c.m_prev) { - c.m_prev.m_next = c.m_next - } - if(c.m_next) { - c.m_next.m_prev = c.m_prev - } - if(this.m_controllerList == c) { - this.m_controllerList = c.m_next - } - this.m_controllerCount-- -}; -b2World.prototype.CreateController = function(controller) { - if(controller.m_world != this) { - throw new Error("Controller can only be a member of one world"); - } - controller.m_next = this.m_controllerList; - controller.m_prev = null; - if(this.m_controllerList) { - this.m_controllerList.m_prev = controller - } - this.m_controllerList = controller; - ++this.m_controllerCount; - controller.m_world = this; - return controller -}; -b2World.prototype.DestroyController = function(controller) { - controller.Clear(); - if(controller.m_next) { - controller.m_next.m_prev = controller.m_prev - } - if(controller.m_prev) { - controller.m_prev.m_next = controller.m_next - } - if(controller == this.m_controllerList) { - this.m_controllerList = controller.m_next - } - --this.m_controllerCount -}; -b2World.prototype.SetWarmStarting = function(flag) { - b2World.m_warmStarting = flag -}; -b2World.prototype.SetContinuousPhysics = function(flag) { - b2World.m_continuousPhysics = flag -}; -b2World.prototype.GetBodyCount = function() { - return this.m_bodyCount -}; -b2World.prototype.GetJointCount = function() { - return this.m_jointCount -}; -b2World.prototype.GetContactCount = function() { - return this.m_contactCount -}; -b2World.prototype.SetGravity = function(gravity) { - this.m_gravity = gravity -}; -b2World.prototype.GetGravity = function() { - return this.m_gravity -}; -b2World.prototype.GetGroundBody = function() { - return this.m_groundBody -}; -b2World.prototype.Step = function(dt, velocityIterations, positionIterations) { - if(this.m_flags & b2World.e_newFixture) { - this.m_contactManager.FindNewContacts(); - this.m_flags &= ~b2World.e_newFixture - } - this.m_flags |= b2World.e_locked; - var step = b2World.s_timestep2; - step.dt = dt; - step.velocityIterations = velocityIterations; - step.positionIterations = positionIterations; - if(dt > 0) { - step.inv_dt = 1 / dt - }else { - step.inv_dt = 0 - } - step.dtRatio = this.m_inv_dt0 * dt; - step.warmStarting = b2World.m_warmStarting; - this.m_contactManager.Collide(); - if(step.dt > 0) { - this.Solve(step) - } - if(b2World.m_continuousPhysics && step.dt > 0) { - this.SolveTOI(step) - } - if(step.dt > 0) { - this.m_inv_dt0 = step.inv_dt - } - this.m_flags &= ~b2World.e_locked -}; -b2World.prototype.ClearForces = function() { - for(var body = this.m_bodyList;body;body = body.m_next) { - body.m_force.SetZero(); - body.m_torque = 0 - } -}; -b2World.prototype.DrawDebugData = function() { - if(this.m_debugDraw == null) { - return - } - this.m_debugDraw.Clear(); - var flags = this.m_debugDraw.GetFlags(); - var i = 0; - var b; - var f; - var s; - var j; - var bp; - var invQ = new b2Vec2; - var x1 = new b2Vec2; - var x2 = new b2Vec2; - var xf; - var b1 = new b2AABB; - var b2 = new b2AABB; - var vs = [new b2Vec2, new b2Vec2, new b2Vec2, new b2Vec2]; - var color = new b2Color(0, 0, 0); - if(flags & b2DebugDraw.e_shapeBit) { - for(b = this.m_bodyList;b;b = b.m_next) { - xf = b.m_xf; - for(f = b.GetFixtureList();f;f = f.m_next) { - s = f.GetShape(); - if(b.IsActive() == false) { - color.Set(0.5, 0.5, 0.3); - this.DrawShape(s, xf, color) - }else { - if(b.GetType() == b2Body.b2_staticBody) { - color.Set(0.5, 0.9, 0.5); - this.DrawShape(s, xf, color) - }else { - if(b.GetType() == b2Body.b2_kinematicBody) { - color.Set(0.5, 0.5, 0.9); - this.DrawShape(s, xf, color) - }else { - if(b.IsAwake() == false) { - color.Set(0.6, 0.6, 0.6); - this.DrawShape(s, xf, color) - }else { - color.Set(0.9, 0.7, 0.7); - this.DrawShape(s, xf, color) - } - } - } - } - } - } - } - if(flags & b2DebugDraw.e_jointBit) { - for(j = this.m_jointList;j;j = j.m_next) { - this.DrawJoint(j) - } - } - if(flags & b2DebugDraw.e_controllerBit) { - for(var c = this.m_controllerList;c;c = c.m_next) { - c.Draw(this.m_debugDraw) - } - } - if(flags & b2DebugDraw.e_pairBit) { - color.Set(0.3, 0.9, 0.9); - for(var contact = this.m_contactManager.m_contactList;contact;contact = contact.GetNext()) { - var fixtureA = contact.GetFixtureA(); - var fixtureB = contact.GetFixtureB(); - var cA = fixtureA.GetAABB().GetCenter(); - var cB = fixtureB.GetAABB().GetCenter(); - this.m_debugDraw.DrawSegment(cA, cB, color) - } - } - if(flags & b2DebugDraw.e_aabbBit) { - bp = this.m_contactManager.m_broadPhase; - vs = [new b2Vec2, new b2Vec2, new b2Vec2, new b2Vec2]; - for(b = this.m_bodyList;b;b = b.GetNext()) { - if(b.IsActive() == false) { - continue - } - for(f = b.GetFixtureList();f;f = f.GetNext()) { - var aabb = bp.GetFatAABB(f.m_proxy); - vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y); - vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y); - vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); - vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); - this.m_debugDraw.DrawPolygon(vs, 4, color) - } - } - } - if(flags & b2DebugDraw.e_centerOfMassBit) { - for(b = this.m_bodyList;b;b = b.m_next) { - xf = b2World.s_xf; - xf.R = b.m_xf.R; - xf.position = b.GetWorldCenter(); - this.m_debugDraw.DrawTransform(xf) - } - } -}; -b2World.prototype.QueryAABB = function(callback, aabb) { - var broadPhase = this.m_contactManager.m_broadPhase; - function WorldQueryWrapper(proxy) { - return callback(broadPhase.GetUserData(proxy)) - } - broadPhase.Query(WorldQueryWrapper, aabb) -}; -b2World.prototype.QueryShape = function(callback, shape, transform) { - if(transform == null) { - transform = new b2Transform; - transform.SetIdentity() - } - var broadPhase = this.m_contactManager.m_broadPhase; - function WorldQueryWrapper(proxy) { - var fixture = broadPhase.GetUserData(proxy); - if(b2Shape.TestOverlap(shape, transform, fixture.GetShape(), fixture.GetBody().GetTransform())) { - return callback(fixture) - } - return true - } - var aabb = new b2AABB; - shape.ComputeAABB(aabb, transform); - broadPhase.Query(WorldQueryWrapper, aabb) -}; -b2World.prototype.QueryPoint = function(callback, p) { - var broadPhase = this.m_contactManager.m_broadPhase; - function WorldQueryWrapper(proxy) { - var fixture = broadPhase.GetUserData(proxy); - if(fixture.TestPoint(p)) { - return callback(fixture) - } - return true - } - var aabb = new b2AABB; - aabb.lowerBound.Set(p.x - b2Settings.b2_linearSlop, p.y - b2Settings.b2_linearSlop); - aabb.upperBound.Set(p.x + b2Settings.b2_linearSlop, p.y + b2Settings.b2_linearSlop); - broadPhase.Query(WorldQueryWrapper, aabb) -}; -b2World.prototype.RayCast = function(callback, point1, point2) { - var broadPhase = this.m_contactManager.m_broadPhase; - var output = new b2RayCastOutput; - function RayCastWrapper(input, proxy) { - var userData = broadPhase.GetUserData(proxy); - var fixture = userData; - var hit = fixture.RayCast(output, input); - if(hit) { - var fraction = output.fraction; - var point = new b2Vec2((1 - fraction) * point1.x + fraction * point2.x, (1 - fraction) * point1.y + fraction * point2.y); - return callback(fixture, point, output.normal, fraction) - } - return input.maxFraction - } - var input = new b2RayCastInput(point1, point2); - broadPhase.RayCast(RayCastWrapper, input) -}; -b2World.prototype.RayCastOne = function(point1, point2) { - var result; - function RayCastOneWrapper(fixture, point, normal, fraction) { - result = fixture; - return fraction - } - this.RayCast(RayCastOneWrapper, point1, point2); - return result -}; -b2World.prototype.RayCastAll = function(point1, point2) { - var result = new Array; - function RayCastAllWrapper(fixture, point, normal, fraction) { - result[result.length] = fixture; - return 1 - } - this.RayCast(RayCastAllWrapper, point1, point2); - return result -}; -b2World.prototype.GetBodyList = function() { - return this.m_bodyList -}; -b2World.prototype.GetJointList = function() { - return this.m_jointList -}; -b2World.prototype.GetContactList = function() { - return this.m_contactList -}; -b2World.prototype.IsLocked = function() { - return(this.m_flags & b2World.e_locked) > 0 -}; -b2World.prototype.s_stack = new Array; -b2World.prototype.m_flags = 0; -b2World.prototype.m_contactManager = new b2ContactManager; -b2World.prototype.m_contactSolver = new b2ContactSolver; -b2World.prototype.m_island = new b2Island; -b2World.prototype.m_bodyList = null; -b2World.prototype.m_jointList = null; -b2World.prototype.m_contactList = null; -b2World.prototype.m_bodyCount = 0; -b2World.prototype.m_contactCount = 0; -b2World.prototype.m_jointCount = 0; -b2World.prototype.m_controllerList = null; -b2World.prototype.m_controllerCount = 0; -b2World.prototype.m_gravity = null; -b2World.prototype.m_allowSleep = null; -b2World.prototype.m_groundBody = null; -b2World.prototype.m_destructionListener = null; -b2World.prototype.m_debugDraw = null; -b2World.prototype.m_inv_dt0 = null;if(typeof exports !== "undefined") { - exports.b2BoundValues = b2BoundValues; - exports.b2Math = b2Math; - exports.b2DistanceOutput = b2DistanceOutput; - exports.b2Mat33 = b2Mat33; - exports.b2ContactPoint = b2ContactPoint; - exports.b2PairManager = b2PairManager; - exports.b2PositionSolverManifold = b2PositionSolverManifold; - exports.b2OBB = b2OBB; - exports.b2CircleContact = b2CircleContact; - exports.b2PulleyJoint = b2PulleyJoint; - exports.b2Pair = b2Pair; - exports.b2TimeStep = b2TimeStep; - exports.b2FixtureDef = b2FixtureDef; - exports.b2World = b2World; - exports.b2PrismaticJoint = b2PrismaticJoint; - exports.b2Controller = b2Controller; - exports.b2ContactID = b2ContactID; - exports.b2RevoluteJoint = b2RevoluteJoint; - exports.b2JointDef = b2JointDef; - exports.b2Transform = b2Transform; - exports.b2GravityController = b2GravityController; - exports.b2EdgeAndCircleContact = b2EdgeAndCircleContact; - exports.b2EdgeShape = b2EdgeShape; - exports.b2BuoyancyController = b2BuoyancyController; - exports.b2LineJointDef = b2LineJointDef; - exports.b2Contact = b2Contact; - exports.b2DistanceJoint = b2DistanceJoint; - exports.b2Body = b2Body; - exports.b2DestructionListener = b2DestructionListener; - exports.b2PulleyJointDef = b2PulleyJointDef; - exports.b2ContactEdge = b2ContactEdge; - exports.b2ContactConstraint = b2ContactConstraint; - exports.b2ContactImpulse = b2ContactImpulse; - exports.b2DistanceJointDef = b2DistanceJointDef; - exports.b2ContactResult = b2ContactResult; - exports.b2EdgeChainDef = b2EdgeChainDef; - exports.b2Vec2 = b2Vec2; - exports.b2Vec3 = b2Vec3; - exports.b2DistanceProxy = b2DistanceProxy; - exports.b2FrictionJointDef = b2FrictionJointDef; - exports.b2PolygonContact = b2PolygonContact; - exports.b2TensorDampingController = b2TensorDampingController; - exports.b2ContactFactory = b2ContactFactory; - exports.b2WeldJointDef = b2WeldJointDef; - exports.b2ConstantAccelController = b2ConstantAccelController; - exports.b2GearJointDef = b2GearJointDef; - exports.ClipVertex = ClipVertex; - exports.b2SeparationFunction = b2SeparationFunction; - exports.b2ManifoldPoint = b2ManifoldPoint; - exports.b2Color = b2Color; - exports.b2PolygonShape = b2PolygonShape; - exports.b2DynamicTreePair = b2DynamicTreePair; - exports.b2ContactConstraintPoint = b2ContactConstraintPoint; - exports.b2FrictionJoint = b2FrictionJoint; - exports.b2ContactFilter = b2ContactFilter; - exports.b2ControllerEdge = b2ControllerEdge; - exports.b2Distance = b2Distance; - exports.b2Fixture = b2Fixture; - exports.b2DynamicTreeNode = b2DynamicTreeNode; - exports.b2MouseJoint = b2MouseJoint; - exports.b2DistanceInput = b2DistanceInput; - exports.b2BodyDef = b2BodyDef; - exports.b2DynamicTreeBroadPhase = b2DynamicTreeBroadPhase; - exports.b2Settings = b2Settings; - exports.b2Proxy = b2Proxy; - exports.b2Point = b2Point; - exports.b2BroadPhase = b2BroadPhase; - exports.b2Manifold = b2Manifold; - exports.b2WorldManifold = b2WorldManifold; - exports.b2PrismaticJointDef = b2PrismaticJointDef; - exports.b2RayCastOutput = b2RayCastOutput; - exports.b2ConstantForceController = b2ConstantForceController; - exports.b2TimeOfImpact = b2TimeOfImpact; - exports.b2CircleShape = b2CircleShape; - exports.b2MassData = b2MassData; - exports.b2Joint = b2Joint; - exports.b2GearJoint = b2GearJoint; - exports.b2DynamicTree = b2DynamicTree; - exports.b2JointEdge = b2JointEdge; - exports.b2LineJoint = b2LineJoint; - exports.b2NullContact = b2NullContact; - exports.b2ContactListener = b2ContactListener; - exports.b2RayCastInput = b2RayCastInput; - exports.b2TOIInput = b2TOIInput; - exports.Features = Features; - exports.b2FilterData = b2FilterData; - exports.b2Island = b2Island; - exports.b2ContactManager = b2ContactManager; - exports.b2ContactSolver = b2ContactSolver; - exports.b2Simplex = b2Simplex; - exports.b2AABB = b2AABB; - exports.b2Jacobian = b2Jacobian; - exports.b2Bound = b2Bound; - exports.b2RevoluteJointDef = b2RevoluteJointDef; - exports.b2PolyAndEdgeContact = b2PolyAndEdgeContact; - exports.b2SimplexVertex = b2SimplexVertex; - exports.b2WeldJoint = b2WeldJoint; - exports.b2Collision = b2Collision; - exports.b2Mat22 = b2Mat22; - exports.b2SimplexCache = b2SimplexCache; - exports.b2PolyAndCircleContact = b2PolyAndCircleContact; - exports.b2MouseJointDef = b2MouseJointDef; - exports.b2Shape = b2Shape; - exports.b2Segment = b2Segment; - exports.b2ContactRegister = b2ContactRegister; - exports.b2DebugDraw = b2DebugDraw; - exports.b2Sweep = b2Sweep -} -; - -}}; -__resources__["/__builtin__/libs/cocos2d/ActionManager.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - console = require('system').console, - Timer = require('./Scheduler').Timer, - Scheduler = require('./Scheduler').Scheduler; - -var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ - targets: null, - currentTarget: null, - currentTargetSalvaged: null, - - /** - *

          A singleton that manages all the actions. Normally you - * won't need to use this singleton directly. 99% of the cases you will use the - * cocos.nodes.Node interface, which uses this singleton. But there are some cases where - * you might need to use this singleton. Examples:

          - * - *
            - *
          • When you want to run an action where the target is different from a cocos.nodes.Node
          • - *
          • When you want to pause / resume the actions
          • - *
          - * - * @memberOf cocos - * @constructs - * @extends BObject - * @singleton - */ - init: function () { - ActionManager.superclass.init.call(this); - - Scheduler.get('sharedScheduler').scheduleUpdate({target: this, priority: 0, paused: false}); - this.targets = []; - }, - - /** - * Adds an action with a target. If the target is already present, then the - * action will be added to the existing target. If the target is not - * present, a new instance of this target will be created either paused or - * paused, and the action will be added to the newly created target. When - * the target is paused, the queued actions won't be 'ticked'. - * - * @opt {cocos.nodes.Node} target Node to run the action on - */ - addAction: function (opts) { - - var targetID = opts.target.get('id'); - var element = this.targets[targetID]; - - if (!element) { - element = this.targets[targetID] = { - paused: false, - target: opts.target, - actions: [] - }; - } - - element.actions.push(opts.action); - - opts.action.startWithTarget(opts.target); - }, - - /** - * Remove an action - * - * @param {cocos.actions.Action} action Action to remove - */ - removeAction: function (action) { - var targetID = action.originalTarget.get('id'), - element = this.targets[targetID]; - - if (!element) { - return; - } - - var actionIndex = element.actions.indexOf(action); - - if (actionIndex == -1) { - return; - } - - if (this.currentTarget == element) { - element.currentActionSalvaged = true; - } - - element.actions[actionIndex] = null; - element.actions.splice(actionIndex, 1); // Delete array item - - if (element.actions.length === 0) { - if (this.currentTarget == element) { - this.set('currentTargetSalvaged', true); - } - } - - }, - - /** - * Remove all actions for a cocos.nodes.Node - * - * @param {cocos.nodes.Node} target Node to remove all actions for - */ - removeAllActionsFromTarget: function (target) { - var targetID = target.get('id'); - - var element = this.targets[targetID]; - if (!element) { - return; - } - - // Delete everything in array but don't replace it incase something else has a reference - element.actions.splice(0, element.actions.length); - }, - - /** - * @private - */ - update: function (dt) { - var self = this; - util.each(this.targets, function (currentTarget, i) { - - if (!currentTarget) { - return; - } - self.currentTarget = currentTarget; - - if (!currentTarget.paused) { - util.each(currentTarget.actions, function (currentAction, j) { - if (!currentAction) { - return; - } - - currentTarget.currentAction = currentAction; - currentTarget.currentActionSalvaged = false; - - currentTarget.currentAction.step(dt); - - if (currentTarget.currentAction.get('isDone')) { - currentTarget.currentAction.stop(); - - var a = currentTarget.currentAction; - currentTarget.currentAction = null; - self.removeAction(a); - } - - currentTarget.currentAction = null; - - }); - } - - if (self.currentTargetSalvaged && currentTarget.actions.length === 0) { - self.targets[i] = null; - delete self.targets[i]; - } - }); - }, - - pauseTarget: function (target) { - }, - - resumeTarget: function (target) { - // TODO - } -}); - -util.extend(ActionManager, /** @lends cocos.ActionManager */{ - /** - * Singleton instance of cocos.ActionManager - * @getter sharedManager - * @type cocos.ActionManager - */ - get_sharedManager: function (key) { - if (!this._instance) { - this._instance = this.create(); - } - - return this._instance; - } -}); - -exports.ActionManager = ActionManager; - -}}; -__resources__["/__builtin__/libs/cocos2d/actions/Action.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - console = require('system').console; - -/** - * @memberOf cocos.actions - * @class Base class for Actions - * @extends BObject - * @constructor - */ -var Action = BObject.extend(/** @lends cocos.actions.Action# */{ - /** - * The Node the action is being performed on - * @type cocos.nodes.Node - */ - target: null, - originalTarget: null, - - /** - * Called every frame with it's delta time. - * - * @param {Float} dt The delta time - */ - step: function (dt) { - console.log('Action.step() Override me'); - }, - - /** - * Called once per frame. - * - * @param {Float} time How much of the animation has played. 0.0 = just started, 1.0 just finished. - */ - update: function (time) { - console.log('Action.update() Override me'); - }, - - /** - * Called before the action start. It will also set the target. - * - * @param {cocos.nodes.Node} target The Node to run the action on - */ - startWithTarget: function (target) { - this.target = this.originalTarget = target; - }, - - /** - * Called after the action has finished. It will set the 'target' to nil. - * Important: You should never call cocos.actions.Action#stop manually. - * Instead, use cocos.nodes.Node#stopAction(action) - */ - stop: function () { - this.target = null; - }, - - /** - * @getter isDone - * @type {Boolean} - */ - get_isDone: function (key) { - return true; - }, - - - /** - * Returns a copy of this Action but in reverse - * - * @returns {cocos.actions.Action} A new Action in reverse - */ - reverse: function () { - } -}); - -var RepeatForever = Action.extend(/** @lends cocos.actions.RepeatForever# */{ - other: null, - - /** - * @memberOf cocos.actions - * @class Repeats an action forever. To repeat the an action for a limited - * number of times use the cocos.Repeat action. - * @extends cocos.actions.Action - * @param {cocos.actions.Action} action An action to repeat forever - * @constructs - */ - init: function (action) { - RepeatForever.superclass.init(this, action); - - this.other = action; - }, - - startWithTarget: function (target) { - RepeatForever.superclass.startWithTarget.call(this, target); - - this.other.startWithTarget(this.target); - }, - - step: function (dt) { - this.other.step(dt); - if (this.other.get('isDone')) { - var diff = dt - this.other.get('duration') - this.other.get('elapsed'); - this.other.startWithTarget(this.target); - - this.other.step(diff); - } - }, - - get_isDone: function () { - return false; - }, - - reverse: function () { - return RepeatForever.create(this.other.reverse()); - }, - - copy: function () { - return RepeatForever.create(this.other.copy()); - } -}); - -var FiniteTimeAction = Action.extend(/** @lends cocos.actions.FiniteTimeAction# */{ - /** - * Number of seconds to run the Action for - * @type Float - */ - duration: 2, - - /** - * Repeats an action a number of times. To repeat an action forever use the - * cocos.RepeatForever action. - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.Action - */ - init: function () { - FiniteTimeAction.superclass.init.call(this); - }, - - /** @ignore */ - reverse: function () { - console.log('FiniteTimeAction.reverse() Override me'); - } -}); - -exports.Action = Action; -exports.RepeatForever = RepeatForever; -exports.FiniteTimeAction = FiniteTimeAction; - -}}; -__resources__["/__builtin__/libs/cocos2d/actions/ActionInstant.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - act = require('./Action'), - ccp = require('geometry').ccp; - -var ActionInstant = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionInstant */{ - /** - * @memberOf cocos.actions - * @class Base class for actions that triggers instantly. They have no duration. - * @extends cocos.actions.FiniteTimeAction - * @constructs - */ - init: function (opts) { - ActionInstant.superclass.init.call(this, opts); - - this.duration = 0; - }, - get_isDone: function () { - return true; - }, - step: function (dt) { - this.update(1); - }, - update: function (t) { - // ignore - }, - reverse: function () { - return this.copy(); - } -}); - -var FlipX = ActionInstant.extend(/** @lends cocos.actions.FlipX# */{ - flipX: false, - - /** - * @memberOf cocos.actions - * @class Flips a sprite horizontally - * @extends cocos.actions.ActionInstant - * @constructs - * - * @opt {Boolean} flipX Should the sprite be flipped - */ - init: function (opts) { - FlipX.superclass.init.call(this, opts); - - this.flipX = opts.flipX; - }, - startWithTarget: function (target) { - FlipX.superclass.startWithTarget.call(this, target); - - target.set('flipX', this.flipX); - }, - reverse: function () { - return FlipX.create({flipX: !this.flipX}); - }, - copy: function () { - return FlipX.create({flipX: this.flipX}); - } -}); - -var FlipY = ActionInstant.extend(/** @lends cocos.actions.FlipY# */{ - flipY: false, - - /** - * @memberOf cocos.actions - * @class Flips a sprite vertically - * @extends cocos.actions.ActionInstant - * @constructs - * - * @opt {Boolean} flipY Should the sprite be flipped - */ - init: function (opts) { - FlipY.superclass.init.call(this, opts); - - this.flipY = opts.flipY; - }, - startWithTarget: function (target) { - FlipY.superclass.startWithTarget.call(this, target); - - target.set('flipY', this.flipY); - }, - reverse: function () { - return FlipY.create({flipY: !this.flipY}); - }, - copy: function () { - return FlipY.create({flipY: this.flipY}); - } -}); - -/* @class */ -// helper for actions that must simply call a function -// Implementation of cocos2d CCCallFunc - -var CallFunc = ActionInstant.extend({ - callback: null, - - init: function(opts) { - CallFunc.superclass.init.call(this, opts); - this.callback = util.callback(opts.target, opts.method); - }, - - startWithTarget: function(target) { - CallFunc.superclass.startWithTarget.call(this, target); - this.execute(); - }, - - execute: function() { - this.callback.call(); - } -}); - -exports.ActionInstant = ActionInstant; -exports.FlipX = FlipX; -exports.FlipY = FlipY; -exports.CallFunc = CallFunc; - - -}}; -__resources__["/__builtin__/libs/cocos2d/actions/ActionInterval.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - act = require('./Action'), - geo = require('geometry'), - ccp = geo.ccp; - -var ActionInterval = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionInterval# */{ - /** - * Number of seconds that have elapsed - * @type Float - */ - elapsed: 0.0, - - _firstTick: true, - - /** - * Base class actions that do have a finite time duration. - * - * Possible actions: - * - * - An action with a duration of 0 seconds - * - An action with a duration of 35.5 seconds Infinite time actions are valid - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.FiniteTimeAction - * - * @opt {Float} duration Number of seconds to run action for - */ - init: function (opts) { - ActionInterval.superclass.init.call(this, opts); - - var dur = opts.duration || 0; - if (dur === 0) { - dur = 0.0000001; - } - - this.set('duration', dur); - this.set('elapsed', 0); - this._firstTick = true; - }, - - get_isDone: function () { - return (this.elapsed >= this.duration); - }, - - step: function (dt) { - if (this._firstTick) { - this._firstTick = false; - this.elapsed = 0; - } else { - this.elapsed += dt; - } - - this.update(Math.min(1, this.elapsed / this.duration)); - }, - - startWithTarget: function (target) { - ActionInterval.superclass.startWithTarget.call(this, target); - - this.elapsed = 0.0; - this._firstTick = true; - }, - - reverse: function () { - throw "Reverse Action not implemented"; - } -}); - -var DelayTime = ActionInterval.extend(/** @lends cocos.actions.DelayTime# */{ - /** - * Delays the action a certain amount of seconds - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.DelayTime - */ - update: function(t) { - return; // No-op - }, - - reverse: function() { - return DelayTime.create({duration: this.get('duration')}); - } -}); - - -var ScaleTo = ActionInterval.extend(/** @lends cocos.actions.ScaleTo# */{ - /** - * Current X Scale - * @type Float - */ - scaleX: 1, - - /** - * Current Y Scale - * @type Float - */ - scaleY: 1, - - /** - * Initial X Scale - * @type Float - */ - startScaleX: 1, - - /** - * Initial Y Scale - * @type Float - */ - startScaleY: 1, - - /** - * Final X Scale - * @type Float - */ - endScaleX: 1, - - /** - * Final Y Scale - * @type Float - */ - endScaleY: 1, - - /** - * Delta X Scale - * @type Float - * @private - */ - deltaX: 0.0, - - /** - * Delta Y Scale - * @type Float - * @private - */ - deltaY: 0.0, - - /** - * Scales a cocos.Node object to a zoom factor by modifying it's scale attribute. - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.ActionInterval - * - * @opt {Float} duration Number of seconds to run action for - * @opt {Float} [scale] Size to scale Node to - * @opt {Float} [scaleX] Size to scale width of Node to - * @opt {Float} [scaleY] Size to scale height of Node to - */ - init: function (opts) { - ScaleTo.superclass.init.call(this, opts); - - if (opts.scale !== undefined) { - this.endScaleX = this.endScaleY = opts.scale; - } else { - this.endScaleX = opts.scaleX; - this.endScaleY = opts.scaleY; - } - - - }, - - startWithTarget: function (target) { - ScaleTo.superclass.startWithTarget.call(this, target); - - this.startScaleX = this.target.get('scaleX'); - this.startScaleY = this.target.get('scaleY'); - this.deltaX = this.endScaleX - this.startScaleX; - this.deltaY = this.endScaleY - this.startScaleY; - }, - - update: function (t) { - if (!this.target) { - return; - } - - this.target.set('scaleX', this.startScaleX + this.deltaX * t); - this.target.set('scaleY', this.startScaleY + this.deltaY * t); - } -}); - -var ScaleBy = ScaleTo.extend(/** @lends cocos.actions.ScaleBy# */{ - /** - * Scales a cocos.Node object to a zoom factor by modifying it's scale attribute. - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.ScaleTo - * - * @opt {Float} duration Number of seconds to run action for - * @opt {Float} [scale] Size to scale Node by - * @opt {Float} [scaleX] Size to scale width of Node by - * @opt {Float} [scaleY] Size to scale height of Node by - */ - init: function (opts) { - ScaleBy.superclass.init.call(this, opts); - }, - - startWithTarget: function (target) { - ScaleBy.superclass.startWithTarget.call(this, target); - - this.deltaX = this.startScaleX * this.endScaleX - this.startScaleX; - this.deltaY = this.startScaleY * this.endScaleY - this.startScaleY; - }, - - reverse: function () { - return ScaleBy.create({duration: this.duration, scaleX: 1 / this.endScaleX, scaleY: 1 / this.endScaleY}); - } -}); - - -var RotateTo = ActionInterval.extend(/** @lends cocos.actions.RotateTo# */{ - /** - * Final angle - * @type Float - */ - dstAngle: 0, - - /** - * Initial angle - * @type Float - */ - startAngle: 0, - - /** - * Angle delta - * @type Float - */ - diffAngle: 0, - - /** - * @class Rotates a cocos.Node object to a certain angle by modifying its rotation - * attribute. The direction will be decided by the shortest angle. - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.ActionInterval - * - * @opt {Float} duration Number of seconds to run action for - * @opt {Float} angle Angle in degrees to rotate to - */ - init: function (opts) { - RotateTo.superclass.init.call(this, opts); - - this.dstAngle = opts.angle; - }, - - startWithTarget: function (target) { - RotateTo.superclass.startWithTarget.call(this, target); - - this.startAngle = target.get('rotation'); - - if (this.startAngle > 0) { - this.startAngle = (this.startAngle % 360); - } else { - this.startAngle = (this.startAngle % -360); - } - - this.diffAngle = this.dstAngle - this.startAngle; - if (this.diffAngle > 180) { - this.diffAngle -= 360; - } else if (this.diffAngle < -180) { - this.diffAngle += 360; - } - }, - - update: function (t) { - this.target.set('rotation', this.startAngle + this.diffAngle * t); - } -}); - -var RotateBy = RotateTo.extend(/** @lends cocos.actions.RotateBy# */{ - /** - * Number of degrees to rotate by - * @type Float - */ - angle: 0, - - /** - * Rotates a cocos.Node object to a certain angle by modifying its rotation - * attribute. The direction will be decided by the shortest angle. - * - * @memberOf cocos.action - * @constructs - * @extends cocos.actions.RotateTo - * - * @opt {Float} duration Number of seconds to run action for - * @opt {Float} angle Angle in degrees to rotate by - */ - init: function (opts) { - RotateBy.superclass.init.call(this, opts); - - this.angle = opts.angle; - }, - - startWithTarget: function (target) { - RotateBy.superclass.startWithTarget.call(this, target); - - this.startAngle = this.target.get('rotation'); - }, - - update: function (t) { - this.target.set('rotation', this.startAngle + this.angle * t); - }, - - reverse: function () { - return RotateBy.create({duration: this.duration, angle: -this.angle}); - }, - - copy: function () { - return RotateBy.create({duration: this.duration, angle: this.angle}); - } -}); - -var MoveTo = ActionInterval.extend(/** @lends cocos.actions.MoveTo# */{ - delta: null, - startPosition: null, - endPosition: null, - - /** - * @class Animates moving a cocos.nodes.Node object to a another point. - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.ActionInterval - * - * @opt {Float} duration Number of seconds to run action for - * @opt {geometry.Point} position Destination poisition - */ - init: function (opts) { - MoveTo.superclass.init.call(this, opts); - - this.set('endPosition', util.copy(opts.position)); - }, - - startWithTarget: function (target) { - MoveTo.superclass.startWithTarget.call(this, target); - - this.set('startPosition', util.copy(target.get('position'))); - this.set('delta', geo.ccpSub(this.get('endPosition'), this.get('startPosition'))); - }, - - update: function (t) { - var startPosition = this.get('startPosition'), - delta = this.get('delta'); - this.target.set('position', ccp(startPosition.x + delta.x * t, startPosition.y + delta.y * t)); - } -}); - -var MoveBy = MoveTo.extend(/** @lends cocos.actions.MoveBy# */{ - /** - * Animates moving a cocos.node.Node object by a given number of pixels - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.MoveTo - * - * @opt {Float} duration Number of seconds to run action for - * @opt {geometry.Point} position Number of pixels to move by - */ - init: function (opts) { - MoveBy.superclass.init.call(this, opts); - - this.set('delta', util.copy(opts.position)); - }, - - startWithTarget: function (target) { - var dTmp = this.get('delta'); - MoveBy.superclass.startWithTarget.call(this, target); - this.set('delta', dTmp); - } -}); - - -/** - * @memberOf cocos.actions - * @class Fades out a cocos.nodes.Node to zero opacity - * @extends cocos.actions.ActionInterval - */ -var FadeOut = ActionInterval.extend(/** @lends cocos.actions.FadeOut# */{ - update: function (t) { - var target = this.get('target'); - if (!target) return; - target.set('opacity', 255 - (255 * t)); - }, - - reverse: function () { - return exports.FadeIn.create({duration: this.get('duration')}); - } -}); - -/** - * @memberOf cocos.actions - * @class Fades in a cocos.nodes.Node to 100% opacity - * @extends cocos.actions.ActionInterval - */ -var FadeIn = ActionInterval.extend(/** @lends cocos.actions.FadeIn# */{ - update: function (t) { - var target = this.get('target'); - if (!target) return; - target.set('opacity', t * 255); - }, - - reverse: function () { - return exports.FadeOut.create({duration: this.get('duration')}); - } -}); - -/** - * @memberOf cocos.actions - * @class Fades a cocos.nodes.Node to a given opacity - * @extends cocos.actions.ActionInterval - */ -var FadeTo = ActionInterval.extend(/** @lends cocos.actions.FadeTo# */{ - /** - * The final opacity - * @type Float - */ - toOpacity: null, - - /** - * The initial opacity - * @type Float - */ - fromOpacity: null, - - init: function (opts) { - FadeTo.superclass.init.call(this, opts); - this.set('toOpacity', opts.toOpacity); - }, - - startWithTarget: function (target) { - FadeTo.superclass.startWithTarget.call(this, target); - this.set('fromOpacity', target.get('opacity')); - }, - - update: function (t) { - var target = this.get('target'); - if (!target) return; - - target.set('opacity', this.fromOpacity + ( this.toOpacity - this.fromOpacity ) * t); - } -}); - -var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ - /** - * Array of actions to run - * @type cocos.nodes.Node[] - */ - actions: null, - - /** - * The array index of the currently running action - * @type Integer - */ - currentActionIndex: 0, - - /** - * The duration when the current action finishes - * @type Float - */ - currentActionEndDuration: 0, - - /** - * Runs a number of actions sequentially, one after another - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.ActionInterval - * - * @opt {Float} duration Number of seconds to run action for - * @opt {cocos.actions.Action[]} Array of actions to run in sequence - */ - init: function (opts) { - Sequence.superclass.init.call(this, opts); - - this.actions = util.copy(opts.actions); - this.actionSequence = {}; - - util.each(this.actions, util.callback(this, function (action) { - this.duration += action.duration; - })); - }, - - startWithTarget: function (target) { - Sequence.superclass.startWithTarget.call(this, target); - - this.currentActionIndex = 0; - this.currentActionEndDuration = this.actions[0].get('duration'); - this.actions[0].startWithTarget(this.target); - }, - - stop: function () { - util.each(this.actions, function (action) { - action.stop(); - }); - - Sequence.superclass.stop.call(this); - }, - - step: function (dt) { - if (this._firstTick) { - this._firstTick = false; - this.elapsed = 0; - } else { - this.elapsed += dt; - } - // Required to prevent array bounds index errors - if (this.currentActionIndex < this.actions.length) { - this.actions[this.currentActionIndex].step(dt); - this.update(Math.min(1, this.elapsed / this.duration)); - } - }, - - update: function (dt) { - // Action finished onto the next one - if (this.elapsed > this.currentActionEndDuration) { - var previousAction = this.actions[this.currentActionIndex]; - previousAction.update(1.0); - previousAction.stop(); - - - this.currentActionIndex++; - - if (this.currentActionIndex < this.actions.length) { - var currentAction = this.actions[this.currentActionIndex]; - currentAction.startWithTarget(this.target); - - this.currentActionEndDuration += currentAction.duration; - } - } - }, - - copy: function () { - return Sequence.create({actions: this.get('actions')}); - } -}); - - -var Spawn = ActionInterval.extend(/** @lends cocos.actions.Spawn# */{ - one: null, - two: null, - - /** helper constructor to create action from array of actions - * - * @opt {Array} actions: list of actions to run simultaneously - */ - initWithActions: function(opts) { - var now, prev = opts.actions.shift(); - while (opts.actions.length > 0) { - now = opts.actions.shift(); - if (now) { - prev = Spawn.create({one: prev, two: now}); - } else { - break; - } - } - return prev; - }, - - /** - * initializes the Spawn action with the 2 actions to spawn - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.ActionInterval - * - * @opt {cocos.actions.FiniteTimeAction} one: first action to spawn - * @opt {cocos.actions.FiniteTimeAction} two: second action to spawn - */ - init: function(opts) { - var action1 = opts.one, - action2 = opts.two; - - if (!action1 || !action2) { - throw "cocos.actions.Spawn: required actions missing"; - } - var d1 = action1.get('duration'), - d2 = action2.get('duration'); - - Spawn.superclass.init.call(this, {duration: Math.max(d1, d2)}); - - this.set('one', action1); - this.set('two', action2); - - if (d1 > d2) { - this.set('two', cocos.actions.Sequence.create({actions: [ - action2, - cocos.actions.DelayTime.create({duration: d1-d2}) - ]})); - } else if (d1 < d2) { - this.set('one', cocos.actions.Sequence.create({actions: [ - action1, - cocos.actions.DelayTime.create({duration: d2-d1}) - ]})); - } - } -}); - -var Animate = ActionInterval.extend(/** @lends cocos.actions.Animate# */{ - animation: null, - restoreOriginalFrame: true, - origFrame: null, - - - /** - * Animates a sprite given the name of an Animation - * - * @memberOf cocos.actions - * @constructs - * @extends cocos.actions.ActionInterval - * - * @opt {Float} duration Number of seconds to run action for - * @opt {cocos.Animation} animation Animation to run - * @opt {Boolean} [restoreOriginalFrame=true] Return to first frame when finished - */ - init: function (opts) { - this.animation = opts.animation; - this.restoreOriginalFrame = opts.restoreOriginalFrame !== false; - opts.duration = this.animation.frames.length * this.animation.delay; - - Animate.superclass.init.call(this, opts); - }, - - startWithTarget: function (target) { - Animate.superclass.startWithTarget.call(this, target); - - if (this.restoreOriginalFrame) { - this.set('origFrame', this.target.get('displayedFrame')); - } - }, - - stop: function () { - if (this.target && this.restoreOriginalFrame) { - var sprite = this.target; - sprite.set('displayFrame', this.origFrame); - } - - Animate.superclass.stop.call(this); - }, - - update: function (t) { - var frames = this.animation.get('frames'), - numberOfFrames = frames.length, - idx = Math.floor(t * numberOfFrames); - - if (idx >= numberOfFrames) { - idx = numberOfFrames - 1; - } - - var sprite = this.target; - if (!sprite.isFrameDisplayed(frames[idx])) { - sprite.set('displayFrame', frames[idx]); - } - }, - - copy: function () { - return Animate.create({animation: this.animation, restoreOriginalFrame: this.restoreOriginalFrame}); - } - -}); - -exports.ActionInterval = ActionInterval; -exports.DelayTime = DelayTime; -exports.ScaleTo = ScaleTo; -exports.ScaleBy = ScaleBy; -exports.RotateTo = RotateTo; -exports.RotateBy = RotateBy; -exports.MoveTo = MoveTo; -exports.MoveBy = MoveBy; -exports.FadeIn = FadeIn; -exports.FadeOut = FadeOut; -exports.FadeTo = FadeTo; -exports.Spawn = Spawn; -exports.Sequence = Sequence; -exports.Animate = Animate; - -}}; -__resources__["/__builtin__/libs/cocos2d/actions/index.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - path = require('path'); - -var modules = 'Action ActionInterval ActionInstant'.w(); - -/** - * @memberOf cocos - * @namespace Actions used to animate or change a Node - */ -var actions = {}; - -util.each(modules, function (mod, i) { - util.extend(actions, require('./' + mod)); -}); - -module.exports = actions; - -}}; -__resources__["/__builtin__/libs/cocos2d/Animation.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'); - -var Animation = BObject.extend(/** @lends cocos.Animation# */{ - name: null, - delay: 0.0, - frames: null, - - /** - * A cocos.Animation object is used to perform animations on the Sprite objects. - * - * The Animation object contains cocos.SpriteFrame objects, and a possible delay between the frames. - * You can animate a cocos.Animation object by using the cocos.actions.Animate action. - * - * @memberOf cocos - * @constructs - * @extends BObject - * - * @opt {cocos.SpriteFrame[]} frames Frames to animate - * @opt {Float} [delay=0.0] Delay between each frame - * - * @example - * var animation = cocos.Animation.create({frames: [f1, f2, f3], delay: 0.1}); - * sprite.runAction(cocos.actions.Animate.create({animation: animation})); - */ - init: function (opts) { - Animation.superclass.init.call(this, opts); - - this.frames = opts.frames || []; - this.delay = opts.delay || 0.0; - } -}); - -exports.Animation = Animation; - -}}; -__resources__["/__builtin__/libs/cocos2d/AnimationCache.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - Plist = require('Plist').Plist; - -var AnimationCache = BObject.extend(/** @lends cocos.AnimationCache# */{ - /** - * Cached animations - * @type Object - */ - animations: null, - - /** - * @memberOf cocos - * @constructs - * @extends BObject - * @singleton - */ - init: function () { - AnimationCache.superclass.init.call(this); - - this.set('animations', {}); - }, - - /** - * Add an animation to the cache - * - * @opt {String} name Unique name of the animation - * @opt {cocos.Animcation} animation Animation to cache - */ - addAnimation: function (opts) { - var name = opts.name, - animation = opts.animation; - - this.get('animations')[name] = animation; - }, - - /** - * Remove an animation from the cache - * - * @opt {String} name Unique name of the animation - */ - removeAnimation: function (opts) { - var name = opts.name; - - delete this.get('animations')[name]; - }, - - /** - * Get an animation from the cache - * - * @opt {String} name Unique name of the animation - * @returns {cocos.Animation} Cached animation - */ - getAnimation: function (opts) { - var name = opts.name; - - return this.get('animations')[name]; - } -}); - -/** - * Class methods - */ -util.extend(AnimationCache, /** @lends cocos.AnimationCache */{ - /** - * @getter sharedAnimationCache - * @type cocos.AnimationCache - */ - get_sharedAnimationCache: function (key) { - if (!this._instance) { - this._instance = this.create(); - } - - return this._instance; - } -}); - -exports.AnimationCache = AnimationCache; - -}}; -__resources__["/__builtin__/libs/cocos2d/Director.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray FLIP_Y_AXIS SHOW_REDRAW_REGIONS*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - geo = require('geometry'), - ccp = geo.ccp, - events = require('events'), - Scheduler = require('./Scheduler').Scheduler, - EventDispatcher = require('./EventDispatcher').EventDispatcher, - Scene = require('./nodes/Scene').Scene; - - -/** - * requestAnimationFrame for smart animating - * @see http://paulirish.com/2011/requestanimationframe-for-smart-animating/ - */ - -window.requestAnimFrame = (function (){ - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function (callback) { - window.setTimeout(callback, 1000 / 30); - }; -})(); - -var Director = BObject.extend(/** @lends cocos.Director# */{ - backgroundColor: 'rgb(0, 0, 0)', - canvas: null, - context: null, - sceneStack: null, - winSize: null, - isPaused: false, - maxFrameRate: 30, - displayFPS: false, - preloadScene: null, - isReady: false, - - // Time delta - dt: 0, - nextDeltaTimeZero: false, - lastUpdate: 0, - - _nextScene: null, - - /** - *

          Creates and handles the main view and manages how and when to execute the - * Scenes.

          - * - *

          This class is a singleton so don't instantiate it yourself, instead use - * cocos.Director.get('sharedDirector') to return the instance.

          - * - * @memberOf cocos - * @constructs - * @extends BObject - * @singleton - */ - init: function () { - Director.superclass.init.call(this); - - this.set('sceneStack', []); - }, - - /** - * Append to a HTML element. It will create a canvas tag - * - * @param {HTMLElement} view Any HTML element to add the application to - */ - attachInView: function (view) { - if (!view.tagName) { - throw "Director.attachInView must be given a HTML DOM Node"; - } - - while (view.firstChild) { - view.removeChild(view.firstChild); - } - - var canvas = document.createElement('canvas'); - this.set('canvas', canvas); - canvas.setAttribute('width', view.clientWidth); - canvas.setAttribute('height', view.clientHeight); - - var context = canvas.getContext('2d'); - this.set('context', context); - - if (FLIP_Y_AXIS) { - context.translate(0, view.clientHeight); - context.scale(1, -1); - } - - view.appendChild(canvas); - - this.set('winSize', {width: view.clientWidth, height: view.clientHeight}); - - // Setup event handling - - // Mouse events - var eventDispatcher = EventDispatcher.get('sharedDispatcher'); - var self = this; - function mouseDown(evt) { - evt.locationInWindow = ccp(evt.clientX, evt.clientY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - - function mouseDragged(evt) { - evt.locationInWindow = ccp(evt.clientX, evt.clientY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - - eventDispatcher.mouseDragged(evt); - } - function mouseUp(evt) { - evt.locationInWindow = ccp(evt.clientX, evt.clientY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - - document.body.removeEventListener('mousemove', mouseDragged, false); - document.body.removeEventListener('mouseup', mouseUp, false); - - eventDispatcher.mouseUp(evt); - } - - document.body.addEventListener('mousemove', mouseDragged, false); - document.body.addEventListener('mouseup', mouseUp, false); - - eventDispatcher.mouseDown(evt); - } - function mouseMoved(evt) { - evt.locationInWindow = ccp(evt.clientX, evt.clientY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - - eventDispatcher.mouseMoved(evt); - } - - canvas.addEventListener('mousedown', mouseDown, false); - canvas.addEventListener('mousemove', mouseMoved, false); - - // Add handlers for touch events. - - // for touchcancel event - can be fired anytime so must be defined outside - // touchStart() - function touchEnd(evt) { - if (!evt) evt = event; - evt.preventDefault(); - - // evt.changedTouches should have the last touch point - if (evt.changedTouches.length == 1) { - evt.locationInWindow = ccp(evt.changedTouches[0].pageX, evt.changedTouches[0].pageY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - } - eventDispatcher.mouseUp(evt); - } - - function touchStart(evt) { - if (!evt) evt = event; - - if (evt.touches.length == 1) { - evt.locationInWindow = ccp(evt.touches[0].pageX, evt.touches[0].pageY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - } else { - // TODO: multitouch support?? - } - - function touchMoved(evt) { - if (!evt) evt = event; - evt.preventDefault(); - - if (evt.touches.length == 1) { - evt.locationInWindow = ccp(evt.touches[0].pageX, evt.touches[0].pageY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - - eventDispatcher.mouseDragged(evt); - } else { - // TODO: multitouch support?? - } - } - - function touchUp(evt) { - if (!evt) evt = event; - evt.preventDefault(); - - // evt.changedTouches should have the last touch point - if (evt.changedTouches.length == 1) { - evt.locationInWindow = ccp(evt.changedTouches[0].pageX, evt.changedTouches[0].pageY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - - canvas.removeEventListener('touchmove', touchMoved, false); - canvas.removeEventListener('touchend', touchUp, false); - - eventDispatcher.mouseUp(evt); - } - } - - canvas.addEventListener('touchmove', touchMoved, false); - canvas.addEventListener('touchend', touchUp, false); - - eventDispatcher.mouseDown(evt); - } - - canvas.addEventListener('touchstart', touchStart, false); - // touchcancel must be bound to the body - document.body.addEventListener('touchcancel', touchEnd, false); - - // Keyboard events - function keyDown(evt) { - this._keysDown = this._keysDown || {}; - eventDispatcher.keyDown(evt); - } - function keyUp(evt) { - eventDispatcher.keyUp(evt); - } - /* - function keyPress(evt) { - eventDispatcher.keyPress(evt) - } - */ - document.documentElement.addEventListener('keydown', keyDown, false); - document.documentElement.addEventListener('keyup', keyUp, false); - - }, - - runPreloadScene: function () { - var preloader = this.get('preloadScene'); - if (!preloader) { - var PreloadScene = require('./nodes/PreloadScene').PreloadScene; - preloader = PreloadScene.create(); - this.set('preloadScene', preloader); - } - - events.addListener(preloader, 'complete', util.callback(this, function (preloader) { - this.isReady = true; - events.trigger(this, 'ready', this); - })); - - this.pushScene(preloader); - this.startAnimation(); - }, - - /** - * Enters the Director's main loop with the given Scene. Call it to run - * only your FIRST scene. Don't call it if there is already a running - * scene. - * - * @param {cocos.Scene} scene The scene to start - */ - runWithScene: function (scene) { - if (!(scene instanceof Scene)) { - throw "Director.runWithScene must be given an instance of Scene"; - } - - if (this._runningScene) { - throw "You can't run a Scene if another Scene is already running. Use replaceScene or pushScene instead"; - } - - this.pushScene(scene); - this.startAnimation(); - }, - - /** - * Replaces the running scene with a new one. The running scene is - * terminated. ONLY call it if there is a running scene. - * - * @param {cocos.Scene} scene The scene to replace with - */ - replaceScene: function (scene) { - var index = this.sceneStack.length; - - this._sendCleanupToScene = true; - this.sceneStack.pop(); - this.sceneStack.push(scene); - this._nextScene = scene; - }, - - /** - * Pops out a scene from the queue. This scene will replace the running - * one. The running scene will be deleted. If there are no more scenes in - * the stack the execution is terminated. ONLY call it if there is a - * running scene. - */ - popScene: function () { - }, - - /** - * Suspends the execution of the running scene, pushing it on the stack of - * suspended scenes. The new scene will be executed. Try to avoid big - * stacks of pushed scenes to reduce memory allocation. ONLY call it if - * there is a running scene. - * - * @param {cocos.Scene} scene The scene to add to the stack - */ - pushScene: function (scene) { - this._nextScene = scene; - }, - - /** - * The main loop is triggered again. Call this function only if - * cocos.Directory#stopAnimation was called earlier. - */ - startAnimation: function () { - this.animate(); - - }, - animate: function() { - this.drawScene(); - window.requestAnimFrame(util.callback(this, 'animate'), this.canvas); - }, - - /** - * Stops the animation. Nothing will be drawn. The main loop won't be - * triggered anymore. If you want to pause your animation call - * cocos.Directory#pause instead. - */ - stopAnimation: function () { - if (this._animationTimer) { - clearInterval(this._animationTimer); - this._animationTimer = null; - } - }, - - /** - * Calculate time since last call - * @private - */ - calculateDeltaTime: function () { - var now = (new Date()).getTime() / 1000; - - if (this.nextDeltaTimeZero) { - this.dt = 0; - this.nextDeltaTimeZero = false; - } - - this.dt = Math.max(0, now - this.lastUpdate); - - this.lastUpdate = now; - }, - - /** - * The main run loop - * @private - */ - drawScene: function () { - this.calculateDeltaTime(); - - if (!this.isPaused) { - Scheduler.get('sharedScheduler').tick(this.dt); - } - - - var context = this.get('context'); - context.fillStyle = this.get('backgroundColor'); - context.fillRect(0, 0, this.winSize.width, this.winSize.height); - //this.canvas.width = this.canvas.width - - - if (this._nextScene) { - this.setNextScene(); - } - - var rect = new geo.Rect(0, 0, this.winSize.width, this.winSize.height); - - if (rect) { - context.beginPath(); - context.rect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); - context.clip(); - context.closePath(); - } - - this._runningScene.visit(context, rect); - - if (SHOW_REDRAW_REGIONS) { - if (rect) { - context.beginPath(); - context.rect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); - context.fillStyle = "rgba(255, 0, 0, 0.5)"; - //context.fill(); - context.closePath(); - } - } - - if (this.get('displayFPS')) { - this.showFPS(); - } - }, - - /** - * Initialises the next scene - * @private - */ - setNextScene: function () { - // TODO transitions - - if (this._runningScene) { - this._runningScene.onExit(); - if (this._sendCleanupToScene) { - this._runningScene.cleanup(); - } - } - - this._runningScene = this._nextScene; - - this._nextScene = null; - - this._runningScene.onEnter(); - }, - - convertEventToCanvas: function (evt) { - var x = this.canvas.offsetLeft - document.documentElement.scrollLeft, - y = this.canvas.offsetTop - document.documentElement.scrollTop; - - var o = this.canvas; - while ((o = o.offsetParent)) { - x += o.offsetLeft - o.scrollLeft; - y += o.offsetTop - o.scrollTop; - } - - var p = geo.ccpSub(evt.locationInWindow, ccp(x, y)); - if (FLIP_Y_AXIS) { - p.y = this.canvas.height - p.y; - } - - return p; - }, - - showFPS: function () { - if (!this._fpsLabel) { - var Label = require('./nodes/Label').Label; - this._fpsLabel = Label.create({string: '', fontSize: 16}); - this._fpsLabel.set('anchorPoint', ccp(0, 1)); - this._frames = 0; - this._accumDt = 0; - } - - - this._frames++; - this._accumDt += this.get('dt'); - - if (this._accumDt > 1.0 / 3.0) { - var frameRate = this._frames / this._accumDt; - this._frames = 0; - this._accumDt = 0; - - this._fpsLabel.set('string', 'FPS: ' + (Math.round(frameRate * 100) / 100).toString()); - } - - - var s = this.get('winSize'); - this._fpsLabel.set('position', ccp(10, s.height - 10)); - - this._fpsLabel.visit(this.get('context')); - } - -}); - -/** - * Class methods - */ -util.extend(Director, /** @lends cocos.Director */{ - /** - * A shared singleton instance of cocos.Director - * - * @getter sharedDirector - * @type cocos.Director - */ - get_sharedDirector: function (key) { - if (!this._instance) { - this._instance = this.create(); - } - - return this._instance; - } -}); - -exports.Director = Director; - -}}; -__resources__["/__builtin__/libs/cocos2d/EventDispatcher.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - geo = require('geometry'); - -var EventDispatcher = BObject.extend(/** @lends cocos.EventDispatcher# */{ - dispatchEvents: true, - keyboardDelegates: null, - mouseDelegates: null, - _keysDown: null, - - /** - * This singleton is responsible for dispatching Mouse and Keyboard events. - * - * @memberOf cocos - * @constructs - * @extends BObject - * @singleton - */ - init: function () { - EventDispatcher.superclass.init.call(this); - - this.keyboardDelegates = []; - this.mouseDelegates = []; - - this._keysDown = {}; - }, - - addDelegate: function (opts) { - var delegate = opts.delegate, - priority = opts.priority, - flags = opts.flags, - list = opts.list; - - var listElement = { - delegate: delegate, - priority: priority, - flags: flags - }; - - var added = false; - for (var i = 0; i < list.length; i++) { - var elem = list[i]; - if (priority < elem.priority) { - // Priority is lower, so insert before elem - list.splice(i, 0, listElement); - added = true; - break; - } - } - - // High priority; append to array - if (!added) { - list.push(listElement); - } - }, - - removeDelegate: function (opts) { - var delegate = opts.delegate, - list = opts.list; - - var idx = -1, - i; - for (i = 0; i < list.length; i++) { - var l = list[i]; - if (l.delegate == delegate) { - idx = i; - break; - } - } - if (idx == -1) { - return; - } - list.splice(idx, 1); - }, - removeAllDelegates: function (opts) { - var list = opts.list; - - list.splice(0, list.length - 1); - }, - - addMouseDelegate: function (opts) { - var delegate = opts.delegate, - priority = opts.priority; - - var flags = 0; - - // TODO flags - - this.addDelegate({delegate: delegate, priority: priority, flags: flags, list: this.mouseDelegates}); - }, - - removeMouseDelegate: function (opts) { - var delegate = opts.delegate; - - this.removeDelegate({delegate: delegate, list: this.mouseDelegates}); - }, - - removeAllMouseDelegate: function () { - this.removeAllDelegates({list: this.mouseDelegates}); - }, - - addKeyboardDelegate: function (opts) { - var delegate = opts.delegate, - priority = opts.priority; - - var flags = 0; - - // TODO flags - - this.addDelegate({delegate: delegate, priority: priority, flags: flags, list: this.keyboardDelegates}); - }, - - removeKeyboardDelegate: function (opts) { - var delegate = opts.delegate; - - this.removeDelegate({delegate: delegate, list: this.keyboardDelegates}); - }, - - removeAllKeyboardDelegate: function () { - this.removeAllDelegates({list: this.keyboardDelegates}); - }, - - - - // Mouse Events - - mouseDown: function (evt) { - if (!this.dispatchEvents) { - return; - } - - this._previousMouseMovePosition = geo.ccp(evt.clientX, evt.clientY); - this._previousMouseDragPosition = geo.ccp(evt.clientX, evt.clientY); - - for (var i = 0; i < this.mouseDelegates.length; i++) { - var entry = this.mouseDelegates[i]; - if (entry.delegate.mouseDown) { - var swallows = entry.delegate.mouseDown(evt); - if (swallows) { - break; - } - } - } - }, - mouseMoved: function (evt) { - if (!this.dispatchEvents) { - return; - } - - if (this._previousMouseMovePosition) { - evt.deltaX = evt.clientX - this._previousMouseMovePosition.x; - evt.deltaY = evt.clientY - this._previousMouseMovePosition.y; - if (FLIP_Y_AXIS) { - evt.deltaY *= -1; - } - } else { - evt.deltaX = 0; - evt.deltaY = 0; - } - this._previousMouseMovePosition = geo.ccp(evt.clientX, evt.clientY); - - for (var i = 0; i < this.mouseDelegates.length; i++) { - var entry = this.mouseDelegates[i]; - if (entry.delegate.mouseMoved) { - var swallows = entry.delegate.mouseMoved(evt); - if (swallows) { - break; - } - } - } - }, - mouseDragged: function (evt) { - if (!this.dispatchEvents) { - return; - } - - if (this._previousMouseDragPosition) { - evt.deltaX = evt.clientX - this._previousMouseDragPosition.x; - evt.deltaY = evt.clientY - this._previousMouseDragPosition.y; - if (FLIP_Y_AXIS) { - evt.deltaY *= -1; - } - } else { - evt.deltaX = 0; - evt.deltaY = 0; - } - this._previousMouseDragPosition = geo.ccp(evt.clientX, evt.clientY); - - for (var i = 0; i < this.mouseDelegates.length; i++) { - var entry = this.mouseDelegates[i]; - if (entry.delegate.mouseDragged) { - var swallows = entry.delegate.mouseDragged(evt); - if (swallows) { - break; - } - } - } - }, - mouseUp: function (evt) { - if (!this.dispatchEvents) { - return; - } - - for (var i = 0; i < this.mouseDelegates.length; i++) { - var entry = this.mouseDelegates[i]; - if (entry.delegate.mouseUp) { - var swallows = entry.delegate.mouseUp(evt); - if (swallows) { - break; - } - } - } - }, - - // Keyboard events - keyDown: function (evt) { - var kc = evt.keyCode; - if (!this.dispatchEvents || this._keysDown[kc]) { - return; - } - - this._keysDown[kc] = true; - - for (var i = 0; i < this.keyboardDelegates.length; i++) { - var entry = this.keyboardDelegates[i]; - if (entry.delegate.keyDown) { - var swallows = entry.delegate.keyDown(evt); - if (swallows) { - break; - } - } - } - }, - - keyUp: function (evt) { - if (!this.dispatchEvents) { - return; - } - - var kc = evt.keyCode; - if (this._keysDown[kc]) { - delete this._keysDown[kc]; - } - - for (var i = 0; i < this.keyboardDelegates.length; i++) { - var entry = this.keyboardDelegates[i]; - if (entry.delegate.keyUp) { - var swallows = entry.delegate.keyUp(evt); - if (swallows) { - break; - } - } - } - } - -}); - -/** - * Class methods - */ -util.extend(EventDispatcher, /** @lends cocos.EventDispatcher */{ - /** - * A shared singleton instance of cocos.EventDispatcher - * - * @getter sharedDispatcher - * @type cocos.EventDispatcher - */ - get_sharedDispatcher: function (key) { - if (!this._instance) { - this._instance = this.create(); - } - - return this._instance; - } -}); -exports.EventDispatcher = EventDispatcher; - -}}; -__resources__["/__builtin__/libs/cocos2d/index.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - path = require('path'); - -var modules = 'Preloader RemoteImage RemoteResource SpriteFrame SpriteFrameCache Director Animation AnimationCache Scheduler ActionManager TMXXMLParser'.w(); - -/** - * @namespace All cocos2d objects live in this namespace - */ -var cocos = { - nodes: require('./nodes'), - actions: require('./actions') -}; - -util.each(modules, function (mod, i) { - util.extend(cocos, require('./' + mod)); -}); - -module.exports = cocos; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/BatchNode.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray SHOW_REDRAW_REGIONS*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - evt = require('events'), - geo = require('geometry'), - ccp = geo.ccp, - TextureAtlas = require('../TextureAtlas').TextureAtlas, - RenderTexture = require('./RenderTexture').RenderTexture, - Node = require('./Node').Node; - -var BatchNode = Node.extend(/** @lends cocos.nodes.BatchNode# */{ - partialDraw: false, - contentRect: null, - renderTexture: null, - dirty: true, - - /** - * Region to redraw - * @type geometry.Rect - */ - dirtyRegion: null, - dynamicResize: false, - - /** @private - * Areas that need redrawing - * - * Not implemented - */ - _dirtyRects: null, - - - /** - * Draws all children to an in-memory canvas and only redraws when something changes - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.Node - * - * @opt {geometry.Size} size The size of the in-memory canvas used for drawing to - * @opt {Boolean} [partialDraw=false] Draw only the area visible on screen. Small maps may be slower in some browsers if this is true. - */ - init: function (opts) { - BatchNode.superclass.init.call(this, opts); - - var size = opts.size || geo.sizeMake(1, 1); - this.set('partialDraw', opts.partialDraw); - - evt.addListener(this, 'contentsize_changed', util.callback(this, this._resizeCanvas)); - - this._dirtyRects = []; - this.set('contentRect', geo.rectMake(0, 0, size.width, size.height)); - this.renderTexture = RenderTexture.create(size); - this.renderTexture.sprite.set('isRelativeAnchorPoint', false); - this.addChild({child: this.renderTexture}); - }, - - addChild: function (opts) { - BatchNode.superclass.addChild.call(this, opts); - - var child = opts.child, - z = opts.z; - - if (child == this.renderTexture) { - return; - } - - // TODO handle texture resize - - // Watch for changes in child - var watchEvents = ['position_before_changed', - 'scalex_before_changed', - 'scaley_before_changed', - 'rotation_before_changed', - 'anchorpoint_before_changed', - 'opacity_before_changed', - 'visible_before_changed']; - evt.addListener(child, watchEvents, util.callback(this, function () { - this.addDirtyRegion(child.get('boundingBox')); - })); - - this.addDirtyRegion(child.get('boundingBox')); - }, - - removeChild: function (opts) { - BatchNode.superclass.removeChild.call(this, opts); - - // TODO remove istransformdirty_changed and visible_changed listeners - - this.set('dirty', true); - }, - - addDirtyRegion: function (rect) { - // Increase rect slightly to compensate for subpixel artifacts - rect = util.copy(rect); - rect.origin.x -= 2; - rect.origin.y -= 2; - rect.size.width += 4; - rect.size.height += 4; - - var region = this.get('dirtyRegion'); - if (!region) { - region = rect; - } else { - region = geo.rectUnion(region, rect); - } - - this.set('dirtyRegion', region); - this.set('dirty', true); - }, - - _resizeCanvas: function (oldSize) { - var size = this.get('contentSize'); - - if (geo.sizeEqualToSize(size, oldSize)) { - return; // No change - } - - - this.renderTexture.set('contentSize', size); - this.set('dirty', true); - }, - - update: function () { - - }, - - visit: function (context) { - if (!this.visible) { - return; - } - - context.save(); - - this.transform(context); - - var rect = this.get('dirtyRegion'); - // Only redraw if something changed - if (this.dirty) { - - if (rect) { - if (this.get('partialDraw')) { - // Clip region to visible area - var s = require('../Director').Director.get('sharedDirector').get('winSize'), - p = this.get('position'); - var r = new geo.Rect( - 0, 0, - s.width, s.height - ); - r = geo.rectApplyAffineTransform(r, this.worldToNodeTransform()); - rect = geo.rectIntersection(r, rect); - } - - this.renderTexture.clear(rect); - - this.renderTexture.context.save(); - this.renderTexture.context.beginPath(); - this.renderTexture.context.rect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); - this.renderTexture.context.clip(); - this.renderTexture.context.closePath(); - } else { - this.renderTexture.clear(); - } - - for (var i = 0, childLen = this.children.length; i < childLen; i++) { - var c = this.children[i]; - if (c == this.renderTexture) { - continue; - } - - // Draw children inside rect - if (!rect || geo.rectOverlapsRect(c.get('boundingBox'), rect)) { - c.visit(this.renderTexture.context, rect); - } - } - - if (SHOW_REDRAW_REGIONS) { - if (rect) { - this.renderTexture.context.beginPath(); - this.renderTexture.context.rect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); - this.renderTexture.context.fillStyle = "rgba(0, 0, 255, 0.5)"; - this.renderTexture.context.fill(); - this.renderTexture.context.closePath(); - } - } - - if (rect) { - this.renderTexture.context.restore(); - } - - this.set('dirty', false); - this.set('dirtyRegion', null); - } - - this.renderTexture.visit(context); - - context.restore(); - }, - - draw: function (ctx) { - }, - - onEnter: function () { - if (this.get('partialDraw')) { - evt.addListener(this.get('parent'), 'istransformdirty_changed', util.callback(this, function () { - var box = this.get('visibleRect'); - this.addDirtyRegion(box); - })); - } - } -}); - -var SpriteBatchNode = BatchNode.extend(/** @lends cocos.nodes.SpriteBatchNode# */{ - textureAtlas: null, - - /** - * @memberOf cocos.nodes - * @class A BatchNode that accepts only Sprite using the same texture - * @extends cocos.nodes.BatchNode - * @constructs - * - * @opt {String} file (Optional) Path to image to use as sprite atlas - * @opt {Texture2D} texture (Optional) Texture to use as sprite atlas - * @opt {cocos.TextureAtlas} textureAtlas (Optional) TextureAtlas to use as sprite atlas - */ - init: function (opts) { - SpriteBatchNode.superclass.init.call(this, opts); - - var file = opts.file, - textureAtlas = opts.textureAtlas, - texture = opts.texture; - - if (file || texture) { - textureAtlas = TextureAtlas.create({file: file, texture: texture}); - } - - this.set('textureAtlas', textureAtlas); - }, - - /** - * @getter texture - * @type cocos.Texture2D - */ - get_texture: function () { - return this.textureAtlas ? this.textureAtlas.texture : null; - } - -}); - -exports.BatchNode = BatchNode; -exports.SpriteBatchNode = SpriteBatchNode; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/index.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - path = require('path'); - -var modules = 'ProgressBar PreloadScene Node Layer Scene Label Sprite TMXTiledMap BatchNode RenderTexture Menu MenuItem Transition'.w(); - -/** - * @memberOf cocos - * @namespace All cocos2d nodes. i.e. anything that can be added to a Scene - */ -var nodes = {}; - -util.each(modules, function (mod, i) { - util.extend(nodes, require('./' + mod)); -}); - -module.exports = nodes; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/Label.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - console = require('system').console, - Director = require('../Director').Director, - Node = require('./Node').Node, - ccp = require('geometry').ccp; - -var Label = Node.extend(/** @lends cocos.nodes.Label# */{ - string: '', - fontName: 'Helvetica', - fontSize: 16, - fontColor: 'white', - - /** - * Renders a simple text label - * - * @constructs - * @extends cocos.nodes.Node - * - * @opt {String} [string=""] The text string to draw - * @opt {Float} [fontSize=16] The size of the font - * @opt {String} [fontName="Helvetica"] The name of the font to use - * @opt {String} [fontColor="white"] The color of the text - */ - init: function (opts) { - Label.superclass.init.call(this, opts); - - util.each('fontSize fontName fontColor string'.w(), util.callback(this, function (name) { - // Set property on init - if (opts[name]) { - this.set(name, opts[name]); - } - - // Update content size - this._updateLabelContentSize(); - })); - }, - - /** - * String of the font name and size to use in a format <canvas> understands - * - * @getter font - * @type String - */ - get_font: function (key) { - return this.get('fontSize') + 'px ' + this.get('fontName'); - }, - - draw: function (context) { - if (FLIP_Y_AXIS) { - context.save(); - - // Flip Y axis - context.scale(1, -1); - context.translate(0, -this.get('fontSize')); - } - - - context.fillStyle = this.get('fontColor'); - context.font = this.get('font'); - context.textBaseline = 'top'; - if (context.fillText) { - context.fillText(this.get('string'), 0, 0); - } else if (context.mozDrawText) { - context.mozDrawText(this.get('string')); - } - - if (FLIP_Y_AXIS) { - context.restore(); - } - }, - - /** - * @private - */ - _updateLabelContentSize: function () { - var ctx = Director.get('sharedDirector').get('context'); - var size = {width: 0, height: this.get('fontSize')}; - - var prevFont = ctx.font; - ctx.font = this.get('font'); - - if (ctx.measureText) { - var txtSize = ctx.measureText(this.get('string')); - size.width = txtSize.width; - } else if (ctx.mozMeasureText) { - size.width = ctx.mozMeasureText(this.get('string')); - } - - ctx.font = prevFont; - - this.set('contentSize', size); - } -}); - -module.exports.Label = Label; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/Layer.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var Node = require('./Node').Node, - util = require('util'), - evt = require('events'), - Director = require('../Director').Director, - ccp = require('geometry').ccp, - EventDispatcher = require('../EventDispatcher').EventDispatcher; - -var Layer = Node.extend(/** @lends cocos.nodes.Layer# */{ - isMouseEnabled: false, - isKeyboardEnabled: false, - mouseDelegatePriority: 0, - keyboardDelegatePriority: 0, - - /** - * A fullscreen Node. You need at least 1 layer in your app to add other nodes to. - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.Node - */ - init: function () { - Layer.superclass.init.call(this); - - var s = Director.get('sharedDirector').get('winSize'); - - this.set('isRelativeAnchorPoint', false); - this.anchorPoint = ccp(0.5, 0.5); - this.set('contentSize', s); - - evt.addListener(this, 'ismouseenabled_changed', util.callback(this, function () { - if (this.isRunning) { - if (this.isMouseEnabled) { - EventDispatcher.get('sharedDispatcher').addMouseDelegate({delegate: this, priority: this.get('mouseDelegatePriority')}); - } else { - EventDispatcher.get('sharedDispatcher').removeMouseDelegate({delegate: this}); - } - } - })); - - - evt.addListener(this, 'iskeyboardenabled_changed', util.callback(this, function () { - if (this.isRunning) { - if (this.isKeyboardEnabled) { - EventDispatcher.get('sharedDispatcher').addKeyboardDelegate({delegate: this, priority: this.get('keyboardDelegatePriority')}); - } else { - EventDispatcher.get('sharedDispatcher').removeKeyboardDelegate({delegate: this}); - } - } - })); - }, - - onEnter: function () { - if (this.isMouseEnabled) { - EventDispatcher.get('sharedDispatcher').addMouseDelegate({delegate: this, priority: this.get('mouseDelegatePriority')}); - } - if (this.isKeyboardEnabled) { - EventDispatcher.get('sharedDispatcher').addKeyboardDelegate({delegate: this, priority: this.get('keyboardDelegatePriority')}); - } - - Layer.superclass.onEnter.call(this); - }, - - onExit: function () { - if (this.isMouseEnabled) { - EventDispatcher.get('sharedDispatcher').removeMouseDelegate({delegate: this}); - } - if (this.isKeyboardEnabled) { - EventDispatcher.get('sharedDispatcher').removeKeyboardDelegate({delegate: this}); - } - - Layer.superclass.onExit.call(this); - } -}); - -module.exports.Layer = Layer; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/Menu.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - Layer = require('./Layer').Layer, - Director = require('../Director').Director, - MenuItem = require('./MenuItem').MenuItem, - geom = require('geometry'), ccp = geom.ccp; - -/** @private - * @constant */ -var kMenuStateWaiting = 0; - -/** @private - * @constant */ -var kMenuStateTrackingTouch = 1; - - -var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ - mouseDelegatePriority: (-Number.MAX_VALUE + 1), - state: kMenuStateWaiting, - selectedItem: null, - opacity: 255, - color: null, - - /** - * A fullscreen node used to render a selection of menu options - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.Layer - * - * @opt {cocos.nodes.MenuItem[]} items An array of MenuItems to draw on the menu - */ - init: function (opts) { - Menu.superclass.init.call(this, opts); - - var items = opts.items; - - this.set('isMouseEnabled', true); - - var s = Director.get('sharedDirector').get('winSize'); - - this.set('isRelativeAnchorPoint', false); - this.anchorPoint = ccp(0.5, 0.5); - this.set('contentSize', s); - - this.set('position', ccp(s.width / 2, s.height / 2)); - - - if (items) { - var z = 0; - util.each(items, util.callback(this, function (item) { - this.addChild({child: item, z: z++}); - })); - } - - - }, - - addChild: function (opts) { - if (!opts.child instanceof MenuItem) { - throw "Menu only supports MenuItem objects as children"; - } - - Menu.superclass.addChild.call(this, opts); - }, - - itemForMouseEvent: function (event) { - var location = event.locationInCanvas; - - var children = this.get('children'); - for (var i = 0, len = children.length; i < len; i++) { - var item = children[i]; - - if (item.get('visible') && item.get('isEnabled')) { - var local = item.convertToNodeSpace(location); - - var r = item.get('rect'); - r.origin = ccp(0, 0); - - if (geom.rectContainsPoint(r, local)) { - return item; - } - - } - } - - return null; - }, - - mouseUp: function (event) { - var selItem = this.get('selectedItem'); - if (selItem) { - selItem.set('isSelected', false); - selItem.activate(); - } - - if (this.state != kMenuStateWaiting) { - this.set('state', kMenuStateWaiting); - } - if (selItem) { - return true; - } - return false; - - }, - mouseDown: function (event) { - if (this.state != kMenuStateWaiting || !this.visible) { - return false; - } - - var selectedItem = this.itemForMouseEvent(event); - this.set('selectedItem', selectedItem); - if (selectedItem) { - selectedItem.set('isSelected', true); - this.set('state', kMenuStateTrackingTouch); - - return true; - } - - return false; - }, - - mouseDragged: function (event) { - var currentItem = this.itemForMouseEvent(event); - - if (currentItem != this.selectedItem) { - if (this.selectedItem) { - this.selectedItem.set('isSelected', false); - } - this.set('selectedItem', currentItem); - if (this.selectedItem) { - this.selectedItem.set('isSelected', true); - } - } - - if (currentItem && this.state == kMenuStateTrackingTouch) { - return true; - } - - return false; - - } - -}); - -exports.Menu = Menu; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/MenuItem.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - Node = require('./Node').Node, - Sprite = require('./Sprite').Sprite, - rectMake = require('geometry').rectMake, - ccp = require('geometry').ccp; - -var MenuItem = Node.extend(/** @lends cocos.nodes.MenuItem# */{ - isEnabled: true, - isSelected: false, - callback: null, - - /** - * Base class for any buttons or options in a menu - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.Node - * - * @opt {Function} callback Function to call when menu item is activated - */ - init: function (opts) { - MenuItem.superclass.init.call(this, opts); - - var callback = opts.callback; - - this.set('anchorPoint', ccp(0.5, 0.5)); - this.set('callback', callback); - }, - - activate: function () { - if (this.isEnabled && this.callback) { - this.callback(this); - } - }, - - /** - * @getter rect - * @type geometry.Rect - */ - get_rect: function () { - return rectMake( - this.position.x - this.contentSize.width * this.anchorPoint.x, - this.position.y - this.contentSize.height * this.anchorPoint.y, - this.contentSize.width, - this.contentSize.height - ); - } -}); - -var MenuItemSprite = MenuItem.extend(/** @lends cocos.nodes.MenuItemSprite# */{ - normalImage: null, - selectedImage: null, - disabledImage: null, - - /** - * A menu item that accepts any cocos.nodes.Node - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.MenuItem - * - * @opt {cocos.nodes.Node} normalImage Main Node to draw - * @opt {cocos.nodes.Node} selectedImage Node to draw when menu item is selected - * @opt {cocos.nodes.Node} disabledImage Node to draw when menu item is disabled - */ - init: function (opts) { - MenuItemSprite.superclass.init.call(this, opts); - - var normalImage = opts.normalImage, - selectedImage = opts.selectedImage, - disabledImage = opts.disabledImage; - - this.set('normalImage', normalImage); - this.set('selectedImage', selectedImage); - this.set('disabledImage', disabledImage); - - this.set('contentSize', normalImage.get('contentSize')); - }, - - draw: function (ctx) { - if (this.isEnabled) { - if (this.isSelected) { - this.selectedImage.draw(ctx); - } else { - this.normalImage.draw(ctx); - } - } else { - if (this.disabledImage) { - this.disabledImage.draw(ctx); - } else { - this.normalImage.draw(ctx); - } - } - } -}); - -var MenuItemImage = MenuItemSprite.extend(/** @lends cocos.nodes.MenuItemImage# */{ - - /** - * MenuItem that accepts image files - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.MenuItemSprite - * - * @opt {String} normalImage Main image file to draw - * @opt {String} selectedImage Image file to draw when menu item is selected - * @opt {String} disabledImage Image file to draw when menu item is disabled - */ - init: function (opts) { - var normalI = opts.normalImage, - selectedI = opts.selectedImage, - disabledI = opts.disabledImage, - callback = opts.callback; - - var normalImage = Sprite.create({file: normalI}), - selectedImage = Sprite.create({file: selectedI}), - disabledImage = null; - - if (disabledI) { - disabledImage = Sprite.create({file: disabledI}); - } - - return MenuItemImage.superclass.init.call(this, {normalImage: normalImage, selectedImage: selectedImage, disabledImage: disabledImage, callback: callback}); - } -}); - -exports.MenuItem = MenuItem; -exports.MenuItemImage = MenuItemImage; -exports.MenuItemSprite = MenuItemSprite; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/Node.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - evt = require('events'), - Scheduler = require('../Scheduler').Scheduler, - ActionManager = require('../ActionManager').ActionManager, - Dispatcher = require('../EventDispatcher').EventDispatcher, - geo = require('geometry'), ccp = geo.ccp; - -var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ - isCocosNode: true, - - /** - * Is the node visible - * @type boolean - */ - visible: true, - - /** - * Position relative to parent node - * @type geometry.Point - */ - position: null, - - /** - * Parent node - * @type cocos.nodes.Node - */ - parent: null, - - /** - * Unique tag to identify the node - * @type * - */ - tag: null, - - /** - * Size of the node - * @type geometry.Size - */ - contentSize: null, - - /** - * Nodes Z index. i.e. draw order - * @type Integer - */ - zOrder: 0, - - /** - * Anchor point for scaling and rotation. 0x0 is top left and 1x1 is bottom right - * @type geometry.Point - */ - anchorPoint: null, - - /** - * Anchor point for scaling and rotation in pixels from top left - * @type geometry.Point - */ - anchorPointInPixels: null, - - /** - * Rotation angle in degrees - * @type Float - */ - rotation: 0, - - /** - * X scale factor - * @type Float - */ - scaleX: 1, - - /** - * Y scale factor - * @type Float - */ - scaleY: 1, - - /** - * Opacity of the Node. 0 is totally transparent, 255 is totally opaque - * @type Float - */ - opacity: 255, - - isRunning: false, - isRelativeAnchorPoint: true, - - isTransformDirty: true, - isInverseDirty: true, - inverse: null, - transformMatrix: null, - - /** - * The child Nodes - * @type cocos.nodes.Node[] - */ - children: null, - - /** - * @memberOf cocos.nodes - * @class The base class all visual elements extend from - * @extends BObject - * @constructs - */ - init: function () { - Node.superclass.init.call(this); - this.set('contentSize', {width: 0, height: 0}); - this.anchorPoint = ccp(0.5, 0.5); - this.anchorPointInPixels = ccp(0, 0); - this.position = ccp(0, 0); - this.children = []; - - util.each(['scaleX', 'scaleY', 'rotation', 'position', 'anchorPoint', 'contentSize', 'isRelativeAnchorPoint'], util.callback(this, function (key) { - evt.addListener(this, key.toLowerCase() + '_changed', util.callback(this, this._dirtyTransform)); - })); - evt.addListener(this, 'anchorpoint_changed', util.callback(this, this._updateAnchorPointInPixels)); - evt.addListener(this, 'contentsize_changed', util.callback(this, this._updateAnchorPointInPixels)); - }, - - /** - * Calculates the anchor point in pixels and updates the - * anchorPointInPixels property - * @private - */ - _updateAnchorPointInPixels: function () { - var ap = this.get('anchorPoint'), - cs = this.get('contentSize'); - this.set('anchorPointInPixels', ccp(cs.width * ap.x, cs.height * ap.y)); - }, - - /** - * Add a child Node - * - * @opt {cocos.nodes.Node} child The child node to add - * @opt {Integer} [z] Z Index for the child - * @opt {Integer|String} [tag] A tag to reference the child with - * @returns {cocos.nodes.Node} The node the child was added to. i.e. 'this' - */ - addChild: function (opts) { - if (opts.isCocosNode) { - return this.addChild({child: opts}); - } - - var child = opts.child, - z = opts.z, - tag = opts.tag; - - if (z === undefined || z === null) { - z = child.get('zOrder'); - } - - //this.insertChild({child: child, z:z}); - var added = false; - - - for (var i = 0, childLen = this.children.length; i < childLen; i++) { - var c = this.children[i]; - if (c.zOrder > z) { - added = true; - this.children.splice(i, 0, child); - break; - } - } - - if (!added) { - this.children.push(child); - } - - child.set('tag', tag); - child.set('zOrder', z); - child.set('parent', this); - - if (this.isRunning) { - child.onEnter(); - } - - return this; - }, - getChild: function (opts) { - var tag = opts.tag; - - for (var i = 0; i < this.children.length; i++) { - if (this.children[i].tag == tag) { - return this.children[i]; - } - } - - return null; - }, - - removeChild: function (opts) { - var child = opts.child, - cleanup = opts.cleanup; - - if (!child) { - return; - } - - var children = this.get('children'), - idx = children.indexOf(child); - - if (idx > -1) { - this.detatchChild({child: child, cleanup: cleanup}); - } - }, - - detatchChild: function (opts) { - var child = opts.child, - cleanup = opts.cleanup; - - var children = this.get('children'), - isRunning = this.get('isRunning'), - idx = children.indexOf(child); - - if (isRunning) { - child.onExit(); - } - - if (cleanup) { - child.cleanup(); - } - - child.set('parent', null); - children.splice(idx, 1); - }, - - reorderChild: function (opts) { - var child = opts.child, - z = opts.z; - - var pos = this.children.indexOf(child); - if (pos == -1) { - throw "Node isn't a child of this node"; - } - - child.set('zOrder', z); - - // Remove child - this.children.splice(pos, 1); - - // Add child back at correct location - var added = false; - for (var i = 0, childLen = this.children.length; i < childLen; i++) { - var c = this.children[i]; - if (c.zOrder > z) { - added = true; - this.children.splice(i, 0, child); - break; - } - } - - if (!added) { - this.children.push(child); - } - }, - - /** - * Draws the node. Override to do custom drawing. If it's less efficient to - * draw only the area inside the rect then don't bother. The result will be - * clipped to that area anyway. - * - * @param {CanvasRenderingContext2D|WebGLRenderingContext} context Canvas rendering context - * @param {geometry.Rect} rect Rectangular region that needs redrawing. Limit drawing to this area only if it's more efficient to do so. - */ - draw: function (context, rect) { - // All draw code goes here - }, - - /** - * @getter scale - * @type Float - */ - get_scale: function () { - if (this.scaleX != this.scaleY) { - throw "scaleX and scaleY aren't identical"; - } - - return this.scaleX; - }, - - /** - * @setter scale - * @type Float - */ - set_scale: function (val) { - this.set('scaleX', val); - this.set('scaleY', val); - }, - - scheduleUpdate: function (opts) { - opts = opts || {}; - var priority = opts.priority || 0; - - Scheduler.get('sharedScheduler').scheduleUpdate({target: this, priority: priority, paused: !this.get('isRunning')}); - }, - - /** - * Triggered when the node is added to a scene - * - * @event - */ - onEnter: function () { - util.each(this.children, function (child) { - child.onEnter(); - }); - - this.resumeSchedulerAndActions(); - this.set('isRunning', true); - }, - - /** - * Triggered when the node is removed from a scene - * - * @event - */ - onExit: function () { - this.pauseSchedulerAndActions(); - this.set('isRunning', false); - - util.each(this.children, function (child) { - child.onExit(); - }); - }, - - cleanup: function () { - this.stopAllActions(); - this.unscheduleAllSelectors(); - util.each(this.children, function (child) { - child.cleanup(); - }); - }, - - resumeSchedulerAndActions: function () { - Scheduler.get('sharedScheduler').resumeTarget(this); - ActionManager.get('sharedManager').resumeTarget(this); - }, - pauseSchedulerAndActions: function () { - Scheduler.get('sharedScheduler').pauseTarget(this); - ActionManager.get('sharedManager').pauseTarget(this); - }, - unscheduleSelector: function(selector) { - Scheduler.get('sharedScheduler').unschedule({target: this, method: selector}); - }, - unscheduleAllSelectors: function () { - Scheduler.get('sharedScheduler').unscheduleAllSelectorsForTarget(this); - }, - stopAllActions: function () { - ActionManager.get('sharedManager').removeAllActionsFromTarget(this); - }, - - visit: function (context, rect) { - if (!this.visible) { - return; - } - - context.save(); - - this.transform(context); - - // Set alpha value (global only for now) - context.globalAlpha = this.get('opacity') / 255.0; - - // Adjust redraw region by nodes position - if (rect) { - var pos = this.get('position'); - rect = new geo.Rect(rect.origin.x - pos.x, rect.origin.y - pos.y, rect.size.width, rect.size.height); - } - - // Draw background nodes - util.each(this.children, function (child, i) { - if (child.zOrder < 0) { - child.visit(context, rect); - } - }); - - this.draw(context, rect); - - // Draw foreground nodes - util.each(this.children, function (child, i) { - if (child.zOrder >= 0) { - child.visit(context, rect); - } - }); - - context.restore(); - }, - transform: function (context) { - // Translate - if (this.isRelativeAnchorPoint && (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels.y !== 0)) { - context.translate(Math.round(-this.anchorPointInPixels.x), Math.round(-this.anchorPointInPixels.y)); - } - - if (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels.y !== 0) { - context.translate(Math.round(this.position.x + this.anchorPointInPixels.x), Math.round(this.position.y + this.anchorPointInPixels.y)); - } else { - context.translate(Math.round(this.position.x), Math.round(this.position.y)); - } - - // Rotate - context.rotate(geo.degreesToRadians(this.get('rotation'))); - - // Scale - context.scale(this.scaleX, this.scaleY); - - if (this.anchorPointInPixels.x !== 0 || this.anchorPointInPixels.y !== 0) { - context.translate(Math.round(-this.anchorPointInPixels.x), Math.round(-this.anchorPointInPixels.y)); - } - }, - - runAction: function (action) { - ActionManager.get('sharedManager').addAction({action: action, target: this, paused: this.get('isRunning')}); - }, - - nodeToParentTransform: function () { - if (this.isTransformDirty) { - this.transformMatrix = geo.affineTransformIdentity(); - - if (!this.isRelativeAnchorPoint && !geo.pointEqualToPoint(this.anchorPointInPixels, ccp(0, 0))) { - this.transformMatrix = geo.affineTransformTranslate(this.transformMatrix, this.anchorPointInPixels.x, this.anchorPointInPixels.y); - } - - if (!geo.pointEqualToPoint(this.position, ccp(0, 0))) { - this.transformMatrix = geo.affineTransformTranslate(this.transformMatrix, this.position.x, this.position.y); - } - - if (this.rotation !== 0) { - this.transformMatrix = geo.affineTransformRotate(this.transformMatrix, -geo.degreesToRadians(this.rotation)); - } - if (!(this.scaleX == 1 && this.scaleY == 1)) { - this.transformMatrix = geo.affineTransformScale(this.transformMatrix, this.scaleX, this.scaleY); - } - - if (!geo.pointEqualToPoint(this.anchorPointInPixels, ccp(0, 0))) { - this.transformMatrix = geo.affineTransformTranslate(this.transformMatrix, -this.anchorPointInPixels.x, -this.anchorPointInPixels.y); - } - - this.set('isTransformDirty', false); - - } - - return this.transformMatrix; - }, - - parentToNodeTransform: function () { - // TODO - }, - - nodeToWorldTransform: function () { - var t = this.nodeToParentTransform(); - - var p; - for (p = this.get('parent'); p; p = p.get('parent')) { - t = geo.affineTransformConcat(t, p.nodeToParentTransform()); - } - - return t; - }, - - worldToNodeTransform: function () { - return geo.affineTransformInvert(this.nodeToWorldTransform()); - }, - - convertToNodeSpace: function (worldPoint) { - return geo.pointApplyAffineTransform(worldPoint, this.worldToNodeTransform()); - }, - - /** - * @getter boundingBox - * @type geometry.Rect - */ - get_boundingBox: function () { - var cs = this.get('contentSize'); - var rect = geo.rectMake(0, 0, cs.width, cs.height); - rect = geo.rectApplyAffineTransform(rect, this.nodeToParentTransform()); - return rect; - }, - - /** - * @getter worldBoundingBox - * @type geometry.Rect - */ - get_worldBoundingBox: function () { - var cs = this.get('contentSize'); - - var rect = geo.rectMake(0, 0, cs.width, cs.height); - rect = geo.rectApplyAffineTransform(rect, this.nodeToWorldTransform()); - return rect; - }, - - /** - * The area of the node currently visible on screen. Returns an rect even - * if visible is false. - * - * @getter visibleRect - * @type geometry.Rect - */ - get_visibleRect: function () { - var s = require('../Director').Director.get('sharedDirector').get('winSize'); - var rect = new geo.Rect( - 0, 0, - s.width, s.height - ); - - return geo.rectApplyAffineTransform(rect, this.worldToNodeTransform()); - }, - - /** - * @private - */ - _dirtyTransform: function () { - this.set('isTransformDirty', true); - } - -}); - -module.exports.Node = Node; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/PreloadScene.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var Scene = require('./Scene').Scene, - Director = require('../Director').Director, - Label = require('./Label').Label, - ProgressBar = require('./ProgressBar').ProgressBar, - Preloader = require('../Preloader').Preloader, - RemoteResource = require('../RemoteResource').RemoteResource, - geo = require('geometry'), - util = require('util'), - events = require('events'); - -var PreloadScene = Scene.extend(/** @lends cocos.nodes.PreloadScene# */{ - progressBar: null, - label: null, - preloader: null, - isReady: false, // True when both progress bar images have loaded - emptyImage: "/__builtin__/libs/cocos2d/resources/progress-bar-empty.png", - fullImage: "/__builtin__/libs/cocos2d/resources/progress-bar-full.png", - - /** - * @memberOf cocos.nodes - * @extends cocos.nodes.Scene - * @constructs - */ - init: function (opts) { - PreloadScene.superclass.init.call(this, opts); - var size = Director.get('sharedDirector').get('winSize'); - - // Setup 'please wait' label - var label = Label.create({ - fontSize: 14, - fontName: 'Helvetica', - fontColor: '#ffffff', - string: 'Please wait...' - }); - label.set('position', new geo.Point(size.width / 2, (size.height / 2) + 32)); - this.set('label', label); - this.addChild({child: label}); - - // Setup preloader - var preloader = Preloader.create(); - this.set('preloader', preloader); - var self = this; - - // Listen for preload events - events.addListener(preloader, 'load', function (uri, preloader) { - var loaded = preloader.get('loaded'), - count = preloader.get('count'); - //console.log("Loaded: %d%% -- %d of %d -- %s", (loaded / count) * 100, loaded, count, uri); - events.trigger(self, 'load', uri, preloader); - }); - - events.addListener(preloader, 'complete', function (preloader) { - events.trigger(self, 'complete', preloader); - }); - - - // Load the images used by the progress bar - var emptyImage = resource(this.get('emptyImage')), - fullImage = resource(this.get('fullImage')); - - - var loaded = 0; - function imageLoaded() { - if (loaded == 2) { - this.isReady = true; - this.createProgressBar(); - if (this.get('isRunning')) { - preloader.load(); - } - } - } - - if (emptyImage instanceof RemoteResource) { - events.addListener(emptyImage, 'load', util.callback(this, function() { - loaded++; - imageLoaded.call(this); - })); - emptyImage.load(); - } else { - loaded++; - imageLoaded.call(this); - } - if (fullImage instanceof RemoteResource) { - events.addListener(fullImage, 'load', util.callback(this, function() { - loaded++; - imageLoaded.call(this); - })); - fullImage.load(); - } else { - loaded++; - imageLoaded.call(this); - } - - }, - - createProgressBar: function () { - var preloader = this.get('preloader'), - size = Director.get('sharedDirector').get('winSize'); - - var progressBar = ProgressBar.create({ - emptyImage: "/__builtin__/libs/cocos2d/resources/progress-bar-empty.png", - fullImage: "/__builtin__/libs/cocos2d/resources/progress-bar-full.png" - }); - - progressBar.set('position', new geo.Point(size.width / 2, size.height / 2)); - - this.set('progressBar', progressBar); - this.addChild({child: progressBar}); - - progressBar.bindTo('maxValue', preloader, 'count'); - progressBar.bindTo('value', preloader, 'loaded'); - }, - - onEnter: function () { - PreloadScene.superclass.onEnter.call(this); - var preloader = this.get('preloader'); - - // Preload everything - if (this.isReady) { - preloader.load(); - } - } -}); - -exports.PreloadScene = PreloadScene; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/ProgressBar.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var Node = require('./Node').Node, - util = require('util'), - geo = require('geometry'), - events = require('events'), - Sprite = require('./Sprite').Sprite; - -var ProgressBar = Node.extend(/** @lends cocos.nodes.ProgressBar# */{ - emptySprite: null, - fullSprite: null, - maxValue: 100, - value: 0, - - /** - * @memberOf cocos.nodes - * @extends cocos.nodes.Node - * @constructs - */ - init: function (opts) { - ProgressBar.superclass.init.call(this, opts); - var size = new geo.Size(272, 32); - this.set('contentSize', size); - - var s; - if (opts.emptyImage) { - s = Sprite.create({file: opts.emptyImage, rect: new geo.Rect(0, 0, size.width, size.height)}); - s.set('anchorPoint', new geo.Point(0, 0)); - this.set('emptySprite', s); - this.addChild({child: s}); - } - if (opts.fullImage) { - s = Sprite.create({file: opts.fullImage, rect: new geo.Rect(0, 0, 0, size.height)}); - s.set('anchorPoint', new geo.Point(0, 0)); - this.set('fullSprite', s); - this.addChild({child: s}); - } - - events.addListener(this, 'maxvalue_changed', util.callback(this, 'updateImages')); - events.addListener(this, 'value_changed', util.callback(this, 'updateImages')); - - this.updateImages(); - }, - - updateImages: function () { - var empty = this.get('emptySprite'), - full = this.get('fullSprite'), - value = this.get('value'), - size = this.get('contentSize'), - maxValue = this.get('maxValue'), - ratio = (value / maxValue); - - var diff = Math.round(size.width * ratio); - if (diff === 0) { - full.set('visible', false); - } else { - full.set('visible', true); - full.set('rect', new geo.Rect(0, 0, diff, size.height)); - full.set('contentSize', new geo.Size(diff, size.height)); - } - - if ((size.width - diff) === 0) { - empty.set('visible', false); - } else { - empty.set('visible', true); - empty.set('rect', new geo.Rect(diff, 0, size.width - diff, size.height)); - empty.set('position', new geo.Point(diff, 0)); - empty.set('contentSize', new geo.Size(size.width - diff, size.height)); - } - } -}); - -exports.ProgressBar = ProgressBar; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/RenderTexture.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - evt = require('events'), - Node = require('./Node').Node, - geo = require('geometry'), - Sprite = require('./Sprite').Sprite, - TextureAtlas = require('../TextureAtlas').TextureAtlas, - ccp = geo.ccp; - -var RenderTexture = Node.extend(/** @lends cocos.nodes.RenderTexture# */{ - canvas: null, - context: null, - sprite: null, - - /** - * An in-memory canvas which can be drawn to in the background before drawing on screen - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.Node - * - * @opt {Integer} width The width of the canvas - * @opt {Integer} height The height of the canvas - */ - init: function (opts) { - RenderTexture.superclass.init.call(this, opts); - - var width = opts.width, - height = opts.height; - - evt.addListener(this, 'contentsize_changed', util.callback(this, this._resizeCanvas)); - - this.canvas = document.createElement('canvas'); - this.context = this.canvas.getContext('2d'); - - var atlas = TextureAtlas.create({canvas: this.canvas}); - this.sprite = Sprite.create({textureAtlas: atlas, rect: {origin: ccp(0, 0), size: {width: width, height: height}}}); - - this.set('contentSize', geo.sizeMake(width, height)); - this.addChild(this.sprite); - this.set('anchorPoint', ccp(0, 0)); - this.sprite.set('anchorPoint', ccp(0, 0)); - - }, - - /** - * @private - */ - _resizeCanvas: function () { - var size = this.get('contentSize'), - canvas = this.get('canvas'); - - canvas.width = size.width; - canvas.height = size.height; - if (FLIP_Y_AXIS) { - this.context.scale(1, -1); - this.context.translate(0, -canvas.height); - } - - var s = this.get('sprite'); - if (s) { - s.set('textureRect', {rect: geo.rectMake(0, 0, size.width, size.height)}); - } - }, - - /** - * Clear the canvas - */ - clear: function (rect) { - if (rect) { - this.context.clearRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); - } else { - this.canvas.width = this.canvas.width; - if (FLIP_Y_AXIS) { - this.context.scale(1, -1); - this.context.translate(0, -this.canvas.height); - } - } - } -}); - -module.exports.RenderTexture = RenderTexture; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/Scene.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var Node = require('./Node').Node, - geo = require('geometry'); - -var Scene = Node.extend(/** @lends cocos.nodes.Scene */{ - /** - * Everything in your view will be a child of this object. You need at least 1 scene per app. - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.Node - */ - init: function () { - Scene.superclass.init.call(this); - - - var Director = require('../Director').Director; - var s = Director.get('sharedDirector').get('winSize'); - this.set('isRelativeAnchorPoint', false); - this.anchorPoint = new geo.Point(0.5, 0.5); - this.set('contentSize', s); - } - -}); - -module.exports.Scene = Scene; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/Sprite.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - evt = require('events'), - Director = require('../Director').Director, - TextureAtlas = require('../TextureAtlas').TextureAtlas, - Node = require('./Node').Node, - geo = require('geometry'), - ccp = geo.ccp; - -var Sprite = Node.extend(/** @lends cocos.nodes.Sprite# */{ - textureAtlas: null, - rect: null, - dirty: true, - recursiveDirty: true, - quad: null, - flipX: false, - flipY: false, - offsetPosition: null, - unflippedOffsetPositionFromCenter: null, - untrimmedSize: null, - - /** - * A small 2D graphics than can be animated - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.Node - * - * @opt {String} file Path to image to use as sprite atlas - * @opt {Rect} [rect] The rect in the sprite atlas image file to use as the sprite - */ - init: function (opts) { - Sprite.superclass.init.call(this, opts); - - opts = opts || {}; - - var file = opts.file, - textureAtlas = opts.textureAtlas, - texture = opts.texture, - frame = opts.frame, - spritesheet = opts.spritesheet, - rect = opts.rect; - - this.set('offsetPosition', ccp(0, 0)); - this.set('unflippedOffsetPositionFromCenter', ccp(0, 0)); - - - if (frame) { - texture = frame.get('texture'); - rect = frame.get('rect'); - } - - util.each(['scale', 'scaleX', 'scaleY', 'rect', 'flipX', 'flipY', 'contentSize'], util.callback(this, function (key) { - evt.addListener(this, key.toLowerCase() + '_changed', util.callback(this, this._updateQuad)); - })); - evt.addListener(this, 'textureatlas_changed', util.callback(this, this._updateTextureQuad)); - - if (file || texture) { - textureAtlas = TextureAtlas.create({file: file, texture: texture}); - } else if (spritesheet) { - textureAtlas = spritesheet.get('textureAtlas'); - this.set('useSpriteSheet', true); - } else if (!textureAtlas) { - //throw "Sprite has no texture"; - } - - if (!rect && textureAtlas) { - rect = {origin: ccp(0, 0), size: {width: textureAtlas.texture.size.width, height: textureAtlas.texture.size.height}}; - } - - if (rect) { - this.set('rect', rect); - this.set('contentSize', rect.size); - - this.quad = { - drawRect: {origin: ccp(0, 0), size: rect.size}, - textureRect: rect - }; - } - - this.set('textureAtlas', textureAtlas); - - if (frame) { - this.set('displayFrame', frame); - } - }, - - /** - * @private - */ - _updateTextureQuad: function (obj, key, texture, oldTexture) { - if (oldTexture) { - oldTexture.removeQuad({quad: this.get('quad')}); - } - - if (texture) { - texture.insertQuad({quad: this.get('quad')}); - } - }, - - /** - * @setter textureCoords - * @type geometry.Rect - */ - set_textureCoords: function (rect) { - var quad = this.get('quad'); - if (!quad) { - quad = { - drawRect: geo.rectMake(0, 0, 0, 0), - textureRect: geo.rectMake(0, 0, 0, 0) - }; - } - - quad.textureRect = util.copy(rect); - - this.set('quad', quad); - }, - - /** - * @setter textureRect - * @type geometry.Rect - */ - set_textureRect: function (opts) { - var rect = opts.rect, - rotated = !!opts.rotated, - untrimmedSize = opts.untrimmedSize || rect.size; - - this.set('contentSize', untrimmedSize); - this.set('rect', util.copy(rect)); - this.set('textureCoords', rect); - - var quad = this.get('quad'); - - var relativeOffset = util.copy(this.get('unflippedOffsetPositionFromCenter')); - - if (this.get('flipX')) { - relativeOffset.x = -relativeOffset.x; - } - if (this.get('flipY')) { - relativeOffset.y = -relativeOffset.y; - } - - var offsetPosition = util.copy(this.get('offsetPosition')); - offsetPosition.x = relativeOffset.x + (this.get('contentSize').width - rect.size.width) / 2; - offsetPosition.y = -relativeOffset.y + (this.get('contentSize').height - rect.size.height) / 2; - - quad.drawRect.origin = util.copy(offsetPosition); - quad.drawRect.size = util.copy(rect.size); - if (this.flipX) { - quad.drawRect.size.width *= -1; - quad.drawRect.origin.x = -rect.size.width; - } - if (this.flipY) { - quad.drawRect.size.height *= -1; - quad.drawRect.origin.y = -rect.size.height; - } - - this.set('quad', quad); - }, - - /** - * @private - */ - _updateQuad: function () { - if (!this.get('rect')) { - return; - } - if (!this.quad) { - this.quad = { - drawRect: geo.rectMake(0, 0, 0, 0), - textureRect: geo.rectMake(0, 0, 0, 0) - }; - } - - var relativeOffset = util.copy(this.get('unflippedOffsetPositionFromCenter')); - - if (this.get('flipX')) { - relativeOffset.x = -relativeOffset.x; - } - if (this.get('flipY')) { - relativeOffset.y = -relativeOffset.y; - } - - var offsetPosition = util.copy(this.get('offsetPosition')); - offsetPosition.x = relativeOffset.x + (this.get('contentSize').width - this.get('rect').size.width) / 2; - offsetPosition.y = relativeOffset.y + (this.get('contentSize').height - this.get('rect').size.height) / 2; - - this.quad.textureRect = util.copy(this.rect); - this.quad.drawRect.origin = util.copy(offsetPosition); - this.quad.drawRect.size = util.copy(this.rect.size); - - if (this.flipX) { - this.quad.drawRect.size.width *= -1; - this.quad.drawRect.origin.x = -this.rect.size.width; - } - if (this.flipY) { - this.quad.drawRect.size.height *= -1; - this.quad.drawRect.origin.y = -this.rect.size.height; - } - }, - - updateTransform: function (ctx) { - if (!this.useSpriteSheet) { - throw "updateTransform is only valid when Sprite is being rendered using a SpriteSheet"; - } - - if (!this.visible) { - this.set('dirty', false); - this.set('recursiveDirty', false); - return; - } - - // TextureAtlas has hard reference to this quad so we can just update it directly - this.quad.drawRect.origin = { - x: this.position.x - this.anchorPointInPixels.x * this.scaleX, - y: this.position.y - this.anchorPointInPixels.y * this.scaleY - }; - this.quad.drawRect.size = { - width: this.rect.size.width * this.scaleX, - height: this.rect.size.height * this.scaleY - }; - - this.set('dirty', false); - this.set('recursiveDirty', false); - }, - - draw: function (ctx) { - if (!this.quad) { - return; - } - this.get('textureAtlas').drawQuad(ctx, this.quad); - }, - - isFrameDisplayed: function (frame) { - if (!this.rect || !this.textureAtlas) { - return false; - } - return (frame.texture === this.textureAtlas.texture && geo.rectEqualToRect(frame.rect, this.rect)); - }, - - - /** - * @setter displayFrame - * @type cocos.SpriteFrame - */ - set_displayFrame: function (frame) { - if (!frame) { - delete this.quad; - return; - } - this.set('unflippedOffsetPositionFromCenter', util.copy(frame.offset)); - - - // change texture - if (!this.textureAtlas || frame.texture !== this.textureAtlas.texture) { - this.set('textureAtlas', TextureAtlas.create({texture: frame.texture})); - } - - this.set('textureRect', {rect: frame.rect, rotated: frame.rotated, untrimmedSize: frame.originalSize}); - } -}); - -module.exports.Sprite = Sprite; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/TMXLayer.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - SpriteBatchNode = require('./BatchNode').SpriteBatchNode, - Sprite = require('./Sprite').Sprite, - TMXOrientationOrtho = require('../TMXOrientation').TMXOrientationOrtho, - TMXOrientationHex = require('../TMXOrientation').TMXOrientationHex, - TMXOrientationIso = require('../TMXOrientation').TMXOrientationIso, - geo = require('geometry'), - ccp = geo.ccp, - Node = require('./Node').Node; - -var TMXLayer = SpriteBatchNode.extend(/** @lends cocos.nodes.TMXLayer# */{ - layerSize: null, - layerName: '', - tiles: null, - tilset: null, - layerOrientation: 0, - mapTileSize: null, - properties: null, - - /** - * A tile map layer loaded from a TMX file. This will probably automatically be made by cocos.TMXTiledMap - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.SpriteBatchNode - * - * @opt {cocos.TMXTilesetInfo} tilesetInfo - * @opt {cocos.TMXLayerInfo} layerInfo - * @opt {cocos.TMXMapInfo} mapInfo - */ - init: function (opts) { - var tilesetInfo = opts.tilesetInfo, - layerInfo = opts.layerInfo, - mapInfo = opts.mapInfo; - - var size = layerInfo.get('layerSize'), - totalNumberOfTiles = size.width * size.height; - - var tex = null; - if (tilesetInfo) { - tex = tilesetInfo.sourceImage; - } - - TMXLayer.superclass.init.call(this, {file: tex}); - - this.set('anchorPoint', ccp(0, 0)); - - this.layerName = layerInfo.get('name'); - this.layerSize = layerInfo.get('layerSize'); - this.tiles = layerInfo.get('tiles'); - this.minGID = layerInfo.get('minGID'); - this.maxGID = layerInfo.get('maxGID'); - this.opacity = layerInfo.get('opacity'); - this.properties = util.copy(layerInfo.properties); - - this.tileset = tilesetInfo; - this.mapTileSize = mapInfo.get('tileSize'); - this.layerOrientation = mapInfo.get('orientation'); - - var offset = this.calculateLayerOffset(layerInfo.get('offset')); - this.set('position', offset); - - this.set('contentSize', geo.sizeMake(this.layerSize.width * this.mapTileSize.width, (this.layerSize.height * (this.mapTileSize.height - 1)) + this.tileset.tileSize.height)); - }, - - calculateLayerOffset: function (pos) { - var ret = ccp(0, 0); - - switch (this.layerOrientation) { - case TMXOrientationOrtho: - ret = ccp(pos.x * this.mapTileSize.width, pos.y * this.mapTileSize.height); - break; - case TMXOrientationIso: - // TODO - break; - case TMXOrientationHex: - // TODO - break; - } - - return ret; - }, - - setupTiles: function () { - this.tileset.bindTo('imageSize', this.get('texture'), 'contentSize'); - - - for (var y = 0; y < this.layerSize.height; y++) { - for (var x = 0; x < this.layerSize.width; x++) { - - var pos = x + this.layerSize.width * y, - gid = this.tiles[pos]; - - if (gid !== 0) { - this.appendTile({gid: gid, position: ccp(x, y)}); - - // Optimization: update min and max GID rendered by the layer - this.minGID = Math.min(gid, this.minGID); - this.maxGID = Math.max(gid, this.maxGID); - } - } - } - }, - appendTile: function (opts) { - var gid = opts.gid, - pos = opts.position; - - var z = pos.x + pos.y * this.layerSize.width; - - var rect = this.tileset.rectForGID(gid); - var tile = Sprite.create({rect: rect, textureAtlas: this.textureAtlas}); - tile.set('position', this.positionAt(pos)); - tile.set('anchorPoint', ccp(0, 0)); - tile.set('opacity', this.get('opacity')); - - this.addChild({child: tile, z: 0, tag: z}); - }, - positionAt: function (pos) { - switch (this.layerOrientation) { - case TMXOrientationOrtho: - return this.positionForOrthoAt(pos); - case TMXOrientationIso: - return this.positionForIsoAt(pos); - /* - case TMXOrientationHex: - // TODO - */ - default: - return ccp(0, 0); - } - }, - positionForOrthoAt: function (pos) { - var overlap = this.mapTileSize.height - this.tileset.tileSize.height; - var x = Math.floor(pos.x * this.mapTileSize.width + 0.49); - var y; - if (FLIP_Y_AXIS) { - y = Math.floor((this.get('layerSize').height - pos.y - 1) * this.mapTileSize.height + 0.49); - } else { - y = Math.floor(pos.y * this.mapTileSize.height + 0.49) + overlap; - } - return ccp(x, y); - }, - - positionForIsoAt: function (pos) { - var mapTileSize = this.get('mapTileSize'), - layerSize = this.get('layerSize'); - - if (FLIP_Y_AXIS) { - return ccp( - mapTileSize.width / 2 * (layerSize.width + pos.x - pos.y - 1), - mapTileSize.height / 2 * ((layerSize.height * 2 - pos.x - pos.y) - 2) - ); - } else { - throw "Isometric tiles without FLIP_Y_AXIS is currently unsupported"; - } - }, - - /** - * Get the tile at a specifix tile coordinate - * - * @param {geometry.Point} pos Position of tile to get in tile coordinates (not pixels) - * @returns {cocos.nodes.Sprite} The tile - */ - tileAt: function (pos) { - var layerSize = this.get('layerSize'), - tiles = this.get('tiles'); - - if (pos.x < 0 || pos.y < 0 || pos.x >= layerSize.width || pos.y >= layerSize.height) { - throw "TMX Layer: Invalid position"; - } - - var tile, - gid = this.tileGIDAt(pos); - - // if GID is 0 then no tile exists at that point - if (gid) { - var z = pos.x + pos.y * layerSize.width; - tile = this.getChild({tag: z}); - } - - return tile; - }, - - - tileGID: function (pos) { - var tilesPerRow = this.get('layerSize').width, - tilePos = pos.x + (pos.y * tilesPerRow); - - return this.tiles[tilePos]; - }, - tileGIDAt: function (pos) { - return this.tileGID(pos); - }, - - removeTile: function (pos) { - var gid = this.tileGID(pos); - if (gid === 0) { - // Tile is already blank - return; - } - - var tiles = this.get('tiles'), - tilesPerRow = this.get('layerSize').width, - tilePos = pos.x + (pos.y * tilesPerRow); - - - tiles[tilePos] = 0; - - var sprite = this.getChild({tag: tilePos}); - if (sprite) { - this.removeChild({child: sprite}); - } - } -}); - -exports.TMXLayer = TMXLayer; - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/TMXTiledMap.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray console*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - geo = require('geometry'), - ccp = geo.ccp, - Node = require('./Node').Node, - TMXOrientationOrtho = require('../TMXOrientation').TMXOrientationOrtho, - TMXOrientationHex = require('../TMXOrientation').TMXOrientationHex, - TMXOrientationIso = require('../TMXOrientation').TMXOrientationIso, - TMXLayer = require('./TMXLayer').TMXLayer, - TMXMapInfo = require('../TMXXMLParser').TMXMapInfo; - -var TMXTiledMap = Node.extend(/** @lends cocos.nodes.TMXTiledMap# */{ - mapSize: null, - tileSize: null, - mapOrientation: 0, - objectGroups: null, - properties: null, - tileProperties: null, - - /** - * A TMX Map loaded from a .tmx file - * - * @memberOf cocos.nodes - * @constructs - * @extends cocos.nodes.Node - * - * @opt {String} file The file path of the TMX map to load - */ - init: function (opts) { - TMXTiledMap.superclass.init.call(this, opts); - - this.set('anchorPoint', ccp(0, 0)); - - var mapInfo = TMXMapInfo.create(opts.file); - - this.mapSize = mapInfo.get('mapSize'); - this.tileSize = mapInfo.get('tileSize'); - this.mapOrientation = mapInfo.get('orientation'); - this.objectGroups = mapInfo.get('objectGroups'); - this.properties = mapInfo.get('properties'); - this.tileProperties = mapInfo.get('tileProperties'); - - // Add layers to map - var idx = 0; - util.each(mapInfo.layers, util.callback(this, function (layerInfo) { - if (layerInfo.get('visible')) { - var child = this.parseLayer({layerInfo: layerInfo, mapInfo: mapInfo}); - this.addChild({child: child, z: idx, tag: idx}); - - var childSize = child.get('contentSize'); - var currentSize = this.get('contentSize'); - currentSize.width = Math.max(currentSize.width, childSize.width); - currentSize.height = Math.max(currentSize.height, childSize.height); - this.set('contentSize', currentSize); - - idx++; - } - })); - }, - - parseLayer: function (opts) { - var tileset = this.tilesetForLayer(opts); - var layer = TMXLayer.create({tilesetInfo: tileset, layerInfo: opts.layerInfo, mapInfo: opts.mapInfo}); - - layer.setupTiles(); - - return layer; - }, - - tilesetForLayer: function (opts) { - var layerInfo = opts.layerInfo, - mapInfo = opts.mapInfo, - size = layerInfo.get('layerSize'); - - // Reverse loop - var tileset; - for (var i = mapInfo.tilesets.length - 1; i >= 0; i--) { - tileset = mapInfo.tilesets[i]; - - for (var y = 0; y < size.height; y++) { - for (var x = 0; x < size.width; x++) { - var pos = x + size.width * y, - gid = layerInfo.tiles[pos]; - - if (gid !== 0 && gid >= tileset.firstGID) { - return tileset; - } - } // for (var x - } // for (var y - } // for (var i - - //console.log("cocos2d: Warning: TMX Layer '%s' has no tiles", layerInfo.name); - return tileset; - }, - - /** - * Get a layer - * - * @opt {String} name The name of the layer to get - * @returns {cocos.nodes.TMXLayer} The layer requested - */ - getLayer: function (opts) { - var layerName = opts.name, - layer = null; - - this.get('children').forEach(function (item) { - if (item instanceof TMXLayer && item.layerName == layerName) { - layer = item; - } - }); - if (layer !== null) { - return layer; - } - }, - - /** - * Return the ObjectGroup for the secific group - * - * @opt {String} name The object group name - * @returns {cocos.TMXObjectGroup} The object group - */ - getObjectGroup: function (opts) { - var objectGroupName = opts.name, - objectGroup = null; - - this.objectGroups.forEach(function (item) { - if (item.name == objectGroupName) { - objectGroup = item; - } - }); - if (objectGroup !== null) { - return objectGroup; - } - }, - - /** - * @deprected Since v0.2. You should now use cocos.TMXTiledMap#getObjectGroup. - */ - objectGroupNamed: function (opts) { - console.warn('TMXTiledMap#objectGroupNamed is deprected. Use TMXTiledMap#getObjectGroup instread'); - return this.getObjectGroup(opts); - } -}); - -exports.TMXTiledMap = TMXTiledMap; - - -}}; -__resources__["/__builtin__/libs/cocos2d/nodes/Transition.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var geo = require('geometry'), - actions = require('../actions'), - Scene = require('./Scene').Scene, - Director = require('../Director').Director, - EventDispatcher = require('../EventDispatcher').EventDispatcher, - Scheduler = require('../Scheduler').Scheduler; - -/** Orientation Type used by some transitions - */ -var tOrientation = { - kOrientationLeftOver: 0, - kOrientationRightOver: 1, - kOrientationUpOver: 0, - kOrientationDownOver: 1 -}; - -/** Base class for CCTransition scenes - */ -var TransitionScene = Scene.extend( -/** @lends cocos.nodes.TransitionScene */ -{ - /* Incoming scene */ - inScene: null, - - /* Outgoing (current) scene */ - outScene: null, - - /* transition duration - * Float - */ - duration: null, - - inSceneOnTop: null, - sendCleanupToScene: null, - - /** initializes a transition with duration and incoming scene */ - init: function(opts) { - TransitionScene.superclass.init.call(this, opts); - - this.set('duration', opts.duration); - if (!opts.scene) { - throw "TransitionScene requires scene property"; - } - this.set('inScene', opts.scene); - this.set('outScene', Director.get('sharedDirector')._runningScene); - - if (this.inScene == this.outScene) { - throw "Incoming scene must be different from the outgoing scene"; - } - EventDispatcher.get('sharedDispatcher').set('dispatchEvents', false); - this.sceneOrder(); - }, - - /** called after the transition finishes */ - finish: function() { - var is = this.get('inScene'), - os = this.get('outScene'); - - /* clean up */ - is.set('visible', true); - is.set('position', geo.PointZero()); - is.set('scale', 1.0); - is.set('rotation', 0); - - os.set('visible', false); - os.set('position', geo.PointZero()); - os.set('scale', 1.0); - os.set('rotation', 0); - - Scheduler.get('sharedScheduler').schedule({ - target: this, - method: this.setNewScene, - interval: 0 - }); - }, - - /** used by some transitions to hide the outer scene */ - hideOutShowIn: function() { - this.get('inScene').set('visible', true); - this.get('outScene').set('visible', false); - }, - - setNewScene: function(dt) { - var dir = Director.get('sharedDirector'); - - this.unscheduleSelector(this.setNewScene); - // Save 'send cleanup to scene' - // Not sure if it's cool to be accessing all these Director privates like this... - this.set('sendCleanupToScene', dir._sendCleanupToScene); - - dir.replaceScene(this.get('inScene')); - - // enable events while transitions - EventDispatcher.get('sharedDispatcher').set('dispatchEvents', true); - - // issue #267 - this.get('outScene').set('visible', true); - }, - - sceneOrder: function() { - this.set('inSceneOnTop', true); - }, - - draw: function(context, rect) { - if (this.get('inSceneOnTop')) { - this.get('outScene').visit(context, rect); - this.get('inScene').visit(context, rect); - } else { - this.get('inScene').visit(context, rect); - this.get('outScene').visit(context, rect); - } - }, - - /** custom onEnter */ - onEnter: function() { - TransitionScene.superclass.onEnter.call(this); - this.get('inScene').onEnter(); - // outScene_ should not receive the onEnter callback - }, - - /** custom onExit */ - onExit: function() { - TransitionScene.superclass.onExit.call(this); - this.get('outScene').onExit(); - // inScene_ should not receive the onExit callback - // only the onEnterTransitionDidFinish - if (this.get('inScene').hasOwnProperty('onEnterTransitionDidFinish')) { - this.get('inScene').onEnterTransitionDidFinish(); - } - }, - - // custom cleanup - cleanup: function() { - TransitionScene.superclass.cleanup.call(this); - - if (this.get('sendCleanupToScene')) { - this.get('outScene').cleanup(); - } - } -}); - -/** CCTransitionRotoZoom: - Rotate and zoom out the outgoing scene, and then rotate and zoom in the incoming - */ -var TransitionRotoZoom = TransitionScene.extend( -/** @lends cocos.nodes.TransitionRotoZoom */ -{ - onEnter: function() { - TransitionRotoZoom.superclass.onEnter.call(this); - - var dur = this.get('duration') / 2; - this.get('inScene').set('scale', 0.001); - this.get('outScene').set('scale', 1.0); - - this.get('inScene').set('anchorPoint', geo.ccp(0.5, 0.5)); - this.get('outScene').set('anchorPoint', geo.ccp(0.5, 0.5)); - - var rotozoom = cocos.actions.Sequence.create({actions: [ - cocos.actions.Spawn.initWithActions({actions: [ - cocos.actions.ScaleBy.create({scale: 0.001, duration: dur/2}), - cocos.actions.RotateBy.create({angle: 360*2, duration: dur/2}) - ]}), - cocos.actions.DelayTime.create({duration: dur}) - ]}); - - this.get('outScene').runAction(rotozoom); - this.get('inScene').runAction(cocos.actions.Sequence.create({actions: [ - rotozoom.reverse(), - actions.CallFunc.create({ - target: this, - method: this.finish - }) - ]})); - } -}); - -/** CCTransitionMoveInL: - Move in from to the left the incoming scene. -*/ -var TransitionMoveInL = TransitionScene.extend( -/** @lends cocos.nodes.TransitionMoveInL */ -{ - onEnter: function() { - TransitionMoveInL.superclass.onEnter.call(this); - - this.initScenes(); - - this.get('inScene').runAction(actions.Sequence.create({actions: [ - this.action(), - actions.CallFunc.create({ - target: this, - method: this.finish - })] - })); - }, - - action: function() { - return actions.MoveTo.create({ - position: geo.ccp(0, 0), - duration: this.get('duration') - }); - }, - - initScenes: function() { - var s = Director.get('sharedDirector').get('winSize'); - this.get('inScene').set('position', geo.ccp(-s.width, 0)); - } -}); - -/** CCTransitionMoveInR: - Move in from to the right the incoming scene. -*/ -var TransitionMoveInR = TransitionMoveInL.extend( -/** @lends cocos.nodes.TransitionMoveInR */ -{ - initScenes: function() { - var s = Director.get('sharedDirector').get('winSize'); - this.get('inScene').set('position', geo.ccp(s.width, 0)); - } -}); - -/** CCTransitionMoveInT: - Move the incoming scene in from the top. -*/ -var TransitionMoveInT = TransitionMoveInL.extend( -/** @lends cocos.nodes.TransitionMoveInT */ -{ - initScenes: function() { - var s = Director.get('sharedDirector').get('winSize'); - this.get('inScene').set('position', geo.ccp(0, s.height)); - } -}); - -/** CCTransitionMoveInB: - Move the incoming scene in from the bottom. -*/ -var TransitionMoveInB = TransitionMoveInL.extend( -/** @lends cocos.nodes.TransitionMoveInB */ -{ - initScenes: function() { - var s = Director.get('sharedDirector').get('winSize'); - this.get('inScene').set('position', geo.ccp(0, -s.height)); - } -}); - -/** TransitionSlideInL: - Slide in the incoming scene from the left . - */ -var TransitionSlideInL = TransitionScene.extend( -/** @lends cocos.nodes.TransitionSlideInL */ -{ - onEnter: function() { - TransitionSlideInL.superclass.onEnter.call(this); - - this.initScenes(); - - var movein = this.action(); - var moveout = this.action(); - var outAction = actions.Sequence.create({ - actions: [ - moveout, - actions.CallFunc.create({ - target: this, - method: this.finish - })] - }); - this.get('inScene').runAction(movein); - this.get('outScene').runAction(outAction); - }, - - sceneOrder: function() { - this.set('inSceneOnTop', false); - }, - - initScenes: function() { - var s = Director.get('sharedDirector').get('winSize'); - this.get('inScene').set('position', geo.ccp(-s.width, 0)); - }, - - action: function() { - var s = Director.get('sharedDirector').get('winSize'); - return actions.MoveBy.create({ - position: geo.ccp(s.width, 0), - duration: this.get('duration') - }); - } -}); - -/** TransitionSlideInR: - Slide in the incoming scene from the right . - */ -var TransitionSlideInR = TransitionSlideInL.extend( -/** @lends cocos.nodes.TransitionSlideInR */ -{ - sceneOrder: function() { - this.set('inSceneOnTop', true); - }, - - initScenes: function() { - var s = Director.get('sharedDirector').get('winSize'); - this.get('inScene').set('position', geo.ccp(s.width, 0)); - }, - - action: function() { - var s = Director.get('sharedDirector').get('winSize'); - return actions.MoveBy.create({ - position: geo.ccp(-s.width, 0), - duration: this.get('duration') - }); - } -}); - -/** TransitionSlideInT: - Slide in the incoming scene from the top . - */ -var TransitionSlideInT = TransitionSlideInL.extend( -/** @lends cocos.nodes.TransitionSlideInT */ -{ - sceneOrder: function() { - this.set('inSceneOnTop', false); - }, - - initScenes: function() { - var s = Director.get('sharedDirector').get('winSize'); - this.get('inScene').set('position', geo.ccp(0, s.height)); - }, - - action: function() { - var s = Director.get('sharedDirector').get('winSize'); - return actions.MoveBy.create({ - position: geo.ccp(0, -s.height), - duration: this.get('duration') - }); - } -}); - -/** TransitionSlideInB: - Slide in the incoming scene from the bottom. - */ -var TransitionSlideInB = TransitionSlideInL.extend( -/** @lends cocos.nodes.TransitionSlideInT */ -{ - sceneOrder: function() { - this.set('inSceneOnTop', true); - }, - - initScenes: function() { - var s = Director.get('sharedDirector').get('winSize'); - this.get('inScene').set('position', geo.ccp(0, -s.height)); - }, - - action: function() { - var s = Director.get('sharedDirector').get('winSize'); - return actions.MoveBy.create({ - position: geo.ccp(0, s.height), - duration: this.get('duration') - }); - } -}); - -exports.TransitionScene = TransitionScene; -exports.TransitionRotoZoom = TransitionRotoZoom; -exports.TransitionMoveInL = TransitionMoveInL; -exports.TransitionMoveInR = TransitionMoveInR; -exports.TransitionMoveInT = TransitionMoveInT; -exports.TransitionMoveInB = TransitionMoveInB; -exports.TransitionSlideInL = TransitionSlideInL; -exports.TransitionSlideInR = TransitionSlideInR; -exports.TransitionSlideInT = TransitionSlideInT; -exports.TransitionSlideInB = TransitionSlideInB; - -}}; -__resources__["/__builtin__/libs/cocos2d/Preloader.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - events = require('events'); - -var Preloader = BObject.extend(/** @lends cocos.Preloader# */{ - /** - * Total number of resources. - * @type Integer - */ - count: -1, - - /** - * Number of resources that have finished loading - * @type Integer - */ - loaded: 0, - - _listeners: null, - - /** - * @class Preloads all remote resources - * @memberOf cocos - * @extends BObject - * @constructs - */ - init: function (opts) { - Preloader.superclass.init.call(this, opts); - - this._listeners = {}; - this.set('count', Object.keys(__remote_resources__).length); - }, - - load: function() { - this.set('loaded', 0); - this.set('count', Object.keys(__remote_resources__).length); - - for (var uri in __remote_resources__) { - if (__remote_resources__.hasOwnProperty(uri)) { - if (__resources__[uri]) { - // Already loaded - this.set('loaded', this.get('loaded') +1); - events.trigger(this, 'load', uri, this); - continue; - } - var file = resource(uri); - - // Notify when a resource has loaded - this._listeners[uri] = events.addListener(file, 'load', util.callback(this, (function(uri) { - return function () { this.didLoadResource(uri); }; - })(uri))); - - file.load() - } - } - }, - - didLoadResource: function(uri) { - this.set('loaded', this.get('loaded') +1); - events.removeListener(this._listeners[uri]); - events.trigger(this, 'load', uri, this); - - if (this.get('loaded') >= this.get('count')) { - events.trigger(this, 'complete', this); - } - } -}); - -exports.Preloader = Preloader; - -}}; -__resources__["/__builtin__/libs/cocos2d/RemoteImage.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - events = require('events'), - RemoteResource = require('./RemoteResource').RemoteResource; - -var RemoteImage = RemoteResource.extend(/** @lends cocos.RemoteImage# */{ - /** - * @memberOf cocos - * @extends RemoteResource - * @constructs - */ - init: function (opts) { - RemoteImage.superclass.init.call(this, opts); - }, - - /** - * Load a remote image - * @returns Image - */ - load: function () { - var img = new Image(); - var self = this; - img.onload = function () { - var path = self.get('path'); - - var r = __remote_resources__[path]; - __resources__[path] = util.copy(r); - __resources__[path].data = img; - __resources__[path].meta.remote = true; - - events.trigger(self, 'load', self); - }; - - img.src = this.get('url'); - - return img; - } -}); - -exports.RemoteImage = RemoteImage; - -}}; -__resources__["/__builtin__/libs/cocos2d/RemoteResource.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - events = require('events'); - -var RemoteResource = BObject.extend(/** @lends cocos.RemoteResource# */{ - /** - * The URL to the remote resource - * @type String - */ - url: null, - - /** - * The path used to reference the resource in the app - * @type String - */ - path: null, - - /** - * @memberOf cocos - * @extends BObject - * @constructs - */ - init: function (opts) { - RemoteResource.superclass.init.call(this, opts); - - this.set('url', opts.url); - this.set('path', opts.path); - - }, - - /** - * Load the remote resource via ajax - */ - load: function () { - var xhr = new XMLHttpRequest(); - var self = this; - xhr.onreadystatechange = function() { - if (xhr.readyState == 4) { - var path = self.get('path'); - - var r = __remote_resources__[path]; - __resources__[path] = util.copy(r); - __resources__[path].data = xhr.responseText; - __resources__[path].meta.remote = true; - - events.trigger(self, 'load', self); - } - }; - - xhr.open('GET', this.get('url'), true); - xhr.send(null); - } -}); - - -exports.RemoteResource = RemoteResource; - -}}; -__remote_resources__["/__builtin__/libs/cocos2d/resources/progress-bar-empty.png"] = {meta: {mimetype: "image/png"}, data: "resources/__builtin__/libs/cocos2d/resources/progress-bar-empty.png"}; -__remote_resources__["/__builtin__/libs/cocos2d/resources/progress-bar-full.png"] = {meta: {mimetype: "image/png"}, data: "resources/__builtin__/libs/cocos2d/resources/progress-bar-full.png"}; -__resources__["/__builtin__/libs/cocos2d/Scheduler.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'); - -/** @ignore */ -function HashUpdateEntry() { - this.timers = []; - this.timerIndex = 0; - this.currentTimer = null; - this.currentTimerSalvaged = false; - this.paused = false; -} - -/** @ignore */ -function HashMethodEntry() { - this.timers = []; - this.timerIndex = 0; - this.currentTimer = null; - this.currentTimerSalvaged = false; - this.paused = false; -} - -var Timer = BObject.extend(/** @lends cocos.Timer# */{ - callback: null, - interval: 0, - elapsed: -1, - - /** - * Runs a function repeatedly at a fixed interval - * - * @memberOf cocos - * @constructs - * @extends BObject - * - * @opt {Function} callback The function to run at each interval - * @opt {Float} interval Number of milliseconds to wait between each exectuion of callback - */ - init: function (opts) { - Timer.superclass.init(this, opts); - - this.set('callback', opts.callback); - this.set('interval', opts.interval || 0); - this.set('elapsed', -1); - }, - - /** - * @private - */ - update: function (dt) { - if (this.elapsed == -1) { - this.elapsed = 0; - } else { - this.elapsed += dt; - } - - if (this.elapsed >= this.interval) { - this.callback(this.elapsed); - this.elapsed = 0; - } - } -}); - - -var Scheduler = BObject.extend(/** @lends cocos.Scheduler# */{ - updates0: null, - updatesNeg: null, - updatesPos: null, - hashForUpdates: null, - hashForMethods: null, - timeScale: 1.0, - - /** - * Runs the timers - * - * @memberOf cocos - * @constructs - * @extends BObject - * @singleton - * @private - */ - init: function () { - this.updates0 = []; - this.updatesNeg = []; - this.updatesPos = []; - this.hashForUpdates = {}; - this.hashForMethods = {}; - }, - - /** The scheduled method will be called every 'interval' seconds. - If paused is YES, then it won't be called until it is resumed. - If 'interval' is 0, it will be called every frame, but if so, it recommened to use 'scheduleUpdateForTarget:' instead. - If the selector is already scheduled, then only the interval parameter will be updated without re-scheduling it again. - - @since v0.99.3 - */ - schedule: function (opts) { - var target = opts.target, - method = opts.method, - interval = opts.interval, - paused = opts.paused || false; - - var element = this.hashForMethods[target.get('id')]; - - if (!element) { - element = new HashMethodEntry(); - this.hashForMethods[target.get('id')] = element; - element.target = target; - element.paused = paused; - } else if (element.paused != paused) { - throw "cocos.Scheduler. Trying to schedule a method with a pause value different than the target"; - } - - var timer = Timer.create({callback: util.callback(target, method), interval: interval}); - element.timers.push(timer); - }, - - /** Schedules the 'update' selector for a given target with a given priority. - The 'update' selector will be called every frame. - The lower the priority, the earlier it is called. - @since v0.99.3 - */ - scheduleUpdate: function (opts) { - var target = opts.target, - priority = opts.priority, - paused = opts.paused; - - var i, len; - var entry = {target: target, priority: priority, paused: paused}; - var added = false; - - if (priority === 0) { - this.updates0.push(entry); - } else if (priority < 0) { - for (i = 0, len = this.updatesNeg.length; i < len; i++) { - if (priority < this.updatesNeg[i].priority) { - this.updatesNeg.splice(i, 0, entry); - added = true; - break; - } - } - - if (!added) { - this.updatesNeg.push(entry); - } - } else /* priority > 0 */{ - for (i = 0, len = this.updatesPos.length; i < len; i++) { - if (priority < this.updatesPos[i].priority) { - this.updatesPos.splice(i, 0, entry); - added = true; - break; - } - } - - if (!added) { - this.updatesPos.push(entry); - } - } - - this.hashForUpdates[target.get('id')] = entry; - }, - - /** 'tick' the scheduler. - You should NEVER call this method, unless you know what you are doing. - */ - tick: function (dt) { - var i, len, x; - if (this.timeScale != 1.0) { - dt *= this.timeScale; - } - - var entry; - for (i = 0, len = this.updatesNeg.length; i < len; i++) { - entry = this.updatesNeg[i]; - if (entry && !entry.paused) { - entry.target.update(dt); - } - } - - for (i = 0, len = this.updates0.length; i < len; i++) { - entry = this.updates0[i]; - if (entry && !entry.paused) { - entry.target.update(dt); - } - } - - for (i = 0, len = this.updatesPos.length; i < len; i++) { - entry = this.updatesPos[i]; - if (entry && !entry.paused) { - entry.target.update(dt); - } - } - - for (x in this.hashForMethods) { - if (this.hashForMethods.hasOwnProperty(x)) { - entry = this.hashForMethods[x]; - if (entry) { - for (i = 0, len = entry.timers.length; i < len; i++) { - var timer = entry.timers[i]; - if (timer) { - timer.update(dt); - } - } - } - } - } - - }, - - /** Unshedules a selector for a given target. - If you want to unschedule the "update", use unscheduleUpdateForTarget. - @since v0.99.3 - */ - unschedule: function(opts) { - if (!opts.target || !opts.method) { - return; - } - var element = this.hashForMethods[opts.target.get('id')]; - if (element) { - for (var i=0; i 0 */{ - this.updatesPos.splice(this.updatesPos.indexOf(elementUpdate), 1); - } - } - // Release HashMethodEntry object - this.hashForUpdates[target.get('id')] = null; - }, - - /** Unschedules all selectors from all targets. - You should NEVER call this method, unless you know what you are doing. - - @since v0.99.3 - */ - unscheduleAllSelectors: function() { - var i, x, entry; - - // Custom selectors - for (x in this.hashForMethods) { - if (this.hashForMethods.hasOwnProperty(x)) { - entry = this.hashForMethods[x]; - this.unscheduleAllSelectorsForTarget(entry.target); - } - } - // Updates selectors - for (i = 0, len = this.updatesNeg.length; i < len; i++) { - entry = this.updatesNeg[i]; - if (entry) { - this.unscheduleUpdateForTarget(entry.target); - } - } - - for (i = 0, len = this.updates0.length; i < len; i++) { - entry = this.updates0[i]; - if (entry) { - this.unscheduleUpdateForTarget(entry.target); - } - } - - for (i = 0, len = this.updatesPos.length; i < len; i++) { - entry = this.updatesPos[i]; - if (entry) { - this.unscheduleUpdateForTarget(entry.target); - } - } - }, - - /** Unschedules all selectors for a given target. - This also includes the "update" selector. - @since v0.99.3 - */ - unscheduleAllSelectorsForTarget: function (target) { - if (!target) { - return; - } - // Custom selector - var element = this.hashForMethods[target.get('id')]; - if (element) { - element.paused = true; - element.timers = []; // Clear all timers - } - // Release HashMethodEntry object - this.hashForMethods[target.get('id')] = null; - - // Update selector - this.unscheduleUpdateForTarget(target); - }, - - /** Pauses the target. - All scheduled selectors/update for a given target won't be 'ticked' until the target is resumed. - If the target is not present, nothing happens. - @since v0.99.3 - */ - pauseTarget: function (target) { - var element = this.hashForMethods[target.get('id')]; - if (element) { - element.paused = true; - } - - var elementUpdate = this.hashForUpdates[target.get('id')]; - if (elementUpdate) { - elementUpdate.paused = true; - } - }, - - /** Resumes the target. - The 'target' will be unpaused, so all schedule selectors/update will be 'ticked' again. - If the target is not present, nothing happens. - @since v0.99.3 - */ - resumeTarget: function (target) { - var element = this.hashForMethods[target.get('id')]; - if (element) { - element.paused = false; - } - - var elementUpdate = this.hashForUpdates[target.get('id')]; - //console.log('foo', target.get('id'), elementUpdate); - if (elementUpdate) { - elementUpdate.paused = false; - } - } -}); - -util.extend(Scheduler, /** @lends cocos.Scheduler */{ - /** - * A shared singleton instance of cocos.Scheduler - * @getter sharedScheduler - * @type cocos.Scheduler - */ - get_sharedScheduler: function (key) { - if (!this._instance) { - this._instance = this.create(); - } - - return this._instance; - } -}); - -exports.Timer = Timer; -exports.Scheduler = Scheduler; - -}}; -__resources__["/__builtin__/libs/cocos2d/SpriteFrame.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - geo = require('geometry'), - ccp = geo.ccp; - -var SpriteFrame = BObject.extend(/** @lends cocos.SpriteFrame# */{ - rect: null, - rotated: false, - offset: null, - originalSize: null, - texture: null, - - /** - * Represents a single frame of animation for a cocos.Sprite - * - *

          A SpriteFrame has:
          - * - texture: A Texture2D that will be used by the Sprite
          - * - rectangle: A rectangle of the texture

          - * - *

          You can modify the frame of a Sprite by doing:

          - * - * var frame = SpriteFrame.create({texture: texture, rect: rect}); - * sprite.set('displayFrame', frame); - * - * @memberOf cocos - * @constructs - * @extends BObject - * - * @opt {cocos.Texture2D} texture The texture to draw this frame using - * @opt {geometry.Rect} rect The rectangle inside the texture to draw - */ - init: function (opts) { - SpriteFrame.superclass.init(this, opts); - - this.texture = opts.texture; - this.rect = opts.rect; - this.rotated = !!opts.rotate; - this.offset = opts.offset || ccp(0, 0); - this.originalSize = opts.originalSize || util.copy(this.rect.size); - }, - - /** - * @ignore - */ - toString: function () { - return "[object SpriteFrame | TextureName=" + this.texture.get('name') + ", Rect = (" + this.rect.origin.x + ", " + this.rect.origin.y + ", " + this.rect.size.width + ", " + this.rect.size.height + ")]"; - }, - - /** - * Make a copy of this frame - * - * @returns {cocos.SpriteFrame} Exact copy of this object - */ - copy: function () { - return SpriteFrame.create({rect: this.rect, rotated: this.rotated, offset: this.offset, originalSize: this.originalSize, texture: this.texture}); - } - -}); - -exports.SpriteFrame = SpriteFrame; - -}}; -__resources__["/__builtin__/libs/cocos2d/SpriteFrameCache.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - geo = require('geometry'), - Plist = require('Plist').Plist, - SpriteFrame = require('./SpriteFrame').SpriteFrame, - Texture2D = require('./Texture2D').Texture2D; - -var SpriteFrameCache = BObject.extend(/** @lends cocos.SpriteFrameCache# */{ - /** - * List of sprite frames - * @type Object - */ - spriteFrames: null, - - /** - * List of sprite frame aliases - * @type Object - */ - spriteFrameAliases: null, - - - /** - * @memberOf cocos - * @extends BObject - * @constructs - * @singleton - */ - init: function () { - SpriteFrameCache.superclass.init.call(this); - - this.set('spriteFrames', {}); - this.set('spriteFrameAliases', {}); - }, - - /** - * Add SpriteFrame(s) to the cache - * - * @param {String} opts.file The filename of a Zwoptex .plist containing the frame definiitons. - */ - addSpriteFrames: function (opts) { - var plistPath = opts.file, - plist = Plist.create({file: plistPath}), - plistData = plist.get('data'); - - - var metaDataDict = plistData.metadata, - framesDict = plistData.frames; - - var format = 0, - texturePath = null; - - if (metaDataDict) { - format = metaDataDict.format; - // Get texture path from meta data - texturePath = metaDataDict.textureFileName; - } - - if (!texturePath) { - // No texture path so assuming it's the same name as the .plist but ending in .png - texturePath = plistPath.replace(/\.plist$/i, '.png'); - } - - - var texture = Texture2D.create({file: texturePath}); - - // Add frames - for (var frameDictKey in framesDict) { - if (framesDict.hasOwnProperty(frameDictKey)) { - var frameDict = framesDict[frameDictKey], - spriteFrame = null; - - switch (format) { - case 0: - var x = frameDict.x, - y = frameDict.y, - w = frameDict.width, - h = frameDict.height, - ox = frameDict.offsetX, - oy = frameDict.offsetY, - ow = frameDict.originalWidth, - oh = frameDict.originalHeight; - - // check ow/oh - if (!ow || !oh) { - //console.log("cocos2d: WARNING: originalWidth/Height not found on the CCSpriteFrame. AnchorPoint won't work as expected. Regenerate the .plist"); - } - - if (FLIP_Y_AXIS) { - oy *= -1; - } - - // abs ow/oh - ow = Math.abs(ow); - oh = Math.abs(oh); - - // create frame - spriteFrame = SpriteFrame.create({texture: texture, - rect: geo.rectMake(x, y, w, h), - rotate: false, - offset: geo.ccp(ox, oy), - originalSize: geo.sizeMake(ow, oh)}); - break; - - case 1: - case 2: - var frame = geo.rectFromString(frameDict.frame), - rotated = !!frameDict.rotated, - offset = geo.pointFromString(frameDict.offset), - sourceSize = geo.sizeFromString(frameDict.sourceSize); - - if (FLIP_Y_AXIS) { - offset.y *= -1; - } - - - // create frame - spriteFrame = SpriteFrame.create({texture: texture, - rect: frame, - rotate: rotated, - offset: offset, - originalSize: sourceSize}); - break; - - case 3: - var spriteSize = geo.sizeFromString(frameDict.spriteSize), - spriteOffset = geo.pointFromString(frameDict.spriteOffset), - spriteSourceSize = geo.sizeFromString(frameDict.spriteSourceSize), - textureRect = geo.rectFromString(frameDict.textureRect), - textureRotated = frameDict.textureRotated; - - - if (FLIP_Y_AXIS) { - spriteOffset.y *= -1; - } - - // get aliases - var aliases = frameDict.aliases; - for (var i = 0, len = aliases.length; i < len; i++) { - var alias = aliases[i]; - this.get('spriteFrameAliases')[frameDictKey] = alias; - } - - // create frame - spriteFrame = SpriteFrame.create({texture: texture, - rect: geo.rectMake(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height), - rotate: textureRotated, - offset: spriteOffset, - originalSize: spriteSourceSize}); - break; - - default: - throw "Unsupported Zwoptex format: " + format; - } - - // Add sprite frame - this.get('spriteFrames')[frameDictKey] = spriteFrame; - } - } - }, - - /** - * Get a single SpriteFrame - * - * @param {String} opts.name The name of the sprite frame - * @returns {cocos.SpriteFrame} The sprite frame - */ - getSpriteFrame: function (opts) { - var name = opts.name; - - var frame = this.get('spriteFrames')[name]; - - if (!frame) { - // No frame, look for an alias - var key = this.get('spriteFrameAliases')[name]; - - if (key) { - frame = this.get('spriteFrames')[key]; - } - - if (!frame) { - throw "Unable to find frame: " + name; - } - } - - return frame; - } -}); - -/** - * Class methods - */ -util.extend(SpriteFrameCache, /** @lends cocos.SpriteFrameCache */{ - /** - * @field - * @name cocos.SpriteFrameCache.sharedSpriteFrameCache - * @type cocos.SpriteFrameCache - */ - get_sharedSpriteFrameCache: function (key) { - if (!this._instance) { - this._instance = this.create(); - } - - return this._instance; - } -}); - -exports.SpriteFrameCache = SpriteFrameCache; - -}}; -__resources__["/__builtin__/libs/cocos2d/Texture2D.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - events = require('events'), - RemoteResource = require('./RemoteResource').RemoteResource; - -var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ - imgElement: null, - size: null, - name: null, - isLoaded: false, - - /** - * @memberOf cocos - * @constructs - * @extends BObject - * - * @opt {String} [file] The file path of the image to use as a texture - * @opt {Texture2D|HTMLImageElement} [data] Image data to read from - */ - init: function (opts) { - var file = opts.file, - data = opts.data, - texture = opts.texture; - - if (file) { - this.name = file; - data = resource(file); - } else if (texture) { - this.name = texture.get('name'); - data = texture.get('imgElement'); - } - - this.size = {width: 0, height: 0}; - - if (data instanceof RemoteResource) { - events.addListener(data, 'load', util.callback(this, this.dataDidLoad)); - this.set('imgElement', data.load()); - } else { - this.set('imgElement', data); - this.dataDidLoad(data); - } - }, - - dataDidLoad: function (data) { - this.isLoaded = true; - this.set('size', {width: this.imgElement.width, height: this.imgElement.height}); - events.trigger(self, 'load', self); - }, - - drawAtPoint: function (ctx, point) { - if (!this.isLoaded) { - return; - } - ctx.drawImage(this.imgElement, point.x, point.y); - }, - drawInRect: function (ctx, rect) { - if (!this.isLoaded) { - return; - } - ctx.drawImage(this.imgElement, - rect.origin.x, rect.origin.y, - rect.size.width, rect.size.height - ); - }, - - /** - * @getter data - * @type {String} Base64 encoded image data - */ - get_data: function () { - return this.imgElement ? this.imgElement.src : null; - }, - - /** - * @getter contentSize - * @type {geometry.Size} Size of the texture - */ - get_contentSize: function () { - return this.size; - } -}); - -exports.Texture2D = Texture2D; - -}}; -__resources__["/__builtin__/libs/cocos2d/TextureAtlas.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray FLIP_Y_AXIS*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - Texture2D = require('./Texture2D').Texture2D; - - -/* QUAD STRUCTURE - quad = { - drawRect: , // Where the quad is drawn to - textureRect: // The slice of the texture to draw in drawRect - } -*/ - -var TextureAtlas = BObject.extend(/** @lends cocos.TextureAtlas# */{ - quads: null, - imgElement: null, - texture: null, - - /** - * A single texture that can represent lots of smaller images - * - * @memberOf cocos - * @constructs - * @extends BObject - * - * @opt {String} file The file path of the image to use as a texture - * @opt {Texture2D|HTMLImageElement} [data] Image data to read from - * @opt {CanvasElement} [canvas] A canvas to use as a texture - */ - init: function (opts) { - var file = opts.file, - data = opts.data, - texture = opts.texture, - canvas = opts.canvas; - - if (canvas) { - // If we've been given a canvas element then we'll use that for our image - this.imgElement = canvas; - } else { - texture = Texture2D.create({texture: texture, file: file, data: data}); - this.set('texture', texture); - this.imgElement = texture.get('imgElement'); - } - - this.quads = []; - }, - - insertQuad: function (opts) { - var quad = opts.quad, - index = opts.index || 0; - - this.quads.splice(index, 0, quad); - }, - removeQuad: function (opts) { - var index = opts.index; - - this.quads.splice(index, 1); - }, - - - drawQuads: function (ctx) { - util.each(this.quads, util.callback(this, function (quad) { - if (!quad) { - return; - } - - this.drawQuad(ctx, quad); - })); - }, - - drawQuad: function (ctx, quad) { - var sx = quad.textureRect.origin.x, - sy = quad.textureRect.origin.y, - sw = quad.textureRect.size.width, - sh = quad.textureRect.size.height; - - var dx = quad.drawRect.origin.x, - dy = quad.drawRect.origin.y, - dw = quad.drawRect.size.width, - dh = quad.drawRect.size.height; - - - var scaleX = 1; - var scaleY = 1; - - if (FLIP_Y_AXIS) { - dy -= dh; - dh *= -1; - } - - - if (dw < 0) { - dw *= -1; - scaleX = -1; - } - - if (dh < 0) { - dh *= -1; - scaleY = -1; - } - - ctx.scale(scaleX, scaleY); - - var img = this.get('imgElement'); - ctx.drawImage(img, - sx, sy, // Draw slice from x,y - sw, sh, // Draw slice size - dx, dy, // Draw at 0, 0 - dw, dh // Draw size - ); - ctx.scale(1, 1); - } -}); - -exports.TextureAtlas = TextureAtlas; - -}}; -__resources__["/__builtin__/libs/cocos2d/TMXOrientation.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -/** - * @memberOf cocos - * @namespace - */ -var TMXOrientation = /** @lends cocos.TMXOrientation */{ - /** - * Orthogonal orientation - * @constant - */ - TMXOrientationOrtho: 1, - - /** - * Hexagonal orientation - * @constant - */ - TMXOrientationHex: 2, - - /** - * Isometric orientation - * @constant - */ - TMXOrientationIso: 3 -}; - -module.exports = TMXOrientation; - -}}; -__resources__["/__builtin__/libs/cocos2d/TMXXMLParser.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray DOMParser console*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - path = require('path'), - ccp = require('geometry').ccp, - base64 = require('base64'), - gzip = require('gzip'), - TMXOrientationOrtho = require('./TMXOrientation').TMXOrientationOrtho, - TMXOrientationHex = require('./TMXOrientation').TMXOrientationHex, - TMXOrientationIso = require('./TMXOrientation').TMXOrientationIso; - -var TMXTilesetInfo = BObject.extend(/** @lends cocos.TMXTilesetInfo# */{ - name: '', - firstGID: 0, - tileSize: null, - spacing: 0, - margin: 0, - sourceImage: null, - - /** - * @memberOf cocos - * @constructs - * @extends BObject - */ - init: function () { - TMXTilesetInfo.superclass.init.call(this); - }, - - rectForGID: function (gid) { - var rect = {size: {}, origin: ccp(0, 0)}; - rect.size = util.copy(this.tileSize); - - gid = gid - this.firstGID; - - var imgSize = this.get('imageSize'); - - var maxX = Math.floor((imgSize.width - this.margin * 2 + this.spacing) / (this.tileSize.width + this.spacing)); - - rect.origin.x = (gid % maxX) * (this.tileSize.width + this.spacing) + this.margin; - rect.origin.y = Math.floor(gid / maxX) * (this.tileSize.height + this.spacing) + this.margin; - - return rect; - } -}); - -var TMXLayerInfo = BObject.extend(/** @lends cocos.TMXLayerInfo# */{ - name: '', - layerSize: null, - tiles: null, - visible: true, - opacity: 255, - minGID: 100000, - maxGID: 0, - properties: null, - offset: null, - - /** - * @memberOf cocos - * @constructs - * @extends BObject - */ - init: function () { - TMXLayerInfo.superclass.init.call(this); - - this.properties = {}; - this.offset = ccp(0, 0); - } -}); - -var TMXObjectGroup = BObject.extend(/** @lends cocos.TMXObjectGroup# */{ - name: '', - properties: null, - offset: null, - objects: null, - - /** - * @memberOf cocos - * @constructs - * @extends BObject - */ - init: function () { - TMXObjectGroup.superclass.init.call(this); - - this.properties = {}; - this.objects = {}; - this.offset = ccp(0, 0); - }, - - /** - * Get the value for the specific property name - * - * @opt {String} name Property name - * @returns {String} Property value - */ - getProperty: function (opts) { - var propertyName = opts.name; - return this.properties[propertyName]; - }, - - /** - * @deprected Since v0.2. You should now use cocos.TMXObjectGroup#getProperty - */ - propertyNamed: function (opts) { - console.warn('TMXObjectGroup#propertyNamed is deprected. Use TMXTiledMap#getProperty instread'); - return this.getProperty(opts); - }, - - /** - * Get the object for the specific object name. It will return the 1st - * object found on the array for the given name. - * - * @opt {String} name Object name - * @returns {Object} Object - */ - getObject: function (opts) { - var objectName = opts.name; - var object = null; - - this.objects.forEach(function (item) { - if (item.name == objectName) { - object = item; - } - }); - if (object !== null) { - return object; - } - }, - - /** - * @deprected Since v0.2. You should now use cocos.TMXObjectGroup#getProperty - */ - objectNamed: function (opts) { - console.warn('TMXObjectGroup#objectNamed is deprected. Use TMXObjectGroup#getObject instread'); - return this.getObject(opts); - } -}); - -var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ - filename: '', - orientation: 0, - mapSize: null, - tileSize: null, - layer: null, - tilesets: null, - objectGroups: null, - properties: null, - tileProperties: null, - - /** - * @memberOf cocos - * @constructs - * @extends BObject - * - * @param {String} tmxFile The file path of the TMX file to load - */ - init: function (tmxFile) { - TMXMapInfo.superclass.init.call(this, tmxFile); - - this.tilesets = []; - this.layers = []; - this.objectGroups = []; - this.properties = {}; - this.tileProperties = {}; - this.filename = tmxFile; - - this.parseXMLFile(tmxFile); - }, - - parseXMLFile: function (xmlFile) { - var parser = new DOMParser(), - doc = parser.parseFromString(resource(xmlFile), 'text/xml'); - - // PARSE - var map = doc.documentElement; - - // Set Orientation - switch (map.getAttribute('orientation')) { - case 'orthogonal': - this.orientation = TMXOrientationOrtho; - break; - case 'isometric': - this.orientation = TMXOrientationIso; - break; - case 'hexagonal': - this.orientation = TMXOrientationHex; - break; - default: - throw "cocos2d: TMXFomat: Unsupported orientation: " + map.getAttribute('orientation'); - } - this.mapSize = {width: parseInt(map.getAttribute('width'), 10), height: parseInt(map.getAttribute('height'), 10)}; - this.tileSize = {width: parseInt(map.getAttribute('tilewidth'), 10), height: parseInt(map.getAttribute('tileheight'), 10)}; - - - // PARSE - var tilesets = map.getElementsByTagName('tileset'); - var i, j, len, jen, s; - for (i = 0, len = tilesets.length; i < len; i++) { - var t = tilesets[i]; - - var tileset = TMXTilesetInfo.create(); - tileset.set('name', t.getAttribute('name')); - tileset.set('firstGID', parseInt(t.getAttribute('firstgid'), 10)); - if (t.getAttribute('spacing')) { - tileset.set('spacing', parseInt(t.getAttribute('spacing'), 10)); - } - if (t.getAttribute('margin')) { - tileset.set('margin', parseInt(t.getAttribute('margin'), 10)); - } - - s = {}; - s.width = parseInt(t.getAttribute('tilewidth'), 10); - s.height = parseInt(t.getAttribute('tileheight'), 10); - tileset.set('tileSize', s); - - // PARSE We assume there's only 1 - var image = t.getElementsByTagName('image')[0]; - tileset.set('sourceImage', path.join(path.dirname(this.filename), image.getAttribute('source'))); - - this.tilesets.push(tileset); - } - - // PARSE - var layers = map.getElementsByTagName('layer'); - for (i = 0, len = layers.length; i < len; i++) { - var l = layers[i]; - var data = l.getElementsByTagName('data')[0]; - var layer = TMXLayerInfo.create(); - - layer.set('name', l.getAttribute('name')); - if (l.getAttribute('visible') !== false) { - layer.set('visible', true); - } else { - layer.set('visible', !!parseInt(l.getAttribute('visible'), 10)); - } - - s = {}; - s.width = parseInt(l.getAttribute('width'), 10); - s.height = parseInt(l.getAttribute('height'), 10); - layer.set('layerSize', s); - - var opacity = l.getAttribute('opacity'); - if (!opacity && opacity !== 0) { - layer.set('opacity', 255); - } else { - layer.set('opacity', 255 * parseFloat(opacity)); - } - - var x = parseInt(l.getAttribute('x'), 10), - y = parseInt(l.getAttribute('y'), 10); - if (isNaN(x)) { - x = 0; - } - if (isNaN(y)) { - y = 0; - } - layer.set('offset', ccp(x, y)); - - - // Firefox has a 4KB limit on node values. It will split larger - // nodes up into multiple nodes. So, we'll stitch them back - // together. - var nodeValue = ''; - for (j = 0, jen = data.childNodes.length; j < jen; j++) { - nodeValue += data.childNodes[j].nodeValue; - } - - // Unpack the tilemap data - var compression = data.getAttribute('compression'); - switch (compression) { - case 'gzip': - layer.set('tiles', gzip.unzipBase64AsArray(nodeValue, 4)); - break; - - // Uncompressed - case null: - case '': - layer.set('tiles', base64.decodeAsArray(nodeValue, 4)); - break; - - default: - throw "Unsupported TMX Tile Map compression: " + compression; - } - - this.layers.push(layer); - } - - // TODO PARSE - - // PARSE - var objectgroups = map.getElementsByTagName('objectgroup'); - for (i = 0, len = objectgroups.length; i < len; i++) { - var g = objectgroups[i], - objectGroup = TMXObjectGroup.create(); - - objectGroup.set('name', g.getAttribute('name')); - - var properties = g.querySelectorAll('objectgroup > properties property'), - propertiesValue = {}, - property; - - for (j = 0; j < properties.length; j++) { - property = properties[j]; - if (property.getAttribute('name')) { - propertiesValue[property.getAttribute('name')] = property.getAttribute('value'); - } - } - - objectGroup.set('properties', propertiesValue); - - var objectsArray = [], - objects = g.querySelectorAll('object'); - - for (j = 0; j < objects.length; j++) { - var object = objects[j]; - var objectValue = { - x : parseInt(object.getAttribute('x'), 10), - y : parseInt(object.getAttribute('y'), 10), - width : parseInt(object.getAttribute('width'), 10), - height : parseInt(object.getAttribute('height'), 10) - }; - if (object.getAttribute('name')) { - objectValue.name = object.getAttribute('name'); - } - if (object.getAttribute('type')) { - objectValue.type = object.getAttribute('type'); - } - properties = object.querySelectorAll('property'); - for (var k = 0; k < properties.length; k++) { - property = properties[k]; - if (property.getAttribute('name')) { - objectValue[property.getAttribute('name')] = property.getAttribute('value'); - } - } - objectsArray.push(objectValue); - - } - objectGroup.set('objects', objectsArray); - this.objectGroups.push(objectGroup); - } - } -}); - -exports.TMXMapInfo = TMXMapInfo; -exports.TMXLayerInfo = TMXLayerInfo; -exports.TMXTilesetInfo = TMXTilesetInfo; -exports.TMXObjectGroup = TMXObjectGroup; - -}}; -__resources__["/__builtin__/libs/geometry.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require BObject BArray*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'); - -var RE_PAIR = /\{\s*([\d.\-]+)\s*,\s*([\d.\-]+)\s*\}/, - RE_DOUBLE_PAIR = /\{\s*(\{[\s\d,.\-]+\})\s*,\s*(\{[\s\d,.\-]+\})\s*\}/; - -/** @namespace */ -var geometry = { - /** - * @class - * A 2D point in space - * - * @param {Float} x X value - * @param {Float} y Y value - */ - Point: function (x, y) { - /** - * X coordinate - * @type Float - */ - this.x = x; - - /** - * Y coordinate - * @type Float - */ - this.y = y; - }, - - /** - * @class - * A 2D size - * - * @param {Float} w Width - * @param {Float} h Height - */ - Size: function (w, h) { - /** - * Width - * @type Float - */ - this.width = w; - - /** - * Height - * @type Float - */ - this.height = h; - }, - - /** - * @class - * A rectangle - * - * @param {Float} x X value - * @param {Float} y Y value - * @param {Float} w Width - * @param {Float} h Height - */ - Rect: function (x, y, w, h) { - /** - * Coordinate in 2D space - * @type {geometry.Point} - */ - this.origin = new geometry.Point(x, y); - - /** - * Size in 2D space - * @type {geometry.Size} - */ - this.size = new geometry.Size(w, h); - }, - - /** - * @class - * Transform matrix - * - * @param {Float} a - * @param {Float} b - * @param {Float} c - * @param {Float} d - * @param {Float} tx - * @param {Float} ty - */ - TransformMatrix: function (a, b, c, d, tx, ty) { - this.a = a; - this.b = b; - this.c = c; - this.d = d; - this.tx = tx; - this.ty = ty; - }, - - /** - * Creates a geometry.Point instance - * - * @param {Float} x X coordinate - * @param {Float} y Y coordinate - * @returns {geometry.Point} - */ - ccp: function (x, y) { - return module.exports.pointMake(x, y); - }, - - /** - * Add the values of two points together - * - * @param {geometry.Point} p1 First point - * @param {geometry.Point} p2 Second point - * @returns {geometry.Point} New point - */ - ccpAdd: function (p1, p2) { - return geometry.ccp(p1.x + p2.x, p1.y + p2.y); - }, - - /** - * Subtract the values of two points - * - * @param {geometry.Point} p1 First point - * @param {geometry.Point} p2 Second point - * @returns {geometry.Point} New point - */ - ccpSub: function (p1, p2) { - return geometry.ccp(p1.x - p2.x, p1.y - p2.y); - }, - - /** - * Muliply the values of two points together - * - * @param {geometry.Point} p1 First point - * @param {geometry.Point} p2 Second point - * @returns {geometry.Point} New point - */ - ccpMult: function (p1, p2) { - return geometry.ccp(p1.x * p2.x, p1.y * p2.y); - }, - - - /** - * Invert the values of a geometry.Point - * - * @param {geometry.Point} p Point to invert - * @returns {geometry.Point} New point - */ - ccpNeg: function (p) { - return geometry.ccp(-p.x, -p.y); - }, - - /** - * Round values on a geometry.Point to whole numbers - * - * @param {geometry.Point} p Point to round - * @returns {geometry.Point} New point - */ - ccpRound: function (p) { - return geometry.ccp(Math.round(p.x), Math.round(p.y)); - }, - - /** - * Round up values on a geometry.Point to whole numbers - * - * @param {geometry.Point} p Point to round - * @returns {geometry.Point} New point - */ - ccpCeil: function (p) { - return geometry.ccp(Math.ceil(p.x), Math.ceil(p.y)); - }, - - /** - * Round down values on a geometry.Point to whole numbers - * - * @param {geometry.Point} p Point to round - * @returns {geometry.Point} New point - */ - ccpFloor: function (p) { - return geometry.ccp(Math.floor(p.x), Math.floor(p.y)); - }, - - /** - * A point at 0x0 - * - * @returns {geometry.Point} New point at 0x0 - */ - PointZero: function () { - return geometry.ccp(0, 0); - }, - - /** - * @returns {geometry.Rect} - */ - rectMake: function (x, y, w, h) { - return new geometry.Rect(x, y, w, h); - }, - - /** - * @returns {geometry.Rect} - */ - rectFromString: function (str) { - var matches = str.match(RE_DOUBLE_PAIR), - p = geometry.pointFromString(matches[1]), - s = geometry.sizeFromString(matches[2]); - - return geometry.rectMake(p.x, p.y, s.width, s.height); - }, - - /** - * @returns {geometry.Size} - */ - sizeMake: function (w, h) { - return new geometry.Size(w, h); - }, - - /** - * @returns {geometry.Size} - */ - sizeFromString: function (str) { - var matches = str.match(RE_PAIR), - w = parseFloat(matches[1]), - h = parseFloat(matches[2]); - - return geometry.sizeMake(w, h); - }, - - /** - * @returns {geometry.Point} - */ - pointMake: function (x, y) { - return new geometry.Point(x, y); - }, - - /** - * @returns {geometry.Point} - */ - pointFromString: function (str) { - var matches = str.match(RE_PAIR), - x = parseFloat(matches[1]), - y = parseFloat(matches[2]); - - return geometry.pointMake(x, y); - }, - - /** - * @returns {Boolean} - */ - rectContainsPoint: function (r, p) { - return ((p.x >= r.origin.x && p.x <= r.origin.x + r.size.width) && - (p.y >= r.origin.y && p.y <= r.origin.y + r.size.height)); - }, - - /** - * Returns the smallest rectangle that contains the two source rectangles. - * - * @param {geometry.Rect} r1 - * @param {geometry.Rect} r2 - * @returns {geometry.Rect} - */ - rectUnion: function (r1, r2) { - var rect = new geometry.Rect(0, 0, 0, 0); - - rect.origin.x = Math.min(r1.origin.x, r2.origin.x); - rect.origin.y = Math.min(r1.origin.y, r2.origin.y); - rect.size.width = Math.max(r1.origin.x + r1.size.width, r2.origin.x + r2.size.width) - rect.origin.x; - rect.size.height = Math.max(r1.origin.y + r1.size.height, r2.origin.y + r2.size.height) - rect.origin.y; - - return rect; - }, - - /** - * @returns {Boolean} - */ - rectOverlapsRect: function (r1, r2) { - if (r1.origin.x + r1.size.width < r2.origin.x) { - return false; - } - if (r2.origin.x + r2.size.width < r1.origin.x) { - return false; - } - if (r1.origin.y + r1.size.height < r2.origin.y) { - return false; - } - if (r2.origin.y + r2.size.height < r1.origin.y) { - return false; - } - - return true; - }, - - /** - * Returns the overlapping portion of 2 rectangles - * - * @param {geometry.Rect} lhsRect First rectangle - * @param {geometry.Rect} rhsRect Second rectangle - * @returns {geometry.Rect} The overlapping portion of the 2 rectangles - */ - rectIntersection: function (lhsRect, rhsRect) { - - var intersection = new geometry.Rect( - Math.max(geometry.rectGetMinX(lhsRect), geometry.rectGetMinX(rhsRect)), - Math.max(geometry.rectGetMinY(lhsRect), geometry.rectGetMinY(rhsRect)), - 0, - 0 - ); - - intersection.size.width = Math.min(geometry.rectGetMaxX(lhsRect), geometry.rectGetMaxX(rhsRect)) - geometry.rectGetMinX(intersection); - intersection.size.height = Math.min(geometry.rectGetMaxY(lhsRect), geometry.rectGetMaxY(rhsRect)) - geometry.rectGetMinY(intersection); - - return intersection; - }, - - /** - * @returns {Boolean} - */ - pointEqualToPoint: function (point1, point2) { - return (point1.x == point2.x && point1.y == point2.y); - }, - - /** - * @returns {Boolean} - */ - sizeEqualToSize: function (size1, size2) { - return (size1.width == size2.width && size1.height == size2.height); - }, - - /** - * @returns {Boolean} - */ - rectEqualToRect: function (rect1, rect2) { - return (module.exports.sizeEqualToSize(rect1.size, rect2.size) && module.exports.pointEqualToPoint(rect1.origin, rect2.origin)); - }, - - /** - * @returns {Float} - */ - rectGetMinX: function (rect) { - return rect.origin.x; - }, - - /** - * @returns {Float} - */ - rectGetMinY: function (rect) { - return rect.origin.y; - }, - - /** - * @returns {Float} - */ - rectGetMaxX: function (rect) { - return rect.origin.x + rect.size.width; - }, - - /** - * @returns {Float} - */ - rectGetMaxY: function (rect) { - return rect.origin.y + rect.size.height; - }, - - boundingRectMake: function (p1, p2, p3, p4) { - var minX = Math.min(p1.x, p2.x, p3.x, p4.x); - var minY = Math.min(p1.y, p2.y, p3.y, p4.y); - var maxX = Math.max(p1.x, p2.x, p3.x, p4.x); - var maxY = Math.max(p1.y, p2.y, p3.y, p4.y); - - return new geometry.Rect(minX, minY, (maxX - minX), (maxY - minY)); - }, - - /** - * @returns {geometry.Point} - */ - pointApplyAffineTransform: function (point, t) { - - /* - aPoint.x * aTransform.a + aPoint.y * aTransform.c + aTransform.tx, - aPoint.x * aTransform.b + aPoint.y * aTransform.d + aTransform.ty - */ - - return new geometry.Point(t.a * point.x + t.c * point.y + t.tx, t.b * point.x + t.d * point.y + t.ty); - - }, - - /** - * Apply a transform matrix to a rectangle - * - * @param {geometry.Rect} rect Rectangle to transform - * @param {geometry.TransformMatrix} trans TransformMatrix to apply to rectangle - * @returns {geometry.Rect} A new transformed rectangle - */ - rectApplyAffineTransform: function (rect, trans) { - - var p1 = geometry.ccp(geometry.rectGetMinX(rect), geometry.rectGetMinY(rect)); - var p2 = geometry.ccp(geometry.rectGetMaxX(rect), geometry.rectGetMinY(rect)); - var p3 = geometry.ccp(geometry.rectGetMinX(rect), geometry.rectGetMaxY(rect)); - var p4 = geometry.ccp(geometry.rectGetMaxX(rect), geometry.rectGetMaxY(rect)); - - p1 = geometry.pointApplyAffineTransform(p1, trans); - p2 = geometry.pointApplyAffineTransform(p2, trans); - p3 = geometry.pointApplyAffineTransform(p3, trans); - p4 = geometry.pointApplyAffineTransform(p4, trans); - - return geometry.boundingRectMake(p1, p2, p3, p4); - }, - - /** - * Inverts a transform matrix - * - * @param {geometry.TransformMatrix} trans TransformMatrix to invert - * @returns {geometry.TransformMatrix} New transform matrix - */ - affineTransformInvert: function (trans) { - var determinant = 1 / (trans.a * trans.d - trans.b * trans.c); - - return new geometry.TransformMatrix( - determinant * trans.d, - -determinant * trans.b, - -determinant * trans.c, - determinant * trans.a, - determinant * (trans.c * trans.ty - trans.d * trans.tx), - determinant * (trans.b * trans.tx - trans.a * trans.ty) - ); - }, - - /** - * Multiply 2 transform matrices together - * @param {geometry.TransformMatrix} lhs Left matrix - * @param {geometry.TransformMatrix} rhs Right matrix - * @returns {geometry.TransformMatrix} New transform matrix - */ - affineTransformConcat: function (lhs, rhs) { - return new geometry.TransformMatrix( - lhs.a * rhs.a + lhs.b * rhs.c, - lhs.a * rhs.b + lhs.b * rhs.d, - lhs.c * rhs.a + lhs.d * rhs.c, - lhs.c * rhs.b + lhs.d * rhs.d, - lhs.tx * rhs.a + lhs.ty * rhs.c + rhs.tx, - lhs.tx * rhs.b + lhs.ty * rhs.d + rhs.ty - ); - }, - - /** - * @returns {Float} - */ - degreesToRadians: function (angle) { - return angle / 180.0 * Math.PI; - }, - - /** - * @returns {Float} - */ - radiansToDegrees: function (angle) { - return angle * (180.0 / Math.PI); - }, - - /** - * Translate (move) a transform matrix - * - * @param {geometry.TransformMatrix} trans TransformMatrix to translate - * @param {Float} tx Amount to translate along X axis - * @param {Float} ty Amount to translate along Y axis - * @returns {geometry.TransformMatrix} A new TransformMatrix - */ - affineTransformTranslate: function (trans, tx, ty) { - var newTrans = util.copy(trans); - newTrans.tx = trans.tx + trans.a * tx + trans.c * ty; - newTrans.ty = trans.ty + trans.b * tx + trans.d * ty; - return newTrans; - }, - - /** - * Rotate a transform matrix - * - * @param {geometry.TransformMatrix} trans TransformMatrix to rotate - * @param {Float} angle Angle in radians - * @returns {geometry.TransformMatrix} A new TransformMatrix - */ - affineTransformRotate: function (trans, angle) { - var sin = Math.sin(angle), - cos = Math.cos(angle); - - return new geometry.TransformMatrix( - trans.a * cos + trans.c * sin, - trans.b * cos + trans.d * sin, - trans.c * cos - trans.a * sin, - trans.d * cos - trans.b * sin, - trans.tx, - trans.ty - ); - }, - - /** - * Scale a transform matrix - * - * @param {geometry.TransformMatrix} trans TransformMatrix to scale - * @param {Float} sx X scale factor - * @param {Float} [sy=sx] Y scale factor - * @returns {geometry.TransformMatrix} A new TransformMatrix - */ - affineTransformScale: function (trans, sx, sy) { - if (sy === undefined) { - sy = sx; - } - - return new geometry.TransformMatrix(trans.a * sx, trans.b * sx, trans.c * sy, trans.d * sy, trans.tx, trans.ty); - }, - - /** - * @returns {geometry.TransformMatrix} identity matrix - */ - affineTransformIdentity: function () { - return new geometry.TransformMatrix(1, 0, 0, 1, 0, 0); - } -}; - -module.exports = geometry; - -}}; -__resources__["/__builtin__/libs/gzip.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/** - * @fileoverview - */ - -/** @ignore */ -var JXG = require('./JXGUtil'); - -/** - * @namespace - * Wrappers around JXG's GZip utils - * @see JXG.Util - */ -var gzip = { - /** - * Unpack a gzipped byte array - * - * @param {Integer[]} input Byte array - * @returns {String} Unpacked byte string - */ - unzip: function(input) { - return (new JXG.Util.Unzip(input)).unzip()[0][0]; - }, - - /** - * Unpack a gzipped byte string encoded as base64 - * - * @param {String} input Byte string encoded as base64 - * @returns {String} Unpacked byte string - */ - unzipBase64: function(input) { - return (new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(input))).unzip()[0][0]; - }, - - /** - * Unpack a gzipped byte string encoded as base64 - * - * @param {String} input Byte string encoded as base64 - * @param {Integer} bytes Bytes per array item - * @returns {Integer[]} Unpacked byte array - */ - unzipBase64AsArray: function(input, bytes) { - bytes = bytes || 1; - - var dec = this.unzipBase64(input), - ar = [], i, j, len; - for (i = 0, len = dec.length/bytes; i < len; i++){ - ar[i] = 0; - for (j = bytes-1; j >= 0; --j){ - ar[i] += dec.charCodeAt((i *bytes) +j) << (j *8); - } - } - return ar; - }, - - /** - * Unpack a gzipped byte array - * - * @param {Integer[]} input Byte array - * @param {Integer} bytes Bytes per array item - * @returns {Integer[]} Unpacked byte array - */ - unzipAsArray: function (input, bytes) { - bytes = bytes || 1; - - var dec = this.unzip(input), - ar = [], i, j, len; - for (i = 0, len = dec.length/bytes; i < len; i++){ - ar[i] = 0; - for (j = bytes-1; j >= 0; --j){ - ar[i] += dec.charCodeAt((i *bytes) +j) << (j *8); - } - } - return ar; - } - -}; - -module.exports = gzip; - -}}; -__resources__["/__builtin__/libs/JXGUtil.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/* - Copyright 2008,2009 - Matthias Ehmann, - Michael Gerhaeuser, - Carsten Miller, - Bianca Valentin, - Alfred Wassermann, - Peter Wilfahrt - - This file is part of JSXGraph. - - JSXGraph is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - JSXGraph is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with JSXGraph. If not, see . -*/ - -/** - * @fileoverview Utilities for uncompressing and base64 decoding - */ - -/** @namespace */ -var JXG = {}; - -/** - * @class Util class - * Class for gunzipping, unzipping and base64 decoding of files. - * It is used for reading GEONExT, Geogebra and Intergeo files. - * - * Only Huffman codes are decoded in gunzip. - * The code is based on the source code for gunzip.c by Pasi Ojala - * @see
          http://www.cs.tut.fi/~albert/Dev/gunzip/gunzip.c - * @see http://www.cs.tut.fi/~albert - */ -JXG.Util = {}; - -/** - * Unzip zip files - */ -JXG.Util.Unzip = function (barray){ - var outputArr = [], - output = "", - debug = false, - gpflags, - files = 0, - unzipped = [], - crc, - buf32k = new Array(32768), - bIdx = 0, - modeZIP=false, - - CRC, SIZE, - - bitReverse = [ - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff - ], - - cplens = [ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ], - - cplext = [ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 - ], /* 99==invalid */ - - cpdist = [ - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, - 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, - 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, - 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001 - ], - - cpdext = [ - 0, 0, 0, 0, 1, 1, 2, 2, - 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, - 11, 11, 12, 12, 13, 13 - ], - - border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], - - bA = barray, - - bytepos=0, - bitpos=0, - bb = 1, - bits=0, - - NAMEMAX = 256, - - nameBuf = [], - - fileout; - - function readByte(){ - bits+=8; - if (bytepos"); - return bA[bytepos++]; - } else - return -1; - }; - - function byteAlign(){ - bb = 1; - }; - - function readBit(){ - var carry; - bits++; - carry = (bb & 1); - bb >>= 1; - if (bb==0){ - bb = readByte(); - carry = (bb & 1); - bb = (bb>>1) | 0x80; - } - return carry; - }; - - function readBits(a) { - var res = 0, - i = a; - - while(i--) { - res = (res<<1) | readBit(); - } - if(a) { - res = bitReverse[res]>>(8-a); - } - return res; - }; - - function flushBuffer(){ - //document.write('FLUSHBUFFER:'+buf32k); - bIdx = 0; - }; - function addBuffer(a){ - SIZE++; - //CRC=updcrc(a,crc); - buf32k[bIdx++] = a; - outputArr.push(String.fromCharCode(a)); - //output+=String.fromCharCode(a); - if(bIdx==0x8000){ - //document.write('ADDBUFFER:'+buf32k); - bIdx=0; - } - }; - - function HufNode() { - this.b0=0; - this.b1=0; - this.jump = null; - this.jumppos = -1; - }; - - var LITERALS = 288; - - var literalTree = new Array(LITERALS); - var distanceTree = new Array(32); - var treepos=0; - var Places = null; - var Places2 = null; - - var impDistanceTree = new Array(64); - var impLengthTree = new Array(64); - - var len = 0; - var fpos = new Array(17); - fpos[0]=0; - var flens; - var fmax; - - function IsPat() { - while (1) { - if (fpos[len] >= fmax) - return -1; - if (flens[fpos[len]] == len) - return fpos[len]++; - fpos[len]++; - } - }; - - function Rec() { - var curplace = Places[treepos]; - var tmp; - if (debug) - document.write("
          len:"+len+" treepos:"+treepos); - if(len==17) { //war 17 - return -1; - } - treepos++; - len++; - - tmp = IsPat(); - if (debug) - document.write("
          IsPat "+tmp); - if(tmp >= 0) { - curplace.b0 = tmp; /* leaf cell for 0-bit */ - if (debug) - document.write("
          b0 "+curplace.b0); - } else { - /* Not a Leaf cell */ - curplace.b0 = 0x8000; - if (debug) - document.write("
          b0 "+curplace.b0); - if(Rec()) - return -1; - } - tmp = IsPat(); - if(tmp >= 0) { - curplace.b1 = tmp; /* leaf cell for 1-bit */ - if (debug) - document.write("
          b1 "+curplace.b1); - curplace.jump = null; /* Just for the display routine */ - } else { - /* Not a Leaf cell */ - curplace.b1 = 0x8000; - if (debug) - document.write("
          b1 "+curplace.b1); - curplace.jump = Places[treepos]; - curplace.jumppos = treepos; - if(Rec()) - return -1; - } - len--; - return 0; - }; - - function CreateTree(currentTree, numval, lengths, show) { - var i; - /* Create the Huffman decode tree/table */ - //document.write("
          createtree
          "); - if (debug) - document.write("currentTree "+currentTree+" numval "+numval+" lengths "+lengths+" show "+show); - Places = currentTree; - treepos=0; - flens = lengths; - fmax = numval; - for (i=0;i<17;i++) - fpos[i] = 0; - len = 0; - if(Rec()) { - //fprintf(stderr, "invalid huffman tree\n"); - if (debug) - alert("invalid huffman tree\n"); - return -1; - } - if (debug){ - document.write('
          Tree: '+Places.length); - for (var a=0;a<32;a++){ - document.write("Places["+a+"].b0="+Places[a].b0+"
          "); - document.write("Places["+a+"].b1="+Places[a].b1+"
          "); - } - } - - return 0; - }; - - function DecodeValue(currentTree) { - var len, i, - xtreepos=0, - X = currentTree[xtreepos], - b; - - /* decode one symbol of the data */ - while(1) { - b=readBit(); - if (debug) - document.write("b="+b); - if(b) { - if(!(X.b1 & 0x8000)){ - if (debug) - document.write("ret1"); - return X.b1; /* If leaf node, return data */ - } - X = X.jump; - len = currentTree.length; - for (i=0;i>1); - if(j > 23) { - j = (j<<1) | readBit(); /* 48..255 */ - - if(j > 199) { /* 200..255 */ - j -= 128; /* 72..127 */ - j = (j<<1) | readBit(); /* 144..255 << */ - } else { /* 48..199 */ - j -= 48; /* 0..151 */ - if(j > 143) { - j = j+136; /* 280..287 << */ - /* 0..143 << */ - } - } - } else { /* 0..23 */ - j += 256; /* 256..279 << */ - } - if(j < 256) { - addBuffer(j); - //document.write("out:"+String.fromCharCode(j)); - /*fprintf(errfp, "@%d %02x\n", SIZE, j);*/ - } else if(j == 256) { - /* EOF */ - break; - } else { - var len, dist; - - j -= 256 + 1; /* bytes + EOF */ - len = readBits(cplext[j]) + cplens[j]; - - j = bitReverse[readBits(5)]>>3; - if(cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j]-8)<<8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - - /*fprintf(errfp, "@%d (l%02x,d%04x)\n", SIZE, len, dist);*/ - for(j=0;jparam: "+literalCodes+" "+distCodes+" "+lenCodes+"
          "); - for(j=0; j<19; j++) { - ll[j] = 0; - } - - // Get the decode tree code lengths - - //document.write("
          "); - for(j=0; jll:'+ll); - len = distanceTree.length; - for (i=0; idistanceTree"); - for(var a=0;a"+distanceTree[a].b0+" "+distanceTree[a].b1+" "+distanceTree[a].jump+" "+distanceTree[a].jumppos); - /*if (distanceTree[a].jumppos!=-1) - document.write(" "+distanceTree[a].jump.b0+" "+distanceTree[a].jump.b1); - */ - } - } - //document.write('
          tree created'); - - //read in literal and distance code lengths - n = literalCodes + distCodes; - i = 0; - var z=-1; - if (debug) - document.write("
          n="+n+" bits: "+bits+"
          "); - while(i < n) { - z++; - j = DecodeValue(distanceTree); - if (debug) - document.write("
          "+z+" i:"+i+" decode: "+j+" bits "+bits+"
          "); - if(j<16) { // length of code in bits (0..15) - ll[i++] = j; - } else if(j==16) { // repeat last length 3 to 6 times - var l; - j = 3 + readBits(2); - if(i+j > n) { - flushBuffer(); - return 1; - } - l = i ? ll[i-1] : 0; - while(j--) { - ll[i++] = l; - } - } else { - if(j==17) { // 3 to 10 zero length codes - j = 3 + readBits(3); - } else { // j == 18: 11 to 138 zero length codes - j = 11 + readBits(7); - } - if(i+j > n) { - flushBuffer(); - return 1; - } - while(j--) { - ll[i++] = 0; - } - } - } - /*for(j=0; jliteralTree"); - while(1) { - j = DecodeValue(literalTree); - if(j >= 256) { // In C64: if carry set - var len, dist; - j -= 256; - if(j == 0) { - // EOF - break; - } - j--; - len = readBits(cplext[j]) + cplens[j]; - - j = DecodeValue(distanceTree); - if(cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j]-8)<<8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - while(len--) { - var c = buf32k[(bIdx - dist) & 0x7fff]; - addBuffer(c); - } - } else { - addBuffer(j); - } - } - } - } while(!last); - flushBuffer(); - - byteAlign(); - return 0; -}; - -JXG.Util.Unzip.prototype.unzipFile = function(name) { - var i; - this.unzip(); - //alert(unzipped[0][1]); - for (i=0;i"); - } - */ - //alert(bA); - nextFile(); - return unzipped; - }; - - function nextFile(){ - if (debug) - alert("NEXTFILE"); - outputArr = []; - var tmp = []; - modeZIP = false; - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("type: "+tmp[0]+" "+tmp[1]); - if (tmp[0] == parseInt("78",16) && tmp[1] == parseInt("da",16)){ //GZIP - if (debug) - alert("GEONExT-GZIP"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "geonext.gxt"; - files++; - } - if (tmp[0] == parseInt("1f",16) && tmp[1] == parseInt("8b",16)){ //GZIP - if (debug) - alert("GZIP"); - //DeflateLoop(); - skipdir(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "file"; - files++; - } - if (tmp[0] == parseInt("50",16) && tmp[1] == parseInt("4b",16)){ //ZIP - modeZIP = true; - tmp[2] = readByte(); - tmp[3] = readByte(); - if (tmp[2] == parseInt("3",16) && tmp[3] == parseInt("4",16)){ - //MODE_ZIP - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("ZIP-Version: "+tmp[1]+" "+tmp[0]/10+"."+tmp[0]%10); - - gpflags = readByte(); - gpflags |= (readByte()<<8); - if (debug) - alert("gpflags: "+gpflags); - - var method = readByte(); - method |= (readByte()<<8); - if (debug) - alert("method: "+method); - - readByte(); - readByte(); - readByte(); - readByte(); - - var crc = readByte(); - crc |= (readByte()<<8); - crc |= (readByte()<<16); - crc |= (readByte()<<24); - - var compSize = readByte(); - compSize |= (readByte()<<8); - compSize |= (readByte()<<16); - compSize |= (readByte()<<24); - - var size = readByte(); - size |= (readByte()<<8); - size |= (readByte()<<16); - size |= (readByte()<<24); - - if (debug) - alert("local CRC: "+crc+"\nlocal Size: "+size+"\nlocal CompSize: "+compSize); - - var filelen = readByte(); - filelen |= (readByte()<<8); - - var extralen = readByte(); - extralen |= (readByte()<<8); - - if (debug) - alert("filelen "+filelen); - i = 0; - nameBuf = []; - while (filelen--){ - var c = readByte(); - if (c == "/" | c ==":"){ - i = 0; - } else if (i < NAMEMAX-1) - nameBuf[i++] = String.fromCharCode(c); - } - if (debug) - alert("nameBuf: "+nameBuf); - - //nameBuf[i] = "\0"; - if (!fileout) - fileout = nameBuf; - - var i = 0; - while (i < extralen){ - c = readByte(); - i++; - } - - CRC = 0xffffffff; - SIZE = 0; - - if (size = 0 && fileOut.charAt(fileout.length-1)=="/"){ - //skipdir - if (debug) - alert("skipdir"); - } - if (method == 8){ - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = nameBuf.join(''); - files++; - //return outputArr.join(''); - } - skipdir(); - } - } - }; - -function skipdir(){ - var crc, - tmp = [], - compSize, size, os, i, c; - - if ((gpflags & 8)) { - tmp[0] = readByte(); - tmp[1] = readByte(); - tmp[2] = readByte(); - tmp[3] = readByte(); - - if (tmp[0] == parseInt("50",16) && - tmp[1] == parseInt("4b",16) && - tmp[2] == parseInt("07",16) && - tmp[3] == parseInt("08",16)) - { - crc = readByte(); - crc |= (readByte()<<8); - crc |= (readByte()<<16); - crc |= (readByte()<<24); - } else { - crc = tmp[0] | (tmp[1]<<8) | (tmp[2]<<16) | (tmp[3]<<24); - } - - compSize = readByte(); - compSize |= (readByte()<<8); - compSize |= (readByte()<<16); - compSize |= (readByte()<<24); - - size = readByte(); - size |= (readByte()<<8); - size |= (readByte()<<16); - size |= (readByte()<<24); - - if (debug) - alert("CRC:"); - } - - if (modeZIP) - nextFile(); - - tmp[0] = readByte(); - if (tmp[0] != 8) { - if (debug) - alert("Unknown compression method!"); - return 0; - } - - gpflags = readByte(); - if (debug){ - if ((gpflags & ~(parseInt("1f",16)))) - alert("Unknown flags set!"); - } - - readByte(); - readByte(); - readByte(); - readByte(); - - readByte(); - os = readByte(); - - if ((gpflags & 4)){ - tmp[0] = readByte(); - tmp[2] = readByte(); - len = tmp[0] + 256*tmp[1]; - if (debug) - alert("Extra field size: "+len); - for (i=0;ihttp://www.webtoolkit.info/ -*/ -JXG.Util.Base64 = { - - // private property - _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", - - // public method for encoding - encode : function (input) { - var output = [], - chr1, chr2, chr3, enc1, enc2, enc3, enc4, - i = 0; - - input = JXG.Util.Base64._utf8_encode(input); - - while (i < input.length) { - - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output.push([this._keyStr.charAt(enc1), - this._keyStr.charAt(enc2), - this._keyStr.charAt(enc3), - this._keyStr.charAt(enc4)].join('')); - } - - return output.join(''); - }, - - // public method for decoding - decode : function (input, utf8) { - var output = [], - chr1, chr2, chr3, - enc1, enc2, enc3, enc4, - i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - - enc1 = this._keyStr.indexOf(input.charAt(i++)); - enc2 = this._keyStr.indexOf(input.charAt(i++)); - enc3 = this._keyStr.indexOf(input.charAt(i++)); - enc4 = this._keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output.push(String.fromCharCode(chr1)); - - if (enc3 != 64) { - output.push(String.fromCharCode(chr2)); - } - if (enc4 != 64) { - output.push(String.fromCharCode(chr3)); - } - } - - output = output.join(''); - - if (utf8) { - output = JXG.Util.Base64._utf8_decode(output); - } - return output; - - }, - - // private method for UTF-8 encoding - _utf8_encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // private method for UTF-8 decoding - _utf8_decode : function (utftext) { - var string = [], - i = 0, - c = 0, c2 = 0, c3 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } - else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } - else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - } - return string.join(''); - }, - - _destrip: function (stripped, wrap){ - var lines = [], lineno, i, - destripped = []; - - if (wrap==null) - wrap = 76; - - stripped.replace(/ /g, ""); - lineno = stripped.length / wrap; - for (i = 0; i < lineno; i++) - lines[i]=stripped.substr(i * wrap, wrap); - if (lineno != stripped.length / wrap) - lines[lines.length]=stripped.substr(lineno * wrap, stripped.length-(lineno * wrap)); - - for (i = 0; i < lines.length; i++) - destripped.push(lines[i]); - return destripped.join('\n'); - }, - - decodeAsArray: function (input){ - var dec = this.decode(input), - ar = [], i; - for (i=0;i255){ - switch (c) { - case 8364: c=128; - break; - case 8218: c=130; - break; - case 402: c=131; - break; - case 8222: c=132; - break; - case 8230: c=133; - break; - case 8224: c=134; - break; - case 8225: c=135; - break; - case 710: c=136; - break; - case 8240: c=137; - break; - case 352: c=138; - break; - case 8249: c=139; - break; - case 338: c=140; - break; - case 381: c=142; - break; - case 8216: c=145; - break; - case 8217: c=146; - break; - case 8220: c=147; - break; - case 8221: c=148; - break; - case 8226: c=149; - break; - case 8211: c=150; - break; - case 8212: c=151; - break; - case 732: c=152; - break; - case 8482: c=153; - break; - case 353: c=154; - break; - case 8250: c=155; - break; - case 339: c=156; - break; - case 382: c=158; - break; - case 376: c=159; - break; - default: - break; - } - } - return c; -}; - -/** - * Decoding string into utf-8 - * @param {String} string to decode - * @return {String} utf8 decoded string - */ -JXG.Util.utf8Decode = function(utftext) { - var string = []; - var i = 0; - var c = 0, c1 = 0, c2 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - }; - return string.join(''); -}; - -// Added to exports for Cocos2d -module.exports = JXG; - -}}; -__resources__["/__builtin__/libs/Plist.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/** - * XML Node types - */ -var ELEMENT_NODE = 1, - ATTRIBUTE_NODE = 2, - TEXT_NODE = 3, - CDATA_SECTION_NODE = 4, - ENTITY_REFERENCE_NODE = 5, - ENTITY_NODE = 6, - PROCESSING_INSTRUCTION_NODE = 7, - COMMENT_NODE = 8, - DOCUMENT_NODE = 9, - DOCUMENT_TYPE_NODE = 10, - DOCUMENT_FRAGMENT_NODE = 11, - NOTATION_NODE = 12; - - -var Plist = BObject.extend (/** @lends Plist# */{ - /** - * The unserialized data inside the Plist file - * @type Object - */ - data: null, - - /** - * An object representation of an XML Property List file - * - * @constructs - * @extends BObject - * @param {Options} opts Options - * @config {String} [file] The path to a .plist file - * @config {String} [data] The contents of a .plist file - */ - init: function(opts) { - var file = opts['file'], - data = opts['data']; - - if (file && !data) { - data = resource(file); - } - - - var parser = new DOMParser(), - doc = parser.parseFromString(data, 'text/xml'), - plist = doc.documentElement; - - if (plist.tagName != 'plist') { - throw "Not a plist file"; - } - - - // Get first real node - var node = null; - for (var i = 0, len = plist.childNodes.length; i < len; i++) { - node = plist.childNodes[i]; - if (node.nodeType == ELEMENT_NODE) { - break; - } - } - - this.set('data', this.parseNode_(node)); - }, - - - /** - * @private - * Parses an XML node inside the Plist file - * @returns {Object/Array/String/Integer/Float} A JS representation of the node value - */ - parseNode_: function(node) { - var data = null; - switch(node.tagName) { - case 'dict': - data = this.parseDict_(node); - break; - case 'array': - data = this.parseArray_(node); - break; - case 'string': - // FIXME - This needs to handle Firefox's 4KB nodeValue limit - data = node.firstChild.nodeValue; - break - case 'false': - data = false; - break - case 'true': - data = true; - break - case 'real': - data = parseFloat(node.firstChild.nodeValue); - break - case 'integer': - data = parseInt(node.firstChild.nodeValue, 10); - break - } - - return data; - }, - - /** - * @private - * Parses a node in a plist file - * - * @param {XMLElement} - * @returns {Object} A simple key/value JS Object representing the - */ - parseDict_: function(node) { - var data = {}; - - var key = null; - for (var i = 0, len = node.childNodes.length; i < len; i++) { - var child = node.childNodes[i]; - if (child.nodeType != ELEMENT_NODE) { - continue; - } - - // Grab the key, next noe should be the value - if (child.tagName == 'key') { - key = child.firstChild.nodeValue; - } else { - // Parse the value node - data[key] = this.parseNode_(child); - } - } - - - return data; - }, - - /** - * @private - * Parses an node in a plist file - * - * @param {XMLElement} - * @returns {Array} A simple JS Array representing the - */ - parseArray_: function(node) { - var data = []; - - for (var i = 0, len = node.childNodes.length; i < len; i++) { - var child = node.childNodes[i]; - if (child.nodeType != ELEMENT_NODE) { - continue; - } - - data.push(this.parseNode_(child)); - } - - return data; - } -}); - - -exports.Plist = Plist; - -}}; -__resources__["/__builtin__/libs/qunit.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/* - * QUnit - A JavaScript Unit Testing Framework - * - * http://docs.jquery.com/QUnit - * - * Copyright (c) 2011 John Resig, Jörn Zaefferer - * Dual licensed under the MIT (MIT-LICENSE.txt) - * or GPL (GPL-LICENSE.txt) licenses. - */ - -(function(window) { - -var defined = { - setTimeout: typeof window.setTimeout !== "undefined", - sessionStorage: (function() { - try { - return !!sessionStorage.getItem; - } catch(e){ - return false; - } - })() -} - -var testId = 0; - -var Test = function(name, testName, expected, testEnvironmentArg, async, callback) { - this.name = name; - this.testName = testName; - this.expected = expected; - this.testEnvironmentArg = testEnvironmentArg; - this.async = async; - this.callback = callback; - this.assertions = []; -}; -Test.prototype = { - init: function() { - var tests = id("qunit-tests"); - if (tests) { - var b = document.createElement("strong"); - b.innerHTML = "Running " + this.name; - var li = document.createElement("li"); - li.appendChild( b ); - li.id = this.id = "test-output" + testId++; - tests.appendChild( li ); - } - }, - setup: function() { - if (this.module != config.previousModule) { - if ( config.previousModule ) { - QUnit.moduleDone( { - name: config.previousModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - } ); - } - config.previousModule = this.module; - config.moduleStats = { all: 0, bad: 0 }; - QUnit.moduleStart( { - name: this.module - } ); - } - - config.current = this; - this.testEnvironment = extend({ - setup: function() {}, - teardown: function() {} - }, this.moduleTestEnvironment); - if (this.testEnvironmentArg) { - extend(this.testEnvironment, this.testEnvironmentArg); - } - - QUnit.testStart( { - name: this.testName - } ); - - // allow utility functions to access the current test environment - // TODO why?? - QUnit.current_testEnvironment = this.testEnvironment; - - try { - if ( !config.pollution ) { - saveGlobal(); - } - - this.testEnvironment.setup.call(this.testEnvironment); - } catch(e) { - QUnit.ok( false, "Setup failed on " + this.testName + ": " + e.message ); - } - }, - run: function() { - if ( this.async ) { - QUnit.stop(); - } - - if ( config.notrycatch ) { - this.callback.call(this.testEnvironment); - return; - } - try { - this.callback.call(this.testEnvironment); - } catch(e) { - fail("Test " + this.testName + " died, exception and test follows", e, this.callback); - QUnit.ok( false, "Died on test #" + (this.assertions.length + 1) + ": " + e.message + " - " + QUnit.jsDump.parse(e) ); - // else next test will carry the responsibility - saveGlobal(); - - // Restart the tests if they're blocking - if ( config.blocking ) { - start(); - } - } - }, - teardown: function() { - try { - checkPollution(); - this.testEnvironment.teardown.call(this.testEnvironment); - } catch(e) { - QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message ); - } - }, - finish: function() { - if ( this.expected && this.expected != this.assertions.length ) { - QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" ); - } - - var good = 0, bad = 0, - tests = id("qunit-tests"); - - config.stats.all += this.assertions.length; - config.moduleStats.all += this.assertions.length; - - if ( tests ) { - var ol = document.createElement("ol"); - - for ( var i = 0; i < this.assertions.length; i++ ) { - var assertion = this.assertions[i]; - - var li = document.createElement("li"); - li.className = assertion.result ? "pass" : "fail"; - li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed"); - ol.appendChild( li ); - - if ( assertion.result ) { - good++; - } else { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - - // store result when possible - defined.sessionStorage && sessionStorage.setItem("qunit-" + this.testName, bad); - - if (bad == 0) { - ol.style.display = "none"; - } - - var b = document.createElement("strong"); - b.innerHTML = this.name + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; - - addEvent(b, "click", function() { - var next = b.nextSibling, display = next.style.display; - next.style.display = display === "none" ? "block" : "none"; - }); - - addEvent(b, "dblclick", function(e) { - var target = e && e.target ? e.target : window.event.srcElement; - if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { - target = target.parentNode; - } - if ( window.location && target.nodeName.toLowerCase() === "strong" ) { - window.location.search = "?" + encodeURIComponent(getText([target]).replace(/\(.+\)$/, "").replace(/(^\s*|\s*$)/g, "")); - } - }); - - var li = id(this.id); - li.className = bad ? "fail" : "pass"; - li.style.display = resultDisplayStyle(!bad); - li.removeChild( li.firstChild ); - li.appendChild( b ); - li.appendChild( ol ); - - } else { - for ( var i = 0; i < this.assertions.length; i++ ) { - if ( !this.assertions[i].result ) { - bad++; - config.stats.bad++; - config.moduleStats.bad++; - } - } - } - - try { - QUnit.reset(); - } catch(e) { - fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset); - } - - QUnit.testDone( { - name: this.testName, - failed: bad, - passed: this.assertions.length - bad, - total: this.assertions.length - } ); - }, - - queue: function() { - var test = this; - synchronize(function() { - test.init(); - }); - function run() { - // each of these can by async - synchronize(function() { - test.setup(); - }); - synchronize(function() { - test.run(); - }); - synchronize(function() { - test.teardown(); - }); - synchronize(function() { - test.finish(); - }); - } - // defer when previous test run passed, if storage is available - var bad = defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.testName); - if (bad) { - run(); - } else { - synchronize(run); - }; - } - -} - -var QUnit = { - - // call on start of module test to prepend name to all tests - module: function(name, testEnvironment) { - config.currentModule = name; - config.currentModuleTestEnviroment = testEnvironment; - }, - - asyncTest: function(testName, expected, callback) { - if ( arguments.length === 2 ) { - callback = expected; - expected = 0; - } - - QUnit.test(testName, expected, callback, true); - }, - - test: function(testName, expected, callback, async) { - var name = '' + testName + '', testEnvironmentArg; - - if ( arguments.length === 2 ) { - callback = expected; - expected = null; - } - // is 2nd argument a testEnvironment? - if ( expected && typeof expected === 'object') { - testEnvironmentArg = expected; - expected = null; - } - - if ( config.currentModule ) { - name = '' + config.currentModule + ": " + name; - } - - if ( !validTest(config.currentModule + ": " + testName) ) { - return; - } - - var test = new Test(name, testName, expected, testEnvironmentArg, async, callback); - test.module = config.currentModule; - test.moduleTestEnvironment = config.currentModuleTestEnviroment; - test.queue(); - }, - - /** - * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. - */ - expect: function(asserts) { - config.current.expected = asserts; - }, - - /** - * Asserts true. - * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); - */ - ok: function(a, msg) { - a = !!a; - var details = { - result: a, - message: msg - }; - msg = escapeHtml(msg); - QUnit.log(details); - config.current.assertions.push({ - result: a, - message: msg - }); - }, - - /** - * Checks that the first two arguments are equal, with an optional message. - * Prints out both actual and expected values. - * - * Prefered to ok( actual == expected, message ) - * - * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." ); - * - * @param Object actual - * @param Object expected - * @param String message (optional) - */ - equal: function(actual, expected, message) { - QUnit.push(expected == actual, actual, expected, message); - }, - - notEqual: function(actual, expected, message) { - QUnit.push(expected != actual, actual, expected, message); - }, - - deepEqual: function(actual, expected, message) { - QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); - }, - - notDeepEqual: function(actual, expected, message) { - QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message); - }, - - strictEqual: function(actual, expected, message) { - QUnit.push(expected === actual, actual, expected, message); - }, - - notStrictEqual: function(actual, expected, message) { - QUnit.push(expected !== actual, actual, expected, message); - }, - - raises: function(block, expected, message) { - var actual, ok = false; - - if (typeof expected === 'string') { - message = expected; - expected = null; - } - - try { - block(); - } catch (e) { - actual = e; - } - - if (actual) { - // we don't want to validate thrown error - if (!expected) { - ok = true; - // expected is a regexp - } else if (QUnit.objectType(expected) === "regexp") { - ok = expected.test(actual); - // expected is a constructor - } else if (actual instanceof expected) { - ok = true; - // expected is a validation function which returns true is validation passed - } else if (expected.call({}, actual) === true) { - ok = true; - } - } - - QUnit.ok(ok, message); - }, - - start: function() { - config.semaphore--; - if (config.semaphore > 0) { - // don't start until equal number of stop-calls - return; - } - if (config.semaphore < 0) { - // ignore if start is called more often then stop - config.semaphore = 0; - } - // A slight delay, to avoid any current callbacks - if ( defined.setTimeout ) { - window.setTimeout(function() { - if ( config.timeout ) { - clearTimeout(config.timeout); - } - - config.blocking = false; - process(); - }, 13); - } else { - config.blocking = false; - process(); - } - }, - - stop: function(timeout) { - config.semaphore++; - config.blocking = true; - - if ( timeout && defined.setTimeout ) { - clearTimeout(config.timeout); - config.timeout = window.setTimeout(function() { - QUnit.ok( false, "Test timed out" ); - QUnit.start(); - }, timeout); - } - } - -}; - -// Backwards compatibility, deprecated -QUnit.equals = QUnit.equal; -QUnit.same = QUnit.deepEqual; - -// Maintain internal state -var config = { - // The queue of tests to run - queue: [], - - // block until document ready - blocking: true -}; - -// Load paramaters -(function() { - var location = window.location || { search: "", protocol: "file:" }, - GETParams = location.search.slice(1).split('&'); - - for ( var i = 0; i < GETParams.length; i++ ) { - GETParams[i] = decodeURIComponent( GETParams[i] ); - if ( GETParams[i] === "noglobals" ) { - GETParams.splice( i, 1 ); - i--; - config.noglobals = true; - } else if ( GETParams[i] === "notrycatch" ) { - GETParams.splice( i, 1 ); - i--; - config.notrycatch = true; - } else if ( GETParams[i].search('=') > -1 ) { - GETParams.splice( i, 1 ); - i--; - } - } - - // restrict modules/tests by get parameters - config.filters = GETParams; - - // Figure out if we're running the tests from a server or not - QUnit.isLocal = !!(location.protocol === 'file:'); -})(); - -// Expose the API as global variables, unless an 'exports' -// object exists, in that case we assume we're in CommonJS -if ( typeof exports === "undefined" || typeof require === "undefined" ) { - extend(window, QUnit); - window.QUnit = QUnit; -} else { - extend(exports, QUnit); - exports.QUnit = QUnit; -} - -// define these after exposing globals to keep them in these QUnit namespace only -extend(QUnit, { - config: config, - - // Initialize the configuration options - init: function() { - extend(config, { - stats: { all: 0, bad: 0 }, - moduleStats: { all: 0, bad: 0 }, - started: +new Date, - updateRate: 1000, - blocking: false, - autostart: true, - autorun: false, - filters: [], - queue: [], - semaphore: 0 - }); - - var tests = id("qunit-tests"), - banner = id("qunit-banner"), - result = id("qunit-testresult"); - - if ( tests ) { - tests.innerHTML = ""; - } - - if ( banner ) { - banner.className = ""; - } - - if ( result ) { - result.parentNode.removeChild( result ); - } - }, - - /** - * Resets the test setup. Useful for tests that modify the DOM. - * - * If jQuery is available, uses jQuery's html(), otherwise just innerHTML. - */ - reset: function() { - if ( window.jQuery ) { - jQuery( "#main, #qunit-fixture" ).html( config.fixture ); - } else { - var main = id( 'main' ) || id( 'qunit-fixture' ); - if ( main ) { - main.innerHTML = config.fixture; - } - } - }, - - /** - * Trigger an event on an element. - * - * @example triggerEvent( document.body, "click" ); - * - * @param DOMElement elem - * @param String type - */ - triggerEvent: function( elem, type, event ) { - if ( document.createEvent ) { - event = document.createEvent("MouseEvents"); - event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, - 0, 0, 0, 0, 0, false, false, false, false, 0, null); - elem.dispatchEvent( event ); - - } else if ( elem.fireEvent ) { - elem.fireEvent("on"+type); - } - }, - - // Safe object type checking - is: function( type, obj ) { - return QUnit.objectType( obj ) == type; - }, - - objectType: function( obj ) { - if (typeof obj === "undefined") { - return "undefined"; - - // consider: typeof null === object - } - if (obj === null) { - return "null"; - } - - var type = Object.prototype.toString.call( obj ) - .match(/^\[object\s(.*)\]$/)[1] || ''; - - switch (type) { - case 'Number': - if (isNaN(obj)) { - return "nan"; - } else { - return "number"; - } - case 'String': - case 'Boolean': - case 'Array': - case 'Date': - case 'RegExp': - case 'Function': - return type.toLowerCase(); - } - if (typeof obj === "object") { - return "object"; - } - return undefined; - }, - - push: function(result, actual, expected, message) { - var details = { - result: result, - message: message, - actual: actual, - expected: expected - }; - - message = escapeHtml(message) || (result ? "okay" : "failed"); - message = '' + message + ""; - expected = escapeHtml(QUnit.jsDump.parse(expected)); - actual = escapeHtml(QUnit.jsDump.parse(actual)); - var output = message + ''; - if (actual != expected) { - output += ''; - output += ''; - } - if (!result) { - var source = sourceFromStacktrace(); - if (source) { - details.source = source; - output += ''; - } - } - output += "
          Expected:
          ' + expected + '
          Result:
          ' + actual + '
          Diff:
          ' + QUnit.diff(expected, actual) +'
          Source:
          ' + source +'
          "; - - QUnit.log(details); - - config.current.assertions.push({ - result: !!result, - message: output - }); - }, - - // Logging callbacks; all receive a single argument with the listed properties - // run test/logs.html for any related changes - begin: function() {}, - // done: { failed, passed, total, runtime } - done: function() {}, - // log: { result, actual, expected, message } - log: function() {}, - // testStart: { name } - testStart: function() {}, - // testDone: { name, failed, passed, total } - testDone: function() {}, - // moduleStart: { name } - moduleStart: function() {}, - // moduleDone: { name, failed, passed, total } - moduleDone: function() {} -}); - -if ( typeof document === "undefined" || document.readyState === "complete" ) { - config.autorun = true; -} - -addEvent(window, "load", function() { - QUnit.begin({}); - - // Initialize the config, saving the execution queue - var oldconfig = extend({}, config); - QUnit.init(); - extend(config, oldconfig); - - config.blocking = false; - - var userAgent = id("qunit-userAgent"); - if ( userAgent ) { - userAgent.innerHTML = navigator.userAgent; - } - var banner = id("qunit-header"); - if ( banner ) { - var paramsIndex = location.href.lastIndexOf(location.search); - if ( paramsIndex > -1 ) { - var mainPageLocation = location.href.slice(0, paramsIndex); - if ( mainPageLocation == location.href ) { - banner.innerHTML = ' ' + banner.innerHTML + ' '; - } else { - var testName = decodeURIComponent(location.search.slice(1)); - banner.innerHTML = '' + banner.innerHTML + '' + testName + ''; - } - } - } - - var toolbar = id("qunit-testrunner-toolbar"); - if ( toolbar ) { - var filter = document.createElement("input"); - filter.type = "checkbox"; - filter.id = "qunit-filter-pass"; - addEvent( filter, "click", function() { - var li = document.getElementsByTagName("li"); - for ( var i = 0; i < li.length; i++ ) { - if ( li[i].className.indexOf("pass") > -1 ) { - li[i].style.display = filter.checked ? "none" : ""; - } - } - if ( defined.sessionStorage ) { - sessionStorage.setItem("qunit-filter-passed-tests", filter.checked ? "true" : ""); - } - }); - if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { - filter.checked = true; - } - toolbar.appendChild( filter ); - - var label = document.createElement("label"); - label.setAttribute("for", "qunit-filter-pass"); - label.innerHTML = "Hide passed tests"; - toolbar.appendChild( label ); - } - - var main = id('main') || id('qunit-fixture'); - if ( main ) { - config.fixture = main.innerHTML; - } - - if (config.autostart) { - QUnit.start(); - } -}); - -function done() { - config.autorun = true; - - // Log the last module results - if ( config.currentModule ) { - QUnit.moduleDone( { - name: config.currentModule, - failed: config.moduleStats.bad, - passed: config.moduleStats.all - config.moduleStats.bad, - total: config.moduleStats.all - } ); - } - - var banner = id("qunit-banner"), - tests = id("qunit-tests"), - runtime = +new Date - config.started, - passed = config.stats.all - config.stats.bad, - html = [ - 'Tests completed in ', - runtime, - ' milliseconds.
          ', - '', - passed, - ' tests of ', - config.stats.all, - ' passed, ', - config.stats.bad, - ' failed.' - ].join(''); - - if ( banner ) { - banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass"); - } - - if ( tests ) { - var result = id("qunit-testresult"); - - if ( !result ) { - result = document.createElement("p"); - result.id = "qunit-testresult"; - result.className = "result"; - tests.parentNode.insertBefore( result, tests.nextSibling ); - } - - result.innerHTML = html; - } - - QUnit.done( { - failed: config.stats.bad, - passed: passed, - total: config.stats.all, - runtime: runtime - } ); -} - -function validTest( name ) { - var i = config.filters.length, - run = false; - - if ( !i ) { - return true; - } - - while ( i-- ) { - var filter = config.filters[i], - not = filter.charAt(0) == '!'; - - if ( not ) { - filter = filter.slice(1); - } - - if ( name.indexOf(filter) !== -1 ) { - return !not; - } - - if ( not ) { - run = true; - } - } - - return run; -} - -// so far supports only Firefox, Chrome and Opera (buggy) -// could be extended in the future to use something like https://github.com/csnover/TraceKit -function sourceFromStacktrace() { - try { - throw new Error(); - } catch ( e ) { - if (e.stacktrace) { - // Opera - return e.stacktrace.split("\n")[6]; - } else if (e.stack) { - // Firefox, Chrome - return e.stack.split("\n")[4]; - } - } -} - -function resultDisplayStyle(passed) { - return passed && id("qunit-filter-pass") && id("qunit-filter-pass").checked ? 'none' : ''; -} - -function escapeHtml(s) { - if (!s) { - return ""; - } - s = s + ""; - return s.replace(/[\&"<>\\]/g, function(s) { - switch(s) { - case "&": return "&"; - case "\\": return "\\\\"; - case '"': return '\"'; - case "<": return "<"; - case ">": return ">"; - default: return s; - } - }); -} - -function synchronize( callback ) { - config.queue.push( callback ); - - if ( config.autorun && !config.blocking ) { - process(); - } -} - -function process() { - var start = (new Date()).getTime(); - - while ( config.queue.length && !config.blocking ) { - if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) { - config.queue.shift()(); - } else { - window.setTimeout( process, 13 ); - break; - } - } - if (!config.blocking && !config.queue.length) { - done(); - } -} - -function saveGlobal() { - config.pollution = []; - - if ( config.noglobals ) { - for ( var key in window ) { - config.pollution.push( key ); - } - } -} - -function checkPollution( name ) { - var old = config.pollution; - saveGlobal(); - - var newGlobals = diff( old, config.pollution ); - if ( newGlobals.length > 0 ) { - ok( false, "Introduced global variable(s): " + newGlobals.join(", ") ); - config.current.expected++; - } - - var deletedGlobals = diff( config.pollution, old ); - if ( deletedGlobals.length > 0 ) { - ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") ); - config.current.expected++; - } -} - -// returns a new Array with the elements that are in a but not in b -function diff( a, b ) { - var result = a.slice(); - for ( var i = 0; i < result.length; i++ ) { - for ( var j = 0; j < b.length; j++ ) { - if ( result[i] === b[j] ) { - result.splice(i, 1); - i--; - break; - } - } - } - return result; -} - -function fail(message, exception, callback) { - if ( typeof console !== "undefined" && console.error && console.warn ) { - console.error(message); - console.error(exception); - console.warn(callback.toString()); - - } else if ( window.opera && opera.postError ) { - opera.postError(message, exception, callback.toString); - } -} - -function extend(a, b) { - for ( var prop in b ) { - a[prop] = b[prop]; - } - - return a; -} - -function addEvent(elem, type, fn) { - if ( elem.addEventListener ) { - elem.addEventListener( type, fn, false ); - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, fn ); - } else { - fn(); - } -} - -function id(name) { - return !!(typeof document !== "undefined" && document && document.getElementById) && - document.getElementById( name ); -} - -// Test for equality any JavaScript type. -// Discussions and reference: http://philrathe.com/articles/equiv -// Test suites: http://philrathe.com/tests/equiv -// Author: Philippe Rathé -QUnit.equiv = function () { - - var innerEquiv; // the real equiv function - var callers = []; // stack to decide between skip/abort functions - var parents = []; // stack to avoiding loops from circular referencing - - // Call the o related callback with the given arguments. - function bindCallbacks(o, callbacks, args) { - var prop = QUnit.objectType(o); - if (prop) { - if (QUnit.objectType(callbacks[prop]) === "function") { - return callbacks[prop].apply(callbacks, args); - } else { - return callbacks[prop]; // or undefined - } - } - } - - var callbacks = function () { - - // for string, boolean, number and null - function useStrictEquality(b, a) { - if (b instanceof a.constructor || a instanceof b.constructor) { - // to catch short annotaion VS 'new' annotation of a declaration - // e.g. var i = 1; - // var j = new Number(1); - return a == b; - } else { - return a === b; - } - } - - return { - "string": useStrictEquality, - "boolean": useStrictEquality, - "number": useStrictEquality, - "null": useStrictEquality, - "undefined": useStrictEquality, - - "nan": function (b) { - return isNaN(b); - }, - - "date": function (b, a) { - return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf(); - }, - - "regexp": function (b, a) { - return QUnit.objectType(b) === "regexp" && - a.source === b.source && // the regex itself - a.global === b.global && // and its modifers (gmi) ... - a.ignoreCase === b.ignoreCase && - a.multiline === b.multiline; - }, - - // - skip when the property is a method of an instance (OOP) - // - abort otherwise, - // initial === would have catch identical references anyway - "function": function () { - var caller = callers[callers.length - 1]; - return caller !== Object && - typeof caller !== "undefined"; - }, - - "array": function (b, a) { - var i, j, loop; - var len; - - // b could be an object literal here - if ( ! (QUnit.objectType(b) === "array")) { - return false; - } - - len = a.length; - if (len !== b.length) { // safe and faster - return false; - } - - //track reference to avoid circular references - parents.push(a); - for (i = 0; i < len; i++) { - loop = false; - for(j=0;j= 0) { - type = "array"; - } else { - type = typeof obj; - } - return type; - }, - separator:function() { - return this.multiline ? this.HTML ? '
          ' : '\n' : this.HTML ? ' ' : ' '; - }, - indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing - if ( !this.multiline ) - return ''; - var chr = this.indentChar; - if ( this.HTML ) - chr = chr.replace(/\t/g,' ').replace(/ /g,' '); - return Array( this._depth_ + (extra||0) ).join(chr); - }, - up:function( a ) { - this._depth_ += a || 1; - }, - down:function( a ) { - this._depth_ -= a || 1; - }, - setParser:function( name, parser ) { - this.parsers[name] = parser; - }, - // The next 3 are exposed so you can use them - quote:quote, - literal:literal, - join:join, - // - _depth_: 1, - // This is the list of parsers, to modify them, use jsDump.setParser - parsers:{ - window: '[Window]', - document: '[Document]', - error:'[ERROR]', //when no parser is found, shouldn't happen - unknown: '[Unknown]', - 'null':'null', - undefined:'undefined', - 'function':function( fn ) { - var ret = 'function', - name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE - if ( name ) - ret += ' ' + name; - ret += '('; - - ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join(''); - return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' ); - }, - array: array, - nodelist: array, - arguments: array, - object:function( map ) { - var ret = [ ]; - QUnit.jsDump.up(); - for ( var key in map ) - ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(map[key]) ); - QUnit.jsDump.down(); - return join( '{', ret, '}' ); - }, - node:function( node ) { - var open = QUnit.jsDump.HTML ? '<' : '<', - close = QUnit.jsDump.HTML ? '>' : '>'; - - var tag = node.nodeName.toLowerCase(), - ret = open + tag; - - for ( var a in QUnit.jsDump.DOMAttrs ) { - var val = node[QUnit.jsDump.DOMAttrs[a]]; - if ( val ) - ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' ); - } - return ret + close + open + '/' + tag + close; - }, - functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function - var l = fn.length; - if ( !l ) return ''; - - var args = Array(l); - while ( l-- ) - args[l] = String.fromCharCode(97+l);//97 is 'a' - return ' ' + args.join(', ') + ' '; - }, - key:quote, //object calls it internally, the key part of an item in a map - functionCode:'[code]', //function calls it internally, it's the content of the function - attribute:quote, //node calls it internally, it's an html attribute value - string:quote, - date:quote, - regexp:literal, //regex - number:literal, - 'boolean':literal - }, - DOMAttrs:{//attributes to dump from nodes, name=>realName - id:'id', - name:'name', - 'class':'className' - }, - HTML:false,//if true, entities are escaped ( <, >, \t, space and \n ) - indentChar:' ',//indentation unit - multiline:true //if true, items in a collection, are separated by a \n, else just a space. - }; - - return jsDump; -})(); - -// from Sizzle.js -function getText( elems ) { - var ret = "", elem; - - for ( var i = 0; elems[i]; i++ ) { - elem = elems[i]; - - // Get the text from text nodes and CDATA nodes - if ( elem.nodeType === 3 || elem.nodeType === 4 ) { - ret += elem.nodeValue; - - // Traverse everything else, except comment nodes - } else if ( elem.nodeType !== 8 ) { - ret += getText( elem.childNodes ); - } - } - - return ret; -}; - -/* - * Javascript Diff Algorithm - * By John Resig (http://ejohn.org/) - * Modified by Chu Alan "sprite" - * - * Released under the MIT license. - * - * More Info: - * http://ejohn.org/projects/javascript-diff-algorithm/ - * - * Usage: QUnit.diff(expected, actual) - * - * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick brown fox jumped jumps over" - */ -QUnit.diff = (function() { - function diff(o, n){ - var ns = new Object(); - var os = new Object(); - - for (var i = 0; i < n.length; i++) { - if (ns[n[i]] == null) - ns[n[i]] = { - rows: new Array(), - o: null - }; - ns[n[i]].rows.push(i); - } - - for (var i = 0; i < o.length; i++) { - if (os[o[i]] == null) - os[o[i]] = { - rows: new Array(), - n: null - }; - os[o[i]].rows.push(i); - } - - for (var i in ns) { - if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { - n[ns[i].rows[0]] = { - text: n[ns[i].rows[0]], - row: os[i].rows[0] - }; - o[os[i].rows[0]] = { - text: o[os[i].rows[0]], - row: ns[i].rows[0] - }; - } - } - - for (var i = 0; i < n.length - 1; i++) { - if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && - n[i + 1] == o[n[i].row + 1]) { - n[i + 1] = { - text: n[i + 1], - row: n[i].row + 1 - }; - o[n[i].row + 1] = { - text: o[n[i].row + 1], - row: i + 1 - }; - } - } - - for (var i = n.length - 1; i > 0; i--) { - if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && - n[i - 1] == o[n[i].row - 1]) { - n[i - 1] = { - text: n[i - 1], - row: n[i].row - 1 - }; - o[n[i].row - 1] = { - text: o[n[i].row - 1], - row: i - 1 - }; - } - } - - return { - o: o, - n: n - }; - } - - return function(o, n){ - o = o.replace(/\s+$/, ''); - n = n.replace(/\s+$/, ''); - var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)); - - var str = ""; - - var oSpace = o.match(/\s+/g); - if (oSpace == null) { - oSpace = [" "]; - } - else { - oSpace.push(" "); - } - var nSpace = n.match(/\s+/g); - if (nSpace == null) { - nSpace = [" "]; - } - else { - nSpace.push(" "); - } - - if (out.n.length == 0) { - for (var i = 0; i < out.o.length; i++) { - str += '' + out.o[i] + oSpace[i] + ""; - } - } - else { - if (out.n[0].text == null) { - for (n = 0; n < out.o.length && out.o[n].text == null; n++) { - str += '' + out.o[n] + oSpace[n] + ""; - } - } - - for (var i = 0; i < out.n.length; i++) { - if (out.n[i].text == null) { - str += '' + out.n[i] + nSpace[i] + ""; - } - else { - var pre = ""; - - for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { - pre += '' + out.o[n] + oSpace[n] + ""; - } - str += " " + out.n[i].text + nSpace[i] + pre; - } - } - } - - return str; - }; -})(); - -})(this); - -}}; -__resources__["/__builtin__/libs/util.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -var path = require('path'); - -/** - * @namespace - * Useful utility functions - */ -var util = { - /** - * Merge two or more objects and return the result. - * - * @param {Object} firstObject First object to merge with - * @param {Object} secondObject Second object to merge with - * @param {Object} [...] More objects to merge - * @returns {Object} A new object containing the properties of all the objects passed in - */ - merge: function(firstObject, secondObject) { - var result = {}; - - for (var i = 0; i < arguments.length; i++) { - var obj = arguments[i]; - - for (var x in obj) { - if (!obj.hasOwnProperty(x)) { - continue; - } - - result[x] = obj[x]; - } - }; - - return result; - }, - - /** - * Creates a deep copy of an object - * - * @param {Object} obj The Object to copy - * @returns {Object} A copy of the original Object - */ - copy: function(obj) { - if (obj === null) { - return null; - } - - var copy; - - if (obj instanceof Array) { - copy = []; - for (var i = 0, len = obj.length; i < len; i++) { - copy[i] = arguments.callee(obj[i]); - } - } else if (typeof(obj) == 'object') { - if (typeof(obj.copy) == 'function') { - copy = obj.copy(); - } else { - copy = {}; - - var o, x; - for (x in obj) { - copy[x] = arguments.callee(obj[x]); - } - } - } else { - // Primative type. Doesn't need copying - copy = obj; - } - - return copy; - }, - - /** - * Iterates over an array and calls a function for each item. - * - * @param {Array} arr An Array to iterate over - * @param {Function} func A function to call for each item in the array - * @returns {Array} The original array - */ - each: function(arr, func) { - var i = 0, - len = arr.length; - for (i = 0; i < len; i++) { - func(arr[i], i); - } - - return arr; - }, - - /** - * Iterates over an array, calls a function for each item and returns the results. - * - * @param {Array} arr An Array to iterate over - * @param {Function} func A function to call for each item in the array - * @returns {Array} The return values from each function call - */ - map: function(arr, func) { - var i = 0, - len = arr.length, - result = []; - - for (i = 0; i < len; i++) { - result.push(func(arr[i], i)); - } - - return result; - }, - - extend: function(target, ext) { - if (arguments.length < 2) { - throw "You must provide at least a target and 1 object to extend from" - } - - var i, j, obj, key, val; - - for (i = 1; i < arguments.length; i++) { - obj = arguments[i]; - for (key in obj) { - // Don't copy built-ins - if (!obj.hasOwnProperty(key)) { - continue; - } - - val = obj[key]; - // Don't copy undefineds or references to target (would cause infinite loop) - if (val === undefined || val === target) { - continue; - } - - // Replace existing function and store reference to it in .base - if (val instanceof Function && target[key] && val !== target[key]) { - val.base = target[key]; - val._isProperty = val.base._isProperty; - } - target[key] = val; - - if (val instanceof Function) { - // If this function observes make a reference to it so we can set - // them up when this get instantiated - if (val._observing) { - // Force a COPY of the array or we will probably end up with various - // classes sharing the same one. - if (!target._observingFunctions) { - target._observingFunctions = []; - } else { - target._observingFunctions = target._observingFunctions.slice(0); - } - - - for (j = 0; j' + - '
        2. Sprites
        3. ' + - '
        4. TileMaps
        5. ' + - '
        6. commonJS
        7. ' + - ''; -}; - -}}; -__remote_resources__["/cocos2d/resources/animations/dragon_animation.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/animations/dragon_animation.png"}; -__remote_resources__["/cocos2d/resources/animations/grossini.plist"] = {meta: {mimetype: "application/xml"}, data: "resources/cocos2d/resources/animations/grossini.plist"}; -__remote_resources__["/cocos2d/resources/animations/grossini.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/animations/grossini.png"}; -__remote_resources__["/cocos2d/resources/animations/grossini_blue.plist"] = {meta: {mimetype: "application/xml"}, data: "resources/cocos2d/resources/animations/grossini_blue.plist"}; -__remote_resources__["/cocos2d/resources/animations/grossini_blue.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/animations/grossini_blue.png"}; -__remote_resources__["/cocos2d/resources/animations/grossini_gray.plist"] = {meta: {mimetype: "application/xml"}, data: "resources/cocos2d/resources/animations/grossini_gray.plist"}; -__remote_resources__["/cocos2d/resources/animations/grossini_gray.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/animations/grossini_gray.png"}; -__remote_resources__["/cocos2d/resources/b1.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/b1.png"}; -__remote_resources__["/cocos2d/resources/b2.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/b2.png"}; -__remote_resources__["/cocos2d/resources/f1.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/f1.png"}; -__remote_resources__["/cocos2d/resources/f2.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/f2.png"}; -__remote_resources__["/cocos2d/resources/grossini_dance_atlas-red.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/grossini_dance_atlas-red.png"}; -__remote_resources__["/cocos2d/resources/grossini_dance_atlas.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/grossini_dance_atlas.png"}; -__remote_resources__["/cocos2d/resources/r1.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/r1.png"}; -__remote_resources__["/cocos2d/resources/r2.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/r2.png"}; -__remote_resources__["/cocos2d/resources/TileMaps/fixed-ortho-test2.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/TileMaps/fixed-ortho-test2.png"}; -__remote_resources__["/cocos2d/resources/TileMaps/iso-test.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/TileMaps/iso-test.png"}; -__remote_resources__["/cocos2d/resources/TileMaps/iso-test.tmx"] = {meta: {mimetype: "application/xml"}, data: "resources/cocos2d/resources/TileMaps/iso-test.tmx"}; -__remote_resources__["/cocos2d/resources/TileMaps/ortho-objects.tmx"] = {meta: {mimetype: "application/xml"}, data: "resources/cocos2d/resources/TileMaps/ortho-objects.tmx"}; -__remote_resources__["/cocos2d/resources/TileMaps/ortho-test1.png"] = {meta: {mimetype: "image/png"}, data: "resources/cocos2d/resources/TileMaps/ortho-test1.png"}; -__remote_resources__["/cocos2d/resources/TileMaps/orthogonal-test1.tmx"] = {meta: {mimetype: "application/xml"}, data: "resources/cocos2d/resources/TileMaps/orthogonal-test1.tmx"}; -__remote_resources__["/cocos2d/resources/TileMaps/orthogonal-test1.tsx"] = {meta: {mimetype: "application/xml"}, data: "resources/cocos2d/resources/TileMaps/orthogonal-test1.tsx"}; -__remote_resources__["/cocos2d/resources/TileMaps/orthogonal-test2.tmx"] = {meta: {mimetype: "application/xml"}, data: "resources/cocos2d/resources/TileMaps/orthogonal-test2.tmx"}; -__remote_resources__["/cocos2d/resources/TileMaps/orthogonal-test4.tmx"] = {meta: {mimetype: "application/xml"}, data: "resources/cocos2d/resources/TileMaps/orthogonal-test4.tmx"}; -__resources__["/cocos2d/SpriteTest.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - Texture2D = require('cocos2d/Texture2D').Texture2D, - cocos = require('cocos2d'), - events = require('events'), - nodes = cocos.nodes, - actions = cocos.actions, - geo = require('geometry'), - ccp = geo.ccp; - -var sceneIdx = -1; -var transitions = [ - "Sprite1", - "SpriteBatchNode1", - "SpriteAnchorPoint", - "SpriteColorOpacity", - "SpriteAnimationFlip", - "SpriteZOrder", - "AnimationCache" -]; - -var tests = {}; - -var kTagTileMap = 1, - kTagSpriteBatchNode = 1, - kTagNode = 2, - kTagAnimation1 = 1, - kTagSpriteLeft = 2, - kTagSpriteRight = 3; - -var kTagSprite1 = 1, - kTagSprite2 = 2, - kTagSprite3 = 3, - kTagSprite4 = 4, - kTagSprite5 = 5, - kTagSprite6 = 6, - kTagSprite7 = 7, - kTagSprite8 = 8; - -function nextAction() { - sceneIdx++; - sceneIdx = sceneIdx % transitions.length; - - var r = transitions[sceneIdx]; - return tests[r]; -} -function backAction() { - sceneIdx--; - if (sceneIdx < 0) { - sceneIdx += transitions.length; - } - - var r = transitions[sceneIdx]; - return tests[r]; -} -function restartAction() { - var r = transitions[sceneIdx]; - return tests[r]; -} - -var SpriteDemo = nodes.Layer.extend({ - title: 'No title', - subtitle: null, - - init: function () { - SpriteDemo.superclass.init.call(this); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); - this.addChild({child: label, z: 1}); - label.set('position', ccp(s.width / 2, s.height - 50)); - - - var subtitle = this.get('subtitle'); - if (subtitle) { - var l = nodes.Label.create({string: subtitle, fontName: "Thonburi", fontSize: 16}); - this.addChild({child: l, z: 1}); - l.set('position', ccp(s.width / 2, s.height - 80)); - } - - - var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); - var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); - var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); - - var menu = nodes.Menu.create({items: [item1, item2, item3]}); - - menu.set('position', ccp(0, 0)); - item1.set('position', ccp(s.width / 2 - 100, 30)); - item2.set('position', ccp(s.width / 2, 30)); - item3.set('position', ccp(s.width / 2 + 100, 30)); - this.addChild({child: menu, z: 1}); - }, - - restartCallback: function () { - var director = cocos.Director.get('sharedDirector'); - - var scene = nodes.Scene.create(); - scene.addChild({child: restartAction().create()}); - - director.replaceScene(scene); - }, - - backCallback: function () { - var director = cocos.Director.get('sharedDirector'); - - var scene = nodes.Scene.create(); - scene.addChild({child: backAction().create()}); - - director.replaceScene(scene); - }, - - nextCallback: function () { - var director = cocos.Director.get('sharedDirector'); - - var scene = nodes.Scene.create(); - scene.addChild({child: nextAction().create()}); - - director.replaceScene(scene); - } -}); - -/** - * @class - * - * Example Sprite 1 - */ -tests.Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ - title: 'Sprite', - subtitle: 'Click screen', - - init: function () { - tests.Sprite1.superclass.init.call(this); - - this.set('isMouseEnabled', true); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - this.addNewSprite(ccp(s.width / 2, s.height / 2)); - }, - - addNewSprite: function (point) { - var idx = Math.floor(Math.random() * 1400 / 100), - x = (idx % 5) * 85, - y = (idx % 3) * 121; - - var sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: new geo.Rect(x, y, 85, 121)}); - this.addChild({child: sprite, z: 0}); - sprite.set('position', ccp(point.x, point.y)); - - var action, actionBack, seq; - var rand = Math.random(); - - if (rand < 0.2) { - action = actions.ScaleBy.create({duration: 3, scale: 2}); - } else if (rand < 0.4) { - action = actions.RotateBy.create({duration: 3, angle: 360}); - } else if (rand < 0.6) { - action = actions.ScaleBy.create({duration: 3, scale: 2}); - //action = cocos.Blink.create({duration:3, scale:2}); - } else if (rand < 0.8) { - action = actions.RotateBy.create({duration: 3, angle: 360}); - //action = cocos.TintBy.create({duration:3, scale:2}); - } else { - action = actions.ScaleBy.create({duration: 3, scale: 2}); - //action = cocos.FadeOut.create({duration:3, scale:2}); - } - - - - - actionBack = action.reverse(); - seq = actions.Sequence.create({actions: [action, actionBack]}); - sprite.runAction(actions.RepeatForever.create(seq)); - - }, - mouseUp: function (event) { - var location = cocos.Director.get('sharedDirector').convertEventToCanvas(event); - this.addNewSprite(location); - - return true; - } -}); - - -/** - * @class - * - * Example SpriteBatchNode 1 - */ -tests.SpriteBatchNode1 = SpriteDemo.extend(/** @lends SpriteBatchNode1.prototype# */{ - title: 'SpriteBatchNode', - subtitle: 'Click screen', - - init: function () { - tests.SpriteBatchNode1.superclass.init.call(this); - - this.set('isMouseEnabled', true); - - var batch = nodes.SpriteBatchNode.create({file: module.dirname + "/resources/grossini_dance_atlas.png", size: geo.sizeMake(480, 320)}); - this.addChild({child: batch, z: 0, tag: kTagSpriteBatchNode}); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - this.addNewSprite(ccp(s.width / 2, s.height / 2)); - }, - - addNewSprite: function (point) { - var batch = this.getChild({tag: kTagSpriteBatchNode}); - - var idx = Math.floor(Math.random() * 1400 / 100), - x = (idx % 5) * 85, - y = (idx % 3) * 121; - - var sprite = nodes.Sprite.create({textureAtlas: batch.get('textureAtlas'), rect: geo.rectMake(x, y, 85, 121)}); - batch.addChild({child: sprite}); - - sprite.set('position', ccp(point.x, point.y)); - - var action, actionBack, seq; - var rand = Math.random(); - - if (rand < 0.2) { - action = actions.ScaleBy.create({duration: 3, scale: 2}); - } else if (rand < 0.4) { - action = actions.RotateBy.create({duration: 3, angle: 360}); - } else if (rand < 0.6) { - action = actions.ScaleBy.create({duration: 3, scale: 2}); - //action = cocos.Blink.create({duration:3, scale:2}); - } else if (rand < 0.8) { - action = actions.RotateBy.create({duration: 3, angle: 360}); - //action = cocos.TintBy.create({duration:3, scale:2}); - } else { - action = actions.ScaleBy.create({duration: 3, scale: 2}); - //action = cocos.FadeOut.create({duration: 3, scale: 2}); - } - - actionBack = action.reverse(); - seq = actions.Sequence.create({actions: [action, actionBack]}); - sprite.runAction(actions.RepeatForever.create(seq)); - }, - mouseUp: function (event) { - - var location = cocos.Director.get('sharedDirector').convertEventToCanvas(event); - this.addNewSprite(location); - - return true; - } -}); - - -/** - * @class - * - * Example Sprite Animation and flip - */ -tests.SpriteAnimationFlip = SpriteDemo.extend(/** @lends SpriteAnimationFlip.prototype# */{ - title: 'Sprite Animation + Flip', - - init: function () { - tests.SpriteAnimationFlip.superclass.init.call(this); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - var texture = Texture2D.create({file: module.dirname + "/resources/animations/dragon_animation.png"}); - - var frame0 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 0, 132 * 0, 132, 132)}), - frame1 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 1, 132 * 0, 132, 132)}), - frame2 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 2, 132 * 0, 132, 132)}), - frame3 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 3, 132 * 0, 132, 132)}), - frame4 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 0, 132 * 1, 132, 132)}), - frame5 = cocos.SpriteFrame.create({texture: texture, rect: geo.rectMake(132 * 1, 132 * 1, 132, 132)}); - - - var sprite = nodes.Sprite.create({frame: frame0}); - sprite.set('position', ccp(s.width / 2 - 80, s.height / 2)); - this.addChild(sprite); - - var animFrames = [ - frame0, - frame1, - frame2, - frame3, - frame4, - frame5 - ]; - - - var animation = cocos.Animation.create({frames: animFrames, delay: 0.2}), - animate = actions.Animate.create({animation: animation, restoreOriginalFrame: false}), - seq = actions.Sequence.create({actions: [animate, - actions.FlipX.create({flipX: true}), - animate.copy(), - actions.FlipX.create({flipX: false})]}); - - sprite.runAction(actions.RepeatForever.create(seq)); - } -}); - -/** - * @class - * - * Example Sprite Anchor Point - */ -tests.SpriteAnchorPoint = SpriteDemo.extend(/** @lends SpriteAnchorPoint.prototype# */{ - title: 'Sprite Anchor Point', - - init: function () { - tests.SpriteAnchorPoint.superclass.init.call(this); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - var rotate = actions.RotateBy.create({duration: 10, angle: 360}); - var action = actions.RepeatForever.create(rotate); - for (var i = 0; i < 3; i++) { - var sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * i, 121 * 1, 85, 121)}); - sprite.position = ccp(s.width / 4 * (i + 1), s.height / 2); - - var point = nodes.Sprite.create({file: module.dirname + "/resources/r1.png"}); - point.set('scale', 0.25); - point.set('position', sprite.get('position')); - this.addChild({child: point, z: 10}); - - switch (i) { - case 0: - sprite.set('anchorPoint', ccp(0, 0)); - break; - case 1: - sprite.set('anchorPoint', ccp(0.5, 0.5)); - break; - case 2: - sprite.set('anchorPoint', ccp(1, 1)); - break; - } - - point.set('position', sprite.get('position')); - - var copy = action.copy(); - sprite.runAction(copy); - this.addChild({child: sprite, z: 1}); - } - } -}); - - -/** - * @class - * - * Example Sprite Z ORder - */ -tests.SpriteZOrder = SpriteDemo.extend(/** @lends SpriteZOrder.prototype# */{ - title: 'Sprite Z Order', - dir: 1, - - init: function () { - tests.SpriteZOrder.superclass.init.call(this); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - var i; - var step = s.width / 11; - var sprite; - for (i = 0; i < 5; i++) { - sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 0, 121 * 1, 85, 121)}); - sprite.set('position', ccp((i + 1) * step, s.height / 2)); - this.addChild({child: sprite, z: i}); - } - - for (i = 5; i < 10; i++) { - sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 1, 121 * 0, 85, 121)}); - sprite.set('position', ccp((i + 1) * step, s.height / 2)); - this.addChild({child: sprite, z: 14 - i}); - } - - sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas-red.png", rect: geo.rectMake(85 * 3, 121 * 0, 85, 121)}); - this.addChild({child: sprite, z: -1, tag: kTagSprite1}); - - sprite.set('position', ccp(s.width / 2, s.height / 2 + 20)); - sprite.set('scaleX', 6); - - cocos.Scheduler.get('sharedScheduler').schedule({target: this, method: this.reorderSprite, interval: 1}); - }, - reorderSprite: function (dt) { - var sprite = this.getChild({tag: kTagSprite1}); - var z = sprite.get('zOrder'); - - if (z < -1) { - this.dir = 1; - } - if (z > 10) { - this.dir = -1; - } - - z += this.dir * 3; - - this.reorderChild({child: sprite, z: z}); - } -}); - -/** - * @class - * - * Example using AnimationCache and loading from a Zwoptex .plist file - */ -tests.AnimationCache = SpriteDemo.extend(/** @lends AnimationCache.prototype# */{ - title: 'AnimationCache', - subtitle: 'Sprite should be animated', - - init: function () { - tests.AnimationCache.superclass.init.call(this); - - var frameCache = cocos.SpriteFrameCache.get('sharedSpriteFrameCache'), - animCache = cocos.AnimationCache.get('sharedAnimationCache'); - - frameCache.addSpriteFrames({file: module.dirname + '/resources/animations/grossini.plist'}); - frameCache.addSpriteFrames({file: module.dirname + '/resources/animations/grossini_gray.plist'}); - frameCache.addSpriteFrames({file: module.dirname + '/resources/animations/grossini_blue.plist'}); - - - // create "dance" animation - var animFrames = [], - frame, - i; - for (i = 1; i < 15; i++) { - frame = frameCache.getSpriteFrame({name: 'grossini_dance_' + (i >= 10 ? i : '0' + i) + '.png'}); - animFrames.push(frame); - } - - var animation = cocos.Animation.create({frames: animFrames, delay: 0.2}); - - // Add an animation to the Cache - animCache.addAnimation({animation: animation, name: 'dance'}); - - - // create animation "dance gray" - animFrames = []; - for (i = 1; i < 15; i++) { - frame = frameCache.getSpriteFrame({name: 'grossini_dance_gray_' + (i >= 10 ? i : '0' + i) + '.png'}); - animFrames.push(frame); - } - - animation = cocos.Animation.create({frames: animFrames, delay: 0.2}); - - // Add an animation to the Cache - animCache.addAnimation({animation: animation, name: 'dance_gray'}); - - - // create animation "dance blue" - animFrames = []; - for (i = 1; i < 4; i++) { - frame = frameCache.getSpriteFrame({name: 'grossini_blue_0' + i + '.png'}); - animFrames.push(frame); - } - - animation = cocos.Animation.create({frames: animFrames, delay: 0.2}); - - // Add an animation to the Cache - animCache.addAnimation({animation: animation, name: 'dance_blue'}); - - - var normal = animCache.getAnimation({name: 'dance'}), - dance_gray = animCache.getAnimation({name: 'dance_gray'}), - dance_blue = animCache.getAnimation({name: 'dance_blue'}); - - var animN = actions.Animate.create({animation: normal}), - animG = actions.Animate.create({animation: dance_gray}), - animB = actions.Animate.create({animation: dance_blue}); - - var seq = actions.Sequence.create({actions: [animN, animG, animB]}); - - // create an sprite without texture - var grossini = nodes.Sprite.create(); - - var winSize = cocos.Director.get('sharedDirector').get('winSize'); - - grossini.set('position', ccp(winSize.width / 2, winSize.height / 2)); - - this.addChild({child: grossini}); - - - // run the animation - grossini.runAction(seq); - } -}); - -tests.SpriteColorOpacity = SpriteDemo.extend(/** @lends SpriteColorOpacity.prototype# */{ - title: "Sprite: Opacity", - - init: function () { - tests.SpriteColorOpacity.superclass.init.call(this); - - - var sprite1 = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 0, 121 * 1, 85, 121)}); - var sprite2 = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 1, 121 * 1, 85, 121)}); - var sprite3 = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 2, 121 * 1, 85, 121)}); - var sprite4 = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 3, 121 * 1, 85, 121)}); - - var sprite5 = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 0, 121 * 1, 85, 121)}); - var sprite6 = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 1, 121 * 1, 85, 121)}); - var sprite7 = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 2, 121 * 1, 85, 121)}); - var sprite8 = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: geo.rectMake(85 * 3, 121 * 1, 85, 121)}); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - sprite1.set('position', ccp((s.width / 5) * 1, (s.height / 3) * 1)); - sprite2.set('position', ccp((s.width / 5) * 2, (s.height / 3) * 1)); - sprite3.set('position', ccp((s.width / 5) * 3, (s.height / 3) * 1)); - sprite4.set('position', ccp((s.width / 5) * 4, (s.height / 3) * 1)); - - sprite5.set('position', ccp((s.width / 5) * 1, (s.height / 3) * 2)); - sprite6.set('position', ccp((s.width / 5) * 2, (s.height / 3) * 2)); - sprite7.set('position', ccp((s.width / 5) * 3, (s.height / 3) * 2)); - sprite8.set('position', ccp((s.width / 5) * 4, (s.height / 3) * 2)); - - var action = actions.FadeIn.create({duration: 3}), - actionBack = action.reverse(), - fade = actions.RepeatForever.create(actions.Sequence.create({actions: [action, actionBack]})); - - /* - id tintred = [CCTintBy actionWithDuration:2 red:0 green:-255 blue:-255]; - id tintred_back = [tintred reverse]; - id red = [CCRepeatForever actionWithAction: [CCSequence actions: tintred, tintred_back, nil]]; - - id tintgreen = [CCTintBy actionWithDuration:2 red:-255 green:0 blue:-255]; - id tintgreen_back = [tintgreen reverse]; - id green = [CCRepeatForever actionWithAction: [CCSequence actions: tintgreen, tintgreen_back, nil]]; - - id tintblue = [CCTintBy actionWithDuration:2 red:-255 green:-255 blue:0]; - id tintblue_back = [tintblue reverse]; - id blue = [CCRepeatForever actionWithAction: [CCSequence actions: tintblue, tintblue_back, nil]]; - */ - - - /* - [sprite5 runAction:red]; - [sprite6 runAction:green]; - [sprite7 runAction:blue]; - */ - sprite8.runAction(fade); - - // late add: test dirtyColor and dirtyPosition - this.addChild({child: sprite1, z: 0, tag: kTagSprite1}); - this.addChild({child: sprite2, z: 0, tag: kTagSprite2}); - this.addChild({child: sprite3, z: 0, tag: kTagSprite3}); - this.addChild({child: sprite4, z: 0, tag: kTagSprite4}); - this.addChild({child: sprite5, z: 0, tag: kTagSprite5}); - this.addChild({child: sprite6, z: 0, tag: kTagSprite6}); - this.addChild({child: sprite7, z: 0, tag: kTagSprite7}); - this.addChild({child: sprite8, z: 0, tag: kTagSprite8}); - - - cocos.Scheduler.get('sharedScheduler').schedule({target: this, method: this.removeAndAddSprite, interval: 2}); - }, - - removeAndAddSprite: function () { - var sprite = this.getChild({tag: kTagSprite5}); - - this.removeChild({child: sprite, cleanup: false}); - this.addChild({child: sprite, z: 0, tag: kTagSprite5}); - } -}); - - -exports.main = function () { - // Initialise test - var director = cocos.Director.get('sharedDirector'); - - director.attachInView(document.getElementById('cocos2d-tests')); - director.set('displayFPS', true); - - events.addListener(director, 'ready', function (director) { - var scene = nodes.Scene.create(); - scene.addChild({child: nextAction().create()}); - director.replaceScene(scene); - }); - - director.runPreloadScene(); -}; - -}}; -__resources__["/cocos2d/TileMapTest.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require FLIP_Y_AXIS console*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - Texture2D = require('cocos2d/Texture2D').Texture2D, - cocos = require('cocos2d'), - nodes = cocos.nodes, - events = require('events'), - actions = cocos.actions, - geo = require('geometry'), - ccp = geo.ccp; - -var sceneIdx = -1; -var transitions = [ - "TMXReadWriteTest", - "TMXOrthoTest2", - "TMXOrthoObjectsTest", - "TMXIsoTest" -]; - -var tests = {}; - - -var kTagTileMap = 1; - -function nextAction() { - sceneIdx++; - sceneIdx = sceneIdx % transitions.length; - - var r = transitions[sceneIdx]; - return tests[r]; -} -function backAction() { - sceneIdx--; - if (sceneIdx < 0) { - sceneIdx += transitions.length; - } - - var r = transitions[sceneIdx]; - return tests[r]; -} -function restartAction() { - var r = transitions[sceneIdx]; - return tests[r]; -} - -var TileDemo = nodes.Layer.extend({ - title: 'No title', - subtitle: null, - - init: function () { - TileDemo.superclass.init.call(this); - - this.set('isMouseEnabled', true); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); - this.addChild({child: label, z: 1}); - label.set('position', ccp(s.width / 2, s.height - 50)); - - - var subtitle = this.get('subtitle'); - if (subtitle) { - var l = nodes.Label.create({string: subtitle, fontName: "Thonburi", fontSize: 16}); - this.addChild({child: l, z: 1}); - l.set('position', ccp(s.width / 2, s.height - 80)); - } - - - var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); - var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); - var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); - - var menu = nodes.Menu.create({items: [item1, item2, item3]}); - - menu.set('position', ccp(0, 0)); - item1.set('position', ccp(s.width / 2 - 100, 30)); - item2.set('position', ccp(s.width / 2, 30)); - item3.set('position', ccp(s.width / 2 + 100, 30)); - this.addChild({child: menu, z: 1}); - }, - - mouseDragged: function (event) { - var node = this.getChild({tag: kTagTileMap}); - var currentPos = node.get('position'); - node.set('position', geo.ccpAdd(currentPos, ccp(event.deltaX, event.deltaY))); - return true; - }, - - restartCallback: function () { - var director = cocos.Director.get('sharedDirector'); - - var scene = nodes.Scene.create(); - scene.addChild({child: restartAction().create()}); - - director.replaceScene(scene); - }, - - backCallback: function () { - var director = cocos.Director.get('sharedDirector'); - - var scene = nodes.Scene.create(); - scene.addChild({child: backAction().create()}); - - director.replaceScene(scene); - }, - - nextCallback: function () { - var director = cocos.Director.get('sharedDirector'); - - var scene = nodes.Scene.create(); - scene.addChild({child: nextAction().create()}); - - director.replaceScene(scene); - } -}); - - -tests.TMXOrthoTest2 = TileDemo.extend({ - title: 'Tile Map Test', - subtitle: 'drag screen', - - init: function () { - tests.TMXOrthoTest2.superclass.init.call(this); - - var map = nodes.TMXTiledMap.create({file: module.dirname + "/resources/TileMaps/orthogonal-test1.tmx"}); - this.addChild({child: map, z: 0, tag: kTagTileMap}); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - map.runAction(actions.ScaleBy.create({duration: 2, scale: 0.5})); - } -}); - - -tests.TMXIsoTest = TileDemo.extend({ - title: 'TMX Isometric test 0', - - init: function () { - tests.TMXIsoTest.superclass.init.call(this); - - /* - CCLayerColor *color = [CCLayerColor layerWithColor:ccc4(64,64,64,255)]; - [self addChild:color z:-1]; - */ - - var map = nodes.TMXTiledMap.create({file: module.dirname + "/resources/TileMaps/iso-test.tmx"}); - this.addChild({child: map, z: 0, tag: kTagTileMap}); - - // move map to the center of the screen - var ms = map.get('mapSize'), - ts = map.get('tileSize'); - - map.set('position', ccp(-ms.width * ts.width / 2, -ms.height * ts.height / 2)); - - //map.runAction(actions.MoveTo.create({duration: 1.0, position: ccp(-ms.width * ts.width / 2, -ms.height * ts.height / 2)})); - } -}); - -tests.TMXOrthoObjectsTest = TileDemo.extend({ - title: 'TMX Ortho object test', - subtitle: 'You should see a white box around the 3 platforms', - - init: function () { - tests.TMXOrthoObjectsTest.superclass.init.call(this); - - var map = nodes.TMXTiledMap.create({file: module.dirname + "/resources/TileMaps/ortho-objects.tmx"}); - this.addChild({child: map, z: -1, tag: kTagTileMap}); - - var s = map.get('contentSize'); - - console.log("ContentSize: %f, %f", s.width, s.height); - console.log("----> Iterating over all the group objects"); - - var group = map.getObjectGroup({name: 'Object Group 1'}), - objs = group.get('objects'); - for (var i = 0, len = objs.length; i < len; i++) { - var obj = objs[i]; - console.log("Object: ", obj); - } - - console.log("----> Fetching 1 object by name"); - var platform = group.getObject({name: "platform"}); - console.log("platform: ", platform); - }, - - draw: function (ctx) { - var map = this.getChild({tag: kTagTileMap}), - group = map.getObjectGroup({name: 'Object Group 1'}), - objs = group.get('objects'); - - ctx.save(); - ctx.strokeStyle = '#fff'; - ctx.lineWidth = 3; - ctx.beginPath(); - - if (FLIP_Y_AXIS) { - ctx.scale(1, -1); - ctx.translate(0, -1024); - } - - for (var i = 0, len = objs.length; i < len; i++) { - var obj = objs[i]; - - var x = obj.x, - y = obj.y, - width = obj.width, - height = obj.height; - - ctx.moveTo(x, y); - ctx.lineTo(x + width, y); - ctx.lineTo(x + width, y + height); - ctx.lineTo(x, y + height); - ctx.lineTo(x, y); - } - ctx.closePath(); - ctx.stroke(); - ctx.restore(); - } -}); - -tests.TMXReadWriteTest = TileDemo.extend({ - title: 'TMX Read/Write test', - - init: function () { - tests.TMXReadWriteTest.superclass.init.call(this); - - var map = nodes.TMXTiledMap.create({file: module.dirname + "/resources/TileMaps/orthogonal-test2.tmx"}); - this.addChild({child: map, z: 0, tag: kTagTileMap}); - - - var s = map.get('contentSize'); - console.log("ContentSize: %f, %f", s.width, s.height); - - - var layer = map.getLayer({name: "Layer 0"}); - var tile0 = layer.tileAt(ccp(1, 63)), - tile1 = layer.tileAt(ccp(2, 63)), - tile2 = layer.tileAt(ccp(2, 62)); - - - tile0.set('anchorPoint', ccp(0.5, 0.5)); - tile1.set('anchorPoint', ccp(0.5, 0.5)); - tile2.set('anchorPoint', ccp(0.5, 0.5)); - - var move = actions.MoveBy.create({duration: 0.5, position: ccp(0, 160)}), - rotate = actions.RotateBy.create({duration: 2.0, angle: 360}), - scale = actions.ScaleBy.create({duration: 2.0, scale: 5}); - - - var seq0 = actions.Sequence.create({actions: [move, rotate, scale]}), /*, scale, opacity, fadein, scaleback, finish, nil];*/ - seq1 = seq0.copy(), - seq2 = seq0.copy(); - - tile0.runAction(seq0); - tile1.runAction(seq1); - tile2.runAction(seq2); - - } -}); - - -exports.main = function () { - // Initialise test - var director = cocos.Director.get('sharedDirector'); - - director.attachInView(document.getElementById('cocos2d-tests')); - director.set('displayFPS', true); - - events.addListener(director, 'ready', function (director) { - var scene = nodes.Scene.create(); - scene.addChild({child: nextAction().create()}); - - director.replaceScene(scene); - }); - - director.runPreloadScene(); -}; - -}}; -__resources__["/cocos2d/TransitionTest.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require FLIP_Y_AXIS console*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var util = require('util'), - Texture2D = require('cocos2d/Texture2D').Texture2D, - cocos = require('cocos2d'), - nodes = cocos.nodes, - events = require('events'), - actions = cocos.actions, - geo = require('geometry'), - ccp = geo.ccp; - -var sceneIdx = -1; -var transitions = [ - "TransitionRotoZoom", - "TransitionMoveInLTest", - "TransitionMoveInRTest", - "TransitionMoveInTTest", - "TransitionMoveInBTest", - "TransitionSlideInLTest", - "TransitionSlideInRTest", - "TransitionSlideInTTest", - "TransitionSlideInBTest"]; -var transObjects = [ - cocos.nodes.TransitionRotoZoom, - cocos.nodes.TransitionMoveInL, - cocos.nodes.TransitionMoveInR, - cocos.nodes.TransitionMoveInT, - cocos.nodes.TransitionMoveInB, - cocos.nodes.TransitionSlideInL, - cocos.nodes.TransitionSlideInR, - cocos.nodes.TransitionSlideInT, - cocos.nodes.TransitionSlideInB]; -var tests = {}; - -function nextAction() { - sceneIdx++; - sceneIdx = sceneIdx % transitions.length; - - var r = transitions[sceneIdx]; - return tests[r]; -} - -function backAction() { - sceneIdx--; - if (sceneIdx < 0) { - sceneIdx += transitions.length; - } - - var r = transitions[sceneIdx]; - return tests[r]; -} - - -function restartAction() { - var r = transitions[sceneIdx]; - return tests[r]; -} - - -var TransitionDemo = nodes.Layer.extend({ - title: '', - subtitle: null, - - init: function() { - TransitionDemo.superclass.init.call(this); - - this.set('isMouseEnabled', true); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - var label = nodes.Label.create({ - string: this.get('title'), - fontName: 'Arial', - fontSize: 26 - }); - this.addChild({ - child: label, - z: 1 - }); - label.set('position', ccp(s.width / 2, s.height - 50)); - - var subtitle = this.get('subtitle'); - if (subtitle) { - var l = nodes.Label.create({ - string: subtitle, - fontName: "Thonburi", - fontSize: 16 - }); - this.addChild({ - child: l, - z: 1 - }); - l.set('position', ccp(s.width / 2, s.height - 80)); - } - - var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); - var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); - var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); - - var menu = nodes.Menu.create({items: [item1, item2, item3]}); - - menu.set('position', ccp(0, 0)); - item1.set('position', ccp(s.width / 2 - 100, 30)); - item2.set('position', ccp(s.width / 2, 30)); - item3.set('position', ccp(s.width / 2 + 100, 30)); - this.addChild({child: menu, z: 1}); - }, - - restartCallback: function() { - var director = cocos.Director.get('sharedDirector'); - - var scene = nodes.Scene.create(); - scene.addChild({ - child: restartAction().create() - }); - - director.replaceScene(scene); - }, - - backCallback: function() { - var director = cocos.Director.get('sharedDirector'); - - var scene = nodes.Scene.create(); - scene.addChild({ - child: backAction().create() - }); - - director.replaceScene(transObjects[sceneIdx].create({duration: 1.5, - scene: scene})); - }, - - nextCallback: function() { - var director = cocos.Director.get('sharedDirector'); - var scene = nodes.Scene.create(); - scene.addChild({ - child: nextAction().create() - }); - var transIdx = (sceneIdx === 0) ? transObjects.length-1 : sceneIdx-1; - director.replaceScene(transObjects[transIdx].create({duration: 1.5, - scene: scene})); - } - -}); - - -tests.TransitionRotoZoomTest = TransitionDemo.extend({ - title: 'TransitionRotoZoom Test', - subtitle: 'rotates and zooms next scene', - - init: function() { - tests.TransitionRotoZoomTest.superclass.init.call(this); - } -}); - -tests.TransitionMoveInLTest = TransitionDemo.extend({ - title: 'TransitionMoveInL Test', - subtitle: 'next scene moves in from the left', - - init: function() { - tests.TransitionMoveInLTest.superclass.init.call(this); - } -}); - -tests.TransitionMoveInRTest = TransitionDemo.extend({ - title: 'TransitionMoveInR Test', - subtitle: 'next scene moves in from the right', - - init: function() { - tests.TransitionMoveInLTest.superclass.init.call(this); - } -}); - -tests.TransitionMoveInTTest = TransitionDemo.extend({ - title: 'TransitionMoveInT Test', - subtitle: 'next scene moves in from the top', - - init: function() { - tests.TransitionMoveInTTest.superclass.init.call(this); - } -}); - -tests.TransitionMoveInBTest = TransitionDemo.extend({ - title: 'TransitionMoveInB Test', - subtitle: 'next scene moves in from the bottom', - - init: function() { - tests.TransitionMoveInBTest.superclass.init.call(this); - } -}); - -tests.TransitionSlideInLTest = TransitionDemo.extend({ - title: 'TransitionSlideInL Test', - subtitle: 'next scene pans in from the left', - - init: function() { - tests.TransitionSlideInLTest.superclass.init.call(this); - } -}); - -tests.TransitionSlideInRTest = TransitionDemo.extend({ - title: 'TransitionSlideInR Test', - subtitle: 'next scene pans in from the right', - - init: function() { - tests.TransitionSlideInRTest.superclass.init.call(this); - } -}); - -tests.TransitionSlideInTTest = TransitionDemo.extend({ - title: 'TransitionSlideInT Test', - subtitle: 'next scene slides in from the top', - - init: function() { - tests.TransitionSlideInTTest.superclass.init.call(this); - } -}); - -tests.TransitionSlideInBTest = TransitionDemo.extend({ - title: 'TransitionSlideInB Test', - subtitle: 'next scene slides in from the bottom', - - init: function() { - tests.TransitionSlideInBTest.superclass.init.call(this); - } -}); - -exports.main = function() { - // Initialise test - var director = cocos.Director.get('sharedDirector'); - - director.attachInView(document.getElementById('cocos2d-tests')); - director.set('displayFPS', true); - - events.addListener(director, 'ready', function(director) { - var scene = nodes.Scene.create(); - scene.addChild({ - child: nextAction().create() - }); - director.replaceScene(scene); - }); - - director.runPreloadScene(); -}; - -}}; -__resources__["/commonjs.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require window*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var container = document.getElementById('cocos2d-tests'); -container.className = 'logs'; - -var logNum = 0; -window.print = function (msg, tag) { - logNum++; - var div = document.createElement('div'); - div.appendChild(document.createTextNode(logNum + '. ' + msg)); - div.className = 'log ' + tag; - container.appendChild(div); - container.scrollTop = container.offsetHeight; -}; - -while (container.firstChild) { - container.removeChild(container.firstChild); -} - -var tests = [ - '/commonjs/modules/1.0/absolute', - '/commonjs/modules/1.0/cyclic', - '/commonjs/modules/1.0/determinism', - '/commonjs/modules/1.0/exactExports', - '/commonjs/modules/1.0/hasOwnProperty', - '/commonjs/modules/1.0/method', - '/commonjs/modules/1.0/missing', - '/commonjs/modules/1.0/monkeys', - '/commonjs/modules/1.0/nested', - '/commonjs/modules/1.0/relative', - '/commonjs/modules/1.0/transitive' -]; - -var i = 0; -function nextTest() { - var test = tests[i]; - require.paths.push(test); - require('program'); - require.paths.splice(require.paths.indexOf(test), 1); - i++; - if (i < tests.length) { - setTimeout(nextTest, 250); - } -} -nextTest(); - -}}; -__resources__["/main.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require window*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var params = window.location.search; -if (params) { - var mod = params.split('=')[1]; - require('./' + mod).main(); -} else { - var c = document.getElementById('cocos2d-tests'); - c.style.textAlign = 'center'; - c.style.fontSize = '20pt'; - c.style.lineHeight = c.clientHeight + 'px'; - while (c.firstChild) { - c.removeChild(c.firstChild); - } - c.appendChild(document.createTextNode('Select a test to run')); -} - -}}; -__resources__["/qunit.js"] = {meta: {mimetype: "application/javascript"}, data: function(exports, require, module, __filename, __dirname) { -/*globals module exports resource require*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -var q = require('qunit'); - -q.test("a basic test example", function () { - q.ok(true, "this test is fine"); - var value = "hello"; - q.equals("hello", value, "We expect value to be hello"); -}); - -q.module("Module A"); - -q.test("first test within module", function () { - q.ok(true, "all pass"); -}); - -q.test("second test within module", function () { - q.ok(true, "all pass"); -}); - -q.module("Module B"); - -q.test("some other test", function () { - q.expect(2); - q.equals(true, false, "failing test"); - q.equals(true, true, "passing test"); -}); - -}};/*globals module exports resource require window Module __main_module_name__ __resources__*/ -/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ -"use strict"; - -function resource(path) { - // Check for packed resource - var r = __resources__[path]; - if (r) { - return r.data; - } - - // Check for remote resource - r = __remote_resources__[path]; - if (r) { - // Load remote image - if (r.meta.mimetype.split('/')[0] == 'image') { - return require('cocos2d').RemoteImage.create({url: r.data, path: path}); - } else { - return require('cocos2d').RemoteResource.create({url: r.data, path: path}); - } - } - - throw("Unable to find resource: " + path.toString()); -} - -(function () { - var process = {}; - var modulePaths = ['/__builtin__', '/__builtin__/libs', '/libs', '/']; - - var path; // Will be loaded further down - - function resolveModulePath(request, parent) { - // If not a relative path then search the modulePaths for it - var start = request.substring(0, 2); - if (start !== "./" && start !== "..") { - return modulePaths; - } - - var parentIsIndex = path.basename(parent.filename).match(/^index\.js$/), - parentPath = parentIsIndex ? parent.id : path.dirname(parent.id); - - // Relative path so searching inside parent's directory - return [path.dirname(parent.filename)]; - } - - function findModulePath(id, dirs) { - if (id.charAt(0) === '/') { - dirs = ['']; - } - for (var i = 0; i < dirs.length; i++) { - var dir = dirs[i]; - var p = path.join(dir, id); - - // Check for index first - if (path.exists(path.join(p, 'index.js'))) { - return path.join(p, 'index.js'); - } else if (path.exists(p + '.js')) { - return p + '.js'; - } - } - - return false; - } - - function loadModule(request, parent) { - parent = parent || process.mainModule; - - var paths = resolveModulePath(request, parent), - filename = findModulePath(request, paths); - - if (filename === false) { - throw "Unable to find module: " + request; - } - - - if (parent) { - var cachedModule = parent.moduleCache[filename]; - if (cachedModule) { - return cachedModule; - } - } - - //console.log('Loading module: ', filename); - - var module = new Module(filename, parent); - - // Assign main module to process - if (request == __main_module_name__ && !process.mainModule) { - process.mainModule = module; - } - - // Run all the code in the module - module._initialize(filename); - - return module; - } - - function Module(id, parent) { - this.id = id; - this.parent = parent; - this.children = []; - this.exports = {}; - - if (parent) { - this.moduleCache = parent.moduleCache; - parent.children.push(this); - } else { - this.moduleCache = {}; - } - this.moduleCache[this.id] = this; - - this.filename = null; - this.dirname = null; - } - - Module.prototype._initialize = function (filename) { - var module = this; - function require(request) { - return loadModule(request, module).exports; - } - - this.filename = filename; - - // Work around incase this IS the path module - if (path) { - this.dirname = path.dirname(filename); - } else { - this.dirname = ''; - } - - require.paths = modulePaths; - require.main = process.mainModule; - - __resources__[this.filename].data.apply(this.exports, [this.exports, require, this, this.filename, this.dirname]); - - return this; - }; - - // Manually load the path module because we need it to load other modules - path = (new Module('path'))._initialize('/__builtin__/path.js').exports; - - var util = loadModule('util').exports; - util.ready(function () { - // Populate globals - var globals = loadModule('global').exports; - for (var x in globals) { - if (globals.hasOwnProperty(x)) { - window[x] = globals[x]; - } - } - - // Add a global require. Useful in the debug console. - window.require = function require(request, parent) { - return loadModule(request, parent).exports; - }; - window.require.paths = modulePaths; - - process.mainModule = loadModule(__main_module_name__); - - window.require.main = process.mainModule; - - if (process.mainModule.exports.main) { - process.mainModule.exports.main(); - } - - }); -})(); - -// vim:ft=javascript - -})(); From 6db6ca1e49d0b6c286fd267623a5732f43372dbf Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 19 May 2011 19:37:10 +1200 Subject: [PATCH 145/176] Fixed recently introduced bug causing MenuItem to render in the wrong place --- src/libs/cocos2d/nodes/Menu.js | 8 +-- src/libs/cocos2d/nodes/MenuItem.js | 84 ++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/libs/cocos2d/nodes/Menu.js b/src/libs/cocos2d/nodes/Menu.js index 971984f..df0c8a4 100644 --- a/src/libs/cocos2d/nodes/Menu.js +++ b/src/libs/cocos2d/nodes/Menu.js @@ -96,7 +96,7 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ mouseUp: function (event) { var selItem = this.get('selectedItem'); if (selItem) { - selItem.set('isSelected', false); + selItem.unselected(); selItem.activate(); } @@ -117,7 +117,7 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ var selectedItem = this.itemForMouseEvent(event); this.set('selectedItem', selectedItem); if (selectedItem) { - selectedItem.set('isSelected', true); + selectedItem.selected() this.set('state', kMenuStateTrackingTouch); return true; @@ -131,11 +131,11 @@ var Menu = Layer.extend(/** @lends cocos.nodes.Menu# */{ if (currentItem != this.selectedItem) { if (this.selectedItem) { - this.selectedItem.set('isSelected', false); + this.selectedItem.unselected(); } this.set('selectedItem', currentItem); if (this.selectedItem) { - this.selectedItem.set('isSelected', true); + this.selectedItem.selected(); } } diff --git a/src/libs/cocos2d/nodes/MenuItem.js b/src/libs/cocos2d/nodes/MenuItem.js index 26760d7..d73ad03 100644 --- a/src/libs/cocos2d/nodes/MenuItem.js +++ b/src/libs/cocos2d/nodes/MenuItem.js @@ -48,6 +48,14 @@ var MenuItem = Node.extend(/** @lends cocos.nodes.MenuItem# */{ this.contentSize.width, this.contentSize.height ); + }, + + selected: function () { + this.isSelected = true; + }, + + unselected: function () { + this.isSelected = false; } }); @@ -81,23 +89,79 @@ var MenuItemSprite = MenuItem.extend(/** @lends cocos.nodes.MenuItemSprite# */{ this.set('contentSize', normalImage.get('contentSize')); }, - visit: function (ctx, rect) { - MenuItemSprite.superclass.visit.call(this, ctx, rect); + set_normalImage: function (image) { + if (image != this.normalImage) { + image.set('anchorPoint', ccp(0, 0)); + image.set('visible', true); + this.removeChild({child: this.normalImage, cleanup: true}); + this.addChild(image); - if (this.isEnabled) { - if (this.isSelected) { - this.selectedImage.visit(ctx); - } else { - this.normalImage.visit(ctx); - } + this.normalImage = image; + } + }, + + set_selectedImage: function (image) { + if (image != this.selectedImage) { + image.set('anchorPoint', ccp(0, 0)); + image.set('visible', false); + this.removeChild({child: this.selectedImage, cleanup: true}); + this.addChild(image); + + this.selectedImage = image; + } + }, + + set_disabledImage: function (image) { + if (image != this.disabledImage) { + image.set('anchorPoint', ccp(0, 0)); + image.set('visible', false); + this.removeChild({child: this.disabledImage, cleanup: true}); + this.addChild(image); + + this.disabledImage = image; + } + }, + + selected: function () { + MenuItemSprite.superclass.selected.call(this); + + if (this.selectedImage) { + this.normalImage.set('visible', false); + this.selectedImage.set('visible', true); + if (this.disabledImage) this.disabledImage.set('visible', false); + } else { + this.normalImage.set('visible', true); + if (this.disabledImage) this.disabledImage.set('visible', false); + } + }, + + unselected: function () { + MenuItemSprite.superclass.unselected.call(this); + + this.normalImage.set('visible', true); + if (this.selectedImage) this.selectedImage.set('visible', false); + if (this.disabledImage) this.disabledImage.set('visible', false); + }, + + set_isEnabled: function (enabled) { + this.isEnabled = enabled; + + if (enabled) { + this.normalImage.set('visible', true); + if (this.selectedImage) this.selectedImage.set('visible', false); + if (this.disabledImage) this.disabledImage.set('visible', false); } else { if (this.disabledImage) { - this.disabledImage.visit(ctx); + this.normalImage.set('visible', false); + if (this.selectedImage) this.selectedImage.set('visible', false); + this.disabledImage.set('visible', true); } else { - this.normalImage.visit(ctx); + this.normalImage.set('visible', true); + if (this.selectedImage) this.selectedImage.set('visible', false); } } } + }); var MenuItemImage = MenuItemSprite.extend(/** @lends cocos.nodes.MenuItemImage# */{ From c70b68e74a021b6fa6641648a4129dcae03e6ec1 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 20 May 2011 23:09:03 +1200 Subject: [PATCH 146/176] Fixed preloader's 'complete' event not firing if all items have already loaded --- src/libs/cocos2d/Preloader.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libs/cocos2d/Preloader.js b/src/libs/cocos2d/Preloader.js index 0bfc0fc..8061e8e 100644 --- a/src/libs/cocos2d/Preloader.js +++ b/src/libs/cocos2d/Preloader.js @@ -41,8 +41,7 @@ var Preloader = BObject.extend(/** @lends cocos.Preloader# */{ if (__remote_resources__.hasOwnProperty(uri)) { if (__resources__[uri]) { // Already loaded - this.set('loaded', this.get('loaded') +1); - events.trigger(this, 'load', uri, this); + this.didLoadResource(uri); continue; } var file = resource(uri); @@ -59,7 +58,9 @@ var Preloader = BObject.extend(/** @lends cocos.Preloader# */{ didLoadResource: function(uri) { this.set('loaded', this.get('loaded') +1); - events.removeListener(this._listeners[uri]); + if (this._listeners[uri]) { + events.removeListener(this._listeners[uri]); + } events.trigger(this, 'load', uri, this); if (this.get('loaded') >= this.get('count')) { From 52341743c3c226bf41bc76f9e91d895435a5de4b Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 21 May 2011 10:32:26 +1200 Subject: [PATCH 147/176] Fixed problems serving some resource files due to special characters --- lib/cocos2d/commands/make.js | 2 +- lib/cocos2d/commands/server.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/cocos2d/commands/make.js b/lib/cocos2d/commands/make.js index c829c4c..9963e95 100644 --- a/lib/cocos2d/commands/make.js +++ b/lib/cocos2d/commands/make.js @@ -297,7 +297,7 @@ function Compiler(configFile) { // Source starts with config path if (uri.indexOf(dest) === 0) { - var realPath = uri.replace(dest, source).replace(/\/+/, '/'); + var realPath = path.join(source, uri.replace(dest, '').replace(/\/+/, '/')); if (path.existsSync(realPath)) { return realPath; } diff --git a/lib/cocos2d/commands/server.js b/lib/cocos2d/commands/server.js index 956255d..8a84f87 100644 --- a/lib/cocos2d/commands/server.js +++ b/lib/cocos2d/commands/server.js @@ -4,6 +4,7 @@ var sys = require('sys'), http = require('http'), + qs = require('querystring'), url = require('url'), path = require('path'), fs = require('fs'), @@ -63,7 +64,8 @@ exports.run = function () { } else { var publicFilename = path.join(process.cwd(), 'public', uri.pathname); // resource paths are prefixed with '/resources' - var resourceFilename = uri.pathname.replace(/^\/resources/, ''); + var resourceFilename = qs.unescape(uri.pathname.replace(/^\/resources/, '')); + sys.puts('Requested:' + resourceFilename); // If file exists in public folder, server that if (path.existsSync(publicFilename)) { @@ -85,6 +87,7 @@ exports.run = function () { // File not found else { + sys.puts("File not found: " + uri.pathname); res.writeHead(404, 'File not found'); res.end('File not found'); } From 0d27f9a74be3cd2e902277f63778e5f1e7b67620 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 21 May 2011 13:57:37 +1200 Subject: [PATCH 148/176] Updated gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 905c8ca..593a970 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ cocos2d-*.gz cocos2d-*.zip .DS_Store nbproject +tests/build/ From ad372e357b47238171593722e94c90f7f24efab2 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 21 May 2011 13:57:47 +1200 Subject: [PATCH 149/176] Bumped version number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef92200..8547950 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "cocos2d", "author": "Ryan Williams ", "description": "Port of the Cocos2D graphics engine to HTML5", - "version": "0.1.1", + "version": "0.2.0-alpha", "homepage": "http://cocos2d-javascript.org/", "engines": { From 2a3e3874acd9366740a2287c1c35969fccf2f7a4 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 22 May 2011 09:48:39 +1200 Subject: [PATCH 150/176] Fixed populateIndex helper so it doesn't replace 'exports' This allows a module to include its parent module --- src/libs/util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/util.js b/src/libs/util.js index 9fdc3aa..7d7ce71 100644 --- a/src/libs/util.js +++ b/src/libs/util.js @@ -342,7 +342,7 @@ var util = { util.extend(namespace, window.require('./' + mod, parent)); }); - parent.exports = namespace; + util.extend(parent.exports, namespace); return namespace; } From d7d321d8dabee642169efa04e0f093fb32e4ee61 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 22 May 2011 23:14:40 +1200 Subject: [PATCH 151/176] Added abillity to get deeper properties by using dot separated path rather than multiple .get() calls --- src/global.js | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/global.js b/src/global.js index 419bc61..049ef0e 100644 --- a/src/global.js +++ b/src/global.js @@ -71,20 +71,35 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ * access the property directly. This will ensure all bindings, setters and * getters work correctly. * - * @param {String} key Name of property to get + * @param {String} key Name of property to get or dot (.) separated path to a property * @returns {*} Value of the property */ get: function (key) { - var accessor = getAccessors(this)[key]; + var next = false + if (~key.indexOf('.')) { + var tokens = key.split('.'); + key = tokens.shift(); + next = tokens.join('.'); + } + + + var accessor = getAccessors(this)[key], + val; if (accessor) { - return accessor.target.get(accessor.key); + val = accessor.target.get(accessor.key); } else { // Call getting function if (this['get_' + key]) { - return this['get_' + key](); + val = this['get_' + key](); + } else { + val = this[key]; } + } - return this[key]; + if (next) { + return val.get(next); + } else { + return val; } }, From 8e1eabc5e4767dd200afe8f8b46e4c4ce807b16e Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 22 May 2011 23:15:01 +1200 Subject: [PATCH 152/176] Added missing Texture2D export --- src/libs/cocos2d/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/cocos2d/index.js b/src/libs/cocos2d/index.js index 32b5d72..faee3a5 100644 --- a/src/libs/cocos2d/index.js +++ b/src/libs/cocos2d/index.js @@ -5,7 +5,7 @@ var util = require('util'), path = require('path'); -var modules = 'Preloader RemoteImage RemoteResource SpriteFrame SpriteFrameCache Director Animation AnimationCache Scheduler ActionManager TMXXMLParser'.w(); +var modules = 'Texture2D Preloader RemoteImage RemoteResource SpriteFrame SpriteFrameCache Director Animation AnimationCache Scheduler ActionManager TMXXMLParser'.w(); /** * @namespace All cocos2d objects live in this namespace From c4d286f80983f16846837dea92c6b706cff90122 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Tue, 24 May 2011 15:53:32 -0700 Subject: [PATCH 153/176] Added JumpTo, JumpBy Actions + tests --- src/libs/cocos2d/ActionManager.js | 2 +- src/libs/cocos2d/actions/ActionInterval.js | 108 ++++++++++++- tests/public/index.html | 1 + tests/src/cocos2d/ActionTest.js | 176 +++++++++++++++++++++ tests/src/cocos2d/SpriteTest.js | 4 + 5 files changed, 283 insertions(+), 8 deletions(-) create mode 100644 tests/src/cocos2d/ActionTest.js diff --git a/src/libs/cocos2d/ActionManager.js b/src/libs/cocos2d/ActionManager.js index 170a6b0..0af266e 100644 --- a/src/libs/cocos2d/ActionManager.js +++ b/src/libs/cocos2d/ActionManager.js @@ -108,7 +108,7 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ if (!element) { return; } - + //window.console.log("removing actions from target " + target.get('tag') + " (" + targetID + ")"); // Delete everything in array but don't replace it incase something else has a reference element.actions.splice(0, element.actions.length); }, diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index 384e354..dbc5cb2 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -7,6 +7,7 @@ var util = require('util'), geo = require('geometry'), ccp = geo.ccp; + var ActionInterval = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionInterval# */{ /** * Number of seconds that have elapsed @@ -391,14 +392,105 @@ var MoveBy = MoveTo.extend(/** @lends cocos.actions.MoveBy# */{ } }); +var JumpBy = ActionInterval.extend(/** @lends cocos.actions.JumpBy# */{ + /** + * Number of pixels to jump by + * @type geometry.Point + */ + delta: null, + + /** + * Height of jump + * @type Float + */ + height: 0, + + /** + * Number of times to jump + * @type Integer + */ + jumps: 0, + + /** + * Starting point + * @type geometry.Point + */ + startPosition: null, + + /** + * Moves a CCNode object simulating a parabolic jump movement by modifying it's position attribute. + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.ActionInterval + * + * @opt {Float} duration Number of seconds to run action for + * @opt {geometry.Point} startPosition Point at which jump starts + * @opt {geometry.Point} delta Number of pixels to jump by + * @opt {Float} height Height of jump + * @opt {Int} jumps Number of times to repeat + */ + init: function(opts) { + JumpBy.superclass.init.call(this, opts); + + this.delta = util.copy(opts.delta); + this.height = opts.height; + this.jumps = opts.jumps; + }, + + copy: function() { + return JumpBy.create({duration: this.duration, + delta: this.delta, + height: this.height, + jumps: this.jumps}); + }, + + startWithTarget: function(target) { + JumpBy.superclass.startWithTarget.call(this, target); + this.set('startPosition', target.get('position')); + }, + + update: function(t) { + // parabolic jump + // the fmod function I added doesn't seem to do the trick here... + // simple modulo works better for now. + //var frac = math.fmod(t * this.jumps, 1.0); + var frac = (t * this.jumps) % 1.0; + var y = this.height * 4 * frac * (1 - frac); + y += this.delta.y * t; + var x = this.delta.x * t; + this.target.set('position', geo.ccp(this.startPosition.x + x, this.startPosition.y + y)); + }, + + reverse: function() { + return JumpBy.create({duration: this.duration, + delta: geo.ccp(-this.delta.x, -this.delta.y), + height: this.height, + jumps: this.jumps}); + } +}); +var JumpTo = JumpBy.extend(/** @lends cocos.actions.JumpTo# */{ + /** + * Moves a Node object to a parabolic position simulating a jump movement by modifying it's position attribute. + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.JumpBy + */ + startWithTarget: function(target) { + JumpTo.superclass.startWithTarget.call(this, target); + this.delta = geo.ccp(this.delta.x - this.startPosition.x, this.delta.y - this.startPosition.y); + } +}); + /** * @memberOf cocos.actions * @class Fades out a cocos.nodes.Node to zero opacity * @extends cocos.actions.ActionInterval */ var FadeOut = ActionInterval.extend(/** @lends cocos.actions.FadeOut# */{ - + update: function (t) { var target = this.get('target'); if (!target) return; @@ -416,7 +508,7 @@ var FadeOut = ActionInterval.extend(/** @lends cocos.actions.FadeOut# */{ * @extends cocos.actions.ActionInterval */ var FadeIn = ActionInterval.extend(/** @lends cocos.actions.FadeIn# */{ - + update: function (t) { var target = this.get('target'); if (!target) return; @@ -527,11 +619,11 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ } else { this.elapsed += dt; } - // Required to prevent array bounds index errors - if (this.currentActionIndex < this.actions.length) { - this.actions[this.currentActionIndex].step(dt); - this.update(Math.min(1, this.elapsed / this.duration)); - } + // Required to prevent array bounds index errors + if (this.currentActionIndex < this.actions.length) { + this.actions[this.currentActionIndex].step(dt); + this.update(Math.min(1, this.elapsed / this.duration)); + } }, update: function (dt) { @@ -728,6 +820,8 @@ exports.RotateTo = RotateTo; exports.RotateBy = RotateBy; exports.MoveTo = MoveTo; exports.MoveBy = MoveBy; +exports.JumpBy = JumpBy; +exports.JumpTo = JumpTo; exports.FadeIn = FadeIn; exports.FadeOut = FadeOut; exports.FadeTo = FadeTo; diff --git a/tests/public/index.html b/tests/public/index.html index 04f3716..209d585 100644 --- a/tests/public/index.html +++ b/tests/public/index.html @@ -239,6 +239,7 @@

          Tests

          • CommonJS
          • Sprites
          • +
          • Actions
          • Tile Maps
          • Scene Transitions
          • QUnit
          • diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js new file mode 100644 index 0000000..df36f0f --- /dev/null +++ b/tests/src/cocos2d/ActionTest.js @@ -0,0 +1,176 @@ +/* module exports resource require*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + +var util = require('util'), + Texture2D = require('cocos2d/Texture2D').Texture2D, + cocos = require('cocos2d'), + events = require('events'), + nodes = cocos.nodes, + actions = cocos.actions, + geo = require('geometry'), + ccp = geo.ccp; + +var sceneIdx = -1; +var transitions = [ + "Jump" +]; + +var tests = {}; + +var kTagSprite1 = 1, + kTagSprite2 = 2, + kTagSprite3 = 3; + +function nextAction() { + sceneIdx++; + sceneIdx = sceneIdx % transitions.length; + + var r = transitions[sceneIdx]; + return tests[r]; +} +function backAction() { + sceneIdx--; + if (sceneIdx < 0) { + sceneIdx += transitions.length; + } + + var r = transitions[sceneIdx]; + return tests[r]; +} +function restartAction() { + var r = transitions[sceneIdx]; + return tests[r]; +} + +var ActionDemo = nodes.Layer.extend({ + title: 'No title', + subtitle: null, + + init: function () { + ActionDemo.superclass.init.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); + this.addChild({child: label, z: 1}); + label.set('position', ccp(s.width / 2, s.height - 50)); + + + var subtitle = this.get('subtitle'); + if (subtitle) { + var l = nodes.Label.create({string: subtitle, fontName: "Thonburi", fontSize: 16}); + this.addChild({child: l, z: 1}); + l.set('position', ccp(s.width / 2, s.height - 80)); + } + + + var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); + var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); + var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); + + var menu = nodes.Menu.create({items: [item1, item2, item3]}); + + menu.set('position', ccp(0, 0)); + item1.set('position', ccp(s.width / 2 - 100, 30)); + item2.set('position', ccp(s.width / 2, 30)); + item3.set('position', ccp(s.width / 2 + 100, 30)); + this.addChild({child: menu, z: 1}); + }, + + restartCallback: function () { + var director = cocos.Director.get('sharedDirector'); + + var scene = nodes.Scene.create(); + scene.addChild({child: restartAction().create()}); + + director.replaceScene(scene); + }, + + backCallback: function () { + var director = cocos.Director.get('sharedDirector'); + + var scene = nodes.Scene.create(); + scene.addChild({child: backAction().create()}); + + director.replaceScene(scene); + }, + + nextCallback: function () { + var director = cocos.Director.get('sharedDirector'); + + var scene = nodes.Scene.create(); + scene.addChild({child: nextAction().create()}); + + director.replaceScene(scene); + } +}); + +/** + * @class + * + * Example Jump Action + */ +tests.Jump = ActionDemo.extend(/** @lends Jump.prototype# */{ + title: 'JumpTo / JumpBy', + subtitle: '', + + init: function () { + tests.Jump.superclass.init.call(this); + + this.set('isMouseEnabled', true); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + this.addNewSprite(ccp(s.width / 2, s.height / 2)); + }, + + addNewSprite: function (point) { + var idx = Math.floor(Math.random() * 1400 / 100), + x = (idx % 5) * 85, + y = (idx % 3) * 121; + + var sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: new geo.Rect(x, y, 85, 121)}); + this.addChild({child: sprite, z: 0}); + sprite.set('position', ccp(point.x, point.y)); + + return sprite; + }, + + onEnter: function() { + tests.Jump.superclass.onEnter.call(this); + + var action, actionBack, seq; + var rand = Math.random(); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var action1 = actions.JumpTo.create({duration: 2, delta: ccp(300, 300), height: 50, jumps: 4}); + var action2 = actions.JumpBy.create({duration: 2, delta: ccp(300, 0), height: 50, jumps: 4}); + var action3 = actions.JumpBy.create({duration: 2, delta: ccp(0, 0), height: 80, jumps: 4}); + actionBack = action2.reverse(); + + var s1 = this.addNewSprite(ccp(s.width/2, s.height/2)); + var s2 = this.addNewSprite(ccp(s.width/2, s.height/2)); + var s3 = this.addNewSprite(ccp(s.width/2, s.height/2)); + + s1.runAction(action1); + s2.runAction(actions.Sequence.create({actions: [action2, actionBack]})); + s3.runAction(actions.RepeatForever.create(action3)); + } +}); + +exports.main = function () { + // Initialise test + var director = cocos.Director.get('sharedDirector'); + + director.attachInView(document.getElementById('cocos2d-tests')); + director.set('displayFPS', true); + + events.addListener(director, 'ready', function (director) { + var scene = nodes.Scene.create(); + scene.addChild({child: nextAction().create()}); + director.replaceScene(scene); + }); + + director.runPreloadScene(); +}; diff --git a/tests/src/cocos2d/SpriteTest.js b/tests/src/cocos2d/SpriteTest.js index 2a8a0b5..7e3ad4b 100644 --- a/tests/src/cocos2d/SpriteTest.js +++ b/tests/src/cocos2d/SpriteTest.js @@ -156,6 +156,7 @@ tests.Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ if (rand < 0.2) { action = actions.ScaleBy.create({duration: 3, scale: 2}); +/* } else if (rand < 0.4) { action = actions.RotateBy.create({duration: 3, angle: 360}); } else if (rand < 0.6) { @@ -164,6 +165,9 @@ tests.Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ } else if (rand < 0.8) { action = actions.RotateBy.create({duration: 3, angle: 360}); //action = cocos.TintBy.create({duration:3, scale:2}); +*/ + } else if (rand < 0.9) { + action = actions.JumpBy.create({duration: 1, delta: geo.ccp(40, 40), height: 2, jumps: 1}); } else { action = actions.ScaleBy.create({duration: 3, scale: 2}); //action = cocos.FadeOut.create({duration:3, scale:2}); From 6dfccba8b3273ca60c217eb6ba5bf3e6693e7c07 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Tue, 24 May 2011 16:27:02 -0700 Subject: [PATCH 154/176] minor test update --- tests/src/cocos2d/ActionTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js index df36f0f..8dcf2bb 100644 --- a/tests/src/cocos2d/ActionTest.js +++ b/tests/src/cocos2d/ActionTest.js @@ -144,7 +144,7 @@ tests.Jump = ActionDemo.extend(/** @lends Jump.prototype# */{ var s = cocos.Director.get('sharedDirector').get('winSize'); - var action1 = actions.JumpTo.create({duration: 2, delta: ccp(300, 300), height: 50, jumps: 4}); + var action1 = actions.JumpTo.create({duration: 2, delta: ccp(s.width/2, 300), height: 50, jumps: 4}); var action2 = actions.JumpBy.create({duration: 2, delta: ccp(300, 0), height: 50, jumps: 4}); var action3 = actions.JumpBy.create({duration: 2, delta: ccp(0, 0), height: 80, jumps: 4}); actionBack = action2.reverse(); From 9dd8b5de1cdcf16a08729ad78e87555e9d357d4b Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Tue, 24 May 2011 16:27:54 -0700 Subject: [PATCH 155/176] another test update --- tests/src/cocos2d/SpriteTest.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/src/cocos2d/SpriteTest.js b/tests/src/cocos2d/SpriteTest.js index 7e3ad4b..7132244 100644 --- a/tests/src/cocos2d/SpriteTest.js +++ b/tests/src/cocos2d/SpriteTest.js @@ -156,7 +156,6 @@ tests.Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ if (rand < 0.2) { action = actions.ScaleBy.create({duration: 3, scale: 2}); -/* } else if (rand < 0.4) { action = actions.RotateBy.create({duration: 3, angle: 360}); } else if (rand < 0.6) { @@ -165,17 +164,11 @@ tests.Sprite1 = SpriteDemo.extend(/** @lends Sprite1.prototype# */{ } else if (rand < 0.8) { action = actions.RotateBy.create({duration: 3, angle: 360}); //action = cocos.TintBy.create({duration:3, scale:2}); -*/ - } else if (rand < 0.9) { - action = actions.JumpBy.create({duration: 1, delta: geo.ccp(40, 40), height: 2, jumps: 1}); } else { action = actions.ScaleBy.create({duration: 3, scale: 2}); //action = cocos.FadeOut.create({duration:3, scale:2}); } - - - actionBack = action.reverse(); seq = actions.Sequence.create({actions: [action, actionBack]}); sprite.runAction(actions.RepeatForever.create(seq)); From 36a21ed9b667257d9eadf83e2cc22dcd4f445c10 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Wed, 25 May 2011 08:16:54 -0700 Subject: [PATCH 156/176] Trying to fix whitespace --- src/libs/cocos2d/actions/ActionInterval.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index dbc5cb2..66f25d6 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -472,7 +472,8 @@ var JumpBy = ActionInterval.extend(/** @lends cocos.actions.JumpBy# */{ var JumpTo = JumpBy.extend(/** @lends cocos.actions.JumpTo# */{ /** - * Moves a Node object to a parabolic position simulating a jump movement by modifying it's position attribute. + * Moves a Node object to a parabolic position simulating a jump + * movement by modifying it's position attribute. * * @memberOf cocos.actions * @constructs From d6942802c21c6acf6b3fd968c3d28a099e65c633 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Wed, 25 May 2011 08:19:16 -0700 Subject: [PATCH 157/176] whitespaces again --- src/libs/cocos2d/actions/ActionInterval.js | 168 ++++++++++----------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index 66f25d6..5ec0b63 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -393,98 +393,98 @@ var MoveBy = MoveTo.extend(/** @lends cocos.actions.MoveBy# */{ }); var JumpBy = ActionInterval.extend(/** @lends cocos.actions.JumpBy# */{ - /** - * Number of pixels to jump by - * @type geometry.Point - */ - delta: null, - - /** - * Height of jump - * @type Float - */ - height: 0, - - /** - * Number of times to jump - * @type Integer - */ - jumps: 0, - - /** - * Starting point - * @type geometry.Point - */ - startPosition: null, - - /** - * Moves a CCNode object simulating a parabolic jump movement by modifying it's position attribute. - * - * @memberOf cocos.actions + /** + * Number of pixels to jump by + * @type geometry.Point + */ + delta: null, + + /** + * Height of jump + * @type Float + */ + height: 0, + + /** + * Number of times to jump + * @type Integer + */ + jumps: 0, + + /** + * Starting point + * @type geometry.Point + */ + startPosition: null, + + /** + * Moves a CCNode object simulating a parabolic jump movement by modifying it's position attribute. + * + * @memberOf cocos.actions * @constructs * @extends cocos.actions.ActionInterval - * - * @opt {Float} duration Number of seconds to run action for - * @opt {geometry.Point} startPosition Point at which jump starts - * @opt {geometry.Point} delta Number of pixels to jump by - * @opt {Float} height Height of jump - * @opt {Int} jumps Number of times to repeat - */ - init: function(opts) { - JumpBy.superclass.init.call(this, opts); - - this.delta = util.copy(opts.delta); - this.height = opts.height; - this.jumps = opts.jumps; - }, - - copy: function() { - return JumpBy.create({duration: this.duration, - delta: this.delta, - height: this.height, - jumps: this.jumps}); - }, - - startWithTarget: function(target) { - JumpBy.superclass.startWithTarget.call(this, target); - this.set('startPosition', target.get('position')); - }, - - update: function(t) { - // parabolic jump - // the fmod function I added doesn't seem to do the trick here... - // simple modulo works better for now. - //var frac = math.fmod(t * this.jumps, 1.0); - var frac = (t * this.jumps) % 1.0; - var y = this.height * 4 * frac * (1 - frac); - y += this.delta.y * t; - var x = this.delta.x * t; - this.target.set('position', geo.ccp(this.startPosition.x + x, this.startPosition.y + y)); - }, - - reverse: function() { - return JumpBy.create({duration: this.duration, - delta: geo.ccp(-this.delta.x, -this.delta.y), - height: this.height, - jumps: this.jumps}); - } + * + * @opt {Float} duration Number of seconds to run action for + * @opt {geometry.Point} startPosition Point at which jump starts + * @opt {geometry.Point} delta Number of pixels to jump by + * @opt {Float} height Height of jump + * @opt {Int} jumps Number of times to repeat + */ + init: function(opts) { + JumpBy.superclass.init.call(this, opts); + + this.delta = util.copy(opts.delta); + this.height = opts.height; + this.jumps = opts.jumps; + }, + + copy: function() { + return JumpBy.create({duration: this.duration, + delta: this.delta, + height: this.height, + jumps: this.jumps}); + }, + + startWithTarget: function(target) { + JumpBy.superclass.startWithTarget.call(this, target); + this.set('startPosition', target.get('position')); + }, + + update: function(t) { + // parabolic jump + // the fmod function I added doesn't seem to do the trick here... + // simple modulo works better for now. + //var frac = math.fmod(t * this.jumps, 1.0); + var frac = (t * this.jumps) % 1.0; + var y = this.height * 4 * frac * (1 - frac); + y += this.delta.y * t; + var x = this.delta.x * t; + this.target.set('position', geo.ccp(this.startPosition.x + x, this.startPosition.y + y)); + }, + + reverse: function() { + return JumpBy.create({duration: this.duration, + delta: geo.ccp(-this.delta.x, -this.delta.y), + height: this.height, + jumps: this.jumps}); + } }); var JumpTo = JumpBy.extend(/** @lends cocos.actions.JumpTo# */{ - /** - * Moves a Node object to a parabolic position simulating a jump - * movement by modifying it's position attribute. - * - * @memberOf cocos.actions + /** + * Moves a Node object to a parabolic position simulating a jump + * movement by modifying it's position attribute. + * + * @memberOf cocos.actions * @constructs * @extends cocos.actions.JumpBy - */ - startWithTarget: function(target) { - JumpTo.superclass.startWithTarget.call(this, target); - this.delta = geo.ccp(this.delta.x - this.startPosition.x, this.delta.y - this.startPosition.y); - } + */ + startWithTarget: function(target) { + JumpTo.superclass.startWithTarget.call(this, target); + this.delta = geo.ccp(this.delta.x - this.startPosition.x, this.delta.y - this.startPosition.y); + } }); - + /** * @memberOf cocos.actions * @class Fades out a cocos.nodes.Node to zero opacity From bff7c72e0de01da4ede9e16fda444c2523abc9db Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 27 May 2011 20:45:02 +1200 Subject: [PATCH 158/176] Added fixed errors when compiling apps with a large number of files --- lib/cocos2d/commands/make.js | 79 +++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/lib/cocos2d/commands/make.js b/lib/cocos2d/commands/make.js index 9963e95..15d8168 100644 --- a/lib/cocos2d/commands/make.js +++ b/lib/cocos2d/commands/make.js @@ -9,6 +9,9 @@ var sys = require('sys'), Template = require('../template').Template, mimetypes = require('../mimetypes'); + +var cwd = process.cwd(); + var OPTIONS = [ { short: 'f', long: 'file', @@ -391,7 +394,7 @@ function mkdir(dir, mode) { mode = mode || 511; // Octal = 0777; if (dir[0] != '/') { - dir = path.join(process.cwd(), dir); + dir = path.join(cwd, dir); } var paths = [dir]; @@ -431,6 +434,52 @@ function copyFolder(src, dst) { } } +/** + * @see https://gist.github.com/563078/afa6c25facaf857712c6847c0bdc748cb6476f93 + */ + +function copytree(src, dst) { + if(!path.existsSync(src)) { + throw new Error(src + ' does not exists. Nothing to be copied'); + } + + if(!fs.statSync(src).isDirectory()) { + throw new Error(src + ' must be a directory'); + } + + var filenames = fs.readdirSync(src); + var basedir = src; + + if(!path.existsSync(dst)) { + fs.mkdirSync(dst, parseInt('0755', 8)); + } + var readNext = function(){ + if (!filenames.length) return; + var filename = filenames.shift(); + console.log(filename); + var file = basedir + '/' + filename; + var newdst = dst + '/' + filename; + + if(fs.statSync(file).isDirectory()) { + copytree(file, newdst); + readNext(); + } else { + copytree.count++; + var reader = fs.createReadStream(file); + var writer = fs.createWriteStream(newdst); + writer.addListener('close', function(){ + copytree.count--; + readNext(); + }); + sys.pump(reader, writer); + } + } + readNext(); + while (filenames.length && copytree.count < copytree.limit) readNext(); +} +copytree.limit = 2; +copytree.count = 0; + exports.description = 'Compile a cocos2d project into a single javascript file'; exports.run = function () { opts.parse(OPTIONS, true); @@ -452,20 +501,40 @@ exports.run = function () { fs.writeFileSync(scriptOutput, code, 'utf8'); // Copy public folder - copyFolder('public', 'build'); + copytree('public', 'build'); // Copy resources sys.puts("Copying resources to: " + resourceOutput); mkdir(resourceOutput); + var files = []; for (var source in compiler.remoteResources) { if (compiler.remoteResources.hasOwnProperty(source)) { var dest = path.join(resourceOutput, compiler.remoteResources[source]); - mkdir(path.dirname(dest)); - sys.puts("Copying resource: " + source + " => " + dest); - sys.pump(fs.createReadStream(source), fs.createWriteStream(dest)); + files.push([source, dest]); + } + } + + function cp(src, dst, callback) { + mkdir(path.dirname(dst)); + + var reader = fs.createReadStream(src), + writer = fs.createWriteStream(dst); + + writer.addListener('close', function () { callback(); }); + + sys.pump(reader, writer); + } + + function next() { + if (!files.length) { + return; } + var names = files.shift(); + cp(names[0], names[1], next); } + next(); + } else { sys.puts(code); } From 5b4f5fa2b046bbc04f03623e518c4d15b13c7937 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 27 May 2011 20:45:30 +1200 Subject: [PATCH 159/176] Fixed missing Object.keys in Opera --- src/global.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/global.js b/src/global.js index 049ef0e..3545c9c 100644 --- a/src/global.js +++ b/src/global.js @@ -6,6 +6,24 @@ var util = require('util'), events = require('events'); + +if (!Object.keys) { + Object.keys = function(o){ + if (o !== Object(o)) { + throw new TypeError('Object.keys called on non-object'); + } + var ret=[], + p; + for (p in o) { + if (Object.prototype.hasOwnProperty.call(o,p)) { + ret.push(p); + } + } + return ret; + } +} + + /** * @ignore */ From f853c04eae89a6cd9b3f919665d8f1700f5401b9 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 27 May 2011 20:45:56 +1200 Subject: [PATCH 160/176] Added TMX Map Properties --- src/libs/cocos2d/TMXXMLParser.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libs/cocos2d/TMXXMLParser.js b/src/libs/cocos2d/TMXXMLParser.js index 3badf83..1bb6fd8 100644 --- a/src/libs/cocos2d/TMXXMLParser.js +++ b/src/libs/cocos2d/TMXXMLParser.js @@ -339,6 +339,17 @@ var TMXMapInfo = BObject.extend(/** @lends cocos.TMXMapInfo# */{ objectGroup.set('objects', objectsArray); this.objectGroups.push(objectGroup); } + + + // PARSE + var properties = doc.querySelectorAll('map > properties > property'); + + for (i = 0; i < properties.length; i++) { + var property = properties[i]; + if (property.getAttribute('name')) { + this.properties[property.getAttribute('name')] = property.getAttribute('value'); + } + } } }); From 6e667ebf78c9d648407376da89c92bcdc19a8bd8 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Fri, 27 May 2011 08:36:34 -0700 Subject: [PATCH 161/176] added removeChildren() to Node --- src/libs/cocos2d/nodes/Node.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index fdf3a09..8573b4f 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -206,6 +206,25 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ } }, + removeChildren: function(opts) { + var children = this.get('children'), + isRunning = this.get('isRunning'); + + // Perform cleanup on each child but can't call removeChild() + // due to Array.splice's destructive nature during iteration. + for (var i = 0; i < children.length; i++) { + if (opts.cleanup) { + children[i].cleanup(); + } + if (isRunning) { + children[i].onExit(); + } + children[i].set('parent', null); + } + // Now safe to empty children list + this.children = []; + }, + detatchChild: function (opts) { var child = opts.child, cleanup = opts.cleanup; From ab42d2d677c276db6245b7b4559727503504e2b1 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 28 May 2011 14:40:05 +1200 Subject: [PATCH 162/176] Added basic LabelAtals support --- src/libs/cocos2d/Texture2D.js | 8 + src/libs/cocos2d/nodes/AtlasNode.js | 77 +++++++++ src/libs/cocos2d/nodes/BatchNode.js | 8 + src/libs/cocos2d/nodes/LabelAtlas.js | 74 ++++++++ src/libs/cocos2d/nodes/Node.js | 42 +++++ src/libs/cocos2d/nodes/index.js | 2 +- src/libs/util.js | 7 + tests/public/index.html | 1 + tests/src/cocos2d/LabelTest.js | 162 ++++++++++++++++++ .../fonts/tuffy_bold_italic-charmap.png | Bin 0 -> 56308 bytes 10 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 src/libs/cocos2d/nodes/AtlasNode.js create mode 100644 src/libs/cocos2d/nodes/LabelAtlas.js create mode 100644 tests/src/cocos2d/LabelTest.js create mode 100644 tests/src/cocos2d/resources/fonts/tuffy_bold_italic-charmap.png diff --git a/src/libs/cocos2d/Texture2D.js b/src/libs/cocos2d/Texture2D.js index 2395a4b..875ca57 100644 --- a/src/libs/cocos2d/Texture2D.js +++ b/src/libs/cocos2d/Texture2D.js @@ -80,6 +80,14 @@ var Texture2D = BObject.extend(/** @lends cocos.Texture2D# */{ */ get_contentSize: function () { return this.size; + }, + + get_pixelsWide: function () { + return this.size.width; + }, + + get_pixelsHigh: function () { + return this.size.height; } }); diff --git a/src/libs/cocos2d/nodes/AtlasNode.js b/src/libs/cocos2d/nodes/AtlasNode.js new file mode 100644 index 0000000..a7374ac --- /dev/null +++ b/src/libs/cocos2d/nodes/AtlasNode.js @@ -0,0 +1,77 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + +var SpriteBatchNode = require('./BatchNode').SpriteBatchNode, + TextureAtlas = require('../TextureAtlas').TextureAtlas, + geo = require('geometry'); + +var AtlasNode = SpriteBatchNode.extend(/** @lends cocos.AtlasNode# */{ + /** + * Characters per row + * @type Integer + */ + itemsPerRow: 0, + + /** + * Characters per column + * @type Integer + */ + itemsPerColumn: 0, + + /** + * Width of a character + * @type Integer + */ + itemWidth: 0, + + /** + * Height of a character + * @type Integer + */ + itemHeight: 0, + + + /** + * @type cocos.TextureAtlas + */ + textureAtlas: null, + + /** + * @class + * It knows how to render a TextureAtlas object. If you are going to + * render a TextureAtlas consider subclassing cocos.nodes.AtlasNode (or a + * subclass of cocos.nodes.AtlasNode) + * @memberOf cocos + * @extends cocos.nodes.SpriteBatchNode + * @constructs + * + * @opt {String} file Path to Atals image + * @opt {Integer} itemWidth Character width + * @opt {Integer} itemHeight Character height + * @opt {Integer} itemsToRender Quantity of items to render + */ + init: function (opts) { + AtlasNode.superclass.init.call(this, opts); + + this.itemWidth = opts.itemWidth; + this.itemHeight = opts.itemHeight; + + this.textureAtlas = TextureAtlas.create({file: opts.file, capacity: opts.itemsToRender}); + + + this._calculateMaxItems(); + }, + + updateAtlasValues: function () { + throw "cocos.nodes.AtlasNode:Abstract - updateAtlasValue not overriden"; + }, + + _calculateMaxItems: function () { + var s = this.textureAtlas.get('texture.contentSize'); + this.itemsPerColumn = s.height / this.itemHeight; + this.itemsPerRow = s.width / this.itemWidth; + } +}); + +exports.AtlasNode = AtlasNode; diff --git a/src/libs/cocos2d/nodes/BatchNode.js b/src/libs/cocos2d/nodes/BatchNode.js index 7b32e49..43d6765 100644 --- a/src/libs/cocos2d/nodes/BatchNode.js +++ b/src/libs/cocos2d/nodes/BatchNode.js @@ -244,6 +244,14 @@ var SpriteBatchNode = BatchNode.extend(/** @lends cocos.nodes.SpriteBatchNode# * */ get_texture: function () { return this.textureAtlas ? this.textureAtlas.texture : null; + }, + + set_opacity: function (newOpacity) { + this.opacity = newOpacity; + for (var i = 0, len = this.children.length; i < len; i++) { + var child = this.children[i]; + child.set('opacity', newOpacity); + } } }); diff --git a/src/libs/cocos2d/nodes/LabelAtlas.js b/src/libs/cocos2d/nodes/LabelAtlas.js new file mode 100644 index 0000000..5e9fc9d --- /dev/null +++ b/src/libs/cocos2d/nodes/LabelAtlas.js @@ -0,0 +1,74 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + +var AtlasNode = require('./AtlasNode').AtlasNode, + Sprite = require('./Sprite').Sprite, + geo = require('geometry'); + +var LabelAtlas = AtlasNode.extend(/** @lends cocos.nodes.LabelAtlas# */{ + string: '', + + mapStartChar: '', + + /** + * @memberOf cocos.nodes + * @extends cocos.nodes.BatchNode + * @constructs + * + * @opt {String} [string=] Initial text to draw + * @opt {String} charMapFile + * @opt {Integer} itemWidth + * @opt {Integer} itemHeight + * @opt {String} startCharMap Single character + */ + init: function (opts) { + LabelAtlas.superclass.init.call(this, { + file: opts.charMapFile, + itemWidth: opts.itemWidth, + itemHeight: opts.itemHeight, + itemsToRender: opts.string.length, + size: new geo.Size(opts.itemWidth * opts.string.length, opts.itemHeight) + }); + + + this.mapStartChar = opts.startCharMap.charCodeAt(0); + this.set('string', opts.string); + }, + + updateAtlasValue: function () { + var n = this.string.length, + s = this.get('string'); + + // FIXME this should reuse children to improve performance + while (this.children.length > 0) { + this.removeChild(this.children[0]); + } + for (var i = 0; i < n; i++) { + var a = s.charCodeAt(i) - this.mapStartChar, + row = (a % this.itemsPerRow), + col = Math.floor(a / this.itemsPerRow); + + var left = row * this.itemWidth, + top = col * this.itemHeight; + + var tile = Sprite.create({rect: new geo.Rect(left, top, this.itemWidth, this.itemHeight), + textureAtlas: this.textureAtlas}); + + tile.set('position', new geo.Point(i * this.itemWidth, 0)); + tile.set('anchorPoint', new geo.Point(0, 0)); + tile.set('opacity', this.get('opacity')); + + this.addChild({child: tile}); + } + }, + + set_string: function (newString) { + this.string = newString; + + this.updateAtlasValue(); + } +}); + + +exports.LabelAtlas = LabelAtlas; diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index 2904ce5..1a10dd1 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -190,6 +190,10 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ }, removeChild: function (opts) { + if (opts.isCocosNode) { + return this.removeChild({child: opts}); + } + var child = opts.child, cleanup = opts.cleanup; @@ -510,6 +514,44 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ */ _dirtyTransform: function () { this.set('isTransformDirty', true); + }, + + /** + * Schedules a custom method with an interval time in seconds. + * If time is 0 it will be ticked every frame. + * If time is 0, it is recommended to use 'scheduleUpdate' instead. + * + * If the method is already scheduled, then the interval parameter will + * be updated without scheduling it again. + * + * @opt {String|Function} method Function of method name to schedule + * @opt {Float} [interval=0] Interval in seconds + */ + schedule: function (opts) { + if (typeof opts == 'string') { + return this.schedule({method: opts, interval: 0}); + } + + opts.interval = opts.interval || 0; + + Scheduler.get('sharedScheduler').schedule({target: this, method: opts.method, interval: opts.interval, paused: this.isRunning}); + }, + + /** + * Unschedules a custom method + * + * @param {String|Function} method + */ + unschedule: function (method) { + if (!method) { + return; + } + + if (typeof method == 'string') { + method = this[method]; + } + + Scheduler.get('sharedScheduler').unschedule({target: this, method: method}); } }); diff --git a/src/libs/cocos2d/nodes/index.js b/src/libs/cocos2d/nodes/index.js index 7c465f4..fcc4d56 100644 --- a/src/libs/cocos2d/nodes/index.js +++ b/src/libs/cocos2d/nodes/index.js @@ -5,7 +5,7 @@ var util = require('util'), path = require('path'); -var modules = 'ProgressBar PreloadScene Node Layer Scene Label Sprite TMXTiledMap BatchNode RenderTexture Menu MenuItem Transition'.w(); +var modules = 'AtlasNode LabelAtlas ProgressBar PreloadScene Node Layer Scene Label Sprite TMXTiledMap BatchNode RenderTexture Menu MenuItem Transition'.w(); /** * @memberOf cocos diff --git a/src/libs/util.js b/src/libs/util.js index 7d7ce71..85e68c1 100644 --- a/src/libs/util.js +++ b/src/libs/util.js @@ -179,7 +179,14 @@ var util = { callback: function(target, method) { if (typeof(method) == 'string') { + var methodName = method; method = target[method]; + if (!method) { + throw "Callback to undefined method: " + methodName; + } + } + if (!method) { + throw "Callback with no method to call"; } return function() { diff --git a/tests/public/index.html b/tests/public/index.html index 04f3716..84a5e6e 100644 --- a/tests/public/index.html +++ b/tests/public/index.html @@ -239,6 +239,7 @@

            Tests

            • CommonJS
            • Sprites
            • +
            • Labels
            • Tile Maps
            • Scene Transitions
            • QUnit
            • diff --git a/tests/src/cocos2d/LabelTest.js b/tests/src/cocos2d/LabelTest.js new file mode 100644 index 0000000..d40d72d --- /dev/null +++ b/tests/src/cocos2d/LabelTest.js @@ -0,0 +1,162 @@ +/*globals module exports resource require*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + +var util = require('util'), + Texture2D = require('cocos2d/Texture2D').Texture2D, + cocos = require('cocos2d'), + events = require('events'), + nodes = cocos.nodes, + actions = cocos.actions, + geo = require('geometry'), + ccp = geo.ccp; + +var sceneIdx = -1; +var transitions = [ + "LabelAtlasTest" +]; + +var tests = {}; + +var kTagSprite1 = 1, + kTagSprite2 = 2, + kTagSprite3 = 3, + kTagSprite4 = 4, + kTagSprite5 = 5, + kTagSprite6 = 6, + kTagSprite7 = 7, + kTagSprite8 = 8; + +function nextAction() { + sceneIdx++; + sceneIdx = sceneIdx % transitions.length; + + var r = transitions[sceneIdx]; + return tests[r]; +} +function backAction() { + sceneIdx--; + if (sceneIdx < 0) { + sceneIdx += transitions.length; + } + + var r = transitions[sceneIdx]; + return tests[r]; +} +function restartAction() { + var r = transitions[sceneIdx]; + return tests[r]; +} + +var AtlasDemo = nodes.Layer.extend({ + title: 'No title', + subtitle: null, + + init: function () { + AtlasDemo.superclass.init.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); + this.addChild({child: label, z: 1}); + label.set('position', ccp(s.width / 2, s.height - 50)); + + + var subtitle = this.get('subtitle'); + if (subtitle) { + var l = nodes.Label.create({string: subtitle, fontName: "Thonburi", fontSize: 16}); + this.addChild({child: l, z: 1}); + l.set('position', ccp(s.width / 2, s.height - 80)); + } + + + var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); + var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); + var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); + + var menu = nodes.Menu.create({items: [item1, item2, item3]}); + + menu.set('position', ccp(0, 0)); + item1.set('position', ccp(s.width / 2 - 100, 30)); + item2.set('position', ccp(s.width / 2, 30)); + item3.set('position', ccp(s.width / 2 + 100, 30)); + this.addChild({child: menu, z: 1}); + }, + + restartCallback: function () { + var director = cocos.Director.get('sharedDirector'); + + var scene = nodes.Scene.create(); + scene.addChild({child: restartAction().create()}); + + director.replaceScene(scene); + }, + + backCallback: function () { + var director = cocos.Director.get('sharedDirector'); + + var scene = nodes.Scene.create(); + scene.addChild({child: backAction().create()}); + + director.replaceScene(scene); + }, + + nextCallback: function () { + var director = cocos.Director.get('sharedDirector'); + + var scene = nodes.Scene.create(); + scene.addChild({child: nextAction().create()}); + + director.replaceScene(scene); + } +}); + + +tests.LabelAtlasTest = AtlasDemo.extend(/** @lends LabelAtlasTest# */{ + title: "LabelAtlas", + subtitle: "Updating label should be fast", + + time: 0, + + init: function () { + tests.LabelAtlasTest.superclass.init.call(this); + + var label1 = nodes.LabelAtlas.create({string: "123 Test", charMapFile: __dirname + "/resources/fonts/tuffy_bold_italic-charmap.png", itemWidth: 48, itemHeight: 64, startCharMap: ' '}); + this.addChild({child: label1, z:0, tag: kTagSprite1}); + label1.set('position', ccp(10, 100)); + label1.set('opacity', 200); + + var label2 = nodes.LabelAtlas.create({string: "0123456789", charMapFile: __dirname + "/resources/fonts/tuffy_bold_italic-charmap.png", itemWidth: 48, itemHeight: 64, startCharMap: ' '}); + this.addChild({child: label2, z:0, tag: kTagSprite2}); + label2.set('position', ccp(10, 200)); + label2.set('opacity', 32); + + this.schedule('step'); + }, + + step: function (dt) { + this.time += dt; + var string = this.time.toString() + ' Test'; + var label1 = this.getChild({tag: kTagSprite1}); + label1.set('string', string); + + var label2 = this.getChild({tag: kTagSprite2}); + label2.set('string', parseInt(this.time).toString()); + } +}); + +exports.main = function () { + // Initialise test + var director = cocos.Director.get('sharedDirector'); + + director.attachInView(document.getElementById('cocos2d-tests')); + director.set('displayFPS', true); + + events.addListener(director, 'ready', function (director) { + var scene = nodes.Scene.create(); + scene.addChild({child: nextAction().create()}); + director.replaceScene(scene); + }); + + director.runPreloadScene(); +}; diff --git a/tests/src/cocos2d/resources/fonts/tuffy_bold_italic-charmap.png b/tests/src/cocos2d/resources/fonts/tuffy_bold_italic-charmap.png new file mode 100644 index 0000000000000000000000000000000000000000..0776533379426c70b37d6c3d1ca7d6fead9f3777 GIT binary patch literal 56308 zcmeFYc|6qL`!_zMkQ6DhL=uv<7?QPw5Gpm8u@q&Qv1H%37P4n&ER%%9SehAQAC;Z4 z8~eT+W8Y>N?&-69@Av)Z@6Y>w{Qels<#o<=opWBV^SYkT>v_VT7-+Me8L`Os8+7nl28+(U0 z0Dw1LX0q3FqhZdlu3ClK?u*y23GeXuGGFUedUToLX}C`C6Z+5(BAyRVYh7X&1HFD; zPp2Jr-CFY!%lmg$gUnlOPnv!`eW*D<9tC4wM*_De;M8W*$>Bxp;IQp_z+e^N$bb{F=gN(-j znM-Mw9g8B_4&iq+FLAGhZ_xvo5*rk2T+c_6745PB-g&lj5e(rvR(b4$srK_rEjE-* zlo8qLws_(n{pnBMkGpoz=VD~If=ir}HR*&+9n z>3U7wXFHj#SG32s{*lN))N^fqTzc_zDUta@xLx%}gzMS#UD!fE>P z{p&^xd*@6eAn()u(zwuT^KZ3`&H@{ z&L-~JFw>}ME6^)~m9ES{s&y*pG1r2;4V!ET`CYEnKv|xNXpx#Hvpjoxv}6P5W$a5x zX-e6tp;xO)eCM0%xo7y^23A}#yW<2bX24z;jH(VM{$ZUK+4QctHF0VE-GyIn8&>{; zb!UV4g7_z61)6Z8pP9i7uy+>(lds)yxbd8ghiQ?C`hoqo+|!WnhVIux*?bzzti;M< zhVIws@QD~CT+#`>!S(EhSQYaa&a21sis$fj(k%(fyE3gci& z#1uba!^FW9uM|rugs7!pknVBbQ3d_eU+TY%LUKw$*;>=+-zpz!a_Dycvz1L5HD-15$<2UHM&JSzVcyawl^~VJoFo;l33V z=66uBlKH{1!{3ZI8B$~B|yz$_RB@H}`CV>T zn2jtZA${bM`Yt(WxdLowifykSJ-na2b`nSbl1AvC1O)`79vs_o~aYB z6WywBG}J%w{AE=ay6YTl!A?Z35Ln&(wRFtXv`CBaMe&bvi+_$!I$4}WCDJ4^lXINY zQi3F5BuSJIFcmXBZQ_VtDW&`wX@JAbtpl1vp|jSg&b;vj46;CS(i2AtP=cG6j&oKU zRCn#2-@AS&a(J6jCCodl_Wb^kyXVd74*>)0#HHzq&dsP` z9F}uj8(jU8S6q8srYrbd@mREDV)hvFCX zF2rd^HYesMEb?@*SbRz;F^)4X!N%`ftwY!IRqv^Wt46DG)Opqw21p;gqS8}6DdXFN z8;g{|LqmqU3`NXKXTLFMF@P9VS?(}jJng~o=NH|t>URRty_Pr3`Z?(z9BFudRAvUA zGrvr6yCNkaS0u9PQ}Mz((A$ea(n|B8Mnm_XV;`;&5}{8Bd(bFg7&WB&z8ST zU2gI73S6CJI|=9bT`>Q+c*nBRYo1{+p*rj^ez8e>F?!Sd;LTASL&}GrA9^09G?<55 z>lEu;)|sU@ypNgk_-VNnGFOoJIWb2}wxFi~Z~p;(fbM%B{3@bU++0>gv{w3$T#k%J zRh#|5+6#`a>OFCfZ@QVIXn3Ptt3CP+@1#@2 zME}z-PfP1w+M(7LnjTa>csgAx*$FxC(CBd4fi!M|LPAGVu3Pl%TD8wa%oqxf#S0wYht_hh9^jOkQK-%T?PZX;!8d!`;PG=E(Vut*=|yYU9;9&?|_`%M13g zuVc}7zW=P%ErDte*X_-cY$_MgCz z_Z=HwjZGK*=^}nzslwR?Sq42MJ=%=x(*CHO+x$D$V?e2YP~p2mqWtgZ_@=U1mu6?` z)UJjfN8$1l*__G)hP#4_n={P^0_$1ll!tvH0)8xuQW1OQ-QWmtHerkqUj9wq-tV#B ze4VtzK7L=jDuaMTA%2)`O;xn~~vMVfT#PRjbf*y_vcNZv-+z1s&`V#hKUE(Yq5tE*-T(D8MHkHf zA8-G1Tp!7_0oeFzm2m4{5&S0@Z@?GEzXAO>wvFrb%7B{hL*LH+ZyVrmSpWRWRP%pT zSiy_C^(nE5bM3yT(}TcT9g>1XZ^jM~c!5$7bz^TmnqP%*oy4Wnn$vl4#f<+Io|QaStX68nLdT>WS>KIWw(YVi zli+39`uT-5Mtf&`Ilfa;U@n|0;A%=xAVdAhfq{Is16pebr}}EZwQ4(OIG=i1z!%lPY+V_ zc)-kX?X5t_G*SElVE;0;H3Au0C+6Im1LPvdB@uwKsflO;^lab^>0AIt73u*#wmB$0 z!r6CP`HbRmxr1%n`nw{=OzJNMLMC~$i--dX?FUzbo!`E`P{iU7Tq;`hd9N5!UloR=ZcUYDfZs>+2!Yo$*XK>DuDR%X=Lq1?kN zGmd4vjQHpP zl81+lD-Y~Dzlt8~F8h4!C4l4HCx-xx>W zpsEBeEAM`8bmM5oo=lM5`TNd8s<-n$^Fo-^r}*jniZzceU#ni?wDX&<8|Ibk%*!4> z>WVR%T~`2VU6p?}IIf^4IPu8vw7^v{XY(1;MWz!Zo9r(MQdXMnvr6Ba{lBa%tlfYN z4H{Fg7=A0J>$Tq-blW>=iUqtWGgC{Ie^6|HJSWkfp=Em!<$A23MDdV8YNqxyy|Gv* zB2VSm7P>e^r)>AF-$1Rr>kt-c=~L?JuWmpiBoRfbf5lt}ro|I2=^i?U-Xm|VD*LF3z}LIju|ot(?e zh*8(&uiTz?4}=$AF*m?=APD?0|1H&wfafXO_1agT(1mdRol@1%66Dc&bv?1b(yO5p z{9BaEAP!4JMx46T`Y1(vXJJdGcjDf_ACxVg@J)(kp;ApsLs7ywa0j{9=<`JHtP<0z z=*HoIAnhK=EZxg%(loNo!`n#!4~J*BSh`Puqsy_!V7KjVH4OYcAtN9a@&PmKXppne zknX9!C^^e{m|wb=nq$|ti9v^EQ3jhkrGNj5h2Sl%%ICY=1XH#-pE88hYtgrN(RSV) zD0HLpV5!5`7HSIfytx0|Ttc5S*2wq0h@MxGq%Bt$V~{9TF*=#wnIef)=&(ORG?=zO zU2(f^sMlrJmC+(PP&B`IAMzu~nyEwN%Py`V&GY<*5&+d6iUZMuaIg8Plbr?2Ee3}Yx7|VVX6f^FE@)!1sq-qJTgPi zdjUowG!w9!BX0t#q=YtY&4X=Gdq2eIh6~r7f6R+>ND3TvZ4G{f zcyLz^9$bnw1gHv<1M6?82cFJx7G*Q&$eM@)zN)p2DQhyz+B|Agb}j4ku10@zQ4Hjw zqpX_mia?l(ZoI6;>f;C-fYP6d2mFFEwZqyCaz(6FNDjqCgVjGHV@I838GBzO6}ZqJ zD_`<9c{v$2O{9sI?Xfcj)Jo4(KEh_HVOLa*?XTmq0BZElC+Uxt)Kvm&ZnA_7d2YVntq>YeP6vCZ>S~^*>rKHu=*(u|!)Ardu(G6kDECjmB32Ox+6B za6#uJDqrS?e6^Oeh+JzK->-&u^~cP5T|D@cYu~QuQiav-Y}YFj;-$Y8BD8o40r)TJP~f*#KX#(Gjh~n-Zphp^7Aoyx za%(gJf9Sf%FB@-NsZ?o%(Q}LS_~v#yVMvPKvJ%n9;Xb$UP%kxw%EMd68?f8ZLr6q7 zkdquH?>UzRoK=(5mL}U%zKLpD+fP8&p}w^ndrd4VUL2ndC)_6eSxhBKe*6IX1!wH0 zrky=q9qVC5PU>v<9Ec!=myAj3)LF|V*Nc|3Sc_v7kr$FB!64AI3(26SM`&Gs(CK!%%^kLd*Jwm72* zY)t3eAg}=FfW6UxFVb$K3xzb`6>=U_%Oee_<3#au{O~R*@`+y_lS(8t*>} zNa}r7f;)Sr^+CND9g*tMuGk?8Fi@I3{SyqgM2)+~Kg4vqGbDTw#jwm;rF4G8{EQ~e zY`!>Dlq?G!^Z$WrvIz~8H2BdR0sIp-e-iCx_{LYyqM-BOh?SZ;(&F7IHG~*jK+__L zzg)IXdzvZbfs0+iflgo0H!Y+S5lL#+4YJNX$$Q!?yKxvv7pQ|97&^R2AT*f05%Sd? zk;La>3f*V9=yMnztb-SWhdvx%*voM-F1o;De4siln-Xh#EP4eQv78xTVEM8PsqGD5 zYQb4t!^IqxihdjceU`i1tXAtX9{fP50JC{FKT`#iqm2&F1CJV2eyI3rWIdFivC+O4 zz)%#}Q|o|jNCK8fSe41 z!M`s2>>KLx-OijB)szYZl75xT39QbLZq>S++glfWxyx4TYIxP~7RGn!o0Qd|Xz4D` zA8ERiZnlilW5cND(*zFTvvt?k&LZOGW{NLQ!u76Vhw@;Ce3N|L<4 zC%>YpFH%`$;hhMRdOa5%k>dJLOpV^1LFxWwdS~B+TFJpL3U!}8-p zBH#9EZ`w9%Ieg9PYkfj;-ODYyzIpF>^4vU!1z$&m8k+ki7ykc=B10s+M*;^ji0WYXPM-yGM4d+@tMG8$#+S zm(NueGr#TeGUso&|2GLYnCcQ>59HFEUQm1Yt5|@Bu?`AO>;4ybRUp(4Y}gb|_6N7h zxM|H}B_+fEHv0?T-Ub5{jv2pj{EP+!ok2%)5&ntsD&RDDXq<9k^PfgLq54zmywXL2 z|A2LGfwcE&v6R5fKaJg5!HmK37A6}1arO85DJU&AGjr93e;U6;)7&`Ll!pEry#5O- z)(y<7@YaLOcHy5!d72ya=5L<=LBzC9jX9?1 zrdGBD`TuEjq`9%1{RsRgXe}10KUF_4uc7=;;|LAjb~mxW{s+p^hGV8r8)0F4nD;-8 zX!a?(FaHlsq>=z2a9dEn&O1|hV_vAnf1E-gB7gV%?=`r^{NWH&iZlb+?v1BNx38Us zT@5l8-Tj`F+>ReH`oizlQ;|P1Ka_KvVZe>r+WH)pYuGNvzyDdINOS`0I*J_ay$ItU zJ{f4935vSAWHuT<>a>=d2u1t#nYD%c(6$A&5ID>*qp{n=u2B>auda7dvfO1xX%FHy zoLwNVRp@Exaj>WzkMsqTV2YjPht|KQmz52grKh;z<*vL{pU)S7tG)N}IGOUhi$6)G z3EQ&w2w!s=J)d(C1py(89Co!%XXCPfYH=A<=K4=poSo}|mEL{IV{8KF4HlpOq2{0I zT+JXL;&$*)#BhBSJxZO9mg3z^4Fix^$v9lk*HsZ6L*29fb%K%NDMiHft=;?Ju8l_Y z@}W_GQKPVoD~Z|E%ly5KDu7S#I$LT55}(ULd6-#H2&VCXI|t7#utY<}yk;Od(@Gi) z+sRd&k1<^M+$UrWauVGE`=a^4&0Y&YSp=`gdjHr6;}GrHQDx?t+?x_{c132uMdbXMNNEV6vRH zs_cXon<2_v<6mTLZG96KhPvz&DdFE+pD+|zu&gXss#{HhR$Sx#_^R`?ljD{H045?! z7n@z^YIU-*9YZfTn|ZGE7(l0g;7R?)yu>Eeig0Jgt8;2i+j~6o4oFDV z^=e|zVo1XnNq-%MRC&4kqOc?=oeJodc}EYI z_QCdG%x3M%Ru2^2Gwb6itBq)>$iu>~bRIK&5xd*e%=Fm#8$QjBVwkl97rD>jZYrP7 z&iN+^9hwmlBhPK(TWgQhw3>fToJ};3-5cZxk)Vxhg0lL83;w^$|V5jTNEGK+Cdi%>& zb|Y3Cc)eGhhE)Za$Uq);Y$d$9{idb5F75_$ ztif6DsOT7@yu+YpTNvVFME1HU5Y8?k*Ov&u8nX9gDT?b0_> z0<{G@#j!Zq6pP|oqAR(WzgnlTX{MadsgJiJ#htMlPU_sQ(25=EpIdzDh4d^V5+=8m z02ecN7ry`iroP039y}KjJZR(MI2KE(plq7CT8-fkBSC56bmD z5yG^Jfd`kOGe1$8sqoGWPP}~Q>;jbonA*7W!4pY9x%M7)@gcGYI1bYs3@Gu$SWx;H zX89XPa!*pxEhy%l89{UM;nsA3tvgXrKu@E9vqS~q6-58?@^3wMr|v5X)wv4g z+rJeE{ngI%HFpffot&jMtCB`$@8%qGh7Blod{X(-eDhD~MDKO^LZ35NbCJ2I7qgEo zg~wI4lT|kd;m)yV2nV8X-4KarZ129WLE_fVS4dywb40!&0L<%zrS?8>7s&zYuXN_@ zJF`GeG8MH2&J9Seo6@!})4*{;&;w0_{{6)l__VO_m?W2+44 zmnWCq;H@H`iH?uSmHk$Yc6snw2hy6aS&|eKiQpuIIylvmNw-M$9daqj70V+-UXciI z^Y%JUoP2q?gr%DLxa%R{{wp zL}2|E(7ISe%^7YxH@<2;7z;2xoy~@SBQCYk`J5tnd`o19{`~;Z@18S}XBHXY)O%}n z&Ts=N4Kskux*V18Yi75qg!FnGmb;CsY`jw^&oA^AK1cOZnmg7h4C+eE%Kme_Tt-X$H|4&Z86w-b5eS0Yg2NEeXknsLNJ^0@Apn{3;`3apR=-dFT3uPO1kX%N(m6j$&3J&EPtNuhKzs;^6|s0JnK6swpdvUAVk>zj zPjeaNSyO+#a+2uyNRpx|?7e;Y+EKCzcVe=n=&UzdTvs|o=(P8-o5cirjr@J9W{wn@ zWYxvlFZ*wq6=>IFwZokp{h_Qu@&gd^1A*T@l3Lx1F4eh$oT5@5C9N9AvPholYlAQ~ zsvn#8@Sf)$|1Q?9s>nPr-VYM9_4ao=W5}p)eiD3caW~)xkjr^5cVe@x_M4yLV)7&% zla-d{q{+DpaP7)4iv6g$VrQpyic@qt&}rUR7n|GKCamD)cV1~XrDDB5zVHp+L@bO) zpa9=mgY-98(dABxK`Or{u~vT8C}`_gWJ;tojjpFPDJG(&)tn(Tnu&9w8mF9X@v5nc z7s$KJhk&=b<(167lxI$DbVx>Ip=}$orgK1tn=Apy?r6`TgHIUL8G9&5pVqgB>k%J4 zs7pn(Js_=rW3Cw$<-0@Moy_=P_4%(1;!MYQU3gBRhLfUe-XIKOH8LI1Xax zN>M=|M75Hi>j$4AH_?;3PD4S@^dA^FbaAA51ZH$K;NHRA4t6|jKFn~EY7qeRr-T!+ zipD?&9@x6zHI<$|E)|%;lQO9%{H{wq*I>Q`zN$n~at z_LfcDGG8)|PZ+11Rp-u-(Tht|_AjD8uZjK_^>(sNEu5V5`dXLxx0)=e zZ2uo{pTYL%r0-$f_WC!O7H=uKK!&ACjIiv#Th&W4{1yd_9Zf#F?QWs}g~qj6WXk*x zeehO0m^a8v_ES9SLFJJMOM7SnMV<6~1X#CgzU!FrbjpqCRvI|XlcgO#$ z1^5?N^Z&}g{xg`;ZMvy;?bQR~emLiO!I$ix{6tqFdmZT62j;Ida=QjyE|c`sdDUUS=VB1q3jc@W-L;1Bi)j>XnDIQ}-u-aX?J!&~Mf}+khf5jO~t>X7513}zhnu;__7o;zJQ4+*&Hf(-z`PwdM zTmG(HA6YU!Nm>;3_VuT>?|U1M6(zh^Fb3{TL>l(?Ifxkw*AE~Vj=UlDdN z&g?I7PSs$(yO0VRuOJ^H-ov@6R`}#tlELTgc%!_Z* z_o~FMTY)d$C-(S!FazIZq%fuz%jxFse>w80xg^nW?(KCOmIU+iw?mpE#u;fIwCp|Q zqJl;3+(d10uCs2y#0*T>=!WKXe_VO zZEf+_&)`wZk+*Pf@bT`yL@XS(jQevIQE3KhFr9Ww*)z*{VO@O}*(-1~0dGcDo$@M| z4|$;gm8Im(Stof$o9M)rca9!N`t&aqm2K7see8rHR4xE!#whb24nlDZ6^-R{kz^l+ zAG~%luVERJ@(r-v@hRWRW&FsgjB)4Rf@?*j^HfQXV+{=}$w1yQCx!8+?@2m}XT2ea zqlNe8I zmn=wdcOeZQhn|-t{VL0S= zg7LfI^|} zmLRWN#RVTdRmajcl?S%;aY-fck)kMP@?H_XSJEvvPzs-N6r^T(2zVKias9?KrBTZ{ z3a}b@4(4D0fb}Gew7DFBk<>1&;OEAj=q3@YQ`6A*J#HQ?|FL3Rq94rpLzc6-ac?$W zEfbflFl)`=OKGawXM%d}27Kaj_H&IGESV^wHUweLZwCD|P}(Yte!8*@HW03UmJw7) zWxs}hS`z$%2xWN!%b#~dO3&LM9n(?bg(4o)u!DHuTPrI!g zoQbv=9&_DRi$o9>f2q}8dZcU(`C(fikad3=#>p9rEj!Tts6wljXkB|4%W&}!3)~$p z`Jpl+5G`DNSSV`I1xGxS3ZVaT*_7qS@W~|^RNsmos;h#ZXQfq`VJy3+*O=FG`)Rf6 z9He?+rj_#IHVlIq!M8PTp&}wLZ-?F+`!U%|#l~8lRAHF^jvu|#C7~uRV>bfcf@H&z z4JFk!akrXBQj^VFf|8o1aGo&x-7h`8DeYw-w?fPC7eu9e@hE%@jGUgWu#}9vtheAd zYZ|DJ03raNN)K`s(GMGlebfn$0z_JKvPi3?wT#gps3j;y-0CFoqfwYD(7^<`*VcOv&tZqBWkDyoh>-8)253k+7l3jbq|{Yu0uq>V7p426cFb6ODE5_WNd8 zWC)P6Q_O}tI`%;P7aU--{UfI24+lVb%%<-u`rtld-UuQNgAyQhm`aY@K*^k0S+_F( z@Xq1g(iz(J*rtd*22qpOaQ-(a0+p|?#+dq`_qrZi%0BfOzz8)HcnHuRG=1`iyM;Ta zPb49FC5)NLs^VSod;BbXFOP`N1D>D*xGgv|AMGnSFuQuv%+LM*^zQLrJL#Be%{yyk;i)P2H_rr{I+00+M|!$I zxDzD?G3PjMksvLv#^$}v`kPcaS&VRFqi5T=U;hX5Z6{0B$hy_oKG1kT_p#^lr`f2V zWb@S`54C;3MmtE9m!$n_SC^_i`+%qv7+tKIRsx-Q5vV5omRyg|a3V-Kx>X-%B5^Zd z=9A3JV*)VEu1B0X0kTzrr*&fCpgC^;tj@s*fqlms0W{77@;c5Ba8P{;3@S5jLCsti zEM{|W$#0zgeB(E*5Gj3qBacW5|LGd7cAr|Dx{O#Y_Z7(~Nsi86g}H}jC@))l72XGY zW|3og#Cl}r&z+!_)J#;R7Xsp>N97wi(@hu6(yte(u+zlg37rad)6_+WBt@=;jS?SA z^15QSnO`#|Z35mZZX8M}8!K-kwg^_Mtm!Mu zEbAQ-k3sr_EAcxo5{PTwKseaJso&W?c?_8)hQth+1|mHO8M*nw6B264ge=99Dqq(g zLPkqZ1h>2HN#ZKlSK`1NgF*Xt7c56&?B#z;3=Ir@3P5HK?bU#(DXV(hDm)lqp%v>P zk}9r#@uu8|9-TNe%=DkSu0H ziUm;7*G87<1SCr)#xLiCyYFl8>|Z;I?XEs3St6T{7{6HZq!w1JZn2!0e;aHpgI3JI zh0;uJzfq0hU2o4AG!_#rse*Wz`ZQs5gKWP54O%C9vysue_VNm``!eLj^_ElhqPDE3 zFpXrR_g$bqF#zPf)rF7?^gH~H8#G;8}K+SM=7KoS>`JJ_+bV@}f zZR&2INv6h{7vN#Q+6@}>>>x>BCIEAEuq6{SQC9nu$AkFJU%g{Iu)Gqv^@E`ZAx~tL z^DUNEZ!yZcqs@)k}(IX^Upk`>fgq?v~uT`YEqkp@0B;q-Q zmXkmVYcE;PA0_OvV3T<=Ufz~npzXnaorO}ZE}`Yzs$iek1~efeCfP0T1@?{e^1WO! z!sw5#pRv?Xs#y#?Hp6kF@8{Lc66C;4S1;e8w7p%pJsG;WU8_ps0N~>;E8mcS&6db? zdPb?U9>SSWNBs>y$_fUohg&m%mO0iKeI0~nCz9~-#E&V_cPZ zq(lj1fU1~YgwR)7n3{(T9OLla`#tWQBcgzJzs@GZ7$%njpV-dd;6(c1_iS&Ytp=9L z31Jn$z;}-Ao^pFj6iy@@nfq(T2FX%ZwEN5EHO$`Rs^3E|lf&0k!RBXICC<#`pj8`| zhrwl#na-`g1PyyUa^!||;Te!cE=JfU*GIfOSMdNtC?W96eS_#3=^GT_hMSQTiNog* zDK%I?r|Pchy{zfUE%s(aw!$9QdWxJ$SrB=8X}t{9QHN2rKK}E0_XO}sLmwUGb^7S3 z&W6&=thRBVyb4%CtM9{$yJwZfAHPV*I(lJyl|wMhMEi<(W#nL@gK@{;iW$3K|Kd4P zJ~{S|Nv*{};@vQE>YFR#%YXl$cJg>C77-T6QyJpuh&W2@k5y8bONPe83OgGr?hph! zb@q(si)iAL4$#ITSfvY9P zk@MI=+amE*h|4>Ci)S7oBjyFgn0UT&tSBgHuinOkRgPLX8+v5pfZ@{$SbzD&-Z>gc zWEpTSDzuU8AK*-%n&u_l%)Km>dKF=s&BIaQ0pAW`rufap&^Wu_Lft$@Sg1UP(eVR)AU=EXO935v}jdkc~z;?jZl|ls262k3Gsyh?PwSj z{q{%MfP3pm--s18xpSy7xUu%yq>G$uI*;og6_Q{jHFvF*@Pm8Ai%#=+9JzE z4vL1sBVa0|?qTE+nS4^n4zx4seM+nYo)k^e2tgMay_y4feDK{{HM($ZkD@*4$44uVlovJCS7NSm5JT!V40l8S#B^W*S$ogZV)UvwCNo2OaC4oX53a^4j$)g1(~KQDvg+-ISog=3YZ9a-JEwj`>`L=b4KR zf>SBM9{kcOVKi3zpfTdkKS?3=DPDS{8vPF5>imDTF#kHT5K>JObG$XKeL_>c|4VK1 zS7Q<)NYjj*o3_6FPu0iT-=h!ayANpcg>HdEnxp?{az=Ott$+`dWL5t`A5AyG_{Ch_JKg?u(S11T| z<$p9j9l{&AJ>y={d#Db{%zQa~3%*T!@npfwja*|DWe8Ylmk@n;^a6LWotxp9XA?1f zLEzsj81jMv?EKYu*}HJ^AW(7@m!v7bo)Fq0 zkm~YSj9G80X-@*9@%)?lUJkc%+@;xDC-6!BGu3kWF6db^C)urdZ^g;`%_XXy$L!~M z%9FdEju-luY(d`RBg|2C12*V0lAE53gs&vla>J>T`D?REe#0I(|NZ&MrUIS)bD|az zcjDU%__XB09w2)8XTnI2qzYZH^jz9n8P00S7tL$TZ?&AH!>@m6GQs8UqsvWfNwiJ6Gc1e` z0@UN@cVF~&;!WRVu2VFbB439)Gbw+p zUsbSew`>Rg`H8U_GfCkfACa}5gxVBZM!k6qWGlUL(!ODhlucH#h0^MHh1b?94vKpD z@69dn(XfpuRr&$@8Em27!vt&uF3HfaWBAxrd5)LIe|W8o_nRrtmjNrCp8~+e4PXK2p(L)X_Ie?`+mx0(=Mu5_PP#5jb2O z9-KLC2_Bp9_~pD#h$ysYEz=^L5y&dH*xvln{v$Kjl#t}xzD0V|*|zySP?838YGo{o zt!W2FFrN~&!f{0y(61s7)Pke-RlM6X`7J1ckWOJcH@`<85qWz~`E1!Z2TYmBENC;BJHznvX_Z5r3Po_=U!D z?tqjxjS7_-GDy+~NLsQ8+oq9MS}>^FEvFyW3uXHmHpFyN*N;ZKqMqI4@-Z`*a=Yp- zLJ5o6RUGY~Y$@YZIEb2sl$V*CR6|Gq%FvP~(gIZ$XH6jmXOcZlt5G;TFk}%q=G0l3 z^k;U}>xAjESFj3x4ArE>xI?Rg95R_WmmWUf(WE%e-w|&H3nXRdrJ2H=Yu3~x5%wRO z*cm1sP3?#Rs-+)+lna8^HOIF`iKsjQ?b(>(lAiCw8Bs`ko~whd;Neq}aA3epj`plW z5J*ahwwz#iQDt&!vZIt1SllrHnz9YFejF)Xr}-Wz;PASd_-2{81M1+poXNfz>hIM3 zec*Sm6zqYeJy9hVRym%LU^_92rae{0{c_vJoca4`mQH(f&=D^XLYBdX)%P9dB~FGD zi!b-(O!OF_U4NQHHDzM>qfw7$80pzVUeIbzqD3B0BW@Usj$d_#Z=BcWCu8#jcYTfU zU^03HA_1caN7GaqD?x-!=FGo@htF1DpW0WP*Z9g9;<=hQSILp_AlC`)Y!72d93z1E z``J4PxccxnTFD~Z5bqzJJ)eUna9rr&sVmAzeP8d$pu6}=Ulo4AaPh5FY#+sUX1}O) zz7F=7$Qr&b$)!h>vJjsggHIx>j0sz}>$Ld+zSkbf_B>IUTPWIWz%8=2BpfSV{?&et z{^WUv$sj!I*yy($>tF-2%>Hb|rcB5v)N1#5GSq&GmNQgj)&DqQtgkvq{DQ3Lj#(00 zrovjM>W?1Pi66k2Zh&G5r8fB>$*|r7RvtY?Z^TKZS4jG9=2B&{8~H8fev)vRaAF7W$ zFNvRoaR|%?$t4<*S+f<;bllMSX5 zbON#*OErWY=dZr=Sz6C8syFf^jpW8j; zcy9nWeFK4XF2{}V+lP-@L3nY5Vv%wi4vJwinB>L}jRlZV|rCeXAff*x_BusYc}ez2A@dQLv9V zDoq2w@fO*$gRx7WwzhdAr{WUDlRk936R4+R082XHwCt)hsZx2HnL91%(>e1I(Z~Rz zo>z}{=;HduL$%s&25W?QW|0{k&1A01pO2?y7+wrTus0Q1RUFaRXbNS%kO@P8@8$N7 zH~n`h8|XDP*4t+8tap=)Bx|i|=|G{xJE)mDB;#?v=G(RF>$}}Mn4O3PYpGUWXGveM z1MzarXs^{sukpmqiK21d_B7w`?T_J%0lT!~jOQ=%ptcn5ZfYzixKDgf2w&4ylB|7Y za3=2vSlv_eK4u&ujxbU*g=_i3L`KtiY$;HDnTTh!K5Pu+r}utAoRq|^iZ+pLcJ3*d zFIqMvW+T;9ikG>}v5RjbkI{@-PdHk2+Ghz>-#mP&E?qR1+lc9Ltip+GgoI*P$yC=& z>6TJ9Xe<%u@f95S;D53A-Cs?uUAG~CfQmE)1*It>(o_f#I-;N=prVw7qM)=;gwRU> zQBmoLfT1c)B%w$sp<4hcp_4%9EtJrE&)s;=`QG!6`v=@{$M}BT*?Z@y`&nzQx#o&+ z5PHr@^^l|Wm70X>1VF%j~w*1Yd9WP;LGw@&Bvdxw~NH|_+2}Y3>w^Da&(K3 z1+P_Wym}ZSG9tXG^tQxlWvKI>%ubxDNlqjG=TP^%0_OvUv8uqybzWqW*d|WG`66^|2 zFH$~s*@O>bR9dNG-rbZ79z(u5vi9!L&b<4nrTX#6gm9B^5RkzhNe-s4Zf!LpdMN@`{=;Y+M&ZAN`Q^$r7W4MKuSbbnE0B~ZyaM7S^){3 z#$?5L&wsXni6SO5v9u>1tu=9R5B8#q(`T{0-%B%Va6>S@z5HHSxt?9qq}|L(Umfai za#CD$VN6_i=?5cwrPVUS?96;($aKkGOH;0v{?~LHf<%>wT3m^2WK90K)zTU4la*gd z*M|(9EXNBQ0D3p^+*%R#!t<2?a9(T~K_aQ3idBm0OLEd#xhFWvxn{E^m>r@r zq5B!~zp?`MAo@kg0I@T%NIE>ZsZcJmf8D#OD5K6&6`w;1qidhw9V#X?SxH8-)`v^tCqkPS$QvuLbEN1 zG@G%Tn~sVP>PNRql-v7nrvcGJyA$)1^Ph8OVqL`95N3pdJ1626$YpVCjrl}<*3cwf zF_crdTnQ|fTRseqPa<;5X2Erk_POU$Td@~I-t*ebBu;AQS`oG+SVhzhPx(G<-PhpE zE*MFvRAw_}z+;yB>~wySt8#K^rev$okQx?B{BghlE>fjS5PX&x`bf93X;JP9ADAWm zOp^6hZ&Y3dd-{MDse;~Byzd88?b%#u)rx%9avWac^nq#f z{^K$3qvBHc^J{t=BK)NlecdN|7f0gi3sfT(2$JE2vt`<;JPVM!J}bG)R072i8vTwY)K^-nipt+}gDWOzoZ(Hf z)Z<|w83#xc;t3)qw&e**JYcD{xLM?2DY`nlxmJ3>-2UzI`2VjKD7Pul;y>4e7I!HcpW0F#h^$P)hViwQS?jFo zYY$p??A^!xJ{stUJI|gQ5{oXe3SA{Q6jwU6-o8wgl-7;3t@>CTMw2jK*3RjJ zFj+*smrRe{l3zUHBK_cC3eo_ZB9GAN8KYL$r*ig@2IgyRFWa;r*arz-by9tT z3_BfMdl@WW#gT7W(Bym!o@bK#_3yR&{PyEI`oIsi&57S8L-5Wlwd-*HvsH=e%|JAe z=9Q0I;*WeClFgA8kYad$1^=SG-@G1eF2P@bmjJ)&hmVWZBH7HMJ^p(RR1w-nEUZkrj!5r3p;_*jz_$n zJ6^GKN<_8709;bW=OmuRX~d>U-X4RXlbf9vddOc%kR2R(VJTPJ`sRbb7l$4=R{(T_ z7%qPhu-`7JzeJ9on4Em(pDmPqHQu1L^=I#*+Kq{|5=x~^e9}yR)eIAw!*?93UzdDTMZ_Vk+X7Y9Rw)1)Up`Hx0!uB^>bbXn` zX(ncgSzGu0^2jkq3^pYp#$g_Y=5{H$kvfW9Tbd5upe;HZ@wJ?rw~`_JaB?OTvu*n2 z)9WUv!)Zhhujz0G)V9Z!bycV|8Ln$^`==P8bf#FLgulg{)8Fw(tu*f=~^w z(LwUctCYz4b|l#6K{pbNaxXTUpZ59^nYo-%9V3NMUC37mNr4pRcle7}PvaN@)m z)xY(l0-V*itK|_^tzUn65Yb7gkE~Rn*iOss+*LfJtw&p zEOg+jlH?DJvi0`ub(Q@sYbSAB{t`4dB*o{w_vL&tEPhUJ#(6&Xy`s)>xa-H6ToEVx zit7zWQ*)f;8RpY} z)Lo?spE__!vM0H=NDN-fn7Qrl%wfflGny(zi;N5!&I)FVgb)ie9&?o}Cr$b5=7$Zh zG}#f7yHZxfl6g{aCAN66e6{_AgiI5s*RK0LKc2nRog8L;~4u9qIOPA{Hx{j8>PjD z*N2Ccl-3(Ezm=tQo}@O~T*(PA3doO)q zLiK6BSt{i#-(}xmk^v6f#tU|UqU+-;NwDSts@2OBN$q#iONz&7+B27xk+y zszUO)R4nT%!&m311OZ8fL`tPafZ@h1q{{G~PObRS4%5J(_t(2Day8)6G4}pzztv8a zY9q?Ey3Ct(;Lxgm*T{7=z4wh=t1s9Nv%aV*p#}>PW zk|F^l7U33BCgbO~NX4dtY(eyo`;COd8)y`K{c#Xt!&= zJHz6?_VO%jXK+{gM#%(cf69)3bm@AVSnC67A4bL0$Y$zfDpx)^fGP?yq&Hz5s&Mi! zAhdtlE?5yDXoiZRjOx$zNK$QVNq%!JW?fgBY;8_x=iE#X@;`IKGUh)okpr(UXZvjp@y2OXxJZpS>p%I*kWx$j#mTeW!O7$- zy${HHQ0aYf1RrUi_bFxFH*c2@cbjIca$~WD3Jyi;pJXe}X>1H`<*&|!m<8;IGX-)I zou{xh;k($(;qz36FVLVp>(}2ngYp(RW0Mqu~0 z;W0#LVo#$fIJXbVSYw{Arjc4apV!P6z+#L@71ylhTQ$~?c-xfV;br@k0I z1J?=Ob1owXy!nvV{|VA6A1=_=Se=#aX$An2g_+vT8kWt{1NOxqGqH90&is;B4FO+S zB*idz$h`nh-O|p*9(ijXr(md8$mY23knGapWf5x8Ib0zXv2T~E52_aCs3m)9NN!oEZ1w4^ zH@PUreI0ZMXSj@8ZD+P7wUP^aNelZA)6ZsGRX~dCn`c&rVB?STxo&MAIoNsU zYu!0ed1>=2BDRg--6$W7i!ZILoard*2~*o<6ZgtD&`S-Qtk;wbS?J$l5PW>L|HP?J zS8+YZ!}CzrYD{QS^WtSXbRILboL&K?B3I}qm5C>l&mS1IXFEy`lF{g8GbmyQF@`{h z)S%ZPXMG$hX8|gt`S?|7U4y&>GTCgHliUO>MZea;KVVfT@BJ^w|Y#%iFOW1m&VJQE0q2 zP7x|G`1w1Ugnkykp@52P^{Sd1{#@}ep39rLrh_-BQ<6NHIirT9GP!Tmpgj;DLR7!G zk)D%?BusH{SgUu>I<8W-H71)#uY%CRuVYHxVB71zzM5FgbQp(PIGVNbF56(=Z^y-F z>H2j83N0jzV~5GN9w3eL)wZ3_@D59D4Y;uh%Q%3}bqi>ji`|GW`{wa9_sy;=jnLcV193!5hvGrxxx^2_|sSArDH+w8JzGZ23%3C6mOlO3SY06&A-X| z-qq`LBRm2Z>@|pF{}&Z5g0``ay`?`$WD`}bDIeMH3AwMixN0p;eW%PaaSFoq?RW{f z0ntZ`Q)g{1i^QqjTf&lLv?2JGYJ9?n9N_ra9*jLCiVa*!|48kCzPC=y=iL};4dEqR zW!%nkr=q?5J!n9rJ@&_~L@UK<*^$@d!vVi;(Z;VWdS|+`-%WvJ`=}r!i%row1vSv@ zsNhYgc-y_{Mv;0L4QX9S||Dg@Q8^A&BaY zu3%&zhc_e$r`9>Hpt{f5^;iHbExJ?`Kc&BO_!-jUVwQJYW`&(r!iI0Dvi#cTSVY*5 z4|O`62IMNt4}D~wQ;81&F$@xez0<^X@IX5w=VE`!+S~R|Mnk0YPmc!)1L-hd-Z1}B zWBkcrJ@k^W21z=7qJ(pV5+LsMLSqCExa3|=j*Z6wn&r*M_2Ik61**TKS)Zcwd3MTV z@A?Sc;qU4kw}Ez-y{`SO+xMG{010(pxYtD=u)TE8%I1hACm=K^M~7k>>01|30)|n5 z4iC-UzkkAMVy|Zr_qm!XGlu7j#~#|ApSvB3OQhfANsnfn8$a%I0Po zZ97h&uf2=jdhs{k;W2kmCn0Nd@qo5Wf5R*AZE4XKX2oF49Bq+#tcHsPpaUFpPx{Se z^v`I9aecuxk`dwa{jPZvWJ{d?;Rt6lE06BvObXt0_7P}bDH97Z z@Sjs%0C;X0w{iKWuNS;+_)!hvaWHh2WX0pJ#5oyJTekHfzZ$-)hP@gu=&Ap?*NXL< z%FxmeCrAxy==9pV{PgR!_fV=2e(fesLq41NkoPuH2cbPRZajkuUv$$|$TR7;;@ZoG zHyhdWMcCvQ?)9`Vn&BPo{GD`_4Pk0lsu4VkzG_UJ16K1g8wNC`NXUjhe$?*{zmo3@ z<51=nAdgi_k*vczgl@z3`^T)!b`j@^(#Ii^*Nou7HGaJZArcB}-&_kWB#)e<;_sJc z;a_K#7$$UMBKwLLB7YHydEEnCMegCsvb0k0$_*!tciiyie4JEE8`)k_cF@Jt5!(yg z>>s`Whr#?8i7B&Pu28IakBQ>NNKPS2B$qLO+=ya5gpC^)mHT|xOvulivJcX3Hm7GE z5p|1S3)$}6kefGOCr)?z=-NLls(z@0KwT&)@yMhQ6VO$4hVY_m`S;FCdPJHdbl=D$ z`qPynRLWI1Amz?>cFR@i7I%DbrpmVBc9Bz!=d-?7>wt?;47YUjlvreUuMAa4VQh9k zs7p4#=jnxoTNJGnc@}N-o%CG0=X@NiS9M@rYTF?MAkx%?;JJGAm?oM%LgPjwlGgaK+VuqVN-JksYQ_@Sy{J3-LGe7iSXxl^q>)QwC?IG{Ka7dwDVhdKMlruJ;mJq zetLSW&hMExN8Q$3WJiKedx@gwUL;4mk9IxwK#UNXQ~r28f(e8LUCTSQAPXd{!dqOo zC+Z~xDyCrT#pJdY(O)Gy(B77?(0os>_MQ0>^9tSk?7ZA3+3Rm7?iZoltK+JB3YUkq z)$Khr7i|@1@R8tFU{mJ$E6d)}OMT>*k4AcThpAi@XcXK3`XnfPIAq~baYw7W^VF*> za(TSS(Q*<-%RwYJVPDVuGTpKO#TrVDLQ6<-E%ruyBZ0?E*ncCuKp{l`*2 z96w9rp77jRGHj=^5Oeb>puj<|#Oxq+We4>5Ee0B-ZyJc zu@lylM)S-+jX2wVY}S;WgSG=s)uUVAWs=ZynD50=+($QShdY;W$RADaPd5<< zoCsp-_+`F!4In9Znns@n33-$2c!HokzhlS_Q*J|J&)Q5_ZCj|=%;;O?&%Tw_Yb*Q^ zB07j}CK|_ECe}@?SrT zP(*CmA#Q3DcKEAQ5KbLpcsrQNG6qYB?~dUu4K-<~;*5mfAA`gVT1^@HgYO+HDY>U~ z^j@xaNSu6~?WolLSdPum!|Z<7o}G-$VZBMe;Cc=@QRf3~x8ZMw)P49`Iu`)2Ou#;x zOCzm{56qvH&eDxEvOD9;vP54^p>g(AnMZyMbTx$KmhCqpkx&v5#zm-JKdbm^5~mkF zd?~UfOfdmh9Xo7y@V@gG!4eD;@SaVL;dV5yFUHpy`{M-w@fxhgg`Y6Mv&FF|a{x3d zZbBSZR5GrW3>8mJiX^KxW0O^~>}oX93%+#Bh-vGDLgXtJAO{jEGp1iO75VLB`Ph&U zm?7DgJeD9-%S+RmPEh4cSV?Vi+{ z{~XZQ3^>2?+_PGQX5QSc!YdBjdN74TrJuU+jW)ZKJ;jwDYrc z%6Y3P>6vYskzSaY6S}2^q@C#!jDsT!e% zxYI=r5G(|ZE6zs7Y{kj3?c507=){q_Z>)M-CMoOP6SbD7%TEQliQ>FIdAyK5(LZ-k zax6P8ZK7~?@eAVWnE?JEcxwoMvI-)_Xw=i@p^wF9?V&+|r))tIK?ZCfB4cRiqmqaD z=VEKpQ3!ni*mINvjz#8%puir!?-vI*Ft>q|3V=LS+f)$!W-aYj5mb4Lelusc$Nlj_9|_z=0L zurnw5Lai3d6*lJlbqvlnH;I?P@fPWjp1vaMXD6V;aaxVpvZT~qGJ9whS)P^ zVU?J|C8_G!uPVg!WFuDDgG6ic%2fqM`L}&R7f4%n*zMCwEwn*V-UEiv-GjT6CN9e9 zx8=vtdkk|H?2OrwG{s5IIddv2UlB)MWv{m%zql1x`w*;_I6Duwadmm8KZXu{2uRtgU@3hemRd zty)(^V*~iv_R0caMp`k@jP)K}Z)G8-qFZ-SI%!kdflddBQ}W4S!-nt9GjE-LzT$Ve zPKvObZjwL!(22}?{oc^m+zIKe^-4#Ax0aOt2)Dw7)4{Wath3IYyk*(_q7zY+UoJuF zZS;X2Kkj@P3VpIze%+@lt7@iV|7r4fYtYbGD!c1LNQ&KFXrjo7nM|WeDU5htk z`&$q-*_EyXBBYPo6idw6idTz-FeBpPay7u!u-5GJkHOW8_r+6eR(&eeMp;*@rEDiJ zZpc?dag;vo)t0XYcoYA}cHby^><&HWHw+gPcyQRNSa{3`w=#fb1VGo*f6L9m zIT7;`0#!)tjy-Dht5GwYwBB8l#&A5o%SxjkGe6^Zq1up%jcgCGUH@XX*t5V=yxc^5m3No`?9VjTNLV3On#qa@ zA6mX=FQl2#Quk6y`AX}J-D9VQtpQjH^Y;nK}JQpac2I{V4 zc|^eF|HB1PhSJ1&&qN;@!zaNI(sPr`H8`4Qowjnzx@y*URY1T|Bq&ZFWH0^M=*5*A zQwK58Pg+m@X_4uzz(m@y(AQ6y)zc!?n?*rH`r59V^OloR6R9Zy7M_Ji0V6z+4V;Pa z3cr)L3W+TU0x{$Xwy&_%o?;OKe8)rgDvJGdmA8Od>hDn?-7m1#1T4c38hZZ3PcyA-HcUDvAAy=Oj zn*pNL@|?Cnel zsRF?zE;_3Jv}pQ|R`JDiTOyCE#I0pNEF^#A1$U>teo#S}OfS|^4AaBGwU&>j~+JQ#8y6s~Jsyhga zAiv=8t{~Y5R+- zhuk|!;$O`-`hKclmWK=`=L!RB&jAAa@n1h6?@@5xg=|xH1s@7Y)d08>uPS@DuQT

              -Ky)qQ*n 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 W*SibvH9)|R;U$xcCFdRg`9A Date: Sun, 29 May 2011 17:36:09 -0700 Subject: [PATCH 163/176] Action updates --- src/libs/cocos2d/ActionManager.js | 26 ++++ src/libs/cocos2d/actions/Action.js | 66 +++++++++- src/libs/cocos2d/actions/ActionInstant.js | 33 ++++- src/libs/cocos2d/actions/ActionInterval.js | 74 +++++++---- src/libs/cocos2d/nodes/Node.js | 9 +- tests/src/cocos2d/ActionTest.js | 142 +++++++++++++++++---- tests/src/cocos2d/TransitionTest.js | 3 +- 7 files changed, 294 insertions(+), 59 deletions(-) diff --git a/src/libs/cocos2d/ActionManager.js b/src/libs/cocos2d/ActionManager.js index 0af266e..14871f7 100644 --- a/src/libs/cocos2d/ActionManager.js +++ b/src/libs/cocos2d/ActionManager.js @@ -96,6 +96,32 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ }, + /** + * Fetch an action belonging to a cocos.nodes.Node + * + * @returns {cocos.actions.Action} + * + * @opts {cocos.nodes.Node} target Target of the action + * @opts {String} tag Tag of the action + */ + getActionFromTarget: function(opts) { + var tag = opts.tag, + targetID = opts.target.get('id'); + + var element = this.targets[targetID]; + if (!element) { + return null; + } + for (var i = 0; i < element.actions.length; i++ ) { + if (element.actions[i] && + (element.actions[i].get('tag') === tag)) { + return element.actions[i]; + } + } + // Not found + return null; + }, + /** * Remove all actions for a cocos.nodes.Node * diff --git a/src/libs/cocos2d/actions/Action.js b/src/libs/cocos2d/actions/Action.js index f599145..3cade20 100644 --- a/src/libs/cocos2d/actions/Action.js +++ b/src/libs/cocos2d/actions/Action.js @@ -18,7 +18,13 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ */ target: null, originalTarget: null, - + + /** + * Unique tag to identify the action + * @type * + */ + tag: null, + /** * Called every frame with it's delta time. * @@ -144,6 +150,64 @@ var FiniteTimeAction = Action.extend(/** @lends cocos.actions.FiniteTimeAction# } }); +var Speed = Action.extend(/** @lends cocos.actions.Speed# */{ + other: null, + + /** + * speed of the inner function + * @type Float + */ + speed: 1.0, + + /** + * Changes the speed of an action, making it take longer (speed>1) + * or less (speed<1) time. + * Useful to simulate 'slow motion' or 'fast forward' effect. + * @warning This action can't be Sequenceable because it is not an IntervalAction + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.Action + */ + init: function(opts) { + Speed.superclass.init.call(this, opts); + + this.other = opts.action; + this.speed = opts.speed; + }, + + startWithTarget: function(target) { + Speed.superclass.startWithTarget.call(this, target); + this.other.startWithTarget(this.target); + }, + + setSpeed: function(speed) { + this.speed = speed; + }, + + stop: function() { + this.other.stop(); + Speed.superclass.stop.call(this); + }, + + step: function(dt) { + this.other.step(dt * this.speed); + }, + + get_isDone: function() { + return this.other.get_isDone(); + }, + + copy: function() { + return Speed.create({action: this.other.copy(), speed: this.speed}); + }, + + reverse: function() { + return Speed.create({action: this.other.reverse(), speed: this.speed}); + } +}); + exports.Action = Action; exports.RepeatForever = RepeatForever; exports.FiniteTimeAction = FiniteTimeAction; +exports.Speed = Speed; diff --git a/src/libs/cocos2d/actions/ActionInstant.js b/src/libs/cocos2d/actions/ActionInstant.js index f5b4a64..532c4f5 100644 --- a/src/libs/cocos2d/actions/ActionInstant.js +++ b/src/libs/cocos2d/actions/ActionInstant.js @@ -27,6 +27,9 @@ var ActionInstant = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionI update: function (t) { // ignore }, + copy: function() { + throw "copy() not implemented on this action"; + }, reverse: function () { return this.copy(); } @@ -90,16 +93,27 @@ var FlipY = ActionInstant.extend(/** @lends cocos.actions.FlipY# */{ } }); -/* @class */ -// helper for actions that must simply call a function -// Implementation of cocos2d CCCallFunc - var CallFunc = ActionInstant.extend({ callback: null, - + target: null, + method: null, + + /** + * @memberOf cocos.actions + * @class Calls a 'callback' + * @extends cocos.actions.ActionInstant + * @constructs + * + * @opt {BObject} target + * @opt {String|Function} method + */ init: function(opts) { CallFunc.superclass.init.call(this, opts); - this.callback = util.callback(opts.target, opts.method); + + // Save target & method so that copy() can recreate callback + this.target = opts.target; + this.method = opts.method; + this.callback = util.callback(this.target, this.method); }, startWithTarget: function(target) { @@ -108,7 +122,12 @@ var CallFunc = ActionInstant.extend({ }, execute: function() { - this.callback.call(); + // Pass target to callback + this.callback.call(this.target); + }, + + copy: function() { + return CallFunc.create({target: this.target, method: this.method}); } }); diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index 5ec0b63..6c09221 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -66,6 +66,10 @@ var ActionInterval = act.FiniteTimeAction.extend(/** @lends cocos.actions.Action this._firstTick = true; }, + copy: function() { + throw "copy() not implemented"; + }, + reverse: function () { throw "Reverse Action not implemented"; } @@ -221,7 +225,7 @@ var ScaleBy = ScaleTo.extend(/** @lends cocos.actions.ScaleBy# */{ }, reverse: function () { - return ScaleBy.create({duration: this.duration, scaleX: 1 / this.endScaleX, scaleY: 1 / this.endScaleY}); + return ScaleBy.create({duration: this.get('duration'), scaleX: 1 / this.endScaleX, scaleY: 1 / this.endScaleY}); } }); @@ -324,12 +328,12 @@ var RotateBy = RotateTo.extend(/** @lends cocos.actions.RotateBy# */{ this.target.set('rotation', this.startAngle + this.angle * t); }, - reverse: function () { - return RotateBy.create({duration: this.duration, angle: -this.angle}); - }, - copy: function () { - return RotateBy.create({duration: this.duration, angle: this.angle}); + return RotateBy.create({duration: this.get('duration'), angle: this.angle}); + }, + + reverse: function () { + return RotateBy.create({duration: this.get('duration'), angle: -this.angle}); } }); @@ -346,7 +350,7 @@ var MoveTo = ActionInterval.extend(/** @lends cocos.actions.MoveTo# */{ * @extends cocos.actions.ActionInterval * * @opt {Float} duration Number of seconds to run action for - * @opt {geometry.Point} position Destination poisition + * @opt {geometry.Point} position Destination position */ init: function (opts) { MoveTo.superclass.init.call(this, opts); @@ -365,6 +369,10 @@ var MoveTo = ActionInterval.extend(/** @lends cocos.actions.MoveTo# */{ var startPosition = this.get('startPosition'), delta = this.get('delta'); this.target.set('position', ccp(startPosition.x + delta.x * t, startPosition.y + delta.y * t)); + }, + + copy: function() { + return MoveTo.create({duration: this.get('duration'), position: this.get('endPosition')}); } }); @@ -389,6 +397,15 @@ var MoveBy = MoveTo.extend(/** @lends cocos.actions.MoveBy# */{ var dTmp = this.get('delta'); MoveBy.superclass.startWithTarget.call(this, target); this.set('delta', dTmp); + }, + + copy: function() { + return MoveBy.create({duration: this.get('duration'), position: this.get('delta')}); + }, + + reverse: function() { + var delta = this.get('delta'); + return MoveBy.create({duration: this.get('duration'), position: geo.ccp(-delta.x, -delta.y)}); } }); @@ -498,8 +515,12 @@ var FadeOut = ActionInterval.extend(/** @lends cocos.actions.FadeOut# */{ target.set('opacity', 255 - (255 * t)); }, + copy: function () { + return FadeOut.create({duration: this.get('duration')}); + }, + reverse: function () { - return FadeIn.create({duration: this.get('duration')}); + return exports.FadeIn.create({duration: this.get('duration')}); } }); @@ -516,8 +537,12 @@ var FadeIn = ActionInterval.extend(/** @lends cocos.actions.FadeIn# */{ target.set('opacity', t * 255); }, + copy: function () { + return FadeIn.create({duration: this.get('duration')}); + }, + reverse: function () { - return FadeOut.create({duration: this.get('duration')}); + return exports.FadeOut.create({duration: this.get('duration')}); } }); @@ -546,7 +571,7 @@ var FadeTo = ActionInterval.extend(/** @lends cocos.actions.FadeTo# */{ startWithTarget: function (target) { FadeTo.superclass.startWithTarget.call(this, target); - this.set('fromOpacity', target.get('opacity')); + this.set('fromOpacity', this.target.get('opacity')); }, update: function (t) { @@ -554,6 +579,10 @@ var FadeTo = ActionInterval.extend(/** @lends cocos.actions.FadeTo# */{ if (!target) return; target.set('opacity', this.fromOpacity + ( this.toOpacity - this.fromOpacity ) * t); + }, + + copy: function() { + return FadeTo.create({duration: this.get('duration'), toOpacity: this.get('toOpacity')}); } }); @@ -589,12 +618,14 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ init: function (opts) { Sequence.superclass.init.call(this, opts); - this.actions = util.copy(opts.actions); // Duplication? this.actionSequence = {}; - - util.each(this.actions, util.callback(this, function (action) { - this.duration += action.duration; - })); + this.actions = []; //util.copy(opts.actions); + + var self = this; + util.each(opts.actions, function(action) { + self.actions.push(action.copy()); + self.duration += action.duration; + }); }, startWithTarget: function (target) { @@ -620,11 +651,8 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ } else { this.elapsed += dt; } - // Required to prevent array bounds index errors - if (this.currentActionIndex < this.actions.length) { - this.actions[this.currentActionIndex].step(dt); - this.update(Math.min(1, this.elapsed / this.duration)); - } + this.actions[this.currentActionIndex].step(dt); + this.update(Math.min(1, this.elapsed / this.duration)); }, update: function (dt) { @@ -647,7 +675,7 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ }, copy: function () { - // Constructor will copy actions array + // Constructor will copy actions return Sequence.create({actions: this.get('actions')}); }, @@ -706,8 +734,8 @@ var Spawn = ActionInterval.extend(/** @lends cocos.actions.Spawn# */{ startWithTarget: function (target) { Spawn.superclass.startWithTarget.call(this, target); - this.get('one').startWithTarget(target); - this.get('two').startWithTarget(target); + this.get('one').startWithTarget(this.target); + this.get('two').startWithTarget(this.target); }, stop: function () { diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index 8573b4f..dab0ea1 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -431,7 +431,14 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ runAction: function (action) { ActionManager.get('sharedManager').addAction({action: action, target: this, paused: this.get('isRunning')}); }, - + + /** + * @opts {String} tag Tag of the action to return + */ + getAction: function(opts) { + return ActionManager.get('sharedManager').getActionFromTarget({target: this, tag: opts.tag}); + }, + nodeToParentTransform: function () { if (this.isTransformDirty) { this.transformMatrix = geo.affineTransformIdentity(); diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js index 8dcf2bb..cd2d936 100644 --- a/tests/src/cocos2d/ActionTest.js +++ b/tests/src/cocos2d/ActionTest.js @@ -4,6 +4,7 @@ var util = require('util'), Texture2D = require('cocos2d/Texture2D').Texture2D, + Scheduler = require('cocos2d/Scheduler').Scheduler, cocos = require('cocos2d'), events = require('events'), nodes = cocos.nodes, @@ -13,7 +14,9 @@ var util = require('util'), var sceneIdx = -1; var transitions = [ - "Jump" + "Jump", + "Spawn", + "Speed" ]; var tests = {}; @@ -22,6 +25,10 @@ var kTagSprite1 = 1, kTagSprite2 = 2, kTagSprite3 = 3; +var kTagAction1 = 1, + kTagAction2 = 2, + kTagSlider = 1; + function nextAction() { sceneIdx++; sceneIdx = sceneIdx % transitions.length; @@ -49,7 +56,8 @@ var ActionDemo = nodes.Layer.extend({ init: function () { ActionDemo.superclass.init.call(this); - + + this.set('isMouseEnabled', true); var s = cocos.Director.get('sharedDirector').get('winSize'); var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); @@ -103,6 +111,18 @@ var ActionDemo = nodes.Layer.extend({ scene.addChild({child: nextAction().create()}); director.replaceScene(scene); + }, + + addNewSprite: function (point, tag) { + var idx = Math.floor(Math.random() * 1400 / 100), + x = (idx % 5) * 85, + y = (idx % 3) * 121; + + var sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: new geo.Rect(x, y, 85, 121)}); + this.addChild({child: sprite, z: 0, tag: tag}); + sprite.set('position', ccp(point.x, point.y)); + + return sprite; } }); @@ -117,23 +137,12 @@ tests.Jump = ActionDemo.extend(/** @lends Jump.prototype# */{ init: function () { tests.Jump.superclass.init.call(this); - - this.set('isMouseEnabled', true); - + var s = cocos.Director.get('sharedDirector').get('winSize'); - this.addNewSprite(ccp(s.width / 2, s.height / 2)); - }, - - addNewSprite: function (point) { - var idx = Math.floor(Math.random() * 1400 / 100), - x = (idx % 5) * 85, - y = (idx % 3) * 121; - - var sprite = nodes.Sprite.create({file: module.dirname + "/resources/grossini_dance_atlas.png", rect: new geo.Rect(x, y, 85, 121)}); - this.addChild({child: sprite, z: 0}); - sprite.set('position', ccp(point.x, point.y)); - - return sprite; + + this.addNewSprite(ccp(s.width/2, s.height/2), kTagSprite1); + this.addNewSprite(ccp(s.width/2, s.height/2), kTagSprite2); + this.addNewSprite(ccp(s.width/2, s.height/2), kTagSprite3); }, onEnter: function() { @@ -148,17 +157,100 @@ tests.Jump = ActionDemo.extend(/** @lends Jump.prototype# */{ var action2 = actions.JumpBy.create({duration: 2, delta: ccp(300, 0), height: 50, jumps: 4}); var action3 = actions.JumpBy.create({duration: 2, delta: ccp(0, 0), height: 80, jumps: 4}); actionBack = action2.reverse(); - - var s1 = this.addNewSprite(ccp(s.width/2, s.height/2)); - var s2 = this.addNewSprite(ccp(s.width/2, s.height/2)); - var s3 = this.addNewSprite(ccp(s.width/2, s.height/2)); - s1.runAction(action1); - s2.runAction(actions.Sequence.create({actions: [action2, actionBack]})); - s3.runAction(actions.RepeatForever.create(action3)); + this.getChild({tag: kTagSprite1}).runAction(action1); + this.getChild({tag: kTagSprite2}).runAction(actions.Sequence.create({actions: [action2, actionBack]})); + this.getChild({tag: kTagSprite3}).runAction(actions.RepeatForever.create(action3)); } }); +/** + * @class + * + * Example Spawn Action + */ +tests.Spawn = ActionDemo.extend(/** @lends Spawn.prototype# */{ + title: 'Spawn: Jump + Rotate', + subtitle: '', + + init: function() { + tests.Spawn.superclass.init.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + this.addNewSprite(ccp(0, s.height/2), kTagSprite1); + }, + + onEnter: function() { + tests.Spawn.superclass.onEnter.call(this); + + var action = actions.Spawn.initWithActions({actions: [ + actions.JumpBy.create({duration: 2, delta: ccp(300, 0), height: 50, jumps: 4}), + actions.RotateBy.create({duration: 2, angle: 720}) + ]}); + this.getChild({tag: kTagSprite1}).runAction(action); + } +}); + +/** + * @class + * + * Example Speed Action + */ +tests.Speed = ActionDemo.extend(/** @lends Speed.prototype# */{ + title: 'Speed', + subtitle: '', + + init: function() { + tests.Speed.superclass.init.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + this.addNewSprite(ccp(0, s.height/2), kTagSprite1); + this.addNewSprite(ccp(0, s.height/2), kTagSprite2); + this.addNewSprite(ccp(0, s.height/2), kTagSprite3); + }, + + onEnter: function() { + tests.Speed.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + // rotate and jump + var jump1 = actions.JumpBy.create({duration: 4, delta: ccp(-s.width+80, 0), height: 100, jumps: 4}); + var jump2 = jump1.reverse(); + var rot1 = actions.RotateBy.create({duration: 4, angle: 720}); + //var rot2 = rot1.reverse(); + + var seq3_1 = actions.Sequence.create({actions: [jump2, jump1]}); + //var seq3_2 = actions.Sequence.create({actions: [rot1, rot2]}); + var spawn = actions.Spawn.create({one: seq3_1, two: rot1}); + var action = actions.Speed.create({action: actions.RepeatForever.create(spawn), speed: 1.0}); + //var action = actions.Speed.create({action: actions.RepeatForever.create(seq3_1), speed: 1.0}); + action.set('tag', kTagAction1); + + //var action2 = action.copy(); + //var action3 = action.copy(); + //action2.set('tag', kTagAction1); + //action3.set('tag', kTagAction1); + + //this.getChild({tag: kTagSprite1}).runAction(action2); + //this.getChild({tag: kTagSprite2}).runAction(action3); + this.getChild({tag: kTagSprite3}).runAction(action); + + Scheduler.get('sharedScheduler').schedule({target: this, method: 'update', interval: 1.0, paused: !this.get('isRunning')}); + }, + + update: function(t) { + //var action1 = this.getChild({tag: kTagSprite1}).getAction({tag: kTagAction1}); + //var action2 = this.getChild({tag: kTagSprite2}).getAction({tag: kTagAction1}); + var action3 = this.getChild({tag: kTagSprite3}).getAction({tag: kTagAction1}); + + //action1.setSpeed(Math.random() * 2); + //action2.setSpeed(Math.random() * 2); + action3.setSpeed(Math.random() * 2); + } +}); + exports.main = function () { // Initialise test var director = cocos.Director.get('sharedDirector'); diff --git a/tests/src/cocos2d/TransitionTest.js b/tests/src/cocos2d/TransitionTest.js index 13f2aee..18415e3 100644 --- a/tests/src/cocos2d/TransitionTest.js +++ b/tests/src/cocos2d/TransitionTest.js @@ -144,8 +144,7 @@ var TransitionDemo = nodes.Layer.extend({ }); -// THIS FAILS RIGHT NOW - THERE IS AN ISSUE WITH THE actions.Sequence OR -// actions.Spawn... + tests.TransitionRotoZoomTest = TransitionDemo.extend({ title: 'TransitionRotoZoom Test', subtitle: 'rotates and zooms & reverse to next scene', From bdfd24590b40425be4c39e4c837fabbb9935f357 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Sun, 29 May 2011 18:27:19 -0700 Subject: [PATCH 164/176] Fixed Spawn to support running Sequence actions --- src/libs/cocos2d/ActionManager.js | 1 - src/libs/cocos2d/actions/ActionInterval.js | 35 ++++++++++++++++++---- tests/src/cocos2d/ActionTest.js | 27 ++++++++--------- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/libs/cocos2d/ActionManager.js b/src/libs/cocos2d/ActionManager.js index 14871f7..21a71e5 100644 --- a/src/libs/cocos2d/ActionManager.js +++ b/src/libs/cocos2d/ActionManager.js @@ -134,7 +134,6 @@ var ActionManager = BObject.extend(/** @lends cocos.ActionManager# */{ if (!element) { return; } - //window.console.log("removing actions from target " + target.get('tag') + " (" + targetID + ")"); // Delete everything in array but don't replace it incase something else has a reference element.actions.splice(0, element.actions.length); }, diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index 6c09221..d42cafe 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -620,6 +620,7 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ this.actionSequence = {}; this.actions = []; //util.copy(opts.actions); + this.currentActionIndex = 0; var self = this; util.each(opts.actions, function(action) { @@ -628,6 +629,14 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ }); }, + initOne: function(one, two) { + var d = one.get('duration') + two.get('duration'); + Sequence.superclass.init.call(this, {duration: d}); + + this.actions.push(one); + this.actions.push(tw0); + }, + startWithTarget: function (target) { Sequence.superclass.startWithTarget.call(this, target); @@ -645,14 +654,17 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ }, step: function (dt) { + //window.console.log("sequence " + this.currentActionIndex + " elapsed: " + this.elapsed); if (this._firstTick) { this._firstTick = false; this.elapsed = 0; } else { this.elapsed += dt; } - this.actions[this.currentActionIndex].step(dt); - this.update(Math.min(1, this.elapsed / this.duration)); + if (this.currentActionIndex < this.actions.length) { + this.actions[this.currentActionIndex].step(dt); + this.update(Math.min(1, this.elapsed / this.duration)); + } }, update: function (dt) { @@ -662,7 +674,7 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ previousAction.update(1.0); previousAction.stop(); - + // UNSAFE? array bounds error in step() is possible this.currentActionIndex++; if (this.currentActionIndex < this.actions.length) { @@ -670,6 +682,8 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ currentAction.startWithTarget(this.target); this.currentActionEndDuration += currentAction.duration; + } else { + this.stop(); } } }, @@ -744,17 +758,28 @@ var Spawn = ActionInterval.extend(/** @lends cocos.actions.Spawn# */{ Spawn.superclass.stop.call(this); }, + step: function (dt) { + if (this._firstTick) { + this._firstTick = false; + this.elapsed = 0; + } else { + this.elapsed += dt; + } + this.get('one').step(dt); + this.get('two').step(dt); + }, + update: function (t) { this.get('one').update(t); this.get('two').update(t); }, copy: function () { - return Spawn.initWithActions({actions: [this.get('one').copy(), this.get('two').copy()]}); + return Spawn.create({one: this.get('one').copy(), two: this.get('two').copy()}); }, reverse: function () { - return Spawn.initWithActions({actions: [this.get('one').reverse(), this.get('two').reverse()]}); + return Spawn.create({one: this.get('one').reverse(), two: this.get('two').reverse()}); } }); diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js index cd2d936..23d0b43 100644 --- a/tests/src/cocos2d/ActionTest.js +++ b/tests/src/cocos2d/ActionTest.js @@ -219,34 +219,33 @@ tests.Speed = ActionDemo.extend(/** @lends Speed.prototype# */{ var jump1 = actions.JumpBy.create({duration: 4, delta: ccp(-s.width+80, 0), height: 100, jumps: 4}); var jump2 = jump1.reverse(); var rot1 = actions.RotateBy.create({duration: 4, angle: 720}); - //var rot2 = rot1.reverse(); + var rot2 = rot1.reverse(); var seq3_1 = actions.Sequence.create({actions: [jump2, jump1]}); - //var seq3_2 = actions.Sequence.create({actions: [rot1, rot2]}); - var spawn = actions.Spawn.create({one: seq3_1, two: rot1}); + var seq3_2 = actions.Sequence.create({actions: [rot1, rot2]}); + var spawn = actions.Spawn.create({one: seq3_1, two: seq3_2}); var action = actions.Speed.create({action: actions.RepeatForever.create(spawn), speed: 1.0}); - //var action = actions.Speed.create({action: actions.RepeatForever.create(seq3_1), speed: 1.0}); action.set('tag', kTagAction1); - //var action2 = action.copy(); - //var action3 = action.copy(); - //action2.set('tag', kTagAction1); - //action3.set('tag', kTagAction1); + var action2 = action.copy(); + var action3 = action.copy(); + action2.set('tag', kTagAction1); + action3.set('tag', kTagAction1); - //this.getChild({tag: kTagSprite1}).runAction(action2); - //this.getChild({tag: kTagSprite2}).runAction(action3); + this.getChild({tag: kTagSprite1}).runAction(action2); + this.getChild({tag: kTagSprite2}).runAction(action3); this.getChild({tag: kTagSprite3}).runAction(action); Scheduler.get('sharedScheduler').schedule({target: this, method: 'update', interval: 1.0, paused: !this.get('isRunning')}); }, update: function(t) { - //var action1 = this.getChild({tag: kTagSprite1}).getAction({tag: kTagAction1}); - //var action2 = this.getChild({tag: kTagSprite2}).getAction({tag: kTagAction1}); + var action1 = this.getChild({tag: kTagSprite1}).getAction({tag: kTagAction1}); + var action2 = this.getChild({tag: kTagSprite2}).getAction({tag: kTagAction1}); var action3 = this.getChild({tag: kTagSprite3}).getAction({tag: kTagAction1}); - //action1.setSpeed(Math.random() * 2); - //action2.setSpeed(Math.random() * 2); + action1.setSpeed(Math.random() * 2); + action2.setSpeed(Math.random() * 2); action3.setSpeed(Math.random() * 2); } }); From c085447b6cff1315b87737e5b8e9e39f31f4a504 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Sun, 29 May 2011 22:18:23 -0700 Subject: [PATCH 165/176] lots of new actions & tests for them --- src/libs/cocos2d/actions/ActionInstant.js | 6 +- src/libs/cocos2d/actions/ActionInterval.js | 214 ++++++++--- src/libs/cocos2d/nodes/Node.js | 4 +- src/libs/geometry.js | 14 + tests/src/cocos2d/ActionTest.js | 361 ++++++++++++++++-- tests/src/cocos2d/resources/grossini.png | Bin 0 -> 1521 bytes .../cocos2d/resources/grossinis_sister1.png | Bin 0 -> 2416 bytes .../cocos2d/resources/grossinis_sister2.png | Bin 0 -> 1656 bytes 8 files changed, 523 insertions(+), 76 deletions(-) create mode 100644 tests/src/cocos2d/resources/grossini.png create mode 100644 tests/src/cocos2d/resources/grossinis_sister1.png create mode 100644 tests/src/cocos2d/resources/grossinis_sister2.png diff --git a/src/libs/cocos2d/actions/ActionInstant.js b/src/libs/cocos2d/actions/ActionInstant.js index 532c4f5..de835bb 100644 --- a/src/libs/cocos2d/actions/ActionInstant.js +++ b/src/libs/cocos2d/actions/ActionInstant.js @@ -118,12 +118,12 @@ var CallFunc = ActionInstant.extend({ startWithTarget: function(target) { CallFunc.superclass.startWithTarget.call(this, target); - this.execute(); + this.execute(target); }, - execute: function() { + execute: function(target) { // Pass target to callback - this.callback.call(this.target); + this.callback.call(this, target); }, copy: function() { diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index d42cafe..d7b2d2c 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -77,7 +77,7 @@ var ActionInterval = act.FiniteTimeAction.extend(/** @lends cocos.actions.Action var DelayTime = ActionInterval.extend(/** @lends cocos.actions.DelayTime# */{ /** - * Delays the action a certain amount of seconds + * @class DelayTime Delays the action a certain amount of seconds * * @memberOf cocos.actions * @constructs @@ -151,7 +151,7 @@ var ScaleTo = ActionInterval.extend(/** @lends cocos.actions.ScaleTo# */{ deltaY: 0.0, /** - * Scales a cocos.Node object to a zoom factor by modifying it's scale attribute. + * @class ScaleTo Scales a cocos.Node object to a zoom factor by modifying it's scale attribute. * * @memberOf cocos.actions * @constructs @@ -202,7 +202,7 @@ var ScaleTo = ActionInterval.extend(/** @lends cocos.actions.ScaleTo# */{ var ScaleBy = ScaleTo.extend(/** @lends cocos.actions.ScaleBy# */{ /** - * Scales a cocos.Node object to a zoom factor by modifying it's scale attribute. + * @class ScaleBy Scales a cocos.Node object to a zoom factor by modifying it's scale attribute. * * @memberOf cocos.actions * @constructs @@ -250,7 +250,7 @@ var RotateTo = ActionInterval.extend(/** @lends cocos.actions.RotateTo# */{ diffAngle: 0, /** - * @class Rotates a cocos.Node object to a certain angle by modifying its rotation + * @class RotateTo Rotates a cocos.Node object to a certain angle by modifying its rotation * attribute. The direction will be decided by the shortest angle. * * @memberOf cocos.actions @@ -302,7 +302,7 @@ var RotateBy = RotateTo.extend(/** @lends cocos.actions.RotateBy# */{ angle: 0, /** - * Rotates a cocos.Node object to a certain angle by modifying its rotation + * @class RotateBy Rotates a cocos.Node object to a certain angle by modifying its rotation * attribute. The direction will be decided by the shortest angle. * * @memberOf cocos.action @@ -343,7 +343,7 @@ var MoveTo = ActionInterval.extend(/** @lends cocos.actions.MoveTo# */{ endPosition: null, /** - * @class Animates moving a cocos.nodes.Node object to a another point. + * @class MoveTo Animates moving a cocos.nodes.Node object to a another point. * * @memberOf cocos.actions * @constructs @@ -378,7 +378,7 @@ var MoveTo = ActionInterval.extend(/** @lends cocos.actions.MoveTo# */{ var MoveBy = MoveTo.extend(/** @lends cocos.actions.MoveBy# */{ /** - * Animates moving a cocos.node.Node object by a given number of pixels + * @class MoveBy Animates moving a cocos.node.Node object by a given number of pixels * * @memberOf cocos.actions * @constructs @@ -435,7 +435,7 @@ var JumpBy = ActionInterval.extend(/** @lends cocos.actions.JumpBy# */{ startPosition: null, /** - * Moves a CCNode object simulating a parabolic jump movement by modifying it's position attribute. + * @class JumpBy Moves a CCNode object simulating a parabolic jump movement by modifying it's position attribute. * * @memberOf cocos.actions * @constructs @@ -469,9 +469,6 @@ var JumpBy = ActionInterval.extend(/** @lends cocos.actions.JumpBy# */{ update: function(t) { // parabolic jump - // the fmod function I added doesn't seem to do the trick here... - // simple modulo works better for now. - //var frac = math.fmod(t * this.jumps, 1.0); var frac = (t * this.jumps) % 1.0; var y = this.height * 4 * frac * (1 - frac); y += this.delta.y * t; @@ -489,11 +486,10 @@ var JumpBy = ActionInterval.extend(/** @lends cocos.actions.JumpBy# */{ var JumpTo = JumpBy.extend(/** @lends cocos.actions.JumpTo# */{ /** - * Moves a Node object to a parabolic position simulating a jump + * @class JumpTo Moves a Node object to a parabolic position simulating a jump * movement by modifying it's position attribute. * * @memberOf cocos.actions - * @constructs * @extends cocos.actions.JumpBy */ startWithTarget: function(target) { @@ -501,14 +497,144 @@ var JumpTo = JumpBy.extend(/** @lends cocos.actions.JumpTo# */{ this.delta = geo.ccp(this.delta.x - this.startPosition.x, this.delta.y - this.startPosition.y); } }); + +var BezierBy = ActionInterval.extend(/** @lends cocos.actions.BezierBy# */{ + /** + * @type {geometry.BezierConfig} + */ + config: null, -/** - * @memberOf cocos.actions - * @class Fades out a cocos.nodes.Node to zero opacity - * @extends cocos.actions.ActionInterval - */ -var FadeOut = ActionInterval.extend(/** @lends cocos.actions.FadeOut# */{ + startPosition: null, + + /** + * @class BezierBy An action that moves the target with a cubic Bezier curve by a certain distance. + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.ActionInterval + * + * @opts {geometry.BezierConfig} bezier Bezier control points object + * @opts {Float} duration + */ + init: function(opts) { + BezierBy.superclass.init.call(this, opts); + + this.config = util.copy(opts.bezier); + }, + + startWithTarget: function(target) { + BezierBy.superclass.startWithTarget.call(this, target); + this.set('startPosition', this.target.get('position')); + }, + + update: function(t) { + var c = this.get('config'); + var xa = 0, + xb = c.controlPoint1.x, + xc = c.controlPoint2.x, + xd = c.endPosition.x, + ya = 0, + yb = c.controlPoint1.y, + yc = c.controlPoint2.y, + yd = c.endPosition.y; + + var x = BezierBy.bezierat(xa, xb, xc, xd, t); + var y = BezierBy.bezierat(ya, yb, yc, yd, t); + this.target.set('position', geo.ccpAdd(this.get('startPosition'), geo.ccp(x, y))); + }, + + copy: function() { + return BezierBy.create({bezier: this.get('config'), duration: this.get('duration')}); + }, + + reverse: function() { + var c = this.get('config'), + bc = new geo.BezierConfig(); + + bc.endPosition = geo.ccpNeg(c.endPosition); + bc.controlPoint1 = geo.ccpAdd(c.controlPoint2, geo.ccpNeg(c.endPosition)); + bc.controlPoint2 = geo.ccpAdd(c.controlPoint1, geo.ccpNeg(c.endPosition)); + + return BezierBy.create({bezier: bc, duration: this.get('duration')}); + } +}); + +util.extend(BezierBy, { + /** + * Bezier cubic formula + * ((1 - t) + t)3 = 1 + */ + bezierat: function(a, b, c, d, t) { + return Math.pow(1-t, 3) * a + + 3 * t * Math.pow(1-t, 2) * b + + 3 * Math.pow(t, 2) * (1 - t) * c + + Math.pow(t, 3) * d; + } +}); + +var BezierTo = BezierBy.extend(/** @lends cocos.actions.BezierTo# */{ + /** + * @class BezierTo An action that moves the target with a cubic Bezier curve to a destination point. + * + * @memberOf cocos.actions + * @extends cocos.actions.BezierBy + */ + startWithTarget: function(target) { + BezierTo.superclass.startWithTarget.call(this, target); + + var c = this.get('config'); + c.controlPoint1 = geo.ccpSub(c.controlPoint1, this.get('startPosition')); + c.controlPoint2 = geo.ccpSub(c.controlPoint2, this.get('startPosition')); + c.endPosition = geo.ccpSub(c.endPosition, this.get('startPosition')); + } +}); + +var Blink = ActionInterval.extend(/** @lends cocos.actions.Blink# */{ + /** + * @type {Integer} + */ + times: 1, + + /** + * @class Blink Blinks a Node object by modifying it's visible attribute + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.ActionInterval + * + * @opts {Integer} blinks Number of times to blink + * @opts {Float} duration + */ + init: function(opts) { + Blink.superclass.init.call(this, opts); + this.times = opts.blinks; + }, + + update: function(t) { + if (! this.get_isDone()) { + var slice = 1 / this.times; + var m = t % slice; + this.target.set('visible', (m > slice/2)); + } + }, + + copy: function() { + return Blink.create({duration: this.get('duration'), blinks: this.get('times')}); + }, + + reverse: function() { + return this.copy(); + } +}); + +var FadeOut = ActionInterval.extend(/** @lends cocos.actions.FadeOut# */{ + /** + * @class FadeOut Fades out a cocos.nodes.Node to zero opacity + * + * @memberOf cocos.actions + * @extends cocos.actions.ActionInterval + */ update: function (t) { var target = this.get('target'); if (!target) return; @@ -524,13 +650,14 @@ var FadeOut = ActionInterval.extend(/** @lends cocos.actions.FadeOut# */{ } }); -/** - * @memberOf cocos.actions - * @class Fades in a cocos.nodes.Node to 100% opacity - * @extends cocos.actions.ActionInterval - */ + var FadeIn = ActionInterval.extend(/** @lends cocos.actions.FadeIn# */{ - + /** + * @class FadeIn Fades in a cocos.nodes.Node to 100% opacity + * + * @memberOf cocos.actions + * @extends cocos.actions.ActionInterval + */ update: function (t) { var target = this.get('target'); if (!target) return; @@ -546,11 +673,7 @@ var FadeIn = ActionInterval.extend(/** @lends cocos.actions.FadeIn# */{ } }); -/** - * @memberOf cocos.actions - * @class Fades a cocos.nodes.Node to a given opacity - * @extends cocos.actions.ActionInterval - */ + var FadeTo = ActionInterval.extend(/** @lends cocos.actions.FadeTo# */{ /** * The final opacity @@ -564,6 +687,13 @@ var FadeTo = ActionInterval.extend(/** @lends cocos.actions.FadeTo# */{ */ fromOpacity: null, + /** + * @class FadeTo Fades a cocos.nodes.Node to a given opacity + * + * @memberOf cocos.actions + * @constructor + * @extends cocos.actions.ActionInterval + */ init: function (opts) { FadeTo.superclass.init.call(this, opts); this.set('toOpacity', opts.toOpacity); @@ -628,14 +758,6 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ self.duration += action.duration; }); }, - - initOne: function(one, two) { - var d = one.get('duration') + two.get('duration'); - Sequence.superclass.init.call(this, {duration: d}); - - this.actions.push(one); - this.actions.push(tw0); - }, startWithTarget: function (target) { Sequence.superclass.startWithTarget.call(this, target); @@ -669,7 +791,7 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ update: function (dt) { // Action finished onto the next one - if (this.elapsed > this.currentActionEndDuration) { + if (!this.get_isDone() && (this.elapsed > this.currentActionEndDuration)) { var previousAction = this.actions[this.currentActionIndex]; previousAction.update(1.0); previousAction.stop(); @@ -682,12 +804,15 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ currentAction.startWithTarget(this.target); this.currentActionEndDuration += currentAction.duration; - } else { - this.stop(); - } + } } }, + get_isDone: function () { + return ((this.elapsed >= this.duration) && + (this.currentActionIndex >= this.actions.length)); + }, + copy: function () { // Constructor will copy actions return Sequence.create({actions: this.get('actions')}); @@ -709,7 +834,7 @@ var Spawn = ActionInterval.extend(/** @lends cocos.actions.Spawn# */{ two: null, /** - * initializes the Spawn action with the 2 actions to spawn + * @class Spawn Executes multiple actions simultaneously * * @memberOf cocos.actions * @constructs @@ -876,6 +1001,9 @@ exports.MoveTo = MoveTo; exports.MoveBy = MoveBy; exports.JumpBy = JumpBy; exports.JumpTo = JumpTo; +exports.BezierBy = BezierBy; +exports.BezierTo = BezierTo; +exports.Blink = Blink; exports.FadeIn = FadeIn; exports.FadeOut = FadeOut; exports.FadeTo = FadeTo; diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index dab0ea1..1a6841d 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -380,7 +380,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ // Set alpha value (global only for now) context.globalAlpha = this.get('opacity') / 255.0; - + // Adjust redraw region by nodes position if (rect) { var pos = this.get('position'); @@ -393,7 +393,7 @@ var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ child.visit(context, rect); } }); - + this.draw(context, rect); // Draw foreground nodes diff --git a/src/libs/geometry.js b/src/libs/geometry.js index 2142b24..3872941 100644 --- a/src/libs/geometry.js +++ b/src/libs/geometry.js @@ -94,6 +94,20 @@ var geometry = { this.ty = ty; }, + /** + * @class + * Bezier curve control object + * + * @param {geometry.Point} controlPoint1 + * @param {geometry.Point} controlPoint2 + * @param {geometry.Point} endPoint + */ + BezierConfig: function(p1, p2, ep) { + this.controlPoint1 = util.copy(p1); + this.controlPoint2 = util.copy(p2); + this.endPosition = util.copy(ep); + }, + /** * Creates a geometry.Point instance * diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js index 23d0b43..6007e22 100644 --- a/tests/src/cocos2d/ActionTest.js +++ b/tests/src/cocos2d/ActionTest.js @@ -14,8 +14,18 @@ var util = require('util'), var sceneIdx = -1; var transitions = [ + "Manual", + "Move", "Jump", + "Bezier", + "Blink", + "Sequence", + "Sequence2", "Spawn", + "Reverse", + "Delay", + "ReverseSequence", + "RepeatForever", "Speed" ]; @@ -58,8 +68,27 @@ var ActionDemo = nodes.Layer.extend({ ActionDemo.superclass.init.call(this); this.set('isMouseEnabled', true); + var s = cocos.Director.get('sharedDirector').get('winSize'); + var grossini = nodes.Sprite.create({file: module.dirname + "/resources/grossini.png", + rect: new geo.Rect(0, 0, 85, 121)}); + var tamara = nodes.Sprite.create({file: module.dirname + "/resources/grossinis_sister1.png", + rect: new geo.Rect(0, 0, 52, 139)}); + var kathia = nodes.Sprite.create({file: module.dirname + "/resources/grossinis_sister2.png", + rect: new geo.Rect(0, 0, 56, 138)}); + this.set('grossini', grossini); + this.set('tamara', tamara); + this.set('kathia', kathia); + + this.addChild({child: grossini, z: 1, tag: kTagSprite1}); + this.addChild({child: tamara, z: 2, tag: kTagSprite2}); + this.addChild({child: kathia, z: 3, tag: kTagSprite3}); + + grossini.set('position', ccp(s.width/2, s.height/3)); + tamara.set('position', ccp(s.width/2, 2*s.height/3)); + kathia.set('position', ccp(s.width/2, s.height/2)); + var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); this.addChild({child: label, z: 1}); label.set('position', ccp(s.width / 2, s.height - 50)); @@ -72,7 +101,6 @@ var ActionDemo = nodes.Layer.extend({ l.set('position', ccp(s.width / 2, s.height - 80)); } - var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); @@ -83,7 +111,7 @@ var ActionDemo = nodes.Layer.extend({ item1.set('position', ccp(s.width / 2 - 100, 30)); item2.set('position', ccp(s.width / 2, 30)); item3.set('position', ccp(s.width / 2 + 100, 30)); - this.addChild({child: menu, z: 1}); + this.addChild({child: menu}); }, restartCallback: function () { @@ -113,6 +141,42 @@ var ActionDemo = nodes.Layer.extend({ director.replaceScene(scene); }, + alignSpritesLeft: function(numSprites) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + + if (numSprites == 1) { + this.get('tamara').set('visible', false); + this.get('kathia').set('visible', false); + this.get('grossini').set('position', ccp(60, s.height/2)); + } else if (numSprites == 2) { + this.get('kathia').set('position', ccp(60, s.height/3)); + this.get('tamara').set('position', ccp(60, 2*s.height/3)); + this.get('grossini').set('visible', false); + } else if (numSprites == 3) { + this.get('grossini').set('position', ccp(60, s.height/2)); + this.get('tamara').set('position', ccp(60, 2*s.height/3)); + this.get('kathia').set('position', ccp(60, s.height/3)); + } + }, + + centerSprites: function(numSprites) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + + if (numSprites == 1) { + this.get('tamara').set('visible', false); + this.get('kathia').set('visible', false); + this.get('grossini').set('position', ccp(s.width/2, s.height/2)); + } else if (numSprites == 2) { + this.get('kathia').set('position', ccp(s.width/3, s.height/2)); + this.get('tamara').set('position', ccp(2*s.width/3, s.height/2)); + this.get('grossini').set('visible', false); + } else if (numSprites == 3) { + this.get('grossini').set('position', ccp(s.width/2, s.height/2)); + this.get('tamara').set('position', ccp(2*s.width/3, s.height/2)); + this.get('kathia').set('position', ccp(s.width/3, s.height/2)); + } + }, + addNewSprite: function (point, tag) { var idx = Math.floor(Math.random() * 1400 / 100), x = (idx % 5) * 85, @@ -126,6 +190,50 @@ var ActionDemo = nodes.Layer.extend({ } }); +tests.Manual = ActionDemo.extend(/** @lends Manual.prototype# */{ + title: 'Manual Transformation', + subtitle: '', + + onEnter: function() { + tests.Manual.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + this.get('tamara').set('scale', ccp(2.5, -1.0)); + this.get('tamara').set('position', ccp(100, 70)); + this.get('tamara').set('opacity', 128); + + this.get('grossini').set('rotation', 120); + this.get('grossini').set('position', ccp(s.width/2, s.height/2)); + } +}); + +/** + * @class + * + * Example Move Action + */ +tests.Move = ActionDemo.extend(/** @lends Move.prototype# */{ + title: 'MoveTo / MoveBy', + subtitle: '', + + onEnter: function() { + tests.Move.superclass.onEnter.call(this); + + this.centerSprites(3); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var actionTo = actions.MoveTo.create({duration: 2, position: ccp(s.width-40, s.height-40)}); + var actionBy = actions.MoveBy.create({duration: 2, position: ccp(80, 80)}); + var actionByBack = actionBy.reverse(); + + this.get('tamara').runAction(actionTo); + this.get('grossini').runAction(actions.Sequence.create({actions: [actionBy, actionByBack]})); + this.get('kathia').runAction(actions.MoveTo.create({duration: 1, position: ccp(40, 40)})); + } +}); + /** * @class * @@ -135,16 +243,6 @@ tests.Jump = ActionDemo.extend(/** @lends Jump.prototype# */{ title: 'JumpTo / JumpBy', subtitle: '', - init: function () { - tests.Jump.superclass.init.call(this); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - this.addNewSprite(ccp(s.width/2, s.height/2), kTagSprite1); - this.addNewSprite(ccp(s.width/2, s.height/2), kTagSprite2); - this.addNewSprite(ccp(s.width/2, s.height/2), kTagSprite3); - }, - onEnter: function() { tests.Jump.superclass.onEnter.call(this); @@ -167,23 +265,146 @@ tests.Jump = ActionDemo.extend(/** @lends Jump.prototype# */{ /** * @class * - * Example Spawn Action + * Example Bezier Action */ -tests.Spawn = ActionDemo.extend(/** @lends Spawn.prototype# */{ - title: 'Spawn: Jump + Rotate', +tests.Bezier = ActionDemo.extend(/** @lends Bezier.prototype# */{ + title: 'BezierBy / BezierTo', + subtitle: '', + + onEnter: function() { + tests.Bezier.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + // this.alignSpritesLeft(); + + var bezier = new geo.BezierConfig(); + bezier.controlPoint1 = ccp(0, s.height/2); + bezier.controlPoint2 = ccp(300, -s.height/2); + bezier.endPosition = ccp(300,100); + + var bezierForward = actions.BezierBy.create({duration: 3, bezier: bezier}); + var bezierBack = bezierForward.reverse(); + var seq = actions.Sequence.create({actions: [bezierForward, bezierBack]}); + + this.get('tamara').set('position', ccp(80, 160)); + var bezier2 = new geo.BezierConfig(); + bezier2.controlPoint1 = ccp(100, s.height/2); + bezier2.controlPoint2 = ccp(200, -s.height/2); + bezier2.endPosition = ccp(240,160); + + var bezierTo1 = actions.BezierTo.create({duration: 2, bezier: bezier2}); + + this.get('kathia').set('position', ccp(400, 160)); + var bezierTo2 = actions.BezierTo.create({duration: 2, bezier: bezier2}); + + this.get('grossini').runAction(actions.RepeatForever.create(seq)); + this.get('tamara').runAction(bezierTo1); + this.get('kathia').runAction(bezierTo2); + } +}); + +/** + * @class + * + * Example Blink Action + */ +tests.Blink = ActionDemo.extend(/** @lends Blink.prototype# */{ + title: 'Blink', + subtitle: '', + + onEnter: function() { + tests.Blink.superclass.onEnter.call(this); + + this.centerSprites(2); + + this.get('tamara').runAction(actions.Blink.create({duration: 2, blinks: 10})); + this.get('kathia').runAction(actions.Blink.create({duration: 2, blinks: 5})); + } +}); + + +/** + * @class + * + * Example Sequence Action + */ +tests.Sequence = ActionDemo.extend(/** @lends Sequence.prototype# */{ + title: 'Sequence: Move + Rotate', subtitle: '', - init: function() { - tests.Spawn.superclass.init.call(this); + onEnter: function() { + tests.Sequence.superclass.onEnter.call(this); - var s = cocos.Director.get('sharedDirector').get('winSize'); + this.alignSpritesLeft(1); + + var action = actions.Sequence.create({actions: [ + actions.MoveBy.create({duration: 2, position: ccp(240, 0)}), + actions.RotateBy.create({duration: 2, angle: 540}) + ]}); + this.get('grossini').runAction(action); + } +}); - this.addNewSprite(ccp(0, s.height/2), kTagSprite1); +/** + * @class + * + * Example Sequence2 Action + */ +tests.Sequence2 = ActionDemo.extend(/** @lends Sequence2.prototype# */{ + title: 'Sequence of InstantActions', + subtitle: '', + + onEnter: function() { + tests.Sequence2.superclass.onEnter.call(this); + + this.alignSpritesLeft(1); + this.get('grossini').set('position', ccp(200, 200)); + + var action = actions.Sequence.create({actions: [ + actions.MoveBy.create({duration: 1, position: ccp(100, 0)}), + actions.CallFunc.create({target: this, method: 'callback1'}), + actions.CallFunc.create({target: this, method: 'callback2'}), + actions.CallFunc.create({target: this, method: 'callback3'}) + ]}); + this.get('grossini').runAction(action); + }, + + callback1: function(target) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + var label = cocos.nodes.Label.create({string: "callback 1 called", fontName: 'Marker Felt', fontSize: 16}); + label.set('position', ccp(s.width / 4, s.height / 2)); + this.addChild({child: label}); + }, + + callback2: function(target) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + var label = cocos.nodes.Label.create({string: "callback 2 called", fontName: 'Marker Felt', fontSize: 16}); + label.set('position', ccp(s.width / 4*2, s.height / 2)); + this.addChild({child: label}); }, + callback3: function(target) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + var label = cocos.nodes.Label.create({string: "callback 3 called", fontName: 'Marker Felt', fontSize: 16}); + label.set('position', ccp(s.width / 4*3, s.height / 2)); + this.addChild({child: label}); + } +}); + +/** + * @class + * + * Example Spawn Action + */ +tests.Spawn = ActionDemo.extend(/** @lends Spawn.prototype# */{ + title: 'Spawn: Jump + Rotate', + subtitle: '', + onEnter: function() { tests.Spawn.superclass.onEnter.call(this); + this.alignSpritesLeft(1); var action = actions.Spawn.initWithActions({actions: [ actions.JumpBy.create({duration: 2, delta: ccp(300, 0), height: 50, jumps: 4}), actions.RotateBy.create({duration: 2, angle: 720}) @@ -195,26 +416,110 @@ tests.Spawn = ActionDemo.extend(/** @lends Spawn.prototype# */{ /** * @class * - * Example Speed Action + * Example Reverse Action */ -tests.Speed = ActionDemo.extend(/** @lends Speed.prototype# */{ - title: 'Speed', +tests.Reverse = ActionDemo.extend(/** @lends Reverse.prototype# */{ + title: 'Reverse an action', subtitle: '', - init: function() { - tests.Speed.superclass.init.call(this); + onEnter: function() { + tests.Reverse.superclass.onEnter.call(this); - var s = cocos.Director.get('sharedDirector').get('winSize'); + this.alignSpritesLeft(1); + + var jump = actions.JumpBy.create({duration: 2, delta: ccp(300, 0), height: 50, jumps: 4}); + var action = actions.Sequence.create({actions: [jump, jump.reverse()]}); + + this.get('grossini').runAction(action); + } +}); + +/** + * @class + * + * Example Delay Action + */ +tests.Delay = ActionDemo.extend(/** @lends Delay.prototype# */{ + title: 'DelayTime: m + delay + m', + subtitle: '', + + onEnter: function() { + tests.Delay.superclass.onEnter.call(this); + + this.alignSpritesLeft(1); + + var move = actions.MoveBy.create({duration: 1, position: ccp(150, 0)}); + var action = actions.Sequence.create({actions: [move, + actions.DelayTime.create({duration: 2}), + move]}); + + this.get('grossini').runAction(action); + } +}); + +/** + * @class + * + * Example ReverseSequence Action + */ +tests.ReverseSequence = ActionDemo.extend(/** @lends ReverseSequence.prototype# */{ + title: 'Reverse a sequence', + subtitle: '', + + onEnter: function() { + tests.ReverseSequence.superclass.onEnter.call(this); + + this.alignSpritesLeft(1); - this.addNewSprite(ccp(0, s.height/2), kTagSprite1); - this.addNewSprite(ccp(0, s.height/2), kTagSprite2); - this.addNewSprite(ccp(0, s.height/2), kTagSprite3); + var move1 = actions.MoveBy.create({duration: 1, position: ccp(250, 0)}); + var move2 = actions.MoveBy.create({duration: 1, position: ccp(0, 50)}); + var seq = actions.Sequence.create({actions: [move1, move2, move1.reverse()]}); + var action = actions.Sequence.create({actions: [seq, seq.reverse()]}); + + this.get('grossini').runAction(action); + } +}); + +/** + * @class + * + * Example RepeatForever Action + */ +tests.RepeatForever = ActionDemo.extend(/** @lends RepeatForever.prototype# */{ + title: 'CallFunc + RepeatForever', + subtitle: '', + + onEnter: function() { + tests.RepeatForever.superclass.onEnter.call(this); + + this.centerSprites(1); + + this.get('grossini').runAction(actions.Sequence.create({actions: [ + actions.DelayTime.create({duration: 1}), + actions.CallFunc.create({target: this, method: 'repeatForever'}) + ]})); }, + repeatForever: function(target) { + target.runAction(actions.RepeatForever.create(actions.RotateBy.create({duration: 1, angle: 360}))); + } +}); + +/** + * @class + * + * Example Speed Action + */ +tests.Speed = ActionDemo.extend(/** @lends Speed.prototype# */{ + title: 'Speed', + subtitle: '', + onEnter: function() { tests.Speed.superclass.onEnter.call(this); var s = cocos.Director.get('sharedDirector').get('winSize'); + + this.alignSpritesLeft(3); // rotate and jump var jump1 = actions.JumpBy.create({duration: 4, delta: ccp(-s.width+80, 0), height: 100, jumps: 4}); var jump2 = jump1.reverse(); diff --git a/tests/src/cocos2d/resources/grossini.png b/tests/src/cocos2d/resources/grossini.png new file mode 100644 index 0000000000000000000000000000000000000000..afb316017ef42f03f5bac55370552f14be5c75f1 GIT binary patch literal 1521 zcmZvcdo&XY9LGnScx zwT)X7Av%SdJZI!xIJg{BZX|i^u7CRDp8GrJ`}_RyJHPXL{PE2S@bgqv(o+He0IJ?z z?r0gYGTl0;Aj@7wWNjG~F8X-7%P5O&x0YlX6t8*(Qvd*E=r_p$3X63B0MKvV?k*(*$#hd4l=!xn4DY#{y%mj5TxXk~a(Phx5KnDHlaLS+TlSazCry zuF%3LAlNGS0Np2LCrB=lgG7n`U$19Xc->T7Wl}q*hOU?9w0i&$PHs~r+i$^7DTh~1 ze}NSM^ThHSgh+cZ@(3S}$vk;4Wt)dC3IzSZVx!AOCrprX#s<$Vt#esQVuQgU5zrEX zmACL#u8VPGLfJL$<%@@*Pi^Zq=V_RwTiL`<^W`z$hNt!zW7&G^ey(rOx>b-(C=YA6 z0*lFB7hA?6Hk)F!_~Qg@vcW%sNqhL>BnmXY&{$(y*^7h=i*$$ z!o-iGLq?3M9_hsl6vFfD1H#d4XKzH~m~M(Z)OC7_;h7m(*ysE9RUrf}H?3c{_7nN7 zwz1iHw$bS2IDs{LYyg^>jEUfkhiI-W-dNX6nPW{TX*HGZdFvtN%(h_l$mSx{jz$04 z(zr@Kzw-PUVF60B|3wlmr%%#(=vPV-xj;Z04lD7iu)eI4orjH{C(R%EToiU`( zg;I438+GvpSQB9g$QC@_O-Z%II@+ZJB2*w!lF=o*A{w*EV~&N_-_Ma_o^TGnq&%1# zSL;yxBJ6e+?D?Fj@7%)sE}Ov6-zR5P^1?gISSej6x?210iR{rzk2@uZItyHbCLDoW zF3`a!A)X30r_d+WR%IvHYIVMTJN4u3gy*$8!}}#bv&e=z78Pv40a_`{SSsd3rct%o z8GEPz6XW!cfBJ#9CKQ}zXWA5CIIS&dR>tCkyJ_lkDxjB$O_&y{k2{8^*LqODT$%ja z0oKp4x?v$UD!bNV%l|o!CUI(xZ7j(=uxi6@Lps+T!#W8^aYEcg{Qd^s^aX@Y1(P_b zJe!y}0q8N+W92|P7rAE}+bkhvfWQha-FZDkLmfgS=Z8uB=g9`Kg#JE|MtJXjP&h}# zgE!l_w5|X{=nFt4n^PQg{pm8qC>~v0h3_9w)i_k>TU~`IGURP8#qJQIh-Ql%cRgu! zc59TUlz`biisSV6T883=Xh%%VMl1iRHxHV<`sGx8$5tcBuVJzqNg0LjJwOe`!Rhzk z0T*h|80FBrmPCoGwTbUa;a(?AO*?9k^X+z{K^#@~;4fkQdlAAXDpB%E7W^uO83G7s zf4^MFugTc^TunN&9F#OdghcVSHPob?k!HzaLY{-TDM;f=EaG9@feF}NQx(MSt_hYw z7-sBt!>!*W)y-5EJvcD!A2NM05<>0c#GoNUw+mbS^o``Kw(( za{hlkDYd5z#B@=Hr(w!PJ*|m`;t^O%&HN9^X%1#$|B>(2|8L`}1*|St(s0AH)(dT7 zD<*BwjS}DiT8VA=Ani68nQ5T*km%S@pX*Dn*P8XNosi?U{{R)c?hNpdBU_(umPF!mWr$l^n NZf_4icfMc6|Y#xwu` literal 0 HcmV?d00001 diff --git a/tests/src/cocos2d/resources/grossinis_sister1.png b/tests/src/cocos2d/resources/grossinis_sister1.png new file mode 100644 index 0000000000000000000000000000000000000000..745a5cd66a52e6fafcf7ced3681aed1f25014788 GIT binary patch literal 2416 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 Date: Mon, 30 May 2011 12:01:10 -0700 Subject: [PATCH 166/176] resolved conflicts --- src/libs/cocos2d/actions/ActionInstant.js | 42 ++++++- src/libs/cocos2d/actions/ActionInterval.js | 111 ++++++++++++++++- tests/src/cocos2d/ActionTest.js | 135 ++++++++++++++++++++- 3 files changed, 274 insertions(+), 14 deletions(-) diff --git a/src/libs/cocos2d/actions/ActionInstant.js b/src/libs/cocos2d/actions/ActionInstant.js index 532c4f5..fba19eb 100644 --- a/src/libs/cocos2d/actions/ActionInstant.js +++ b/src/libs/cocos2d/actions/ActionInstant.js @@ -8,8 +8,9 @@ var util = require('util'), var ActionInstant = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionInstant */{ /** - * @memberOf cocos.actions * @class Base class for actions that triggers instantly. They have no duration. + * + * @memberOf cocos.actions * @extends cocos.actions.FiniteTimeAction * @constructs */ @@ -39,8 +40,9 @@ var FlipX = ActionInstant.extend(/** @lends cocos.actions.FlipX# */{ flipX: false, /** + * @class FlipX Flips a sprite horizontally + * * @memberOf cocos.actions - * @class Flips a sprite horizontally * @extends cocos.actions.ActionInstant * @constructs * @@ -68,8 +70,9 @@ var FlipY = ActionInstant.extend(/** @lends cocos.actions.FlipY# */{ flipY: false, /** + * @class FlipY Flips a sprite vertically + * * @memberOf cocos.actions - * @class Flips a sprite vertically * @extends cocos.actions.ActionInstant * @constructs * @@ -93,14 +96,42 @@ var FlipY = ActionInstant.extend(/** @lends cocos.actions.FlipY# */{ } }); -var CallFunc = ActionInstant.extend({ +var Place = ActionInstant.extend(/** @lends cocos.actions.Place# */{ + position: null, + + /** + * @class Place Places the node in a certain position + * + * @memberOf cocos.actions + * @extends cocos.actions.ActionInstant + * @constructs + * + * @opt {geometry.Point} position + */ + init: function(opts) { + Place.superclass.init.call(this, opts); + this.set('position', util.copy(opts.position)); + }, + + startWithTarget: function(target) { + Place.superclass.startWithTarget.call(this, target); + this.target.set('position', this.position); + }, + + copy: function() { + return Place.create({position: this.position}); + } +}); + +var CallFunc = ActionInstant.extend(/** @lends cocos.actions.CallFunc# */{ callback: null, target: null, method: null, /** + * @class CallFunc Calls a 'callback' + * * @memberOf cocos.actions - * @class Calls a 'callback' * @extends cocos.actions.ActionInstant * @constructs * @@ -134,5 +165,6 @@ var CallFunc = ActionInstant.extend({ exports.ActionInstant = ActionInstant; exports.FlipX = FlipX; exports.FlipY = FlipY; +exports.Place = Place; exports.CallFunc = CallFunc; diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index d42cafe..0e96592 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -621,11 +621,14 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ this.actionSequence = {}; this.actions = []; //util.copy(opts.actions); this.currentActionIndex = 0; + this.duration = 0; var self = this; util.each(opts.actions, function(action) { self.actions.push(action.copy()); - self.duration += action.duration; + if (action.get('duration') !== undefined) { + self.duration += action.get('duration'); + } }); }, @@ -642,10 +645,16 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ this.currentActionIndex = 0; this.currentActionEndDuration = this.actions[0].get('duration'); + // Not all actions have durations + if (this.currentActionEndDuration === undefined) { + this.currentActionEndDuration = 0; + } + window.console.log("starting sequence 0 duration = " + this.currentActionEndDuration); this.actions[0].startWithTarget(this.target); }, stop: function () { + window.console.log("stopping sequence"); util.each(this.actions, function (action) { action.stop(); }); @@ -654,7 +663,7 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ }, step: function (dt) { - //window.console.log("sequence " + this.currentActionIndex + " elapsed: " + this.elapsed); + window.console.log("sequence step: " + dt); if (this._firstTick) { this._firstTick = false; this.elapsed = 0; @@ -662,14 +671,21 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ this.elapsed += dt; } if (this.currentActionIndex < this.actions.length) { + window.console.log("sequence " + this.currentActionIndex + " elapsed: " + this.elapsed); this.actions[this.currentActionIndex].step(dt); - this.update(Math.min(1, this.elapsed / this.duration)); } + this.update(Math.min(1, this.elapsed / this.duration)); + }, update: function (dt) { // Action finished onto the next one - if (this.elapsed > this.currentActionEndDuration) { + + window.console.log("sequence update " + this.elapsed); + if (!this.get_isDone() && + (this.elapsed > this.currentActionEndDuration)) { + window.console.log("stopping action # " + (this.currentActionIndex+1)); + var previousAction = this.actions[this.currentActionIndex]; previousAction.update(1.0); previousAction.stop(); @@ -694,15 +710,97 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ }, reverse: function() { - // reverse() would modify actions array + // reverse() would modify existing actions array so build new one var ractions = []; for (var i=0; i total+1"); + this.other.update(1); + this.total += 1; + this.other.stop(); + this.other.startWithTarget(this.target); + + // If repeat is over + if (this.total == this.times) { + window.console.log("repeat is over"); + // set it in the original position + this.other.update(0); + } else { + window.console.log("starting next repeat"); + // otherwise start next repeat + this.other.update(t - this.total); + } + } else { + var r = t % 1.0; + + // fix last repeat position otherwise it could be 0 + if (dt == 1) { + r = 1; + this.total += 1; + } + this.other.update(Math.min(r, 1)); + } + }, + + get_isDone: function() { + return this.total == this.times; + }, + + copy: function() { + // Constructor copies action + return Repeat.create({action: this.other, times: this.times}); + }, + + reverse: function() { + return Repeat.create({action: this.other.reverse(), times: this.times}); + } +}); var Spawn = ActionInterval.extend(/** @lends cocos.actions.Spawn# */{ one: null, @@ -881,4 +979,5 @@ exports.FadeOut = FadeOut; exports.FadeTo = FadeTo; exports.Spawn = Spawn; exports.Sequence = Sequence; +exports.Repeat = Repeat; exports.Animate = Animate; diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js index 23d0b43..5943acb 100644 --- a/tests/src/cocos2d/ActionTest.js +++ b/tests/src/cocos2d/ActionTest.js @@ -14,9 +14,19 @@ var util = require('util'), var sceneIdx = -1; var transitions = [ +/* + "Manual", + "Move", "Jump", "Spawn", + "Reverse", + "Delay", + */ + "Repeat" /*, + "RepeatForever", + "ReverseSequence", "Speed" + */ ]; var tests = {}; @@ -173,9 +183,30 @@ tests.Spawn = ActionDemo.extend(/** @lends Spawn.prototype# */{ title: 'Spawn: Jump + Rotate', subtitle: '', - init: function() { - tests.Spawn.superclass.init.call(this); + onEnter: function() { + tests.Sequence2.superclass.onEnter.call(this); + this.alignSpritesLeft(1); + + var action = actions.Sequence.create({actions: [ + actions.Place.create({position: ccp(200, 200)}), + actions.MoveBy.create({duration: 1, position: ccp(100, 0)}), + actions.CallFunc.create({target: this, method: 'callback1'}), + actions.CallFunc.create({target: this, method: 'callback2'}), + actions.CallFunc.create({target: this, method: 'callback3'}) + ]}); + this.get('grossini').runAction(action); + }, + + callback1: function(target) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + var label = cocos.nodes.Label.create({string: "callback 1 called", fontName: 'Marker Felt', fontSize: 16}); + label.set('position', ccp(s.width / 4, s.height / 2)); + this.addChild({child: label}); + }, + + callback2: function(target) { +>>>>>>> Stashed changes var s = cocos.Director.get('sharedDirector').get('winSize'); this.addNewSprite(ccp(0, s.height/2), kTagSprite1); @@ -195,7 +226,105 @@ tests.Spawn = ActionDemo.extend(/** @lends Spawn.prototype# */{ /** * @class * - * Example Speed Action + * Example Reverse Action + */ +tests.Reverse = ActionDemo.extend(/** @lends Reverse.prototype# */{ + title: 'Reverse an action', + subtitle: '', + + onEnter: function() { + tests.Reverse.superclass.onEnter.call(this); + + this.alignSpritesLeft(1); + + var jump = actions.JumpBy.create({duration: 2, delta: ccp(300, 0), height: 50, jumps: 4}); + var action = actions.Sequence.create({actions: [jump, jump.reverse()]}); + + this.get('grossini').runAction(action); + } +}); + +/** + * @class + * + * Example Delay Action + */ +tests.Delay = ActionDemo.extend(/** @lends Delay.prototype# */{ + title: 'DelayTime: m + delay + m', + subtitle: '', + + onEnter: function() { + tests.Delay.superclass.onEnter.call(this); + + this.alignSpritesLeft(1); + + var move = actions.MoveBy.create({duration: 1, position: ccp(150, 0)}); + var action = actions.Sequence.create({actions: [move, + actions.DelayTime.create({duration: 2}), + move]}); + + this.get('grossini').runAction(action); + } +}); + +/** + * @class + * + * Example ReverseSequence Action + */ +tests.ReverseSequence = ActionDemo.extend(/** @lends ReverseSequence.prototype# */{ + title: 'Reverse a sequence', + subtitle: '', + + onEnter: function() { + tests.ReverseSequence.superclass.onEnter.call(this); + + this.alignSpritesLeft(1); + + var move1 = actions.MoveBy.create({duration: 1, position: ccp(250, 0)}); + var move2 = actions.MoveBy.create({duration: 1, position: ccp(0, 50)}); + var seq = actions.Sequence.create({actions: [move1, move2, move1.reverse()]}); + var action = actions.Sequence.create({actions: [seq, seq.reverse()]}); + + this.get('grossini').runAction(action); + } +}); + +/** + * @class + * + * Example Repeat Action + */ +tests.Repeat = ActionDemo.extend(/** @lends Repeat.prototype# */{ + title: 'Repeat / RepeatForever actions', + subtitle: '', + + onEnter: function() { + tests.Repeat.superclass.onEnter.call(this); + + this.alignSpritesLeft(2); + + var a1 = actions.MoveBy.create({duration: 1, position: ccp(150, 0)}); + var action1 = actions.Repeat.create({action: actions.Sequence.create({actions: [ + a1, + actions.Place.create({position: ccp(60, 60)}) + ]}), + times: 3}); + /* + var action2 = actions.RepeatForever.create(actions.Sequence.create({actions: [ + a1.copy(), a1.reverse() + ]})); + */ + this.get('kathia').runAction(action1); + //this.get('tamara').runAction(action2); + } +}); + +/** + * @class + * + * Example RepeatForever Action +>>>>>>> Stashed changes */ tests.Speed = ActionDemo.extend(/** @lends Speed.prototype# */{ title: 'Speed', From f0cac59b5f8969baf49602ac7f2a6bcb893e9649 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Mon, 30 May 2011 13:30:49 -0700 Subject: [PATCH 167/176] Sequence constructor modified --- src/libs/cocos2d/actions/ActionInterval.js | 190 ++++++------ tests/src/cocos2d/ActionTest.js | 286 ++++++++++++++---- tests/src/cocos2d/resources/grossini.png | Bin 0 -> 1521 bytes .../cocos2d/resources/grossinis_sister1.png | Bin 0 -> 2416 bytes .../cocos2d/resources/grossinis_sister2.png | Bin 0 -> 1656 bytes 5 files changed, 325 insertions(+), 151 deletions(-) create mode 100644 tests/src/cocos2d/resources/grossini.png create mode 100644 tests/src/cocos2d/resources/grossinis_sister1.png create mode 100644 tests/src/cocos2d/resources/grossinis_sister2.png diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index 0e96592..87ed11f 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -502,13 +502,12 @@ var JumpTo = JumpBy.extend(/** @lends cocos.actions.JumpTo# */{ } }); -/** - * @memberOf cocos.actions - * @class Fades out a cocos.nodes.Node to zero opacity - * @extends cocos.actions.ActionInterval - */ var FadeOut = ActionInterval.extend(/** @lends cocos.actions.FadeOut# */{ - + /** + * @memberOf cocos.actions + * @class Fades out a cocos.nodes.Node to zero opacity + * @extends cocos.actions.ActionInterval + */ update: function (t) { var target = this.get('target'); if (!target) return; @@ -546,11 +545,6 @@ var FadeIn = ActionInterval.extend(/** @lends cocos.actions.FadeIn# */{ } }); -/** - * @memberOf cocos.actions - * @class Fades a cocos.nodes.Node to a given opacity - * @extends cocos.actions.ActionInterval - */ var FadeTo = ActionInterval.extend(/** @lends cocos.actions.FadeTo# */{ /** * The final opacity @@ -564,6 +558,12 @@ var FadeTo = ActionInterval.extend(/** @lends cocos.actions.FadeTo# */{ */ fromOpacity: null, + /** + * @class FadeTo Fades a cocos.nodes.Node to a given opacity + * + * @memberOf cocos.actions + * @extends cocos.actions.ActionInterval + */ init: function (opts) { FadeTo.superclass.init.call(this, opts); this.set('toOpacity', opts.toOpacity); @@ -593,115 +593,86 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ */ actions: null, + split: 0, + last: 0, + /** - * The array index of the currently running action - * @type Integer - */ - currentActionIndex: 0, - - /** - * The duration when the current action finishes - * @type Float - */ - currentActionEndDuration: 0, - - /** - * Runs a number of actions sequentially, one after another + * Runs a pair of actions sequentially, one after another * * @memberOf cocos.actions * @constructs * @extends cocos.actions.ActionInterval * - * @opt {Float} duration Number of seconds to run action for - * @opt {cocos.actions.Action[]} Array of actions to run in sequence + * @opt {cocos.actions.FiniteTimeAction} one 1st action to run + * @opt {cocos.actions.FiniteTimeAction} two 2nd action to run */ init: function (opts) { - Sequence.superclass.init.call(this, opts); - - this.actionSequence = {}; - this.actions = []; //util.copy(opts.actions); - this.currentActionIndex = 0; - this.duration = 0; + if (!opts.one) { + throw "Sequence argument one must be non-nil"; + } + if (!opts.two) { + throw "Sequence argument two must be non-nil"; + } + this.actions = []; + + var d = opts.one.get('duration') + opts.two.get('duration'); - var self = this; - util.each(opts.actions, function(action) { - self.actions.push(action.copy()); - if (action.get('duration') !== undefined) { - self.duration += action.get('duration'); - } - }); - }, - - initOne: function(one, two) { - var d = one.get('duration') + two.get('duration'); Sequence.superclass.init.call(this, {duration: d}); - this.actions.push(one); - this.actions.push(tw0); + this.actions[0] = opts.one; + this.actions[1] = opts.two; }, startWithTarget: function (target) { Sequence.superclass.startWithTarget.call(this, target); - - this.currentActionIndex = 0; - this.currentActionEndDuration = this.actions[0].get('duration'); - // Not all actions have durations - if (this.currentActionEndDuration === undefined) { - this.currentActionEndDuration = 0; - } - window.console.log("starting sequence 0 duration = " + this.currentActionEndDuration); - this.actions[0].startWithTarget(this.target); + this.split = this.actions[0].get('duration') / this.get('duration'); + this.last = -1; }, stop: function () { - window.console.log("stopping sequence"); util.each(this.actions, function (action) { action.stop(); }); - Sequence.superclass.stop.call(this); }, - step: function (dt) { - window.console.log("sequence step: " + dt); - if (this._firstTick) { - this._firstTick = false; - this.elapsed = 0; - } else { - this.elapsed += dt; - } - if (this.currentActionIndex < this.actions.length) { - window.console.log("sequence " + this.currentActionIndex + " elapsed: " + this.elapsed); - this.actions[this.currentActionIndex].step(dt); - } - this.update(Math.min(1, this.elapsed / this.duration)); - - }, - - update: function (dt) { - // Action finished onto the next one - + update: function (t) { window.console.log("sequence update " + this.elapsed); - if (!this.get_isDone() && - (this.elapsed > this.currentActionEndDuration)) { - window.console.log("stopping action # " + (this.currentActionIndex+1)); - - var previousAction = this.actions[this.currentActionIndex]; - previousAction.update(1.0); - previousAction.stop(); - // UNSAFE? array bounds error in step() is possible - this.currentActionIndex++; - - if (this.currentActionIndex < this.actions.length) { - var currentAction = this.actions[this.currentActionIndex]; - currentAction.startWithTarget(this.target); - - this.currentActionEndDuration += currentAction.duration; + // This is confusing but will hopefully work better in conjunction + // with modifer actions like Repeat & Spawn... + var found = 0; + var new_t = 0; + + if (t >= this.split) { + found = 1; + if (this.split == 1) { + new_t = 1; } else { - this.stop(); + new_t = (t - this.split) / (1 - this.split); } + } else { + found = 0; + if (this.split != 0) { + new_t = t / this.split; + } else { + new_t = 1; + } + } + if (this.last == -1 && found == 1) { + this.actions[0].startWithTarget(this.target); + this.actions[0].update(1); + this.actions[0].stop(); + } + if (this.last != found) { + if (this.last != -1) { + this.actions[this.last].update(1); + this.actions[this.last].stop(); + } + this.actions[found].startWithTarget(this.target); } + this.actions[found].update(new_t); + this.last = found; }, copy: function () { @@ -710,12 +681,39 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ }, reverse: function() { - // reverse() would modify existing actions array so build new one - var ractions = []; - for (var i=0; i 0) { + var now = actions.shift().copy(); + if (now) { + prev = this.initFromPair(prev, now); + } else { + break; + } } - return Sequence.create({actions: ractions}); + return prev; + }, + + /** + * Create sequence object from a pair of actions + */ + initFromPair: function(a1, a2) { + var ret = new this(); + ret.init.apply(ret, [{one: a1, two: a2}]); + return ret; } }); diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js index 5943acb..6007e22 100644 --- a/tests/src/cocos2d/ActionTest.js +++ b/tests/src/cocos2d/ActionTest.js @@ -14,19 +14,19 @@ var util = require('util'), var sceneIdx = -1; var transitions = [ -/* "Manual", "Move", "Jump", + "Bezier", + "Blink", + "Sequence", + "Sequence2", "Spawn", "Reverse", "Delay", - */ - "Repeat" /*, - "RepeatForever", "ReverseSequence", + "RepeatForever", "Speed" - */ ]; var tests = {}; @@ -68,8 +68,27 @@ var ActionDemo = nodes.Layer.extend({ ActionDemo.superclass.init.call(this); this.set('isMouseEnabled', true); + var s = cocos.Director.get('sharedDirector').get('winSize'); + var grossini = nodes.Sprite.create({file: module.dirname + "/resources/grossini.png", + rect: new geo.Rect(0, 0, 85, 121)}); + var tamara = nodes.Sprite.create({file: module.dirname + "/resources/grossinis_sister1.png", + rect: new geo.Rect(0, 0, 52, 139)}); + var kathia = nodes.Sprite.create({file: module.dirname + "/resources/grossinis_sister2.png", + rect: new geo.Rect(0, 0, 56, 138)}); + this.set('grossini', grossini); + this.set('tamara', tamara); + this.set('kathia', kathia); + + this.addChild({child: grossini, z: 1, tag: kTagSprite1}); + this.addChild({child: tamara, z: 2, tag: kTagSprite2}); + this.addChild({child: kathia, z: 3, tag: kTagSprite3}); + + grossini.set('position', ccp(s.width/2, s.height/3)); + tamara.set('position', ccp(s.width/2, 2*s.height/3)); + kathia.set('position', ccp(s.width/2, s.height/2)); + var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); this.addChild({child: label, z: 1}); label.set('position', ccp(s.width / 2, s.height - 50)); @@ -82,7 +101,6 @@ var ActionDemo = nodes.Layer.extend({ l.set('position', ccp(s.width / 2, s.height - 80)); } - var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); @@ -93,7 +111,7 @@ var ActionDemo = nodes.Layer.extend({ item1.set('position', ccp(s.width / 2 - 100, 30)); item2.set('position', ccp(s.width / 2, 30)); item3.set('position', ccp(s.width / 2 + 100, 30)); - this.addChild({child: menu, z: 1}); + this.addChild({child: menu}); }, restartCallback: function () { @@ -123,6 +141,42 @@ var ActionDemo = nodes.Layer.extend({ director.replaceScene(scene); }, + alignSpritesLeft: function(numSprites) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + + if (numSprites == 1) { + this.get('tamara').set('visible', false); + this.get('kathia').set('visible', false); + this.get('grossini').set('position', ccp(60, s.height/2)); + } else if (numSprites == 2) { + this.get('kathia').set('position', ccp(60, s.height/3)); + this.get('tamara').set('position', ccp(60, 2*s.height/3)); + this.get('grossini').set('visible', false); + } else if (numSprites == 3) { + this.get('grossini').set('position', ccp(60, s.height/2)); + this.get('tamara').set('position', ccp(60, 2*s.height/3)); + this.get('kathia').set('position', ccp(60, s.height/3)); + } + }, + + centerSprites: function(numSprites) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + + if (numSprites == 1) { + this.get('tamara').set('visible', false); + this.get('kathia').set('visible', false); + this.get('grossini').set('position', ccp(s.width/2, s.height/2)); + } else if (numSprites == 2) { + this.get('kathia').set('position', ccp(s.width/3, s.height/2)); + this.get('tamara').set('position', ccp(2*s.width/3, s.height/2)); + this.get('grossini').set('visible', false); + } else if (numSprites == 3) { + this.get('grossini').set('position', ccp(s.width/2, s.height/2)); + this.get('tamara').set('position', ccp(2*s.width/3, s.height/2)); + this.get('kathia').set('position', ccp(s.width/3, s.height/2)); + } + }, + addNewSprite: function (point, tag) { var idx = Math.floor(Math.random() * 1400 / 100), x = (idx % 5) * 85, @@ -136,6 +190,50 @@ var ActionDemo = nodes.Layer.extend({ } }); +tests.Manual = ActionDemo.extend(/** @lends Manual.prototype# */{ + title: 'Manual Transformation', + subtitle: '', + + onEnter: function() { + tests.Manual.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + this.get('tamara').set('scale', ccp(2.5, -1.0)); + this.get('tamara').set('position', ccp(100, 70)); + this.get('tamara').set('opacity', 128); + + this.get('grossini').set('rotation', 120); + this.get('grossini').set('position', ccp(s.width/2, s.height/2)); + } +}); + +/** + * @class + * + * Example Move Action + */ +tests.Move = ActionDemo.extend(/** @lends Move.prototype# */{ + title: 'MoveTo / MoveBy', + subtitle: '', + + onEnter: function() { + tests.Move.superclass.onEnter.call(this); + + this.centerSprites(3); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var actionTo = actions.MoveTo.create({duration: 2, position: ccp(s.width-40, s.height-40)}); + var actionBy = actions.MoveBy.create({duration: 2, position: ccp(80, 80)}); + var actionByBack = actionBy.reverse(); + + this.get('tamara').runAction(actionTo); + this.get('grossini').runAction(actions.Sequence.create({actions: [actionBy, actionByBack]})); + this.get('kathia').runAction(actions.MoveTo.create({duration: 1, position: ccp(40, 40)})); + } +}); + /** * @class * @@ -145,16 +243,6 @@ tests.Jump = ActionDemo.extend(/** @lends Jump.prototype# */{ title: 'JumpTo / JumpBy', subtitle: '', - init: function () { - tests.Jump.superclass.init.call(this); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - this.addNewSprite(ccp(s.width/2, s.height/2), kTagSprite1); - this.addNewSprite(ccp(s.width/2, s.height/2), kTagSprite2); - this.addNewSprite(ccp(s.width/2, s.height/2), kTagSprite3); - }, - onEnter: function() { tests.Jump.superclass.onEnter.call(this); @@ -177,19 +265,103 @@ tests.Jump = ActionDemo.extend(/** @lends Jump.prototype# */{ /** * @class * - * Example Spawn Action + * Example Bezier Action */ -tests.Spawn = ActionDemo.extend(/** @lends Spawn.prototype# */{ - title: 'Spawn: Jump + Rotate', +tests.Bezier = ActionDemo.extend(/** @lends Bezier.prototype# */{ + title: 'BezierBy / BezierTo', + subtitle: '', + + onEnter: function() { + tests.Bezier.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + // this.alignSpritesLeft(); + + var bezier = new geo.BezierConfig(); + bezier.controlPoint1 = ccp(0, s.height/2); + bezier.controlPoint2 = ccp(300, -s.height/2); + bezier.endPosition = ccp(300,100); + + var bezierForward = actions.BezierBy.create({duration: 3, bezier: bezier}); + var bezierBack = bezierForward.reverse(); + var seq = actions.Sequence.create({actions: [bezierForward, bezierBack]}); + + this.get('tamara').set('position', ccp(80, 160)); + var bezier2 = new geo.BezierConfig(); + bezier2.controlPoint1 = ccp(100, s.height/2); + bezier2.controlPoint2 = ccp(200, -s.height/2); + bezier2.endPosition = ccp(240,160); + + var bezierTo1 = actions.BezierTo.create({duration: 2, bezier: bezier2}); + + this.get('kathia').set('position', ccp(400, 160)); + var bezierTo2 = actions.BezierTo.create({duration: 2, bezier: bezier2}); + + this.get('grossini').runAction(actions.RepeatForever.create(seq)); + this.get('tamara').runAction(bezierTo1); + this.get('kathia').runAction(bezierTo2); + } +}); + +/** + * @class + * + * Example Blink Action + */ +tests.Blink = ActionDemo.extend(/** @lends Blink.prototype# */{ + title: 'Blink', + subtitle: '', + + onEnter: function() { + tests.Blink.superclass.onEnter.call(this); + + this.centerSprites(2); + + this.get('tamara').runAction(actions.Blink.create({duration: 2, blinks: 10})); + this.get('kathia').runAction(actions.Blink.create({duration: 2, blinks: 5})); + } +}); + + +/** + * @class + * + * Example Sequence Action + */ +tests.Sequence = ActionDemo.extend(/** @lends Sequence.prototype# */{ + title: 'Sequence: Move + Rotate', + subtitle: '', + + onEnter: function() { + tests.Sequence.superclass.onEnter.call(this); + + this.alignSpritesLeft(1); + + var action = actions.Sequence.create({actions: [ + actions.MoveBy.create({duration: 2, position: ccp(240, 0)}), + actions.RotateBy.create({duration: 2, angle: 540}) + ]}); + this.get('grossini').runAction(action); + } +}); + +/** + * @class + * + * Example Sequence2 Action + */ +tests.Sequence2 = ActionDemo.extend(/** @lends Sequence2.prototype# */{ + title: 'Sequence of InstantActions', subtitle: '', onEnter: function() { tests.Sequence2.superclass.onEnter.call(this); this.alignSpritesLeft(1); + this.get('grossini').set('position', ccp(200, 200)); var action = actions.Sequence.create({actions: [ - actions.Place.create({position: ccp(200, 200)}), actions.MoveBy.create({duration: 1, position: ccp(100, 0)}), actions.CallFunc.create({target: this, method: 'callback1'}), actions.CallFunc.create({target: this, method: 'callback2'}), @@ -206,15 +378,33 @@ tests.Spawn = ActionDemo.extend(/** @lends Spawn.prototype# */{ }, callback2: function(target) { ->>>>>>> Stashed changes var s = cocos.Director.get('sharedDirector').get('winSize'); - - this.addNewSprite(ccp(0, s.height/2), kTagSprite1); + var label = cocos.nodes.Label.create({string: "callback 2 called", fontName: 'Marker Felt', fontSize: 16}); + label.set('position', ccp(s.width / 4*2, s.height / 2)); + this.addChild({child: label}); }, + callback3: function(target) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + var label = cocos.nodes.Label.create({string: "callback 3 called", fontName: 'Marker Felt', fontSize: 16}); + label.set('position', ccp(s.width / 4*3, s.height / 2)); + this.addChild({child: label}); + } +}); + +/** + * @class + * + * Example Spawn Action + */ +tests.Spawn = ActionDemo.extend(/** @lends Spawn.prototype# */{ + title: 'Spawn: Jump + Rotate', + subtitle: '', + onEnter: function() { tests.Spawn.superclass.onEnter.call(this); + this.alignSpritesLeft(1); var action = actions.Spawn.initWithActions({actions: [ actions.JumpBy.create({duration: 2, delta: ccp(300, 0), height: 50, jumps: 4}), actions.RotateBy.create({duration: 2, angle: 720}) @@ -293,57 +483,43 @@ tests.ReverseSequence = ActionDemo.extend(/** @lends ReverseSequence.prototype# /** * @class * - * Example Repeat Action + * Example RepeatForever Action */ -tests.Repeat = ActionDemo.extend(/** @lends Repeat.prototype# */{ - title: 'Repeat / RepeatForever actions', +tests.RepeatForever = ActionDemo.extend(/** @lends RepeatForever.prototype# */{ + title: 'CallFunc + RepeatForever', subtitle: '', onEnter: function() { - tests.Repeat.superclass.onEnter.call(this); - - this.alignSpritesLeft(2); - - var a1 = actions.MoveBy.create({duration: 1, position: ccp(150, 0)}); - var action1 = actions.Repeat.create({action: actions.Sequence.create({actions: [ - a1, - actions.Place.create({position: ccp(60, 60)}) - ]}), - times: 3}); - /* - var action2 = actions.RepeatForever.create(actions.Sequence.create({actions: [ - a1.copy(), a1.reverse() + tests.RepeatForever.superclass.onEnter.call(this); + + this.centerSprites(1); + + this.get('grossini').runAction(actions.Sequence.create({actions: [ + actions.DelayTime.create({duration: 1}), + actions.CallFunc.create({target: this, method: 'repeatForever'}) ]})); - */ - this.get('kathia').runAction(action1); - //this.get('tamara').runAction(action2); + }, + + repeatForever: function(target) { + target.runAction(actions.RepeatForever.create(actions.RotateBy.create({duration: 1, angle: 360}))); } }); /** * @class * - * Example RepeatForever Action ->>>>>>> Stashed changes + * Example Speed Action */ tests.Speed = ActionDemo.extend(/** @lends Speed.prototype# */{ title: 'Speed', subtitle: '', - init: function() { - tests.Speed.superclass.init.call(this); - - var s = cocos.Director.get('sharedDirector').get('winSize'); - - this.addNewSprite(ccp(0, s.height/2), kTagSprite1); - this.addNewSprite(ccp(0, s.height/2), kTagSprite2); - this.addNewSprite(ccp(0, s.height/2), kTagSprite3); - }, - onEnter: function() { tests.Speed.superclass.onEnter.call(this); var s = cocos.Director.get('sharedDirector').get('winSize'); + + this.alignSpritesLeft(3); // rotate and jump var jump1 = actions.JumpBy.create({duration: 4, delta: ccp(-s.width+80, 0), height: 100, jumps: 4}); var jump2 = jump1.reverse(); diff --git a/tests/src/cocos2d/resources/grossini.png b/tests/src/cocos2d/resources/grossini.png new file mode 100644 index 0000000000000000000000000000000000000000..afb316017ef42f03f5bac55370552f14be5c75f1 GIT binary patch literal 1521 zcmZvcdo&XY9LGnScx zwT)X7Av%SdJZI!xIJg{BZX|i^u7CRDp8GrJ`}_RyJHPXL{PE2S@bgqv(o+He0IJ?z z?r0gYGTl0;Aj@7wWNjG~F8X-7%P5O&x0YlX6t8*(Qvd*E=r_p$3X63B0MKvV?k*(*$#hd4l=!xn4DY#{y%mj5TxXk~a(Phx5KnDHlaLS+TlSazCry zuF%3LAlNGS0Np2LCrB=lgG7n`U$19Xc->T7Wl}q*hOU?9w0i&$PHs~r+i$^7DTh~1 ze}NSM^ThHSgh+cZ@(3S}$vk;4Wt)dC3IzSZVx!AOCrprX#s<$Vt#esQVuQgU5zrEX zmACL#u8VPGLfJL$<%@@*Pi^Zq=V_RwTiL`<^W`z$hNt!zW7&G^ey(rOx>b-(C=YA6 z0*lFB7hA?6Hk)F!_~Qg@vcW%sNqhL>BnmXY&{$(y*^7h=i*$$ z!o-iGLq?3M9_hsl6vFfD1H#d4XKzH~m~M(Z)OC7_;h7m(*ysE9RUrf}H?3c{_7nN7 zwz1iHw$bS2IDs{LYyg^>jEUfkhiI-W-dNX6nPW{TX*HGZdFvtN%(h_l$mSx{jz$04 z(zr@Kzw-PUVF60B|3wlmr%%#(=vPV-xj;Z04lD7iu)eI4orjH{C(R%EToiU`( zg;I438+GvpSQB9g$QC@_O-Z%II@+ZJB2*w!lF=o*A{w*EV~&N_-_Ma_o^TGnq&%1# zSL;yxBJ6e+?D?Fj@7%)sE}Ov6-zR5P^1?gISSej6x?210iR{rzk2@uZItyHbCLDoW zF3`a!A)X30r_d+WR%IvHYIVMTJN4u3gy*$8!}}#bv&e=z78Pv40a_`{SSsd3rct%o z8GEPz6XW!cfBJ#9CKQ}zXWA5CIIS&dR>tCkyJ_lkDxjB$O_&y{k2{8^*LqODT$%ja z0oKp4x?v$UD!bNV%l|o!CUI(xZ7j(=uxi6@Lps+T!#W8^aYEcg{Qd^s^aX@Y1(P_b zJe!y}0q8N+W92|P7rAE}+bkhvfWQha-FZDkLmfgS=Z8uB=g9`Kg#JE|MtJXjP&h}# zgE!l_w5|X{=nFt4n^PQg{pm8qC>~v0h3_9w)i_k>TU~`IGURP8#qJQIh-Ql%cRgu! zc59TUlz`biisSV6T883=Xh%%VMl1iRHxHV<`sGx8$5tcBuVJzqNg0LjJwOe`!Rhzk z0T*h|80FBrmPCoGwTbUa;a(?AO*?9k^X+z{K^#@~;4fkQdlAAXDpB%E7W^uO83G7s zf4^MFugTc^TunN&9F#OdghcVSHPob?k!HzaLY{-TDM;f=EaG9@feF}NQx(MSt_hYw z7-sBt!>!*W)y-5EJvcD!A2NM05<>0c#GoNUw+mbS^o``Kw(( za{hlkDYd5z#B@=Hr(w!PJ*|m`;t^O%&HN9^X%1#$|B>(2|8L`}1*|St(s0AH)(dT7 zD<*BwjS}DiT8VA=Ani68nQ5T*km%S@pX*Dn*P8XNosi?U{{R)c?hNpdBU_(umPF!mWr$l^n NZf_4icfMc6|Y#xwu` literal 0 HcmV?d00001 diff --git a/tests/src/cocos2d/resources/grossinis_sister1.png b/tests/src/cocos2d/resources/grossinis_sister1.png new file mode 100644 index 0000000000000000000000000000000000000000..745a5cd66a52e6fafcf7ced3681aed1f25014788 GIT binary patch literal 2416 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 Date: Mon, 30 May 2011 13:58:26 -0700 Subject: [PATCH 168/176] Sequence passing tests and working with Repeat --- src/libs/cocos2d/actions/ActionInterval.js | 12 ++------- tests/src/cocos2d/ActionTest.js | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index 0e7ac01..7124657 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -759,15 +759,12 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ }, stop: function () { - util.each(this.actions, function (action) { - action.stop(); - }); + this.actions[0].stop(); + this.actions[1].stop(); Sequence.superclass.stop.call(this); }, update: function (t) { - window.console.log("sequence update " + this.elapsed); - // This is confusing but will hopefully work better in conjunction // with modifer actions like Repeat & Spawn... var found = 0; @@ -804,11 +801,6 @@ var Sequence = ActionInterval.extend(/** @lends cocos.actions.Sequence# */{ this.last = found; }, - get_isDone: function () { - return ((this.elapsed >= this.duration) && - (this.currentActionIndex >= this.actions.length)); - }, - copy: function () { // Constructor will copy actions return Sequence.create({actions: this.get('actions')}); diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js index 6007e22..3d71a1b 100644 --- a/tests/src/cocos2d/ActionTest.js +++ b/tests/src/cocos2d/ActionTest.js @@ -25,6 +25,7 @@ var transitions = [ "Reverse", "Delay", "ReverseSequence", + "Repeat", "RepeatForever", "Speed" ]; @@ -480,6 +481,35 @@ tests.ReverseSequence = ActionDemo.extend(/** @lends ReverseSequence.prototype# } }); +/** + * @class + * + * Example Repeat Action + */ +tests.Repeat = ActionDemo.extend(/** @lends Repeat.prototype# */{ + title: 'Repeat / RepeatForever actions', + subtitle: '', + + onEnter: function() { + tests.Repeat.superclass.onEnter.call(this); + + this.alignSpritesLeft(2); + + var a1 = actions.MoveBy.create({duration: 1, position: ccp(150, 0)}); + var action1 = actions.Repeat.create({action: actions.Sequence.create({actions: [ + actions.Place.create({position: ccp(60, 60)}), + a1 + ]}), + times: 3}); + + var action2 = actions.RepeatForever.create(actions.Sequence.create({actions: [ + a1.copy(), a1.reverse()]})); + + this.get('kathia').runAction(action1); + this.get('tamara').runAction(action2); + } +}); + /** * @class * From 4b6cc1916ebcb06282b3f5dbe26007e94fe2f108 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Mon, 30 May 2011 15:57:07 -0700 Subject: [PATCH 169/176] Hide, Show, ToggleVisibility added --- src/libs/cocos2d/actions/ActionInstant.js | 67 +++++++++++++++- src/libs/cocos2d/actions/ActionInterval.js | 8 +- tests/src/cocos2d/ActionTest.js | 93 +++++++++++++++++++++- 3 files changed, 160 insertions(+), 8 deletions(-) diff --git a/src/libs/cocos2d/actions/ActionInstant.js b/src/libs/cocos2d/actions/ActionInstant.js index 695a245..9a7aced 100644 --- a/src/libs/cocos2d/actions/ActionInstant.js +++ b/src/libs/cocos2d/actions/ActionInstant.js @@ -19,23 +19,79 @@ var ActionInstant = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionI this.duration = 0; }, + get_isDone: function () { return true; }, + step: function (dt) { this.update(1); }, + update: function (t) { // ignore }, + copy: function() { - throw "copy() not implemented on this action"; + throw "Implement copy()"; }, + reverse: function () { return this.copy(); } }); +var Show = ActionInstant.extend(/** @lends cocos.actions.Show# */{ + /** + * @class Show Show the node + **/ + startWithTarget: function(target) { + Show.superclass.startWithTarget.call(this, target); + this.target.set('visible', true); + }, + + copy: function() { + return Show.create(); + }, + + reverse: function() { + return exports.Hide.create(); + } +}); + +var Hide = ActionInstant.extend(/** @lends cocos.actions.Hide# */{ + /** + * @class Hide Hide the node + **/ + startWithTarget: function(target) { + Show.superclass.startWithTarget.call(this, target); + this.target.set('visible', false); + }, + + copy: function() { + return Hide.create(); + }, + + reverse: function() { + return exports.Show.create(); + } +}); + +var ToggleVisibility = ActionInstant.extend(/** @lends cocos.actions.ToggleVisibility# */{ + /** + * @class ToggleVisibility Toggles the visibility of a node + **/ + startWithTarget: function(target) { + ToggleVisibility.superclass.startWithTarget.call(this, target); + var vis = this.target.get('visible'); + this.target.set('visible', !vis); + }, + + copy: function() { + return ToggleVisibility.create(); + } +}); + var FlipX = ActionInstant.extend(/** @lends cocos.actions.FlipX# */{ flipX: false, @@ -53,14 +109,17 @@ var FlipX = ActionInstant.extend(/** @lends cocos.actions.FlipX# */{ this.flipX = opts.flipX; }, + startWithTarget: function (target) { FlipX.superclass.startWithTarget.call(this, target); target.set('flipX', this.flipX); }, + reverse: function () { return FlipX.create({flipX: !this.flipX}); }, + copy: function () { return FlipX.create({flipX: this.flipX}); } @@ -83,14 +142,17 @@ var FlipY = ActionInstant.extend(/** @lends cocos.actions.FlipY# */{ this.flipY = opts.flipY; }, + startWithTarget: function (target) { FlipY.superclass.startWithTarget.call(this, target); target.set('flipY', this.flipY); }, + reverse: function () { return FlipY.create({flipY: !this.flipY}); }, + copy: function () { return FlipY.create({flipY: this.flipY}); } @@ -163,6 +225,9 @@ var CallFunc = ActionInstant.extend(/** @lends cocos.actions.CallFunc# */{ }); exports.ActionInstant = ActionInstant; +exports.Show = Show; +exports.Hide = Hide; +exports.ToggleVisibility = ToggleVisibility; exports.FlipX = FlipX; exports.FlipY = FlipY; exports.Place = Place; diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index 7124657..4e4dddd 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -819,11 +819,11 @@ util.extend(Sequence, { create: function() { // Copy actions array var actions = util.copy(arguments[0].actions); - var prev = actions.shift().copy(); + var prev = actions.shift(); // Recursively create Sequence with pair of actions while (actions.length > 0) { - var now = actions.shift().copy(); + var now = actions.shift(); if (now) { prev = this.initFromPair(prev, now); } else { @@ -881,10 +881,8 @@ var Repeat = ActionInterval.extend(/** @lends cocos.actions.Repeat# */{ update: function(dt) { var t = dt * this.times; - //window.console.log("Repeat:update() dt = " + dt + ", t = " + t); if (t > (this.total+1)) { - window.console.log("t > total+1"); this.other.update(1); this.total += 1; this.other.stop(); @@ -892,11 +890,9 @@ var Repeat = ActionInterval.extend(/** @lends cocos.actions.Repeat# */{ // If repeat is over if (this.total == this.times) { - window.console.log("repeat is over"); // set it in the original position this.other.update(0); } else { - window.console.log("starting next repeat"); // otherwise start next repeat this.other.update(t - this.total); } diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js index 3d71a1b..8332c80 100644 --- a/tests/src/cocos2d/ActionTest.js +++ b/tests/src/cocos2d/ActionTest.js @@ -24,9 +24,12 @@ var transitions = [ "Spawn", "Reverse", "Delay", - "ReverseSequence", "Repeat", "RepeatForever", + "RotateToRepeat", + "RotateJerk", + "ReverseSequence", + "ReverseSequence2", "Speed" ]; @@ -535,6 +538,94 @@ tests.RepeatForever = ActionDemo.extend(/** @lends RepeatForever.prototype# */{ } }); +/** + * @class + * + * Example RotateToRepeat Action + */ +tests.RotateToRepeat = ActionDemo.extend(/** @lends RotateToRepeat.prototype# */{ + title: 'Repeat/RepeatForever + RotateTo', + subtitle: 'You should see smooth movements', + + onEnter: function() { + tests.RotateToRepeat.superclass.onEnter.call(this); + + this.centerSprites(2); + + var act1 = actions.RotateTo.create({duration: 1, angle: 90}); + var act2 = actions.RotateTo.create({duration: 1, angle: 0}); + var seq = actions.Sequence.create({actions: [act1, act2]}); + var rep1 = actions.RepeatForever.create(seq); + var rep2 = actions.Repeat.create({action: seq, times: 10}); + + this.get('tamara').runAction(rep1); + this.get('kathia').runAction(rep2); + } +}); + +/** + * @class + * + * Example RotateJerk Action + */ +tests.RotateJerk = ActionDemo.extend(/** @lends RotateJerk.prototype# */{ + title: 'RepeatForever / Repeat + RotateTo', + subtitle: 'You should see smooth movements', + + onEnter: function() { + tests.RotateJerk.superclass.onEnter.call(this); + + this.centerSprites(2); + + var seq = actions.Sequence.create({actions: [ + actions.RotateTo.create({duration: 0.5, angle :-20}), + actions.RotateTo.create({duration: 0.5, angle: 20}) + ]}); + var rep1 = actions.Repeat.create({action: seq, times: 10}); + var rep2 = actions.RepeatForever.create(seq); + this.get('tamara').runAction(rep1); + this.get('kathia').runAction(rep2); + } +}); + +/** + * @class + * + * Example ReverseSequence2 Action + */ +tests.ReverseSequence2 = ActionDemo.extend(/** @lends ReverseSequence2.prototype# */{ + title: 'Reverse sequence 2', + subtitle: '', + + onEnter: function() { + tests.ReverseSequence2.superclass.onEnter.call(this); + + this.alignSpritesLeft(2); + + // Sequence should work both with IntervalAction and InstantActions + var move1 = actions.MoveBy.create({duration: 1, position: ccp(250, 0)}); + var move2 = actions.MoveBy.create({duration: 1, position: ccp(0, 50)}); + var tog1 = actions.ToggleVisibility.create(); + var tog2 = actions.ToggleVisibility.create(); + var seq = actions.Sequence.create({actions: [move1, tog1, move2, tog2, move1.reverse()]}); + var action = actions.Repeat.create({action: actions.Sequence.create({actions: [ + seq, seq.reverse() + ]}), + times: 3}); + this.get('kathia').runAction(action); + + // Also test that the reverse of Hide is Show, and vice-versa + var move_t = actions.MoveBy.create({duration: 1, position: ccp(100, 0)}); + var move_t2 = actions.MoveBy.create({duration: 1, position: ccp(50, 0)}); + var hide = actions.Hide.create(); + var seq_t = actions.Sequence.create({actions: [ + move_t, hide, move_t2]}); + var seq_back = seq_t.reverse(); + this.get('tamara').runAction(actions.Sequence.create({actions: [ + seq_t, seq_back]})); + } +}); + /** * @class * From 9ce6000b6cee9cb432254c8903804a203064e17c Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Mon, 30 May 2011 20:25:27 -0700 Subject: [PATCH 170/176] EaseIn to EaseSineOut implemented --- src/global.js | 43 +-- src/libs/cocos2d/actions/Action.js | 4 +- src/libs/cocos2d/actions/ActionEase.js | 265 ++++++++++++++++ src/libs/cocos2d/actions/ActionInterval.js | 10 +- src/libs/cocos2d/actions/index.js | 2 +- src/libs/geometry.js | 2 + tests/public/index.html | 1 + tests/src/cocos2d/EaseActionTest.js | 344 +++++++++++++++++++++ 8 files changed, 625 insertions(+), 46 deletions(-) create mode 100644 src/libs/cocos2d/actions/ActionEase.js create mode 100644 tests/src/cocos2d/EaseActionTest.js diff --git a/src/global.js b/src/global.js index 3545c9c..419bc61 100644 --- a/src/global.js +++ b/src/global.js @@ -6,24 +6,6 @@ var util = require('util'), events = require('events'); - -if (!Object.keys) { - Object.keys = function(o){ - if (o !== Object(o)) { - throw new TypeError('Object.keys called on non-object'); - } - var ret=[], - p; - for (p in o) { - if (Object.prototype.hasOwnProperty.call(o,p)) { - ret.push(p); - } - } - return ret; - } -} - - /** * @ignore */ @@ -89,35 +71,20 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ * access the property directly. This will ensure all bindings, setters and * getters work correctly. * - * @param {String} key Name of property to get or dot (.) separated path to a property + * @param {String} key Name of property to get * @returns {*} Value of the property */ get: function (key) { - var next = false - if (~key.indexOf('.')) { - var tokens = key.split('.'); - key = tokens.shift(); - next = tokens.join('.'); - } - - - var accessor = getAccessors(this)[key], - val; + var accessor = getAccessors(this)[key]; if (accessor) { - val = accessor.target.get(accessor.key); + return accessor.target.get(accessor.key); } else { // Call getting function if (this['get_' + key]) { - val = this['get_' + key](); - } else { - val = this[key]; + return this['get_' + key](); } - } - if (next) { - return val.get(next); - } else { - return val; + return this[key]; } }, diff --git a/src/libs/cocos2d/actions/Action.js b/src/libs/cocos2d/actions/Action.js index 3cade20..3da2b80 100644 --- a/src/libs/cocos2d/actions/Action.js +++ b/src/libs/cocos2d/actions/Action.js @@ -31,7 +31,7 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ * @param {Float} dt The delta time */ step: function (dt) { - console.warn("Action.step() Override me"); + window.console.warn("Action.step() Override me"); }, /** @@ -40,7 +40,7 @@ var Action = BObject.extend(/** @lends cocos.actions.Action# */{ * @param {Float} time How much of the animation has played. 0.0 = just started, 1.0 just finished. */ update: function (time) { - console.warn("Action.update() Override me"); + window.console.warn("Action.update() Override me"); }, /** diff --git a/src/libs/cocos2d/actions/ActionEase.js b/src/libs/cocos2d/actions/ActionEase.js new file mode 100644 index 0000000..941d15d --- /dev/null +++ b/src/libs/cocos2d/actions/ActionEase.js @@ -0,0 +1,265 @@ +/*globals module exports resource require BObject BArray*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + +var util = require('util'), + ActionInterval = require('./ActionInterval').ActionInterval, + geo = require('geometry'), + ccp = geo.ccp; + +var ActionEase = ActionInterval.extend(/** @lends cocos.actions.ActionEase# */{ + other: null, + + /** + * @class Base class for Easing actions + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.ActionEase + * + * @opt {cocos.actions.ActionInterval} action + */ + init: function(opts) { + if (!opts.action) { + throw "Ease: action argument must be non-nil"; + } + ActionEase.superclass.init.call(this, {duration: opts.action.duration}); + + this.other = opts.action; + }, + + startWithTarget: function(target) { + ActionEase.superclass.startWithTarget.call(this, target); + this.other.startWithTarget(this.target); + }, + + stop: function() { + this.other.stop(); + ActionEase.superclass.stop.call(this); + }, + /* + update: function(t) { + this.other.update(t); + }, + */ + copy: function() { + return ActionEase.create({action: this.other.copy()}); + }, + + reverse: function() { + return ActionEase.create({action: this.other.reverse()}); + } +}); + +var EaseRate = ActionEase.extend(/** @lends cocos.actions.EaseRate# */{ + /** + * rate value for the actions + * @type {Float} + */ + rate: 0, + + /** + * @class EaseRate Base class for Easing actions with rate parameter + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.ActionEase + * + * @opt {cocos.actions.ActionInterval} action + * @opt {Float} rate + */ + init: function(opts) { + EaseRate.superclass.init.call(this, opts); + + this.rate = opts.rate; + }, + + copy: function() { + return EaseRate.create({action: this.other.copy(), rate: this.rate}); + }, + + reverse: function() { + return EaseRate.create({action: this.other.reverse(), rate: 1 / this.rate}); + } +}); + +var EaseIn = EaseRate.extend(/** @lends cocos.actions.EaseIn# */{ + /** + * @class EaseIn EaseIn action with a rate + */ + update: function(t) { + this.other.update(Math.pow(t, this.rate)); + }, + + copy: function() { + return EaseIn.create({action: this.other.copy(), rate: this.rate}); + }, + + reverse: function() { + return EaseIn.create({action: this.other.reverse(), rate: 1 / this.rate}); + } +}); + +var EaseOut = EaseRate.extend(/** @lends cocos.actions.EaseOut# */{ + /** + * @class EaseOut EaseOut action with a rate + */ + update: function(t) { + this.other.update(Math.pow(t, 1/this.rate)); + }, + + copy: function() { + return EaseOut.create({action: this.other.copy(), rate: this.rate}); + }, + + reverse: function() { + return EaseOut.create({action: this.other.reverse(), rate: 1 / this.rate}); + } +}); + +var EaseInOut = EaseRate.extend(/** @lends cocos.actions.EaseInOut# */{ + /** + * @class EaseInOut EaseInOut action with a rate + */ + update: function(t) { + var sign = 1; + var r = Math.floor(this.rate); + if (r % 2 == 0) { + sign = -1; + } + t *= 2; + if (t < 1) { + this.other.update(0.5 * Math.pow(t, this.rate)); + } else { + this.other.update(sign * 0.5 * (Math.pow(t-2, this.rate) + sign * 2)); + } + }, + + copy: function() { + return EaseInOut.create({action: this.other.copy(), rate: this.rate}); + }, + + reverse: function() { + return EaseInOut.create({action: this.other.reverse(), rate: this.rate}); + } +}); + +var EaseExponentialIn = ActionEase.extend(/** @lends cocos.actions.EaseExponentialIn# */{ + /** + * @class EaseExponentialIn EaseExponentialIn action + */ + update: function(t) { + this.other.update((t == 0) ? 0 : Math.pow(2, 10 * (t/1 - 1)) - 1 * 0.001); + }, + + copy: function() { + return EaseExponentialIn.create({action: this.other.copy()}); + }, + + reverse: function() { + return exports.EaseExponentialOut.create({action: this.other.reverse()}); + } +}); + +var EaseExponentialOut = ActionEase.extend(/** @lends cocos.actions.EaseExponentialOut# */{ + /** + * @class EaseExponentialOut EaseExponentialOut action + */ + update: function(t) { + this.other.update((t == 1) ? 1 : (-Math.pow(2, -10 * t/1) + 1)); + }, + + copy: function() { + return EaseExponentialOut.create({action: this.other.copy()}); + }, + + reverse: function() { + return exports.EaseExponentialIn.create({action: this.other.reverse()}); + } +}); + +var EaseExponentialInOut = ActionEase.extend(/** @lends cocos.actions.EaseExponentialInOut# */{ + /** + * @class EaseExponentialInOut EaseExponentialInOut action + */ + update: function(t) { + t /= 0.5; + if (t < 1) { + t = 0.5 * Math.pow(2, 10 * (t - 1)); + } else { + t = 0.5 * (Math.pow(2, -10 * (t - 1)) + 2); + } + this.other.update(t); + }, + + copy: function() { + return EaseExponentialInOut.create({action: this.other.copy()}); + }, + + reverse: function() { + return EaseExponentialInOut.create({action: this.other.reverse()}); + } +}); + +var EaseSineIn = ActionEase.extend(/** @lends cocos.actions.EaseSineIn# */{ + /** + * @class EaseSineIn EaseSineIn action + */ + update: function(t) { + this.other.update(-1 * Math.cos(t * Math.PI_2) + 1); + }, + + copy: function() { + return EaseSineIn.create({action: this.other.copy()}); + }, + + reverse: function() { + return exports.EaseSineOut.create({action: this.other.reverse()}); + } +}); + +var EaseSineOut = ActionEase.extend(/** @lends cocos.actions.EaseSineOut# */{ + /** + * @class EaseSineOut EaseSineOut action + */ + update: function(t) { + this.other.update(t * Math.sin(t * Math.PI_2)); + }, + + copy: function() { + return EaseSineOut.create({action: this.other.copy()}); + }, + + reverse: function() { + return exports.EaseSineIn.create({action: this.other.reverse()}); + } +}); + +var EaseSineInOut = ActionEase.extend(/** @lends cocos.actions.EaseSineInOut# */{ + /** + * @class EaseSineInOut EaseSineInOut action + */ + update: function(t) { + this.other.update(-0.5 * (Math.cos(t * Math.PI) - 1)); + }, + + copy: function() { + return EaseSineInOut.create({action: this.other.copy()}); + }, + + reverse: function() { + return EaseSineInOut.create({action: this.other.reverse()}); + } +}); + +exports.ActionEase = ActionEase; +exports.EaseRate = EaseRate; +exports.EaseIn = EaseIn; +exports.EaseOut = EaseOut; +exports.EaseInOut = EaseInOut; +exports.EaseExponentialIn = EaseExponentialIn; +exports.EaseExponentialOut = EaseExponentialOut; +exports.EaseExponentialInOut = EaseExponentialInOut; +exports.EaseSineIn = EaseSineIn; +exports.EaseSineOut = EaseSineOut; +exports.EaseSineInOut = EaseSineInOut; diff --git a/src/libs/cocos2d/actions/ActionInterval.js b/src/libs/cocos2d/actions/ActionInterval.js index 4e4dddd..7be4b2a 100644 --- a/src/libs/cocos2d/actions/ActionInterval.js +++ b/src/libs/cocos2d/actions/ActionInterval.js @@ -817,13 +817,13 @@ util.extend(Sequence, { * of actions array */ create: function() { - // Copy actions array - var actions = util.copy(arguments[0].actions); - var prev = actions.shift(); + // Don't copy actions array, copy the actions + var actions = arguments[0].actions; + var prev = actions[0].copy(); // Recursively create Sequence with pair of actions - while (actions.length > 0) { - var now = actions.shift(); + for (var i=1; iTests

            • CommonJS
            • Sprites
            • Actions
            • +
            • Ease Actions
            • Tile Maps
            • Scene Transitions
            • QUnit
            • diff --git a/tests/src/cocos2d/EaseActionTest.js b/tests/src/cocos2d/EaseActionTest.js new file mode 100644 index 0000000..6ba2cd5 --- /dev/null +++ b/tests/src/cocos2d/EaseActionTest.js @@ -0,0 +1,344 @@ +/* module exports resource require*/ +/*jslint undef: true, strict: true, white: true, newcap: true, browser: true, indent: 4 */ +"use strict"; + +var util = require('util'), + Texture2D = require('cocos2d/Texture2D').Texture2D, + Scheduler = require('cocos2d/Scheduler').Scheduler, + cocos = require('cocos2d'), + events = require('events'), + nodes = cocos.nodes, + actions = cocos.actions, + geo = require('geometry'), + ccp = geo.ccp; + +var sceneIdx = -1; +var transitions = [ + "SpriteEase", + "SpriteEaseInOut", + "SpriteEaseExponential", + "SpriteEaseExponentialInOut", + "SpriteEaseSine", + "SpriteEaseSineInOut" +]; + +var tests = {}; + +var kTagSprite1 = 1, + kTagSprite2 = 2, + kTagSprite3 = 3; + +var kTagAction1 = 1, + kTagAction2 = 2, + kTagSlider = 1; + +function nextAction() { + sceneIdx++; + sceneIdx = sceneIdx % transitions.length; + + var r = transitions[sceneIdx]; + return tests[r]; +} +function backAction() { + sceneIdx--; + if (sceneIdx < 0) { + sceneIdx += transitions.length; + } + + var r = transitions[sceneIdx]; + return tests[r]; +} +function restartAction() { + var r = transitions[sceneIdx]; + return tests[r]; +} + +var SpriteDemo = nodes.Layer.extend({ + title: 'No title', + subtitle: null, + + init: function () { + SpriteDemo.superclass.init.call(this); + + this.set('isMouseEnabled', true); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var grossini = nodes.Sprite.create({file: module.dirname + "/resources/grossini.png", + rect: new geo.Rect(0, 0, 85, 121)}); + var tamara = nodes.Sprite.create({file: module.dirname + "/resources/grossinis_sister1.png", + rect: new geo.Rect(0, 0, 52, 139)}); + var kathia = nodes.Sprite.create({file: module.dirname + "/resources/grossinis_sister2.png", + rect: new geo.Rect(0, 0, 56, 138)}); + this.set('grossini', grossini); + this.set('tamara', tamara); + this.set('kathia', kathia); + + this.addChild({child: grossini, z: 3, tag: kTagSprite1}); + this.addChild({child: kathia, z: 2, tag: kTagSprite3}); + this.addChild({child: tamara, z: 1, tag: kTagSprite2}); + + grossini.set('position', ccp(60, 50)); + kathia.set('position', ccp(60, 150)); + tamara.set('position', ccp(60, 250)); + + var label = nodes.Label.create({string: this.get('title'), fontName: 'Arial', fontSize: 26}); + this.addChild({child: label, z: 1}); + label.set('position', ccp(s.width / 2, s.height - 50)); + + + var subtitle = this.get('subtitle'); + if (subtitle) { + var l = nodes.Label.create({string: subtitle, fontName: "Thonburi", fontSize: 16}); + this.addChild({child: l, z: 1}); + l.set('position', ccp(s.width / 2, s.height - 80)); + } + + var item1 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/b1.png", selectedImage: module.dirname + "/resources/b2.png", callback: util.callback(this, 'backCallback')}); + var item2 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/r1.png", selectedImage: module.dirname + "/resources/r2.png", callback: util.callback(this, 'restartCallback')}); + var item3 = nodes.MenuItemImage.create({normalImage: module.dirname + "/resources/f1.png", selectedImage: module.dirname + "/resources/f2.png", callback: util.callback(this, 'nextCallback')}); + + var menu = nodes.Menu.create({items: [item1, item2, item3]}); + + menu.set('position', ccp(0, 0)); + item1.set('position', ccp(s.width / 2 - 100, 30)); + item2.set('position', ccp(s.width / 2, 30)); + item3.set('position', ccp(s.width / 2 + 100, 30)); + this.addChild({child: menu}); + }, + + restartCallback: function () { + var director = cocos.Director.get('sharedDirector'); + + var scene = nodes.Scene.create(); + scene.addChild({child: restartAction().create()}); + + director.replaceScene(scene); + }, + + backCallback: function () { + var director = cocos.Director.get('sharedDirector'); + + var scene = nodes.Scene.create(); + scene.addChild({child: backAction().create()}); + + director.replaceScene(scene); + }, + + nextCallback: function () { + var director = cocos.Director.get('sharedDirector'); + + var scene = nodes.Scene.create(); + scene.addChild({child: nextAction().create()}); + + director.replaceScene(scene); + }, + + positionForTwo: function() { + this.get('grossini').set('position', ccp(60, 120)); + this.get('tamara').set('position', ccp(60, 220)); + this.get('kathia').set('visible', false); + } +}); + +tests.SpriteEase = SpriteDemo.extend(/** @lends SpriteEase.prototype# */{ + title: 'EaseIn - EaseOut - Stop', + subtitle: '', + + onEnter: function() { + tests.SpriteEase.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease_in = actions.EaseIn.create({action: move.copy(), rate: 3}); + var move_ease_in_back = move_ease_in.reverse(); + + var move_ease_out = actions.EaseOut.create({action: move.copy(), rate: 3}); + var move_ease_out_back = move_ease_out.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease_in, delay.copy(), move_ease_in_back, delay.copy()]}); + var seq3 = actions.Sequence.create({actions: [move_ease_out, delay.copy(), move_ease_out_back, delay.copy()]}); + + var a2 = this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + var a1 = this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + var a = this.get('kathia').runAction(actions.RepeatForever.create(seq3)); + + Scheduler.get('sharedScheduler').schedule({target: this, method: 'testStopAction', interval: 6.25, paused: !this.get('isRunning')}); + }, + + testStopAction: function(dt) { + Scheduler.get('sharedScheduler').unschedule({target: this, method: 'testStopAction'}); + this.get('tamara').stopAllActions(); + this.get('kathia').stopAllActions(); + this.get('grossini').stopAllActions(); + } +}); + +tests.SpriteEaseInOut = SpriteDemo.extend(/** @lends SpriteEaseInOut.prototype# */{ + title: 'EaseInOut and rates', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseInOut.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + + var move_ease_inout1 = actions.EaseInOut.create({action: move.copy(), rate: 2}); + var move_ease_inout_back1 = move_ease_inout1.reverse(); + + var move_ease_inout2 = actions.EaseInOut.create({action: move.copy(), rate: 3}); + var move_ease_inout_back2 = move_ease_inout2.reverse(); + + var move_ease_inout3 = actions.EaseInOut.create({action: move.copy(), rate: 4}); + var move_ease_inout_back3 = move_ease_inout3.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move_ease_inout1, delay, move_ease_inout_back1, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease_inout2, delay.copy(), move_ease_inout_back2, delay.copy()]}); + var seq3 = actions.Sequence.create({actions: [move_ease_inout3, delay.copy(), move_ease_inout_back3, delay.copy()]}); + + this.get('tamara').runAction(actions.RepeatForever.create(seq1)); + this.get('kathia').runAction(actions.RepeatForever.create(seq2)); + this.get('grossini').runAction(actions.RepeatForever.create(seq3)); + } +}); + +tests.SpriteEaseExponential = SpriteDemo.extend(/** @lends SpriteEaseExponential.prototype# */{ + title: 'ExpIn - ExpOut actions', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseExponential.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease_in = actions.EaseExponentialIn.create({action: move.copy()}); + var move_ease_in_back = move_ease_in.reverse(); + + var move_ease_out = actions.EaseExponentialOut.create({action: move.copy()}); + var move_ease_out_back = move_ease_out.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease_in, delay.copy(), move_ease_in_back, delay.copy()]}); + var seq3 = actions.Sequence.create({actions: [move_ease_out, delay.copy(), move_ease_out_back, delay.copy()]}); + + this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + this.get('kathia').runAction(actions.RepeatForever.create(seq3)); + } +}); + +tests.SpriteEaseExponentialInOut = SpriteDemo.extend(/** @lends SpriteEaseExponentialInOut.prototype# */{ + title: 'EaseExponentialInOut action', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseExponentialInOut.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease = actions.EaseExponentialInOut.create({action: move.copy()}); + var move_ease_back = move_ease.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease, delay.copy(), move_ease_back, delay.copy()]}); + + this.positionForTwo(); + + this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + } +}); + +tests.SpriteEaseSine = SpriteDemo.extend(/** @lends SpriteEaseSine.prototype# */{ + title: 'EaseSineIn - EaseSineOut', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseSine.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease_in = actions.EaseSineIn.create({action: move.copy()}); + var move_ease_in_back = move_ease_in.reverse(); + + var move_ease_out = actions.EaseSineOut.create({action: move.copy()}); + var move_ease_out_back = move_ease_out.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease_in, delay.copy(), move_ease_in_back, delay.copy()]}); + var seq3 = actions.Sequence.create({actions: [move_ease_out, delay.copy(), move_ease_out_back, delay.copy()]}); + + this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + this.get('kathia').runAction(actions.RepeatForever.create(seq3)); + } +}); + +tests.SpriteEaseSineInOut = SpriteDemo.extend(/** @lends SpriteEaseSineInOut.prototype# */{ + title: 'EaseSineInOut action', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseSineInOut.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease = actions.EaseSineInOut.create({action: move.copy()}); + var move_ease_back = move_ease.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease, delay.copy(), move_ease_back, delay.copy()]}); + + this.positionForTwo(); + + this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + } +}); + + +exports.main = function () { + // Initialise test + var director = cocos.Director.get('sharedDirector'); + + director.attachInView(document.getElementById('cocos2d-tests')); + director.set('displayFPS', true); + + events.addListener(director, 'ready', function (director) { + var scene = nodes.Scene.create(); + scene.addChild({child: nextAction().create()}); + director.replaceScene(scene); + }); + + director.runPreloadScene(); +}; From 05453b77bbe47ffa9f37b0542a57295aa0284271 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Wed, 1 Jun 2011 20:32:40 -0700 Subject: [PATCH 171/176] added last few ease actions --- src/libs/cocos2d/actions/ActionEase.js | 283 +++++++++++++++++++++- src/libs/cocos2d/actions/ActionInstant.js | 2 +- tests/src/cocos2d/EaseActionTest.js | 183 +++++++++++++- 3 files changed, 463 insertions(+), 5 deletions(-) diff --git a/src/libs/cocos2d/actions/ActionEase.js b/src/libs/cocos2d/actions/ActionEase.js index 941d15d..87b8cc0 100644 --- a/src/libs/cocos2d/actions/ActionEase.js +++ b/src/libs/cocos2d/actions/ActionEase.js @@ -149,7 +149,7 @@ var EaseExponentialIn = ActionEase.extend(/** @lends cocos.actions.EaseExponenti * @class EaseExponentialIn EaseExponentialIn action */ update: function(t) { - this.other.update((t == 0) ? 0 : Math.pow(2, 10 * (t/1 - 1)) - 1 * 0.001); + this.other.update((t == 0) ? 0 : (Math.pow(2, 10 * (t/1 - 1)) - 1 * 0.001)); }, copy: function() { @@ -187,7 +187,7 @@ var EaseExponentialInOut = ActionEase.extend(/** @lends cocos.actions.EaseExpone if (t < 1) { t = 0.5 * Math.pow(2, 10 * (t - 1)); } else { - t = 0.5 * (Math.pow(2, -10 * (t - 1)) + 2); + t = 0.5 * (-Math.pow(2, -10 * (t - 1)) + 2); } this.other.update(t); }, @@ -223,7 +223,7 @@ var EaseSineOut = ActionEase.extend(/** @lends cocos.actions.EaseSineOut# */{ * @class EaseSineOut EaseSineOut action */ update: function(t) { - this.other.update(t * Math.sin(t * Math.PI_2)); + this.other.update(Math.sin(t * Math.PI_2)); }, copy: function() { @@ -252,6 +252,271 @@ var EaseSineInOut = ActionEase.extend(/** @lends cocos.actions.EaseSineInOut# */ } }); +var EaseElastic = ActionEase.extend(/** @lends cocos.actions.EaseElastic# */{ + /** + * period of the wave in radians. default is 0.3 + * @type {Float} + */ + period: 0.3, + + /** + * @class EaseElastic Ease Elastic abstract class + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.ActionEase + * + * @opt {cocos.actions.ActionInterval} action + * @opt {Float} period + */ + init: function(opts) { + EaseElastic.superclass.init.call(this, {action: opts.action}); + + if (opts.period !== undefined) { + this.period = opts.period; + } + }, + + copy: function() { + return EaseElastic.create({action: this.other.copy(), period: this.period}); + }, + + reverse: function() { + window.console.warn("EaseElastic reverse(): Override me"); + return null; + } +}); + +var EaseElasticIn = EaseElastic.extend(/** @lends cocos.actions.EaseElasticIn# */{ + /** + * @class EaseElasticIn Ease Elastic In action + */ + update: function(t) { + var newT = 0; + if (t == 0 || t == 1) { + newT = t; + } else { + var s = this.period / 4; + t -= 1; + newT = -Math.pow(2, 10 * t) * Math.sin((t - s) * Math.PI*2 / this.period); + } + this.other.update(newT); + }, + + // Wish we could use base class's copy + copy: function() { + return EaseElasticIn.create({action: this.other.copy(), period: this.period}); + }, + + reverse: function() { + return exports.EaseElasticOut.create({action: this.other.reverse(), period: this.period}); + } +}); + +var EaseElasticOut = EaseElastic.extend(/** @lends cocos.actions.EaseElasticOut# */{ + /** + * @class EaseElasticOut Ease Elastic Out action + */ + update: function(t) { + var newT = 0; + if (t == 0 || t == 1) { + newT = t; + } else { + var s = this.period / 4; + newT = Math.pow(2, -10 * t) * Math.sin((t - s) * Math.PI*2 / this.period) + 1; + } + this.other.update(newT); + }, + + copy: function() { + return EaseElasticOut.create({action: this.other.copy(), period: this.period}); + }, + + reverse: function() { + return exports.EaseElasticIn.create({action: this.other.reverse(), period: this.period}); + } +}); + +var EaseElasticInOut = EaseElastic.extend(/** @lends cocos.actions.EaseElasticInOut# */{ + /** + * @class EaseElasticInOut Ease Elastic InOut action + */ + update: function(t) { + var newT = 0; + if (t == 0 || t == 1) { + newT = t; + } else { + t *= 2; + if (this.period == 0) { + this.period = 0.3 * 1.5; + } + var s = this.period / 4; + + t -= 1; + if (t < 0) { + newT = -0.5 * Math.pow(2, 10 * t) * Math.sin((t - s) * Math.PI*2 / this.period); + } else { + newT = Math.pow(2, -10 * t) * Math.sin((t - s) * Math.PI*2 / this.period) * 0.5 + 1; + } + } + this.other.update(newT); + }, + + copy: function() { + return EaseElasticInOut.create({action: this.other.copy(), period: this.period}); + }, + + reverse: function() { + return EaseElasticInOut.create({action: this.other.reverse(), period: this.period}); + } +}); + +var EaseBounce = ActionEase.extend(/** @lends cocos.actions.EaseBounce# */{ + /** + * @class EaseBounce abstract class + */ + bounceTime: function(t) { + // Direct cut & paste from CCActionEase.m, obviously. + // Glad someone else figured out all this math... + if (t < 1 / 2.75) { + return 7.5625 * t * t; + } + else if (t < 2 / 2.75) { + t -= 1.5 / 2.75; + return 7.5625 * t * t + 0.75; + } + else if (t < 2.5 / 2.75) { + t -= 2.25 / 2.75; + return 7.5625 * t * t + 0.9375; + } + + t -= 2.625 / 2.75; + return 7.5625 * t * t + 0.984375; + } +}); + +var EaseBounceIn = EaseBounce.extend(/** @lends cocos.actions.EaseBounceIn# */{ + /** + * @class EaseBounceIn EaseBounceIn action + */ + update: function(t) { + var newT = 1 - this.bounceTime(1-t); + this.other.update(newT); + }, + + copy: function() { + return EaseBounceIn.create({action: this.other.copy()}); + }, + + reverse: function() { + return exports.EaseBounceOut.create({action: this.other.reverse()}); + } +}); + +var EaseBounceOut = EaseBounce.extend(/** @lends cocos.actions.EaseBounceOut# */{ + /** + * @class EaseBounceOut EaseBounceOut action + */ + update: function(t) { + var newT = this.bounceTime(t); + this.other.update(newT); + }, + + copy: function() { + return EaseBounceOut.create({action: this.other.copy()}); + }, + + reverse: function() { + return exports.EaseBounceIn.create({action: this.other.reverse()}); + } +}); + +var EaseBounceInOut = EaseBounce.extend(/** @lends cocos.actions.EaseBounceInOut# */{ + /** + * @class EaseBounceInOut EaseBounceInOut action + */ + update: function(t) { + var newT = 0; + if (t < 0.5) { + t *= 2; + newT = (1 - this.bounceTime(1 - t)) * 0.5; + } else { + newT = this.bounceTime(t * 2 - 1) * 0.5 + 0.5; + } + this.other.update(newT); + }, + + copy: function() { + return EaseBounceInOut.create({action: this.other.copy()}); + }, + + reverse: function() { + return EaseBounceInOut.create({action: this.other.reverse()}); + } +}); + +var EaseBackIn = ActionEase.extend(/** @lends cocos.actions.EaseBackIn# */{ + /** + * @class EaseBackIn EaseBackIn action + */ + update: function(t) { + var overshoot = 1.70158; + this.other.update(t * t * ((overshoot + 1) * t - overshoot)); + }, + + copy: function() { + return EaseBackIn.create({action: this.other.copy()}); + }, + + reverse: function() { + return exports.EaseBackOut.create({action: this.other.reverse()}); + } +}); + +var EaseBackOut = ActionEase.extend(/** @lends cocos.actions.EaseBackOut# */{ + /** + * @class EaseBackOut EaseBackOut action + */ + update: function(t) { + var overshoot = 1.70158; + t -= 1; + this.other.update(t * t * ((overshoot + 1) * t + overshoot) + 1); + }, + + copy: function() { + return EaseBackOut.create({action: this.other.copy()}); + }, + + reverse: function() { + return exports.EaseBackIn.create({action: this.other.reverse()}); + } +}); + +var EaseBackInOut = ActionEase.extend(/** @lends cocos.actions.EaseBackInOut# */{ + /** + * @class EaseBackInOut EaseBackInOut action + */ + update: function(t) { + // Where do these constants come from? + var overshoot = 1.70158 * 1.525; + t *= 2; + if (t < 1) { + this.other.update((t * t * ((overshoot + 1) * t - overshoot)) / 2); + } else { + t -= 2; + this.other.update((t * t * ((overshoot + 1) * t + overshoot)) / 2 + 1); + } + }, + + copy: function() { + return EaseBackInOut.create({action: this.other.copy()}); + }, + + reverse: function() { + return EaseBackInOut.create({action: this.other.reverse()}); + } +}); + exports.ActionEase = ActionEase; exports.EaseRate = EaseRate; exports.EaseIn = EaseIn; @@ -263,3 +528,15 @@ exports.EaseExponentialInOut = EaseExponentialInOut; exports.EaseSineIn = EaseSineIn; exports.EaseSineOut = EaseSineOut; exports.EaseSineInOut = EaseSineInOut; +exports.EaseElastic = EaseElastic; +exports.EaseElasticIn = EaseElasticIn; +exports.EaseElasticOut = EaseElasticOut; +exports.EaseElasticInOut = EaseElasticInOut; +exports.EaseBounce = EaseBounce; +exports.EaseBounceIn = EaseBounceIn; +exports.EaseBounceOut = EaseBounceOut; +exports.EaseBounceInOut = EaseBounceInOut; +exports.EaseBackIn = EaseBackIn; +exports.EaseBackOut = EaseBackOut; +exports.EaseBackInOut = EaseBackInOut; + diff --git a/src/libs/cocos2d/actions/ActionInstant.js b/src/libs/cocos2d/actions/ActionInstant.js index 9a7aced..0fb642a 100644 --- a/src/libs/cocos2d/actions/ActionInstant.js +++ b/src/libs/cocos2d/actions/ActionInstant.js @@ -33,7 +33,7 @@ var ActionInstant = act.FiniteTimeAction.extend(/** @lends cocos.actions.ActionI }, copy: function() { - throw "Implement copy()"; + return this; }, reverse: function () { diff --git a/tests/src/cocos2d/EaseActionTest.js b/tests/src/cocos2d/EaseActionTest.js index 6ba2cd5..9978180 100644 --- a/tests/src/cocos2d/EaseActionTest.js +++ b/tests/src/cocos2d/EaseActionTest.js @@ -19,7 +19,13 @@ var transitions = [ "SpriteEaseExponential", "SpriteEaseExponentialInOut", "SpriteEaseSine", - "SpriteEaseSineInOut" + "SpriteEaseSineInOut", + "SpriteEaseElastic", + "SpriteEaseElasticInOut", + "SpriteEaseBounce", + "SpriteEaseBounceInOut", + "SpriteEaseBack", + "SpriteEaseBackInOut" ]; var tests = {}; @@ -326,6 +332,181 @@ tests.SpriteEaseSineInOut = SpriteDemo.extend(/** @lends SpriteEaseSineInOut.pro } }); +tests.SpriteEaseElastic = SpriteDemo.extend(/** @lends SpriteEaseElastic.prototype# */{ + title: 'Elastic In - Out actions', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseElastic.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease_in = actions.EaseElasticIn.create({action: move.copy()}); + var move_ease_in_back = move_ease_in.reverse(); + + var move_ease_out = actions.EaseElasticOut.create({action: move.copy()}); + var move_ease_out_back = move_ease_out.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease_in, delay.copy(), move_ease_in_back, delay.copy()]}); + var seq3 = actions.Sequence.create({actions: [move_ease_out, delay.copy(), move_ease_out_back, delay.copy()]}); + + this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + this.get('kathia').runAction(actions.RepeatForever.create(seq3)); + } +}); + +tests.SpriteEaseElasticInOut = SpriteDemo.extend(/** @lends SpriteEaseElasticInOut.prototype# */{ + title: 'EaseElasticInOut action', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseElasticInOut.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + + var move_ease_inout1 = actions.EaseElasticInOut.create({action: move.copy(), period: 0.3}); + var move_ease_inout_back1 = move_ease_inout1.reverse(); + + var move_ease_inout2 = actions.EaseElasticInOut.create({action: move.copy(), period: 0.45}); + var move_ease_inout_back2 = move_ease_inout2.reverse(); + + var move_ease_inout3 = actions.EaseElasticInOut.create({action: move.copy(), period: 0.6}); + var move_ease_inout_back3 = move_ease_inout3.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move_ease_inout1, delay, move_ease_inout_back1, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease_inout2, delay.copy(), move_ease_inout_back2, delay.copy()]}); + var seq3 = actions.Sequence.create({actions: [move_ease_inout3, delay.copy(), move_ease_inout_back3, delay.copy()]}); + + this.get('tamara').runAction(actions.RepeatForever.create(seq1)); + this.get('kathia').runAction(actions.RepeatForever.create(seq2)); + this.get('grossini').runAction(actions.RepeatForever.create(seq3)); + } +}); + +tests.SpriteEaseBounce = SpriteDemo.extend(/** @lends SpriteEaseBounce.prototype# */{ + title: 'Bounce In - Out actions', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseBounce.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease_in = actions.EaseBounceIn.create({action: move.copy()}); + var move_ease_in_back = move_ease_in.reverse(); + + var move_ease_out = actions.EaseBounceOut.create({action: move.copy()}); + var move_ease_out_back = move_ease_out.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease_in, delay.copy(), move_ease_in_back, delay.copy()]}); + var seq3 = actions.Sequence.create({actions: [move_ease_out, delay.copy(), move_ease_out_back, delay.copy()]}); + + this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + this.get('kathia').runAction(actions.RepeatForever.create(seq3)); + } +}); + +tests.SpriteEaseBounceInOut = SpriteDemo.extend(/** @lends SpriteEaseBounceInOut.prototype# */{ + title: 'EaseBounceInOut action', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseBounceInOut.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease = actions.EaseBounceInOut.create({action: move.copy()}); + var move_ease_back = move_ease.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease, delay.copy(), move_ease_back, delay.copy()]}); + + this.positionForTwo(); + + this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + } +}); + +tests.SpriteEaseBack = SpriteDemo.extend(/** @lends SpriteEaseBack.prototype# */{ + title: 'Back In - Out actions', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseBack.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease_in = actions.EaseBackIn.create({action: move.copy()}); + var move_ease_in_back = move_ease_in.reverse(); + + var move_ease_out = actions.EaseBackOut.create({action: move.copy()}); + var move_ease_out_back = move_ease_out.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease_in, delay.copy(), move_ease_in_back, delay.copy()]}); + var seq3 = actions.Sequence.create({actions: [move_ease_out, delay.copy(), move_ease_out_back, delay.copy()]}); + + this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + this.get('kathia').runAction(actions.RepeatForever.create(seq3)); + } +}); + +tests.SpriteEaseBackInOut = SpriteDemo.extend(/** @lends SpriteEaseBackInOut.prototype# */{ + title: 'EaseBackInOut action', + subtitle: '', + + onEnter: function() { + tests.SpriteEaseBackInOut.superclass.onEnter.call(this); + + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var move = actions.MoveBy.create({duration: 3, position: ccp(s.width-130, 0)}); + var move_back = move.reverse(); + + var move_ease = actions.EaseBackInOut.create({action: move.copy()}); + var move_ease_back = move_ease.reverse(); + + var delay = actions.DelayTime.create({duration: 0.25}); + + var seq1 = actions.Sequence.create({actions: [move, delay, move_back, delay.copy()]}); + var seq2 = actions.Sequence.create({actions: [move_ease, delay.copy(), move_ease_back, delay.copy()]}); + + this.positionForTwo(); + + this.get('grossini').runAction(actions.RepeatForever.create(seq1)); + this.get('tamara').runAction(actions.RepeatForever.create(seq2)); + } +}); exports.main = function () { // Initialise test From cc6a45b55ee529c62771f4272c670a3fa4233495 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Wed, 1 Jun 2011 20:58:36 -0700 Subject: [PATCH 172/176] removed unused require from Node.js --- src/libs/cocos2d/nodes/Node.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/cocos2d/nodes/Node.js b/src/libs/cocos2d/nodes/Node.js index ad37b32..d2c763a 100644 --- a/src/libs/cocos2d/nodes/Node.js +++ b/src/libs/cocos2d/nodes/Node.js @@ -6,7 +6,6 @@ var util = require('util'), evt = require('events'), Scheduler = require('../Scheduler').Scheduler, ActionManager = require('../ActionManager').ActionManager, - Dispatcher = require('../EventDispatcher').EventDispatcher, geo = require('geometry'), ccp = geo.ccp; var Node = BObject.extend(/** @lends cocos.nodes.Node# */{ From 66fbd68165c4370743f3b6d8d48bcc07a56ce51d Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Wed, 1 Jun 2011 21:16:51 -0700 Subject: [PATCH 173/176] whitespaces fixed --- src/libs/cocos2d/Director.js | 212 +++++++++++++++++------------------ 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/src/libs/cocos2d/Director.js b/src/libs/cocos2d/Director.js index 436228d..b8a716f 100644 --- a/src/libs/cocos2d/Director.js +++ b/src/libs/cocos2d/Director.js @@ -70,150 +70,150 @@ var Director = BObject.extend(/** @lends cocos.Director# */{ * @param {HTMLElement} view Any HTML element to add the application to */ - attachInView: function (view) { - if (!view.tagName) { - throw "Director.attachInView must be given a HTML DOM Node"; - } + attachInView: function (view) { + if (!view.tagName) { + throw "Director.attachInView must be given a HTML DOM Node"; + } - while (view.firstChild) { - view.removeChild(view.firstChild); - } + while (view.firstChild) { + view.removeChild(view.firstChild); + } - var canvas = document.createElement('canvas'); - this.set('canvas', canvas); - canvas.setAttribute('width', view.clientWidth); - canvas.setAttribute('height', view.clientHeight); + var canvas = document.createElement('canvas'); + this.set('canvas', canvas); + canvas.setAttribute('width', view.clientWidth); + canvas.setAttribute('height', view.clientHeight); - var context = canvas.getContext('2d'); - this.set('context', context); + var context = canvas.getContext('2d'); + this.set('context', context); - if (FLIP_Y_AXIS) { - context.translate(0, view.clientHeight); - context.scale(1, -1); - } + if (FLIP_Y_AXIS) { + context.translate(0, view.clientHeight); + context.scale(1, -1); + } + + view.appendChild(canvas); - view.appendChild(canvas); + this.set('winSize', {width: view.clientWidth, height: view.clientHeight}); - this.set('winSize', {width: view.clientWidth, height: view.clientHeight}); + // Setup event handling - // Setup event handling + // Mouse events + var eventDispatcher = EventDispatcher.get('sharedDispatcher'); + var self = this; + function mouseDown(evt) { + evt.locationInWindow = ccp(evt.clientX, evt.clientY); + evt.locationInCanvas = self.convertEventToCanvas(evt); - // Mouse events - var eventDispatcher = EventDispatcher.get('sharedDispatcher'); - var self = this; - function mouseDown(evt) { + function mouseDragged(evt) { evt.locationInWindow = ccp(evt.clientX, evt.clientY); evt.locationInCanvas = self.convertEventToCanvas(evt); - function mouseDragged(evt) { - evt.locationInWindow = ccp(evt.clientX, evt.clientY); - evt.locationInCanvas = self.convertEventToCanvas(evt); + eventDispatcher.mouseDragged(evt); + } + function mouseUp(evt) { + evt.locationInWindow = ccp(evt.clientX, evt.clientY); + evt.locationInCanvas = self.convertEventToCanvas(evt); - eventDispatcher.mouseDragged(evt); - } - function mouseUp(evt) { - evt.locationInWindow = ccp(evt.clientX, evt.clientY); - evt.locationInCanvas = self.convertEventToCanvas(evt); + document.body.removeEventListener('mousemove', mouseDragged, false); + document.body.removeEventListener('mouseup', mouseUp, false); - document.body.removeEventListener('mousemove', mouseDragged, false); - document.body.removeEventListener('mouseup', mouseUp, false); + eventDispatcher.mouseUp(evt); + } - eventDispatcher.mouseUp(evt); - } + document.body.addEventListener('mousemove', mouseDragged, false); + document.body.addEventListener('mouseup', mouseUp, false); - document.body.addEventListener('mousemove', mouseDragged, false); - document.body.addEventListener('mouseup', mouseUp, false); + eventDispatcher.mouseDown(evt); + } + function mouseMoved(evt) { + evt.locationInWindow = ccp(evt.clientX, evt.clientY); + evt.locationInCanvas = self.convertEventToCanvas(evt); - eventDispatcher.mouseDown(evt); - } - function mouseMoved(evt) { - evt.locationInWindow = ccp(evt.clientX, evt.clientY); - evt.locationInCanvas = self.convertEventToCanvas(evt); + eventDispatcher.mouseMoved(evt); + } - eventDispatcher.mouseMoved(evt); - } + canvas.addEventListener('mousedown', mouseDown, false); + canvas.addEventListener('mousemove', mouseMoved, false); - canvas.addEventListener('mousedown', mouseDown, false); - canvas.addEventListener('mousemove', mouseMoved, false); + // Add handlers for touch events. - // Add handlers for touch events. + // for touchcancel event - can be fired anytime so must be defined outside + // touchStart() + function touchEnd(evt) { + if (!evt) evt = event; + evt.preventDefault(); - // for touchcancel event - can be fired anytime so must be defined outside - // touchStart() - function touchEnd(evt) { - if (!evt) evt = event; - evt.preventDefault(); + // evt.changedTouches should have the last touch point + if (evt.changedTouches.length == 1) { + evt.locationInWindow = ccp(evt.changedTouches[0].pageX, evt.changedTouches[0].pageY); + evt.locationInCanvas = self.convertEventToCanvas(evt); + } + eventDispatcher.mouseUp(evt); + } - // evt.changedTouches should have the last touch point - if (evt.changedTouches.length == 1) { - evt.locationInWindow = ccp(evt.changedTouches[0].pageX, evt.changedTouches[0].pageY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - } - eventDispatcher.mouseUp(evt); + function touchStart(evt) { + if (!evt) evt = event; + + if (evt.touches.length == 1) { + evt.locationInWindow = ccp(evt.touches[0].pageX, evt.touches[0].pageY); + evt.locationInCanvas = self.convertEventToCanvas(evt); + } else { + // TODO: multitouch support?? } - function touchStart(evt) { + function touchMoved(evt) { if (!evt) evt = event; + evt.preventDefault(); if (evt.touches.length == 1) { evt.locationInWindow = ccp(evt.touches[0].pageX, evt.touches[0].pageY); evt.locationInCanvas = self.convertEventToCanvas(evt); + + eventDispatcher.mouseDragged(evt); } else { // TODO: multitouch support?? } + } - function touchMoved(evt) { - if (!evt) evt = event; - evt.preventDefault(); - - if (evt.touches.length == 1) { - evt.locationInWindow = ccp(evt.touches[0].pageX, evt.touches[0].pageY); - evt.locationInCanvas = self.convertEventToCanvas(evt); - - eventDispatcher.mouseDragged(evt); - } else { - // TODO: multitouch support?? - } - } - - function touchUp(evt) { - if (!evt) evt = event; - evt.preventDefault(); + function touchUp(evt) { + if (!evt) evt = event; + evt.preventDefault(); - // evt.changedTouches should have the last touch point - if (evt.changedTouches.length == 1) { - evt.locationInWindow = ccp(evt.changedTouches[0].pageX, evt.changedTouches[0].pageY); - evt.locationInCanvas = self.convertEventToCanvas(evt); + // evt.changedTouches should have the last touch point + if (evt.changedTouches.length == 1) { + evt.locationInWindow = ccp(evt.changedTouches[0].pageX, evt.changedTouches[0].pageY); + evt.locationInCanvas = self.convertEventToCanvas(evt); - canvas.removeEventListener('touchmove', touchMoved, false); - canvas.removeEventListener('touchend', touchUp, false); + canvas.removeEventListener('touchmove', touchMoved, false); + canvas.removeEventListener('touchend', touchUp, false); - eventDispatcher.mouseUp(evt); - } + eventDispatcher.mouseUp(evt); } - - canvas.addEventListener('touchmove', touchMoved, false); - canvas.addEventListener('touchend', touchUp, false); - - eventDispatcher.mouseDown(evt); } - canvas.addEventListener('touchstart', touchStart, false); - // touchcancel must be bound to the body - document.body.addEventListener('touchcancel', touchEnd, false); - - // Keyboard events - function keyDown(evt) { - this._keysDown = this._keysDown || {}; - eventDispatcher.keyDown(evt); - } - function keyUp(evt) { - eventDispatcher.keyUp(evt); - } - - document.documentElement.addEventListener('keydown', keyDown, false); - document.documentElement.addEventListener('keyup', keyUp, false); - }, + canvas.addEventListener('touchmove', touchMoved, false); + canvas.addEventListener('touchend', touchUp, false); + + eventDispatcher.mouseDown(evt); + } + + canvas.addEventListener('touchstart', touchStart, false); + // touchcancel must be bound to the body + document.body.addEventListener('touchcancel', touchEnd, false); + + // Keyboard events + function keyDown(evt) { + this._keysDown = this._keysDown || {}; + eventDispatcher.keyDown(evt); + } + function keyUp(evt) { + eventDispatcher.keyUp(evt); + } + + document.documentElement.addEventListener('keydown', keyDown, false); + document.documentElement.addEventListener('keyup', keyUp, false); + }, runPreloadScene: function () { var preloader = this.get('preloadScene'); From f9a5889fbc17b2e8fcffd0858981697cf7053924 Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Wed, 1 Jun 2011 22:23:40 -0700 Subject: [PATCH 174/176] Fixed bad overrite of ryanw's src/global.js get() function --- src/global.js | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/global.js b/src/global.js index 419bc61..049ef0e 100644 --- a/src/global.js +++ b/src/global.js @@ -71,20 +71,35 @@ BObject.prototype = util.extend(BObject.prototype, /** @lends BObject# */{ * access the property directly. This will ensure all bindings, setters and * getters work correctly. * - * @param {String} key Name of property to get + * @param {String} key Name of property to get or dot (.) separated path to a property * @returns {*} Value of the property */ get: function (key) { - var accessor = getAccessors(this)[key]; + var next = false + if (~key.indexOf('.')) { + var tokens = key.split('.'); + key = tokens.shift(); + next = tokens.join('.'); + } + + + var accessor = getAccessors(this)[key], + val; if (accessor) { - return accessor.target.get(accessor.key); + val = accessor.target.get(accessor.key); } else { // Call getting function if (this['get_' + key]) { - return this['get_' + key](); + val = this['get_' + key](); + } else { + val = this[key]; } + } - return this[key]; + if (next) { + return val.get(next); + } else { + return val; } }, From ec77f7492f532d33bc748af7cdd3a80fe09db79d Mon Sep 17 00:00:00 2001 From: "Marc A. Mauger" Date: Sat, 4 Jun 2011 15:42:32 -0700 Subject: [PATCH 175/176] Follow action added --- src/libs/cocos2d/actions/Action.js | 107 ++++++++++++++++++++++++++++- tests/src/cocos2d/ActionTest.js | 45 +++++++++++- 2 files changed, 150 insertions(+), 2 deletions(-) diff --git a/src/libs/cocos2d/actions/Action.js b/src/libs/cocos2d/actions/Action.js index 3da2b80..47d82cd 100644 --- a/src/libs/cocos2d/actions/Action.js +++ b/src/libs/cocos2d/actions/Action.js @@ -3,7 +3,9 @@ "use strict"; var util = require('util'), - console = require('system').console; + console = require('system').console, + geo = require('geometry'), + ccp = geo.ccp; /** * @memberOf cocos.actions @@ -207,7 +209,110 @@ var Speed = Action.extend(/** @lends cocos.actions.Speed# */{ } }); +var Follow = Action.extend(/** @lends cocos.actions.Follow# */{ + /** + * node to follow + */ + followedNode: null, + + /** + * whether camera should be limited to certain area + * @type {Boolean} + */ + boundarySet: false, + + /** + * if screensize is bigger than the boundary - update not needed + * @type {Boolean} + */ + boundaryFullyCovered: false, + + /** + * fast access to the screen dimensions + * @type {geometry.Point} + */ + halfScreenSize: null, + fullScreenSize: null, + + /** + * world boundaries + * @type {Float} + */ + leftBoundary: 0, + rightBoundary: 0, + topBoundary: 0, + bottomBoundary: 0, + + /** + * @class Follow an action that "follows" a node. + * + * Eg: + * layer.runAction(cocos.actions.Follow.create({target: hero})) + * + * @memberOf cocos.actions + * @constructs + * @extends cocos.actions.Action + * + * @opt {cocos.nodes.Node} target + * @opt {geometry.Rect} worldBoundary + */ + init: function(opts) { + Follow.superclass.init.call(this, opts); + + this.followedNode = opts.target; + + var s = require('../Director').Director.get('sharedDirector').get('winSize'); + this.fullScreenSize = geo.ccp(s.width, s.height); + this.halfScreenSize = geo.ccpMult(this.fullScreenSize, geo.ccp(0.5, 0.5)); + + if (opts.worldBoundary !== undefined) { + this.boundarySet = true; + this.leftBoundary = -((opts.worldBoundary.origin.x + opts.worldBoundary.size.width) - this.fullScreenSize.x); + this.rightBoundary = -opts.worldBoundary.origin.x; + this.topBoundary = -opts.worldBoundary.origin.y; + this.bottomBoundary = -((opts.worldBoundary.origin.y+opts.worldBoundary.size.height) - this.fullScreenSize.y); + + if (this.rightBoundary < this.leftBoundary) { + // screen width is larger than world's boundary width + //set both in the middle of the world + this.rightBoundary = this.leftBoundary = (this.leftBoundary + this.rightBoundary) / 2; + } + if (this.topBoundary < this.bottomBoundary) + { + // screen width is larger than world's boundary width + //set both in the middle of the world + this.topBoundary = this.bottomBoundary = (this.topBoundary + this.bottomBoundary) / 2; + } + if ((this.topBoundary == this.bottomBoundary) && (this.leftBoundary == this.rightBoundary)) { + this.boundaryFullyCovered = true; + } + } + }, + + step: function(dt) { + if (this.boundarySet) { + // whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased + if (this.boundaryFullyCovered) { + return; + } + var tempPos = geo.ccpSub(this.halfScreenSize, this.followedNode.get('position')); + this.target.set('position', ccp( + Math.min(Math.max(tempPos.x, this.leftBoundary), this.rightBoundary), + Math.min(Math.max(tempPos.y, this.bottomBoundary), this.topBoundary)) + ); + } else { + this.target.set('position', geo.ccpSub(this.halfScreenSize, this.followedNode.get('position'))); + } + }, + + get_isDone: function() { + return !this.followedNode.get('isRunning'); + } +}); + + exports.Action = Action; exports.RepeatForever = RepeatForever; exports.FiniteTimeAction = FiniteTimeAction; exports.Speed = Speed; +exports.Follow = Follow; diff --git a/tests/src/cocos2d/ActionTest.js b/tests/src/cocos2d/ActionTest.js index 8332c80..20f05e3 100644 --- a/tests/src/cocos2d/ActionTest.js +++ b/tests/src/cocos2d/ActionTest.js @@ -30,7 +30,8 @@ var transitions = [ "RotateJerk", "ReverseSequence", "ReverseSequence2", - "Speed" + "Speed", + "Follow" ]; var tests = {}; @@ -676,6 +677,48 @@ tests.Speed = ActionDemo.extend(/** @lends Speed.prototype# */{ } }); +tests.Follow = ActionDemo.extend(/** @lends Follow.prototype# */{ + title: 'Follow action', + subtitle: 'The sprite should be centered, even though it is being moved', + + onEnter: function() { + tests.Follow.superclass.onEnter.call(this); + + this.centerSprites(1); + var s = cocos.Director.get('sharedDirector').get('winSize'); + + this.get('grossini').set('position', ccp(-200, s.height/2)); + + var move = actions.MoveBy.create({duration: 2, position: ccp(s.width*3, 0)}); + var move_back = move.reverse(); + var seq = actions.Sequence.create({actions: [move, move_back]}); + var rep = actions.RepeatForever.create(seq); + + this.get('grossini').runAction(rep); + + this.runAction(actions.Follow.create({target: this.get('grossini'), + worldBoundary: new geo.Rect(0, 0, s.width*2-100, s.height)})); + + }, + + draw: function(ctxt) { + var s = cocos.Director.get('sharedDirector').get('winSize'); + + var x = s.width*2 - 100, + y = s.height; + + var vertices = [ccp(x-5, 5), ccp(x-5, y-5), ccp(5, y-5)]; + ctxt.beginPath(); + ctxt.moveTo(5, 5); + for (var i=0; i Date: Sat, 18 Jun 2011 10:03:28 +1200 Subject: [PATCH 176/176] Fixed 'cocos' command in Node v0.4.8 --- lib/cocos2d/commands/make.js | 39 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/cocos2d/commands/make.js b/lib/cocos2d/commands/make.js index 15d8168..3e5f63b 100644 --- a/lib/cocos2d/commands/make.js +++ b/lib/cocos2d/commands/make.js @@ -491,6 +491,26 @@ exports.run = function () { var code = compiler.make(); + function cp(src, dst, callback) { + mkdir(path.dirname(dst)); + + var reader = fs.createReadStream(src), + writer = fs.createWriteStream(dst); + + writer.addListener('close', function () { callback(); }); + + sys.pump(reader, writer); + } + + var files = []; + function next() { + if (!files.length) { + return; + } + var names = files.shift(); + cp(names[0], names[1], next); + } + if (output) { var scriptOutput = path.join(outputDir, output.script || output); var resourceOutput = path.join(outputDir, output.resources) || path.join(path.dirname(scriptOutput), 'resources'); @@ -507,7 +527,6 @@ exports.run = function () { sys.puts("Copying resources to: " + resourceOutput); mkdir(resourceOutput); - var files = []; for (var source in compiler.remoteResources) { if (compiler.remoteResources.hasOwnProperty(source)) { var dest = path.join(resourceOutput, compiler.remoteResources[source]); @@ -515,24 +534,6 @@ exports.run = function () { } } - function cp(src, dst, callback) { - mkdir(path.dirname(dst)); - - var reader = fs.createReadStream(src), - writer = fs.createWriteStream(dst); - - writer.addListener('close', function () { callback(); }); - - sys.pump(reader, writer); - } - - function next() { - if (!files.length) { - return; - } - var names = files.shift(); - cp(names[0], names[1], next); - } next(); } else {