Beispiel #1
0
        public void ArbiterRemoved(Arbiter arbiter)
        {
            arbiter.body1.arbiters.Remove(arbiter);
            arbiter.body2.arbiters.Remove(arbiter);

            if (arbiter.body1.island != null)
            {
                arbiter.body1.island.arbiter.Remove(arbiter);
            }
            else if (arbiter.body2.island != null)
            {
                arbiter.body2.island.arbiter.Remove(arbiter);
            }

            RemoveConnection(arbiter.body1, arbiter.body2);
        }
Beispiel #2
0
        public void ArbiterCreated(Arbiter arbiter)
        {
            AddConnection(arbiter.body1, arbiter.body2);

            arbiter.body1.arbiters.Add(arbiter);
            arbiter.body2.arbiters.Add(arbiter);

            if (arbiter.body1.island != null)
            {
                arbiter.body1.island.arbiter.Add(arbiter);
            }
            else if (arbiter.body2.island != null)
            {
                arbiter.body2.island.arbiter.Add(arbiter);
            }
        }
        public void Restore(Arbiter arb)
        {
            arb.body1 = body1;
            arb.body2 = body2;

            arb.contactList.Clear();

            for (index = 0, length = contactList.Count; index < length; index++)
            {
                ContactClone cc = contactList[index];

                Contact contact = Contact.Pool.GetNew();
                cc.Restore(contact);

                arb.contactList.Add(contact);
            }
        }
Beispiel #4
0
        private void UpdateContacts(ArbiterMap selectedArbiterMap)
        {
            foreach (Arbiter arbiter in selectedArbiterMap.Arbiters)
            {
                UpdateArbiterContacts(arbiter);
            }

            while (removedArbiterStack.Count > 0)
            {
                Arbiter arbiter = removedArbiterStack.Pop();
                Arbiter.Pool.GiveBack(arbiter);
                selectedArbiterMap.Remove(arbiter);

                if (selectedArbiterMap == arbiterMap)
                {
                    removedArbiterQueue.Enqueue(arbiter);
                    events.RaiseBodiesEndCollide(arbiter.body1, arbiter.body2);

                    cacheOverPairContact.SetBodies(arbiter.body1, arbiter.body2);
                    Contact.Pool.GiveBack(initialCollisions[cacheOverPairContact]);
                    initialCollisions.Remove(cacheOverPairContact);
                }
                else
                {
                    if (arbiter.body1.isColliderOnly)
                    {
                        events.RaiseTriggerEndCollide(arbiter.body1, arbiter.body2);
                    }
                    else
                    {
                        events.RaiseTriggerEndCollide(arbiter.body2, arbiter.body1);
                    }

                    cacheOverPairContact.SetBodies(arbiter.body1, arbiter.body2);
                    Contact.Pool.GiveBack(initialTriggers[cacheOverPairContact]);
                    initialTriggers.Remove(cacheOverPairContact);
                }
            }
        }
        private void UpdateArbiterContacts(Arbiter arbiter)
        {
            if (arbiter.contactList.Count == 0)
            {
                lock (removedArbiterStack) { removedArbiterStack.Push(arbiter); }
                return;
            }

            for (int i = arbiter.contactList.Count - 1; i >= 0; i--)
            {
                Contact c = arbiter.contactList[i];
                c.UpdatePosition();

                if (c.penetration < -contactSettings.breakThreshold)
                {
                    Contact.Pool.GiveBack(c);
                    arbiter.contactList.RemoveAt(i);
                    continue;
                }
                else
                {
                    TSVector diff; TSVector.Subtract(ref c.p1, ref c.p2, out diff);
                    FP       distance = TSVector.Dot(ref diff, ref c.normal);

                    diff     = diff - distance * c.normal;
                    distance = diff.sqrMagnitude;

                    // hack (multiplication by factor 100) in the
                    // following line.
                    if (distance > contactSettings.breakThreshold * contactSettings.breakThreshold * 100)
                    {
                        Contact.Pool.GiveBack(c);
                        arbiter.contactList.RemoveAt(i);
                        continue;
                    }
                }
            }
        }
        private bool RemoveBody(RigidBody body, bool removeMassPoints)
        {
            // Its very important to clean up, after removing a body
            if (!removeMassPoints && body.IsParticle)
            {
                return(false);
            }

            // remove the body from the world list
            if (!rigidBodies.Remove(body))
            {
                return(false);
            }

            // Remove all connected constraints and arbiters
            for (int index = 0, length = body.arbiters.Count; index < length; index++)
            {
                Arbiter arbiter = body.arbiters[index];

                arbiterMap.Remove(arbiter);

                events.RaiseBodiesEndCollide(arbiter.body1, arbiter.body2);

                cacheOverPairContact.SetBodies(arbiter.body1, arbiter.body2);
                initialCollisions.Remove(cacheOverPairContact);
            }

            for (int index = 0, length = body.arbitersTrigger.Count; index < length; index++)
            {
                Arbiter arbiter = body.arbitersTrigger[index];
                arbiterTriggerMap.Remove(arbiter);

                if (arbiter.body1.isColliderOnly)
                {
                    events.RaiseTriggerEndCollide(arbiter.body1, arbiter.body2);
                }
                else
                {
                    events.RaiseTriggerEndCollide(arbiter.body2, arbiter.body1);
                }

                cacheOverPairContact.SetBodies(arbiter.body1, arbiter.body2);
                initialTriggers.Remove(cacheOverPairContact);
            }

            for (int index = 0, length = body.constraints.Count; index < length; index++)
            {
                Constraint constraint = body.constraints[index];

                constraints.Remove(constraint);
                events.RaiseRemovedConstraint(constraint);
            }

            // remove the body from the collision system
            CollisionSystem.RemoveEntity(body);

            // remove the body from the island manager
            islands.RemoveBody(body);

            events.RaiseRemovedRigidBody(body);

            return(true);
        }
        private void CollisionDetected(RigidBody body1, RigidBody body2, TSVector point1, TSVector point2, TSVector normal, FP penetration)
        {
            bool anyBodyColliderOnly = body1.IsColliderOnly || body2.IsColliderOnly;

            Arbiter    arbiter            = null;
            ArbiterMap selectedArbiterMap = null;

            if (anyBodyColliderOnly)
            {
                selectedArbiterMap = arbiterTriggerMap;
            }
            else
            {
                selectedArbiterMap = arbiterMap;
            }

            bool arbiterCreated = false;

            lock (selectedArbiterMap) {
                selectedArbiterMap.LookUpArbiter(body1, body2, out arbiter);
                if (arbiter == null)
                {
                    arbiter       = Arbiter.Pool.GetNew();
                    arbiter.body1 = body1; arbiter.body2 = body2;
                    selectedArbiterMap.Add(new ArbiterKey(body1, body2), arbiter);

                    arbiterCreated = true;
                }
            }

            Contact contact = null;

            if (arbiter.body1 == body1)
            {
                TSVector.Negate(ref normal, out normal);
                contact = arbiter.AddContact(point1, point2, normal, penetration, contactSettings);
            }
            else
            {
                contact = arbiter.AddContact(point2, point1, normal, penetration, contactSettings);
            }

            if (arbiterCreated)
            {
                if (anyBodyColliderOnly)
                {
                    /*if (body1.isColliderOnly) {
                     *  events.RaiseTriggerBeginCollide(body1, body2);
                     * } else {
                     *  events.RaiseTriggerBeginCollide(body2, body1);
                     * }*/

                    events.RaiseTriggerBeginCollide(contact);

                    body1.arbitersTrigger.Add(arbiter);
                    body2.arbitersTrigger.Add(arbiter);

                    OverlapPairContact overlapContact = new OverlapPairContact(body1, body2);
                    overlapContact.contact = contact;

                    initialTriggers.Add(overlapContact);
                }
                else
                {
                    events.RaiseBodiesBeginCollide(contact);
                    addedArbiterQueue.Enqueue(arbiter);

                    OverlapPairContact overlapContact = new OverlapPairContact(body1, body2);
                    overlapContact.contact = contact;

                    initialCollisions.Add(overlapContact);
                }
            }
            else if (contact != null)
            {
                cacheOverPairContact.SetBodies(body1, body2);
                //if (!initialTriggers.Contains(cacheOverPairContact)) Debug.LogWarning("不包含==========");
                int cacheOverPairContactHashCode = cacheOverPairContact.GetHashCode();
                //cacheOverPairContact.contact = contact;//为什么不在这里这里赋值?因为cacheOverPairContact居然不一定能正确拿到对应在initialTriggers里面的op
                //所以只能在下面循环查找出对应的实例化对象
                for (int index = 0, length = initialTriggers.Count; index < length; index++)
                {
                    OverlapPairContact op = initialTriggers[index];
                    if (op.GetHashCode() == cacheOverPairContactHashCode)
                    {
                        op.contact = contact;
                        //Debug.LogErrorFormat("包含3=====:法向量{0},穿透{1},哈希{2}", op.contact.normal.ToString(), op.contact.Penetration, op.GetHashCode());
                    }
                }
            }

            if (!anyBodyColliderOnly && contact != null)
            {
                events.RaiseContactCreated(contact);
            }
        }
Beispiel #8
0
        public void Restore(IWorld iWorld)
        {
            World world = (World)iWorld;

            List <RigidBody> bodiesToRemove = new List <RigidBody>();

            foreach (RigidBody rb in world.RigidBodies)
            {
                if (!clonedPhysics.ContainsKey(rb.GetInstance()))
                {
                    bodiesToRemove.Add(rb);
                }
            }

            for (index = 0, length = bodiesToRemove.Count; index < length; index++)
            {
                RigidBody rb = bodiesToRemove[index];

                world.RemoveBody(rb);
            }

            foreach (RigidBody rb in world.RigidBodies)
            {
                if (clonedPhysics.ContainsKey(rb.GetInstance()))
                {
                    RigidBodyClone rbClone = clonedPhysics[rb.GetInstance()];
                    rbClone.Restore(world, rb);

                    rb.island = null;
                    rb.arbiters.Clear();
                    rb.arbitersTrigger.Clear();
                }
            }

            foreach (Arbiter arb in world.ArbiterMap.Arbiters)
            {
                for (index = 0, length = arb.contactList.Count; index < length; index++)
                {
                    Contact c = arb.contactList[index];

                    contactsToGiveBack.Add(c);
                }
                arbiterToGiveBack.Add(arb);
            }
            world.ArbiterMap.Clear();

            foreach (Arbiter arb in world.ArbiterTriggerMap.Arbiters)
            {
                foreach (Contact c in arb.contactList)
                {
                    contactsToGiveBack.Add(c);
                }

                arbiterToGiveBack.Add(arb);
            }
            world.ArbiterTriggerMap.Clear();

            for (index = 0, length = world.islands.islands.Count; index < length; index++)
            {
                CollisionIsland ci = world.islands.islands[index];

                collisionIslandToGiveBack.Add(ci);
            }

            for (index = 0, length = clonedArbiters.Count; index < length; index++)
            {
                ArbiterClone arbC = clonedArbiters[index];

                Arbiter arbiter = Arbiter.Pool.GetNew();
                arbC.Restore(arbiter);

                arbiter.body1.arbiters.Add(arbiter);
                arbiter.body2.arbiters.Add(arbiter);

                world.ArbiterMap.lookUpKey.body1 = arbiter.body1;
                world.ArbiterMap.lookUpKey.body2 = arbiter.body2;
                world.ArbiterMap.Add(world.ArbiterMap.lookUpKey.GetHashCode(), arbiter);
            }

            for (index = 0, length = clonedArbitersTrigger.Count; index < length; index++)
            {
                ArbiterClone arbC = clonedArbitersTrigger[index];

                Arbiter arbiter = Arbiter.Pool.GetNew();
                arbC.Restore(arbiter);

                arbiter.body1.arbitersTrigger.Add(arbiter);
                arbiter.body2.arbitersTrigger.Add(arbiter);

                world.ArbiterTriggerMap.lookUpKey.body1 = arbiter.body1;
                world.ArbiterTriggerMap.lookUpKey.body2 = arbiter.body2;
                world.ArbiterTriggerMap.Add(world.ArbiterTriggerMap.lookUpKey.GetHashCode(), arbiter);
            }

            world.islands.islands.Clear();

            for (index = 0, length = collisionIslands.Count; index < length; index++)
            {
                CollisionIslandClone ci = collisionIslands[index];

                CollisionIsland collisionIsland = IslandManager.Pool.GetNew();
                ci.Restore(collisionIsland, world);

                world.islands.islands.Add(collisionIsland);
            }

            cloneCollision.Restore((CollisionSystemPersistentSAP)world.CollisionSystem);

            world.initialCollisions.Clear();
            world.initialCollisions.AddRange(clonedInitialCollisions);

            world.initialTriggers.Clear();
            world.initialTriggers.AddRange(clonedInitialTriggers);

            RigidBody.instanceCount  = rigidBodyInstanceCount;
            Constraint.instanceCount = constraintInstanceCount;

            for (index = 0, length = contactsToGiveBack.Count; index < length; index++)
            {
                Contact obj = contactsToGiveBack[index];

                Contact.Pool.GiveBack(obj);
            }
            contactsToGiveBack.Clear();

            for (index = 0, length = arbiterToGiveBack.Count; index < length; index++)
            {
                Arbiter obj = arbiterToGiveBack[index];

                Arbiter.Pool.GiveBack(obj);
            }
            arbiterToGiveBack.Clear();

            for (index = 0, length = collisionIslandToGiveBack.Count; index < length; index++)
            {
                CollisionIsland obj = collisionIslandToGiveBack[index];

                IslandManager.Pool.GiveBack(obj);
            }
            collisionIslandToGiveBack.Clear();
        }
Beispiel #9
0
        private void CollisionDetected(RigidBody body1, RigidBody body2, TSVector point1, TSVector point2, TSVector normal, FP penetration)
        {
            bool anyBodyColliderOnly = body1.IsColliderOnly || body2.IsColliderOnly;

            Arbiter    arbiter            = null;
            ArbiterMap selectedArbiterMap = null;

            if (anyBodyColliderOnly)
            {
                selectedArbiterMap = arbiterTriggerMap;
            }
            else
            {
                selectedArbiterMap = arbiterMap;
            }

            bool arbiterCreated = false;

            lock (selectedArbiterMap) {
                selectedArbiterMap.LookUpArbiter(body1, body2, out arbiter);
                if (arbiter == null)
                {
                    arbiter       = Arbiter.Pool.GetNew();
                    arbiter.body1 = body1; arbiter.body2 = body2;
                    selectedArbiterMap.Add(new ArbiterKey(body1, body2), arbiter);

                    arbiterCreated = true;
                }
            }

            Contact contact = null;

            if (arbiter.body1 == body1)
            {
                TSVector.Negate(ref normal, out normal);
                contact = arbiter.AddContact(point1, point2, normal, penetration, contactSettings);
            }
            else
            {
                contact = arbiter.AddContact(point2, point1, normal, penetration, contactSettings);
            }

            if (arbiterCreated)
            {
                if (anyBodyColliderOnly)
                {
                    /*if (body1.isColliderOnly) {
                     *  events.RaiseTriggerBeginCollide(body1, body2);
                     * } else {
                     *  events.RaiseTriggerBeginCollide(body2, body1);
                     * }*/

                    events.RaiseTriggerBeginCollide(contact);

                    body1.arbitersTrigger.Add(arbiter);
                    body2.arbitersTrigger.Add(arbiter);

                    OverlapPairContact overlapContact = new OverlapPairContact(body1, body2);
                    overlapContact.contact = contact;

                    initialTriggers.Add(overlapContact);
                }
                else
                {
                    events.RaiseBodiesBeginCollide(contact);
                    addedArbiterQueue.Enqueue(arbiter);

                    OverlapPairContact overlapContact = new OverlapPairContact(body1, body2);
                    overlapContact.contact = contact;

                    initialCollisions.Add(overlapContact);
                }
            }

            if (!anyBodyColliderOnly && contact != null)
            {
                events.RaiseContactCreated(contact);
            }
        }
Beispiel #10
0
 internal void Remove(Arbiter arbiter)
 {
     lookUpKey.SetBodies(arbiter.body1, arbiter.body2);
     dictionaryKeys.Remove(lookUpKey.GetHashCode());
 }
Beispiel #11
0
 internal void Add(int key, Arbiter arbiter)
 {
     dictionaryKeys.Add(key, arbiter);
 }
Beispiel #12
0
 /// <summary>
 /// Gets an arbiter by it's bodies. Not threadsafe.
 /// </summary>
 /// <param name="body1">The first body.</param>
 /// <param name="body2">The second body.</param>
 /// <param name="arbiter">The arbiter which was found.</param>
 /// <returns>Returns true if the arbiter could be found, otherwise false.</returns>
 public bool LookUpArbiter(RigidBody body1, RigidBody body2, out Arbiter arbiter)
 {
     lookUpKey.SetBodies(body1, body2);
     return(dictionaryKeys.TryGetValue(lookUpKey.GetHashCode(), out arbiter));
 }
Beispiel #13
0
 internal void Remove(Arbiter arbiter)
 {
     lookUpKey.SetBodies(arbiter.body1, arbiter.body2);
     keysSortedList.Remove(lookUpKey);
     dictionaryKeys.Remove(lookUpKey);
 }
Beispiel #14
0
 internal void Add(ArbiterKey key, Arbiter arbiter)
 {
     keysSortedList.Add(key);
     dictionaryKeys.Add(key, arbiter);
 }