38f1ddb...178a853: v0.8.9.1, removed content folder

This commit is contained in:
Joonas Rikkonen
2019-03-18 19:46:58 +02:00
parent 38f1ddb6fe
commit 6c0679c297
1054 changed files with 151673 additions and 144931 deletions
@@ -1,10 +1,11 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using Barotrauma.Extensions;
namespace Barotrauma
{
//TODO: perhaps find a better place for this?
//TODO: Currently this is only used for text positioning? -> move there?
[Flags]
public enum Alignment
{
@@ -21,6 +22,27 @@ namespace Barotrauma
return (i % n + n) % n;
}
public static double Distance(double x1, double y1, double x2, double y2)
{
double dX = x1 - x2;
double dY = y1 - y2;
return Math.Sqrt(dX * dX + dY * dY);
}
public static double DistanceSquared(double x1, double y1, double x2, double y2)
{
double dX = x1 - x2;
double dY = y1 - y2;
return dX * dX + dY * dY;
}
public static int DistanceSquared(int x1, int y1, int x2, int y2)
{
int dX = x1 - x2;
int dY = y1 - y2;
return dX * dX + dY * dY;
}
public static Vector2 SmoothStep(Vector2 v1, Vector2 v2, float amount)
{
return new Vector2(
@@ -31,13 +53,18 @@ namespace Barotrauma
public static Vector2 ClampLength(this Vector2 v, float length)
{
float currLength = v.Length();
if (v.Length() > length)
if (currLength > length)
{
return v / currLength * length;
}
return v;
}
public static bool Contains(this Rectangle rect, double x, double y)
{
return x > rect.X && x < rect.Right && y > rect.Y && y < rect.Bottom;
}
public static float Round(float value, float div)
{
return (value < 0.0f) ?
@@ -217,101 +244,116 @@ namespace Barotrauma
}
// a1 is line1 start, a2 is line1 end, b1 is line2 start, b2 is line2 end
public static Vector2? GetLineIntersection(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2)
public static bool GetLineIntersection(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2, out Vector2 intersection)
{
intersection = Vector2.Zero;
Vector2 b = a2 - a1;
Vector2 d = b2 - b1;
float bDotDPerp = b.X * d.Y - b.Y * d.X;
// if b dot d == 0, it means the lines are parallel so have infinite intersection points
if (bDotDPerp == 0) return null;
if (bDotDPerp == 0) return false;
Vector2 c = b1 - a1;
float t = (c.X * d.Y - c.Y * d.X) / bDotDPerp;
if (t < 0 || t > 1) return null;
if (t < 0 || t > 1) return false;
float u = (c.X * b.Y - c.Y * b.X) / bDotDPerp;
if (u < 0 || u > 1) return null;
if (u < 0 || u > 1) return false;
return a1 + t * b;
intersection = a1 + t * b;
return true;
}
public static Vector2? GetAxisAlignedLineIntersection(Vector2 a1, Vector2 a2, Vector2 axisAligned1, Vector2 axisAligned2, bool isHorizontal)
public static bool GetAxisAlignedLineIntersection(Vector2 a1, Vector2 a2, Vector2 axisAligned1, Vector2 axisAligned2, bool isHorizontal, out Vector2 intersection)
{
intersection = Vector2.Zero;
if (!isHorizontal)
{
if (Math.Sign(a1.X - axisAligned1.X) == Math.Sign(a2.X - axisAligned1.X))
return null;
float xDiff = axisAligned1.X - a1.X;
if (Math.Sign(xDiff) == Math.Sign(axisAligned1.X - a2.X)) { return false; }
float s = (a2.Y - a1.Y) / (a2.X - a1.X);
float y = a1.Y + (axisAligned1.X - a1.X) * s;
float y = a1.Y + xDiff * s;
if (axisAligned1.Y < axisAligned2.Y)
{
if (y < axisAligned1.Y) return null;
if (y > axisAligned2.Y) return null;
if (y < axisAligned1.Y) return false;
if (y > axisAligned2.Y) return false;
}
else
{
if (y > axisAligned1.Y) return null;
if (y < axisAligned2.Y) return null;
if (y > axisAligned1.Y) return false;
if (y < axisAligned2.Y) return false;
}
return new Vector2(axisAligned1.X, y);
intersection = new Vector2(axisAligned1.X, y);
return true;
}
else //horizontal line
{
if (Math.Sign(a1.Y - axisAligned1.Y) == Math.Sign(a2.Y - axisAligned1.Y))
return null;
float yDiff = axisAligned1.Y - a1.Y;
if (Math.Sign(yDiff) == Math.Sign(axisAligned1.Y - a2.Y)) { return false; }
float s = (a2.X - a1.X) / (a2.Y - a1.Y);
float x = a1.X + (axisAligned1.Y - a1.Y) * s;
float x = a1.X + yDiff * s;
if (axisAligned1.X < axisAligned2.X)
{
if (x < axisAligned1.X) return null;
if (x > axisAligned2.X) return null;
if (x < axisAligned1.X) return false;
if (x > axisAligned2.X) return false;
}
else
{
if (x > axisAligned1.X) return null;
if (x < axisAligned2.X) return null;
if (x > axisAligned1.X) return false;
if (x < axisAligned2.X) return false;
}
return new Vector2(x, axisAligned1.Y);
intersection = new Vector2(x, axisAligned1.Y);
return true;
}
}
public static Vector2? GetLineRectangleIntersection(Vector2 a1, Vector2 a2, Rectangle rect)
public static bool GetLineRectangleIntersection(Vector2 a1, Vector2 a2, Rectangle rect, out Vector2 intersection)
{
Vector2? intersection = GetAxisAlignedLineIntersection(a1, a2,
if (GetAxisAlignedLineIntersection(a1, a2,
new Vector2(rect.X, rect.Y),
new Vector2(rect.Right, rect.Y),
true);
true, out intersection))
{
return true;
}
if (intersection != null) return intersection;
intersection = GetAxisAlignedLineIntersection(a1, a2,
if (GetAxisAlignedLineIntersection(a1, a2,
new Vector2(rect.X, rect.Y-rect.Height),
new Vector2(rect.Right, rect.Y-rect.Height),
true);
true, out intersection))
{
return true;
}
if (intersection != null) return intersection;
intersection = GetAxisAlignedLineIntersection(a1, a2,
if(GetAxisAlignedLineIntersection(a1, a2,
new Vector2(rect.X, rect.Y),
new Vector2(rect.X, rect.Y - rect.Height),
false);
false, out intersection))
{
return true;
}
if (intersection != null) return intersection;
return GetAxisAlignedLineIntersection(a1, a2,
if (GetAxisAlignedLineIntersection(a1, a2,
new Vector2(rect.Right, rect.Y),
new Vector2(rect.Right, rect.Y - rect.Height),
false);
false, out intersection))
{
return true;
}
return 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>();
@@ -344,6 +386,91 @@ namespace Barotrauma
if (intersection != null) intersections.Add((Vector2)intersection);
return intersections;
}*/
/// <summary>
/// Get the intersections between a line (either infinite or a line segment) and a circle
/// </summary>
/// <param name="circlePos">Center of the circle</param>
/// <param name="radius">Radius of the circle</param>
/// <param name="point1">1st point on the line</param>
/// <param name="point2">2nd point on the line</param>
/// <param name="isLineSegment">Is the line a segment or infinite</param>
/// <returns>The number of intersections</returns>
public static int GetLineCircleIntersections(Vector2 circlePos, float radius,
Vector2 point1, Vector2 point2, bool isLineSegment, out Vector2? intersection1, out Vector2? intersection2)
{
float dx, dy, A, B, C, det;
dx = point2.X - point1.X;
dy = point2.Y - point1.Y;
A = dx * dx + dy * dy;
B = 2 * (dx * (point1.X - circlePos.X) + dy * (point1.Y - circlePos.Y));
C = (point1.X - circlePos.X) * (point1.X - circlePos.X) + (point1.Y - circlePos.Y) * (point1.Y - circlePos.Y) - radius * radius;
det = B * B - 4 * A * C;
if ((A <= 0.0000001) || (det < 0))
{
// No real solutions.
intersection1 = null;
intersection2 = null;
return 0;
}
else if (det == 0)
{
// One solution.
float t = -B / (2 * A);
intersection1 = new Vector2(point1.X + t * dx, point1.Y + t * dy);
intersection2 = null;
return 1;
}
else
{
// Two solutions.
float t1 = (float)((-B + Math.Sqrt(det)) / (2 * A));
float t2 = (float)((-B - Math.Sqrt(det)) / (2 * A));
//if the line is not infinite, we need to check if the intersections are on the segment
if (isLineSegment)
{
if (t1 >= 0 && t1 <= 1.0f)
{
intersection1 = point1 + new Vector2(dx, dy) * t1;
if (t2 >= 0 && t2 <= 1.0f)
{
//both intersections on the segment
intersection2 = point1 + new Vector2(dx, dy) * t2;
return 2;
}
//only the first intersection is on the segment
intersection2 = null;
return 1;
}
else if (t2 >= 0 && t2 <= 1.0f)
{
//only the second intersection is on the segment
intersection1 = point1 + new Vector2(dx, dy) * t2;
intersection2 = null;
return 1;
}
else
{
//neither is on the segment
intersection1 = null;
intersection2 = null;
return 0;
}
}
else
{
intersection1 = point1 + new Vector2(dx, dy) * t1;
intersection2 = point1 + new Vector2(dx, dy) * t2;
return 2;
}
}
}
public static float LineToPointDistance(Vector2 lineA, Vector2 lineB, Vector2 point)
@@ -358,29 +485,26 @@ namespace Barotrauma
return (float)(Math.Abs(xDiff * (lineA.Y - point.Y) - yDiff * (lineA.X - point.X)) /
Math.Sqrt(xDiff * xDiff + yDiff * yDiff));
}
}
public static bool CircleIntersectsRectangle(Vector2 circlePos, float radius, Rectangle rect)
{
float xDist = Math.Abs(circlePos.X - rect.Center.X);
float yDist = Math.Abs(circlePos.Y - rect.Center.Y);
int halfWidth = rect.Width / 2;
float xDist = Math.Abs(circlePos.X - (rect.X + halfWidth));
if (xDist > halfWidth + radius) { return false; }
int halfHeight = rect.Height / 2;
if (xDist > (halfWidth + radius)) { return false; }
if (yDist > (halfHeight + radius)) { return false; }
float yDist = Math.Abs(circlePos.Y - (rect.Y + halfHeight));
if (yDist > halfHeight + radius) { return false; }
if (xDist <= (halfWidth)) { return true; }
if (yDist <= (halfHeight)) { return true; }
if (xDist <= halfWidth || yDist <= halfHeight) { return true; }
float distSqX = xDist - halfWidth;
float distSqY = yDist - halfHeight;
return (distSqX * distSqX + distSqY * distSqY <= (radius * radius));
return distSqX * distSqX + distSqY * distSqY <= radius * radius;
}
/// <summary>
/// divide a convex hull into triangles
/// </summary>
@@ -449,13 +573,13 @@ namespace Barotrauma
return wrappedPoints;
}
public static List<Vector2[]> GenerateJaggedLine(Vector2 start, Vector2 end, int generations, float offsetAmount)
public static List<Vector2[]> GenerateJaggedLine(Vector2 start, Vector2 end, int iterations, float offsetAmount)
{
List<Vector2[]> segments = new List<Vector2[]>();
segments.Add(new Vector2[] { start, end });
for (int n = 0; n < generations; n++)
for (int n = 0; n < iterations; n++)
{
for (int i = 0; i < segments.Count; i++)
{
@@ -475,6 +599,8 @@ namespace Barotrauma
i++;
}
offsetAmount *= 0.5f;
}
return segments;
@@ -574,6 +700,155 @@ namespace Barotrauma
}
}*/
}
/// <summary>
/// Float comparison. Note that may still fail in some cases.
/// </summary>
// References:
// http://floating-point-gui.de/errors/comparison/
// https://stackoverflow.com/questions/3874627/floating-point-comparison-functions-for-c-sharp
public static bool NearlyEqual(float a, float b, float epsilon = 0.0001f)
{
float diff = Math.Abs(a - b);
if (a == b)
{
// shortcut, handles infinities
return true;
}
else if (a == 0 || b == 0 || diff < float.Epsilon)
{
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < epsilon;
}
else
{
// use relative error
return diff / (Math.Abs(a) + Math.Abs(b)) < epsilon;
}
}
/// Returns a position in a curve.
/// </summary>
public static Vector2 Bezier(Vector2 start, Vector2 control, Vector2 end, float t)
{
return Pow(1 - t, 2) * start + 2 * t * (1 - t) * control + Pow(t, 2) * end;
}
public static float Pow(float f, float p)
{
return (float)Math.Pow(f, p);
}
/// <summary>
/// Rotates a point in 2d space around another point.
/// Modified from:
/// http://www.gamefromscratch.com/post/2012/11/24/GameDev-math-recipes-Rotating-one-point-around-another-point.aspx
/// </summary>
public static Vector2 RotatePointAroundTarget(Vector2 point, Vector2 target, float degrees, bool clockWise = true)
{
// (Math.PI / 180) * degrees
var angle = MathHelper.ToRadians(degrees);
var sin = Math.Sin(angle);
var cos = Math.Cos(angle);
if (!clockWise)
{
sin = -sin;
}
Vector2 dir = point - target;
var x = (cos * dir.X) - (sin * dir.Y) + target.X;
var y = (sin * dir.X) + (cos * dir.Y) + target.Y;
return new Vector2((float)x, (float)y);
}
/// <summary>
/// Returns the corners of an imaginary rectangle.
/// Unlike the XNA rectangle, this can be rotated with the up parameter.
/// </summary>
public static Vector2[] GetImaginaryRect(Vector2 up, Vector2 center, Vector2 size)
{
return GetImaginaryRect(new Vector2[4], up, center, size);
}
/// <summary>
/// Returns the corners of an imaginary rectangle.
/// Unlike the XNA Rectangle, this can be rotated with the up parameter.
/// </summary>
public static Vector2[] GetImaginaryRect(Vector2[] corners, Vector2 up, Vector2 center, Vector2 size)
{
if (corners.Length != 4)
{
throw new Exception("Invalid length for the corners array. Must be 4.");
}
Vector2 halfSize = size / 2;
Vector2 left = up.Right();
corners[0] = center + up * halfSize.Y + left * halfSize.X;
corners[1] = center + up * halfSize.Y - left * halfSize.X;
corners[2] = center - up * halfSize.Y - left * halfSize.X;
corners[3] = center - up * halfSize.Y + left * halfSize.X;
return corners;
}
/// <summary>
/// Check if a point is inside a rectangle.
/// Unlike the XNA Rectangle, this rectangle might have been rotated.
/// For XNA Rectangles, use the Contains instance method.
/// </summary>
public static bool RectangleContainsPoint(Vector2[] corners, Vector2 point)
{
if (corners.Length != 4)
{
throw new Exception("Invalid length of the corners array! Must be 4");
}
return RectangleContainsPoint(corners[0], corners[1], corners[2], corners[3], point);
}
/// <summary>
/// Check if a point is inside a rectangle.
/// Unlike the XNA Rectangle, this rectangle might have been rotated.
/// For XNA Rectangles, use the Contains instance method.
/// </summary>
public static bool RectangleContainsPoint(Vector2 c1, Vector2 c2, Vector2 c3, Vector2 c4, Vector2 point)
{
return TriangleContainsPoint(c1, c2, c3, point) || TriangleContainsPoint(c1, c3, c4, point);
}
/// <summary>
/// Slightly modified from https://gamedev.stackexchange.com/questions/110229/how-do-i-efficiently-check-if-a-point-is-inside-a-rotated-rectangle
/// </summary>
public static bool TriangleContainsPoint(Vector2 c1, Vector2 c2, Vector2 c3, Vector2 point)
{
// Compute vectors
Vector2 v0 = c3 - c1;
Vector2 v1 = c2 - c1;
Vector2 v2 = point - c1;
// Compute dot products
float dot00 = Vector2.Dot(v0, v0);
float dot01 = Vector2.Dot(v0, v1);
float dot02 = Vector2.Dot(v0, v2);
float dot11 = Vector2.Dot(v1, v1);
float dot12 = Vector2.Dot(v1, v2);
// Compute barycentric coordinates
float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
// Check if the point is in triangle
return u >= 0 && v >= 0 && (u + v) < 1;
}
/// <summary>
/// Returns a scalar t from a value v between a range from min to max. Clamped between 0 and 1.
/// </summary>
public static float InverseLerp(float min, float max, float v)
{
float diff = max - min;
// Ensure that we don't get division by zero exceptions.
if (diff == 0) { return v >= max ? 1f : 0f; }
return MathHelper.Clamp((v - min) / diff, 0f, 1f);
}
}
class CompareCCW : IComparer<Vector2>