/* * 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. */ package Box2D.Dynamics{ import Box2D.Common.Math.*; import Box2D.Common.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Dynamics.*; import Box2D.Dynamics.Contacts.*; import Box2D.Dynamics.Joints.*; import Box2D.Common.b2internal; use namespace b2internal; /** * 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. */ public class b2Fixture { /** * Get the type of the child shape. You can use this to down cast to the concrete shape. * @return the shape type. */ public function GetType():int { return 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 function GetShape():b2Shape { return m_shape; } /** * Set if this fixture is a sensor. */ public function SetSensor(sensor:Boolean):void { if ( m_isSensor == sensor) return; m_isSensor = sensor; if (m_body == null) return; var edge:b2ContactEdge = m_body.GetContactList(); while (edge) { var contact:b2Contact = edge.contact; var fixtureA:b2Fixture = contact.GetFixtureA(); var 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 function IsSensor():Boolean { return 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 function SetFilterData(filter:b2FilterData):void { m_filter = filter.Copy(); if (m_body) return; var edge:b2ContactEdge = m_body.GetContactList(); while (edge) { var contact:b2Contact = edge.contact; var fixtureA:b2Fixture = contact.GetFixtureA(); var fixtureB:b2Fixture = contact.GetFixtureB(); if (fixtureA == this || fixtureB == this) contact.FlagForFiltering(); edge = edge.next; } } /** * Get the contact filtering data. */ public function GetFilterData(): b2FilterData { return m_filter.Copy(); } /** * Get the parent body of this fixture. This is NULL if the fixture is not attached. * @return the parent body. */ public function GetBody():b2Body { return m_body; } /** * Get the next fixture in the parent body's fixture list. * @return the next shape. */ public function GetNext():b2Fixture { return m_next; } /** * Get the user data that was assigned in the fixture definition. Use this to * store your application specific data. */ public function GetUserData():* { return m_userData; } /** * Set the user data. Use this to store your application specific data. */ public function SetUserData(data:*):void { 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 function TestPoint(p:b2Vec2):Boolean { return m_shape.TestPoint(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 function RayCast(output:b2RayCastOutput, input:b2RayCastInput):Boolean { return m_shape.RayCast(output, input, 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 function GetMassData(massData:b2MassData = null):b2MassData { if ( massData == null ) { massData = new b2MassData(); } m_shape.ComputeMass(massData, 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 function SetDensity(density:number):void { //b2Settings.b2Assert(b2Math.b2IsValid(density) && density >= 0.0); m_density = density; } /** * Get the density of this fixture. * @return density */ public function GetDensity():number { return m_density; } /** * Get the coefficient of friction. */ public function GetFriction():number { return m_friction; } /** * Set the coefficient of friction. */ public function SetFriction(friction:number):void { m_friction = friction; } /** * Get the coefficient of restitution. */ public function GetRestitution():number { return m_restitution; } /** * Get the coefficient of restitution. */ public function SetRestitution(restitution:number):void { 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 function GetAABB():b2AABB { return m_aabb; } /** * @private */ public function b2Fixture() { m_aabb = new b2AABB(); m_userData = null; m_body = null; m_next = null; //m_proxyId = b2BroadPhase.e_nullProxy; m_shape = null; m_density = 0.0; m_friction = 0.0; 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 function Create( body:b2Body, xf:b2Transform, def:b2FixtureDef):void { m_userData = def.userData; m_friction = def.friction; m_restitution = def.restitution; m_body = body; m_next = null; m_filter = def.filter.Copy(); m_isSensor = def.isSensor; m_shape = def.shape.Copy(); 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 function Destroy():void { // The proxy must be destroyed before calling this. //b2Assert(m_proxyId == b2BroadPhase::e_nullProxy); // Free the child shape m_shape = null; } /** * This supports body activation/deactivation. */ public function CreateProxy(broadPhase:IBroadPhase, xf:b2Transform):void { //b2Assert(m_proxyId == b2BroadPhase::e_nullProxy); // Create proxy in the broad-phase. m_shape.ComputeAABB(m_aabb, xf); m_proxy = broadPhase.CreateProxy(m_aabb, this); } /** * This supports body activation/deactivation. */ public function DestroyProxy(broadPhase:IBroadPhase):void { if (m_proxy == null) { return; } // Destroy proxy in the broad-phase. broadPhase.DestroyProxy(m_proxy); m_proxy = null; } public function Synchronize(broadPhase:IBroadPhase, transform1:b2Transform, transform2:b2Transform):void { if (!m_proxy) return; // Compute an AABB that ocvers the swept shape (may miss some rotation effect) var aabb1:b2AABB = new b2AABB(); var aabb2:b2AABB = new b2AABB(); m_shape.ComputeAABB(aabb1, transform1); m_shape.ComputeAABB(aabb2, transform2); m_aabb.Combine(aabb1, aabb2); var displacement:b2Vec2 = b2Math.SubtractVV(transform2.position, transform1.position); broadPhase.MoveProxy(m_proxy, m_aabb, displacement); } private var m_massData:b2MassData; public var m_aabb:b2AABB; public var m_density:number; public var m_next:b2Fixture; public var m_body:b2Body; public var m_shape:b2Shape; public var m_friction:number; public var m_restitution:number; public var m_proxy:*; public var m_filter:b2FilterData = new b2FilterData(); public var m_isSensor:Boolean; public var m_userData:*; }; }