Example #1
0
 public Arbiter(SequentialImpulsesSolver parent, Body body1, Body body2)
 {
     if (body1.ID < body2.ID)
     {
         this.body1 = body1;
         this.body2 = body2;
     }
     else
     {
         this.body1 = body2;
         this.body2 = body1;
     }
     this.tag1     = (SequentialImpulsesTag)this.body1.SolverTag;
     this.tag2     = (SequentialImpulsesTag)this.body2.SolverTag;
     this.circle1  = this.body1.Shape as CircleShape;
     this.circle2  = this.body2.Shape as CircleShape;
     this.friction = MathHelper.Sqrt(
         this.body1.Coefficients.DynamicFriction *
         this.body2.Coefficients.DynamicFriction);
     this.restitution = Math.Min(body1.Coefficients.Restitution, body2.Coefficients.Restitution);
     this.parent      = parent;
     this.contacts    = new LinkedList <ContactPoint>();
     this.lastUpdate  = -1;
     this.state       = ContactState.New;
     this.ignoresCollisionResponse = body1.IgnoresCollisionResponse || body2.IgnoresCollisionResponse;
 }
Example #2
0
        protected internal override void Solve(TimeStep step)
        {
            foreach (Arbiter arb in arbiters.Values)
            {
                arb.Updated = false;
            }
            Detect(step);
            RemoveEmpty();
            this.Engine.RunLogic(step);
            for (int index = 0; index < tags.Count; ++index)
            {
                SequentialImpulsesTag tag = tags[index];
                tag.biasVelocity = ALVector2D.Zero;
                tag.body.UpdateVelocity(step);
                tag.body.ClearForces();
            }

            Arbiter[] arbs = new Arbiter[arbiters.Count];
            arbiters.Values.CopyTo(arbs, 0);
            for (int index = 0; index < arbs.Length; ++index)
            {
                arbs[index].PreApply(step.DtInv);
            }
            for (int index = 0; index < siJoints.Count; ++index)
            {
                siJoints[index].PreStep(step);
            }
            for (int i = 0; i < iterations; ++i)
            {
                for (int index = 0; index < arbs.Length; ++index)
                {
                    arbs[index].Apply();
                }
                for (int index = 0; index < siJoints.Count; ++index)
                {
                    siJoints[index].ApplyImpulse();
                }
            }
            for (int index = 0; index < tags.Count; ++index)
            {
                SequentialImpulsesTag tag = tags[index];
                if (splitImpulse)
                {
                    tag.body.UpdatePosition(step, ref tag.biasVelocity);
                }
                else
                {
                    tag.body.UpdatePosition(step);
                }
            }
        }
Example #3
0
 protected internal override void AddBodyRange(List <Body> collection)
 {
     foreach (Body item in collection)
     {
         if (item.SolverTag == null)
         {
             SequentialImpulsesTag tag = new SequentialImpulsesTag(item);
             SetTag(item, tag);
             tags.Add(tag);
         }
         else
         {
             tags.Add((SequentialImpulsesTag)item.SolverTag);
         }
     }
 }
Example #4
0
 public Arbiter(SequentialImpulsesSolver parent, Body body1, Body body2)
 {
     if (body1.ID < body2.ID)
     {
         this.body1 = body1;
         this.body2 = body2;
     }
     else
     {
         this.body1 = body2;
         this.body2 = body1;
     }
     this.tag1     = (SequentialImpulsesTag)this.body1.SolverTag;
     this.tag2     = (SequentialImpulsesTag)this.body2.SolverTag;
     this.circle1  = this.body1.Shape as CircleShape;
     this.circle2  = this.body2.Shape as CircleShape;
     this.friction = MathHelper.Sqrt(
         this.body1.Coefficients.DynamicFriction *
         this.body2.Coefficients.DynamicFriction);
     this.restitution = Math.Min(body1.Coefficients.Restitution, body2.Coefficients.Restitution);
     this.parent      = parent;
     this.contacts    = new LinkedList <Contact>();
 }
Example #5
0
        protected internal override void Solve(TimeStep step)
        {
            Detect(step);
            Arbiter[] arbs = RemoveEmpty(step);
            this.Engine.RunLogic(step);
            if (freezing)
            {
                for (int index = 0; index < siJoints.Count; ++index)
                {
                    siJoints[index].CheckFrozen();
                }
            }
            for (int index = 0; index < tags.Count; ++index)
            {
                SequentialImpulsesTag tag = tags[index];
                tag.biasVelocity = ALVector2D.Zero;

                if (freezing)
                {
                    bool accelSame = tag.body.State.Acceleration == tag.lastAccel;

                    ALVector2D vel   = tag.body.State.Velocity;
                    ALVector2D force = tag.body.State.ForceAccumulator;


                    bool isVelZero =
                        Math.Abs(vel.X) < freezeVelocityTolerance.X &&
                        Math.Abs(vel.Y) < freezeVelocityTolerance.Y &&
                        Math.Abs(vel.Angular) < freezeVelocityTolerance.Angular;
                    bool isForceZero = tag.body.State.ForceAccumulator == ALVector2D.Zero;


                    if (accelSame && isVelZero && isForceZero)
                    {
                        if (tag.body.Joints.Count == 0)
                        {
                            tag.body.idleCount++;
                        }
                        if (tag.body.idleCount > freezeTimeout)
                        {
                            tag.body.idleCount      = freezeTimeout;
                            tag.body.IsFrozen       = true;
                            tag.body.State.Velocity = ALVector2D.Zero;
                        }
                    }
                    else
                    {
                        tag.body.IsFrozen  = false;
                        tag.body.idleCount = 0;
                    }
                    tag.lastAccel = tag.body.State.Acceleration;
                    if (tag.body.IsFrozen)
                    {
                        tag.body.State.ForceAccumulator = ALVector2D.Zero;
                        tag.body.State.Acceleration     = ALVector2D.Zero;
                    }
                }

                tag.body.UpdateVelocity(step);
                tag.body.ClearForces();
            }
            for (int index = 0; index < arbs.Length; ++index)
            {
                arbs[index].PreApply(step.DtInv);
            }
            for (int index = 0; index < siJoints.Count; ++index)
            {
                siJoints[index].PreStep(step);
            }
            for (int i = 0; i < iterations; ++i)
            {
                for (int index = 0; index < arbs.Length; ++index)
                {
                    arbs[index].Apply();
                }
                for (int index = 0; index < siJoints.Count; ++index)
                {
                    siJoints[index].ApplyImpulse();
                }
            }
            for (int index = 0; index < tags.Count; ++index)
            {
                SequentialImpulsesTag tag = tags[index];
                if (splitImpulse)
                {
                    tag.body.UpdatePosition(step, ref tag.biasVelocity);
                }
                else
                {
                    tag.body.UpdatePosition(step);
                }
                tag.body.ApplyPosition();
            }
        }
Example #6
0
 static bool IsTagRemoved(SequentialImpulsesTag tag)
 {
     return(!tag.body.IsAdded);
 }
Example #7
0
 protected internal override void AddBodyRange(List<Body> collection)
 {
     foreach (Body item in collection)
     {
         if (item.SolverTag == null)
         {
             SequentialImpulsesTag tag = new SequentialImpulsesTag(item);
             SetTag(item, tag);
             tags.Add(tag);
         }
         else
         {
             tags.Add((SequentialImpulsesTag)item.SolverTag);
         }
     }
 }
Example #8
0
 static bool IsTagRemoved(SequentialImpulsesTag tag)
 {
     return !tag.body.IsAdded;
 }
Example #9
0
 public Arbiter(SequentialImpulsesSolver parent, Body body1, Body body2)
 {
     if (body1.ID < body2.ID)
     {
         this.body1 = body1;
         this.body2 = body2;
     }
     else
     {
         this.body1 = body2;
         this.body2 = body1;
     }
     this.tag1 = (SequentialImpulsesTag)this.body1.SolverTag;
     this.tag2 = (SequentialImpulsesTag)this.body2.SolverTag;
     this.circle1 = this.body1.Shape as CircleShape;
     this.circle2 = this.body2.Shape as CircleShape;
     this.friction = MathHelper.Sqrt(
             this.body1.Coefficients.DynamicFriction *
             this.body2.Coefficients.DynamicFriction);
     this.restitution = Math.Min(body1.Coefficients.Restitution, body2.Coefficients.Restitution);
     this.parent = parent;
     this.contacts = new LinkedList<ContactPoint>();
     this.lastUpdate = -1;
     this.state = ContactState.New;
     this.ignoresCollisionResponse = body1.IgnoresCollisionResponse || body2.IgnoresCollisionResponse;
 }