示例#1
0
        internal void Collide()
        {
            // Update awake contacts.
#if USE_ACTIVE_CONTACT_SET
            ActiveList.AddRange(ActiveContacts);

            foreach (var c in ActiveList)
            {
#else
            for (int i = 0; i < ContactList.Count; i++)
            {
                Contact c = ContactList[i];
#endif
                Fixture fixtureA = c.FixtureA;
                Fixture fixtureB = c.FixtureB;
                int     indexA   = c.ChildIndexA;
                int     indexB   = c.ChildIndexB;
                Body    bodyA    = fixtureA.Body;
                Body    bodyB    = fixtureB.Body;

                //Do no try to collide disabled bodies
                if (!bodyA.Enabled || !bodyB.Enabled)
                {
                    continue;
                }

                // Is this contact flagged for filtering?
                if (c.FilterFlag)
                {
                    // Should these bodies collide?
                    if (bodyB.ShouldCollide(bodyA) == false)
                    {
                        Contact cNuke = c;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check default filtering
                    if (ShouldCollide(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check user filtering.
                    if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        Destroy(cNuke);
                        continue;
                    }

                    // Clear the filtering flag.
                    c.FilterFlag = false;
                }

                bool activeA = bodyA.Awake && bodyA.BodyType != BodyType.Static;
                bool activeB = bodyB.Awake && bodyB.BodyType != BodyType.Static;

                // At least one body must be awake and it must be dynamic or kinematic.
                if (activeA == false && activeB == false)
                {
#if USE_ACTIVE_CONTACT_SET
                    ActiveContacts.Remove(c);
#endif
                    continue;
                }

                int proxyIdA = fixtureA.Proxies[indexA].ProxyId;
                int proxyIdB = fixtureB.Proxies[indexB].ProxyId;

                bool overlap = BroadPhase.TestOverlap(proxyIdA, proxyIdB);

                // Here we destroy contacts that cease to overlap in the broad-phase.
                if (overlap == false)
                {
                    Contact cNuke = c;
                    Destroy(cNuke);
                    continue;
                }

                // The contact persists.
                c.Update(this);
            }

#if USE_ACTIVE_CONTACT_SET
            ActiveList.Clear();
#endif
        }
        internal void Collide()
        {
#if NET40 || NET45 || NETSTANDARD2_0 || PORTABLE40 || PORTABLE45 || W10 || W8_1 || WP8_1
            if (this.ContactCount > CollideMultithreadThreshold && System.Environment.ProcessorCount > 1)
            {
                CollideMultiCore();
                return;
            }
#endif

            // Update awake contacts.
#if USE_ACTIVE_CONTACT_SET
            ActiveList.AddRange(ActiveContacts);
            foreach (var tmpc in ActiveList)
            {
                Contact c = tmpc;
#else
            for (Contact c = ContactList.Next; c != ContactList;)
            {
#endif
                Fixture fixtureA = c.FixtureA;
                Fixture fixtureB = c.FixtureB;
                int     indexA   = c.ChildIndexA;
                int     indexB   = c.ChildIndexB;
                Body    bodyA    = fixtureA.Body;
                Body    bodyB    = fixtureB.Body;

                //Do no try to collide disabled bodies
                if (!bodyA.Enabled || !bodyB.Enabled)
                {
                    c = c.Next;
                    continue;
                }

                // Is this contact flagged for filtering?
                if (c.FilterFlag)
                {
                    // Should these bodies collide?
                    if (bodyB.ShouldCollide(bodyA) == false)
                    {
                        Contact cNuke = c;
                        c = c.Next;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check default filtering
                    if (ShouldCollide(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        c = c.Next;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check user filtering.
                    if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        c = c.Next;
                        Destroy(cNuke);
                        continue;
                    }

                    // Clear the filtering flag.
                    c.FilterFlag = false;
                }

                bool activeA = bodyA.Awake && bodyA.BodyType != BodyType.Static;
                bool activeB = bodyB.Awake && bodyB.BodyType != BodyType.Static;

                // At least one body must be awake and it must be dynamic or kinematic.
                if (activeA == false && activeB == false)
                {
#if USE_ACTIVE_CONTACT_SET
                    ActiveContacts.Remove(c);
#endif
                    c = c.Next;
                    continue;
                }

                int proxyIdA = fixtureA.Proxies[indexA].ProxyId;
                int proxyIdB = fixtureB.Proxies[indexB].ProxyId;

                bool overlap = BroadPhase.TestOverlap(proxyIdA, proxyIdB);

                // Here we destroy contacts that cease to overlap in the broad-phase.
                if (overlap == false)
                {
                    Contact cNuke = c;
                    c = c.Next;
                    Destroy(cNuke);
                    continue;
                }

                // The contact persists.
                c.Update(this);

                c = c.Next;
            }

#if USE_ACTIVE_CONTACT_SET
            ActiveList.Clear();
#endif
        }

        /// <summary>
        /// A temporary list of contacts to be updated during Collide().
        /// </summary>
        List <Contact> updateList = new List <Contact>();
示例#3
0
        internal void Collide()
        {
            // Update awake contacts.
            var elements = ContactList.Elements;

            for (int i = 0, count = ContactList.count; i < count; i++)
            {
                Contact c        = elements[i];
                Fixture fixtureA = c.FixtureA;
                Fixture fixtureB = c.FixtureB;
                int     indexA   = c.ChildIndexA;
                int     indexB   = c.ChildIndexB;
                Body    bodyA    = fixtureA.Body;
                Body    bodyB    = fixtureB.Body;

                if (bodyA.Awake == false && bodyB.Awake == false)
                {
                    continue;
                }

                // Is this contact flagged for filtering?
                if ((c.Flags & ContactFlags.Filter) == ContactFlags.Filter)
                {
                    // Should these bodies collide?
                    if (bodyB.ShouldCollide(bodyA) == false)
                    {
                        Destroy(c, i);
                        count--;
                        continue;
                    }

                    // Check default filtering
                    if (ShouldCollide(fixtureA, fixtureB) == false)
                    {
                        Destroy(c, i);
                        count--;
                        continue;
                    }

                    // Check user filtering.
                    if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false)
                    {
                        Destroy(c, i);
                        count--;
                        continue;
                    }

                    // Clear the filtering flag.
                    c.Flags &= ~ContactFlags.Filter;
                }

                int proxyIdA = fixtureA.Proxies[indexA].ProxyId;
                int proxyIdB = fixtureB.Proxies[indexB].ProxyId;

                bool overlap = BroadPhase.TestOverlap(proxyIdA, proxyIdB);

                // Here we destroy contacts that cease to overlap in the broad-phase.
                if (overlap == false)
                {
                    Destroy(c, i);
                    count--;
                    continue;
                }

                // The contact persists.
                c.Update(this);
            }
        }
示例#4
0
        internal void CollideMultiCore()
        {
            int lockOrder = 0;

            // Update awake contacts.
#if USE_ACTIVE_CONTACT_SET
            ActiveList.AddRange(ActiveContacts);
            foreach (var tmpc in ActiveList)
            {
                Contact c = tmpc;
#else
            for (Contact c = ContactList.Next; c != ContactList;)
            {
#endif
                Fixture fixtureA = c.FixtureA;
                Fixture fixtureB = c.FixtureB;
                int     indexA   = c.ChildIndexA;
                int     indexB   = c.ChildIndexB;
                Body    bodyA    = fixtureA.Body;
                Body    bodyB    = fixtureB.Body;

                //Do no try to collide disabled bodies
                if (!bodyA.Enabled || !bodyB.Enabled)
                {
                    c = c.Next;
                    continue;
                }

                // Is this contact flagged for filtering?
                if (c.FilterFlag)
                {
                    // Should these bodies collide?
                    if (bodyB.ShouldCollide(bodyA) == false)
                    {
                        Contact cNuke = c;
                        c = c.Next;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check default filtering
                    if (ShouldCollide(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        c = c.Next;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check user filtering.
                    if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        c = c.Next;
                        Destroy(cNuke);
                        continue;
                    }

                    // Clear the filtering flag.
                    c.FilterFlag = false;
                }

                bool activeA = bodyA.Awake && bodyA.BodyType != BodyType.Static;
                bool activeB = bodyB.Awake && bodyB.BodyType != BodyType.Static;

                // At least one body must be awake and it must be dynamic or kinematic.
                if (activeA == false && activeB == false)
                {
#if USE_ACTIVE_CONTACT_SET
                    ActiveContacts.Remove(c);
#endif
                    c = c.Next;
                    continue;
                }

                int proxyIdA = fixtureA.Proxies[indexA].ProxyId;
                int proxyIdB = fixtureB.Proxies[indexB].ProxyId;

                bool overlap = BroadPhase.TestOverlap(proxyIdA, proxyIdB);

                // Here we destroy contacts that cease to overlap in the broad-phase.
                if (overlap == false)
                {
                    Contact cNuke = c;
                    c = c.Next;
                    Destroy(cNuke);
                    continue;
                }

                // The contact persists.
                updateList.Add(c);
                // Assign a unique id for lock order
                bodyA._lockOrder = lockOrder++;
                bodyB._lockOrder = lockOrder++;


                c = c.Next;
            }

#if USE_ACTIVE_CONTACT_SET
            ActiveList.Clear();
#endif

            // update contacts
            System.Threading.Tasks.Parallel.ForEach <Contact>(updateList, (c) =>
            {
                // find lower order item
                Fixture fixtureA = c.FixtureA;
                Fixture fixtureB = c.FixtureB;

                // find lower order item
                Body orderedBodyA = fixtureA.Body;
                Body orderedBodyB = fixtureB.Body;
                int idA           = orderedBodyA._lockOrder;
                int idB           = orderedBodyB._lockOrder;
                if (idA == idB)
                {
                    throw new System.Exception();
                }

                if (idA > idB)
                {
                    orderedBodyA = fixtureB.Body;
                    orderedBodyB = fixtureA.Body;
                }

                // obtain lock
                for (; ;)
                {
                    if (System.Threading.Interlocked.CompareExchange(ref orderedBodyA._lock, 1, 0) == 0)
                    {
                        if (System.Threading.Interlocked.CompareExchange(ref orderedBodyB._lock, 1, 0) == 0)
                        {
                            break;
                        }
                        System.Threading.Interlocked.Exchange(ref orderedBodyA._lock, 0);
                    }
#if NET40 || NET45
                    System.Threading.Thread.Sleep(0);
#endif
                }

                c.Update(this);

                System.Threading.Interlocked.Exchange(ref orderedBodyB._lock, 0);
                System.Threading.Interlocked.Exchange(ref orderedBodyA._lock, 0);
            });

            updateList.Clear();
        }
示例#5
0
        internal void Collide()
        {
            // Update awake contacts.
#if USE_ACTIVE_CONTACT_SET
            ActiveList.AddRange(ActiveContacts);

            foreach (var c in ActiveList)
            {
#else
            for (int i = 0; i < ContactList.Count; i++)
            {
                Contact c = ContactList[i];
#endif
                Fixture fixtureA = c.FixtureA;
                Fixture fixtureB = c.FixtureB;
                int     indexA   = c.ChildIndexA;
                int     indexB   = c.ChildIndexB;
                Body    bodyA    = fixtureA.Body;
                Body    bodyB    = fixtureB.Body;

                if (bodyA.Awake == false && bodyB.Awake == false)
                {
#if USE_ACTIVE_CONTACT_SET
                    ActiveContacts.Remove(c);
#endif
                    continue;
                }

                // Is this contact flagged for filtering?
                if ((c.Flags & ContactFlags.Filter) == ContactFlags.Filter)
                {
                    // Should these bodies collide?
                    if (bodyB.ShouldCollide(bodyA) == false)
                    {
                        Contact cNuke = c;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check default filtering
                    if (ShouldCollide(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check user filtering.
                    if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        Destroy(cNuke);
                        continue;
                    }

                    // Clear the filtering flag.
                    c.Flags &= ~ContactFlags.Filter;
                }

                int proxyIdA = fixtureA.Proxies[indexA].ProxyId;
                int proxyIdB = fixtureB.Proxies[indexB].ProxyId;

                bool overlap = BroadPhase.TestOverlap(proxyIdA, proxyIdB);

                // Here we destroy contacts that cease to overlap in the broad-phase.
                if (overlap == false)
                {
                    Contact cNuke = c;
                    Destroy(cNuke);
                    continue;
                }

                // The contact persists.
                c.Update(this);
            }

#if USE_ACTIVE_CONTACT_SET
            ActiveList.Clear();
#endif
        }
示例#6
0
        internal void Collide()
        {
            // Update awake contacts.
            for (int i = 0; i < ContactList.Count; i++)
            {
                Contact c        = ContactList[i];
                Fixture fixtureA = c.FixtureA;
                Fixture fixtureB = c.FixtureB;
                int     indexA   = c.ChildIndexA;
                int     indexB   = c.ChildIndexB;
                Body    bodyA    = fixtureA.Body;
                Body    bodyB    = fixtureB.Body;

                if (bodyA.Awake == false && bodyB.Awake == false)
                {
                    // If one or both of the fixtures are sensors, it is OK that they are not awake.
                    if (!fixtureA.IsSensor && !fixtureB.IsSensor)
                    {
                        continue;
                    }
                }

                // Is this contact flagged for filtering?
                if ((c.Flags & ContactFlags.Filter) == ContactFlags.Filter)
                {
                    // Should these bodies collide?
                    if (bodyB.ShouldCollide(bodyA) == false)
                    {
                        Contact cNuke = c;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check default filtering
                    if (ShouldCollide(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        Destroy(cNuke);
                        continue;
                    }

                    // Check user filtering.
                    if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false)
                    {
                        Contact cNuke = c;
                        Destroy(cNuke);
                        continue;
                    }

                    // Clear the filtering flag.
                    c.Flags &= ~ContactFlags.Filter;
                }

                int proxyIdA = fixtureA.Proxies[indexA].ProxyId;
                int proxyIdB = fixtureB.Proxies[indexB].ProxyId;

                bool overlap = BroadPhase.TestOverlap(proxyIdA, proxyIdB);

                // Here we destroy contacts that cease to overlap in the broad-phase.
                if (overlap == false)
                {
                    Contact cNuke = c;
                    Destroy(cNuke);
                    continue;
                }

                // The contact persists.
                c.Update(this);
            }
        }