(61d00a474) v0.9.7.1
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common.ConvexHull
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common.ConvexHull
|
||||
{
|
||||
@@ -53,7 +58,6 @@ namespace FarseerPhysics.Common.ConvexHull
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -83,7 +87,6 @@ namespace FarseerPhysics.Common.ConvexHull
|
||||
{
|
||||
result.Add(vertices[hull[i]]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common.ConvexHull
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+11
-15
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
@@ -98,7 +103,6 @@ namespace FarseerPhysics.Common.Decomposition.CDT.Delaunay.Sweep
|
||||
EdgeEvent(tcx, e, node);
|
||||
}
|
||||
}
|
||||
tcx.Update(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -518,10 +522,7 @@ namespace FarseerPhysics.Common.Decomposition.CDT.Delaunay.Sweep
|
||||
{
|
||||
throw new PointOnEdgeException("EdgeEvent - Point on constrained edge not supported yet");
|
||||
}
|
||||
if (tcx.IsDebugEnabled)
|
||||
{
|
||||
Debug.WriteLine("EdgeEvent - Point on constrained edge");
|
||||
}
|
||||
Debug.WriteLine("EdgeEvent - Point on constrained edge");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -542,10 +543,7 @@ namespace FarseerPhysics.Common.Decomposition.CDT.Delaunay.Sweep
|
||||
{
|
||||
throw new PointOnEdgeException("EdgeEvent - Point on constrained edge not supported yet");
|
||||
}
|
||||
if (tcx.IsDebugEnabled)
|
||||
{
|
||||
Debug.WriteLine("EdgeEvent - Point on constrained edge");
|
||||
}
|
||||
Debug.WriteLine("EdgeEvent - Point on constrained edge");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -600,7 +598,7 @@ namespace FarseerPhysics.Common.Decomposition.CDT.Delaunay.Sweep
|
||||
if (eq == tcx.EdgeEvent.ConstrainedEdge.Q
|
||||
&& ep == tcx.EdgeEvent.ConstrainedEdge.P)
|
||||
{
|
||||
if (tcx.IsDebugEnabled) Console.WriteLine("[FLIP] - constrained edge done"); // TODO: remove
|
||||
Debug.WriteLine("[FLIP] - constrained edge done"); // TODO: remove
|
||||
t.MarkConstrainedEdge(ep, eq);
|
||||
ot.MarkConstrainedEdge(ep, eq);
|
||||
Legalize(tcx, t);
|
||||
@@ -608,15 +606,13 @@ namespace FarseerPhysics.Common.Decomposition.CDT.Delaunay.Sweep
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tcx.IsDebugEnabled) Console.WriteLine("[FLIP] - subedge done"); // TODO: remove
|
||||
Debug.WriteLine("[FLIP] - subedge done"); // TODO: remove
|
||||
// XXX: I think one of the triangles should be legalized here?
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tcx.IsDebugEnabled)
|
||||
Console.WriteLine("[FLIP] - flipping and continuing with triangle still crossing edge");
|
||||
// TODO: remove
|
||||
Debug.WriteLine("[FLIP] - flipping and continuing with triangle still crossing edge"); // TODO: remove
|
||||
Orientation o = TriangulationUtil.Orient2d(eq, op, ep);
|
||||
t = NextFlipTriangle(tcx, o, t, ot, p, op);
|
||||
FlipEdgeEvent(tcx, ep, eq, t, p);
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-7
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
@@ -53,7 +58,6 @@ namespace FarseerPhysics.Common.Decomposition.CDT
|
||||
public bool Terminated { get; set; }
|
||||
|
||||
public int StepCount { get; private set; }
|
||||
public virtual bool IsDebugEnabled { get; protected set; }
|
||||
|
||||
public void Done()
|
||||
{
|
||||
@@ -69,11 +73,6 @@ namespace FarseerPhysics.Common.Decomposition.CDT
|
||||
|
||||
public abstract TriangulationConstraint NewConstraint(TriangulationPoint a, TriangulationPoint b);
|
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)]
|
||||
public void Update(string message)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
Points.Clear();
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.CDT.Util
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
/* Poly2Tri
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/* Poly2Tri
|
||||
* Copyright (c) 2009-2010, Poly2Tri Contributors
|
||||
* http://code.google.com/p/poly2tri/
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/*
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Farseer Physics Engine:
|
||||
* Copyright (c) 2012 Ian Qvist
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/*
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* C# Version Ported by Matt Bettcher and Ian Qvist 2009-2010
|
||||
*
|
||||
* Original C++ Version Copyright (c) 2007 Eric Jordan
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
{
|
||||
|
||||
+6
-1
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
{
|
||||
internal class Point
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
{
|
||||
internal class Sink : Node
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
{
|
||||
internal class XNode : Node
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
namespace FarseerPhysics.Common.Decomposition.Seidel
|
||||
{
|
||||
internal class YNode : Node
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/*
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Farseer Physics Engine:
|
||||
* Copyright (c) 2012 Ian Qvist
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using FarseerPhysics.Common.ConvexHull;
|
||||
@@ -69,7 +74,12 @@ namespace FarseerPhysics.Common.Decomposition
|
||||
|
||||
public static class Triangulate
|
||||
{
|
||||
public static List<Vertices> ConvexPartition(Vertices vertices, TriangulationAlgorithm algorithm, bool discardAndFixInvalid = true, float tolerance = 0.001f)
|
||||
/// <param name="skipSanityChecks">
|
||||
/// Set this to true to skip sanity checks in the engine. This will speed up the
|
||||
/// tools by removing the overhead of the checks, but you will need to handle checks
|
||||
/// yourself where it is needed.
|
||||
/// </param>
|
||||
public static List<Vertices> ConvexPartition(Vertices vertices, TriangulationAlgorithm algorithm, bool discardAndFixInvalid = true, float tolerance = 0.001f, bool skipSanityChecks = false)
|
||||
{
|
||||
if (vertices.Count <= 3)
|
||||
return new List<Vertices> { vertices };
|
||||
@@ -79,49 +89,37 @@ namespace FarseerPhysics.Common.Decomposition
|
||||
switch (algorithm)
|
||||
{
|
||||
case TriangulationAlgorithm.Earclip:
|
||||
if (Settings.SkipSanityChecks)
|
||||
if (skipSanityChecks)
|
||||
Debug.Assert(!vertices.IsCounterClockWise(), "The Earclip algorithm expects the polygon to be clockwise.");
|
||||
else
|
||||
else if (vertices.IsCounterClockWise())
|
||||
{
|
||||
if (vertices.IsCounterClockWise())
|
||||
{
|
||||
Vertices temp = new Vertices(vertices);
|
||||
temp.Reverse();
|
||||
results = EarclipDecomposer.ConvexPartition(temp, tolerance);
|
||||
}
|
||||
else
|
||||
results = EarclipDecomposer.ConvexPartition(vertices, tolerance);
|
||||
Vertices temp = new Vertices(vertices);
|
||||
temp.Reverse();
|
||||
vertices = temp;
|
||||
}
|
||||
results = EarclipDecomposer.ConvexPartition(vertices, tolerance);
|
||||
break;
|
||||
case TriangulationAlgorithm.Bayazit:
|
||||
if (Settings.SkipSanityChecks)
|
||||
if (skipSanityChecks)
|
||||
Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
|
||||
else
|
||||
else if (!vertices.IsCounterClockWise())
|
||||
{
|
||||
if (!vertices.IsCounterClockWise())
|
||||
{
|
||||
Vertices temp = new Vertices(vertices);
|
||||
temp.Reverse();
|
||||
results = BayazitDecomposer.ConvexPartition(temp);
|
||||
}
|
||||
else
|
||||
results = BayazitDecomposer.ConvexPartition(vertices);
|
||||
Vertices temp = new Vertices(vertices);
|
||||
temp.Reverse();
|
||||
vertices = temp;
|
||||
}
|
||||
results = BayazitDecomposer.ConvexPartition(vertices);
|
||||
break;
|
||||
case TriangulationAlgorithm.Flipcode:
|
||||
if (Settings.SkipSanityChecks)
|
||||
if (skipSanityChecks)
|
||||
Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
|
||||
else
|
||||
else if (!vertices.IsCounterClockWise())
|
||||
{
|
||||
if (!vertices.IsCounterClockWise())
|
||||
{
|
||||
Vertices temp = new Vertices(vertices);
|
||||
temp.Reverse();
|
||||
results = FlipcodeDecomposer.ConvexPartition(temp);
|
||||
}
|
||||
else
|
||||
results = FlipcodeDecomposer.ConvexPartition(vertices);
|
||||
Vertices temp = new Vertices(vertices);
|
||||
temp.Reverse();
|
||||
vertices = temp;
|
||||
}
|
||||
results = FlipcodeDecomposer.ConvexPartition(vertices);
|
||||
break;
|
||||
case TriangulationAlgorithm.Seidel:
|
||||
results = SeidelDecomposer.ConvexPartition(vertices, tolerance);
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/*
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Farseer Physics Engine:
|
||||
* Copyright (c) 2012 Ian Qvist
|
||||
*
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using FarseerPhysics.Collision;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/*
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Farseer Physics Engine:
|
||||
* Copyright (c) 2012 Ian Qvist
|
||||
*
|
||||
@@ -24,6 +29,7 @@ using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics.Common.Maths;
|
||||
|
||||
namespace FarseerPhysics.Common
|
||||
{
|
||||
@@ -40,9 +46,11 @@ namespace FarseerPhysics.Common
|
||||
}
|
||||
|
||||
/// Perform the cross product on two vectors.
|
||||
public static Vector3 Cross(Vector3 a, Vector3 b)
|
||||
public static Vector3 Cross(ref Vector3 a, ref Vector3 b)
|
||||
{
|
||||
return new Vector3(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
|
||||
return new Vector3( a.Y * b.Z - a.Z * b.Y,
|
||||
a.Z * b.X - a.X * b.Z,
|
||||
a.X * b.Y - a.Y * b.X);
|
||||
}
|
||||
|
||||
public static Vector2 Cross(Vector2 a, float s)
|
||||
@@ -50,11 +58,21 @@ namespace FarseerPhysics.Common
|
||||
return new Vector2(s * a.Y, -s * a.X);
|
||||
}
|
||||
|
||||
public static Vector2 Cross(float s, Vector2 a)
|
||||
public static Vector2 Rot270(ref Vector2 a)
|
||||
{
|
||||
return new Vector2(a.Y, -a.X);
|
||||
}
|
||||
|
||||
public static Vector2 Cross(float s, ref Vector2 a)
|
||||
{
|
||||
return new Vector2(-s * a.Y, s * a.X);
|
||||
}
|
||||
|
||||
public static Vector2 Rot90(ref Vector2 a)
|
||||
{
|
||||
return new Vector2(-a.Y, a.X);
|
||||
}
|
||||
|
||||
public static Vector2 Abs(Vector2 v)
|
||||
{
|
||||
return new Vector2(Math.Abs(v.X), Math.Abs(v.Y));
|
||||
@@ -69,19 +87,7 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
return new Vector2(A.ex.X * v.X + A.ey.X * v.Y, A.ex.Y * v.X + A.ey.Y * v.Y);
|
||||
}
|
||||
|
||||
public static Vector2 Mul(ref Transform T, Vector2 v)
|
||||
{
|
||||
return Mul(ref T, ref v);
|
||||
}
|
||||
|
||||
public static Vector2 Mul(ref Transform T, ref Vector2 v)
|
||||
{
|
||||
return new Vector2(
|
||||
(T.q.c * v.X - T.q.s * v.Y) + T.p.X,
|
||||
(T.q.s * v.X + T.q.c * v.Y) + T.p.Y);
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 MulT(ref Mat22 A, Vector2 v)
|
||||
{
|
||||
return MulT(ref A, ref v);
|
||||
@@ -92,18 +98,6 @@ namespace FarseerPhysics.Common
|
||||
return new Vector2(v.X * A.ex.X + v.Y * A.ex.Y, v.X * A.ey.X + v.Y * A.ey.Y);
|
||||
}
|
||||
|
||||
public static Vector2 MulT(ref Transform T, Vector2 v)
|
||||
{
|
||||
return MulT(ref T, ref v);
|
||||
}
|
||||
|
||||
public static Vector2 MulT(ref Transform T, ref Vector2 v)
|
||||
{
|
||||
float px = v.X - T.p.X;
|
||||
float py = v.Y - T.p.Y;
|
||||
|
||||
return new Vector2(T.q.c * px + T.q.s * py, -T.q.s * px + T.q.c * py);
|
||||
}
|
||||
|
||||
// A^T * B
|
||||
public static void MulT(ref Mat22 A, ref Mat22 B, out Mat22 C)
|
||||
@@ -120,26 +114,7 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
return v.X * A.ex + v.Y * A.ey + v.Z * A.ez;
|
||||
}
|
||||
|
||||
// v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p
|
||||
// = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p
|
||||
public static Transform Mul(Transform A, Transform B)
|
||||
{
|
||||
Transform C = new Transform();
|
||||
C.q = Mul(A.q, B.q);
|
||||
C.p = Mul(A.q, B.p) + A.p;
|
||||
return C;
|
||||
}
|
||||
|
||||
// v2 = A.q' * (B.q * v1 + B.p - A.p)
|
||||
// = A.q' * B.q * v1 + A.q' * (B.p - A.p)
|
||||
public static void MulT(ref Transform A, ref Transform B, out Transform C)
|
||||
{
|
||||
C = new Transform();
|
||||
C.q = MulT(A.q, B.q);
|
||||
C.p = MulT(A.q, B.p - A.p);
|
||||
}
|
||||
|
||||
|
||||
public static void Swap<T>(ref T a, ref T b)
|
||||
{
|
||||
T tmp = a;
|
||||
@@ -152,65 +127,7 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
return new Vector2(A.ex.X * v.X + A.ey.X * v.Y, A.ex.Y * v.X + A.ey.Y * v.Y);
|
||||
}
|
||||
|
||||
/// Multiply two rotations: q * r
|
||||
public static Rot Mul(Rot q, Rot r)
|
||||
{
|
||||
// [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc]
|
||||
// [qs qc] [rs rc] [qs*rc+qc*rs -qs*rs+qc*rc]
|
||||
// s = qs * rc + qc * rs
|
||||
// c = qc * rc - qs * rs
|
||||
Rot qr;
|
||||
qr.s = q.s * r.c + q.c * r.s;
|
||||
qr.c = q.c * r.c - q.s * r.s;
|
||||
return qr;
|
||||
}
|
||||
|
||||
public static Vector2 MulT(Transform T, Vector2 v)
|
||||
{
|
||||
float px = v.X - T.p.X;
|
||||
float py = v.Y - T.p.Y;
|
||||
float x = (T.q.c * px + T.q.s * py);
|
||||
float y = (-T.q.s * px + T.q.c * py);
|
||||
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
/// Transpose multiply two rotations: qT * r
|
||||
public static Rot MulT(Rot q, Rot r)
|
||||
{
|
||||
// [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc]
|
||||
// [-qs qc] [rs rc] [-qs*rc+qc*rs qs*rs+qc*rc]
|
||||
// s = qc * rs - qs * rc
|
||||
// c = qc * rc + qs * rs
|
||||
Rot qr;
|
||||
qr.s = q.c * r.s - q.s * r.c;
|
||||
qr.c = q.c * r.c + q.s * r.s;
|
||||
return qr;
|
||||
}
|
||||
|
||||
// v2 = A.q' * (B.q * v1 + B.p - A.p)
|
||||
// = A.q' * B.q * v1 + A.q' * (B.p - A.p)
|
||||
public static Transform MulT(Transform A, Transform B)
|
||||
{
|
||||
Transform C = new Transform();
|
||||
C.q = MulT(A.q, B.q);
|
||||
C.p = MulT(A.q, B.p - A.p);
|
||||
return C;
|
||||
}
|
||||
|
||||
/// Rotate a vector
|
||||
public static Vector2 Mul(Rot q, Vector2 v)
|
||||
{
|
||||
return new Vector2(q.c * v.X - q.s * v.Y, q.s * v.X + q.c * v.Y);
|
||||
}
|
||||
|
||||
/// Inverse rotate a vector
|
||||
public static Vector2 MulT(Rot q, Vector2 v)
|
||||
{
|
||||
return new Vector2(q.c * v.X + q.s * v.Y, -q.s * v.X + q.c * v.Y);
|
||||
}
|
||||
|
||||
|
||||
/// Get the skew vector such that dot(skew_vec, other) == cross(vec, other)
|
||||
public static Vector2 Skew(Vector2 input)
|
||||
{
|
||||
@@ -301,6 +218,12 @@ namespace FarseerPhysics.Common
|
||||
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
|
||||
}
|
||||
|
||||
/// Perform the dot product on two vectors.
|
||||
public static float Dot(Vector2 a, ref Vector2 b)
|
||||
{
|
||||
return a.X * b.X + a.Y * b.Y;
|
||||
}
|
||||
|
||||
public static double VectorAngle(Vector2 p1, Vector2 p2)
|
||||
{
|
||||
return VectorAngle(ref p1, ref p2);
|
||||
@@ -389,15 +312,6 @@ namespace FarseerPhysics.Common
|
||||
|
||||
#endregion
|
||||
|
||||
public static Vector2 Mul(ref Rot rot, Vector2 axis)
|
||||
{
|
||||
return Mul(rot, axis);
|
||||
}
|
||||
|
||||
public static Vector2 MulT(ref Rot rot, Vector2 axis)
|
||||
{
|
||||
return MulT(rot, axis);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -598,7 +512,7 @@ namespace FarseerPhysics.Common
|
||||
/// Returns the zero matrix if singular.
|
||||
public void GetSymInverse33(ref Mat33 M)
|
||||
{
|
||||
float det = MathUtils.Dot(ex, MathUtils.Cross(ey, ez));
|
||||
float det = MathUtils.Dot(ex, MathUtils.Cross(ref ey, ref ez));
|
||||
if (det != 0.0f)
|
||||
{
|
||||
det = 1.0f / det;
|
||||
@@ -622,108 +536,108 @@ namespace FarseerPhysics.Common
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rotation
|
||||
/// </summary>
|
||||
public struct Rot
|
||||
{
|
||||
/// Sine and cosine
|
||||
public float s, c;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize from an angle in radians
|
||||
/// </summary>
|
||||
/// <param name="angle">Angle in radians</param>
|
||||
public Rot(float angle)
|
||||
{
|
||||
// TODO_ERIN optimize
|
||||
s = (float)Math.Sin(angle);
|
||||
c = (float)Math.Cos(angle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set using an angle in radians.
|
||||
/// </summary>
|
||||
/// <param name="angle"></param>
|
||||
public void Set(float angle)
|
||||
{
|
||||
// TODO_ERIN optimize
|
||||
s = (float)Math.Sin(angle);
|
||||
c = (float)Math.Cos(angle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set to the identity rotation
|
||||
/// </summary>
|
||||
public void SetIdentity()
|
||||
{
|
||||
s = 0.0f;
|
||||
c = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the angle in radians
|
||||
/// </summary>
|
||||
public float GetAngle()
|
||||
{
|
||||
return (float)Math.Atan2(s, c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the x-axis
|
||||
/// </summary>
|
||||
public Vector2 GetXAxis()
|
||||
{
|
||||
return new Vector2(c, s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the y-axis
|
||||
/// </summary>
|
||||
public Vector2 GetYAxis()
|
||||
{
|
||||
return new Vector2(-s, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A transform contains translation and rotation. It is used to represent
|
||||
/// the position and orientation of rigid frames.
|
||||
/// </summary>
|
||||
public struct Transform
|
||||
{
|
||||
private static readonly Transform _identity = new Transform(Vector2.Zero, Complex.One);
|
||||
|
||||
public Complex q;
|
||||
public Vector2 p;
|
||||
public Rot q;
|
||||
|
||||
public static Transform Identity { get { return _identity; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize using a position vector and a rotation matrix.
|
||||
/// Initialize using a position vector and a Complex rotation.
|
||||
/// </summary>
|
||||
/// <param name="position">The position.</param>
|
||||
/// <param name="rotation">The r.</param>
|
||||
public Transform(ref Vector2 position, ref Rot rotation)
|
||||
/// <param name="rotation">The rotation</param>
|
||||
public Transform(Vector2 position, Complex rotation)
|
||||
{
|
||||
p = position;
|
||||
q = rotation;
|
||||
p = position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this to the identity transform.
|
||||
/// </summary>
|
||||
public void SetIdentity()
|
||||
{
|
||||
p = Vector2.Zero;
|
||||
q.SetIdentity();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set this based on the position and angle.
|
||||
/// Initialize using a position vector and a rotation.
|
||||
/// </summary>
|
||||
/// <param name="position">The position.</param>
|
||||
/// <param name="angle">The angle.</param>
|
||||
public void Set(Vector2 position, float angle)
|
||||
/// <param name="angle">The rotation angle</param>
|
||||
public Transform(Vector2 position, float angle)
|
||||
: this(position, Complex.FromAngle(angle))
|
||||
{
|
||||
p = position;
|
||||
q.Set(angle);
|
||||
}
|
||||
|
||||
public static Vector2 Multiply(Vector2 left, ref Transform right)
|
||||
{
|
||||
return Multiply(ref left, ref right);
|
||||
}
|
||||
|
||||
public static Vector2 Multiply(ref Vector2 left, ref Transform right)
|
||||
{
|
||||
// Opt: var result = Complex.Multiply(left, right.q) + right.p;
|
||||
return new Vector2(
|
||||
(left.X * right.q.Real - left.Y * right.q.Imaginary) + right.p.X,
|
||||
(left.Y * right.q.Real + left.X * right.q.Imaginary) + right.p.Y);
|
||||
}
|
||||
|
||||
public static Vector2 Divide(Vector2 left, ref Transform right)
|
||||
{
|
||||
return Divide(ref left, ref right);
|
||||
}
|
||||
|
||||
public static Vector2 Divide(ref Vector2 left, ref Transform right)
|
||||
{
|
||||
// Opt: var result = Complex.Divide(left - right.p, right);
|
||||
float px = left.X - right.p.X;
|
||||
float py = left.Y - right.p.Y;
|
||||
return new Vector2(
|
||||
(px * right.q.Real + py * right.q.Imaginary),
|
||||
(py * right.q.Real - px * right.q.Imaginary));
|
||||
}
|
||||
|
||||
public static void Divide(Vector2 left, ref Transform right, out Vector2 result)
|
||||
{
|
||||
// Opt: var result = Complex.Divide(left - right.p, right);
|
||||
float px = left.X - right.p.X;
|
||||
float py = left.Y - right.p.Y;
|
||||
result.X = (px * right.q.Real + py * right.q.Imaginary);
|
||||
result.Y = (py * right.q.Real - px * right.q.Imaginary);
|
||||
}
|
||||
|
||||
public static Transform Multiply(ref Transform left, ref Transform right)
|
||||
{
|
||||
return new Transform(
|
||||
Complex.Multiply(ref left.p, ref right.q) + right.p,
|
||||
Complex.Multiply(ref left.q, ref right.q));
|
||||
}
|
||||
|
||||
public static Transform Divide(ref Transform left, ref Transform right)
|
||||
{
|
||||
return new Transform(
|
||||
Complex.Divide(left.p - right.p, ref right.q),
|
||||
Complex.Divide(ref left.q, ref right.q));
|
||||
}
|
||||
|
||||
public static void Divide(ref Transform left, ref Transform right, out Transform result)
|
||||
{
|
||||
Complex.Divide(left.p - right.p, ref right.q, out result.p);
|
||||
Complex.Divide(ref left.q, ref right.q, out result.q);
|
||||
}
|
||||
|
||||
public static void Multiply(ref Transform left, Complex right, out Transform result)
|
||||
{
|
||||
result.p = Complex.Multiply(ref left.p, ref right);
|
||||
result.q = Complex.Multiply(ref left.q, ref right);
|
||||
}
|
||||
|
||||
public static void Divide(ref Transform left, Complex right, out Transform result)
|
||||
{
|
||||
result.p = Complex.Divide(ref left.p, ref right);
|
||||
result.q = Complex.Divide(ref left.q, ref right);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -771,10 +685,10 @@ namespace FarseerPhysics.Common
|
||||
xfb.p.X = (1.0f - beta) * C0.X + beta * C.X;
|
||||
xfb.p.Y = (1.0f - beta) * C0.Y + beta * C.Y;
|
||||
float angle = (1.0f - beta) * A0 + beta * A;
|
||||
xfb.q.Set(angle);
|
||||
xfb.q.Phase = angle;
|
||||
|
||||
// Shift to origin
|
||||
xfb.p -= MathUtils.Mul(xfb.q, LocalCenter);
|
||||
xfb.p -= Complex.Multiply(ref LocalCenter, ref xfb.q);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
#if !XNA && !WINDOWS_PHONE && !XBOX && !ANDROID
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
MIT License
|
||||
Copyright © 2006 The Mono.Xna Team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#endregion License
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Xna.Framework
|
||||
{
|
||||
public static class MathHelper
|
||||
{
|
||||
public const float E = (float) Math.E;
|
||||
public const float Log10E = 0.4342945f;
|
||||
public const float Log2E = 1.442695f;
|
||||
public const float Pi = (float) Math.PI;
|
||||
public const float PiOver2 = (float) (Math.PI/2.0);
|
||||
public const float PiOver4 = (float) (Math.PI/4.0);
|
||||
public const float TwoPi = (float) (Math.PI*2.0);
|
||||
|
||||
public static float Barycentric(float value1, float value2, float value3, float amount1, float amount2)
|
||||
{
|
||||
return value1 + (value2 - value1)*amount1 + (value3 - value1)*amount2;
|
||||
}
|
||||
|
||||
public static float CatmullRom(float value1, float value2, float value3, float value4, float amount)
|
||||
{
|
||||
// Using formula from http://www.mvps.org/directx/articles/catmull/
|
||||
// Internally using doubles not to lose precission
|
||||
double amountSquared = amount*amount;
|
||||
double amountCubed = amountSquared*amount;
|
||||
return (float) (0.5*(2.0*value2 +
|
||||
(value3 - value1)*amount +
|
||||
(2.0*value1 - 5.0*value2 + 4.0*value3 - value4)*amountSquared +
|
||||
(3.0*value2 - value1 - 3.0*value3 + value4)*amountCubed));
|
||||
}
|
||||
|
||||
public static float Clamp(float value, float min, float max)
|
||||
{
|
||||
// First we check to see if we're greater than the max
|
||||
value = (value > max) ? max : value;
|
||||
|
||||
// Then we check to see if we're less than the min.
|
||||
value = (value < min) ? min : value;
|
||||
|
||||
// There's no check to see if min > max.
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int Clamp(int value, int min, int max)
|
||||
{
|
||||
// First we check to see if we're greater than the max
|
||||
value = (value > max) ? max : value;
|
||||
|
||||
// Then we check to see if we're less than the min.
|
||||
value = (value < min) ? min : value;
|
||||
|
||||
// There's no check to see if min > max.
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float Distance(float value1, float value2)
|
||||
{
|
||||
return Math.Abs(value1 - value2);
|
||||
}
|
||||
|
||||
public static float Hermite(float value1, float tangent1, float value2, float tangent2, float amount)
|
||||
{
|
||||
// All transformed to double not to lose precission
|
||||
// Otherwise, for high numbers of param:amount the result is NaN instead of Infinity
|
||||
double v1 = value1, v2 = value2, t1 = tangent1, t2 = tangent2, s = amount, result;
|
||||
double sCubed = s*s*s;
|
||||
double sSquared = s*s;
|
||||
|
||||
if (amount == 0f)
|
||||
result = value1;
|
||||
else if (amount == 1f)
|
||||
result = value2;
|
||||
else
|
||||
result = (2*v1 - 2*v2 + t2 + t1)*sCubed +
|
||||
(3*v2 - 3*v1 - 2*t1 - t2)*sSquared +
|
||||
t1*s +
|
||||
v1;
|
||||
return (float) result;
|
||||
}
|
||||
|
||||
public static float Lerp(float value1, float value2, float amount)
|
||||
{
|
||||
return value1 + (value2 - value1)*amount;
|
||||
}
|
||||
|
||||
public static float Max(float value1, float value2)
|
||||
{
|
||||
return Math.Max(value1, value2);
|
||||
}
|
||||
|
||||
public static float Min(float value1, float value2)
|
||||
{
|
||||
return Math.Min(value1, value2);
|
||||
}
|
||||
|
||||
public static float SmoothStep(float value1, float value2, float amount)
|
||||
{
|
||||
// It is expected that 0 < amount < 1
|
||||
// If amount < 0, return value1
|
||||
// If amount > 1, return value2
|
||||
float result = Clamp(amount, 0f, 1f);
|
||||
result = Hermite(value1, 0f, value2, 0f, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static float ToDegrees(float radians)
|
||||
{
|
||||
// This method uses double precission internally,
|
||||
// though it returns single float
|
||||
// Factor = 180 / pi
|
||||
return (float) (radians*57.295779513082320876798154814105);
|
||||
}
|
||||
|
||||
public static float ToRadians(float degrees)
|
||||
{
|
||||
// This method uses double precission internally,
|
||||
// though it returns single float
|
||||
// Factor = pi / 180
|
||||
return (float) (degrees*0.017453292519943295769236907684886);
|
||||
}
|
||||
|
||||
public static float WrapAngle(float angle)
|
||||
{
|
||||
angle = (float) Math.IEEERemainder((double) angle, 6.2831854820251465); //2xPi precission is double
|
||||
if (angle <= -3.141593f)
|
||||
{
|
||||
angle += 6.283185f;
|
||||
return angle;
|
||||
}
|
||||
if (angle > 3.141593f)
|
||||
{
|
||||
angle -= 6.283185f;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,155 @@
|
||||
// Copyright (c) 2017 Kastellanos Nikolaos
|
||||
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common.Maths
|
||||
{
|
||||
public struct Complex
|
||||
{
|
||||
private static readonly Complex _one = new Complex(1, 0);
|
||||
private static readonly Complex _imaginaryOne = new Complex(0, 1);
|
||||
|
||||
public float Real;
|
||||
public float Imaginary;
|
||||
|
||||
public static Complex One { get { return _one; } }
|
||||
public static Complex ImaginaryOne { get { return _imaginaryOne; } }
|
||||
|
||||
public float Phase
|
||||
{
|
||||
get { return (float)Math.Atan2(Imaginary, Real); }
|
||||
set
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
this = Complex.One;
|
||||
return;
|
||||
}
|
||||
this.Real = (float)Math.Cos(value);
|
||||
this.Imaginary = (float)Math.Sin(value);
|
||||
}
|
||||
}
|
||||
|
||||
public float Magnitude
|
||||
{
|
||||
get { return (float)Math.Round(Math.Sqrt(MagnitudeSquared())); }
|
||||
}
|
||||
|
||||
|
||||
public Complex(float real, float imaginary)
|
||||
{
|
||||
Real = real;
|
||||
Imaginary = imaginary;
|
||||
}
|
||||
|
||||
public static Complex FromAngle(float angle)
|
||||
{
|
||||
if (angle == 0)
|
||||
return Complex.One;
|
||||
|
||||
return new Complex(
|
||||
(float)Math.Cos(angle),
|
||||
(float)Math.Sin(angle));
|
||||
}
|
||||
|
||||
public void Conjugate()
|
||||
{
|
||||
Imaginary = -Imaginary;
|
||||
}
|
||||
|
||||
public void Negate()
|
||||
{
|
||||
Real = -Real;
|
||||
Imaginary = -Imaginary;
|
||||
}
|
||||
|
||||
public float MagnitudeSquared()
|
||||
{
|
||||
return (Real * Real) + (Imaginary * Imaginary);
|
||||
}
|
||||
|
||||
public void Normalize()
|
||||
{
|
||||
var mag = Magnitude;
|
||||
Real = Real / mag;
|
||||
Imaginary = Imaginary / mag;
|
||||
}
|
||||
|
||||
public Vector2 ToVector2()
|
||||
{
|
||||
return new Vector2(Real, Imaginary);
|
||||
}
|
||||
|
||||
public static Complex Multiply(ref Complex left, ref Complex right)
|
||||
{
|
||||
return new Complex( left.Real * right.Real - left.Imaginary * right.Imaginary,
|
||||
left.Imaginary * right.Real + left.Real * right.Imaginary);
|
||||
}
|
||||
|
||||
public static Complex Divide(ref Complex left, ref Complex right)
|
||||
{
|
||||
return new Complex( right.Real * left.Real + right.Imaginary * left.Imaginary,
|
||||
right.Real * left.Imaginary - right.Imaginary * left.Real);
|
||||
}
|
||||
public static void Divide(ref Complex left, ref Complex right, out Complex result)
|
||||
{
|
||||
result = new Complex(right.Real * left.Real + right.Imaginary * left.Imaginary,
|
||||
right.Real * left.Imaginary - right.Imaginary * left.Real);
|
||||
}
|
||||
|
||||
public static Vector2 Multiply(ref Vector2 left, ref Complex right)
|
||||
{
|
||||
return new Vector2(left.X * right.Real - left.Y * right.Imaginary,
|
||||
left.Y * right.Real + left.X * right.Imaginary);
|
||||
}
|
||||
public static void Multiply(ref Vector2 left, ref Complex right, out Vector2 result)
|
||||
{
|
||||
result = new Vector2(left.X * right.Real - left.Y * right.Imaginary,
|
||||
left.Y * right.Real + left.X * right.Imaginary);
|
||||
}
|
||||
public static Vector2 Multiply(Vector2 left, ref Complex right)
|
||||
{
|
||||
return new Vector2(left.X * right.Real - left.Y * right.Imaginary,
|
||||
left.Y * right.Real + left.X * right.Imaginary);
|
||||
}
|
||||
|
||||
public static Vector2 Divide(ref Vector2 left, ref Complex right)
|
||||
{
|
||||
return new Vector2(left.X * right.Real + left.Y * right.Imaginary,
|
||||
left.Y * right.Real - left.X * right.Imaginary);
|
||||
}
|
||||
|
||||
public static Vector2 Divide(Vector2 left, ref Complex right)
|
||||
{
|
||||
return new Vector2(left.X * right.Real + left.Y * right.Imaginary,
|
||||
left.Y * right.Real - left.X * right.Imaginary);
|
||||
}
|
||||
public static void Divide(Vector2 left, ref Complex right, out Vector2 result)
|
||||
{
|
||||
result = new Vector2(left.X * right.Real + left.Y * right.Imaginary,
|
||||
left.Y * right.Real - left.X * right.Imaginary);
|
||||
}
|
||||
|
||||
public static Complex Conjugate(ref Complex value)
|
||||
{
|
||||
return new Complex(value.Real, -value.Imaginary);
|
||||
}
|
||||
|
||||
public static Complex Negate(ref Complex value)
|
||||
{
|
||||
return new Complex(-value.Real, -value.Real);
|
||||
}
|
||||
|
||||
public static Complex Normalize(ref Complex value)
|
||||
{
|
||||
var mag = value.Magnitude;
|
||||
return new Complex(value.Real / mag, -value.Imaginary / mag);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{{Real: {0} Imaginary: {1} Phase: {2} Magnitude: {3}}}", Real, Imaginary, Phase, Magnitude);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
@@ -239,9 +244,6 @@ namespace FarseerPhysics.Common
|
||||
|
||||
Vector2.Subtract(ref a, ref b, out temp);
|
||||
|
||||
#if (XBOX360 || WINDOWS_PHONE)
|
||||
output = new Vector2();
|
||||
#endif
|
||||
output.X = -temp.Y;
|
||||
output.Y = temp.X;
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FarseerPhysics.Collision.Shapes;
|
||||
using FarseerPhysics.Common.Decomposition;
|
||||
@@ -90,7 +95,7 @@ namespace FarseerPhysics.Common
|
||||
|
||||
for (int i = 0; i < centers.Count; i++)
|
||||
{
|
||||
Body b = new Body(world);
|
||||
Body b = world.CreateBody();
|
||||
|
||||
// copy the type from original body
|
||||
b.BodyType = type;
|
||||
@@ -120,20 +125,14 @@ namespace FarseerPhysics.Common
|
||||
/// <param name="copies">The copies.</param>
|
||||
/// <param name="userData">The user data.</param>
|
||||
/// <returns></returns>
|
||||
public static List<Body> EvenlyDistributeShapesAlongPath(World world, Path path, Shape shape, BodyType type,
|
||||
int copies, object userData)
|
||||
public static List<Body> EvenlyDistributeShapesAlongPath(World world, Path path, Shape shape, BodyType type, int copies, object userData = null)
|
||||
{
|
||||
List<Shape> shapes = new List<Shape>(1);
|
||||
shapes.Add(shape);
|
||||
|
||||
return EvenlyDistributeShapesAlongPath(world, path, shapes, type, copies, userData);
|
||||
}
|
||||
|
||||
public static List<Body> EvenlyDistributeShapesAlongPath(World world, Path path, Shape shape, BodyType type, int copies)
|
||||
{
|
||||
return EvenlyDistributeShapesAlongPath(world, path, shape, type, copies, null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Moves the given body along the defined path.
|
||||
/// </summary>
|
||||
@@ -168,7 +167,7 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
RevoluteJoint joint = new RevoluteJoint(bodies[i], bodies[i - 1], localAnchorA, localAnchorB);
|
||||
joint.CollideConnected = collideConnected;
|
||||
world.AddJoint(joint);
|
||||
world.Add(joint);
|
||||
joints.Add(joint);
|
||||
}
|
||||
|
||||
@@ -176,7 +175,7 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
RevoluteJoint lastjoint = new RevoluteJoint(bodies[0], bodies[bodies.Count - 1], localAnchorA, localAnchorB);
|
||||
lastjoint.CollideConnected = collideConnected;
|
||||
world.AddJoint(lastjoint);
|
||||
world.Add(lastjoint);
|
||||
joints.Add(lastjoint);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics.Collision.Shapes;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Dynamics.Contacts;
|
||||
using FarseerPhysics.Common.Decomposition;
|
||||
|
||||
namespace FarseerPhysics.Common.PhysicsLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// A type of body that supports multiple fixtures that can break apart.
|
||||
/// </summary>
|
||||
public class BreakableBody
|
||||
{
|
||||
public enum BreakableBodyState
|
||||
{
|
||||
Unbroken,
|
||||
ShouldBreak,
|
||||
Broken,
|
||||
}
|
||||
|
||||
private float[] _angularVelocitiesCache = new float[8];
|
||||
private Vector2[] _velocitiesCache = new Vector2[8];
|
||||
|
||||
public List<Fixture> Parts = new List<Fixture>(8);
|
||||
|
||||
public World World { get; private set; }
|
||||
public Body MainBody { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The force needed to break the body apart.
|
||||
/// Default: 500
|
||||
/// </summary>
|
||||
public float Strength = 500.0f;
|
||||
|
||||
public BreakableBodyState State { get; private set; }
|
||||
|
||||
private BreakableBody(World world)
|
||||
{
|
||||
World = world;
|
||||
World.ContactManager.PostSolve += PostSolve;
|
||||
|
||||
State = BreakableBodyState.Unbroken;
|
||||
}
|
||||
|
||||
public BreakableBody(World world, IEnumerable<Vertices> vertices, float density, Vector2 position = new Vector2(), float rotation = 0) : this(world)
|
||||
{
|
||||
MainBody = World.CreateBody(position, rotation, BodyType.Dynamic);
|
||||
|
||||
foreach (Vertices part in vertices)
|
||||
{
|
||||
PolygonShape polygonShape = new PolygonShape(part, density);
|
||||
Fixture fixture = MainBody.CreateFixture(polygonShape);
|
||||
Parts.Add(fixture);
|
||||
}
|
||||
}
|
||||
|
||||
public BreakableBody(World world, IEnumerable<Shape> shapes, Vector2 position = new Vector2(), float rotation = 0) : this(world)
|
||||
{
|
||||
MainBody = World.CreateBody(position, rotation, BodyType.Dynamic);
|
||||
|
||||
foreach (Shape part in shapes)
|
||||
{
|
||||
Fixture fixture = MainBody.CreateFixture(part);
|
||||
Parts.Add(fixture);
|
||||
}
|
||||
}
|
||||
|
||||
public BreakableBody(World world, Vertices vertices, float density, Vector2 position = new Vector2(), float rotation = 0) : this(world)
|
||||
{
|
||||
MainBody = World.CreateBody(position, rotation, BodyType.Dynamic);
|
||||
|
||||
//TODO: Implement a Voronoi diagram algorithm to split up the vertices
|
||||
List<Vertices> triangles = Triangulate.ConvexPartition(vertices, TriangulationAlgorithm.Earclip);
|
||||
|
||||
foreach (Vertices part in triangles)
|
||||
{
|
||||
PolygonShape polygonShape = new PolygonShape(part, density);
|
||||
Fixture fixture = MainBody.CreateFixture(polygonShape);
|
||||
Parts.Add(fixture);
|
||||
}
|
||||
}
|
||||
|
||||
private void PostSolve(Contact contact, ContactVelocityConstraint impulse)
|
||||
{
|
||||
if (State != BreakableBodyState.Broken)
|
||||
{
|
||||
if (Parts.Contains(contact.FixtureA) || Parts.Contains(contact.FixtureB))
|
||||
{
|
||||
float maxImpulse = 0.0f;
|
||||
int count = contact.Manifold.PointCount;
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
maxImpulse = Math.Max(maxImpulse, impulse.points[i].normalImpulse);
|
||||
}
|
||||
|
||||
if (maxImpulse > Strength)
|
||||
{
|
||||
// Flag the body for breaking.
|
||||
State = BreakableBodyState.ShouldBreak;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
switch (State)
|
||||
{
|
||||
case BreakableBodyState.Unbroken:
|
||||
CacheVelocities();
|
||||
break;
|
||||
case BreakableBodyState.ShouldBreak:
|
||||
Decompose();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache velocities to improve movement on breakage.
|
||||
private void CacheVelocities()
|
||||
{
|
||||
//Enlarge the cache if needed
|
||||
if (Parts.Count > _angularVelocitiesCache.Length)
|
||||
{
|
||||
_velocitiesCache = new Vector2[Parts.Count];
|
||||
_angularVelocitiesCache = new float[Parts.Count];
|
||||
}
|
||||
|
||||
//Cache the linear and angular velocities.
|
||||
for (int i = 0; i < Parts.Count; i++)
|
||||
{
|
||||
_velocitiesCache[i] = Parts[i].Body.LinearVelocity;
|
||||
_angularVelocitiesCache[i] = Parts[i].Body.AngularVelocity;
|
||||
}
|
||||
}
|
||||
|
||||
private void Decompose()
|
||||
{
|
||||
if (State == BreakableBodyState.Broken)
|
||||
throw new InvalidOperationException("BreakableBody is allready broken");
|
||||
|
||||
//Unsubsribe from the PostSolve delegate
|
||||
World.ContactManager.PostSolve -= PostSolve;
|
||||
|
||||
for (int i = 0; i < Parts.Count; i++)
|
||||
{
|
||||
Fixture oldFixture = Parts[i];
|
||||
|
||||
Shape shape = oldFixture.Shape.Clone();
|
||||
object fixtureTag = oldFixture.UserData;
|
||||
|
||||
MainBody.Remove(oldFixture);
|
||||
|
||||
Body body = World.CreateBody(MainBody.Position, MainBody.Rotation, BodyType.Dynamic);
|
||||
body.UserData = MainBody.UserData;
|
||||
|
||||
Fixture newFixture = body.CreateFixture(shape);
|
||||
newFixture.UserData = fixtureTag;
|
||||
Parts[i] = newFixture;
|
||||
|
||||
body.AngularVelocity = _angularVelocitiesCache[i];
|
||||
body.LinearVelocity = _velocitiesCache[i];
|
||||
}
|
||||
|
||||
World.Remove(MainBody);
|
||||
|
||||
State = BreakableBodyState.Broken;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2017 Kastellanos Nikolaos
|
||||
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace FarseerPhysics.Common.PhysicsLogic
|
||||
{
|
||||
[Flags]
|
||||
public enum ControllerCategory
|
||||
{
|
||||
None = 0x00000000,
|
||||
Cat01 = 0x00000001,
|
||||
Cat02 = 0x00000002,
|
||||
Cat03 = 0x00000004,
|
||||
Cat04 = 0x00000008,
|
||||
Cat05 = 0x00000010,
|
||||
Cat06 = 0x00000020,
|
||||
Cat07 = 0x00000040,
|
||||
Cat08 = 0x00000080,
|
||||
Cat09 = 0x00000100,
|
||||
Cat10 = 0x00000200,
|
||||
Cat11 = 0x00000400,
|
||||
Cat12 = 0x00000800,
|
||||
Cat13 = 0x00001000,
|
||||
Cat14 = 0x00002000,
|
||||
Cat15 = 0x00004000,
|
||||
Cat16 = 0x00008000,
|
||||
Cat17 = 0x00010000,
|
||||
Cat18 = 0x00020000,
|
||||
Cat19 = 0x00040000,
|
||||
Cat20 = 0x00080000,
|
||||
Cat21 = 0x00100000,
|
||||
Cat22 = 0x00200000,
|
||||
Cat23 = 0x00400000,
|
||||
Cat24 = 0x00800000,
|
||||
Cat25 = 0x01000000,
|
||||
Cat26 = 0x02000000,
|
||||
Cat27 = 0x04000000,
|
||||
Cat28 = 0x08000000,
|
||||
Cat29 = 0x10000000,
|
||||
Cat30 = 0x20000000,
|
||||
Cat31 = 0x40000000,
|
||||
All = int.MaxValue,
|
||||
}
|
||||
|
||||
public struct ControllerFilter
|
||||
{
|
||||
public ControllerCategory ControllerCategories;
|
||||
|
||||
public ControllerFilter(ControllerCategory controllerCategory)
|
||||
{
|
||||
this.ControllerCategories = controllerCategory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignores the controller. The controller has no effect on this body.
|
||||
/// </summary>
|
||||
/// <param name="type">The logic type.</param>
|
||||
public void IgnoreController(ControllerCategory category)
|
||||
{
|
||||
ControllerCategories &= ~category;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restore the controller. The controller affects this body.
|
||||
/// </summary>
|
||||
/// <param name="category">The logic type.</param>
|
||||
public void RestoreController(ControllerCategory category)
|
||||
{
|
||||
ControllerCategories |= category;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this body ignores the the specified controller.
|
||||
/// </summary>
|
||||
/// <param name="category">The logic type.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the body has the specified flag; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsControllerIgnored(ControllerCategory category)
|
||||
{
|
||||
return (ControllerCategories & category) != category;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
using FarseerPhysics.Dynamics;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using FarseerPhysics.Dynamics;
|
||||
|
||||
namespace FarseerPhysics.Common.PhysicsLogic
|
||||
{
|
||||
@@ -36,7 +41,7 @@ namespace FarseerPhysics.Common.PhysicsLogic
|
||||
/// <returns></returns>
|
||||
public virtual bool IsActiveOn(Body body)
|
||||
{
|
||||
if (body == null || !body.Enabled || body.IsStatic)
|
||||
if (body == null || !body.Enabled || body.BodyType == BodyType.Static)
|
||||
return false;
|
||||
|
||||
if (body.FixtureList == null)
|
||||
|
||||
@@ -1,66 +1,29 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using FarseerPhysics.Dynamics;
|
||||
|
||||
namespace FarseerPhysics.Common.PhysicsLogic
|
||||
{
|
||||
[Flags]
|
||||
public enum PhysicsLogicType
|
||||
{
|
||||
Explosion = (1 << 0)
|
||||
}
|
||||
|
||||
public struct PhysicsLogicFilter
|
||||
{
|
||||
public PhysicsLogicType ControllerIgnores;
|
||||
|
||||
/// <summary>
|
||||
/// Ignores the controller. The controller has no effect on this body.
|
||||
/// </summary>
|
||||
/// <param name="type">The logic type.</param>
|
||||
public void IgnorePhysicsLogic(PhysicsLogicType type)
|
||||
{
|
||||
ControllerIgnores |= type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restore the controller. The controller affects this body.
|
||||
/// </summary>
|
||||
/// <param name="type">The logic type.</param>
|
||||
public void RestorePhysicsLogic(PhysicsLogicType type)
|
||||
{
|
||||
ControllerIgnores &= ~type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this body ignores the the specified controller.
|
||||
/// </summary>
|
||||
/// <param name="type">The logic type.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the body has the specified flag; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsPhysicsLogicIgnored(PhysicsLogicType type)
|
||||
{
|
||||
return (ControllerIgnores & type) == type;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class PhysicsLogic : FilterData
|
||||
{
|
||||
private PhysicsLogicType _type;
|
||||
public World World;
|
||||
public ControllerCategory ControllerCategory = ControllerCategory.Cat01;
|
||||
|
||||
public World World { get; internal set; }
|
||||
|
||||
public PhysicsLogic(World world)
|
||||
{
|
||||
World = world;
|
||||
}
|
||||
public override bool IsActiveOn(Body body)
|
||||
{
|
||||
if (body.PhysicsLogicFilter.IsPhysicsLogicIgnored(_type))
|
||||
if (body.ControllerFilter.IsControllerIgnored(ControllerCategory))
|
||||
return false;
|
||||
|
||||
return base.IsActiveOn(body);
|
||||
}
|
||||
|
||||
public PhysicsLogic(World world, PhysicsLogicType type)
|
||||
{
|
||||
_type = type;
|
||||
World = world;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,15 @@
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics.Collision;
|
||||
using FarseerPhysics.Collision.Shapes;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common.PhysicsLogic
|
||||
{
|
||||
@@ -98,8 +103,7 @@ namespace FarseerPhysics.Common.PhysicsLogic
|
||||
private List<ShapeData> _data = new List<ShapeData>();
|
||||
private RayDataComparer _rdc;
|
||||
|
||||
public RealExplosion(World world)
|
||||
: base(world, PhysicsLogicType.Explosion)
|
||||
public RealExplosion(World world) : base(world)
|
||||
{
|
||||
_rdc = new RayDataComparer();
|
||||
_data = new List<ShapeData>();
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics.Collision;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common.PhysicsLogic
|
||||
{
|
||||
@@ -11,8 +16,7 @@ namespace FarseerPhysics.Common.PhysicsLogic
|
||||
/// </summary>
|
||||
public sealed class SimpleExplosion : PhysicsLogic
|
||||
{
|
||||
public SimpleExplosion(World world)
|
||||
: base(world, PhysicsLogicType.Explosion)
|
||||
public SimpleExplosion(World world): base(world)
|
||||
{
|
||||
Power = 1; //linear
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using FarseerPhysics.Collision.Shapes;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Factories;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common.PolygonManipulation
|
||||
@@ -191,7 +195,7 @@ namespace FarseerPhysics.Common.PolygonManipulation
|
||||
//Delete the original shape and create two new. Retain the properties of the body.
|
||||
if (first.CheckPolygon() == PolygonError.NoError)
|
||||
{
|
||||
Body firstFixture = BodyFactory.CreatePolygon(world, first, fixtures[i].Shape.Density, fixtures[i].Body.Position);
|
||||
Body firstFixture = world.CreatePolygon(first, fixtures[i].Shape.Density, fixtures[i].Body.Position);
|
||||
firstFixture.Rotation = fixtures[i].Body.Rotation;
|
||||
firstFixture.LinearVelocity = fixtures[i].Body.LinearVelocity;
|
||||
firstFixture.AngularVelocity = fixtures[i].Body.AngularVelocity;
|
||||
@@ -200,14 +204,14 @@ namespace FarseerPhysics.Common.PolygonManipulation
|
||||
|
||||
if (second.CheckPolygon() == PolygonError.NoError)
|
||||
{
|
||||
Body secondFixture = BodyFactory.CreatePolygon(world, second, fixtures[i].Shape.Density, fixtures[i].Body.Position);
|
||||
Body secondFixture = world.CreatePolygon(second, fixtures[i].Shape.Density, fixtures[i].Body.Position);
|
||||
secondFixture.Rotation = fixtures[i].Body.Rotation;
|
||||
secondFixture.LinearVelocity = fixtures[i].Body.LinearVelocity;
|
||||
secondFixture.AngularVelocity = fixtures[i].Body.AngularVelocity;
|
||||
secondFixture.BodyType = BodyType.Dynamic;
|
||||
}
|
||||
|
||||
world.RemoveBody(fixtures[i].Body);
|
||||
world.Remove(fixtures[i].Body);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/*
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* C# Version Ported by Matt Bettcher and Ian Qvist 2009-2010
|
||||
*
|
||||
* Original C++ Version Copyright (c) 2007 Eric Jordan
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
+466
-461
@@ -1,514 +1,519 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common.PolygonManipulation
|
||||
{
|
||||
internal enum PolyClipType
|
||||
{
|
||||
Intersect,
|
||||
Union,
|
||||
Difference
|
||||
}
|
||||
|
||||
public enum PolyClipError
|
||||
{
|
||||
None,
|
||||
DegeneratedOutput,
|
||||
NonSimpleInput,
|
||||
BrokenResult
|
||||
}
|
||||
|
||||
//Clipper contributed by Helge Backhaus
|
||||
|
||||
public static class YuPengClipper
|
||||
{
|
||||
private const float ClipperEpsilonSquared = 1.192092896e-07f;
|
||||
|
||||
public static List<Vertices> Union(Vertices polygon1, Vertices polygon2, out PolyClipError error)
|
||||
internal enum PolyClipType
|
||||
{
|
||||
return Execute(polygon1, polygon2, PolyClipType.Union, out error);
|
||||
Intersect,
|
||||
Union,
|
||||
Difference
|
||||
}
|
||||
|
||||
public static List<Vertices> Difference(Vertices polygon1, Vertices polygon2, out PolyClipError error)
|
||||
public enum PolyClipError
|
||||
{
|
||||
return Execute(polygon1, polygon2, PolyClipType.Difference, out error);
|
||||
None,
|
||||
DegeneratedOutput,
|
||||
NonSimpleInput,
|
||||
BrokenResult
|
||||
}
|
||||
|
||||
public static List<Vertices> Intersect(Vertices polygon1, Vertices polygon2, out PolyClipError error)
|
||||
//Clipper contributed by Helge Backhaus
|
||||
|
||||
public static class YuPengClipper
|
||||
{
|
||||
return Execute(polygon1, polygon2, PolyClipType.Intersect, out error);
|
||||
}
|
||||
private const float ClipperEpsilonSquared = 1.192092896e-07f;
|
||||
|
||||
/// <summary>
|
||||
/// Implements "A new algorithm for Boolean operations on general polygons"
|
||||
/// available here: http://liama.ia.ac.cn/wiki/_media/user:dong:dong_cg_05.pdf
|
||||
/// Merges two polygons, a subject and a clip with the specified operation. Polygons may not be
|
||||
/// self-intersecting.
|
||||
///
|
||||
/// Warning: May yield incorrect results or even crash if polygons contain collinear points.
|
||||
/// </summary>
|
||||
/// <param name="subject">The subject polygon.</param>
|
||||
/// <param name="clip">The clip polygon, which is added,
|
||||
/// substracted or intersected with the subject</param>
|
||||
/// <param name="clipType">The operation to be performed. Either
|
||||
/// Union, Difference or Intersection.</param>
|
||||
/// <param name="error">The error generated (if any)</param>
|
||||
/// <returns>A list of closed polygons, which make up the result of the clipping operation.
|
||||
/// Outer contours are ordered counter clockwise, holes are ordered clockwise.</returns>
|
||||
private static List<Vertices> Execute(Vertices subject, Vertices clip, PolyClipType clipType, out PolyClipError error)
|
||||
{
|
||||
Debug.Assert(subject.IsSimple() && clip.IsSimple(), "Non simple input!", "Input polygons must be simple (cannot intersect themselves).");
|
||||
|
||||
// Copy polygons
|
||||
Vertices slicedSubject;
|
||||
Vertices slicedClip;
|
||||
// Calculate the intersection and touch points between
|
||||
// subject and clip and add them to both
|
||||
CalculateIntersections(subject, clip, out slicedSubject, out slicedClip);
|
||||
|
||||
// Translate polygons into upper right quadrant
|
||||
// as the algorithm depends on it
|
||||
Vector2 lbSubject = subject.GetAABB().LowerBound;
|
||||
Vector2 lbClip = clip.GetAABB().LowerBound;
|
||||
Vector2 translate;
|
||||
Vector2.Min(ref lbSubject, ref lbClip, out translate);
|
||||
translate = Vector2.One - translate;
|
||||
if (translate != Vector2.Zero)
|
||||
{
|
||||
slicedSubject.Translate(ref translate);
|
||||
slicedClip.Translate(ref translate);
|
||||
}
|
||||
|
||||
// Enforce counterclockwise contours
|
||||
slicedSubject.ForceCounterClockWise();
|
||||
slicedClip.ForceCounterClockWise();
|
||||
|
||||
List<Edge> subjectSimplices;
|
||||
List<float> subjectCoeff;
|
||||
List<Edge> clipSimplices;
|
||||
List<float> clipCoeff;
|
||||
// Build simplical chains from the polygons and calculate the
|
||||
// the corresponding coefficients
|
||||
CalculateSimplicalChain(slicedSubject, out subjectCoeff, out subjectSimplices);
|
||||
CalculateSimplicalChain(slicedClip, out clipCoeff, out clipSimplices);
|
||||
|
||||
List<Edge> resultSimplices;
|
||||
|
||||
// Determine the characteristics function for all non-original edges
|
||||
// in subject and clip simplical chain and combine the edges contributing
|
||||
// to the result, depending on the clipType
|
||||
CalculateResultChain(subjectCoeff, subjectSimplices, clipCoeff, clipSimplices, clipType,
|
||||
out resultSimplices);
|
||||
|
||||
List<Vertices> result;
|
||||
// Convert result chain back to polygon(s)
|
||||
error = BuildPolygonsFromChain(resultSimplices, out result);
|
||||
|
||||
// Reverse the polygon translation from the beginning
|
||||
// and remove collinear points from output
|
||||
translate *= -1f;
|
||||
for (int i = 0; i < result.Count; ++i)
|
||||
{
|
||||
result[i].Translate(ref translate);
|
||||
SimplifyTools.CollinearSimplify(result[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates all intersections between two polygons.
|
||||
/// </summary>
|
||||
/// <param name="polygon1">The first polygon.</param>
|
||||
/// <param name="polygon2">The second polygon.</param>
|
||||
/// <param name="slicedPoly1">Returns the first polygon with added intersection points.</param>
|
||||
/// <param name="slicedPoly2">Returns the second polygon with added intersection points.</param>
|
||||
private static void CalculateIntersections(Vertices polygon1, Vertices polygon2,
|
||||
out Vertices slicedPoly1, out Vertices slicedPoly2)
|
||||
{
|
||||
slicedPoly1 = new Vertices(polygon1);
|
||||
slicedPoly2 = new Vertices(polygon2);
|
||||
|
||||
// Iterate through polygon1's edges
|
||||
for (int i = 0; i < polygon1.Count; i++)
|
||||
{
|
||||
// Get edge vertices
|
||||
Vector2 a = polygon1[i];
|
||||
Vector2 b = polygon1[polygon1.NextIndex(i)];
|
||||
|
||||
// Get intersections between this edge and polygon2
|
||||
for (int j = 0; j < polygon2.Count; j++)
|
||||
public static List<Vertices> Union(Vertices polygon1, Vertices polygon2, out PolyClipError error)
|
||||
{
|
||||
Vector2 c = polygon2[j];
|
||||
Vector2 d = polygon2[polygon2.NextIndex(j)];
|
||||
return Execute(polygon1, polygon2, PolyClipType.Union, out error);
|
||||
}
|
||||
|
||||
Vector2 intersectionPoint;
|
||||
// Check if the edges intersect
|
||||
if (LineTools.LineIntersect(a, b, c, d, out intersectionPoint))
|
||||
{
|
||||
// calculate alpha values for sorting multiple intersections points on a edge
|
||||
float alpha;
|
||||
// Insert intersection point into first polygon
|
||||
alpha = GetAlpha(a, b, intersectionPoint);
|
||||
if (alpha > 0f && alpha < 1f)
|
||||
public static List<Vertices> Difference(Vertices polygon1, Vertices polygon2, out PolyClipError error)
|
||||
{
|
||||
return Execute(polygon1, polygon2, PolyClipType.Difference, out error);
|
||||
}
|
||||
|
||||
public static List<Vertices> Intersect(Vertices polygon1, Vertices polygon2, out PolyClipError error)
|
||||
{
|
||||
return Execute(polygon1, polygon2, PolyClipType.Intersect, out error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements "A new algorithm for Boolean operations on general polygons"
|
||||
/// available here: http://liama.ia.ac.cn/wiki/_media/user:dong:dong_cg_05.pdf
|
||||
/// Merges two polygons, a subject and a clip with the specified operation. Polygons may not be
|
||||
/// self-intersecting.
|
||||
///
|
||||
/// Warning: May yield incorrect results or even crash if polygons contain collinear points.
|
||||
/// </summary>
|
||||
/// <param name="subject">The subject polygon.</param>
|
||||
/// <param name="clip">The clip polygon, which is added,
|
||||
/// substracted or intersected with the subject</param>
|
||||
/// <param name="clipType">The operation to be performed. Either
|
||||
/// Union, Difference or Intersection.</param>
|
||||
/// <param name="error">The error generated (if any)</param>
|
||||
/// <returns>A list of closed polygons, which make up the result of the clipping operation.
|
||||
/// Outer contours are ordered counter clockwise, holes are ordered clockwise.</returns>
|
||||
private static List<Vertices> Execute(Vertices subject, Vertices clip, PolyClipType clipType, out PolyClipError error)
|
||||
{
|
||||
Debug.Assert(subject.IsSimple() && clip.IsSimple(), "Non simple input! Input polygons must be simple (cannot intersect themselves).");
|
||||
|
||||
// Copy polygons
|
||||
Vertices slicedSubject;
|
||||
Vertices slicedClip;
|
||||
// Calculate the intersection and touch points between
|
||||
// subject and clip and add them to both
|
||||
CalculateIntersections(subject, clip, out slicedSubject, out slicedClip);
|
||||
|
||||
// Translate polygons into upper right quadrant
|
||||
// as the algorithm depends on it
|
||||
Vector2 lbSubject = subject.GetAABB().LowerBound;
|
||||
Vector2 lbClip = clip.GetAABB().LowerBound;
|
||||
Vector2 translate;
|
||||
Vector2.Min(ref lbSubject, ref lbClip, out translate);
|
||||
translate = Vector2.One - translate;
|
||||
if (translate != Vector2.Zero)
|
||||
{
|
||||
int index = slicedPoly1.IndexOf(a) + 1;
|
||||
while (index < slicedPoly1.Count &&
|
||||
GetAlpha(a, b, slicedPoly1[index]) <= alpha)
|
||||
{
|
||||
++index;
|
||||
}
|
||||
slicedPoly1.Insert(index, intersectionPoint);
|
||||
slicedSubject.Translate(ref translate);
|
||||
slicedClip.Translate(ref translate);
|
||||
}
|
||||
// Insert intersection point into second polygon
|
||||
alpha = GetAlpha(c, d, intersectionPoint);
|
||||
if (alpha > 0f && alpha < 1f)
|
||||
|
||||
// Enforce counterclockwise contours
|
||||
slicedSubject.ForceCounterClockWise();
|
||||
slicedClip.ForceCounterClockWise();
|
||||
|
||||
List<Edge> subjectSimplices;
|
||||
List<float> subjectCoeff;
|
||||
List<Edge> clipSimplices;
|
||||
List<float> clipCoeff;
|
||||
// Build simplical chains from the polygons and calculate the
|
||||
// the corresponding coefficients
|
||||
CalculateSimplicalChain(slicedSubject, out subjectCoeff, out subjectSimplices);
|
||||
CalculateSimplicalChain(slicedClip, out clipCoeff, out clipSimplices);
|
||||
|
||||
List<Edge> resultSimplices;
|
||||
|
||||
// Determine the characteristics function for all non-original edges
|
||||
// in subject and clip simplical chain and combine the edges contributing
|
||||
// to the result, depending on the clipType
|
||||
CalculateResultChain(subjectCoeff, subjectSimplices, clipCoeff, clipSimplices, clipType,
|
||||
out resultSimplices);
|
||||
|
||||
List<Vertices> result;
|
||||
// Convert result chain back to polygon(s)
|
||||
error = BuildPolygonsFromChain(resultSimplices, out result);
|
||||
|
||||
// Reverse the polygon translation from the beginning
|
||||
// and remove collinear points from output
|
||||
translate *= -1f;
|
||||
for (int i = 0; i < result.Count; ++i)
|
||||
{
|
||||
int index = slicedPoly2.IndexOf(c) + 1;
|
||||
while (index < slicedPoly2.Count &&
|
||||
GetAlpha(c, d, slicedPoly2[index]) <= alpha)
|
||||
{
|
||||
++index;
|
||||
}
|
||||
slicedPoly2.Insert(index, intersectionPoint);
|
||||
result[i].Translate(ref translate);
|
||||
SimplifyTools.CollinearSimplify(result[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Check for very small edges
|
||||
for (int i = 0; i < slicedPoly1.Count; ++i)
|
||||
{
|
||||
int iNext = slicedPoly1.NextIndex(i);
|
||||
//If they are closer than the distance remove vertex
|
||||
if ((slicedPoly1[iNext] - slicedPoly1[i]).LengthSquared() <= ClipperEpsilonSquared)
|
||||
{
|
||||
slicedPoly1.RemoveAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < slicedPoly2.Count; ++i)
|
||||
{
|
||||
int iNext = slicedPoly2.NextIndex(i);
|
||||
//If they are closer than the distance remove vertex
|
||||
if ((slicedPoly2[iNext] - slicedPoly2[i]).LengthSquared() <= ClipperEpsilonSquared)
|
||||
{
|
||||
slicedPoly2.RemoveAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the simplical chain corresponding to the input polygon.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>Execute()</c>.</remarks>
|
||||
private static void CalculateSimplicalChain(Vertices poly, out List<float> coeff,
|
||||
out List<Edge> simplicies)
|
||||
{
|
||||
simplicies = new List<Edge>();
|
||||
coeff = new List<float>();
|
||||
for (int i = 0; i < poly.Count; ++i)
|
||||
{
|
||||
simplicies.Add(new Edge(poly[i], poly[poly.NextIndex(i)]));
|
||||
coeff.Add(CalculateSimplexCoefficient(Vector2.Zero, poly[i], poly[poly.NextIndex(i)]));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Calculates all intersections between two polygons.
|
||||
/// </summary>
|
||||
/// <param name="polygon1">The first polygon.</param>
|
||||
/// <param name="polygon2">The second polygon.</param>
|
||||
/// <param name="slicedPoly1">Returns the first polygon with added intersection points.</param>
|
||||
/// <param name="slicedPoly2">Returns the second polygon with added intersection points.</param>
|
||||
private static void CalculateIntersections(Vertices polygon1, Vertices polygon2,
|
||||
out Vertices slicedPoly1, out Vertices slicedPoly2)
|
||||
{
|
||||
slicedPoly1 = new Vertices(polygon1);
|
||||
slicedPoly2 = new Vertices(polygon2);
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the characteristics function for all edges of
|
||||
/// the given simplical chains and builds the result chain.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>Execute()</c>.</remarks>
|
||||
private static void CalculateResultChain(List<float> poly1Coeff, List<Edge> poly1Simplicies,
|
||||
List<float> poly2Coeff, List<Edge> poly2Simplicies,
|
||||
PolyClipType clipType, out List<Edge> resultSimplices)
|
||||
{
|
||||
resultSimplices = new List<Edge>();
|
||||
|
||||
for (int i = 0; i < poly1Simplicies.Count; ++i)
|
||||
{
|
||||
float edgeCharacter = 0;
|
||||
if (poly2Simplicies.Contains(poly1Simplicies[i]))
|
||||
{
|
||||
edgeCharacter = 1f;
|
||||
}
|
||||
else if (poly2Simplicies.Contains(-poly1Simplicies[i]) && clipType == PolyClipType.Union)
|
||||
{
|
||||
edgeCharacter = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < poly2Simplicies.Count; ++j)
|
||||
{
|
||||
if (!poly2Simplicies.Contains(-poly1Simplicies[i]))
|
||||
// Iterate through polygon1's edges
|
||||
for (int i = 0; i < polygon1.Count; i++)
|
||||
{
|
||||
edgeCharacter += CalculateBeta(poly1Simplicies[i].GetCenter(),
|
||||
poly2Simplicies[j], poly2Coeff[j]);
|
||||
// Get edge vertices
|
||||
Vector2 a = polygon1[i];
|
||||
Vector2 b = polygon1[polygon1.NextIndex(i)];
|
||||
|
||||
// Get intersections between this edge and polygon2
|
||||
for (int j = 0; j < polygon2.Count; j++)
|
||||
{
|
||||
Vector2 c = polygon2[j];
|
||||
Vector2 d = polygon2[polygon2.NextIndex(j)];
|
||||
|
||||
Vector2 intersectionPoint;
|
||||
// Check if the edges intersect
|
||||
if (LineTools.LineIntersect(a, b, c, d, out intersectionPoint))
|
||||
{
|
||||
// calculate alpha values for sorting multiple intersections points on a edge
|
||||
float alpha;
|
||||
// Insert intersection point into first polygon
|
||||
alpha = GetAlpha(a, b, intersectionPoint);
|
||||
if (alpha > 0f && alpha < 1f)
|
||||
{
|
||||
int index = slicedPoly1.IndexOf(a) + 1;
|
||||
while (index < slicedPoly1.Count &&
|
||||
GetAlpha(a, b, slicedPoly1[index]) <= alpha)
|
||||
{
|
||||
++index;
|
||||
}
|
||||
slicedPoly1.Insert(index, intersectionPoint);
|
||||
}
|
||||
// Insert intersection point into second polygon
|
||||
alpha = GetAlpha(c, d, intersectionPoint);
|
||||
if (alpha > 0f && alpha < 1f)
|
||||
{
|
||||
int index = slicedPoly2.IndexOf(c) + 1;
|
||||
while (index < slicedPoly2.Count &&
|
||||
GetAlpha(c, d, slicedPoly2[index]) <= alpha)
|
||||
{
|
||||
++index;
|
||||
}
|
||||
slicedPoly2.Insert(index, intersectionPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check for very small edges
|
||||
for (int i = 0; i < slicedPoly1.Count; ++i)
|
||||
{
|
||||
int iNext = slicedPoly1.NextIndex(i);
|
||||
//If they are closer than the distance remove vertex
|
||||
if ((slicedPoly1[iNext] - slicedPoly1[i]).LengthSquared() <= ClipperEpsilonSquared)
|
||||
{
|
||||
slicedPoly1.RemoveAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < slicedPoly2.Count; ++i)
|
||||
{
|
||||
int iNext = slicedPoly2.NextIndex(i);
|
||||
//If they are closer than the distance remove vertex
|
||||
if ((slicedPoly2[iNext] - slicedPoly2[i]).LengthSquared() <= ClipperEpsilonSquared)
|
||||
{
|
||||
slicedPoly2.RemoveAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (clipType == PolyClipType.Intersect)
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the simplical chain corresponding to the input polygon.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>Execute()</c>.</remarks>
|
||||
private static void CalculateSimplicalChain(Vertices poly, out List<float> coeff,
|
||||
out List<Edge> simplicies)
|
||||
{
|
||||
if (edgeCharacter == 1f)
|
||||
{
|
||||
resultSimplices.Add(poly1Simplicies[i]);
|
||||
}
|
||||
simplicies = new List<Edge>();
|
||||
coeff = new List<float>();
|
||||
for (int i = 0; i < poly.Count; ++i)
|
||||
{
|
||||
simplicies.Add(new Edge(poly[i], poly[poly.NextIndex(i)]));
|
||||
coeff.Add(CalculateSimplexCoefficient(Vector2.Zero, poly[i], poly[poly.NextIndex(i)]));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the characteristics function for all edges of
|
||||
/// the given simplical chains and builds the result chain.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>Execute()</c>.</remarks>
|
||||
private static void CalculateResultChain(List<float> poly1Coeff, List<Edge> poly1Simplicies,
|
||||
List<float> poly2Coeff, List<Edge> poly2Simplicies,
|
||||
PolyClipType clipType, out List<Edge> resultSimplices)
|
||||
{
|
||||
if (edgeCharacter == 0f)
|
||||
{
|
||||
resultSimplices.Add(poly1Simplicies[i]);
|
||||
}
|
||||
resultSimplices = new List<Edge>();
|
||||
|
||||
for (int i = 0; i < poly1Simplicies.Count; ++i)
|
||||
{
|
||||
float edgeCharacter = 0;
|
||||
if (poly2Simplicies.Contains(poly1Simplicies[i]))
|
||||
{
|
||||
edgeCharacter = 1f;
|
||||
}
|
||||
else if (poly2Simplicies.Contains(-poly1Simplicies[i]) && clipType == PolyClipType.Union)
|
||||
{
|
||||
edgeCharacter = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < poly2Simplicies.Count; ++j)
|
||||
{
|
||||
if (!poly2Simplicies.Contains(-poly1Simplicies[i]))
|
||||
{
|
||||
edgeCharacter += CalculateBeta(poly1Simplicies[i].GetCenter(),
|
||||
poly2Simplicies[j], poly2Coeff[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (clipType == PolyClipType.Intersect)
|
||||
{
|
||||
if (edgeCharacter == 1f)
|
||||
{
|
||||
resultSimplices.Add(poly1Simplicies[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (edgeCharacter == 0f)
|
||||
{
|
||||
resultSimplices.Add(poly1Simplicies[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < poly2Simplicies.Count; ++i)
|
||||
{
|
||||
float edgeCharacter = 0f;
|
||||
if (!resultSimplices.Contains(poly2Simplicies[i]) &&
|
||||
!resultSimplices.Contains(-poly2Simplicies[i]))
|
||||
{
|
||||
if (poly1Simplicies.Contains(-poly2Simplicies[i]) && clipType == PolyClipType.Union)
|
||||
{
|
||||
edgeCharacter = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgeCharacter = 0f;
|
||||
for (int j = 0; j < poly1Simplicies.Count; ++j)
|
||||
{
|
||||
if (!poly1Simplicies.Contains(poly2Simplicies[i]) && !poly1Simplicies.Contains(-poly2Simplicies[i]))
|
||||
{
|
||||
edgeCharacter += CalculateBeta(poly2Simplicies[i].GetCenter(),
|
||||
poly1Simplicies[j], poly1Coeff[j]);
|
||||
}
|
||||
}
|
||||
if (clipType == PolyClipType.Intersect || clipType == PolyClipType.Difference)
|
||||
{
|
||||
if (edgeCharacter == 1f)
|
||||
{
|
||||
resultSimplices.Add(-poly2Simplicies[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (edgeCharacter == 0f)
|
||||
{
|
||||
resultSimplices.Add(poly2Simplicies[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < poly2Simplicies.Count; ++i)
|
||||
{
|
||||
float edgeCharacter = 0f;
|
||||
if (!resultSimplices.Contains(poly2Simplicies[i]) &&
|
||||
!resultSimplices.Contains(-poly2Simplicies[i]))
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the polygon(s) from the result simplical chain.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>Execute()</c>.</remarks>
|
||||
private static PolyClipError BuildPolygonsFromChain(List<Edge> simplicies, out List<Vertices> result)
|
||||
{
|
||||
if (poly1Simplicies.Contains(-poly2Simplicies[i]) && clipType == PolyClipType.Union)
|
||||
{
|
||||
edgeCharacter = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgeCharacter = 0f;
|
||||
for (int j = 0; j < poly1Simplicies.Count; ++j)
|
||||
result = new List<Vertices>();
|
||||
PolyClipError errVal = PolyClipError.None;
|
||||
|
||||
while (simplicies.Count > 0)
|
||||
{
|
||||
if (!poly1Simplicies.Contains(poly2Simplicies[i]) && !poly1Simplicies.Contains(-poly2Simplicies[i]))
|
||||
{
|
||||
edgeCharacter += CalculateBeta(poly2Simplicies[i].GetCenter(),
|
||||
poly1Simplicies[j], poly1Coeff[j]);
|
||||
}
|
||||
Vertices output = new Vertices();
|
||||
output.Add(simplicies[0].EdgeStart);
|
||||
output.Add(simplicies[0].EdgeEnd);
|
||||
simplicies.RemoveAt(0);
|
||||
bool closed = false;
|
||||
int index = 0;
|
||||
int count = simplicies.Count; // Needed to catch infinite loops
|
||||
while (!closed && simplicies.Count > 0)
|
||||
{
|
||||
if (VectorEqual(output[output.Count - 1], simplicies[index].EdgeStart))
|
||||
{
|
||||
if (VectorEqual(simplicies[index].EdgeEnd, output[0]))
|
||||
{
|
||||
closed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
output.Add(simplicies[index].EdgeEnd);
|
||||
}
|
||||
simplicies.RemoveAt(index);
|
||||
--index;
|
||||
}
|
||||
else if (VectorEqual(output[output.Count - 1], simplicies[index].EdgeEnd))
|
||||
{
|
||||
if (VectorEqual(simplicies[index].EdgeStart, output[0]))
|
||||
{
|
||||
closed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
output.Add(simplicies[index].EdgeStart);
|
||||
}
|
||||
simplicies.RemoveAt(index);
|
||||
--index;
|
||||
}
|
||||
if (!closed)
|
||||
{
|
||||
if (++index == simplicies.Count)
|
||||
{
|
||||
if (count == simplicies.Count)
|
||||
{
|
||||
result = new List<Vertices>();
|
||||
Debug.WriteLine("Undefined error while building result polygon(s).");
|
||||
return PolyClipError.BrokenResult;
|
||||
}
|
||||
index = 0;
|
||||
count = simplicies.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (output.Count < 3)
|
||||
{
|
||||
errVal = PolyClipError.DegeneratedOutput;
|
||||
Debug.WriteLine("Degenerated output polygon produced (vertices < 3).");
|
||||
}
|
||||
result.Add(output);
|
||||
}
|
||||
if (clipType == PolyClipType.Intersect || clipType == PolyClipType.Difference)
|
||||
{
|
||||
if (edgeCharacter == 1f)
|
||||
{
|
||||
resultSimplices.Add(-poly2Simplicies[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (edgeCharacter == 0f)
|
||||
{
|
||||
resultSimplices.Add(poly2Simplicies[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return errVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the polygon(s) from the result simplical chain.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>Execute()</c>.</remarks>
|
||||
private static PolyClipError BuildPolygonsFromChain(List<Edge> simplicies, out List<Vertices> result)
|
||||
{
|
||||
result = new List<Vertices>();
|
||||
PolyClipError errVal = PolyClipError.None;
|
||||
|
||||
while (simplicies.Count > 0)
|
||||
{
|
||||
Vertices output = new Vertices();
|
||||
output.Add(simplicies[0].EdgeStart);
|
||||
output.Add(simplicies[0].EdgeEnd);
|
||||
simplicies.RemoveAt(0);
|
||||
bool closed = false;
|
||||
int index = 0;
|
||||
int count = simplicies.Count; // Needed to catch infinite loops
|
||||
while (!closed && simplicies.Count > 0)
|
||||
/// <summary>
|
||||
/// Needed to calculate the characteristics function of a simplex.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>CalculateEdgeCharacter()</c>.</remarks>
|
||||
private static float CalculateBeta(Vector2 point, Edge e, float coefficient)
|
||||
{
|
||||
if (VectorEqual(output[output.Count - 1], simplicies[index].EdgeStart))
|
||||
{
|
||||
if (VectorEqual(simplicies[index].EdgeEnd, output[0]))
|
||||
float result = 0f;
|
||||
if (PointInSimplex(point, e))
|
||||
{
|
||||
closed = true;
|
||||
result = coefficient;
|
||||
}
|
||||
else
|
||||
if (PointOnLineSegment(Vector2.Zero, e.EdgeStart, point) ||
|
||||
PointOnLineSegment(Vector2.Zero, e.EdgeEnd, point))
|
||||
{
|
||||
output.Add(simplicies[index].EdgeEnd);
|
||||
result = .5f * coefficient;
|
||||
}
|
||||
simplicies.RemoveAt(index);
|
||||
--index;
|
||||
}
|
||||
else if (VectorEqual(output[output.Count - 1], simplicies[index].EdgeEnd))
|
||||
{
|
||||
if (VectorEqual(simplicies[index].EdgeStart, output[0]))
|
||||
{
|
||||
closed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
output.Add(simplicies[index].EdgeStart);
|
||||
}
|
||||
simplicies.RemoveAt(index);
|
||||
--index;
|
||||
}
|
||||
if (!closed)
|
||||
{
|
||||
if (++index == simplicies.Count)
|
||||
{
|
||||
if (count == simplicies.Count)
|
||||
{
|
||||
result = new List<Vertices>();
|
||||
Debug.WriteLine("Undefined error while building result polygon(s).");
|
||||
return PolyClipError.BrokenResult;
|
||||
}
|
||||
index = 0;
|
||||
count = simplicies.Count;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (output.Count < 3)
|
||||
|
||||
/// <summary>
|
||||
/// Needed for sorting multiple intersections points on the same edge.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>CalculateIntersections()</c>.</remarks>
|
||||
private static float GetAlpha(Vector2 start, Vector2 end, Vector2 point)
|
||||
{
|
||||
errVal = PolyClipError.DegeneratedOutput;
|
||||
Debug.WriteLine("Degenerated output polygon produced (vertices < 3).");
|
||||
return (point - start).LengthSquared() / (end - start).LengthSquared();
|
||||
}
|
||||
result.Add(output);
|
||||
}
|
||||
return errVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Needed to calculate the characteristics function of a simplex.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>CalculateEdgeCharacter()</c>.</remarks>
|
||||
private static float CalculateBeta(Vector2 point, Edge e, float coefficient)
|
||||
{
|
||||
float result = 0f;
|
||||
if (PointInSimplex(point, e))
|
||||
{
|
||||
result = coefficient;
|
||||
}
|
||||
if (PointOnLineSegment(Vector2.Zero, e.EdgeStart, point) ||
|
||||
PointOnLineSegment(Vector2.Zero, e.EdgeEnd, point))
|
||||
{
|
||||
result = .5f * coefficient;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Needed for sorting multiple intersections points on the same edge.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>CalculateIntersections()</c>.</remarks>
|
||||
private static float GetAlpha(Vector2 start, Vector2 end, Vector2 point)
|
||||
{
|
||||
return (point - start).LengthSquared() / (end - start).LengthSquared();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the coefficient of a simplex.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>CalculateSimplicalChain()</c>.</remarks>
|
||||
private static float CalculateSimplexCoefficient(Vector2 a, Vector2 b, Vector2 c)
|
||||
{
|
||||
float isLeft = MathUtils.Area(ref a, ref b, ref c);
|
||||
if (isLeft < 0f)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
|
||||
if (isLeft > 0f)
|
||||
{
|
||||
return 1f;
|
||||
}
|
||||
|
||||
return 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Winding number test for a point in a simplex.
|
||||
/// </summary>
|
||||
/// <param name="point">The point to be tested.</param>
|
||||
/// <param name="edge">The edge that the point is tested against.</param>
|
||||
/// <returns>False if the winding number is even and the point is outside
|
||||
/// the simplex and True otherwise.</returns>
|
||||
private static bool PointInSimplex(Vector2 point, Edge edge)
|
||||
{
|
||||
Vertices polygon = new Vertices();
|
||||
polygon.Add(Vector2.Zero);
|
||||
polygon.Add(edge.EdgeStart);
|
||||
polygon.Add(edge.EdgeEnd);
|
||||
return (polygon.PointInPolygon(ref point) == 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if a point lies on a line segment.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>CalculateBeta()</c>.</remarks>
|
||||
private static bool PointOnLineSegment(Vector2 start, Vector2 end, Vector2 point)
|
||||
{
|
||||
Vector2 segment = end - start;
|
||||
return MathUtils.Area(ref start, ref end, ref point) == 0f &&
|
||||
Vector2.Dot(point - start, segment) >= 0f &&
|
||||
Vector2.Dot(point - end, segment) <= 0f;
|
||||
}
|
||||
|
||||
private static bool VectorEqual(Vector2 vec1, Vector2 vec2)
|
||||
{
|
||||
return (vec2 - vec1).LengthSquared() <= ClipperEpsilonSquared;
|
||||
}
|
||||
|
||||
#region Nested type: Edge
|
||||
|
||||
/// <summary>Specifies an Edge. Edges are used to represent simplicies in simplical chains</summary>
|
||||
private sealed class Edge
|
||||
{
|
||||
public Edge(Vector2 edgeStart, Vector2 edgeEnd)
|
||||
{
|
||||
EdgeStart = edgeStart;
|
||||
EdgeEnd = edgeEnd;
|
||||
}
|
||||
|
||||
public Vector2 EdgeStart { get; private set; }
|
||||
public Vector2 EdgeEnd { get; private set; }
|
||||
|
||||
public Vector2 GetCenter()
|
||||
{
|
||||
return (EdgeStart + EdgeEnd) / 2f;
|
||||
}
|
||||
|
||||
public static Edge operator -(Edge e)
|
||||
{
|
||||
return new Edge(e.EdgeEnd, e.EdgeStart);
|
||||
}
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
// If parameter is null return false.
|
||||
if (obj == null)
|
||||
/// <summary>
|
||||
/// Returns the coefficient of a simplex.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>CalculateSimplicalChain()</c>.</remarks>
|
||||
private static float CalculateSimplexCoefficient(Vector2 a, Vector2 b, Vector2 c)
|
||||
{
|
||||
return false;
|
||||
float isLeft = MathUtils.Area(ref a, ref b, ref c);
|
||||
if (isLeft < 0f)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
|
||||
if (isLeft > 0f)
|
||||
{
|
||||
return 1f;
|
||||
}
|
||||
|
||||
return 0f;
|
||||
}
|
||||
|
||||
// If parameter cannot be cast to Point return false.
|
||||
return Equals(obj as Edge);
|
||||
}
|
||||
|
||||
public bool Equals(Edge e)
|
||||
{
|
||||
// If parameter is null return false:
|
||||
if (e == null)
|
||||
/// <summary>
|
||||
/// Winding number test for a point in a simplex.
|
||||
/// </summary>
|
||||
/// <param name="point">The point to be tested.</param>
|
||||
/// <param name="edge">The edge that the point is tested against.</param>
|
||||
/// <returns>False if the winding number is even and the point is outside
|
||||
/// the simplex and True otherwise.</returns>
|
||||
private static bool PointInSimplex(Vector2 point, Edge edge)
|
||||
{
|
||||
return false;
|
||||
Vertices polygon = new Vertices();
|
||||
polygon.Add(Vector2.Zero);
|
||||
polygon.Add(edge.EdgeStart);
|
||||
polygon.Add(edge.EdgeEnd);
|
||||
return (polygon.PointInPolygon(ref point) == 1);
|
||||
}
|
||||
|
||||
// Return true if the fields match
|
||||
return VectorEqual(EdgeStart, e.EdgeStart) && VectorEqual(EdgeEnd, e.EdgeEnd);
|
||||
}
|
||||
/// <summary>
|
||||
/// Tests if a point lies on a line segment.
|
||||
/// </summary>
|
||||
/// <remarks>Used by method <c>CalculateBeta()</c>.</remarks>
|
||||
private static bool PointOnLineSegment(Vector2 start, Vector2 end, Vector2 point)
|
||||
{
|
||||
Vector2 segment = end - start;
|
||||
return MathUtils.Area(ref start, ref end, ref point) == 0f &&
|
||||
Vector2.Dot(point - start, segment) >= 0f &&
|
||||
Vector2.Dot(point - end, segment) <= 0f;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return EdgeStart.GetHashCode() ^ EdgeEnd.GetHashCode();
|
||||
}
|
||||
private static bool VectorEqual(Vector2 vec1, Vector2 vec2)
|
||||
{
|
||||
return (vec2 - vec1).LengthSquared() <= ClipperEpsilonSquared;
|
||||
}
|
||||
|
||||
#region Nested type: Edge
|
||||
|
||||
/// <summary>Specifies an Edge. Edges are used to represent simplicies in simplical chains</summary>
|
||||
private sealed class Edge
|
||||
{
|
||||
public Edge(Vector2 edgeStart, Vector2 edgeEnd)
|
||||
{
|
||||
EdgeStart = edgeStart;
|
||||
EdgeEnd = edgeEnd;
|
||||
}
|
||||
|
||||
public Vector2 EdgeStart { get; private set; }
|
||||
public Vector2 EdgeEnd { get; private set; }
|
||||
|
||||
public Vector2 GetCenter()
|
||||
{
|
||||
return (EdgeStart + EdgeEnd) / 2f;
|
||||
}
|
||||
|
||||
public static Edge operator -(Edge e)
|
||||
{
|
||||
return new Edge(e.EdgeEnd, e.EdgeStart);
|
||||
}
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
// If parameter is null return false.
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If parameter cannot be cast to Point return false.
|
||||
return Equals(obj as Edge);
|
||||
}
|
||||
|
||||
public bool Equals(Edge e)
|
||||
{
|
||||
// If parameter is null return false:
|
||||
if (e == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if the fields match
|
||||
return VectorEqual(EdgeStart, e.EdgeStart) && VectorEqual(EdgeEnd, e.EdgeEnd);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return EdgeStart.GetHashCode() ^ EdgeEnd.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using FarseerPhysics.Common.TextureTools;
|
||||
using FarseerPhysics.Common.Maths;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common
|
||||
@@ -35,14 +41,12 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
Vertices vertices = CreateRectangle(hx, hy);
|
||||
|
||||
Transform xf = new Transform();
|
||||
xf.p = center;
|
||||
xf.q.Set(angle);
|
||||
Transform xf = new Transform(center, angle);
|
||||
|
||||
// Transform vertices
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
vertices[i] = MathUtils.Mul(ref xf, vertices[i]);
|
||||
vertices[i] = Transform.Multiply(vertices[i], ref xf);
|
||||
}
|
||||
|
||||
return vertices;
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -18,28 +23,22 @@ namespace FarseerPhysics.Common
|
||||
public static class WorldSerializer
|
||||
{
|
||||
/// <summary>
|
||||
/// Serialize the world to an XML file
|
||||
/// Serialize the world to a stream in XML format
|
||||
/// </summary>
|
||||
/// <param name="world"></param>
|
||||
/// <param name="filename"></param>
|
||||
public static void Serialize(World world, string filename)
|
||||
/// <param name="stream"></param>
|
||||
public static void Serialize(World world, Stream stream)
|
||||
{
|
||||
using (FileStream fs = new FileStream(filename, FileMode.Create))
|
||||
{
|
||||
WorldXmlSerializer.Serialize(world, fs);
|
||||
}
|
||||
WorldXmlSerializer.Serialize(world, stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize the world from an XML file
|
||||
/// Deserialize the world from a stream XML
|
||||
/// </summary>
|
||||
/// <param name="filename"></param>
|
||||
public static World Deserialize(string filename)
|
||||
/// <param name="stream"></param>
|
||||
public static World Deserialize(Stream stream)
|
||||
{
|
||||
using (FileStream fs = new FileStream(filename, FileMode.Open))
|
||||
{
|
||||
return WorldXmlDeserializer.Deserialize(fs);
|
||||
}
|
||||
return WorldXmlDeserializer.Deserialize(stream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +50,7 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
_writer.WriteStartElement("Shape");
|
||||
_writer.WriteAttributeString("Type", shape.ShapeType.ToString());
|
||||
_writer.WriteAttributeString("Density", shape.Density.ToString());
|
||||
_writer.WriteAttributeString("Density", FloatToString(shape.Density));
|
||||
|
||||
switch (shape.ShapeType)
|
||||
{
|
||||
@@ -59,7 +58,7 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
CircleShape circle = (CircleShape)shape;
|
||||
|
||||
_writer.WriteElementString("Radius", circle.Radius.ToString());
|
||||
WriteElement("Radius", circle.Radius);
|
||||
|
||||
WriteElement("Position", circle.Position);
|
||||
}
|
||||
@@ -103,51 +102,50 @@ namespace FarseerPhysics.Common
|
||||
_writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private static void SerializeFixture(Fixture fixture)
|
||||
private static void SerializeFixture(List<Fixture> fixtures, Fixture fixture)
|
||||
{
|
||||
_writer.WriteStartElement("Fixture");
|
||||
_writer.WriteAttributeString("Id", fixture.FixtureId.ToString());
|
||||
_writer.WriteAttributeString("Id", fixtures.IndexOf(fixture).ToString());
|
||||
|
||||
_writer.WriteStartElement("FilterData");
|
||||
_writer.WriteElementString("CategoryBits", ((int)fixture.CollisionCategories).ToString());
|
||||
_writer.WriteElementString("MaskBits", ((int)fixture.CollidesWith).ToString());
|
||||
_writer.WriteElementString("GroupIndex", fixture.CollisionGroup.ToString());
|
||||
_writer.WriteElementString("CollisionIgnores", Join("|", fixture._collisionIgnores));
|
||||
_writer.WriteEndElement();
|
||||
|
||||
_writer.WriteElementString("Friction", fixture.Friction.ToString());
|
||||
WriteElement("Friction", fixture.Friction);
|
||||
_writer.WriteElementString("IsSensor", fixture.IsSensor.ToString());
|
||||
_writer.WriteElementString("Restitution", fixture.Restitution.ToString());
|
||||
WriteElement("Restitution", fixture.Restitution);
|
||||
|
||||
if (fixture.UserData != null)
|
||||
{
|
||||
_writer.WriteStartElement("UserData");
|
||||
_writer.WriteStartElement("Tag");
|
||||
WriteDynamicType(fixture.UserData.GetType(), fixture.UserData);
|
||||
_writer.WriteEndElement();
|
||||
}
|
||||
|
||||
_writer.WriteEndElement();
|
||||
}
|
||||
|
||||
|
||||
private static void SerializeBody(List<Fixture> fixtures, List<Shape> shapes, Body body)
|
||||
{
|
||||
_writer.WriteStartElement("Body");
|
||||
_writer.WriteAttributeString("Type", body.BodyType.ToString());
|
||||
_writer.WriteElementString("Active", body.Enabled.ToString());
|
||||
_writer.WriteElementString("AllowSleep", body.SleepingAllowed.ToString());
|
||||
_writer.WriteElementString("Angle", body.Rotation.ToString());
|
||||
_writer.WriteElementString("AngularDamping", body.AngularDamping.ToString());
|
||||
_writer.WriteElementString("AngularVelocity", body.AngularVelocity.ToString());
|
||||
WriteElement("Angle", body.Rotation);
|
||||
WriteElement("AngularDamping", body.AngularDamping);
|
||||
WriteElement("AngularVelocity", body.AngularVelocity);
|
||||
_writer.WriteElementString("Awake", body.Awake.ToString());
|
||||
_writer.WriteElementString("Bullet", body.IsBullet.ToString());
|
||||
_writer.WriteElementString("FixedRotation", body.FixedRotation.ToString());
|
||||
_writer.WriteElementString("LinearDamping", body.LinearDamping.ToString());
|
||||
WriteElement("LinearDamping", body.LinearDamping);
|
||||
WriteElement("LinearVelocity", body.LinearVelocity);
|
||||
WriteElement("Position", body.Position);
|
||||
|
||||
if (body.UserData != null)
|
||||
{
|
||||
_writer.WriteStartElement("UserData");
|
||||
_writer.WriteStartElement("Tag");
|
||||
WriteDynamicType(body.UserData.GetType(), body.UserData);
|
||||
_writer.WriteEndElement();
|
||||
}
|
||||
@@ -156,8 +154,8 @@ namespace FarseerPhysics.Common
|
||||
for (int i = 0; i < body.FixtureList.Count; i++)
|
||||
{
|
||||
_writer.WriteStartElement("Pair");
|
||||
_writer.WriteAttributeString("FixtureId", FindIndex(fixtures, body.FixtureList[i]).ToString());
|
||||
_writer.WriteAttributeString("ShapeId", FindIndex(shapes, body.FixtureList[i].Shape).ToString());
|
||||
_writer.WriteAttributeString("FixtureId", fixtures.IndexOf(body.FixtureList[i]).ToString());
|
||||
_writer.WriteAttributeString("ShapeId", shapes.IndexOf(body.FixtureList[i].Shape).ToString());
|
||||
_writer.WriteEndElement();
|
||||
}
|
||||
|
||||
@@ -170,17 +168,17 @@ namespace FarseerPhysics.Common
|
||||
_writer.WriteStartElement("Joint");
|
||||
_writer.WriteAttributeString("Type", joint.JointType.ToString());
|
||||
|
||||
WriteElement("BodyA", FindIndex(bodies, joint.BodyA));
|
||||
WriteElement("BodyB", FindIndex(bodies, joint.BodyB));
|
||||
WriteElement("BodyA", bodies.IndexOf(joint.BodyA));
|
||||
WriteElement("BodyB", bodies.IndexOf(joint.BodyB));
|
||||
|
||||
WriteElement("CollideConnected", joint.CollideConnected);
|
||||
|
||||
WriteElement("Breakpoint", joint.Breakpoint);
|
||||
|
||||
if (joint.UserData != null)
|
||||
if (joint.Tag != null)
|
||||
{
|
||||
_writer.WriteStartElement("UserData");
|
||||
WriteDynamicType(joint.UserData.GetType(), joint.UserData);
|
||||
_writer.WriteStartElement("Tag");
|
||||
WriteDynamicType(joint.Tag.GetType(), joint.Tag);
|
||||
_writer.WriteEndElement();
|
||||
}
|
||||
|
||||
@@ -313,15 +311,13 @@ namespace FarseerPhysics.Common
|
||||
|
||||
_writer.WriteStartElement("Value");
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
|
||||
xmlnsEmpty.Add("", "");
|
||||
serializer.Serialize(_writer, val, xmlnsEmpty);
|
||||
serializer.Serialize(_writer, val);
|
||||
_writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private static void WriteElement(string name, Vector2 vec)
|
||||
{
|
||||
_writer.WriteElementString(name, vec.X + " " + vec.Y);
|
||||
_writer.WriteElementString(name, FloatToString(vec.X) + " " + FloatToString(vec.Y));
|
||||
}
|
||||
|
||||
private static void WriteElement(string name, int val)
|
||||
@@ -336,39 +332,17 @@ namespace FarseerPhysics.Common
|
||||
|
||||
private static void WriteElement(string name, float val)
|
||||
{
|
||||
_writer.WriteElementString(name, val.ToString());
|
||||
_writer.WriteElementString(name, FloatToString(val));
|
||||
}
|
||||
|
||||
private static int FindIndex(List<Body> list, Body item)
|
||||
private static string FloatToString(float value)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
if (list[i] == item)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
return value.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private static int FindIndex(List<Fixture> list, Fixture item)
|
||||
private static String Join(List<Fixture> fixtures, IEnumerable<Fixture> values)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
if (list[i].CompareTo(item))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int FindIndex(List<Shape> list, Shape item)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
if (list[i].CompareTo(item))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static String Join<T>(String separator, IEnumerable<T> values)
|
||||
{
|
||||
using (IEnumerator<T> en = values.GetEnumerator())
|
||||
using (var en = values.GetEnumerator())
|
||||
{
|
||||
if (!en.MoveNext())
|
||||
return String.Empty;
|
||||
@@ -376,24 +350,18 @@ namespace FarseerPhysics.Common
|
||||
StringBuilder result = new StringBuilder();
|
||||
if (en.Current != null)
|
||||
{
|
||||
// handle the case that the enumeration has null entries
|
||||
// and the case where their ToString() override is broken
|
||||
string value = en.Current.ToString();
|
||||
if (value != null)
|
||||
result.Append(value);
|
||||
var fixture = en.Current;
|
||||
var fixtureId = fixtures.IndexOf(fixture);
|
||||
result.Append(fixtureId.ToString());
|
||||
}
|
||||
|
||||
while (en.MoveNext())
|
||||
{
|
||||
result.Append(separator);
|
||||
if (en.Current != null)
|
||||
{
|
||||
// handle the case that the enumeration has null entries
|
||||
// and the case where their ToString() override is broken
|
||||
string value = en.Current.ToString();
|
||||
if (value != null)
|
||||
result.Append(value);
|
||||
}
|
||||
result.Append("|");
|
||||
|
||||
var fixture = en.Current;
|
||||
var fixtureId = fixtures.IndexOf(fixture);
|
||||
result.Append(fixtureId.ToString());
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
@@ -422,10 +390,10 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
foreach (Fixture fixture in body.FixtureList)
|
||||
{
|
||||
if (!shapes.Any(s2 => fixture.Shape.CompareTo(s2)))
|
||||
if (!shapes.Contains(fixture.Shape))
|
||||
{
|
||||
SerializeShape(fixture.Shape);
|
||||
shapes.Add(fixture.Shape);
|
||||
SerializeShape(fixture.Shape);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -437,10 +405,10 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
foreach (Fixture fixture in body.FixtureList)
|
||||
{
|
||||
if (!fixtures.Any(f2 => fixture.CompareTo(f2)))
|
||||
if (!fixtures.Contains(fixture))
|
||||
{
|
||||
SerializeFixture(fixture);
|
||||
fixtures.Add(fixture);
|
||||
SerializeFixture(fixtures, fixture);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -466,7 +434,6 @@ namespace FarseerPhysics.Common
|
||||
_writer.WriteEndElement();
|
||||
|
||||
_writer.Flush();
|
||||
_writer.Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,6 +450,7 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
List<Body> bodies = new List<Body>();
|
||||
List<Fixture> fixtures = new List<Fixture>();
|
||||
|
||||
List<Joint> joints = new List<Joint>();
|
||||
List<Shape> shapes = new List<Shape>();
|
||||
|
||||
@@ -512,7 +480,7 @@ namespace FarseerPhysics.Common
|
||||
throw new Exception();
|
||||
|
||||
ShapeType type = (ShapeType)Enum.Parse(typeof(ShapeType), element.Attributes[0].Value, true);
|
||||
float density = float.Parse(element.Attributes[1].Value);
|
||||
float density = ParseFloat(element.Attributes[1].Value);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@@ -526,7 +494,7 @@ namespace FarseerPhysics.Common
|
||||
switch (sn.Name.ToLower())
|
||||
{
|
||||
case "radius":
|
||||
shape.Radius = float.Parse(sn.Value);
|
||||
shape.Radius = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "position":
|
||||
shape.Position = ReadVector(sn);
|
||||
@@ -651,7 +619,7 @@ namespace FarseerPhysics.Common
|
||||
if (element.Name.ToLower() != "fixture")
|
||||
throw new Exception();
|
||||
|
||||
fixture.FixtureId = int.Parse(element.Attributes[0].Value);
|
||||
int fixtureId = int.Parse(element.Attributes[0].Value);
|
||||
|
||||
foreach (XMLFragmentElement sn in element.Elements)
|
||||
{
|
||||
@@ -671,27 +639,20 @@ namespace FarseerPhysics.Common
|
||||
case "groupindex":
|
||||
fixture._collisionGroup = short.Parse(ssn.Value);
|
||||
break;
|
||||
case "CollisionIgnores":
|
||||
string[] split = ssn.Value.Split('|');
|
||||
foreach (string s in split)
|
||||
{
|
||||
fixture._collisionIgnores.Add(int.Parse(s));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case "friction":
|
||||
fixture.Friction = float.Parse(sn.Value);
|
||||
fixture.Friction = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "issensor":
|
||||
fixture.IsSensor = bool.Parse(sn.Value);
|
||||
break;
|
||||
case "restitution":
|
||||
fixture.Restitution = float.Parse(sn.Value);
|
||||
fixture.Restitution = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "userdata":
|
||||
case "tag":
|
||||
fixture.UserData = ReadSimpleType(sn, null, false);
|
||||
break;
|
||||
}
|
||||
@@ -701,15 +662,16 @@ namespace FarseerPhysics.Common
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Read bodies
|
||||
Dictionary<Fixture, Fixture> mapFixtureClones = new Dictionary<Fixture,Fixture>();
|
||||
foreach (XMLFragmentElement bodyElement in root.Elements)
|
||||
{
|
||||
if (bodyElement.Name.ToLower() == "bodies")
|
||||
{
|
||||
foreach (XMLFragmentElement element in bodyElement.Elements)
|
||||
{
|
||||
Body body = new Body(world);
|
||||
Body body = world.CreateBody();
|
||||
|
||||
if (element.Name.ToLower() != "body")
|
||||
throw new Exception();
|
||||
@@ -729,14 +691,14 @@ namespace FarseerPhysics.Common
|
||||
case "angle":
|
||||
{
|
||||
Vector2 position = body.Position;
|
||||
body.SetTransformIgnoreContacts(ref position, float.Parse(sn.Value));
|
||||
body.SetTransformIgnoreContacts(ref position, ParseFloat(sn.Value));
|
||||
}
|
||||
break;
|
||||
case "angulardamping":
|
||||
body.AngularDamping = float.Parse(sn.Value);
|
||||
body.AngularDamping = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "angularvelocity":
|
||||
body.AngularVelocity = float.Parse(sn.Value);
|
||||
body.AngularVelocity = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "awake":
|
||||
body.Awake = bool.Parse(sn.Value);
|
||||
@@ -748,7 +710,7 @@ namespace FarseerPhysics.Common
|
||||
body.FixedRotation = bool.Parse(sn.Value);
|
||||
break;
|
||||
case "lineardamping":
|
||||
body.LinearDamping = float.Parse(sn.Value);
|
||||
body.LinearDamping = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "linearvelocity":
|
||||
body.LinearVelocity = ReadVector(sn);
|
||||
@@ -760,7 +722,7 @@ namespace FarseerPhysics.Common
|
||||
body.SetTransformIgnoreContacts(ref position, rotation);
|
||||
}
|
||||
break;
|
||||
case "userdata":
|
||||
case "tag":
|
||||
body.UserData = ReadSimpleType(sn, null, false);
|
||||
break;
|
||||
case "bindings":
|
||||
@@ -768,8 +730,9 @@ namespace FarseerPhysics.Common
|
||||
foreach (XMLFragmentElement pair in sn.Elements)
|
||||
{
|
||||
Fixture fix = fixtures[int.Parse(pair.Attributes[0].Value)];
|
||||
fix.Shape = shapes[int.Parse(pair.Attributes[1].Value)].Clone();
|
||||
fix.CloneOnto(body);
|
||||
var shape = shapes[int.Parse(pair.Attributes[1].Value)].Clone();
|
||||
var clone = fix.CloneOnto(body, shape);
|
||||
mapFixtureClones[fix] = clone;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -797,7 +760,7 @@ namespace FarseerPhysics.Common
|
||||
|
||||
int bodyAIndex = -1, bodyBIndex = -1;
|
||||
bool collideConnected = false;
|
||||
object userData = null;
|
||||
object jointTag = null;
|
||||
|
||||
foreach (XMLFragmentElement sn in n.Elements)
|
||||
{
|
||||
@@ -812,8 +775,8 @@ namespace FarseerPhysics.Common
|
||||
case "collideconnected":
|
||||
collideConnected = bool.Parse(sn.Value);
|
||||
break;
|
||||
case "userdata":
|
||||
userData = ReadSimpleType(sn, null, false);
|
||||
case "tag":
|
||||
jointTag = ReadSimpleType(sn, null, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -875,11 +838,11 @@ namespace FarseerPhysics.Common
|
||||
}
|
||||
|
||||
joint.CollideConnected = collideConnected;
|
||||
joint.UserData = userData;
|
||||
joint.Tag = jointTag;
|
||||
joint.BodyA = bodyA;
|
||||
joint.BodyB = bodyB;
|
||||
joints.Add(joint);
|
||||
world.AddJoint(joint);
|
||||
world.Add(joint);
|
||||
|
||||
foreach (XMLFragmentElement sn in n.Elements)
|
||||
{
|
||||
@@ -891,13 +854,13 @@ namespace FarseerPhysics.Common
|
||||
switch (sn.Name.ToLower())
|
||||
{
|
||||
case "dampingratio":
|
||||
((DistanceJoint)joint).DampingRatio = float.Parse(sn.Value);
|
||||
((DistanceJoint)joint).DampingRatio = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "frequencyhz":
|
||||
((DistanceJoint)joint).Frequency = float.Parse(sn.Value);
|
||||
((DistanceJoint)joint).Frequency = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "length":
|
||||
((DistanceJoint)joint).Length = float.Parse(sn.Value);
|
||||
((DistanceJoint)joint).Length = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "localanchora":
|
||||
((DistanceJoint)joint).LocalAnchorA = ReadVector(sn);
|
||||
@@ -919,10 +882,10 @@ namespace FarseerPhysics.Common
|
||||
((FrictionJoint)joint).LocalAnchorB = ReadVector(sn);
|
||||
break;
|
||||
case "maxforce":
|
||||
((FrictionJoint)joint).MaxForce = float.Parse(sn.Value);
|
||||
((FrictionJoint)joint).MaxForce = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "maxtorque":
|
||||
((FrictionJoint)joint).MaxTorque = float.Parse(sn.Value);
|
||||
((FrictionJoint)joint).MaxTorque = ParseFloat(sn.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -941,16 +904,16 @@ namespace FarseerPhysics.Common
|
||||
((WheelJoint)joint).LocalAnchorB = ReadVector(sn);
|
||||
break;
|
||||
case "motorspeed":
|
||||
((WheelJoint)joint).MotorSpeed = float.Parse(sn.Value);
|
||||
((WheelJoint)joint).MotorSpeed = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "dampingratio":
|
||||
((WheelJoint)joint).DampingRatio = float.Parse(sn.Value);
|
||||
((WheelJoint)joint).DampingRatio = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "maxmotortorque":
|
||||
((WheelJoint)joint).MaxMotorTorque = float.Parse(sn.Value);
|
||||
((WheelJoint)joint).MaxMotorTorque = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "frequencyhz":
|
||||
((WheelJoint)joint).Frequency = float.Parse(sn.Value);
|
||||
((WheelJoint)joint).Frequency = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "axis":
|
||||
((WheelJoint)joint).Axis = ReadVector(sn);
|
||||
@@ -978,19 +941,19 @@ namespace FarseerPhysics.Common
|
||||
((PrismaticJoint)joint).Axis = ReadVector(sn);
|
||||
break;
|
||||
case "maxmotorforce":
|
||||
((PrismaticJoint)joint).MaxMotorForce = float.Parse(sn.Value);
|
||||
((PrismaticJoint)joint).MaxMotorForce = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "motorspeed":
|
||||
((PrismaticJoint)joint).MotorSpeed = float.Parse(sn.Value);
|
||||
((PrismaticJoint)joint).MotorSpeed = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "lowertranslation":
|
||||
((PrismaticJoint)joint).LowerLimit = float.Parse(sn.Value);
|
||||
((PrismaticJoint)joint).LowerLimit = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "uppertranslation":
|
||||
((PrismaticJoint)joint).UpperLimit = float.Parse(sn.Value);
|
||||
((PrismaticJoint)joint).UpperLimit = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "referenceangle":
|
||||
((PrismaticJoint)joint).ReferenceAngle = float.Parse(sn.Value);
|
||||
((PrismaticJoint)joint).ReferenceAngle = ParseFloat(sn.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1006,10 +969,10 @@ namespace FarseerPhysics.Common
|
||||
((PulleyJoint)joint).WorldAnchorB = ReadVector(sn);
|
||||
break;
|
||||
case "lengtha":
|
||||
((PulleyJoint)joint).LengthA = float.Parse(sn.Value);
|
||||
((PulleyJoint)joint).LengthA = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "lengthb":
|
||||
((PulleyJoint)joint).LengthB = float.Parse(sn.Value);
|
||||
((PulleyJoint)joint).LengthB = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "localanchora":
|
||||
((PulleyJoint)joint).LocalAnchorA = ReadVector(sn);
|
||||
@@ -1018,10 +981,10 @@ namespace FarseerPhysics.Common
|
||||
((PulleyJoint)joint).LocalAnchorB = ReadVector(sn);
|
||||
break;
|
||||
case "ratio":
|
||||
((PulleyJoint)joint).Ratio = float.Parse(sn.Value);
|
||||
((PulleyJoint)joint).Ratio = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "constant":
|
||||
((PulleyJoint)joint).Constant = float.Parse(sn.Value);
|
||||
((PulleyJoint)joint).Constant = ParseFloat(sn.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1043,19 +1006,19 @@ namespace FarseerPhysics.Common
|
||||
((RevoluteJoint)joint).LocalAnchorB = ReadVector(sn);
|
||||
break;
|
||||
case "maxmotortorque":
|
||||
((RevoluteJoint)joint).MaxMotorTorque = float.Parse(sn.Value);
|
||||
((RevoluteJoint)joint).MaxMotorTorque = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "motorspeed":
|
||||
((RevoluteJoint)joint).MotorSpeed = float.Parse(sn.Value);
|
||||
((RevoluteJoint)joint).MotorSpeed = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "lowerangle":
|
||||
((RevoluteJoint)joint).LowerLimit = float.Parse(sn.Value);
|
||||
((RevoluteJoint)joint).LowerLimit = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "upperangle":
|
||||
((RevoluteJoint)joint).UpperLimit = float.Parse(sn.Value);
|
||||
((RevoluteJoint)joint).UpperLimit = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "referenceangle":
|
||||
((RevoluteJoint)joint).ReferenceAngle = float.Parse(sn.Value);
|
||||
((RevoluteJoint)joint).ReferenceAngle = ParseFloat(sn.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1084,7 +1047,7 @@ namespace FarseerPhysics.Common
|
||||
((RopeJoint)joint).LocalAnchorB = ReadVector(sn);
|
||||
break;
|
||||
case "maxlength":
|
||||
((RopeJoint)joint).MaxLength = float.Parse(sn.Value);
|
||||
((RopeJoint)joint).MaxLength = ParseFloat(sn.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1096,16 +1059,16 @@ namespace FarseerPhysics.Common
|
||||
switch (sn.Name.ToLower())
|
||||
{
|
||||
case "biasfactor":
|
||||
((AngleJoint)joint).BiasFactor = float.Parse(sn.Value);
|
||||
((AngleJoint)joint).BiasFactor = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "maximpulse":
|
||||
((AngleJoint)joint).MaxImpulse = float.Parse(sn.Value);
|
||||
((AngleJoint)joint).MaxImpulse = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "softness":
|
||||
((AngleJoint)joint).Softness = float.Parse(sn.Value);
|
||||
((AngleJoint)joint).Softness = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "targetangle":
|
||||
((AngleJoint)joint).TargetAngle = float.Parse(sn.Value);
|
||||
((AngleJoint)joint).TargetAngle = ParseFloat(sn.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1114,19 +1077,19 @@ namespace FarseerPhysics.Common
|
||||
switch (sn.Name.ToLower())
|
||||
{
|
||||
case "angularoffset":
|
||||
((MotorJoint)joint).AngularOffset = float.Parse(sn.Value);
|
||||
((MotorJoint)joint).AngularOffset = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "linearoffset":
|
||||
((MotorJoint)joint).LinearOffset = ReadVector(sn);
|
||||
break;
|
||||
case "maxforce":
|
||||
((MotorJoint)joint).MaxForce = float.Parse(sn.Value);
|
||||
((MotorJoint)joint).MaxForce = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "maxtorque":
|
||||
((MotorJoint)joint).MaxTorque = float.Parse(sn.Value);
|
||||
((MotorJoint)joint).MaxTorque = ParseFloat(sn.Value);
|
||||
break;
|
||||
case "correctionfactor":
|
||||
((MotorJoint)joint).CorrectionFactor = float.Parse(sn.Value);
|
||||
((MotorJoint)joint).CorrectionFactor = ParseFloat(sn.Value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1142,7 +1105,7 @@ namespace FarseerPhysics.Common
|
||||
private static Vector2 ReadVector(XMLFragmentElement node)
|
||||
{
|
||||
string[] values = node.Value.Split(' ');
|
||||
return new Vector2(float.Parse(values[0]), float.Parse(values[1]));
|
||||
return new Vector2(ParseFloat(values[0]), ParseFloat(values[1]));
|
||||
}
|
||||
|
||||
private static object ReadSimpleType(XMLFragmentElement node, Type type, bool outer)
|
||||
@@ -1151,8 +1114,6 @@ namespace FarseerPhysics.Common
|
||||
return ReadSimpleType(node.Elements[1], Type.GetType(node.Elements[0].Value), outer);
|
||||
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
|
||||
xmlnsEmpty.Add("", "");
|
||||
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
@@ -1168,6 +1129,12 @@ namespace FarseerPhysics.Common
|
||||
return serializer.Deserialize(XmlReader.Create(stream, settings));
|
||||
}
|
||||
}
|
||||
|
||||
private static float ParseFloat(string value)
|
||||
{
|
||||
return float.Parse(value, System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#region XMLFragment
|
||||
@@ -1252,13 +1219,7 @@ namespace FarseerPhysics.Common
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
|
||||
public XMLFragmentParser(string fileName)
|
||||
{
|
||||
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
|
||||
Load(fs);
|
||||
}
|
||||
|
||||
|
||||
public XMLFragmentElement RootNode
|
||||
{
|
||||
get { return _rootNode; }
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
#if SILVERLIGHT
|
||||
using System;
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using FarseerPhysics.Collision;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using FarseerPhysics.Collision;
|
||||
using FarseerPhysics.Common.Decomposition;
|
||||
using FarseerPhysics.Common.PolygonManipulation;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Factories;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Common.TextureTools
|
||||
@@ -218,7 +222,7 @@ namespace FarseerPhysics.Common.TextureTools
|
||||
{
|
||||
for (int i = 0; i < _bodyMap[x, y].Count; i++)
|
||||
{
|
||||
World.RemoveBody(_bodyMap[x, y][i]);
|
||||
World.Remove(_bodyMap[x, y][i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +260,7 @@ namespace FarseerPhysics.Common.TextureTools
|
||||
foreach (Vertices poly in decompPolys)
|
||||
{
|
||||
if (poly.Count > 2)
|
||||
_bodyMap[gx, gy].Add(BodyFactory.CreatePolygon(World, poly, 1));
|
||||
_bodyMap[gx, gy].Add(World.CreatePolygon(poly, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using System;
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
@@ -1,588 +0,0 @@
|
||||
#if !XNA && !WINDOWS_PHONE && !XBOX && !ANDROID
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
MIT License
|
||||
Copyright © 2006 The Mono.Xna Team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Authors
|
||||
* Alan McGovern
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#endregion License
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Xna.Framework
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector2 : IEquatable<Vector2>
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private static Vector2 zeroVector = new Vector2(0f, 0f);
|
||||
private static Vector2 unitVector = new Vector2(1f, 1f);
|
||||
private static Vector2 unitXVector = new Vector2(1f, 0f);
|
||||
private static Vector2 unitYVector = new Vector2(0f, 1f);
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Public Fields
|
||||
|
||||
public float X;
|
||||
public float Y;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Properties
|
||||
|
||||
public static Vector2 Zero
|
||||
{
|
||||
get { return zeroVector; }
|
||||
}
|
||||
|
||||
public static Vector2 One
|
||||
{
|
||||
get { return unitVector; }
|
||||
}
|
||||
|
||||
public static Vector2 UnitX
|
||||
{
|
||||
get { return unitXVector; }
|
||||
}
|
||||
|
||||
public static Vector2 UnitY
|
||||
{
|
||||
get { return unitYVector; }
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructor foe standard 2D vector.
|
||||
/// </summary>
|
||||
/// <param name="x">
|
||||
/// A <see cref="System.Single"/>
|
||||
/// </param>
|
||||
/// <param name="y">
|
||||
/// A <see cref="System.Single"/>
|
||||
/// </param>
|
||||
public Vector2(float x, float y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for "square" vector.
|
||||
/// </summary>
|
||||
/// <param name="value">
|
||||
/// A <see cref="System.Single"/>
|
||||
/// </param>
|
||||
public Vector2(float value)
|
||||
{
|
||||
X = value;
|
||||
Y = value;
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public static void Reflect(ref Vector2 vector, ref Vector2 normal, out Vector2 result)
|
||||
{
|
||||
float dot = Dot(vector, normal);
|
||||
result.X = vector.X - ((2f*dot)*normal.X);
|
||||
result.Y = vector.Y - ((2f*dot)*normal.Y);
|
||||
}
|
||||
|
||||
public static Vector2 Reflect(Vector2 vector, Vector2 normal)
|
||||
{
|
||||
Vector2 result;
|
||||
Reflect(ref vector, ref normal, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Vector2 Add(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
value1.X += value2.X;
|
||||
value1.Y += value2.Y;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static void Add(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
|
||||
{
|
||||
result.X = value1.X + value2.X;
|
||||
result.Y = value1.Y + value2.Y;
|
||||
}
|
||||
|
||||
public static Vector2 Barycentric(Vector2 value1, Vector2 value2, Vector2 value3, float amount1, float amount2)
|
||||
{
|
||||
return new Vector2(
|
||||
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
||||
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2));
|
||||
}
|
||||
|
||||
public static void Barycentric(ref Vector2 value1, ref Vector2 value2, ref Vector2 value3, float amount1,
|
||||
float amount2, out Vector2 result)
|
||||
{
|
||||
result = new Vector2(
|
||||
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
||||
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2));
|
||||
}
|
||||
|
||||
public static Vector2 CatmullRom(Vector2 value1, Vector2 value2, Vector2 value3, Vector2 value4, float amount)
|
||||
{
|
||||
return new Vector2(
|
||||
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
||||
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount));
|
||||
}
|
||||
|
||||
public static void CatmullRom(ref Vector2 value1, ref Vector2 value2, ref Vector2 value3, ref Vector2 value4,
|
||||
float amount, out Vector2 result)
|
||||
{
|
||||
result = new Vector2(
|
||||
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
||||
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount));
|
||||
}
|
||||
|
||||
public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max)
|
||||
{
|
||||
return new Vector2(
|
||||
MathHelper.Clamp(value1.X, min.X, max.X),
|
||||
MathHelper.Clamp(value1.Y, min.Y, max.Y));
|
||||
}
|
||||
|
||||
public static void Clamp(ref Vector2 value1, ref Vector2 min, ref Vector2 max, out Vector2 result)
|
||||
{
|
||||
result = new Vector2(
|
||||
MathHelper.Clamp(value1.X, min.X, max.X),
|
||||
MathHelper.Clamp(value1.Y, min.Y, max.Y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns float precison distanve between two vectors
|
||||
/// </summary>
|
||||
/// <param name="value1">
|
||||
/// A <see cref="Vector2"/>
|
||||
/// </param>
|
||||
/// <param name="value2">
|
||||
/// A <see cref="Vector2"/>
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="System.Single"/>
|
||||
/// </returns>
|
||||
public static float Distance(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
float result;
|
||||
DistanceSquared(ref value1, ref value2, out result);
|
||||
return (float) Math.Sqrt(result);
|
||||
}
|
||||
|
||||
|
||||
public static void Distance(ref Vector2 value1, ref Vector2 value2, out float result)
|
||||
{
|
||||
DistanceSquared(ref value1, ref value2, out result);
|
||||
result = (float) Math.Sqrt(result);
|
||||
}
|
||||
|
||||
public static float DistanceSquared(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
float result;
|
||||
DistanceSquared(ref value1, ref value2, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void DistanceSquared(ref Vector2 value1, ref Vector2 value2, out float result)
|
||||
{
|
||||
result = (value1.X - value2.X)*(value1.X - value2.X) + (value1.Y - value2.Y)*(value1.Y - value2.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Devide first vector with the secund vector
|
||||
/// </summary>
|
||||
/// <param name="value1">
|
||||
/// A <see cref="Vector2"/>
|
||||
/// </param>
|
||||
/// <param name="value2">
|
||||
/// A <see cref="Vector2"/>
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="Vector2"/>
|
||||
/// </returns>
|
||||
public static Vector2 Divide(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
value1.X /= value2.X;
|
||||
value1.Y /= value2.Y;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static void Divide(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
|
||||
{
|
||||
result.X = value1.X/value2.X;
|
||||
result.Y = value1.Y/value2.Y;
|
||||
}
|
||||
|
||||
public static Vector2 Divide(Vector2 value1, float divider)
|
||||
{
|
||||
float factor = 1/divider;
|
||||
value1.X *= factor;
|
||||
value1.Y *= factor;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static void Divide(ref Vector2 value1, float divider, out Vector2 result)
|
||||
{
|
||||
float factor = 1/divider;
|
||||
result.X = value1.X*factor;
|
||||
result.Y = value1.Y*factor;
|
||||
}
|
||||
|
||||
public static float Dot(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
return value1.X*value2.X + value1.Y*value2.Y;
|
||||
}
|
||||
|
||||
public static void Dot(ref Vector2 value1, ref Vector2 value2, out float result)
|
||||
{
|
||||
result = value1.X*value2.X + value1.Y*value2.Y;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is Vector2) ? this == ((Vector2) obj) : false;
|
||||
}
|
||||
|
||||
public bool Equals(Vector2 other)
|
||||
{
|
||||
return this == other;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int) (X + Y);
|
||||
}
|
||||
|
||||
public static Vector2 Hermite(Vector2 value1, Vector2 tangent1, Vector2 value2, Vector2 tangent2, float amount)
|
||||
{
|
||||
Vector2 result = new Vector2();
|
||||
Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void Hermite(ref Vector2 value1, ref Vector2 tangent1, ref Vector2 value2, ref Vector2 tangent2,
|
||||
float amount, out Vector2 result)
|
||||
{
|
||||
result.X = MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount);
|
||||
result.Y = MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount);
|
||||
}
|
||||
|
||||
public float Length()
|
||||
{
|
||||
float result;
|
||||
DistanceSquared(ref this, ref zeroVector, out result);
|
||||
return (float) Math.Sqrt(result);
|
||||
}
|
||||
|
||||
public float LengthSquared()
|
||||
{
|
||||
float result;
|
||||
DistanceSquared(ref this, ref zeroVector, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Vector2 Lerp(Vector2 value1, Vector2 value2, float amount)
|
||||
{
|
||||
return new Vector2(
|
||||
MathHelper.Lerp(value1.X, value2.X, amount),
|
||||
MathHelper.Lerp(value1.Y, value2.Y, amount));
|
||||
}
|
||||
|
||||
public static void Lerp(ref Vector2 value1, ref Vector2 value2, float amount, out Vector2 result)
|
||||
{
|
||||
result = new Vector2(
|
||||
MathHelper.Lerp(value1.X, value2.X, amount),
|
||||
MathHelper.Lerp(value1.Y, value2.Y, amount));
|
||||
}
|
||||
|
||||
public static Vector2 Max(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
return new Vector2(
|
||||
MathHelper.Max(value1.X, value2.X),
|
||||
MathHelper.Max(value1.Y, value2.Y));
|
||||
}
|
||||
|
||||
public static void Max(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
|
||||
{
|
||||
result = new Vector2(
|
||||
MathHelper.Max(value1.X, value2.X),
|
||||
MathHelper.Max(value1.Y, value2.Y));
|
||||
}
|
||||
|
||||
public static Vector2 Min(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
return new Vector2(
|
||||
MathHelper.Min(value1.X, value2.X),
|
||||
MathHelper.Min(value1.Y, value2.Y));
|
||||
}
|
||||
|
||||
public static void Min(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
|
||||
{
|
||||
result = new Vector2(
|
||||
MathHelper.Min(value1.X, value2.X),
|
||||
MathHelper.Min(value1.Y, value2.Y));
|
||||
}
|
||||
|
||||
public static Vector2 Multiply(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
value1.X *= value2.X;
|
||||
value1.Y *= value2.Y;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector2 Multiply(Vector2 value1, float scaleFactor)
|
||||
{
|
||||
value1.X *= scaleFactor;
|
||||
value1.Y *= scaleFactor;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static void Multiply(ref Vector2 value1, float scaleFactor, out Vector2 result)
|
||||
{
|
||||
result.X = value1.X*scaleFactor;
|
||||
result.Y = value1.Y*scaleFactor;
|
||||
}
|
||||
|
||||
public static void Multiply(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
|
||||
{
|
||||
result.X = value1.X*value2.X;
|
||||
result.Y = value1.Y*value2.Y;
|
||||
}
|
||||
|
||||
public static Vector2 Negate(Vector2 value)
|
||||
{
|
||||
value.X = -value.X;
|
||||
value.Y = -value.Y;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void Negate(ref Vector2 value, out Vector2 result)
|
||||
{
|
||||
result.X = -value.X;
|
||||
result.Y = -value.Y;
|
||||
}
|
||||
|
||||
public void Normalize()
|
||||
{
|
||||
Normalize(ref this, out this);
|
||||
}
|
||||
|
||||
public static Vector2 Normalize(Vector2 value)
|
||||
{
|
||||
Normalize(ref value, out value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void Normalize(ref Vector2 value, out Vector2 result)
|
||||
{
|
||||
float factor;
|
||||
DistanceSquared(ref value, ref zeroVector, out factor);
|
||||
factor = 1f/(float) Math.Sqrt(factor);
|
||||
result.X = value.X*factor;
|
||||
result.Y = value.Y*factor;
|
||||
}
|
||||
|
||||
public static Vector2 SmoothStep(Vector2 value1, Vector2 value2, float amount)
|
||||
{
|
||||
return new Vector2(
|
||||
MathHelper.SmoothStep(value1.X, value2.X, amount),
|
||||
MathHelper.SmoothStep(value1.Y, value2.Y, amount));
|
||||
}
|
||||
|
||||
public static void SmoothStep(ref Vector2 value1, ref Vector2 value2, float amount, out Vector2 result)
|
||||
{
|
||||
result = new Vector2(
|
||||
MathHelper.SmoothStep(value1.X, value2.X, amount),
|
||||
MathHelper.SmoothStep(value1.Y, value2.Y, amount));
|
||||
}
|
||||
|
||||
public static Vector2 Subtract(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
value1.X -= value2.X;
|
||||
value1.Y -= value2.Y;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static void Subtract(ref Vector2 value1, ref Vector2 value2, out Vector2 result)
|
||||
{
|
||||
result.X = value1.X - value2.X;
|
||||
result.Y = value1.Y - value2.Y;
|
||||
}
|
||||
|
||||
public static Vector2 Transform(Vector2 position, Matrix matrix)
|
||||
{
|
||||
Transform(ref position, ref matrix, out position);
|
||||
return position;
|
||||
}
|
||||
|
||||
public static void Transform(ref Vector2 position, ref Matrix matrix, out Vector2 result)
|
||||
{
|
||||
result = new Vector2((position.X*matrix.M11) + (position.Y*matrix.M21) + matrix.M41,
|
||||
(position.X*matrix.M12) + (position.Y*matrix.M22) + matrix.M42);
|
||||
}
|
||||
|
||||
public static void Transform(Vector2[] sourceArray, ref Matrix matrix, Vector2[] destinationArray)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static void Transform(Vector2[] sourceArray, int sourceIndex, ref Matrix matrix,
|
||||
Vector2[] destinationArray, int destinationIndex, int length)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static Vector2 TransformNormal(Vector2 normal, Matrix matrix)
|
||||
{
|
||||
TransformNormal(ref normal, ref matrix, out normal);
|
||||
return normal;
|
||||
}
|
||||
|
||||
public static void TransformNormal(ref Vector2 normal, ref Matrix matrix, out Vector2 result)
|
||||
{
|
||||
result = new Vector2((normal.X*matrix.M11) + (normal.Y*matrix.M21),
|
||||
(normal.X*matrix.M12) + (normal.Y*matrix.M22));
|
||||
}
|
||||
|
||||
public static void TransformNormal(Vector2[] sourceArray, ref Matrix matrix, Vector2[] destinationArray)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static void TransformNormal(Vector2[] sourceArray, int sourceIndex, ref Matrix matrix,
|
||||
Vector2[] destinationArray, int destinationIndex, int length)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(24);
|
||||
sb.Append("{X:");
|
||||
sb.Append(X);
|
||||
sb.Append(" Y:");
|
||||
sb.Append(Y);
|
||||
sb.Append("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Operators
|
||||
|
||||
public static Vector2 operator -(Vector2 value)
|
||||
{
|
||||
value.X = -value.X;
|
||||
value.Y = -value.Y;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static bool operator ==(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
return value1.X == value2.X && value1.Y == value2.Y;
|
||||
}
|
||||
|
||||
|
||||
public static bool operator !=(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
return value1.X != value2.X || value1.Y != value2.Y;
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 operator +(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
value1.X += value2.X;
|
||||
value1.Y += value2.Y;
|
||||
return value1;
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 operator -(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
value1.X -= value2.X;
|
||||
value1.Y -= value2.Y;
|
||||
return value1;
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 operator *(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
value1.X *= value2.X;
|
||||
value1.Y *= value2.Y;
|
||||
return value1;
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 operator *(Vector2 value, float scaleFactor)
|
||||
{
|
||||
value.X *= scaleFactor;
|
||||
value.Y *= scaleFactor;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 operator *(float scaleFactor, Vector2 value)
|
||||
{
|
||||
value.X *= scaleFactor;
|
||||
value.Y *= scaleFactor;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 operator /(Vector2 value1, Vector2 value2)
|
||||
{
|
||||
value1.X /= value2.X;
|
||||
value1.Y /= value2.Y;
|
||||
return value1;
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 operator /(Vector2 value1, float divider)
|
||||
{
|
||||
float factor = 1/divider;
|
||||
value1.X *= factor;
|
||||
value1.Y *= factor;
|
||||
return value1;
|
||||
}
|
||||
|
||||
#endregion Operators
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,648 +0,0 @@
|
||||
#if !XNA && !WINDOWS_PHONE && !XBOX && !ANDROID
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
MIT License
|
||||
Copyright © 2006 The Mono.Xna Team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Authors:
|
||||
* Alan McGovern
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#endregion License
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Xna.Framework
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector3 : IEquatable<Vector3>
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private static Vector3 zero = new Vector3(0f, 0f, 0f);
|
||||
private static Vector3 one = new Vector3(1f, 1f, 1f);
|
||||
private static Vector3 unitX = new Vector3(1f, 0f, 0f);
|
||||
private static Vector3 unitY = new Vector3(0f, 1f, 0f);
|
||||
private static Vector3 unitZ = new Vector3(0f, 0f, 1f);
|
||||
private static Vector3 up = new Vector3(0f, 1f, 0f);
|
||||
private static Vector3 down = new Vector3(0f, -1f, 0f);
|
||||
private static Vector3 right = new Vector3(1f, 0f, 0f);
|
||||
private static Vector3 left = new Vector3(-1f, 0f, 0f);
|
||||
private static Vector3 forward = new Vector3(0f, 0f, -1f);
|
||||
private static Vector3 backward = new Vector3(0f, 0f, 1f);
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Public Fields
|
||||
|
||||
public float X;
|
||||
public float Y;
|
||||
public float Z;
|
||||
|
||||
#endregion Public Fields
|
||||
|
||||
#region Properties
|
||||
|
||||
public static Vector3 Zero
|
||||
{
|
||||
get { return zero; }
|
||||
}
|
||||
|
||||
public static Vector3 One
|
||||
{
|
||||
get { return one; }
|
||||
}
|
||||
|
||||
public static Vector3 UnitX
|
||||
{
|
||||
get { return unitX; }
|
||||
}
|
||||
|
||||
public static Vector3 UnitY
|
||||
{
|
||||
get { return unitY; }
|
||||
}
|
||||
|
||||
public static Vector3 UnitZ
|
||||
{
|
||||
get { return unitZ; }
|
||||
}
|
||||
|
||||
public static Vector3 Up
|
||||
{
|
||||
get { return up; }
|
||||
}
|
||||
|
||||
public static Vector3 Down
|
||||
{
|
||||
get { return down; }
|
||||
}
|
||||
|
||||
public static Vector3 Right
|
||||
{
|
||||
get { return right; }
|
||||
}
|
||||
|
||||
public static Vector3 Left
|
||||
{
|
||||
get { return left; }
|
||||
}
|
||||
|
||||
public static Vector3 Forward
|
||||
{
|
||||
get { return forward; }
|
||||
}
|
||||
|
||||
public static Vector3 Backward
|
||||
{
|
||||
get { return backward; }
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Constructors
|
||||
|
||||
public Vector3(float x, float y, float z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
|
||||
public Vector3(float value)
|
||||
{
|
||||
X = value;
|
||||
Y = value;
|
||||
Z = value;
|
||||
}
|
||||
|
||||
|
||||
public Vector3(Vector2 value, float z)
|
||||
{
|
||||
X = value.X;
|
||||
Y = value.Y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public static Vector3 Add(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
value1.X += value2.X;
|
||||
value1.Y += value2.Y;
|
||||
value1.Z += value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static void Add(ref Vector3 value1, ref Vector3 value2, out Vector3 result)
|
||||
{
|
||||
result.X = value1.X + value2.X;
|
||||
result.Y = value1.Y + value2.Y;
|
||||
result.Z = value1.Z + value2.Z;
|
||||
}
|
||||
|
||||
public static Vector3 Barycentric(Vector3 value1, Vector3 value2, Vector3 value3, float amount1, float amount2)
|
||||
{
|
||||
return new Vector3(
|
||||
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
||||
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2),
|
||||
MathHelper.Barycentric(value1.Z, value2.Z, value3.Z, amount1, amount2));
|
||||
}
|
||||
|
||||
public static void Barycentric(ref Vector3 value1, ref Vector3 value2, ref Vector3 value3, float amount1,
|
||||
float amount2, out Vector3 result)
|
||||
{
|
||||
result = new Vector3(
|
||||
MathHelper.Barycentric(value1.X, value2.X, value3.X, amount1, amount2),
|
||||
MathHelper.Barycentric(value1.Y, value2.Y, value3.Y, amount1, amount2),
|
||||
MathHelper.Barycentric(value1.Z, value2.Z, value3.Z, amount1, amount2));
|
||||
}
|
||||
|
||||
public static Vector3 CatmullRom(Vector3 value1, Vector3 value2, Vector3 value3, Vector3 value4, float amount)
|
||||
{
|
||||
return new Vector3(
|
||||
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
||||
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount),
|
||||
MathHelper.CatmullRom(value1.Z, value2.Z, value3.Z, value4.Z, amount));
|
||||
}
|
||||
|
||||
public static void CatmullRom(ref Vector3 value1, ref Vector3 value2, ref Vector3 value3, ref Vector3 value4,
|
||||
float amount, out Vector3 result)
|
||||
{
|
||||
result = new Vector3(
|
||||
MathHelper.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
|
||||
MathHelper.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount),
|
||||
MathHelper.CatmullRom(value1.Z, value2.Z, value3.Z, value4.Z, amount));
|
||||
}
|
||||
|
||||
public static Vector3 Clamp(Vector3 value1, Vector3 min, Vector3 max)
|
||||
{
|
||||
return new Vector3(
|
||||
MathHelper.Clamp(value1.X, min.X, max.X),
|
||||
MathHelper.Clamp(value1.Y, min.Y, max.Y),
|
||||
MathHelper.Clamp(value1.Z, min.Z, max.Z));
|
||||
}
|
||||
|
||||
public static void Clamp(ref Vector3 value1, ref Vector3 min, ref Vector3 max, out Vector3 result)
|
||||
{
|
||||
result = new Vector3(
|
||||
MathHelper.Clamp(value1.X, min.X, max.X),
|
||||
MathHelper.Clamp(value1.Y, min.Y, max.Y),
|
||||
MathHelper.Clamp(value1.Z, min.Z, max.Z));
|
||||
}
|
||||
|
||||
public static Vector3 Cross(Vector3 vector1, Vector3 vector2)
|
||||
{
|
||||
Cross(ref vector1, ref vector2, out vector1);
|
||||
return vector1;
|
||||
}
|
||||
|
||||
public static void Cross(ref Vector3 vector1, ref Vector3 vector2, out Vector3 result)
|
||||
{
|
||||
result = new Vector3(vector1.Y*vector2.Z - vector2.Y*vector1.Z,
|
||||
-(vector1.X*vector2.Z - vector2.X*vector1.Z),
|
||||
vector1.X*vector2.Y - vector2.X*vector1.Y);
|
||||
}
|
||||
|
||||
public static float Distance(Vector3 vector1, Vector3 vector2)
|
||||
{
|
||||
float result;
|
||||
DistanceSquared(ref vector1, ref vector2, out result);
|
||||
return (float) Math.Sqrt(result);
|
||||
}
|
||||
|
||||
public static void Distance(ref Vector3 value1, ref Vector3 value2, out float result)
|
||||
{
|
||||
DistanceSquared(ref value1, ref value2, out result);
|
||||
result = (float) Math.Sqrt(result);
|
||||
}
|
||||
|
||||
public static float DistanceSquared(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
float result;
|
||||
DistanceSquared(ref value1, ref value2, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void DistanceSquared(ref Vector3 value1, ref Vector3 value2, out float result)
|
||||
{
|
||||
result = (value1.X - value2.X)*(value1.X - value2.X) +
|
||||
(value1.Y - value2.Y)*(value1.Y - value2.Y) +
|
||||
(value1.Z - value2.Z)*(value1.Z - value2.Z);
|
||||
}
|
||||
|
||||
public static Vector3 Divide(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
value1.X /= value2.X;
|
||||
value1.Y /= value2.Y;
|
||||
value1.Z /= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector3 Divide(Vector3 value1, float value2)
|
||||
{
|
||||
float factor = 1/value2;
|
||||
value1.X *= factor;
|
||||
value1.Y *= factor;
|
||||
value1.Z *= factor;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static void Divide(ref Vector3 value1, float divisor, out Vector3 result)
|
||||
{
|
||||
float factor = 1/divisor;
|
||||
result.X = value1.X*factor;
|
||||
result.Y = value1.Y*factor;
|
||||
result.Z = value1.Z*factor;
|
||||
}
|
||||
|
||||
public static void Divide(ref Vector3 value1, ref Vector3 value2, out Vector3 result)
|
||||
{
|
||||
result.X = value1.X/value2.X;
|
||||
result.Y = value1.Y/value2.Y;
|
||||
result.Z = value1.Z/value2.Z;
|
||||
}
|
||||
|
||||
public static float Dot(Vector3 vector1, Vector3 vector2)
|
||||
{
|
||||
return vector1.X*vector2.X + vector1.Y*vector2.Y + vector1.Z*vector2.Z;
|
||||
}
|
||||
|
||||
public static void Dot(ref Vector3 vector1, ref Vector3 vector2, out float result)
|
||||
{
|
||||
result = vector1.X*vector2.X + vector1.Y*vector2.Y + vector1.Z*vector2.Z;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is Vector3) ? this == (Vector3) obj : false;
|
||||
}
|
||||
|
||||
public bool Equals(Vector3 other)
|
||||
{
|
||||
return this == other;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int) (X + Y + Z);
|
||||
}
|
||||
|
||||
public static Vector3 Hermite(Vector3 value1, Vector3 tangent1, Vector3 value2, Vector3 tangent2, float amount)
|
||||
{
|
||||
Vector3 result = new Vector3();
|
||||
Hermite(ref value1, ref tangent1, ref value2, ref tangent2, amount, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void Hermite(ref Vector3 value1, ref Vector3 tangent1, ref Vector3 value2, ref Vector3 tangent2,
|
||||
float amount, out Vector3 result)
|
||||
{
|
||||
result.X = MathHelper.Hermite(value1.X, tangent1.X, value2.X, tangent2.X, amount);
|
||||
result.Y = MathHelper.Hermite(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount);
|
||||
result.Z = MathHelper.Hermite(value1.Z, tangent1.Z, value2.Z, tangent2.Z, amount);
|
||||
}
|
||||
|
||||
public float Length()
|
||||
{
|
||||
float result;
|
||||
DistanceSquared(ref this, ref zero, out result);
|
||||
return (float) Math.Sqrt(result);
|
||||
}
|
||||
|
||||
public float LengthSquared()
|
||||
{
|
||||
float result;
|
||||
DistanceSquared(ref this, ref zero, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Vector3 Lerp(Vector3 value1, Vector3 value2, float amount)
|
||||
{
|
||||
return new Vector3(
|
||||
MathHelper.Lerp(value1.X, value2.X, amount),
|
||||
MathHelper.Lerp(value1.Y, value2.Y, amount),
|
||||
MathHelper.Lerp(value1.Z, value2.Z, amount));
|
||||
}
|
||||
|
||||
public static void Lerp(ref Vector3 value1, ref Vector3 value2, float amount, out Vector3 result)
|
||||
{
|
||||
result = new Vector3(
|
||||
MathHelper.Lerp(value1.X, value2.X, amount),
|
||||
MathHelper.Lerp(value1.Y, value2.Y, amount),
|
||||
MathHelper.Lerp(value1.Z, value2.Z, amount));
|
||||
}
|
||||
|
||||
public static Vector3 Max(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
return new Vector3(
|
||||
MathHelper.Max(value1.X, value2.X),
|
||||
MathHelper.Max(value1.Y, value2.Y),
|
||||
MathHelper.Max(value1.Z, value2.Z));
|
||||
}
|
||||
|
||||
public static void Max(ref Vector3 value1, ref Vector3 value2, out Vector3 result)
|
||||
{
|
||||
result = new Vector3(
|
||||
MathHelper.Max(value1.X, value2.X),
|
||||
MathHelper.Max(value1.Y, value2.Y),
|
||||
MathHelper.Max(value1.Z, value2.Z));
|
||||
}
|
||||
|
||||
public static Vector3 Min(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
return new Vector3(
|
||||
MathHelper.Min(value1.X, value2.X),
|
||||
MathHelper.Min(value1.Y, value2.Y),
|
||||
MathHelper.Min(value1.Z, value2.Z));
|
||||
}
|
||||
|
||||
public static void Min(ref Vector3 value1, ref Vector3 value2, out Vector3 result)
|
||||
{
|
||||
result = new Vector3(
|
||||
MathHelper.Min(value1.X, value2.X),
|
||||
MathHelper.Min(value1.Y, value2.Y),
|
||||
MathHelper.Min(value1.Z, value2.Z));
|
||||
}
|
||||
|
||||
public static Vector3 Multiply(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
value1.X *= value2.X;
|
||||
value1.Y *= value2.Y;
|
||||
value1.Z *= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector3 Multiply(Vector3 value1, float scaleFactor)
|
||||
{
|
||||
value1.X *= scaleFactor;
|
||||
value1.Y *= scaleFactor;
|
||||
value1.Z *= scaleFactor;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static void Multiply(ref Vector3 value1, float scaleFactor, out Vector3 result)
|
||||
{
|
||||
result.X = value1.X*scaleFactor;
|
||||
result.Y = value1.Y*scaleFactor;
|
||||
result.Z = value1.Z*scaleFactor;
|
||||
}
|
||||
|
||||
public static void Multiply(ref Vector3 value1, ref Vector3 value2, out Vector3 result)
|
||||
{
|
||||
result.X = value1.X*value2.X;
|
||||
result.Y = value1.Y*value2.Y;
|
||||
result.Z = value1.Z*value2.Z;
|
||||
}
|
||||
|
||||
public static Vector3 Negate(Vector3 value)
|
||||
{
|
||||
value = new Vector3(-value.X, -value.Y, -value.Z);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void Negate(ref Vector3 value, out Vector3 result)
|
||||
{
|
||||
result = new Vector3(-value.X, -value.Y, -value.Z);
|
||||
}
|
||||
|
||||
public void Normalize()
|
||||
{
|
||||
Normalize(ref this, out this);
|
||||
}
|
||||
|
||||
public static Vector3 Normalize(Vector3 vector)
|
||||
{
|
||||
Normalize(ref vector, out vector);
|
||||
return vector;
|
||||
}
|
||||
|
||||
public static void Normalize(ref Vector3 value, out Vector3 result)
|
||||
{
|
||||
float factor;
|
||||
Distance(ref value, ref zero, out factor);
|
||||
factor = 1f/factor;
|
||||
result.X = value.X*factor;
|
||||
result.Y = value.Y*factor;
|
||||
result.Z = value.Z*factor;
|
||||
}
|
||||
|
||||
public static Vector3 Reflect(Vector3 vector, Vector3 normal)
|
||||
{
|
||||
Vector3 result;
|
||||
Reflect(ref vector, ref normal, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void Reflect(ref Vector3 vector, ref Vector3 normal, out Vector3 result)
|
||||
{
|
||||
float dot = Dot(vector, normal);
|
||||
result.X = vector.X - ((2f*dot)*normal.X);
|
||||
result.Y = vector.Y - ((2f*dot)*normal.Y);
|
||||
result.Z = vector.Z - ((2f*dot)*normal.Z);
|
||||
}
|
||||
|
||||
public static Vector3 SmoothStep(Vector3 value1, Vector3 value2, float amount)
|
||||
{
|
||||
return new Vector3(
|
||||
MathHelper.SmoothStep(value1.X, value2.X, amount),
|
||||
MathHelper.SmoothStep(value1.Y, value2.Y, amount),
|
||||
MathHelper.SmoothStep(value1.Z, value2.Z, amount));
|
||||
}
|
||||
|
||||
public static void SmoothStep(ref Vector3 value1, ref Vector3 value2, float amount, out Vector3 result)
|
||||
{
|
||||
result = new Vector3(
|
||||
MathHelper.SmoothStep(value1.X, value2.X, amount),
|
||||
MathHelper.SmoothStep(value1.Y, value2.Y, amount),
|
||||
MathHelper.SmoothStep(value1.Z, value2.Z, amount));
|
||||
}
|
||||
|
||||
public static Vector3 Subtract(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
value1.X -= value2.X;
|
||||
value1.Y -= value2.Y;
|
||||
value1.Z -= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static void Subtract(ref Vector3 value1, ref Vector3 value2, out Vector3 result)
|
||||
{
|
||||
result.X = value1.X - value2.X;
|
||||
result.Y = value1.Y - value2.Y;
|
||||
result.Z = value1.Z - value2.Z;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(32);
|
||||
sb.Append("{X:");
|
||||
sb.Append(X);
|
||||
sb.Append(" Y:");
|
||||
sb.Append(Y);
|
||||
sb.Append(" Z:");
|
||||
sb.Append(Z);
|
||||
sb.Append("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static Vector3 Transform(Vector3 position, Matrix matrix)
|
||||
{
|
||||
Transform(ref position, ref matrix, out position);
|
||||
return position;
|
||||
}
|
||||
|
||||
public static void Transform(ref Vector3 position, ref Matrix matrix, out Vector3 result)
|
||||
{
|
||||
result =
|
||||
new Vector3((position.X*matrix.M11) + (position.Y*matrix.M21) + (position.Z*matrix.M31) + matrix.M41,
|
||||
(position.X*matrix.M12) + (position.Y*matrix.M22) + (position.Z*matrix.M32) + matrix.M42,
|
||||
(position.X*matrix.M13) + (position.Y*matrix.M23) + (position.Z*matrix.M33) + matrix.M43);
|
||||
}
|
||||
|
||||
public static void Transform(Vector3[] sourceArray, ref Matrix matrix, Vector3[] destinationArray)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static void Transform(Vector3[] sourceArray, int sourceIndex, ref Matrix matrix,
|
||||
Vector3[] destinationArray, int destinationIndex, int length)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static void TransformNormal(Vector3[] sourceArray, ref Matrix matrix, Vector3[] destinationArray)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static void TransformNormal(Vector3[] sourceArray, int sourceIndex, ref Matrix matrix,
|
||||
Vector3[] destinationArray, int destinationIndex, int length)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static Vector3 TransformNormal(Vector3 normal, Matrix matrix)
|
||||
{
|
||||
TransformNormal(ref normal, ref matrix, out normal);
|
||||
return normal;
|
||||
}
|
||||
|
||||
public static void TransformNormal(ref Vector3 normal, ref Matrix matrix, out Vector3 result)
|
||||
{
|
||||
result = new Vector3((normal.X*matrix.M11) + (normal.Y*matrix.M21) + (normal.Z*matrix.M31),
|
||||
(normal.X*matrix.M12) + (normal.Y*matrix.M22) + (normal.Z*matrix.M32),
|
||||
(normal.X*matrix.M13) + (normal.Y*matrix.M23) + (normal.Z*matrix.M33));
|
||||
}
|
||||
|
||||
#endregion Public methods
|
||||
|
||||
#region Operators
|
||||
|
||||
public static bool operator ==(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
return value1.X == value2.X
|
||||
&& value1.Y == value2.Y
|
||||
&& value1.Z == value2.Z;
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
return !(value1 == value2);
|
||||
}
|
||||
|
||||
public static Vector3 operator +(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
value1.X += value2.X;
|
||||
value1.Y += value2.Y;
|
||||
value1.Z += value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector3 operator -(Vector3 value)
|
||||
{
|
||||
value = new Vector3(-value.X, -value.Y, -value.Z);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Vector3 operator -(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
value1.X -= value2.X;
|
||||
value1.Y -= value2.Y;
|
||||
value1.Z -= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector3 operator *(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
value1.X *= value2.X;
|
||||
value1.Y *= value2.Y;
|
||||
value1.Z *= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector3 operator *(Vector3 value, float scaleFactor)
|
||||
{
|
||||
value.X *= scaleFactor;
|
||||
value.Y *= scaleFactor;
|
||||
value.Z *= scaleFactor;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Vector3 operator *(float scaleFactor, Vector3 value)
|
||||
{
|
||||
value.X *= scaleFactor;
|
||||
value.Y *= scaleFactor;
|
||||
value.Z *= scaleFactor;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Vector3 operator /(Vector3 value1, Vector3 value2)
|
||||
{
|
||||
value1.X /= value2.X;
|
||||
value1.Y /= value2.Y;
|
||||
value1.Z /= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector3 operator /(Vector3 value, float divider)
|
||||
{
|
||||
float factor = 1/divider;
|
||||
value.X *= factor;
|
||||
value.Y *= factor;
|
||||
value.Z *= factor;
|
||||
return value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,9 @@
|
||||
/*
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Farseer Physics Engine:
|
||||
* Copyright (c) 2012 Ian Qvist
|
||||
*/
|
||||
@@ -49,10 +54,8 @@ namespace FarseerPhysics.Common
|
||||
/// </summary>
|
||||
SideTooSmall
|
||||
}
|
||||
|
||||
#if !(XBOX360)
|
||||
|
||||
[DebuggerDisplay("Count = {Count} Vertices = {ToString()}")]
|
||||
#endif
|
||||
public class Vertices : List<Vector2>
|
||||
{
|
||||
public Vertices() { }
|
||||
|
||||
Reference in New Issue
Block a user