Пример #1
0
        ///<summary>
        /// Updates the manifold.
        ///</summary>
        ///<param name="dt">Timestep duration.</param>
        public override void Update(float dt)
        {
            //Now, generate a contact between the two shapes.
            float               distance;
            Vector3             axis;
            BoxContactDataCache manifold;

            if (BoxBoxCollider.AreBoxesColliding(boxA.Shape, boxB.Shape, ref boxA.worldTransform, ref boxB.worldTransform, out distance, out axis, out manifold))
            {
                unsafe
                {
                    BoxContactData *manifoldPointer = &manifold.D1;
                    Vector3.Negate(ref axis, out axis);
                    var toRemove = new TinyList <int>();
                    for (int i = 0; i < contacts.Count; i++)
                    {
                        bool found = false;
                        for (int j = manifold.Count - 1; j >= 0; j--)
                        {
                            if (contacts.Elements[i].Id == manifoldPointer[j].Id)
                            {
                                found = true;
                                contacts.Elements[i].Validate();
                                //Update contact...
                                contacts.Elements[i].Position         = manifoldPointer[j].Position;
                                contacts.Elements[i].PenetrationDepth = -manifoldPointer[j].Depth;
                                contacts.Elements[i].Normal           = axis;
                                //Remove manifold entry
                                contacts.Elements[i].Validate();
                                manifold.RemoveAt(j);
                                break;
                            }
                        }
                        if (!found)
                        {//No match found
                            toRemove.Add(i);
                        }
                    }


                    //toRemove is sorted by increasing index.  Go backwards along it so that the indices are valid all the way through.
                    for (int i = toRemove.Count - 1; i >= 0; i--)
                    {
                        Remove(toRemove[i]);
                    }

                    //Add new contacts.
                    for (int i = 0; i < manifold.Count; i++)
                    {
                        var newContact = new ContactData
                        {
                            Position         = manifoldPointer[i].Position,
                            PenetrationDepth = -manifoldPointer[i].Depth,
                            Normal           = axis,
                            Id = manifoldPointer[i].Id
                        };

                        Add(ref newContact);
                    }
                }
            }
            else
            {
                //Not colliding, so get rid of it.
                for (int i = contacts.Count - 1; i >= 0; i--)
                {
                    Remove(i);
                }
            }
        }
Пример #2
0
        public override void Update(float dt)
        {
            //Now, generate a contact between the two shapes.
            float   distance;
            Vector3 axis;
            var     manifold = new TinyStructList <BoxContactData>();

            if (BoxBoxCollider.AreBoxesColliding(boxA.Shape, boxB.Shape, ref boxA.worldTransform, ref boxB.worldTransform, out distance, out axis, out manifold))
            {
                Vector3.Negate(ref axis, out axis);
                TinyList <int> toRemove = new TinyList <int>();
                BoxContactData data;
                for (int i = 0; i < contacts.Count; i++)
                {
                    bool found = false;
                    for (int j = manifold.Count - 1; j >= 0; j--)
                    {
                        manifold.Get(j, out data);
                        if (contacts.Elements[i].Id == data.Id)
                        {
                            found = true;
                            //Update contact...
                            contacts.Elements[i].Position         = data.Position;
                            contacts.Elements[i].PenetrationDepth = -data.Depth;
                            contacts.Elements[i].Normal           = axis;
                            contacts.Elements[i].Validate();
                            //Remove manifold entry
                            manifold.RemoveAt(j);
                            break;
                        }
                    }
                    if (!found)
                    {//No match found
                        toRemove.Add(i);
                    }
                }

                ////Go through the indices to remove.
                ////For each one, replace the removal index with a contact in the new manifold.
                //int removalIndex;
                //for (removalIndex = toRemove.count - 1; removalIndex >= 0 && manifold.count > 0; removalIndex--)
                //{
                //    int indexToReplace = toRemove[removalIndex];
                //    toRemove.RemoveAt(removalIndex);
                //    manifold.Get(manifold.count - 1, out data);
                //    //Update contact...
                //    contacts.Elements[indexToReplace].Position = data.Position;
                //    contacts.Elements[indexToReplace].PenetrationDepth = -data.Depth;
                //    contacts.Elements[indexToReplace].Normal = axis;
                //    contacts.Elements[indexToReplace].Id = data.Id;
                //    //Remove manifold entry
                //    manifold.RemoveAt(manifold.count - 1);

                //}

                //Alright, we ran out of contacts to replace (if, in fact, toRemove isn't empty now).  Just remove the remainder.
                //toRemove is sorted by increasing index.  Go backwards along it so that the indices are valid all the way through.
                for (int i = toRemove.Count - 1; i >= 0; i--)
                {
                    Remove(toRemove[i]);
                }

                //Add new contacts.
                for (int i = 0; i < manifold.Count; i++)
                {
                    manifold.Get(i, out data);
                    ContactData newContact = new ContactData();
                    newContact.Position         = data.Position;
                    newContact.PenetrationDepth = -data.Depth;
                    newContact.Normal           = axis;
                    newContact.Id = data.Id;

                    Add(ref newContact);
                }
            }
            else
            {
                //Not colliding, so get rid of it.
                for (int i = contacts.Count - 1; i >= 0; i--)
                {
                    Remove(i);
                }
            }
        }