@playcanvas/web-components 0.1.4 → 0.1.6
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/README.md +43 -61
- package/dist/app.d.ts +56 -5
- package/dist/asset.d.ts +0 -1
- package/dist/async-element.d.ts +23 -0
- package/dist/components/camera-component.d.ts +3 -0
- package/dist/components/component.d.ts +4 -2
- package/dist/components/element-component.d.ts +1 -1
- package/dist/components/render-component.d.ts +2 -2
- package/dist/components/script-component.d.ts +1 -1
- package/dist/components/sound-component.d.ts +48 -0
- package/dist/components/sound-slot.d.ts +2 -1
- package/dist/entity.d.ts +2 -3
- package/dist/index.d.ts +10 -1
- package/dist/model.d.ts +2 -1
- package/dist/pwc.cjs +426 -141
- package/dist/pwc.cjs.map +1 -1
- package/dist/pwc.js +426 -141
- package/dist/pwc.js.map +1 -1
- package/dist/pwc.min.js +1 -1
- package/dist/pwc.min.js.map +1 -1
- package/dist/pwc.mjs +427 -143
- package/dist/pwc.mjs.map +1 -1
- package/dist/scene.d.ts +2 -1
- package/dist/sky.d.ts +15 -6
- package/package.json +9 -8
- package/src/app.ts +103 -17
- package/src/asset.ts +1 -3
- package/src/async-element.ts +45 -0
- package/src/components/camera-component.ts +22 -1
- package/src/components/component.ts +15 -26
- package/src/components/element-component.ts +15 -4
- package/src/components/render-component.ts +1 -6
- package/src/components/script-component.ts +25 -7
- package/src/components/sound-component.ts +110 -1
- package/src/components/sound-slot.ts +7 -10
- package/src/entity.ts +19 -29
- package/src/index.ts +11 -0
- package/src/model.ts +20 -15
- package/src/module.ts +18 -10
- package/src/scene.ts +6 -11
- package/src/sky.ts +82 -40
package/dist/pwc.js
CHANGED
|
@@ -4,6 +4,41 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pd = {}, global.pc));
|
|
5
5
|
})(this, (function (exports, playcanvas) { 'use strict';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Base class for all PlayCanvas web components that initialize asynchronously.
|
|
9
|
+
*/
|
|
10
|
+
class AsyncElement extends HTMLElement {
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
this._readyPromise = new Promise((resolve) => {
|
|
14
|
+
this._readyResolve = resolve;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
get closestApp() {
|
|
18
|
+
var _a;
|
|
19
|
+
return (_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.closest('pc-app');
|
|
20
|
+
}
|
|
21
|
+
get closestEntity() {
|
|
22
|
+
var _a;
|
|
23
|
+
return (_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.closest('pc-entity');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Called when the element is fully initialized and ready.
|
|
27
|
+
* Subclasses should call this when they're ready.
|
|
28
|
+
*/
|
|
29
|
+
_onReady() {
|
|
30
|
+
this._readyResolve();
|
|
31
|
+
this.dispatchEvent(new CustomEvent('ready'));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns a promise that resolves with this element when it's ready.
|
|
35
|
+
* @returns A promise that resolves with this element when it's ready.
|
|
36
|
+
*/
|
|
37
|
+
ready() {
|
|
38
|
+
return this._readyPromise.then(() => this);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
7
42
|
class ModuleElement extends HTMLElement {
|
|
8
43
|
constructor() {
|
|
9
44
|
super();
|
|
@@ -14,14 +49,23 @@
|
|
|
14
49
|
const glue = this.getAttribute('glue');
|
|
15
50
|
const wasm = this.getAttribute('wasm');
|
|
16
51
|
const fallback = this.getAttribute('fallback');
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
52
|
+
if (name === 'Basis') {
|
|
53
|
+
playcanvas.basisInitialize({
|
|
54
|
+
glueUrl: glue,
|
|
55
|
+
wasmUrl: wasm,
|
|
56
|
+
fallbackUrl: fallback
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
playcanvas.WasmModule.setConfig(name, {
|
|
61
|
+
glueUrl: glue,
|
|
62
|
+
wasmUrl: wasm,
|
|
63
|
+
fallbackUrl: fallback
|
|
64
|
+
});
|
|
65
|
+
await new Promise((resolve) => {
|
|
66
|
+
playcanvas.WasmModule.getInstance(name, () => resolve());
|
|
67
|
+
});
|
|
68
|
+
}
|
|
25
69
|
}
|
|
26
70
|
getLoadPromise() {
|
|
27
71
|
return this.loadPromise;
|
|
@@ -32,7 +76,7 @@
|
|
|
32
76
|
/**
|
|
33
77
|
* The main application element.
|
|
34
78
|
*/
|
|
35
|
-
class AppElement extends
|
|
79
|
+
class AppElement extends AsyncElement {
|
|
36
80
|
/**
|
|
37
81
|
* Creates a new AppElement.
|
|
38
82
|
*/
|
|
@@ -42,6 +86,10 @@
|
|
|
42
86
|
* The canvas element.
|
|
43
87
|
*/
|
|
44
88
|
this._canvas = null;
|
|
89
|
+
this._alpha = true;
|
|
90
|
+
this._antialias = true;
|
|
91
|
+
this._depth = true;
|
|
92
|
+
this._stencil = true;
|
|
45
93
|
this._highResolution = false;
|
|
46
94
|
/**
|
|
47
95
|
* The PlayCanvas application instance.
|
|
@@ -49,9 +97,6 @@
|
|
|
49
97
|
this.app = null;
|
|
50
98
|
// Bind methods to maintain 'this' context
|
|
51
99
|
this._onWindowResize = this._onWindowResize.bind(this);
|
|
52
|
-
this.appReadyPromise = new Promise((resolve) => {
|
|
53
|
-
this.appReadyResolve = resolve;
|
|
54
|
-
});
|
|
55
100
|
}
|
|
56
101
|
async connectedCallback() {
|
|
57
102
|
// Get all pc-module elements that are direct children of the pc-app element
|
|
@@ -64,11 +109,15 @@
|
|
|
64
109
|
// Initialize the PlayCanvas application
|
|
65
110
|
this.app = new playcanvas.Application(this._canvas, {
|
|
66
111
|
graphicsDeviceOptions: {
|
|
67
|
-
|
|
112
|
+
alpha: this._alpha,
|
|
113
|
+
antialias: this._antialias,
|
|
114
|
+
depth: this._depth,
|
|
115
|
+
stencil: this._stencil
|
|
68
116
|
},
|
|
69
117
|
keyboard: new playcanvas.Keyboard(window),
|
|
70
118
|
mouse: new playcanvas.Mouse(this._canvas)
|
|
71
119
|
});
|
|
120
|
+
this.app.graphicsDevice.maxPixelRatio = this._highResolution ? window.devicePixelRatio : 1;
|
|
72
121
|
this.app.setCanvasFillMode(playcanvas.FILLMODE_FILL_WINDOW);
|
|
73
122
|
this.app.setCanvasResolution(playcanvas.RESOLUTION_AUTO);
|
|
74
123
|
// Get all pc-asset elements that are direct children of the pc-app element
|
|
@@ -91,7 +140,7 @@
|
|
|
91
140
|
this.app.start();
|
|
92
141
|
// Handle window resize to keep the canvas responsive
|
|
93
142
|
window.addEventListener('resize', this._onWindowResize);
|
|
94
|
-
this.
|
|
143
|
+
this._onReady();
|
|
95
144
|
});
|
|
96
145
|
}
|
|
97
146
|
disconnectedCallback() {
|
|
@@ -108,31 +157,104 @@
|
|
|
108
157
|
this._canvas = null;
|
|
109
158
|
}
|
|
110
159
|
}
|
|
111
|
-
async getApplication() {
|
|
112
|
-
await this.appReadyPromise;
|
|
113
|
-
return this.app;
|
|
114
|
-
}
|
|
115
160
|
_onWindowResize() {
|
|
116
161
|
if (this.app) {
|
|
117
162
|
this.app.resizeCanvas();
|
|
118
163
|
}
|
|
119
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Sets the alpha flag.
|
|
167
|
+
* @param value - The alpha flag.
|
|
168
|
+
*/
|
|
169
|
+
set alpha(value) {
|
|
170
|
+
this._alpha = value;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Gets the alpha flag.
|
|
174
|
+
* @returns The alpha flag.
|
|
175
|
+
*/
|
|
176
|
+
get alpha() {
|
|
177
|
+
return this._alpha;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Sets the antialias flag.
|
|
181
|
+
* @param value - The antialias flag.
|
|
182
|
+
*/
|
|
183
|
+
set antialias(value) {
|
|
184
|
+
this._antialias = value;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Gets the antialias flag.
|
|
188
|
+
* @returns The antialias flag.
|
|
189
|
+
*/
|
|
190
|
+
get antialias() {
|
|
191
|
+
return this._antialias;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Sets the depth flag.
|
|
195
|
+
* @param value - The depth flag.
|
|
196
|
+
*/
|
|
197
|
+
set depth(value) {
|
|
198
|
+
this._depth = value;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Gets the depth flag.
|
|
202
|
+
* @returns The depth flag.
|
|
203
|
+
*/
|
|
204
|
+
get depth() {
|
|
205
|
+
return this._depth;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Sets the high resolution flag. When true, the application will render at the device's
|
|
209
|
+
* physical resolution. When false, the application will render at CSS resolution.
|
|
210
|
+
* @param value - The high resolution flag.
|
|
211
|
+
*/
|
|
120
212
|
set highResolution(value) {
|
|
121
213
|
this._highResolution = value;
|
|
122
214
|
if (this.app) {
|
|
123
215
|
this.app.graphicsDevice.maxPixelRatio = value ? window.devicePixelRatio : 1;
|
|
124
216
|
}
|
|
125
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Gets the high resolution flag.
|
|
220
|
+
* @returns The high resolution flag.
|
|
221
|
+
*/
|
|
126
222
|
get highResolution() {
|
|
127
223
|
return this._highResolution;
|
|
128
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Sets the stencil flag.
|
|
227
|
+
* @param value - The stencil flag.
|
|
228
|
+
*/
|
|
229
|
+
set stencil(value) {
|
|
230
|
+
this._stencil = value;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Gets the stencil flag.
|
|
234
|
+
* @returns The stencil flag.
|
|
235
|
+
*/
|
|
236
|
+
get stencil() {
|
|
237
|
+
return this._stencil;
|
|
238
|
+
}
|
|
129
239
|
static get observedAttributes() {
|
|
130
|
-
return ['high-resolution'];
|
|
240
|
+
return ['alpha', 'antialias', 'depth', 'stencil', 'high-resolution'];
|
|
131
241
|
}
|
|
132
|
-
attributeChangedCallback(name, _oldValue,
|
|
242
|
+
attributeChangedCallback(name, _oldValue, newValue) {
|
|
133
243
|
switch (name) {
|
|
244
|
+
case 'alpha':
|
|
245
|
+
this.alpha = newValue !== 'false';
|
|
246
|
+
break;
|
|
247
|
+
case 'antialias':
|
|
248
|
+
this.antialias = newValue !== 'false';
|
|
249
|
+
break;
|
|
250
|
+
case 'depth':
|
|
251
|
+
this.depth = newValue !== 'false';
|
|
252
|
+
break;
|
|
134
253
|
case 'high-resolution':
|
|
135
|
-
this.highResolution =
|
|
254
|
+
this.highResolution = newValue !== 'false';
|
|
255
|
+
break;
|
|
256
|
+
case 'stencil':
|
|
257
|
+
this.stencil = newValue !== 'false';
|
|
136
258
|
break;
|
|
137
259
|
}
|
|
138
260
|
}
|
|
@@ -199,7 +321,7 @@
|
|
|
199
321
|
/**
|
|
200
322
|
* Represents an entity in the PlayCanvas engine.
|
|
201
323
|
*/
|
|
202
|
-
class EntityElement extends
|
|
324
|
+
class EntityElement extends AsyncElement {
|
|
203
325
|
constructor() {
|
|
204
326
|
super(...arguments);
|
|
205
327
|
/**
|
|
@@ -226,33 +348,20 @@
|
|
|
226
348
|
* The tags of the entity.
|
|
227
349
|
*/
|
|
228
350
|
this._tags = [];
|
|
229
|
-
this._entityReady = new Promise((resolve) => {
|
|
230
|
-
this._resolveEntity = resolve;
|
|
231
|
-
});
|
|
232
351
|
/**
|
|
233
352
|
* The PlayCanvas entity instance.
|
|
234
353
|
*/
|
|
235
354
|
this.entity = null;
|
|
236
355
|
}
|
|
237
356
|
async connectedCallback() {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (!appElement) {
|
|
241
|
-
console.warn(`${this.tagName} must be a child of pc-app`);
|
|
357
|
+
const closestApp = this.closestApp;
|
|
358
|
+
if (!closestApp)
|
|
242
359
|
return;
|
|
243
|
-
|
|
244
|
-
|
|
360
|
+
// Wait for the app to complete initialization
|
|
361
|
+
await closestApp.ready();
|
|
362
|
+
const app = closestApp.app;
|
|
245
363
|
// Create a new entity
|
|
246
364
|
this.entity = new playcanvas.Entity(this._name, app);
|
|
247
|
-
this._resolveEntity(this.entity);
|
|
248
|
-
if (this.parentElement &&
|
|
249
|
-
this.parentElement.tagName.toLowerCase() === 'pc-entity') {
|
|
250
|
-
const parentEntity = await this.parentElement._entityReady;
|
|
251
|
-
parentEntity.addChild(this.entity);
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
app.root.addChild(this.entity);
|
|
255
|
-
}
|
|
256
365
|
// Initialize from attributes
|
|
257
366
|
const nameAttr = this.getAttribute('name');
|
|
258
367
|
const positionAttr = this.getAttribute('position');
|
|
@@ -269,6 +378,17 @@
|
|
|
269
378
|
this.scale = parseVec3(scaleAttr);
|
|
270
379
|
if (tagsAttr)
|
|
271
380
|
this.tags = tagsAttr.split(',').map(tag => tag.trim());
|
|
381
|
+
const closestEntity = this.closestEntity;
|
|
382
|
+
if (closestEntity) {
|
|
383
|
+
closestEntity.ready().then(() => {
|
|
384
|
+
closestEntity.entity.addChild(this.entity);
|
|
385
|
+
this._onReady();
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
app.root.addChild(this.entity);
|
|
390
|
+
this._onReady();
|
|
391
|
+
}
|
|
272
392
|
}
|
|
273
393
|
disconnectedCallback() {
|
|
274
394
|
if (this.entity) {
|
|
@@ -280,10 +400,6 @@
|
|
|
280
400
|
this.entity.destroy();
|
|
281
401
|
this.entity = null;
|
|
282
402
|
}
|
|
283
|
-
// Reset the promise for potential reconnection
|
|
284
|
-
this._entityReady = new Promise((resolve) => {
|
|
285
|
-
this._resolveEntity = resolve;
|
|
286
|
-
});
|
|
287
403
|
}
|
|
288
404
|
/**
|
|
289
405
|
* Sets the enabled state of the entity.
|
|
@@ -422,6 +538,7 @@
|
|
|
422
538
|
['frag', 'shader'],
|
|
423
539
|
['glb', 'container'],
|
|
424
540
|
['glsl', 'shader'],
|
|
541
|
+
['hdr', 'texture'],
|
|
425
542
|
['html', 'html'],
|
|
426
543
|
['jpg', 'texture'],
|
|
427
544
|
['js', 'script'],
|
|
@@ -446,8 +563,6 @@
|
|
|
446
563
|
*/
|
|
447
564
|
this.asset = null;
|
|
448
565
|
}
|
|
449
|
-
async connectedCallback() {
|
|
450
|
-
}
|
|
451
566
|
disconnectedCallback() {
|
|
452
567
|
this.destroyAsset();
|
|
453
568
|
}
|
|
@@ -511,7 +626,7 @@
|
|
|
511
626
|
*
|
|
512
627
|
* @category Components
|
|
513
628
|
*/
|
|
514
|
-
class ComponentElement extends
|
|
629
|
+
class ComponentElement extends AsyncElement {
|
|
515
630
|
/**
|
|
516
631
|
* Constructor for the ComponentElement.
|
|
517
632
|
* @param componentName - The name of the component.
|
|
@@ -526,27 +641,23 @@
|
|
|
526
641
|
getInitialComponentData() {
|
|
527
642
|
return {};
|
|
528
643
|
}
|
|
529
|
-
async
|
|
530
|
-
const
|
|
531
|
-
if (
|
|
532
|
-
|
|
533
|
-
return;
|
|
534
|
-
}
|
|
535
|
-
await appElement.getApplication();
|
|
536
|
-
this.addComponent();
|
|
537
|
-
}
|
|
538
|
-
addComponent() {
|
|
539
|
-
// Access the parent pc-entity's 'entity' property
|
|
540
|
-
const entityElement = this.closest('pc-entity');
|
|
541
|
-
if (!entityElement) {
|
|
542
|
-
console.error(`${this.tagName.toLowerCase()} should be a child of pc-entity`);
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
if (entityElement && entityElement.entity) {
|
|
644
|
+
async addComponent() {
|
|
645
|
+
const entityElement = this.closestEntity;
|
|
646
|
+
if (entityElement) {
|
|
647
|
+
await entityElement.ready();
|
|
546
648
|
// Add the component to the entity
|
|
547
|
-
|
|
649
|
+
const data = this.getInitialComponentData();
|
|
650
|
+
this._component = entityElement.entity.addComponent(this._componentName, data);
|
|
548
651
|
}
|
|
549
652
|
}
|
|
653
|
+
initComponent() { }
|
|
654
|
+
async connectedCallback() {
|
|
655
|
+
var _a;
|
|
656
|
+
await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
|
|
657
|
+
await this.addComponent();
|
|
658
|
+
this.initComponent();
|
|
659
|
+
this._onReady();
|
|
660
|
+
}
|
|
550
661
|
disconnectedCallback() {
|
|
551
662
|
// Remove the component when the element is disconnected
|
|
552
663
|
if (this.component && this.component.entity) {
|
|
@@ -651,6 +762,26 @@
|
|
|
651
762
|
scissorRect: this._scissorRect
|
|
652
763
|
};
|
|
653
764
|
}
|
|
765
|
+
get xrAvailable() {
|
|
766
|
+
var _a;
|
|
767
|
+
const xrManager = (_a = this.component) === null || _a === void 0 ? void 0 : _a.system.app.xr;
|
|
768
|
+
return xrManager && xrManager.supported && xrManager.isAvailable(playcanvas.XRTYPE_VR);
|
|
769
|
+
}
|
|
770
|
+
startXr(type, space) {
|
|
771
|
+
if (this.component && this.xrAvailable) {
|
|
772
|
+
this.component.startXr(type, space, {
|
|
773
|
+
callback: (err) => {
|
|
774
|
+
if (err)
|
|
775
|
+
console.error(`WebXR Immersive VR failed to start: ${err.message}`);
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
endXr() {
|
|
781
|
+
if (this.component) {
|
|
782
|
+
this.component.endXr();
|
|
783
|
+
}
|
|
784
|
+
}
|
|
654
785
|
/**
|
|
655
786
|
* Gets the camera component.
|
|
656
787
|
* @returns The camera component.
|
|
@@ -1152,8 +1283,7 @@
|
|
|
1152
1283
|
this._width = 0;
|
|
1153
1284
|
this._wrapLines = false;
|
|
1154
1285
|
}
|
|
1155
|
-
|
|
1156
|
-
await super.connectedCallback();
|
|
1286
|
+
initComponent() {
|
|
1157
1287
|
this.component._text._material.useFog = true;
|
|
1158
1288
|
}
|
|
1159
1289
|
getInitialComponentData() {
|
|
@@ -1287,7 +1417,20 @@
|
|
|
1287
1417
|
return this._wrapLines;
|
|
1288
1418
|
}
|
|
1289
1419
|
static get observedAttributes() {
|
|
1290
|
-
return [
|
|
1420
|
+
return [
|
|
1421
|
+
...super.observedAttributes,
|
|
1422
|
+
'anchor',
|
|
1423
|
+
'asset',
|
|
1424
|
+
'auto-width',
|
|
1425
|
+
'color',
|
|
1426
|
+
'font-size',
|
|
1427
|
+
'line-height',
|
|
1428
|
+
'pivot',
|
|
1429
|
+
'text',
|
|
1430
|
+
'type',
|
|
1431
|
+
'width',
|
|
1432
|
+
'wrap-lines'
|
|
1433
|
+
];
|
|
1291
1434
|
}
|
|
1292
1435
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
1293
1436
|
super.attributeChangedCallback(name, _oldValue, newValue);
|
|
@@ -1773,14 +1916,11 @@
|
|
|
1773
1916
|
this._receiveShadows = true;
|
|
1774
1917
|
this._type = 'asset';
|
|
1775
1918
|
}
|
|
1776
|
-
async connectedCallback() {
|
|
1777
|
-
await super.connectedCallback();
|
|
1778
|
-
this.material = this._material;
|
|
1779
|
-
}
|
|
1780
1919
|
getInitialComponentData() {
|
|
1781
1920
|
return {
|
|
1782
1921
|
type: this._type,
|
|
1783
1922
|
castShadows: this._castShadows,
|
|
1923
|
+
material: MaterialElement.get(this._material),
|
|
1784
1924
|
receiveShadows: this._receiveShadows
|
|
1785
1925
|
};
|
|
1786
1926
|
}
|
|
@@ -2192,6 +2332,9 @@
|
|
|
2192
2332
|
}
|
|
2193
2333
|
customElements.define('pc-screen', ScreenComponentElement);
|
|
2194
2334
|
|
|
2335
|
+
const tmpV2 = new playcanvas.Vec2();
|
|
2336
|
+
const tmpV3 = new playcanvas.Vec3();
|
|
2337
|
+
const tmpV4 = new playcanvas.Vec4();
|
|
2195
2338
|
/**
|
|
2196
2339
|
* Represents a script component in the PlayCanvas engine.
|
|
2197
2340
|
*
|
|
@@ -2209,8 +2352,7 @@
|
|
|
2209
2352
|
this.addEventListener('scriptattributeschange', this.handleScriptAttributesChange.bind(this));
|
|
2210
2353
|
this.addEventListener('scriptenablechange', this.handleScriptEnableChange.bind(this));
|
|
2211
2354
|
}
|
|
2212
|
-
|
|
2213
|
-
await super.connectedCallback();
|
|
2355
|
+
initComponent() {
|
|
2214
2356
|
// Handle initial script elements
|
|
2215
2357
|
this.querySelectorAll(':scope > pc-script').forEach((scriptElement) => {
|
|
2216
2358
|
const scriptName = scriptElement.getAttribute('name');
|
|
@@ -2224,7 +2366,22 @@
|
|
|
2224
2366
|
try {
|
|
2225
2367
|
// Parse the attributes string into an object and set them on the script
|
|
2226
2368
|
const attributesObject = attributes ? JSON.parse(attributes) : {};
|
|
2227
|
-
|
|
2369
|
+
for (const key in attributesObject) {
|
|
2370
|
+
const value = attributesObject[key];
|
|
2371
|
+
if (Array.isArray(value) && script[key] instanceof playcanvas.Vec2) {
|
|
2372
|
+
script[key] = tmpV2.set(value[0], value[1]);
|
|
2373
|
+
continue;
|
|
2374
|
+
}
|
|
2375
|
+
if (Array.isArray(value) && script[key] instanceof playcanvas.Vec3) {
|
|
2376
|
+
script[key] = tmpV3.set(value[0], value[1], value[2]);
|
|
2377
|
+
continue;
|
|
2378
|
+
}
|
|
2379
|
+
if (Array.isArray(value) && script[key] instanceof playcanvas.Vec4) {
|
|
2380
|
+
script[key] = tmpV4.set(value[0], value[1], value[2], value[3]);
|
|
2381
|
+
continue;
|
|
2382
|
+
}
|
|
2383
|
+
script[key] = value;
|
|
2384
|
+
}
|
|
2228
2385
|
}
|
|
2229
2386
|
catch (error) {
|
|
2230
2387
|
console.error(`Error parsing attributes JSON string ${attributes}:`, error);
|
|
@@ -2388,14 +2545,22 @@
|
|
|
2388
2545
|
class SoundComponentElement extends ComponentElement {
|
|
2389
2546
|
constructor() {
|
|
2390
2547
|
super('sound');
|
|
2548
|
+
this._distanceModel = 'linear';
|
|
2549
|
+
this._maxDistance = 10000;
|
|
2391
2550
|
this._pitch = 1;
|
|
2392
2551
|
this._positional = false;
|
|
2552
|
+
this._refDistance = 1;
|
|
2553
|
+
this._rollOffFactor = 1;
|
|
2393
2554
|
this._volume = 1;
|
|
2394
2555
|
}
|
|
2395
2556
|
getInitialComponentData() {
|
|
2396
2557
|
return {
|
|
2558
|
+
distanceModel: this._distanceModel,
|
|
2559
|
+
maxDistance: this._maxDistance,
|
|
2397
2560
|
pitch: this._pitch,
|
|
2398
2561
|
positional: this._positional,
|
|
2562
|
+
refDistance: this._refDistance,
|
|
2563
|
+
rollOffFactor: this._rollOffFactor,
|
|
2399
2564
|
volume: this._volume
|
|
2400
2565
|
};
|
|
2401
2566
|
}
|
|
@@ -2406,6 +2571,40 @@
|
|
|
2406
2571
|
get component() {
|
|
2407
2572
|
return super.component;
|
|
2408
2573
|
}
|
|
2574
|
+
/**
|
|
2575
|
+
* Sets which algorithm to use to reduce the volume of the sound as it moves away from the listener.
|
|
2576
|
+
* @param value - The distance model.
|
|
2577
|
+
*/
|
|
2578
|
+
set distanceModel(value) {
|
|
2579
|
+
this._distanceModel = value;
|
|
2580
|
+
if (this.component) {
|
|
2581
|
+
this.component.distanceModel = value;
|
|
2582
|
+
}
|
|
2583
|
+
}
|
|
2584
|
+
/**
|
|
2585
|
+
* Gets which algorithm to use to reduce the volume of the sound as it moves away from the listener.
|
|
2586
|
+
* @returns The distance model.
|
|
2587
|
+
*/
|
|
2588
|
+
get distanceModel() {
|
|
2589
|
+
return this._distanceModel;
|
|
2590
|
+
}
|
|
2591
|
+
/**
|
|
2592
|
+
* Sets the maximum distance from the listener at which audio falloff stops.
|
|
2593
|
+
* @param value - The max distance.
|
|
2594
|
+
*/
|
|
2595
|
+
set maxDistance(value) {
|
|
2596
|
+
this._maxDistance = value;
|
|
2597
|
+
if (this.component) {
|
|
2598
|
+
this.component.maxDistance = value;
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
/**
|
|
2602
|
+
* Gets the maximum distance from the listener at which audio falloff stops.
|
|
2603
|
+
* @returns The max distance.
|
|
2604
|
+
*/
|
|
2605
|
+
get maxDistance() {
|
|
2606
|
+
return this._maxDistance;
|
|
2607
|
+
}
|
|
2409
2608
|
/**
|
|
2410
2609
|
* Sets the pitch of the sound.
|
|
2411
2610
|
* @param value - The pitch.
|
|
@@ -2440,6 +2639,40 @@
|
|
|
2440
2639
|
get positional() {
|
|
2441
2640
|
return this._positional;
|
|
2442
2641
|
}
|
|
2642
|
+
/**
|
|
2643
|
+
* Sets the reference distance for reducing volume as the sound source moves further from the listener. Defaults to 1.
|
|
2644
|
+
* @param value - The ref distance.
|
|
2645
|
+
*/
|
|
2646
|
+
set refDistance(value) {
|
|
2647
|
+
this._refDistance = value;
|
|
2648
|
+
if (this.component) {
|
|
2649
|
+
this.component.refDistance = value;
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
/**
|
|
2653
|
+
* Gets the reference distance for reducing volume as the sound source moves further from the listener.
|
|
2654
|
+
* @returns The ref distance.
|
|
2655
|
+
*/
|
|
2656
|
+
get refDistance() {
|
|
2657
|
+
return this._refDistance;
|
|
2658
|
+
}
|
|
2659
|
+
/**
|
|
2660
|
+
* Sets the factor used in the falloff equation. Defaults to 1.
|
|
2661
|
+
* @param value - The roll-off factor.
|
|
2662
|
+
*/
|
|
2663
|
+
set rollOffFactor(value) {
|
|
2664
|
+
this._rollOffFactor = value;
|
|
2665
|
+
if (this.component) {
|
|
2666
|
+
this.component.rollOffFactor = value;
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
/**
|
|
2670
|
+
* Gets the factor used in the falloff equation.
|
|
2671
|
+
* @returns The roll-off factor.
|
|
2672
|
+
*/
|
|
2673
|
+
get rollOffFactor() {
|
|
2674
|
+
return this._rollOffFactor;
|
|
2675
|
+
}
|
|
2443
2676
|
/**
|
|
2444
2677
|
* Sets the volume of the sound.
|
|
2445
2678
|
* @param value - The volume.
|
|
@@ -2458,17 +2691,38 @@
|
|
|
2458
2691
|
return this._volume;
|
|
2459
2692
|
}
|
|
2460
2693
|
static get observedAttributes() {
|
|
2461
|
-
return [
|
|
2694
|
+
return [
|
|
2695
|
+
...super.observedAttributes,
|
|
2696
|
+
'distance-model',
|
|
2697
|
+
'max-distance',
|
|
2698
|
+
'pitch',
|
|
2699
|
+
'positional',
|
|
2700
|
+
'ref-distance',
|
|
2701
|
+
'roll-off-factor',
|
|
2702
|
+
'volume'
|
|
2703
|
+
];
|
|
2462
2704
|
}
|
|
2463
2705
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
2464
2706
|
super.attributeChangedCallback(name, _oldValue, newValue);
|
|
2465
2707
|
switch (name) {
|
|
2708
|
+
case 'distance-model':
|
|
2709
|
+
this.distanceModel = newValue;
|
|
2710
|
+
break;
|
|
2711
|
+
case 'max-distance':
|
|
2712
|
+
this.maxDistance = parseFloat(newValue);
|
|
2713
|
+
break;
|
|
2466
2714
|
case 'pitch':
|
|
2467
2715
|
this.pitch = parseFloat(newValue);
|
|
2468
2716
|
break;
|
|
2469
2717
|
case 'positional':
|
|
2470
2718
|
this.positional = this.hasAttribute('positional');
|
|
2471
2719
|
break;
|
|
2720
|
+
case 'ref-distance':
|
|
2721
|
+
this.refDistance = parseFloat(newValue);
|
|
2722
|
+
break;
|
|
2723
|
+
case 'roll-off-factor':
|
|
2724
|
+
this.rollOffFactor = parseFloat(newValue);
|
|
2725
|
+
break;
|
|
2472
2726
|
case 'volume':
|
|
2473
2727
|
this.volume = parseFloat(newValue);
|
|
2474
2728
|
break;
|
|
@@ -2480,7 +2734,7 @@
|
|
|
2480
2734
|
/**
|
|
2481
2735
|
* Represents a sound slot in the PlayCanvas engine.
|
|
2482
2736
|
*/
|
|
2483
|
-
class SoundSlotElement extends
|
|
2737
|
+
class SoundSlotElement extends AsyncElement {
|
|
2484
2738
|
constructor() {
|
|
2485
2739
|
super(...arguments);
|
|
2486
2740
|
this._asset = '';
|
|
@@ -2498,12 +2752,8 @@
|
|
|
2498
2752
|
this.soundSlot = null;
|
|
2499
2753
|
}
|
|
2500
2754
|
async connectedCallback() {
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
console.error(`${this.tagName.toLowerCase()} should be a descendant of pc-app`);
|
|
2504
|
-
return;
|
|
2505
|
-
}
|
|
2506
|
-
await appElement.getApplication();
|
|
2755
|
+
var _a;
|
|
2756
|
+
await ((_a = this.soundElement) === null || _a === void 0 ? void 0 : _a.ready());
|
|
2507
2757
|
const options = {
|
|
2508
2758
|
autoPlay: this._autoPlay,
|
|
2509
2759
|
loop: this._loop,
|
|
@@ -2518,6 +2768,7 @@
|
|
|
2518
2768
|
this.soundSlot = this.soundElement.component.addSlot(this._name, options);
|
|
2519
2769
|
this.asset = this._asset;
|
|
2520
2770
|
this.soundSlot.play();
|
|
2771
|
+
this._onReady();
|
|
2521
2772
|
}
|
|
2522
2773
|
disconnectedCallback() {
|
|
2523
2774
|
this.soundElement.component.removeSlot(this._name);
|
|
@@ -2724,23 +2975,19 @@
|
|
|
2724
2975
|
/**
|
|
2725
2976
|
* Represents a model in the PlayCanvas engine.
|
|
2726
2977
|
*/
|
|
2727
|
-
class ModelElement extends
|
|
2978
|
+
class ModelElement extends AsyncElement {
|
|
2728
2979
|
constructor() {
|
|
2729
2980
|
super(...arguments);
|
|
2730
2981
|
this._asset = '';
|
|
2731
2982
|
}
|
|
2732
2983
|
async connectedCallback() {
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
if (!appElement) {
|
|
2736
|
-
console.warn(`${this.tagName} must be a child of pc-app`);
|
|
2737
|
-
return;
|
|
2738
|
-
}
|
|
2739
|
-
await appElement.getApplication();
|
|
2984
|
+
var _a;
|
|
2985
|
+
await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
|
|
2740
2986
|
const asset = this.getAttribute('asset');
|
|
2741
2987
|
if (asset) {
|
|
2742
2988
|
this.asset = asset;
|
|
2743
2989
|
}
|
|
2990
|
+
this._onReady();
|
|
2744
2991
|
}
|
|
2745
2992
|
_loadModel() {
|
|
2746
2993
|
const asset = AssetElement.get(this._asset);
|
|
@@ -2748,13 +2995,23 @@
|
|
|
2748
2995
|
return;
|
|
2749
2996
|
}
|
|
2750
2997
|
const entity = asset.resource.instantiateRenderEntity();
|
|
2751
|
-
|
|
2998
|
+
if (asset.resource.animations.length > 0) {
|
|
2999
|
+
entity.addComponent('anim');
|
|
3000
|
+
entity.anim.assignAnimation('animation', asset.resource.animations[0].resource);
|
|
3001
|
+
}
|
|
3002
|
+
const parentEntityElement = this.closestEntity;
|
|
2752
3003
|
if (parentEntityElement) {
|
|
2753
|
-
parentEntityElement.
|
|
3004
|
+
parentEntityElement.ready().then(() => {
|
|
3005
|
+
parentEntityElement.entity.addChild(entity);
|
|
3006
|
+
});
|
|
2754
3007
|
}
|
|
2755
3008
|
else {
|
|
2756
|
-
const appElement = this.
|
|
2757
|
-
appElement
|
|
3009
|
+
const appElement = this.closestApp;
|
|
3010
|
+
if (appElement) {
|
|
3011
|
+
appElement.ready().then(() => {
|
|
3012
|
+
appElement.app.root.addChild(entity);
|
|
3013
|
+
});
|
|
3014
|
+
}
|
|
2758
3015
|
}
|
|
2759
3016
|
}
|
|
2760
3017
|
/**
|
|
@@ -2788,7 +3045,7 @@
|
|
|
2788
3045
|
/**
|
|
2789
3046
|
* Represents a scene in the PlayCanvas engine.
|
|
2790
3047
|
*/
|
|
2791
|
-
class SceneElement extends
|
|
3048
|
+
class SceneElement extends AsyncElement {
|
|
2792
3049
|
constructor() {
|
|
2793
3050
|
super(...arguments);
|
|
2794
3051
|
/**
|
|
@@ -2817,15 +3074,11 @@
|
|
|
2817
3074
|
this.scene = null;
|
|
2818
3075
|
}
|
|
2819
3076
|
async connectedCallback() {
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
console.warn(`${this.tagName} must be a child of pc-app`);
|
|
2824
|
-
return;
|
|
2825
|
-
}
|
|
2826
|
-
const app = await appElement.getApplication();
|
|
2827
|
-
this.scene = app.scene;
|
|
3077
|
+
var _a;
|
|
3078
|
+
await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
|
|
3079
|
+
this.scene = this.closestApp.app.scene;
|
|
2828
3080
|
this.updateSceneSettings();
|
|
3081
|
+
this._onReady();
|
|
2829
3082
|
}
|
|
2830
3083
|
updateSceneSettings() {
|
|
2831
3084
|
if (this.scene) {
|
|
@@ -2951,57 +3204,71 @@
|
|
|
2951
3204
|
/**
|
|
2952
3205
|
* Represents a sky in the PlayCanvas engine.
|
|
2953
3206
|
*/
|
|
2954
|
-
class SkyElement extends
|
|
3207
|
+
class SkyElement extends AsyncElement {
|
|
2955
3208
|
constructor() {
|
|
2956
3209
|
super(...arguments);
|
|
2957
3210
|
this._asset = '';
|
|
3211
|
+
this._center = new playcanvas.Vec3(0, 0.01, 0);
|
|
2958
3212
|
this._intensity = 1;
|
|
2959
|
-
this._rotation =
|
|
3213
|
+
this._rotation = new playcanvas.Vec3();
|
|
2960
3214
|
this._level = 0;
|
|
2961
|
-
this.
|
|
3215
|
+
this._scale = new playcanvas.Vec3(100, 100, 100);
|
|
3216
|
+
this._type = 'infinite';
|
|
2962
3217
|
}
|
|
2963
3218
|
async connectedCallback() {
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
if (!appElement) {
|
|
2967
|
-
console.warn(`${this.tagName} must be a child of pc-app`);
|
|
2968
|
-
return;
|
|
2969
|
-
}
|
|
2970
|
-
await appElement.getApplication();
|
|
3219
|
+
var _a;
|
|
3220
|
+
await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
|
|
2971
3221
|
this.asset = this.getAttribute('asset') || '';
|
|
2972
|
-
this.
|
|
3222
|
+
this._onReady();
|
|
2973
3223
|
}
|
|
2974
3224
|
getScene() {
|
|
2975
|
-
const
|
|
2976
|
-
if (!appElement) {
|
|
2977
|
-
return;
|
|
2978
|
-
}
|
|
2979
|
-
const app = appElement.app;
|
|
3225
|
+
const app = this.closestApp.app;
|
|
2980
3226
|
if (!app) {
|
|
2981
3227
|
return;
|
|
2982
3228
|
}
|
|
2983
3229
|
return app.scene;
|
|
2984
3230
|
}
|
|
3231
|
+
initSkybox(source) {
|
|
3232
|
+
source.anisotropy = 4;
|
|
3233
|
+
const skybox = playcanvas.EnvLighting.generateSkyboxCubemap(source);
|
|
3234
|
+
const lighting = playcanvas.EnvLighting.generateLightingSource(source);
|
|
3235
|
+
const envAtlas = playcanvas.EnvLighting.generateAtlas(lighting);
|
|
3236
|
+
const app = this.closestApp.app;
|
|
3237
|
+
if (app) {
|
|
3238
|
+
app.scene.envAtlas = envAtlas;
|
|
3239
|
+
app.scene.skybox = skybox;
|
|
3240
|
+
const layer = app.scene.layers.getLayerById(playcanvas.LAYERID_SKYBOX);
|
|
3241
|
+
if (layer) {
|
|
3242
|
+
layer.enabled = this._type !== 'none';
|
|
3243
|
+
}
|
|
3244
|
+
app.scene.sky.type = this._type;
|
|
3245
|
+
app.scene.sky.node.setLocalScale(this._scale);
|
|
3246
|
+
app.scene.sky.center = this._center;
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
2985
3249
|
set asset(value) {
|
|
2986
3250
|
this._asset = value;
|
|
2987
3251
|
const scene = this.getScene();
|
|
2988
3252
|
if (scene) {
|
|
2989
3253
|
const asset = AssetElement.get(value);
|
|
2990
3254
|
if (asset) {
|
|
2991
|
-
|
|
2992
|
-
scene.envAtlas = asset.resource;
|
|
2993
|
-
}
|
|
2994
|
-
else {
|
|
2995
|
-
asset.once('load', () => {
|
|
2996
|
-
scene.envAtlas = asset.resource;
|
|
2997
|
-
});
|
|
2998
|
-
}
|
|
3255
|
+
this.initSkybox(asset.resource);
|
|
2999
3256
|
}
|
|
3000
3257
|
}
|
|
3001
3258
|
}
|
|
3002
3259
|
get asset() {
|
|
3003
3260
|
return this._asset;
|
|
3004
3261
|
}
|
|
3262
|
+
set center(value) {
|
|
3263
|
+
this._center = value;
|
|
3264
|
+
const scene = this.getScene();
|
|
3265
|
+
if (scene) {
|
|
3266
|
+
scene.sky.center = this._center;
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
get center() {
|
|
3270
|
+
return this._center;
|
|
3271
|
+
}
|
|
3005
3272
|
set intensity(value) {
|
|
3006
3273
|
this._intensity = value;
|
|
3007
3274
|
const scene = this.getScene();
|
|
@@ -3016,24 +3283,21 @@
|
|
|
3016
3283
|
this._rotation = value;
|
|
3017
3284
|
const scene = this.getScene();
|
|
3018
3285
|
if (scene) {
|
|
3019
|
-
scene.skyboxRotation = new playcanvas.Quat().setFromEulerAngles(
|
|
3286
|
+
scene.skyboxRotation = new playcanvas.Quat().setFromEulerAngles(value);
|
|
3020
3287
|
}
|
|
3021
3288
|
}
|
|
3022
3289
|
get rotation() {
|
|
3023
3290
|
return this._rotation;
|
|
3024
3291
|
}
|
|
3025
|
-
set
|
|
3026
|
-
this.
|
|
3292
|
+
set scale(value) {
|
|
3293
|
+
this._scale = value;
|
|
3027
3294
|
const scene = this.getScene();
|
|
3028
3295
|
if (scene) {
|
|
3029
|
-
|
|
3030
|
-
if (layer) {
|
|
3031
|
-
layer.enabled = !this._solidColor;
|
|
3032
|
-
}
|
|
3296
|
+
scene.sky.node.setLocalScale(this._scale);
|
|
3033
3297
|
}
|
|
3034
3298
|
}
|
|
3035
|
-
get
|
|
3036
|
-
return this.
|
|
3299
|
+
get scale() {
|
|
3300
|
+
return this._scale;
|
|
3037
3301
|
}
|
|
3038
3302
|
set level(value) {
|
|
3039
3303
|
this._level = value;
|
|
@@ -3045,25 +3309,45 @@
|
|
|
3045
3309
|
get level() {
|
|
3046
3310
|
return this._level;
|
|
3047
3311
|
}
|
|
3312
|
+
set type(value) {
|
|
3313
|
+
this._type = value;
|
|
3314
|
+
const scene = this.getScene();
|
|
3315
|
+
if (scene) {
|
|
3316
|
+
scene.sky.type = this._type;
|
|
3317
|
+
const layer = scene.layers.getLayerById(playcanvas.LAYERID_SKYBOX);
|
|
3318
|
+
if (layer) {
|
|
3319
|
+
layer.enabled = this._type !== 'none';
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
get type() {
|
|
3324
|
+
return this._type;
|
|
3325
|
+
}
|
|
3048
3326
|
static get observedAttributes() {
|
|
3049
|
-
return ['asset', 'intensity', 'level', 'rotation', '
|
|
3327
|
+
return ['asset', 'center', 'intensity', 'level', 'rotation', 'scale', 'type'];
|
|
3050
3328
|
}
|
|
3051
3329
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
3052
3330
|
switch (name) {
|
|
3053
3331
|
case 'asset':
|
|
3054
3332
|
this.asset = newValue;
|
|
3055
3333
|
break;
|
|
3334
|
+
case 'center':
|
|
3335
|
+
this.center = parseVec3(newValue);
|
|
3336
|
+
break;
|
|
3056
3337
|
case 'intensity':
|
|
3057
3338
|
this.intensity = parseFloat(newValue);
|
|
3058
3339
|
break;
|
|
3059
3340
|
case 'rotation':
|
|
3060
|
-
this.rotation = newValue
|
|
3341
|
+
this.rotation = parseVec3(newValue);
|
|
3061
3342
|
break;
|
|
3062
3343
|
case 'level':
|
|
3063
3344
|
this.level = parseInt(newValue, 10);
|
|
3064
3345
|
break;
|
|
3065
|
-
case '
|
|
3066
|
-
this.
|
|
3346
|
+
case 'scale':
|
|
3347
|
+
this.scale = parseVec3(newValue);
|
|
3348
|
+
break;
|
|
3349
|
+
case 'type':
|
|
3350
|
+
this.type = newValue;
|
|
3067
3351
|
break;
|
|
3068
3352
|
}
|
|
3069
3353
|
}
|
|
@@ -3072,6 +3356,7 @@
|
|
|
3072
3356
|
|
|
3073
3357
|
exports.AppElement = AppElement;
|
|
3074
3358
|
exports.AssetElement = AssetElement;
|
|
3359
|
+
exports.AsyncElement = AsyncElement;
|
|
3075
3360
|
exports.CameraComponentElement = CameraComponentElement;
|
|
3076
3361
|
exports.CollisionComponentElement = CollisionComponentElement;
|
|
3077
3362
|
exports.ComponentElement = ComponentElement;
|