This commit is contained in:
2025-01-04 00:34:03 +01:00
parent 41829408dc
commit 0ca14bbc19
18111 changed files with 1871397 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2013-2023 Mathew Groves, Chad Engler
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,113 @@
"use strict";
var core = require("@pixi/core");
class ParticleBuffer {
/**
* @param {object} properties - The properties to upload.
* @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic.
* @param {number} size - The size of the batch.
*/
constructor(properties, dynamicPropertyFlags, size) {
this.geometry = new core.Geometry(), this.indexBuffer = null, this.size = size, this.dynamicProperties = [], this.staticProperties = [];
for (let i = 0; i < properties.length; ++i) {
let property = properties[i];
property = {
attributeName: property.attributeName,
size: property.size,
uploadFunction: property.uploadFunction,
type: property.type || core.TYPES.FLOAT,
offset: property.offset
}, dynamicPropertyFlags[i] ? this.dynamicProperties.push(property) : this.staticProperties.push(property);
}
this.staticStride = 0, this.staticBuffer = null, this.staticData = null, this.staticDataUint32 = null, this.dynamicStride = 0, this.dynamicBuffer = null, this.dynamicData = null, this.dynamicDataUint32 = null, this._updateID = 0, this.initBuffers();
}
/** Sets up the renderer context and necessary buffers. */
initBuffers() {
const geometry = this.geometry;
let dynamicOffset = 0;
this.indexBuffer = new core.Buffer(core.utils.createIndicesForQuads(this.size), !0, !0), geometry.addIndex(this.indexBuffer), this.dynamicStride = 0;
for (let i = 0; i < this.dynamicProperties.length; ++i) {
const property = this.dynamicProperties[i];
property.offset = dynamicOffset, dynamicOffset += property.size, this.dynamicStride += property.size;
}
const dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4);
this.dynamicData = new Float32Array(dynBuffer), this.dynamicDataUint32 = new Uint32Array(dynBuffer), this.dynamicBuffer = new core.Buffer(this.dynamicData, !1, !1);
let staticOffset = 0;
this.staticStride = 0;
for (let i = 0; i < this.staticProperties.length; ++i) {
const property = this.staticProperties[i];
property.offset = staticOffset, staticOffset += property.size, this.staticStride += property.size;
}
const statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4);
this.staticData = new Float32Array(statBuffer), this.staticDataUint32 = new Uint32Array(statBuffer), this.staticBuffer = new core.Buffer(this.staticData, !0, !1);
for (let i = 0; i < this.dynamicProperties.length; ++i) {
const property = this.dynamicProperties[i];
geometry.addAttribute(
property.attributeName,
this.dynamicBuffer,
0,
property.type === core.TYPES.UNSIGNED_BYTE,
property.type,
this.dynamicStride * 4,
property.offset * 4
);
}
for (let i = 0; i < this.staticProperties.length; ++i) {
const property = this.staticProperties[i];
geometry.addAttribute(
property.attributeName,
this.staticBuffer,
0,
property.type === core.TYPES.UNSIGNED_BYTE,
property.type,
this.staticStride * 4,
property.offset * 4
);
}
}
/**
* Uploads the dynamic properties.
* @param children - The children to upload.
* @param startIndex - The index to start at.
* @param amount - The number to upload.
*/
uploadDynamic(children, startIndex, amount) {
for (let i = 0; i < this.dynamicProperties.length; i++) {
const property = this.dynamicProperties[i];
property.uploadFunction(
children,
startIndex,
amount,
property.type === core.TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData,
this.dynamicStride,
property.offset
);
}
this.dynamicBuffer._updateID++;
}
/**
* Uploads the static properties.
* @param children - The children to upload.
* @param startIndex - The index to start at.
* @param amount - The number to upload.
*/
uploadStatic(children, startIndex, amount) {
for (let i = 0; i < this.staticProperties.length; i++) {
const property = this.staticProperties[i];
property.uploadFunction(
children,
startIndex,
amount,
property.type === core.TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData,
this.staticStride,
property.offset
);
}
this.staticBuffer._updateID++;
}
/** Destroys the ParticleBuffer. */
destroy() {
this.indexBuffer = null, this.dynamicProperties = null, this.dynamicBuffer = null, this.dynamicData = null, this.dynamicDataUint32 = null, this.staticProperties = null, this.staticBuffer = null, this.staticData = null, this.staticDataUint32 = null, this.geometry.destroy();
}
}
exports.ParticleBuffer = ParticleBuffer;
//# sourceMappingURL=ParticleBuffer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,114 @@
import { Geometry, TYPES, Buffer, utils } from "@pixi/core";
class ParticleBuffer {
/**
* @param {object} properties - The properties to upload.
* @param {boolean[]} dynamicPropertyFlags - Flags for which properties are dynamic.
* @param {number} size - The size of the batch.
*/
constructor(properties, dynamicPropertyFlags, size) {
this.geometry = new Geometry(), this.indexBuffer = null, this.size = size, this.dynamicProperties = [], this.staticProperties = [];
for (let i = 0; i < properties.length; ++i) {
let property = properties[i];
property = {
attributeName: property.attributeName,
size: property.size,
uploadFunction: property.uploadFunction,
type: property.type || TYPES.FLOAT,
offset: property.offset
}, dynamicPropertyFlags[i] ? this.dynamicProperties.push(property) : this.staticProperties.push(property);
}
this.staticStride = 0, this.staticBuffer = null, this.staticData = null, this.staticDataUint32 = null, this.dynamicStride = 0, this.dynamicBuffer = null, this.dynamicData = null, this.dynamicDataUint32 = null, this._updateID = 0, this.initBuffers();
}
/** Sets up the renderer context and necessary buffers. */
initBuffers() {
const geometry = this.geometry;
let dynamicOffset = 0;
this.indexBuffer = new Buffer(utils.createIndicesForQuads(this.size), !0, !0), geometry.addIndex(this.indexBuffer), this.dynamicStride = 0;
for (let i = 0; i < this.dynamicProperties.length; ++i) {
const property = this.dynamicProperties[i];
property.offset = dynamicOffset, dynamicOffset += property.size, this.dynamicStride += property.size;
}
const dynBuffer = new ArrayBuffer(this.size * this.dynamicStride * 4 * 4);
this.dynamicData = new Float32Array(dynBuffer), this.dynamicDataUint32 = new Uint32Array(dynBuffer), this.dynamicBuffer = new Buffer(this.dynamicData, !1, !1);
let staticOffset = 0;
this.staticStride = 0;
for (let i = 0; i < this.staticProperties.length; ++i) {
const property = this.staticProperties[i];
property.offset = staticOffset, staticOffset += property.size, this.staticStride += property.size;
}
const statBuffer = new ArrayBuffer(this.size * this.staticStride * 4 * 4);
this.staticData = new Float32Array(statBuffer), this.staticDataUint32 = new Uint32Array(statBuffer), this.staticBuffer = new Buffer(this.staticData, !0, !1);
for (let i = 0; i < this.dynamicProperties.length; ++i) {
const property = this.dynamicProperties[i];
geometry.addAttribute(
property.attributeName,
this.dynamicBuffer,
0,
property.type === TYPES.UNSIGNED_BYTE,
property.type,
this.dynamicStride * 4,
property.offset * 4
);
}
for (let i = 0; i < this.staticProperties.length; ++i) {
const property = this.staticProperties[i];
geometry.addAttribute(
property.attributeName,
this.staticBuffer,
0,
property.type === TYPES.UNSIGNED_BYTE,
property.type,
this.staticStride * 4,
property.offset * 4
);
}
}
/**
* Uploads the dynamic properties.
* @param children - The children to upload.
* @param startIndex - The index to start at.
* @param amount - The number to upload.
*/
uploadDynamic(children, startIndex, amount) {
for (let i = 0; i < this.dynamicProperties.length; i++) {
const property = this.dynamicProperties[i];
property.uploadFunction(
children,
startIndex,
amount,
property.type === TYPES.UNSIGNED_BYTE ? this.dynamicDataUint32 : this.dynamicData,
this.dynamicStride,
property.offset
);
}
this.dynamicBuffer._updateID++;
}
/**
* Uploads the static properties.
* @param children - The children to upload.
* @param startIndex - The index to start at.
* @param amount - The number to upload.
*/
uploadStatic(children, startIndex, amount) {
for (let i = 0; i < this.staticProperties.length; i++) {
const property = this.staticProperties[i];
property.uploadFunction(
children,
startIndex,
amount,
property.type === TYPES.UNSIGNED_BYTE ? this.staticDataUint32 : this.staticData,
this.staticStride,
property.offset
);
}
this.staticBuffer._updateID++;
}
/** Destroys the ParticleBuffer. */
destroy() {
this.indexBuffer = null, this.dynamicProperties = null, this.dynamicBuffer = null, this.dynamicData = null, this.dynamicDataUint32 = null, this.staticProperties = null, this.staticBuffer = null, this.staticData = null, this.staticDataUint32 = null, this.geometry.destroy();
}
}
export {
ParticleBuffer
};
//# sourceMappingURL=ParticleBuffer.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,85 @@
"use strict";
var core = require("@pixi/core"), display = require("@pixi/display");
class ParticleContainer extends display.Container {
/**
* @param maxSize - The maximum number of particles that can be rendered by the container.
* Affects size of allocated buffers.
* @param properties - The properties of children that should be uploaded to the gpu and applied.
* @param {boolean} [properties.vertices=false] - When true, vertices be uploaded and applied.
* if sprite's ` scale/anchor/trim/frame/orig` is dynamic, please set `true`.
* @param {boolean} [properties.position=true] - When true, position be uploaded and applied.
* @param {boolean} [properties.rotation=false] - When true, rotation be uploaded and applied.
* @param {boolean} [properties.uvs=false] - When true, uvs be uploaded and applied.
* @param {boolean} [properties.tint=false] - When true, alpha and tint be uploaded and applied.
* @param {number} [batchSize=16384] - Number of particles per batch. If less than maxSize, it uses maxSize instead.
* @param {boolean} [autoResize=false] - If true, container allocates more batches in case
* there are more than `maxSize` particles.
*/
constructor(maxSize = 1500, properties, batchSize = 16384, autoResize = !1) {
super();
const maxBatchSize = 16384;
batchSize > maxBatchSize && (batchSize = maxBatchSize), this._properties = [!1, !0, !1, !1, !1], this._maxSize = maxSize, this._batchSize = batchSize, this._buffers = null, this._bufferUpdateIDs = [], this._updateID = 0, this.interactiveChildren = !1, this.blendMode = core.BLEND_MODES.NORMAL, this.autoResize = autoResize, this.roundPixels = !0, this.baseTexture = null, this.setProperties(properties), this._tintColor = new core.Color(0), this.tintRgb = new Float32Array(3), this.tint = 16777215;
}
/**
* Sets the private properties array to dynamic / static based on the passed properties object
* @param properties - The properties to be uploaded
*/
setProperties(properties) {
properties && (this._properties[0] = "vertices" in properties || "scale" in properties ? !!properties.vertices || !!properties.scale : this._properties[0], this._properties[1] = "position" in properties ? !!properties.position : this._properties[1], this._properties[2] = "rotation" in properties ? !!properties.rotation : this._properties[2], this._properties[3] = "uvs" in properties ? !!properties.uvs : this._properties[3], this._properties[4] = "tint" in properties || "alpha" in properties ? !!properties.tint || !!properties.alpha : this._properties[4]);
}
updateTransform() {
this.displayObjectUpdateTransform();
}
/**
* The tint applied to the container. This is a hex value.
* A value of 0xFFFFFF will remove any tint effect.
* IMPORTANT: This is a WebGL only feature and will be ignored by the canvas renderer.
* @default 0xFFFFFF
*/
get tint() {
return this._tintColor.value;
}
set tint(value) {
this._tintColor.setValue(value), this._tintColor.toRgbArray(this.tintRgb);
}
/**
* Renders the container using the WebGL renderer.
* @param renderer - The WebGL renderer.
*/
render(renderer) {
!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable || (this.baseTexture || (this.baseTexture = this.children[0]._texture.baseTexture, this.baseTexture.valid || this.baseTexture.once("update", () => this.onChildrenChange(0))), renderer.batch.setObjectRenderer(renderer.plugins.particle), renderer.plugins.particle.render(this));
}
/**
* Set the flag that static data should be updated to true
* @param smallestChildIndex - The smallest child index.
*/
onChildrenChange(smallestChildIndex) {
const bufferIndex = Math.floor(smallestChildIndex / this._batchSize);
for (; this._bufferUpdateIDs.length < bufferIndex; )
this._bufferUpdateIDs.push(0);
this._bufferUpdateIDs[bufferIndex] = ++this._updateID;
}
dispose() {
if (this._buffers) {
for (let i = 0; i < this._buffers.length; ++i)
this._buffers[i].destroy();
this._buffers = null;
}
}
/**
* Destroys the container
* @param options - Options parameter. A boolean will act as if all options
* have been set to that value
* @param {boolean} [options.children=false] - if set to true, all the children will have their
* destroy method called as well. 'options' will be passed on to those calls.
* @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true
* Should it destroy the texture of the child sprite
* @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true
* Should it destroy the base texture of the child sprite
*/
destroy(options) {
super.destroy(options), this.dispose(), this._properties = null, this._buffers = null, this._bufferUpdateIDs = null;
}
}
exports.ParticleContainer = ParticleContainer;
//# sourceMappingURL=ParticleContainer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,87 @@
import { BLEND_MODES, Color } from "@pixi/core";
import { Container } from "@pixi/display";
class ParticleContainer extends Container {
/**
* @param maxSize - The maximum number of particles that can be rendered by the container.
* Affects size of allocated buffers.
* @param properties - The properties of children that should be uploaded to the gpu and applied.
* @param {boolean} [properties.vertices=false] - When true, vertices be uploaded and applied.
* if sprite's ` scale/anchor/trim/frame/orig` is dynamic, please set `true`.
* @param {boolean} [properties.position=true] - When true, position be uploaded and applied.
* @param {boolean} [properties.rotation=false] - When true, rotation be uploaded and applied.
* @param {boolean} [properties.uvs=false] - When true, uvs be uploaded and applied.
* @param {boolean} [properties.tint=false] - When true, alpha and tint be uploaded and applied.
* @param {number} [batchSize=16384] - Number of particles per batch. If less than maxSize, it uses maxSize instead.
* @param {boolean} [autoResize=false] - If true, container allocates more batches in case
* there are more than `maxSize` particles.
*/
constructor(maxSize = 1500, properties, batchSize = 16384, autoResize = !1) {
super();
const maxBatchSize = 16384;
batchSize > maxBatchSize && (batchSize = maxBatchSize), this._properties = [!1, !0, !1, !1, !1], this._maxSize = maxSize, this._batchSize = batchSize, this._buffers = null, this._bufferUpdateIDs = [], this._updateID = 0, this.interactiveChildren = !1, this.blendMode = BLEND_MODES.NORMAL, this.autoResize = autoResize, this.roundPixels = !0, this.baseTexture = null, this.setProperties(properties), this._tintColor = new Color(0), this.tintRgb = new Float32Array(3), this.tint = 16777215;
}
/**
* Sets the private properties array to dynamic / static based on the passed properties object
* @param properties - The properties to be uploaded
*/
setProperties(properties) {
properties && (this._properties[0] = "vertices" in properties || "scale" in properties ? !!properties.vertices || !!properties.scale : this._properties[0], this._properties[1] = "position" in properties ? !!properties.position : this._properties[1], this._properties[2] = "rotation" in properties ? !!properties.rotation : this._properties[2], this._properties[3] = "uvs" in properties ? !!properties.uvs : this._properties[3], this._properties[4] = "tint" in properties || "alpha" in properties ? !!properties.tint || !!properties.alpha : this._properties[4]);
}
updateTransform() {
this.displayObjectUpdateTransform();
}
/**
* The tint applied to the container. This is a hex value.
* A value of 0xFFFFFF will remove any tint effect.
* IMPORTANT: This is a WebGL only feature and will be ignored by the canvas renderer.
* @default 0xFFFFFF
*/
get tint() {
return this._tintColor.value;
}
set tint(value) {
this._tintColor.setValue(value), this._tintColor.toRgbArray(this.tintRgb);
}
/**
* Renders the container using the WebGL renderer.
* @param renderer - The WebGL renderer.
*/
render(renderer) {
!this.visible || this.worldAlpha <= 0 || !this.children.length || !this.renderable || (this.baseTexture || (this.baseTexture = this.children[0]._texture.baseTexture, this.baseTexture.valid || this.baseTexture.once("update", () => this.onChildrenChange(0))), renderer.batch.setObjectRenderer(renderer.plugins.particle), renderer.plugins.particle.render(this));
}
/**
* Set the flag that static data should be updated to true
* @param smallestChildIndex - The smallest child index.
*/
onChildrenChange(smallestChildIndex) {
const bufferIndex = Math.floor(smallestChildIndex / this._batchSize);
for (; this._bufferUpdateIDs.length < bufferIndex; )
this._bufferUpdateIDs.push(0);
this._bufferUpdateIDs[bufferIndex] = ++this._updateID;
}
dispose() {
if (this._buffers) {
for (let i = 0; i < this._buffers.length; ++i)
this._buffers[i].destroy();
this._buffers = null;
}
}
/**
* Destroys the container
* @param options - Options parameter. A boolean will act as if all options
* have been set to that value
* @param {boolean} [options.children=false] - if set to true, all the children will have their
* destroy method called as well. 'options' will be passed on to those calls.
* @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true
* Should it destroy the texture of the child sprite
* @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true
* Should it destroy the base texture of the child sprite
*/
destroy(options) {
super.destroy(options), this.dispose(), this._properties = null, this._buffers = null, this._bufferUpdateIDs = null;
}
}
export {
ParticleContainer
};
//# sourceMappingURL=ParticleContainer.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,180 @@
"use strict";
var core = require("@pixi/core"), ParticleBuffer = require("./ParticleBuffer.js"), particles$1 = require("./particles.frag.js"), particles = require("./particles.vert.js");
class ParticleRenderer extends core.ObjectRenderer {
/**
* @param renderer - The renderer this sprite batch works for.
*/
constructor(renderer) {
super(renderer), this.shader = null, this.properties = null, this.tempMatrix = new core.Matrix(), this.properties = [
// verticesData
{
attributeName: "aVertexPosition",
size: 2,
uploadFunction: this.uploadVertices,
offset: 0
},
// positionData
{
attributeName: "aPositionCoord",
size: 2,
uploadFunction: this.uploadPosition,
offset: 0
},
// rotationData
{
attributeName: "aRotation",
size: 1,
uploadFunction: this.uploadRotation,
offset: 0
},
// uvsData
{
attributeName: "aTextureCoord",
size: 2,
uploadFunction: this.uploadUvs,
offset: 0
},
// tintData
{
attributeName: "aColor",
size: 1,
type: core.TYPES.UNSIGNED_BYTE,
uploadFunction: this.uploadTint,
offset: 0
}
], this.shader = core.Shader.from(particles.default, particles$1.default, {}), this.state = core.State.for2d();
}
/**
* Renders the particle container object.
* @param container - The container to render using this ParticleRenderer.
*/
render(container) {
const children = container.children, maxSize = container._maxSize, batchSize = container._batchSize, renderer = this.renderer;
let totalChildren = children.length;
if (totalChildren === 0)
return;
totalChildren > maxSize && !container.autoResize && (totalChildren = maxSize);
let buffers = container._buffers;
buffers || (buffers = container._buffers = this.generateBuffers(container));
const baseTexture = children[0]._texture.baseTexture, premultiplied = baseTexture.alphaMode > 0;
this.state.blendMode = core.utils.correctBlendMode(container.blendMode, premultiplied), renderer.state.set(this.state);
const gl = renderer.gl, m = container.worldTransform.copyTo(this.tempMatrix);
m.prepend(renderer.globalUniforms.uniforms.projectionMatrix), this.shader.uniforms.translationMatrix = m.toArray(!0), this.shader.uniforms.uColor = core.Color.shared.setValue(container.tintRgb).premultiply(container.worldAlpha, premultiplied).toArray(this.shader.uniforms.uColor), this.shader.uniforms.uSampler = baseTexture, this.renderer.shader.bind(this.shader);
let updateStatic = !1;
for (let i = 0, j = 0; i < totalChildren; i += batchSize, j += 1) {
let amount = totalChildren - i;
amount > batchSize && (amount = batchSize), j >= buffers.length && buffers.push(this._generateOneMoreBuffer(container));
const buffer = buffers[j];
buffer.uploadDynamic(children, i, amount);
const bid = container._bufferUpdateIDs[j] || 0;
updateStatic = updateStatic || buffer._updateID < bid, updateStatic && (buffer._updateID = container._updateID, buffer.uploadStatic(children, i, amount)), renderer.geometry.bind(buffer.geometry), gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0);
}
}
/**
* Creates one particle buffer for each child in the container we want to render and updates internal properties.
* @param container - The container to render using this ParticleRenderer
* @returns - The buffers
*/
generateBuffers(container) {
const buffers = [], size = container._maxSize, batchSize = container._batchSize, dynamicPropertyFlags = container._properties;
for (let i = 0; i < size; i += batchSize)
buffers.push(new ParticleBuffer.ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize));
return buffers;
}
/**
* Creates one more particle buffer, because container has autoResize feature.
* @param container - The container to render using this ParticleRenderer
* @returns - The generated buffer
*/
_generateOneMoreBuffer(container) {
const batchSize = container._batchSize, dynamicPropertyFlags = container._properties;
return new ParticleBuffer.ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize);
}
/**
* Uploads the vertices.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their vertices uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadVertices(children, startIndex, amount, array, stride, offset) {
let w0 = 0, w1 = 0, h0 = 0, h1 = 0;
for (let i = 0; i < amount; ++i) {
const sprite = children[startIndex + i], texture = sprite._texture, sx = sprite.scale.x, sy = sprite.scale.y, trim = texture.trim, orig = texture.orig;
trim ? (w1 = trim.x - sprite.anchor.x * orig.width, w0 = w1 + trim.width, h1 = trim.y - sprite.anchor.y * orig.height, h0 = h1 + trim.height) : (w0 = orig.width * (1 - sprite.anchor.x), w1 = orig.width * -sprite.anchor.x, h0 = orig.height * (1 - sprite.anchor.y), h1 = orig.height * -sprite.anchor.y), array[offset] = w1 * sx, array[offset + 1] = h1 * sy, array[offset + stride] = w0 * sx, array[offset + stride + 1] = h1 * sy, array[offset + stride * 2] = w0 * sx, array[offset + stride * 2 + 1] = h0 * sy, array[offset + stride * 3] = w1 * sx, array[offset + stride * 3 + 1] = h0 * sy, offset += stride * 4;
}
}
/**
* Uploads the position.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their positions uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadPosition(children, startIndex, amount, array, stride, offset) {
for (let i = 0; i < amount; i++) {
const spritePosition = children[startIndex + i].position;
array[offset] = spritePosition.x, array[offset + 1] = spritePosition.y, array[offset + stride] = spritePosition.x, array[offset + stride + 1] = spritePosition.y, array[offset + stride * 2] = spritePosition.x, array[offset + stride * 2 + 1] = spritePosition.y, array[offset + stride * 3] = spritePosition.x, array[offset + stride * 3 + 1] = spritePosition.y, offset += stride * 4;
}
}
/**
* Uploads the rotation.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their rotation uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadRotation(children, startIndex, amount, array, stride, offset) {
for (let i = 0; i < amount; i++) {
const spriteRotation = children[startIndex + i].rotation;
array[offset] = spriteRotation, array[offset + stride] = spriteRotation, array[offset + stride * 2] = spriteRotation, array[offset + stride * 3] = spriteRotation, offset += stride * 4;
}
}
/**
* Uploads the UVs.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their rotation uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadUvs(children, startIndex, amount, array, stride, offset) {
for (let i = 0; i < amount; ++i) {
const textureUvs = children[startIndex + i]._texture._uvs;
textureUvs ? (array[offset] = textureUvs.x0, array[offset + 1] = textureUvs.y0, array[offset + stride] = textureUvs.x1, array[offset + stride + 1] = textureUvs.y1, array[offset + stride * 2] = textureUvs.x2, array[offset + stride * 2 + 1] = textureUvs.y2, array[offset + stride * 3] = textureUvs.x3, array[offset + stride * 3 + 1] = textureUvs.y3, offset += stride * 4) : (array[offset] = 0, array[offset + 1] = 0, array[offset + stride] = 0, array[offset + stride + 1] = 0, array[offset + stride * 2] = 0, array[offset + stride * 2 + 1] = 0, array[offset + stride * 3] = 0, array[offset + stride * 3 + 1] = 0, offset += stride * 4);
}
}
/**
* Uploads the tint.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their rotation uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadTint(children, startIndex, amount, array, stride, offset) {
for (let i = 0; i < amount; ++i) {
const sprite = children[startIndex + i], result = core.Color.shared.setValue(sprite._tintRGB).toPremultiplied(sprite.alpha, sprite.texture.baseTexture.alphaMode > 0);
array[offset] = result, array[offset + stride] = result, array[offset + stride * 2] = result, array[offset + stride * 3] = result, offset += stride * 4;
}
}
/** Destroys the ParticleRenderer. */
destroy() {
super.destroy(), this.shader && (this.shader.destroy(), this.shader = null), this.tempMatrix = null;
}
}
ParticleRenderer.extension = {
name: "particle",
type: core.ExtensionType.RendererPlugin
};
core.extensions.add(ParticleRenderer);
exports.ParticleRenderer = ParticleRenderer;
//# sourceMappingURL=ParticleRenderer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,184 @@
import { ObjectRenderer, Matrix, TYPES, Shader, State, utils, Color, ExtensionType, extensions } from "@pixi/core";
import { ParticleBuffer } from "./ParticleBuffer.mjs";
import fragment from "./particles.frag.mjs";
import vertex from "./particles.vert.mjs";
class ParticleRenderer extends ObjectRenderer {
/**
* @param renderer - The renderer this sprite batch works for.
*/
constructor(renderer) {
super(renderer), this.shader = null, this.properties = null, this.tempMatrix = new Matrix(), this.properties = [
// verticesData
{
attributeName: "aVertexPosition",
size: 2,
uploadFunction: this.uploadVertices,
offset: 0
},
// positionData
{
attributeName: "aPositionCoord",
size: 2,
uploadFunction: this.uploadPosition,
offset: 0
},
// rotationData
{
attributeName: "aRotation",
size: 1,
uploadFunction: this.uploadRotation,
offset: 0
},
// uvsData
{
attributeName: "aTextureCoord",
size: 2,
uploadFunction: this.uploadUvs,
offset: 0
},
// tintData
{
attributeName: "aColor",
size: 1,
type: TYPES.UNSIGNED_BYTE,
uploadFunction: this.uploadTint,
offset: 0
}
], this.shader = Shader.from(vertex, fragment, {}), this.state = State.for2d();
}
/**
* Renders the particle container object.
* @param container - The container to render using this ParticleRenderer.
*/
render(container) {
const children = container.children, maxSize = container._maxSize, batchSize = container._batchSize, renderer = this.renderer;
let totalChildren = children.length;
if (totalChildren === 0)
return;
totalChildren > maxSize && !container.autoResize && (totalChildren = maxSize);
let buffers = container._buffers;
buffers || (buffers = container._buffers = this.generateBuffers(container));
const baseTexture = children[0]._texture.baseTexture, premultiplied = baseTexture.alphaMode > 0;
this.state.blendMode = utils.correctBlendMode(container.blendMode, premultiplied), renderer.state.set(this.state);
const gl = renderer.gl, m = container.worldTransform.copyTo(this.tempMatrix);
m.prepend(renderer.globalUniforms.uniforms.projectionMatrix), this.shader.uniforms.translationMatrix = m.toArray(!0), this.shader.uniforms.uColor = Color.shared.setValue(container.tintRgb).premultiply(container.worldAlpha, premultiplied).toArray(this.shader.uniforms.uColor), this.shader.uniforms.uSampler = baseTexture, this.renderer.shader.bind(this.shader);
let updateStatic = !1;
for (let i = 0, j = 0; i < totalChildren; i += batchSize, j += 1) {
let amount = totalChildren - i;
amount > batchSize && (amount = batchSize), j >= buffers.length && buffers.push(this._generateOneMoreBuffer(container));
const buffer = buffers[j];
buffer.uploadDynamic(children, i, amount);
const bid = container._bufferUpdateIDs[j] || 0;
updateStatic = updateStatic || buffer._updateID < bid, updateStatic && (buffer._updateID = container._updateID, buffer.uploadStatic(children, i, amount)), renderer.geometry.bind(buffer.geometry), gl.drawElements(gl.TRIANGLES, amount * 6, gl.UNSIGNED_SHORT, 0);
}
}
/**
* Creates one particle buffer for each child in the container we want to render and updates internal properties.
* @param container - The container to render using this ParticleRenderer
* @returns - The buffers
*/
generateBuffers(container) {
const buffers = [], size = container._maxSize, batchSize = container._batchSize, dynamicPropertyFlags = container._properties;
for (let i = 0; i < size; i += batchSize)
buffers.push(new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize));
return buffers;
}
/**
* Creates one more particle buffer, because container has autoResize feature.
* @param container - The container to render using this ParticleRenderer
* @returns - The generated buffer
*/
_generateOneMoreBuffer(container) {
const batchSize = container._batchSize, dynamicPropertyFlags = container._properties;
return new ParticleBuffer(this.properties, dynamicPropertyFlags, batchSize);
}
/**
* Uploads the vertices.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their vertices uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadVertices(children, startIndex, amount, array, stride, offset) {
let w0 = 0, w1 = 0, h0 = 0, h1 = 0;
for (let i = 0; i < amount; ++i) {
const sprite = children[startIndex + i], texture = sprite._texture, sx = sprite.scale.x, sy = sprite.scale.y, trim = texture.trim, orig = texture.orig;
trim ? (w1 = trim.x - sprite.anchor.x * orig.width, w0 = w1 + trim.width, h1 = trim.y - sprite.anchor.y * orig.height, h0 = h1 + trim.height) : (w0 = orig.width * (1 - sprite.anchor.x), w1 = orig.width * -sprite.anchor.x, h0 = orig.height * (1 - sprite.anchor.y), h1 = orig.height * -sprite.anchor.y), array[offset] = w1 * sx, array[offset + 1] = h1 * sy, array[offset + stride] = w0 * sx, array[offset + stride + 1] = h1 * sy, array[offset + stride * 2] = w0 * sx, array[offset + stride * 2 + 1] = h0 * sy, array[offset + stride * 3] = w1 * sx, array[offset + stride * 3 + 1] = h0 * sy, offset += stride * 4;
}
}
/**
* Uploads the position.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their positions uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadPosition(children, startIndex, amount, array, stride, offset) {
for (let i = 0; i < amount; i++) {
const spritePosition = children[startIndex + i].position;
array[offset] = spritePosition.x, array[offset + 1] = spritePosition.y, array[offset + stride] = spritePosition.x, array[offset + stride + 1] = spritePosition.y, array[offset + stride * 2] = spritePosition.x, array[offset + stride * 2 + 1] = spritePosition.y, array[offset + stride * 3] = spritePosition.x, array[offset + stride * 3 + 1] = spritePosition.y, offset += stride * 4;
}
}
/**
* Uploads the rotation.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their rotation uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadRotation(children, startIndex, amount, array, stride, offset) {
for (let i = 0; i < amount; i++) {
const spriteRotation = children[startIndex + i].rotation;
array[offset] = spriteRotation, array[offset + stride] = spriteRotation, array[offset + stride * 2] = spriteRotation, array[offset + stride * 3] = spriteRotation, offset += stride * 4;
}
}
/**
* Uploads the UVs.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their rotation uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadUvs(children, startIndex, amount, array, stride, offset) {
for (let i = 0; i < amount; ++i) {
const textureUvs = children[startIndex + i]._texture._uvs;
textureUvs ? (array[offset] = textureUvs.x0, array[offset + 1] = textureUvs.y0, array[offset + stride] = textureUvs.x1, array[offset + stride + 1] = textureUvs.y1, array[offset + stride * 2] = textureUvs.x2, array[offset + stride * 2 + 1] = textureUvs.y2, array[offset + stride * 3] = textureUvs.x3, array[offset + stride * 3 + 1] = textureUvs.y3, offset += stride * 4) : (array[offset] = 0, array[offset + 1] = 0, array[offset + stride] = 0, array[offset + stride + 1] = 0, array[offset + stride * 2] = 0, array[offset + stride * 2 + 1] = 0, array[offset + stride * 3] = 0, array[offset + stride * 3 + 1] = 0, offset += stride * 4);
}
}
/**
* Uploads the tint.
* @param children - the array of sprites to render
* @param startIndex - the index to start from in the children array
* @param amount - the amount of children that will have their rotation uploaded
* @param array - The vertices to upload.
* @param stride - Stride to use for iteration.
* @param offset - Offset to start at.
*/
uploadTint(children, startIndex, amount, array, stride, offset) {
for (let i = 0; i < amount; ++i) {
const sprite = children[startIndex + i], result = Color.shared.setValue(sprite._tintRGB).toPremultiplied(sprite.alpha, sprite.texture.baseTexture.alphaMode > 0);
array[offset] = result, array[offset + stride] = result, array[offset + stride * 2] = result, array[offset + stride * 3] = result, offset += stride * 4;
}
}
/** Destroys the ParticleRenderer. */
destroy() {
super.destroy(), this.shader && (this.shader.destroy(), this.shader = null), this.tempMatrix = null;
}
}
ParticleRenderer.extension = {
name: "particle",
type: ExtensionType.RendererPlugin
};
extensions.add(ParticleRenderer);
export {
ParticleRenderer
};
//# sourceMappingURL=ParticleRenderer.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
"use strict";
var ParticleContainer = require("./ParticleContainer.js"), ParticleRenderer = require("./ParticleRenderer.js");
exports.ParticleContainer = ParticleContainer.ParticleContainer;
exports.ParticleRenderer = ParticleRenderer.ParticleRenderer;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}

View File

@@ -0,0 +1,7 @@
import { ParticleContainer } from "./ParticleContainer.mjs";
import { ParticleRenderer } from "./ParticleRenderer.mjs";
export {
ParticleContainer,
ParticleRenderer
};
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: !0 });
var fragment = `varying vec2 vTextureCoord;
varying vec4 vColor;
uniform sampler2D uSampler;
void main(void){
vec4 color = texture2D(uSampler, vTextureCoord) * vColor;
gl_FragColor = color;
}`;
exports.default = fragment;
//# sourceMappingURL=particles.frag.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"particles.frag.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}

View File

@@ -0,0 +1,13 @@
var fragment = `varying vec2 vTextureCoord;
varying vec4 vColor;
uniform sampler2D uSampler;
void main(void){
vec4 color = texture2D(uSampler, vTextureCoord) * vColor;
gl_FragColor = color;
}`;
export {
fragment as default
};
//# sourceMappingURL=particles.frag.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"particles.frag.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}

View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: !0 });
var vertex = `attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
attribute vec4 aColor;
attribute vec2 aPositionCoord;
attribute float aRotation;
uniform mat3 translationMatrix;
uniform vec4 uColor;
varying vec2 vTextureCoord;
varying vec4 vColor;
void main(void){
float x = (aVertexPosition.x) * cos(aRotation) - (aVertexPosition.y) * sin(aRotation);
float y = (aVertexPosition.x) * sin(aRotation) + (aVertexPosition.y) * cos(aRotation);
vec2 v = vec2(x, y);
v = v + aPositionCoord;
gl_Position = vec4((translationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0);
vTextureCoord = aTextureCoord;
vColor = aColor * uColor;
}
`;
exports.default = vertex;
//# sourceMappingURL=particles.vert.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"particles.vert.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,30 @@
var vertex = `attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
attribute vec4 aColor;
attribute vec2 aPositionCoord;
attribute float aRotation;
uniform mat3 translationMatrix;
uniform vec4 uColor;
varying vec2 vTextureCoord;
varying vec4 vColor;
void main(void){
float x = (aVertexPosition.x) * cos(aRotation) - (aVertexPosition.y) * sin(aRotation);
float y = (aVertexPosition.x) * sin(aRotation) + (aVertexPosition.y) * cos(aRotation);
vec2 v = vec2(x, y);
v = v + aPositionCoord;
gl_Position = vec4((translationMatrix * vec3(v, 1.0)).xy, 0.0, 1.0);
vTextureCoord = aTextureCoord;
vColor = aColor * uColor;
}
`;
export {
vertex as default
};
//# sourceMappingURL=particles.vert.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"particles.vert.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,39 @@
{
"name": "@pixi/particle-container",
"version": "7.4.2",
"main": "lib/index.js",
"module": "lib/index.mjs",
"types": "lib/index.d.ts",
"exports": {
".": {
"import": {
"types": "./lib/index.d.ts",
"default": "./lib/index.mjs"
},
"require": {
"types": "./lib/index.d.ts",
"default": "./lib/index.js"
}
}
},
"description": "Render many sprite particles as efficiently as possible",
"author": "Mat Groves",
"homepage": "http://pixijs.com/",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/pixijs/pixijs.git"
},
"publishConfig": {
"access": "public"
},
"files": [
"lib",
"*.d.ts"
],
"peerDependencies": {
"@pixi/core": "7.4.2",
"@pixi/display": "7.4.2",
"@pixi/sprite": "7.4.2"
}
}