/// Creates a fixture and attach it to this body. Use this function if you need /// to set some fixture parameters, like friction. Otherwise you can create the /// fixture directly from a shape. /// If the Density is non-zero, this function automatically updates the mass of the body. /// Contacts are not created until the next time step. /// @param def the fixture definition. /// @warning This function is locked during callbacks. public Fixture CreateFixture(FixtureDef def){ Utilities.Assert(m_world.IsLocked() == false); if (m_world.IsLocked() == true) { return null; } Fixture fixture = new Fixture(); fixture.Create(this, def); if (m_flags.HasFlag(BodyFlags.e_activeFlag)) { BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase; fixture.CreateProxies(broadPhase, m_xf); } m_fixtureList.Add(fixture); fixture.m_body = this; // Adjust mass properties if needed. if (fixture.m_Density > 0.0f) { ResetMassData(); } // Let the world know we have a new fixture. This will cause new contacts // to be created at the beginning of the next time step. m_world.m_flags |= WorldFlags.e_newFixture; return fixture; }
public override float ReportFixture(Fixture fixture, Vec2 point, Vec2 normal, float fraction) { m_fixture = fixture; m_point = point; m_normal = normal; return fraction; }
/// Return true if contact calculations should be performed between these two shapes. /// @warning for performance reasons this is only called when the AABBs begin to overlap. public virtual bool ShouldCollide(Fixture fixtureA, Fixture fixtureB){ Filter filterA = fixtureA.Filter; Filter filterB = fixtureB.Filter; if (filterA.GroupIndex == filterB.GroupIndex && filterA.GroupIndex != 0) { return filterA.GroupIndex > 0; } bool collide = (filterA.MaskBits & filterB.CategoryBits) != 0 && (filterA.CategoryBits & filterB.MaskBits) != 0; return collide; }
public override bool ReportFixture(Fixture fixture) { throw new NotImplementedException(); //Body body = fixture.GetBody(); //if (body.GetType() == BodyType._dynamicBody) //{ // bool inside = fixture.TestPoint(m_point); // if (inside) // { // m_fixture = fixture; // // We are done, terminate the query. // return false; // } //} //// Continue the query. //return true; }
/// Called for each fixture found in the query AABB. /// @return false to terminate the query. public override bool ReportFixture(Fixture fixture) { if (m_count == e_maxCount) { return false; } Body body = fixture.GetBody(); Shape shape = fixture.GetShape(); bool overlap = Collision.TestOverlap(shape, 0, m_circle, 0, body.GetTransform(), m_transform); if (overlap) { DrawFixture(fixture); ++m_count; } return true; }
public override float ReportFixture(Fixture fixture, Vec2 point, Vec2 normal, float fraction) { Body body = fixture.GetBody(); if (body.UserData != null) { int index = (int)body.UserData; if (index == 0) { // By returning -1, we instruct the calling code to ignore this fixture // and continue the ray-cast to the next fixture. return -1.0f; } } m_hit = true; m_point = point; m_normal = normal; // At this point we have a hit, so we know the ray is obstructed. // By returning 0, we instruct the calling code to terminate the ray-cast. return 0.0f; }
public void DrawFixture(Fixture fixture) { Color color = Color.FromArgb(245, 245, 150); Transform xf = fixture.GetBody().GetTransform(); switch (fixture.GetShapeType()) { case ShapeType.Circle: { CircleShape circle = (CircleShape)fixture.GetShape(); Vec2 center = Utilities.Mul(xf, circle.m_p); float radius = circle.m_radius; m_debugDraw.DrawCircle(center, radius, color); } break; case ShapeType.Polygon: { PolygonShape poly = (PolygonShape)fixture.GetShape(); int vertexCount = poly.m_count; Utilities.Assert(vertexCount <= Settings._maxPolygonVertices); Vec2[] vertices = new Vec2[Settings._maxPolygonVertices]; for (int i = 0; i < vertexCount; ++i) { vertices[i] = Utilities.Mul(xf, poly.m_vertices[i]); } m_debugDraw.DrawPolygon(vertices, vertexCount, color); } break; default: break; } }
public override float ReportFixture(Fixture fixture, Vec2 point, Vec2 normal, float fraction) { Body body = fixture.GetBody(); if (body.UserData != null) { int index = (int)body.UserData; if (index == 0) { // By returning -1, we instruct the calling code to ignore this fixture and // continue the ray-cast to the next fixture. return -1.0f; } } m_hit = true; m_point = point; m_normal = normal; // By returning the current fraction, we instruct the calling code to clip the ray and // continue the ray-cast to the next fixture. WARNING: do not assume that fixtures // are reported in order. However, by clipping, we can always get the closest fixture. return fraction; }
/// Destroy a fixture. This removes the fixture from the broad-phase and /// destroys all contacts associated with this fixture. This will /// automatically adjust the mass of the body if the body is dynamic and the /// fixture has positive Density. /// All fixtures attached to a body are implicitly destroyed when the body is destroyed. /// @param fixture the fixture to be removed. /// @warning This function is locked during callbacks. public void DestroyFixture(Fixture fixture){ throw new NotImplementedException(); //Utilities.Assert(m_world.IsLocked() == false); //if (m_world.IsLocked() == true) //{ // return; //} //Utilities.Assert(fixture.m_body == this); //// Remove the fixture from this body's singly linked list. //Utilities.Assert(m_fixtureCount > 0); //Fixture** node = &m_fixtureList; //bool found = false; //while (*node != null) //{ // if (*node == fixture) // { // *node = fixture.m_next; // found = true; // break; // } // node = &(*node).m_next; //} //// You tried to remove a shape that is not attached to this body. //Utilities.Assert(found); //// Destroy any contacts associated with the fixture. //ContactEdge* edge = m_contactList; //while (edge) //{ // Contact* c = edge.contact; // edge = edge.next; // Fixture fixtureA = c.FixtureA; // Fixture fixtureB = c.FixtureB; // if (fixture == fixtureA || fixture == fixtureB) // { // // This destroys the contact and removes it from // // this body's contact list. // m_world.m_contactManager.Destroy(c); // } //} //BlockAllocator* allocator = &m_world.m_blockAllocator; //if (m_flags & e_activeFlag) //{ // BroadPhase* broadPhase = &m_world.m_contactManager.m_broadPhase; // fixture.DestroyProxies(broadPhase); //} //fixture.Destroy(allocator); //fixture.m_body = null; //fixture.m_next = null; //fixture.~Fixture(); //allocator.Free(fixture, sizeof(Fixture)); //--m_fixtureCount; //// Reset the mass data. //ResetMassData(); }
public override float ReportFixture(Fixture fixture, Vec2 point, Vec2 normal, float fraction) { Body body = fixture.GetBody(); if (body.UserData != null) { int index = (int)body.UserData; if (index == 0) { // By returning -1, we instruct the calling code to ignore this fixture // and continue the ray-cast to the next fixture. return -1.0f; } } Utilities.Assert(m_count < e_maxCount); m_points[m_count] = point; m_normals[m_count] = normal; ++m_count; if (m_count == e_maxCount) { // At this point the buffer is full. // By returning 0, we instruct the calling code to terminate the ray-cast. return 0.0f; } // By returning 1, we instruct the caller to continue without clipping the ray. return 1.0f; }
public static Contact Create(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB){ return new PolygonContact(fixtureA, fixtureB); }
public PolygonContact(Fixture fixtureA, Fixture fixtureB): base(fixtureA, 0, fixtureB, 0) { Utilities.Assert(m_fixtureA.GetShapeType() == ShapeType.Polygon); Utilities.Assert(m_fixtureB.GetShapeType() == ShapeType.Polygon); }
// We need separation create/destroy functions from the constructor/destructor because // the destructor cannot access the allocator (no destructor arguments allowed by C++). internal void Create(Body body, FixtureDef def){ m_userData = def.UserData; m_friction = def.friction; m_restitution = def.restitution; m_body = body; m_next = null; m_filter = def.Filter; m_isSensor = def.IsSensor; m_shape = def.shape.Clone(); // Reserve proxy space int childCount = m_shape.GetChildCount(); m_proxies = new List<FixtureProxy>(); m_Density = def.Density; }
/// Called for each fixture found in the query AABB. /// @return false to terminate the query. public abstract bool ReportFixture(Fixture fixture); //fixture was pointer
public EdgeAndCircleContact(Fixture fixtureA, Fixture fixtureB) : base(fixtureA, 0, fixtureB, 0) { Utilities.Assert(m_fixtureA.GetShapeType() == ShapeType.Edge); Utilities.Assert(m_fixtureB.GetShapeType() == ShapeType.Circle); }
internal Fixture(){ m_userData = null; m_body = null; m_next = null; m_proxies = new List<FixtureProxy>(); m_shape = null; m_Density = 0.0f; }
public override void SayGoodbye(Fixture fixture) { }
private void DrawShape(Fixture fixture, Transform xf, Color color){ switch (fixture.GetShapeType()) { case ShapeType.Circle: { CircleShape circle = (CircleShape)fixture.GetShape(); Vec2 center = Utilities.Mul(xf, circle.m_p); float radius = circle.m_radius; Vec2 axis = Utilities.Mul(xf.q, new Vec2(1.0f, 0.0f)); m_debugDraw.DrawSolidCircle(center, radius, axis, color); } break; case ShapeType.Edge: { EdgeShape edge = (EdgeShape)fixture.GetShape(); Vec2 v1 = Utilities.Mul(xf, edge.m_vertex1); Vec2 v2 = Utilities.Mul(xf, edge.m_vertex2); m_debugDraw.DrawSegment(v1, v2, color); } break; case ShapeType.Chain: { ChainShape chain = (ChainShape)fixture.GetShape(); int count = chain.m_count; List<Vec2> vertices = chain.m_vertices; Vec2 v1 = Utilities.Mul(xf, vertices[0]); for (int i = 1; i < count; ++i) { Vec2 v2 = Utilities.Mul(xf, vertices[i]); m_debugDraw.DrawSegment(v1, v2, color); m_debugDraw.DrawCircle(v1, 0.05f, color); v1 = v2; } } break; case ShapeType.Polygon: { PolygonShape poly = (PolygonShape)fixture.GetShape(); int vertexCount = poly.m_count; Utilities.Assert(vertexCount <= Settings._maxPolygonVertices); Vec2[] vertices = new Vec2[Settings._maxPolygonVertices]; for (int i = 0; i < vertexCount; ++i) { vertices[i] = Utilities.Mul(xf, poly.m_vertices[i]); } m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color); } break; default: break; } }
public ChainAndCircleContact(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB) : base(fixtureA, indexA, fixtureB, indexB) { Utilities.Assert(m_fixtureA.GetShapeType() == ShapeType.Chain); Utilities.Assert(m_fixtureB.GetShapeType() == ShapeType.Circle); }
protected Contact(Fixture fA, int indexA, Fixture fB, int indexB) { m_flags = ContactFlags.e_enabledFlag; m_fixtureA = fA; m_fixtureB = fB; m_indexA = indexA; m_indexB = indexB; m_manifold = new Manifold(); m_manifold.points.Clear(); m_nodeA.contact = null; m_nodeA.other = null; m_nodeB.contact = null; m_nodeB.other = null; m_toiCount = 0; m_friction = MixFriction(m_fixtureA.m_friction, m_fixtureB.m_friction); m_restitution = MixRestitution(m_fixtureA.m_restitution, m_fixtureB.m_restitution); m_tangentSpeed = 0.0f; }
protected Contact(){ m_fixtureA = null; m_fixtureB = null; }
internal static Contact Create(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB){ if (s_initialized == false) { InitializeRegisters(); s_initialized = true; } ShapeType type1 = fixtureA.GetShapeType(); ShapeType type2 = fixtureB.GetShapeType(); Utilities.Assert(0 <= type1 && type1 < ShapeType.Count); Utilities.Assert(0 <= type2 && type2 < ShapeType.Count); ContactCreateFcn createFcn = s_registers[(int)type1, (int)type2].createFcn; if (createFcn != null) { if (s_registers[(int)type1, (int)type2].primary) { return createFcn(fixtureA, indexA, fixtureB, indexB); } else { return createFcn(fixtureB, indexB, fixtureA, indexA); } } else { return null; } }
/// Called when any fixture is about to be destroyed due /// to the destruction of its parent body. public abstract void SayGoodbye(Fixture fixture);
public static Contact Create(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB){ return new ChainAndCircleContact(fixtureA, indexA, fixtureB, indexB); }
/// Called for each fixture found in the query. You control how the ray cast /// proceeds by returning a float: /// return -1: ignore this fixture and continue /// return 0: terminate the ray cast /// return fraction: clip the ray to this point /// return 1: don't clip the ray and continue /// @param fixture the fixture hit by the ray /// @param point the point of initial intersection /// @param normal the normal vector at the point of intersection /// @return -1 to filter, 0 to terminate, fraction to clip the ray for /// closest hit, 1 to continue public abstract float ReportFixture(Fixture fixture, Vec2 point, Vec2 normal, float fraction);