particle-container.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /*!
  2. * @pixi/particle-container - v6.5.10
  3. * Compiled Thu, 06 Jul 2023 15:25:11 UTC
  4. *
  5. * @pixi/particle-container is licensed under the MIT License.
  6. * http://www.opensource.org/licenses/mit-license
  7. */
  8. 'use strict';
  9. Object.defineProperty(exports, '__esModule', { value: true });
  10. var constants = require('@pixi/constants');
  11. var display = require('@pixi/display');
  12. var utils = require('@pixi/utils');
  13. var core = require('@pixi/core');
  14. var math = require('@pixi/math');
  15. /*! *****************************************************************************
  16. Copyright (c) Microsoft Corporation.
  17. Permission to use, copy, modify, and/or distribute this software for any
  18. purpose with or without fee is hereby granted.
  19. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  20. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  21. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  22. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  23. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  24. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  25. PERFORMANCE OF THIS SOFTWARE.
  26. ***************************************************************************** */
  27. /* global Reflect, Promise */
  28. var extendStatics = function(d, b) {
  29. extendStatics = Object.setPrototypeOf ||
  30. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  31. function (d, b) { for (var p in b) { if (b.hasOwnProperty(p)) { d[p] = b[p]; } } };
  32. return extendStatics(d, b);
  33. };
  34. function __extends(d, b) {
  35. extendStatics(d, b);
  36. function __() { this.constructor = d; }
  37. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  38. }
  39. /**
  40. * The ParticleContainer class is a really fast version of the Container built solely for speed,
  41. * so use when you need a lot of sprites or particles.
  42. *
  43. * The tradeoff of the ParticleContainer is that most advanced functionality will not work.
  44. * ParticleContainer implements the basic object transform (position, scale, rotation)
  45. * and some advanced functionality like tint (as of v4.5.6).
  46. *
  47. * Other more advanced functionality like masking, children, filters, etc will not work on sprites in this batch.
  48. *
  49. * It's extremely easy to use:
  50. * ```js
  51. * let container = new ParticleContainer();
  52. *
  53. * for (let i = 0; i < 100; ++i)
  54. * {
  55. * let sprite = PIXI.Sprite.from("myImage.png");
  56. * container.addChild(sprite);
  57. * }
  58. * ```
  59. *
  60. * And here you have a hundred sprites that will be rendered at the speed of light.
  61. * @memberof PIXI
  62. */
  63. var ParticleContainer = /** @class */ (function (_super) {
  64. __extends(ParticleContainer, _super);
  65. /**
  66. * @param maxSize - The maximum number of particles that can be rendered by the container.
  67. * Affects size of allocated buffers.
  68. * @param properties - The properties of children that should be uploaded to the gpu and applied.
  69. * @param {boolean} [properties.vertices=false] - When true, vertices be uploaded and applied.
  70. * if sprite's ` scale/anchor/trim/frame/orig` is dynamic, please set `true`.
  71. * @param {boolean} [properties.position=true] - When true, position be uploaded and applied.
  72. * @param {boolean} [properties.rotation=false] - When true, rotation be uploaded and applied.
  73. * @param {boolean} [properties.uvs=false] - When true, uvs be uploaded and applied.
  74. * @param {boolean} [properties.tint=false] - When true, alpha and tint be uploaded and applied.
  75. * @param {number} [batchSize=16384] - Number of particles per batch. If less than maxSize, it uses maxSize instead.
  76. * @param {boolean} [autoResize=false] - If true, container allocates more batches in case
  77. * there are more than `maxSize` particles.
  78. */
  79. function ParticleContainer(maxSize, properties, batchSize, autoResize) {
  80. if (maxSize === void 0) { maxSize = 1500; }
  81. if (batchSize === void 0) { batchSize = 16384; }
  82. if (autoResize === void 0) { autoResize = false; }
  83. var _this = _super.call(this) || this;
  84. // Making sure the batch size is valid
  85. // 65535 is max vertex index in the index buffer (see ParticleRenderer)
  86. // so max number of particles is 65536 / 4 = 16384
  87. var maxBatchSize = 16384;
  88. if (batchSize > maxBatchSize) {
  89. batchSize = maxBatchSize;
  90. }
  91. _this._properties = [false, true, false, false, false];
  92. _this._maxSize = maxSize;
  93. _this._batchSize = batchSize;
  94. _this._buffers = null;
  95. _this._bufferUpdateIDs = [];
  96. _this._updateID = 0;
  97. _this.interactiveChildren = false;
  98. _this.blendMode = constants.BLEND_MODES.NORMAL;
  99. _this.autoResize = autoResize;
  100. _this.roundPixels = true;
  101. _this.baseTexture = null;
  102. _this.setProperties(properties);
  103. _this._tint = 0;
  104. _this.tintRgb = new Float32Array(4);
  105. _this.tint = 0xFFFFFF;
  106. return _this;
  107. }
  108. /**
  109. * Sets the private properties array to dynamic / static based on the passed properties object
  110. * @param properties - The properties to be uploaded
  111. */
  112. ParticleContainer.prototype.setProperties = function (properties) {
  113. if (properties) {
  114. this._properties[0] = 'vertices' in properties || 'scale' in properties
  115. ? !!properties.vertices || !!properties.scale : this._properties[0];
  116. this._properties[1] = 'position' in properties ? !!properties.position : this._properties[1];
  117. this._properties[2] = 'rotation' in properties ? !!properties.rotation : this._properties[2];
  118. this._properties[3] = 'uvs' in properties ? !!properties.uvs : this._properties[3];
  119. this._properties[4] = 'tint' in properties || 'alpha' in properties
  120. ? !!properties.tint || !!properties.alpha : this._properties[4];
  121. }
  122. };
  123. ParticleContainer.prototype.updateTransform = function () {
  124. // TODO don't need to!
  125. this.displayObjectUpdateTransform();
  126. };
  127. Object.defineProperty(ParticleContainer.prototype, "tint", {
  128. /**
  129. * The tint applied to the container. This is a hex value.
  130. * A value of 0xFFFFFF will remove any tint effect.
  131. * IMPORTANT: This is a WebGL only feature and will be ignored by the canvas renderer.
  132. * @default 0xFFFFFF
  133. */
  134. get: function () {
  135. return this._tint;
  136. },
  137. set: function (value) {
  138. this._tint = value;
  139. utils.hex2rgb(value, this.tintRgb);
  140. },
  141. enumerable: false,
  142. configurable: true
  143. });
  144. /**
  145. * Renders the container using the WebGL renderer.
  146. * @param renderer - The WebGL renderer.
  147. */
  148. ParticleContainer.prototype.render = function (renderer) {
  149. var _this = this;
  150. if (!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable) {
  151. return;
  152. }
  153. if (!this.baseTexture) {
  154. this.baseTexture = this.children[0]._texture.baseTexture;
  155. if (!this.baseTexture.valid) {
  156. this.baseTexture.once('update', function () { return _this.onChildrenChange(0); });
  157. }
  158. }
  159. renderer.batch.setObjectRenderer(renderer.plugins.particle);
  160. renderer.plugins.particle.render(this);
  161. };
  162. /**
  163. * Set the flag that static data should be updated to true
  164. * @param smallestChildIndex - The smallest child index.
  165. */
  166. ParticleContainer.prototype.onChildrenChange = function (smallestChildIndex) {
  167. var bufferIndex = Math.floor(smallestChildIndex / this._batchSize);
  168. while (this._bufferUpdateIDs.length < bufferIndex) {
  169. this._bufferUpdateIDs.push(0);
  170. }
  171. this._bufferUpdateIDs[bufferIndex] = ++this._updateID;
  172. };
  173. ParticleContainer.prototype.dispose = function () {
  174. if (this._buffers) {
  175. for (var i = 0; i < this._buffers.length; ++i) {
  176. this._buffers[i].destroy();
  177. }
  178. this._buffers = null;
  179. }
  180. };
  181. /**
  182. * Destroys the container
  183. * @param options - Options parameter. A boolean will act as if all options
  184. * have been set to that value
  185. * @param {boolean} [options.children=false] - if set to true, all the children will have their
  186. * destroy method called as well. 'options' will be passed on to those calls.
  187. * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true
  188. * Should it destroy the texture of the child sprite
  189. * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true
  190. * Should it destroy the base texture of the child sprite
  191. */
  192. ParticleContainer.prototype.destroy = function (options) {
  193. _super.prototype.destroy.call(this, options);
  194. this.dispose();
  195. this._properties = null;
  196. this._buffers = null;
  197. this._bufferUpdateIDs = null;
  198. };
  199. return ParticleContainer;
  200. }(display.Container));
  201. /*
  202. * @author Mat Groves
  203. *
  204. * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
  205. * for creating the original PixiJS version!
  206. * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that
  207. * they now share 4 bytes on the vertex buffer
  208. *
  209. * Heavily inspired by LibGDX's ParticleBuffer:
  210. * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/ParticleBuffer.java
  211. */
  212. /**
  213. * The particle buffer manages the static and dynamic buffers for a particle container.
  214. * @private
  215. * @memberof PIXI
  216. */
  217. var ParticleBuffer = /** @class */ (function () {
  218. /**
  219. * @param {object} properties - The properties to upload.
  220. * @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic.
  221. * @param {number} size - The size of the batch.
  222. */
  223. function ParticleBuffer(properties, dynamicPropertyFlags, size) {
  224. this.geometry = new core.Geometry();
  225. this.indexBuffer = null;
  226. this.size = size;
  227. this.dynamicProperties = [];
  228. this.staticProperties = [];
  229. for (var i = 0; i < properties.length; ++i) {
  230. var property = properties[i];
  231. // Make copy of properties object so that when we edit the offset it doesn't
  232. // change all other instances of the object literal
  233. property = {
  234. attributeName: property.attributeName,
  235. size: property.size,
  236. uploadFunction: property.uploadFunction,
  237. type: property.type || constants.TYPES.FLOAT,
  238. offset: property.offset,
  239. };
  240. if (dynamicPropertyFlags[i]) {
  241. this.dynamicProperties.push(property);
  242. }
  243. else {
  244. this.staticProperties.push(property);
  245. }
  246. }
  247. this.staticStride = 0;
  248. this.staticBuffer = null;
  249. this.staticData = null;
  250. this.staticDataUint32 = null;
  251. this.dynamicStride = 0;
  252. this.dynamicBuffer = null;
  253. this.dynamicData = null;
  254. this.dynamicDataUint32 = null;
  255. this._updateID = 0;
  256. this.initBuffers();
  257. }
  258. /** Sets up the renderer context and necessary buffers. */
  259. ParticleBuffer.prototype.initBuffers = function () {
  260. var geometry = this.geometry;
  261. var dynamicOffset = 0;
  262. this.indexBuffer = new core.Buffer(utils.createIndicesForQuads(this.size), true, true);
  263. geometry.addIndex(this.indexBuffer);
  264. this.dynamicStride = 0;
  265. for (var i = 0; i < this.dynamicProperties.length; ++i) {
  266. var property = this.dynamicProperties[i];
  267. property.offset = dynamicOffset;
  268. dynamicOffset += property.size;
  269. this.dynamicStride += property.size;
  270. }
  271. var dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4);
  272. this.dynamicData = new Float32Array(dynBuffer);
  273. this.dynamicDataUint32 = new Uint32Array(dynBuffer);
  274. this.dynamicBuffer = new core.Buffer(this.dynamicData, false, false);
  275. // static //
  276. var staticOffset = 0;
  277. this.staticStride = 0;
  278. for (var i = 0; i < this.staticProperties.length; ++i) {
  279. var property = this.staticProperties[i];
  280. property.offset = staticOffset;
  281. staticOffset += property.size;
  282. this.staticStride += property.size;
  283. }
  284. var statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4);
  285. this.staticData = new Float32Array(statBuffer);
  286. this.staticDataUint32 = new Uint32Array(statBuffer);
  287. this.staticBuffer = new core.Buffer(this.staticData, true, false);
  288. for (var i = 0; i < this.dynamicProperties.length; ++i) {
  289. var property = this.dynamicProperties[i];
  290. geometry.addAttribute(property.attributeName, this.dynamicBuffer, 0, property.type === constants.TYPES.UNSIGNED_BYTE, property.type, this.dynamicStride * 4, property.offset * 4);
  291. }
  292. for (var i = 0; i < this.staticProperties.length; ++i) {
  293. var property = this.staticProperties[i];
  294. geometry.addAttribute(property.attributeName, this.staticBuffer, 0, property.type === constants.TYPES.UNSIGNED_BYTE, property.type, this.staticStride * 4, property.offset * 4);
  295. }
  296. };
  297. /**
  298. * Uploads the dynamic properties.
  299. * @param children - The children to upload.
  300. * @param startIndex - The index to start at.
  301. * @param amount - The number to upload.
  302. */
  303. ParticleBuffer.prototype.uploadDynamic = function (children, startIndex, amount) {
  304. for (var i = 0; i < this.dynamicProperties.length; i++) {
  305. var property = this.dynamicProperties[i];
  306. property.uploadFunction(children, startIndex, amount, property.type === constants.TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData, this.dynamicStride, property.offset);
  307. }
  308. this.dynamicBuffer._updateID++;
  309. };
  310. /**
  311. * Uploads the static properties.
  312. * @param children - The children to upload.
  313. * @param startIndex - The index to start at.
  314. * @param amount - The number to upload.
  315. */
  316. ParticleBuffer.prototype.uploadStatic = function (children, startIndex, amount) {
  317. for (var i = 0; i < this.staticProperties.length; i++) {
  318. var property = this.staticProperties[i];
  319. property.uploadFunction(children, startIndex, amount, property.type === constants.TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData, this.staticStride, property.offset);
  320. }
  321. this.staticBuffer._updateID++;
  322. };
  323. /** Destroys the ParticleBuffer. */
  324. ParticleBuffer.prototype.destroy = function () {
  325. this.indexBuffer = null;
  326. this.dynamicProperties = null;
  327. this.dynamicBuffer = null;
  328. this.dynamicData = null;
  329. this.dynamicDataUint32 = null;
  330. this.staticProperties = null;
  331. this.staticBuffer = null;
  332. this.staticData = null;
  333. this.staticDataUint32 = null;
  334. // all buffers are destroyed inside geometry
  335. this.geometry.destroy();
  336. };
  337. return ParticleBuffer;
  338. }());
  339. var fragment = "varying vec2 vTextureCoord;\nvarying vec4 vColor;\n\nuniform sampler2D uSampler;\n\nvoid main(void){\n vec4 color = texture2D(uSampler, vTextureCoord) * vColor;\n gl_FragColor = color;\n}";
  340. var vertex = "attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nattribute vec4 aColor;\n\nattribute vec2 aPositionCoord;\nattribute float aRotation;\n\nuniform mat3 translationMatrix;\nuniform vec4 uColor;\n\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\n\nvoid main(void){\n float x = (aVertexPosition.x) * cos(aRotation) - (aVertexPosition.y) * sin(aRotation);\n float y = (aVertexPosition.x) * sin(aRotation) + (aVertexPosition.y) * cos(aRotation);\n\n vec2 v = vec2(x, y);\n v = v + aPositionCoord;\n\n gl_Position = vec4((translationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0);\n\n vTextureCoord = aTextureCoord;\n vColor = aColor * uColor;\n}\n";
  341. /*
  342. * @author Mat Groves
  343. *
  344. * Big thanks to the very clever Matt DesLauriers <mattdesl> https://github.com/mattdesl/
  345. * for creating the original PixiJS version!
  346. * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now
  347. * share 4 bytes on the vertex buffer
  348. *
  349. * Heavily inspired by LibGDX's ParticleRenderer:
  350. * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/ParticleRenderer.java
  351. */
  352. /**
  353. * Renderer for Particles that is designer for speed over feature set.
  354. * @memberof PIXI
  355. */
  356. var ParticleRenderer = /** @class */ (function (_super) {
  357. __extends(ParticleRenderer, _super);
  358. /**
  359. * @param renderer - The renderer this sprite batch works for.
  360. */
  361. function ParticleRenderer(renderer) {
  362. var _this = _super.call(this, renderer) || this;
  363. // 65535 is max vertex index in the index buffer (see ParticleRenderer)
  364. // so max number of particles is 65536 / 4 = 16384
  365. // and max number of element in the index buffer is 16384 * 6 = 98304
  366. // Creating a full index buffer, overhead is 98304 * 2 = 196Ko
  367. // let numIndices = 98304;
  368. _this.shader = null;
  369. _this.properties = null;
  370. _this.tempMatrix = new math.Matrix();
  371. _this.properties = [
  372. // verticesData
  373. {
  374. attributeName: 'aVertexPosition',
  375. size: 2,
  376. uploadFunction: _this.uploadVertices,
  377. offset: 0,
  378. },
  379. // positionData
  380. {
  381. attributeName: 'aPositionCoord',
  382. size: 2,
  383. uploadFunction: _this.uploadPosition,
  384. offset: 0,
  385. },
  386. // rotationData
  387. {
  388. attributeName: 'aRotation',
  389. size: 1,
  390. uploadFunction: _this.uploadRotation,
  391. offset: 0,
  392. },
  393. // uvsData
  394. {
  395. attributeName: 'aTextureCoord',
  396. size: 2,
  397. uploadFunction: _this.uploadUvs,
  398. offset: 0,
  399. },
  400. // tintData
  401. {
  402. attributeName: 'aColor',
  403. size: 1,
  404. type: constants.TYPES.UNSIGNED_BYTE,
  405. uploadFunction: _this.uploadTint,
  406. offset: 0,
  407. } ];
  408. _this.shader = core.Shader.from(vertex, fragment, {});
  409. _this.state = core.State.for2d();
  410. return _this;
  411. }
  412. /**
  413. * Renders the particle container object.
  414. * @param container - The container to render using this ParticleRenderer.
  415. */
  416. ParticleRenderer.prototype.render = function (container) {
  417. var children = container.children;
  418. var maxSize = container._maxSize;
  419. var batchSize = container._batchSize;
  420. var renderer = this.renderer;
  421. var totalChildren = children.length;
  422. if (totalChildren === 0) {
  423. return;
  424. }
  425. else if (totalChildren > maxSize && !container.autoResize) {
  426. totalChildren = maxSize;
  427. }
  428. var buffers = container._buffers;
  429. if (!buffers) {
  430. buffers = container._buffers = this.generateBuffers(container);
  431. }
  432. var baseTexture = children[0]._texture.baseTexture;
  433. var premultiplied = baseTexture.alphaMode > 0;
  434. // if the uvs have not updated then no point rendering just yet!
  435. this.state.blendMode = utils.correctBlendMode(container.blendMode, premultiplied);
  436. renderer.state.set(this.state);
  437. var gl = renderer.gl;
  438. var m = container.worldTransform.copyTo(this.tempMatrix);
  439. m.prepend(renderer.globalUniforms.uniforms.projectionMatrix);
  440. this.shader.uniforms.translationMatrix = m.toArray(true);
  441. this.shader.uniforms.uColor = utils.premultiplyRgba(container.tintRgb, container.worldAlpha, this.shader.uniforms.uColor, premultiplied);
  442. this.shader.uniforms.uSampler = baseTexture;
  443. this.renderer.shader.bind(this.shader);
  444. var updateStatic = false;
  445. // now lets upload and render the buffers..
  446. for (var i = 0, j = 0; i < totalChildren; i += batchSize, j += 1) {
  447. var amount = (totalChildren - i);
  448. if (amount > batchSize) {
  449. amount = batchSize;
  450. }
  451. if (j >= buffers.length) {
  452. buffers.push(this._generateOneMoreBuffer(container));
  453. }
  454. var buffer = buffers[j];
  455. // we always upload the dynamic
  456. buffer.uploadDynamic(children, i, amount);
  457. var bid = container._bufferUpdateIDs[j] || 0;
  458. updateStatic = updateStatic || (buffer._updateID < bid);
  459. // we only upload the static content when we have to!
  460. if (updateStatic) {
  461. buffer._updateID = container._updateID;
  462. buffer.uploadStatic(children, i, amount);
  463. }
  464. // bind the buffer
  465. renderer.geometry.bind(buffer.geometry);
  466. gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0);
  467. }
  468. };
  469. /**
  470. * Creates one particle buffer for each child in the container we want to render and updates internal properties.
  471. * @param container - The container to render using this ParticleRenderer
  472. * @returns - The buffers
  473. */
  474. ParticleRenderer.prototype.generateBuffers = function (container) {
  475. var buffers = [];
  476. var size = container._maxSize;
  477. var batchSize = container._batchSize;
  478. var dynamicPropertyFlags = container._properties;
  479. for (var i = 0; i < size; i += batchSize) {
  480. buffers.push(new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize));
  481. }
  482. return buffers;
  483. };
  484. /**
  485. * Creates one more particle buffer, because container has autoResize feature.
  486. * @param container - The container to render using this ParticleRenderer
  487. * @returns - The generated buffer
  488. */
  489. ParticleRenderer.prototype._generateOneMoreBuffer = function (container) {
  490. var batchSize = container._batchSize;
  491. var dynamicPropertyFlags = container._properties;
  492. return new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize);
  493. };
  494. /**
  495. * Uploads the vertices.
  496. * @param children - the array of sprites to render
  497. * @param startIndex - the index to start from in the children array
  498. * @param amount - the amount of children that will have their vertices uploaded
  499. * @param array - The vertices to upload.
  500. * @param stride - Stride to use for iteration.
  501. * @param offset - Offset to start at.
  502. */
  503. ParticleRenderer.prototype.uploadVertices = function (children, startIndex, amount, array, stride, offset) {
  504. var w0 = 0;
  505. var w1 = 0;
  506. var h0 = 0;
  507. var h1 = 0;
  508. for (var i = 0; i < amount; ++i) {
  509. var sprite = children[startIndex + i];
  510. var texture = sprite._texture;
  511. var sx = sprite.scale.x;
  512. var sy = sprite.scale.y;
  513. var trim = texture.trim;
  514. var orig = texture.orig;
  515. if (trim) {
  516. // if the sprite is trimmed and is not a tilingsprite then we need to add the
  517. // extra space before transforming the sprite coords..
  518. w1 = trim.x - (sprite.anchor.x * orig.width);
  519. w0 = w1 + trim.width;
  520. h1 = trim.y - (sprite.anchor.y * orig.height);
  521. h0 = h1 + trim.height;
  522. }
  523. else {
  524. w0 = (orig.width) * (1 - sprite.anchor.x);
  525. w1 = (orig.width) * -sprite.anchor.x;
  526. h0 = orig.height * (1 - sprite.anchor.y);
  527. h1 = orig.height * -sprite.anchor.y;
  528. }
  529. array[offset] = w1 * sx;
  530. array[offset + 1] = h1 * sy;
  531. array[offset + stride] = w0 * sx;
  532. array[offset + stride + 1] = h1 * sy;
  533. array[offset + (stride * 2)] = w0 * sx;
  534. array[offset + (stride * 2) + 1] = h0 * sy;
  535. array[offset + (stride * 3)] = w1 * sx;
  536. array[offset + (stride * 3) + 1] = h0 * sy;
  537. offset += stride * 4;
  538. }
  539. };
  540. /**
  541. * Uploads the position.
  542. * @param children - the array of sprites to render
  543. * @param startIndex - the index to start from in the children array
  544. * @param amount - the amount of children that will have their positions uploaded
  545. * @param array - The vertices to upload.
  546. * @param stride - Stride to use for iteration.
  547. * @param offset - Offset to start at.
  548. */
  549. ParticleRenderer.prototype.uploadPosition = function (children, startIndex, amount, array, stride, offset) {
  550. for (var i = 0; i < amount; i++) {
  551. var spritePosition = children[startIndex + i].position;
  552. array[offset] = spritePosition.x;
  553. array[offset + 1] = spritePosition.y;
  554. array[offset + stride] = spritePosition.x;
  555. array[offset + stride + 1] = spritePosition.y;
  556. array[offset + (stride * 2)] = spritePosition.x;
  557. array[offset + (stride * 2) + 1] = spritePosition.y;
  558. array[offset + (stride * 3)] = spritePosition.x;
  559. array[offset + (stride * 3) + 1] = spritePosition.y;
  560. offset += stride * 4;
  561. }
  562. };
  563. /**
  564. * Uploads the rotation.
  565. * @param children - the array of sprites to render
  566. * @param startIndex - the index to start from in the children array
  567. * @param amount - the amount of children that will have their rotation uploaded
  568. * @param array - The vertices to upload.
  569. * @param stride - Stride to use for iteration.
  570. * @param offset - Offset to start at.
  571. */
  572. ParticleRenderer.prototype.uploadRotation = function (children, startIndex, amount, array, stride, offset) {
  573. for (var i = 0; i < amount; i++) {
  574. var spriteRotation = children[startIndex + i].rotation;
  575. array[offset] = spriteRotation;
  576. array[offset + stride] = spriteRotation;
  577. array[offset + (stride * 2)] = spriteRotation;
  578. array[offset + (stride * 3)] = spriteRotation;
  579. offset += stride * 4;
  580. }
  581. };
  582. /**
  583. * Uploads the UVs.
  584. * @param children - the array of sprites to render
  585. * @param startIndex - the index to start from in the children array
  586. * @param amount - the amount of children that will have their rotation uploaded
  587. * @param array - The vertices to upload.
  588. * @param stride - Stride to use for iteration.
  589. * @param offset - Offset to start at.
  590. */
  591. ParticleRenderer.prototype.uploadUvs = function (children, startIndex, amount, array, stride, offset) {
  592. for (var i = 0; i < amount; ++i) {
  593. var textureUvs = children[startIndex + i]._texture._uvs;
  594. if (textureUvs) {
  595. array[offset] = textureUvs.x0;
  596. array[offset + 1] = textureUvs.y0;
  597. array[offset + stride] = textureUvs.x1;
  598. array[offset + stride + 1] = textureUvs.y1;
  599. array[offset + (stride * 2)] = textureUvs.x2;
  600. array[offset + (stride * 2) + 1] = textureUvs.y2;
  601. array[offset + (stride * 3)] = textureUvs.x3;
  602. array[offset + (stride * 3) + 1] = textureUvs.y3;
  603. offset += stride * 4;
  604. }
  605. else {
  606. // TODO you know this can be easier!
  607. array[offset] = 0;
  608. array[offset + 1] = 0;
  609. array[offset + stride] = 0;
  610. array[offset + stride + 1] = 0;
  611. array[offset + (stride * 2)] = 0;
  612. array[offset + (stride * 2) + 1] = 0;
  613. array[offset + (stride * 3)] = 0;
  614. array[offset + (stride * 3) + 1] = 0;
  615. offset += stride * 4;
  616. }
  617. }
  618. };
  619. /**
  620. * Uploads the tint.
  621. * @param children - the array of sprites to render
  622. * @param startIndex - the index to start from in the children array
  623. * @param amount - the amount of children that will have their rotation uploaded
  624. * @param array - The vertices to upload.
  625. * @param stride - Stride to use for iteration.
  626. * @param offset - Offset to start at.
  627. */
  628. ParticleRenderer.prototype.uploadTint = function (children, startIndex, amount, array, stride, offset) {
  629. for (var i = 0; i < amount; ++i) {
  630. var sprite = children[startIndex + i];
  631. var premultiplied = sprite._texture.baseTexture.alphaMode > 0;
  632. var alpha = sprite.alpha;
  633. // we dont call extra function if alpha is 1.0, that's faster
  634. var argb = alpha < 1.0 && premultiplied
  635. ? utils.premultiplyTint(sprite._tintRGB, alpha) : sprite._tintRGB + (alpha * 255 << 24);
  636. array[offset] = argb;
  637. array[offset + stride] = argb;
  638. array[offset + (stride * 2)] = argb;
  639. array[offset + (stride * 3)] = argb;
  640. offset += stride * 4;
  641. }
  642. };
  643. /** Destroys the ParticleRenderer. */
  644. ParticleRenderer.prototype.destroy = function () {
  645. _super.prototype.destroy.call(this);
  646. if (this.shader) {
  647. this.shader.destroy();
  648. this.shader = null;
  649. }
  650. this.tempMatrix = null;
  651. };
  652. /** @ignore */
  653. ParticleRenderer.extension = {
  654. name: 'particle',
  655. type: core.ExtensionType.RendererPlugin,
  656. };
  657. return ParticleRenderer;
  658. }(core.ObjectRenderer));
  659. exports.ParticleContainer = ParticleContainer;
  660. exports.ParticleRenderer = ParticleRenderer;
  661. //# sourceMappingURL=particle-container.js.map