From 8bc65f983ddf20452c74a89a50a1128562b13e24 Mon Sep 17 00:00:00 2001 From: Regalis11 Date: Mon, 22 Jun 2015 16:55:42 +0300 Subject: [PATCH] Farseer physics body generation from voronoi cells --- Subsurface/DebugConsole.cs | 2 +- Subsurface/Map/Level.cs | 64 +++++++++++++++++------------- Subsurface/Map/Voronoi.cs | 4 +- Subsurface/Map/VoronoiElements.cs | 11 +++-- Subsurface_Solution.v12.suo | Bin 280576 -> 299008 bytes 5 files changed, 47 insertions(+), 34 deletions(-) diff --git a/Subsurface/DebugConsole.cs b/Subsurface/DebugConsole.cs index 58db40c6f..b47e4a30f 100644 --- a/Subsurface/DebugConsole.cs +++ b/Subsurface/DebugConsole.cs @@ -200,7 +200,7 @@ namespace Subsurface } break; case "generatelevel": - Game1.Level = new Level(Game1.localRandom.Next(), 20, 5000, 5000); + Game1.Level = new Level(Game1.localRandom.Next(), 20, 500, 500); break; case "fowenabled": case "fow": diff --git a/Subsurface/Map/Level.cs b/Subsurface/Map/Level.cs index 039baa400..0c6715bfe 100644 --- a/Subsurface/Map/Level.cs +++ b/Subsurface/Map/Level.cs @@ -41,7 +41,7 @@ namespace Subsurface { for (int i = 0; i<2; i++) { - int site = (i==0) ? ge.site1 : ge.site2; + Site site = (i==0) ? ge.site1 : ge.site2; VoronoiCell cell = cells.Find(c => c.site == site); if (cell == null) { @@ -60,11 +60,11 @@ namespace Subsurface List vlist = new List(); foreach (GraphEdge ge in cell.edges) { - if (vlist.Contains(ge.point1)) continue; - vlist.Add(ge.point1); + if (!vlist.Contains(ge.point1)) vlist.Add(ge.point1); + if (!vlist.Contains(ge.point2)) vlist.Add(ge.point2); } - if (vlist.Count < 2) continue; + if (vlist.Count < 3) continue; for (int i = 0; i < vlist.Count; i++ ) { @@ -74,7 +74,7 @@ namespace Subsurface //get farseer 'vertices' from vectors Vertices _shapevertices = new Vertices(vlist); - //_shapevertices.Sort(less); + _shapevertices.Sort(new CompareCCW(cell.Center)); //feed vertices array to BodyFactory.CreatePolygon to get a new farseer polygonal body Body _newBody = BodyFactory.CreatePolygon(Game1.world, _shapevertices, 15); @@ -85,29 +85,6 @@ namespace Subsurface } } - - public int Compare(Vector2 a, Vector2 b, Vector2 center) - { - if (a.X - center.X >= 0 && b.X - center.X < 0) return 1; - if (a.X - center.X < 0 && b.X - center.X >= 0) return -1; - if (a.X - center.X == 0 && b.X - center.X == 0) - { - if (a.Y - center.Y >= 0 || b.Y - center.Y >= 0) return Math.Sign(a.Y - b.Y); - return Math.Sign(b.Y-a.Y); - } - - // compute the cross product of vectors (center -> a) x (center -> b) - float det = (a.X - center.X) * (b.Y - center.Y) - (b.X - center.X) * (a.Y - center.Y); - if (det < 0) return 1; - if (det > 0) return -1; - - // points a and b are on the same line from the center - // check which point is closer to the center - float d1 = (a.X - center.X) * (a.X - center.X) + (a.Y - center.Y) * (a.Y - center.Y); - float d2 = (b.X - center.X) * (b.X - center.X) + (b.Y - center.Y) * (b.Y - center.Y); - return Math.Sign(d1 - d2); - } - List MakeVoronoiGraph(List sites, Voronoi voronoi, int width, int height) { double[] xVal = new double[sites.Count]; @@ -132,4 +109,35 @@ namespace Subsurface } } + class CompareCCW : IComparer + { + private Vector2 center; + + public CompareCCW(Vector2 center) + { + this.center = center; + } + public int Compare(Vector2 a, Vector2 b) + { + if (a.X - center.X >= 0 && b.X - center.X < 0) return 1; + if (a.X - center.X < 0 && b.X - center.X >= 0) return -1; + if (a.X - center.X == 0 && b.X - center.X == 0) + { + if (a.Y - center.Y >= 0 || b.Y - center.Y >= 0) return Math.Sign(a.Y - b.Y); + return Math.Sign(b.Y - a.Y); + } + + // compute the cross product of vectors (center -> a) x (center -> b) + float det = (a.X - center.X) * (b.Y - center.Y) - (b.X - center.X) * (a.Y - center.Y); + if (det < 0) return 1; + if (det > 0) return -1; + + // points a and b are on the same line from the center + // check which point is closer to the center + float d1 = (a.X - center.X) * (a.X - center.X) + (a.Y - center.Y) * (a.Y - center.Y); + float d2 = (b.X - center.X) * (b.X - center.X) + (b.Y - center.Y) * (b.Y - center.Y); + return Math.Sign(d1 - d2); + } + } + } diff --git a/Subsurface/Map/Voronoi.cs b/Subsurface/Map/Voronoi.cs index 52c62fad9..8b8e0ed16 100644 --- a/Subsurface/Map/Voronoi.cs +++ b/Subsurface/Map/Voronoi.cs @@ -543,8 +543,8 @@ namespace Voronoi2 newEdge.point1 = point1; newEdge.point2 = point2; - newEdge.site1 = leftSite.sitenbr; - newEdge.site2 = rightSite.sitenbr; + newEdge.site1 = leftSite; + newEdge.site2 = rightSite; } private void clip_line( Edge e ) diff --git a/Subsurface/Map/VoronoiElements.cs b/Subsurface/Map/VoronoiElements.cs index d5e933de0..3728524d9 100644 --- a/Subsurface/Map/VoronoiElements.cs +++ b/Subsurface/Map/VoronoiElements.cs @@ -117,9 +117,14 @@ namespace Voronoi2 public class VoronoiCell { public List edges; - public int site; + public Site site; - public VoronoiCell(int site) + public Vector2 Center + { + get { return new Vector2((float)site.coord.x, (float)site.coord.y); } + } + + public VoronoiCell(Site site) { edges = new List(); this.site = site; @@ -129,7 +134,7 @@ namespace Voronoi2 public class GraphEdge { public Vector2 point1, point2; - public int site1, site2; + public Site site1, site2; } // للترتيب diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 14e4973e3b3950464b5a7592adec90cf54d3f31b..83392413fd386fc231ccf1f83ee523adcf2924bf 100644 GIT binary patch delta 8321 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 DH=zWk delta 8130 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 F{s*jMN%Q~!