Exemple #1
0
 public void Remove(Rib rib)
 {
     if (times.ContainsKey(rib))
     {
         rib.Collision.times.Remove(self);
         times.Remove(rib);
     }
 }
Exemple #2
0
 public Rib(Rib other)
 {
     speed  = other.speed;
     pos0   = other.pos0;
     pos1   = other.pos1;
     time0  = other.time0;
     time1  = other.time1;
     sprite = other.sprite;
 }
Exemple #3
0
        public double GetTime(Rib rib)
        {
            double res;

            if (!times.TryGetValue(rib, out res))
            {
                throw new KeyNotFoundException(string.Format("the rib {0} is not found", rib.Sprite.Id));
            }
            return(res);
        }
Exemple #4
0
        public void Clip(List <Rib> ribs)
        {
            var    radius = sprite.Radius;
            bool   hit    = false;
            double poshit = 0.0;

            if (speed.X < 0)
            {
                if (pos1.X < radius)
                {
                    hit    = true;
                    poshit = radius;
                }
            }
            else if (pos1.X > U.WX - radius)
            {
                hit    = true;
                poshit = U.WX - radius;
            }
            if (hit)
            {
                // clipped by X
                double thit = (poshit - pos0.X) / speed.X;
                Rib    next = Split(thit);
                next.setSpeed(new Vec(-speed.X, speed.Y));
                next.Clip(ribs);
                ribs.Add(next);
                hit = false;
            }

            if (speed.Y < 0)
            {
                if (pos1.Y < radius)
                {
                    hit    = true;
                    poshit = radius;
                }
            }
            else if (pos1.Y > U.WY - radius)
            {
                hit    = true;
                poshit = U.WY - radius;
            }
            if (hit)
            {
                double thit = (poshit - pos0.Y) / speed.Y;
                Rib    next = Split(thit);
                next.setSpeed(new Vec(speed.X, -speed.Y));
                next.Clip(ribs);
                ribs.Add(next);
                hit = false;
            }
        }
Exemple #5
0
        public Rib Split(double deltat)
        {
            Rib next = new Rib(this);

            next.pos0  = pos0.Add(speed.Scale(deltat));
            next.pos1  = pos1;
            pos1       = next.pos0;
            next.time0 = time0 + deltat;
            next.time1 = time1;
            time1      = next.time0;
            return(next);
        }
Exemple #6
0
        public Rib GetFirstHit(out double time)
        {
            Rib rib = null;

            time = 0.0;
            foreach (KeyValuePair <Rib, double> kv in times)
            {
                if (rib == null || kv.Value < time)
                {
                    rib  = kv.Key;
                    time = kv.Value;
                }
            }
            return(rib);
        }
Exemple #7
0
        public RibRect(Rib r)
        {
            var radius = r.Sprite.Radius;

            min = r.StartPos;
            max = r.EndPos;
            if (max.X < min.X)
            {
                var t = max.X;
                max.X = min.X;
                min.X = t;
            }
            if (max.Y < min.Y)
            {
                var t = max.Y;
                max.Y = min.Y;
                min.Y = t;
            }
            min.X -= radius;
            min.Y -= radius;
            max.X += radius;
            max.Y += radius;
        }
Exemple #8
0
        public bool CollidesWith(Rib rib, out double hittime)
        {
            // we are working in the reference frame of this.pos0, moving with the speed this.speed
            Vec    ribpos = rib.pos0.Subtract(pos0);
            Vec    ribspd = rib.speed.Subtract(speed);
            double time   = time0;

            if (time0 < rib.time0)
            {
                // correct the position
                time   = rib.time0;
                ribpos = ribpos.Subtract(speed.Scale(time - time0));
            }
            else if (time0 > rib.time0)
            {
                ribpos = ribpos.Add(rib.speed.Scale(time - rib.time0));
            }
            var spd2 = ribspd.Length2;

            if (spd2 <= 0.00001)
            {
                hittime = 0;
                return(false);
            }
            // Let's only find the closest position
            // Xclose = X - (X*V)*V / (V*V)
            // Tclose = -(X*V) / (V*V)
            hittime = -ribpos.Scalar(ribspd) / spd2;
            if (hittime < time ||
                hittime > time1 ||
                hittime > rib.time1)
            {
                return(false);
            }
            return(true);
        }
Exemple #9
0
 public static int CompareByTime(Rib a, Rib b)
 {
     return(a.time0.CompareTo(b.time0));
 }
Exemple #10
0
 public int CompareTo(Rib r)
 {
     return(pos0.X < r.pos0.X ? -1 : (pos0.X > r.pos0.X ? 1 : 0));
 }
Exemple #11
0
 private static bool matchRibNull(Rib rib)
 {
     return(rib == null || rib.Sprite == null);
 }
Exemple #12
0
        public void Run(double dt)
        {
            List <Collision> collisions = new List <Collision>();

            foreach (Rib rib in ribs)
            {
                if (rib.Collision.Fill(ribs))
                {
                    collisions.Add(rib.Collision);
                }
            }

            while (collisions.Count > 0)
            {
                U.show(string.Format("Total {0} collisions", collisions.Count));

                // run through all collisions
                Collision first     = null;
                double    firsttime = 0.0;
                Rib       firstrib  = null;
                foreach (var coll in collisions)
                {
                    if (coll == null || coll.IsEmpty || coll.SelfRib == null)
                    {
                        continue;
                    }
                    double time;
                    Rib    rib = coll.GetFirstHit(out time);
                    if (rib == null)
                    {
                        throw new Exception("the collection must have a hit");
                    }
                    if (first == null || time < firsttime)
                    {
                        first     = coll;
                        firsttime = time;
                        firstrib  = rib;
                    }
                }
                if (first == null)
                {
                    break;
                }
                U.show(string.Format("first collision time found: {0}", firsttime));
                List <Rib> moreribs = applyCollision(first, firstrib, dt);
                if (moreribs != null)
                {
                    // we have more ribs
                    foreach (Rib rib in moreribs)
                    {
                        if (rib.Collision.Fill(ribs))
                        {
                            collisions.Add(rib.Collision);
                        }
                    }
                    ribs.AddRange(moreribs);
                }
            }

            // finally, cleanup ribs
            ribs.RemoveAll(rib => rib == null || rib.Sprite == null);
            ribs.Sort(compareRibsByEndTime);
        }
Exemple #13
0
        /*
         * private static int compareRibRectsByX(RibRect a, RibRect b) {
         *      return a.min.X.CompareTo(b.min.X);
         * }
         */

        private static int compareRibsByEndTime(Rib a, Rib b)
        {
            return(a.EndTime.CompareTo(b.EndTime));
        }
Exemple #14
0
 public Collision(Rib rib)
 {
     self  = rib;
     rect  = new RibRect(rib);
     times = new Dictionary <Rib, double>();
 }
Exemple #15
0
 public void Update(Rib rib)
 {
     Position = rib.EndPos;
     Speed    = rib.Speed;
     alpha   += omega * rib.DeltaTime;
 }