babylon.polygonMesh.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. var __extends = (this && 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. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5. };
  6. var BABYLON;
  7. (function (BABYLON) {
  8. var IndexedVector2 = (function (_super) {
  9. __extends(IndexedVector2, _super);
  10. function IndexedVector2(original, index) {
  11. _super.call(this, original.x, original.y);
  12. this.index = index;
  13. }
  14. return IndexedVector2;
  15. })(BABYLON.Vector2);
  16. var PolygonPoints = (function () {
  17. function PolygonPoints() {
  18. this.elements = new Array();
  19. }
  20. PolygonPoints.prototype.add = function (originalPoints) {
  21. var _this = this;
  22. var result = new Array();
  23. originalPoints.forEach(function (point) {
  24. if (result.length === 0 || !point.equalsWithEpsilon(result[0])) {
  25. var newPoint = new IndexedVector2(point, _this.elements.length);
  26. result.push(newPoint);
  27. _this.elements.push(newPoint);
  28. }
  29. });
  30. return result;
  31. };
  32. PolygonPoints.prototype.computeBounds = function () {
  33. var lmin = new BABYLON.Vector2(this.elements[0].x, this.elements[0].y);
  34. var lmax = new BABYLON.Vector2(this.elements[0].x, this.elements[0].y);
  35. this.elements.forEach(function (point) {
  36. // x
  37. if (point.x < lmin.x) {
  38. lmin.x = point.x;
  39. }
  40. else if (point.x > lmax.x) {
  41. lmax.x = point.x;
  42. }
  43. // y
  44. if (point.y < lmin.y) {
  45. lmin.y = point.y;
  46. }
  47. else if (point.y > lmax.y) {
  48. lmax.y = point.y;
  49. }
  50. });
  51. return {
  52. min: lmin,
  53. max: lmax,
  54. width: lmax.x - lmin.x,
  55. height: lmax.y - lmin.y
  56. };
  57. };
  58. return PolygonPoints;
  59. })();
  60. var Polygon = (function () {
  61. function Polygon() {
  62. }
  63. Polygon.Rectangle = function (xmin, ymin, xmax, ymax) {
  64. return [
  65. new BABYLON.Vector2(xmin, ymin),
  66. new BABYLON.Vector2(xmax, ymin),
  67. new BABYLON.Vector2(xmax, ymax),
  68. new BABYLON.Vector2(xmin, ymax)
  69. ];
  70. };
  71. Polygon.Circle = function (radius, cx, cy, numberOfSides) {
  72. if (cx === void 0) { cx = 0; }
  73. if (cy === void 0) { cy = 0; }
  74. if (numberOfSides === void 0) { numberOfSides = 32; }
  75. var result = new Array();
  76. var angle = 0;
  77. var increment = (Math.PI * 2) / numberOfSides;
  78. for (var i = 0; i < numberOfSides; i++) {
  79. result.push(new BABYLON.Vector2(cx + Math.cos(angle) * radius, cy + Math.sin(angle) * radius));
  80. angle -= increment;
  81. }
  82. return result;
  83. };
  84. Polygon.Parse = function (input) {
  85. var floats = input.split(/[^-+eE\.\d]+/).map(parseFloat).filter(function (val) { return (!isNaN(val)); });
  86. var i, result = [];
  87. for (i = 0; i < (floats.length & 0x7FFFFFFE); i += 2) {
  88. result.push(new BABYLON.Vector2(floats[i], floats[i + 1]));
  89. }
  90. return result;
  91. };
  92. Polygon.StartingAt = function (x, y) {
  93. return BABYLON.Path2.StartingAt(x, y);
  94. };
  95. return Polygon;
  96. })();
  97. BABYLON.Polygon = Polygon;
  98. var PolygonMeshBuilder = (function () {
  99. function PolygonMeshBuilder(name, contours, scene) {
  100. this._points = new PolygonPoints();
  101. this._outlinepoints = new PolygonPoints();
  102. this._holes = [];
  103. if (!("poly2tri" in window)) {
  104. throw "PolygonMeshBuilder cannot be used because poly2tri is not referenced";
  105. }
  106. this._name = name;
  107. this._scene = scene;
  108. var points;
  109. if (contours instanceof BABYLON.Path2) {
  110. points = contours.getPoints();
  111. }
  112. else {
  113. points = contours;
  114. }
  115. this._swctx = new poly2tri.SweepContext(this._points.add(points));
  116. this._outlinepoints.add(points);
  117. }
  118. PolygonMeshBuilder.prototype.addHole = function (hole) {
  119. this._swctx.addHole(this._points.add(hole));
  120. var holepoints = new PolygonPoints();
  121. holepoints.add(hole);
  122. this._holes.push(holepoints);
  123. return this;
  124. };
  125. PolygonMeshBuilder.prototype.build = function (updatable, depth) {
  126. var _this = this;
  127. if (updatable === void 0) { updatable = false; }
  128. var result = new BABYLON.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. if (depth > 0) {
  146. var positionscount = (positions.length / 3); //get the current pointcount
  147. this._points.elements.forEach(function (p) {
  148. normals.push(0, -1.0, 0);
  149. positions.push(p.x, -depth, p.y);
  150. uvs.push(1 - (p.x - bounds.min.x) / bounds.width, 1 - (p.y - bounds.min.y) / bounds.height);
  151. });
  152. var p1; //we need to change order of point so the triangles are made in the rigth way.
  153. var p2;
  154. var poscounter = 0;
  155. this._swctx.getTriangles().forEach(function (triangle) {
  156. triangle.getPoints().forEach(function (point) {
  157. switch (poscounter) {
  158. case 0:
  159. p1 = point;
  160. break;
  161. case 1:
  162. p2 = point;
  163. break;
  164. case 2:
  165. indices.push(point.index + positionscount);
  166. indices.push(p2.index + positionscount);
  167. indices.push(p1.index + positionscount);
  168. poscounter = -1;
  169. break;
  170. }
  171. poscounter++;
  172. //indices.push((<IndexedVector2>point).index + positionscount);
  173. });
  174. });
  175. //Add the sides
  176. this.addSide(positions, normals, uvs, indices, bounds, this._outlinepoints, depth, false);
  177. this._holes.forEach(function (hole) {
  178. _this.addSide(positions, normals, uvs, indices, bounds, hole, depth, true);
  179. });
  180. }
  181. result.setVerticesData(BABYLON.VertexBuffer.PositionKind, positions, updatable);
  182. result.setVerticesData(BABYLON.VertexBuffer.NormalKind, normals, updatable);
  183. result.setVerticesData(BABYLON.VertexBuffer.UVKind, uvs, updatable);
  184. result.setIndices(indices);
  185. return result;
  186. };
  187. PolygonMeshBuilder.prototype.addSide = function (positions, normals, uvs, indices, bounds, points, depth, flip) {
  188. var StartIndex = positions.length / 3;
  189. var ulength = 0;
  190. for (var i = 0; i < points.elements.length; i++) {
  191. var p = points.elements[i];
  192. var p1;
  193. if ((i + 1) > points.elements.length - 1) {
  194. p1 = points.elements[0];
  195. }
  196. else {
  197. p1 = points.elements[i + 1];
  198. }
  199. positions.push(p.x, 0, p.y);
  200. positions.push(p.x, -depth, p.y);
  201. positions.push(p1.x, 0, p1.y);
  202. positions.push(p1.x, -depth, p1.y);
  203. var v1 = new BABYLON.Vector3(p.x, 0, p.y);
  204. var v2 = new BABYLON.Vector3(p1.x, 0, p1.y);
  205. var v3 = v2.subtract(v1);
  206. var v4 = new BABYLON.Vector3(0, 1, 0);
  207. var vn = BABYLON.Vector3.Cross(v3, v4);
  208. vn = vn.normalize();
  209. uvs.push(ulength / bounds.width, 0);
  210. uvs.push(ulength / bounds.width, 1);
  211. ulength += v3.length();
  212. uvs.push((ulength / bounds.width), 0);
  213. uvs.push((ulength / bounds.width), 1);
  214. if (!flip) {
  215. normals.push(-vn.x, -vn.y, -vn.z);
  216. normals.push(-vn.x, -vn.y, -vn.z);
  217. normals.push(-vn.x, -vn.y, -vn.z);
  218. normals.push(-vn.x, -vn.y, -vn.z);
  219. indices.push(StartIndex);
  220. indices.push(StartIndex + 1);
  221. indices.push(StartIndex + 2);
  222. indices.push(StartIndex + 1);
  223. indices.push(StartIndex + 3);
  224. indices.push(StartIndex + 2);
  225. }
  226. else {
  227. normals.push(vn.x, vn.y, vn.z);
  228. normals.push(vn.x, vn.y, vn.z);
  229. normals.push(vn.x, vn.y, vn.z);
  230. normals.push(vn.x, vn.y, vn.z);
  231. indices.push(StartIndex);
  232. indices.push(StartIndex + 2);
  233. indices.push(StartIndex + 1);
  234. indices.push(StartIndex + 1);
  235. indices.push(StartIndex + 2);
  236. indices.push(StartIndex + 3);
  237. }
  238. StartIndex += 4;
  239. }
  240. ;
  241. };
  242. return PolygonMeshBuilder;
  243. })();
  244. BABYLON.PolygonMeshBuilder = PolygonMeshBuilder;
  245. })(BABYLON || (BABYLON = {}));