@skewedaspect/sage 0.9.0-beta.10 → 0.9.0-beta.11
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/sage.es.js +738 -735
- package/dist/sage.es.js.map +1 -1
- package/dist/sage.umd.js +1 -1
- package/dist/sage.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/sage.es.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { CreateAudioEngineAsync as
|
|
2
|
-
import { Scene as
|
|
1
|
+
import { CreateAudioEngineAsync as ce } from "@babylonjs/core/AudioV2/webAudio/webAudioEngine";
|
|
2
|
+
import { Scene as de, Vector3 as p, HavokPlugin as J, FreeCamera as B, HemisphericLight as X, DirectionalLight as Q, PointLight as ee, SpotLight as te, RectAreaLight as ie, MeshBuilder as y, PhysicsAggregate as se, LoadAssetContainerAsync as ue, ImportMeshAsync as ge, ImageProcessingConfiguration as v, DefaultRenderingPipeline as _e, Color4 as fe, SSAO2RenderingPipeline as pe, StandardMaterial as R, Texture as ye, CubeTexture as me, HDRCubeTexture as ve, UniversalCamera as be, ArcRotateCamera as O, TransformNode as H, Color3 as we, PBRMaterial as $e, SoundState as ne, NullEngine as Se, WebGPUEngine as Ee, Engine as Ce, Mesh as w, PhysicsShapeType as S, AbstractMesh as oe, ActionManager as L, ExecuteCodeAction as xe } from "@babylonjs/core";
|
|
3
3
|
import "@babylonjs/loaders/glTF";
|
|
4
4
|
import Me from "@babylonjs/havok";
|
|
5
|
-
const E = "0.9.0-beta.
|
|
5
|
+
const E = "0.9.0-beta.11";
|
|
6
6
|
class ke {
|
|
7
7
|
canvas;
|
|
8
8
|
renderEngine;
|
|
@@ -29,8 +29,8 @@ class ke {
|
|
|
29
29
|
* @param engines
|
|
30
30
|
* @param managers
|
|
31
31
|
*/
|
|
32
|
-
constructor(e, t,
|
|
33
|
-
this.canvas = e, this.renderEngine = t, this.physics =
|
|
32
|
+
constructor(e, t, i, s, n, o, a, l, h) {
|
|
33
|
+
this.canvas = e, this.renderEngine = t, this.physics = i, this.eventBus = s, this.logger = n, this.raycast = o, this.timer = a, this.engines = l, this.managers = h, this._log = n.getLogger("GameEngine");
|
|
34
34
|
}
|
|
35
35
|
//------------------------------------------------------------------------------------------------------------------
|
|
36
36
|
// Public API
|
|
@@ -146,21 +146,21 @@ class ke {
|
|
|
146
146
|
this._log.error(`Error in onTeardown hook: ${t}`), e = e || t;
|
|
147
147
|
}
|
|
148
148
|
for (const t of Object.keys(this.managers)) {
|
|
149
|
-
const
|
|
150
|
-
if (
|
|
149
|
+
const i = this.managers[t];
|
|
150
|
+
if (i)
|
|
151
151
|
try {
|
|
152
|
-
this._log.debug(`Tearing down manager: ${t}`), await
|
|
153
|
-
} catch (
|
|
154
|
-
this._log.error(`Error tearing down manager ${t}: ${
|
|
152
|
+
this._log.debug(`Tearing down manager: ${t}`), await i.$teardown();
|
|
153
|
+
} catch (s) {
|
|
154
|
+
this._log.error(`Error tearing down manager ${t}: ${s}`), e = e || s;
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
for (const t of Object.keys(this.engines)) {
|
|
158
|
-
const
|
|
159
|
-
if (
|
|
158
|
+
const i = this.engines[t];
|
|
159
|
+
if (i)
|
|
160
160
|
try {
|
|
161
|
-
this._log.debug(`Tearing down engine: ${t}`), await
|
|
162
|
-
} catch (
|
|
163
|
-
this._log.error(`Error tearing down engine ${t}: ${
|
|
161
|
+
this._log.debug(`Tearing down engine: ${t}`), await i.$teardown();
|
|
162
|
+
} catch (s) {
|
|
163
|
+
this._log.error(`Error tearing down engine ${t}: ${s}`), e = e || s;
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
if (this.started = !1, this._log.info("Game engine stopped successfully"), e)
|
|
@@ -200,7 +200,7 @@ class De {
|
|
|
200
200
|
* Format a log message with category, timestamp and log level
|
|
201
201
|
*/
|
|
202
202
|
formatMessage(e, t) {
|
|
203
|
-
const
|
|
203
|
+
const i = /* @__PURE__ */ new Date(), s = i.getHours() % 12 || 12, n = i.getMinutes().toString().padStart(2, "0"), o = i.getSeconds().toString().padStart(2, "0"), a = i.getHours() >= 12 ? "PM" : "AM", l = `[${s}:${n}:${o} ${a}]`, h = t.toUpperCase();
|
|
204
204
|
return [
|
|
205
205
|
`${l} %c${h}%c (${e}): `,
|
|
206
206
|
// Format string with placeholders
|
|
@@ -212,41 +212,41 @@ class De {
|
|
|
212
212
|
// Reset style
|
|
213
213
|
];
|
|
214
214
|
}
|
|
215
|
-
trace(e, t, ...
|
|
216
|
-
const [
|
|
217
|
-
console.debug(
|
|
215
|
+
trace(e, t, ...i) {
|
|
216
|
+
const [s, n, o, a] = this.formatMessage(e, "trace");
|
|
217
|
+
console.debug(s, n, o, a, t, ...i);
|
|
218
218
|
}
|
|
219
|
-
debug(e, t, ...
|
|
220
|
-
const [
|
|
221
|
-
console.debug(
|
|
219
|
+
debug(e, t, ...i) {
|
|
220
|
+
const [s, n, o, a] = this.formatMessage(e, "debug");
|
|
221
|
+
console.debug(s, n, o, a, t, ...i);
|
|
222
222
|
}
|
|
223
|
-
info(e, t, ...
|
|
224
|
-
const [
|
|
225
|
-
console.info(
|
|
223
|
+
info(e, t, ...i) {
|
|
224
|
+
const [s, n, o, a] = this.formatMessage(e, "info");
|
|
225
|
+
console.info(s, n, o, a, t, ...i);
|
|
226
226
|
}
|
|
227
|
-
warn(e, t, ...
|
|
228
|
-
const [
|
|
229
|
-
console.warn(
|
|
227
|
+
warn(e, t, ...i) {
|
|
228
|
+
const [s, n, o, a] = this.formatMessage(e, "warn");
|
|
229
|
+
console.warn(s, n, o, a, t, ...i);
|
|
230
230
|
}
|
|
231
|
-
error(e, t, ...
|
|
232
|
-
const [
|
|
233
|
-
console.error(
|
|
231
|
+
error(e, t, ...i) {
|
|
232
|
+
const [s, n, o, a] = this.formatMessage(e, "error");
|
|
233
|
+
console.error(s, n, o, a, t, ...i);
|
|
234
234
|
}
|
|
235
235
|
/**
|
|
236
236
|
* Start a timer with the specified label.
|
|
237
237
|
*/
|
|
238
238
|
time(e, t) {
|
|
239
|
-
const
|
|
240
|
-
this.timers.set(
|
|
239
|
+
const i = `${e}:${t}`;
|
|
240
|
+
this.timers.set(i, performance.now());
|
|
241
241
|
}
|
|
242
242
|
/**
|
|
243
243
|
* End a timer and log the elapsed time.
|
|
244
244
|
*/
|
|
245
245
|
timeEnd(e, t) {
|
|
246
|
-
const
|
|
247
|
-
if (
|
|
248
|
-
const n = performance.now() -
|
|
249
|
-
this.timers.delete(
|
|
246
|
+
const i = `${e}:${t}`, s = this.timers.get(i);
|
|
247
|
+
if (s !== void 0) {
|
|
248
|
+
const n = performance.now() - s;
|
|
249
|
+
this.timers.delete(i);
|
|
250
250
|
const [o, a, l, h] = this.formatMessage(e, "timer");
|
|
251
251
|
console.info(
|
|
252
252
|
`${o} Timer '${t}' completed in ${n.toFixed(2)}ms`,
|
|
@@ -259,15 +259,15 @@ class De {
|
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
class Ae {
|
|
262
|
-
trace(e, t, ...
|
|
262
|
+
trace(e, t, ...i) {
|
|
263
263
|
}
|
|
264
|
-
debug(e, t, ...
|
|
264
|
+
debug(e, t, ...i) {
|
|
265
265
|
}
|
|
266
|
-
info(e, t, ...
|
|
266
|
+
info(e, t, ...i) {
|
|
267
267
|
}
|
|
268
|
-
warn(e, t, ...
|
|
268
|
+
warn(e, t, ...i) {
|
|
269
269
|
}
|
|
270
|
-
error(e, t, ...
|
|
270
|
+
error(e, t, ...i) {
|
|
271
271
|
}
|
|
272
272
|
time(e, t) {
|
|
273
273
|
}
|
|
@@ -278,8 +278,8 @@ class u {
|
|
|
278
278
|
category;
|
|
279
279
|
backend;
|
|
280
280
|
minLevel;
|
|
281
|
-
constructor(e, t = "none",
|
|
282
|
-
this.category = e, this.backend =
|
|
281
|
+
constructor(e, t = "none", i = new Ae()) {
|
|
282
|
+
this.category = e, this.backend = i, this.minLevel = t;
|
|
283
283
|
}
|
|
284
284
|
/**
|
|
285
285
|
* Update the logger's backend and minimum level
|
|
@@ -431,13 +431,13 @@ class Le {
|
|
|
431
431
|
*/
|
|
432
432
|
subscribeExact(e, t) {
|
|
433
433
|
this._log.debug(`Adding exact subscription for: ${e}`);
|
|
434
|
-
let
|
|
435
|
-
|
|
436
|
-
const
|
|
434
|
+
let i = this.directMap.get(e);
|
|
435
|
+
i || (i = /* @__PURE__ */ new Set(), this.directMap.set(e, i));
|
|
436
|
+
const s = {
|
|
437
437
|
callback: (n) => t(n)
|
|
438
438
|
};
|
|
439
|
-
return
|
|
440
|
-
this._log.debug(`Removing exact subscription for: ${e}`),
|
|
439
|
+
return i.add(s), () => {
|
|
440
|
+
this._log.debug(`Removing exact subscription for: ${e}`), i.delete(s), i.size === 0 && this.directMap.delete(e);
|
|
441
441
|
};
|
|
442
442
|
}
|
|
443
443
|
/**
|
|
@@ -452,20 +452,20 @@ class Le {
|
|
|
452
452
|
* @returns A function that removes this subscription when called
|
|
453
453
|
*/
|
|
454
454
|
subscribePattern(e, t) {
|
|
455
|
-
let
|
|
455
|
+
let i;
|
|
456
456
|
if (typeof e == "string") {
|
|
457
457
|
const n = e.replace(/[-/\\^$+?.()|[\]{}]/g, "\\$&").replace(/\*/g, ".*");
|
|
458
|
-
|
|
459
|
-
`Adding pattern subscription for string: ${e}, regex: ${
|
|
458
|
+
i = new RegExp(`^${n}$`), this._log.debug(
|
|
459
|
+
`Adding pattern subscription for string: ${e}, regex: ${i.toString()}`
|
|
460
460
|
);
|
|
461
461
|
} else
|
|
462
|
-
|
|
463
|
-
const
|
|
464
|
-
pattern:
|
|
462
|
+
i = e, this._log.debug(`Adding pattern subscription for regex: ${i.toString()}`);
|
|
463
|
+
const s = {
|
|
464
|
+
pattern: i,
|
|
465
465
|
callback: (n) => t(n)
|
|
466
466
|
};
|
|
467
|
-
return this.patternSubs.add(
|
|
468
|
-
this._log.debug(`Removing pattern subscription: ${
|
|
467
|
+
return this.patternSubs.add(s), () => {
|
|
468
|
+
this._log.debug(`Removing pattern subscription: ${i.toString()}`), this.patternSubs.delete(s);
|
|
469
469
|
};
|
|
470
470
|
}
|
|
471
471
|
//------------------------------------------------------------------------------------------------------------------
|
|
@@ -490,16 +490,16 @@ class Le {
|
|
|
490
490
|
publish(e) {
|
|
491
491
|
this._log.trace(`Publishing event: ${e.type}`, e);
|
|
492
492
|
let t = 0;
|
|
493
|
-
const
|
|
494
|
-
if (
|
|
495
|
-
t +=
|
|
496
|
-
for (const
|
|
497
|
-
Promise.resolve().then(() =>
|
|
493
|
+
const i = this.directMap.get(e.type);
|
|
494
|
+
if (i) {
|
|
495
|
+
t += i.size;
|
|
496
|
+
for (const s of i)
|
|
497
|
+
Promise.resolve().then(() => s.callback(e)).catch((n) => {
|
|
498
498
|
this._log.error(`Error in event handler for '${e.type}':`, n);
|
|
499
499
|
});
|
|
500
500
|
}
|
|
501
|
-
for (const
|
|
502
|
-
|
|
501
|
+
for (const s of this.patternSubs)
|
|
502
|
+
s.pattern && s.pattern.test(e.type) && (t++, Promise.resolve().then(() => s.callback(e)).catch((n) => {
|
|
503
503
|
this._log.error(`Error in pattern event handler for '${e.type}':`, n);
|
|
504
504
|
}));
|
|
505
505
|
t === 0 ? this._log.debug(`No subscribers found for event: ${e.type}`) : this._log.trace(`Event ${e.type} dispatched to ${t} subscribers`);
|
|
@@ -527,7 +527,7 @@ class Te {
|
|
|
527
527
|
// Lifecycle
|
|
528
528
|
//------------------------------------------------------------------------------------------------------------------
|
|
529
529
|
async initialize() {
|
|
530
|
-
this._log.info("Initializing audio engine..."), this._engine = await
|
|
530
|
+
this._log.info("Initializing audio engine..."), this._engine = await ce(), this._mainBus = await this._engine.createMainBusAsync("main"), this._log.info("Audio engine initialized.");
|
|
531
531
|
}
|
|
532
532
|
async $teardown() {
|
|
533
533
|
this._log.info("Tearing down audio engine..."), this._buses.clear(), this._mainBus = null, this._engine && (this._engine.dispose(), this._engine = null), this._log.info("Audio engine torn down.");
|
|
@@ -548,11 +548,11 @@ class Te {
|
|
|
548
548
|
//------------------------------------------------------------------------------------------------------------------
|
|
549
549
|
// Sound Creation
|
|
550
550
|
//------------------------------------------------------------------------------------------------------------------
|
|
551
|
-
async createSound(e, t,
|
|
551
|
+
async createSound(e, t, i, s) {
|
|
552
552
|
if (!this._engine)
|
|
553
553
|
throw new Error("AudioEngine not initialized");
|
|
554
|
-
const n =
|
|
555
|
-
...
|
|
554
|
+
const n = i ?? this._mainBus ?? void 0, o = {
|
|
555
|
+
...s,
|
|
556
556
|
...n ? { outBus: n } : {}
|
|
557
557
|
};
|
|
558
558
|
return this._engine.createSoundAsync(e, t, o);
|
|
@@ -577,21 +577,21 @@ class Ie {
|
|
|
577
577
|
_engine;
|
|
578
578
|
_havok;
|
|
579
579
|
_log;
|
|
580
|
-
constructor(e, t,
|
|
581
|
-
this._canvas = e, this._engine = t, this._havok =
|
|
580
|
+
constructor(e, t, i, s) {
|
|
581
|
+
this._canvas = e, this._engine = t, this._havok = i, this._log = s.getLogger("SceneEngine");
|
|
582
582
|
}
|
|
583
583
|
/**
|
|
584
584
|
* Creates a new scene with physics enabled
|
|
585
585
|
*/
|
|
586
586
|
createScene() {
|
|
587
|
-
return new
|
|
587
|
+
return new de(this._engine);
|
|
588
588
|
}
|
|
589
589
|
enablePhysics(e, t = new p(0, -9.8, 0)) {
|
|
590
590
|
this._log.debug(
|
|
591
591
|
`Enabling physics with gravity (${t.x}, ${t.y}, ${t.z})...`
|
|
592
592
|
);
|
|
593
|
-
const
|
|
594
|
-
e.enablePhysics(t,
|
|
593
|
+
const i = new J(!0, this._havok);
|
|
594
|
+
e.enablePhysics(t, i);
|
|
595
595
|
}
|
|
596
596
|
// Camera Utilities
|
|
597
597
|
/**
|
|
@@ -602,9 +602,9 @@ class Ie {
|
|
|
602
602
|
* @param scene
|
|
603
603
|
* @param canvas - Overrides the default canvas for input controls
|
|
604
604
|
*/
|
|
605
|
-
createFreeCamera(e, t,
|
|
606
|
-
const n = new B(e, t,
|
|
607
|
-
return n.setTarget(p.Zero()),
|
|
605
|
+
createFreeCamera(e, t, i, s) {
|
|
606
|
+
const n = new B(e, t, i);
|
|
607
|
+
return n.setTarget(p.Zero()), s = s ?? this._canvas, s && n.attachControl(s, !0), n;
|
|
608
608
|
}
|
|
609
609
|
// Lighting Utilities
|
|
610
610
|
/**
|
|
@@ -614,9 +614,9 @@ class Ie {
|
|
|
614
614
|
* @param scene
|
|
615
615
|
* @param intensity - Default: 0.7
|
|
616
616
|
*/
|
|
617
|
-
createHemisphericLight(e, t,
|
|
618
|
-
const n = new
|
|
619
|
-
return n.intensity =
|
|
617
|
+
createHemisphericLight(e, t, i, s = 0.7) {
|
|
618
|
+
const n = new X(e, t, i);
|
|
619
|
+
return n.intensity = s, n;
|
|
620
620
|
}
|
|
621
621
|
/**
|
|
622
622
|
* Creates a directional light (sun-like lighting)
|
|
@@ -625,9 +625,9 @@ class Ie {
|
|
|
625
625
|
* @param scene
|
|
626
626
|
* @param intensity - Default: 1.0
|
|
627
627
|
*/
|
|
628
|
-
createDirectionalLight(e, t,
|
|
629
|
-
const n = new
|
|
630
|
-
return n.intensity =
|
|
628
|
+
createDirectionalLight(e, t, i, s = 1) {
|
|
629
|
+
const n = new Q(e, t, i);
|
|
630
|
+
return n.intensity = s, n;
|
|
631
631
|
}
|
|
632
632
|
/**
|
|
633
633
|
* Creates a point light (bulb-like lighting)
|
|
@@ -636,9 +636,9 @@ class Ie {
|
|
|
636
636
|
* @param scene
|
|
637
637
|
* @param intensity - Default: 1.0
|
|
638
638
|
*/
|
|
639
|
-
createPointLight(e, t,
|
|
640
|
-
const n = new
|
|
641
|
-
return n.intensity =
|
|
639
|
+
createPointLight(e, t, i, s = 1) {
|
|
640
|
+
const n = new ee(e, t, i);
|
|
641
|
+
return n.intensity = s, n;
|
|
642
642
|
}
|
|
643
643
|
/**
|
|
644
644
|
* Creates a spotlight (flashlight-like lighting)
|
|
@@ -650,8 +650,8 @@ class Ie {
|
|
|
650
650
|
* @param scene
|
|
651
651
|
* @param intensity - Default: 1.0
|
|
652
652
|
*/
|
|
653
|
-
createSpotLight(e, t,
|
|
654
|
-
const l = new
|
|
653
|
+
createSpotLight(e, t, i, s, n, o, a = 1) {
|
|
654
|
+
const l = new te(e, t, i, s, n, o);
|
|
655
655
|
return l.intensity = a, l;
|
|
656
656
|
}
|
|
657
657
|
/**
|
|
@@ -663,8 +663,8 @@ class Ie {
|
|
|
663
663
|
* @param scene
|
|
664
664
|
* @param intensity - Default: 1.0
|
|
665
665
|
*/
|
|
666
|
-
createRectAreaLight(e, t,
|
|
667
|
-
const a = new
|
|
666
|
+
createRectAreaLight(e, t, i, s, n, o = 1) {
|
|
667
|
+
const a = new ie(e, t, i, s, n);
|
|
668
668
|
return a.intensity = o, a;
|
|
669
669
|
}
|
|
670
670
|
// Mesh Creation Utilities
|
|
@@ -674,9 +674,9 @@ class Ie {
|
|
|
674
674
|
* @param options
|
|
675
675
|
* @param scene
|
|
676
676
|
*/
|
|
677
|
-
createSphere(e, t = {},
|
|
678
|
-
const
|
|
679
|
-
return y.CreateSphere(e, { ...
|
|
677
|
+
createSphere(e, t = {}, i) {
|
|
678
|
+
const s = { diameter: 1, segments: 32 };
|
|
679
|
+
return y.CreateSphere(e, { ...s, ...t }, i);
|
|
680
680
|
}
|
|
681
681
|
/**
|
|
682
682
|
* Creates a box mesh. Default size: 1.
|
|
@@ -684,9 +684,9 @@ class Ie {
|
|
|
684
684
|
* @param options
|
|
685
685
|
* @param scene
|
|
686
686
|
*/
|
|
687
|
-
createBox(e, t = {},
|
|
688
|
-
const
|
|
689
|
-
return y.CreateBox(e, { ...
|
|
687
|
+
createBox(e, t = {}, i) {
|
|
688
|
+
const s = { size: 1 };
|
|
689
|
+
return y.CreateBox(e, { ...s, ...t }, i);
|
|
690
690
|
}
|
|
691
691
|
/**
|
|
692
692
|
* Creates a ground mesh. Defaults: 6x6 with 2 subdivisions.
|
|
@@ -694,9 +694,9 @@ class Ie {
|
|
|
694
694
|
* @param options
|
|
695
695
|
* @param scene
|
|
696
696
|
*/
|
|
697
|
-
createGround(e, t = {},
|
|
698
|
-
const
|
|
699
|
-
return y.CreateGround(e, { ...
|
|
697
|
+
createGround(e, t = {}, i) {
|
|
698
|
+
const s = { width: 6, height: 6, subdivisions: 2 };
|
|
699
|
+
return y.CreateGround(e, { ...s, ...t }, i);
|
|
700
700
|
}
|
|
701
701
|
/**
|
|
702
702
|
* Creates a cylinder mesh. Defaults: height 2, diameter 1 (top and bottom).
|
|
@@ -704,9 +704,9 @@ class Ie {
|
|
|
704
704
|
* @param options
|
|
705
705
|
* @param scene
|
|
706
706
|
*/
|
|
707
|
-
createCylinder(e, t = {},
|
|
708
|
-
const
|
|
709
|
-
return y.CreateCylinder(e, { ...
|
|
707
|
+
createCylinder(e, t = {}, i) {
|
|
708
|
+
const s = { height: 2, diameterTop: 1, diameterBottom: 1 };
|
|
709
|
+
return y.CreateCylinder(e, { ...s, ...t }, i);
|
|
710
710
|
}
|
|
711
711
|
// Physics Utilities
|
|
712
712
|
/**
|
|
@@ -716,9 +716,9 @@ class Ie {
|
|
|
716
716
|
* @param physicsProps
|
|
717
717
|
* @param scene
|
|
718
718
|
*/
|
|
719
|
-
addPhysics(e, t,
|
|
719
|
+
addPhysics(e, t, i = {}, s) {
|
|
720
720
|
const n = { mass: 1, restitution: 0.75, friction: 0.5 };
|
|
721
|
-
return new se(e, t, { ...n, ...
|
|
721
|
+
return new se(e, t, { ...n, ...i }, s);
|
|
722
722
|
}
|
|
723
723
|
// Model Loading Utilities
|
|
724
724
|
/**
|
|
@@ -729,10 +729,10 @@ class Ie {
|
|
|
729
729
|
async loadModel(e, t) {
|
|
730
730
|
this._log.debug(`Loading model: ${e}`);
|
|
731
731
|
try {
|
|
732
|
-
const
|
|
733
|
-
return this._log.debug(`Model loaded successfully: ${e}`),
|
|
734
|
-
} catch (
|
|
735
|
-
throw this._log.error(`Failed to load model: ${e}`,
|
|
732
|
+
const i = await ue(`${e}`, t);
|
|
733
|
+
return this._log.debug(`Model loaded successfully: ${e}`), i;
|
|
734
|
+
} catch (i) {
|
|
735
|
+
throw this._log.error(`Failed to load model: ${e}`, i), i;
|
|
736
736
|
}
|
|
737
737
|
}
|
|
738
738
|
/**
|
|
@@ -741,13 +741,13 @@ class Ie {
|
|
|
741
741
|
* @param sceneFilename
|
|
742
742
|
* @param scene
|
|
743
743
|
*/
|
|
744
|
-
async importMeshes(e, t,
|
|
744
|
+
async importMeshes(e, t, i) {
|
|
745
745
|
this._log.debug(`Importing meshes from: ${t}`);
|
|
746
746
|
try {
|
|
747
|
-
const
|
|
747
|
+
const s = e.length > 0 ? { meshNames: e } : void 0, n = await ge(`${t}`, i, s);
|
|
748
748
|
return this._log.debug(`Meshes imported successfully: ${e.length > 0 ? e.join(", ") : "all"}`), n;
|
|
749
|
-
} catch (
|
|
750
|
-
throw this._log.error(`Failed to import meshes from: ${t}`,
|
|
749
|
+
} catch (s) {
|
|
750
|
+
throw this._log.error(`Failed to import meshes from: ${t}`, s), s;
|
|
751
751
|
}
|
|
752
752
|
}
|
|
753
753
|
/**
|
|
@@ -766,8 +766,8 @@ class Pe {
|
|
|
766
766
|
/** Extracted fragment meshes (source meshes for instancing), keyed by full fragment path */
|
|
767
767
|
_sourceMeshes = /* @__PURE__ */ new Map();
|
|
768
768
|
//------------------------------------------------------------------------------------------------------------------
|
|
769
|
-
constructor(e, t,
|
|
770
|
-
this._eventBus = e, this._sceneEngine = t, this._log =
|
|
769
|
+
constructor(e, t, i) {
|
|
770
|
+
this._eventBus = e, this._sceneEngine = t, this._log = i?.getLogger("AssetManager") ?? new u("AssetManager");
|
|
771
771
|
}
|
|
772
772
|
//------------------------------------------------------------------------------------------------------------------
|
|
773
773
|
// Private Helpers
|
|
@@ -791,26 +791,26 @@ class Pe {
|
|
|
791
791
|
if (t)
|
|
792
792
|
return t.refCount++, t.container;
|
|
793
793
|
this._log.debug(`Loading asset container: ${e}`);
|
|
794
|
-
const
|
|
794
|
+
const i = this._sceneEngine.createScene();
|
|
795
795
|
try {
|
|
796
|
-
const
|
|
797
|
-
return this._containers.set(e, { container:
|
|
796
|
+
const s = await this._sceneEngine.loadModel(e, i);
|
|
797
|
+
return this._containers.set(e, { container: s, refCount: 1 }), this._log.debug(`Cached asset container: ${e}`), s;
|
|
798
798
|
} finally {
|
|
799
|
-
|
|
799
|
+
i.dispose();
|
|
800
800
|
}
|
|
801
801
|
}
|
|
802
802
|
/**
|
|
803
803
|
* Find a mesh by name inside a container. Throws if not found.
|
|
804
804
|
*/
|
|
805
|
-
_findMeshInContainer(e, t,
|
|
806
|
-
const
|
|
807
|
-
if (!
|
|
805
|
+
_findMeshInContainer(e, t, i) {
|
|
806
|
+
const s = e.meshes.find((n) => n.name === t);
|
|
807
|
+
if (!s) {
|
|
808
808
|
const n = e.meshes.map((o) => o.name).join(", ");
|
|
809
809
|
throw new Error(
|
|
810
|
-
`Mesh '${t}' not found in container for '${
|
|
810
|
+
`Mesh '${t}' not found in container for '${i}'. Available meshes: ${n}`
|
|
811
811
|
);
|
|
812
812
|
}
|
|
813
|
-
return
|
|
813
|
+
return s;
|
|
814
814
|
}
|
|
815
815
|
//------------------------------------------------------------------------------------------------------------------
|
|
816
816
|
// Public API
|
|
@@ -824,14 +824,14 @@ class Pe {
|
|
|
824
824
|
* Increments refCount on the underlying container each time.
|
|
825
825
|
*/
|
|
826
826
|
async load(e) {
|
|
827
|
-
const { basePath: t, fragment:
|
|
828
|
-
if (
|
|
829
|
-
const
|
|
830
|
-
if (
|
|
827
|
+
const { basePath: t, fragment: i } = this._parsePath(e);
|
|
828
|
+
if (i) {
|
|
829
|
+
const s = this._sourceMeshes.get(e);
|
|
830
|
+
if (s) {
|
|
831
831
|
const a = this._containers.get(t);
|
|
832
|
-
return a && a.refCount++,
|
|
832
|
+
return a && a.refCount++, s;
|
|
833
833
|
}
|
|
834
|
-
const n = await this._loadContainer(t), o = this._findMeshInContainer(n,
|
|
834
|
+
const n = await this._loadContainer(t), o = this._findMeshInContainer(n, i, e);
|
|
835
835
|
return this._sourceMeshes.set(e, o), o;
|
|
836
836
|
}
|
|
837
837
|
return this._loadContainer(t);
|
|
@@ -859,12 +859,12 @@ class Pe {
|
|
|
859
859
|
*/
|
|
860
860
|
async preload(e) {
|
|
861
861
|
const t = e.length;
|
|
862
|
-
for (let
|
|
863
|
-
await this.load(e[
|
|
862
|
+
for (let i = 0; i < e.length; i++)
|
|
863
|
+
await this.load(e[i]), this._eventBus.publish({
|
|
864
864
|
type: "asset:progress",
|
|
865
865
|
payload: {
|
|
866
|
-
path: e[
|
|
867
|
-
loaded:
|
|
866
|
+
path: e[i],
|
|
867
|
+
loaded: i + 1,
|
|
868
868
|
total: t
|
|
869
869
|
}
|
|
870
870
|
});
|
|
@@ -878,12 +878,12 @@ class Pe {
|
|
|
878
878
|
* When refCount hits 0, dispose the container and clean up all fragment meshes from it.
|
|
879
879
|
*/
|
|
880
880
|
dispose(e) {
|
|
881
|
-
const { basePath: t } = this._parsePath(e),
|
|
882
|
-
if (
|
|
881
|
+
const { basePath: t } = this._parsePath(e), i = this._containers.get(t);
|
|
882
|
+
if (i && (i.refCount--, i.refCount <= 0)) {
|
|
883
883
|
this._log.debug(`Disposing asset container: ${t} (refCount reached 0)`);
|
|
884
|
-
for (const [
|
|
885
|
-
|
|
886
|
-
|
|
884
|
+
for (const [s, n] of this._sourceMeshes)
|
|
885
|
+
s.startsWith(`${t}#`) && (n.dispose(), this._sourceMeshes.delete(s));
|
|
886
|
+
i.container.dispose(), this._containers.delete(t);
|
|
887
887
|
}
|
|
888
888
|
}
|
|
889
889
|
/**
|
|
@@ -911,10 +911,10 @@ const ze = [
|
|
|
911
911
|
function Ve(r) {
|
|
912
912
|
return r.type === "keyboard";
|
|
913
913
|
}
|
|
914
|
-
function
|
|
914
|
+
function U(r) {
|
|
915
915
|
return r.type === "mouse";
|
|
916
916
|
}
|
|
917
|
-
function
|
|
917
|
+
function K(r) {
|
|
918
918
|
return r.type === "gamepad";
|
|
919
919
|
}
|
|
920
920
|
class Ne {
|
|
@@ -951,8 +951,8 @@ class Ne {
|
|
|
951
951
|
* @param reader
|
|
952
952
|
* @param options
|
|
953
953
|
*/
|
|
954
|
-
constructor(e, t,
|
|
955
|
-
this.action = e, this.deviceID = t, this.deviceType =
|
|
954
|
+
constructor(e, t, i, s, n = {}) {
|
|
955
|
+
this.action = e, this.deviceID = t, this.deviceType = i, this.reader = s, this.context = n.context, this._edgeMode = n.edgeMode ?? "rising", this._threshold = n.threshold ?? 0.5;
|
|
956
956
|
}
|
|
957
957
|
//------------------------------------------------------------------------------------------------------------------
|
|
958
958
|
// Public Methods
|
|
@@ -964,23 +964,23 @@ class Ne {
|
|
|
964
964
|
* @param eventBus
|
|
965
965
|
*/
|
|
966
966
|
process(e, t) {
|
|
967
|
-
const
|
|
967
|
+
const i = this.reader.getValue(e) ?? !1, s = typeof i == "boolean" ? i : i >= this._threshold;
|
|
968
968
|
let n = !1;
|
|
969
969
|
switch (this._edgeMode) {
|
|
970
970
|
case "rising":
|
|
971
|
-
n =
|
|
971
|
+
n = s && !this._lastDigitalState;
|
|
972
972
|
break;
|
|
973
973
|
case "falling":
|
|
974
|
-
n = !
|
|
974
|
+
n = !s && this._lastDigitalState;
|
|
975
975
|
break;
|
|
976
976
|
case "both":
|
|
977
|
-
n =
|
|
977
|
+
n = s !== this._lastDigitalState;
|
|
978
978
|
break;
|
|
979
979
|
}
|
|
980
|
-
if (this._lastDigitalState =
|
|
980
|
+
if (this._lastDigitalState = s, n) {
|
|
981
981
|
let o;
|
|
982
982
|
if (this.action.type === "analog") {
|
|
983
|
-
let l = typeof
|
|
983
|
+
let l = typeof i == "number" ? i : i ? 1 : 0;
|
|
984
984
|
if (this.action.minValue !== void 0 || this.action.maxValue !== void 0) {
|
|
985
985
|
const h = this.action.minValue ?? 0, c = this.action.maxValue ?? 1;
|
|
986
986
|
l = h + l * (c - h);
|
|
@@ -1098,8 +1098,8 @@ class Ge {
|
|
|
1098
1098
|
* @param reader
|
|
1099
1099
|
* @param options
|
|
1100
1100
|
*/
|
|
1101
|
-
constructor(e, t,
|
|
1102
|
-
this.action = e, this.deviceID = t, this.deviceType =
|
|
1101
|
+
constructor(e, t, i, s, n = {}) {
|
|
1102
|
+
this.action = e, this.deviceID = t, this.deviceType = i, this.reader = s, this.context = n.context, this._invert = n.invert ?? !1, this._threshold = n.threshold ?? 0.5, this._initialState = n.initialState ?? !1, this._toggleState = this._initialState, this._onValue = n.onValue ?? !0, this._offValue = n.offValue ?? !1;
|
|
1103
1103
|
}
|
|
1104
1104
|
//------------------------------------------------------------------------------------------------------------------
|
|
1105
1105
|
// Public Methods
|
|
@@ -1111,8 +1111,8 @@ class Ge {
|
|
|
1111
1111
|
* @param eventBus
|
|
1112
1112
|
*/
|
|
1113
1113
|
process(e, t) {
|
|
1114
|
-
const
|
|
1115
|
-
this._lastDigitalState =
|
|
1114
|
+
const i = this.reader.getValue(e) ?? !1, s = typeof i == "boolean" ? i : i >= this._threshold, n = this._invert ? !s && this._lastDigitalState : s && !this._lastDigitalState;
|
|
1115
|
+
this._lastDigitalState = s, n && (this._toggleState = !this._toggleState, t.publish({
|
|
1116
1116
|
type: `action:${this.action.name}`,
|
|
1117
1117
|
payload: {
|
|
1118
1118
|
value: this.value,
|
|
@@ -1200,8 +1200,8 @@ class Re {
|
|
|
1200
1200
|
* @param reader
|
|
1201
1201
|
* @param options
|
|
1202
1202
|
*/
|
|
1203
|
-
constructor(e, t,
|
|
1204
|
-
this.action = e, this.deviceID = t, this.deviceType =
|
|
1203
|
+
constructor(e, t, i, s, n = {}) {
|
|
1204
|
+
this.action = e, this.deviceID = t, this.deviceType = i, this.reader = s, this.context = n.context, this._scale = n.scale ?? 1, this._offset = n.offset ?? 0, this._invert = n.invert ?? !1, this._emitOnChange = n.emitOnChange ?? !0, this._deadzone = n.deadzone ?? 0, this._onValue = n.onValue ?? !0, this._offValue = n.offValue ?? !1;
|
|
1205
1205
|
const o = this.action.type === "analog" ? this.action.minValue ?? Number.NEGATIVE_INFINITY : Number.NEGATIVE_INFINITY;
|
|
1206
1206
|
this._min = n.min ?? o;
|
|
1207
1207
|
const a = this.action.type === "analog" ? this.action.maxValue ?? Number.POSITIVE_INFINITY : Number.POSITIVE_INFINITY;
|
|
@@ -1217,11 +1217,11 @@ class Re {
|
|
|
1217
1217
|
* @param eventBus
|
|
1218
1218
|
*/
|
|
1219
1219
|
process(e, t) {
|
|
1220
|
-
const
|
|
1221
|
-
if (
|
|
1220
|
+
const i = this.reader.getValue(e);
|
|
1221
|
+
if (i === void 0)
|
|
1222
1222
|
return;
|
|
1223
|
-
const
|
|
1224
|
-
let n = this._deadzone > 0 && Math.abs(
|
|
1223
|
+
const s = typeof i == "boolean" ? i ? 1 : 0 : i;
|
|
1224
|
+
let n = this._deadzone > 0 && Math.abs(s) < this._deadzone ? 0 : s;
|
|
1225
1225
|
n = (this._invert ? -n : n) * this._scale + this._offset, n = Math.max(this._min, Math.min(this._max, n)), !(this._emitOnChange && this._lastValue === n) && (this._lastValue = n, t.publish({
|
|
1226
1226
|
type: `action:${this.action.name}`,
|
|
1227
1227
|
payload: {
|
|
@@ -1339,8 +1339,8 @@ class z {
|
|
|
1339
1339
|
return t ? t.pressed : void 0;
|
|
1340
1340
|
}
|
|
1341
1341
|
case "position": {
|
|
1342
|
-
const [t,
|
|
1343
|
-
return !t || !
|
|
1342
|
+
const [t, i] = this.sourceKey.split(":");
|
|
1343
|
+
return !t || !i || t !== "absolute" && t !== "relative" || i !== "x" && i !== "y" ? void 0 : e.position[t][i];
|
|
1344
1344
|
}
|
|
1345
1345
|
case "wheel": {
|
|
1346
1346
|
const t = this.sourceKey === "deltaX" || this.sourceKey === "deltaY" || this.sourceKey === "deltaZ";
|
|
@@ -1356,12 +1356,12 @@ class z {
|
|
|
1356
1356
|
* @param sourceTypeString
|
|
1357
1357
|
*/
|
|
1358
1358
|
static fromString(e) {
|
|
1359
|
-
const [t, ...
|
|
1360
|
-
if (!t || !
|
|
1359
|
+
const [t, ...i] = e.split(":"), s = i.join(":");
|
|
1360
|
+
if (!t || !s)
|
|
1361
1361
|
throw new Error(`Invalid mouse source format: ${e}`);
|
|
1362
1362
|
return new z(
|
|
1363
1363
|
t,
|
|
1364
|
-
|
|
1364
|
+
s
|
|
1365
1365
|
);
|
|
1366
1366
|
}
|
|
1367
1367
|
/**
|
|
@@ -1403,8 +1403,8 @@ class V {
|
|
|
1403
1403
|
* @param sourceKey - e.g. "button-0", "axis-1"
|
|
1404
1404
|
* @param options
|
|
1405
1405
|
*/
|
|
1406
|
-
constructor(e, t,
|
|
1407
|
-
this.sourceType = e, this.sourceKey = t, this.useAnalogValue =
|
|
1406
|
+
constructor(e, t, i = {}) {
|
|
1407
|
+
this.sourceType = e, this.sourceKey = t, this.useAnalogValue = i.useAnalogValue || !1, this.deadzone = i.deadzone || 0.1, this.invert = i.invert || !1;
|
|
1408
1408
|
}
|
|
1409
1409
|
/**
|
|
1410
1410
|
* Gets the value of the input source. Returns undefined for non-gamepad input states.
|
|
@@ -1433,12 +1433,12 @@ class V {
|
|
|
1433
1433
|
* @param options
|
|
1434
1434
|
*/
|
|
1435
1435
|
static fromString(e, t = {}) {
|
|
1436
|
-
const [
|
|
1437
|
-
if (!
|
|
1436
|
+
const [i, s] = e.split(":");
|
|
1437
|
+
if (!i || !s)
|
|
1438
1438
|
throw new Error(`Invalid gamepad source format: ${e}`);
|
|
1439
1439
|
return new V(
|
|
1440
|
-
s,
|
|
1441
1440
|
i,
|
|
1441
|
+
s,
|
|
1442
1442
|
t
|
|
1443
1443
|
);
|
|
1444
1444
|
}
|
|
@@ -1492,9 +1492,9 @@ class Ue {
|
|
|
1492
1492
|
constructor(e, t) {
|
|
1493
1493
|
this._eventBus = e, this._inputUnsubscribe = this._eventBus.subscribe(
|
|
1494
1494
|
"input:changed",
|
|
1495
|
-
(
|
|
1496
|
-
const
|
|
1497
|
-
|
|
1495
|
+
(i) => {
|
|
1496
|
+
const s = i.payload;
|
|
1497
|
+
s && this.$handleInput(s.device, s.state);
|
|
1498
1498
|
}
|
|
1499
1499
|
), this._log = t?.getLogger("BindingManager") || new u("BindingManager"), this._log.debug("BindingManager initialized");
|
|
1500
1500
|
}
|
|
@@ -1517,11 +1517,11 @@ class Ue {
|
|
|
1517
1517
|
* @param exclusive - Only used when creating a new context
|
|
1518
1518
|
*/
|
|
1519
1519
|
_getOrCreateContext(e, t = !0) {
|
|
1520
|
-
let
|
|
1521
|
-
return
|
|
1520
|
+
let i = this._contexts.get(e);
|
|
1521
|
+
return i || (i = {
|
|
1522
1522
|
name: e,
|
|
1523
1523
|
exclusive: t
|
|
1524
|
-
}, this._contexts.set(e,
|
|
1524
|
+
}, this._contexts.set(e, i), this._log.debug(`Auto-created context "${e}" (exclusive: ${t})`)), i;
|
|
1525
1525
|
}
|
|
1526
1526
|
/**
|
|
1527
1527
|
* Deactivate all exclusive contexts except the specified one.
|
|
@@ -1531,10 +1531,10 @@ class Ue {
|
|
|
1531
1531
|
*/
|
|
1532
1532
|
_deactivateExclusiveContexts(e) {
|
|
1533
1533
|
const t = [];
|
|
1534
|
-
for (const
|
|
1535
|
-
if (
|
|
1534
|
+
for (const i of this._activeContexts) {
|
|
1535
|
+
if (i === e)
|
|
1536
1536
|
continue;
|
|
1537
|
-
this._contexts.get(
|
|
1537
|
+
this._contexts.get(i)?.exclusive && (this._activeContexts.delete(i), t.push(i));
|
|
1538
1538
|
}
|
|
1539
1539
|
return t;
|
|
1540
1540
|
}
|
|
@@ -1545,7 +1545,7 @@ class Ue {
|
|
|
1545
1545
|
* @param state
|
|
1546
1546
|
*/
|
|
1547
1547
|
_shouldUpdateActiveDevice(e) {
|
|
1548
|
-
return
|
|
1548
|
+
return U(e) ? Object.values(e.buttons).some((t) => t.pressed) || e.wheel !== void 0 : K(e) ? Object.values(e.buttons).some((t) => t.pressed) || Object.values(e.axes).some((t) => Math.abs(t) > Oe) : !0;
|
|
1549
1549
|
}
|
|
1550
1550
|
/**
|
|
1551
1551
|
* Create a binding from a binding definition.
|
|
@@ -1557,14 +1557,14 @@ class Ue {
|
|
|
1557
1557
|
const t = this._actions.get(e.action);
|
|
1558
1558
|
if (!t)
|
|
1559
1559
|
return this._log.warn(`Cannot create binding: Action "${e.action}" not found.`), null;
|
|
1560
|
-
const { deviceID:
|
|
1560
|
+
const { deviceID: i, ...s } = e.input;
|
|
1561
1561
|
switch (e.type) {
|
|
1562
1562
|
case "trigger":
|
|
1563
1563
|
return new Ne(
|
|
1564
1564
|
t,
|
|
1565
|
-
|
|
1565
|
+
i,
|
|
1566
1566
|
e.input.type,
|
|
1567
|
-
this._createInputSourceFromDefinition(
|
|
1567
|
+
this._createInputSourceFromDefinition(s),
|
|
1568
1568
|
{
|
|
1569
1569
|
...e.options || {},
|
|
1570
1570
|
context: e.context
|
|
@@ -1573,9 +1573,9 @@ class Ue {
|
|
|
1573
1573
|
case "toggle":
|
|
1574
1574
|
return new Ge(
|
|
1575
1575
|
t,
|
|
1576
|
-
|
|
1576
|
+
i,
|
|
1577
1577
|
e.input.type,
|
|
1578
|
-
this._createInputSourceFromDefinition(
|
|
1578
|
+
this._createInputSourceFromDefinition(s),
|
|
1579
1579
|
{
|
|
1580
1580
|
...e.options || {},
|
|
1581
1581
|
context: e.context
|
|
@@ -1584,9 +1584,9 @@ class Ue {
|
|
|
1584
1584
|
case "value":
|
|
1585
1585
|
return new Re(
|
|
1586
1586
|
t,
|
|
1587
|
-
|
|
1587
|
+
i,
|
|
1588
1588
|
e.input.type,
|
|
1589
|
-
this._createInputSourceFromDefinition(
|
|
1589
|
+
this._createInputSourceFromDefinition(s),
|
|
1590
1590
|
{
|
|
1591
1591
|
...e.options || {},
|
|
1592
1592
|
context: e.context
|
|
@@ -1640,11 +1640,11 @@ class Ue {
|
|
|
1640
1640
|
* @param state
|
|
1641
1641
|
*/
|
|
1642
1642
|
_processCaptureInput(e, t) {
|
|
1643
|
-
const
|
|
1644
|
-
if (!
|
|
1643
|
+
const i = this._captureState;
|
|
1644
|
+
if (!i)
|
|
1645
1645
|
return;
|
|
1646
|
-
const { options:
|
|
1647
|
-
if (!
|
|
1646
|
+
const { options: s } = i;
|
|
1647
|
+
if (!s.deviceTypes.includes(e.type))
|
|
1648
1648
|
return;
|
|
1649
1649
|
let n = null;
|
|
1650
1650
|
if (Ve(t)) {
|
|
@@ -1655,13 +1655,13 @@ class Ue {
|
|
|
1655
1655
|
n = { type: "keyboard", sourceType: "key", sourceKey: a, deviceID: e.id };
|
|
1656
1656
|
break;
|
|
1657
1657
|
}
|
|
1658
|
-
} else if (
|
|
1658
|
+
} else if (U(t)) {
|
|
1659
1659
|
for (const a of Object.keys(t.buttons))
|
|
1660
1660
|
if (t.buttons[a].pressed) {
|
|
1661
1661
|
n = { type: "mouse", sourceType: "button", sourceKey: a, deviceID: e.id };
|
|
1662
1662
|
break;
|
|
1663
1663
|
}
|
|
1664
|
-
} else if (
|
|
1664
|
+
} else if (K(t)) {
|
|
1665
1665
|
for (const a of Object.keys(t.buttons))
|
|
1666
1666
|
if (t.buttons[a].pressed) {
|
|
1667
1667
|
n = { type: "gamepad", sourceType: "button", sourceKey: a, deviceID: e.id };
|
|
@@ -1675,9 +1675,9 @@ class Ue {
|
|
|
1675
1675
|
}
|
|
1676
1676
|
}
|
|
1677
1677
|
}
|
|
1678
|
-
if (!n ||
|
|
1678
|
+
if (!n || s.sourceTypes && !s.sourceTypes.includes(n.sourceType))
|
|
1679
1679
|
return;
|
|
1680
|
-
const { resolve: o } =
|
|
1680
|
+
const { resolve: o } = i;
|
|
1681
1681
|
this._cleanupCapture(), o(n);
|
|
1682
1682
|
}
|
|
1683
1683
|
/**
|
|
@@ -1691,8 +1691,8 @@ class Ue {
|
|
|
1691
1691
|
e.abortCleanup && e.abortCleanup();
|
|
1692
1692
|
const { snapshot: t } = e;
|
|
1693
1693
|
this._captureState = null, this.deactivateContext("__sage_capture__"), this._contexts.delete("__sage_capture__");
|
|
1694
|
-
for (const
|
|
1695
|
-
this.activateContext(
|
|
1694
|
+
for (const i of t)
|
|
1695
|
+
this.activateContext(i);
|
|
1696
1696
|
}
|
|
1697
1697
|
//------------------------------------------------------------------------------------------------------------------
|
|
1698
1698
|
// Internal API
|
|
@@ -1711,20 +1711,20 @@ class Ue {
|
|
|
1711
1711
|
*/
|
|
1712
1712
|
$handleInput(e, t) {
|
|
1713
1713
|
if (this._lastInputState.set(e.id, t), this._shouldUpdateActiveDevice(t) && e.type !== this._lastActiveDeviceType) {
|
|
1714
|
-
const
|
|
1714
|
+
const s = this._lastActiveDeviceType;
|
|
1715
1715
|
this._lastActiveDeviceType = e.type, this._eventBus.publish({
|
|
1716
1716
|
type: "input:device-type:changed",
|
|
1717
|
-
payload: { deviceType: e.type, previousDeviceType:
|
|
1717
|
+
payload: { deviceType: e.type, previousDeviceType: s }
|
|
1718
1718
|
});
|
|
1719
1719
|
}
|
|
1720
1720
|
if (this._captureState) {
|
|
1721
1721
|
this._processCaptureInput(e, t);
|
|
1722
1722
|
return;
|
|
1723
1723
|
}
|
|
1724
|
-
const
|
|
1725
|
-
if (!(!
|
|
1726
|
-
for (const
|
|
1727
|
-
this._isBindingContextActive(
|
|
1724
|
+
const i = this._bindings.get(e.id);
|
|
1725
|
+
if (!(!i || i.length === 0) && !(this._activeContexts.size === 0 && i.some((s) => s.context)))
|
|
1726
|
+
for (const s of i)
|
|
1727
|
+
this._isBindingContextActive(s) && s.process(t, this._eventBus);
|
|
1728
1728
|
}
|
|
1729
1729
|
//------------------------------------------------------------------------------------------------------------------
|
|
1730
1730
|
// Action Management API
|
|
@@ -1777,16 +1777,16 @@ class Ue {
|
|
|
1777
1777
|
if (this._captureState)
|
|
1778
1778
|
throw new Error("captureInput() already in progress");
|
|
1779
1779
|
const t = [...this._activeContexts];
|
|
1780
|
-
return this.registerContext("__sage_capture__", !0), this.activateContext("__sage_capture__"), new Promise((
|
|
1781
|
-
const n = { resolve:
|
|
1780
|
+
return this.registerContext("__sage_capture__", !0), this.activateContext("__sage_capture__"), new Promise((i, s) => {
|
|
1781
|
+
const n = { resolve: i, reject: s, options: e, snapshot: t };
|
|
1782
1782
|
if (this._captureState = n, e.signal) {
|
|
1783
1783
|
if (e.signal.aborted) {
|
|
1784
|
-
this._cleanupCapture(),
|
|
1784
|
+
this._cleanupCapture(), s(e.signal.reason ?? new Error("captureInput() aborted"));
|
|
1785
1785
|
return;
|
|
1786
1786
|
}
|
|
1787
1787
|
const o = () => {
|
|
1788
1788
|
const a = e.signal?.reason ?? new Error("captureInput() aborted");
|
|
1789
|
-
this._cleanupCapture(),
|
|
1789
|
+
this._cleanupCapture(), s(a);
|
|
1790
1790
|
};
|
|
1791
1791
|
e.signal.addEventListener("abort", o, { once: !0 }), n.abortCleanup = () => {
|
|
1792
1792
|
e.signal?.removeEventListener("abort", o);
|
|
@@ -1805,8 +1805,8 @@ class Ue {
|
|
|
1805
1805
|
* @param exclusive
|
|
1806
1806
|
*/
|
|
1807
1807
|
registerContext(e, t = !0) {
|
|
1808
|
-
const
|
|
1809
|
-
return
|
|
1808
|
+
const i = this._getOrCreateContext(e, t);
|
|
1809
|
+
return i.exclusive !== t && (i.exclusive = t, this._log.info(`Updated context "${e}" exclusivity: ${t}`)), i;
|
|
1810
1810
|
}
|
|
1811
1811
|
/**
|
|
1812
1812
|
* Activates a context, enabling all bindings associated with it.
|
|
@@ -1815,21 +1815,21 @@ class Ue {
|
|
|
1815
1815
|
* @param contextName
|
|
1816
1816
|
*/
|
|
1817
1817
|
activateContext(e) {
|
|
1818
|
-
const
|
|
1819
|
-
this._log.debug(`Activating context "${e}" (exclusive: ${
|
|
1820
|
-
const
|
|
1821
|
-
if (
|
|
1818
|
+
const i = this._getOrCreateContext(e).exclusive;
|
|
1819
|
+
this._log.debug(`Activating context "${e}" (exclusive: ${i})`);
|
|
1820
|
+
const s = this._activeContexts.has(e);
|
|
1821
|
+
if (i) {
|
|
1822
1822
|
const n = this._deactivateExclusiveContexts(e);
|
|
1823
1823
|
n.length > 0 && this._log.info(`Deactivated exclusive contexts: ${n.join(", ")}`);
|
|
1824
1824
|
}
|
|
1825
|
-
if (!
|
|
1825
|
+
if (!s) {
|
|
1826
1826
|
this._activeContexts.add(e);
|
|
1827
1827
|
for (const [n, o] of this._bindings.entries()) {
|
|
1828
1828
|
const a = this._lastInputState.get(n);
|
|
1829
1829
|
for (const l of o)
|
|
1830
1830
|
l.context === e && l.resetEdgeState(a);
|
|
1831
1831
|
}
|
|
1832
|
-
this._log.info(`Context "${e}" activated${
|
|
1832
|
+
this._log.info(`Context "${e}" activated${i ? " as exclusive" : ""}`);
|
|
1833
1833
|
}
|
|
1834
1834
|
}
|
|
1835
1835
|
/**
|
|
@@ -1895,15 +1895,15 @@ class Ue {
|
|
|
1895
1895
|
*/
|
|
1896
1896
|
unregisterBindings(e, t = null) {
|
|
1897
1897
|
this._log.debug(`Unregistering all bindings for action "${e}" in context "${t}"`);
|
|
1898
|
-
let
|
|
1899
|
-
for (const [
|
|
1898
|
+
let i = 0;
|
|
1899
|
+
for (const [s, n] of this._bindings.entries()) {
|
|
1900
1900
|
const o = n.filter((a) => {
|
|
1901
1901
|
const l = a.context || null, h = a.action.name !== e || l !== t;
|
|
1902
|
-
return h ||
|
|
1902
|
+
return h || i++, h;
|
|
1903
1903
|
});
|
|
1904
|
-
o.length !== n.length && this._bindings.set(
|
|
1904
|
+
o.length !== n.length && this._bindings.set(s, o);
|
|
1905
1905
|
}
|
|
1906
|
-
this._log.info(`Removed ${
|
|
1906
|
+
this._log.info(`Removed ${i} bindings for action "${e}" in context "${t}"`);
|
|
1907
1907
|
}
|
|
1908
1908
|
/**
|
|
1909
1909
|
* Gets all bindings for a specific action, optionally filtered by device type and/or context.
|
|
@@ -1912,16 +1912,16 @@ class Ue {
|
|
|
1912
1912
|
* @param deviceType - If provided, filters to only bindings for that device type
|
|
1913
1913
|
* @param context - If provided, filters to only bindings in that context
|
|
1914
1914
|
*/
|
|
1915
|
-
getBindingsForAction(e, t,
|
|
1916
|
-
const
|
|
1915
|
+
getBindingsForAction(e, t, i) {
|
|
1916
|
+
const s = [];
|
|
1917
1917
|
for (const n of this._bindings.values())
|
|
1918
1918
|
for (const o of n) {
|
|
1919
1919
|
if (o.action.name !== e || t !== void 0 && o.deviceType !== t)
|
|
1920
1920
|
continue;
|
|
1921
1921
|
const a = o.context || null;
|
|
1922
|
-
|
|
1922
|
+
i !== void 0 && a !== i || s.push(o);
|
|
1923
1923
|
}
|
|
1924
|
-
return
|
|
1924
|
+
return s;
|
|
1925
1925
|
}
|
|
1926
1926
|
//------------------------------------------------------------------------------------------------------------------
|
|
1927
1927
|
// Configuration Management API
|
|
@@ -1932,25 +1932,25 @@ class Ue {
|
|
|
1932
1932
|
*/
|
|
1933
1933
|
exportConfiguration() {
|
|
1934
1934
|
this._log.debug("Exporting binding configuration");
|
|
1935
|
-
const e = [...this._actions.values()].map((
|
|
1936
|
-
name:
|
|
1937
|
-
type:
|
|
1938
|
-
label:
|
|
1939
|
-
minValue:
|
|
1940
|
-
maxValue:
|
|
1941
|
-
} :
|
|
1942
|
-
for (const
|
|
1943
|
-
for (const n of
|
|
1935
|
+
const e = [...this._actions.values()].map((s) => s.type === "analog" ? {
|
|
1936
|
+
name: s.name,
|
|
1937
|
+
type: s.type,
|
|
1938
|
+
label: s.label,
|
|
1939
|
+
minValue: s.minValue ?? 0,
|
|
1940
|
+
maxValue: s.maxValue ?? 1
|
|
1941
|
+
} : s), t = [];
|
|
1942
|
+
for (const s of this._bindings.values())
|
|
1943
|
+
for (const n of s)
|
|
1944
1944
|
t.push(n.toJSON());
|
|
1945
|
-
const
|
|
1946
|
-
name:
|
|
1947
|
-
exclusive:
|
|
1948
|
-
active: this._activeContexts.has(
|
|
1945
|
+
const i = [...this._contexts.values()].map((s) => ({
|
|
1946
|
+
name: s.name,
|
|
1947
|
+
exclusive: s.exclusive,
|
|
1948
|
+
active: this._activeContexts.has(s.name)
|
|
1949
1949
|
}));
|
|
1950
|
-
return this._log.info(`Configuration exported: ${e.length} actions, ${t.length} bindings, ${
|
|
1950
|
+
return this._log.info(`Configuration exported: ${e.length} actions, ${t.length} bindings, ${i.length} contexts`), {
|
|
1951
1951
|
actions: e,
|
|
1952
1952
|
bindings: t,
|
|
1953
|
-
contexts:
|
|
1953
|
+
contexts: i
|
|
1954
1954
|
};
|
|
1955
1955
|
}
|
|
1956
1956
|
/**
|
|
@@ -1967,8 +1967,8 @@ class Ue {
|
|
|
1967
1967
|
for (const t of e.bindings)
|
|
1968
1968
|
try {
|
|
1969
1969
|
this.registerBinding(t);
|
|
1970
|
-
} catch (
|
|
1971
|
-
|
|
1970
|
+
} catch (i) {
|
|
1971
|
+
i instanceof Error && this._log.error(`Failed to import binding for action "${t.action}": ${i.message}`);
|
|
1972
1972
|
}
|
|
1973
1973
|
this._log.info(`Configuration imported: ${e.actions.length} actions, ${e.bindings.length} bindings, ${e.contexts.length} contexts`);
|
|
1974
1974
|
}
|
|
@@ -1986,7 +1986,7 @@ class Ue {
|
|
|
1986
1986
|
function T() {
|
|
1987
1987
|
return typeof window < "u" && typeof window.document < "u";
|
|
1988
1988
|
}
|
|
1989
|
-
function
|
|
1989
|
+
function F() {
|
|
1990
1990
|
return T() && !!window.navigator.gpu;
|
|
1991
1991
|
}
|
|
1992
1992
|
class Ke {
|
|
@@ -2006,8 +2006,8 @@ class Ke {
|
|
|
2006
2006
|
_paused = !1;
|
|
2007
2007
|
started = !1;
|
|
2008
2008
|
//------------------------------------------------------------------------------------------------------------------
|
|
2009
|
-
constructor(e, t,
|
|
2010
|
-
this._engine = e, this._eventBus = t, this._entityManager =
|
|
2009
|
+
constructor(e, t, i, s, n, o) {
|
|
2010
|
+
this._engine = e, this._eventBus = t, this._entityManager = i, this._inputManager = s, this._levelManager = n, this._log = o?.getLogger("GameManager") || new u("GameManager"), this._boundRenderLoop = this._renderLoop.bind(this), this._boundResizeHandler = this._resizeHandler.bind(this), T() && window.addEventListener("resize", this._boundResizeHandler);
|
|
2011
2011
|
}
|
|
2012
2012
|
get currentScene() {
|
|
2013
2013
|
return this._levelManager.currentLevel?.scene ?? null;
|
|
@@ -2047,8 +2047,8 @@ class Ke {
|
|
|
2047
2047
|
registerFrameCallback(e) {
|
|
2048
2048
|
const t = this._nextCallbackId++;
|
|
2049
2049
|
return this._frameCallbacks.push({ id: t, callback: e }), this._log.debug(`Registered frame callback (id: ${t})`), () => {
|
|
2050
|
-
const
|
|
2051
|
-
|
|
2050
|
+
const i = this._frameCallbacks.findIndex((s) => s.id === t);
|
|
2051
|
+
i !== -1 && (this._frameCallbacks.splice(i, 1), this._log.debug(`Unregistered frame callback (id: ${t})`));
|
|
2052
2052
|
};
|
|
2053
2053
|
}
|
|
2054
2054
|
//------------------------------------------------------------------------------------------------------------------
|
|
@@ -2056,11 +2056,11 @@ class Ke {
|
|
|
2056
2056
|
const t = this._engine.getDeltaTime() / 1e3;
|
|
2057
2057
|
if (this._inputManager.pollGamepads(), !this._paused) {
|
|
2058
2058
|
this._entityManager.$frameUpdate(t);
|
|
2059
|
-
for (const { callback:
|
|
2059
|
+
for (const { callback: i } of this._frameCallbacks)
|
|
2060
2060
|
try {
|
|
2061
|
-
|
|
2062
|
-
} catch (
|
|
2063
|
-
this._log.error("Error in frame callback:",
|
|
2061
|
+
i(t);
|
|
2062
|
+
} catch (s) {
|
|
2063
|
+
this._log.error("Error in frame callback:", s);
|
|
2064
2064
|
}
|
|
2065
2065
|
}
|
|
2066
2066
|
this.currentScene && this.currentScene.render();
|
|
@@ -2135,7 +2135,7 @@ function Fe(r) {
|
|
|
2135
2135
|
};
|
|
2136
2136
|
}
|
|
2137
2137
|
const We = Fe(16);
|
|
2138
|
-
class
|
|
2138
|
+
class ae {
|
|
2139
2139
|
entity = null;
|
|
2140
2140
|
//------------------------------------------------------------------------------------------------------------------
|
|
2141
2141
|
// Internal API
|
|
@@ -2205,9 +2205,9 @@ class je {
|
|
|
2205
2205
|
* @param behaviors - Attached in order; order determines event processing priority.
|
|
2206
2206
|
* @param name
|
|
2207
2207
|
*/
|
|
2208
|
-
constructor(e, t,
|
|
2209
|
-
this.id = We(), this.type = e, this.name = n, this.state =
|
|
2210
|
-
for (const o of
|
|
2208
|
+
constructor(e, t, i, s, n) {
|
|
2209
|
+
this.id = We(), this.type = e, this.name = n, this.state = i, this.eventBus = t;
|
|
2210
|
+
for (const o of s)
|
|
2211
2211
|
this.attachBehavior(new o());
|
|
2212
2212
|
}
|
|
2213
2213
|
//------------------------------------------------------------------------------------------------------------------
|
|
@@ -2262,9 +2262,9 @@ class je {
|
|
|
2262
2262
|
if (!this.node)
|
|
2263
2263
|
return;
|
|
2264
2264
|
let t = this.node;
|
|
2265
|
-
for (const
|
|
2265
|
+
for (const i of e.split("/"))
|
|
2266
2266
|
t = t?.getChildren(
|
|
2267
|
-
(
|
|
2267
|
+
(s) => s.name === i,
|
|
2268
2268
|
!1
|
|
2269
2269
|
)[0];
|
|
2270
2270
|
return t;
|
|
@@ -2278,10 +2278,10 @@ class je {
|
|
|
2278
2278
|
*/
|
|
2279
2279
|
$attachToNode(e, t) {
|
|
2280
2280
|
this.node = e, this._gameEngine = t;
|
|
2281
|
-
for (const
|
|
2282
|
-
|
|
2283
|
-
for (const
|
|
2284
|
-
|
|
2281
|
+
for (const i of this.behaviors)
|
|
2282
|
+
i.onNodeAttached?.(e, t);
|
|
2283
|
+
for (const i of this.children)
|
|
2284
|
+
i.node && (i.node.parent = e);
|
|
2285
2285
|
}
|
|
2286
2286
|
/**
|
|
2287
2287
|
* Internal method for EntityManager to detach entity from its node.
|
|
@@ -2335,12 +2335,12 @@ class je {
|
|
|
2335
2335
|
* @param type - Event type string
|
|
2336
2336
|
* @param payload - Optional event payload
|
|
2337
2337
|
*/
|
|
2338
|
-
async send(e, t,
|
|
2338
|
+
async send(e, t, i) {
|
|
2339
2339
|
if (e === this.id)
|
|
2340
|
-
return this.$send(t,
|
|
2340
|
+
return this.$send(t, i, this.id);
|
|
2341
2341
|
if (!this._entityManager)
|
|
2342
2342
|
throw new Error("Entity is not registered with an EntityManager.");
|
|
2343
|
-
return this._entityManager.send(e, t,
|
|
2343
|
+
return this._entityManager.send(e, t, i, this.id);
|
|
2344
2344
|
}
|
|
2345
2345
|
/**
|
|
2346
2346
|
* Sends a request to a specific entity's behaviors and returns the first response.
|
|
@@ -2350,12 +2350,12 @@ class je {
|
|
|
2350
2350
|
* @param type - Request type string
|
|
2351
2351
|
* @param payload - Optional request payload
|
|
2352
2352
|
*/
|
|
2353
|
-
async request(e, t,
|
|
2353
|
+
async request(e, t, i) {
|
|
2354
2354
|
if (e === this.id)
|
|
2355
|
-
return this.$request(t,
|
|
2355
|
+
return this.$request(t, i, this.id);
|
|
2356
2356
|
if (!this._entityManager)
|
|
2357
2357
|
throw new Error("Entity is not registered with an EntityManager.");
|
|
2358
|
-
return this._entityManager.request(e, t,
|
|
2358
|
+
return this._entityManager.request(e, t, i, this.id);
|
|
2359
2359
|
}
|
|
2360
2360
|
/**
|
|
2361
2361
|
* Sends a fire-and-forget event directly to this entity's own behaviors.
|
|
@@ -2364,8 +2364,8 @@ class je {
|
|
|
2364
2364
|
* @param payload - Optional event payload
|
|
2365
2365
|
* @internal
|
|
2366
2366
|
*/
|
|
2367
|
-
async $send(e, t,
|
|
2368
|
-
await this.$processEvent({ type: e, targetID: this.id, senderID:
|
|
2367
|
+
async $send(e, t, i) {
|
|
2368
|
+
await this.$processEvent({ type: e, targetID: this.id, senderID: i, payload: t });
|
|
2369
2369
|
}
|
|
2370
2370
|
/**
|
|
2371
2371
|
* Sends a request to this entity's own behaviors and returns the first response.
|
|
@@ -2374,12 +2374,12 @@ class je {
|
|
|
2374
2374
|
* @param payload - Optional request payload
|
|
2375
2375
|
* @internal
|
|
2376
2376
|
*/
|
|
2377
|
-
async $request(e, t,
|
|
2378
|
-
const
|
|
2377
|
+
async $request(e, t, i) {
|
|
2378
|
+
const s = { type: e, targetID: this.id, senderID: i, payload: t };
|
|
2379
2379
|
let n;
|
|
2380
2380
|
for (const o of this.behaviors)
|
|
2381
2381
|
try {
|
|
2382
|
-
const a = await o.processRequest?.(
|
|
2382
|
+
const a = await o.processRequest?.(s, this.state);
|
|
2383
2383
|
if (a !== void 0)
|
|
2384
2384
|
return { success: !0, value: a };
|
|
2385
2385
|
} catch (a) {
|
|
@@ -2401,13 +2401,13 @@ class je {
|
|
|
2401
2401
|
*/
|
|
2402
2402
|
$reset(e, t) {
|
|
2403
2403
|
this.state = { ...e }, this._tags.clear();
|
|
2404
|
-
for (const
|
|
2405
|
-
this._tags.add(
|
|
2404
|
+
for (const i of t)
|
|
2405
|
+
this._tags.add(i);
|
|
2406
2406
|
this.node && this.$detachFromNode();
|
|
2407
|
-
for (const
|
|
2408
|
-
|
|
2409
|
-
for (const
|
|
2410
|
-
|
|
2407
|
+
for (const i of this.behaviors)
|
|
2408
|
+
i.onReset?.(this.state);
|
|
2409
|
+
for (const i of this.children)
|
|
2410
|
+
i.$reset({}, []);
|
|
2411
2411
|
this.parent = null;
|
|
2412
2412
|
}
|
|
2413
2413
|
/**
|
|
@@ -2480,33 +2480,33 @@ class je {
|
|
|
2480
2480
|
attachBehavior(e, t) {
|
|
2481
2481
|
if (this.hasBehavior(e.constructor))
|
|
2482
2482
|
throw new Error(`Behavior ${e.constructor.name} is already attached to this entity.`);
|
|
2483
|
-
for (const
|
|
2484
|
-
const
|
|
2485
|
-
if (
|
|
2486
|
-
|
|
2483
|
+
for (const i of e.eventSubscriptions) {
|
|
2484
|
+
const s = this.subscriptions.get(i);
|
|
2485
|
+
if (s)
|
|
2486
|
+
s.count++;
|
|
2487
2487
|
else {
|
|
2488
|
-
const o = this.eventBus.subscribe(
|
|
2489
|
-
this.subscriptions.set(
|
|
2488
|
+
const o = this.eventBus.subscribe(i, this.$processEvent.bind(this));
|
|
2489
|
+
this.subscriptions.set(i, { count: 1, unsubscribe: o });
|
|
2490
2490
|
}
|
|
2491
2491
|
}
|
|
2492
2492
|
if (!t)
|
|
2493
2493
|
this.behaviors.push(e);
|
|
2494
2494
|
else {
|
|
2495
|
-
if ([t.before, t.after, t.at].filter((
|
|
2495
|
+
if ([t.before, t.after, t.at].filter((s) => s !== void 0).length > 1)
|
|
2496
2496
|
throw new Error("attachBehavior: specify only one of before, after, or at");
|
|
2497
2497
|
if (t.before) {
|
|
2498
|
-
const
|
|
2499
|
-
if (
|
|
2498
|
+
const s = this.findBehaviorIndex(t.before);
|
|
2499
|
+
if (s === -1)
|
|
2500
2500
|
throw new Error(`attachBehavior: no behavior of type ${t.before.name} found`);
|
|
2501
|
-
this.behaviors.splice(
|
|
2501
|
+
this.behaviors.splice(s, 0, e);
|
|
2502
2502
|
} else if (t.after) {
|
|
2503
|
-
const
|
|
2504
|
-
if (
|
|
2503
|
+
const s = this.findBehaviorIndex(t.after);
|
|
2504
|
+
if (s === -1)
|
|
2505
2505
|
throw new Error(`attachBehavior: no behavior of type ${t.after.name} found`);
|
|
2506
|
-
this.behaviors.splice(
|
|
2506
|
+
this.behaviors.splice(s + 1, 0, e);
|
|
2507
2507
|
} else if (t.at !== void 0) {
|
|
2508
|
-
const
|
|
2509
|
-
this.behaviors.splice(
|
|
2508
|
+
const s = Math.max(0, Math.min(t.at, this.behaviors.length));
|
|
2509
|
+
this.behaviors.splice(s, 0, e);
|
|
2510
2510
|
} else
|
|
2511
2511
|
this.behaviors.push(e);
|
|
2512
2512
|
}
|
|
@@ -2520,13 +2520,13 @@ class je {
|
|
|
2520
2520
|
const t = this.findBehaviorIndex(e);
|
|
2521
2521
|
if (t === -1)
|
|
2522
2522
|
return !1;
|
|
2523
|
-
const
|
|
2524
|
-
this.node &&
|
|
2525
|
-
for (const
|
|
2526
|
-
const n = this.subscriptions.get(
|
|
2527
|
-
n && (n.count--, n.count <= 0 && (n.unsubscribe(), this.subscriptions.delete(
|
|
2523
|
+
const i = this.behaviors[t];
|
|
2524
|
+
this.node && i.onNodeDetached?.();
|
|
2525
|
+
for (const s of i.eventSubscriptions) {
|
|
2526
|
+
const n = this.subscriptions.get(s);
|
|
2527
|
+
n && (n.count--, n.count <= 0 && (n.unsubscribe(), this.subscriptions.delete(s)));
|
|
2528
2528
|
}
|
|
2529
|
-
return this.behaviors.splice(t, 1),
|
|
2529
|
+
return this.behaviors.splice(t, 1), i.$setEntity(null), !0;
|
|
2530
2530
|
}
|
|
2531
2531
|
}
|
|
2532
2532
|
class Ze {
|
|
@@ -2561,8 +2561,8 @@ class Ze {
|
|
|
2561
2561
|
* @param logger
|
|
2562
2562
|
* @param bindingManager
|
|
2563
2563
|
*/
|
|
2564
|
-
constructor(e, t,
|
|
2565
|
-
this.eventBus = e, this.bindingManager =
|
|
2564
|
+
constructor(e, t, i) {
|
|
2565
|
+
this.eventBus = e, this.bindingManager = i, this._log = t?.getLogger("EntityManager") || new u("EntityManager"), this._log.info("EntityManager initialized");
|
|
2566
2566
|
}
|
|
2567
2567
|
//------------------------------------------------------------------------------------------------------------------
|
|
2568
2568
|
// Internal API
|
|
@@ -2586,8 +2586,8 @@ class Ze {
|
|
|
2586
2586
|
* Gets or creates a Set in a Map, returning the Set.
|
|
2587
2587
|
*/
|
|
2588
2588
|
_getOrCreateSet(e, t) {
|
|
2589
|
-
let
|
|
2590
|
-
return
|
|
2589
|
+
let i = e.get(t);
|
|
2590
|
+
return i || (i = /* @__PURE__ */ new Set(), e.set(t, i)), i;
|
|
2591
2591
|
}
|
|
2592
2592
|
/**
|
|
2593
2593
|
* Adds an entity to all relevant indices.
|
|
@@ -2604,12 +2604,12 @@ class Ze {
|
|
|
2604
2604
|
_unindexEntity(e) {
|
|
2605
2605
|
const t = this._entitiesByType.get(e.type);
|
|
2606
2606
|
if (t && (t.delete(e), t.size === 0 && this._entitiesByType.delete(e.type)), e.name) {
|
|
2607
|
-
const
|
|
2608
|
-
|
|
2607
|
+
const i = this._entitiesByName.get(e.name);
|
|
2608
|
+
i && (i.delete(e), i.size === 0 && this._entitiesByName.delete(e.name));
|
|
2609
2609
|
}
|
|
2610
|
-
for (const
|
|
2611
|
-
const
|
|
2612
|
-
|
|
2610
|
+
for (const i of e.tags) {
|
|
2611
|
+
const s = this._entitiesByTag.get(i);
|
|
2612
|
+
s && (s.delete(e), s.size === 0 && this._entitiesByTag.delete(i));
|
|
2613
2613
|
}
|
|
2614
2614
|
e.node && this._entitiesByNode.delete(e.node);
|
|
2615
2615
|
}
|
|
@@ -2624,34 +2624,34 @@ class Ze {
|
|
|
2624
2624
|
const t = e.extends;
|
|
2625
2625
|
if (!t)
|
|
2626
2626
|
return e;
|
|
2627
|
-
const
|
|
2628
|
-
if (!
|
|
2627
|
+
const i = this.entityDefinitions.get(t);
|
|
2628
|
+
if (!i) {
|
|
2629
2629
|
const o = `Cannot extend "${t}": base entity definition is not registered.`;
|
|
2630
2630
|
throw this._log.error(o), new Error(o);
|
|
2631
2631
|
}
|
|
2632
|
-
let
|
|
2633
|
-
return (
|
|
2632
|
+
let s;
|
|
2633
|
+
return (i.tags || e.tags) && (s = [.../* @__PURE__ */ new Set([...i.tags ?? [], ...e.tags ?? []])]), {
|
|
2634
2634
|
// Scalar fields: child overrides if provided, else inherit
|
|
2635
2635
|
type: e.type,
|
|
2636
|
-
name: e.name ??
|
|
2637
|
-
mesh: e.mesh ??
|
|
2636
|
+
name: e.name ?? i.name,
|
|
2637
|
+
mesh: e.mesh ?? i.mesh,
|
|
2638
2638
|
// Shallow-merged state
|
|
2639
|
-
defaultState: { ...
|
|
2639
|
+
defaultState: { ...i.defaultState, ...e.defaultState },
|
|
2640
2640
|
// Replace-entirely fields: child overrides if provided, else inherit
|
|
2641
|
-
behaviors: e.behaviors ??
|
|
2642
|
-
actions: e.actions ??
|
|
2641
|
+
behaviors: e.behaviors ?? i.behaviors,
|
|
2642
|
+
actions: e.actions ?? i.actions,
|
|
2643
2643
|
// Concatenated tags
|
|
2644
|
-
tags:
|
|
2644
|
+
tags: s,
|
|
2645
2645
|
// Pooling: child overrides if provided, else inherit
|
|
2646
|
-
poolable: e.poolable ??
|
|
2647
|
-
poolSize: e.poolSize ??
|
|
2646
|
+
poolable: e.poolable ?? i.poolable,
|
|
2647
|
+
poolSize: e.poolSize ?? i.poolSize,
|
|
2648
2648
|
// Children: child overrides if provided, else inherit
|
|
2649
|
-
children: e.children ??
|
|
2649
|
+
children: e.children ?? i.children,
|
|
2650
2650
|
// Lifecycle hooks: child overrides if provided, else inherit
|
|
2651
|
-
onBeforeCreate: e.onBeforeCreate ??
|
|
2652
|
-
onCreate: e.onCreate ??
|
|
2653
|
-
onBeforeDestroy: e.onBeforeDestroy ??
|
|
2654
|
-
onDestroy: e.onDestroy ??
|
|
2651
|
+
onBeforeCreate: e.onBeforeCreate ?? i.onBeforeCreate,
|
|
2652
|
+
onCreate: e.onCreate ?? i.onCreate,
|
|
2653
|
+
onBeforeDestroy: e.onBeforeDestroy ?? i.onBeforeDestroy,
|
|
2654
|
+
onDestroy: e.onDestroy ?? i.onDestroy
|
|
2655
2655
|
};
|
|
2656
2656
|
}
|
|
2657
2657
|
//------------------------------------------------------------------------------------------------------------------
|
|
@@ -2674,14 +2674,14 @@ class Ze {
|
|
|
2674
2674
|
if (e.actions)
|
|
2675
2675
|
for (const t of e.actions)
|
|
2676
2676
|
try {
|
|
2677
|
-
const
|
|
2678
|
-
|
|
2677
|
+
const i = this.bindingManager.getAction(t.name);
|
|
2678
|
+
i ? this._areActionsCompatible(i, t) ? this._log.trace(
|
|
2679
2679
|
`Action "${t.name}" already registered with compatible options, skipping registration`
|
|
2680
2680
|
) : this._log.warn(
|
|
2681
|
-
`Action "${t.name}" already registered with different options. Entity "${e.type}" requires: ${JSON.stringify(t)}, but found: ${JSON.stringify(
|
|
2681
|
+
`Action "${t.name}" already registered with different options. Entity "${e.type}" requires: ${JSON.stringify(t)}, but found: ${JSON.stringify(i)}`
|
|
2682
2682
|
) : (this._log.debug(`Registering action "${t.name}" from entity type "${e.type}"`), this.bindingManager.registerAction(t));
|
|
2683
|
-
} catch (
|
|
2684
|
-
this._log.debug(`Failed to register action "${t.name}": ${
|
|
2683
|
+
} catch (i) {
|
|
2684
|
+
this._log.debug(`Failed to register action "${t.name}": ${i instanceof Error ? i.message : String(i)}`);
|
|
2685
2685
|
}
|
|
2686
2686
|
}
|
|
2687
2687
|
$frameUpdate(e) {
|
|
@@ -2717,52 +2717,52 @@ class Ze {
|
|
|
2717
2717
|
*/
|
|
2718
2718
|
async createEntity(e, t = {}) {
|
|
2719
2719
|
this._log.debug(`Creating entity of type: ${e}`);
|
|
2720
|
-
const
|
|
2721
|
-
if (!
|
|
2720
|
+
const i = this.entityDefinitions.get(e);
|
|
2721
|
+
if (!i) {
|
|
2722
2722
|
const a = `Entity type ${e} is not registered.`;
|
|
2723
2723
|
throw this._log.error(a), new Error(a);
|
|
2724
2724
|
}
|
|
2725
|
-
if (
|
|
2725
|
+
if (i.poolable) {
|
|
2726
2726
|
const a = this._pools.get(e);
|
|
2727
2727
|
if (a && a.length > 0) {
|
|
2728
2728
|
this._log.trace(`Recycling entity from pool for type: ${e}`);
|
|
2729
2729
|
const l = a.pop();
|
|
2730
2730
|
if (l.$reset(
|
|
2731
|
-
|
|
2732
|
-
|
|
2731
|
+
i.defaultState,
|
|
2732
|
+
i.tags ?? []
|
|
2733
2733
|
), l.$setEntityManager(this), t.initialState && (l.state = { ...l.state, ...t.initialState }), t.tags)
|
|
2734
2734
|
for (const h of t.tags)
|
|
2735
2735
|
l.$addTag(h);
|
|
2736
2736
|
return t.node && l.$attachToNode(t.node, this._engine), this.entities.set(l.id, l), this._indexEntity(l), this._log.debug(`Recycled entity ${l.id} from pool`), l;
|
|
2737
2737
|
}
|
|
2738
2738
|
}
|
|
2739
|
-
this._log.trace(`Using entity definition with ${
|
|
2740
|
-
let
|
|
2741
|
-
if (
|
|
2739
|
+
this._log.trace(`Using entity definition with ${i.behaviors?.length || 0} behaviors`);
|
|
2740
|
+
let s = { ...i.defaultState, ...t.initialState };
|
|
2741
|
+
if (i.onBeforeCreate) {
|
|
2742
2742
|
this._log.trace(`Calling onBeforeCreate hook for entity type: ${e}`);
|
|
2743
|
-
const a = await
|
|
2744
|
-
a !== void 0 && (
|
|
2743
|
+
const a = await i.onBeforeCreate(s);
|
|
2744
|
+
a !== void 0 && (s = a);
|
|
2745
2745
|
}
|
|
2746
|
-
const n = t.name ??
|
|
2747
|
-
|
|
2746
|
+
const n = t.name ?? i.name, o = new je(
|
|
2747
|
+
i.type,
|
|
2748
2748
|
this.eventBus,
|
|
2749
|
-
|
|
2750
|
-
|
|
2749
|
+
s,
|
|
2750
|
+
i.behaviors,
|
|
2751
2751
|
n
|
|
2752
2752
|
);
|
|
2753
|
-
if (o.$setEntityManager(this), t.node && o.$attachToNode(t.node, this._engine),
|
|
2754
|
-
for (const a of
|
|
2753
|
+
if (o.$setEntityManager(this), t.node && o.$attachToNode(t.node, this._engine), i.tags)
|
|
2754
|
+
for (const a of i.tags)
|
|
2755
2755
|
o.$addTag(a);
|
|
2756
2756
|
if (t.tags)
|
|
2757
2757
|
for (const a of t.tags)
|
|
2758
2758
|
o.$addTag(a);
|
|
2759
|
-
if (this.entities.set(o.id, o), this._indexEntity(o), this._log.debug(`Entity created with ID: ${o.id}${n ? ` (name: ${n})` : ""}`),
|
|
2759
|
+
if (this.entities.set(o.id, o), this._indexEntity(o), this._log.debug(`Entity created with ID: ${o.id}${n ? ` (name: ${n})` : ""}`), i.onCreate) {
|
|
2760
2760
|
this._log.trace(`Calling onCreate hook for entity type: ${e}`);
|
|
2761
|
-
const a = await
|
|
2761
|
+
const a = await i.onCreate(o.state);
|
|
2762
2762
|
a !== void 0 && (o.state = a);
|
|
2763
2763
|
}
|
|
2764
|
-
if (
|
|
2765
|
-
for (const a of
|
|
2764
|
+
if (i.children)
|
|
2765
|
+
for (const a of i.children) {
|
|
2766
2766
|
const l = { ...a.initialState };
|
|
2767
2767
|
a.position && (l._position = a.position), a.rotation && (l._rotation = a.rotation);
|
|
2768
2768
|
const h = await this.createEntity(a.type, {
|
|
@@ -2782,24 +2782,24 @@ class Ze {
|
|
|
2782
2782
|
this._log.debug(`Destroying entity: ${e}`);
|
|
2783
2783
|
const t = this.entities.get(e);
|
|
2784
2784
|
if (t) {
|
|
2785
|
-
const
|
|
2786
|
-
if (
|
|
2785
|
+
const i = this.entityDefinitions.get(t.type);
|
|
2786
|
+
if (i?.poolable) {
|
|
2787
2787
|
this._log.trace(`Pooling entity ${e} instead of destroying`);
|
|
2788
2788
|
for (const n of [...t.children])
|
|
2789
2789
|
await this.destroyEntity(n.id);
|
|
2790
|
-
t.parent && t.parent.$removeChild(t), this._unindexEntity(t), t.$reset(
|
|
2791
|
-
let
|
|
2792
|
-
|
|
2790
|
+
t.parent && t.parent.$removeChild(t), this._unindexEntity(t), t.$reset(i.defaultState, i.tags ?? []);
|
|
2791
|
+
let s = this._pools.get(t.type);
|
|
2792
|
+
s || (s = [], this._pools.set(t.type, s)), s.push(t), this.entities.delete(e), this._log.debug(`Entity ${e} pooled`);
|
|
2793
2793
|
return;
|
|
2794
2794
|
}
|
|
2795
|
-
for (const
|
|
2796
|
-
await this.destroyEntity(
|
|
2797
|
-
if (t.parent && t.parent.$removeChild(t),
|
|
2795
|
+
for (const s of [...t.children])
|
|
2796
|
+
await this.destroyEntity(s.id);
|
|
2797
|
+
if (t.parent && t.parent.$removeChild(t), i?.onBeforeDestroy) {
|
|
2798
2798
|
this._log.trace(`Calling onBeforeDestroy hook for entity: ${e}`);
|
|
2799
|
-
const
|
|
2800
|
-
|
|
2799
|
+
const s = await i.onBeforeDestroy(t.state);
|
|
2800
|
+
s !== void 0 && (t.state = s);
|
|
2801
2801
|
}
|
|
2802
|
-
this._unindexEntity(t), await t.$destroy(),
|
|
2802
|
+
this._unindexEntity(t), await t.$destroy(), i?.onDestroy && (this._log.trace(`Calling onDestroy hook for entity: ${e}`), await i.onDestroy(t.state)), this.entities.delete(e), this._log.debug(`Entity ${e} destroyed`);
|
|
2803
2803
|
} else
|
|
2804
2804
|
this._log.warn(`Attempted to destroy non-existent entity: ${e}`);
|
|
2805
2805
|
}
|
|
@@ -2836,8 +2836,8 @@ class Ze {
|
|
|
2836
2836
|
* @returns False if either entity is not found
|
|
2837
2837
|
*/
|
|
2838
2838
|
addChild(e, t) {
|
|
2839
|
-
const
|
|
2840
|
-
return
|
|
2839
|
+
const i = this.entities.get(e), s = this.entities.get(t);
|
|
2840
|
+
return i ? s ? (i.$addChild(s), this._log.trace(`Added child ${t} to parent ${e}`), !0) : (this._log.warn(`addChild: child entity "${t}" not found`), !1) : (this._log.warn(`addChild: parent entity "${e}" not found`), !1);
|
|
2841
2841
|
}
|
|
2842
2842
|
/**
|
|
2843
2843
|
* Removes a child entity from a parent entity.
|
|
@@ -2846,8 +2846,8 @@ class Ze {
|
|
|
2846
2846
|
* @returns False if either entity is not found
|
|
2847
2847
|
*/
|
|
2848
2848
|
removeChild(e, t) {
|
|
2849
|
-
const
|
|
2850
|
-
return
|
|
2849
|
+
const i = this.entities.get(e), s = this.entities.get(t);
|
|
2850
|
+
return i ? s ? (i.$removeChild(s), this._log.trace(`Removed child ${t} from parent ${e}`), !0) : (this._log.warn(`removeChild: child entity "${t}" not found`), !1) : (this._log.warn(`removeChild: parent entity "${e}" not found`), !1);
|
|
2851
2851
|
}
|
|
2852
2852
|
//------------------------------------------------------------------------------------------------------------------
|
|
2853
2853
|
// Query Methods
|
|
@@ -2895,21 +2895,21 @@ class Ze {
|
|
|
2895
2895
|
if (e.length === 0)
|
|
2896
2896
|
return [];
|
|
2897
2897
|
if (t === "any") {
|
|
2898
|
-
const
|
|
2899
|
-
for (const
|
|
2900
|
-
const n = this._entitiesByTag.get(
|
|
2898
|
+
const i = /* @__PURE__ */ new Set();
|
|
2899
|
+
for (const s of e) {
|
|
2900
|
+
const n = this._entitiesByTag.get(s);
|
|
2901
2901
|
if (n)
|
|
2902
2902
|
for (const o of n)
|
|
2903
|
-
|
|
2903
|
+
i.add(o);
|
|
2904
2904
|
}
|
|
2905
|
-
return Array.from(
|
|
2905
|
+
return Array.from(i);
|
|
2906
2906
|
} else {
|
|
2907
|
-
const
|
|
2908
|
-
if (
|
|
2907
|
+
const i = e.map((o) => this._entitiesByTag.get(o)).filter((o) => o !== void 0);
|
|
2908
|
+
if (i.length !== e.length)
|
|
2909
2909
|
return [];
|
|
2910
|
-
|
|
2911
|
-
const [
|
|
2912
|
-
return Array.from(
|
|
2910
|
+
i.sort((o, a) => o.size - a.size);
|
|
2911
|
+
const [s, ...n] = i;
|
|
2912
|
+
return Array.from(s).filter((o) => n.every((a) => a.has(o)));
|
|
2913
2913
|
}
|
|
2914
2914
|
}
|
|
2915
2915
|
/**
|
|
@@ -2936,13 +2936,13 @@ class Ze {
|
|
|
2936
2936
|
* @param type - Event type string
|
|
2937
2937
|
* @param payload - Optional event payload
|
|
2938
2938
|
*/
|
|
2939
|
-
async send(e, t,
|
|
2939
|
+
async send(e, t, i, s) {
|
|
2940
2940
|
const n = this.entities.get(e) ?? this.getByName(e);
|
|
2941
2941
|
if (!n) {
|
|
2942
2942
|
this._log.warn(`send: entity "${e}" not found`);
|
|
2943
2943
|
return;
|
|
2944
2944
|
}
|
|
2945
|
-
await n.$send(t,
|
|
2945
|
+
await n.$send(t, i, s);
|
|
2946
2946
|
}
|
|
2947
2947
|
/**
|
|
2948
2948
|
* Sends a request to a specific entity's behaviors and returns the first response.
|
|
@@ -2953,9 +2953,9 @@ class Ze {
|
|
|
2953
2953
|
* @param payload - Optional request payload
|
|
2954
2954
|
* @param senderID - Optional sender entity ID (stamped on the event)
|
|
2955
2955
|
*/
|
|
2956
|
-
async request(e, t,
|
|
2956
|
+
async request(e, t, i, s) {
|
|
2957
2957
|
const n = this.entities.get(e) ?? this.getByName(e);
|
|
2958
|
-
return n ? n.$request(t,
|
|
2958
|
+
return n ? n.$request(t, i, s) : { success: !1, error: `Entity "${e}" not found` };
|
|
2959
2959
|
}
|
|
2960
2960
|
//------------------------------------------------------------------------------------------------------------------
|
|
2961
2961
|
// Tag Manipulation
|
|
@@ -2967,8 +2967,8 @@ class Ze {
|
|
|
2967
2967
|
* @returns False if already present or entity not found
|
|
2968
2968
|
*/
|
|
2969
2969
|
addTag(e, t) {
|
|
2970
|
-
const
|
|
2971
|
-
return
|
|
2970
|
+
const i = typeof e == "string" ? this.entities.get(e) : e;
|
|
2971
|
+
return i ? i.hasTag(t) ? !1 : (i.$addTag(t), this._getOrCreateSet(this._entitiesByTag, t).add(i), this._log.trace(`Added tag "${t}" to entity ${i.id}`), !0) : (this._log.warn("addTag: entity not found"), !1);
|
|
2972
2972
|
}
|
|
2973
2973
|
/**
|
|
2974
2974
|
* Removes a tag from an entity and updates the tag index.
|
|
@@ -2977,13 +2977,13 @@ class Ze {
|
|
|
2977
2977
|
* @returns False if not present or entity not found
|
|
2978
2978
|
*/
|
|
2979
2979
|
removeTag(e, t) {
|
|
2980
|
-
const
|
|
2981
|
-
if (!
|
|
2980
|
+
const i = typeof e == "string" ? this.entities.get(e) : e;
|
|
2981
|
+
if (!i)
|
|
2982
2982
|
return this._log.warn("removeTag: entity not found"), !1;
|
|
2983
|
-
if (!
|
|
2983
|
+
if (!i.$removeTag(t))
|
|
2984
2984
|
return !1;
|
|
2985
|
-
const
|
|
2986
|
-
return
|
|
2985
|
+
const s = this._entitiesByTag.get(t);
|
|
2986
|
+
return s && (s.delete(i), s.size === 0 && this._entitiesByTag.delete(t)), this._log.trace(`Removed tag "${t}" from entity ${i.id}`), !0;
|
|
2987
2987
|
}
|
|
2988
2988
|
//------------------------------------------------------------------------------------------------------------------
|
|
2989
2989
|
// Node Attachment
|
|
@@ -3004,8 +3004,8 @@ class Ze {
|
|
|
3004
3004
|
* @returns False if entity not found or node already has an entity
|
|
3005
3005
|
*/
|
|
3006
3006
|
attachToNode(e, t) {
|
|
3007
|
-
const
|
|
3008
|
-
return
|
|
3007
|
+
const i = typeof e == "string" ? this.entities.get(e) : e;
|
|
3008
|
+
return i ? this._entitiesByNode.has(t) ? (this._log.warn("attachToNode: node already has an attached entity"), !1) : (i.node && this._entitiesByNode.delete(i.node), i.$attachToNode(t, this._engine), this._entitiesByNode.set(t, i), this._log.trace(`Attached entity ${i.id} to node "${t.name}"`), !0) : (this._log.warn("attachToNode: entity not found"), !1);
|
|
3009
3009
|
}
|
|
3010
3010
|
/**
|
|
3011
3011
|
* Detaches an entity from its scene node.
|
|
@@ -3020,8 +3020,8 @@ class Ze {
|
|
|
3020
3020
|
if (!t.node)
|
|
3021
3021
|
return !1;
|
|
3022
3022
|
this._entitiesByNode.delete(t.node);
|
|
3023
|
-
const
|
|
3024
|
-
return t.$detachFromNode(), this._log.trace(`Detached entity ${t.id} from node "${
|
|
3023
|
+
const i = t.node.name;
|
|
3024
|
+
return t.$detachFromNode(), this._log.trace(`Detached entity ${t.id} from node "${i}"`), !0;
|
|
3025
3025
|
}
|
|
3026
3026
|
//------------------------------------------------------------------------------------------------------------------
|
|
3027
3027
|
// Object Pooling
|
|
@@ -3033,9 +3033,9 @@ class Ze {
|
|
|
3033
3033
|
*/
|
|
3034
3034
|
async prewarm(e, t) {
|
|
3035
3035
|
this._log.debug(`Prewarming pool for "${e}" with ${t} entities`);
|
|
3036
|
-
for (let
|
|
3037
|
-
const
|
|
3038
|
-
await this.destroyEntity(
|
|
3036
|
+
for (let i = 0; i < t; i++) {
|
|
3037
|
+
const s = await this.createEntity(e);
|
|
3038
|
+
await this.destroyEntity(s.id);
|
|
3039
3039
|
}
|
|
3040
3040
|
}
|
|
3041
3041
|
/**
|
|
@@ -3046,8 +3046,8 @@ class Ze {
|
|
|
3046
3046
|
const t = this._pools.get(e);
|
|
3047
3047
|
if (t) {
|
|
3048
3048
|
this._log.debug(`Draining pool for "${e}" (${t.length} entities)`);
|
|
3049
|
-
for (const
|
|
3050
|
-
await
|
|
3049
|
+
for (const i of t)
|
|
3050
|
+
await i.$destroy();
|
|
3051
3051
|
t.length = 0, this._pools.delete(e);
|
|
3052
3052
|
}
|
|
3053
3053
|
}
|
|
@@ -3064,14 +3064,14 @@ class Ze {
|
|
|
3064
3064
|
for (const t of e)
|
|
3065
3065
|
try {
|
|
3066
3066
|
await this.destroyEntity(t);
|
|
3067
|
-
} catch (
|
|
3068
|
-
this._log.error(`Error destroying entity ${t}: ${
|
|
3067
|
+
} catch (i) {
|
|
3068
|
+
this._log.error(`Error destroying entity ${t}: ${i}`);
|
|
3069
3069
|
}
|
|
3070
3070
|
for (const t of [...this._pools.keys()])
|
|
3071
3071
|
try {
|
|
3072
3072
|
await this.drainPool(t);
|
|
3073
|
-
} catch (
|
|
3074
|
-
this._log.error(`Error draining pool for "${t}": ${
|
|
3073
|
+
} catch (i) {
|
|
3074
|
+
this._log.error(`Error draining pool for "${t}": ${i}`);
|
|
3075
3075
|
}
|
|
3076
3076
|
this.entityDefinitions.clear(), this._entitiesByName.clear(), this._entitiesByType.clear(), this._entitiesByTag.clear(), this._entitiesByNode.clear(), this._log.info("EntityManager torn down successfully");
|
|
3077
3077
|
}
|
|
@@ -3086,15 +3086,15 @@ const qe = {
|
|
|
3086
3086
|
function Ye(r, e) {
|
|
3087
3087
|
if (!r.activeCamera)
|
|
3088
3088
|
return;
|
|
3089
|
-
const t = new
|
|
3090
|
-
if (e.bloom && (t.bloomEnabled = !0, e.bloom.weight !== void 0 && (t.bloomWeight = e.bloom.weight), e.bloom.threshold !== void 0 && (t.bloomThreshold = e.bloom.threshold), e.bloom.scale !== void 0 && (t.bloomScale = e.bloom.scale), e.bloom.kernel !== void 0 && (t.bloomKernel = e.bloom.kernel)), e.tonemap && (t.imageProcessingEnabled = !0, t.imageProcessing.toneMappingEnabled = !0, e.tonemap.operator && (t.imageProcessing.toneMappingType = qe[e.tonemap.operator] ?? v.TONEMAPPING_STANDARD)), e.grain && (t.grainEnabled = !0, e.grain.intensity !== void 0 && (t.grain.intensity = e.grain.intensity), e.grain.animated !== void 0 && (t.grain.animated = e.grain.animated)), e.vignette && (t.imageProcessingEnabled = !0, t.imageProcessing.vignetteEnabled = !0, e.vignette.weight !== void 0 && (t.imageProcessing.vignetteWeight = e.vignette.weight), e.vignette.stretch !== void 0 && (t.imageProcessing.vignetteStretch = e.vignette.stretch), e.vignette.color && (t.imageProcessing.vignetteColor = new
|
|
3089
|
+
const t = new _e("sage-default", !0, r, r.cameras);
|
|
3090
|
+
if (e.bloom && (t.bloomEnabled = !0, e.bloom.weight !== void 0 && (t.bloomWeight = e.bloom.weight), e.bloom.threshold !== void 0 && (t.bloomThreshold = e.bloom.threshold), e.bloom.scale !== void 0 && (t.bloomScale = e.bloom.scale), e.bloom.kernel !== void 0 && (t.bloomKernel = e.bloom.kernel)), e.tonemap && (t.imageProcessingEnabled = !0, t.imageProcessing.toneMappingEnabled = !0, e.tonemap.operator && (t.imageProcessing.toneMappingType = qe[e.tonemap.operator] ?? v.TONEMAPPING_STANDARD)), e.grain && (t.grainEnabled = !0, e.grain.intensity !== void 0 && (t.grain.intensity = e.grain.intensity), e.grain.animated !== void 0 && (t.grain.animated = e.grain.animated)), e.vignette && (t.imageProcessingEnabled = !0, t.imageProcessing.vignetteEnabled = !0, e.vignette.weight !== void 0 && (t.imageProcessing.vignetteWeight = e.vignette.weight), e.vignette.stretch !== void 0 && (t.imageProcessing.vignetteStretch = e.vignette.stretch), e.vignette.color && (t.imageProcessing.vignetteColor = new fe(
|
|
3091
3091
|
e.vignette.color.r,
|
|
3092
3092
|
e.vignette.color.g,
|
|
3093
3093
|
e.vignette.color.b,
|
|
3094
3094
|
1
|
|
3095
3095
|
))), e.sharpen && (t.sharpenEnabled = !0, e.sharpen.edge !== void 0 && (t.sharpen.edgeAmount = e.sharpen.edge), e.sharpen.color !== void 0 && (t.sharpen.colorAmount = e.sharpen.color)), e.chromaticAberration && (t.chromaticAberrationEnabled = !0, e.chromaticAberration.amount !== void 0 && (t.chromaticAberration.aberrationAmount = e.chromaticAberration.amount)), e.ssao) {
|
|
3096
|
-
const
|
|
3097
|
-
e.ssao.radius !== void 0 && (
|
|
3096
|
+
const i = new pe("sage-ssao", r, { ssaoRatio: 0.5, blurRatio: 1 });
|
|
3097
|
+
e.ssao.radius !== void 0 && (i.radius = e.ssao.radius), e.ssao.samples !== void 0 && (i.samples = e.ssao.samples), e.ssao.totalStrength !== void 0 && (i.totalStrength = e.ssao.totalStrength);
|
|
3098
3098
|
}
|
|
3099
3099
|
}
|
|
3100
3100
|
class Je {
|
|
@@ -3239,8 +3239,8 @@ class Xe extends Je {
|
|
|
3239
3239
|
async buildScene() {
|
|
3240
3240
|
const { sceneEngine: e } = this.gameEngine.engines, { assetManager: t } = this.gameEngine.managers;
|
|
3241
3241
|
this._config.preload && this._config.preload.length > 0 && (this.$emitProgress(2, "Preloading assets..."), await t.preload(this._config.preload));
|
|
3242
|
-
const
|
|
3243
|
-
return this._scene =
|
|
3242
|
+
const i = e.createScene();
|
|
3243
|
+
return this._scene = i, this._config.physics && (this.$emitProgress(5, "Initializing physics..."), await this._enablePhysics(i)), this._config.scene && (this.$emitProgress(10, "Loading scene file..."), await this._loadSceneFile(i)), this._config.environment && (this.$emitProgress(15, "Setting up environment..."), this._processEnvironment(i)), this._processCameras(i), this._processLights(i), this._config.postProcessing && Ye(i, this._config.postProcessing), this.$emitProgress(50, "Processing scene properties..."), await this._processNodeProperties(i), this.$emitProgress(70, "Spawning entities..."), await this._processSpawnPoints(), this.$emitProgress(85, "Configuring entities..."), await this._processEntityNodes(), this._config.sounds && (this.$emitProgress(95, "Loading sounds..."), await this._processLevelSounds()), i;
|
|
3244
3244
|
}
|
|
3245
3245
|
/**
|
|
3246
3246
|
* Import all meshes from the configured scene file (GLB/GLTF/Babylon) into the scene.
|
|
@@ -3262,16 +3262,16 @@ class Xe extends Je {
|
|
|
3262
3262
|
const t = this._config.environment;
|
|
3263
3263
|
if (t) {
|
|
3264
3264
|
if (t.ibl && (e.environmentTexture = this._createEnvironmentTexture(t.ibl, t.iblResolution ?? 256, e), this._log.debug(`IBL set from: ${t.ibl}`)), t.skybox) {
|
|
3265
|
-
const
|
|
3266
|
-
if (
|
|
3265
|
+
const i = this._getFileExtension(t.skybox);
|
|
3266
|
+
if (i === ".hdr" || i === ".env") {
|
|
3267
3267
|
if (!t.ibl) {
|
|
3268
|
-
const
|
|
3269
|
-
e.environmentTexture = this._createEnvironmentTexture(t.skybox,
|
|
3268
|
+
const s = t.iblResolution ?? 256;
|
|
3269
|
+
e.environmentTexture = this._createEnvironmentTexture(t.skybox, s, e);
|
|
3270
3270
|
}
|
|
3271
3271
|
e.environmentTexture && e.createDefaultSkybox(e.environmentTexture, !0, t.skyboxSize ?? 1e3, 0, !1);
|
|
3272
3272
|
} else {
|
|
3273
|
-
const
|
|
3274
|
-
o.backFaceCulling = !1, o.disableLighting = !0, o.emissiveTexture = new
|
|
3273
|
+
const s = t.skyboxSize ?? 1e3, n = y.CreateSphere("skybox", { diameter: s, segments: 32 }, e), o = new R("skybox-mat", e);
|
|
3274
|
+
o.backFaceCulling = !1, o.disableLighting = !0, o.emissiveTexture = new ye(t.skybox, e), n.material = o, n.infiniteDistance = !0;
|
|
3275
3275
|
}
|
|
3276
3276
|
this._log.debug(`Skybox set from: ${t.skybox}`);
|
|
3277
3277
|
}
|
|
@@ -3281,8 +3281,8 @@ class Xe extends Je {
|
|
|
3281
3281
|
/**
|
|
3282
3282
|
* Create an environment texture from an HDR or env file.
|
|
3283
3283
|
*/
|
|
3284
|
-
_createEnvironmentTexture(e, t,
|
|
3285
|
-
return this._getFileExtension(e) === ".env" ?
|
|
3284
|
+
_createEnvironmentTexture(e, t, i) {
|
|
3285
|
+
return this._getFileExtension(e) === ".env" ? me.CreateFromPrefilteredData(e, i) : new ve(e, i, t);
|
|
3286
3286
|
}
|
|
3287
3287
|
_getFileExtension(e) {
|
|
3288
3288
|
const t = e.lastIndexOf(".");
|
|
@@ -3294,35 +3294,35 @@ class Xe extends Je {
|
|
|
3294
3294
|
* If no YAML cameras config exists, the first imported camera (if any) is activated.
|
|
3295
3295
|
*/
|
|
3296
3296
|
_processCameras(e) {
|
|
3297
|
-
const t = this._config.cameras,
|
|
3297
|
+
const t = this._config.cameras, i = this.gameEngine.canvas;
|
|
3298
3298
|
if (!t) {
|
|
3299
|
-
e.cameras.length > 0 && (e.activeCamera = e.cameras[0],
|
|
3299
|
+
e.cameras.length > 0 && (e.activeCamera = e.cameras[0], i && e.activeCamera.attachControl(i, !0), this._log.debug(`Activated imported camera: "${e.activeCamera.name}"`));
|
|
3300
3300
|
return;
|
|
3301
3301
|
}
|
|
3302
|
-
let
|
|
3302
|
+
let s = null;
|
|
3303
3303
|
for (const [n, o] of Object.entries(t)) {
|
|
3304
3304
|
const a = e.getCameraByName(n);
|
|
3305
3305
|
if (a)
|
|
3306
|
-
this._applyCameraConfig(a, o), this._log.debug(`Applied overrides to camera: "${n}"`), (!
|
|
3306
|
+
this._applyCameraConfig(a, o), this._log.debug(`Applied overrides to camera: "${n}"`), (!s || o.active) && (s = a);
|
|
3307
3307
|
else if (o.type) {
|
|
3308
3308
|
const l = this._createCamera(n, o, e);
|
|
3309
|
-
this._log.debug(`Created ${o.type} camera: "${n}"`), (!
|
|
3309
|
+
this._log.debug(`Created ${o.type} camera: "${n}"`), (!s || o.active) && (s = l);
|
|
3310
3310
|
} else
|
|
3311
3311
|
this._log.warn(
|
|
3312
3312
|
`Camera "${n}" not found in scene and no type specified — skipping`
|
|
3313
3313
|
);
|
|
3314
3314
|
}
|
|
3315
|
-
if (
|
|
3316
|
-
e.activeCamera =
|
|
3317
|
-
const n = t[
|
|
3318
|
-
|
|
3315
|
+
if (s) {
|
|
3316
|
+
e.activeCamera = s;
|
|
3317
|
+
const n = t[s.name];
|
|
3318
|
+
i && n?.attachControl !== !1 && s.attachControl(i, !0);
|
|
3319
3319
|
}
|
|
3320
3320
|
}
|
|
3321
3321
|
/**
|
|
3322
3322
|
* Create a new camera from a YAML definition.
|
|
3323
3323
|
*/
|
|
3324
|
-
_createCamera(e, t,
|
|
3325
|
-
const
|
|
3324
|
+
_createCamera(e, t, i) {
|
|
3325
|
+
const s = t.position ? this._toVector3(t.position) : p.Zero();
|
|
3326
3326
|
let n;
|
|
3327
3327
|
switch (t.type) {
|
|
3328
3328
|
case "arcRotate": {
|
|
@@ -3333,16 +3333,16 @@ class Xe extends Je {
|
|
|
3333
3333
|
t.beta ?? Math.PI / 3,
|
|
3334
3334
|
t.radius ?? 10,
|
|
3335
3335
|
o,
|
|
3336
|
-
|
|
3336
|
+
i
|
|
3337
3337
|
);
|
|
3338
3338
|
break;
|
|
3339
3339
|
}
|
|
3340
3340
|
case "universal": {
|
|
3341
|
-
n = new
|
|
3341
|
+
n = new be(e, s, i);
|
|
3342
3342
|
break;
|
|
3343
3343
|
}
|
|
3344
3344
|
default: {
|
|
3345
|
-
n = new B(e,
|
|
3345
|
+
n = new B(e, s, i);
|
|
3346
3346
|
break;
|
|
3347
3347
|
}
|
|
3348
3348
|
}
|
|
@@ -3362,55 +3362,58 @@ class Xe extends Je {
|
|
|
3362
3362
|
_processLights(e) {
|
|
3363
3363
|
const t = this._config.lights;
|
|
3364
3364
|
if (t)
|
|
3365
|
-
for (const [
|
|
3366
|
-
const n = e.getLightByName(
|
|
3367
|
-
n ? (this._applyLightConfig(n,
|
|
3368
|
-
`Light "${
|
|
3365
|
+
for (const [i, s] of Object.entries(t)) {
|
|
3366
|
+
const n = e.getLightByName(i);
|
|
3367
|
+
n ? (this._applyLightConfig(n, s), this._log.debug(`Applied overrides to light: "${i}"`)) : s.type ? (this._createLight(i, s, e), this._log.debug(`Created ${s.type} light: "${i}"`)) : this._log.warn(
|
|
3368
|
+
`Light "${i}" not found in scene and no type specified — skipping`
|
|
3369
3369
|
);
|
|
3370
3370
|
}
|
|
3371
3371
|
}
|
|
3372
3372
|
/**
|
|
3373
3373
|
* Create a new light from a YAML definition.
|
|
3374
3374
|
*/
|
|
3375
|
-
_createLight(e, t,
|
|
3376
|
-
const
|
|
3375
|
+
_createLight(e, t, i) {
|
|
3376
|
+
const s = t.direction ? this._toVector3(t.direction) : new p(0, -1, 0), n = t.position ? this._toVector3(t.position) : p.Zero();
|
|
3377
3377
|
switch (t.type) {
|
|
3378
3378
|
case "hemispheric": {
|
|
3379
|
-
const o = new
|
|
3379
|
+
const o = new X(e, s, i);
|
|
3380
3380
|
t.groundColor && (o.groundColor = this._toColor3(t.groundColor)), this._applyLightConfig(o, t);
|
|
3381
3381
|
break;
|
|
3382
3382
|
}
|
|
3383
3383
|
case "directional": {
|
|
3384
|
-
const o = new
|
|
3384
|
+
const o = new Q(e, s, i);
|
|
3385
3385
|
this._applyLightConfig(o, t);
|
|
3386
3386
|
break;
|
|
3387
3387
|
}
|
|
3388
3388
|
case "point": {
|
|
3389
|
-
const o = new
|
|
3389
|
+
const o = new ee(e, n, i);
|
|
3390
3390
|
this._applyLightConfig(o, t);
|
|
3391
3391
|
break;
|
|
3392
3392
|
}
|
|
3393
3393
|
case "spot": {
|
|
3394
|
-
const o = new
|
|
3394
|
+
const o = new te(
|
|
3395
3395
|
e,
|
|
3396
3396
|
n,
|
|
3397
|
-
|
|
3397
|
+
s,
|
|
3398
3398
|
t.angle ?? Math.PI / 3,
|
|
3399
3399
|
t.exponent ?? 2,
|
|
3400
|
-
|
|
3400
|
+
i
|
|
3401
3401
|
);
|
|
3402
3402
|
this._applyLightConfig(o, t);
|
|
3403
3403
|
break;
|
|
3404
3404
|
}
|
|
3405
3405
|
case "rectarea": {
|
|
3406
|
-
const o = new
|
|
3406
|
+
const o = new ie(
|
|
3407
3407
|
e,
|
|
3408
3408
|
n,
|
|
3409
3409
|
t.width ?? 1,
|
|
3410
3410
|
t.height ?? 1,
|
|
3411
|
-
|
|
3411
|
+
i
|
|
3412
3412
|
);
|
|
3413
|
-
this._applyLightConfig(o, t)
|
|
3413
|
+
if (this._applyLightConfig(o, t), t.direction) {
|
|
3414
|
+
const a = new H(`${e}_pivot`, i);
|
|
3415
|
+
a.position = o.position.clone(), o.position = p.Zero(), o.parent = a, a.lookAt(a.position.subtract(s));
|
|
3416
|
+
}
|
|
3414
3417
|
break;
|
|
3415
3418
|
}
|
|
3416
3419
|
}
|
|
@@ -3426,28 +3429,28 @@ class Xe extends Je {
|
|
|
3426
3429
|
return new p(e.x, e.y, e.z);
|
|
3427
3430
|
}
|
|
3428
3431
|
_toColor3(e) {
|
|
3429
|
-
return new
|
|
3432
|
+
return new we(e.r, e.g, e.b);
|
|
3430
3433
|
}
|
|
3431
3434
|
/**
|
|
3432
3435
|
* Configure and enable the Havok physics plugin with the level's gravity settings.
|
|
3433
3436
|
*/
|
|
3434
3437
|
async _enablePhysics(e) {
|
|
3435
3438
|
const t = this._config.physics;
|
|
3436
|
-
let
|
|
3437
|
-
typeof t == "object" && t.gravity && (
|
|
3439
|
+
let i = new p(0, -9.81, 0);
|
|
3440
|
+
typeof t == "object" && t.gravity && (i = new p(
|
|
3438
3441
|
t.gravity.x,
|
|
3439
3442
|
t.gravity.y,
|
|
3440
3443
|
t.gravity.z
|
|
3441
|
-
)), this._log.debug(`Enabling physics with gravity: ${
|
|
3444
|
+
)), this._log.debug(`Enabling physics with gravity: ${i.toString()}`), await this.gameEngine.engines.sceneEngine.enablePhysics(e, i);
|
|
3442
3445
|
}
|
|
3443
3446
|
/**
|
|
3444
3447
|
* Walk all transform nodes and meshes, normalizing glTF metadata and dispatching to property handlers.
|
|
3445
3448
|
*/
|
|
3446
3449
|
async _processNodeProperties(e) {
|
|
3447
3450
|
const t = e.transformNodes.concat(e.meshes);
|
|
3448
|
-
for (const
|
|
3449
|
-
const
|
|
3450
|
-
|
|
3451
|
+
for (const i of t) {
|
|
3452
|
+
const s = this._getNormalizedMetadata(i);
|
|
3453
|
+
s && Object.keys(s).length > 0 && (i.metadata = { ...i.metadata, ...s }, await this._processNodeMetadata(i));
|
|
3451
3454
|
}
|
|
3452
3455
|
this._log.debug(
|
|
3453
3456
|
`Processed ${t.length} nodes, found ${this._spawnPoints.length} spawn points and ${this._entityNodes.length} entity nodes`
|
|
@@ -3479,14 +3482,14 @@ class Xe extends Je {
|
|
|
3479
3482
|
type: e.metadata.entity,
|
|
3480
3483
|
node: e
|
|
3481
3484
|
});
|
|
3482
|
-
for (const [t,
|
|
3485
|
+
for (const [t, i] of this.propertyHandlers)
|
|
3483
3486
|
if (t in e.metadata)
|
|
3484
3487
|
try {
|
|
3485
|
-
await
|
|
3486
|
-
} catch (
|
|
3488
|
+
await i(e, e.metadata[t], this, this.gameEngine);
|
|
3489
|
+
} catch (s) {
|
|
3487
3490
|
this._log.error(
|
|
3488
3491
|
`Error in property handler '${t}' for node '${e.name}':`,
|
|
3489
|
-
|
|
3492
|
+
s
|
|
3490
3493
|
);
|
|
3491
3494
|
}
|
|
3492
3495
|
}
|
|
@@ -3504,23 +3507,23 @@ class Xe extends Je {
|
|
|
3504
3507
|
*/
|
|
3505
3508
|
async _processSpawnPoint(e, t) {
|
|
3506
3509
|
try {
|
|
3507
|
-
const
|
|
3508
|
-
this._spawnedEntities.push(
|
|
3509
|
-
} catch (
|
|
3510
|
-
this._log.error(`Failed to spawn entity at spawn point '${e.name}':`,
|
|
3510
|
+
const i = await this._spawnEntity(t, e);
|
|
3511
|
+
this._spawnedEntities.push(i), e.node.dispose(), this._log.debug(`Spawned entity '${t.entity}' at spawn point '${e.name}'`);
|
|
3512
|
+
} catch (i) {
|
|
3513
|
+
this._log.error(`Failed to spawn entity at spawn point '${e.name}':`, i);
|
|
3511
3514
|
}
|
|
3512
3515
|
}
|
|
3513
3516
|
/**
|
|
3514
3517
|
* Create an entity from a spawn definition, inheriting position/rotation/scaling from the spawn point.
|
|
3515
3518
|
*/
|
|
3516
3519
|
async _spawnEntity(e, t) {
|
|
3517
|
-
const
|
|
3520
|
+
const i = {
|
|
3518
3521
|
...e.config,
|
|
3519
3522
|
position: this._vectorToObject(t.position),
|
|
3520
3523
|
rotation: this._vectorToObject(t.rotation),
|
|
3521
3524
|
scaling: this._vectorToObject(t.scaling)
|
|
3522
|
-
},
|
|
3523
|
-
return await this._createEntityMesh(
|
|
3525
|
+
}, s = await this.gameEngine.managers.entityManager.createEntity(e.entity, { initialState: i });
|
|
3526
|
+
return await this._createEntityMesh(s, t), s;
|
|
3524
3527
|
}
|
|
3525
3528
|
/**
|
|
3526
3529
|
* Converts a Vector3 to a plain `{ x, y, z }` object for serialization into entity state.
|
|
@@ -3535,43 +3538,43 @@ class Xe extends Je {
|
|
|
3535
3538
|
async _createEntityMesh(e, t) {
|
|
3536
3539
|
if (!this._scene)
|
|
3537
3540
|
return;
|
|
3538
|
-
const
|
|
3539
|
-
if (!
|
|
3541
|
+
const i = this.gameEngine.managers.entityManager.getDefinition(e.type);
|
|
3542
|
+
if (!i?.mesh)
|
|
3540
3543
|
return;
|
|
3541
|
-
const
|
|
3544
|
+
const s = i.mesh, n = this._scene, o = new H(`entity-${e.id}`, n);
|
|
3542
3545
|
o.position.copyFrom(t.position), o.rotation.copyFrom(t.rotation);
|
|
3543
3546
|
let a;
|
|
3544
|
-
switch (
|
|
3547
|
+
switch (s.source) {
|
|
3545
3548
|
case "box":
|
|
3546
3549
|
a = [y.CreateBox(`${e.type}-mesh`, {
|
|
3547
|
-
size:
|
|
3548
|
-
width:
|
|
3549
|
-
height:
|
|
3550
|
-
depth:
|
|
3550
|
+
size: s.params?.size ?? 1,
|
|
3551
|
+
width: s.params?.width,
|
|
3552
|
+
height: s.params?.height,
|
|
3553
|
+
depth: s.params?.depth
|
|
3551
3554
|
}, n)];
|
|
3552
3555
|
break;
|
|
3553
3556
|
case "sphere":
|
|
3554
3557
|
a = [y.CreateSphere(`${e.type}-mesh`, {
|
|
3555
|
-
diameter:
|
|
3556
|
-
segments:
|
|
3558
|
+
diameter: s.params?.diameter ?? 1,
|
|
3559
|
+
segments: s.params?.segments ?? 16
|
|
3557
3560
|
}, n)];
|
|
3558
3561
|
break;
|
|
3559
3562
|
case "capsule":
|
|
3560
3563
|
a = [y.CreateCapsule(`${e.type}-mesh`, {
|
|
3561
|
-
height:
|
|
3562
|
-
radius:
|
|
3564
|
+
height: s.params?.height ?? 1.8,
|
|
3565
|
+
radius: s.params?.radius ?? 0.4
|
|
3563
3566
|
}, n)];
|
|
3564
3567
|
break;
|
|
3565
3568
|
case "cylinder":
|
|
3566
3569
|
a = [y.CreateCylinder(`${e.type}-mesh`, {
|
|
3567
|
-
height:
|
|
3568
|
-
diameter:
|
|
3570
|
+
height: s.params?.height ?? 1,
|
|
3571
|
+
diameter: s.params?.diameter ?? 1
|
|
3569
3572
|
}, n)];
|
|
3570
3573
|
break;
|
|
3571
3574
|
default: {
|
|
3572
|
-
const h = await this.gameEngine.engines.sceneEngine.importMeshes([],
|
|
3575
|
+
const h = await this.gameEngine.engines.sceneEngine.importMeshes([], s.source, n);
|
|
3573
3576
|
if (h.meshes.length === 0) {
|
|
3574
|
-
this._log.warn(`No meshes loaded from: ${
|
|
3577
|
+
this._log.warn(`No meshes loaded from: ${s.source}`), o.dispose();
|
|
3575
3578
|
return;
|
|
3576
3579
|
}
|
|
3577
3580
|
a = h.meshes;
|
|
@@ -3582,8 +3585,8 @@ class Xe extends Je {
|
|
|
3582
3585
|
}
|
|
3583
3586
|
for (const h of a)
|
|
3584
3587
|
h.parent || (h.parent = o);
|
|
3585
|
-
|
|
3586
|
-
const l =
|
|
3588
|
+
s.scale && (typeof s.scale == "number" ? o.scaling.setAll(s.scale) : o.scaling.set(s.scale.x, s.scale.y, s.scale.z));
|
|
3589
|
+
const l = s.material;
|
|
3587
3590
|
if (l?.color) {
|
|
3588
3591
|
const h = l.color;
|
|
3589
3592
|
if (l.type === "pbr") {
|
|
@@ -3613,17 +3616,17 @@ class Xe extends Je {
|
|
|
3613
3616
|
async _processEntityNode(e) {
|
|
3614
3617
|
const t = this._config.entities?.[e.type];
|
|
3615
3618
|
try {
|
|
3616
|
-
const
|
|
3619
|
+
const i = {
|
|
3617
3620
|
...t?.config,
|
|
3618
3621
|
position: this._vectorToObject(e.node.position)
|
|
3619
|
-
},
|
|
3622
|
+
}, s = await this.gameEngine.managers.entityManager.createEntity(e.type, {
|
|
3620
3623
|
name: e.node.name,
|
|
3621
|
-
initialState:
|
|
3624
|
+
initialState: i,
|
|
3622
3625
|
node: e.node
|
|
3623
3626
|
});
|
|
3624
|
-
this._spawnedEntities.push(
|
|
3625
|
-
} catch (
|
|
3626
|
-
this._log.error(`Failed to create entity for node '${e.node.name}':`,
|
|
3627
|
+
this._spawnedEntities.push(s), this._log.debug(`Created entity '${e.type}' for node '${e.node.name}'`);
|
|
3628
|
+
} catch (i) {
|
|
3629
|
+
this._log.error(`Failed to create entity for node '${e.node.name}':`, i);
|
|
3627
3630
|
}
|
|
3628
3631
|
}
|
|
3629
3632
|
//------------------------------------------------------------------------------------------------------------------
|
|
@@ -3642,15 +3645,15 @@ class Xe extends Je {
|
|
|
3642
3645
|
this._log.warn("No AudioManager configured. Level sounds will not be created.");
|
|
3643
3646
|
return;
|
|
3644
3647
|
}
|
|
3645
|
-
for (const [
|
|
3648
|
+
for (const [i, s] of Object.entries(e))
|
|
3646
3649
|
try {
|
|
3647
|
-
const n = await t.createSound(
|
|
3648
|
-
loop:
|
|
3649
|
-
volume:
|
|
3650
|
+
const n = await t.createSound(i, s.url, s.channel, {
|
|
3651
|
+
loop: s.loop ?? !1,
|
|
3652
|
+
volume: s.volume ?? 1
|
|
3650
3653
|
});
|
|
3651
|
-
this._levelSounds.set(
|
|
3654
|
+
this._levelSounds.set(i, n), s.autoplay && n.play(), this._log.debug(`Created level sound: "${i}"`);
|
|
3652
3655
|
} catch (n) {
|
|
3653
|
-
this._log.error(`Failed to create level sound "${
|
|
3656
|
+
this._log.error(`Failed to create level sound "${i}":`, n);
|
|
3654
3657
|
}
|
|
3655
3658
|
}
|
|
3656
3659
|
//------------------------------------------------------------------------------------------------------------------
|
|
@@ -3662,7 +3665,7 @@ class Xe extends Je {
|
|
|
3662
3665
|
*/
|
|
3663
3666
|
async onDeactivate() {
|
|
3664
3667
|
for (const [e, t] of this._levelSounds)
|
|
3665
|
-
t.state ===
|
|
3668
|
+
t.state === ne.Started && (this._playingSoundsBeforeDeactivate.add(e), t.pause());
|
|
3666
3669
|
}
|
|
3667
3670
|
/**
|
|
3668
3671
|
* Resume previously playing level sounds when the level is reactivated.
|
|
@@ -3682,16 +3685,16 @@ class Xe extends Je {
|
|
|
3682
3685
|
* Dispose of this level's resources
|
|
3683
3686
|
*/
|
|
3684
3687
|
async $dispose() {
|
|
3685
|
-
const { entityManager: e } = this.gameEngine.managers, t = this._spawnedEntities.map(async (
|
|
3688
|
+
const { entityManager: e } = this.gameEngine.managers, t = this._spawnedEntities.map(async (i) => {
|
|
3686
3689
|
try {
|
|
3687
|
-
await e.destroyEntity(
|
|
3688
|
-
} catch (
|
|
3689
|
-
this._log.error(`Failed to destroy entity ${
|
|
3690
|
+
await e.destroyEntity(i.id);
|
|
3691
|
+
} catch (s) {
|
|
3692
|
+
this._log.error(`Failed to destroy entity ${i.id}:`, s);
|
|
3690
3693
|
}
|
|
3691
3694
|
});
|
|
3692
3695
|
await Promise.all(t), this._spawnedEntities = [], this._spawnPoints = [], this._entityNodes = [];
|
|
3693
|
-
for (const
|
|
3694
|
-
|
|
3696
|
+
for (const i of this._levelSounds.values())
|
|
3697
|
+
i.dispose();
|
|
3695
3698
|
this._levelSounds.clear(), this._playingSoundsBeforeDeactivate.clear(), await super.$dispose();
|
|
3696
3699
|
}
|
|
3697
3700
|
}
|
|
@@ -3728,16 +3731,16 @@ class Qe {
|
|
|
3728
3731
|
//------------------------------------------------------------------------------------------------------------------
|
|
3729
3732
|
constructor(e, t) {
|
|
3730
3733
|
this._eventBus = e, this._logger = t, this._log = t?.getLogger("LevelManager") || new u("LevelManager"), this._eventUnsubscribers.push(
|
|
3731
|
-
this._eventBus.subscribe("level:progress", (
|
|
3732
|
-
this._handleProgress(
|
|
3734
|
+
this._eventBus.subscribe("level:progress", (i) => {
|
|
3735
|
+
this._handleProgress(i.payload);
|
|
3733
3736
|
})
|
|
3734
3737
|
), this._eventUnsubscribers.push(
|
|
3735
|
-
this._eventBus.subscribe("level:complete", (
|
|
3736
|
-
this._handleComplete(
|
|
3738
|
+
this._eventBus.subscribe("level:complete", (i) => {
|
|
3739
|
+
this._handleComplete(i.payload);
|
|
3737
3740
|
})
|
|
3738
3741
|
), this._eventUnsubscribers.push(
|
|
3739
|
-
this._eventBus.subscribe("level:error", (
|
|
3740
|
-
this._handleError(
|
|
3742
|
+
this._eventBus.subscribe("level:error", (i) => {
|
|
3743
|
+
this._handleError(i.payload);
|
|
3741
3744
|
})
|
|
3742
3745
|
), this._log.info("LevelManager initialized");
|
|
3743
3746
|
}
|
|
@@ -3781,10 +3784,10 @@ class Qe {
|
|
|
3781
3784
|
_createLevelInstance(e) {
|
|
3782
3785
|
const t = this._createContext();
|
|
3783
3786
|
if (e.class) {
|
|
3784
|
-
const
|
|
3785
|
-
if (!
|
|
3787
|
+
const i = this._levelClasses.get(e.class);
|
|
3788
|
+
if (!i)
|
|
3786
3789
|
throw new Error(`Level class '${e.class}' is not registered.`);
|
|
3787
|
-
return this._log.debug(`Creating level '${e.name}' using class '${e.class}'`), new
|
|
3790
|
+
return this._log.debug(`Creating level '${e.name}' using class '${e.class}'`), new i(e, t);
|
|
3788
3791
|
}
|
|
3789
3792
|
return this._log.debug(`Creating level '${e.name}' using GameLevel`), new Xe(e, t);
|
|
3790
3793
|
}
|
|
@@ -3874,12 +3877,12 @@ class Qe {
|
|
|
3874
3877
|
t = n;
|
|
3875
3878
|
} else
|
|
3876
3879
|
t = e, this.registerLevelConfig(t);
|
|
3877
|
-
const
|
|
3878
|
-
if (
|
|
3879
|
-
return this._log.warn(`Level '${t.name}' is already loaded`),
|
|
3880
|
+
const i = this._loadedLevels.get(t.name);
|
|
3881
|
+
if (i)
|
|
3882
|
+
return this._log.warn(`Level '${t.name}' is already loaded`), i;
|
|
3880
3883
|
this._log.debug(`Loading level: ${t.name}`);
|
|
3881
|
-
const
|
|
3882
|
-
return await
|
|
3884
|
+
const s = this._createLevelInstance(t);
|
|
3885
|
+
return await s.load(), this._loadedLevels.set(t.name, s), s;
|
|
3883
3886
|
}
|
|
3884
3887
|
/**
|
|
3885
3888
|
* Activates a level, loading it if necessary.
|
|
@@ -3920,37 +3923,37 @@ class Qe {
|
|
|
3920
3923
|
* @param options
|
|
3921
3924
|
*/
|
|
3922
3925
|
async transition(e, t) {
|
|
3923
|
-
const
|
|
3926
|
+
const i = this._currentLevel;
|
|
3924
3927
|
try {
|
|
3925
3928
|
this._eventBus.publish({
|
|
3926
3929
|
type: "level:transition:start",
|
|
3927
3930
|
payload: {
|
|
3928
|
-
from:
|
|
3931
|
+
from: i?.name,
|
|
3929
3932
|
to: e
|
|
3930
3933
|
}
|
|
3931
|
-
}),
|
|
3934
|
+
}), i?.onDeactivate && await i.onDeactivate(), this._eventBus.publish({
|
|
3932
3935
|
type: "level:transition:progress",
|
|
3933
3936
|
payload: {
|
|
3934
3937
|
stage: "loading",
|
|
3935
3938
|
levelName: e
|
|
3936
3939
|
}
|
|
3937
3940
|
});
|
|
3938
|
-
const
|
|
3941
|
+
const s = await this.loadLevel(e);
|
|
3939
3942
|
if (t?.preloadOnly)
|
|
3940
3943
|
return;
|
|
3941
|
-
|
|
3944
|
+
i && !t?.keepAlive && await this.unloadLevel(i.name), this._currentLevel = s, s.onActivate && await s.onActivate(), this._eventBus.publish({
|
|
3942
3945
|
type: "level:transition:complete",
|
|
3943
3946
|
payload: { levelName: e }
|
|
3944
3947
|
});
|
|
3945
|
-
} catch (
|
|
3948
|
+
} catch (s) {
|
|
3946
3949
|
throw this._eventBus.publish({
|
|
3947
3950
|
type: "level:transition:error",
|
|
3948
3951
|
payload: {
|
|
3949
|
-
from:
|
|
3952
|
+
from: i?.name,
|
|
3950
3953
|
to: e,
|
|
3951
|
-
error:
|
|
3954
|
+
error: s
|
|
3952
3955
|
}
|
|
3953
|
-
}),
|
|
3956
|
+
}), s;
|
|
3954
3957
|
}
|
|
3955
3958
|
}
|
|
3956
3959
|
//------------------------------------------------------------------------------------------------------------------
|
|
@@ -3983,8 +3986,8 @@ class et {
|
|
|
3983
3986
|
async initialize(e) {
|
|
3984
3987
|
this._log.info(`Initializing audio channels: ${e.join(", ")}`);
|
|
3985
3988
|
for (const t of e) {
|
|
3986
|
-
const
|
|
3987
|
-
this._channels.set(t, { bus:
|
|
3989
|
+
const i = await this._audioEngine.createBus(t);
|
|
3990
|
+
this._channels.set(t, { bus: i, volume: 1, muted: !1 });
|
|
3988
3991
|
}
|
|
3989
3992
|
this._log.info("Audio channels initialized.");
|
|
3990
3993
|
}
|
|
@@ -3997,13 +4000,13 @@ class et {
|
|
|
3997
4000
|
//------------------------------------------------------------------------------------------------------------------
|
|
3998
4001
|
// Sound Creation
|
|
3999
4002
|
//------------------------------------------------------------------------------------------------------------------
|
|
4000
|
-
async createSound(e, t,
|
|
4003
|
+
async createSound(e, t, i, s) {
|
|
4001
4004
|
let n;
|
|
4002
|
-
if (
|
|
4003
|
-
const o = this._channels.get(
|
|
4004
|
-
o ? n = o.bus : this._log.warn(`Unknown audio channel "${
|
|
4005
|
+
if (i) {
|
|
4006
|
+
const o = this._channels.get(i);
|
|
4007
|
+
o ? n = o.bus : this._log.warn(`Unknown audio channel "${i}", sound "${e}" will use default bus.`);
|
|
4005
4008
|
}
|
|
4006
|
-
return this._audioEngine.createSound(e, t, n,
|
|
4009
|
+
return this._audioEngine.createSound(e, t, n, s);
|
|
4007
4010
|
}
|
|
4008
4011
|
//------------------------------------------------------------------------------------------------------------------
|
|
4009
4012
|
// Master Volume
|
|
@@ -4024,23 +4027,23 @@ class et {
|
|
|
4024
4027
|
// Channel Volume
|
|
4025
4028
|
//------------------------------------------------------------------------------------------------------------------
|
|
4026
4029
|
setChannelVolume(e, t) {
|
|
4027
|
-
const
|
|
4028
|
-
if (!
|
|
4030
|
+
const i = this._channels.get(e);
|
|
4031
|
+
if (!i) {
|
|
4029
4032
|
this._log.warn(`Unknown audio channel: ${e}`);
|
|
4030
4033
|
return;
|
|
4031
4034
|
}
|
|
4032
|
-
|
|
4035
|
+
i.volume = t, i.muted || this._audioEngine.setBusVolume(i.bus, t);
|
|
4033
4036
|
}
|
|
4034
4037
|
getChannelVolume(e) {
|
|
4035
4038
|
return this._channels.get(e)?.volume ?? 1;
|
|
4036
4039
|
}
|
|
4037
4040
|
setChannelMuted(e, t) {
|
|
4038
|
-
const
|
|
4039
|
-
if (!
|
|
4041
|
+
const i = this._channels.get(e);
|
|
4042
|
+
if (!i) {
|
|
4040
4043
|
this._log.warn(`Unknown audio channel: ${e}`);
|
|
4041
4044
|
return;
|
|
4042
4045
|
}
|
|
4043
|
-
t !==
|
|
4046
|
+
t !== i.muted && (i.muted = t, this._audioEngine.setBusVolume(i.bus, t ? 0 : i.volume));
|
|
4044
4047
|
}
|
|
4045
4048
|
isChannelMuted(e) {
|
|
4046
4049
|
return this._channels.get(e)?.muted ?? !1;
|
|
@@ -4055,8 +4058,8 @@ class tt {
|
|
|
4055
4058
|
_log;
|
|
4056
4059
|
_beforeSerializeHooks = [];
|
|
4057
4060
|
_afterDeserializeHooks = [];
|
|
4058
|
-
constructor(e, t,
|
|
4059
|
-
this._entityManager = e, this._levelManager = t, this._log =
|
|
4061
|
+
constructor(e, t, i) {
|
|
4062
|
+
this._entityManager = e, this._levelManager = t, this._log = i?.getLogger("SaveManager") || new u("SaveManager"), this._log.info("SaveManager initialized");
|
|
4060
4063
|
}
|
|
4061
4064
|
//------------------------------------------------------------------------------------------------------------------
|
|
4062
4065
|
// Hook Registration
|
|
@@ -4103,18 +4106,18 @@ class tt {
|
|
|
4103
4106
|
}
|
|
4104
4107
|
t.push(o);
|
|
4105
4108
|
}
|
|
4106
|
-
let
|
|
4109
|
+
let i = {};
|
|
4107
4110
|
for (const n of this._beforeSerializeHooks) {
|
|
4108
4111
|
const o = n();
|
|
4109
|
-
|
|
4112
|
+
i = { ...i, ...o };
|
|
4110
4113
|
}
|
|
4111
|
-
const
|
|
4114
|
+
const s = {
|
|
4112
4115
|
version: 1,
|
|
4113
4116
|
levelName: e,
|
|
4114
4117
|
entities: t,
|
|
4115
|
-
custom:
|
|
4118
|
+
custom: i
|
|
4116
4119
|
};
|
|
4117
|
-
return this._log.info(`Serialized ${t.length} entities from level "${e}"`),
|
|
4120
|
+
return this._log.info(`Serialized ${t.length} entities from level "${e}"`), s;
|
|
4118
4121
|
}
|
|
4119
4122
|
//------------------------------------------------------------------------------------------------------------------
|
|
4120
4123
|
// Deserialize
|
|
@@ -4133,31 +4136,31 @@ class tt {
|
|
|
4133
4136
|
async deserialize(e) {
|
|
4134
4137
|
this._log.debug(`Deserializing save data (version ${e.version}, level "${e.levelName}")...`), await this._levelManager.transition(e.levelName);
|
|
4135
4138
|
const t = [];
|
|
4136
|
-
for (const
|
|
4137
|
-
t.push(
|
|
4138
|
-
for (const
|
|
4139
|
-
await this._entityManager.destroyEntity(
|
|
4140
|
-
const
|
|
4141
|
-
for (const
|
|
4142
|
-
const n = await this._entityManager.createEntity(
|
|
4143
|
-
name:
|
|
4144
|
-
initialState:
|
|
4145
|
-
tags:
|
|
4139
|
+
for (const s of this._entityManager.getAllEntities())
|
|
4140
|
+
t.push(s.id);
|
|
4141
|
+
for (const s of t)
|
|
4142
|
+
await this._entityManager.destroyEntity(s);
|
|
4143
|
+
const i = /* @__PURE__ */ new Map();
|
|
4144
|
+
for (const s of e.entities) {
|
|
4145
|
+
const n = await this._entityManager.createEntity(s.type, {
|
|
4146
|
+
name: s.name,
|
|
4147
|
+
initialState: s.state,
|
|
4148
|
+
tags: s.tags
|
|
4146
4149
|
});
|
|
4147
|
-
if (
|
|
4148
|
-
const { position: o, rotation: a, scaling: l } =
|
|
4150
|
+
if (i.set(s.id, n.id), s.transform && n.node) {
|
|
4151
|
+
const { position: o, rotation: a, scaling: l } = s.transform;
|
|
4149
4152
|
n.node.position.x = o.x, n.node.position.y = o.y, n.node.position.z = o.z, n.node.rotation.x = a.x, n.node.rotation.y = a.y, n.node.rotation.z = a.z, n.node.scaling.x = l.x, n.node.scaling.y = l.y, n.node.scaling.z = l.z;
|
|
4150
4153
|
}
|
|
4151
4154
|
}
|
|
4152
|
-
for (const
|
|
4153
|
-
if (
|
|
4154
|
-
const n =
|
|
4155
|
+
for (const s of e.entities)
|
|
4156
|
+
if (s.parentId) {
|
|
4157
|
+
const n = i.get(s.parentId), o = i.get(s.id);
|
|
4155
4158
|
n && o ? this._entityManager.addChild(n, o) : this._log.warn(
|
|
4156
|
-
`Could not restore parent-child: ${
|
|
4159
|
+
`Could not restore parent-child: ${s.id} -> ${s.parentId} (mapped: ${o} -> ${n})`
|
|
4157
4160
|
);
|
|
4158
4161
|
}
|
|
4159
|
-
for (const
|
|
4160
|
-
|
|
4162
|
+
for (const s of this._afterDeserializeHooks)
|
|
4163
|
+
s(e.custom);
|
|
4161
4164
|
this._log.info(`Deserialized ${e.entities.length} entities for level "${e.levelName}"`);
|
|
4162
4165
|
}
|
|
4163
4166
|
//------------------------------------------------------------------------------------------------------------------
|
|
@@ -4167,7 +4170,7 @@ class tt {
|
|
|
4167
4170
|
this._beforeSerializeHooks = [], this._afterDeserializeHooks = [], this._log.info("SaveManager torn down");
|
|
4168
4171
|
}
|
|
4169
4172
|
}
|
|
4170
|
-
class
|
|
4173
|
+
class it {
|
|
4171
4174
|
_keyboardDevice;
|
|
4172
4175
|
_keysState = {};
|
|
4173
4176
|
// Callbacks
|
|
@@ -4242,13 +4245,13 @@ class st {
|
|
|
4242
4245
|
this._keysState[e.code] = !0;
|
|
4243
4246
|
const t = {};
|
|
4244
4247
|
t[e.code] = !0;
|
|
4245
|
-
const
|
|
4248
|
+
const i = {
|
|
4246
4249
|
type: "keyboard",
|
|
4247
4250
|
keys: { ...this._keysState },
|
|
4248
4251
|
delta: t,
|
|
4249
4252
|
event: e
|
|
4250
4253
|
};
|
|
4251
|
-
this._notifyInputChanged(
|
|
4254
|
+
this._notifyInputChanged(i);
|
|
4252
4255
|
}
|
|
4253
4256
|
/**
|
|
4254
4257
|
* Handle keyboard key up events
|
|
@@ -4257,13 +4260,13 @@ class st {
|
|
|
4257
4260
|
this._keysState[e.code] = !1;
|
|
4258
4261
|
const t = {};
|
|
4259
4262
|
t[e.code] = !1;
|
|
4260
|
-
const
|
|
4263
|
+
const i = {
|
|
4261
4264
|
type: "keyboard",
|
|
4262
4265
|
keys: { ...this._keysState },
|
|
4263
4266
|
delta: t,
|
|
4264
4267
|
event: e
|
|
4265
4268
|
};
|
|
4266
|
-
this._notifyInputChanged(
|
|
4269
|
+
this._notifyInputChanged(i);
|
|
4267
4270
|
}
|
|
4268
4271
|
/**
|
|
4269
4272
|
* Notify subscribers of device connected event
|
|
@@ -4278,7 +4281,7 @@ class st {
|
|
|
4278
4281
|
this._onInputChanged && this._onInputChanged(this._keyboardDevice, e);
|
|
4279
4282
|
}
|
|
4280
4283
|
}
|
|
4281
|
-
class
|
|
4284
|
+
class st {
|
|
4282
4285
|
_targetElement;
|
|
4283
4286
|
_mouseDevice;
|
|
4284
4287
|
_buttonState = {};
|
|
@@ -4369,10 +4372,10 @@ class it {
|
|
|
4369
4372
|
* Handle mouse button down events
|
|
4370
4373
|
*/
|
|
4371
4374
|
_handleMouseDown(e) {
|
|
4372
|
-
const t = `button-${e.button}`,
|
|
4375
|
+
const t = `button-${e.button}`, i = {
|
|
4373
4376
|
pressed: !0
|
|
4374
4377
|
};
|
|
4375
|
-
this._buttonState[t] =
|
|
4378
|
+
this._buttonState[t] = i, this._notifyInputChanged({
|
|
4376
4379
|
type: "mouse",
|
|
4377
4380
|
event: e,
|
|
4378
4381
|
buttons: { ...this._buttonState },
|
|
@@ -4384,10 +4387,10 @@ class it {
|
|
|
4384
4387
|
* Handle mouse button up events
|
|
4385
4388
|
*/
|
|
4386
4389
|
_handleMouseUp(e) {
|
|
4387
|
-
const t = `button-${e.button}`,
|
|
4390
|
+
const t = `button-${e.button}`, i = {
|
|
4388
4391
|
pressed: !1
|
|
4389
4392
|
};
|
|
4390
|
-
this._buttonState[t] =
|
|
4393
|
+
this._buttonState[t] = i, this._notifyInputChanged({
|
|
4391
4394
|
type: "mouse",
|
|
4392
4395
|
event: e,
|
|
4393
4396
|
buttons: { ...this._buttonState },
|
|
@@ -4501,10 +4504,10 @@ class nt {
|
|
|
4501
4504
|
getStates() {
|
|
4502
4505
|
const e = {};
|
|
4503
4506
|
return Object.keys(this._buttonStates).forEach((t) => {
|
|
4504
|
-
const
|
|
4505
|
-
e[
|
|
4507
|
+
const i = Number(t), s = this._buttonStates[i] || {}, n = this._axesStates[i] || {};
|
|
4508
|
+
e[i] = {
|
|
4506
4509
|
type: "gamepad",
|
|
4507
|
-
buttons: { ...
|
|
4510
|
+
buttons: { ...s },
|
|
4508
4511
|
axes: { ...n }
|
|
4509
4512
|
};
|
|
4510
4513
|
}), e;
|
|
@@ -4524,11 +4527,11 @@ class nt {
|
|
|
4524
4527
|
* @param index
|
|
4525
4528
|
*/
|
|
4526
4529
|
getState(e) {
|
|
4527
|
-
const t = this._buttonStates[e],
|
|
4528
|
-
return !t && !
|
|
4530
|
+
const t = this._buttonStates[e], i = this._axesStates[e];
|
|
4531
|
+
return !t && !i ? null : {
|
|
4529
4532
|
type: "gamepad",
|
|
4530
4533
|
buttons: t ? { ...t } : {},
|
|
4531
|
-
axes:
|
|
4534
|
+
axes: i ? { ...i } : {}
|
|
4532
4535
|
};
|
|
4533
4536
|
}
|
|
4534
4537
|
/**
|
|
@@ -4541,15 +4544,15 @@ class nt {
|
|
|
4541
4544
|
for (const t of e) {
|
|
4542
4545
|
if (!t)
|
|
4543
4546
|
continue;
|
|
4544
|
-
const
|
|
4545
|
-
if (!this._gamepadDevices[
|
|
4547
|
+
const i = t.index;
|
|
4548
|
+
if (!this._gamepadDevices[i]) {
|
|
4546
4549
|
this._handleGamepadConnected(t);
|
|
4547
4550
|
continue;
|
|
4548
4551
|
}
|
|
4549
|
-
const
|
|
4550
|
-
if (!
|
|
4552
|
+
const s = this._gamepadDevices[i];
|
|
4553
|
+
if (!s)
|
|
4551
4554
|
continue;
|
|
4552
|
-
const n = this._buttonStates[
|
|
4555
|
+
const n = this._buttonStates[i] || {}, o = this._axesStates[i] || {}, a = {};
|
|
4553
4556
|
let l = !1;
|
|
4554
4557
|
t.buttons.forEach((d, m) => {
|
|
4555
4558
|
const f = `button-${m}`, g = {
|
|
@@ -4566,13 +4569,13 @@ class nt {
|
|
|
4566
4569
|
if (t.axes.forEach((d, m) => {
|
|
4567
4570
|
const f = `axis-${m}`;
|
|
4568
4571
|
h[f] = d, o[f] !== d && (c = !0);
|
|
4569
|
-
}), this._buttonStates[
|
|
4572
|
+
}), this._buttonStates[i] = a, this._axesStates[i] = h, l || c) {
|
|
4570
4573
|
const d = {
|
|
4571
4574
|
type: "gamepad",
|
|
4572
4575
|
buttons: { ...a },
|
|
4573
4576
|
axes: { ...h }
|
|
4574
4577
|
};
|
|
4575
|
-
this._notifyInputChanged(
|
|
4578
|
+
this._notifyInputChanged(s, d);
|
|
4576
4579
|
}
|
|
4577
4580
|
}
|
|
4578
4581
|
}
|
|
@@ -4599,17 +4602,17 @@ class nt {
|
|
|
4599
4602
|
* Handle gamepad connected event
|
|
4600
4603
|
*/
|
|
4601
4604
|
_handleGamepadConnected(e) {
|
|
4602
|
-
const t = e instanceof GamepadEvent ? e.gamepad : e,
|
|
4603
|
-
id: `gamepad-${
|
|
4605
|
+
const t = e instanceof GamepadEvent ? e.gamepad : e, i = t.index, s = {
|
|
4606
|
+
id: `gamepad-${i}`,
|
|
4604
4607
|
name: t.id,
|
|
4605
4608
|
type: "gamepad",
|
|
4606
4609
|
connected: !0,
|
|
4607
|
-
index:
|
|
4610
|
+
index: i,
|
|
4608
4611
|
mapping: t.mapping,
|
|
4609
4612
|
axes: Array.from(t.axes),
|
|
4610
4613
|
buttons: Array.from(t.buttons)
|
|
4611
4614
|
};
|
|
4612
|
-
this._gamepadDevices[
|
|
4615
|
+
this._gamepadDevices[i] = s;
|
|
4613
4616
|
const n = {};
|
|
4614
4617
|
Array.from(t.buttons).forEach((a, l) => {
|
|
4615
4618
|
n[`button-${l}`] = {
|
|
@@ -4617,11 +4620,11 @@ class nt {
|
|
|
4617
4620
|
touched: a.touched,
|
|
4618
4621
|
value: a.value
|
|
4619
4622
|
};
|
|
4620
|
-
}), this._buttonStates[
|
|
4623
|
+
}), this._buttonStates[i] = n;
|
|
4621
4624
|
const o = {};
|
|
4622
4625
|
Array.from(t.axes).forEach((a, l) => {
|
|
4623
4626
|
o[`axis-${l}`] = a;
|
|
4624
|
-
}), this._axesStates[
|
|
4627
|
+
}), this._axesStates[i] = o, this._notifyDeviceConnected(s), this._notifyInputChanged(s, {
|
|
4625
4628
|
type: "gamepad",
|
|
4626
4629
|
buttons: { ...n },
|
|
4627
4630
|
axes: { ...o },
|
|
@@ -4632,8 +4635,8 @@ class nt {
|
|
|
4632
4635
|
* Handle gamepad disconnected event
|
|
4633
4636
|
*/
|
|
4634
4637
|
_handleGamepadDisconnected(e) {
|
|
4635
|
-
const
|
|
4636
|
-
|
|
4638
|
+
const i = e.gamepad.index, s = this._gamepadDevices[i];
|
|
4639
|
+
s && (s.connected = !1, this._notifyDeviceDisconnected(s), this._gamepadDevices[i] = void 0, this._buttonStates[i] = void 0, this._axesStates[i] = void 0);
|
|
4637
4640
|
}
|
|
4638
4641
|
/**
|
|
4639
4642
|
* Notify subscribers of device connected event
|
|
@@ -4669,8 +4672,8 @@ class ot {
|
|
|
4669
4672
|
* @param canvas - The DOM element to attach input listeners to (used by mouse input)
|
|
4670
4673
|
* @param logger
|
|
4671
4674
|
*/
|
|
4672
|
-
constructor(e, t,
|
|
4673
|
-
this._eventBus = e, this._log =
|
|
4675
|
+
constructor(e, t, i) {
|
|
4676
|
+
this._eventBus = e, this._log = i?.getLogger("UserInputManager") || new u("UserInputManager"), this._log.info("Initializing UserInputManager"), this._log.debug("Initializing input resource access classes"), this._keyboardRA = new it(), this._mouseRA = new st(t), this._gamepadRA = new nt(), this._log.debug("Registering input event callbacks"), this._keyboardRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._keyboardRA.onInputChanged(this._publishInputChanged.bind(this)), this._mouseRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._mouseRA.onInputChanged(this._publishInputChanged.bind(this)), this._gamepadRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._gamepadRA.onDeviceDisconnected(this._publishDeviceDisconnected.bind(this)), this._gamepadRA.onInputChanged(this._publishInputChanged.bind(this)), this._log.info("UserInputManager initialized successfully");
|
|
4674
4677
|
}
|
|
4675
4678
|
//------------------------------------------------------------------------------------------------------------------
|
|
4676
4679
|
// Private methods
|
|
@@ -4738,10 +4741,10 @@ class ot {
|
|
|
4738
4741
|
if (e.startsWith("mouse-"))
|
|
4739
4742
|
return this._mouseRA.getDevice();
|
|
4740
4743
|
if (e.startsWith("gamepad-")) {
|
|
4741
|
-
const
|
|
4742
|
-
return this._gamepadRA.getDevice(
|
|
4744
|
+
const i = parseInt(e.split("-")[1], 10);
|
|
4745
|
+
return this._gamepadRA.getDevice(i);
|
|
4743
4746
|
}
|
|
4744
|
-
const t = this.listDevices().find((
|
|
4747
|
+
const t = this.listDevices().find((i) => i.id === e);
|
|
4745
4748
|
return t || (this._log.warn(`Device not found: ${e}`), null);
|
|
4746
4749
|
}
|
|
4747
4750
|
/**
|
|
@@ -4751,7 +4754,7 @@ class ot {
|
|
|
4751
4754
|
this._gamepadRA.pollGamepads();
|
|
4752
4755
|
}
|
|
4753
4756
|
}
|
|
4754
|
-
async function
|
|
4757
|
+
async function W(r, e) {
|
|
4755
4758
|
const t = new Ee(r, e);
|
|
4756
4759
|
return await t.initAsync(), t;
|
|
4757
4760
|
}
|
|
@@ -4766,11 +4769,11 @@ async function rt(r, e) {
|
|
|
4766
4769
|
return console.debug("Using Null Engine"), at(e);
|
|
4767
4770
|
const t = e.engine || "auto";
|
|
4768
4771
|
if (t === "webgpu")
|
|
4769
|
-
if (
|
|
4772
|
+
if (F())
|
|
4770
4773
|
try {
|
|
4771
|
-
return console.debug("Using forced WebGPU engine"), await
|
|
4772
|
-
} catch (
|
|
4773
|
-
throw console.error("Forced WebGPU initialization failed:",
|
|
4774
|
+
return console.debug("Using forced WebGPU engine"), await W(r, e);
|
|
4775
|
+
} catch (i) {
|
|
4776
|
+
throw console.error("Forced WebGPU initialization failed:", i), new Error(
|
|
4774
4777
|
"Forced WebGPU failed to initialize. If WebGPU is required, check browser compatibility."
|
|
4775
4778
|
);
|
|
4776
4779
|
}
|
|
@@ -4778,11 +4781,11 @@ async function rt(r, e) {
|
|
|
4778
4781
|
throw new Error("WebGPU was forced but is not available in this browser.");
|
|
4779
4782
|
if (t === "webgl")
|
|
4780
4783
|
return console.debug("Using forced WebGL engine"), D(r, e);
|
|
4781
|
-
if (
|
|
4784
|
+
if (F())
|
|
4782
4785
|
try {
|
|
4783
|
-
return console.debug("Using WebGPU"),
|
|
4784
|
-
} catch (
|
|
4785
|
-
console.warn("WebGPU initialization failed, falling back to WebGL:",
|
|
4786
|
+
return console.debug("Using WebGPU"), W(r, e).catch((i) => (console.warn("WebGPU initialization failed, falling back to WebGL:", i), D(r, e)));
|
|
4787
|
+
} catch (i) {
|
|
4788
|
+
console.warn("WebGPU initialization failed, falling back to WebGL:", i);
|
|
4786
4789
|
}
|
|
4787
4790
|
else
|
|
4788
4791
|
console.warn("WebGPU not supported, falling back to WebGL.");
|
|
@@ -4792,7 +4795,7 @@ async function lt() {
|
|
|
4792
4795
|
return await Me();
|
|
4793
4796
|
}
|
|
4794
4797
|
function ht(r) {
|
|
4795
|
-
return new
|
|
4798
|
+
return new J(!0, r);
|
|
4796
4799
|
}
|
|
4797
4800
|
class ct {
|
|
4798
4801
|
_entityManager;
|
|
@@ -4802,39 +4805,39 @@ class ct {
|
|
|
4802
4805
|
//------------------------------------------------------------------------------------------------------------------
|
|
4803
4806
|
// Public API
|
|
4804
4807
|
//------------------------------------------------------------------------------------------------------------------
|
|
4805
|
-
pickEntity(e, t,
|
|
4806
|
-
const n = e.pick(t,
|
|
4807
|
-
return this._toEntityResult(n,
|
|
4808
|
+
pickEntity(e, t, i, s) {
|
|
4809
|
+
const n = e.pick(t, i);
|
|
4810
|
+
return this._toEntityResult(n, s);
|
|
4808
4811
|
}
|
|
4809
|
-
pickEntities(e, t,
|
|
4810
|
-
const n = e.multiPick(t,
|
|
4812
|
+
pickEntities(e, t, i, s) {
|
|
4813
|
+
const n = e.multiPick(t, i);
|
|
4811
4814
|
if (!n)
|
|
4812
4815
|
return [];
|
|
4813
4816
|
const o = [];
|
|
4814
4817
|
for (const a of n) {
|
|
4815
|
-
const l = this._toEntityResult(a,
|
|
4818
|
+
const l = this._toEntityResult(a, s);
|
|
4816
4819
|
l && o.push(l);
|
|
4817
4820
|
}
|
|
4818
4821
|
return o;
|
|
4819
4822
|
}
|
|
4820
|
-
pickEntityWithRay(e, t,
|
|
4821
|
-
const
|
|
4822
|
-
return
|
|
4823
|
+
pickEntityWithRay(e, t, i) {
|
|
4824
|
+
const s = e.pickWithRay(t);
|
|
4825
|
+
return s ? this._toEntityResult(s, i) : null;
|
|
4823
4826
|
}
|
|
4824
|
-
pickEntitiesWithRay(e, t,
|
|
4825
|
-
const
|
|
4826
|
-
if (!
|
|
4827
|
+
pickEntitiesWithRay(e, t, i) {
|
|
4828
|
+
const s = e.multiPickWithRay(t);
|
|
4829
|
+
if (!s)
|
|
4827
4830
|
return [];
|
|
4828
4831
|
const n = [];
|
|
4829
|
-
for (const o of
|
|
4830
|
-
const a = this._toEntityResult(o,
|
|
4832
|
+
for (const o of s) {
|
|
4833
|
+
const a = this._toEntityResult(o, i);
|
|
4831
4834
|
a && n.push(a);
|
|
4832
4835
|
}
|
|
4833
4836
|
return n;
|
|
4834
4837
|
}
|
|
4835
|
-
pickEntityForward(e, t,
|
|
4836
|
-
const n = t.getForwardRay(
|
|
4837
|
-
return this.pickEntityWithRay(e, n,
|
|
4838
|
+
pickEntityForward(e, t, i = 1e3, s) {
|
|
4839
|
+
const n = t.getForwardRay(i);
|
|
4840
|
+
return this.pickEntityWithRay(e, n, s);
|
|
4838
4841
|
}
|
|
4839
4842
|
//------------------------------------------------------------------------------------------------------------------
|
|
4840
4843
|
// Private
|
|
@@ -4842,33 +4845,33 @@ class ct {
|
|
|
4842
4845
|
_toEntityResult(e, t) {
|
|
4843
4846
|
if (!e.hit || !e.pickedMesh || !e.pickedPoint)
|
|
4844
4847
|
return null;
|
|
4845
|
-
const
|
|
4846
|
-
let
|
|
4847
|
-
if (!
|
|
4848
|
-
let o =
|
|
4849
|
-
for (; o && (
|
|
4848
|
+
const i = e.pickedMesh;
|
|
4849
|
+
let s = this._entityManager.getByNode(i);
|
|
4850
|
+
if (!s) {
|
|
4851
|
+
let o = i.parent;
|
|
4852
|
+
for (; o && (s = this._entityManager.getByNode(o), !s); )
|
|
4850
4853
|
o = o.parent;
|
|
4851
4854
|
}
|
|
4852
|
-
if (!
|
|
4855
|
+
if (!s)
|
|
4853
4856
|
return null;
|
|
4854
4857
|
if (t) {
|
|
4855
|
-
if (t.type &&
|
|
4858
|
+
if (t.type && s.type !== t.type)
|
|
4856
4859
|
return null;
|
|
4857
4860
|
if (t.tags) {
|
|
4858
4861
|
for (const o of t.tags)
|
|
4859
|
-
if (!
|
|
4862
|
+
if (!s.hasTag(o))
|
|
4860
4863
|
return null;
|
|
4861
4864
|
}
|
|
4862
|
-
if (t.predicate && !t.predicate(
|
|
4865
|
+
if (t.predicate && !t.predicate(s))
|
|
4863
4866
|
return null;
|
|
4864
4867
|
}
|
|
4865
4868
|
const n = e.getNormal(!0, !0);
|
|
4866
4869
|
return {
|
|
4867
|
-
entity:
|
|
4870
|
+
entity: s,
|
|
4868
4871
|
point: e.pickedPoint,
|
|
4869
4872
|
distance: e.distance,
|
|
4870
4873
|
normal: n ?? { x: 0, y: 0, z: 0 },
|
|
4871
|
-
mesh:
|
|
4874
|
+
mesh: i,
|
|
4872
4875
|
pickingInfo: e
|
|
4873
4876
|
};
|
|
4874
4877
|
}
|
|
@@ -4889,9 +4892,9 @@ class dt {
|
|
|
4889
4892
|
delay(e, t) {
|
|
4890
4893
|
if (e < 0)
|
|
4891
4894
|
throw new RangeError(`delay() requires ms >= 0, got ${e}`);
|
|
4892
|
-
const
|
|
4893
|
-
return this._delays.push({ id:
|
|
4894
|
-
this._delays = this._delays.filter((
|
|
4895
|
+
const i = this._nextId++;
|
|
4896
|
+
return this._delays.push({ id: i, remaining: e, callback: t }), () => {
|
|
4897
|
+
this._delays = this._delays.filter((s) => s.id !== i);
|
|
4895
4898
|
};
|
|
4896
4899
|
}
|
|
4897
4900
|
/**
|
|
@@ -4902,22 +4905,22 @@ class dt {
|
|
|
4902
4905
|
interval(e, t) {
|
|
4903
4906
|
if (e <= 0)
|
|
4904
4907
|
throw new RangeError(`interval() requires ms > 0, got ${e}`);
|
|
4905
|
-
const
|
|
4906
|
-
return this._intervals.push({ id:
|
|
4907
|
-
this._intervals = this._intervals.filter((
|
|
4908
|
+
const i = this._nextId++;
|
|
4909
|
+
return this._intervals.push({ id: i, periodMs: e, elapsed: 0, callback: t }), () => {
|
|
4910
|
+
this._intervals = this._intervals.filter((s) => s.id !== i);
|
|
4908
4911
|
};
|
|
4909
4912
|
}
|
|
4910
4913
|
/**
|
|
4911
4914
|
* Pollable cooldown. Starts ready; after calling `reset()`, becomes not-ready until `ms` elapses.
|
|
4912
4915
|
*/
|
|
4913
4916
|
cooldown(e) {
|
|
4914
|
-
const
|
|
4915
|
-
return this._cooldowns.push(
|
|
4917
|
+
const i = { id: this._nextId++, periodMs: e, remaining: 0 };
|
|
4918
|
+
return this._cooldowns.push(i), {
|
|
4916
4919
|
get ready() {
|
|
4917
|
-
return
|
|
4920
|
+
return i.remaining <= 0;
|
|
4918
4921
|
},
|
|
4919
4922
|
reset() {
|
|
4920
|
-
|
|
4923
|
+
i.remaining = i.periodMs;
|
|
4921
4924
|
}
|
|
4922
4925
|
};
|
|
4923
4926
|
}
|
|
@@ -4935,14 +4938,14 @@ class dt {
|
|
|
4935
4938
|
*/
|
|
4936
4939
|
tick(e) {
|
|
4937
4940
|
const t = [];
|
|
4938
|
-
for (const
|
|
4939
|
-
|
|
4940
|
-
t.length > 0 && (this._delays = this._delays.filter((
|
|
4941
|
-
for (const
|
|
4942
|
-
for (
|
|
4943
|
-
|
|
4944
|
-
for (const
|
|
4945
|
-
|
|
4941
|
+
for (const i of this._delays)
|
|
4942
|
+
i.remaining -= e, i.remaining <= 0 && (i.callback(), t.push(i.id));
|
|
4943
|
+
t.length > 0 && (this._delays = this._delays.filter((i) => !t.includes(i.id)));
|
|
4944
|
+
for (const i of this._intervals)
|
|
4945
|
+
for (i.elapsed += e; i.elapsed >= i.periodMs; )
|
|
4946
|
+
i.callback(), i.elapsed -= i.periodMs;
|
|
4947
|
+
for (const i of this._cooldowns)
|
|
4948
|
+
i.remaining > 0 && (i.remaining = Math.max(0, i.remaining - e));
|
|
4946
4949
|
}
|
|
4947
4950
|
}
|
|
4948
4951
|
const Mt = [
|
|
@@ -4953,7 +4956,7 @@ const Mt = [
|
|
|
4953
4956
|
"error",
|
|
4954
4957
|
"none"
|
|
4955
4958
|
];
|
|
4956
|
-
class kt extends
|
|
4959
|
+
class kt extends ae {
|
|
4957
4960
|
name = "sound";
|
|
4958
4961
|
eventSubscriptions = [];
|
|
4959
4962
|
/** Map of sound name to StaticSound instance */
|
|
@@ -4979,9 +4982,9 @@ class kt extends oe {
|
|
|
4979
4982
|
}
|
|
4980
4983
|
if (!this.entity)
|
|
4981
4984
|
return;
|
|
4982
|
-
const
|
|
4983
|
-
if (
|
|
4984
|
-
for (const [n, o] of Object.entries(
|
|
4985
|
+
const s = this.entity.state.sounds;
|
|
4986
|
+
if (s)
|
|
4987
|
+
for (const [n, o] of Object.entries(s))
|
|
4985
4988
|
this._createSound(n, o);
|
|
4986
4989
|
}
|
|
4987
4990
|
processEvent(e, t) {
|
|
@@ -4999,9 +5002,9 @@ class kt extends oe {
|
|
|
4999
5002
|
_createSound(e, t) {
|
|
5000
5003
|
if (!this._audioManager || !this.entity)
|
|
5001
5004
|
return;
|
|
5002
|
-
const
|
|
5005
|
+
const i = this.entity.id, s = this._node;
|
|
5003
5006
|
this._audioManager.createSound(
|
|
5004
|
-
`${
|
|
5007
|
+
`${i}_${e}`,
|
|
5005
5008
|
t.url,
|
|
5006
5009
|
t.channel,
|
|
5007
5010
|
{
|
|
@@ -5013,7 +5016,7 @@ class kt extends oe {
|
|
|
5013
5016
|
spatialDistanceModel: "linear"
|
|
5014
5017
|
}
|
|
5015
5018
|
).then((n) => {
|
|
5016
|
-
this._sounds.set(e, n), (t.spatial ?? !1) &&
|
|
5019
|
+
this._sounds.set(e, n), (t.spatial ?? !1) && s && n.spatial.attach(s);
|
|
5017
5020
|
}).catch((n) => {
|
|
5018
5021
|
this._log.error(`Failed to create sound "${e}": ${n}`);
|
|
5019
5022
|
});
|
|
@@ -5033,8 +5036,8 @@ class kt extends oe {
|
|
|
5033
5036
|
* @param time - Optional time offset in seconds to start playing from
|
|
5034
5037
|
*/
|
|
5035
5038
|
play(e, t) {
|
|
5036
|
-
const
|
|
5037
|
-
|
|
5039
|
+
const i = this._getSound(e);
|
|
5040
|
+
i && (t !== void 0 ? i.play({ startOffset: t }) : i.play());
|
|
5038
5041
|
}
|
|
5039
5042
|
/**
|
|
5040
5043
|
* Stop a sound by name.
|
|
@@ -5066,11 +5069,11 @@ class kt extends oe {
|
|
|
5066
5069
|
*/
|
|
5067
5070
|
setVolume(e, t) {
|
|
5068
5071
|
if (t) {
|
|
5069
|
-
const
|
|
5070
|
-
|
|
5072
|
+
const i = this._sounds.get(t);
|
|
5073
|
+
i && (i.volume = e);
|
|
5071
5074
|
} else
|
|
5072
|
-
for (const
|
|
5073
|
-
|
|
5075
|
+
for (const i of this._sounds.values())
|
|
5076
|
+
i.volume = e;
|
|
5074
5077
|
}
|
|
5075
5078
|
/**
|
|
5076
5079
|
* Check if a sound is currently playing.
|
|
@@ -5078,7 +5081,7 @@ class kt extends oe {
|
|
|
5078
5081
|
* @param name - The name of the sound. If omitted and only one sound exists, checks that sound.
|
|
5079
5082
|
*/
|
|
5080
5083
|
isPlaying(e) {
|
|
5081
|
-
return this._getSound(e)?.state ===
|
|
5084
|
+
return this._getSound(e)?.state === ne.Started;
|
|
5082
5085
|
}
|
|
5083
5086
|
/**
|
|
5084
5087
|
* Get all registered sound names.
|
|
@@ -5103,8 +5106,8 @@ class kt extends oe {
|
|
|
5103
5106
|
registerSound(e, t) {
|
|
5104
5107
|
if (!this._initialized || !this._audioManager)
|
|
5105
5108
|
throw new Error("SoundBehavior must be initialized before registering sounds");
|
|
5106
|
-
const
|
|
5107
|
-
|
|
5109
|
+
const i = this._sounds.get(e);
|
|
5110
|
+
i && i.dispose(), this._createSound(e, t);
|
|
5108
5111
|
}
|
|
5109
5112
|
/**
|
|
5110
5113
|
* Unregister and dispose a sound.
|
|
@@ -5128,7 +5131,7 @@ class kt extends oe {
|
|
|
5128
5131
|
return this._sounds.values().next().value;
|
|
5129
5132
|
}
|
|
5130
5133
|
}
|
|
5131
|
-
class
|
|
5134
|
+
class j {
|
|
5132
5135
|
_currentState;
|
|
5133
5136
|
transitions = /* @__PURE__ */ new Map();
|
|
5134
5137
|
wildcardTransitions = /* @__PURE__ */ new Map();
|
|
@@ -5150,9 +5153,9 @@ class W {
|
|
|
5150
5153
|
/**
|
|
5151
5154
|
* Register a valid transition from one state to another, with an optional guard function.
|
|
5152
5155
|
*/
|
|
5153
|
-
addTransition(e, t,
|
|
5154
|
-
const
|
|
5155
|
-
this.transitions.set(
|
|
5156
|
+
addTransition(e, t, i) {
|
|
5157
|
+
const s = `${e}->${t}`;
|
|
5158
|
+
this.transitions.set(s, { guard: i });
|
|
5156
5159
|
}
|
|
5157
5160
|
/**
|
|
5158
5161
|
* Register a wildcard transition: allows transitioning to the given state from any state.
|
|
@@ -5164,15 +5167,15 @@ class W {
|
|
|
5164
5167
|
* Register a callback to run when entering a state.
|
|
5165
5168
|
*/
|
|
5166
5169
|
onEnter(e, t) {
|
|
5167
|
-
const
|
|
5168
|
-
|
|
5170
|
+
const i = this.enterCallbacks.get(e) ?? [];
|
|
5171
|
+
i.push(t), this.enterCallbacks.set(e, i);
|
|
5169
5172
|
}
|
|
5170
5173
|
/**
|
|
5171
5174
|
* Register a callback to run when exiting a state.
|
|
5172
5175
|
*/
|
|
5173
5176
|
onExit(e, t) {
|
|
5174
|
-
const
|
|
5175
|
-
|
|
5177
|
+
const i = this.exitCallbacks.get(e) ?? [];
|
|
5178
|
+
i.push(t), this.exitCallbacks.set(e, i);
|
|
5176
5179
|
}
|
|
5177
5180
|
//------------------------------------------------------------------------------------------------------------------
|
|
5178
5181
|
// Queries
|
|
@@ -5195,22 +5198,22 @@ class W {
|
|
|
5195
5198
|
*/
|
|
5196
5199
|
transition(e) {
|
|
5197
5200
|
const t = `${this._currentState}->${e}`;
|
|
5198
|
-
let
|
|
5199
|
-
if (
|
|
5201
|
+
let i = this.transitions.get(t);
|
|
5202
|
+
if (i || (i = this.wildcardTransitions.get(e)), !i)
|
|
5200
5203
|
throw new Error(
|
|
5201
5204
|
`No transition defined from '${this._currentState}' to '${e}'.`
|
|
5202
5205
|
);
|
|
5203
|
-
if (
|
|
5206
|
+
if (i.guard && !i.guard())
|
|
5204
5207
|
throw new Error(
|
|
5205
5208
|
`Guard rejected transition from '${this._currentState}' to '${e}'.`
|
|
5206
5209
|
);
|
|
5207
|
-
const
|
|
5210
|
+
const s = this._currentState, n = this.exitCallbacks.get(s);
|
|
5208
5211
|
if (n)
|
|
5209
5212
|
for (const a of n)
|
|
5210
5213
|
a();
|
|
5211
5214
|
this.eventBus && this.eventBus.publish({
|
|
5212
|
-
type: `state:exit:${
|
|
5213
|
-
payload: { from:
|
|
5215
|
+
type: `state:exit:${s}`,
|
|
5216
|
+
payload: { from: s, to: e }
|
|
5214
5217
|
}), this._currentState = e;
|
|
5215
5218
|
const o = this.enterCallbacks.get(e);
|
|
5216
5219
|
if (o)
|
|
@@ -5218,17 +5221,17 @@ class W {
|
|
|
5218
5221
|
a();
|
|
5219
5222
|
this.eventBus && this.eventBus.publish({
|
|
5220
5223
|
type: `state:enter:${e}`,
|
|
5221
|
-
payload: { from:
|
|
5224
|
+
payload: { from: s, to: e }
|
|
5222
5225
|
});
|
|
5223
5226
|
}
|
|
5224
5227
|
}
|
|
5225
|
-
class
|
|
5228
|
+
class re extends ae {
|
|
5226
5229
|
name = "stateMachine";
|
|
5227
5230
|
eventSubscriptions = [];
|
|
5228
5231
|
stateMachine;
|
|
5229
5232
|
stateKey;
|
|
5230
5233
|
constructor() {
|
|
5231
|
-
super(), this.stateMachine = new
|
|
5234
|
+
super(), this.stateMachine = new j(""), this.stateKey = "";
|
|
5232
5235
|
}
|
|
5233
5236
|
//------------------------------------------------------------------------------------------------------------------
|
|
5234
5237
|
// Public API
|
|
@@ -5261,11 +5264,11 @@ class ae extends oe {
|
|
|
5261
5264
|
* The returned class can be used directly as a behavior constructor.
|
|
5262
5265
|
*/
|
|
5263
5266
|
static create(e) {
|
|
5264
|
-
const { initialState: t, stateKey:
|
|
5265
|
-
class o extends
|
|
5267
|
+
const { initialState: t, stateKey: i, transitions: s, wildcardTransitions: n } = e;
|
|
5268
|
+
class o extends re {
|
|
5266
5269
|
constructor() {
|
|
5267
|
-
super(), this.stateKey =
|
|
5268
|
-
for (const l of
|
|
5270
|
+
super(), this.stateKey = i, this.stateMachine = new j(t);
|
|
5271
|
+
for (const l of s)
|
|
5269
5272
|
this.stateMachine.addTransition(l.from, l.to, l.guard);
|
|
5270
5273
|
if (n)
|
|
5271
5274
|
for (const l of n)
|
|
@@ -5277,19 +5280,19 @@ class ae extends oe {
|
|
|
5277
5280
|
}
|
|
5278
5281
|
const A = new u("ColliderHandler");
|
|
5279
5282
|
function C(r, e, t) {
|
|
5280
|
-
const
|
|
5281
|
-
new se(r, e, { mass: t },
|
|
5283
|
+
const i = r.getScene();
|
|
5284
|
+
new se(r, e, { mass: t }, i);
|
|
5282
5285
|
}
|
|
5283
5286
|
function ut(r, e) {
|
|
5284
5287
|
const t = r.getChildMeshes().find(
|
|
5285
|
-
(
|
|
5288
|
+
(i) => i.metadata?.collider_mesh === !0
|
|
5286
5289
|
);
|
|
5287
5290
|
t instanceof w ? (t.isVisible = !1, C(t, S.MESH, e)) : C(r, S.MESH, e);
|
|
5288
5291
|
}
|
|
5289
5292
|
function gt(r) {
|
|
5290
|
-
r.registerPropertyHandler("collider", (e, t,
|
|
5293
|
+
r.registerPropertyHandler("collider", (e, t, i, s) => {
|
|
5291
5294
|
const n = t;
|
|
5292
|
-
if (A.debug(`Processing collider: ${e.name} -> ${n} (isMesh: ${e instanceof w})`), !
|
|
5295
|
+
if (A.debug(`Processing collider: ${e.name} -> ${n} (isMesh: ${e instanceof w})`), !i.scene)
|
|
5293
5296
|
throw new Error("Scene not available for collider handler");
|
|
5294
5297
|
if (!(e instanceof w)) {
|
|
5295
5298
|
A.warn(`Skipping collider for ${e.name}: not a Mesh instance`);
|
|
@@ -5323,7 +5326,7 @@ function ft(r) {
|
|
|
5323
5326
|
return r.split(",").map((e) => parseFloat(e.trim())).filter((e) => !isNaN(e));
|
|
5324
5327
|
}
|
|
5325
5328
|
function pt(r) {
|
|
5326
|
-
r.registerPropertyHandler("lod_distances", (e, t,
|
|
5329
|
+
r.registerPropertyHandler("lod_distances", (e, t, i, s) => {
|
|
5327
5330
|
const n = t;
|
|
5328
5331
|
if (!(e instanceof w))
|
|
5329
5332
|
return;
|
|
@@ -5340,31 +5343,31 @@ function pt(r) {
|
|
|
5340
5343
|
});
|
|
5341
5344
|
}
|
|
5342
5345
|
function yt(r) {
|
|
5343
|
-
r.registerPropertyHandler("occluder", (e, t,
|
|
5346
|
+
r.registerPropertyHandler("occluder", (e, t, i, s) => {
|
|
5344
5347
|
t && e instanceof w && (e.isOccluder = !0, e.isVisible = !1);
|
|
5345
5348
|
});
|
|
5346
5349
|
}
|
|
5347
5350
|
function mt(r, e) {
|
|
5348
|
-
const t = {},
|
|
5349
|
-
for (const [
|
|
5350
|
-
if (
|
|
5351
|
-
const o =
|
|
5351
|
+
const t = {}, i = `${e}_`;
|
|
5352
|
+
for (const [s, n] of Object.entries(r))
|
|
5353
|
+
if (s.startsWith(i)) {
|
|
5354
|
+
const o = s.slice(i.length);
|
|
5352
5355
|
t[o] = n;
|
|
5353
5356
|
}
|
|
5354
5357
|
return t;
|
|
5355
5358
|
}
|
|
5356
|
-
const
|
|
5359
|
+
const Z = new u("SoundHandler");
|
|
5357
5360
|
function vt(r) {
|
|
5358
|
-
r.registerPropertyHandler("sound", (e, t,
|
|
5361
|
+
r.registerPropertyHandler("sound", (e, t, i, s) => {
|
|
5359
5362
|
const n = t;
|
|
5360
|
-
if (!
|
|
5363
|
+
if (!i.scene)
|
|
5361
5364
|
throw new Error("Scene not available for sound handler");
|
|
5362
5365
|
const a = mt(
|
|
5363
5366
|
e.metadata,
|
|
5364
5367
|
"sound"
|
|
5365
|
-
), l = a.volume ?? 1, h = a.loop ?? !0, c = a.spatial ?? !0, d = a.distance ?? 100, m = a.autoplay ?? !0, f = a.channel ?? "ambient", g =
|
|
5368
|
+
), l = a.volume ?? 1, h = a.loop ?? !0, c = a.spatial ?? !0, d = a.distance ?? 100, m = a.autoplay ?? !0, f = a.channel ?? "ambient", g = s.managers.audioManager;
|
|
5366
5369
|
if (!g) {
|
|
5367
|
-
|
|
5370
|
+
Z.warn(`No AudioManager available. Sound for "${e.name}" skipped.`);
|
|
5368
5371
|
return;
|
|
5369
5372
|
}
|
|
5370
5373
|
g.createSound(
|
|
@@ -5382,17 +5385,17 @@ function vt(r) {
|
|
|
5382
5385
|
).then((_) => {
|
|
5383
5386
|
c && _.spatial.attach(e);
|
|
5384
5387
|
}).catch((_) => {
|
|
5385
|
-
|
|
5388
|
+
Z.error(`Failed to create sound for node "${e.name}": ${_}`);
|
|
5386
5389
|
});
|
|
5387
5390
|
});
|
|
5388
5391
|
}
|
|
5389
|
-
function
|
|
5390
|
-
const n =
|
|
5392
|
+
function q(r, e, t, i, s) {
|
|
5393
|
+
const n = s === "enter" ? L.OnIntersectionEnterTrigger : L.OnIntersectionExitTrigger, o = `trigger:${s}`;
|
|
5391
5394
|
r.registerAction(
|
|
5392
5395
|
new xe(
|
|
5393
5396
|
{
|
|
5394
5397
|
trigger: n,
|
|
5395
|
-
parameter: { mesh:
|
|
5398
|
+
parameter: { mesh: i }
|
|
5396
5399
|
},
|
|
5397
5400
|
(a) => {
|
|
5398
5401
|
t.publish({
|
|
@@ -5406,24 +5409,24 @@ function Z(r, e, t, s, i) {
|
|
|
5406
5409
|
)
|
|
5407
5410
|
);
|
|
5408
5411
|
}
|
|
5409
|
-
function
|
|
5410
|
-
|
|
5412
|
+
function Y(r, e, t, i) {
|
|
5413
|
+
q(r, e, t, i, "enter"), q(r, e, t, i, "exit");
|
|
5411
5414
|
}
|
|
5412
5415
|
function bt(r) {
|
|
5413
|
-
r.registerPropertyHandler("trigger", (e, t,
|
|
5414
|
-
const n = t, o =
|
|
5416
|
+
r.registerPropertyHandler("trigger", (e, t, i, s) => {
|
|
5417
|
+
const n = t, o = i.scene;
|
|
5415
5418
|
if (!o)
|
|
5416
5419
|
throw new Error("Scene not available for trigger handler");
|
|
5417
|
-
if (!(e instanceof
|
|
5420
|
+
if (!(e instanceof oe))
|
|
5418
5421
|
return;
|
|
5419
|
-
const a =
|
|
5422
|
+
const a = s.eventBus;
|
|
5420
5423
|
e.isVisible = !1, e.checkCollisions = !0;
|
|
5421
5424
|
const l = e.actionManager ?? new L(o);
|
|
5422
5425
|
e.actionManager = l;
|
|
5423
5426
|
for (const c of o.meshes)
|
|
5424
|
-
c !== e && !c.metadata?.trigger &&
|
|
5427
|
+
c !== e && !c.metadata?.trigger && Y(l, n, a, c);
|
|
5425
5428
|
const h = o.onNewMeshAddedObservable.add((c) => {
|
|
5426
|
-
c !== e && !c.metadata?.trigger &&
|
|
5429
|
+
c !== e && !c.metadata?.trigger && Y(l, n, a, c);
|
|
5427
5430
|
});
|
|
5428
5431
|
e.onDisposeObservable.add(() => {
|
|
5429
5432
|
o.onNewMeshAddedObservable.remove(h);
|
|
@@ -5431,8 +5434,8 @@ function bt(r) {
|
|
|
5431
5434
|
});
|
|
5432
5435
|
}
|
|
5433
5436
|
function wt(r) {
|
|
5434
|
-
r.registerPropertyHandler("visible", (e, t,
|
|
5435
|
-
if (!(e instanceof
|
|
5437
|
+
r.registerPropertyHandler("visible", (e, t, i, s) => {
|
|
5438
|
+
if (!(e instanceof oe))
|
|
5436
5439
|
return;
|
|
5437
5440
|
let n = !0;
|
|
5438
5441
|
typeof t == "boolean" ? n = t : typeof t == "string" ? n = t.toLowerCase() === "true" || t === "1" : typeof t == "number" && (n = t !== 0), e.isVisible = n;
|
|
@@ -5442,31 +5445,31 @@ function Dt(r) {
|
|
|
5442
5445
|
gt(r), pt(r), yt(r), vt(r), bt(r), wt(r);
|
|
5443
5446
|
}
|
|
5444
5447
|
async function At(r, e, t = {}) {
|
|
5445
|
-
const
|
|
5446
|
-
|
|
5448
|
+
const i = new Be(t.logLevel || "debug"), s = i.getLogger("SAGE");
|
|
5449
|
+
s.info(`Initializing SAGE Game Engine v${E}...`), s.debug("Creating rendering engine...");
|
|
5447
5450
|
const n = {
|
|
5448
5451
|
antialias: !0,
|
|
5449
5452
|
adaptToDeviceRatio: !0,
|
|
5450
5453
|
...t.renderOptions
|
|
5451
5454
|
}, o = await rt(r, n);
|
|
5452
|
-
|
|
5455
|
+
s.debug("Creating physics engine...");
|
|
5453
5456
|
const a = await lt(), l = ht(a);
|
|
5454
|
-
|
|
5455
|
-
const h = new Le(
|
|
5456
|
-
|
|
5457
|
-
const c = new Ie(r, o, a,
|
|
5458
|
-
|
|
5459
|
-
const d = new Pe(h, c,
|
|
5460
|
-
|
|
5461
|
-
const
|
|
5462
|
-
|
|
5457
|
+
s.debug("Creating event bus...");
|
|
5458
|
+
const h = new Le(i);
|
|
5459
|
+
s.debug("Creating scene engine...");
|
|
5460
|
+
const c = new Ie(r, o, a, i);
|
|
5461
|
+
s.debug("Creating managers...");
|
|
5462
|
+
const d = new Pe(h, c, i), m = new ot(h, r, i), f = new Ue(h, i), g = new Ze(h, i, f), _ = new Qe(h, i), le = new tt(g, _, i), N = new Ke(o, h, g, m, _, i);
|
|
5463
|
+
s.debug("Creating raycast helper...");
|
|
5464
|
+
const he = new ct(g);
|
|
5465
|
+
s.debug("Creating game timer...");
|
|
5463
5466
|
const G = new dt();
|
|
5464
5467
|
N.registerFrameCallback((b) => G.tick(b * 1e3));
|
|
5465
5468
|
let $, x;
|
|
5466
|
-
t.audioChannels && t.audioChannels.length > 0 && (
|
|
5469
|
+
t.audioChannels && t.audioChannels.length > 0 && (s.debug("Creating audio engine..."), $ = new Te(i), await $.initialize(), s.debug("Creating audio manager..."), x = new et($, i), await x.initialize(t.audioChannels)), s.info(`SAGE Game Engine v${E} initialized successfully.`), s.debug("Loading entities...");
|
|
5467
5470
|
for (const b of e)
|
|
5468
5471
|
g.registerEntityDefinition(b);
|
|
5469
|
-
if (
|
|
5472
|
+
if (s.debug("Registering default input bindings..."), t.bindings)
|
|
5470
5473
|
for (const b of t.bindings)
|
|
5471
5474
|
f.registerBinding(b);
|
|
5472
5475
|
const M = new ke(
|
|
@@ -5474,8 +5477,8 @@ async function At(r, e, t = {}) {
|
|
|
5474
5477
|
o,
|
|
5475
5478
|
l,
|
|
5476
5479
|
h,
|
|
5477
|
-
|
|
5478
|
-
|
|
5480
|
+
i,
|
|
5481
|
+
he,
|
|
5479
5482
|
G,
|
|
5480
5483
|
// Engines
|
|
5481
5484
|
{
|
|
@@ -5490,7 +5493,7 @@ async function At(r, e, t = {}) {
|
|
|
5490
5493
|
gameManager: N,
|
|
5491
5494
|
inputManager: m,
|
|
5492
5495
|
levelManager: _,
|
|
5493
|
-
saveManager:
|
|
5496
|
+
saveManager: le,
|
|
5494
5497
|
audioManager: x
|
|
5495
5498
|
}
|
|
5496
5499
|
);
|
|
@@ -5503,7 +5506,7 @@ export {
|
|
|
5503
5506
|
De as ConsoleBackend,
|
|
5504
5507
|
ke as GameEngine,
|
|
5505
5508
|
je as GameEntity,
|
|
5506
|
-
|
|
5509
|
+
ae as GameEntityBehavior,
|
|
5507
5510
|
Le as GameEventBus,
|
|
5508
5511
|
Xe as GameLevel,
|
|
5509
5512
|
dt as GameTimer,
|
|
@@ -5516,17 +5519,17 @@ export {
|
|
|
5516
5519
|
tt as SaveManager,
|
|
5517
5520
|
Ie as SceneEngine,
|
|
5518
5521
|
kt as SoundBehavior,
|
|
5519
|
-
|
|
5520
|
-
|
|
5522
|
+
j as StateMachine,
|
|
5523
|
+
re as StateMachineBehavior,
|
|
5521
5524
|
E as VERSION,
|
|
5522
5525
|
Ye as applyPostProcessing,
|
|
5523
5526
|
ze as bindingTypes,
|
|
5524
5527
|
mt as collectPrefixedProperties,
|
|
5525
5528
|
At as createGameEngine,
|
|
5526
5529
|
We as generateId,
|
|
5527
|
-
|
|
5530
|
+
K as isGamepadState,
|
|
5528
5531
|
Ve as isKeyboardState,
|
|
5529
|
-
|
|
5532
|
+
U as isMouseState,
|
|
5530
5533
|
Dt as registerAllPropertyHandlers,
|
|
5531
5534
|
gt as registerColliderHandler,
|
|
5532
5535
|
pt as registerLodHandler,
|