@zylem/behaviors 0.2.0 → 0.3.1
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/LICENSE +21 -0
- package/dist/chunk-7JJEIADR.js +2631 -0
- package/dist/chunk-7JJEIADR.js.map +1 -0
- package/dist/{chunk-POZER3MQ.js → chunk-ZPSAXX73.js} +100 -94
- package/dist/chunk-ZPSAXX73.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/particle-emitter/presets.d.ts +2 -2
- package/dist/particle-emitter/presets.js +1 -1
- package/dist/particle-emitter.d.ts +9 -4
- package/dist/particle-emitter.js +2 -2
- package/dist/spark-Dx3cJbTW.d.ts +356 -0
- package/package.json +159 -159
- package/dist/chunk-GYURWCIQ.js +0 -1985
- package/dist/chunk-GYURWCIQ.js.map +0 -1
- package/dist/chunk-POZER3MQ.js.map +0 -1
- package/dist/spark-DDlIg1nM.d.ts +0 -148
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
createRangeValue,
|
|
4
|
-
createTextureSystemOptions,
|
|
2
|
+
Particles,
|
|
5
3
|
electricityPresets,
|
|
6
4
|
firePresets,
|
|
7
5
|
gasPresets,
|
|
8
6
|
magicPresets,
|
|
9
7
|
particleEffect,
|
|
10
|
-
toColorVector,
|
|
11
8
|
waterPresets
|
|
12
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7JJEIADR.js";
|
|
13
10
|
import {
|
|
14
11
|
VEC3_ZERO,
|
|
15
12
|
normalizeVec3,
|
|
@@ -21,9 +18,6 @@ import {
|
|
|
21
18
|
|
|
22
19
|
// src/lib/behaviors/particle-emitter/particle-emitter.descriptor.ts
|
|
23
20
|
import { Group, Quaternion, Vector3 } from "three";
|
|
24
|
-
import {
|
|
25
|
-
BatchedRenderer
|
|
26
|
-
} from "three.quarks";
|
|
27
21
|
function getRefGlobals(ref) {
|
|
28
22
|
return ref.__getGlobals ?? null;
|
|
29
23
|
}
|
|
@@ -48,28 +42,26 @@ var defaultOptions = {
|
|
|
48
42
|
var ParticleRendererService = class {
|
|
49
43
|
constructor(sceneRoot) {
|
|
50
44
|
this.sceneRoot = sceneRoot;
|
|
51
|
-
this.renderer.name = "zylem-particle-batch-renderer";
|
|
52
|
-
this.sceneRoot.add(this.renderer);
|
|
53
45
|
}
|
|
54
46
|
sceneRoot;
|
|
55
|
-
renderer = new BatchedRenderer();
|
|
56
47
|
systems = /* @__PURE__ */ new Set();
|
|
48
|
+
/** Scene node that emitter anchors are parented to. */
|
|
49
|
+
get root() {
|
|
50
|
+
return this.sceneRoot;
|
|
51
|
+
}
|
|
57
52
|
register(system) {
|
|
58
|
-
if (this.systems.has(system)) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
this.renderer.addSystem(system);
|
|
62
53
|
this.systems.add(system);
|
|
63
54
|
}
|
|
64
55
|
forget(system) {
|
|
65
56
|
this.systems.delete(system);
|
|
66
57
|
}
|
|
67
58
|
update(delta) {
|
|
68
|
-
this.
|
|
59
|
+
for (const system of this.systems) {
|
|
60
|
+
system.update(delta);
|
|
61
|
+
}
|
|
69
62
|
}
|
|
70
63
|
destroy() {
|
|
71
64
|
this.systems.clear();
|
|
72
|
-
this.renderer.removeFromParent();
|
|
73
65
|
}
|
|
74
66
|
};
|
|
75
67
|
function getParticleControlState(ref) {
|
|
@@ -146,7 +138,15 @@ function applyRuntimeState(ref) {
|
|
|
146
138
|
}
|
|
147
139
|
if (state.pendingRestart) {
|
|
148
140
|
runtime.system.restart();
|
|
141
|
+
runtime.started = true;
|
|
149
142
|
state.pendingRestart = false;
|
|
143
|
+
if (state.desiredState === "paused") {
|
|
144
|
+
runtime.system.pause();
|
|
145
|
+
} else if (state.desiredState === "stopped") {
|
|
146
|
+
runtime.system.stop();
|
|
147
|
+
runtime.started = false;
|
|
148
|
+
}
|
|
149
|
+
return;
|
|
150
150
|
}
|
|
151
151
|
if (state.desiredState === "paused") {
|
|
152
152
|
runtime.system.pause();
|
|
@@ -154,9 +154,15 @@ function applyRuntimeState(ref) {
|
|
|
154
154
|
}
|
|
155
155
|
if (state.desiredState === "stopped") {
|
|
156
156
|
runtime.system.stop();
|
|
157
|
+
runtime.started = false;
|
|
157
158
|
return;
|
|
158
159
|
}
|
|
159
|
-
runtime.
|
|
160
|
+
if (!runtime.started) {
|
|
161
|
+
runtime.system.start();
|
|
162
|
+
runtime.started = true;
|
|
163
|
+
} else {
|
|
164
|
+
runtime.system.resume();
|
|
165
|
+
}
|
|
160
166
|
}
|
|
161
167
|
function releaseRuntime(ref, reason) {
|
|
162
168
|
const state = getParticleControlState(ref);
|
|
@@ -166,7 +172,6 @@ function releaseRuntime(ref, reason) {
|
|
|
166
172
|
}
|
|
167
173
|
state.runtime = null;
|
|
168
174
|
state.pendingRestart = false;
|
|
169
|
-
runtime.system.removeEventListener("destroy", runtime.onDestroy);
|
|
170
175
|
runtime.service.forget(runtime.system);
|
|
171
176
|
if (reason === "manual") {
|
|
172
177
|
runtime.system.dispose();
|
|
@@ -191,14 +196,12 @@ function createRuntime(entity, ref, service) {
|
|
|
191
196
|
service,
|
|
192
197
|
initialPosition: initialTransform.position.clone(),
|
|
193
198
|
initialQuaternion: initialTransform.quaternion.clone(),
|
|
194
|
-
|
|
199
|
+
started: false
|
|
195
200
|
};
|
|
196
201
|
anchor.name = `${entity.name || entity.uuid}:particle-anchor`;
|
|
197
|
-
system
|
|
198
|
-
anchor.add(system.emitter);
|
|
202
|
+
anchor.add(system);
|
|
199
203
|
service.register(system);
|
|
200
|
-
service.
|
|
201
|
-
system.addEventListener("destroy", runtime.onDestroy);
|
|
204
|
+
service.root.add(anchor);
|
|
202
205
|
syncRuntimeTransform(entity, ref, runtime);
|
|
203
206
|
return runtime;
|
|
204
207
|
}
|
|
@@ -237,7 +240,7 @@ function createParticleEmitterHandle(ref) {
|
|
|
237
240
|
if (!runtime) {
|
|
238
241
|
return getParticleControlState(ref).desiredState === "playing";
|
|
239
242
|
}
|
|
240
|
-
return
|
|
243
|
+
return runtime.system.running;
|
|
241
244
|
},
|
|
242
245
|
getSystem: () => getParticleControlState(ref).runtime?.system ?? null
|
|
243
246
|
};
|
|
@@ -287,6 +290,9 @@ var ParticleEmitterBehaviorSystem = class {
|
|
|
287
290
|
hasRuntime = true;
|
|
288
291
|
syncRuntimeTransform(entity, ref, state.runtime);
|
|
289
292
|
applyRuntimeState(ref);
|
|
293
|
+
if (ref.options.autoDestroy && state.runtime.started && state.desiredState === "playing" && state.runtime.system.isComplete()) {
|
|
294
|
+
handleSystemDestroyed(entity, ref);
|
|
295
|
+
}
|
|
290
296
|
}
|
|
291
297
|
if (hasRuntime && rendererService) {
|
|
292
298
|
rendererService.update(delta);
|
|
@@ -320,78 +326,78 @@ var ParticleEmitterBehavior = defineBehavior({
|
|
|
320
326
|
});
|
|
321
327
|
|
|
322
328
|
// src/lib/behaviors/particle-emitter/particle-effect.ts
|
|
323
|
-
import {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
329
|
+
import { AdditiveBlending, Color } from "three";
|
|
330
|
+
function toRange(value, fallback) {
|
|
331
|
+
if (value === void 0) return fallback;
|
|
332
|
+
if (Array.isArray(value)) {
|
|
333
|
+
return [value[0] ?? fallback[0], value[1] ?? fallback[1]];
|
|
334
|
+
}
|
|
335
|
+
const single = value;
|
|
336
|
+
return [single, single];
|
|
337
|
+
}
|
|
338
|
+
function toHexColor(color) {
|
|
339
|
+
return `#${new Color(color).getHexString()}`;
|
|
340
|
+
}
|
|
341
|
+
function makeBurstConfig(options, defaults) {
|
|
342
|
+
const count = Math.max(1, Math.round(options.count ?? defaults.count));
|
|
343
|
+
const color = toHexColor(options.color ?? defaults.color);
|
|
344
|
+
const blending = options.blending ?? AdditiveBlending;
|
|
345
|
+
const particles = {
|
|
346
|
+
count,
|
|
347
|
+
intensity: options.opacity ?? defaults.intensity,
|
|
348
|
+
colors: [
|
|
349
|
+
[
|
|
350
|
+
{ color, stop: 0 },
|
|
351
|
+
{ color, stop: 1 }
|
|
352
|
+
]
|
|
353
|
+
],
|
|
354
|
+
fadeAlpha: [0.05, 0.7],
|
|
355
|
+
fadeSize: [0.1, 0.85]
|
|
356
|
+
};
|
|
357
|
+
if (options.texture) {
|
|
358
|
+
particles.alphaMapsStart = [options.texture];
|
|
359
|
+
}
|
|
360
|
+
return {
|
|
361
|
+
particles,
|
|
362
|
+
emitter: {
|
|
363
|
+
duration: options.duration ?? defaults.duration,
|
|
364
|
+
loop: false,
|
|
365
|
+
spawnMode: "burst",
|
|
366
|
+
rate: count,
|
|
367
|
+
static: 0,
|
|
368
|
+
lifetime: toRange(options.life, defaults.life),
|
|
369
|
+
speed: toRange(options.speed, defaults.speed),
|
|
370
|
+
size: toRange(options.size, defaults.size),
|
|
371
|
+
directionMin: [-1, -1, -1],
|
|
372
|
+
directionMax: [1, 1, 1]
|
|
373
|
+
},
|
|
374
|
+
render: { blendingMode: blending }
|
|
375
|
+
};
|
|
376
|
+
}
|
|
330
377
|
var particlePresets = {
|
|
331
378
|
burst(options = {}) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
),
|
|
343
|
-
emissionOverTime: new ConstantValue(0),
|
|
344
|
-
emissionBursts: [
|
|
345
|
-
{
|
|
346
|
-
time: 0,
|
|
347
|
-
count: new ConstantValue(options.count ?? 18),
|
|
348
|
-
cycle: 1,
|
|
349
|
-
interval: 0,
|
|
350
|
-
probability: 1
|
|
351
|
-
}
|
|
352
|
-
],
|
|
353
|
-
shape: new PointEmitter(),
|
|
354
|
-
material: createParticleMaterial(
|
|
355
|
-
options.color ?? "#ffffff",
|
|
356
|
-
options
|
|
357
|
-
),
|
|
358
|
-
...createTextureSystemOptions(options),
|
|
359
|
-
renderMode: RenderMode.BillBoard
|
|
360
|
-
})
|
|
361
|
-
);
|
|
379
|
+
const config = makeBurstConfig(options, {
|
|
380
|
+
duration: 0.25,
|
|
381
|
+
life: [0.3, 0.7],
|
|
382
|
+
speed: [1.5, 4],
|
|
383
|
+
size: [0.08, 0.18],
|
|
384
|
+
color: "#ffffff",
|
|
385
|
+
count: 18,
|
|
386
|
+
intensity: 1
|
|
387
|
+
});
|
|
388
|
+
return particleEffect(() => new Particles(config));
|
|
362
389
|
},
|
|
363
390
|
smoke(options = {}) {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
),
|
|
375
|
-
emissionOverTime: new ConstantValue(0),
|
|
376
|
-
emissionBursts: [
|
|
377
|
-
{
|
|
378
|
-
time: 0,
|
|
379
|
-
count: new ConstantValue(options.count ?? 10),
|
|
380
|
-
cycle: 1,
|
|
381
|
-
interval: 0,
|
|
382
|
-
probability: 1
|
|
383
|
-
}
|
|
384
|
-
],
|
|
385
|
-
shape: new PointEmitter(),
|
|
386
|
-
material: createParticleMaterial(
|
|
387
|
-
options.color ?? "#999999",
|
|
388
|
-
options,
|
|
389
|
-
0.85
|
|
390
|
-
),
|
|
391
|
-
...createTextureSystemOptions(options),
|
|
392
|
-
renderMode: RenderMode.BillBoard
|
|
393
|
-
})
|
|
394
|
-
);
|
|
391
|
+
const config = makeBurstConfig(options, {
|
|
392
|
+
duration: 1.1,
|
|
393
|
+
life: [0.8, 1.6],
|
|
394
|
+
speed: [0.2, 0.8],
|
|
395
|
+
size: [0.2, 0.5],
|
|
396
|
+
color: "#999999",
|
|
397
|
+
count: 10,
|
|
398
|
+
intensity: 0.85
|
|
399
|
+
});
|
|
400
|
+
return particleEffect(() => new Particles(config));
|
|
395
401
|
},
|
|
396
402
|
fire: firePresets,
|
|
397
403
|
water: waterPresets,
|
|
@@ -404,4 +410,4 @@ export {
|
|
|
404
410
|
ParticleEmitterBehavior,
|
|
405
411
|
particlePresets
|
|
406
412
|
};
|
|
407
|
-
//# sourceMappingURL=chunk-
|
|
413
|
+
//# sourceMappingURL=chunk-ZPSAXX73.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/behaviors/particle-emitter/particle-emitter.descriptor.ts","../src/lib/behaviors/particle-emitter/particle-effect.ts"],"sourcesContent":["import { Group, Object3D, Quaternion, Vector3 } from 'three';\n\nimport { Particles } from './gpu';\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { VEC3_ZERO, type Vec3Input, normalizeVec3, toThreeVector3 } from '../../core/vector';\nfunction getRefGlobals(\n\tref: BehaviorRef<ParticleEmitterBehaviorOptions>,\n): (() => any) | null {\n\treturn ((ref as any).__getGlobals ?? null) as (() => any) | null;\n}\nimport type { ParticleEffectDefinition } from './particle-effect';\n\nexport interface ParticleEmitterBehaviorOptions {\n\teffect: ParticleEffectDefinition;\n\tautoplay: boolean;\n\tlocalOffset?: Vec3Input;\n\tfollowPosition: boolean;\n\tfollowRotation: boolean;\n\tautoDestroy: boolean;\n}\n\nexport interface ParticleEmitterHandle {\n\tplay(): void;\n\tstop(): void;\n\tpause(): void;\n\trestart(): void;\n\tburst(): void;\n\tisPlaying(): boolean;\n\tgetSystem(): Particles | null;\n}\n\ntype DesiredParticleState = 'playing' | 'paused' | 'stopped';\n\ninterface ParticleEmitterControlState {\n\tdesiredState: DesiredParticleState;\n\tpendingRestart: boolean;\n\truntime: ParticleEmitterRuntime | null;\n}\n\ninterface ParticleEmitterRuntime {\n\tsystem: Particles;\n\tanchor: Group;\n\tservice: ParticleRendererService;\n\tinitialPosition: Vector3;\n\tinitialQuaternion: Quaternion;\n\t/** Whether the system has been started at least once in this lifecycle. */\n\tstarted: boolean;\n}\n\ninterface ParticleEmitterHostEntity {\n\tuuid: string;\n\tname?: string;\n\tbody?: {\n\t\ttranslation(): { x: number; y: number; z: number };\n\t\trotation?(): { x: number; y: number; z: number; w: number };\n\t} | null;\n\tgroup?: Object3D | null;\n\tmesh?: Object3D | null;\n\toptions?: {\n\t\tposition?: Vec3Input;\n\t};\n\tmarkedForRemoval?: boolean;\n\tnodeDestroy?(params: { me: unknown; globals: unknown }): void;\n\t__zylemParticleSystemEntity?: boolean;\n}\n\nconst PARTICLE_EMITTER_BEHAVIOR_KEY = Symbol.for(\n\t'zylem:behavior:particle-emitter',\n);\n\nconst DEFAULT_PARTICLE_EFFECT: ParticleEffectDefinition = {\n\tcreate() {\n\t\tthrow new Error(\n\t\t\t'ParticleEmitterBehavior requires an effect definition created with particleEffect(...).',\n\t\t);\n\t},\n};\n\nconst defaultOptions: ParticleEmitterBehaviorOptions = {\n\teffect: DEFAULT_PARTICLE_EFFECT,\n\tautoplay: true,\n\tlocalOffset: undefined,\n\tfollowPosition: true,\n\tfollowRotation: true,\n\tautoDestroy: false,\n};\n\n/**\n * Ticks the GPU particle systems each frame.\n *\n * The previous backend (three.quarks) required a `BatchedRenderer` Object3D in\n * the scene graph; the WebGPU engine instead exposes `Particles` Object3Ds that\n * self-render and only need `update(delta)` called for CPU-side emission.\n */\nclass ParticleRendererService {\n\tprivate readonly systems = new Set<Particles>();\n\n\tconstructor(private readonly sceneRoot: Object3D) {}\n\n\t/** Scene node that emitter anchors are parented to. */\n\tget root(): Object3D {\n\t\treturn this.sceneRoot;\n\t}\n\n\tregister(system: Particles): void {\n\t\tthis.systems.add(system);\n\t}\n\n\tforget(system: Particles): void {\n\t\tthis.systems.delete(system);\n\t}\n\n\tupdate(delta: number): void {\n\t\tfor (const system of this.systems) {\n\t\t\tsystem.update(delta);\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.systems.clear();\n\t}\n}\n\nfunction getParticleControlState(\n\tref: BehaviorRef<ParticleEmitterBehaviorOptions>,\n): ParticleEmitterControlState {\n\tconst runtimeState = (ref as any).__particleEmitterControlState as\n\t\t| ParticleEmitterControlState\n\t\t| undefined;\n\tif (runtimeState) {\n\t\treturn runtimeState;\n\t}\n\n\tconst nextState: ParticleEmitterControlState = {\n\t\tdesiredState: ref.options.autoplay ? 'playing' : 'stopped',\n\t\tpendingRestart: false,\n\t\truntime: null,\n\t};\n\t(ref as any).__particleEmitterControlState = nextState;\n\treturn nextState;\n}\n\nfunction shouldCreateRuntime(\n\tstate: ParticleEmitterControlState,\n): boolean {\n\treturn state.runtime == null\n\t\t&& (state.desiredState !== 'stopped' || state.pendingRestart);\n}\n\nfunction getLocalOffset(options: ParticleEmitterBehaviorOptions): Vector3 {\n\treturn toThreeVector3(options.localOffset, VEC3_ZERO);\n}\n\nfunction readHostTransform(entity: ParticleEmitterHostEntity): {\n\tposition: Vector3;\n\tquaternion: Quaternion;\n} {\n\tconst wasmPose = (entity as any).getPose?.();\n\tif (wasmPose && (entity as any).runtimeHandle >= 0) {\n\t\treturn {\n\t\t\tposition: new Vector3(wasmPose.position.x, wasmPose.position.y, wasmPose.position.z),\n\t\t\tquaternion: new Quaternion(\n\t\t\t\twasmPose.rotation.x,\n\t\t\t\twasmPose.rotation.y,\n\t\t\t\twasmPose.rotation.z,\n\t\t\t\twasmPose.rotation.w,\n\t\t\t),\n\t\t};\n\t}\n\n\tif (entity.body?.translation) {\n\t\tconst position = entity.body.translation();\n\t\tconst rotation = entity.body.rotation?.() ?? { x: 0, y: 0, z: 0, w: 1 };\n\t\treturn {\n\t\t\tposition: new Vector3(position.x, position.y, position.z),\n\t\t\tquaternion: new Quaternion(rotation.x, rotation.y, rotation.z, rotation.w),\n\t\t};\n\t}\n\n\tconst visualRoot = entity.group ?? entity.mesh;\n\tif (visualRoot) {\n\t\tconst position = new Vector3();\n\t\tconst quaternion = new Quaternion();\n\t\tvisualRoot.getWorldPosition(position);\n\t\tvisualRoot.getWorldQuaternion(quaternion);\n\t\treturn { position, quaternion };\n\t}\n\n\tconst position = normalizeVec3(entity.options?.position, VEC3_ZERO);\n\treturn {\n\t\tposition: new Vector3(position.x, position.y, position.z),\n\t\tquaternion: new Quaternion(),\n\t};\n}\n\nfunction syncRuntimeTransform(\n\tentity: ParticleEmitterHostEntity,\n\tref: BehaviorRef<ParticleEmitterBehaviorOptions>,\n\truntime: ParticleEmitterRuntime,\n): void {\n\tconst current = readHostTransform(entity);\n\tconst options = ref.options;\n\tconst basePosition = options.followPosition\n\t\t? current.position\n\t\t: runtime.initialPosition;\n\tconst baseQuaternion = options.followRotation\n\t\t? current.quaternion\n\t\t: runtime.initialQuaternion;\n\tconst offset = getLocalOffset(options);\n\n\tif (options.followRotation) {\n\t\toffset.applyQuaternion(baseQuaternion);\n\t}\n\n\truntime.anchor.position.copy(basePosition).add(offset);\n\truntime.anchor.quaternion.copy(baseQuaternion);\n}\n\nfunction applyRuntimeState(\n\tref: BehaviorRef<ParticleEmitterBehaviorOptions>,\n): void {\n\tconst state = getParticleControlState(ref);\n\tconst runtime = state.runtime;\n\tif (!runtime) {\n\t\treturn;\n\t}\n\n\tif (state.pendingRestart) {\n\t\truntime.system.restart();\n\t\truntime.started = true;\n\t\tstate.pendingRestart = false;\n\n\t\tif (state.desiredState === 'paused') {\n\t\t\truntime.system.pause();\n\t\t} else if (state.desiredState === 'stopped') {\n\t\t\truntime.system.stop();\n\t\t\truntime.started = false;\n\t\t}\n\t\treturn;\n\t}\n\n\tif (state.desiredState === 'paused') {\n\t\truntime.system.pause();\n\t\treturn;\n\t}\n\n\tif (state.desiredState === 'stopped') {\n\t\truntime.system.stop();\n\t\truntime.started = false;\n\t\treturn;\n\t}\n\n\t// playing\n\tif (!runtime.started) {\n\t\truntime.system.start();\n\t\truntime.started = true;\n\t} else {\n\t\truntime.system.resume();\n\t}\n}\n\nfunction releaseRuntime(\n\tref: BehaviorRef<ParticleEmitterBehaviorOptions>,\n\treason: 'manual' | 'system-destroyed',\n): void {\n\tconst state = getParticleControlState(ref);\n\tconst runtime = state.runtime;\n\tif (!runtime) {\n\t\treturn;\n\t}\n\n\tstate.runtime = null;\n\tstate.pendingRestart = false;\n\n\truntime.service.forget(runtime.system);\n\n\tif (reason === 'manual') {\n\t\truntime.system.dispose();\n\t}\n\n\truntime.anchor.removeFromParent();\n}\n\nfunction handleSystemDestroyed(\n\tentity: ParticleEmitterHostEntity,\n\tref: BehaviorRef<ParticleEmitterBehaviorOptions>,\n): void {\n\treleaseRuntime(ref, 'system-destroyed');\n\tconst state = getParticleControlState(ref);\n\tstate.desiredState = 'stopped';\n\n\tif (\n\t\tref.options.autoDestroy\n\t\t&& entity.__zylemParticleSystemEntity\n\t\t&& !entity.markedForRemoval\n\t) {\n\t\tentity.nodeDestroy?.({ me: entity, globals: getRefGlobals(ref)?.() ?? {} });\n\t}\n}\n\nfunction createRuntime(\n\tentity: ParticleEmitterHostEntity,\n\tref: BehaviorRef<ParticleEmitterBehaviorOptions>,\n\tservice: ParticleRendererService,\n): ParticleEmitterRuntime {\n\tconst system = ref.options.effect.create();\n\tconst anchor = new Group();\n\tconst initialTransform = readHostTransform(entity);\n\tconst runtime: ParticleEmitterRuntime = {\n\t\tsystem,\n\t\tanchor,\n\t\tservice,\n\t\tinitialPosition: initialTransform.position.clone(),\n\t\tinitialQuaternion: initialTransform.quaternion.clone(),\n\t\tstarted: false,\n\t};\n\n\tanchor.name = `${entity.name || entity.uuid}:particle-anchor`;\n\tanchor.add(system);\n\tservice.register(system);\n\tservice.root.add(anchor);\n\n\tsyncRuntimeTransform(entity, ref, runtime);\n\treturn runtime;\n}\n\nfunction createParticleEmitterHandle(\n\tref: BehaviorRef<ParticleEmitterBehaviorOptions>,\n): ParticleEmitterHandle {\n\treturn {\n\t\tplay: () => {\n\t\t\tconst state = getParticleControlState(ref);\n\t\t\tstate.desiredState = 'playing';\n\t\t\tapplyRuntimeState(ref);\n\t\t},\n\t\tstop: () => {\n\t\t\tconst state = getParticleControlState(ref);\n\t\t\tstate.desiredState = 'stopped';\n\t\t\tstate.pendingRestart = false;\n\t\t\tapplyRuntimeState(ref);\n\t\t},\n\t\tpause: () => {\n\t\t\tconst state = getParticleControlState(ref);\n\t\t\tstate.desiredState = 'paused';\n\t\t\tapplyRuntimeState(ref);\n\t\t},\n\t\trestart: () => {\n\t\t\tconst state = getParticleControlState(ref);\n\t\t\tstate.desiredState = 'playing';\n\t\t\tstate.pendingRestart = true;\n\t\t\tapplyRuntimeState(ref);\n\t\t},\n\t\tburst: () => {\n\t\t\tconst state = getParticleControlState(ref);\n\t\t\tstate.desiredState = 'playing';\n\t\t\tstate.pendingRestart = true;\n\t\t\tapplyRuntimeState(ref);\n\t\t},\n\t\tisPlaying: () => {\n\t\t\tconst runtime = getParticleControlState(ref).runtime;\n\t\t\tif (!runtime) {\n\t\t\t\treturn getParticleControlState(ref).desiredState === 'playing';\n\t\t\t}\n\t\t\treturn runtime.system.running;\n\t\t},\n\t\tgetSystem: () => getParticleControlState(ref).runtime?.system ?? null,\n\t};\n}\n\nclass ParticleEmitterBehaviorSystem implements BehaviorSystem {\n\tprivate rendererService: ParticleRendererService | null = null;\n\n\tconstructor(\n\t\tprivate readonly scene: { scene: Object3D },\n\t\tprivate readonly getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t\tprivate readonly getGlobals?: () => any,\n\t) {}\n\n\tprivate getRendererService(): ParticleRendererService {\n\t\tif (!this.rendererService) {\n\t\t\tthis.rendererService = new ParticleRendererService(this.scene.scene);\n\t\t}\n\t\treturn this.rendererService;\n\t}\n\n\tupdate(_ecs: unknown, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(PARTICLE_EMITTER_BEHAVIOR_KEY);\n\t\tif (!links) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet hasRuntime = false;\n\t\tlet rendererService = this.rendererService;\n\n\t\tfor (const link of links) {\n\t\t\tconst entity = link.entity as ParticleEmitterHostEntity;\n\t\t\tconst ref = link.ref as BehaviorRef<ParticleEmitterBehaviorOptions>;\n\t\t\t(ref as any).__getGlobals = this.getGlobals;\n\t\t\tconst state = getParticleControlState(ref);\n\n\t\t\tif (shouldCreateRuntime(state)) {\n\t\t\t\ttry {\n\t\t\t\t\trendererService ??= this.getRendererService();\n\t\t\t\t\tstate.runtime = createRuntime(entity, ref, rendererService);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tstate.desiredState = 'stopped';\n\t\t\t\t\tstate.pendingRestart = false;\n\t\t\t\t\tconsole.error('Failed to create particle runtime:', error);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!state.runtime) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\thasRuntime = true;\n\t\t\tsyncRuntimeTransform(entity, ref, state.runtime);\n\t\t\tapplyRuntimeState(ref);\n\n\t\t\tif (\n\t\t\t\tref.options.autoDestroy\n\t\t\t\t&& state.runtime.started\n\t\t\t\t&& state.desiredState === 'playing'\n\t\t\t\t&& state.runtime.system.isComplete()\n\t\t\t) {\n\t\t\t\thandleSystemDestroyed(entity, ref);\n\t\t\t}\n\t\t}\n\n\t\tif (hasRuntime && rendererService) {\n\t\t\trendererService.update(delta);\n\t\t}\n\t}\n\n\tdetach(link: BehaviorEntityLink): void {\n\t\treleaseRuntime(\n\t\t\tlink.ref as BehaviorRef<ParticleEmitterBehaviorOptions>,\n\t\t\t'manual',\n\t\t);\n\t}\n\n\tdestroy(_ecs: unknown): void {\n\t\tconst links = this.getBehaviorLinks?.(PARTICLE_EMITTER_BEHAVIOR_KEY);\n\t\tif (links) {\n\t\t\tfor (const link of links) {\n\t\t\t\treleaseRuntime(\n\t\t\t\t\tlink.ref as BehaviorRef<ParticleEmitterBehaviorOptions>,\n\t\t\t\t\t'manual',\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis.rendererService?.destroy();\n\t\tthis.rendererService = null;\n\t}\n}\n\nexport const ParticleEmitterBehavior = defineBehavior<\n\tParticleEmitterBehaviorOptions,\n\tParticleEmitterHandle\n>({\n\tname: 'particle-emitter',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew ParticleEmitterBehaviorSystem(ctx.scene, ctx.getBehaviorLinks, ctx.getGlobals),\n\tcreateHandle: createParticleEmitterHandle,\n});\n","import { AdditiveBlending, Color, type ColorRepresentation } from 'three';\n\nimport { Particles } from './gpu';\nimport type { ParticleSettings, ParticlesConfig, RenderSettings } from './gpu';\nimport {\n\tparticleEffect,\n\ttype ParticleEffectDefinition,\n\ttype ParticlePresetMaterialOptions,\n} from './preset-builder';\nimport { electricityPresets, firePresets, gasPresets, magicPresets, waterPresets } from './presets';\n\nexport type {\n\tParticleEffectDefinition,\n\tParticleMagicAgency,\n\tParticleMagicAlignment,\n\tParticleMagicModifierInput,\n\tParticleMagicModifierOptions,\n\tParticleMagicOrder,\n\tParticleMagicRealityEffect,\n\tParticleMagicTemperament,\n\tParticlePresetMaterialOptions,\n\tSemanticParticlePresetOptions,\n} from './preset-builder';\n\nexport interface BurstParticlePresetOptions extends ParticlePresetMaterialOptions {\n\tcolor?: ColorRepresentation;\n\tcount?: number;\n\tduration?: number;\n\tlife?: number | readonly [number, number];\n\tsize?: number | readonly [number, number];\n\tspeed?: number | readonly [number, number];\n\t/**\n\t * Kept for API compatibility. Emitter follow behavior is controlled by the\n\t * particle-emitter behavior (followPosition/followRotation), so this flag is\n\t * not used by the GPU engine.\n\t */\n\tworldSpace?: boolean;\n}\n\ninterface BurstDefaults {\n\tduration: number;\n\tlife: [number, number];\n\tspeed: [number, number];\n\tsize: [number, number];\n\tcolor: ColorRepresentation;\n\tcount: number;\n\tintensity: number;\n}\n\nfunction toRange(\n\tvalue: number | readonly [number, number] | undefined,\n\tfallback: [number, number],\n): [number, number] {\n\tif (value === undefined) return fallback;\n\tif (Array.isArray(value)) {\n\t\treturn [value[0] ?? fallback[0], value[1] ?? fallback[1]];\n\t}\n\tconst single = value as number;\n\treturn [single, single];\n}\n\nfunction toHexColor(color: ColorRepresentation): string {\n\treturn `#${new Color(color).getHexString()}`;\n}\n\nfunction makeBurstConfig(\n\toptions: BurstParticlePresetOptions,\n\tdefaults: BurstDefaults,\n): ParticlesConfig {\n\tconst count = Math.max(1, Math.round(options.count ?? defaults.count));\n\tconst color = toHexColor(options.color ?? defaults.color);\n\tconst blending = (options.blending ?? AdditiveBlending) as RenderSettings['blendingMode'];\n\n\tconst particles: Partial<ParticleSettings> & Pick<ParticleSettings, 'count'> = {\n\t\tcount,\n\t\tintensity: options.opacity ?? defaults.intensity,\n\t\tcolors: [\n\t\t\t[\n\t\t\t\t{ color, stop: 0 },\n\t\t\t\t{ color, stop: 1 },\n\t\t\t],\n\t\t],\n\t\tfadeAlpha: [0.05, 0.7],\n\t\tfadeSize: [0.1, 0.85],\n\t};\n\tif (options.texture) {\n\t\tparticles.alphaMapsStart = [options.texture] as unknown as ParticleSettings['alphaMapsStart'];\n\t}\n\n\treturn {\n\t\tparticles,\n\t\temitter: {\n\t\t\tduration: options.duration ?? defaults.duration,\n\t\t\tloop: false,\n\t\t\tspawnMode: 'burst',\n\t\t\trate: count,\n\t\t\tstatic: 0,\n\t\t\tlifetime: toRange(options.life, defaults.life),\n\t\t\tspeed: toRange(options.speed, defaults.speed),\n\t\t\tsize: toRange(options.size, defaults.size),\n\t\t\tdirectionMin: [-1, -1, -1],\n\t\t\tdirectionMax: [1, 1, 1],\n\t\t},\n\t\trender: { blendingMode: blending },\n\t};\n}\n\nexport const particlePresets = {\n\tburst(options: BurstParticlePresetOptions = {}): ParticleEffectDefinition {\n\t\tconst config = makeBurstConfig(options, {\n\t\t\tduration: 0.25,\n\t\t\tlife: [0.3, 0.7],\n\t\t\tspeed: [1.5, 4],\n\t\t\tsize: [0.08, 0.18],\n\t\t\tcolor: '#ffffff',\n\t\t\tcount: 18,\n\t\t\tintensity: 1,\n\t\t});\n\t\treturn particleEffect(() => new Particles(config));\n\t},\n\tsmoke(options: BurstParticlePresetOptions = {}): ParticleEffectDefinition {\n\t\tconst config = makeBurstConfig(options, {\n\t\t\tduration: 1.1,\n\t\t\tlife: [0.8, 1.6],\n\t\t\tspeed: [0.2, 0.8],\n\t\t\tsize: [0.2, 0.5],\n\t\t\tcolor: '#999999',\n\t\t\tcount: 10,\n\t\t\tintensity: 0.85,\n\t\t});\n\t\treturn particleEffect(() => new Particles(config));\n\t},\n\tfire: firePresets,\n\twater: waterPresets,\n\tgas: gasPresets,\n\telectricity: electricityPresets,\n\tmagic: magicPresets,\n} as const;\n\nexport { particleEffect } from './preset-builder';\n"],"mappings":"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","names":["position"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export { BoundaryRicochet3DCoordinator } from './coordinators/boundary-ricochet-
|
|
|
28
28
|
export { FirstPersonShooterCoordinator, FirstPersonShooterInput } from './coordinators/first-person-shooter.js';
|
|
29
29
|
export { TopDownShooterCoordinator, TopDownShooterInput } from './coordinators/top-down-shooter.js';
|
|
30
30
|
export { MultidirectionalSpaceShooterCoordinator, MultidirectionalSpaceShooterInput } from './coordinators/multidirectional-space-shooter.js';
|
|
31
|
-
export { P as ParticleEffectDefinition, a as ParticleMagicAgency, b as ParticleMagicAlignment, c as ParticleMagicModifierInput, d as ParticleMagicModifierOptions, e as ParticleMagicOrder, f as ParticleMagicRealityEffect, g as ParticleMagicTemperament, h as ParticlePresetMaterialOptions, S as SemanticParticlePresetOptions,
|
|
31
|
+
export { P as ParticleEffectDefinition, a as ParticleMagicAgency, b as ParticleMagicAlignment, c as ParticleMagicModifierInput, d as ParticleMagicModifierOptions, e as ParticleMagicOrder, f as ParticleMagicRealityEffect, g as ParticleMagicTemperament, h as ParticlePresetMaterialOptions, S as SemanticParticlePresetOptions, v as particleEffect } from './spark-Dx3cJbTW.js';
|
|
32
32
|
import '@dimforge/rapier3d-compat';
|
|
33
33
|
import 'three';
|
|
34
34
|
import './sync-state-machine-CZyspBpj.js';
|
|
@@ -36,5 +36,5 @@ import 'typescript-fsm';
|
|
|
36
36
|
import './vector-Bm65-FOG.js';
|
|
37
37
|
import './entity-types-CmtQ-IBp.js';
|
|
38
38
|
import './first-person-perspective-C9Mptl0-.js';
|
|
39
|
-
import 'three.quarks';
|
|
40
39
|
import './moveable-BCRpjAQb.js';
|
|
40
|
+
import 'three/webgpu';
|
package/dist/index.js
CHANGED
|
@@ -67,10 +67,10 @@ import "./chunk-OHCPV2NT.js";
|
|
|
67
67
|
import {
|
|
68
68
|
ParticleEmitterBehavior,
|
|
69
69
|
particlePresets
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-ZPSAXX73.js";
|
|
71
71
|
import {
|
|
72
72
|
particleEffect
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-7JJEIADR.js";
|
|
74
74
|
import {
|
|
75
75
|
Platformer3DBehavior,
|
|
76
76
|
Platformer3DBehavior2,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { k as arcane, r as holy, m as corrupted, u as nature, J as voidMagic, x as psychic, B as spark, j as arc, G as surge, y as pulse, F as storm, I as vapor, z as smoke, q as haze, w as plume, s as miasma, t as mist, E as spray, D as splash, n as drizzle, H as torrent, C as spark$1, o as ember, p as flamelet, l as blaze, A as smolder } from '../spark-Dx3cJbTW.js';
|
|
2
2
|
import 'three';
|
|
3
|
-
import 'three
|
|
3
|
+
import 'three/webgpu';
|
|
4
4
|
|
|
5
5
|
declare const magicPresets: {
|
|
6
6
|
readonly arcane: typeof arcane;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { a as BehaviorDescriptor } from './behavior-system-DYbx-x_-.js';
|
|
2
2
|
import { i as Vec3Input } from './vector-Bm65-FOG.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export { a as ParticleMagicAgency, b as ParticleMagicAlignment, c as ParticleMagicModifierInput, d as ParticleMagicModifierOptions, e as ParticleMagicOrder, f as ParticleMagicRealityEffect, g as ParticleMagicTemperament, S as SemanticParticlePresetOptions, u as particleEffect } from './spark-DDlIg1nM.js';
|
|
3
|
+
import { h as ParticlePresetMaterialOptions, P as ParticleEffectDefinition, C as spark, o as ember, p as flamelet, l as blaze, A as smolder, t as mist, E as spray, D as splash, n as drizzle, H as torrent, I as vapor, z as smoke, q as haze, w as plume, s as miasma, B as spark$1, j as arc, G as surge, y as pulse, F as storm, k as arcane, r as holy, m as corrupted, u as nature, J as voidMagic, x as psychic, i as Particles } from './spark-Dx3cJbTW.js';
|
|
4
|
+
export { a as ParticleMagicAgency, b as ParticleMagicAlignment, c as ParticleMagicModifierInput, d as ParticleMagicModifierOptions, e as ParticleMagicOrder, f as ParticleMagicRealityEffect, g as ParticleMagicTemperament, S as SemanticParticlePresetOptions, v as particleEffect } from './spark-Dx3cJbTW.js';
|
|
6
5
|
import { ColorRepresentation } from 'three';
|
|
7
6
|
import '@dimforge/rapier3d-compat';
|
|
7
|
+
import 'three/webgpu';
|
|
8
8
|
|
|
9
9
|
interface BurstParticlePresetOptions extends ParticlePresetMaterialOptions {
|
|
10
10
|
color?: ColorRepresentation;
|
|
@@ -13,6 +13,11 @@ interface BurstParticlePresetOptions extends ParticlePresetMaterialOptions {
|
|
|
13
13
|
life?: number | readonly [number, number];
|
|
14
14
|
size?: number | readonly [number, number];
|
|
15
15
|
speed?: number | readonly [number, number];
|
|
16
|
+
/**
|
|
17
|
+
* Kept for API compatibility. Emitter follow behavior is controlled by the
|
|
18
|
+
* particle-emitter behavior (followPosition/followRotation), so this flag is
|
|
19
|
+
* not used by the GPU engine.
|
|
20
|
+
*/
|
|
16
21
|
worldSpace?: boolean;
|
|
17
22
|
}
|
|
18
23
|
declare const particlePresets: {
|
|
@@ -71,7 +76,7 @@ interface ParticleEmitterHandle {
|
|
|
71
76
|
restart(): void;
|
|
72
77
|
burst(): void;
|
|
73
78
|
isPlaying(): boolean;
|
|
74
|
-
getSystem():
|
|
79
|
+
getSystem(): Particles | null;
|
|
75
80
|
}
|
|
76
81
|
declare const ParticleEmitterBehavior: BehaviorDescriptor<ParticleEmitterBehaviorOptions, ParticleEmitterHandle, unknown>;
|
|
77
82
|
|
package/dist/particle-emitter.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ParticleEmitterBehavior,
|
|
3
3
|
particlePresets
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZPSAXX73.js";
|
|
5
5
|
import {
|
|
6
6
|
particleEffect
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7JJEIADR.js";
|
|
8
8
|
import "./chunk-WWVD5DR5.js";
|
|
9
9
|
import "./chunk-EZNCCO4L.js";
|
|
10
10
|
export {
|