Server job assigning logic, submarine movement syncing, submarine collision improvements, spawnpoints in levels

This commit is contained in:
Regalis
2015-07-08 11:37:47 +03:00
parent 3af9b8183b
commit d56f7f3f77
155 changed files with 39772 additions and 261 deletions
@@ -0,0 +1,143 @@
using System.Collections.Generic;
using Microsoft.Xna.Framework;
namespace FarseerPhysics.Common.ConvexHull
{
/// <summary>
/// Andrew's Monotone Chain Convex Hull algorithm.
/// Used to get the convex hull of a point cloud.
///
/// Source: http://www.softsurfer.com/Archive/algorithm_0109/algorithm_0109.htm
/// </summary>
public static class ChainHull
{
//Copyright 2001, softSurfer (www.softsurfer.com)
private static PointComparer _pointComparer = new PointComparer();
/// <summary>
/// Returns the convex hull from the given vertices..
/// </summary>
public static Vertices GetConvexHull(Vertices vertices)
{
if (vertices.Count <= 3)
return vertices;
Vertices pointSet = new Vertices(vertices);
//Sort by X-axis
pointSet.Sort(_pointComparer);
Vector2[] h = new Vector2[pointSet.Count];
Vertices res;
int top = -1; // indices for bottom and top of the stack
int i; // array scan index
// Get the indices of points with min x-coord and min|max y-coord
const int minmin = 0;
float xmin = pointSet[0].X;
for (i = 1; i < pointSet.Count; i++)
{
if (pointSet[i].X != xmin)
break;
}
// degenerate case: all x-coords == xmin
int minmax = i - 1;
if (minmax == pointSet.Count - 1)
{
h[++top] = pointSet[minmin];
if (pointSet[minmax].Y != pointSet[minmin].Y) // a nontrivial segment
h[++top] = pointSet[minmax];
h[++top] = pointSet[minmin]; // add polygon endpoint
res = new Vertices(top + 1);
for (int j = 0; j < top + 1; j++)
{
res.Add(h[j]);
}
return res;
}
top = -1;
// Get the indices of points with max x-coord and min|max y-coord
int maxmax = pointSet.Count - 1;
float xmax = pointSet[pointSet.Count - 1].X;
for (i = pointSet.Count - 2; i >= 0; i--)
{
if (pointSet[i].X != xmax)
break;
}
int maxmin = i + 1;
// Compute the lower hull on the stack H
h[++top] = pointSet[minmin]; // push minmin point onto stack
i = minmax;
while (++i <= maxmin)
{
// the lower line joins P[minmin] with P[maxmin]
if (MathUtils.Area(pointSet[minmin], pointSet[maxmin], pointSet[i]) >= 0 && i < maxmin)
continue; // ignore P[i] above or on the lower line
while (top > 0) // there are at least 2 points on the stack
{
// test if P[i] is left of the line at the stack top
if (MathUtils.Area(h[top - 1], h[top], pointSet[i]) > 0)
break; // P[i] is a new hull vertex
top--; // pop top point off stack
}
h[++top] = pointSet[i]; // push P[i] onto stack
}
// Next, compute the upper hull on the stack H above the bottom hull
if (maxmax != maxmin) // if distinct xmax points
h[++top] = pointSet[maxmax]; // push maxmax point onto stack
int bot = top;
i = maxmin;
while (--i >= minmax)
{
// the upper line joins P[maxmax] with P[minmax]
if (MathUtils.Area(pointSet[maxmax], pointSet[minmax], pointSet[i]) >= 0 && i > minmax)
continue; // ignore P[i] below or on the upper line
while (top > bot) // at least 2 points on the upper stack
{
// test if P[i] is left of the line at the stack top
if (MathUtils.Area(h[top - 1], h[top], pointSet[i]) > 0)
break; // P[i] is a new hull vertex
top--; // pop top point off stack
}
h[++top] = pointSet[i]; // push P[i] onto stack
}
if (minmax != minmin)
h[++top] = pointSet[minmin]; // push joining endpoint onto stack
res = new Vertices(top + 1);
for (int j = 0; j < top + 1; j++)
{
res.Add(h[j]);
}
return res;
}
private class PointComparer : Comparer<Vector2>
{
public override int Compare(Vector2 a, Vector2 b)
{
int f = a.X.CompareTo(b.X);
return f != 0 ? f : a.Y.CompareTo(b.Y);
}
}
}
}
@@ -0,0 +1,90 @@
using Microsoft.Xna.Framework;
namespace FarseerPhysics.Common.ConvexHull
{
/// <summary>
/// Giftwrap convex hull algorithm.
/// O(nh) time complexity, where n is the number of points and h is the number of points on the convex hull.
///
/// See http://en.wikipedia.org/wiki/Gift_wrapping_algorithm for more details.
/// </summary>
public static class GiftWrap
{
//Extracted from Box2D
/// <summary>
/// Returns the convex hull from the given vertices.
/// </summary>
/// <param name="vertices">The vertices.</param>
public static Vertices GetConvexHull(Vertices vertices)
{
if (vertices.Count <= 3)
return vertices;
// Find the right most point on the hull
int i0 = 0;
float x0 = vertices[0].X;
for (int i = 1; i < vertices.Count; ++i)
{
float x = vertices[i].X;
if (x > x0 || (x == x0 && vertices[i].Y < vertices[i0].Y))
{
i0 = i;
x0 = x;
}
}
int[] hull = new int[vertices.Count];
int m = 0;
int ih = i0;
for (; ; )
{
hull[m] = ih;
int ie = 0;
for (int j = 1; j < vertices.Count; ++j)
{
if (ie == ih)
{
ie = j;
continue;
}
Vector2 r = vertices[ie] - vertices[hull[m]];
Vector2 v = vertices[j] - vertices[hull[m]];
float c = MathUtils.Cross(ref r, ref v);
if (c < 0.0f)
{
ie = j;
}
// Collinearity check
if (c == 0.0f && v.LengthSquared() > r.LengthSquared())
{
ie = j;
}
}
++m;
ih = ie;
if (ie == i0)
{
break;
}
}
Vertices result = new Vertices(m);
// Copy vertices.
for (int i = 0; i < m; ++i)
{
result.Add(vertices[hull[i]]);
}
return result;
}
}
}
@@ -0,0 +1,132 @@
using Microsoft.Xna.Framework;
namespace FarseerPhysics.Common.ConvexHull
{
/// <summary>
/// Creates a convex hull.
/// Note:
/// 1. Vertices must be of a simple polygon, i.e. edges do not overlap.
/// 2. Melkman does not work on point clouds
/// </summary>
/// <remarks>
/// Implemented using Melkman's Convex Hull Algorithm - O(n) time complexity.
/// Reference: http://www.ams.sunysb.edu/~jsbm/courses/345/melkman.pdf
/// </remarks>
public static class Melkman
{
//Melkman based convex hull algorithm contributed by Cowdozer
/// <summary>
/// Returns a convex hull from the given vertices.
/// </summary>
/// <returns>A convex hull in counter clockwise winding order.</returns>
public static Vertices GetConvexHull(Vertices vertices)
{
if (vertices.Count <= 3)
return vertices;
//We'll never need a queue larger than the current number of Vertices +1
//Create double-ended queue
Vector2[] deque = new Vector2[vertices.Count + 1];
int qf = 3, qb = 0; //Queue front index, queue back index
//Start by placing first 3 vertices in convex CCW order
int startIndex = 3;
float k = MathUtils.Area(vertices[0], vertices[1], vertices[2]);
if (k == 0)
{
//Vertices are collinear.
deque[0] = vertices[0];
deque[1] = vertices[2]; //We can skip vertex 1 because it should be between 0 and 2
deque[2] = vertices[0];
qf = 2;
//Go until the end of the collinear sequence of vertices
for (startIndex = 3; startIndex < vertices.Count; startIndex++)
{
Vector2 tmp = vertices[startIndex];
if (MathUtils.Area(ref deque[0], ref deque[1], ref tmp) == 0) //This point is also collinear
deque[1] = vertices[startIndex];
else break;
}
}
else
{
deque[0] = deque[3] = vertices[2];
if (k > 0)
{
//Is Left. Set deque = {2, 0, 1, 2}
deque[1] = vertices[0];
deque[2] = vertices[1];
}
else
{
//Is Right. Set deque = {2, 1, 0, 2}
deque[1] = vertices[1];
deque[2] = vertices[0];
}
}
int qfm1 = qf == 0 ? deque.Length - 1 : qf - 1;
int qbm1 = qb == deque.Length - 1 ? 0 : qb + 1;
//Add vertices one at a time and adjust convex hull as needed
for (int i = startIndex; i < vertices.Count; i++)
{
Vector2 nextPt = vertices[i];
//Ignore if it is already within the convex hull we have constructed
if (MathUtils.Area(ref deque[qfm1], ref deque[qf], ref nextPt) > 0 && MathUtils.Area(ref deque[qb], ref deque[qbm1], ref nextPt) > 0)
continue;
//Pop front until convex
while (!(MathUtils.Area(ref deque[qfm1], ref deque[qf], ref nextPt) > 0))
{
//Pop the front element from the queue
qf = qfm1; //qf--;
qfm1 = qf == 0 ? deque.Length - 1 : qf - 1; //qfm1 = qf - 1;
}
//Add vertex to the front of the queue
qf = qf == deque.Length - 1 ? 0 : qf + 1; //qf++;
qfm1 = qf == 0 ? deque.Length - 1 : qf - 1; //qfm1 = qf - 1;
deque[qf] = nextPt;
//Pop back until convex
while (!(MathUtils.Area(ref deque[qb], ref deque[qbm1], ref nextPt) > 0))
{
//Pop the back element from the queue
qb = qbm1; //qb++;
qbm1 = qb == deque.Length - 1 ? 0 : qb + 1; //qbm1 = qb + 1;
}
//Add vertex to the back of the queue
qb = qb == 0 ? deque.Length - 1 : qb - 1; //qb--;
qbm1 = qb == deque.Length - 1 ? 0 : qb + 1; //qbm1 = qb + 1;
deque[qb] = nextPt;
}
//Create the convex hull from what is left in the deque
if (qb < qf)
{
Vertices convexHull = new Vertices(qf);
for (int i = qb; i < qf; i++)
convexHull.Add(deque[i]);
return convexHull;
}
else
{
Vertices convexHull = new Vertices(qf + deque.Length);
for (int i = 0; i < qf; i++)
convexHull.Add(deque[i]);
for (int i = qb; i < deque.Length; i++)
convexHull.Add(deque[i]);
return convexHull;
}
}
}
}