Exemple #1
0
        public void Reset(int bodyCapacity, int contactCapacity, int jointCapacity, IContactListener listener)
        {
            _bodyCapacity = bodyCapacity;
	        _contactCapacity = contactCapacity;
	        _jointCapacity	 = jointCapacity;
	        _bodyCount = 0;
	        _jointCount = 0;

	        _listener = listener;

            if (_bodies == null || _bodies.Length < bodyCapacity)
            {
                _bodies = new Body[bodyCapacity];
            }

            if (_contacts == null || _contacts.Length < contactCapacity)
            {
                _contacts = new Contact[contactCapacity * 2];
            }

            if (_joints == null || _joints.Length < jointCapacity)
            {
                _joints = new Joint[jointCapacity * 2];
            }
        }
        public void BeginContact(Contact contact)
        {
            GameObject A = (GameObject)contact.GetFixtureA().GetUserData();
            GameObject B = (GameObject)contact.GetFixtureB().GetUserData();

            Manifold manifold;
            Transform xfA;
            Transform xfB;
            float radiusA;
            float radiusB;

            contact.GetFixtureA().GetBody().GetTransform(out xfA);
            contact.GetFixtureB().GetBody().GetTransform(out xfB);
            radiusA = contact.GetFixtureA().GetShape()._radius;
            radiusB = contact.GetFixtureB().GetShape()._radius;

            contact.GetManifold(out manifold);

            WorldManifold worldManifold = new WorldManifold(ref manifold,ref xfA,radiusA,ref xfB,radiusB);

            Vector2 ptA = worldManifold._points[0];
            Vector2 ptB = worldManifold._points[1];

            //System.Console.Write(" point {0} {1}\n", ptA, ptB);

            ColHdr cHdr;
            cHdr.goID1 = A.getIndexNum();
            cHdr.goID2 = B.getIndexNum();
            cHdr.pos = ptA;

            InputHdr iHdr;
            iHdr.colInfo = cHdr;
            iHdr.input = InputType.Collision;
            iHdr.player = PlayerID.none;
            iHdr.networked = false;

            OutputQueue.pushHeader(iHdr);

            //if (A.CollideAvailable == true && B.CollideAvailable == true)
            //{
            //    if (A.type < B.type)
            //    {
            //        A.Accept(B, ptA);
            //    }
            //    else
            //    {
            //        B.Accept(A, ptA);
            //    }
            //}

            //if (A.type == GameObjType.p1missiles || A.type == GameObjType.p2missiles)
            //{
            //    A.CollideAvailable = false;
            //}

            //if (B.type == GameObjType.p1missiles || B.type == GameObjType.p2missiles)
            //{
            //    B.CollideAvailable = false;
            //}
        }
        internal ContactManager()
        {
            _addPair = AddPair;

            _contactList = null;
            _contactCount = 0;
            ContactFilter = new DefaultContactFilter();
            ContactListener = new DefaultContactListener();
        }
Exemple #4
0
 public void PostSolve(Contact contact, ref ContactImpulse impulse)
 {
     Body[] bodies = new Body[2];
     bodies[0] = contact.GetFixtureA().GetBody();
     bodies[1] = contact.GetFixtureB().GetBody();
     mBodies.Add(bodies);
     if (mBodies.Count > 10000)
     {
         mBodies.Clear();
         Console.WriteLine("Clear contacts.");
     }
 }
        public void BeginContact(Contact contact)
        {
            Fixture fixtureA = contact.GetFixtureA();
            Fixture fixtureB = contact.GetFixtureB();
            var unitA = (Unit) fixtureA.GetBody().GetUserData();
            var unitB = (Unit) fixtureB.GetBody().GetUserData();

            bool shouldContact = GroupManager.Instance.ShouldContact(unitA.Group, unitB.Group);
            if (shouldContact)
            {
                if (fixtureA.IsSensor())
                {
                    var sensorData = (SensorInfo) fixtureA.GetUserData();
                    if (sensorData.Enable && !fixtureB.IsSensor())
                    {
                        if (unitB is Character && sensorData.SensorName == Constants.SURFACE_SENSOR)
                        {

                        }
                        sensorData.Add(unitB);
                    }
                }
                if (fixtureB.IsSensor())
                {
                    var sensorData = (SensorInfo) fixtureB.GetUserData();
                    if (sensorData.Enable && !fixtureA.IsSensor())
                    {
                        sensorData.Add(unitA);
                    }
                }
            }
            else
            {
                if (fixtureA.IsSensor())
                {
                    var sensorData = (SensorInfo)fixtureA.GetUserData();
                    if (sensorData.SensorName == Constants.VISUAL_SENSOR && sensorData.Enable && !fixtureB.IsSensor() && unitB is Character)
                    {
                        sensorData.Add(unitB);
                    }
                }
                if (fixtureB.IsSensor())
                {
                    var sensorData = (SensorInfo)fixtureB.GetUserData();
                    if (sensorData.SensorName == Constants.VISUAL_SENSOR && sensorData.Enable && !fixtureA.IsSensor() && unitA is Character)
                    {
                        sensorData.Add(unitA);
                    }
                }
            }
        }
        /// <summary>
        /// Update the gameworld
        /// </summary>
        /// <param name="gameTime">GameTime</param>
        public virtual void update(GameTime gameTime)
        {
            Vector2 t_CP = getCheckPoint(entityManager.player.my_Body.Position);

            if (t_CP.X > lastCP.X)
            {
                lastCP = t_CP;
                entityManager.player.copyInventory();
                EntityManager.getEntityManager(game).pushAFloater("Checkpoint", Color.DarkBlue);
            }
            physicsWorld.Step((float)gameTime.ElapsedGameTime.TotalSeconds, 15, 6);
            Box2D.XNA.Contact contact = physicsWorld.GetContactList();
            if (contact != null)
            {
                entityManager.processContacts(contact);
            }
            entityManager.updateAIs(entities.ToArray());
        }
Exemple #7
0
        public void BeginContact(Contact contact)
        {
            object obj1 = contact.GetFixtureA().GetBody().GetUserData();
            object obj2 = contact.GetFixtureB().GetBody().GetUserData();

            if (obj1 == TYPE_WATER || obj2 == TYPE_WATER)
            {

                if (obj1 is Sprite)
                {
                    ((Sprite)obj1).Drown = true;
                }
                else if (obj2 is Sprite)
                {
                    ((Sprite)obj2).Drown = true;
                }

            }
        }
 public void EndContact(Contact contact)
 {
     Fixture fixtureA = contact.GetFixtureA();
     Fixture fixtureB = contact.GetFixtureB();
     if (fixtureA.IsSensor())
     {
         var sensorData = (SensorInfo) fixtureA.GetUserData();
         var unitB = (Unit) fixtureB.GetBody().GetUserData();
         if (sensorData.Enable)
         {
             sensorData.Remove(unitB);
         }
     }
     if (fixtureB.IsSensor())
     {
         var sensorData = (SensorInfo) fixtureB.GetUserData();
         var unitA = (Unit) fixtureA.GetBody().GetUserData();
         if (sensorData.Enable)
         {
             sensorData.Remove(unitA);
         }
     }
 }
Exemple #9
0
        /// <summary> Call this to draw shapes and other debug draw data.
        /// </summary>
        public void DrawDebugData()
        {
            if (DebugDraw == null)
            {
                return;
            }

            DebugDrawFlags flags = DebugDraw.Flags;

            if ((flags & DebugDrawFlags.Shape) == DebugDrawFlags.Shape)
            {
                for (Body b = _bodyList; b != null; b = b.GetNext())
                {
                    Transform xf;
                    b.GetTransform(out xf);
                    for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext())
                    {
                        if (b.IsActive() == false)
                        {
                            DrawShape(f, xf, new Color(0.5f, 0.5f, 0.3f));
                        }
                        else if (b.GetType() == BodyType.Static)
                        {
                            DrawShape(f, xf, new Color(0.5f, 0.9f, 0.5f));
                        }
                        else if (b.GetType() == BodyType.Kinematic)
                        {
                            DrawShape(f, xf, new Color(0.5f, 0.5f, 0.9f));
                        }
                        else if (b.IsAwake() == false)
                        {
                            DrawShape(f, xf, new Color(0.6f, 0.6f, 0.6f));
                        }
                        else
                        {
                            DrawShape(f, xf, new Color(0.9f, 0.7f, 0.7f));
                        }
                    }
                }
            }

            if ((flags & DebugDrawFlags.Joint) == DebugDrawFlags.Joint)
            {
                for (Joint j = _jointList; j != null; j = j.GetNext())
                {
                    DrawJoint(j);
                }
            }

            if ((flags & DebugDrawFlags.Pair) == DebugDrawFlags.Pair)
            {
                Color color = new Color(0.3f, 0.9f, 0.9f);
                for (Contact c = _contactManager._contactList; c != null; c = c.GetNext())
                {
                    /*
                     * Fixture fixtureA = c.GetFixtureA();
                     * Fixture fixtureB = c.GetFixtureB();
                     *
                     * AABB aabbA;
                     * AABB aabbB;
                     * fixtureA.GetAABB(out aabbA);
                     * fixtureB.GetAABB(out aabbB);
                     *
                     * Vector2 cA = aabbA.GetCenter();
                     * Vector2 cB = aabbB.GetCenter();
                     *
                     * DebugDraw.DrawSegment(cA, cB, color);
                     */
                }
            }

            if ((flags & DebugDrawFlags.AABB) == DebugDrawFlags.AABB)
            {
                Color      color = new Color(0.9f, 0.3f, 0.9f);
                BroadPhase bp    = _contactManager._broadPhase;

                for (Body b = _bodyList; b != null; b = b.GetNext())
                {
                    if (b.IsActive() == false)
                    {
                        continue;
                    }

                    for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext())
                    {
                        for (int i = 0; i < f._proxyCount; ++i)
                        {
                            FixtureProxy proxy = f._proxies[i];
                            AABB         aabb;
                            bp.GetFatAABB(proxy.proxyId, out aabb);
                            FixedArray8 <Vector2> vs = new FixedArray8 <Vector2>();
                            vs[0] = new Vector2(aabb.lowerBound.X, aabb.lowerBound.Y);
                            vs[1] = new Vector2(aabb.upperBound.X, aabb.lowerBound.Y);
                            vs[2] = new Vector2(aabb.upperBound.X, aabb.upperBound.Y);
                            vs[3] = new Vector2(aabb.lowerBound.X, aabb.upperBound.Y);

                            DebugDraw.DrawPolygon(ref vs, 4, color);
                        }
                    }
                }
            }

            if ((flags & DebugDrawFlags.CenterOfMass) == DebugDrawFlags.CenterOfMass)
            {
                for (Body b = _bodyList; b != null; b = b.GetNext())
                {
                    Transform xf;
                    b.GetTransform(out xf);
                    xf.Position = b.GetWorldCenter();
                    DebugDraw.DrawTransform(ref xf);
                }
            }
        }
        internal void Destroy(Contact c)
        {
            Fixture fixtureA = c.GetFixtureA();
            Fixture fixtureB = c.GetFixtureB();
            Body bodyA = fixtureA.GetBody();
            Body bodyB = fixtureB.GetBody();

            if (c.IsTouching())
            {
                ContactListener.EndContact(c);
            }

            // Remove from the world.
            if (c._prev != null)
            {
                c._prev._next = c._next;
            }

            if (c._next != null)
            {
                c._next._prev = c._prev;
            }

            if (c == _contactList)
            {
                _contactList = c._next;
            }

            // Remove from body 1
            if (c._nodeA.Prev != null)
            {
                c._nodeA.Prev.Next = c._nodeA.Next;
            }

            if (c._nodeA.Next != null)
            {
                c._nodeA.Next.Prev = c._nodeA.Prev;
            }

            if (c._nodeA == bodyA._contactList)
            {
                bodyA._contactList = c._nodeA.Next;
            }

            // Remove from body 2
            if (c._nodeB.Prev != null)
            {
                c._nodeB.Prev.Next = c._nodeB.Next;
            }

            if (c._nodeB.Next != null)
            {
                c._nodeB.Next.Prev = c._nodeB.Prev;
            }

            if (c._nodeB == bodyB._contactList)
            {
                bodyB._contactList = c._nodeB.Next;
            }

            c.Destroy();

            --_contactCount;
        }
Exemple #11
0
        // Sequentially solve TOIs for each body. We bring each
        // body to the time of contact and perform some position correction.
        // Time is not conserved.
        void SolveTOI()
        {
            // Prepare all contacts.
            for (Contact c = _contactManager._contactList; c != null; c = c._next)
            {
                // Enable the contact
                c._flags |= ContactFlags.Enabled;

                // Set the number of TOI events for this contact to zero.
                c._toiCount = 0;
            }

            // Initialize the TOI flag.
            for (Body body = _bodyList; body != null; body = body._next)
            {
                // Kinematic, and static bodies will not be affected by the TOI event.
                // If a body was not in an island then it did not move.
                if ((body._flags & BodyFlags.Island) == 0 || body.GetType() == BodyType.Kinematic || body.GetType() == BodyType.Static)
                {
                    body._flags |= BodyFlags.Toi;
                }
                else
                {
                    body._flags &= ~BodyFlags.Toi;
                }
            }

            // Collide non-bullets.
            for (Body body = _bodyList; body != null; body = body._next)
            {
                if ((body._flags & BodyFlags.Toi) != BodyFlags.None)
                {
                    continue;
                }

                if (body.IsBullet == true)
                {
                    continue;
                }

                SolveTOI(body);

                body._flags |= BodyFlags.Toi;
            }

            // Collide bullets.
            for (Body body = _bodyList; body != null; body = body._next)
            {
                if ((body._flags & BodyFlags.Toi) != BodyFlags.None)
                {
                    continue;
                }

                if (body.IsBullet == false)
                {
                    continue;
                }

                SolveTOI(body);

                body._flags |= BodyFlags.Toi;
            }
        }
Exemple #12
0
 /// <summary>
 /// This is one the methods of the IContactListener interface.
 /// No implementation.
 /// </summary>
 /// <param name="contact">Box2D Contact</param>
 /// <param name="impulse">Box2D ContactImpulse</param>
 public void PostSolve(Contact contact, ref ContactImpulse impulse)
 {
 }
Exemple #13
0
        /// <summary>
        /// A callback function for Box2D to inform that two shapes are beginning to contact with 
        /// each other. Collects the information of the contacts and that information will be 
        /// handled after the physics simulation iterations are completed.
        /// </summary>
        /// <param name="contact">Box2D Contact</param>
        public virtual void BeginContact(Contact contact)
        {
            if (!bike.OffTheBike)
            {
                UserData data = (UserData)contact.GetFixtureA().GetBody().GetUserData();
                if (data != null)
                {
                    if (data.Name == "finish")
                    {
                        if (Win != null)
                            Win(this);
                    }
                    else if (data.Name == "nail")
                    {
                        if (TireFail != null)
                            TireFail(this);
                    }
                    else if ( (data.Name == "head" && contact.GetFixtureB().GetBody().GetType() == BodyType.Static) ||
                              (data.Name == null && ((UserData)contact.GetFixtureB().GetBody().GetUserData()).Name == "head") )
                    {
                        bikeShouldBeReleased = true;

                        if (HeadFail != null)
                            HeadFail(this);
                    }
                }
            }
        }
Exemple #14
0
        void Solve(ref TimeStep step)
        {
            // Size the island for the worst case.
            _island.Reset(_bodyCount,
                          _contactManager._contactCount,
                          _jointCount,
                          _contactManager.ContactListener);

            // Clear all the island flags.
            for (Body b = _bodyList; b != null; b = b._next)
            {
                b._flags &= ~BodyFlags.Island;
            }
            for (Contact c = _contactManager._contactList; c != null; c = c._next)
            {
                c._flags &= ~ContactFlags.Island;
            }
            for (Joint j = _jointList; j != null; j = j._next)
            {
                j._islandFlag = false;
            }

            // Build and simulate all awake islands.
            int stackSize = _bodyCount;

            if (stackSize > stack.Length)
            {
                stack = new Body[Math.Max(stack.Length * 2, stackSize)];
            }

            for (Body seed = _bodyList; seed != null; seed = seed._next)
            {
                if ((seed._flags & (BodyFlags.Island)) != BodyFlags.None)
                {
                    continue;
                }

                if (seed.IsAwake() == false || seed.IsActive() == false)
                {
                    continue;
                }

                // The seed can be dynamic or kinematic.
                if (seed.GetType() == BodyType.Static)
                {
                    continue;
                }

                // Reset island and stack.
                _island.Clear();
                int stackCount = 0;
                stack[stackCount++] = seed;
                seed._flags        |= BodyFlags.Island;

                // Perform a depth first search (DFS) on the raint graph.
                while (stackCount > 0)
                {
                    // Grab the next body off the stack and add it to the island.
                    Body b = stack[--stackCount];
                    Debug.Assert(b.IsActive() == true);
                    _island.Add(b);

                    // Make sure the body is awake.
                    b.SetAwake(true);

                    // To keep islands as small as possible, we don't
                    // propagate islands across static bodies.
                    if (b.GetType() == BodyType.Static)
                    {
                        continue;
                    }

                    // Search all contacts connected to this body.
                    for (ContactEdge ce = b._contactList; ce != null; ce = ce.Next)
                    {
                        Contact contact = ce.Contact;

                        // Has this contact already been added to an island?
                        if ((contact._flags & ContactFlags.Island) != ContactFlags.None)
                        {
                            continue;
                        }

                        // Is this contact solid and touching?
                        if (!ce.Contact.IsEnabled() || !ce.Contact.IsTouching())
                        {
                            continue;
                        }

                        // Skip sensors.
                        bool sensorA = contact._fixtureA._isSensor;
                        bool sensorB = contact._fixtureB._isSensor;
                        if (sensorA || sensorB)
                        {
                            continue;
                        }

                        _island.Add(contact);
                        contact._flags |= ContactFlags.Island;

                        Body other = ce.Other;

                        // Was the other body already added to this island?
                        if ((other._flags & BodyFlags.Island) != BodyFlags.None)
                        {
                            continue;
                        }

                        Debug.Assert(stackCount < stackSize);
                        stack[stackCount++] = other;
                        other._flags       |= BodyFlags.Island;
                    }

                    // Search all joints connect to this body.
                    for (JointEdge je = b._jointList; je != null; je = je.Next)
                    {
                        if (je.Joint._islandFlag == true)
                        {
                            continue;
                        }

                        Body other = je.Other;

                        // Don't simulate joints connected to inactive bodies.
                        if (other.IsActive() == false)
                        {
                            continue;
                        }

                        _island.Add(je.Joint);
                        je.Joint._islandFlag = true;

                        if ((other._flags & BodyFlags.Island) != BodyFlags.None)
                        {
                            continue;
                        }

                        Debug.Assert(stackCount < stackSize);
                        stack[stackCount++] = other;
                        other._flags       |= BodyFlags.Island;
                    }
                }

                _island.Solve(ref step, Gravity, _allowSleep);

                // Post solve cleanup.
                for (int i = 0; i < _island._bodyCount; ++i)
                {
                    // Allow static bodies to participate in other islands.
                    Body b = _island._bodies[i];
                    if (b.GetType() == BodyType.Static)
                    {
                        b._flags &= ~BodyFlags.Island;
                    }
                }
            }

            // Synchronize fixtures, check for out of range bodies.
            for (Body b = _bodyList; b != null; b = b.GetNext())
            {
                // If a body was not in an island then it did not move.
                if ((b._flags & BodyFlags.Island) != BodyFlags.Island)
                {
                    continue;
                }

                if (b.GetType() == BodyType.Static)
                {
                    continue;
                }

                // Update fixtures (for broad-phase).
                b.SynchronizeFixtures();
            }

            // Look for new contacts.
            _contactManager.FindNewContacts();
        }
 public override void PostSolve(Contact contact, ref Box2D.XNA.ContactImpulse impulse)
 {
     float intensity = impulse.normalImpulses[0] / 2800F;
     //intensity = Math.Min(1F, intensity);
     if (intensity > 0.20F)
     {
         Camera.Shake(intensity);
         OnShake(contact, intensity);
     }
     base.PostSolve(contact, ref impulse);
 }
Exemple #16
0
        internal static Contact Create(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB)
        {
            ShapeType type1 = fixtureA.ShapeType;
	        ShapeType type2 = fixtureB.ShapeType;

	        Debug.Assert(ShapeType.Unknown < type1 && type1 < ShapeType.TypeCount);
            Debug.Assert(ShapeType.Unknown < type2 && type2 < ShapeType.TypeCount);

            Contact c;
            var pool = fixtureA._body._world._contactPool;
            if (pool.Count > 0)
            {
                c = pool.Dequeue();
                if ((type1 >= type2 || (type1 == ShapeType.Edge && type2 == ShapeType.Polygon))
                    &&
                    !(type2 == ShapeType.Edge && type1 == ShapeType.Polygon))
                {
                    c.Reset(fixtureA, indexA, fixtureB, indexB);
                }
                else
                {
                    c.Reset(fixtureB, indexB, fixtureA, indexA);
                }
            }
            else
            {
                // Edge+Polygon is non-symetrical due to the way Erin handles collision type registration.
                if ((type1 >= type2 || (type1 == ShapeType.Edge && type2 == ShapeType.Polygon))
                    && 
                    !(type2 == ShapeType.Edge && type1 == ShapeType.Polygon))
                {
                    c = new Contact(fixtureA, indexA, fixtureB, indexB);
                }
                else
                {
                    c = new Contact(fixtureB, indexB, fixtureA, indexA);
                }
            }

            c._type = Contact.s_registers[(int)type1, (int)type2];

            return c;
        }
 public override void BeginContact(Contact contact)
 {
     base.BeginContact(contact);
 }
        public void Initialize(Contact[] contacts, int count, Body toiBody)
        {
            _count = count;
            _toiBody = toiBody;
            if (_constraints.Length < _count)
                _constraints = new TOIConstraint[Math.Max(_constraints.Length * 2, _count)];

            for (int i = 0; i < _count; ++i)
            {
                Contact contact = contacts[i];

                Fixture fixtureA = contact.GetFixtureA();
                Fixture fixtureB = contact.GetFixtureB();
                Shape shapeA = fixtureA.GetShape();
                Shape shapeB = fixtureB.GetShape();
                float radiusA = shapeA._radius;
                float radiusB = shapeB._radius;
                Body bodyA = fixtureA.GetBody();
                Body bodyB = fixtureB.GetBody();
                Manifold manifold;
                contact.GetManifold(out manifold);

                Debug.Assert(manifold._pointCount > 0);

                TOIConstraint constraint = _constraints[i];
                constraint.bodyA = bodyA;
                constraint.bodyB = bodyB;
                constraint.localNormal = manifold._localNormal;
                constraint.localPoint = manifold._localPoint;
                constraint.type = manifold._type;
                constraint.pointCount = manifold._pointCount;
                constraint.radius = radiusA + radiusB;

                for (int j = 0; j < constraint.pointCount; ++j)
                {
                    constraint.localPoints[j] = manifold._points[j].LocalPoint;
                }

                _constraints[i] = constraint;
            }
        }
 public void PreSolve(Contact contact, ref Manifold oldManifold)
 {
     var unitA = (Unit) contact.GetFixtureA().GetBody().GetUserData();
     var unitB = (Unit) contact.GetFixtureB().GetBody().GetUserData();
     if (!(unitA.EnableCollision && unitB.EnableCollision
           && GroupManager.Instance.ShouldContact(unitA.Group, unitB.Group)))
     {
         contact.SetEnabled(false);
     }
 }
        // Broad-phase callback.
        internal void AddPair(Fixture proxyUserDataA, Fixture proxyUserDataB)
        {
            Fixture fixtureA = proxyUserDataA;
            Fixture fixtureB = proxyUserDataB;

            Body bodyA = fixtureA.GetBody();
            Body bodyB = fixtureB.GetBody();

            // Are the fixtures on the same body?
            if (bodyA == bodyB)
            {
                return;
            }

            // Does a contact already exist?
            ContactEdge edge = bodyB.GetContactList();
            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    Fixture fA = edge.Contact.GetFixtureA();
                    Fixture fB = edge.Contact.GetFixtureB();
                    if (fA == fixtureA && fB == fixtureB)
                    {
                        // A contact already exists.
                        return;
                    }

                    if (fA == fixtureB && fB == fixtureA)
                    {
                        // A contact already exists.
                        return;
                    }
                }

                edge = edge.Next;
            }

            // Does a joint override collision? Is at least one body dynamic?
            if (bodyB.ShouldCollide(bodyA) == false)
            {
                return;
            }

            // Check user filtering.
            if (ContactFilter.ShouldCollide(fixtureA, fixtureB) == false)
            {
                return;
            }

            // Call the factory.
            Contact c = Contact.Create(fixtureA, fixtureB);

            // Contact creation may swap fixtures.
            fixtureA = c.GetFixtureA();
            fixtureB = c.GetFixtureB();
            bodyA = fixtureA.GetBody();
            bodyB = fixtureB.GetBody();

            // Insert into the world.
            c._prev = null;
            c._next = _contactList;
            if (_contactList != null)
            {
                _contactList._prev = c;
            }
            _contactList = c;

            // Connect to island graph.

            // Connect to body A
            c._nodeA.Contact = c;
            c._nodeA.Other = bodyB;

            c._nodeA.Prev = null;
            c._nodeA.Next = bodyA._contactList;
            if (bodyA._contactList != null)
            {
                bodyA._contactList.Prev = c._nodeA;
            }
            bodyA._contactList = c._nodeA;

            // Connect to body B
            c._nodeB.Contact = c;
            c._nodeB.Other = bodyA;

            c._nodeB.Prev = null;
            c._nodeB.Next = bodyB._contactList;
            if (bodyB._contactList != null)
            {
                bodyB._contactList.Prev = c._nodeB;
            }
            bodyB._contactList = c._nodeB;

            ++_contactCount;
        }
Exemple #21
0
 public void BeginContact(Contact contact)
 {
 }
Exemple #22
0
        public void EndContact(Contact contact)
        {
            while (contact != null)
            {
                var lhsInfo = new ContactInfo();
                var rhsInfo = new ContactInfo();

                lhsInfo.contact = contact;
                rhsInfo.contact = contact;

                lhsInfo.fixtureType = FixtureType.A;
                rhsInfo.fixtureType = FixtureType.B;

                var lhsGo = contact.GetFixtureA().GetBody().GetUserData() as GameObject;
                var rhsGo = contact.GetFixtureB().GetBody().GetUserData() as GameObject;

                lhsInfo.other = rhsGo;
                rhsInfo.other = lhsGo;

                if (lhsGo != null) { lhsGo.EndContact(lhsInfo); }
                if (rhsGo != null) { rhsGo.EndContact(rhsInfo); }

                contact = contact.GetNext();
            }
        }
Exemple #23
0
        // Advance a dynamic body to its first time of contact
        // and adjust the position to ensure clearance.
        void SolveTOI(Body body)
        {
            // Find the minimum contact.
            Contact toiContact = null;
            float   toi        = 1.0f;
            Body    toiOther   = null;
            bool    found;
            int     count;
            int     iter = 0;

            bool bullet = body.IsBullet;

            // Iterate until all contacts agree on the minimum TOI. We have
            // to iterate because the TOI algorithm may skip some intermediate
            // collisions when objects rotate through each other.
            do
            {
                count = 0;
                found = false;
                for (ContactEdge ce = body._contactList; ce != null; ce = ce.Next)
                {
                    if (ce.Contact == toiContact)
                    {
                        continue;
                    }

                    Body     other = ce.Other;
                    BodyType type  = other.GetType();

                    // Only bullets perform TOI with dynamic bodies.
                    if (bullet == true)
                    {
                        // Bullets only perform TOI with bodies that have their TOI resolved.
                        if ((other._flags & BodyFlags.Toi) == 0)
                        {
                            continue;
                        }

                        // No repeated hits on non-static bodies
                        if (type != BodyType.Static && (ce.Contact._flags & ContactFlags.BulletHit) != 0)
                        {
                            continue;
                        }
                    }
                    else if (type == BodyType.Dynamic)
                    {
                        continue;
                    }

                    // Check for a disabled contact.
                    Contact contact = ce.Contact;
                    if (contact.IsEnabled() == false)
                    {
                        continue;
                    }

                    // Prevent infinite looping.
                    if (contact._toiCount > 10)
                    {
                        continue;
                    }

                    Fixture fixtureA = contact._fixtureA;
                    Fixture fixtureB = contact._fixtureB;
                    int     indexA   = contact._indexA;
                    int     indexB   = contact._indexB;

                    // Cull sensors.
                    if (fixtureA.IsSensor() || fixtureB.IsSensor())
                    {
                        continue;
                    }

                    Body bodyA = fixtureA._body;
                    Body bodyB = fixtureB._body;

                    // Compute the time of impact in interval [0, minTOI]
                    TOIInput input = new TOIInput();
                    input.proxyA.Set(fixtureA.GetShape(), indexA);
                    input.proxyB.Set(fixtureB.GetShape(), indexB);
                    input.sweepA = bodyA._sweep;
                    input.sweepB = bodyB._sweep;
                    input.tMax   = toi;

                    TOIOutput output;
                    TimeOfImpact.CalculateTimeOfImpact(out output, ref input);

                    if (output.State == TOIOutputState.Touching && output.t < toi)
                    {
                        toiContact = contact;
                        toi        = output.t;
                        toiOther   = other;
                        found      = true;
                    }

                    ++count;
                }

                ++iter;
            } while (found && count > 1 && iter < 50);

            if (toiContact == null)
            {
                body.Advance(1.0f);
                return;
            }

            Sweep backup = body._sweep;

            body.Advance(toi);
            toiContact.Update(_contactManager.ContactListener);
            if (toiContact.IsEnabled() == false)
            {
                // Contact disabled. Backup and recurse.
                body._sweep = backup;
                SolveTOI(body);
            }

            ++toiContact._toiCount;

            // Update all the valid contacts on this body and build a contact island.
            count = 0;
            for (ContactEdge ce = body._contactList; (ce != null) && (count < Settings.b2_maxTOIContacts); ce = ce.Next)
            {
                Body     other = ce.Other;
                BodyType type  = other.GetType();

                // Only perform correction with static bodies, so the
                // body won't get pushed out of the world.
                if (type == BodyType.Dynamic)
                {
                    continue;
                }

                // Check for a disabled contact.
                Contact contact = ce.Contact;
                if (contact.IsEnabled() == false)
                {
                    continue;
                }

                Fixture fixtureA = contact._fixtureA;
                Fixture fixtureB = contact._fixtureB;

                // Cull sensors.
                if (fixtureA.IsSensor() || fixtureB.IsSensor())
                {
                    continue;
                }

                // The contact likely has some new contact points. The listener
                // gives the user a chance to disable the contact.
                if (contact != toiContact)
                {
                    contact.Update(_contactManager.ContactListener);
                }

                // Did the user disable the contact?
                if (contact.IsEnabled() == false)
                {
                    // Skip this contact.
                    continue;
                }

                if (contact.IsTouching() == false)
                {
                    continue;
                }

                _toiContacts[count] = contact;
                ++count;
            }

            // Reduce the TOI body's overlap with the contact island.
            _toiSolver.Initialize(_toiContacts, count, body);

            float k_toiBaumgarte = 0.75f;

            //bool solved = false;
            for (int i = 0; i < 20; ++i)
            {
                bool contactsOkay = _toiSolver.Solve(k_toiBaumgarte);
                if (contactsOkay)
                {
                    //solved = true;
                    break;
                }
            }

            if (toiOther.GetType() != BodyType.Static)
            {
                toiContact._flags |= ContactFlags.BulletHit;
            }
        }
        public void Reset(Contact[] contacts, int contactCount, float impulseRatio)
        {
            _contacts = contacts;

            _constraintCount = contactCount;

            // grow the array
            if (_constraints == null || _constraints.Length < _constraintCount)
            {
                _constraints = new ContactConstraint[_constraintCount * 2];
            }

            for (int i = 0; i < _constraintCount; ++i)
            {
                Contact contact = contacts[i];

                Fixture fixtureA = contact._fixtureA;
                Fixture fixtureB = contact._fixtureB;
                Shape shapeA = fixtureA.GetShape();
                Shape shapeB = fixtureB.GetShape();
                float radiusA = shapeA._radius;
                float radiusB = shapeB._radius;
                Body bodyA = fixtureA.GetBody();
                Body bodyB = fixtureB.GetBody();
                Manifold manifold;
                contact.GetManifold(out manifold);

                float friction = Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction());
                float restitution = Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution());

                Vector2 vA = bodyA._linearVelocity;
                Vector2 vB = bodyB._linearVelocity;
                float wA = bodyA._angularVelocity;
                float wB = bodyB._angularVelocity;

                Debug.Assert(manifold._pointCount > 0);

                WorldManifold worldManifold = new WorldManifold(ref manifold, ref bodyA._xf, radiusA, ref bodyB._xf, radiusB);

                ContactConstraint cc = _constraints[i];
                cc.bodyA = bodyA;
                cc.bodyB = bodyB;
                cc.manifold = manifold;
                cc.normal = worldManifold._normal;
                cc.pointCount = manifold._pointCount;
                cc.friction = friction;

                cc.localNormal = manifold._localNormal;
                cc.localPoint = manifold._localPoint;
                cc.radius = radiusA + radiusB;
                cc.type = manifold._type;

                for (int j = 0; j < cc.pointCount; ++j)
                {
                    ManifoldPoint cp = manifold._points[j];
                    ContactConstraintPoint ccp = cc.points[j];

                    ccp.normalImpulse = impulseRatio * cp.NormalImpulse;
                    ccp.tangentImpulse = impulseRatio * cp.TangentImpulse;

                    ccp.localPoint = cp.LocalPoint;

                    ccp.rA = worldManifold._points[j] - bodyA._sweep.c;
                    ccp.rB = worldManifold._points[j] - bodyB._sweep.c;

            #if MATH_OVERLOADS
                    float rnA = MathUtils.Cross(ccp.rA, cc.normal);
                    float rnB = MathUtils.Cross(ccp.rB, cc.normal);
            #else
                    float rnA = ccp.rA.X * cc.normal.Y - ccp.rA.Y * cc.normal.X;
                    float rnB = ccp.rB.X * cc.normal.Y - ccp.rB.Y * cc.normal.X;
            #endif
                    rnA *= rnA;
                    rnB *= rnB;

                    float kNormal = bodyA._invMass + bodyB._invMass + bodyA._invI * rnA + bodyB._invI * rnB;

                    Debug.Assert(kNormal > Settings.b2_epsilon);
                    ccp.normalMass = 1.0f / kNormal;

            #if MATH_OVERLOADS
                    Vector2 tangent = MathUtils.Cross(cc.normal, 1.0f);

                    float rtA = MathUtils.Cross(ccp.rA, tangent);
                    float rtB = MathUtils.Cross(ccp.rB, tangent);
            #else
                    Vector2 tangent = new Vector2(cc.normal.Y, -cc.normal.X);

                    float rtA = ccp.rA.X * tangent.Y - ccp.rA.Y * tangent.X;
                    float rtB = ccp.rB.X * tangent.Y - ccp.rB.Y * tangent.X;
            #endif
                    rtA *= rtA;
                    rtB *= rtB;
                    float kTangent = bodyA._invMass + bodyB._invMass + bodyA._invI * rtA + bodyB._invI * rtB;

                    Debug.Assert(kTangent > Settings.b2_epsilon);
                    ccp.tangentMass = 1.0f / kTangent;

                    // Setup a velocity bias for restitution.
                    ccp.velocityBias = 0.0f;
                    float vRel = Vector2.Dot(cc.normal, vB + MathUtils.Cross(wB, ccp.rB) - vA - MathUtils.Cross(wA, ccp.rA));
                    if (vRel < -Settings.b2_velocityThreshold)
                    {
                        ccp.velocityBias = -restitution * vRel;
                    }

                    cc.points[j] = ccp;
                }

                // If we have two points, then prepare the block solver.
                if (cc.pointCount == 2)
                {
                    ContactConstraintPoint ccp1 = cc.points[0];
                    ContactConstraintPoint ccp2 = cc.points[1];

                    float invMassA = bodyA._invMass;
                    float invIA = bodyA._invI;
                    float invMassB = bodyB._invMass;
                    float invIB = bodyB._invI;

                    float rn1A = MathUtils.Cross(ccp1.rA, cc.normal);
                    float rn1B = MathUtils.Cross(ccp1.rB, cc.normal);
                    float rn2A = MathUtils.Cross(ccp2.rA, cc.normal);
                    float rn2B = MathUtils.Cross(ccp2.rB, cc.normal);

                    float k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B;
                    float k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B;
                    float k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B;

                    // Ensure a reasonable condition number.
                    const float k_maxConditionNumber = 100.0f;
                    if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12))
                    {
                        // K is safe to invert.
                        cc.K = new Mat22(new Vector2(k11, k12), new Vector2(k12, k22));
                        cc.normalMass = cc.K.GetInverse();
                    }
                    else
                    {
                        // The constraints are redundant, just use one.
                        // TODO_ERIN use deepest?
                        cc.pointCount = 1;
                    }
                }

                _constraints[i] = cc;
            }
        }
        internal static Contact Create(Fixture fixtureA, Fixture fixtureB)
        {
            ShapeType type1 = fixtureA.ShapeType;
            ShapeType type2 = fixtureB.ShapeType;

            Debug.Assert(ShapeType.Unknown < type1 && type1 < ShapeType.TypeCount);
            Debug.Assert(ShapeType.Unknown < type2 && type2 < ShapeType.TypeCount);

            Contact c;
            var pool = fixtureA._body._world._contactPool;
            if (pool.Count > 0)
            {
                c = pool.Dequeue();
                if (type1 >= type2)
                {
                    c.Reset(fixtureA, fixtureB);
                }
                else
                {
                    c.Reset(fixtureB, fixtureA);
                }
            }
            else
            {
                if (type1 >= type2)
                {
                    c = new Contact(fixtureA, fixtureB);
                }
                else
                {
                    c = new Contact(fixtureB, fixtureA);
                }
            }

            c._type = Contact.s_registers[(int)type1, (int)type2];

            return c;
        }
        //public override void BeginContact(Contact contact)
        //{
        //    base.BeginContact(contact);
        //    object objA = contact.GetFixtureA().GetBody().GetUserData();
        //    object objB = contact.GetFixtureB().GetBody().GetUserData();
        //    foreach (Type t in contactTypes.Keys)
        //    {
        //        if (objA.GetType() == t)
        //        {
        //            contactTypes[t](objA, objB);
        //            break;
        //        }
        //        else if (objB.GetType() == t)
        //        {
        //            contactTypes[t](objB, objA);
        //            break;
        //        }
        //    }
        //}
        public override void EndContact(Contact contact)
        {
            base.EndContact(contact);
            object objA = contact.GetFixtureA().GetBody().GetUserData();
            object objB = contact.GetFixtureB().GetBody().GetUserData();

            if (objA is Walker || objB is Walker)
            {
                walker.EndContact();
            }
        }
        internal void Reset(Fixture fA, Fixture fB)
        {
            _flags = ContactFlags.Enabled;

            _fixtureA = fA;
            _fixtureB = fB;

            _manifold._pointCount = 0;

            _prev = null;
            _next = null;

            _nodeA.Contact = null;
            _nodeA.Prev = null;
            _nodeA.Next = null;
            _nodeA.Other = null;

            _nodeB.Contact = null;
            _nodeB.Prev = null;
            _nodeB.Next = null;
            _nodeB.Other = null;

            _toiCount = 0;
        }
        protected virtual void OnShake(Contact contact, float intensity)
        {
            if (!(contact.GetFixtureA().GetBody().GetUserData() is Walker) && !(contact.GetFixtureB().GetBody().GetUserData() is Walker))
            {
                if (stage != null)
                {
                    if (intensity < .5f)
                    {
                        Cue c = stage.audio.PlaySound(Sfx.woodHit);
                        c.SetVariable("Volume", 1);
                    }
                    else
                    {
                        float vol = intensity / 4 + .75f;
                        vol = vol > 1 ? 1f : vol < 0.75f ? 0.75f : vol;

                        Cue c = stage.audio.PlaySound(Sfx.smash);
                        c.SetVariable("Volume", vol);
                    }
                }
            }
        }
Exemple #29
0
 public void Add(Contact contact)
 {
     Debug.Assert(_contactCount < _contactCapacity);
     _contacts[_contactCount++] = contact;
 }
Exemple #30
0
 public void EndContact(Contact contact)
 {
 }
Exemple #31
0
        public virtual void EndContact(Contact contact)
        {
            object objA = contact.GetFixtureA().GetBody().GetUserData();
            object objB = contact.GetFixtureB().GetBody().GetUserData();

            foreach (Type t in contactEndTypes.Keys)
            {
                if (objA.GetType() == t)
                {
                    contactEndTypes[t](objA, objB, contact.GetFixtureA(), contact.GetFixtureB());
                    break;
                }
                else if (objB.GetType() == t)
                {
                    contactEndTypes[t](objB, objA, contact.GetFixtureB(), contact.GetFixtureA());
                    break;
                }
            }
        }
Exemple #32
0
 /// <summary>
 /// This is one the methods of the IContactListener interface.
 /// No implementation.
 /// </summary>
 /// <param name="contact">Box2D Contact</param>
 public virtual void EndContact(Contact contact)
 {
 }
Exemple #33
0
 public virtual void PreSolve(Contact contact, ref Manifold oldManifold)
 {
     // call this in the base class if points are needed
     // PreSolveCalcPoints(contact, ref oldManifold);
 }
Exemple #34
0
 /// <summary>
 /// This is one the methods of the IContactListener interface.
 /// No implementation.
 /// </summary>
 /// <param name="contact">Box2D Contact</param>
 /// <param name="oldManifold">Box2D Manifold</param>
 public void PreSolve(Contact contact, ref Manifold oldManifold)
 {
 }
Exemple #35
0
        protected void PreSolveCalcPoints(Contact contact, ref Manifold oldManifold)
        {
            Manifold manifold;
            contact.GetManifold(out manifold);

            if (manifold._pointCount == 0)
            {
                return;
            }

            Fixture fixtureA = contact.GetFixtureA();
            Fixture fixtureB = contact.GetFixtureB();

            FixedArray2<PointState> state1, state2;
            Collision.GetPointStates(out state1, out state2, ref oldManifold, ref manifold);

            WorldManifold worldManifold;
            contact.GetWorldManifold(out worldManifold);

            for (int i = 0; i < manifold._pointCount && _pointCount < k_maxContactPoints; ++i)
            {
                if (fixtureA == null)
                {
                    _points[i] = new ContactPoint();
                }
                ContactPoint cp = _points[_pointCount];
                cp.fixtureA = fixtureA;
                cp.fixtureB = fixtureB;
                cp.position = worldManifold._points[i];
                cp.normal = worldManifold._normal;
                cp.state = state2[i];
                _points[_pointCount] = cp;
                ++_pointCount;
            }
        }