@awayfl/awayfl-player
Version:
Flash Player emulator for executing SWF files (published for FP versions 6 and up) in javascript
175 lines (170 loc) • 8.45 kB
JavaScript
/*
* 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 { __extends } from "tslib";
import { b2Vec2 } from "../../Common/Math";
import { b2Settings } from "../../Common/b2Settings";
import { b2PolygonShape } from "./b2PolygonShape";
import { b2Shape } from "./b2Shape";
///A polygon with a circle subtracted from it.
///It works exactly the same as b2PolyShape, except the edge from vertex 0 to vertex 1 is a concave arc,
///with radius given by the radius property. The diameter should be longer than the distance between the
///vertices, and the rest of the polygonal shape should be large enough to enclose the resulting curve (this is not checked).
var b2ConcaveArcShape = /** @class */ (function (_super) {
__extends(b2ConcaveArcShape, _super);
//--------------- Internals Below -------------------
function b2ConcaveArcShape(def) {
var _this = _super.call(this, def) || this;
var arcDef = def;
_this.m_radius = arcDef.radius;
_this.m_radius2 = _this.m_radius * _this.m_radius;
var p1 = _this.m_vertices[0];
var p2 = _this.m_vertices[1];
//Find the point at m_radius from p1 and p2;
var dx = p1.x - p2.x;
var dy = p1.y - p2.y;
var d2 = dx * dx + dy * dy;
var d = Math.sqrt(d2);
if (d2 / 4 > _this.m_radius2) {
//Increase radius to fit the edge it is replacing
_this.m_radius2 = d2 / 4;
_this.m_radius = d / 2;
}
var dot = Math.sqrt(_this.m_radius2 - d2 * .25); //The perp distance from p1p2 to m_arcCenter
_this.m_arcCenter = new b2Vec2((p1.x + p2.x) / 2 + dot * _this.m_normals[0].x, (p1.y + p2.y) / 2 + dot * _this.m_normals[0].y);
_this.m_dot = dot / _this.m_radius;
_this.m_norm = d / 2 / _this.m_radius;
//Adjust core vertices so that the core curved edge is of radius m_radius+b2Settings.b2_toiSlop, from core vertex 0 to core vertex 1, and with the same center
var coreRadius2 = (_this.m_radius + b2Settings.b2_toiSlop) * (_this.m_radius + b2Settings.b2_toiSlop);
var nx, ny;
//Vertex 0
nx = _this.m_normals[_this.m_vertexCount - 1].x;
ny = _this.m_normals[_this.m_vertexCount - 1].y;
dx = _this.m_coreVertices[0].x - _this.m_arcCenter.x;
dy = _this.m_coreVertices[0].y - _this.m_arcCenter.y;
d = dx * nx + dy * ny;
d2 = Math.sqrt(coreRadius2 - d * d);
_this.m_coreVertices[0].x = _this.m_arcCenter.x + d * nx + d2 * ny;
_this.m_coreVertices[0].y = _this.m_arcCenter.y + d * ny - d2 * nx;
//Vertex 1
nx = _this.m_normals[1].x;
ny = _this.m_normals[1].y;
dx = _this.m_coreVertices[1].x - _this.m_arcCenter.x;
dy = _this.m_coreVertices[1].y - _this.m_arcCenter.y;
d = dx * nx + dy * ny;
d2 = Math.sqrt(coreRadius2 - d * d);
_this.m_coreVertices[1].x = _this.m_arcCenter.x + d * nx - d2 * ny;
_this.m_coreVertices[1].y = _this.m_arcCenter.y + d * ny + d2 * nx;
_this.m_type = b2Shape.e_concaveArcShape;
return _this;
}
/// @see b2Shape::TestPoint
b2ConcaveArcShape.prototype.TestPoint = function (xf, p) {
//b2Vec2 pLocal = b2MulT(xf.R, p - xf.position);
var tMat = xf.R;
var tX = p.x - xf.position.x;
var tY = p.y - xf.position.y;
var pLocalX = (tX * tMat.col1.x + tY * tMat.col1.y);
var pLocalY = (tX * tMat.col2.x + tY * tMat.col2.y);
for (var i /** uint */ = 0; i < this.m_vertexCount; ++i) {
//float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]);
var tVec = this.m_vertices[i];
tX = pLocalX - tVec.x;
tY = pLocalY - tVec.y;
var dot = (tVec.x * tX + tVec.y * tY);
if (dot > 0.0) {
return false;
}
}
tX = pLocalX - this.m_arcCenter.x;
tY = pLocalY - this.m_arcCenter.y;
return (tX * tX + tY * tY) > this.m_radius2;
};
/// @see b2Shape::TestSegment
b2ConcaveArcShape.prototype.TestSegment = function (xf, lambda, // float ptr
normal, // ptr
segment, maxLambda) {
b2Settings.b2Assert(false);
return false;
};
/// @see b2Shape::ComputeMass
b2ConcaveArcShape.prototype.ComputeMass = function (massData) {
/*var polyMass:b2MassData = new b2MassData();
var triMass:b2MassData = new b2MassData();
var segMass:b2MassData = new b2MassData();
super.ComputeMass(polyMass);
if(m_dot > Number.MIN_VALUE)
TriangleMass(triMass, m_vertices[0], m_arcCenter, m_vertices[1], m_density);
SegmentMass(segMass, m_arcCenter, m_radius, m_normals[0].Negative(), m_norm*m_radius*2, -m_density);
//massData=polyMass+triMass+segMass
massData.Set(b2MassData.Add(polyMass,triMass,segMass));*/
_super.prototype.ComputeMass.call(this, massData);
};
//Calculate the mass of a segment of a circle
//arcCenter, radius defines the circle
//norm defines the reverse direction of the segment
//d is the distance between the two vertices on the perimeter
//See the code for the relationship between d and theta, the angle of the segment.
b2ConcaveArcShape.SegmentMass = function (massData, arcCenter, radius, norm, d, density) {
//var theta:number = Math.acos(dot / radius) * 2;
var theta = Math.asin(d / radius / 2) * 2;
massData.mass = 0.5 * radius * radius * theta * density;
var v = 2 / 3 * d / theta;
if (theta < Number.MIN_VALUE)
v = 2 / 3 * radius;
massData.center = new b2Vec2(arcCenter.x - norm.x * v, arcCenter.y - norm.y * v);
massData.I = 0.5 * massData.mass * radius * radius - massData.mass * v * v;
};
b2ConcaveArcShape.TriangleMass = function (massData, p1, p2, p3, density) {
var k_inv3 = 1.0 / 3.0;
//b2Vec2 e1 = p2 - p1;
var e1X = p2.x - p1.x;
var e1Y = p2.y - p1.y;
//b2Vec2 e2 = p3 - p1;
var e2X = p3.x - p1.x;
var e2Y = p3.y - p1.y;
//float32 D = b2Cross(e1, e2);
var D = e1X * e2Y - e1Y * e2X;
//float32 triangleArea = 0.5f * D;
var triangleArea = 0.5 * D;
//area += triangleArea;
massData.mass = triangleArea * density;
// Area weighted centroid
//center += triangleArea * k_inv3 * (p1 + p2 + p3);
//centerX += triangleArea * k_inv3 * (p1X + p2.x + p3.x);
//centerY += triangleArea * k_inv3 * (p1Y + p2.y + p3.y);
massData.center.x = k_inv3 * (p1.x + p2.x + p3.x);
massData.center.y = k_inv3 * (p1.y + p2.y + p3.y);
//float32 px = p1.x, py = p1.y;
var px = p1.x;
var py = p1.y;
//float32 ex1 = e1.x, ey1 = e1.y;
var ex1 = e1X;
var ey1 = e1Y;
//float32 ex2 = e2.x, ey2 = e2.y;
var ex2 = e2X;
var ey2 = e2Y;
//float32 intx2 = k_inv3 * (0.25f * (ex1*ex1 + ex2*ex1 + ex2*ex2) + (px*ex1 + px*ex2)) + 0.5f*px*px;
var intx2 = k_inv3 * (0.25 * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5 * px * px;
//float32 inty2 = k_inv3 * (0.25f * (ey1*ey1 + ey2*ey1 + ey2*ey2) + (py*ey1 + py*ey2)) + 0.5f*py*py;
var inty2 = k_inv3 * (0.25 * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5 * py * py;
//I += D * (intx2 + inty2);
massData.I = D * (intx2 + inty2) * density;
};
return b2ConcaveArcShape;
}(b2PolygonShape));
export { b2ConcaveArcShape };