Optimized lightsource raycasts
This commit is contained in:
@@ -70,6 +70,8 @@ namespace Barotrauma.Lights
|
|||||||
public SegmentPoint Start;
|
public SegmentPoint Start;
|
||||||
public SegmentPoint End;
|
public SegmentPoint End;
|
||||||
|
|
||||||
|
public bool IsHorizontal;
|
||||||
|
|
||||||
public Segment(SegmentPoint start, SegmentPoint end)
|
public Segment(SegmentPoint start, SegmentPoint end)
|
||||||
{
|
{
|
||||||
Start = start;
|
Start = start;
|
||||||
@@ -77,6 +79,8 @@ namespace Barotrauma.Lights
|
|||||||
|
|
||||||
start.Segment = this;
|
start.Segment = this;
|
||||||
end.Segment = this;
|
end.Segment = this;
|
||||||
|
|
||||||
|
IsHorizontal = Math.Abs(start.Pos.X - end.Pos.X) > Math.Abs(start.Pos.Y - end.Pos.Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ namespace Barotrauma.Lights
|
|||||||
|
|
||||||
foreach (Segment s in segments)
|
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)
|
if (intersection != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -208,98 +208,110 @@ namespace Barotrauma
|
|||||||
return a1 + t * b;
|
return a1 + t * b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static Vector2? GetAxisAlignedLineIntersection(Vector2 a1, Vector2 a2, Vector2 axisAligned1, Vector2 axisAligned2, bool isHorizontal)
|
||||||
/// 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)
|
|
||||||
{
|
{
|
||||||
if (Math.Abs(axisAligned1.X - axisAligned2.X) < 1.0f)
|
if (!isHorizontal)
|
||||||
{
|
{
|
||||||
if (Math.Sign(a1.X - axisAligned1.X) == Math.Sign(a2.X - axisAligned1.X))
|
if (Math.Sign(a1.X - axisAligned1.X) == Math.Sign(a2.X - axisAligned1.X))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (Math.Max(a1.Y, a2.Y) < Math.Min(axisAligned1.Y, axisAligned2.Y))
|
float s = (a2.Y - a1.Y) / (a2.X - a1.X);
|
||||||
return null;
|
float y = a1.Y + (axisAligned1.X - a1.X) * s;
|
||||||
|
|
||||||
if (Math.Min(a1.Y, a2.Y) > Math.Max(axisAligned1.Y, axisAligned2.Y))
|
if (axisAligned1.Y < axisAligned2.Y)
|
||||||
return null;
|
{
|
||||||
|
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))
|
if (Math.Sign(a1.Y - axisAligned1.Y) == Math.Sign(a2.Y - axisAligned1.Y))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (Math.Max(a1.X, a2.X) < Math.Min(axisAligned1.X, axisAligned2.X))
|
float s = (a2.X - a1.X) / (a2.Y - a1.Y);
|
||||||
return null;
|
float x = a1.X + (axisAligned1.Y - a1.Y) * s;
|
||||||
|
|
||||||
if (Math.Min(a1.X, a2.X) > Math.Max(axisAligned1.X, axisAligned2.X))
|
if (axisAligned1.X < axisAligned2.X)
|
||||||
return null;
|
{
|
||||||
|
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)
|
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.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),
|
||||||
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)
|
public static List<Vector2> GetLineRectangleIntersections(Vector2 a1, Vector2 a2, Rectangle rect)
|
||||||
{
|
{
|
||||||
List<Vector2> intersections = new List<Vector2>();
|
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.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),
|
||||||
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);
|
if (intersection != null) intersections.Add((Vector2)intersection);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user