mirror of
https://github.com/photonstorm/phaser
synced 2024-11-27 15:12:18 +00:00
204 lines
No EOL
5.2 KiB
TypeScript
204 lines
No EOL
5.2 KiB
TypeScript
/// <reference path="../../math/Vec2.ts" />
|
|
/// <reference path="../../math/Vec2Utils.ts" />
|
|
/// <reference path="../AdvancedPhysics.ts" />
|
|
/// <reference path="../Body.ts" />
|
|
/// <reference path="Shape.ts" />
|
|
|
|
/**
|
|
* Phaser - Advanced Physics - Shapes - Segment
|
|
*
|
|
* Based on the work Ju Hyung Lee started in JS PhyRus.
|
|
*/
|
|
|
|
module Phaser.Physics.Shapes {
|
|
|
|
export class Segment extends Phaser.Physics.Shape implements IShape {
|
|
|
|
constructor(a, b, radius: number) {
|
|
|
|
super(AdvancedPhysics.SHAPE_TYPE_SEGMENT);
|
|
|
|
this.a = a.duplicate();
|
|
this.b = b.duplicate();
|
|
this.radius = radius;
|
|
|
|
this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(b, a));
|
|
this.normal.normalize();
|
|
|
|
this.ta = new Phaser.Vec2;
|
|
this.tb = new Phaser.Vec2;
|
|
this.tn = new Phaser.Vec2;
|
|
|
|
this.finishVerts();
|
|
|
|
}
|
|
|
|
public a: Phaser.Vec2;
|
|
public b: Phaser.Vec2;
|
|
public radius: number;
|
|
|
|
public normal: Phaser.Vec2;
|
|
public ta: Phaser.Vec2;
|
|
public tb: Phaser.Vec2;
|
|
public tn: Phaser.Vec2;
|
|
|
|
public finishVerts() {
|
|
|
|
this.normal = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.b, this.a));
|
|
this.normal.normalize();
|
|
|
|
this.radius = Math.abs(this.radius);
|
|
|
|
}
|
|
|
|
public duplicate() {
|
|
return new Phaser.Physics.Shapes.Segment(this.a, this.b, this.radius);
|
|
}
|
|
|
|
public recenter(c) {
|
|
this.a.subtract(c);
|
|
this.b.subtract(c);
|
|
}
|
|
|
|
public transform(xf:Transform) {
|
|
|
|
Phaser.TransformUtils.transform(xf, this.a, this.a);
|
|
Phaser.TransformUtils.transform(xf, this.b, this.b);
|
|
|
|
//this.a = xf.transform(this.a);
|
|
//this.b = xf.transform(this.b);
|
|
|
|
}
|
|
|
|
public untransform(xf:Transform) {
|
|
|
|
Phaser.TransformUtils.untransform(xf, this.a, this.a);
|
|
Phaser.TransformUtils.untransform(xf, this.b, this.b);
|
|
|
|
//this.a = xf.untransform(this.a);
|
|
//this.b = xf.untransform(this.b);
|
|
|
|
}
|
|
|
|
public area(): number {
|
|
return AdvancedPhysics.areaForSegment(this.a, this.b, this.radius);
|
|
}
|
|
|
|
public centroid(): Phaser.Vec2 {
|
|
return AdvancedPhysics.centroidForSegment(this.a, this.b);
|
|
}
|
|
|
|
public inertia(mass: number): number {
|
|
return AdvancedPhysics.inertiaForSegment(mass, this.a, this.b);
|
|
}
|
|
|
|
public cacheData(xf:Transform) {
|
|
|
|
Phaser.TransformUtils.transform(xf, this.a, this.ta);
|
|
Phaser.TransformUtils.transform(xf, this.b, this.tb);
|
|
|
|
//this.ta = xf.transform(this.a);
|
|
//this.tb = xf.transform(this.b);
|
|
|
|
this.tn = Phaser.Vec2Utils.perp(Phaser.Vec2Utils.subtract(this.tb, this.ta)).normalize();
|
|
|
|
var l;
|
|
var r;
|
|
var t;
|
|
var b;
|
|
|
|
if (this.ta.x < this.tb.x)
|
|
{
|
|
l = this.ta.x;
|
|
r = this.tb.x;
|
|
}
|
|
else
|
|
{
|
|
l = this.tb.x;
|
|
r = this.ta.x;
|
|
}
|
|
|
|
if (this.ta.y < this.tb.y)
|
|
{
|
|
b = this.ta.y;
|
|
t = this.tb.y;
|
|
} else
|
|
{
|
|
b = this.tb.y;
|
|
t = this.ta.y;
|
|
}
|
|
|
|
this.bounds.mins.setTo(l - this.radius, b - this.radius);
|
|
this.bounds.maxs.setTo(r + this.radius, t + this.radius);
|
|
|
|
}
|
|
|
|
public pointQuery(p: Phaser.Vec2): bool {
|
|
|
|
if (!this.bounds.containPoint(p))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var dn = Phaser.Vec2Utils.dot(this.tn, p) - Phaser.Vec2Utils.dot(this.ta, this.tn);
|
|
var dist = Math.abs(dn);
|
|
|
|
if (dist > this.radius)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var dt = Phaser.Vec2Utils.cross(p, this.tn);
|
|
var dta = Phaser.Vec2Utils.cross(this.ta, this.tn);
|
|
var dtb = Phaser.Vec2Utils.cross(this.tb, this.tn);
|
|
|
|
if (dt <= dta)
|
|
{
|
|
if (dt < dta - this.radius)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return Phaser.Vec2Utils.distanceSq(this.ta, p) < (this.radius * this.radius);
|
|
}
|
|
else if (dt > dtb)
|
|
{
|
|
if (dt > dtb + this.radius)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return Phaser.Vec2Utils.distanceSq(this.tb, p) < (this.radius * this.radius);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public findVertexByPoint(p:Phaser.Vec2, minDist: number): number {
|
|
|
|
var dsq = minDist * minDist;
|
|
|
|
if (Phaser.Vec2Utils.distanceSq(this.ta, p) < dsq)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (Phaser.Vec2Utils.distanceSq(this.tb, p) < dsq)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
public distanceOnPlane(n, d) {
|
|
|
|
var a = Phaser.Vec2Utils.dot(n, this.ta) - this.radius;
|
|
var b = Phaser.Vec2Utils.dot(n, this.tb) - this.radius;
|
|
|
|
return Math.min(a, b) - d;
|
|
}
|
|
|
|
}
|
|
|
|
} |