Optimized lightsource raycasts
This commit is contained in:
@@ -70,6 +70,8 @@ namespace Barotrauma.Lights
|
||||
public SegmentPoint Start;
|
||||
public SegmentPoint End;
|
||||
|
||||
public bool IsHorizontal;
|
||||
|
||||
public Segment(SegmentPoint start, SegmentPoint end)
|
||||
{
|
||||
Start = start;
|
||||
@@ -77,6 +79,8 @@ namespace Barotrauma.Lights
|
||||
|
||||
start.Segment = this;
|
||||
end.Segment = this;
|
||||
|
||||
IsHorizontal = Math.Abs(start.Pos.X - end.Pos.X) > Math.Abs(start.Pos.Y - end.Pos.Y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -377,10 +377,10 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
float closestDist = 0.0f;
|
||||
Vector2? closestIntersection = null;
|
||||
|
||||
|
||||
foreach (Segment s in segments)
|
||||
{
|
||||
Vector2? intersection = MathUtils.GetAxisAlignedLineIntersection(rayStart, rayEnd, s.Start.WorldPos, s.End.WorldPos);
|
||||
Vector2? intersection = MathUtils.GetAxisAlignedLineIntersection(rayStart, rayEnd, s.Start.WorldPos, s.End.WorldPos, s.IsHorizontal);
|
||||
|
||||
if (intersection != null)
|
||||
{
|
||||
|
||||
@@ -207,99 +207,111 @@ namespace Barotrauma
|
||||
|
||||
return a1 + t * b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the point where line segment (a1, a2) intersects the axis-aligned line segment (axisAligned1, axisAligned2)
|
||||
/// </summary>
|
||||
public static Vector2? GetAxisAlignedLineIntersection(Vector2 a1, Vector2 a2, Vector2 axisAligned1, Vector2 axisAligned2)
|
||||
|
||||
public static Vector2? GetAxisAlignedLineIntersection(Vector2 a1, Vector2 a2, Vector2 axisAligned1, Vector2 axisAligned2, bool isHorizontal)
|
||||
{
|
||||
if (Math.Abs(axisAligned1.X - axisAligned2.X) < 1.0f)
|
||||
if (!isHorizontal)
|
||||
{
|
||||
if (Math.Sign(a1.X - axisAligned1.X) == Math.Sign(a2.X - axisAligned1.X))
|
||||
return null;
|
||||
|
||||
if (Math.Max(a1.Y, a2.Y) < Math.Min(axisAligned1.Y, axisAligned2.Y))
|
||||
return null;
|
||||
float s = (a2.Y - a1.Y) / (a2.X - a1.X);
|
||||
float y = a1.Y + (axisAligned1.X - a1.X) * s;
|
||||
|
||||
if (Math.Min(a1.Y, a2.Y) > Math.Max(axisAligned1.Y, axisAligned2.Y))
|
||||
return null;
|
||||
if (axisAligned1.Y < axisAligned2.Y)
|
||||
{
|
||||
if (y < axisAligned1.Y) return null;
|
||||
if (y > axisAligned2.Y) return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y > axisAligned1.Y) return null;
|
||||
if (y < axisAligned2.Y) return null;
|
||||
}
|
||||
|
||||
return new Vector2(axisAligned1.X, y);
|
||||
}
|
||||
else
|
||||
else //horizontal line
|
||||
{
|
||||
if (Math.Sign(a1.Y - axisAligned1.Y) == Math.Sign(a2.Y - axisAligned1.Y))
|
||||
return null;
|
||||
|
||||
if (Math.Max(a1.X, a2.X) < Math.Min(axisAligned1.X, axisAligned2.X))
|
||||
return null;
|
||||
float s = (a2.X - a1.X) / (a2.Y - a1.Y);
|
||||
float x = a1.X + (axisAligned1.Y - a1.Y) * s;
|
||||
|
||||
if (Math.Min(a1.X, a2.X) > Math.Max(axisAligned1.X, axisAligned2.X))
|
||||
return null;
|
||||
if (axisAligned1.X < axisAligned2.X)
|
||||
{
|
||||
if (x < axisAligned1.X) return null;
|
||||
if (x > axisAligned2.X) return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x > axisAligned1.X) return null;
|
||||
if (x < axisAligned2.X) return null;
|
||||
}
|
||||
|
||||
return new Vector2(x, axisAligned1.Y);
|
||||
}
|
||||
|
||||
Vector2 b = a2 - a1;
|
||||
Vector2 d = axisAligned2 - axisAligned1;
|
||||
float bDotDPerp = b.X * d.Y - b.Y * d.X;
|
||||
|
||||
Vector2 c = axisAligned1 - a1;
|
||||
float t = (c.X * d.Y - c.Y * d.X) / bDotDPerp;
|
||||
if (t < 0 || t > 1) return null;
|
||||
|
||||
float u = (c.X * b.Y - c.Y * b.X) / bDotDPerp;
|
||||
if (u < 0 || u > 1) return null;
|
||||
|
||||
return a1 + t * b;
|
||||
}
|
||||
|
||||
public static Vector2? GetLineRectangleIntersection(Vector2 a1, Vector2 a2, Rectangle rect)
|
||||
{
|
||||
Vector2? intersection = GetLineIntersection(a1, a2,
|
||||
Vector2? intersection = GetAxisAlignedLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y),
|
||||
new Vector2(rect.Right, rect.Y));
|
||||
|
||||
if (intersection != null) return intersection;
|
||||
|
||||
intersection = GetLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y-rect.Height),
|
||||
new Vector2(rect.Right, rect.Y-rect.Height));
|
||||
|
||||
if (intersection != null) return intersection;
|
||||
|
||||
intersection = GetLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y),
|
||||
new Vector2(rect.X, rect.Y - rect.Height));
|
||||
|
||||
if (intersection != null) return intersection;
|
||||
|
||||
return GetLineIntersection(a1, a2,
|
||||
new Vector2(rect.Right, rect.Y),
|
||||
new Vector2(rect.Right, rect.Y - rect.Height));
|
||||
true);
|
||||
|
||||
if (intersection != null) return intersection;
|
||||
|
||||
intersection = GetAxisAlignedLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y-rect.Height),
|
||||
new Vector2(rect.Right, rect.Y-rect.Height),
|
||||
true);
|
||||
|
||||
if (intersection != null) return intersection;
|
||||
|
||||
intersection = GetAxisAlignedLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y),
|
||||
new Vector2(rect.X, rect.Y - rect.Height),
|
||||
false);
|
||||
|
||||
if (intersection != null) return intersection;
|
||||
|
||||
return GetAxisAlignedLineIntersection(a1, a2,
|
||||
new Vector2(rect.Right, rect.Y),
|
||||
new Vector2(rect.Right, rect.Y - rect.Height),
|
||||
false);
|
||||
}
|
||||
|
||||
public static List<Vector2> GetLineRectangleIntersections(Vector2 a1, Vector2 a2, Rectangle rect)
|
||||
{
|
||||
List<Vector2> intersections = new List<Vector2>();
|
||||
|
||||
Vector2? intersection = GetLineIntersection(a1, a2,
|
||||
Vector2? intersection = GetAxisAlignedLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y),
|
||||
new Vector2(rect.Right, rect.Y));
|
||||
|
||||
if (intersection != null) intersections.Add((Vector2)intersection);
|
||||
|
||||
intersection = GetLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y - rect.Height),
|
||||
new Vector2(rect.Right, rect.Y - rect.Height));
|
||||
|
||||
if (intersection != null) intersections.Add((Vector2)intersection);
|
||||
|
||||
intersection = GetLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y),
|
||||
new Vector2(rect.X, rect.Y - rect.Height));
|
||||
|
||||
if (intersection != null) intersections.Add((Vector2)intersection);
|
||||
|
||||
intersection = GetLineIntersection(a1, a2,
|
||||
new Vector2(rect.Right, rect.Y),
|
||||
new Vector2(rect.Right, rect.Y - rect.Height));
|
||||
true);
|
||||
|
||||
if (intersection != null) intersections.Add((Vector2)intersection);
|
||||
|
||||
intersection = GetAxisAlignedLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y - rect.Height),
|
||||
new Vector2(rect.Right, rect.Y - rect.Height),
|
||||
true);
|
||||
|
||||
if (intersection != null) intersections.Add((Vector2)intersection);
|
||||
|
||||
intersection = GetAxisAlignedLineIntersection(a1, a2,
|
||||
new Vector2(rect.X, rect.Y),
|
||||
new Vector2(rect.X, rect.Y - rect.Height),
|
||||
false);
|
||||
|
||||
if (intersection != null) intersections.Add((Vector2)intersection);
|
||||
|
||||
intersection = GetAxisAlignedLineIntersection(a1, a2,
|
||||
new Vector2(rect.Right, rect.Y),
|
||||
new Vector2(rect.Right, rect.Y - rect.Height),
|
||||
false);
|
||||
|
||||
if (intersection != null) intersections.Add((Vector2)intersection);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user