/// <summary> /// Creates a new circle collider with the given position and radius. /// </summary> /// <param name="position">the center of the circle</param> /// <param name="radius">the radius of the circle</param> public DCircleCollider(Vector2F position, Fix32 radius, bool isTrigger) : base(ColliderType.Circle, isTrigger) { this.center = position; this.radius = radius; Vector2F min = center - Vector2F.One * radius; Vector2F max = center + Vector2F.One * radius; boundingBox = new DBoxCollider(min, max, isTrigger); }
public bool Intersects(DCollider collider) { DBoxCollider bbox = (collider.Type == ColliderType.Box) ? (DBoxCollider)collider : ((DCircleCollider)collider).BoundingBox; Vector2F min = position; Vector2F max = position + Vector2F.One * size; if (max.x < bbox.Min.x || min.x > bbox.Max.x) { return(false); } if (max.y < bbox.Min.y || min.y > bbox.Max.y) { return(false); } return(true); }
/// <summary> /// Removes the given object from the grid. /// </summary> /// <param name="obj">the rigid body</param> public void Remove(DBody obj) { DBoxCollider box = obj.Collider.GetContainer(); Coord min = Hash(box.Min); Coord max = Hash(box.Max); if (!IsInsideBounds(min) || !IsInsideBounds(max)) { return; } for (int i = min.x; i <= max.x; i++) { for (int j = min.y; j <= max.y; j++) { Remove(obj, i, j); } } }
/// <summary> /// Checks whether the given box collider intersects with this circle, calculating /// the collision data in that case. /// </summary> /// <param name="other">box collider to check</param> /// <param name="intersection">the collision data, <code>null</code> if no collision has been detected.</param> /// <returns>true if the colliders intersect, false otherwise.</returns> public override bool Intersects(DBoxCollider other, out Manifold intersection) { intersection = null; Vector2F halfExtents = other.GetExtents() / 2; Vector2F boxCenter = other.Min + halfExtents; Vector2F difference = center - boxCenter; Vector2F clamped = Vector2F.Clamp(difference, -halfExtents, halfExtents); Vector2F closest = boxCenter + clamped; difference = closest - center; if (difference.SqrtMagnitude > radius * radius) { return(false); } //check if one of them is a trigger if (this.IsTrigger || other.IsTrigger) { intersection = new Manifold(this.Body, other.Body); return(true); } Fix32 dist = difference.Magnitude; Fix32 penetration; Vector2F normal; if (dist > Fix32.Zero) { penetration = radius - dist; normal = difference / dist; } else { penetration = radius; normal = new Vector2F(1, 0); } intersection = new Manifold(this.Body, other.Body, normal, penetration); return(true); }
public override bool Intersects(DBoxCollider other, out Manifold intersection) { throw new NotImplementedException(); }
/// <summary> /// Checks whether the two boxes collide, generating an intersection containing the collision data. /// This function can only compare bounding boxes againsts other bounding boxes. /// </summary> /// <param name="other">bounding box to check</param> /// <param name="intersection">the collision data, <code>null</code> if no collision has been detected.</param> /// <returns></returns> public override bool Intersects(DBoxCollider other, out Manifold intersection) { intersection = null; //check if one of them is a trigger if (this.IsTrigger || other.IsTrigger) { intersection = new Manifold(this.Body, other.Body); return(true); } // Vector from A to B Vector2F distance = other.Body.Position - Body.Position; // Calculate half extents along x axis for each object Fix32 xEntentA = (max.x - min.x) / (Fix32)2; Fix32 xExtentB = (other.max.x - other.min.x) / (Fix32)2; // Calculate overlap on x axis Fix32 offsetX = xEntentA + xExtentB - Fix32.Abs(distance.x); // SAT test on x axis if (offsetX > Fix32.Zero) { // Calculate half extents along x axis for each object Fix32 yExtentA = (max.y - min.y) / (Fix32)2; Fix32 yExtentB = (other.max.y - other.min.y) / (Fix32)2; // Calculate overlap on y axis Fix32 offsetY = yExtentA + yExtentB - Fix32.Abs(distance.y); // SAT test on y axis if (offsetY > Fix32.Zero) { Vector2F n; // Find out which axis is axis of least penetration if (offsetX < offsetY) { // Point towards B knowing that n points from A to B if (distance.x < Fix32.Zero) { n = new Vector2F(-1, 0); } else { n = new Vector2F(1, 0); } intersection = new Manifold(Body, other.Body, n, offsetX); return(true); } else { // Point toward B knowing that n points from A to B if (distance.y < Fix32.Zero) { n = new Vector2F(0, -1); } else { n = new Vector2F(0, 1); } intersection = new Manifold(Body, other.Body, n, offsetY); return(true); } } } return(false); }
/// <summary> /// Abstract function for intersections with boxes. /// </summary> /// <param name="other">box collider.</param> /// <param name="intersection">collision data.</param> /// <returns></returns> public abstract bool Intersects(DBoxCollider other, out Manifold intersection);