All physics projections added.

This commit is contained in:
Richard Davey
2013-08-11 19:02:10 +01:00
parent c2d7fb7fab
commit 7aa82a1cb0
36 changed files with 5811 additions and 874 deletions
+19
View File
@@ -0,0 +1,19 @@
var Shapes;
(function (Shapes) {
var Point = Shapes.Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.getDist = function () {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
};
Point.origin = new Point(0, 0);
return Point;
})();
})(Shapes || (Shapes = {}));
var p = new Shapes.Point(3, 4);
var dist = p.getDist();
+597
View File
@@ -0,0 +1,597 @@
/// <reference path="../../_definitions.ts" />
/**
* Phaser - Physics - Projection
*/
module Phaser.Physics.Projection {
export class Circle22Deg {
public static CollideS(x, y, oH, oV, obj: Phaser.Physics.Circle, t: Phaser.Physics.TileMapCell) {
//if the object is in a cell pointed at by signy, no collision will ever occur
//otherwise,
//
//if we're colliding diagonally:
// -collide vs. the appropriate vertex
//if obj is in this tile: collide vs slope or vertex
//if obj is horiz neighb in direction of slope: collide vs. slope or vertex
//if obj is horiz neighb against the slope:
// if(distance in y from circle to 90deg corner of tile < 1/2 tileheight, collide vs. face)
// else(collide vs. corner of slope) (vert collision with a non-grid-aligned vert)
//if obj is vert neighb against direction of slope: collide vs. face
var signx = t.signx;
var signy = t.signy;
if (0 < (signy * oV))
{
//object will never collide vs tile, it can't reach that far
return Phaser.Physics.Circle.COL_NONE;
}
else if (oH == 0)
{
if (oV == 0)
{
//colliding with current tile
//we could only be colliding vs the slope OR a vertex
//look at the vector form the closest vert to the circle to decide
var sx = t.sx;
var sy = t.sy;
var r = obj.radius;
var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//this gives is the coordinates of the innermost
var oy = obj.pos.y - t.pos.y;//point on the circle, relative to the tile corner
//if the component of (ox,oy) parallel to the normal's righthand normal
//has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy)
//then we project by the vertex, otherwise by the normal or axially.
//note that this is simply a VERY tricky/weird method of determining
//if the circle is in side the slope/face's voronio region, or that of the vertex.
var perp = (ox * -sy) + (oy * sx);
if (0 < (perp * signx * signy))
{
//collide vs. vertex
var len = Math.sqrt(ox * ox + oy * oy);
var pen = r - len;
if (0 < pen)
{
//note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0
ox /= len;
oy /= len;
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
else
{
//collide vs. slope or vs axis
ox -= r * sx;//this gives us the vector from
oy -= r * sy;//a point on the slope to the innermost point on the circle
//if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
var dp = (ox * sx) + (oy * sy);
if (dp < 0)
{
//collision; project delta onto slope and use this to displace the object
sx *= -dp;//(sx,sy) is now the projection vector
sy *= -dp;
var lenN = Math.sqrt(sx * sx + sy * sy);
var lenP;
//find the smallest axial projection vector
if (x < y)
{
//penetration in x is smaller
lenP = x;
y = 0;
//get sign for projection along x-axis
if ((obj.pos.x - t.pos.x) < 0)
{
x *= -1;
}
}
else
{
//penetration in y is smaller
lenP = y;
x = 0;
//get sign for projection along y-axis
if ((obj.pos.y - t.pos.y) < 0)
{
y *= -1;
}
}
if (lenP < lenN)
{
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
}
else
{
//colliding vertically; we can assume that (signy*oV) < 0
//due to the first conditional far above
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
}
else if (oV == 0)
{
//colliding horizontally
if ((signx * oH) < 0)
{
//colliding with face/edge OR with corner of wedge, depending on our position vertically
//collide vs. vertex
//get diag vertex position
var vx = t.pos.x - (signx * t.xw);
var vy = t.pos.y;
var dx = obj.pos.x - vx;//calc vert->circle vector
var dy = obj.pos.y - vy;
if ((dy * signy) < 0)
{
//colliding vs face
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//colliding vs. vertex
var len = Math.sqrt(dx * dx + dy * dy);
var pen = obj.radius - len;
if (0 < pen)
{
//vertex is in the circle; project outward
if (len == 0)
{
//project out by 45deg
dx = oH / Math.SQRT2;
dy = oV / Math.SQRT2;
}
else
{
dx /= len;
dy /= len;
}
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
else
{
//we could only be colliding vs the slope OR a vertex
//look at the vector form the closest vert to the circle to decide
var sx = t.sx;
var sy = t.sy;
var ox = obj.pos.x - (t.pos.x + (oH * t.xw));//this gives is the coordinates of the innermost
var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//point on the circle, relative to the closest tile vert
//if the component of (ox,oy) parallel to the normal's righthand normal
//has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy)
//then we project by the normal, otherwise by the vertex.
//(NOTE: this is the opposite logic of the vertical case;
// for vertical, if the perp prod and the slope's slope agree, it's outside.
// for horizontal, if the perp prod and the slope's slope agree, circle is inside.
// ..but this is only a property of flahs' coord system (i.e the rules might swap
// in righthanded systems))
//note that this is simply a VERY tricky/weird method of determining
//if the circle is in side the slope/face's voronio region, or that of the vertex.
var perp = (ox * -sy) + (oy * sx);
if ((perp * signx * signy) < 0)
{
//collide vs. vertex
var len = Math.sqrt(ox * ox + oy * oy);
var pen = obj.radius - len;
if (0 < pen)
{
//note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0
ox /= len;
oy /= len;
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
else
{
//collide vs. slope
//if the component of (ox,oy) parallel to the normal is less than the circle radius, we're
//penetrating the slope. note that this method of penetration calculation doesn't hold
//in general (i.e it won't work if the circle is in the slope), but works in this case
//because we know the circle is in a neighboring cell
var dp = (ox * sx) + (oy * sy);
var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case..
if (0 < pen)
{
//collision; circle out along normal by penetration amount
obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
}
else
{
//colliding diagonally; due to the first conditional above,
//obj is vertically offset against slope, and offset in either direction horizontally
//collide vs. vertex
//get diag vertex position
var vx = t.pos.x + (oH * t.xw);
var vy = t.pos.y + (oV * t.yw);
var dx = obj.pos.x - vx;//calc vert->circle vector
var dy = obj.pos.y - vy;
var len = Math.sqrt(dx * dx + dy * dy);
var pen = obj.radius - len;
if (0 < pen)
{
//vertex is in the circle; project outward
if (len == 0)
{
//project out by 45deg
dx = oH / Math.SQRT2;
dy = oV / Math.SQRT2;
}
else
{
dx /= len;
dy /= len;
}
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
return Phaser.Physics.Circle.COL_NONE;
}
public static CollideB(x, y, oH, oV, obj: Phaser.Physics.Circle, t: Phaser.Physics.TileMapCell) {
//if we're colliding diagonally:
// -if we're in the cell pointed at by the normal, collide vs slope, else
// collide vs. the appropriate corner/vertex
//
//if obj is in this tile: collide as with aabb
//
//if obj is horiz or vertical neighbor AGAINST the slope: collide with edge
//
//if obj is horiz neighb in direction of slope: collide vs. slope or vertex or edge
//
//if obj is vert neighb in direction of slope: collide vs. slope or vertex
var signx = t.signx;
var signy = t.signy;
var sx: number;
var sy: number;
if (oH == 0)
{
if (oV == 0)
{
//colliding with current cell
sx = t.sx;
sy = t.sy;
var r = obj.radius;
var ox = (obj.pos.x - (sx * r)) - (t.pos.x - (signx * t.xw));//this gives is the coordinates of the innermost
var oy = (obj.pos.y - (sy * r)) - (t.pos.y + (signy * t.yw));//point on the AABB, relative to a point on the slope
//if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
var dp = (ox * sx) + (oy * sy);
if (dp < 0)
{
//collision; project delta onto slope and use this to displace the object
sx *= -dp;//(sx,sy) is now the projection vector
sy *= -dp;
var lenN = Math.sqrt(sx * sx + sy * sy);
var lenP;
//find the smallest axial projection vector
if (x < y)
{
//penetration in x is smaller
lenP = x;
y = 0;
//get sign for projection along x-axis
if ((obj.pos.x - t.pos.x) < 0)
{
x *= -1;
}
}
else
{
//penetration in y is smaller
lenP = y;
x = 0;
//get sign for projection along y-axis
if ((obj.pos.y - t.pos.y) < 0)
{
y *= -1;
}
}
if (lenP < lenN)
{
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
else
{
//colliding vertically
if ((signy * oV) < 0)
{
//colliding with face/edge
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//we could only be colliding vs the slope OR a vertex
//look at the vector form the closest vert to the circle to decide
sx = t.sx;
sy = t.sy;
var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//this gives is the coordinates of the innermost
var oy = obj.pos.y - (t.pos.y + (signy * t.yw));//point on the circle, relative to the closest tile vert
//if the component of (ox,oy) parallel to the normal's righthand normal
//has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy)
//then we project by the vertex, otherwise by the normal.
//note that this is simply a VERY tricky/weird method of determining
//if the circle is in side the slope/face's voronio region, or that of the vertex.
var perp = (ox * -sy) + (oy * sx);
if (0 < (perp * signx * signy))
{
//collide vs. vertex
var len = Math.sqrt(ox * ox + oy * oy);
var pen = obj.radius - len;
if (0 < pen)
{
//note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0
ox /= len;
oy /= len;
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
else
{
//collide vs. slope
//if the component of (ox,oy) parallel to the normal is less than the circle radius, we're
//penetrating the slope. note that this method of penetration calculation doesn't hold
//in general (i.e it won't work if the circle is in the slope), but works in this case
//because we know the circle is in a neighboring cell
var dp = (ox * sx) + (oy * sy);
var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case..
if (0 < pen)
{
//collision; circle out along normal by penetration amount
obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
}
}
else if (oV == 0)
{
//colliding horizontally
if ((signx * oH) < 0)
{
//colliding with face/edge
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//colliding with edge, slope, or vertex
var ox = obj.pos.x - (t.pos.x + (signx * t.xw));//this gives is the coordinates of the innermost
var oy = obj.pos.y - t.pos.y;//point on the circle, relative to the closest tile vert
if ((oy * signy) < 0)
{
//we're colliding with the halfface
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//colliding with the vertex or slope
sx = t.sx;
sy = t.sy;
//if the component of (ox,oy) parallel to the normal's righthand normal
//has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy)
//then we project by the slope, otherwise by the vertex.
//note that this is simply a VERY tricky/weird method of determining
//if the circle is in side the slope/face's voronio region, or that of the vertex.
var perp = (ox * -sy) + (oy * sx);
if ((perp * signx * signy) < 0)
{
//collide vs. vertex
var len = Math.sqrt(ox * ox + oy * oy);
var pen = obj.radius - len;
if (0 < pen)
{
//note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0
ox /= len;
oy /= len;
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
else
{
//collide vs. slope
//if the component of (ox,oy) parallel to the normal is less than the circle radius, we're
//penetrating the slope. note that this method of penetration calculation doesn't hold
//in general (i.e it won't work if the circle is in the slope), but works in this case
//because we know the circle is in a neighboring cell
var dp = (ox * sx) + (oy * sy);
var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case..
if (0 < pen)
{
//collision; circle out along normal by penetration amount
obj.reportCollisionVsWorld(sx * pen, sy * pen, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
}
}
else
{
//colliding diagonally
if (0 < ((signx * oH) + (signy * oV)))
{
//the dotprod of slope normal and cell offset is strictly positive,
//therefore obj is in the diagonal neighb pointed at by the normal.
//collide vs slope
//we should really precalc this at compile time, but for now, fuck it
var slen: number = Math.sqrt(2 * 2 + 1 * 1);//the raw slope is (-2,-1)
sx = (signx * 1) / slen;//get slope _unit_ normal;
sy = (signy * 2) / slen;//raw RH normal is (1,-2)
var r = obj.radius;
var ox = (obj.pos.x - (sx * r)) - (t.pos.x - (signx * t.xw));//this gives is the coordinates of the innermost
var oy = (obj.pos.y - (sy * r)) - (t.pos.y + (signy * t.yw));//point on the circle, relative to a point on the slope
//if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
var dp = (ox * sx) + (oy * sy);
if (dp < 0)
{
//collision; project delta onto slope and use this to displace the object
//(sx,sy)*-dp is the projection vector
obj.reportCollisionVsWorld(-sx * dp, -sy * dp, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
return Phaser.Physics.Circle.COL_NONE;
}
else
{
//collide vs the appropriate vertex
var vx = t.pos.x + (oH * t.xw);
var vy = t.pos.y + (oV * t.yw);
var dx = obj.pos.x - vx;//calc vert->circle vector
var dy = obj.pos.y - vy;
var len = Math.sqrt(dx * dx + dy * dy);
var pen = obj.radius - len;
if (0 < pen)
{
//vertex is in the circle; project outward
if (len == 0)
{
//project out by 45deg
dx = oH / Math.SQRT2;
dy = oV / Math.SQRT2;
}
else
{
dx /= len;
dy /= len;
}
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
return Phaser.Physics.Circle.COL_NONE;
}
}
}
+9 -9
View File
@@ -58,11 +58,11 @@ var Phaser;
var lenN = Math.sqrt(sx * sx + sy * sy);
if (lenP < lenN) {
obj.ReportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
obj.ReportCollisionVsWorld(sx, sy, t.sx, t.sy, t);
obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -70,7 +70,7 @@ var Phaser;
} else {
if ((signy * oV) < 0) {
//colliding with face/edge
obj.ReportCollisionVsWorld(0, y * oV, 0, oV, t);
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
@@ -97,7 +97,7 @@ var Phaser;
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -111,7 +111,7 @@ var Phaser;
var pen = obj.radius - Math.abs(dp);
if (0 < pen) {
//collision; circle out along normal by penetration amount
obj.ReportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -121,7 +121,7 @@ var Phaser;
} else if (oV == 0) {
if ((signx * oH) < 0) {
//colliding with face/edge
obj.ReportCollisionVsWorld(x * oH, 0, oH, 0, t);
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
@@ -153,7 +153,7 @@ var Phaser;
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -167,7 +167,7 @@ var Phaser;
var pen = obj.radius - Math.abs(dp);
if (0 < pen) {
//collision; circle out along normal by penetration amount
obj.ReportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -200,7 +200,7 @@ var Phaser;
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
+9 -9
View File
@@ -72,13 +72,13 @@ module Phaser.Physics.Projection {
if (lenP < lenN)
{
obj.ReportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
obj.ReportCollisionVsWorld(sx, sy, t.sx, t.sy, t);
obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -91,7 +91,7 @@ module Phaser.Physics.Projection {
if ((signy * oV) < 0)
{
//colliding with face/edge
obj.ReportCollisionVsWorld(0, y * oV, 0, oV, t);
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
@@ -123,7 +123,7 @@ module Phaser.Physics.Projection {
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -141,7 +141,7 @@ module Phaser.Physics.Projection {
if (0 < pen)
{
//collision; circle out along normal by penetration amount
obj.ReportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -155,7 +155,7 @@ module Phaser.Physics.Projection {
if ((signx * oH) < 0)
{
//colliding with face/edge
obj.ReportCollisionVsWorld(x * oH, 0, oH, 0, t);
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
@@ -192,7 +192,7 @@ module Phaser.Physics.Projection {
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -210,7 +210,7 @@ module Phaser.Physics.Projection {
if (0 < pen)
{
//collision; circle out along normal by penetration amount
obj.ReportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -254,7 +254,7 @@ module Phaser.Physics.Projection {
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
+19
View File
@@ -0,0 +1,19 @@
var Shapes;
(function (Shapes) {
var Point = Shapes.Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.getDist = function () {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
};
Point.origin = new Point(0, 0);
return Point;
})();
})(Shapes || (Shapes = {}));
var p = new Shapes.Point(3, 4);
var dist = p.getDist();
+591
View File
@@ -0,0 +1,591 @@
/// <reference path="../../_definitions.ts" />
/**
* Phaser - Physics - Projection
*/
module Phaser.Physics.Projection {
export class Circle67Deg {
public static CollideS(x, y, oH, oV, obj: Phaser.Physics.Circle, t: Phaser.Physics.TileMapCell) {
//if the object is in a cell pointed at by signx, no collision will ever occur
//otherwise,
//
//if we're colliding diagonally:
// -collide vs. the appropriate vertex
//if obj is in this tile: collide vs slope or vertex or axis
//if obj is vert neighb in direction of slope: collide vs. slope or vertex
//if obj is vert neighb against the slope:
// if(distance in y from circle to 90deg corner of tile < 1/2 tileheight, collide vs. face)
// else(collide vs. corner of slope) (vert collision with a non-grid-aligned vert)
//if obj is horiz neighb against direction of slope: collide vs. face
var signx = t.signx;
var signy = t.signy;
var sx: number;
var sy: number;
if (0 < (signx * oH))
{
//object will never collide vs tile, it can't reach that far
return Phaser.Physics.Circle.COL_NONE;
}
else if (oH == 0)
{
if (oV == 0)
{
//colliding with current tile
//we could only be colliding vs the slope OR a vertex
//look at the vector form the closest vert to the circle to decide
sx = t.sx;
sy = t.sy;
var r = obj.radius;
var ox = obj.pos.x - t.pos.x;//this gives is the coordinates of the innermost
var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//point on the circle, relative to the tile corner
//if the component of (ox,oy) parallel to the normal's righthand normal
//has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy)
//then we project by the normal or axis, otherwise by the corner/vertex
//note that this is simply a VERY tricky/weird method of determining
//if the circle is in side the slope/face's voronoi region, or that of the vertex.
var perp = (ox * -sy) + (oy * sx);
if ((perp * signx * signy) < 0)
{
//collide vs. vertex
var len = Math.sqrt(ox * ox + oy * oy);
var pen = r - len;
if (0 < pen)
{
//note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0
ox /= len;
oy /= len;
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
else
{
//collide vs. slope or vs axis
ox -= r * sx;//this gives us the vector from
oy -= r * sy;//a point on the slope to the innermost point on the circle
//if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
var dp = (ox * sx) + (oy * sy);
var lenP;
if (dp < 0)
{
//collision; project delta onto slope and use this to displace the object
sx *= -dp;//(sx,sy) is now the projection vector
sy *= -dp;
var lenN = Math.sqrt(sx * sx + sy * sy);
//find the smallest axial projection vector
if (x < y)
{
//penetration in x is smaller
lenP = x;
y = 0;
//get sign for projection along x-axis
if ((obj.pos.x - t.pos.x) < 0)
{
x *= -1;
}
}
else
{
//penetration in y is smaller
lenP = y;
x = 0;
//get sign for projection along y-axis
if ((obj.pos.y - t.pos.y) < 0)
{
y *= -1;
}
}
if (lenP < lenN)
{
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS
}
else
{
obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
}
else
{
//colliding vertically
if ((signy * oV) < 0)
{
//colliding with face/edge OR with corner of wedge, depending on our position vertically
//collide vs. vertex
//get diag vertex position
var vx = t.pos.x;
var vy = t.pos.y - (signy * t.yw);
var dx = obj.pos.x - vx;//calc vert->circle vector
var dy = obj.pos.y - vy;
if ((dx * signx) < 0)
{
//colliding vs face
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//colliding vs. vertex
var len = Math.sqrt(dx * dx + dy * dy);
var pen = obj.radius - len;
if (0 < pen)
{
//vertex is in the circle; project outward
if (len == 0)
{
//project out by 45deg
dx = oH / Math.SQRT2;
dy = oV / Math.SQRT2;
}
else
{
dx /= len;
dy /= len;
}
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
else
{
//we could only be colliding vs the slope OR a vertex
//look at the vector form the closest vert to the circle to decide
sx = t.sx;
sy = t.sy;
var ox = obj.pos.x - (t.pos.x - (signx * t.xw));//this gives is the coordinates of the innermost
var oy = obj.pos.y - (t.pos.y + (oV * t.yw));//point on the circle, relative to the closest tile vert
//if the component of (ox,oy) parallel to the normal's righthand normal
//has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy)
//then we project by the vertex, otherwise by the normal.
//note that this is simply a VERY tricky/weird method of determining
//if the circle is in side the slope/face's voronio region, or that of the vertex.
var perp = (ox * -sy) + (oy * sx);
if (0 < (perp * signx * signy))
{
//collide vs. vertex
var len = Math.sqrt(ox * ox + oy * oy);
var pen = obj.radius - len;
if (0 < pen)
{
//note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0
ox /= len;
oy /= len;
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
else
{
//collide vs. slope
//if the component of (ox,oy) parallel to the normal is less than the circle radius, we're
//penetrating the slope. note that this method of penetration calculation doesn't hold
//in general (i.e it won't work if the circle is in the slope), but works in this case
//because we know the circle is in a neighboring cell
var dp = (ox * sx) + (oy * sy);
var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case..
if (0 < pen)
{
//collision; circle out along normal by penetration amount
obj.reportCollisionVsWorld(sx * pen, sy * pen, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
}
}
else if (oV == 0)
{
//colliding horizontally; we can assume that (signy*oV) < 0
//due to the first conditional far above
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//colliding diagonally; due to the first conditional above,
//obj is vertically offset against slope, and offset in either direction horizontally
//collide vs. vertex
//get diag vertex position
var vx = t.pos.x + (oH * t.xw);
var vy = t.pos.y + (oV * t.yw);
var dx = obj.pos.x - vx;//calc vert->circle vector
var dy = obj.pos.y - vy;
var len = Math.sqrt(dx * dx + dy * dy);
var pen = obj.radius - len;
if (0 < pen)
{
//vertex is in the circle; project outward
if (len == 0)
{
//project out by 45deg
dx = oH / Math.SQRT2;
dy = oV / Math.SQRT2;
}
else
{
dx /= len;
dy /= len;
}
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
return Phaser.Physics.Circle.COL_NONE;
}
public static CollideB(x, y, oH, oV, obj: Phaser.Physics.Circle, t: Phaser.Physics.TileMapCell) {
//if we're colliding diagonally:
// -if we're in the cell pointed at by the normal, collide vs slope, else
// collide vs. the appropriate corner/vertex
//
//if obj is in this tile: collide as with aabb
//
//if obj is horiz or vertical neighbor AGAINST the slope: collide with edge
//
//if obj is vert neighb in direction of slope: collide vs. slope or vertex or halfedge
//
//if obj is horiz neighb in direction of slope: collide vs. slope or vertex
var signx = t.signx;
var signy = t.signy;
var sx: number;
var sy: number;
if (oH == 0)
{
if (oV == 0)
{
//colliding with current cell
sx = t.sx;
sy = t.sy;
var r = obj.radius;
var ox = (obj.pos.x - (sx * r)) - (t.pos.x + (signx * t.xw));//this gives is the coordinates of the innermost
var oy = (obj.pos.y - (sy * r)) - (t.pos.y - (signy * t.yw));//point on the AABB, relative to a point on the slope
//if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
var dp = (ox * sx) + (oy * sy);
var lenP;
if (dp < 0)
{
//collision; project delta onto slope and use this to displace the object
sx *= -dp;//(sx,sy) is now the projection vector
sy *= -dp;
var lenN = Math.sqrt(sx * sx + sy * sy);
//find the smallest axial projection vector
if (x < y)
{
//penetration in x is smaller
lenP = x;
y = 0;
//get sign for projection along x-axis
if ((obj.pos.x - t.pos.x) < 0)
{
x *= -1;
}
}
else
{
//penetration in y is smaller
lenP = y;
x = 0;
//get sign for projection along y-axis
if ((obj.pos.y - t.pos.y) < 0)
{
y *= -1;
}
}
if (lenP < lenN)
{
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
obj.reportCollisionVsWorld(sx, sy, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
else
{
//colliding vertically
if ((signy * oV) < 0)
{
//colliding with face/edge
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//colliding with edge, slope, or vertex
var ox = obj.pos.x - t.pos.x;//this gives is the coordinates of the innermost
var oy = obj.pos.y - (t.pos.y + (signy * t.yw));//point on the circle, relative to the closest tile vert
if ((ox * signx) < 0)
{
//we're colliding with the halfface
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//colliding with the vertex or slope
sx = t.sx;
sy = t.sy;
//if the component of (ox,oy) parallel to the normal's righthand normal
//has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy)
//then we project by the vertex, otherwise by the slope.
//note that this is simply a VERY tricky/weird method of determining
//if the circle is in side the slope/face's voronio region, or that of the vertex.
var perp = (ox * -sy) + (oy * sx);
if (0 < (perp * signx * signy))
{
//collide vs. vertex
var len = Math.sqrt(ox * ox + oy * oy);
var pen = obj.radius - len;
if (0 < pen)
{
//note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0
ox /= len;
oy /= len;
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
else
{
//collide vs. slope
//if the component of (ox,oy) parallel to the normal is less than the circle radius, we're
//penetrating the slope. note that this method of penetration calculation doesn't hold
//in general (i.e it won't work if the circle is in the slope), but works in this case
//because we know the circle is in a neighboring cell
var dp = (ox * sx) + (oy * sy);
var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case..
if (0 < pen)
{
//collision; circle out along normal by penetration amount
obj.reportCollisionVsWorld(sx * pen, sy * pen, sx, sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
}
}
}
else if (oV == 0)
{
//colliding horizontally
if ((signx * oH) < 0)
{
//colliding with face/edge
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//we could only be colliding vs the slope OR a vertex
//look at the vector form the closest vert to the circle to decide
var slen = Math.sqrt(2 * 2 + 1 * 1);//the raw slope is (-2,-1)
var sx = (signx * 2) / slen;//get slope _unit_ normal;
var sy = (signy * 1) / slen;//raw RH normal is (1,-2)
var ox = obj.pos.x - (t.pos.x + (signx * t.xw));//this gives is the coordinates of the innermost
var oy = obj.pos.y - (t.pos.y - (signy * t.yw));//point on the circle, relative to the closest tile vert
//if the component of (ox,oy) parallel to the normal's righthand normal
//has the same sign as the slope of the slope (the sign of the slope's slope is signx*signy)
//then we project by the slope, otherwise by the vertex.
//note that this is simply a VERY tricky/weird method of determining
//if the circle is in side the slope/face's voronio region, or that of the vertex.
var perp = (ox * -sy) + (oy * sx);
if ((perp * signx * signy) < 0)
{
//collide vs. vertex
var len = Math.sqrt(ox * ox + oy * oy);
var pen = obj.radius - len;
if (0 < pen)
{
//note: if len=0, then perp=0 and we'll never reach here, so don't worry about div-by-0
ox /= len;
oy /= len;
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
else
{
//collide vs. slope
//if the component of (ox,oy) parallel to the normal is less than the circle radius, we're
//penetrating the slope. note that this method of penetration calculation doesn't hold
//in general (i.e it won't work if the circle is in the slope), but works in this case
//because we know the circle is in a neighboring cell
var dp = (ox * sx) + (oy * sy);
var pen = obj.radius - Math.abs(dp);//note: we don't need the abs because we know the dp will be positive, but just in case..
if (0 < pen)
{
//collision; circle out along normal by penetration amount
obj.reportCollisionVsWorld(sx * pen, sy * pen, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
}
else
{
//colliding diagonally
if (0 < ((signx * oH) + (signy * oV)))
{
//the dotprod of slope normal and cell offset is strictly positive,
//therefore obj is in the diagonal neighb pointed at by the normal.
//collide vs slope
sx = t.sx;
sy = t.sy;
var r = obj.radius;
var ox = (obj.pos.x - (sx * r)) - (t.pos.x + (signx * t.xw));//this gives is the coordinates of the innermost
var oy = (obj.pos.y - (sy * r)) - (t.pos.y - (signy * t.yw));//point on the circle, relative to a point on the slope
//if the dotprod of (ox,oy) and (sx,sy) is negative, the point on the circle is in the slope
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
var dp = (ox * sx) + (oy * sy);
if (dp < 0)
{
//collision; project delta onto slope and use this to displace the object
//(sx,sy)*-dp is the projection vector
obj.reportCollisionVsWorld(-sx * dp, -sy * dp, t.sx, t.sy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
return Phaser.Physics.Circle.COL_NONE;
}
else
{
//collide vs the appropriate vertex
var vx = t.pos.x + (oH * t.xw);
var vy = t.pos.y + (oV * t.yw);
var dx = obj.pos.x - vx;//calc vert->circle vector
var dy = obj.pos.y - vy;
var len = Math.sqrt(dx * dx + dy * dy);
var pen = obj.radius - len;
if (0 < pen)
{
//vertex is in the circle; project outward
if (len == 0)
{
//project out by 45deg
dx = oH / Math.SQRT2;
dy = oV / Math.SQRT2;
}
else
{
dx /= len;
dy /= len;
}
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
return Phaser.Physics.Circle.COL_NONE;
}
}
}
+7 -7
View File
@@ -53,7 +53,7 @@ var Phaser;
}
if (lenP < pen) {
obj.ReportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
@@ -63,7 +63,7 @@ var Phaser;
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -73,7 +73,7 @@ var Phaser;
} else {
if ((signy * oV) < 0) {
//colliding with face/edge
obj.ReportCollisionVsWorld(0, y * oV, 0, oV, t);
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
@@ -97,7 +97,7 @@ var Phaser;
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -106,7 +106,7 @@ var Phaser;
} else if (oV == 0) {
if ((signx * oH) < 0) {
//colliding with face/edge
obj.ReportCollisionVsWorld(x * oH, 0, oH, 0, t);
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
@@ -130,7 +130,7 @@ var Phaser;
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -162,7 +162,7 @@ var Phaser;
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
+7 -7
View File
@@ -68,7 +68,7 @@ module Phaser.Physics.Projection {
if (lenP < pen)
{
obj.ReportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
}
@@ -80,7 +80,7 @@ module Phaser.Physics.Projection {
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -97,7 +97,7 @@ module Phaser.Physics.Projection {
if ((signy * oV) < 0)
{
//colliding with face/edge
obj.ReportCollisionVsWorld(0, y * oV, 0, oV, t);
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
@@ -129,7 +129,7 @@ module Phaser.Physics.Projection {
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -142,7 +142,7 @@ module Phaser.Physics.Projection {
if ((signx * oH) < 0)
{
//colliding with face/edge
obj.ReportCollisionVsWorld(x * oH, 0, oH, 0, t);
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
@@ -174,7 +174,7 @@ module Phaser.Physics.Projection {
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -217,7 +217,7 @@ module Phaser.Physics.Projection {
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
+8 -8
View File
@@ -53,7 +53,7 @@ var Phaser;
}
if (lenP < pen) {
obj.ReportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
@@ -63,7 +63,7 @@ var Phaser;
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -71,7 +71,7 @@ var Phaser;
} else {
if ((signy * oV) < 0) {
//colliding with face/edge
obj.ReportCollisionVsWorld(0, y * oV, 0, oV, t);
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
@@ -93,7 +93,7 @@ var Phaser;
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -102,7 +102,7 @@ var Phaser;
} else if (oV == 0) {
if ((signx * oH) < 0) {
//colliding with face/edge
obj.ReportCollisionVsWorld(x * oH, 0, oH, 0, t);
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
@@ -124,7 +124,7 @@ var Phaser;
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -149,7 +149,7 @@ var Phaser;
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -174,7 +174,7 @@ var Phaser;
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
+8 -8
View File
@@ -69,7 +69,7 @@ module Phaser.Physics.Projection {
if (lenP < pen)
{
obj.ReportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
}
@@ -81,7 +81,7 @@ module Phaser.Physics.Projection {
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
@@ -94,7 +94,7 @@ module Phaser.Physics.Projection {
if ((signy * oV) < 0)
{
//colliding with face/edge
obj.ReportCollisionVsWorld(0, y * oV, 0, oV, t);
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
@@ -121,7 +121,7 @@ module Phaser.Physics.Projection {
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -134,7 +134,7 @@ module Phaser.Physics.Projection {
if ((signx * oH) < 0)
{
//colliding with face/edge
obj.ReportCollisionVsWorld(x * oH, 0, oH, 0, t);
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
@@ -161,7 +161,7 @@ module Phaser.Physics.Projection {
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -193,7 +193,7 @@ module Phaser.Physics.Projection {
ox /= len;
oy /= len;
obj.ReportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
obj.reportCollisionVsWorld(ox * pen, oy * pen, ox, oy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
@@ -225,7 +225,7 @@ module Phaser.Physics.Projection {
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
+7 -7
View File
@@ -17,10 +17,10 @@ var Phaser;
var dx = obj.pos.x - t.pos.x;
if (dx < 0) {
obj.ReportCollisionVsWorld(-x, 0, -1, 0, t);
obj.reportCollisionVsWorld(-x, 0, -1, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
obj.ReportCollisionVsWorld(x, 0, 1, 0, t);
obj.reportCollisionVsWorld(x, 0, 1, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
} else {
@@ -28,22 +28,22 @@ var Phaser;
var dy = obj.pos.y - t.pos.y;
if (dy < 0) {
obj.ReportCollisionVsWorld(0, -y, 0, -1, t);
obj.reportCollisionVsWorld(0, -y, 0, -1, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
obj.ReportCollisionVsWorld(0, y, 0, 1, t);
obj.reportCollisionVsWorld(0, y, 0, 1, t);
return Phaser.Physics.Circle.COL_AXIS;
}
}
} else {
//collision with vertical neighbor
obj.ReportCollisionVsWorld(0, y * oV, 0, oV, t);
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
} else if (oV == 0) {
//collision with horizontal neighbor
obj.ReportCollisionVsWorld(x * oH, 0, oH, 0, t);
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
} else {
//diagonal collision
@@ -66,7 +66,7 @@ var Phaser;
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
+7 -7
View File
@@ -28,12 +28,12 @@ module Phaser.Physics.Projection {
//NOTE: should we handle the delta == 0 case?! and how? (project towards oldpos?)
if (dx < 0)
{
obj.ReportCollisionVsWorld(-x, 0, -1, 0, t);
obj.reportCollisionVsWorld(-x, 0, -1, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
obj.ReportCollisionVsWorld(x, 0, 1, 0, t);
obj.reportCollisionVsWorld(x, 0, 1, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
}
@@ -45,12 +45,12 @@ module Phaser.Physics.Projection {
//NOTE: should we handle the delta == 0 case?! and how? (project towards oldpos?)
if (dy < 0)
{
obj.ReportCollisionVsWorld(0, -y, 0, -1, t);
obj.reportCollisionVsWorld(0, -y, 0, -1, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
obj.ReportCollisionVsWorld(0, y, 0, 1, t);
obj.reportCollisionVsWorld(0, y, 0, 1, t);
return Phaser.Physics.Circle.COL_AXIS;
}
}
@@ -58,7 +58,7 @@ module Phaser.Physics.Projection {
else
{
//collision with vertical neighbor
obj.ReportCollisionVsWorld(0, y * oV, 0, oV, t);
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
@@ -66,7 +66,7 @@ module Phaser.Physics.Projection {
else if (oV == 0)
{
//collision with horizontal neighbor
obj.ReportCollisionVsWorld(x * oH, 0, oH, 0, t);
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
@@ -97,7 +97,7 @@ module Phaser.Physics.Projection {
dy /= len;
}
obj.ReportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
+19
View File
@@ -0,0 +1,19 @@
var Shapes;
(function (Shapes) {
var Point = Shapes.Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.getDist = function () {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
};
Point.origin = new Point(0, 0);
return Point;
})();
})(Shapes || (Shapes = {}));
var p = new Shapes.Point(3, 4);
var dist = p.getDist();
+236
View File
@@ -0,0 +1,236 @@
/// <reference path="../../_definitions.ts" />
/**
* Phaser - Physics - Projection
*/
module Phaser.Physics.Projection {
export class CircleHalf {
public static Collide(x, y, oH, oV, obj: Phaser.Physics.Circle, t: Phaser.Physics.TileMapCell) {
//if obj is in a neighbor pointed at by the halfedge normal,
//we'll never collide (i.e if the normal is (0,1) and the obj is in the DL.D, or R neighbors)
//
//if obj is in a neigbor perpendicular to the halfedge normal, it might
//collide with the halfedge-vertex, or with the halfedge side.
//
//if obj is in a neigb pointing opposite the halfedge normal, obj collides with edge
//
//if obj is in a diagonal (pointing away from the normal), obj collides vs vertex
//
//if obj is in the halfedge cell, it collides as with aabb
var signx = t.signx;
var signy = t.signy;
var celldp = (oH * signx + oV * signy);//this tells us about the configuration of cell-offset relative to tile normal
if (0 < celldp)
{
//obj is in "far" (pointed-at-by-normal) neighbor of halffull tile, and will never hit
return Phaser.Physics.Circle.COL_NONE;
}
else if (oH == 0)
{
if (oV == 0)
{
//colliding with current tile
var r = obj.radius;
var ox = (obj.pos.x - (signx * r)) - t.pos.x;//this gives is the coordinates of the innermost
var oy = (obj.pos.y - (signy * r)) - t.pos.y;//point on the circle, relative to the tile center
//we perform operations analogous to the 45deg tile, except we're using
//an axis-aligned slope instead of an angled one..
var sx = signx;
var sy = signy;
//if the dotprod of (ox,oy) and (sx,sy) is negative, the corner is in the slope
//and we need toproject it out by the magnitude of the projection of (ox,oy) onto (sx,sy)
var dp = (ox * sx) + (oy * sy);
if (dp < 0)
{
//collision; project delta onto slope and use this to displace the object
sx *= -dp;//(sx,sy) is now the projection vector
sy *= -dp;
var lenN = Math.sqrt(sx * sx + sy * sy);
var lenP = Math.sqrt(x * x + y * y);
if (lenP < lenN)
{
obj.reportCollisionVsWorld(x, y, x / lenP, y / lenP, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
obj.reportCollisionVsWorld(sx, sy, t.signx, t.signy);
return Phaser.Physics.Circle.COL_OTHER;
}
return true;
}
}
else
{
//colliding vertically
if (celldp == 0)
{
var r = obj.radius;
var dx = obj.pos.x - t.pos.x;
//we're in a cell perpendicular to the normal, and can collide vs. halfedge vertex
//or halfedge side
if ((dx * signx) < 0)
{
//collision with halfedge side
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//collision with halfedge vertex
var dy = obj.pos.y - (t.pos.y + oV * t.yw);//(dx,dy) is now the vector from the appropriate halfedge vertex to the circle
var len = Math.sqrt(dx * dx + dy * dy);
var pen = obj.radius - len;
if (0 < pen)
{
//vertex is in the circle; project outward
if (len == 0)
{
//project out by 45deg
dx = signx / Math.SQRT2;
dy = oV / Math.SQRT2;
}
else
{
dx /= len;
dy /= len;
}
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
else
{
//due to the first conditional (celldp >0), we know we're in the cell "opposite" the normal, and so
//we can only collide with the cell edge
//collision with vertical neighbor
obj.reportCollisionVsWorld(0, y * oV, 0, oV, t);
return Phaser.Physics.Circle.COL_AXIS;
}
}
}
else if (oV == 0)
{
//colliding horizontally
if (celldp == 0)
{
var r = obj.radius;
var dy = obj.pos.y - t.pos.y;
//we're in a cell perpendicular to the normal, and can collide vs. halfedge vertex
//or halfedge side
if ((dy * signy) < 0)
{
//collision with halfedge side
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
else
{
//collision with halfedge vertex
var dx = obj.pos.x - (t.pos.x + oH * t.xw);//(dx,dy) is now the vector from the appropriate halfedge vertex to the circle
var len = Math.sqrt(dx * dx + dy * dy);
var pen = obj.radius - len;
if (0 < pen)
{
//vertex is in the circle; project outward
if (len == 0)
{
//project out by 45deg
dx = signx / Math.SQRT2;
dy = oV / Math.SQRT2;
}
else
{
dx /= len;
dy /= len;
}
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
}
else
{
//due to the first conditional (celldp >0), we know w're in the cell "opposite" the normal, and so
//we can only collide with the cell edge
obj.reportCollisionVsWorld(x * oH, 0, oH, 0, t);
return Phaser.Physics.Circle.COL_AXIS;
}
}
else
{
//colliding diagonally; we know, due to the initial (celldp >0) test which has failed
//if we've reached this point, that we're in a diagonal neighbor on the non-normal side, so
//we could only be colliding with the cell vertex, if at all.
//get diag vertex position
var vx = t.pos.x + (oH * t.xw);
var vy = t.pos.y + (oV * t.yw);
var dx = obj.pos.x - vx;//calc vert->circle vector
var dy = obj.pos.y - vy;
var len = Math.sqrt(dx * dx + dy * dy);
var pen = obj.radius - len;
if (0 < pen)
{
//vertex is in the circle; project outward
if (len == 0)
{
//project out by 45deg
dx = oH / Math.SQRT2;
dy = oV / Math.SQRT2;
}
else
{
dx /= len;
dy /= len;
}
obj.reportCollisionVsWorld(dx * pen, dy * pen, dx, dy, t);
return Phaser.Physics.Circle.COL_OTHER;
}
}
return Phaser.Physics.Circle.COL_NONE;
}
}
}