Exemplo n.º 1
0
        ///<summary>
        /// Updates the pair handler's contacts.
        ///</summary>
        ///<param name="dt">Timestep duration.</param>
        protected virtual void UpdateContacts(float dt)
        {
            UpdateContainedPairs();
            //Eliminate old pairs.
            foreach (CollidablePair pair in subPairs.Keys)
            {
                if (!containedPairs.Contains(pair))
                {
                    pairsToRemove.Add(pair);
                }
            }
            for (int i = 0; i < pairsToRemove.Count; i++)
            {
                CollidablePairHandler toReturn = subPairs[pairsToRemove.Elements[i]];
                subPairs.Remove(pairsToRemove.Elements[i]);
                toReturn.CleanUp();
                toReturn.Factory.GiveBack(toReturn);
            }
            containedPairs.Clear();
            pairsToRemove.Clear();

            foreach (CollidablePairHandler pair in subPairs.Values)
            {
                if (pair.BroadPhaseOverlap.collisionRule < CollisionRule.NoNarrowPhaseUpdate) //Don't test if the collision rules say don't.
                {
                    pair.UpdateCollision(dt);
                }
            }
        }
        ///<summary>
        /// Constructs a new nonconvex manifold constraint.
        ///</summary>
        public NonConvexContactManifoldConstraint(CollidablePairHandler pairHandler)
            : base(pairHandler)
        {
            //All of the constraints are always in the solver group.  Some of them are just deactivated sometimes.
            //This reduces some bookkeeping complications.

            penetrationConstraints = new RawList <ContactPenetrationConstraint>(4);
            frictionConstraints    = new RawList <ContactFrictionConstraint>(4);

            for (int i = 0; i < 4; i++)
            {
                var penetrationConstraint = new ContactPenetrationConstraint();
                penetrationConstraintPool.Push(penetrationConstraint);
                Add(penetrationConstraint);

                var frictionConstraint = new ContactFrictionConstraint();
                frictionConstraintPool.Push(frictionConstraint);
                Add(frictionConstraint);
            }
        }
Exemplo n.º 3
0
 internal void RemovePair(CollidablePairHandler pair, ref int index)
 {
     if (pairs.Count > index)
     {
         pairs.FastRemoveAt(index);
         if (pairs.Count > index)
         {
             var endPair = pairs.Elements[index];
             if (endPair.CollidableA == this)
             {
                 endPair.listIndexA = index;
             }
             else
             {
                 endPair.listIndexB = index;
             }
         }
     }
     index = -1;
 }
        ///<summary>
        /// Constructs a new convex contact manifold constraint.
        ///</summary>
        public ConvexContactManifoldConstraint(CollidablePairHandler pairHandler)
            : base(pairHandler)
        {
            //All of the constraints are always in the solver group.  Some of them are just deactivated sometimes.
            //This reduces some bookkeeping complications.


            penetrationConstraints = new RawList <ContactPenetrationConstraint>(4);


            //Order matters in this adding process.  Sliding friction computes some information used by the twist friction, and both use penetration impulses.
            for (int i = 0; i < 4; i++)
            {
                var penetrationConstraint = new ContactPenetrationConstraint();
                Add(penetrationConstraint);
                penetrationConstraintPool.Push(penetrationConstraint);
            }
            slidingFriction = new SlidingFrictionTwoAxis();
            Add(slidingFriction);
            twistFriction = new TwistFrictionConstraint();
            Add(twistFriction);
        }
Exemplo n.º 5
0
 static bool DefaultCCDFilter(CollidablePairHandler pair)
 {
     return(pair.broadPhaseOverlap.collisionRule < CollisionRule.NoSolver);
 }
Exemplo n.º 6
0
 internal void AddPair(CollidablePairHandler pair, ref int index)
 {
     index = pairs.Count;
     pairs.Add(pair);
 }
Exemplo n.º 7
0
 protected ContactManifoldConstraint(CollidablePairHandler pairHandler)
 {
     this.pair = pairHandler;
 }
Exemplo n.º 8
0
 internal ContactCollection(CollidablePairHandler pair)
 {
     this.pair = pair;
 }
        /// <summary>
        /// Takes a collision pair and distributes its contacts into categories according to the categorizer's thresholds.
        /// </summary>
        /// <param name="pair">Source of the contacts to categorize.</param>
        /// <param name="characterCollidable">Collidable associated with the character.</param>
        /// <param name="downDirection">Down direction of the character.</param>
        /// <param name="tractionContacts">List to contain the traction contacts found in the input contacts list.</param>
        /// <param name="supportContacts">List to contain the support contacts found in the input contacts list.</param>
        /// <param name="sideContacts">List to contain the side contacts found in the input contacts list.</param>
        /// <param name="headContacts">List to contain the head contacts found in the input contacts list.</param>
        /// <typeparam name="TOutputContacts">List type used to store the output character contact structs.</typeparam>
        public void CategorizeContacts <TOutputContacts>(CollidablePairHandler pair, EntityCollidable characterCollidable, ref Vector3 downDirection,
                                                         ref TOutputContacts tractionContacts, ref TOutputContacts supportContacts, ref TOutputContacts sideContacts, ref TOutputContacts headContacts)
            where TOutputContacts : IList <CharacterContact>
        {
            var contactCollection = pair.Contacts;

            for (int i = pair.ContactCount - 1; i >= 0; --i)
            {
                var contactInfo = contactCollection[i];
                CharacterContact characterContact;
                characterContact.Contact    = new ContactData(contactInfo.Contact);
                characterContact.Collidable = pair.CollidableA == characterCollidable ? pair.CollidableB : pair.CollidableA;

                //It's possible that a subpair has a non-normal collision rule, even if the parent pair is normal.
                //Note that only contacts with nonnegative penetration depths are used.
                //Negative depth contacts are 'speculative' in nature.
                //If we were to use such a speculative contact for support, the character would find supports
                //in situations where it should not.
                //This can actually be useful in some situations, but keep it disabled by default.
                if (contactInfo.Pair.CollisionRule != CollisionRule.Normal || characterContact.Contact.PenetrationDepth < 0)
                {
                    continue;
                }

                float   dot;
                Vector3 offset;
                Vector3.Subtract(ref characterContact.Contact.Position, ref characterCollidable.worldTransform.Position, out offset);
                Vector3.Dot(ref characterContact.Contact.Normal, ref offset, out dot);
                if (dot < 0)
                {
                    //The normal should face outward.
                    Vector3.Negate(ref characterContact.Contact.Normal, out characterContact.Contact.Normal);
                }

                Vector3.Dot(ref characterContact.Contact.Normal, ref downDirection, out dot);
                if (dot > SupportThreshold)
                {
                    //It's a support.
                    supportContacts.Add(characterContact);
                    if (dot > TractionThreshold)
                    {
                        //It's a traction contact.
                        tractionContacts.Add(characterContact);
                    }
                    else
                    {
                        //Considering the side contacts to be supports can help with upstepping.
                        sideContacts.Add(characterContact);
                    }
                }
                else if (dot < HeadThreshold)
                {
                    //It's a head contact.
                    headContacts.Add(characterContact);
                }
                else
                {
                    //It's a side contact.  These could obstruct the stepping.
                    sideContacts.Add(characterContact);
                }
            }
        }