@flighthq/particles-formats 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/detect.d.ts +18 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +75 -0
- package/dist/detect.js.map +1 -0
- package/dist/formatRegistry.d.ts +60 -0
- package/dist/formatRegistry.d.ts.map +1 -0
- package/dist/formatRegistry.js +75 -0
- package/dist/formatRegistry.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/libgdxParse.d.ts +27 -0
- package/dist/libgdxParse.d.ts.map +1 -0
- package/dist/libgdxParse.js +316 -0
- package/dist/libgdxParse.js.map +1 -0
- package/dist/libgdxSchema.d.ts +68 -0
- package/dist/libgdxSchema.d.ts.map +1 -0
- package/dist/libgdxSchema.js +12 -0
- package/dist/libgdxSchema.js.map +1 -0
- package/dist/libgdxSerialize.d.ts +17 -0
- package/dist/libgdxSerialize.d.ts.map +1 -0
- package/dist/libgdxSerialize.js +295 -0
- package/dist/libgdxSerialize.js.map +1 -0
- package/dist/parseParticleConfig.d.ts +34 -0
- package/dist/parseParticleConfig.d.ts.map +1 -0
- package/dist/parseParticleConfig.js +96 -0
- package/dist/parseParticleConfig.js.map +1 -0
- package/dist/particleDesignerParse.d.ts +23 -0
- package/dist/particleDesignerParse.d.ts.map +1 -0
- package/dist/particleDesignerParse.js +214 -0
- package/dist/particleDesignerParse.js.map +1 -0
- package/dist/particleDesignerSchema.d.ts +51 -0
- package/dist/particleDesignerSchema.d.ts.map +1 -0
- package/dist/particleDesignerSchema.js +5 -0
- package/dist/particleDesignerSchema.js.map +1 -0
- package/dist/particleDesignerSerialize.d.ts +22 -0
- package/dist/particleDesignerSerialize.d.ts.map +1 -0
- package/dist/particleDesignerSerialize.js +209 -0
- package/dist/particleDesignerSerialize.js.map +1 -0
- package/dist/pixiParse.d.ts +18 -0
- package/dist/pixiParse.d.ts.map +1 -0
- package/dist/pixiParse.js +173 -0
- package/dist/pixiParse.js.map +1 -0
- package/dist/serializeResult.d.ts +15 -0
- package/dist/serializeResult.d.ts.map +1 -0
- package/dist/serializeResult.js +2 -0
- package/dist/serializeResult.js.map +1 -0
- package/dist/spineParse.d.ts +18 -0
- package/dist/spineParse.d.ts.map +1 -0
- package/dist/spineParse.js +263 -0
- package/dist/spineParse.js.map +1 -0
- package/dist/spineSchema.d.ts +41 -0
- package/dist/spineSchema.d.ts.map +1 -0
- package/dist/spineSchema.js +8 -0
- package/dist/spineSchema.js.map +1 -0
- package/dist/spineSerialize.d.ts +16 -0
- package/dist/spineSerialize.d.ts.map +1 -0
- package/dist/spineSerialize.js +108 -0
- package/dist/spineSerialize.js.map +1 -0
- package/dist/starlingPexParse.d.ts +29 -0
- package/dist/starlingPexParse.d.ts.map +1 -0
- package/dist/starlingPexParse.js +254 -0
- package/dist/starlingPexParse.js.map +1 -0
- package/dist/starlingPexSchema.d.ts +49 -0
- package/dist/starlingPexSchema.d.ts.map +1 -0
- package/dist/starlingPexSchema.js +15 -0
- package/dist/starlingPexSchema.js.map +1 -0
- package/dist/starlingPexSerialize.d.ts +20 -0
- package/dist/starlingPexSerialize.d.ts.map +1 -0
- package/dist/starlingPexSerialize.js +184 -0
- package/dist/starlingPexSerialize.js.map +1 -0
- package/dist/unityParse.d.ts +23 -0
- package/dist/unityParse.d.ts.map +1 -0
- package/dist/unityParse.js +347 -0
- package/dist/unityParse.js.map +1 -0
- package/dist/unitySchema.d.ts +109 -0
- package/dist/unitySchema.d.ts.map +1 -0
- package/dist/unitySchema.js +9 -0
- package/dist/unitySchema.js.map +1 -0
- package/dist/unitySerialize.d.ts +20 -0
- package/dist/unitySerialize.d.ts.map +1 -0
- package/dist/unitySerialize.js +148 -0
- package/dist/unitySerialize.js.map +1 -0
- package/package.json +38 -0
- package/src/detect.test.ts +99 -0
- package/src/formatRegistry.test.ts +118 -0
- package/src/libgdxParse.test.ts +309 -0
- package/src/libgdxSerialize.test.ts +279 -0
- package/src/parseParticleConfig.test.ts +447 -0
- package/src/particleDesignerParse.test.ts +279 -0
- package/src/particleDesignerSerialize.test.ts +113 -0
- package/src/pixiParse.test.ts +131 -0
- package/src/spineParse.test.ts +289 -0
- package/src/spineSerialize.test.ts +81 -0
- package/src/starlingPexParse.test.ts +154 -0
- package/src/starlingPexSerialize.test.ts +115 -0
- package/src/unityParse.test.ts +328 -0
- package/src/unitySerialize.test.ts +77 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { particleColorCurveToKeyframes, particleCurveToKeyframes } from '@flighthq/particles';
|
|
2
|
+
const RAD2DEG = 180 / Math.PI;
|
|
3
|
+
function rgbToHex(r, g, b) {
|
|
4
|
+
const byte = (v) => Math.round(Math.max(0, Math.min(1, v)) * 255)
|
|
5
|
+
.toString(16)
|
|
6
|
+
.padStart(2, '0');
|
|
7
|
+
return `${byte(r)}${byte(g)}${byte(b)}`;
|
|
8
|
+
}
|
|
9
|
+
function configToDocument(config, existing) {
|
|
10
|
+
const angleMid = Math.atan2(-config.directionY, config.directionX) * RAD2DEG;
|
|
11
|
+
const spreadDeg = config.spread * RAD2DEG;
|
|
12
|
+
return {
|
|
13
|
+
name: existing.name ?? '',
|
|
14
|
+
maxParticles: config.maxParticles,
|
|
15
|
+
continuous: config.loop,
|
|
16
|
+
duration: config.duration > 0 && !config.loop ? config.duration * 1000 : (existing.duration ?? -1),
|
|
17
|
+
emission: { low: config.spawnRate * 0.8, high: config.spawnRate * 1.2 },
|
|
18
|
+
life: { low: config.lifetimeMin * 1000, high: config.lifetimeMax * 1000 },
|
|
19
|
+
lifeOffset: existing.lifeOffset ?? { low: 0, high: 0 },
|
|
20
|
+
x: existing.x ?? { low: 0, high: 0 },
|
|
21
|
+
y: existing.y ?? { low: 0, high: 0 },
|
|
22
|
+
spawnShape: config.emitterShape === 'rect' ? 'ellipse' : config.emitterShape === 'circle' ? 'ellipse' : 'point',
|
|
23
|
+
spawnWidth: config.emitterShape === 'circle'
|
|
24
|
+
? { low: config.emitterRadius * 2, high: config.emitterRadius * 2 }
|
|
25
|
+
: config.emitterShape === 'rect'
|
|
26
|
+
? { low: config.emitterWidth, high: config.emitterWidth }
|
|
27
|
+
: { low: 0, high: 0 },
|
|
28
|
+
spawnHeight: config.emitterShape === 'circle'
|
|
29
|
+
? { low: config.emitterRadius * 2, high: config.emitterRadius * 2 }
|
|
30
|
+
: config.emitterShape === 'rect'
|
|
31
|
+
? { low: config.emitterHeight, high: config.emitterHeight }
|
|
32
|
+
: { low: 0, high: 0 },
|
|
33
|
+
velocity: { low: config.speedMin, high: config.speedMax },
|
|
34
|
+
angle: { low: angleMid - spreadDeg, high: angleMid + spreadDeg },
|
|
35
|
+
rotation: { low: config.rotationSpeedMin * RAD2DEG, high: config.rotationSpeedMax * RAD2DEG },
|
|
36
|
+
wind: { low: 0, high: 0 }, // gravityX not representable as wind range
|
|
37
|
+
gravity: { low: config.gravityY, high: config.gravityY },
|
|
38
|
+
scale: { low: config.scaleMin, high: config.scaleMax },
|
|
39
|
+
scaleEnd: {
|
|
40
|
+
low: config.scaleMin * config.scaleEnd,
|
|
41
|
+
high: config.scaleMax * config.scaleEnd,
|
|
42
|
+
},
|
|
43
|
+
// A baked color/alpha curve serializes back to a full multi-stop timeline;
|
|
44
|
+
// otherwise emit the 2-stop start→end timeline.
|
|
45
|
+
tint: config.colorCurve
|
|
46
|
+
? particleColorCurveToKeyframes(config.colorCurve).map((k) => ({ time: k.time, color: rgbToHex(k.r, k.g, k.b) }))
|
|
47
|
+
: [
|
|
48
|
+
{ time: 0, color: rgbToHex(config.colorStartR, config.colorStartG, config.colorStartB) },
|
|
49
|
+
{ time: 1, color: rgbToHex(config.colorEndR, config.colorEndG, config.colorEndB) },
|
|
50
|
+
],
|
|
51
|
+
alpha: config.alphaCurve
|
|
52
|
+
? particleCurveToKeyframes(config.alphaCurve).map((k) => ({ time: k.time, alpha: k.value }))
|
|
53
|
+
: [
|
|
54
|
+
{ time: 0, alpha: config.alphaStart },
|
|
55
|
+
{ time: 1, alpha: config.alphaEnd },
|
|
56
|
+
],
|
|
57
|
+
blendMode: configToSpineBlendMode(config.blendMode) ?? existing.blendMode ?? 'normal',
|
|
58
|
+
premultiplied: existing.premultiplied ?? false,
|
|
59
|
+
images: existing.images ?? [],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function configToSpineBlendMode(mode) {
|
|
63
|
+
if (mode === 'add')
|
|
64
|
+
return 'additive';
|
|
65
|
+
if (mode === 'multiply')
|
|
66
|
+
return 'multiply';
|
|
67
|
+
if (mode === 'screen')
|
|
68
|
+
return 'screen';
|
|
69
|
+
if (mode === 'normal')
|
|
70
|
+
return 'normal';
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/** Serialise a ParticleEmitterConfig to a Spine particle effect JSON string.
|
|
74
|
+
*
|
|
75
|
+
* Pass the `document` returned by `parseSpineParticle` to preserve fields
|
|
76
|
+
* that don't round-trip through the config (name, image list, blend mode, etc.). */
|
|
77
|
+
export function serializeSpineParticle(config, existing) {
|
|
78
|
+
const doc = configToDocument(config, existing ?? {});
|
|
79
|
+
return JSON.stringify(doc, null, 2);
|
|
80
|
+
}
|
|
81
|
+
/** Serialise a ParticleEmitterConfig to a Spine particle effect JSON string,
|
|
82
|
+
* returning both the serialized text and any warnings for features the format
|
|
83
|
+
* cannot represent.
|
|
84
|
+
*
|
|
85
|
+
* Pass the `document` returned by `parseSpineParticleDocument` to preserve
|
|
86
|
+
* fields that don't round-trip through the config. */
|
|
87
|
+
export function serializeSpineParticleDocument(config, existing) {
|
|
88
|
+
const text = serializeSpineParticle(config, existing);
|
|
89
|
+
const warnings = collectSpineSerializeWarnings(config);
|
|
90
|
+
return { text, warnings };
|
|
91
|
+
}
|
|
92
|
+
function collectSpineSerializeWarnings(config) {
|
|
93
|
+
const warnings = [];
|
|
94
|
+
if (config.burstCount > 0) {
|
|
95
|
+
warnings.push('Emission bursts are not supported by the Spine particle format and were ignored');
|
|
96
|
+
}
|
|
97
|
+
if (config.colorEndVarianceR !== 0 || config.colorEndVarianceG !== 0 || config.colorEndVarianceB !== 0) {
|
|
98
|
+
warnings.push('colorEndVariance is not supported by the Spine format and was ignored');
|
|
99
|
+
}
|
|
100
|
+
if (config.colorStartVarianceR !== 0 || config.colorStartVarianceG !== 0 || config.colorStartVarianceB !== 0) {
|
|
101
|
+
warnings.push('colorStartVariance is not supported by the Spine format and was ignored');
|
|
102
|
+
}
|
|
103
|
+
if (config.velocityInheritance !== 0) {
|
|
104
|
+
warnings.push('velocityInheritance is not supported by the Spine format and was ignored');
|
|
105
|
+
}
|
|
106
|
+
return warnings;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=spineSerialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spineSerialize.js","sourceRoot":"","sources":["../src/spineSerialize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ParticleEmitterConfig } from '@flighthq/types';
|
|
2
|
+
import type { StarlingPexDocument } from './starlingPexSchema';
|
|
3
|
+
export interface StarlingPexParseOptions {
|
|
4
|
+
/** Side length of the particle texture in pixels, used to normalise pixel sizes
|
|
5
|
+
* to dimensionless scale multipliers. Defaults to 1 (no normalisation). */
|
|
6
|
+
textureSize?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface StarlingPexParseResult {
|
|
9
|
+
config: ParticleEmitterConfig;
|
|
10
|
+
document: StarlingPexDocument;
|
|
11
|
+
/** Features present in the source that the common-subset importer cannot
|
|
12
|
+
* represent and silently dropped — surface these in your asset pipeline. */
|
|
13
|
+
warnings: string[];
|
|
14
|
+
}
|
|
15
|
+
/** @deprecated Use `StarlingPexParseResult`. */
|
|
16
|
+
export type StarlingPexParsed = StarlingPexParseResult;
|
|
17
|
+
/** Parse a Starling / Sparrow PEX XML string directly to a ParticleEmitterConfig.
|
|
18
|
+
*
|
|
19
|
+
* Handles both attribute-style (`<attribute name="X" value="Y"/>`) and
|
|
20
|
+
* element-style (plist-like key/value pairs) PEX variants.
|
|
21
|
+
* Single-pass: no intermediate document object is allocated.
|
|
22
|
+
* Use `parseStarlingPexDocument` instead when you need round-trip serialisation.
|
|
23
|
+
* Throws a clear, format-tagged error when the input is not XML. */
|
|
24
|
+
export declare function parseStarlingPex(xml: string, options?: StarlingPexParseOptions): ParticleEmitterConfig;
|
|
25
|
+
/** Parse a Starling / Sparrow PEX XML string and preserve the full document for
|
|
26
|
+
* round-trip serialisation via `serializeStarlingPex`.
|
|
27
|
+
* Throws a clear, format-tagged error when the input is not XML. */
|
|
28
|
+
export declare function parseStarlingPexDocument(xml: string, options?: StarlingPexParseOptions): StarlingPexParseResult;
|
|
29
|
+
//# sourceMappingURL=starlingPexParse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"starlingPexParse.d.ts","sourceRoot":"","sources":["../src/starlingPexParse.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAqB,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAEhF,OAAO,KAAK,EAAoB,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,MAAM,WAAW,uBAAuB;IACtC;gFAC4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,EAAE,mBAAmB,CAAC;IAC9B;iFAC6E;IAC7E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,gDAAgD;AAChD,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;AAEvD;;;;;;qEAMqE;AACrE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,qBAAqB,CAOtG;AAED;;qEAEqE;AACrE,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,sBAAsB,CAW/G"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { createParticleEmitterConfig } from '@flighthq/particles';
|
|
2
|
+
/** Parse a Starling / Sparrow PEX XML string directly to a ParticleEmitterConfig.
|
|
3
|
+
*
|
|
4
|
+
* Handles both attribute-style (`<attribute name="X" value="Y"/>`) and
|
|
5
|
+
* element-style (plist-like key/value pairs) PEX variants.
|
|
6
|
+
* Single-pass: no intermediate document object is allocated.
|
|
7
|
+
* Use `parseStarlingPexDocument` instead when you need round-trip serialisation.
|
|
8
|
+
* Throws a clear, format-tagged error when the input is not XML. */
|
|
9
|
+
export function parseStarlingPex(xml, options) {
|
|
10
|
+
if (typeof xml !== 'string' || !xml.trim().startsWith('<')) {
|
|
11
|
+
throw new Error('Invalid Starling PEX: input must be an XML string beginning with <');
|
|
12
|
+
}
|
|
13
|
+
const d = parsePexXml(xml);
|
|
14
|
+
const doc = dictToDocument(d);
|
|
15
|
+
return documentToConfig(doc, options?.textureSize ?? 1);
|
|
16
|
+
}
|
|
17
|
+
/** Parse a Starling / Sparrow PEX XML string and preserve the full document for
|
|
18
|
+
* round-trip serialisation via `serializeStarlingPex`.
|
|
19
|
+
* Throws a clear, format-tagged error when the input is not XML. */
|
|
20
|
+
export function parseStarlingPexDocument(xml, options) {
|
|
21
|
+
if (typeof xml !== 'string' || !xml.trim().startsWith('<')) {
|
|
22
|
+
throw new Error('Invalid Starling PEX: input must be an XML string beginning with <');
|
|
23
|
+
}
|
|
24
|
+
const d = parsePexXml(xml);
|
|
25
|
+
const doc = dictToDocument(d);
|
|
26
|
+
return {
|
|
27
|
+
config: documentToConfig(doc, options?.textureSize ?? 1),
|
|
28
|
+
document: doc,
|
|
29
|
+
warnings: collectStarlingPexWarnings(doc),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const DEG2RAD = Math.PI / 180;
|
|
33
|
+
function collectStarlingPexWarnings(doc) {
|
|
34
|
+
const warnings = [];
|
|
35
|
+
if (doc.emitterType === 1) {
|
|
36
|
+
warnings.push('Radial (emitterType=1) emitter was approximated as a gravity emitter; radial motion is not simulated');
|
|
37
|
+
}
|
|
38
|
+
if (doc.radialAcceleration !== 0 || doc.radialAccelVariance !== 0) {
|
|
39
|
+
warnings.push('radialAcceleration is not supported and was ignored');
|
|
40
|
+
}
|
|
41
|
+
if (doc.tangentialAcceleration !== 0 || doc.tangentialAccelVariance !== 0) {
|
|
42
|
+
warnings.push('tangentialAcceleration is not supported and was ignored');
|
|
43
|
+
}
|
|
44
|
+
return warnings;
|
|
45
|
+
}
|
|
46
|
+
function dictToDocument(d) {
|
|
47
|
+
const WHITE = { red: 1, green: 1, blue: 1, alpha: 1 };
|
|
48
|
+
const CLEAR = { red: 1, green: 1, blue: 1, alpha: 0 };
|
|
49
|
+
const ZERO = { red: 0, green: 0, blue: 0, alpha: 0 };
|
|
50
|
+
return {
|
|
51
|
+
maxParticles: pNum(d, 'maxParticles', 200) | 0,
|
|
52
|
+
emitterType: (pNum(d, 'emitterType', 0) === 1 ? 1 : 0),
|
|
53
|
+
duration: pNum(d, 'duration', -1),
|
|
54
|
+
particleLifespan: pNum(d, 'particleLifespan', 1),
|
|
55
|
+
particleLifespanVariance: pNum(d, 'particleLifespanVariance', 0),
|
|
56
|
+
speed: pNum(d, 'speed', 100),
|
|
57
|
+
speedVariance: pNum(d, 'speedVariance', 0),
|
|
58
|
+
angle: pNum(d, 'angle', 90),
|
|
59
|
+
angleVariance: pNum(d, 'angleVariance', 0),
|
|
60
|
+
gravityx: pNum(d, 'gravityx', 0),
|
|
61
|
+
gravityy: pNum(d, 'gravityy', 0),
|
|
62
|
+
sourcePositionVariancex: pNum(d, 'sourcePositionVariancex', 0),
|
|
63
|
+
sourcePositionVariancey: pNum(d, 'sourcePositionVariancey', 0),
|
|
64
|
+
startParticleSize: pNum(d, 'startParticleSize', 32),
|
|
65
|
+
startParticleSizeVariance: pNum(d, 'startParticleSizeVariance', 0),
|
|
66
|
+
finishParticleSize: pNum(d, 'finishParticleSize', 16),
|
|
67
|
+
finishParticleSizeVariance: pNum(d, 'finishParticleSizeVariance', 0),
|
|
68
|
+
startColor: pColor(d, 'startColor', WHITE),
|
|
69
|
+
startColorVariance: pColor(d, 'startColorVariance', ZERO),
|
|
70
|
+
finishColor: pColor(d, 'finishColor', CLEAR),
|
|
71
|
+
finishColorVariance: pColor(d, 'finishColorVariance', ZERO),
|
|
72
|
+
rotationStart: pNum(d, 'rotationStart', 0),
|
|
73
|
+
rotationStartVariance: pNum(d, 'rotationStartVariance', 0),
|
|
74
|
+
rotationEnd: pNum(d, 'rotationEnd', 0),
|
|
75
|
+
rotationEndVariance: pNum(d, 'rotationEndVariance', 0),
|
|
76
|
+
maxRadius: pNum(d, 'maxRadius', 0),
|
|
77
|
+
maxRadiusVariance: pNum(d, 'maxRadiusVariance', 0),
|
|
78
|
+
minRadius: pNum(d, 'minRadius', 0),
|
|
79
|
+
minRadiusVariance: pNum(d, 'minRadiusVariance', 0),
|
|
80
|
+
rotatePerSecond: pNum(d, 'rotatePerSecond', 0),
|
|
81
|
+
rotatePerSecondVariance: pNum(d, 'rotatePerSecondVariance', 0),
|
|
82
|
+
radialAcceleration: pNum(d, 'radialAcceleration', 0),
|
|
83
|
+
radialAccelVariance: pNum(d, 'radialAccelVariance', 0),
|
|
84
|
+
tangentialAcceleration: pNum(d, 'tangentialAcceleration', 0),
|
|
85
|
+
tangentialAccelVariance: pNum(d, 'tangentialAccelVariance', 0),
|
|
86
|
+
blendFuncSource: pNum(d, 'blendFuncSource', 770),
|
|
87
|
+
blendFuncDestination: pNum(d, 'blendFuncDestination', 771),
|
|
88
|
+
textureFileName: pStr(d, 'textureFileName', ''),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function documentToConfig(doc, textureSize) {
|
|
92
|
+
const angleRad = doc.angle * DEG2RAD;
|
|
93
|
+
const lifespan = doc.particleLifespan;
|
|
94
|
+
const lifespanVar = doc.particleLifespanVariance;
|
|
95
|
+
const speed = doc.speed;
|
|
96
|
+
const speedVar = doc.speedVariance;
|
|
97
|
+
const vx = doc.sourcePositionVariancex;
|
|
98
|
+
const vy = doc.sourcePositionVariancey;
|
|
99
|
+
const emitterShape = vx === 0 && vy === 0 ? 'point' : vx === vy ? 'circle' : 'rect';
|
|
100
|
+
const startSize = doc.startParticleSize / textureSize;
|
|
101
|
+
const startVar = doc.startParticleSizeVariance / textureSize;
|
|
102
|
+
const finishSize = doc.finishParticleSize / textureSize;
|
|
103
|
+
const rotStart = doc.rotationStart;
|
|
104
|
+
const rotEnd = doc.rotationEnd;
|
|
105
|
+
const rotStartVar = doc.rotationStartVariance;
|
|
106
|
+
const rotEndVar = doc.rotationEndVariance;
|
|
107
|
+
const lifetimeMid = lifespan + lifespanVar * 0.5 || 1;
|
|
108
|
+
const rotSpeedMid = ((rotStart + rotEnd) * 0.5 * DEG2RAD) / lifetimeMid;
|
|
109
|
+
const rotSpeedVar = (Math.max(rotStartVar, rotEndVar) * DEG2RAD) / lifetimeMid;
|
|
110
|
+
const pdDuration = doc.duration;
|
|
111
|
+
return createParticleEmitterConfig({
|
|
112
|
+
maxParticles: doc.maxParticles,
|
|
113
|
+
loop: pdDuration <= 0,
|
|
114
|
+
duration: pdDuration > 0 ? pdDuration : 0,
|
|
115
|
+
lifetimeMin: Math.max(0, lifespan - lifespanVar),
|
|
116
|
+
lifetimeMax: lifespan + lifespanVar,
|
|
117
|
+
speedMin: Math.max(0, speed - speedVar),
|
|
118
|
+
speedMax: speed + speedVar,
|
|
119
|
+
directionX: Math.cos(angleRad),
|
|
120
|
+
directionY: -Math.sin(angleRad),
|
|
121
|
+
spread: doc.angleVariance * DEG2RAD,
|
|
122
|
+
gravityX: doc.gravityx,
|
|
123
|
+
gravityY: doc.gravityy,
|
|
124
|
+
emitterShape,
|
|
125
|
+
emitterRadius: emitterShape === 'circle' ? vx : 0,
|
|
126
|
+
emitterWidth: emitterShape === 'rect' ? vx * 2 : 0,
|
|
127
|
+
emitterHeight: emitterShape === 'rect' ? vy * 2 : 0,
|
|
128
|
+
scaleMin: Math.max(0, startSize - startVar),
|
|
129
|
+
scaleMax: startSize + startVar,
|
|
130
|
+
scaleEnd: startSize > 0 ? finishSize / startSize : 1,
|
|
131
|
+
colorStartR: doc.startColor.red,
|
|
132
|
+
colorStartG: doc.startColor.green,
|
|
133
|
+
colorStartB: doc.startColor.blue,
|
|
134
|
+
colorStartVarianceR: doc.startColorVariance.red,
|
|
135
|
+
colorStartVarianceG: doc.startColorVariance.green,
|
|
136
|
+
colorStartVarianceB: doc.startColorVariance.blue,
|
|
137
|
+
colorEndR: doc.finishColor.red,
|
|
138
|
+
colorEndG: doc.finishColor.green,
|
|
139
|
+
colorEndB: doc.finishColor.blue,
|
|
140
|
+
colorEndVarianceR: doc.finishColorVariance.red,
|
|
141
|
+
colorEndVarianceG: doc.finishColorVariance.green,
|
|
142
|
+
colorEndVarianceB: doc.finishColorVariance.blue,
|
|
143
|
+
alphaStart: doc.startColor.alpha,
|
|
144
|
+
alphaEnd: doc.finishColor.alpha,
|
|
145
|
+
rotationSpeedMin: rotSpeedMid - rotSpeedVar,
|
|
146
|
+
rotationSpeedMax: rotSpeedMid + rotSpeedVar,
|
|
147
|
+
blendMode: pexBlendMode(doc.blendFuncSource, doc.blendFuncDestination),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/** Minimal XML attribute extractor. Reads `name="..."` and `value="..."` from self-closing tags. */
|
|
151
|
+
function extractAttr(tag, attrName) {
|
|
152
|
+
const re = new RegExp(`${attrName}\\s*=\\s*["']([^"']*)["']`);
|
|
153
|
+
const m = re.exec(tag);
|
|
154
|
+
return m ? m[1] : null;
|
|
155
|
+
}
|
|
156
|
+
function pColor(d, prefix, defColor) {
|
|
157
|
+
// Try dot-notation (from attribute-style) first, then direct keys.
|
|
158
|
+
const r = pNum(d, `${prefix}.red`, pNum(d, `${prefix}Red`, defColor.red));
|
|
159
|
+
const g = pNum(d, `${prefix}.green`, pNum(d, `${prefix}Green`, defColor.green));
|
|
160
|
+
const b = pNum(d, `${prefix}.blue`, pNum(d, `${prefix}Blue`, defColor.blue));
|
|
161
|
+
const a = pNum(d, `${prefix}.alpha`, pNum(d, `${prefix}Alpha`, defColor.alpha));
|
|
162
|
+
return { red: r, green: g, blue: b, alpha: a };
|
|
163
|
+
}
|
|
164
|
+
function pexBlendMode(src, dst) {
|
|
165
|
+
if ((src === 770 || src === 1) && dst === 1)
|
|
166
|
+
return 'add';
|
|
167
|
+
if (src === 770 && dst === 771)
|
|
168
|
+
return 'normal';
|
|
169
|
+
if (src === 1 && dst === 771)
|
|
170
|
+
return 'normal';
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
function pNum(d, key, def = 0) {
|
|
174
|
+
const v = d[key];
|
|
175
|
+
if (v === undefined)
|
|
176
|
+
return def;
|
|
177
|
+
const n = parseFloat(v);
|
|
178
|
+
return Number.isFinite(n) ? n : def;
|
|
179
|
+
}
|
|
180
|
+
/** Parse the PEX XML into a flat key/value dict supporting both attribute-style and element-style. */
|
|
181
|
+
function parsePexXml(xml) {
|
|
182
|
+
const dict = {};
|
|
183
|
+
// Pass 1: attribute-style <attribute name="X" value="Y"/>
|
|
184
|
+
const ATTR_RE = /<attribute\b([^>]*)\/>/gi;
|
|
185
|
+
let m;
|
|
186
|
+
while ((m = ATTR_RE.exec(xml)) !== null) {
|
|
187
|
+
const tag = m[1];
|
|
188
|
+
const name = extractAttr(tag, 'name');
|
|
189
|
+
const value = extractAttr(tag, 'value');
|
|
190
|
+
if (name !== null && value !== null)
|
|
191
|
+
dict[name] = value;
|
|
192
|
+
}
|
|
193
|
+
// Pass 2: color attribute-style <attribute name="X" red="R" green="G" blue="B" alpha="A"/>
|
|
194
|
+
const COL_RE = /<attribute\b([^>]*)\/>/gi;
|
|
195
|
+
while ((m = COL_RE.exec(xml)) !== null) {
|
|
196
|
+
const tag = m[1];
|
|
197
|
+
const name = extractAttr(tag, 'name');
|
|
198
|
+
if (name === null)
|
|
199
|
+
continue;
|
|
200
|
+
const red = extractAttr(tag, 'red');
|
|
201
|
+
const green = extractAttr(tag, 'green');
|
|
202
|
+
const blue = extractAttr(tag, 'blue');
|
|
203
|
+
const alpha = extractAttr(tag, 'alpha');
|
|
204
|
+
if (red !== null)
|
|
205
|
+
dict[`${name}.red`] = red;
|
|
206
|
+
if (green !== null)
|
|
207
|
+
dict[`${name}.green`] = green;
|
|
208
|
+
if (blue !== null)
|
|
209
|
+
dict[`${name}.blue`] = blue;
|
|
210
|
+
if (alpha !== null)
|
|
211
|
+
dict[`${name}.alpha`] = alpha;
|
|
212
|
+
}
|
|
213
|
+
// Pass 3: element-style <key>X</key>...<real/integer/string>Y</...> (plist variant)
|
|
214
|
+
const TAG_RE = /<(\/?)(\w+)([^>]*)>/g;
|
|
215
|
+
let currentKey = null;
|
|
216
|
+
let inTag = null;
|
|
217
|
+
let lastTagEnd = 0;
|
|
218
|
+
while ((m = TAG_RE.exec(xml)) !== null) {
|
|
219
|
+
const [full, close, name, attrs] = m;
|
|
220
|
+
const isSelfClose = attrs.trimEnd().endsWith('/') || full.endsWith('/>');
|
|
221
|
+
const text = xml.slice(lastTagEnd, m.index).trim();
|
|
222
|
+
lastTagEnd = m.index + full.length;
|
|
223
|
+
if (!close && !isSelfClose) {
|
|
224
|
+
if (name === 'key')
|
|
225
|
+
inTag = 'key';
|
|
226
|
+
else if (name === 'integer' || name === 'real' || name === 'string')
|
|
227
|
+
inTag = name;
|
|
228
|
+
}
|
|
229
|
+
else if (isSelfClose) {
|
|
230
|
+
if ((name === 'true' || name === 'false') && currentKey !== null && !(currentKey in dict)) {
|
|
231
|
+
dict[currentKey] = name;
|
|
232
|
+
currentKey = null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
if (name === 'key' && inTag === 'key') {
|
|
237
|
+
currentKey = text || null;
|
|
238
|
+
inTag = null;
|
|
239
|
+
}
|
|
240
|
+
else if (currentKey !== null && !(currentKey in dict)) {
|
|
241
|
+
if ((name === 'integer' || name === 'real' || name === 'string') && inTag === name) {
|
|
242
|
+
dict[currentKey] = text;
|
|
243
|
+
currentKey = null;
|
|
244
|
+
inTag = null;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return dict;
|
|
250
|
+
}
|
|
251
|
+
function pStr(d, key, def = '') {
|
|
252
|
+
return d[key] ?? def;
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=starlingPexParse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"starlingPexParse.js","sourceRoot":"","sources":["../src/starlingPexParse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface StarlingPexColor {
|
|
2
|
+
red: number;
|
|
3
|
+
green: number;
|
|
4
|
+
blue: number;
|
|
5
|
+
alpha: number;
|
|
6
|
+
}
|
|
7
|
+
/** Full Starling PEX particle document. */
|
|
8
|
+
export interface StarlingPexDocument {
|
|
9
|
+
maxParticles: number;
|
|
10
|
+
/** Emitter type: 0 = gravity, 1 = radial. */
|
|
11
|
+
emitterType: 0 | 1;
|
|
12
|
+
duration: number;
|
|
13
|
+
particleLifespan: number;
|
|
14
|
+
particleLifespanVariance: number;
|
|
15
|
+
speed: number;
|
|
16
|
+
speedVariance: number;
|
|
17
|
+
angle: number;
|
|
18
|
+
angleVariance: number;
|
|
19
|
+
gravityx: number;
|
|
20
|
+
gravityy: number;
|
|
21
|
+
sourcePositionVariancex: number;
|
|
22
|
+
sourcePositionVariancey: number;
|
|
23
|
+
startParticleSize: number;
|
|
24
|
+
startParticleSizeVariance: number;
|
|
25
|
+
finishParticleSize: number;
|
|
26
|
+
finishParticleSizeVariance: number;
|
|
27
|
+
startColor: StarlingPexColor;
|
|
28
|
+
startColorVariance: StarlingPexColor;
|
|
29
|
+
finishColor: StarlingPexColor;
|
|
30
|
+
finishColorVariance: StarlingPexColor;
|
|
31
|
+
rotationStart: number;
|
|
32
|
+
rotationStartVariance: number;
|
|
33
|
+
rotationEnd: number;
|
|
34
|
+
rotationEndVariance: number;
|
|
35
|
+
maxRadius: number;
|
|
36
|
+
maxRadiusVariance: number;
|
|
37
|
+
minRadius: number;
|
|
38
|
+
minRadiusVariance: number;
|
|
39
|
+
rotatePerSecond: number;
|
|
40
|
+
rotatePerSecondVariance: number;
|
|
41
|
+
radialAcceleration: number;
|
|
42
|
+
radialAccelVariance: number;
|
|
43
|
+
tangentialAcceleration: number;
|
|
44
|
+
tangentialAccelVariance: number;
|
|
45
|
+
blendFuncSource: number;
|
|
46
|
+
blendFuncDestination: number;
|
|
47
|
+
textureFileName: string;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=starlingPexSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"starlingPexSchema.d.ts","sourceRoot":"","sources":["../src/starlingPexSchema.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,MAAM,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB,EAAE,MAAM,CAAC;IAChC,uBAAuB,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yBAAyB,EAAE,MAAM,CAAC;IAClC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,MAAM,CAAC;IACnC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,kBAAkB,EAAE,gBAAgB,CAAC;IACrC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,mBAAmB,EAAE,gBAAgB,CAAC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;CACzB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Starling / Sparrow PEX particle format schema.
|
|
2
|
+
// The PEX format is an XML particle descriptor popularised by the Sparrow framework
|
|
3
|
+
// and used by Starling, Cocos2d-x, and various OpenFL/Starling toolchains.
|
|
4
|
+
// It differs from Particle Designer's plist in that values are stored as XML attributes
|
|
5
|
+
// rather than nested key/value pairs: <attribute name="key" value="val"/>.
|
|
6
|
+
//
|
|
7
|
+
// Two common sub-variants:
|
|
8
|
+
// - "attribute" style: <attribute name="key" value="v"/> (original Sparrow/Starling)
|
|
9
|
+
// - "element" style: identical to Particle Designer plist (common in some exporters)
|
|
10
|
+
// This parser handles both.
|
|
11
|
+
//
|
|
12
|
+
// Field naming follows the Starling PEX 2.x convention.
|
|
13
|
+
// Units: time in seconds, sizes in pixels, angles in degrees.
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=starlingPexSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"starlingPexSchema.js","sourceRoot":"","sources":["../src/starlingPexSchema.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,oFAAoF;AACpF,2EAA2E;AAC3E,wFAAwF;AACxF,2EAA2E;AAC3E,EAAE;AACF,2BAA2B;AAC3B,sFAAsF;AACtF,sFAAsF;AACtF,4BAA4B;AAC5B,EAAE;AACF,wDAAwD;AACxD,8DAA8D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ParticleEmitterConfig } from '@flighthq/types';
|
|
2
|
+
import type { ParticleSerializeResult } from './serializeResult';
|
|
3
|
+
import type { StarlingPexDocument } from './starlingPexSchema';
|
|
4
|
+
export interface StarlingPexSerializeOptions {
|
|
5
|
+
/** Side length of the particle texture in pixels — reverses the normalisation
|
|
6
|
+
* applied during parsing. Defaults to 1. */
|
|
7
|
+
textureSize?: number;
|
|
8
|
+
}
|
|
9
|
+
/** Serialise a ParticleEmitterConfig to a Starling / Sparrow PEX XML string
|
|
10
|
+
* (attribute style).
|
|
11
|
+
*
|
|
12
|
+
* Pass the `document` returned by `parseStarlingPexDocument` to preserve fields
|
|
13
|
+
* that don't round-trip through the config (texture filename, emitter type,
|
|
14
|
+
* radial parameters). */
|
|
15
|
+
export declare function serializeStarlingPex(config: Readonly<ParticleEmitterConfig>, existing?: Partial<StarlingPexDocument>, options?: StarlingPexSerializeOptions): string;
|
|
16
|
+
/** Serialise a ParticleEmitterConfig to a Starling / Sparrow PEX XML string,
|
|
17
|
+
* returning both the serialized text and any warnings for features the format
|
|
18
|
+
* cannot represent. */
|
|
19
|
+
export declare function serializeStarlingPexDocument(config: Readonly<ParticleEmitterConfig>, existing?: Partial<StarlingPexDocument>, options?: StarlingPexSerializeOptions): ParticleSerializeResult;
|
|
20
|
+
//# sourceMappingURL=starlingPexSerialize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"starlingPexSerialize.d.ts","sourceRoot":"","sources":["../src/starlingPexSerialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAoB,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,MAAM,WAAW,2BAA2B;IAC1C;iDAC6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;0BAK0B;AAC1B,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACvC,QAAQ,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,EACvC,OAAO,CAAC,EAAE,2BAA2B,GACpC,MAAM,CAIR;AAED;;wBAEwB;AACxB,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACvC,QAAQ,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,EACvC,OAAO,CAAC,EAAE,2BAA2B,GACpC,uBAAuB,CAIzB"}
|