babylon.prim2dBase.js 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  7. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  8. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  9. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  10. return c > 3 && r && Object.defineProperty(target, key, r), r;
  11. };
  12. var BABYLON;
  13. (function (BABYLON) {
  14. var PrepareRender2DContext = (function () {
  15. function PrepareRender2DContext() {
  16. this.forceRefreshPrimitive = false;
  17. }
  18. return PrepareRender2DContext;
  19. }());
  20. BABYLON.PrepareRender2DContext = PrepareRender2DContext;
  21. var Render2DContext = (function () {
  22. function Render2DContext(renderMode) {
  23. this._renderMode = renderMode;
  24. this.useInstancing = false;
  25. this.groupInfoPartData = null;
  26. this.partDataStartIndex = this.partDataEndIndex = null;
  27. }
  28. Object.defineProperty(Render2DContext.prototype, "renderMode", {
  29. /**
  30. * Define which render Mode should be used to render the primitive: one of Render2DContext.RenderModeXxxx property
  31. */
  32. get: function () {
  33. return this._renderMode;
  34. },
  35. enumerable: true,
  36. configurable: true
  37. });
  38. Object.defineProperty(Render2DContext, "RenderModeOpaque", {
  39. /**
  40. * The set of primitives to render is opaque.
  41. * This is the first rendering pass. All Opaque primitives are rendered. Depth Compare and Write are both enabled.
  42. */
  43. get: function () {
  44. return Render2DContext._renderModeOpaque;
  45. },
  46. enumerable: true,
  47. configurable: true
  48. });
  49. Object.defineProperty(Render2DContext, "RenderModeAlphaTest", {
  50. /**
  51. * The set of primitives to render is using Alpha Test (aka masking).
  52. * Alpha Blend is enabled, the AlphaMode must be manually set, the render occurs after the RenderModeOpaque and is depth independent (i.e. primitives are not sorted by depth). Depth Compare and Write are both enabled.
  53. */
  54. get: function () {
  55. return Render2DContext._renderModeAlphaTest;
  56. },
  57. enumerable: true,
  58. configurable: true
  59. });
  60. Object.defineProperty(Render2DContext, "RenderModeTransparent", {
  61. /**
  62. * The set of primitives to render is transparent.
  63. * Alpha Blend is enabled, the AlphaMode must be manually set, the render occurs after the RenderModeAlphaTest and is depth dependent (i.e. primitives are stored by depth and rendered back to front). Depth Compare is on, but Depth write is Off.
  64. */
  65. get: function () {
  66. return Render2DContext._renderModeTransparent;
  67. },
  68. enumerable: true,
  69. configurable: true
  70. });
  71. Render2DContext._renderModeOpaque = 1;
  72. Render2DContext._renderModeAlphaTest = 2;
  73. Render2DContext._renderModeTransparent = 3;
  74. return Render2DContext;
  75. }());
  76. BABYLON.Render2DContext = Render2DContext;
  77. /**
  78. * This class store information for the pointerEventObservable Observable.
  79. * The Observable is divided into many sub events (using the Mask feature of the Observable pattern): PointerOver, PointerEnter, PointerDown, PointerMouseWheel, PointerMove, PointerUp, PointerDown, PointerLeave, PointerGotCapture and PointerLostCapture.
  80. */
  81. var PrimitivePointerInfo = (function () {
  82. function PrimitivePointerInfo() {
  83. this.primitivePointerPos = BABYLON.Vector2.Zero();
  84. this.tilt = BABYLON.Vector2.Zero();
  85. this.cancelBubble = false;
  86. }
  87. Object.defineProperty(PrimitivePointerInfo, "PointerOver", {
  88. // The behavior is based on the HTML specifications of the Pointer Events (https://www.w3.org/TR/pointerevents/#list-of-pointer-events). This is not 100% compliant and not meant to be, but still, it's based on these specs for most use cases to be programmed the same way (as closest as possible) as it would have been in HTML.
  89. /**
  90. * This event type is raised when a pointing device is moved into the hit test boundaries of a primitive.
  91. * Bubbles: yes
  92. */
  93. get: function () {
  94. return PrimitivePointerInfo._pointerOver;
  95. },
  96. enumerable: true,
  97. configurable: true
  98. });
  99. Object.defineProperty(PrimitivePointerInfo, "PointerEnter", {
  100. /**
  101. * This event type is raised when a pointing device is moved into the hit test boundaries of a primitive or one of its descendants.
  102. * Bubbles: no
  103. */
  104. get: function () {
  105. return PrimitivePointerInfo._pointerEnter;
  106. },
  107. enumerable: true,
  108. configurable: true
  109. });
  110. Object.defineProperty(PrimitivePointerInfo, "PointerDown", {
  111. /**
  112. * This event type is raised when a pointer enters the active button state (non-zero value in the buttons property). For mouse it's when the device transitions from no buttons depressed to at least one button depressed. For touch/pen this is when a physical contact is made.
  113. * Bubbles: yes
  114. */
  115. get: function () {
  116. return PrimitivePointerInfo._pointerDown;
  117. },
  118. enumerable: true,
  119. configurable: true
  120. });
  121. Object.defineProperty(PrimitivePointerInfo, "PointerMouseWheel", {
  122. /**
  123. * This event type is raised when the pointer is a mouse and it's wheel is rolling
  124. * Bubbles: yes
  125. */
  126. get: function () {
  127. return PrimitivePointerInfo._pointerMouseWheel;
  128. },
  129. enumerable: true,
  130. configurable: true
  131. });
  132. Object.defineProperty(PrimitivePointerInfo, "PointerMove", {
  133. /**
  134. * This event type is raised when a pointer change coordinates or when a pointer changes button state, pressure, tilt, or contact geometry and the circumstances produce no other pointers events.
  135. * Bubbles: yes
  136. */
  137. get: function () {
  138. return PrimitivePointerInfo._pointerMove;
  139. },
  140. enumerable: true,
  141. configurable: true
  142. });
  143. Object.defineProperty(PrimitivePointerInfo, "PointerUp", {
  144. /**
  145. * This event type is raised when the pointer leaves the active buttons states (zero value in the buttons property). For mouse, this is when the device transitions from at least one button depressed to no buttons depressed. For touch/pen, this is when physical contact is removed.
  146. * Bubbles: yes
  147. */
  148. get: function () {
  149. return PrimitivePointerInfo._pointerUp;
  150. },
  151. enumerable: true,
  152. configurable: true
  153. });
  154. Object.defineProperty(PrimitivePointerInfo, "PointerOut", {
  155. /**
  156. * This event type is raised when a pointing device is moved out of the hit test the boundaries of a primitive.
  157. * Bubbles: yes
  158. */
  159. get: function () {
  160. return PrimitivePointerInfo._pointerOut;
  161. },
  162. enumerable: true,
  163. configurable: true
  164. });
  165. Object.defineProperty(PrimitivePointerInfo, "PointerLeave", {
  166. /**
  167. * This event type is raised when a pointing device is moved out of the hit test boundaries of a primitive and all its descendants.
  168. * Bubbles: no
  169. */
  170. get: function () {
  171. return PrimitivePointerInfo._pointerLeave;
  172. },
  173. enumerable: true,
  174. configurable: true
  175. });
  176. Object.defineProperty(PrimitivePointerInfo, "PointerGotCapture", {
  177. /**
  178. * This event type is raised when a primitive receives the pointer capture. This event is fired at the element that is receiving pointer capture. Subsequent events for that pointer will be fired at this element.
  179. * Bubbles: yes
  180. */
  181. get: function () {
  182. return PrimitivePointerInfo._pointerGotCapture;
  183. },
  184. enumerable: true,
  185. configurable: true
  186. });
  187. Object.defineProperty(PrimitivePointerInfo, "PointerLostCapture", {
  188. /**
  189. * This event type is raised after pointer capture is released for a pointer.
  190. * Bubbles: yes
  191. */
  192. get: function () {
  193. return PrimitivePointerInfo._pointerLostCapture;
  194. },
  195. enumerable: true,
  196. configurable: true
  197. });
  198. Object.defineProperty(PrimitivePointerInfo, "MouseWheelPrecision", {
  199. get: function () {
  200. return PrimitivePointerInfo._mouseWheelPrecision;
  201. },
  202. enumerable: true,
  203. configurable: true
  204. });
  205. PrimitivePointerInfo.prototype.updateRelatedTarget = function (prim, primPointerPos) {
  206. this.relatedTarget = prim;
  207. this.relatedTargetPointerPos = primPointerPos;
  208. };
  209. PrimitivePointerInfo.getEventTypeName = function (mask) {
  210. switch (mask) {
  211. case PrimitivePointerInfo.PointerOver: return "PointerOver";
  212. case PrimitivePointerInfo.PointerEnter: return "PointerEnter";
  213. case PrimitivePointerInfo.PointerDown: return "PointerDown";
  214. case PrimitivePointerInfo.PointerMouseWheel: return "PointerMouseWheel";
  215. case PrimitivePointerInfo.PointerMove: return "PointerMove";
  216. case PrimitivePointerInfo.PointerUp: return "PointerUp";
  217. case PrimitivePointerInfo.PointerOut: return "PointerOut";
  218. case PrimitivePointerInfo.PointerLeave: return "PointerLeave";
  219. case PrimitivePointerInfo.PointerGotCapture: return "PointerGotCapture";
  220. case PrimitivePointerInfo.PointerLostCapture: return "PointerLostCapture";
  221. }
  222. };
  223. PrimitivePointerInfo._pointerOver = 0x0001;
  224. PrimitivePointerInfo._pointerEnter = 0x0002;
  225. PrimitivePointerInfo._pointerDown = 0x0004;
  226. PrimitivePointerInfo._pointerMouseWheel = 0x0008;
  227. PrimitivePointerInfo._pointerMove = 0x0010;
  228. PrimitivePointerInfo._pointerUp = 0x0020;
  229. PrimitivePointerInfo._pointerOut = 0x0040;
  230. PrimitivePointerInfo._pointerLeave = 0x0080;
  231. PrimitivePointerInfo._pointerGotCapture = 0x0100;
  232. PrimitivePointerInfo._pointerLostCapture = 0x0200;
  233. PrimitivePointerInfo._mouseWheelPrecision = 3.0;
  234. return PrimitivePointerInfo;
  235. }());
  236. BABYLON.PrimitivePointerInfo = PrimitivePointerInfo;
  237. /**
  238. * Stores information about a Primitive that was intersected
  239. */
  240. var PrimitiveIntersectedInfo = (function () {
  241. function PrimitiveIntersectedInfo(prim, intersectionLocation) {
  242. this.prim = prim;
  243. this.intersectionLocation = intersectionLocation;
  244. }
  245. return PrimitiveIntersectedInfo;
  246. }());
  247. BABYLON.PrimitiveIntersectedInfo = PrimitiveIntersectedInfo;
  248. var PrimitiveMargin = (function () {
  249. function PrimitiveMargin(owner) {
  250. this._owner = owner;
  251. this._left = this._top = this._bottom = this.right = 0;
  252. }
  253. Object.defineProperty(PrimitiveMargin.prototype, "top", {
  254. get: function () {
  255. return this._top;
  256. },
  257. set: function (value) {
  258. if (value === this._top) {
  259. return;
  260. }
  261. this._top = value;
  262. this._owner._marginChanged();
  263. },
  264. enumerable: true,
  265. configurable: true
  266. });
  267. Object.defineProperty(PrimitiveMargin.prototype, "left", {
  268. get: function () {
  269. return this._left;
  270. },
  271. set: function (value) {
  272. if (value === this._left) {
  273. return;
  274. }
  275. this._left = value;
  276. this._owner._marginChanged();
  277. },
  278. enumerable: true,
  279. configurable: true
  280. });
  281. Object.defineProperty(PrimitiveMargin.prototype, "right", {
  282. get: function () {
  283. return this._right;
  284. },
  285. set: function (value) {
  286. if (value === this._right) {
  287. return;
  288. }
  289. this._right = value;
  290. this._owner._marginChanged();
  291. },
  292. enumerable: true,
  293. configurable: true
  294. });
  295. Object.defineProperty(PrimitiveMargin.prototype, "bottom", {
  296. get: function () {
  297. return this._bottom;
  298. },
  299. set: function (value) {
  300. if (value === this._bottom) {
  301. return;
  302. }
  303. this._bottom = value;
  304. this._owner._marginChanged();
  305. },
  306. enumerable: true,
  307. configurable: true
  308. });
  309. PrimitiveMargin.Zero = function (owner) {
  310. return new PrimitiveMargin(owner);
  311. };
  312. return PrimitiveMargin;
  313. }());
  314. BABYLON.PrimitiveMargin = PrimitiveMargin;
  315. /**
  316. * Main class used for the Primitive Intersection API
  317. */
  318. var IntersectInfo2D = (function () {
  319. function IntersectInfo2D() {
  320. this.findFirstOnly = false;
  321. this.intersectHidden = false;
  322. this.pickPosition = BABYLON.Vector2.Zero();
  323. }
  324. Object.defineProperty(IntersectInfo2D.prototype, "isIntersected", {
  325. /**
  326. * true if at least one primitive intersected during the test
  327. */
  328. get: function () {
  329. return this.intersectedPrimitives && this.intersectedPrimitives.length > 0;
  330. },
  331. enumerable: true,
  332. configurable: true
  333. });
  334. IntersectInfo2D.prototype.isPrimIntersected = function (prim) {
  335. for (var _i = 0, _a = this.intersectedPrimitives; _i < _a.length; _i++) {
  336. var cur = _a[_i];
  337. if (cur.prim === prim) {
  338. return cur.intersectionLocation;
  339. }
  340. }
  341. return null;
  342. };
  343. // Internals, don't use
  344. IntersectInfo2D.prototype._exit = function (firstLevel) {
  345. if (firstLevel) {
  346. this._globalPickPosition = null;
  347. }
  348. };
  349. return IntersectInfo2D;
  350. }());
  351. BABYLON.IntersectInfo2D = IntersectInfo2D;
  352. var Prim2DBase = (function (_super) {
  353. __extends(Prim2DBase, _super);
  354. function Prim2DBase() {
  355. _super.apply(this, arguments);
  356. }
  357. Object.defineProperty(Prim2DBase, "HAlignLeft", {
  358. get: function () { return Prim2DBase._hAlignLeft; },
  359. enumerable: true,
  360. configurable: true
  361. });
  362. Object.defineProperty(Prim2DBase, "HAlignCenter", {
  363. get: function () { return Prim2DBase._hAlignCenter; },
  364. enumerable: true,
  365. configurable: true
  366. });
  367. Object.defineProperty(Prim2DBase, "HAlignRight", {
  368. get: function () { return Prim2DBase._hAlignRight; },
  369. enumerable: true,
  370. configurable: true
  371. });
  372. Object.defineProperty(Prim2DBase, "HAlignStretch", {
  373. get: function () { return Prim2DBase._hAlignStretch; },
  374. enumerable: true,
  375. configurable: true
  376. });
  377. Object.defineProperty(Prim2DBase, "VAlignTop", {
  378. get: function () { return Prim2DBase._vAlignTop; },
  379. enumerable: true,
  380. configurable: true
  381. });
  382. Object.defineProperty(Prim2DBase, "VAlignCenter", {
  383. get: function () { return Prim2DBase._vAlignCenter; },
  384. enumerable: true,
  385. configurable: true
  386. });
  387. Object.defineProperty(Prim2DBase, "VAlignBottom", {
  388. get: function () { return Prim2DBase._vAlignBottom; },
  389. enumerable: true,
  390. configurable: true
  391. });
  392. Object.defineProperty(Prim2DBase, "VAlignStretch", {
  393. get: function () { return Prim2DBase._vAlignStretch; },
  394. enumerable: true,
  395. configurable: true
  396. });
  397. Prim2DBase.prototype.setupPrim2DBase = function (owner, parent, id, position, origin, isVisible, marginTop, marginLeft, marginRight, marginBottom, vAlignment, hAlignment) {
  398. if (!(this instanceof BABYLON.Group2D) && !(this instanceof BABYLON.Sprite2D && id !== null && id.indexOf("__cachedSpriteOfGroup__") === 0) && (owner.cachingStrategy === BABYLON.Canvas2D.CACHESTRATEGY_TOPLEVELGROUPS) && (parent === owner)) {
  399. throw new Error("Can't create a primitive with the canvas as direct parent when the caching strategy is TOPLEVELGROUPS. You need to create a Group below the canvas and use it as the parent for the primitive");
  400. }
  401. var m = null;
  402. if (marginTop || marginLeft || marginRight || marginBottom) {
  403. m = new PrimitiveMargin(this);
  404. m.top = marginTop || 0;
  405. m.left = marginLeft || 0;
  406. m.right = marginRight || 0;
  407. m.bottom = marginBottom || 0;
  408. }
  409. this.setupSmartPropertyPrim();
  410. this._pointerEventObservable = new BABYLON.Observable();
  411. this._isPickable = true;
  412. this._siblingDepthOffset = this._hierarchyDepthOffset = 0;
  413. this._boundingInfoDirty = true;
  414. this._boundingInfo = new BABYLON.BoundingInfo2D();
  415. this._owner = owner;
  416. this._parent = parent;
  417. this._id = id;
  418. if (parent != null) {
  419. this._hierarchyDepth = parent._hierarchyDepth + 1;
  420. this._renderGroup = this.parent.traverseUp(function (p) { return p instanceof BABYLON.Group2D && p.isRenderableGroup; });
  421. parent.addChild(this);
  422. }
  423. else {
  424. this._hierarchyDepth = 0;
  425. this._renderGroup = null;
  426. }
  427. this.propertyChanged = new BABYLON.Observable();
  428. this._children = new Array();
  429. this._globalTransformProcessStep = 0;
  430. this._globalTransformStep = 0;
  431. if (this instanceof BABYLON.Group2D) {
  432. var group = this;
  433. group.detectGroupStates();
  434. }
  435. this.position = position;
  436. this.rotation = 0;
  437. this.scale = 1;
  438. this.levelVisible = isVisible;
  439. this.origin = origin || new BABYLON.Vector2(0.5, 0.5);
  440. this.margin = m;
  441. this.hAlignment = hAlignment;
  442. this.vAlignment = vAlignment;
  443. };
  444. Object.defineProperty(Prim2DBase.prototype, "actionManager", {
  445. get: function () {
  446. if (!this._actionManager) {
  447. this._actionManager = new BABYLON.ActionManager(this.owner.scene);
  448. }
  449. return this._actionManager;
  450. },
  451. enumerable: true,
  452. configurable: true
  453. });
  454. /**
  455. * From 'this' primitive, traverse up (from parent to parent) until the given predicate is true
  456. * @param predicate the predicate to test on each parent
  457. * @return the first primitive where the predicate was successful
  458. */
  459. Prim2DBase.prototype.traverseUp = function (predicate) {
  460. var p = this;
  461. while (p != null) {
  462. if (predicate(p)) {
  463. return p;
  464. }
  465. p = p._parent;
  466. }
  467. return null;
  468. };
  469. Object.defineProperty(Prim2DBase.prototype, "owner", {
  470. /**
  471. * Retrieve the owner Canvas2D
  472. */
  473. get: function () {
  474. return this._owner;
  475. },
  476. enumerable: true,
  477. configurable: true
  478. });
  479. Object.defineProperty(Prim2DBase.prototype, "parent", {
  480. /**
  481. * Get the parent primitive (can be the Canvas, only the Canvas has no parent)
  482. */
  483. get: function () {
  484. return this._parent;
  485. },
  486. enumerable: true,
  487. configurable: true
  488. });
  489. Object.defineProperty(Prim2DBase.prototype, "children", {
  490. /**
  491. * The array of direct children primitives
  492. */
  493. get: function () {
  494. return this._children;
  495. },
  496. enumerable: true,
  497. configurable: true
  498. });
  499. Object.defineProperty(Prim2DBase.prototype, "id", {
  500. /**
  501. * The identifier of this primitive, may not be unique, it's for information purpose only
  502. */
  503. get: function () {
  504. return this._id;
  505. },
  506. enumerable: true,
  507. configurable: true
  508. });
  509. Object.defineProperty(Prim2DBase.prototype, "position", {
  510. get: function () {
  511. return this._position;
  512. },
  513. set: function (value) {
  514. this._position = value;
  515. },
  516. enumerable: true,
  517. configurable: true
  518. });
  519. Object.defineProperty(Prim2DBase.prototype, "rotation", {
  520. get: function () {
  521. return this._rotation;
  522. },
  523. set: function (value) {
  524. this._rotation = value;
  525. },
  526. enumerable: true,
  527. configurable: true
  528. });
  529. Object.defineProperty(Prim2DBase.prototype, "scale", {
  530. get: function () {
  531. return this._scale;
  532. },
  533. set: function (value) {
  534. this._scale = value;
  535. },
  536. enumerable: true,
  537. configurable: true
  538. });
  539. Object.defineProperty(Prim2DBase.prototype, "actualSize", {
  540. /**
  541. * this method must be implemented by the primitive type to return its size
  542. * @returns The size of the primitive
  543. */
  544. get: function () {
  545. return undefined;
  546. },
  547. enumerable: true,
  548. configurable: true
  549. });
  550. Object.defineProperty(Prim2DBase.prototype, "origin", {
  551. /**
  552. * The origin defines the normalized coordinate of the center of the primitive, from the top/left corner.
  553. * The origin is used only to compute transformation of the primitive, it has no meaning in the primitive local frame of reference
  554. * For instance:
  555. * 0,0 means the center is bottom/left. Which is the default for Canvas2D instances
  556. * 0.5,0.5 means the center is at the center of the primitive, which is default of all types of Primitives
  557. * 0,1 means the center is top/left
  558. * @returns The normalized center.
  559. */
  560. get: function () {
  561. return this._origin;
  562. },
  563. set: function (value) {
  564. this._origin = value;
  565. },
  566. enumerable: true,
  567. configurable: true
  568. });
  569. Object.defineProperty(Prim2DBase.prototype, "levelVisible", {
  570. get: function () {
  571. return this._levelVisible;
  572. },
  573. set: function (value) {
  574. this._levelVisible = value;
  575. },
  576. enumerable: true,
  577. configurable: true
  578. });
  579. Object.defineProperty(Prim2DBase.prototype, "isVisible", {
  580. get: function () {
  581. return this._isVisible;
  582. },
  583. set: function (value) {
  584. this._isVisible = value;
  585. },
  586. enumerable: true,
  587. configurable: true
  588. });
  589. Object.defineProperty(Prim2DBase.prototype, "zOrder", {
  590. get: function () {
  591. return this._zOrder;
  592. },
  593. set: function (value) {
  594. this._zOrder = value;
  595. this.onZOrderChanged();
  596. },
  597. enumerable: true,
  598. configurable: true
  599. });
  600. Object.defineProperty(Prim2DBase.prototype, "margin", {
  601. get: function () {
  602. if (!this._margin) {
  603. this._margin = new PrimitiveMargin(this);
  604. }
  605. return this._margin;
  606. },
  607. set: function (value) {
  608. this._margin = value;
  609. },
  610. enumerable: true,
  611. configurable: true
  612. });
  613. Object.defineProperty(Prim2DBase.prototype, "hAlignment", {
  614. get: function () {
  615. return this._hAlignment;
  616. },
  617. set: function (value) {
  618. this._hAlignment = value;
  619. },
  620. enumerable: true,
  621. configurable: true
  622. });
  623. Object.defineProperty(Prim2DBase.prototype, "vAlignment", {
  624. get: function () {
  625. return this._vAlignment;
  626. },
  627. set: function (value) {
  628. this._vAlignment = value;
  629. },
  630. enumerable: true,
  631. configurable: true
  632. });
  633. Object.defineProperty(Prim2DBase.prototype, "isPickable", {
  634. /**
  635. * Define if the Primitive can be subject to intersection test or not (default is true)
  636. */
  637. get: function () {
  638. return this._isPickable;
  639. },
  640. set: function (value) {
  641. this._isPickable = value;
  642. },
  643. enumerable: true,
  644. configurable: true
  645. });
  646. Object.defineProperty(Prim2DBase.prototype, "hierarchyDepth", {
  647. /**
  648. * Return the depth level of the Primitive into the Canvas' Graph. A Canvas will be 0, its direct children 1, and so on.
  649. * @returns {}
  650. */
  651. get: function () {
  652. return this._hierarchyDepth;
  653. },
  654. enumerable: true,
  655. configurable: true
  656. });
  657. Object.defineProperty(Prim2DBase.prototype, "renderGroup", {
  658. /**
  659. * Retrieve the Group that is responsible to render this primitive
  660. * @returns {}
  661. */
  662. get: function () {
  663. return this._renderGroup;
  664. },
  665. enumerable: true,
  666. configurable: true
  667. });
  668. Object.defineProperty(Prim2DBase.prototype, "globalTransform", {
  669. /**
  670. * Get the global transformation matrix of the primitive
  671. */
  672. get: function () {
  673. return this._globalTransform;
  674. },
  675. enumerable: true,
  676. configurable: true
  677. });
  678. Object.defineProperty(Prim2DBase.prototype, "invGlobalTransform", {
  679. /**
  680. * Get invert of the global transformation matrix of the primitive
  681. * @returns {}
  682. */
  683. get: function () {
  684. return this._invGlobalTransform;
  685. },
  686. enumerable: true,
  687. configurable: true
  688. });
  689. Object.defineProperty(Prim2DBase.prototype, "localTransform", {
  690. /**
  691. * Get the local transformation of the primitive
  692. */
  693. get: function () {
  694. this._updateLocalTransform();
  695. return this._localTransform;
  696. },
  697. enumerable: true,
  698. configurable: true
  699. });
  700. Object.defineProperty(Prim2DBase.prototype, "boundingInfo", {
  701. /**
  702. * Get the boundingInfo associated to the primitive and its children.
  703. * The value is supposed to be always up to date
  704. */
  705. get: function () {
  706. if (this._boundingInfoDirty) {
  707. this._boundingInfo = this.levelBoundingInfo.clone();
  708. var bi = this._boundingInfo;
  709. var tps = new BABYLON.BoundingInfo2D();
  710. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  711. var curChild = _a[_i];
  712. curChild.boundingInfo.transformToRef(curChild.localTransform, tps);
  713. bi.unionToRef(tps, bi);
  714. }
  715. this._boundingInfoDirty = false;
  716. }
  717. return this._boundingInfo;
  718. },
  719. enumerable: true,
  720. configurable: true
  721. });
  722. Object.defineProperty(Prim2DBase.prototype, "pointerEventObservable", {
  723. /**
  724. * Interaction with the primitive can be create using this Observable. See the PrimitivePointerInfo class for more information
  725. */
  726. get: function () {
  727. return this._pointerEventObservable;
  728. },
  729. enumerable: true,
  730. configurable: true
  731. });
  732. Prim2DBase.prototype.onZOrderChanged = function () {
  733. };
  734. Prim2DBase.prototype.levelIntersect = function (intersectInfo) {
  735. return false;
  736. };
  737. /**
  738. * Capture all the Events of the given PointerId for this primitive.
  739. * Don't forget to call releasePointerEventsCapture when done.
  740. * @param pointerId the Id of the pointer to capture the events from.
  741. */
  742. Prim2DBase.prototype.setPointerEventCapture = function (pointerId) {
  743. return this.owner._setPointerCapture(pointerId, this);
  744. };
  745. /**
  746. * Release a captured pointer made with setPointerEventCapture.
  747. * @param pointerId the Id of the pointer to release the capture from.
  748. */
  749. Prim2DBase.prototype.releasePointerEventsCapture = function (pointerId) {
  750. return this.owner._releasePointerCapture(pointerId, this);
  751. };
  752. /**
  753. * Make an intersection test with the primitive, all inputs/outputs are stored in the IntersectInfo2D class, see its documentation for more information.
  754. * @param intersectInfo contains the settings of the intersection to perform, to setup before calling this method as well as the result, available after a call to this method.
  755. */
  756. Prim2DBase.prototype.intersect = function (intersectInfo) {
  757. if (!intersectInfo) {
  758. return false;
  759. }
  760. // If this is null it means this method is call for the first level, initialize stuffs
  761. var firstLevel = !intersectInfo._globalPickPosition;
  762. if (firstLevel) {
  763. // Compute the pickPosition in global space and use it to find the local position for each level down, always relative from the world to get the maximum accuracy (and speed). The other way would have been to compute in local every level down relative to its parent's local, which wouldn't be as accurate (even if javascript number is 80bits accurate).
  764. intersectInfo._globalPickPosition = BABYLON.Vector2.Zero();
  765. BABYLON.Vector2.TransformToRef(intersectInfo.pickPosition, this.globalTransform, intersectInfo._globalPickPosition);
  766. intersectInfo._localPickPosition = intersectInfo.pickPosition.clone();
  767. intersectInfo.intersectedPrimitives = new Array();
  768. intersectInfo.topMostIntersectedPrimitive = null;
  769. }
  770. if (!intersectInfo.intersectHidden && !this.isVisible) {
  771. return false;
  772. }
  773. // Fast rejection test with boundingInfo
  774. if (this.isPickable && !this.boundingInfo.doesIntersect(intersectInfo._localPickPosition)) {
  775. // Important to call this before each return to allow a good recursion next time this intersectInfo is reused
  776. intersectInfo._exit(firstLevel);
  777. return false;
  778. }
  779. // We hit the boundingInfo that bounds this primitive and its children, now we have to test on the primitive of this level
  780. var levelIntersectRes = false;
  781. if (this.isPickable) {
  782. levelIntersectRes = this.levelIntersect(intersectInfo);
  783. if (levelIntersectRes) {
  784. var pii = new PrimitiveIntersectedInfo(this, intersectInfo._localPickPosition.clone());
  785. intersectInfo.intersectedPrimitives.push(pii);
  786. if (!intersectInfo.topMostIntersectedPrimitive || (intersectInfo.topMostIntersectedPrimitive.prim.getActualZOffset() > pii.prim.getActualZOffset())) {
  787. intersectInfo.topMostIntersectedPrimitive = pii;
  788. }
  789. // If we must stop at the first intersection, we're done, quit!
  790. if (intersectInfo.findFirstOnly) {
  791. intersectInfo._exit(firstLevel);
  792. return true;
  793. }
  794. }
  795. }
  796. // Recurse to children if needed
  797. if (!levelIntersectRes || !intersectInfo.findFirstOnly) {
  798. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  799. var curChild = _a[_i];
  800. // Don't test primitive not pick able or if it's hidden and we don't test hidden ones
  801. if (!curChild.isPickable || (!intersectInfo.intersectHidden && !curChild.isVisible)) {
  802. continue;
  803. }
  804. // Must compute the localPickLocation for the children level
  805. BABYLON.Vector2.TransformToRef(intersectInfo._globalPickPosition, curChild.invGlobalTransform, intersectInfo._localPickPosition);
  806. // If we got an intersection with the child and we only need to find the first one, quit!
  807. if (curChild.intersect(intersectInfo) && intersectInfo.findFirstOnly) {
  808. intersectInfo._exit(firstLevel);
  809. return true;
  810. }
  811. }
  812. }
  813. intersectInfo._exit(firstLevel);
  814. return intersectInfo.isIntersected;
  815. };
  816. Prim2DBase.prototype.moveChild = function (child, previous) {
  817. if (child.parent !== this) {
  818. return false;
  819. }
  820. var prevOffset, nextOffset;
  821. var childIndex = this._children.indexOf(child);
  822. var prevIndex = previous ? this._children.indexOf(previous) : -1;
  823. // Move to first position
  824. if (!previous) {
  825. prevOffset = 1;
  826. nextOffset = this._children[1]._siblingDepthOffset;
  827. }
  828. else {
  829. prevOffset = this._children[prevIndex]._siblingDepthOffset;
  830. nextOffset = this._children[prevIndex + 1]._siblingDepthOffset;
  831. }
  832. child._siblingDepthOffset = (nextOffset - prevOffset) / 2;
  833. this._children.splice(prevIndex + 1, 0, this._children.splice(childIndex, 1)[0]);
  834. };
  835. Prim2DBase.prototype.addChild = function (child) {
  836. child._hierarchyDepthOffset = this._hierarchyDepthOffset + ((this._children.length + 1) * this._siblingDepthOffset);
  837. // console.log(`Node: ${child.id} has depth: ${child._hierarchyDepthOffset}`);
  838. child._siblingDepthOffset = this._siblingDepthOffset / this.owner.hierarchyLevelMaxSiblingCount;
  839. this._children.push(child);
  840. };
  841. Prim2DBase.prototype.dispose = function () {
  842. if (!_super.prototype.dispose.call(this)) {
  843. return false;
  844. }
  845. if (this._actionManager) {
  846. this._actionManager.dispose();
  847. this._actionManager = null;
  848. }
  849. // If there's a parent, remove this object from its parent list
  850. if (this._parent) {
  851. var i = this._parent._children.indexOf(this);
  852. if (i !== undefined) {
  853. this._parent._children.splice(i, 1);
  854. }
  855. this._parent = null;
  856. }
  857. // Recurse dispose to children
  858. if (this._children) {
  859. while (this._children.length > 0) {
  860. this._children[this._children.length - 1].dispose();
  861. }
  862. }
  863. return true;
  864. };
  865. Prim2DBase.prototype.getActualZOffset = function () {
  866. return this._zOrder || (1 - this._hierarchyDepthOffset);
  867. };
  868. Prim2DBase.prototype.onPrimBecomesDirty = function () {
  869. if (this._renderGroup) {
  870. this._renderGroup._addPrimToDirtyList(this);
  871. }
  872. };
  873. Prim2DBase.prototype._marginChanged = function () {
  874. };
  875. Prim2DBase.prototype._needPrepare = function () {
  876. return this._visibilityChanged || this._modelDirty || (this._instanceDirtyFlags !== 0) || (this._globalTransformProcessStep !== this._globalTransformStep);
  877. };
  878. Prim2DBase.prototype._prepareRender = function (context) {
  879. this._prepareRenderPre(context);
  880. this._prepareRenderPost(context);
  881. };
  882. Prim2DBase.prototype._prepareRenderPre = function (context) {
  883. };
  884. Prim2DBase.prototype._prepareRenderPost = function (context) {
  885. // Don't recurse if it's a renderable group, the content will be processed by the group itself
  886. if (this instanceof BABYLON.Group2D) {
  887. var self = this;
  888. if (self.isRenderableGroup) {
  889. return;
  890. }
  891. }
  892. // Check if we need to recurse the prepare to children primitives
  893. // - must have children
  894. // - the global transform of this level have changed, or
  895. // - the visible state of primitive has changed
  896. if (this._children.length > 0 && ((this._globalTransformProcessStep !== this._globalTransformStep) ||
  897. this.checkPropertiesDirty(Prim2DBase.isVisibleProperty.flagId))) {
  898. this._children.forEach(function (c) {
  899. // As usual stop the recursion if we meet a renderable group
  900. if (!(c instanceof BABYLON.Group2D && c.isRenderableGroup)) {
  901. c._prepareRender(context);
  902. }
  903. });
  904. }
  905. // Finally reset the dirty flags as we've processed everything
  906. this._modelDirty = false;
  907. this._instanceDirtyFlags = 0;
  908. };
  909. Prim2DBase.CheckParent = function (parent) {
  910. if (!parent) {
  911. throw new Error("A Primitive needs a valid Parent, it can be any kind of Primitives based types, even the Canvas (with the exception that only Group2D can be direct child of a Canvas if the cache strategy used is TOPLEVELGROUPS)");
  912. }
  913. };
  914. Prim2DBase.prototype.updateGlobalTransVisOf = function (list, recurse) {
  915. for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
  916. var cur = list_1[_i];
  917. cur.updateGlobalTransVis(recurse);
  918. }
  919. };
  920. Prim2DBase.prototype._updateLocalTransform = function () {
  921. var tflags = Prim2DBase.positionProperty.flagId | Prim2DBase.rotationProperty.flagId | Prim2DBase.scaleProperty.flagId;
  922. if (this.checkPropertiesDirty(tflags)) {
  923. var rot = BABYLON.Quaternion.RotationAxis(new BABYLON.Vector3(0, 0, 1), this._rotation);
  924. var local = BABYLON.Matrix.Compose(new BABYLON.Vector3(this._scale, this._scale, this._scale), rot, new BABYLON.Vector3(this._position.x, this._position.y, 0));
  925. this._localTransform = local;
  926. this.clearPropertiesDirty(tflags);
  927. // this is important to access actualSize AFTER fetching a first version of the local transform and reset the dirty flag, because accessing actualSize on a Group2D which actualSize is built from its content will trigger a call to this very method on this very object. We won't mind about the origin offset not being computed, as long as we return a local transform based on the position/rotation/scale
  928. //var actualSize = this.actualSize;
  929. //if (!actualSize) {
  930. // throw new Error(`The primitive type: ${Tools.getClassName(this)} must implement the actualSize get property!`);
  931. //}
  932. //local.m[12] -= (actualSize.width * this.origin.x) * local.m[0] + (actualSize.height * this.origin.y) * local.m[4];
  933. //local.m[13] -= (actualSize.width * this.origin.x) * local.m[1] + (actualSize.height * this.origin.y) * local.m[5];
  934. return true;
  935. }
  936. return false;
  937. };
  938. Prim2DBase.prototype.updateGlobalTransVis = function (recurse) {
  939. if (this.isDisposed) {
  940. return;
  941. }
  942. // Check if the parent is synced
  943. if (this._parent && this._parent._globalTransformProcessStep !== this.owner._globalTransformProcessStep) {
  944. this._parent.updateGlobalTransVis(false);
  945. }
  946. // Check if we must update this prim
  947. if (this === this.owner || this._globalTransformProcessStep !== this.owner._globalTransformProcessStep) {
  948. var curVisibleState = this.isVisible;
  949. this.isVisible = (!this._parent || this._parent.isVisible) && this.levelVisible;
  950. // Detect a change of visibility
  951. this._visibilityChanged = curVisibleState !== this.isVisible;
  952. // Get/compute the localTransform
  953. var localDirty = this._updateLocalTransform();
  954. // Check if we have to update the globalTransform
  955. if (!this._globalTransform || localDirty || (this._parent && this._parent._globalTransformStep !== this._parentTransformStep)) {
  956. this._globalTransform = this._parent ? this._localTransform.multiply(this._parent._globalTransform) : this._localTransform;
  957. this._invGlobalTransform = BABYLON.Matrix.Invert(this._globalTransform);
  958. this._globalTransformStep = this.owner._globalTransformProcessStep + 1;
  959. this._parentTransformStep = this._parent ? this._parent._globalTransformStep : 0;
  960. }
  961. this._globalTransformProcessStep = this.owner._globalTransformProcessStep;
  962. }
  963. if (recurse) {
  964. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  965. var child = _a[_i];
  966. // Stop the recursion if we meet a renderable group
  967. child.updateGlobalTransVis(!(child instanceof BABYLON.Group2D && child.isRenderableGroup));
  968. }
  969. }
  970. };
  971. Prim2DBase.PRIM2DBASE_PROPCOUNT = 12;
  972. Prim2DBase._hAlignLeft = 1;
  973. Prim2DBase._hAlignCenter = 2;
  974. Prim2DBase._hAlignRight = 3;
  975. Prim2DBase._hAlignStretch = 4;
  976. Prim2DBase._vAlignTop = 1;
  977. Prim2DBase._vAlignCenter = 2;
  978. Prim2DBase._vAlignBottom = 3;
  979. Prim2DBase._vAlignStretch = 4;
  980. __decorate([
  981. BABYLON.instanceLevelProperty(1, function (pi) { return Prim2DBase.positionProperty = pi; }, false, true)
  982. ], Prim2DBase.prototype, "position", null);
  983. __decorate([
  984. BABYLON.instanceLevelProperty(2, function (pi) { return Prim2DBase.rotationProperty = pi; }, false, true)
  985. ], Prim2DBase.prototype, "rotation", null);
  986. __decorate([
  987. BABYLON.instanceLevelProperty(3, function (pi) { return Prim2DBase.scaleProperty = pi; }, false, true)
  988. ], Prim2DBase.prototype, "scale", null);
  989. __decorate([
  990. BABYLON.instanceLevelProperty(4, function (pi) { return Prim2DBase.originProperty = pi; }, false, true)
  991. ], Prim2DBase.prototype, "origin", null);
  992. __decorate([
  993. BABYLON.dynamicLevelProperty(5, function (pi) { return Prim2DBase.levelVisibleProperty = pi; })
  994. ], Prim2DBase.prototype, "levelVisible", null);
  995. __decorate([
  996. BABYLON.instanceLevelProperty(6, function (pi) { return Prim2DBase.isVisibleProperty = pi; })
  997. ], Prim2DBase.prototype, "isVisible", null);
  998. __decorate([
  999. BABYLON.instanceLevelProperty(7, function (pi) { return Prim2DBase.zOrderProperty = pi; })
  1000. ], Prim2DBase.prototype, "zOrder", null);
  1001. __decorate([
  1002. BABYLON.dynamicLevelProperty(8, function (pi) { return Prim2DBase.marginProperty = pi; })
  1003. ], Prim2DBase.prototype, "margin", null);
  1004. __decorate([
  1005. BABYLON.dynamicLevelProperty(9, function (pi) { return Prim2DBase.hAlignmentProperty = pi; })
  1006. ], Prim2DBase.prototype, "hAlignment", null);
  1007. __decorate([
  1008. BABYLON.dynamicLevelProperty(10, function (pi) { return Prim2DBase.vAlignmentProperty = pi; })
  1009. ], Prim2DBase.prototype, "vAlignment", null);
  1010. Prim2DBase = __decorate([
  1011. BABYLON.className("Prim2DBase")
  1012. ], Prim2DBase);
  1013. return Prim2DBase;
  1014. }(BABYLON.SmartPropertyPrim));
  1015. BABYLON.Prim2DBase = Prim2DBase;
  1016. })(BABYLON || (BABYLON = {}));