@playcanvas/web-components 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pwc.mjs ADDED
@@ -0,0 +1,2488 @@
1
+ import { WasmModule, Application, Keyboard, Mouse, FILLMODE_FILL_WINDOW, RESOLUTION_AUTO, Color, Vec2, Vec3, Vec4, Entity, Asset, PROJECTION_ORTHOGRAPHIC, PROJECTION_PERSPECTIVE, Quat, LAYERID_SKYBOX } from 'playcanvas';
2
+
3
+ class ModuleElement extends HTMLElement {
4
+ constructor() {
5
+ super();
6
+ this.loadPromise = this.loadModule();
7
+ }
8
+ async loadModule() {
9
+ const name = this.getAttribute('name');
10
+ const glue = this.getAttribute('glue');
11
+ const wasm = this.getAttribute('wasm');
12
+ const fallback = this.getAttribute('fallback');
13
+ WasmModule.setConfig(name, {
14
+ glueUrl: glue,
15
+ wasmUrl: wasm,
16
+ fallbackUrl: fallback
17
+ });
18
+ await new Promise((resolve) => {
19
+ WasmModule.getInstance(name, () => resolve());
20
+ });
21
+ }
22
+ getLoadPromise() {
23
+ return this.loadPromise;
24
+ }
25
+ }
26
+ customElements.define('pc-module', ModuleElement);
27
+
28
+ /**
29
+ * The main application element.
30
+ */
31
+ class AppElement extends HTMLElement {
32
+ /**
33
+ * Creates a new AppElement.
34
+ */
35
+ constructor() {
36
+ super();
37
+ /**
38
+ * The canvas element.
39
+ */
40
+ this._canvas = null;
41
+ this._highResolution = false;
42
+ /**
43
+ * The PlayCanvas application instance.
44
+ */
45
+ this.app = null;
46
+ // Bind methods to maintain 'this' context
47
+ this._onWindowResize = this._onWindowResize.bind(this);
48
+ this.appReadyPromise = new Promise((resolve) => {
49
+ this.appReadyResolve = resolve;
50
+ });
51
+ }
52
+ async connectedCallback() {
53
+ // Get all pc-module elements that are direct children of the pc-app element
54
+ const moduleElements = this.querySelectorAll(':scope > pc-module');
55
+ // Wait for all modules to load
56
+ await Promise.all(Array.from(moduleElements).map(module => module.getLoadPromise()));
57
+ // Create and append the canvas to the element
58
+ this._canvas = document.createElement('canvas');
59
+ this.appendChild(this._canvas);
60
+ // Initialize the PlayCanvas application
61
+ this.app = new Application(this._canvas, {
62
+ graphicsDeviceOptions: {
63
+ devicePixelRatio: this._highResolution ? window.devicePixelRatio : 1
64
+ },
65
+ keyboard: new Keyboard(window),
66
+ mouse: new Mouse(this._canvas)
67
+ });
68
+ this.app.setCanvasFillMode(FILLMODE_FILL_WINDOW);
69
+ this.app.setCanvasResolution(RESOLUTION_AUTO);
70
+ // Get all pc-asset elements that are direct children of the pc-app element
71
+ const assetElements = this.querySelectorAll(':scope > pc-asset');
72
+ Array.from(assetElements).forEach((assetElement) => {
73
+ assetElement.createAsset();
74
+ const asset = assetElement.asset;
75
+ if (asset) {
76
+ this.app.assets.add(asset);
77
+ }
78
+ });
79
+ // Load assets before starting the application
80
+ this.app.preload(() => {
81
+ // Start the application
82
+ this.app.start();
83
+ // Handle window resize to keep the canvas responsive
84
+ window.addEventListener('resize', this._onWindowResize);
85
+ this.appReadyResolve(this.app);
86
+ });
87
+ }
88
+ disconnectedCallback() {
89
+ // Clean up the application
90
+ if (this.app) {
91
+ this.app.destroy();
92
+ this.app = null;
93
+ }
94
+ // Remove event listeners
95
+ window.removeEventListener('resize', this._onWindowResize);
96
+ // Remove the canvas
97
+ if (this._canvas && this.contains(this._canvas)) {
98
+ this.removeChild(this._canvas);
99
+ this._canvas = null;
100
+ }
101
+ }
102
+ async getApplication() {
103
+ await this.appReadyPromise;
104
+ return this.app;
105
+ }
106
+ _onWindowResize() {
107
+ if (this.app) {
108
+ this.app.resizeCanvas();
109
+ }
110
+ }
111
+ set highResolution(value) {
112
+ this._highResolution = value;
113
+ if (this.app) {
114
+ this.app.graphicsDevice.maxPixelRatio = value ? window.devicePixelRatio : 1;
115
+ }
116
+ }
117
+ get highResolution() {
118
+ return this._highResolution;
119
+ }
120
+ static get observedAttributes() {
121
+ return ['high-resolution'];
122
+ }
123
+ attributeChangedCallback(name, _oldValue, _newValue) {
124
+ switch (name) {
125
+ case 'high-resolution':
126
+ this.highResolution = this.hasAttribute(name);
127
+ break;
128
+ }
129
+ }
130
+ }
131
+ customElements.define('pc-app', AppElement);
132
+
133
+ /**
134
+ * Parse a color string into a Color object. String can be in the format of '#rgb', '#rgba',
135
+ * '#rrggbb', '#rrggbbaa', or a string of 3 or 4 comma-delimited numbers.
136
+ *
137
+ * @param value - The color string to parse.
138
+ * @returns The parsed Color object.
139
+ */
140
+ const parseColor = (value) => {
141
+ if (value.startsWith('#')) {
142
+ return new Color().fromString(value);
143
+ }
144
+ const components = value.split(',').map(Number);
145
+ return new Color(components);
146
+ };
147
+ /**
148
+ * Parse a Vec2 string into a Vec2 object. String can be in the format of 'x,y'.
149
+ *
150
+ * @param value - The Vec2 string to parse.
151
+ * @returns The parsed Vec2 object.
152
+ */
153
+ const parseVec2 = (value) => {
154
+ const components = value.split(',').map(Number);
155
+ return new Vec2(components);
156
+ };
157
+ /**
158
+ * Parse a Vec3 string into a Vec3 object. String can be in the format of 'x,y,z'.
159
+ *
160
+ * @param value - The Vec3 string to parse.
161
+ * @returns The parsed Vec3 object.
162
+ */
163
+ const parseVec3 = (value) => {
164
+ const components = value.split(',').map(Number);
165
+ return new Vec3(components);
166
+ };
167
+ /**
168
+ * Parse a Vec4 string into a Vec4 object. String can be in the format of 'x,y,z,w'.
169
+ *
170
+ * @param value - The Vec4 string to parse.
171
+ * @returns The parsed Vec4 object.
172
+ */
173
+ const parseVec4 = (value) => {
174
+ const components = value.split(',').map(Number);
175
+ return new Vec4(components);
176
+ };
177
+
178
+ /**
179
+ * Represents an entity in the PlayCanvas engine.
180
+ */
181
+ class EntityElement extends HTMLElement {
182
+ constructor() {
183
+ super(...arguments);
184
+ /**
185
+ * Whether the entity is enabled.
186
+ */
187
+ this._enabled = true;
188
+ /**
189
+ * The name of the entity.
190
+ */
191
+ this._name = 'Untitled';
192
+ /**
193
+ * The position of the entity.
194
+ */
195
+ this._position = new Vec3();
196
+ /**
197
+ * The rotation of the entity.
198
+ */
199
+ this._rotation = new Vec3();
200
+ /**
201
+ * The scale of the entity.
202
+ */
203
+ this._scale = new Vec3(1, 1, 1);
204
+ /**
205
+ * The tags of the entity.
206
+ */
207
+ this._tags = [];
208
+ /**
209
+ * The PlayCanvas entity instance.
210
+ */
211
+ this.entity = null;
212
+ }
213
+ async connectedCallback() {
214
+ // Get the application
215
+ const appElement = this.closest('pc-app');
216
+ if (!appElement) {
217
+ console.warn(`${this.tagName} must be a child of pc-app`);
218
+ return;
219
+ }
220
+ const app = await appElement.getApplication();
221
+ // Create a new entity
222
+ this.entity = new Entity(this._name, app);
223
+ if (this.parentElement && this.parentElement.tagName === 'pc-entity' && this.parentElement.entity) {
224
+ this.parentElement.entity.addChild(this.entity);
225
+ }
226
+ else {
227
+ app.root.addChild(this.entity);
228
+ }
229
+ // Initialize from attributes
230
+ const nameAttr = this.getAttribute('name');
231
+ const positionAttr = this.getAttribute('position');
232
+ const rotationAttr = this.getAttribute('rotation');
233
+ const scaleAttr = this.getAttribute('scale');
234
+ const tagsAttr = this.getAttribute('tags');
235
+ if (nameAttr)
236
+ this.name = nameAttr;
237
+ if (positionAttr)
238
+ this.position = parseVec3(positionAttr);
239
+ if (rotationAttr)
240
+ this.rotation = parseVec3(rotationAttr);
241
+ if (scaleAttr)
242
+ this.scale = parseVec3(scaleAttr);
243
+ if (tagsAttr)
244
+ this.tags = tagsAttr.split(',').map(tag => tag.trim());
245
+ }
246
+ disconnectedCallback() {
247
+ if (this.entity) {
248
+ this.entity.destroy();
249
+ this.entity = null;
250
+ }
251
+ }
252
+ /**
253
+ * Sets the enabled state of the entity.
254
+ * @param value - Whether the entity is enabled.
255
+ */
256
+ set enabled(value) {
257
+ this._enabled = value;
258
+ if (this.entity) {
259
+ this.entity.enabled = value;
260
+ }
261
+ }
262
+ /**
263
+ * Gets the enabled state of the entity.
264
+ * @returns Whether the entity is enabled.
265
+ */
266
+ get enabled() {
267
+ return this._enabled;
268
+ }
269
+ /**
270
+ * Sets the name of the entity.
271
+ * @param value - The name of the entity.
272
+ */
273
+ set name(value) {
274
+ this._name = value;
275
+ if (this.entity) {
276
+ this.entity.name = value;
277
+ }
278
+ }
279
+ /**
280
+ * Gets the name of the entity.
281
+ * @returns The name of the entity.
282
+ */
283
+ get name() {
284
+ return this._name;
285
+ }
286
+ /**
287
+ * Sets the position of the entity.
288
+ * @param value - The position of the entity.
289
+ */
290
+ set position(value) {
291
+ this._position = value;
292
+ if (this.entity) {
293
+ this.entity.setLocalPosition(this._position);
294
+ }
295
+ }
296
+ /**
297
+ * Gets the position of the entity.
298
+ * @returns The position of the entity.
299
+ */
300
+ get position() {
301
+ return this._position;
302
+ }
303
+ /**
304
+ * Sets the rotation of the entity.
305
+ * @param value - The rotation of the entity.
306
+ */
307
+ set rotation(value) {
308
+ this._rotation = value;
309
+ if (this.entity) {
310
+ this.entity.setLocalEulerAngles(this._rotation);
311
+ }
312
+ }
313
+ /**
314
+ * Gets the rotation of the entity.
315
+ * @returns The rotation of the entity.
316
+ */
317
+ get rotation() {
318
+ return this._rotation;
319
+ }
320
+ /**
321
+ * Sets the scale of the entity.
322
+ * @param value - The scale of the entity.
323
+ */
324
+ set scale(value) {
325
+ this._scale = value;
326
+ if (this.entity) {
327
+ this.entity.setLocalScale(this._scale);
328
+ }
329
+ }
330
+ /**
331
+ * Gets the scale of the entity.
332
+ * @returns The scale of the entity.
333
+ */
334
+ get scale() {
335
+ return this._scale;
336
+ }
337
+ /**
338
+ * Sets the tags of the entity.
339
+ * @param value - The tags of the entity.
340
+ */
341
+ set tags(value) {
342
+ this._tags = value;
343
+ if (this.entity) {
344
+ this.entity.tags.clear();
345
+ this.entity.tags.add(this._tags);
346
+ }
347
+ }
348
+ /**
349
+ * Gets the tags of the entity.
350
+ * @returns The tags of the entity.
351
+ */
352
+ get tags() {
353
+ return this._tags;
354
+ }
355
+ static get observedAttributes() {
356
+ return ['enabled', 'name', 'position', 'rotation', 'scale', 'tags'];
357
+ }
358
+ attributeChangedCallback(name, _oldValue, newValue) {
359
+ switch (name) {
360
+ case 'enabled':
361
+ this.enabled = newValue !== 'false';
362
+ break;
363
+ case 'name':
364
+ this.name = newValue;
365
+ break;
366
+ case 'position':
367
+ this.position = parseVec3(newValue);
368
+ break;
369
+ case 'rotation':
370
+ this.rotation = parseVec3(newValue);
371
+ break;
372
+ case 'scale':
373
+ this.scale = parseVec3(newValue);
374
+ break;
375
+ case 'tags':
376
+ this.tags = newValue.split(',').map(tag => tag.trim());
377
+ break;
378
+ }
379
+ }
380
+ }
381
+ customElements.define('pc-entity', EntityElement);
382
+
383
+ const extToType = new Map([
384
+ ['bin', 'binary'],
385
+ ['css', 'css'],
386
+ ['frag', 'shader'],
387
+ ['glb', 'container'],
388
+ ['glsl', 'shader'],
389
+ ['html', 'html'],
390
+ ['jpg', 'texture'],
391
+ ['js', 'script'],
392
+ ['json', 'json'],
393
+ ['mp3', 'audio'],
394
+ ['mjs', 'script'],
395
+ ['ply', 'gsplat'],
396
+ ['png', 'texture'],
397
+ ['txt', 'text'],
398
+ ['vert', 'shader'],
399
+ ['webp', 'texture']
400
+ ]);
401
+ /**
402
+ * Loads an asset into the PlayCanvas engine.
403
+ */
404
+ class AssetElement extends HTMLElement {
405
+ constructor() {
406
+ super(...arguments);
407
+ this._preload = false;
408
+ /**
409
+ * The asset that is loaded.
410
+ */
411
+ this.asset = null;
412
+ }
413
+ async connectedCallback() {
414
+ }
415
+ disconnectedCallback() {
416
+ this.destroyAsset();
417
+ }
418
+ createAsset() {
419
+ var _a;
420
+ const id = this.getAttribute('id') || '';
421
+ const src = this.getAttribute('src') || '';
422
+ let type = this.getAttribute('type');
423
+ // If no type is specified, try to infer it from the file extension.
424
+ if (!type) {
425
+ const ext = src.split('.').pop();
426
+ type = (_a = extToType.get(ext || '')) !== null && _a !== void 0 ? _a : null;
427
+ }
428
+ if (!type) {
429
+ console.warn(`Unsupported asset type: ${src}`);
430
+ return;
431
+ }
432
+ this.asset = new Asset(id, type, { url: src });
433
+ this.asset.preload = this.preload;
434
+ }
435
+ destroyAsset() {
436
+ if (this.asset) {
437
+ this.asset.unload();
438
+ this.asset = null;
439
+ }
440
+ }
441
+ /**
442
+ * Sets the preload flag of the asset.
443
+ * @param value - The preload flag.
444
+ */
445
+ set preload(value) {
446
+ this._preload = value;
447
+ if (this.asset) {
448
+ this.asset.preload = value;
449
+ }
450
+ }
451
+ /**
452
+ * Gets the preload flag of the asset.
453
+ * @returns The preload flag.
454
+ */
455
+ get preload() {
456
+ return this._preload;
457
+ }
458
+ static get observedAttributes() {
459
+ return ['preload'];
460
+ }
461
+ attributeChangedCallback(name, _oldValue, _newValue) {
462
+ if (name === 'preload') {
463
+ this.preload = this.hasAttribute('preload');
464
+ }
465
+ }
466
+ }
467
+ customElements.define('pc-asset', AssetElement);
468
+
469
+ /**
470
+ * Represents a component in the PlayCanvas engine.
471
+ *
472
+ * @category Components
473
+ */
474
+ class ComponentElement extends HTMLElement {
475
+ /**
476
+ * Constructor for the ComponentElement.
477
+ * @param componentName - The name of the component.
478
+ */
479
+ constructor(componentName) {
480
+ super();
481
+ this._enabled = true;
482
+ this._component = null;
483
+ this._componentName = componentName;
484
+ }
485
+ // Method to be overridden by subclasses to provide initial component data
486
+ getInitialComponentData() {
487
+ return {};
488
+ }
489
+ async connectedCallback() {
490
+ const appElement = this.closest('pc-app');
491
+ if (!appElement) {
492
+ console.error(`${this.tagName.toLowerCase()} should be a descendant of pc-app`);
493
+ return;
494
+ }
495
+ await appElement.getApplication();
496
+ this.addComponent();
497
+ }
498
+ addComponent() {
499
+ // Access the parent pc-entity's 'entity' property
500
+ const entityElement = this.closest('pc-entity');
501
+ if (!entityElement) {
502
+ console.error(`${this.tagName.toLowerCase()} should be a child of pc-entity`);
503
+ return;
504
+ }
505
+ if (entityElement && entityElement.entity) {
506
+ // Add the component to the entity
507
+ this._component = entityElement.entity.addComponent(this._componentName, this.getInitialComponentData());
508
+ }
509
+ }
510
+ disconnectedCallback() {
511
+ // Remove the component when the element is disconnected
512
+ if (this.component && this.component.entity) {
513
+ this._component.entity.removeComponent(this._componentName);
514
+ this._component = null;
515
+ }
516
+ }
517
+ get component() {
518
+ return this._component;
519
+ }
520
+ /**
521
+ * Sets the enabled state of the component.
522
+ * @param value - The enabled state of the component.
523
+ */
524
+ set enabled(value) {
525
+ this._enabled = value;
526
+ if (this.component) {
527
+ this.component.enabled = value;
528
+ }
529
+ }
530
+ /**
531
+ * Gets the enabled state of the component.
532
+ * @returns The enabled state of the component.
533
+ */
534
+ get enabled() {
535
+ return this._enabled;
536
+ }
537
+ static get observedAttributes() {
538
+ return ['enabled'];
539
+ }
540
+ attributeChangedCallback(name, _oldValue, newValue) {
541
+ switch (name) {
542
+ case 'enabled':
543
+ this.enabled = newValue !== 'false';
544
+ break;
545
+ }
546
+ }
547
+ }
548
+
549
+ /**
550
+ * Represents a audio listener component in the PlayCanvas engine.
551
+ *
552
+ * @category Components
553
+ */
554
+ class ListenerComponentElement extends ComponentElement {
555
+ constructor() {
556
+ super('audiolistener');
557
+ }
558
+ /**
559
+ * Gets the audio listener component.
560
+ * @returns The audio listener component.
561
+ */
562
+ get component() {
563
+ return super.component;
564
+ }
565
+ }
566
+ customElements.define('pc-listener', ListenerComponentElement);
567
+
568
+ /**
569
+ * Represents a camera component in the PlayCanvas engine.
570
+ *
571
+ * @category Components
572
+ */
573
+ class CameraComponentElement extends ComponentElement {
574
+ /**
575
+ * Creates a new CameraComponentElement.
576
+ */
577
+ constructor() {
578
+ super('camera');
579
+ this._clearColor = new Color(1, 1, 1, 1);
580
+ this._farClip = 1000;
581
+ this._fov = 45;
582
+ this._nearClip = 0.1;
583
+ this._orthographic = false;
584
+ this._orthoHeight = 10;
585
+ }
586
+ getInitialComponentData() {
587
+ return {
588
+ clearColor: this._clearColor,
589
+ farClip: this._farClip,
590
+ fov: this._fov,
591
+ nearClip: this._nearClip,
592
+ projection: this._orthographic ? PROJECTION_ORTHOGRAPHIC : PROJECTION_PERSPECTIVE,
593
+ orthoHeight: this._orthoHeight
594
+ };
595
+ }
596
+ /**
597
+ * Gets the camera component.
598
+ * @returns The camera component.
599
+ */
600
+ get component() {
601
+ return super.component;
602
+ }
603
+ /**
604
+ * Sets the clear color of the camera.
605
+ * @param value - The clear color.
606
+ */
607
+ set clearColor(value) {
608
+ this._clearColor = value;
609
+ if (this.component) {
610
+ this.component.clearColor = value;
611
+ }
612
+ }
613
+ /**
614
+ * Gets the clear color of the camera.
615
+ * @returns The clear color.
616
+ */
617
+ get clearColor() {
618
+ return this._clearColor;
619
+ }
620
+ /**
621
+ * Sets the far clip distance of the camera.
622
+ * @param value - The far clip distance.
623
+ */
624
+ set farClip(value) {
625
+ this._farClip = value;
626
+ if (this.component) {
627
+ this.component.farClip = value;
628
+ }
629
+ }
630
+ /**
631
+ * Gets the far clip distance of the camera.
632
+ * @returns The far clip distance.
633
+ */
634
+ get farClip() {
635
+ return this._farClip;
636
+ }
637
+ /**
638
+ * Sets the field of view of the camera.
639
+ * @param value - The field of view.
640
+ */
641
+ set fov(value) {
642
+ this._fov = value;
643
+ if (this.component) {
644
+ this.component.fov = value;
645
+ }
646
+ }
647
+ /**
648
+ * Gets the field of view of the camera.
649
+ * @returns The field of view.
650
+ */
651
+ get fov() {
652
+ return this._fov;
653
+ }
654
+ /**
655
+ * Sets the near clip distance of the camera.
656
+ * @param value - The near clip distance.
657
+ */
658
+ set nearClip(value) {
659
+ this._nearClip = value;
660
+ if (this.component) {
661
+ this.component.nearClip = value;
662
+ }
663
+ }
664
+ /**
665
+ * Gets the near clip distance of the camera.
666
+ * @returns The near clip distance.
667
+ */
668
+ get nearClip() {
669
+ return this._nearClip;
670
+ }
671
+ /**
672
+ * Sets the orthographic projection of the camera.
673
+ * @param value - The orthographic projection.
674
+ */
675
+ set orthographic(value) {
676
+ this._orthographic = value;
677
+ if (this.component) {
678
+ this.component.projection = value ? PROJECTION_ORTHOGRAPHIC : PROJECTION_PERSPECTIVE;
679
+ }
680
+ }
681
+ /**
682
+ * Gets the orthographic projection of the camera.
683
+ * @returns The orthographic projection.
684
+ */
685
+ get orthographic() {
686
+ return this._orthographic;
687
+ }
688
+ /**
689
+ * Sets the orthographic height of the camera.
690
+ * @param value - The orthographic height.
691
+ */
692
+ set orthoHeight(value) {
693
+ this._orthoHeight = value;
694
+ if (this.component) {
695
+ this.component.orthoHeight = value;
696
+ }
697
+ }
698
+ /**
699
+ * Gets the orthographic height of the camera.
700
+ * @returns The orthographic height.
701
+ */
702
+ get orthoHeight() {
703
+ return this._orthoHeight;
704
+ }
705
+ static get observedAttributes() {
706
+ return [...super.observedAttributes, 'clear-color', 'near-clip', 'far-clip', 'fov', 'orthographic', 'ortho-height'];
707
+ }
708
+ attributeChangedCallback(name, _oldValue, newValue) {
709
+ super.attributeChangedCallback(name, _oldValue, newValue);
710
+ switch (name) {
711
+ case 'clear-color':
712
+ this.clearColor = parseColor(newValue);
713
+ break;
714
+ case 'far-clip':
715
+ this.farClip = parseFloat(newValue);
716
+ break;
717
+ case 'fov':
718
+ this.fov = parseFloat(newValue);
719
+ break;
720
+ case 'near-clip':
721
+ this.nearClip = parseFloat(newValue);
722
+ break;
723
+ case 'orthographic':
724
+ this.orthographic = this.hasAttribute('orthographic');
725
+ break;
726
+ case 'ortho-height':
727
+ this.orthoHeight = parseFloat(newValue);
728
+ break;
729
+ }
730
+ }
731
+ }
732
+ customElements.define('pc-camera', CameraComponentElement);
733
+
734
+ /**
735
+ * Represents a collision component in the PlayCanvas engine.
736
+ *
737
+ * @category Components
738
+ */
739
+ class CollisionComponentElement extends ComponentElement {
740
+ /**
741
+ * Creates a new CollisionComponentElement.
742
+ */
743
+ constructor() {
744
+ super('collision');
745
+ this._axis = 1;
746
+ this._convexHull = false;
747
+ this._halfExtents = new Vec3(0.5, 0.5, 0.5);
748
+ this._height = 2;
749
+ this._radius = 0.5;
750
+ this._type = 'box';
751
+ }
752
+ getInitialComponentData() {
753
+ return {
754
+ axis: this._axis,
755
+ convexHull: this._convexHull,
756
+ halfExtents: this._halfExtents,
757
+ height: this._height,
758
+ radius: this._radius,
759
+ type: this._type
760
+ };
761
+ }
762
+ /**
763
+ * Gets the collision component.
764
+ * @returns The collision component.
765
+ */
766
+ get component() {
767
+ return super.component;
768
+ }
769
+ set axis(value) {
770
+ this._axis = value;
771
+ if (this.component) {
772
+ this.component.axis = value;
773
+ }
774
+ }
775
+ get axis() {
776
+ return this._axis;
777
+ }
778
+ set convexHull(value) {
779
+ this._convexHull = value;
780
+ if (this.component) {
781
+ this.component.convexHull = value;
782
+ }
783
+ }
784
+ get convexHull() {
785
+ return this._convexHull;
786
+ }
787
+ set halfExtents(value) {
788
+ this._halfExtents = value;
789
+ if (this.component) {
790
+ this.component.halfExtents = value;
791
+ }
792
+ }
793
+ get halfExtents() {
794
+ return this._halfExtents;
795
+ }
796
+ set height(value) {
797
+ this._height = value;
798
+ if (this.component) {
799
+ this.component.height = value;
800
+ }
801
+ }
802
+ get height() {
803
+ return this._height;
804
+ }
805
+ set radius(value) {
806
+ this._radius = value;
807
+ if (this.component) {
808
+ this.component.radius = value;
809
+ }
810
+ }
811
+ get radius() {
812
+ return this._radius;
813
+ }
814
+ set type(value) {
815
+ this._type = value;
816
+ if (this.component) {
817
+ this.component.type = value;
818
+ }
819
+ }
820
+ get type() {
821
+ return this._type;
822
+ }
823
+ static get observedAttributes() {
824
+ return [...super.observedAttributes, 'axis', 'convex-hull', 'half-extents', 'height', 'radius', 'type'];
825
+ }
826
+ attributeChangedCallback(name, _oldValue, newValue) {
827
+ super.attributeChangedCallback(name, _oldValue, newValue);
828
+ switch (name) {
829
+ case 'axis':
830
+ this.axis = parseInt(newValue, 10);
831
+ break;
832
+ case 'convex-hull':
833
+ this.convexHull = this.hasAttribute('convex-hull');
834
+ break;
835
+ case 'half-extents':
836
+ this.halfExtents = parseVec3(newValue);
837
+ break;
838
+ case 'height':
839
+ this.height = parseFloat(newValue);
840
+ break;
841
+ case 'radius':
842
+ this.radius = parseFloat(newValue);
843
+ break;
844
+ case 'type':
845
+ this.type = newValue;
846
+ break;
847
+ }
848
+ }
849
+ }
850
+ customElements.define('pc-collision', CollisionComponentElement);
851
+
852
+ /**
853
+ * Represents an element component in the PlayCanvas engine.
854
+ *
855
+ * @category Components
856
+ */
857
+ class ElementComponentElement extends ComponentElement {
858
+ constructor() {
859
+ super('element');
860
+ this._anchor = new Vec4(0.5, 0.5, 0.5, 0.5);
861
+ this._asset = '';
862
+ this._autoWidth = true;
863
+ this._color = new Color(1, 1, 1, 1);
864
+ this._fontSize = 32;
865
+ this._lineHeight = 32;
866
+ this._pivot = new Vec2(0.5, 0.5);
867
+ this._text = '';
868
+ this._type = 'group';
869
+ this._width = 0;
870
+ this._wrapLines = false;
871
+ }
872
+ async connectedCallback() {
873
+ await super.connectedCallback();
874
+ this.component._text._material.useFog = true;
875
+ }
876
+ getAsset() {
877
+ const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
878
+ return assetElement.asset;
879
+ }
880
+ getInitialComponentData() {
881
+ return {
882
+ anchor: this._anchor,
883
+ autoWidth: this._autoWidth,
884
+ color: this._color,
885
+ fontAsset: this.getAsset().id,
886
+ fontSize: this._fontSize,
887
+ lineHeight: this._lineHeight,
888
+ pivot: this._pivot,
889
+ type: this._type,
890
+ text: this._text,
891
+ width: this._width,
892
+ wrapLines: this._wrapLines
893
+ };
894
+ }
895
+ /**
896
+ * Gets the element component.
897
+ * @returns The element component.
898
+ */
899
+ get component() {
900
+ return super.component;
901
+ }
902
+ set anchor(value) {
903
+ this._anchor = value;
904
+ if (this.component) {
905
+ this.component.anchor = value;
906
+ }
907
+ }
908
+ get anchor() {
909
+ return this._anchor;
910
+ }
911
+ set asset(value) {
912
+ this._asset = value;
913
+ const asset = this.getAsset();
914
+ if (this.component && asset) {
915
+ this.component.fontAsset = asset.id;
916
+ }
917
+ }
918
+ get asset() {
919
+ return this._asset;
920
+ }
921
+ set autoWidth(value) {
922
+ this._autoWidth = value;
923
+ if (this.component) {
924
+ this.component.autoWidth = value;
925
+ }
926
+ }
927
+ get autoWidth() {
928
+ return this._autoWidth;
929
+ }
930
+ set color(value) {
931
+ this._color = value;
932
+ if (this.component) {
933
+ this.component.color = value;
934
+ }
935
+ }
936
+ get color() {
937
+ return this._color;
938
+ }
939
+ set fontSize(value) {
940
+ this._fontSize = value;
941
+ if (this.component) {
942
+ this.component.fontSize = value;
943
+ }
944
+ }
945
+ get fontSize() {
946
+ return this._fontSize;
947
+ }
948
+ set lineHeight(value) {
949
+ this._lineHeight = value;
950
+ if (this.component) {
951
+ this.component.lineHeight = value;
952
+ }
953
+ }
954
+ get lineHeight() {
955
+ return this._lineHeight;
956
+ }
957
+ set pivot(value) {
958
+ this._pivot = value;
959
+ if (this.component) {
960
+ this.component.pivot = value;
961
+ }
962
+ }
963
+ get pivot() {
964
+ return this._pivot;
965
+ }
966
+ set text(value) {
967
+ this._text = value;
968
+ if (this.component) {
969
+ this.component.text = value;
970
+ }
971
+ }
972
+ get text() {
973
+ return this._text;
974
+ }
975
+ /**
976
+ * Sets the type of the element component.
977
+ * @param value - The type.
978
+ */
979
+ set type(value) {
980
+ this._type = value;
981
+ if (this.component) {
982
+ this.component.type = value;
983
+ }
984
+ }
985
+ /**
986
+ * Gets the type of the element component.
987
+ * @returns The type.
988
+ */
989
+ get type() {
990
+ return this._type;
991
+ }
992
+ set width(value) {
993
+ this._width = value;
994
+ if (this.component) {
995
+ this.component.width = value;
996
+ }
997
+ }
998
+ get width() {
999
+ return this._width;
1000
+ }
1001
+ set wrapLines(value) {
1002
+ this._wrapLines = value;
1003
+ if (this.component) {
1004
+ this.component.wrapLines = value;
1005
+ }
1006
+ }
1007
+ get wrapLines() {
1008
+ return this._wrapLines;
1009
+ }
1010
+ static get observedAttributes() {
1011
+ return [...super.observedAttributes, 'anchor', 'asset', 'auto-width', 'color', 'font-size', 'line-height', 'pivot', 'text', 'type', 'width', 'wrap-lines'];
1012
+ }
1013
+ attributeChangedCallback(name, _oldValue, newValue) {
1014
+ super.attributeChangedCallback(name, _oldValue, newValue);
1015
+ switch (name) {
1016
+ case 'anchor':
1017
+ this.anchor = parseVec4(newValue);
1018
+ break;
1019
+ case 'asset':
1020
+ this.asset = newValue;
1021
+ break;
1022
+ case 'auto-width':
1023
+ this.autoWidth = newValue !== 'false';
1024
+ break;
1025
+ case 'color':
1026
+ this.color = parseColor(newValue);
1027
+ break;
1028
+ case 'font-size':
1029
+ this.fontSize = Number(newValue);
1030
+ break;
1031
+ case 'line-height':
1032
+ this.lineHeight = Number(newValue);
1033
+ break;
1034
+ case 'pivot':
1035
+ this.pivot = parseVec2(newValue);
1036
+ break;
1037
+ case 'text':
1038
+ this.text = newValue;
1039
+ break;
1040
+ case 'type':
1041
+ this.type = newValue;
1042
+ break;
1043
+ case 'width':
1044
+ this.width = Number(newValue);
1045
+ break;
1046
+ case 'wrap-lines':
1047
+ this.wrapLines = this.hasAttribute(name);
1048
+ break;
1049
+ }
1050
+ }
1051
+ }
1052
+ customElements.define('pc-element', ElementComponentElement);
1053
+
1054
+ /**
1055
+ * Represents a gsplat component in the PlayCanvas engine.
1056
+ *
1057
+ * @category Components
1058
+ */
1059
+ class GSplatComponentElement extends ComponentElement {
1060
+ constructor() {
1061
+ super('gsplat');
1062
+ this._asset = '';
1063
+ }
1064
+ getAsset() {
1065
+ const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
1066
+ return assetElement.asset;
1067
+ }
1068
+ getInitialComponentData() {
1069
+ return {
1070
+ asset: this.getAsset()
1071
+ };
1072
+ }
1073
+ /**
1074
+ * Gets the gsplat component.
1075
+ * @returns The gsplat component.
1076
+ */
1077
+ get component() {
1078
+ return super.component;
1079
+ }
1080
+ set asset(value) {
1081
+ this._asset = value;
1082
+ const asset = this.getAsset();
1083
+ if (this.component && asset) {
1084
+ this.component.asset = asset;
1085
+ }
1086
+ }
1087
+ get asset() {
1088
+ return this._asset;
1089
+ }
1090
+ static get observedAttributes() {
1091
+ return [...super.observedAttributes, 'asset'];
1092
+ }
1093
+ attributeChangedCallback(name, _oldValue, newValue) {
1094
+ super.attributeChangedCallback(name, _oldValue, newValue);
1095
+ switch (name) {
1096
+ case 'asset':
1097
+ this.asset = newValue;
1098
+ break;
1099
+ }
1100
+ }
1101
+ }
1102
+ customElements.define('pc-gsplat', GSplatComponentElement);
1103
+
1104
+ /**
1105
+ * Represents a light component in the PlayCanvas engine.
1106
+ *
1107
+ * @category Components
1108
+ */
1109
+ class LightComponentElement extends ComponentElement {
1110
+ /**
1111
+ * Creates a new LightComponentElement.
1112
+ */
1113
+ constructor() {
1114
+ super('light');
1115
+ this._castShadows = false;
1116
+ this._color = new Color(1, 1, 1);
1117
+ this._innerConeAngle = 40;
1118
+ this._intensity = 1;
1119
+ this._normalOffsetBias = 0.05;
1120
+ this._outerConeAngle = 45;
1121
+ this._range = 10;
1122
+ this._shadowBias = 0.2;
1123
+ this._shadowDistance = 16;
1124
+ this._type = 'directional';
1125
+ }
1126
+ getInitialComponentData() {
1127
+ return {
1128
+ castShadows: this._castShadows,
1129
+ color: this._color,
1130
+ innerConeAngle: this._innerConeAngle,
1131
+ intensity: this._intensity,
1132
+ normalOffsetBias: this._normalOffsetBias,
1133
+ outerConeAngle: this._outerConeAngle,
1134
+ range: this._range,
1135
+ shadowBias: this._shadowBias,
1136
+ shadowDistance: this._shadowDistance,
1137
+ type: this._type
1138
+ };
1139
+ }
1140
+ /**
1141
+ * Gets the light component.
1142
+ * @returns The light component.
1143
+ */
1144
+ get component() {
1145
+ return super.component;
1146
+ }
1147
+ /**
1148
+ * Sets the cast shadows flag of the light.
1149
+ * @param value - The cast shadows flag.
1150
+ */
1151
+ set castShadows(value) {
1152
+ this._castShadows = value;
1153
+ if (this.component) {
1154
+ this.component.castShadows = value;
1155
+ }
1156
+ }
1157
+ /**
1158
+ * Gets the cast shadows flag of the light.
1159
+ * @returns The cast shadows flag.
1160
+ */
1161
+ get castShadows() {
1162
+ return this._castShadows;
1163
+ }
1164
+ /**
1165
+ * Sets the color of the light.
1166
+ * @param value - The color.
1167
+ */
1168
+ set color(value) {
1169
+ this._color = value;
1170
+ if (this.component) {
1171
+ this.component.color = value;
1172
+ }
1173
+ }
1174
+ /**
1175
+ * Gets the color of the light.
1176
+ * @returns The color.
1177
+ */
1178
+ get color() {
1179
+ return this._color;
1180
+ }
1181
+ /**
1182
+ * Sets the inner cone angle of the light.
1183
+ * @param value - The inner cone angle.
1184
+ */
1185
+ set innerConeAngle(value) {
1186
+ this._innerConeAngle = value;
1187
+ if (this.component) {
1188
+ this.component.innerConeAngle = value;
1189
+ }
1190
+ }
1191
+ /**
1192
+ * Gets the inner cone angle of the light.
1193
+ * @returns The inner cone angle.
1194
+ */
1195
+ get innerConeAngle() {
1196
+ return this._innerConeAngle;
1197
+ }
1198
+ /**
1199
+ * Sets the intensity of the light.
1200
+ * @param value - The intensity.
1201
+ */
1202
+ set intensity(value) {
1203
+ this._intensity = value;
1204
+ if (this.component) {
1205
+ this.component.intensity = value;
1206
+ }
1207
+ }
1208
+ /**
1209
+ * Gets the intensity of the light.
1210
+ * @returns The intensity.
1211
+ */
1212
+ get intensity() {
1213
+ return this._intensity;
1214
+ }
1215
+ /**
1216
+ * Sets the normal offset bias of the light.
1217
+ * @param value - The normal offset bias.
1218
+ */
1219
+ set normalOffsetBias(value) {
1220
+ this._normalOffsetBias = value;
1221
+ if (this.component) {
1222
+ this.component.normalOffsetBias = value;
1223
+ }
1224
+ }
1225
+ /**
1226
+ * Gets the normal offset bias of the light.
1227
+ * @returns The normal offset bias.
1228
+ */
1229
+ get normalOffsetBias() {
1230
+ return this._normalOffsetBias;
1231
+ }
1232
+ /**
1233
+ * Sets the outer cone angle of the light.
1234
+ * @param value - The outer cone angle.
1235
+ */
1236
+ set outerConeAngle(value) {
1237
+ this._outerConeAngle = value;
1238
+ if (this.component) {
1239
+ this.component.outerConeAngle = value;
1240
+ }
1241
+ }
1242
+ /**
1243
+ * Gets the outer cone angle of the light.
1244
+ * @returns The outer cone angle.
1245
+ */
1246
+ get outerConeAngle() {
1247
+ return this._outerConeAngle;
1248
+ }
1249
+ /**
1250
+ * Sets the range of the light.
1251
+ * @param value - The range.
1252
+ */
1253
+ set range(value) {
1254
+ this._range = value;
1255
+ if (this.component) {
1256
+ this.component.range = value;
1257
+ }
1258
+ }
1259
+ /**
1260
+ * Gets the range of the light.
1261
+ * @returns The range.
1262
+ */
1263
+ get range() {
1264
+ return this._range;
1265
+ }
1266
+ /**
1267
+ * Sets the shadow bias of the light.
1268
+ * @param value - The shadow bias.
1269
+ */
1270
+ set shadowBias(value) {
1271
+ this._shadowBias = value;
1272
+ if (this.component) {
1273
+ this.component.shadowBias = value;
1274
+ }
1275
+ }
1276
+ /**
1277
+ * Gets the shadow bias of the light.
1278
+ * @returns The shadow bias.
1279
+ */
1280
+ get shadowBias() {
1281
+ return this._shadowBias;
1282
+ }
1283
+ /**
1284
+ * Sets the shadow distance of the light.
1285
+ * @param value - The shadow distance.
1286
+ */
1287
+ set shadowDistance(value) {
1288
+ this._shadowDistance = value;
1289
+ if (this.component) {
1290
+ this.component.shadowDistance = value;
1291
+ }
1292
+ }
1293
+ /**
1294
+ * Gets the shadow distance of the light.
1295
+ * @returns The shadow distance.
1296
+ */
1297
+ get shadowDistance() {
1298
+ return this._shadowDistance;
1299
+ }
1300
+ /**
1301
+ * Sets the type of the light.
1302
+ * @param value - The type.
1303
+ */
1304
+ set type(value) {
1305
+ if (!['directional', 'omni', 'spot'].includes(value)) {
1306
+ console.warn(`Invalid light type '${value}', using default type '${this._type}'.`);
1307
+ return;
1308
+ }
1309
+ this._type = value;
1310
+ if (this.component) {
1311
+ this.component.type = value;
1312
+ }
1313
+ }
1314
+ /**
1315
+ * Gets the type of the light.
1316
+ * @returns The type.
1317
+ */
1318
+ get type() {
1319
+ return this._type;
1320
+ }
1321
+ static get observedAttributes() {
1322
+ return [
1323
+ ...super.observedAttributes,
1324
+ 'color',
1325
+ 'cast-shadows',
1326
+ 'intensity',
1327
+ 'inner-cone-angle',
1328
+ 'normal-offset-bias',
1329
+ 'outer-cone-angle',
1330
+ 'range',
1331
+ 'shadow-bias',
1332
+ 'shadow-distance',
1333
+ 'type'
1334
+ ];
1335
+ }
1336
+ attributeChangedCallback(name, _oldValue, newValue) {
1337
+ super.attributeChangedCallback(name, _oldValue, newValue);
1338
+ switch (name) {
1339
+ case 'color':
1340
+ this.color = parseColor(newValue);
1341
+ break;
1342
+ case 'cast-shadows':
1343
+ this.castShadows = this.hasAttribute('cast-shadows');
1344
+ break;
1345
+ case 'inner-cone-angle':
1346
+ this.innerConeAngle = Number(newValue);
1347
+ break;
1348
+ case 'intensity':
1349
+ this.intensity = Number(newValue);
1350
+ break;
1351
+ case 'normal-offset-bias':
1352
+ this.normalOffsetBias = Number(newValue);
1353
+ break;
1354
+ case 'outer-cone-angle':
1355
+ this.outerConeAngle = Number(newValue);
1356
+ break;
1357
+ case 'range':
1358
+ this.range = Number(newValue);
1359
+ break;
1360
+ case 'shadow-bias':
1361
+ this.shadowBias = Number(newValue);
1362
+ break;
1363
+ case 'shadow-distance':
1364
+ this.shadowDistance = Number(newValue);
1365
+ break;
1366
+ case 'type':
1367
+ this.type = newValue;
1368
+ break;
1369
+ }
1370
+ }
1371
+ }
1372
+ customElements.define('pc-light', LightComponentElement);
1373
+
1374
+ /**
1375
+ * Represents a render component in the PlayCanvas engine.
1376
+ *
1377
+ * @category Components
1378
+ */
1379
+ class RenderComponentElement extends ComponentElement {
1380
+ constructor() {
1381
+ super('render');
1382
+ this._type = 'asset';
1383
+ this._castShadows = true;
1384
+ this._receiveShadows = true;
1385
+ }
1386
+ getInitialComponentData() {
1387
+ return {
1388
+ type: this._type,
1389
+ castShadows: this._castShadows,
1390
+ receiveShadows: this._receiveShadows
1391
+ };
1392
+ }
1393
+ /**
1394
+ * Gets the render component.
1395
+ * @returns The render component.
1396
+ */
1397
+ get component() {
1398
+ return super.component;
1399
+ }
1400
+ /**
1401
+ * Sets the type of the render component.
1402
+ * @param value - The type.
1403
+ */
1404
+ set type(value) {
1405
+ this._type = value;
1406
+ if (this.component) {
1407
+ this.component.type = value;
1408
+ }
1409
+ }
1410
+ /**
1411
+ * Gets the type of the render component.
1412
+ * @returns The type.
1413
+ */
1414
+ get type() {
1415
+ return this._type;
1416
+ }
1417
+ /**
1418
+ * Sets the cast shadows flag of the render component.
1419
+ * @param value - The cast shadows flag.
1420
+ */
1421
+ set castShadows(value) {
1422
+ this._castShadows = value;
1423
+ if (this.component) {
1424
+ this.component.castShadows = value;
1425
+ }
1426
+ }
1427
+ /**
1428
+ * Gets the cast shadows flag of the render component.
1429
+ * @returns The cast shadows flag.
1430
+ */
1431
+ get castShadows() {
1432
+ return this._castShadows;
1433
+ }
1434
+ /**
1435
+ * Sets the receive shadows flag of the render component.
1436
+ * @param value - The receive shadows flag.
1437
+ */
1438
+ set receiveShadows(value) {
1439
+ this._receiveShadows = value;
1440
+ if (this.component) {
1441
+ this.component.receiveShadows = value;
1442
+ }
1443
+ }
1444
+ /**
1445
+ * Gets the receive shadows flag of the render component.
1446
+ * @returns The receive shadows flag.
1447
+ */
1448
+ get receiveShadows() {
1449
+ return this._receiveShadows;
1450
+ }
1451
+ static get observedAttributes() {
1452
+ return [...super.observedAttributes, 'cast-shadows', 'receive-shadows', 'type'];
1453
+ }
1454
+ attributeChangedCallback(name, _oldValue, newValue) {
1455
+ super.attributeChangedCallback(name, _oldValue, newValue);
1456
+ switch (name) {
1457
+ case 'type':
1458
+ this.type = newValue;
1459
+ break;
1460
+ case 'cast-shadows':
1461
+ this.castShadows = newValue !== 'false';
1462
+ break;
1463
+ case 'receive-shadows':
1464
+ this.receiveShadows = newValue !== 'false';
1465
+ break;
1466
+ }
1467
+ }
1468
+ }
1469
+ customElements.define('pc-render', RenderComponentElement);
1470
+
1471
+ /**
1472
+ * Represents a rigidbody component in the PlayCanvas engine.
1473
+ *
1474
+ * @category Components
1475
+ */
1476
+ class RigidBodyComponentElement extends ComponentElement {
1477
+ /**
1478
+ * Creates a new RigidBodyComponentElement.
1479
+ */
1480
+ constructor() {
1481
+ super('rigidbody');
1482
+ /**
1483
+ * The angular damping of the rigidbody.
1484
+ */
1485
+ this._angularDamping = 0;
1486
+ /**
1487
+ * The angular factor of the rigidbody.
1488
+ */
1489
+ this._angularFactor = new Vec3(1, 1, 1);
1490
+ /**
1491
+ * The friction of the rigidbody.
1492
+ */
1493
+ this._friction = 0.5;
1494
+ /**
1495
+ * The linear damping of the rigidbody.
1496
+ */
1497
+ this._linearDamping = 0;
1498
+ /**
1499
+ * The linear factor of the rigidbody.
1500
+ */
1501
+ this._linearFactor = new Vec3(1, 1, 1);
1502
+ /**
1503
+ * The mass of the rigidbody.
1504
+ */
1505
+ this._mass = 1;
1506
+ /**
1507
+ * The restitution of the rigidbody.
1508
+ */
1509
+ this._restitution = 0;
1510
+ /**
1511
+ * The rolling friction of the rigidbody.
1512
+ */
1513
+ this._rollingFriction = 0;
1514
+ /**
1515
+ * The type of the rigidbody.
1516
+ */
1517
+ this._type = 'static';
1518
+ }
1519
+ getInitialComponentData() {
1520
+ return {
1521
+ angularDamping: this._angularDamping,
1522
+ angularFactor: this._angularFactor,
1523
+ friction: this._friction,
1524
+ linearDamping: this._linearDamping,
1525
+ linearFactor: this._linearFactor,
1526
+ mass: this._mass,
1527
+ restitution: this._restitution,
1528
+ rollingFriction: this._rollingFriction,
1529
+ type: this._type
1530
+ };
1531
+ }
1532
+ /**
1533
+ * Gets the collision component.
1534
+ * @returns The collision component.
1535
+ */
1536
+ get component() {
1537
+ return super.component;
1538
+ }
1539
+ set angularDamping(value) {
1540
+ this._angularDamping = value;
1541
+ if (this.component) {
1542
+ this.component.angularDamping = value;
1543
+ }
1544
+ }
1545
+ get angularDamping() {
1546
+ return this._angularDamping;
1547
+ }
1548
+ set angularFactor(value) {
1549
+ this._angularFactor = value;
1550
+ if (this.component) {
1551
+ this.component.angularFactor = value;
1552
+ }
1553
+ }
1554
+ get angularFactor() {
1555
+ return this._angularFactor;
1556
+ }
1557
+ set friction(value) {
1558
+ this._friction = value;
1559
+ if (this.component) {
1560
+ this.component.friction = value;
1561
+ }
1562
+ }
1563
+ get friction() {
1564
+ return this._friction;
1565
+ }
1566
+ set linearDamping(value) {
1567
+ this._linearDamping = value;
1568
+ if (this.component) {
1569
+ this.component.linearDamping = value;
1570
+ }
1571
+ }
1572
+ get linearDamping() {
1573
+ return this._linearDamping;
1574
+ }
1575
+ set linearFactor(value) {
1576
+ this._linearFactor = value;
1577
+ if (this.component) {
1578
+ this.component.linearFactor = value;
1579
+ }
1580
+ }
1581
+ get linearFactor() {
1582
+ return this._linearFactor;
1583
+ }
1584
+ set mass(value) {
1585
+ this._mass = value;
1586
+ if (this.component) {
1587
+ this.component.mass = value;
1588
+ }
1589
+ }
1590
+ get mass() {
1591
+ return this._mass;
1592
+ }
1593
+ set restitution(value) {
1594
+ this._restitution = value;
1595
+ if (this.component) {
1596
+ this.component.restitution = value;
1597
+ }
1598
+ }
1599
+ get restitution() {
1600
+ return this._restitution;
1601
+ }
1602
+ set rollingFriction(value) {
1603
+ this._rollingFriction = value;
1604
+ if (this.component) {
1605
+ this.component.rollingFriction = value;
1606
+ }
1607
+ }
1608
+ get rollingFriction() {
1609
+ return this._rollingFriction;
1610
+ }
1611
+ set type(value) {
1612
+ this._type = value;
1613
+ if (this.component) {
1614
+ this.component.type = value;
1615
+ }
1616
+ }
1617
+ get type() {
1618
+ return this._type;
1619
+ }
1620
+ static get observedAttributes() {
1621
+ return [...super.observedAttributes, 'angular-damping', 'angular-factor', 'friction', 'linear-damping', 'linear-factor', 'mass', 'restitution', 'rolling-friction', 'type'];
1622
+ }
1623
+ attributeChangedCallback(name, _oldValue, newValue) {
1624
+ super.attributeChangedCallback(name, _oldValue, newValue);
1625
+ switch (name) {
1626
+ case 'angular-damping':
1627
+ this.angularDamping = parseFloat(newValue);
1628
+ break;
1629
+ case 'angular-factor':
1630
+ this.angularFactor = parseVec3(newValue);
1631
+ break;
1632
+ case 'friction':
1633
+ this.friction = parseFloat(newValue);
1634
+ break;
1635
+ case 'linear-damping':
1636
+ this.linearDamping = parseFloat(newValue);
1637
+ break;
1638
+ case 'linear-factor':
1639
+ this.linearFactor = parseVec3(newValue);
1640
+ break;
1641
+ case 'mass':
1642
+ this.mass = parseFloat(newValue);
1643
+ break;
1644
+ case 'restitution':
1645
+ this.restitution = parseFloat(newValue);
1646
+ break;
1647
+ case 'rolling-friction':
1648
+ this.rollingFriction = parseFloat(newValue);
1649
+ break;
1650
+ case 'type':
1651
+ this.type = newValue;
1652
+ break;
1653
+ }
1654
+ }
1655
+ }
1656
+ customElements.define('pc-rigidbody', RigidBodyComponentElement);
1657
+
1658
+ /**
1659
+ * Represents a script component in the PlayCanvas engine.
1660
+ *
1661
+ * @category Components
1662
+ */
1663
+ class ScriptComponentElement extends ComponentElement {
1664
+ constructor() {
1665
+ super('script');
1666
+ }
1667
+ /**
1668
+ * Gets the script component.
1669
+ * @returns The script component.
1670
+ */
1671
+ get component() {
1672
+ return super.component;
1673
+ }
1674
+ }
1675
+ customElements.define('pc-scripts', ScriptComponentElement);
1676
+
1677
+ /**
1678
+ * Represents a script in the PlayCanvas engine.
1679
+ */
1680
+ class ScriptElement extends HTMLElement {
1681
+ constructor() {
1682
+ super(...arguments);
1683
+ this._attributes = {};
1684
+ this._enabled = true;
1685
+ this._name = '';
1686
+ this._script = null;
1687
+ }
1688
+ async connectedCallback() {
1689
+ var _a, _b, _c;
1690
+ const appElement = this.closest('pc-app');
1691
+ if (!appElement) {
1692
+ console.error(`${this.tagName.toLowerCase()} should be a descendant of pc-app`);
1693
+ return;
1694
+ }
1695
+ await appElement.getApplication();
1696
+ const scriptAttributes = this.getAttribute('attributes');
1697
+ if (scriptAttributes) {
1698
+ try {
1699
+ this._attributes = JSON.parse(scriptAttributes);
1700
+ }
1701
+ catch (e) {
1702
+ console.error('Failed to parse script attributes:', e);
1703
+ }
1704
+ }
1705
+ // When the script is created, initialize it with the necessary attributes
1706
+ (_a = this.scriptsElement) === null || _a === void 0 ? void 0 : _a.component.on(`create:${this._name}`, (scriptInstance) => {
1707
+ Object.assign(scriptInstance, this._attributes);
1708
+ });
1709
+ this._script = (_c = (_b = this.scriptsElement) === null || _b === void 0 ? void 0 : _b.component.create(this._name, { preloading: false })) !== null && _c !== void 0 ? _c : null;
1710
+ }
1711
+ disconnectedCallback() {
1712
+ var _a;
1713
+ (_a = this.scriptsElement) === null || _a === void 0 ? void 0 : _a.component.destroy(this._name);
1714
+ }
1715
+ refreshAttributes() {
1716
+ if (this._script) {
1717
+ Object.entries(this._attributes).forEach(([name, value]) => {
1718
+ if (this._script && name in this._script) {
1719
+ this._script[name] = value;
1720
+ }
1721
+ });
1722
+ }
1723
+ }
1724
+ get scriptsElement() {
1725
+ const scriptsElement = this.parentElement;
1726
+ if (!(scriptsElement instanceof ScriptComponentElement)) {
1727
+ console.warn('pc-script must be a direct child of a pc-scripts element');
1728
+ return null;
1729
+ }
1730
+ return scriptsElement;
1731
+ }
1732
+ set scriptAttributes(value) {
1733
+ this._attributes = JSON.parse(value);
1734
+ this.refreshAttributes();
1735
+ }
1736
+ get scriptAttributes() {
1737
+ return JSON.stringify(this._attributes);
1738
+ }
1739
+ set enabled(value) {
1740
+ this._enabled = value;
1741
+ if (this._script) {
1742
+ this._script.enabled = value;
1743
+ }
1744
+ }
1745
+ /**
1746
+ * Gets the enabled state of the script.
1747
+ * @returns The enabled state of the script.
1748
+ */
1749
+ get enabled() {
1750
+ return this._enabled;
1751
+ }
1752
+ /**
1753
+ * Sets the name of the script to create.
1754
+ * @param value - The name.
1755
+ */
1756
+ set name(value) {
1757
+ this._name = value;
1758
+ }
1759
+ /**
1760
+ * Gets the name of the script.
1761
+ * @returns The name.
1762
+ */
1763
+ get name() {
1764
+ return this._name;
1765
+ }
1766
+ static get observedAttributes() {
1767
+ return ['attributes', 'enabled', 'name'];
1768
+ }
1769
+ attributeChangedCallback(name, _oldValue, newValue) {
1770
+ switch (name) {
1771
+ case 'attributes':
1772
+ this.scriptAttributes = newValue;
1773
+ break;
1774
+ case 'enabled':
1775
+ this.enabled = newValue !== 'false';
1776
+ break;
1777
+ case 'name':
1778
+ this.name = newValue;
1779
+ break;
1780
+ }
1781
+ }
1782
+ }
1783
+ customElements.define('pc-script', ScriptElement);
1784
+
1785
+ /**
1786
+ * Represents a sound component in the PlayCanvas engine.
1787
+ *
1788
+ * @category Components
1789
+ */
1790
+ class SoundComponentElement extends ComponentElement {
1791
+ constructor() {
1792
+ super('sound');
1793
+ this._pitch = 1;
1794
+ this._positional = false;
1795
+ this._volume = 1;
1796
+ }
1797
+ getInitialComponentData() {
1798
+ return {
1799
+ pitch: this._pitch,
1800
+ positional: this._positional,
1801
+ volume: this._volume
1802
+ };
1803
+ }
1804
+ /**
1805
+ * Gets the sound component.
1806
+ * @returns The sound component.
1807
+ */
1808
+ get component() {
1809
+ return super.component;
1810
+ }
1811
+ /**
1812
+ * Sets the pitch of the sound.
1813
+ * @param value - The pitch.
1814
+ */
1815
+ set pitch(value) {
1816
+ this._pitch = value;
1817
+ if (this.component) {
1818
+ this.component.pitch = value;
1819
+ }
1820
+ }
1821
+ /**
1822
+ * Gets the pitch of the sound.
1823
+ * @returns The pitch.
1824
+ */
1825
+ get pitch() {
1826
+ return this._pitch;
1827
+ }
1828
+ /**
1829
+ * Sets the positional flag of the sound.
1830
+ * @param value - The positional flag.
1831
+ */
1832
+ set positional(value) {
1833
+ this._positional = value;
1834
+ if (this.component) {
1835
+ this.component.positional = value;
1836
+ }
1837
+ }
1838
+ /**
1839
+ * Gets the positional flag of the sound.
1840
+ * @returns The positional flag.
1841
+ */
1842
+ get positional() {
1843
+ return this._positional;
1844
+ }
1845
+ /**
1846
+ * Sets the volume of the sound.
1847
+ * @param value - The volume.
1848
+ */
1849
+ set volume(value) {
1850
+ this._volume = value;
1851
+ if (this.component) {
1852
+ this.component.volume = value;
1853
+ }
1854
+ }
1855
+ /**
1856
+ * Gets the volume of the sound.
1857
+ * @returns The volume.
1858
+ */
1859
+ get volume() {
1860
+ return this._volume;
1861
+ }
1862
+ static get observedAttributes() {
1863
+ return [...super.observedAttributes, 'pitch', 'positional', 'volume'];
1864
+ }
1865
+ attributeChangedCallback(name, _oldValue, newValue) {
1866
+ super.attributeChangedCallback(name, _oldValue, newValue);
1867
+ switch (name) {
1868
+ case 'pitch':
1869
+ this.pitch = parseFloat(newValue);
1870
+ break;
1871
+ case 'positional':
1872
+ this.positional = this.hasAttribute('positional');
1873
+ break;
1874
+ case 'volume':
1875
+ this.volume = parseFloat(newValue);
1876
+ break;
1877
+ }
1878
+ }
1879
+ }
1880
+ customElements.define('pc-sound', SoundComponentElement);
1881
+
1882
+ /**
1883
+ * Represents a sound slot in the PlayCanvas engine.
1884
+ */
1885
+ class SoundSlotElement extends HTMLElement {
1886
+ constructor() {
1887
+ super(...arguments);
1888
+ this._asset = '';
1889
+ this._autoPlay = false;
1890
+ this._duration = null;
1891
+ this._loop = false;
1892
+ this._name = '';
1893
+ this._overlap = false;
1894
+ this._pitch = 1;
1895
+ this._startTime = 0;
1896
+ this._volume = 1;
1897
+ /**
1898
+ * The sound slot.
1899
+ */
1900
+ this.soundSlot = null;
1901
+ }
1902
+ getAsset() {
1903
+ const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
1904
+ return assetElement.asset;
1905
+ }
1906
+ async connectedCallback() {
1907
+ const appElement = this.closest('pc-app');
1908
+ if (!appElement) {
1909
+ console.error(`${this.tagName.toLowerCase()} should be a descendant of pc-app`);
1910
+ return;
1911
+ }
1912
+ await appElement.getApplication();
1913
+ const options = {
1914
+ autoPlay: this._autoPlay,
1915
+ loop: this._loop,
1916
+ overlap: this._overlap,
1917
+ pitch: this._pitch,
1918
+ startTime: this._startTime,
1919
+ volume: this._volume
1920
+ };
1921
+ if (this._duration) {
1922
+ options.duration = this._duration;
1923
+ }
1924
+ this.soundSlot = this.soundElement.component.addSlot(this._name, options);
1925
+ this.asset = this._asset;
1926
+ this.soundSlot.play();
1927
+ }
1928
+ disconnectedCallback() {
1929
+ this.soundElement.component.removeSlot(this._name);
1930
+ }
1931
+ get soundElement() {
1932
+ const soundElement = this.parentElement;
1933
+ if (!(soundElement instanceof SoundComponentElement)) {
1934
+ console.warn('pc-sound-slot must be a direct child of a pc-sound element');
1935
+ return null;
1936
+ }
1937
+ return soundElement;
1938
+ }
1939
+ /**
1940
+ * Sets the asset of the sound slot.
1941
+ * @param value - The asset.
1942
+ */
1943
+ set asset(value) {
1944
+ var _a;
1945
+ this._asset = value;
1946
+ if (this.soundSlot) {
1947
+ const id = (_a = this.getAsset()) === null || _a === void 0 ? void 0 : _a.id;
1948
+ if (id) {
1949
+ this.soundSlot.asset = id;
1950
+ }
1951
+ }
1952
+ }
1953
+ /**
1954
+ * Gets the asset of the sound slot.
1955
+ * @returns The asset.
1956
+ */
1957
+ get asset() {
1958
+ return this._asset;
1959
+ }
1960
+ /**
1961
+ * Sets the auto play flag of the sound slot.
1962
+ * @param value - The auto play flag.
1963
+ */
1964
+ set autoPlay(value) {
1965
+ this._autoPlay = value;
1966
+ if (this.soundSlot) {
1967
+ this.soundSlot.autoPlay = value;
1968
+ }
1969
+ }
1970
+ /**
1971
+ * Gets the auto play flag of the sound slot.
1972
+ * @returns The auto play flag.
1973
+ */
1974
+ get autoPlay() {
1975
+ return this._autoPlay;
1976
+ }
1977
+ /**
1978
+ * Sets the duration of the sound slot.
1979
+ * @param value - The duration.
1980
+ */
1981
+ set duration(value) {
1982
+ this._duration = value;
1983
+ if (this.soundSlot) {
1984
+ this.soundSlot.duration = value;
1985
+ }
1986
+ }
1987
+ /**
1988
+ * Gets the duration of the sound slot.
1989
+ * @returns The duration.
1990
+ */
1991
+ get duration() {
1992
+ return this._duration;
1993
+ }
1994
+ /**
1995
+ * Sets the loop flag of the sound slot.
1996
+ * @param value - The loop flag.
1997
+ */
1998
+ set loop(value) {
1999
+ this._loop = value;
2000
+ if (this.soundSlot) {
2001
+ this.soundSlot.loop = value;
2002
+ }
2003
+ }
2004
+ /**
2005
+ * Gets the loop flag of the sound slot.
2006
+ * @returns The loop flag.
2007
+ */
2008
+ get loop() {
2009
+ return this._loop;
2010
+ }
2011
+ /**
2012
+ * Sets the name of the sound slot.
2013
+ * @param value - The name.
2014
+ */
2015
+ set name(value) {
2016
+ this._name = value;
2017
+ if (this.soundSlot) {
2018
+ this.soundSlot.name = value;
2019
+ }
2020
+ }
2021
+ /**
2022
+ * Gets the name of the sound slot.
2023
+ * @returns The name.
2024
+ */
2025
+ get name() {
2026
+ return this._name;
2027
+ }
2028
+ /**
2029
+ * Sets the overlap flag of the sound slot.
2030
+ * @param value - The overlap flag.
2031
+ */
2032
+ set overlap(value) {
2033
+ this._overlap = value;
2034
+ if (this.soundSlot) {
2035
+ this.soundSlot.overlap = value;
2036
+ }
2037
+ }
2038
+ /**
2039
+ * Gets the overlap flag of the sound slot.
2040
+ * @returns The overlap flag.
2041
+ */
2042
+ get overlap() {
2043
+ return this._overlap;
2044
+ }
2045
+ /**
2046
+ * Sets the pitch of the sound slot.
2047
+ * @param value - The pitch.
2048
+ */
2049
+ set pitch(value) {
2050
+ this._pitch = value;
2051
+ if (this.soundSlot) {
2052
+ this.soundSlot.pitch = value;
2053
+ }
2054
+ }
2055
+ /**
2056
+ * Gets the pitch of the sound slot.
2057
+ * @returns The pitch.
2058
+ */
2059
+ get pitch() {
2060
+ return this._pitch;
2061
+ }
2062
+ /**
2063
+ * Sets the start time of the sound slot.
2064
+ * @param value - The start time.
2065
+ */
2066
+ set startTime(value) {
2067
+ this._startTime = value;
2068
+ if (this.soundSlot) {
2069
+ this.soundSlot.startTime = value;
2070
+ }
2071
+ }
2072
+ /**
2073
+ * Gets the start time of the sound slot.
2074
+ * @returns The start time.
2075
+ */
2076
+ get startTime() {
2077
+ return this._startTime;
2078
+ }
2079
+ /**
2080
+ * Sets the volume of the sound slot.
2081
+ * @param value - The volume.
2082
+ */
2083
+ set volume(value) {
2084
+ this._volume = value;
2085
+ if (this.soundSlot) {
2086
+ this.soundSlot.volume = value;
2087
+ }
2088
+ }
2089
+ /**
2090
+ * Gets the volume of the sound slot.
2091
+ * @returns The volume.
2092
+ */
2093
+ get volume() {
2094
+ return this._volume;
2095
+ }
2096
+ static get observedAttributes() {
2097
+ return ['asset', 'autoPlay', 'duration', 'loop', 'name', 'overlap', 'pitch', 'startTime', 'volume'];
2098
+ }
2099
+ attributeChangedCallback(name, _oldValue, newValue) {
2100
+ switch (name) {
2101
+ case 'asset':
2102
+ this.asset = newValue;
2103
+ break;
2104
+ case 'duration':
2105
+ this.duration = parseFloat(newValue);
2106
+ break;
2107
+ case 'loop':
2108
+ this.loop = this.hasAttribute('loop');
2109
+ break;
2110
+ case 'name':
2111
+ this.name = newValue;
2112
+ break;
2113
+ case 'overlap':
2114
+ this.overlap = this.hasAttribute('overlap');
2115
+ break;
2116
+ case 'pitch':
2117
+ this.pitch = parseFloat(newValue);
2118
+ break;
2119
+ case 'startTime':
2120
+ this.startTime = parseFloat(newValue);
2121
+ break;
2122
+ case 'volume':
2123
+ this.volume = parseFloat(newValue);
2124
+ break;
2125
+ }
2126
+ }
2127
+ }
2128
+ customElements.define('pc-sound-slot', SoundSlotElement);
2129
+
2130
+ /**
2131
+ * Represents a model in the PlayCanvas engine.
2132
+ */
2133
+ class ModelElement extends HTMLElement {
2134
+ constructor() {
2135
+ super(...arguments);
2136
+ this._asset = '';
2137
+ }
2138
+ async connectedCallback() {
2139
+ // Get the application
2140
+ const appElement = this.closest('pc-app');
2141
+ if (!appElement) {
2142
+ console.warn(`${this.tagName} must be a child of pc-app`);
2143
+ return;
2144
+ }
2145
+ await appElement.getApplication();
2146
+ const asset = this.getAttribute('asset');
2147
+ if (asset) {
2148
+ this.asset = asset;
2149
+ }
2150
+ }
2151
+ getAsset() {
2152
+ const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
2153
+ return assetElement.asset;
2154
+ }
2155
+ _loadModel() {
2156
+ const asset = this.getAsset();
2157
+ if (!asset) {
2158
+ return;
2159
+ }
2160
+ const entity = asset.resource.instantiateRenderEntity();
2161
+ const parentEntityElement = this.closest('pc-entity');
2162
+ if (parentEntityElement) {
2163
+ parentEntityElement.entity.addChild(entity);
2164
+ }
2165
+ else {
2166
+ const appElement = this.closest('pc-app');
2167
+ appElement.app.root.addChild(entity);
2168
+ }
2169
+ }
2170
+ /**
2171
+ * Sets the asset ID of the model.
2172
+ * @param value - The asset ID.
2173
+ */
2174
+ set asset(value) {
2175
+ this._asset = value;
2176
+ this._loadModel();
2177
+ }
2178
+ /**
2179
+ * Gets the source URL of the model.
2180
+ * @returns The source URL of the model.
2181
+ */
2182
+ get asset() {
2183
+ return this._asset;
2184
+ }
2185
+ static get observedAttributes() {
2186
+ return ['asset'];
2187
+ }
2188
+ attributeChangedCallback(name, _oldValue, newValue) {
2189
+ switch (name) {
2190
+ case 'asset':
2191
+ this.asset = newValue;
2192
+ break;
2193
+ }
2194
+ }
2195
+ }
2196
+ customElements.define('pc-model', ModelElement);
2197
+
2198
+ /**
2199
+ * Represents a scene in the PlayCanvas engine.
2200
+ */
2201
+ class SceneElement extends HTMLElement {
2202
+ constructor() {
2203
+ super(...arguments);
2204
+ /**
2205
+ * The fog type of the scene.
2206
+ */
2207
+ this._fog = 'none'; // possible values: 'none', 'linear', 'exp', 'exp2'
2208
+ /**
2209
+ * The color of the fog.
2210
+ */
2211
+ this._fogColor = new Color(1, 1, 1);
2212
+ /**
2213
+ * The density of the fog.
2214
+ */
2215
+ this._fogDensity = 0;
2216
+ /**
2217
+ * The start distance of the fog.
2218
+ */
2219
+ this._fogStart = 0;
2220
+ /**
2221
+ * The end distance of the fog.
2222
+ */
2223
+ this._fogEnd = 1000;
2224
+ /**
2225
+ * The PlayCanvas scene instance.
2226
+ */
2227
+ this.scene = null;
2228
+ }
2229
+ async connectedCallback() {
2230
+ // Get the application
2231
+ const appElement = this.closest('pc-app');
2232
+ if (!appElement) {
2233
+ console.warn(`${this.tagName} must be a child of pc-app`);
2234
+ return;
2235
+ }
2236
+ const app = await appElement.getApplication();
2237
+ this.scene = app.scene;
2238
+ this.updateSceneSettings();
2239
+ }
2240
+ updateSceneSettings() {
2241
+ if (this.scene) {
2242
+ this.scene.rendering.fog = this._fog;
2243
+ this.scene.rendering.fogColor = this._fogColor;
2244
+ this.scene.rendering.fogDensity = this._fogDensity;
2245
+ this.scene.rendering.fogStart = this._fogStart;
2246
+ this.scene.rendering.fogEnd = this._fogEnd;
2247
+ // ... set other properties on the scene as well
2248
+ }
2249
+ }
2250
+ /**
2251
+ * Sets the fog type of the scene.
2252
+ * @param value - The fog type.
2253
+ */
2254
+ set fog(value) {
2255
+ this._fog = value;
2256
+ if (this.scene) {
2257
+ this.scene.rendering.fog = value;
2258
+ }
2259
+ }
2260
+ /**
2261
+ * Gets the fog type of the scene.
2262
+ * @returns The fog type.
2263
+ */
2264
+ get fog() {
2265
+ return this._fog;
2266
+ }
2267
+ /**
2268
+ * Sets the fog color of the scene.
2269
+ * @param value - The fog color.
2270
+ */
2271
+ set fogColor(value) {
2272
+ this._fogColor = value;
2273
+ if (this.scene) {
2274
+ this.scene.rendering.fogColor = value;
2275
+ }
2276
+ }
2277
+ /**
2278
+ * Gets the fog color of the scene.
2279
+ * @returns The fog color.
2280
+ */
2281
+ get fogColor() {
2282
+ return this._fogColor;
2283
+ }
2284
+ /**
2285
+ * Sets the fog density of the scene.
2286
+ * @param value - The fog density.
2287
+ */
2288
+ set fogDensity(value) {
2289
+ this._fogDensity = value;
2290
+ if (this.scene) {
2291
+ this.scene.rendering.fogDensity = value;
2292
+ }
2293
+ }
2294
+ /**
2295
+ * Gets the fog density of the scene.
2296
+ * @returns The fog density.
2297
+ */
2298
+ get fogDensity() {
2299
+ return this._fogDensity;
2300
+ }
2301
+ /**
2302
+ * Sets the fog start distance of the scene.
2303
+ * @param value - The fog start distance.
2304
+ */
2305
+ set fogStart(value) {
2306
+ this._fogStart = value;
2307
+ if (this.scene) {
2308
+ this.scene.rendering.fogStart = value;
2309
+ }
2310
+ }
2311
+ /**
2312
+ * Gets the fog start distance of the scene.
2313
+ * @returns The fog start distance.
2314
+ */
2315
+ get fogStart() {
2316
+ return this._fogStart;
2317
+ }
2318
+ /**
2319
+ * Sets the fog end distance of the scene.
2320
+ * @param value - The fog end distance.
2321
+ */
2322
+ set fogEnd(value) {
2323
+ this._fogEnd = value;
2324
+ if (this.scene) {
2325
+ this.scene.rendering.fogEnd = value;
2326
+ }
2327
+ }
2328
+ /**
2329
+ * Gets the fog end distance of the scene.
2330
+ * @returns The fog end distance.
2331
+ */
2332
+ get fogEnd() {
2333
+ return this._fogEnd;
2334
+ }
2335
+ static get observedAttributes() {
2336
+ return ['fog', 'fog-color', 'fog-density', 'fog-start', 'fog-end'];
2337
+ }
2338
+ attributeChangedCallback(name, _oldValue, newValue) {
2339
+ switch (name) {
2340
+ case 'fog':
2341
+ this.fog = newValue;
2342
+ break;
2343
+ case 'fog-color':
2344
+ this.fogColor = parseColor(newValue);
2345
+ break;
2346
+ case 'fog-density':
2347
+ this.fogDensity = parseFloat(newValue);
2348
+ break;
2349
+ case 'fog-start':
2350
+ this.fogStart = parseFloat(newValue);
2351
+ break;
2352
+ case 'fog-end':
2353
+ this.fogEnd = parseFloat(newValue);
2354
+ break;
2355
+ // ... handle other attributes as well
2356
+ }
2357
+ }
2358
+ }
2359
+ customElements.define('pc-scene', SceneElement);
2360
+
2361
+ /**
2362
+ * Represents a sky in the PlayCanvas engine.
2363
+ */
2364
+ class SkyElement extends HTMLElement {
2365
+ constructor() {
2366
+ super(...arguments);
2367
+ this._asset = '';
2368
+ this._intensity = 1;
2369
+ this._rotation = [0, 0, 0];
2370
+ this._level = 0;
2371
+ this._solidColor = false;
2372
+ }
2373
+ async connectedCallback() {
2374
+ // Get the application
2375
+ const appElement = this.closest('pc-app');
2376
+ if (!appElement) {
2377
+ console.warn(`${this.tagName} must be a child of pc-app`);
2378
+ return;
2379
+ }
2380
+ await appElement.getApplication();
2381
+ this.asset = this.getAttribute('asset') || '';
2382
+ this.solidColor = this.hasAttribute('solid-color');
2383
+ }
2384
+ getAsset() {
2385
+ const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
2386
+ return assetElement.asset;
2387
+ }
2388
+ getScene() {
2389
+ const appElement = this.closest('pc-app');
2390
+ if (!appElement) {
2391
+ return;
2392
+ }
2393
+ const app = appElement.app;
2394
+ if (!app) {
2395
+ return;
2396
+ }
2397
+ return app.scene;
2398
+ }
2399
+ set asset(value) {
2400
+ this._asset = value;
2401
+ const scene = this.getScene();
2402
+ if (scene) {
2403
+ const asset = this.getAsset();
2404
+ if (asset) {
2405
+ if (asset.resource) {
2406
+ scene.envAtlas = asset.resource;
2407
+ }
2408
+ else {
2409
+ asset.once('load', () => {
2410
+ scene.envAtlas = asset.resource;
2411
+ });
2412
+ }
2413
+ }
2414
+ }
2415
+ }
2416
+ get asset() {
2417
+ return this._asset;
2418
+ }
2419
+ set intensity(value) {
2420
+ this._intensity = value;
2421
+ const scene = this.getScene();
2422
+ if (scene) {
2423
+ scene.skyboxIntensity = this._intensity;
2424
+ }
2425
+ }
2426
+ get intensity() {
2427
+ return this._intensity;
2428
+ }
2429
+ set rotation(value) {
2430
+ this._rotation = value;
2431
+ const scene = this.getScene();
2432
+ if (scene) {
2433
+ scene.skyboxRotation = new Quat().setFromEulerAngles(this._rotation[0], this._rotation[1], this._rotation[2]);
2434
+ }
2435
+ }
2436
+ get rotation() {
2437
+ return this._rotation;
2438
+ }
2439
+ set solidColor(value) {
2440
+ this._solidColor = value;
2441
+ const scene = this.getScene();
2442
+ if (scene) {
2443
+ const layer = scene.layers.getLayerById(LAYERID_SKYBOX);
2444
+ if (layer) {
2445
+ layer.enabled = !this._solidColor;
2446
+ }
2447
+ }
2448
+ }
2449
+ get solidColor() {
2450
+ return this._solidColor;
2451
+ }
2452
+ set level(value) {
2453
+ this._level = value;
2454
+ const scene = this.getScene();
2455
+ if (scene) {
2456
+ scene.skyboxMip = this._level;
2457
+ }
2458
+ }
2459
+ get level() {
2460
+ return this._level;
2461
+ }
2462
+ static get observedAttributes() {
2463
+ return ['asset', 'intensity', 'level', 'rotation', 'solid-color'];
2464
+ }
2465
+ attributeChangedCallback(name, _oldValue, newValue) {
2466
+ switch (name) {
2467
+ case 'asset':
2468
+ this.asset = newValue;
2469
+ break;
2470
+ case 'intensity':
2471
+ this.intensity = parseFloat(newValue);
2472
+ break;
2473
+ case 'rotation':
2474
+ this.rotation = newValue.split(',').map(Number);
2475
+ break;
2476
+ case 'level':
2477
+ this.level = parseInt(newValue, 10);
2478
+ break;
2479
+ case 'solid-color':
2480
+ this.solidColor = this.hasAttribute('solid-color');
2481
+ break;
2482
+ }
2483
+ }
2484
+ }
2485
+ customElements.define('pc-sky', SkyElement);
2486
+
2487
+ export { AppElement, AssetElement, CameraComponentElement, CollisionComponentElement, ComponentElement, ElementComponentElement, EntityElement, GSplatComponentElement, LightComponentElement, ListenerComponentElement, ModelElement, ModuleElement, RenderComponentElement, RigidBodyComponentElement, SceneElement, ScriptComponentElement, ScriptElement, SkyElement, SoundComponentElement, SoundSlotElement };
2488
+ //# sourceMappingURL=pwc.mjs.map