UNPKG

@petkoneo/phaser3-rex-plugins

Version:
187 lines (156 loc) 5.82 kB
import MeshBase from '../../utils/MeshBase.js'; import ShatterRectangleToTriangles from '../../../../utils/math/triangulate/ShatterRectangleToTriangles.js'; import Face from './Face.js'; import { WorldXYToLocalXY } from '../../utils/LocalXY.js'; const IsPlainObject = Phaser.Utils.Objects.IsPlainObject; const GetValue = Phaser.Utils.Objects.GetValue; const GenerateGridVerts = Phaser.Geom.Mesh.GenerateGridVerts; const Vertex = Phaser.Geom.Mesh.Vertex; const DistanceSquared = Phaser.Math.Distance.Squared; const DefaultRingRadiusList = [1 / 27, 3 / 27, 9 / 27]; class ShatterImage extends MeshBase { constructor(scene, x, y, key, frame, config) { if (IsPlainObject(x)) { config = x; x = GetValue(config, 'x', 0); y = GetValue(config, 'y', 0); key = GetValue(config, 'key', null); frame = GetValue(config, 'frame', null); } super(scene, x, y, key, frame); this.type = 'rexShatterImage'; this.hideCCW = false; this.resetImage(); this.shatterCenter = { x: null, y: null }; this.setRingRadiusList(GetValue(config, 'ringRadiusList', DefaultRingRadiusList)); this.setSamplesPerRing(GetValue(config, 'samplesPerRing', 12)); this.setVariation(GetValue(config, 'variation', 0.25)); } setRingRadiusList(ringRadiusList) { this.ringRadiusList = ringRadiusList; return this; } setSamplesPerRing(samples) { this.samplesPerRing = samples; return this; } setVariation(variation) { this.variation = variation; return this; } resetImage() { this.setSizeToFrame(); this.clear(); this.dirtyCache[9] = -1; GenerateGridVerts({ mesh: this, width: this.frame.cutWidth / this.height, height: this.frame.cutHeight / this.height, }); this.setOrtho(this.width / this.height, 1); return this } shatter(centerX, centerY, config) { if (IsPlainObject(centerX)) { config = centerX; centerX = undefined; centerY = undefined; } if (IsPlainObject(config)) { if (config.hasOwnProperty('centerX')) { centerX = config.centerX; } if (config.hasOwnProperty('centerY')) { centerY = config.centerY; } if (config.hasOwnProperty('ringRadiusList')) { this.setRingRadiusList(config.ringRadiusList); } if (config.hasOwnProperty('samplesPerRing')) { this.setSamplesPerRing(config.samplesPerRing); } if (config.hasOwnProperty('variation')) { this.setVariation(config.variation); } } if (centerX === undefined) { centerX = this.width / 2; centerY = this.height / 2; } else { var worldXY = WorldXYToLocalXY(this, centerX, centerY); centerX = worldXY.x; centerY = worldXY.y; } this.shatterCenter.x = centerX; this.shatterCenter.y = centerY; // Clear faces and vertices this.clear(); this.dirtyCache[9] = -1; if ((this.width === 0) || (this.height === 0)) { return this; } var result = ShatterRectangleToTriangles({ width: this.width, height: this.height, center: this.shatterCenter, triangleOutput: false, ringRadiusList: this.ringRadiusList, variation: this.variation, samplesPerRing: this.samplesPerRing }) var vertices = result.vertices; var indices = result.indices; // Calculate vertex data var verticesData = []; var srcWidth = this.width; var srcHeight = this.height; var vHalfWidth = (this.frame.cutWidth / srcHeight) / 2; var vHalfHeight = (this.frame.cutHeight / srcHeight) / 2; var frameU0 = this.frame.u0; var frameU1 = this.frame.u1; var frameV0 = this.frame.v0; var frameV1 = this.frame.v1; var frameU = frameU1 - frameU0; var frameV = frameV1 - frameV0; for (var i = 0, cnt = vertices.length; i < cnt; i++) { var p = vertices[i]; var px = p[0]; var py = p[1]; verticesData.push({ g: DistanceSquared(centerX, centerY, px, py), x: (px / srcHeight) - vHalfWidth, y: (py / srcHeight) - vHalfHeight, u: frameU0 + (frameU * (px / srcWidth)), v: frameV0 + (frameV * (py / srcHeight)) }) } // Build face for (var i = 0, cnt = indices.length; i < cnt; i += 3) { var v0 = verticesData[indices[i + 0]]; var v1 = verticesData[indices[i + 1]]; var v2 = verticesData[indices[i + 2]]; var vert1 = new Vertex(v0.x, -v0.y, 0, v0.u, v0.v); var vert2 = new Vertex(v1.x, -v1.y, 0, v1.u, v1.v); var vert3 = new Vertex(v2.x, -v2.y, 0, v2.u, v2.v); var face = new Face(vert1, vert2, vert3); this.vertices.push(vert1, vert2, vert3); this.faces.push(face); // Sort faces from center face.g = Math.min(v0.g, v1.g, v2.g); } // Sort faces from center this.faces.sort(function (faceA, faceB) { return faceA.g - faceB.g; }) return this; } startUpdate() { this.ignoreDirtyCache = true; return this; } stopUpdate() { this.ignoreDirtyCache = false; return this; } } export default ShatterImage;