@awayfl/awayfl-player
Version:
Flash Player emulator for executing SWF files (published for FP versions 6 and up) in javascript
330 lines (278 loc) • 8.7 kB
text/typescript
import { b2Shape } from '../Collision/Shapes/b2Shape';
import { b2Body } from './b2Body';
import { b2Vec2, b2Transform, b2Math } from '../Common/Math';
import { b2RayCastOutput } from '../Collision/b2RayCastOutput';
import { b2RayCastInput } from '../Collision/b2RayCastInput';
import { b2MassData } from '../Collision/Shapes/b2MassData';
import { b2AABB } from '../Collision/b2AABB';
import { b2FixtureDef } from './b2FixtureDef';
import { b2FilterData } from './b2FilterData';
import { b2ContactEdge, b2Contact } from './Contacts';
import { IBroadPhase } from '../Collision/IBroadPhase';
/**
* A fixture is used to attach a shape to a body for collision detection. A fixture
* inherits its transform from its parent. Fixtures hold additional non-geometric data
* such as friction, collision filters, etc.
* Fixtures are created via b2Body::CreateFixture.
* @warning you cannot reuse fixtures.
*/
export class b2Fixture {
__fast__: boolean = true;
/**
* Get the type of the child shape. You can use this to down cast to the concrete shape.
* @return the shape type.
*/
public GetType(): number /** int */
{
return this.m_shape.GetType();
}
/**
* Get the child shape. You can modify the child shape, however you should not change the
* number of vertices because this will crash some collision caching mechanisms.
*/
public GetShape(): b2Shape {
return this.m_shape;
}
/**
* Set if this fixture is a sensor.
*/
public SetSensor(sensor: boolean): void {
if (this.m_isSensor == sensor)
return;
this.m_isSensor = sensor;
if (this.m_body == null)
return;
let edge: b2ContactEdge = this.m_body.GetContactList();
while (edge) {
const contact: b2Contact = edge.contact;
const fixtureA: b2Fixture = contact.GetFixtureA();
const fixtureB: b2Fixture = contact.GetFixtureB();
if (fixtureA == this || fixtureB == this)
contact.SetSensor(fixtureA.IsSensor() || fixtureB.IsSensor());
edge = edge.next;
}
}
/**
* Is this fixture a sensor (non-solid)?
* @return the true if the shape is a sensor.
*/
public IsSensor(): boolean {
return this.m_isSensor;
}
/**
* Set the contact filtering data. This will not update contacts until the next time
* step when either parent body is active and awake.
*/
public SetFilterData(filter: b2FilterData): void {
this.m_filter = filter.Copy();
if (this.m_body)
return;
let edge: b2ContactEdge = this.m_body.GetContactList();
while (edge) {
const contact: b2Contact = edge.contact;
const fixtureA: b2Fixture = contact.GetFixtureA();
const fixtureB: b2Fixture = contact.GetFixtureB();
if (fixtureA == this || fixtureB == this)
contact.FlagForFiltering();
edge = edge.next;
}
}
/**
* Get the contact filtering data.
*/
public GetFilterData(): b2FilterData {
return this.m_filter.Copy();
}
public GetTrueFilterData(): b2FilterData
{
return this.m_filter;
}
/**
* Get the parent body of this fixture. This is NULL if the fixture is not attached.
* @return the parent body.
*/
public GetBody(): b2Body {
return this.m_body;
}
/**
* Get the next fixture in the parent body's fixture list.
* @return the next shape.
*/
public GetNext(): b2Fixture {
return this.m_next;
}
/**
* Get the user data that was assigned in the fixture definition. Use this to
* store your application specific data.
*/
public GetUserData(): any {
return this.m_userData;
}
/**
* Set the user data. Use this to store your application specific data.
*/
public SetUserData(data: any): void {
this.m_userData = data;
}
/**
* Test a point for containment in this fixture.
* @param xf the shape world transform.
* @param p a point in world coordinates.
*/
public TestPoint(p: b2Vec2): boolean {
return this.m_shape.TestPoint(this.m_body.GetTransform(), p);
}
/**
* Perform a ray cast against this shape.
* @param output the ray-cast results.
* @param input the ray-cast input parameters.
*/
public RayCast(output: b2RayCastOutput, input: b2RayCastInput): boolean {
return this.m_shape.RayCast(output, input, this.m_body.GetTransform());
}
/**
* Get the mass data for this fixture. The mass data is based on the density and
* the shape. The rotational inertia is about the shape's origin. This operation may be expensive
* @param massData - this is a reference to a valid massData, if it is null a new b2MassData is allocated and then returned
* @note if the input is null then you must get the return value.
*/
public GetMassData(massData: b2MassData = null): b2MassData {
if (massData == null) {
massData = new b2MassData();
}
this.m_shape.ComputeMass(massData, this.m_density);
return massData;
}
/**
* Set the density of this fixture. This will _not_ automatically adjust the mass
* of the body. You must call b2Body::ResetMassData to update the body's mass.
* @param density
*/
public SetDensity(density: number): void {
//b2Settings.b2Assert(b2Math.b2IsValid(density) && density >= 0.0);
this.m_density = density;
}
/**
* Get the density of this fixture.
* @return density
*/
public GetDensity(): number {
return this.m_density;
}
/**
* Get the coefficient of friction.
*/
public GetFriction(): number {
return this.m_friction;
}
/**
* Set the coefficient of friction.
*/
public SetFriction(friction: number): void {
this.m_friction = friction;
}
/**
* Get the coefficient of restitution.
*/
public GetRestitution(): number {
return this.m_restitution;
}
/**
* Get the coefficient of restitution.
*/
public SetRestitution(restitution: number): void {
this.m_restitution = restitution;
}
/**
* Get the fixture's AABB. This AABB may be enlarge and/or stale.
* If you need a more accurate AABB, compute it using the shape and
* the body transform.
* @return
*/
public GetAABB(): b2AABB {
return this.m_aabb;
}
/**
* @private
*/
constructor() {
this.m_aabb = new b2AABB();
this.m_userData = null;
this.m_body = null;
this.m_next = null;
//this.m_proxyId = b2BroadPhase.e_nullProxy;
this.m_shape = null;
this.m_density = 0.0;
this.m_friction = 0.0;
this.m_restitution = 0.0;
}
/**
* the destructor cannot access the allocator (no destructor arguments allowed by C++).
* We need separation create/destroy functions from the constructor/destructor because
*/
public Create(body: b2Body, xf: b2Transform, def: b2FixtureDef): void {
this.m_userData = def.userData;
this.m_friction = def.friction;
this.m_restitution = def.restitution;
this.m_body = body;
this.m_next = null;
this.m_filter = def.filter.Copy();
this.m_isSensor = def.isSensor;
this.m_shape = def.shape.Copy();
this.m_density = def.density;
}
/**
* the destructor cannot access the allocator (no destructor arguments allowed by C++).
* We need separation create/destroy functions from the constructor/destructor because
*/
public Destroy(): void {
// The proxy must be destroyed before calling this.
//b2Assert(m_proxyId == b2BroadPhase::e_nullProxy);
// Free the child shape
this.m_shape = null;
}
/**
* This supports body activation/deactivation.
*/
public CreateProxy(broadPhase: IBroadPhase, xf: b2Transform): void {
//b2Assert(m_proxyId == b2BroadPhase::e_nullProxy);
// Create proxy in the broad-phase.
this.m_shape.ComputeAABB(this.m_aabb, xf);
this.m_proxy = broadPhase.CreateProxy(this.m_aabb, this);
}
/**
* This supports body activation/deactivation.
*/
public DestroyProxy(broadPhase: IBroadPhase): void {
if (this.m_proxy == null) {
return;
}
// Destroy proxy in the broad-phase.
broadPhase.DestroyProxy(this.m_proxy);
this.m_proxy = null;
}
public Synchronize(broadPhase: IBroadPhase, transform1: b2Transform, transform2: b2Transform): void {
if (!this.m_proxy)
return;
// Compute an AABB that ocvers the swept shape (may miss some rotation effect)
const aabb1: b2AABB = new b2AABB();
const aabb2: b2AABB = new b2AABB();
this.m_shape.ComputeAABB(aabb1, transform1);
this.m_shape.ComputeAABB(aabb2, transform2);
this.m_aabb.Combine(aabb1, aabb2);
const displacement: b2Vec2 = b2Math.SubtractVV(transform2.position, transform1.position);
broadPhase.MoveProxy(this.m_proxy, this.m_aabb, displacement);
}
private m_massData: b2MassData;
public m_aabb: b2AABB;
public m_density: number;
public m_next: b2Fixture;
public m_body: b2Body;
public m_shape: b2Shape;
public m_friction: number;
public m_restitution: number;
public m_proxy: any;
public m_filter: b2FilterData = new b2FilterData();
public m_isSensor: boolean;
public m_userData: any;
}