mirror of
https://github.com/wassname/phaser.git
synced 2026-06-30 16:40:20 +08:00
Space and Joints interface added.
This commit is contained in:
@@ -57,7 +57,6 @@
|
||||
<TypeScriptGeneratesDeclarations>true</TypeScriptGeneratesDeclarations>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="physics\advanced\joints\" />
|
||||
<Folder Include="physics\arcade\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -200,6 +199,10 @@
|
||||
<DependentUpon>Joint.ts</DependentUpon>
|
||||
</Content>
|
||||
<TypeScriptCompile Include="physics\advanced\Manager.ts" />
|
||||
<TypeScriptCompile Include="physics\advanced\joints\IJoint.ts" />
|
||||
<Content Include="physics\advanced\joints\IJoint.js">
|
||||
<DependentUpon>IJoint.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="physics\advanced\Manager.js">
|
||||
<DependentUpon>Manager.ts</DependentUpon>
|
||||
</Content>
|
||||
@@ -227,6 +230,10 @@
|
||||
<Content Include="physics\advanced\ShapeTriangle.js">
|
||||
<DependentUpon>ShapeTriangle.ts</DependentUpon>
|
||||
</Content>
|
||||
<TypeScriptCompile Include="physics\advanced\Space.ts" />
|
||||
<Content Include="physics\advanced\Space.js">
|
||||
<DependentUpon>Space.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="physics\ArcadePhysics.js">
|
||||
<DependentUpon>ArcadePhysics.ts</DependentUpon>
|
||||
</Content>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
/// <reference path="Manager.ts" />
|
||||
/// <reference path="Joint.ts" />
|
||||
/// <reference path="Bounds.ts" />
|
||||
/// <reference path="Space.ts" />
|
||||
|
||||
/**
|
||||
* Phaser - Advanced Physics - Body
|
||||
@@ -133,6 +134,7 @@ module Phaser.Physics.Advanced {
|
||||
public categoryBits = 0x0001;
|
||||
public maskBits = 0xFFFF;
|
||||
public stepCount = 0;
|
||||
public space: Space;
|
||||
|
||||
// duplicate = Util function
|
||||
// serialize = Util function
|
||||
|
||||
@@ -17,6 +17,8 @@ module Phaser.Physics.Advanced {
|
||||
|
||||
this.game = game;
|
||||
|
||||
Manager.collision = new Collision();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,6 +26,8 @@ module Phaser.Physics.Advanced {
|
||||
*/
|
||||
public game: Game;
|
||||
|
||||
public static collision: Collision;
|
||||
|
||||
public static SHAPE_TYPE_CIRCLE: number = 0;
|
||||
public static SHAPE_TYPE_SEGMENT: number = 1;
|
||||
public static SHAPE_TYPE_POLY: number = 2;
|
||||
|
||||
@@ -0,0 +1,831 @@
|
||||
/// <reference path="../../math/Vec2.ts" />
|
||||
/// <reference path="../../geom/Point.ts" />
|
||||
/// <reference path="../../math/Vec2Utils.ts" />
|
||||
/// <reference path="Manager.ts" />
|
||||
/// <reference path="Body.ts" />
|
||||
/// <reference path="Shape.ts" />
|
||||
/// <reference path="ContactSolver.ts" />
|
||||
/// <reference path="Contact.ts" />
|
||||
/// <reference path="Collision.ts" />
|
||||
/// <reference path="joints/IJoint.ts" />
|
||||
|
||||
/**
|
||||
* Phaser - Advanced Physics - Space
|
||||
*
|
||||
* Based on the work Ju Hyung Lee started in JS PhyRus.
|
||||
*/
|
||||
|
||||
module Phaser.Physics.Advanced {
|
||||
|
||||
export class Space {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.bodyArr = [];
|
||||
this.bodyHash = {};
|
||||
|
||||
this.jointArr = [];
|
||||
this.jointHash = {};
|
||||
|
||||
this.numContacts = 0;
|
||||
this.contactSolvers = [];
|
||||
|
||||
//this.postSolve(arb) { };
|
||||
|
||||
this.gravity = new Phaser.Vec2;
|
||||
this.damping = 0;
|
||||
|
||||
}
|
||||
|
||||
public static TIME_TO_SLEEP = 0.5;
|
||||
public static SLEEP_LINEAR_TOLERANCE = 0.5;
|
||||
public static SLEEP_ANGULAR_TOLERANCE = 2 * Phaser.GameMath.DEG_TO_RAD;
|
||||
|
||||
public bodyArr: Body[];
|
||||
public bodyHash;
|
||||
public jointArr: IJoint[];
|
||||
public jointHash;
|
||||
public numContacts: number;
|
||||
public contactSolvers: ContactSolver[];
|
||||
public postSolve;
|
||||
public gravity: Phaser.Vec2;
|
||||
public damping: number;
|
||||
public stepCount: number = 0;
|
||||
|
||||
public clear() {
|
||||
|
||||
Manager.shapeCounter = 0;
|
||||
Manager.bodyCounter = 0;
|
||||
Manager.jointCounter = 0;
|
||||
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
if (this.bodyArr[i])
|
||||
{
|
||||
this.removeBody(this.bodyArr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
this.bodyArr = [];
|
||||
this.bodyHash = {};
|
||||
|
||||
this.jointArr = [];
|
||||
this.jointHash = {};
|
||||
|
||||
this.contactSolvers = [];
|
||||
|
||||
this.stepCount = 0;
|
||||
|
||||
}
|
||||
|
||||
public addBody(body: Body) {
|
||||
|
||||
if (this.bodyHash[body.id] != undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var index = this.bodyArr.push(body) - 1;
|
||||
this.bodyHash[body.id] = index;
|
||||
|
||||
body.awake(true);
|
||||
body.space = this;
|
||||
body.cacheData();
|
||||
|
||||
}
|
||||
|
||||
public removeBody(body: Body) {
|
||||
|
||||
if (this.bodyHash[body.id] == undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove linked joint
|
||||
for (var i = 0; i < body.joints.length; i++)
|
||||
{
|
||||
if (body.joints[i])
|
||||
{
|
||||
this.removeJoint(body.joints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
body.space = null;
|
||||
|
||||
var index = this.bodyHash[body.id];
|
||||
delete this.bodyHash[body.id];
|
||||
delete this.bodyArr[index];
|
||||
|
||||
}
|
||||
|
||||
public addJoint(joint: IJoint) {
|
||||
|
||||
if (this.jointHash[joint.id] != undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
joint.body1.awake(true);
|
||||
joint.body2.awake(true);
|
||||
|
||||
var index = this.jointArr.push(joint) - 1;
|
||||
this.jointHash[joint.id] = index;
|
||||
|
||||
var index = joint.body1.joints.push(joint) - 1;
|
||||
joint.body1.jointHash[joint.id] = index;
|
||||
|
||||
var index = joint.body2.joints.push(joint) - 1;
|
||||
joint.body2.jointHash[joint.id] = index;
|
||||
|
||||
}
|
||||
|
||||
public removeJoint(joint: IJoint) {
|
||||
|
||||
if (this.jointHash[joint.id] == undefined)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
joint.body1.awake(true);
|
||||
joint.body2.awake(true);
|
||||
|
||||
var index = joint.body1.jointHash[joint.id];
|
||||
delete joint.body1.jointHash[joint.id];
|
||||
delete joint.body1.joints[index];
|
||||
|
||||
var index = joint.body2.jointHash[joint.id];
|
||||
delete joint.body2.jointHash[joint.id];
|
||||
delete joint.body2.joints[index];
|
||||
|
||||
var index = this.jointHash[joint.id];
|
||||
delete this.jointHash[joint.id];
|
||||
delete this.jointArr[index];
|
||||
|
||||
}
|
||||
|
||||
public findShapeByPoint(p, refShape) {
|
||||
|
||||
var firstShape;
|
||||
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var j = 0; j < body.shapes.length; j++)
|
||||
{
|
||||
var shape = body.shapes[j];
|
||||
|
||||
if (shape.pointQuery(p))
|
||||
{
|
||||
if (!refShape)
|
||||
{
|
||||
return shape;
|
||||
}
|
||||
|
||||
if (!firstShape)
|
||||
{
|
||||
firstShape = shape;
|
||||
}
|
||||
|
||||
if (shape == refShape)
|
||||
{
|
||||
refShape = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return firstShape;
|
||||
}
|
||||
|
||||
public findBodyByPoint(p, refBody: Body) {
|
||||
|
||||
var firstBody;
|
||||
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var j = 0; j < body.shapes.length; j++)
|
||||
{
|
||||
var shape = body.shapes[j];
|
||||
|
||||
if (shape.pointQuery(p))
|
||||
{
|
||||
if (!refBody)
|
||||
{
|
||||
return shape.body;
|
||||
}
|
||||
|
||||
if (!firstBody)
|
||||
{
|
||||
firstBody = shape.body;
|
||||
}
|
||||
|
||||
if (shape.body == refBody)
|
||||
{
|
||||
refBody = null;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return firstBody;
|
||||
|
||||
}
|
||||
|
||||
// TODO: Replace this function to shape hashing
|
||||
public shapeById(id) {
|
||||
|
||||
var shape;
|
||||
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var j = 0; j < body.shapes.length; j++)
|
||||
{
|
||||
if (body.shapes[j].id == id)
|
||||
{
|
||||
return body.shapes[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public jointById(id) {
|
||||
|
||||
var index = this.jointHash[id];
|
||||
|
||||
if (index != undefined)
|
||||
{
|
||||
return this.jointArr[index];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public findVertexByPoint(p, minDist, refVertexId) {
|
||||
|
||||
var firstVertexId = -1;
|
||||
|
||||
refVertexId = refVertexId || -1;
|
||||
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var j = 0; j < body.shapes.length; j++)
|
||||
{
|
||||
var shape = body.shapes[j];
|
||||
var index = shape.findVertexByPoint(p, minDist);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
var vertex = (shape.id << 16) | index;
|
||||
|
||||
if (refVertexId == -1)
|
||||
{
|
||||
return vertex;
|
||||
}
|
||||
|
||||
if (firstVertexId == -1)
|
||||
{
|
||||
firstVertexId = vertex;
|
||||
}
|
||||
|
||||
if (vertex == refVertexId)
|
||||
{
|
||||
refVertexId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return firstVertexId;
|
||||
|
||||
}
|
||||
|
||||
public findEdgeByPoint(p, minDist, refEdgeId) {
|
||||
|
||||
var firstEdgeId = -1;
|
||||
|
||||
refEdgeId = refEdgeId || -1;
|
||||
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var j = 0; j < body.shapes.length; j++)
|
||||
{
|
||||
var shape = body.shapes[j];
|
||||
|
||||
if (shape.type != Manager.SHAPE_TYPE_POLY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var index = shape.findEdgeByPoint(p, minDist);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
var edge = (shape.id << 16) | index;
|
||||
|
||||
if (refEdgeId == -1)
|
||||
{
|
||||
return edge;
|
||||
}
|
||||
|
||||
if (firstEdgeId == -1)
|
||||
{
|
||||
firstEdgeId = edge;
|
||||
}
|
||||
|
||||
if (edge == refEdgeId)
|
||||
{
|
||||
refEdgeId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return firstEdgeId;
|
||||
}
|
||||
|
||||
public findJointByPoint(p, minDist, refJointId) {
|
||||
|
||||
var firstJointId = -1;
|
||||
|
||||
var dsq = minDist * minDist;
|
||||
|
||||
refJointId = refJointId || -1;
|
||||
|
||||
for (var i = 0; i < this.jointArr.length; i++)
|
||||
{
|
||||
var joint = this.jointArr[i];
|
||||
|
||||
if (!joint)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var jointId = -1;
|
||||
|
||||
if (Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor1()) < dsq)
|
||||
{
|
||||
jointId = (joint.id << 16 | 0);
|
||||
}
|
||||
else if (Phaser.Vec2Utils.distanceSq(p, joint.getWorldAnchor2()) < dsq)
|
||||
{
|
||||
jointId = (joint.id << 16 | 1);
|
||||
}
|
||||
|
||||
if (jointId != -1)
|
||||
{
|
||||
if (refJointId == -1)
|
||||
{
|
||||
return jointId;
|
||||
}
|
||||
|
||||
if (firstJointId == -1)
|
||||
{
|
||||
firstJointId = jointId;
|
||||
}
|
||||
|
||||
if (jointId == refJointId)
|
||||
{
|
||||
refJointId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return firstJointId;
|
||||
}
|
||||
|
||||
public findContactSolver(shape1, shape2) {
|
||||
|
||||
for (var i = 0; i < this.contactSolvers.length; i++)
|
||||
{
|
||||
var contactSolver = this.contactSolvers[i];
|
||||
|
||||
if (shape1 == contactSolver.shape1 && shape2 == contactSolver.shape2)
|
||||
{
|
||||
return contactSolver;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public genTemporalContactSolvers() {
|
||||
|
||||
//var t0 = Date.now();
|
||||
|
||||
var newContactSolverArr = [];
|
||||
|
||||
this.numContacts = 0;
|
||||
|
||||
for (var body1_index = 0; body1_index < this.bodyArr.length; body1_index++)
|
||||
{
|
||||
var body1 = this.bodyArr[body1_index];
|
||||
|
||||
if (!body1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
body1.stepCount = this.stepCount;
|
||||
|
||||
for (var body2_index = 0; body2_index < this.bodyArr.length; body2_index++)
|
||||
{
|
||||
var body2 = this.bodyArr[body2_index];
|
||||
if (!body2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (body1.stepCount == body2.stepCount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var active1 = body1.isAwake && !body1.isStatic;
|
||||
var active2 = body2.isAwake && !body2.isStatic;
|
||||
|
||||
if (!active1 && !active2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!body1.isCollidable(body2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!body1.bounds.intersectsBounds(body2.bounds))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var i = 0; i < body1.shapes.length; i++)
|
||||
{
|
||||
for (var j = 0; j < body2.shapes.length; j++)
|
||||
{
|
||||
var shape1 = body1.shapes[i];
|
||||
var shape2 = body2.shapes[j];
|
||||
|
||||
var contactArr = [];
|
||||
|
||||
if (!Manager.collision.collide(shape1, shape2, contactArr))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shape1.type > shape2.type)
|
||||
{
|
||||
var temp = shape1;
|
||||
shape1 = shape2;
|
||||
shape2 = temp;
|
||||
}
|
||||
|
||||
this.numContacts += contactArr.length;
|
||||
|
||||
var contactSolver = this.findContactSolver(shape1, shape2);
|
||||
|
||||
if (contactSolver)
|
||||
{
|
||||
contactSolver.update(contactArr);
|
||||
newContactSolverArr.push(contactSolver);
|
||||
}
|
||||
else
|
||||
{
|
||||
body1.awake(true);
|
||||
body2.awake(true);
|
||||
|
||||
var newContactSolver = new ContactSolver(shape1, shape2);
|
||||
newContactSolver.contacts = contactArr;
|
||||
newContactSolver.elasticity = Math.max(shape1.e, shape2.e);
|
||||
newContactSolver.friction = Math.sqrt(shape1.u * shape2.u);
|
||||
newContactSolverArr.push(newContactSolver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//stats.timeCollision = Date.now() - t0;
|
||||
|
||||
return newContactSolverArr;
|
||||
}
|
||||
|
||||
public initSolver(dt, dt_inv, warmStarting) {
|
||||
|
||||
//var t0 = Date.now();
|
||||
|
||||
// Initialize contact solvers
|
||||
for (var i = 0; i < this.contactSolvers.length; i++)
|
||||
{
|
||||
this.contactSolvers[i].initSolver(dt_inv);
|
||||
}
|
||||
|
||||
// Initialize joint solver
|
||||
for (var i = 0; i < this.jointArr.length; i++)
|
||||
{
|
||||
if (this.jointArr[i])
|
||||
{
|
||||
this.jointArr[i].initSolver(dt, warmStarting);
|
||||
}
|
||||
}
|
||||
|
||||
// Warm starting (apply cached impulse)
|
||||
if (warmStarting)
|
||||
{
|
||||
for (var i = 0; i < this.contactSolvers.length; i++)
|
||||
{
|
||||
this.contactSolvers[i].warmStart();
|
||||
}
|
||||
}
|
||||
|
||||
//stats.timeInitSolver = Date.now() - t0;
|
||||
}
|
||||
|
||||
public velocitySolver(iteration) {
|
||||
|
||||
//var t0 = Date.now();
|
||||
|
||||
for (var i = 0; i < iteration; i++)
|
||||
{
|
||||
for (var j = 0; j < this.jointArr.length; j++)
|
||||
{
|
||||
if (this.jointArr[j])
|
||||
{
|
||||
this.jointArr[j].solveVelocityConstraints();
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < this.contactSolvers.length; j++)
|
||||
{
|
||||
this.contactSolvers[j].solveVelocityConstraints();
|
||||
}
|
||||
}
|
||||
|
||||
//stats.timeVelocitySolver = Date.now() - t0;
|
||||
}
|
||||
|
||||
public positionSolver(iteration) {
|
||||
|
||||
//var t0 = Date.now();
|
||||
|
||||
var positionSolved = false;
|
||||
|
||||
//stats.positionIterations = 0;
|
||||
|
||||
for (var i = 0; i < iteration; i++)
|
||||
{
|
||||
var contactsOk = true;
|
||||
var jointsOk = true;
|
||||
|
||||
for (var j = 0; j < this.contactSolvers.length; j++)
|
||||
{
|
||||
var contactOk = this.contactSolvers[j].solvePositionConstraints();
|
||||
contactsOk = contactOk && contactsOk;
|
||||
}
|
||||
|
||||
for (var j = 0; j < this.jointArr.length; j++)
|
||||
{
|
||||
if (this.jointArr[j])
|
||||
{
|
||||
var jointOk = this.jointArr[j].solvePositionConstraints();
|
||||
jointsOk = jointOk && jointsOk;
|
||||
}
|
||||
}
|
||||
|
||||
if (contactsOk && jointsOk)
|
||||
{
|
||||
// exit early if the position errors are small
|
||||
positionSolved = true;
|
||||
break;
|
||||
}
|
||||
|
||||
//stats.positionIterations++;
|
||||
}
|
||||
|
||||
//stats.timePositionSolver = Date.now() - t0;
|
||||
|
||||
return positionSolved;
|
||||
|
||||
}
|
||||
|
||||
public step(dt, vel_iteration, pos_iteration, warmStarting, allowSleep) {
|
||||
|
||||
var dt_inv = 1 / dt;
|
||||
|
||||
this.stepCount++;
|
||||
|
||||
// Generate contact & contactSolver
|
||||
this.contactSolvers = this.genTemporalContactSolvers();
|
||||
|
||||
// Initialize contacts & joints solver
|
||||
this.initSolver(dt, dt_inv, warmStarting);
|
||||
|
||||
// Intergrate velocity
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (body.isDynamic && body.isAwake)
|
||||
{
|
||||
body.updateVelocity(this.gravity, dt, this.damping);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.jointArr.length; i++)
|
||||
{
|
||||
var joint = this.jointArr[i];
|
||||
|
||||
if (!joint)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var body1 = joint.body1;
|
||||
var body2 = joint.body2;
|
||||
|
||||
var awake1 = body1.isAwake && !body1.isStatic;
|
||||
var awake2 = body2.isAwake && !body2.isStatic;
|
||||
|
||||
if (awake1 ^ awake2)
|
||||
{
|
||||
if (!awake1)
|
||||
{
|
||||
body1.awake(true);
|
||||
}
|
||||
|
||||
if (!awake2)
|
||||
{
|
||||
body2.awake(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Iterative velocity constraints solver
|
||||
this.velocitySolver(vel_iteration);
|
||||
|
||||
// Intergrate position
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
|
||||
if (!body)
|
||||
{
|
||||
continue
|
||||
}
|
||||
|
||||
if (body.isDynamic && body.isAwake)
|
||||
{
|
||||
body.updatePosition(dt);
|
||||
}
|
||||
}
|
||||
|
||||
// Process breakable joint
|
||||
for (var i = 0; i < this.jointArr.length; i++)
|
||||
{
|
||||
var joint = this.jointArr[i];
|
||||
|
||||
if (!joint)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (joint.breakable)
|
||||
{
|
||||
if (joint.getReactionForce(dt_inv).lengthsq() >= joint.maxForce * joint.maxForce)
|
||||
{
|
||||
this.removeJoint(joint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Iterative position constraints solver
|
||||
var positionSolved = this.positionSolver(pos_iteration);
|
||||
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
body.syncTransform();
|
||||
}
|
||||
|
||||
// Post solve collision callback
|
||||
for (var i = 0; i < this.contactSolvers.length; i++)
|
||||
{
|
||||
var arb = this.contactSolvers[i];
|
||||
this.postSolve(arb);
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (body.isDynamic && body.isAwake)
|
||||
{
|
||||
body.cacheData();
|
||||
}
|
||||
}
|
||||
|
||||
// Process sleeping
|
||||
if (allowSleep)
|
||||
{
|
||||
var minSleepTime = 999999;
|
||||
|
||||
var linTolSqr = Space.SLEEP_LINEAR_TOLERANCE * Space.SLEEP_LINEAR_TOLERANCE;
|
||||
var angTolSqr = Space.SLEEP_ANGULAR_TOLERANCE * Space.SLEEP_ANGULAR_TOLERANCE;
|
||||
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!body.isDynamic)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (body.angularVelocity * body.angularVelocity > angTolSqr || body.velocity.dot(body.velocity) > linTolSqr)
|
||||
{
|
||||
body.sleepTime = 0;
|
||||
minSleepTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
body.sleepTime += dt;
|
||||
minSleepTime = Math.min(minSleepTime, body.sleepTime);
|
||||
}
|
||||
}
|
||||
|
||||
if (positionSolved && minSleepTime >= Space.TIME_TO_SLEEP)
|
||||
{
|
||||
for (var i = 0; i < this.bodyArr.length; i++)
|
||||
{
|
||||
var body = this.bodyArr[i];
|
||||
|
||||
if (!body)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
body.awake(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/// <reference path="../../../math/Vec2.ts" />
|
||||
/// <reference path="../../../geom/Point.ts" />
|
||||
/// <reference path="../../../math/Vec2Utils.ts" />
|
||||
/// <reference path="../Manager.ts" />
|
||||
/// <reference path="../Body.ts" />
|
||||
|
||||
/**
|
||||
* Phaser - Advanced Physics - Joint
|
||||
*
|
||||
* Based on the work Ju Hyung Lee started in JS PhyRus.
|
||||
*/
|
||||
|
||||
module Phaser.Physics.Advanced {
|
||||
|
||||
export interface IJoint {
|
||||
|
||||
id: number;
|
||||
type: number;
|
||||
|
||||
body1: Phaser.Physics.Advanced.Body;
|
||||
body2: Phaser.Physics.Advanced.Body;
|
||||
|
||||
collideConnected; // bool?
|
||||
maxForce: number;
|
||||
breakable: bool;
|
||||
|
||||
anchor1: Phaser.Vec2;
|
||||
anchor2: Phaser.Vec2;
|
||||
|
||||
getWorldAnchor1();
|
||||
getWorldAnchor2();
|
||||
setWorldAnchor1(anchor1);
|
||||
setWorldAnchor2(anchor2);
|
||||
|
||||
initSolver(dt, warmStarting);
|
||||
solveVelocityConstraints();
|
||||
solvePositionConstraints();
|
||||
getReactionForce(dt_inv);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1077
-547
File diff suppressed because it is too large
Load Diff
Vendored
+173
-104
@@ -9583,6 +9583,7 @@ module Phaser.Physics.Advanced {
|
||||
* Local reference to Game.
|
||||
*/
|
||||
public game: Game;
|
||||
static collision: Collision;
|
||||
static SHAPE_TYPE_CIRCLE: number;
|
||||
static SHAPE_TYPE_SEGMENT: number;
|
||||
static SHAPE_TYPE_POLY: number;
|
||||
@@ -9658,97 +9659,6 @@ module Phaser.Physics.Advanced {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Phaser - Advanced Physics - Body
|
||||
*
|
||||
* Based on the work Ju Hyung Lee started in JS PhyRus.
|
||||
*/
|
||||
module Phaser.Physics.Advanced {
|
||||
class Body {
|
||||
constructor(sprite: Sprite, type: number);
|
||||
/**
|
||||
* Reference to Phaser.Game
|
||||
*/
|
||||
public game: Game;
|
||||
/**
|
||||
* Reference to the parent Sprite
|
||||
*/
|
||||
public sprite: Sprite;
|
||||
/**
|
||||
* The Body ID
|
||||
*/
|
||||
public id: number;
|
||||
/**
|
||||
* The Body name
|
||||
*/
|
||||
public name: string;
|
||||
/**
|
||||
* The type of Body (disabled, dynamic, static or kinematic)
|
||||
* Disabled = skips all physics operations / tests (default)
|
||||
* Dynamic = gives and receives impacts
|
||||
* Static = gives but doesn't receive impacts, cannot be moved by physics
|
||||
* Kinematic = gives impacts, but never receives, can be moved by physics
|
||||
* @type {number}
|
||||
*/
|
||||
public type: number;
|
||||
public angle: number;
|
||||
public transform: Transform;
|
||||
public centroid: Vec2;
|
||||
public position: Vec2;
|
||||
public velocity: Vec2;
|
||||
public force: Vec2;
|
||||
public angularVelocity: number;
|
||||
public torque: number;
|
||||
public linearDamping: number;
|
||||
public angularDamping: number;
|
||||
public sleepTime: number;
|
||||
public awaked: bool;
|
||||
public shapes: any[];
|
||||
public joints: any[];
|
||||
public jointHash: {};
|
||||
public bounds;
|
||||
public fixedRotation: bool;
|
||||
public categoryBits: number;
|
||||
public maskBits: number;
|
||||
public stepCount: number;
|
||||
public isDisabled : bool;
|
||||
public isStatic : bool;
|
||||
public isKinetic : bool;
|
||||
public isDynamic : bool;
|
||||
public setType(type: number): void;
|
||||
public addShape(shape): void;
|
||||
public removeShape(shape): void;
|
||||
public mass: number;
|
||||
public massInverted: number;
|
||||
public inertia: number;
|
||||
public inertiaInverted: number;
|
||||
private setMass(mass);
|
||||
private setInertia(inertia);
|
||||
public setTransform(pos, angle): void;
|
||||
public syncTransform(): void;
|
||||
public getWorldPoint(p: Vec2): Vec2;
|
||||
public getWorldVector(v): Vec2;
|
||||
public getLocalPoint(p): Vec2;
|
||||
public getLocalVector(v): Vec2;
|
||||
public setFixedRotation(flag): void;
|
||||
public resetMassData(): void;
|
||||
public resetJointAnchors(): void;
|
||||
public cacheData(): void;
|
||||
private _tempVec2;
|
||||
public updateVelocity(gravity, dt, damping): void;
|
||||
public updatePosition(dt): void;
|
||||
public resetForce(): void;
|
||||
public applyForce(force, p): void;
|
||||
public applyForceToCenter(force): void;
|
||||
public applyTorque(torque): void;
|
||||
public applyLinearImpulse(impulse, p): void;
|
||||
public applyAngularImpulse(impulse): void;
|
||||
public kineticEnergy(): number;
|
||||
public isAwake : bool;
|
||||
public awake(flag): void;
|
||||
public isCollidable(other): bool;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Phaser - Advanced Physics - Shape
|
||||
*
|
||||
* Based on the work Ju Hyung Lee started in JS PhyRus.
|
||||
@@ -9787,6 +9697,22 @@ module Phaser.Physics.Advanced {
|
||||
public lambdaTangential;
|
||||
}
|
||||
}
|
||||
module Phaser.Physics.Advanced {
|
||||
class ContactSolver {
|
||||
constructor(shape1, shape2);
|
||||
public shape1;
|
||||
public shape2;
|
||||
public contacts: Contact[];
|
||||
public elasticity: number;
|
||||
public friction: number;
|
||||
public update(newContactArr: Contact[]): void;
|
||||
public initSolver(dt_inv): void;
|
||||
public warmStart(): void;
|
||||
public solveVelocityConstraints(): void;
|
||||
public solvePositionConstraints(): bool;
|
||||
public clamp(v, min, max);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Phaser - Advanced Physics - Shape
|
||||
*
|
||||
@@ -9838,20 +9764,163 @@ module Phaser.Physics.Advanced {
|
||||
public poly2Poly(poly1, poly2, contactArr): number;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Phaser - Advanced Physics - Joint
|
||||
*
|
||||
* Based on the work Ju Hyung Lee started in JS PhyRus.
|
||||
*/
|
||||
module Phaser.Physics.Advanced {
|
||||
class ContactSolver {
|
||||
constructor(shape1, shape2);
|
||||
public shape1;
|
||||
public shape2;
|
||||
public contacts: Contact[];
|
||||
public elasticity: number;
|
||||
public friction: number;
|
||||
public update(newContactArr: Contact[]): void;
|
||||
public initSolver(dt_inv): void;
|
||||
public warmStart(): void;
|
||||
public solveVelocityConstraints(): void;
|
||||
public solvePositionConstraints(): bool;
|
||||
public clamp(v, min, max);
|
||||
interface IJoint {
|
||||
id: number;
|
||||
type: number;
|
||||
body1: Body;
|
||||
body2: Body;
|
||||
collideConnected;
|
||||
maxForce: number;
|
||||
breakable: bool;
|
||||
anchor1: Vec2;
|
||||
anchor2: Vec2;
|
||||
getWorldAnchor1();
|
||||
getWorldAnchor2();
|
||||
setWorldAnchor1(anchor1);
|
||||
setWorldAnchor2(anchor2);
|
||||
initSolver(dt, warmStarting);
|
||||
solveVelocityConstraints();
|
||||
solvePositionConstraints();
|
||||
getReactionForce(dt_inv);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Phaser - Advanced Physics - Space
|
||||
*
|
||||
* Based on the work Ju Hyung Lee started in JS PhyRus.
|
||||
*/
|
||||
module Phaser.Physics.Advanced {
|
||||
class Space {
|
||||
constructor();
|
||||
static TIME_TO_SLEEP: number;
|
||||
static SLEEP_LINEAR_TOLERANCE: number;
|
||||
static SLEEP_ANGULAR_TOLERANCE: number;
|
||||
public bodyArr: Body[];
|
||||
public bodyHash;
|
||||
public jointArr: IJoint[];
|
||||
public jointHash;
|
||||
public numContacts: number;
|
||||
public contactSolvers: ContactSolver[];
|
||||
public postSolve;
|
||||
public gravity: Vec2;
|
||||
public damping: number;
|
||||
public stepCount: number;
|
||||
public clear(): void;
|
||||
public addBody(body: Body): void;
|
||||
public removeBody(body: Body): void;
|
||||
public addJoint(joint: IJoint): void;
|
||||
public removeJoint(joint: IJoint): void;
|
||||
public findShapeByPoint(p, refShape);
|
||||
public findBodyByPoint(p, refBody: Body);
|
||||
public shapeById(id);
|
||||
public jointById(id): IJoint;
|
||||
public findVertexByPoint(p, minDist, refVertexId): number;
|
||||
public findEdgeByPoint(p, minDist, refEdgeId): number;
|
||||
public findJointByPoint(p, minDist, refJointId): number;
|
||||
public findContactSolver(shape1, shape2): ContactSolver;
|
||||
public genTemporalContactSolvers(): any[];
|
||||
public initSolver(dt, dt_inv, warmStarting): void;
|
||||
public velocitySolver(iteration): void;
|
||||
public positionSolver(iteration): bool;
|
||||
public step(dt, vel_iteration, pos_iteration, warmStarting, allowSleep): void;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Phaser - Advanced Physics - Body
|
||||
*
|
||||
* Based on the work Ju Hyung Lee started in JS PhyRus.
|
||||
*/
|
||||
module Phaser.Physics.Advanced {
|
||||
class Body {
|
||||
constructor(sprite: Sprite, type: number);
|
||||
/**
|
||||
* Reference to Phaser.Game
|
||||
*/
|
||||
public game: Game;
|
||||
/**
|
||||
* Reference to the parent Sprite
|
||||
*/
|
||||
public sprite: Sprite;
|
||||
/**
|
||||
* The Body ID
|
||||
*/
|
||||
public id: number;
|
||||
/**
|
||||
* The Body name
|
||||
*/
|
||||
public name: string;
|
||||
/**
|
||||
* The type of Body (disabled, dynamic, static or kinematic)
|
||||
* Disabled = skips all physics operations / tests (default)
|
||||
* Dynamic = gives and receives impacts
|
||||
* Static = gives but doesn't receive impacts, cannot be moved by physics
|
||||
* Kinematic = gives impacts, but never receives, can be moved by physics
|
||||
* @type {number}
|
||||
*/
|
||||
public type: number;
|
||||
public angle: number;
|
||||
public transform: Transform;
|
||||
public centroid: Vec2;
|
||||
public position: Vec2;
|
||||
public velocity: Vec2;
|
||||
public force: Vec2;
|
||||
public angularVelocity: number;
|
||||
public torque: number;
|
||||
public linearDamping: number;
|
||||
public angularDamping: number;
|
||||
public sleepTime: number;
|
||||
public awaked: bool;
|
||||
public shapes: any[];
|
||||
public joints: any[];
|
||||
public jointHash: {};
|
||||
public bounds;
|
||||
public fixedRotation: bool;
|
||||
public categoryBits: number;
|
||||
public maskBits: number;
|
||||
public stepCount: number;
|
||||
public space: Space;
|
||||
public isDisabled : bool;
|
||||
public isStatic : bool;
|
||||
public isKinetic : bool;
|
||||
public isDynamic : bool;
|
||||
public setType(type: number): void;
|
||||
public addShape(shape): void;
|
||||
public removeShape(shape): void;
|
||||
public mass: number;
|
||||
public massInverted: number;
|
||||
public inertia: number;
|
||||
public inertiaInverted: number;
|
||||
private setMass(mass);
|
||||
private setInertia(inertia);
|
||||
public setTransform(pos, angle): void;
|
||||
public syncTransform(): void;
|
||||
public getWorldPoint(p: Vec2): Vec2;
|
||||
public getWorldVector(v): Vec2;
|
||||
public getLocalPoint(p): Vec2;
|
||||
public getLocalVector(v): Vec2;
|
||||
public setFixedRotation(flag): void;
|
||||
public resetMassData(): void;
|
||||
public resetJointAnchors(): void;
|
||||
public cacheData(): void;
|
||||
private _tempVec2;
|
||||
public updateVelocity(gravity, dt, damping): void;
|
||||
public updatePosition(dt): void;
|
||||
public resetForce(): void;
|
||||
public applyForce(force, p): void;
|
||||
public applyForceToCenter(force): void;
|
||||
public applyTorque(torque): void;
|
||||
public applyLinearImpulse(impulse, p): void;
|
||||
public applyAngularImpulse(impulse): void;
|
||||
public kineticEnergy(): number;
|
||||
public isAwake : bool;
|
||||
public awake(flag): void;
|
||||
public isCollidable(other): bool;
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
||||
+1077
-547
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user