Server job assigning logic, submarine movement syncing, submarine collision improvements, spawnpoints in levels
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user