示例#1
0
        public void ComputeCollision(Collider collider)
        {
            if (!ComputedCollision.ContainsKey(collider) || !collider.Collidable)
            {
                return;
            }

            Pair <Collider> test_pair = new Pair <Collider>(collider, null);

            IEnumerable <Cell> to_test;

            ColliderPhysics colliderPhy = null;
            Vector2         velocity    = Vector2.Zero;

            if (collider is ColliderPhysics)
            {
                colliderPhy = collider as ColliderPhysics;
                velocity    = colliderPhy.Velocity * GameCore.DeltaTime;
                to_test     = GetCells(GetTransformVelocity(colliderPhy.WorldTransform, velocity));
            }
            else
            {
                to_test = GetCells(collider.WorldTransform);
            }

            foreach (Cell cell in to_test)
            {
                foreach (Collider other in cell.Colliders)
                {
                    test_pair.second = other;

                    if (collider == other || !other.Collidable || CollisionPair.Contains(test_pair))
                    {
                        continue;
                    }

                    if (colliderPhy.IsNotNull())
                    {
                        if (SweptAABB(colliderPhy, other, velocity, out Vector3 normal))
                        {
                            ComputedCollision[collider].Add(other);
                            ComputedCollision[other].Add(collider);
                            CollisionPair.Add(new Pair <Collider>(collider, other, normal));
                        }
                    }
                    else if (collider.WorldTransform.IntersectBox(other.WorldTransform))
                    {
                        ComputedCollision[collider].Add(other);
                        ComputedCollision[other].Add(collider);
                        CollisionPair.Add(new Pair <Collider>(collider, other));
                    }
                }
            }
        }
示例#2
0
 public override void OnAdded(Scene scene)
 {
     base.OnAdded(scene);
     Add(new Sprite(Scene.Resources.Get <Texture2D>("target_dummy"), true, 0, null, new Vector2(-Scene.Resources.Get <Texture2D>("target_dummy").Width / 2, -Scene.Resources.Get <Texture2D>("target_dummy").Height / 2)));
     collider = new ColliderPhysics(
         new Transform(
             -Scene.Resources.Get <Texture2D>("target_dummy").Width / 2,
             -Scene.Resources.Get <Texture2D>("target_dummy").Height / 2,
             Scene.Resources.Get <Texture2D>("target_dummy").Width,
             Scene.Resources.Get <Texture2D>("target_dummy").Height),
         0.5f, null, 0.5f);
     Add(collider);
 }
示例#3
0
        private void UpdatePhysics()
        {
            foreach (Collider collider in ColliderList)
            {
                if (collider is ColliderPhysics && collider.Active && !collider.Static)
                {
                    ColliderPhysics colliderPhy = collider as ColliderPhysics;

                    colliderPhy.Velocity += (colliderPhy.Acceleration - colliderPhy.Friction * colliderPhy.Velocity) * GameCore.DeltaTime;

                    /*
                     * if (colliderPhy.Velocity.X < 0.01f && colliderPhy.Velocity.X > -0.01f)
                     *  colliderPhy.Velocity.X = 0;
                     * if (colliderPhy.Velocity.Y < 0.01f && colliderPhy.Velocity.Y > -0.01f)
                     *  colliderPhy.Velocity.Y = 0;
                     */
                }
            }
        }
示例#4
0
        public void Update()
        {
            CollisionPair.Clear();

            foreach (HashSet <Collider> collider_list in ComputedCollision.Values)
            {
                collider_list.Clear();
            }

            UpdatePhysics();

            foreach (Collider collider in ColliderList)
            {
                if (collider.Changed)
                {
                    List <Cell> next_cell = new List <Cell>(GetCells(collider.WorldTransform));

                    TempRemove(collider);

                    foreach (Cell cell in next_cell)
                    {
                        cell.Colliders.Add(collider);
                    }

                    // OR

                    // ForEach((cell) => { if (cell.Colliders.Contains(collider)) { cell.Colliders.Remove(collider); } );
                    // GetCells(collider.WorldTransform).ForEach((cell) => { if (!cell.Colliders.Contains(collider)) cell.Colliders.Add(collider); } ));
                }

                ComputeCollision(collider);
            }

            foreach (Pair <Collider> pair in CollisionPair)
            {
                if (pair.first is ColliderPhysics)
                {
                    ColliderPhysics pairFirst = pair.first as ColliderPhysics;
                    Vector3         data      = (Vector3)pair.UserData;

                    if (pair.second.Solid)
                    {
                        pairFirst.Entity.WorldPosition += pairFirst.Velocity * GameCore.DeltaTime * (data.Z);

                        //data.Z.Printl();
                        pairFirst.Velocity = Vector2.Zero;

                        /*
                         * "Velocity : ".Print();
                         * pairFirst.Velocity.Printl();
                         * "Position : ".Print();
                         * pairFirst.WorldTransform.Printl();
                         * "Time : ".Print();
                         * data.Z.Printl();
                         */
                    }
                    pair.first.OnCollide(pair.second, data);
                    pair.second.OnCollide(pair.first, -data);
                }
                else
                {
                    pair.first.OnCollide(pair.second);
                    pair.second.OnCollide(pair.first);
                }
            }

            foreach (Collider collider in ColliderList)
            {
                if (collider is ColliderPhysics)
                {
                    Vector2 move = (collider as ColliderPhysics).Velocity * GameCore.DeltaTime;

                    (collider as ColliderPhysics).Entity.WorldPosition.X += (float)Math.Round(move.X);
                    (collider as ColliderPhysics).Entity.WorldPosition.Y += (float)Math.Round(move.Y);
                }
            }
        }
示例#5
0
        public static bool SweptAABB(ColliderPhysics origin, Collider other, Vector2 velocity, out Vector3 normal)
        {
            Vector2 invEntry, invExit, entry, exit;

            if (velocity.X > 0)
            {
                invEntry.X = other.WorldTransform.Left - origin.WorldTransform.Right;
                invExit.X  = other.WorldTransform.Right - origin.WorldTransform.Left;
            }
            else
            {
                invEntry.X = other.WorldTransform.Right - origin.WorldTransform.Left;
                invExit.X  = other.WorldTransform.Left - origin.WorldTransform.Right;
            }

            if (velocity.Y > 0)
            {
                invEntry.Y = other.WorldTransform.Top - origin.WorldTransform.Bottom;
                invExit.Y  = other.WorldTransform.Bottom - origin.WorldTransform.Top;
            }
            else
            {
                invEntry.Y = other.WorldTransform.Bottom - origin.WorldTransform.Top;
                invExit.Y  = other.WorldTransform.Top - origin.WorldTransform.Bottom;
            }

            if (Math.Abs(velocity.X) < 0.00001f)
            {
                entry.X = float.MinValue;
                exit.X  = float.MaxValue;
            }
            else
            {
                entry.X = invEntry.X / velocity.X;
                exit.X  = invExit.X / velocity.X;
            }

            if (Math.Abs(velocity.Y) < 0.00001f)
            {
                entry.Y = float.MinValue;
                exit.Y  = float.MaxValue;
            }
            else
            {
                entry.Y = invEntry.Y / velocity.Y;
                exit.Y  = invExit.Y / velocity.Y;
            }

            if (entry.Y > 1.0f)
            {
                entry.Y = float.MinValue;
            }
            if (entry.X > 1.0f)
            {
                entry.X = float.MinValue;
            }

            var entryTime = Math.Max(entry.X, entry.Y);
            var exitTime  = Math.Min(exit.X, exit.Y);

            if (
                (entryTime > exitTime || entry.X < 0.0f && entry.Y < 0.0f) ||
                (entry.X < 0.0f && (origin.WorldTransform.Right < other.WorldTransform.Left || origin.WorldTransform.Left > other.WorldTransform.Right)) ||
                entry.Y < 0.0f && (origin.WorldTransform.Bottom < other.WorldTransform.Top || origin.WorldTransform.Top > other.WorldTransform.Bottom))
            {
                normal = Vector3.Zero;
                return(false);
            }

            Vector2 to_normal;

            if (entry.X > entry.Y)
            {
                to_normal = (invEntry.X < 0.0f) || (Math.Abs(invEntry.X) < 0.00001f && invExit.X < 0) ? Vector2.UnitX : -Vector2.UnitX;
            }
            else
            {
                to_normal = (invEntry.Y < 0.0f || (Math.Abs(invEntry.Y) < 0.00001f && invExit.Y < 0)) ? Vector2.UnitY : -Vector2.UnitY;
            }

            normal = new Vector3(to_normal.X, to_normal.Y, entryTime);

            return(true);
        }
示例#6
0
 public static bool SweptAABB(ColliderPhysics origin, Collider other, out Vector3 normal)
 {
     return(SweptAABB(origin, other, origin.Velocity, out normal));
 }