@awayfl/awayfl-player
Version:
Flash Player emulator for executing SWF files (published for FP versions 6 and up) in javascript
202 lines (173 loc) • 6.19 kB
text/typescript
/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
import { b2Vec2, b2XForm } from "../../Common/Math";
import { b2Settings } from "../../Common/b2Settings";
import { b2AABB } from "../b2AABB";
import { b2Segment } from "../b2Segment";
import { b2Shape } from "./b2Shape";
import { b2StaticEdgeChain } from "./b2StaticEdgeChain";
import { b2StaticEdgeChainDef } from "./b2StaticEdgeChainDef";
export class b2StaticEdgeShape extends b2Shape
{
/// @see b2Shape::TestSegment
public TestSegment( transform:b2XForm,
lambda:number[], // float pointer
normal:b2Vec2, // pointer
segment:b2Segment,
maxLambda:number) :boolean
{
// This is mostly copied from b2Segment.TestSegment(), since
// b2StaticEdgeShapes are much like b2Segments.
var k_slop:number = 100.0 * Number.MIN_VALUE;
var rX:number = segment.p2.x - segment.p1.x;
var rY:number = segment.p2.y - segment.p1.y;
var nX:number = this.m_v2.y - this.m_v1.y;
var nY:number = this.m_v1.x - this.m_v2.x;
var denom:number = -(rX*nX + rY*nY);
if (denom > k_slop) {
var bX:number = segment.p1.x - this.m_v1.x;
var bY:number = segment.p1.y - this.m_v1.y;
var a:number = (bX*nX + bY*nY);
if (0.0 <= a && a <= maxLambda * denom) {
var mu2:number = -rX * bY + rY * bX;
if (-k_slop * denom <= mu2 && mu2 <= denom * (1.0 + k_slop)) {
a /= denom;
var nLen:number = Math.sqrt(nX*nX + nY*nY);
nX /= nLen;
nY /= nLen;
lambda[0] = a;
normal.Set(nX, nY);
return true;
}
}
}
return false;
}
/// @see b2Shape::ComputeAABB
public ComputeAABB(aabb:b2AABB, transform:b2XForm) : void{
if (this.m_v1.x < this.m_v2.x) {
aabb.lowerBound.x = this.m_v1.x;
aabb.upperBound.x = this.m_v2.x;
} else {
aabb.lowerBound.x = this.m_v2.x;
aabb.upperBound.x = this.m_v1.x;
}
if (this.m_v1.y < this.m_v2.y) {
aabb.lowerBound.y = this.m_v1.y;
aabb.upperBound.y = this.m_v2.y;
} else {
aabb.lowerBound.y = this.m_v2.y;
aabb.upperBound.y = this.m_v1.y;
}
}
/// @see b2Shape::ComputeSweptAABB
public ComputeSweptAABB( aabb:b2AABB,
transform1:b2XForm,
transform2:b2XForm) : void
{
return this.ComputeAABB(aabb, transform1);
}
public GetVertex1() : b2Vec2{
return this.m_v1;
}
public GetVertex2() : b2Vec2{
return this.m_v2;
}
public GetLength() :number{
return this.m_length;
}
public GetNormalVector() : b2Vec2{
return this.m_normal;
}
public GetDirectionVector() : b2Vec2{
return this.m_direction;
}
public GetParentChain() : b2StaticEdgeChain{
return this.m_chain;
}
public GetFirstVertex(xf:b2XForm) : b2Vec2{
return this.m_coreV1;
}
public Support(xf:b2XForm, dX:number, dY:number) : b2Vec2{
return (this.m_coreV1.x*dX + this.m_coreV1.y*dY) > (this.m_coreV2.x*dX + this.m_coreV2.y*dY) ? this.m_coreV1 : this.m_coreV2;
}
//--------------- Internals Below -------------------
constructor(v1: b2Vec2, v2: b2Vec2, edgeDef:b2StaticEdgeChainDef){
super(edgeDef);
this.m_type = b2Shape.e_staticEdgeShape;
this.m_v1 = v1;
this.m_v2 = v2;
this.m_direction = this.m_v2.Copy();
this.m_direction.Subtract(this.m_v1);
this.m_length = this.m_direction.Normalize();
this.m_normal = new b2Vec2(this.m_direction.y, -this.m_direction.x);
this.m_coreV1 = this.m_normal.Copy();
this.m_coreV1.Subtract(this.m_direction);
this.m_coreV1.Multiply(-b2Settings.b2_toiSlop);
this.m_coreV1.Add(this.m_v1);
this.m_coreV2 = this.m_normal.Copy();
this.m_coreV2.Add(this.m_direction);
this.m_coreV2.Multiply(-b2Settings.b2_toiSlop);
this.m_coreV2.Add(this.m_v2);
this.m_cornerDir1 = this.m_normal;
this.m_cornerDir2 = this.m_normal.Copy();
this.m_cornerDir2.Multiply(-1);
}
public SetPrevEdge(edge: b2StaticEdgeShape, core: b2Vec2, cornerDir: b2Vec2): void {
this.m_prevEdge = edge;
this.m_coreV1 = core;
this.m_cornerDir1 = cornerDir;
}
public SetNextEdge(edge: b2StaticEdgeShape, core: b2Vec2, cornerDir: b2Vec2): void {
this.m_nextEdge = edge;
this.m_coreV2 = core;
this.m_cornerDir2 = cornerDir;
}
// Update the sweep radius (maximum radius) as measured from
// a local center point.
public UpdateSweepRadius(center:b2Vec2) : void{
var dX:number = this.m_v1.x - center.x;
var dY:number = this.m_v1.y - center.y;
var d1:number = dX*dX + dY*dY;
dX = this.m_v2.x - center.x;
dY = this.m_v2.y - center.y;
var d2:number = dX*dX + dY*dY;
dX = Math.sqrt(d1 > d2 ? d1 : d2); // length
this.m_sweepRadius = dX;
}
// Local positions of vertices in parent body
public m_v1:b2Vec2;
public m_v2:b2Vec2;
// "Core" vertices with TOI slop for b2Distance functions:
public m_coreV1:b2Vec2;
public m_coreV2:b2Vec2;
// Linear distance from v1 to v2:
public m_length: number;
// Perpendicular unit vector point, pointing from the solid side to the empty side:
public m_normal:b2Vec2;
// Parallel unit vector, pointing from v1 to v2:
public m_direction:b2Vec2;
// Unit vector halfway between m_direction and m_prevEdge.m_direction:
public m_cornerDir1:b2Vec2;
// Unit vector halfway between m_direction and m_nextEdge.m_direction:
public m_cornerDir2:b2Vec2;
// Reference to parent chain and adjacent siblings:
public m_chain:b2StaticEdgeChain;
public m_nextEdge: b2StaticEdgeShape;
public m_prevEdge: b2StaticEdgeShape;
}