public bool CastRay( Vector2 origin, Vector2 normal, float distance, T attributes, out Raycast hit) { hit = default; if (IsCollidable) { var tileSize = TileSize.ToVector2(); var gStart = origin.ToGrid(tileSize, AbsolutePosition); var gEnd = (origin + normal * distance).ToGrid(tileSize, AbsolutePosition); foreach (var location in PlotLine(gStart, gEnd)) { var tile = GetTileShape(location); var hitDetected = tile?.CastRay(origin, normal, distance, out hit) ?? false; if (hitDetected && HasTags(location, attributes)) { return(true); } } } return(false); }
public static bool CastRay( Vector2 origin, Vector2 normal, float distance, Shape shape, out Raycast hit) { hit = default; if (shape is Circle) { return(CastRay(origin, normal, distance, shape as Circle, out hit)); } var vertices = shape.GetVertices(); var polyNorms = vertices.Normalize(); var polyNorm = Vector2.Zero; var minDist = 0f; var maxDist = distance; for (int i = 0; i < vertices.Length; i++) { var num = Vector2.Dot(polyNorms[i], vertices[i] - origin); var denom = Vector2.Dot(polyNorms[i], normal); if (denom == 0f && num < 0f) { return(false); } if (denom < 0f && num < minDist * denom) { minDist = num / denom; polyNorm = polyNorms[i]; } else if (denom > 0f && num < maxDist * denom) { maxDist = num / denom; } if (maxDist < minDist) { return(false); } } if (polyNorm != Vector2.Zero) { hit.Contact = origin + normal * minDist; hit.Normal = polyNorm; hit.Depth = distance - minDist; hit.Percent = minDist.Divide(distance); hit.Distance = minDist; return(true); } return(false); }
static bool CastRay( Vector2 origin, Vector2 normal, float distance, Circle circ, out Raycast hit) { hit = default; var m = origin - circ.Center; var b = Vector2.Dot(m, normal); var c = Vector2.Dot(m, m) - circ.Radius * circ.Radius; if (b > 0f && c > 0f) { return(false); } var discr = b * b - c; if (discr < 0f) { return(false); } var depth = -b - discr.Sqrt(); if (depth.Between(0f, distance)) { var contact = origin + normal * depth; hit.Contact = contact; hit.Normal = Vector2.Normalize(contact - circ.Center); hit.Depth = distance - depth; hit.Percent = depth.Divide(distance); hit.Distance = depth; return(true); } return(false); }
public virtual bool CastRay(Vector2 origin, Vector2 normal, float distance, out Raycast hit) { hit = default; return(IsCollidable); }
public bool CastRay(Vector2 origin, Vector2 normal, float distance, out Raycast hit) { return(Collision.CastRay(origin, normal, distance, this, out hit)); }
public sealed override bool CastRay(Vector2 origin, Vector2 normal, float distance, out Raycast hit) { return(base.CastRay(origin, normal, distance, out hit) && Shape.CastRay(origin, normal, distance, out hit)); }
public sealed override bool CastRay(Vector2 origin, Vector2 normal, float distance, out Raycast hit) { if (base.CastRay(origin, normal, distance, out hit)) { var tileSize = TileSize.ToVector2(); var gStart = origin.ToGrid(tileSize, AbsolutePosition); var gEnd = (origin + normal * distance).ToGrid(tileSize, AbsolutePosition); foreach (var location in PlotLine(gStart, gEnd)) { var tile = GetTileShape(location); var hitDetected = tile?.CastRay(origin, normal, distance, out hit) ?? false; if (hitDetected) { return(true); } } } return(false); }