暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /*
  2. ** SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
  3. ** Copyright (C) 2011 Silicon Graphics, Inc.
  4. ** All Rights Reserved.
  5. **
  6. ** Permission is hereby granted, free of charge, to any person obtaining a copy
  7. ** of this software and associated documentation files (the "Software"), to deal
  8. ** in the Software without restriction, including without limitation the rights
  9. ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  10. ** of the Software, and to permit persons to whom the Software is furnished to do so,
  11. ** subject to the following conditions:
  12. **
  13. ** The above copyright notice including the dates of first publication and either this
  14. ** permission notice or a reference to http://oss.sgi.com/projects/FreeB/ shall be
  15. ** included in all copies or substantial portions of the Software.
  16. **
  17. ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  18. ** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  19. ** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL SILICON GRAPHICS, INC.
  20. ** BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21. ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
  22. ** OR OTHER DEALINGS IN THE SOFTWARE.
  23. **
  24. ** Except as contained in this notice, the name of Silicon Graphics, Inc. shall not
  25. ** be used in advertising or otherwise to promote the sale, use or other dealings in
  26. ** this Software without prior written authorization from Silicon Graphics, Inc.
  27. */
  28. /*
  29. ** Original Author: Eric Veach, July 1994.
  30. ** libtess2: Mikko Mononen, http://code.google.com/p/libtess2/.
  31. ** LibTessDotNet: Remi Gillig, https://github.com/speps/LibTessDotNet
  32. */
  33. using System;
  34. using System.Collections.Generic;
  35. using System.Diagnostics;
  36. namespace Unity.SpriteShape.External
  37. {
  38. using Real = System.Single;
  39. namespace LibTessDotNet
  40. {
  41. internal struct Vec3
  42. {
  43. public readonly static Vec3 Zero = new Vec3();
  44. public Real X, Y, Z;
  45. public Real this[int index]
  46. {
  47. get
  48. {
  49. if (index == 0) return X;
  50. if (index == 1) return Y;
  51. if (index == 2) return Z;
  52. throw new IndexOutOfRangeException();
  53. }
  54. set
  55. {
  56. if (index == 0) X = value;
  57. else if (index == 1) Y = value;
  58. else if (index == 2) Z = value;
  59. else throw new IndexOutOfRangeException();
  60. }
  61. }
  62. public static void Sub(ref Vec3 lhs, ref Vec3 rhs, out Vec3 result)
  63. {
  64. result.X = lhs.X - rhs.X;
  65. result.Y = lhs.Y - rhs.Y;
  66. result.Z = lhs.Z - rhs.Z;
  67. }
  68. public static void Neg(ref Vec3 v)
  69. {
  70. v.X = -v.X;
  71. v.Y = -v.Y;
  72. v.Z = -v.Z;
  73. }
  74. public static void Dot(ref Vec3 u, ref Vec3 v, out Real dot)
  75. {
  76. dot = u.X * v.X + u.Y * v.Y + u.Z * v.Z;
  77. }
  78. public static void Normalize(ref Vec3 v)
  79. {
  80. var len = v.X * v.X + v.Y * v.Y + v.Z * v.Z;
  81. Debug.Assert(len >= 0.0f);
  82. len = 1.0f / (Real)Math.Sqrt(len);
  83. v.X *= len;
  84. v.Y *= len;
  85. v.Z *= len;
  86. }
  87. public static int LongAxis(ref Vec3 v)
  88. {
  89. int i = 0;
  90. if (Math.Abs(v.Y) > Math.Abs(v.X)) i = 1;
  91. if (Math.Abs(v.Z) > Math.Abs(i == 0 ? v.X : v.Y)) i = 2;
  92. return i;
  93. }
  94. public override string ToString()
  95. {
  96. return string.Format("{0}, {1}, {2}", X, Y, Z);
  97. }
  98. }
  99. internal static class MeshUtils
  100. {
  101. public const int Undef = ~0;
  102. public abstract class Pooled<T> where T : Pooled<T>, new()
  103. {
  104. private static Stack<T> _stack;
  105. public abstract void Reset();
  106. public virtual void OnFree() { }
  107. public static T Create()
  108. {
  109. if (_stack != null && _stack.Count > 0)
  110. {
  111. return _stack.Pop();
  112. }
  113. return new T();
  114. }
  115. public void Free()
  116. {
  117. OnFree();
  118. Reset();
  119. if (_stack == null)
  120. {
  121. _stack = new Stack<T>();
  122. }
  123. _stack.Push((T)this);
  124. }
  125. }
  126. public class Vertex : Pooled<Vertex>
  127. {
  128. internal Vertex _prev, _next;
  129. internal Edge _anEdge;
  130. internal Vec3 _coords;
  131. internal Real _s, _t;
  132. internal PQHandle _pqHandle;
  133. internal int _n;
  134. internal object _data;
  135. public override void Reset()
  136. {
  137. _prev = _next = null;
  138. _anEdge = null;
  139. _coords = Vec3.Zero;
  140. _s = 0;
  141. _t = 0;
  142. _pqHandle = new PQHandle();
  143. _n = 0;
  144. _data = null;
  145. }
  146. }
  147. public class Face : Pooled<Face>
  148. {
  149. internal Face _prev, _next;
  150. internal Edge _anEdge;
  151. internal Face _trail;
  152. internal int _n;
  153. internal bool _marked, _inside;
  154. internal int VertsCount
  155. {
  156. get
  157. {
  158. int n = 0;
  159. var eCur = _anEdge;
  160. do {
  161. n++;
  162. eCur = eCur._Lnext;
  163. } while (eCur != _anEdge);
  164. return n;
  165. }
  166. }
  167. public override void Reset()
  168. {
  169. _prev = _next = null;
  170. _anEdge = null;
  171. _trail = null;
  172. _n = 0;
  173. _marked = false;
  174. _inside = false;
  175. }
  176. }
  177. public struct EdgePair
  178. {
  179. internal Edge _e, _eSym;
  180. public static EdgePair Create()
  181. {
  182. var pair = new MeshUtils.EdgePair();
  183. pair._e = MeshUtils.Edge.Create();
  184. pair._e._pair = pair;
  185. pair._eSym = MeshUtils.Edge.Create();
  186. pair._eSym._pair = pair;
  187. return pair;
  188. }
  189. public void Reset()
  190. {
  191. _e = _eSym = null;
  192. }
  193. }
  194. public class Edge : Pooled<Edge>
  195. {
  196. internal EdgePair _pair;
  197. internal Edge _next, _Sym, _Onext, _Lnext;
  198. internal Vertex _Org;
  199. internal Face _Lface;
  200. internal Tess.ActiveRegion _activeRegion;
  201. internal int _winding;
  202. internal Face _Rface { get { return _Sym._Lface; } set { _Sym._Lface = value; } }
  203. internal Vertex _Dst { get { return _Sym._Org; } set { _Sym._Org = value; } }
  204. internal Edge _Oprev { get { return _Sym._Lnext; } set { _Sym._Lnext = value; } }
  205. internal Edge _Lprev { get { return _Onext._Sym; } set { _Onext._Sym = value; } }
  206. internal Edge _Dprev { get { return _Lnext._Sym; } set { _Lnext._Sym = value; } }
  207. internal Edge _Rprev { get { return _Sym._Onext; } set { _Sym._Onext = value; } }
  208. internal Edge _Dnext { get { return _Rprev._Sym; } set { _Rprev._Sym = value; } }
  209. internal Edge _Rnext { get { return _Oprev._Sym; } set { _Oprev._Sym = value; } }
  210. internal static void EnsureFirst(ref Edge e)
  211. {
  212. if (e == e._pair._eSym)
  213. {
  214. e = e._Sym;
  215. }
  216. }
  217. public override void Reset()
  218. {
  219. _pair.Reset();
  220. _next = _Sym = _Onext = _Lnext = null;
  221. _Org = null;
  222. _Lface = null;
  223. _activeRegion = null;
  224. _winding = 0;
  225. }
  226. }
  227. /// <summary>
  228. /// MakeEdge creates a new pair of half-edges which form their own loop.
  229. /// No vertex or face structures are allocated, but these must be assigned
  230. /// before the current edge operation is completed.
  231. /// </summary>
  232. public static Edge MakeEdge(Edge eNext)
  233. {
  234. Debug.Assert(eNext != null);
  235. var pair = EdgePair.Create();
  236. var e = pair._e;
  237. var eSym = pair._eSym;
  238. // Make sure eNext points to the first edge of the edge pair
  239. Edge.EnsureFirst(ref eNext);
  240. // Insert in circular doubly-linked list before eNext.
  241. // Note that the prev pointer is stored in Sym->next.
  242. var ePrev = eNext._Sym._next;
  243. eSym._next = ePrev;
  244. ePrev._Sym._next = e;
  245. e._next = eNext;
  246. eNext._Sym._next = eSym;
  247. e._Sym = eSym;
  248. e._Onext = e;
  249. e._Lnext = eSym;
  250. e._Org = null;
  251. e._Lface = null;
  252. e._winding = 0;
  253. e._activeRegion = null;
  254. eSym._Sym = e;
  255. eSym._Onext = eSym;
  256. eSym._Lnext = e;
  257. eSym._Org = null;
  258. eSym._Lface = null;
  259. eSym._winding = 0;
  260. eSym._activeRegion = null;
  261. return e;
  262. }
  263. /// <summary>
  264. /// Splice( a, b ) is best described by the Guibas/Stolfi paper or the
  265. /// CS348a notes (see Mesh.cs). Basically it modifies the mesh so that
  266. /// a->Onext and b->Onext are exchanged. This can have various effects
  267. /// depending on whether a and b belong to different face or vertex rings.
  268. /// For more explanation see Mesh.Splice().
  269. /// </summary>
  270. public static void Splice(Edge a, Edge b)
  271. {
  272. var aOnext = a._Onext;
  273. var bOnext = b._Onext;
  274. aOnext._Sym._Lnext = b;
  275. bOnext._Sym._Lnext = a;
  276. a._Onext = bOnext;
  277. b._Onext = aOnext;
  278. }
  279. /// <summary>
  280. /// MakeVertex( eOrig, vNext ) attaches a new vertex and makes it the
  281. /// origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives
  282. /// a place to insert the new vertex in the global vertex list. We insert
  283. /// the new vertex *before* vNext so that algorithms which walk the vertex
  284. /// list will not see the newly created vertices.
  285. /// </summary>
  286. public static void MakeVertex(Edge eOrig, Vertex vNext)
  287. {
  288. var vNew = MeshUtils.Vertex.Create();
  289. // insert in circular doubly-linked list before vNext
  290. var vPrev = vNext._prev;
  291. vNew._prev = vPrev;
  292. vPrev._next = vNew;
  293. vNew._next = vNext;
  294. vNext._prev = vNew;
  295. vNew._anEdge = eOrig;
  296. // leave coords, s, t undefined
  297. // fix other edges on this vertex loop
  298. var e = eOrig;
  299. do {
  300. e._Org = vNew;
  301. e = e._Onext;
  302. } while (e != eOrig);
  303. }
  304. /// <summary>
  305. /// MakeFace( eOrig, fNext ) attaches a new face and makes it the left
  306. /// face of all edges in the face loop to which eOrig belongs. "fNext" gives
  307. /// a place to insert the new face in the global face list. We insert
  308. /// the new face *before* fNext so that algorithms which walk the face
  309. /// list will not see the newly created faces.
  310. /// </summary>
  311. public static void MakeFace(Edge eOrig, Face fNext)
  312. {
  313. var fNew = MeshUtils.Face.Create();
  314. // insert in circular doubly-linked list before fNext
  315. var fPrev = fNext._prev;
  316. fNew._prev = fPrev;
  317. fPrev._next = fNew;
  318. fNew._next = fNext;
  319. fNext._prev = fNew;
  320. fNew._anEdge = eOrig;
  321. fNew._trail = null;
  322. fNew._marked = false;
  323. // The new face is marked "inside" if the old one was. This is a
  324. // convenience for the common case where a face has been split in two.
  325. fNew._inside = fNext._inside;
  326. // fix other edges on this face loop
  327. var e = eOrig;
  328. do {
  329. e._Lface = fNew;
  330. e = e._Lnext;
  331. } while (e != eOrig);
  332. }
  333. /// <summary>
  334. /// KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym),
  335. /// and removes from the global edge list.
  336. /// </summary>
  337. public static void KillEdge(Edge eDel)
  338. {
  339. // Half-edges are allocated in pairs, see EdgePair above
  340. Edge.EnsureFirst(ref eDel);
  341. // delete from circular doubly-linked list
  342. var eNext = eDel._next;
  343. var ePrev = eDel._Sym._next;
  344. eNext._Sym._next = ePrev;
  345. ePrev._Sym._next = eNext;
  346. eDel.Free();
  347. }
  348. /// <summary>
  349. /// KillVertex( vDel ) destroys a vertex and removes it from the global
  350. /// vertex list. It updates the vertex loop to point to a given new vertex.
  351. /// </summary>
  352. public static void KillVertex(Vertex vDel, Vertex newOrg)
  353. {
  354. var eStart = vDel._anEdge;
  355. // change the origin of all affected edges
  356. var e = eStart;
  357. do {
  358. e._Org = newOrg;
  359. e = e._Onext;
  360. } while (e != eStart);
  361. // delete from circular doubly-linked list
  362. var vPrev = vDel._prev;
  363. var vNext = vDel._next;
  364. vNext._prev = vPrev;
  365. vPrev._next = vNext;
  366. vDel.Free();
  367. }
  368. /// <summary>
  369. /// KillFace( fDel ) destroys a face and removes it from the global face
  370. /// list. It updates the face loop to point to a given new face.
  371. /// </summary>
  372. public static void KillFace(Face fDel, Face newLFace)
  373. {
  374. var eStart = fDel._anEdge;
  375. // change the left face of all affected edges
  376. var e = eStart;
  377. do {
  378. e._Lface = newLFace;
  379. e = e._Lnext;
  380. } while (e != eStart);
  381. // delete from circular doubly-linked list
  382. var fPrev = fDel._prev;
  383. var fNext = fDel._next;
  384. fNext._prev = fPrev;
  385. fPrev._next = fNext;
  386. fDel.Free();
  387. }
  388. /// <summary>
  389. /// Return signed area of face.
  390. /// </summary>
  391. public static Real FaceArea(Face f)
  392. {
  393. Real area = 0;
  394. var e = f._anEdge;
  395. do
  396. {
  397. area += (e._Org._s - e._Dst._s) * (e._Org._t + e._Dst._t);
  398. e = e._Lnext;
  399. } while (e != f._anEdge);
  400. return area;
  401. }
  402. }
  403. }
  404. } // namespace Unity.VectorGraphics.External