/// /// /// /// /// /** * 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; } } }