particle-container.mjs 29 KB

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