babylon.polygonmesh.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. var __extends = this.__extends || function (d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function __() { this.constructor = d; }
  4. __.prototype = b.prototype;
  5. d.prototype = new __();
  6. };
  7. var BABYLON;
  8. (function (BABYLON) {
  9. var IndexedVector2 = (function (_super) {
  10. __extends(IndexedVector2, _super);
  11. function IndexedVector2(original, index) {
  12. _super.call(this, original.x, original.y);
  13. this.index = index;
  14. }
  15. return IndexedVector2;
  16. })(Vector2);
  17. function nearlyEqual(a, b, epsilon) {
  18. if (typeof epsilon === "undefined") { epsilon = 0.0001; }
  19. if (a === b) {
  20. return true;
  21. }
  22. return Math.abs(a - b) < epsilon;
  23. }
  24. var PolygonPoints = (function () {
  25. function PolygonPoints() {
  26. this.elements = new Array();
  27. }
  28. PolygonPoints.prototype.add = function (originalPoints) {
  29. var _this = this;
  30. var result = new Array();
  31. originalPoints.forEach(function (point) {
  32. if (result.length === 0 || !(nearlyEqual(point.x, result[0].x) && nearlyEqual(point.y, result[0].y))) {
  33. var newPoint = new IndexedVector2(point, _this.elements.length);
  34. result.push(newPoint);
  35. _this.elements.push(newPoint);
  36. }
  37. });
  38. return result;
  39. };
  40. PolygonPoints.prototype.computeBounds = function () {
  41. var lmin = new Vector2(this.elements[0].x, this.elements[0].y);
  42. var lmax = new Vector2(this.elements[0].x, this.elements[0].y);
  43. this.elements.forEach(function (point) {
  44. // x
  45. if (point.x < lmin.x) {
  46. lmin.x = point.x;
  47. } else if (point.x > lmax.x) {
  48. lmax.x = point.x;
  49. }
  50. // y
  51. if (point.y < lmin.y) {
  52. lmin.y = point.y;
  53. } else if (point.y > lmax.y) {
  54. lmax.y = point.y;
  55. }
  56. });
  57. return {
  58. min: lmin,
  59. max: lmax,
  60. width: lmax.x - lmin.x,
  61. height: lmax.y - lmin.y
  62. };
  63. };
  64. return PolygonPoints;
  65. })();
  66. var Polygon = (function () {
  67. function Polygon() {
  68. }
  69. Polygon.Rectangle = function (xmin, ymin, xmax, ymax) {
  70. return [
  71. new Vector2(xmin, ymin),
  72. new Vector2(xmax, ymin),
  73. new Vector2(xmax, ymax),
  74. new Vector2(xmin, ymax)
  75. ];
  76. };
  77. Polygon.Circle = function (radius, cx, cy, numberOfSides) {
  78. if (typeof cx === "undefined") { cx = 0; }
  79. if (typeof cy === "undefined") { cy = 0; }
  80. if (typeof numberOfSides === "undefined") { numberOfSides = 32; }
  81. var result = new Array();
  82. var angle = 0;
  83. var increment = (Math.PI * 2) / numberOfSides;
  84. for (var i = 0; i < numberOfSides; i++) {
  85. result.push(new Vector2(cx + Math.cos(angle) * radius, cy + Math.sin(angle) * radius));
  86. angle -= increment;
  87. }
  88. return result;
  89. };
  90. Polygon.Parse = function (input) {
  91. var floats = input.split(/[^-+eE\.\d]+/).map(parseFloat).filter(function (val) {
  92. return (!isNaN(val));
  93. });
  94. var i, result = [];
  95. for (i = 0; i < (floats.length & 0x7FFFFFFE); i += 2) {
  96. result.push(new poly2tri.Point(floats[i], floats[i + 1]));
  97. }
  98. return result;
  99. };
  100. Polygon.StartingAt = function (x, y) {
  101. return Path2.StartingAt(x, y);
  102. };
  103. return Polygon;
  104. })();
  105. BABYLON.Polygon = Polygon;
  106. var PolygonMeshBuilder = (function () {
  107. function PolygonMeshBuilder(name, contours, scene) {
  108. this._points = new PolygonPoints();
  109. if (!("poly2tri" in window)) {
  110. throw "PolygonMeshBuilder cannot be used because poly2tri is not referenced";
  111. }
  112. this._name = name;
  113. this._scene = scene;
  114. var points;
  115. if (contours instanceof Path2) {
  116. points = contours.getPoints();
  117. } else {
  118. points = contours;
  119. }
  120. this._swctx = new poly2tri.SweepContext(this._points.add(points));
  121. }
  122. PolygonMeshBuilder.prototype.addHole = function (hole) {
  123. this._swctx.addHole(this._points.add(hole));
  124. return this;
  125. };
  126. PolygonMeshBuilder.prototype.build = function (updatable) {
  127. if (typeof updatable === "undefined") { updatable = false; }
  128. var result = new Mesh(this._name, this._scene);
  129. var normals = [];
  130. var positions = [];
  131. var uvs = [];
  132. var bounds = this._points.computeBounds();
  133. this._points.elements.forEach(function (p) {
  134. normals.push(0, 1.0, 0);
  135. positions.push(p.x, 0, p.y);
  136. uvs.push((p.x - bounds.min.x) / bounds.width, (p.y - bounds.min.y) / bounds.height);
  137. });
  138. var indices = [];
  139. this._swctx.triangulate();
  140. this._swctx.getTriangles().forEach(function (triangle) {
  141. triangle.getPoints().forEach(function (point) {
  142. indices.push(point.index);
  143. });
  144. });
  145. result.setVerticesData(positions, VertexBuffer.PositionKind, updatable);
  146. result.setVerticesData(normals, VertexBuffer.NormalKind, updatable);
  147. result.setVerticesData(uvs, VertexBuffer.UVKind, updatable);
  148. result.setIndices(indices);
  149. return result;
  150. };
  151. return PolygonMeshBuilder;
  152. })();
  153. BABYLON.PolygonMeshBuilder = PolygonMeshBuilder;
  154. })(BABYLON || (BABYLON = {}));