Client LuaCsForBarotrauma
VoronoiElements.cs
1 /*
2  * Created by SharpDevelop.
3  * User: Burhan
4  * Date: 17/06/2014
5  * Time: 09:29 م
6  *
7  * To change this template use Tools | Options | Coding | Edit Standard Headers.
8  */
9 
10 /*
11  Copyright 2011 James Humphreys. All rights reserved.
12 
13  Redistribution and use in source and binary forms, with or without modification, are
14  permitted provided that the following conditions are met:
15 
16  1. Redistributions of source code must retain the above copyright notice, this list of
17  conditions and the following disclaimer.
18 
19  2. Redistributions in binary form must reproduce the above copyright notice, this list
20  of conditions and the following disclaimer in the documentation and/or other materials
21  provided with the distribution.
22 
23  THIS SOFTWARE IS PROVIDED BY James Humphreys ``AS IS\" AND ANY EXPRESS OR IMPLIED
24  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
25  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
26  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33  The views and conclusions contained in the software and documentation are those of the
34  authors and should not be interpreted as representing official policies, either expressed
35  or implied, of James Humphreys.
36  */
37 
38 /*
39  * C# Version by Burhan Joukhadar
40  *
41  * Permission to use, copy, modify, and distribute this software for any
42  * purpose without fee is hereby granted, provided that this entire notice
43  * is included in all copies of any software which is or includes a copy
44  * or modification of this software and in all copies of the supporting
45  * documentation for such software.
46  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
47  * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
48  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
49  * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
50  */
51 
52 
53 using Barotrauma;
54 using FarseerPhysics.Dynamics;
55 using Microsoft.Xna.Framework;
56 using System;
57 using System.Collections.Generic;
58 using System.Linq;
59 
60 namespace Voronoi2
61 {
62  public class DoubleVector2
63  {
64  public double X, Y;
65 
66  public DoubleVector2()
67  {
68  }
69 
70  public DoubleVector2(double x, double y)
71  {
72  this.X = x;
73  this.Y = y;
74  }
75 
76  public void SetPoint(double x, double y)
77  {
78  this.X = x;
79  this.Y = y;
80  }
81 
82  public void Normalize()
83  {
84  double length = System.Math.Sqrt(X * X + Y * Y);
85  X /= length;
86  Y /= length;
87  }
88  }
89 
90  // use for sites and vertecies
91  public class Site
92  {
94  public int SiteNbr;
95 
96  public void SetPoint(Vector2 point)
97  {
98  Coord.SetPoint(point.X, point.Y);
99  }
100 
101  public Site ()
102  {
103  Coord = new DoubleVector2();
104  }
105  }
106 
107  public class Edge
108  {
109  public double a = 0, b = 0, c = 0;
110  public Site[] ep;
111  public Site[] reg;
112  public int edgenbr;
113 
114  public Edge ()
115  {
116  ep = new Site[2];
117  reg = new Site[2];
118  }
119  }
120 
121 
122  public class Halfedge
123  {
124  public Halfedge ELleft, ELright;
125  public Edge ELedge;
126  public bool deleted;
127  public int ELpm;
128  public Site vertex;
129  public double ystar;
130  public Halfedge PQnext;
131 
132  public Halfedge ()
133  {
134  PQnext = null;
135  }
136  }
137 
138  public enum CellType
139  {
140  Solid, Empty, Path, Removed
141  }
142 
143  public class VoronoiCell
144  {
145  public List<GraphEdge> Edges;
146  public Site Site;
147 
148  public List<Vector2> BodyVertices;
149 
150  public Body Body;
151 
153 
154  public Vector2 Translation;
155 
156  public bool Island;
157 
158  public bool IsDestructible;
159  public bool DoesDamage;
160 
164  public Action OnDestroyed;
165 
166  public Vector2 Center
167  {
168  get { return new Vector2((float)Site.Coord.X, (float)Site.Coord.Y) + Translation; }
169  }
170 
171  public VoronoiCell(Vector2[] vertices)
172  {
173  Edges = new List<GraphEdge>();
174  BodyVertices = new List<Vector2>();
175 
176  Vector2 midPoint = Vector2.Zero;
177  foreach (Vector2 vertex in vertices)
178  {
179  midPoint += vertex;
180  }
181  midPoint /= vertices.Length;
182 
183  for (int i = 0; i < vertices.Length; i++)
184  {
185  GraphEdge ge = new GraphEdge(vertices[i], vertices[MathUtils.PositiveModulo(i + 1, vertices.Length)]);
186  System.Diagnostics.Debug.Assert(ge.Point1 != ge.Point2);
187  Edges.Add(ge);
188  }
189 
190  Site = new Site();
191  Site.SetPoint(midPoint);
192  }
193 
194  public VoronoiCell(Site site)
195  {
196  Edges = new List<GraphEdge>();
197  BodyVertices = new List<Vector2>();
198  //bodies = new List<Body>();
199  this.Site = site;
200  }
201 
202  public bool IsPointInside(Vector2 point)
203  {
204  if (!IsPointInsideAABB(point, margin: 0.0f)) { return false; }
205  Vector2 transformedPoint = point - Translation;
206  foreach (GraphEdge edge in Edges)
207  {
208  if (MathUtils.LineSegmentsIntersect(transformedPoint, Center - Translation, edge.Point1, edge.Point2)) { return false; }
209  }
210  return true;
211  }
212 
213  public bool IsPointInsideAABB(Vector2 point2, float margin)
214  {
215  Vector2 transformedPoint = point2 - Translation;
216  Vector2 max = transformedPoint + Vector2.One * margin;
217  Vector2 min = transformedPoint - Vector2.One * margin;
218 
219  if (Edges.All(e => e.Point1.X < min.X && e.Point2.X < min.X)) { return false; }
220  if (Edges.All(e => e.Point1.Y < min.Y && e.Point2.Y < min.Y)) { return false; }
221  if (Edges.All(e => e.Point1.X > max.X && e.Point2.X > max.X)) { return false; }
222  if (Edges.All(e => e.Point1.Y > max.Y && e.Point2.Y > max.Y)) { return false; }
223 
224  return true;
225  }
226  }
227 
228  public class GraphEdge
229  {
230  public Vector2 Point1, Point2;
231  public Site Site1, Site2;
232  public VoronoiCell Cell1, Cell2;
233 
234  public bool IsSolid;
235  public bool OutsideLevel;
236  public bool NextToCave, NextToMainPath, NextToSidePath;
237 
238  public Vector2 Center
239  {
240  get { return (Point1 + Point2) / 2.0f; }
241  }
242 
243  public GraphEdge(Vector2 point1, Vector2 point2)
244  {
245  this.Point1 = point1;
246  this.Point2 = point2;
247  }
248 
250  {
251  if (Cell1 == cell)
252  {
253  return Cell2;
254  }
255  else if (Cell2 == cell)
256  {
257  return Cell1;
258  }
259 
260  return null;
261  }
262 
266  public Vector2 GetNormal(VoronoiCell cell)
267  {
268  Vector2 dir = Vector2.Normalize(Point1 - Point2);
269  Vector2 normal = new Vector2(dir.Y, -dir.X);
270  if (cell != null && Vector2.Dot(normal, Vector2.Normalize(Center - (cell.Center - cell.Translation))) < 0)
271  {
272  normal = -normal;
273  }
274  return normal;
275  }
276 
277  public override string ToString()
278  {
279  return "GraphEdge (" + Point1.ToString() + ", " + Point2.ToString() + ")";
280  }
281  }
282 
283  // للترتيب
284  public class SiteSorterYX : IComparer<Site>
285  {
286  public int Compare ( Site p1, Site p2 )
287  {
288  DoubleVector2 s1 = p1.Coord;
289  DoubleVector2 s2 = p2.Coord;
290  if ( s1.Y < s2.Y ) return -1;
291  if ( s1.Y > s2.Y ) return 1;
292  if ( s1.X < s2.X ) return -1;
293  if ( s1.X > s2.X ) return 1;
294  return 0;
295  }
296  }
297 }
void SetPoint(double x, double y)
DoubleVector2(double x, double y)
override string ToString()
GraphEdge(Vector2 point1, Vector2 point2)
VoronoiCell AdjacentCell(VoronoiCell cell)
Vector2 GetNormal(VoronoiCell cell)
Returns the normal of the edge that points outwards from the specified cell
DoubleVector2 Coord
void SetPoint(Vector2 point)
int Compare(Site p1, Site p2)
VoronoiCell(Vector2[] vertices)
Action OnDestroyed
Executed when the cell is destroyed (only applies to destructible level walls)
List< GraphEdge > Edges
bool IsPointInsideAABB(Vector2 point2, float margin)
List< Vector2 > BodyVertices
bool IsPointInside(Vector2 point)