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)); } } } }
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); }
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; */ } } }
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); } } }
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); }
public static bool SweptAABB(ColliderPhysics origin, Collider other, out Vector3 normal) { return(SweptAABB(origin, other, origin.Velocity, out normal)); }