phaser/todo/physics/shapes/Segment.ts
2013-08-02 12:38:56 +01:00

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