@playcanvas/web-components 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +38 -6
- package/dist/app.d.ts +11 -0
- package/dist/components/camera-component.d.ts +37 -0
- package/dist/components/light-component.d.ts +46 -0
- package/dist/components/sound-component.d.ts +1 -1
- package/dist/entity.d.ts +7 -0
- package/dist/fog.d.ts +28 -0
- package/dist/pwc.cjs +451 -38
- package/dist/pwc.cjs.map +1 -1
- package/dist/pwc.js +451 -38
- 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 +452 -39
- package/dist/pwc.mjs.map +1 -1
- package/package.json +16 -15
- package/src/app.ts +180 -1
- package/src/components/camera-component.ts +92 -3
- package/src/components/light-component.ts +103 -3
- package/src/components/script-component.ts +22 -13
- package/src/entity.ts +88 -1
- package/src/fog.ts +121 -0
- package/src/material.ts +2 -2
package/dist/pwc.cjs
CHANGED
|
@@ -15,11 +15,11 @@ class AsyncElement extends HTMLElement {
|
|
|
15
15
|
}
|
|
16
16
|
get closestApp() {
|
|
17
17
|
var _a;
|
|
18
|
-
return (_a = this.parentElement) === null || _a ===
|
|
18
|
+
return (_a = this.parentElement) === null || _a === undefined ? undefined : _a.closest('pc-app');
|
|
19
19
|
}
|
|
20
20
|
get closestEntity() {
|
|
21
21
|
var _a;
|
|
22
|
-
return (_a = this.parentElement) === null || _a ===
|
|
22
|
+
return (_a = this.parentElement) === null || _a === undefined ? undefined : _a.closest('pc-entity');
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Called when the element is fully initialized and ready.
|
|
@@ -99,6 +99,20 @@ class AppElement extends AsyncElement {
|
|
|
99
99
|
this._stencil = true;
|
|
100
100
|
this._highResolution = false;
|
|
101
101
|
this._hierarchyReady = false;
|
|
102
|
+
this._picker = null;
|
|
103
|
+
this._hasPointerListeners = {
|
|
104
|
+
pointerenter: false,
|
|
105
|
+
pointerleave: false,
|
|
106
|
+
pointerdown: false,
|
|
107
|
+
pointerup: false,
|
|
108
|
+
pointermove: false
|
|
109
|
+
};
|
|
110
|
+
this._hoveredEntity = null;
|
|
111
|
+
this._pointerHandlers = {
|
|
112
|
+
pointermove: null,
|
|
113
|
+
pointerdown: null,
|
|
114
|
+
pointerup: null
|
|
115
|
+
};
|
|
102
116
|
/**
|
|
103
117
|
* The PlayCanvas application instance.
|
|
104
118
|
*/
|
|
@@ -128,6 +142,7 @@ class AppElement extends AsyncElement {
|
|
|
128
142
|
this.app.graphicsDevice.maxPixelRatio = this._highResolution ? window.devicePixelRatio : 1;
|
|
129
143
|
this.app.setCanvasFillMode(playcanvas.FILLMODE_FILL_WINDOW);
|
|
130
144
|
this.app.setCanvasResolution(playcanvas.RESOLUTION_AUTO);
|
|
145
|
+
this._pickerCreate();
|
|
131
146
|
// Get all pc-asset elements that are direct children of the pc-app element
|
|
132
147
|
const assetElements = this.querySelectorAll(':scope > pc-asset');
|
|
133
148
|
Array.from(assetElements).forEach((assetElement) => {
|
|
@@ -162,6 +177,7 @@ class AppElement extends AsyncElement {
|
|
|
162
177
|
});
|
|
163
178
|
}
|
|
164
179
|
disconnectedCallback() {
|
|
180
|
+
this._pickerDestroy();
|
|
165
181
|
// Clean up the application
|
|
166
182
|
if (this.app) {
|
|
167
183
|
this.app.destroy();
|
|
@@ -180,6 +196,139 @@ class AppElement extends AsyncElement {
|
|
|
180
196
|
this.app.resizeCanvas();
|
|
181
197
|
}
|
|
182
198
|
}
|
|
199
|
+
_pickerCreate() {
|
|
200
|
+
const { width, height } = this.app.graphicsDevice;
|
|
201
|
+
this._picker = new playcanvas.Picker(this.app, width, height);
|
|
202
|
+
// Create bound handlers but don't attach them yet
|
|
203
|
+
this._pointerHandlers.pointermove = this._onPointerMove.bind(this);
|
|
204
|
+
this._pointerHandlers.pointerdown = this._onPointerDown.bind(this);
|
|
205
|
+
this._pointerHandlers.pointerup = this._onPointerUp.bind(this);
|
|
206
|
+
// Listen for pointer listeners being added/removed
|
|
207
|
+
['pointermove', 'pointerdown', 'pointerup', 'pointerenter', 'pointerleave'].forEach((type) => {
|
|
208
|
+
this.addEventListener(`${type}:connect`, () => this._onPointerListenerAdded(type));
|
|
209
|
+
this.addEventListener(`${type}:disconnect`, () => this._onPointerListenerRemoved(type));
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
_pickerDestroy() {
|
|
213
|
+
if (this._canvas) {
|
|
214
|
+
Object.entries(this._pointerHandlers).forEach(([type, handler]) => {
|
|
215
|
+
if (handler) {
|
|
216
|
+
this._canvas.removeEventListener(type, handler);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
this._picker = null;
|
|
221
|
+
this._pointerHandlers = {
|
|
222
|
+
pointermove: null,
|
|
223
|
+
pointerdown: null,
|
|
224
|
+
pointerup: null
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
_onPointerMove(event) {
|
|
228
|
+
if (!this._picker || !this.app)
|
|
229
|
+
return;
|
|
230
|
+
const camera = this.app.root.findComponent('camera');
|
|
231
|
+
if (!camera)
|
|
232
|
+
return;
|
|
233
|
+
const canvasRect = this._canvas.getBoundingClientRect();
|
|
234
|
+
const x = event.clientX - canvasRect.left;
|
|
235
|
+
const y = event.clientY - canvasRect.top;
|
|
236
|
+
this._picker.prepare(camera, this.app.scene);
|
|
237
|
+
const selection = this._picker.getSelection(x, y);
|
|
238
|
+
// Get the currently hovered entity by walking up the hierarchy
|
|
239
|
+
let newHoverEntity = null;
|
|
240
|
+
if (selection.length > 0) {
|
|
241
|
+
let node = selection[0].node;
|
|
242
|
+
while (node && !newHoverEntity) {
|
|
243
|
+
const entityElement = this.querySelector(`pc-entity[name="${node.name}"]`);
|
|
244
|
+
if (entityElement) {
|
|
245
|
+
newHoverEntity = entityElement;
|
|
246
|
+
}
|
|
247
|
+
node = node.parent;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Handle enter/leave events
|
|
251
|
+
if (this._hoveredEntity !== newHoverEntity) {
|
|
252
|
+
if (this._hoveredEntity && this._hoveredEntity.hasListeners('pointerleave')) {
|
|
253
|
+
this._hoveredEntity.dispatchEvent(new PointerEvent('pointerleave', event));
|
|
254
|
+
}
|
|
255
|
+
if (newHoverEntity && newHoverEntity.hasListeners('pointerenter')) {
|
|
256
|
+
newHoverEntity.dispatchEvent(new PointerEvent('pointerenter', event));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// Update hover state
|
|
260
|
+
this._hoveredEntity = newHoverEntity;
|
|
261
|
+
// Handle pointermove event
|
|
262
|
+
if (newHoverEntity && newHoverEntity.hasListeners('pointermove')) {
|
|
263
|
+
newHoverEntity.dispatchEvent(new PointerEvent('pointermove', event));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
_onPointerDown(event) {
|
|
267
|
+
if (!this._picker || !this.app)
|
|
268
|
+
return;
|
|
269
|
+
const camera = this.app.root.findComponent('camera');
|
|
270
|
+
if (!camera)
|
|
271
|
+
return;
|
|
272
|
+
const canvasRect = this._canvas.getBoundingClientRect();
|
|
273
|
+
const x = event.clientX - canvasRect.left;
|
|
274
|
+
const y = event.clientY - canvasRect.top;
|
|
275
|
+
this._picker.prepare(camera, this.app.scene);
|
|
276
|
+
const selection = this._picker.getSelection(x, y);
|
|
277
|
+
if (selection.length > 0) {
|
|
278
|
+
let node = selection[0].node;
|
|
279
|
+
while (node) {
|
|
280
|
+
const entityElement = this.querySelector(`pc-entity[name="${node.name}"]`);
|
|
281
|
+
if (entityElement && entityElement.hasListeners('pointerdown')) {
|
|
282
|
+
entityElement.dispatchEvent(new PointerEvent('pointerdown', event));
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
node = node.parent;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
_onPointerUp(event) {
|
|
290
|
+
if (!this._picker || !this.app)
|
|
291
|
+
return;
|
|
292
|
+
const camera = this.app.root.findComponent('camera');
|
|
293
|
+
if (!camera)
|
|
294
|
+
return;
|
|
295
|
+
const canvasRect = this._canvas.getBoundingClientRect();
|
|
296
|
+
const x = event.clientX - canvasRect.left;
|
|
297
|
+
const y = event.clientY - canvasRect.top;
|
|
298
|
+
this._picker.prepare(camera, this.app.scene);
|
|
299
|
+
const selection = this._picker.getSelection(x, y);
|
|
300
|
+
if (selection.length > 0) {
|
|
301
|
+
const entityElement = this.querySelector(`pc-entity[name="${selection[0].node.name}"]`);
|
|
302
|
+
if (entityElement && entityElement.hasListeners('pointerup')) {
|
|
303
|
+
entityElement.dispatchEvent(new PointerEvent('pointerup', event));
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
_onPointerListenerAdded(type) {
|
|
308
|
+
if (!this._hasPointerListeners[type] && this._canvas) {
|
|
309
|
+
this._hasPointerListeners[type] = true;
|
|
310
|
+
// For enter/leave events, we need the move handler
|
|
311
|
+
const handler = (type === 'pointerenter' || type === 'pointerleave') ?
|
|
312
|
+
this._pointerHandlers.pointermove :
|
|
313
|
+
this._pointerHandlers[type];
|
|
314
|
+
if (handler) {
|
|
315
|
+
this._canvas.addEventListener(type === 'pointerenter' || type === 'pointerleave' ? 'pointermove' : type, handler);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
_onPointerListenerRemoved(type) {
|
|
320
|
+
const hasListeners = Array.from(this.querySelectorAll('pc-entity'))
|
|
321
|
+
.some(entity => entity.hasListeners(type));
|
|
322
|
+
if (!hasListeners && this._canvas) {
|
|
323
|
+
this._hasPointerListeners[type] = false;
|
|
324
|
+
const handler = (type === 'pointerenter' || type === 'pointerleave') ?
|
|
325
|
+
this._pointerHandlers.pointermove :
|
|
326
|
+
this._pointerHandlers[type];
|
|
327
|
+
if (handler) {
|
|
328
|
+
this._canvas.removeEventListener(type === 'pointerenter' || type === 'pointerleave' ? 'pointermove' : type, handler);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
183
332
|
/**
|
|
184
333
|
* Sets the alpha flag.
|
|
185
334
|
* @param value - The alpha flag.
|
|
@@ -532,6 +681,10 @@ class EntityElement extends AsyncElement {
|
|
|
532
681
|
* The tags of the entity.
|
|
533
682
|
*/
|
|
534
683
|
this._tags = [];
|
|
684
|
+
/**
|
|
685
|
+
* The pointer event listeners for the entity.
|
|
686
|
+
*/
|
|
687
|
+
this._listeners = {};
|
|
535
688
|
/**
|
|
536
689
|
* The PlayCanvas entity instance.
|
|
537
690
|
*/
|
|
@@ -560,12 +713,36 @@ class EntityElement extends AsyncElement {
|
|
|
560
713
|
if (tags) {
|
|
561
714
|
this.entity.tags.add(tags.split(',').map(tag => tag.trim()));
|
|
562
715
|
}
|
|
716
|
+
// Handle pointer events
|
|
717
|
+
const pointerEvents = [
|
|
718
|
+
'onpointerenter',
|
|
719
|
+
'onpointerleave',
|
|
720
|
+
'onpointerdown',
|
|
721
|
+
'onpointerup',
|
|
722
|
+
'onpointermove'
|
|
723
|
+
];
|
|
724
|
+
pointerEvents.forEach((eventName) => {
|
|
725
|
+
const handler = this.getAttribute(eventName);
|
|
726
|
+
if (handler) {
|
|
727
|
+
const eventType = eventName.substring(2); // remove 'on' prefix
|
|
728
|
+
const eventHandler = (event) => {
|
|
729
|
+
try {
|
|
730
|
+
/* eslint-disable-next-line no-new-func */
|
|
731
|
+
new Function('event', handler).call(this, event);
|
|
732
|
+
}
|
|
733
|
+
catch (e) {
|
|
734
|
+
console.error('Error in event handler:', e);
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
this.addEventListener(eventType, eventHandler);
|
|
738
|
+
}
|
|
739
|
+
});
|
|
563
740
|
}
|
|
564
741
|
buildHierarchy(app) {
|
|
565
742
|
if (!this.entity)
|
|
566
743
|
return;
|
|
567
744
|
const closestEntity = this.closestEntity;
|
|
568
|
-
if (closestEntity === null || closestEntity ===
|
|
745
|
+
if (closestEntity === null || closestEntity === undefined ? undefined : closestEntity.entity) {
|
|
569
746
|
closestEntity.entity.addChild(this.entity);
|
|
570
747
|
}
|
|
571
748
|
else {
|
|
@@ -709,7 +886,19 @@ class EntityElement extends AsyncElement {
|
|
|
709
886
|
return this._tags;
|
|
710
887
|
}
|
|
711
888
|
static get observedAttributes() {
|
|
712
|
-
return [
|
|
889
|
+
return [
|
|
890
|
+
'enabled',
|
|
891
|
+
'name',
|
|
892
|
+
'position',
|
|
893
|
+
'rotation',
|
|
894
|
+
'scale',
|
|
895
|
+
'tags',
|
|
896
|
+
'onpointerenter',
|
|
897
|
+
'onpointerleave',
|
|
898
|
+
'onpointerdown',
|
|
899
|
+
'onpointerup',
|
|
900
|
+
'onpointermove'
|
|
901
|
+
];
|
|
713
902
|
}
|
|
714
903
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
715
904
|
switch (name) {
|
|
@@ -731,7 +920,51 @@ class EntityElement extends AsyncElement {
|
|
|
731
920
|
case 'tags':
|
|
732
921
|
this.tags = newValue.split(',').map(tag => tag.trim());
|
|
733
922
|
break;
|
|
923
|
+
case 'onpointerenter':
|
|
924
|
+
case 'onpointerleave':
|
|
925
|
+
case 'onpointerdown':
|
|
926
|
+
case 'onpointerup':
|
|
927
|
+
case 'onpointermove':
|
|
928
|
+
if (newValue) {
|
|
929
|
+
const eventName = name.substring(2);
|
|
930
|
+
// Use Function.prototype.bind to avoid new Function
|
|
931
|
+
const handler = (event) => {
|
|
932
|
+
try {
|
|
933
|
+
const handlerStr = this.getAttribute(eventName) || '';
|
|
934
|
+
/* eslint-disable-next-line no-new-func */
|
|
935
|
+
new Function('event', handlerStr).call(this, event);
|
|
936
|
+
}
|
|
937
|
+
catch (e) {
|
|
938
|
+
console.error('Error in event handler:', e);
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
this.addEventListener(eventName, handler);
|
|
942
|
+
}
|
|
943
|
+
break;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
addEventListener(type, listener, options) {
|
|
947
|
+
if (!this._listeners[type]) {
|
|
948
|
+
this._listeners[type] = [];
|
|
949
|
+
}
|
|
950
|
+
this._listeners[type].push(listener);
|
|
951
|
+
super.addEventListener(type, listener, options);
|
|
952
|
+
if (type.startsWith('pointer')) {
|
|
953
|
+
this.dispatchEvent(new CustomEvent(`${type}:connect`, { bubbles: true }));
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
removeEventListener(type, listener, options) {
|
|
957
|
+
if (this._listeners[type]) {
|
|
958
|
+
this._listeners[type] = this._listeners[type].filter(l => l !== listener);
|
|
734
959
|
}
|
|
960
|
+
super.removeEventListener(type, listener, options);
|
|
961
|
+
if (type.startsWith('pointer')) {
|
|
962
|
+
this.dispatchEvent(new CustomEvent(`${type}:disconnect`, { bubbles: true }));
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
hasListeners(type) {
|
|
966
|
+
var _a;
|
|
967
|
+
return Boolean((_a = this._listeners[type]) === null || _a === undefined ? undefined : _a.length);
|
|
735
968
|
}
|
|
736
969
|
}
|
|
737
970
|
customElements.define('pc-entity', EntityElement);
|
|
@@ -780,7 +1013,7 @@ class AssetElement extends HTMLElement {
|
|
|
780
1013
|
// If no type is specified, try to infer it from the file extension.
|
|
781
1014
|
if (!type) {
|
|
782
1015
|
const ext = src.split('.').pop();
|
|
783
|
-
type = (_a = extToType.get(ext || '')) !== null && _a !==
|
|
1016
|
+
type = (_a = extToType.get(ext || '')) !== null && _a !== undefined ? _a : null;
|
|
784
1017
|
}
|
|
785
1018
|
if (!type) {
|
|
786
1019
|
console.warn(`Unsupported asset type: ${src}`);
|
|
@@ -814,7 +1047,7 @@ class AssetElement extends HTMLElement {
|
|
|
814
1047
|
}
|
|
815
1048
|
static get(id) {
|
|
816
1049
|
const assetElement = document.querySelector(`pc-asset[id="${id}"]`);
|
|
817
|
-
return assetElement === null || assetElement ===
|
|
1050
|
+
return assetElement === null || assetElement === undefined ? undefined : assetElement.asset;
|
|
818
1051
|
}
|
|
819
1052
|
static get observedAttributes() {
|
|
820
1053
|
return ['preload'];
|
|
@@ -861,7 +1094,7 @@ class ComponentElement extends AsyncElement {
|
|
|
861
1094
|
initComponent() { }
|
|
862
1095
|
async connectedCallback() {
|
|
863
1096
|
var _a;
|
|
864
|
-
await ((_a = this.closestApp) === null || _a ===
|
|
1097
|
+
await ((_a = this.closestApp) === null || _a === undefined ? undefined : _a.ready());
|
|
865
1098
|
await this.addComponent();
|
|
866
1099
|
this.initComponent();
|
|
867
1100
|
this._onReady();
|
|
@@ -927,6 +1160,15 @@ class ListenerComponentElement extends ComponentElement {
|
|
|
927
1160
|
}
|
|
928
1161
|
customElements.define('pc-listener', ListenerComponentElement);
|
|
929
1162
|
|
|
1163
|
+
const tonemaps = new Map([
|
|
1164
|
+
['none', playcanvas.TONEMAP_NONE],
|
|
1165
|
+
['linear', playcanvas.TONEMAP_LINEAR],
|
|
1166
|
+
['filmic', playcanvas.TONEMAP_FILMIC],
|
|
1167
|
+
['hejl', playcanvas.TONEMAP_HEJL],
|
|
1168
|
+
['aces', playcanvas.TONEMAP_ACES],
|
|
1169
|
+
['aces2', playcanvas.TONEMAP_ACES2],
|
|
1170
|
+
['neutral', playcanvas.TONEMAP_NEUTRAL]
|
|
1171
|
+
]);
|
|
930
1172
|
/**
|
|
931
1173
|
* The CameraComponentElement interface provides properties and methods for manipulating
|
|
932
1174
|
* `<pc-camera>` elements. The CameraComponentElement interface also inherits the properties and
|
|
@@ -947,12 +1189,15 @@ class CameraComponentElement extends ComponentElement {
|
|
|
947
1189
|
this._flipFaces = false;
|
|
948
1190
|
this._fov = 45;
|
|
949
1191
|
this._frustumCulling = true;
|
|
1192
|
+
this._gamma = 'srgb';
|
|
1193
|
+
this._horizontalFov = false;
|
|
950
1194
|
this._nearClip = 0.1;
|
|
951
1195
|
this._orthographic = false;
|
|
952
1196
|
this._orthoHeight = 10;
|
|
953
1197
|
this._priority = 0;
|
|
954
1198
|
this._rect = new playcanvas.Vec4(0, 0, 1, 1);
|
|
955
1199
|
this._scissorRect = new playcanvas.Vec4(0, 0, 1, 1);
|
|
1200
|
+
this._tonemap = 'none';
|
|
956
1201
|
}
|
|
957
1202
|
getInitialComponentData() {
|
|
958
1203
|
return {
|
|
@@ -965,17 +1210,20 @@ class CameraComponentElement extends ComponentElement {
|
|
|
965
1210
|
flipFaces: this._flipFaces,
|
|
966
1211
|
fov: this._fov,
|
|
967
1212
|
frustumCulling: this._frustumCulling,
|
|
1213
|
+
gammaCorrection: this._gamma === 'srgb' ? playcanvas.GAMMA_SRGB : playcanvas.GAMMA_NONE,
|
|
1214
|
+
horizontalFov: this._horizontalFov,
|
|
968
1215
|
nearClip: this._nearClip,
|
|
969
1216
|
orthographic: this._orthographic,
|
|
970
1217
|
orthoHeight: this._orthoHeight,
|
|
971
1218
|
priority: this._priority,
|
|
972
1219
|
rect: this._rect,
|
|
973
|
-
scissorRect: this._scissorRect
|
|
1220
|
+
scissorRect: this._scissorRect,
|
|
1221
|
+
toneMapping: tonemaps.get(this._tonemap)
|
|
974
1222
|
};
|
|
975
1223
|
}
|
|
976
1224
|
get xrAvailable() {
|
|
977
1225
|
var _a;
|
|
978
|
-
const xrManager = (_a = this.component) === null || _a ===
|
|
1226
|
+
const xrManager = (_a = this.component) === null || _a === undefined ? undefined : _a.system.app.xr;
|
|
979
1227
|
return xrManager && xrManager.supported && xrManager.isAvailable(playcanvas.XRTYPE_VR);
|
|
980
1228
|
}
|
|
981
1229
|
startXr(type, space) {
|
|
@@ -1153,6 +1401,41 @@ class CameraComponentElement extends ComponentElement {
|
|
|
1153
1401
|
get frustumCulling() {
|
|
1154
1402
|
return this._frustumCulling;
|
|
1155
1403
|
}
|
|
1404
|
+
/**
|
|
1405
|
+
* Sets the gamma correction of the camera.
|
|
1406
|
+
* @param value - The gamma correction.
|
|
1407
|
+
*/
|
|
1408
|
+
set gamma(value) {
|
|
1409
|
+
this._gamma = value;
|
|
1410
|
+
if (this.component) {
|
|
1411
|
+
this.component.gammaCorrection = value === 'srgb' ? playcanvas.GAMMA_SRGB : playcanvas.GAMMA_NONE;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Gets the gamma correction of the camera.
|
|
1416
|
+
* @returns The gamma correction.
|
|
1417
|
+
*/
|
|
1418
|
+
get gamma() {
|
|
1419
|
+
return this._gamma;
|
|
1420
|
+
}
|
|
1421
|
+
/**
|
|
1422
|
+
* Sets whether the camera's field of view (fov) is horizontal or vertical. Defaults to false
|
|
1423
|
+
* (meaning it is vertical be default).
|
|
1424
|
+
* @param value - Whether the camera's field of view is horizontal.
|
|
1425
|
+
*/
|
|
1426
|
+
set horizontalFov(value) {
|
|
1427
|
+
this._horizontalFov = value;
|
|
1428
|
+
if (this.component) {
|
|
1429
|
+
this.component.horizontalFov = value;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Gets whether the camera's field of view (fov) is horizontal or vertical.
|
|
1434
|
+
* @returns Whether the camera's field of view is horizontal.
|
|
1435
|
+
*/
|
|
1436
|
+
get horizontalFov() {
|
|
1437
|
+
return this._horizontalFov;
|
|
1438
|
+
}
|
|
1156
1439
|
/**
|
|
1157
1440
|
* Sets the near clip distance of the camera.
|
|
1158
1441
|
* @param value - The near clip distance.
|
|
@@ -1255,6 +1538,24 @@ class CameraComponentElement extends ComponentElement {
|
|
|
1255
1538
|
get scissorRect() {
|
|
1256
1539
|
return this._scissorRect;
|
|
1257
1540
|
}
|
|
1541
|
+
/**
|
|
1542
|
+
* Sets the tone mapping of the camera.
|
|
1543
|
+
* @param value - The tone mapping.
|
|
1544
|
+
*/
|
|
1545
|
+
set tonemap(value) {
|
|
1546
|
+
var _a;
|
|
1547
|
+
this._tonemap = value;
|
|
1548
|
+
if (this.component) {
|
|
1549
|
+
this.component.toneMapping = (_a = tonemaps.get(value)) !== null && _a !== undefined ? _a : playcanvas.TONEMAP_NONE;
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Gets the tone mapping of the camera.
|
|
1554
|
+
* @returns The tone mapping.
|
|
1555
|
+
*/
|
|
1556
|
+
get tonemap() {
|
|
1557
|
+
return this._tonemap;
|
|
1558
|
+
}
|
|
1258
1559
|
static get observedAttributes() {
|
|
1259
1560
|
return [
|
|
1260
1561
|
...super.observedAttributes,
|
|
@@ -1267,12 +1568,15 @@ class CameraComponentElement extends ComponentElement {
|
|
|
1267
1568
|
'flip-faces',
|
|
1268
1569
|
'fov',
|
|
1269
1570
|
'frustum-culling',
|
|
1571
|
+
'gamma',
|
|
1572
|
+
'horizontal-fov',
|
|
1270
1573
|
'near-clip',
|
|
1271
1574
|
'orthographic',
|
|
1272
1575
|
'ortho-height',
|
|
1273
1576
|
'priority',
|
|
1274
1577
|
'rect',
|
|
1275
|
-
'scissor-rect'
|
|
1578
|
+
'scissor-rect',
|
|
1579
|
+
'tonemap'
|
|
1276
1580
|
];
|
|
1277
1581
|
}
|
|
1278
1582
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
@@ -1305,6 +1609,12 @@ class CameraComponentElement extends ComponentElement {
|
|
|
1305
1609
|
case 'frustum-culling':
|
|
1306
1610
|
this.frustumCulling = newValue !== 'false';
|
|
1307
1611
|
break;
|
|
1612
|
+
case 'gamma':
|
|
1613
|
+
this.gamma = newValue;
|
|
1614
|
+
break;
|
|
1615
|
+
case 'horizontal-fov':
|
|
1616
|
+
this.horizontalFov = this.hasAttribute('horizontal-fov');
|
|
1617
|
+
break;
|
|
1308
1618
|
case 'near-clip':
|
|
1309
1619
|
this.nearClip = parseFloat(newValue);
|
|
1310
1620
|
break;
|
|
@@ -1323,6 +1633,9 @@ class CameraComponentElement extends ComponentElement {
|
|
|
1323
1633
|
case 'scissor-rect':
|
|
1324
1634
|
this.scissorRect = parseVec4(newValue);
|
|
1325
1635
|
break;
|
|
1636
|
+
case 'tonemap':
|
|
1637
|
+
this.tonemap = newValue;
|
|
1638
|
+
break;
|
|
1326
1639
|
}
|
|
1327
1640
|
}
|
|
1328
1641
|
}
|
|
@@ -1736,6 +2049,17 @@ class GSplatComponentElement extends ComponentElement {
|
|
|
1736
2049
|
}
|
|
1737
2050
|
customElements.define('pc-splat', GSplatComponentElement);
|
|
1738
2051
|
|
|
2052
|
+
const shadowTypes = new Map([
|
|
2053
|
+
['pcf1-16f', playcanvas.SHADOW_PCF1_16F],
|
|
2054
|
+
['pcf1-32f', playcanvas.SHADOW_PCF1_32F],
|
|
2055
|
+
['pcf3-16f', playcanvas.SHADOW_PCF3_16F],
|
|
2056
|
+
['pcf3-32f', playcanvas.SHADOW_PCF3_32F],
|
|
2057
|
+
['pcf5-16f', playcanvas.SHADOW_PCF5_16F],
|
|
2058
|
+
['pcf5-32f', playcanvas.SHADOW_PCF5_32F],
|
|
2059
|
+
['vsm-16f', playcanvas.SHADOW_VSM_16F],
|
|
2060
|
+
['vsm-32f', playcanvas.SHADOW_VSM_32F],
|
|
2061
|
+
['pcss-32f', playcanvas.SHADOW_PCSS_32F]
|
|
2062
|
+
]);
|
|
1739
2063
|
/**
|
|
1740
2064
|
* The LightComponentElement interface provides properties and methods for manipulating
|
|
1741
2065
|
* `<pc-light>` elements. The LightComponentElement interface also inherits the properties and
|
|
@@ -1756,8 +2080,11 @@ class LightComponentElement extends ComponentElement {
|
|
|
1756
2080
|
this._range = 10;
|
|
1757
2081
|
this._shadowBias = 0.2;
|
|
1758
2082
|
this._shadowDistance = 16;
|
|
2083
|
+
this._shadowIntensity = 1;
|
|
1759
2084
|
this._shadowResolution = 1024;
|
|
2085
|
+
this._shadowType = 'pcf3-32f';
|
|
1760
2086
|
this._type = 'directional';
|
|
2087
|
+
this._vsmBias = 0.01;
|
|
1761
2088
|
}
|
|
1762
2089
|
getInitialComponentData() {
|
|
1763
2090
|
return {
|
|
@@ -1770,8 +2097,11 @@ class LightComponentElement extends ComponentElement {
|
|
|
1770
2097
|
range: this._range,
|
|
1771
2098
|
shadowBias: this._shadowBias,
|
|
1772
2099
|
shadowDistance: this._shadowDistance,
|
|
2100
|
+
shadowIntensity: this._shadowIntensity,
|
|
1773
2101
|
shadowResolution: this._shadowResolution,
|
|
1774
|
-
|
|
2102
|
+
shadowType: shadowTypes.get(this._shadowType),
|
|
2103
|
+
type: this._type,
|
|
2104
|
+
vsmBias: this._vsmBias
|
|
1775
2105
|
};
|
|
1776
2106
|
}
|
|
1777
2107
|
/**
|
|
@@ -1934,6 +2264,23 @@ class LightComponentElement extends ComponentElement {
|
|
|
1934
2264
|
get shadowDistance() {
|
|
1935
2265
|
return this._shadowDistance;
|
|
1936
2266
|
}
|
|
2267
|
+
/**
|
|
2268
|
+
* Sets the shadow intensity of the light.
|
|
2269
|
+
* @param value - The shadow intensity.
|
|
2270
|
+
*/
|
|
2271
|
+
set shadowIntensity(value) {
|
|
2272
|
+
this._shadowIntensity = value;
|
|
2273
|
+
if (this.component) {
|
|
2274
|
+
this.component.shadowIntensity = value;
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
/**
|
|
2278
|
+
* Gets the shadow intensity of the light.
|
|
2279
|
+
* @returns The shadow intensity.
|
|
2280
|
+
*/
|
|
2281
|
+
get shadowIntensity() {
|
|
2282
|
+
return this._shadowIntensity;
|
|
2283
|
+
}
|
|
1937
2284
|
/**
|
|
1938
2285
|
* Sets the shadow resolution of the light.
|
|
1939
2286
|
* @param value - The shadow resolution.
|
|
@@ -1951,6 +2298,34 @@ class LightComponentElement extends ComponentElement {
|
|
|
1951
2298
|
get shadowResolution() {
|
|
1952
2299
|
return this._shadowResolution;
|
|
1953
2300
|
}
|
|
2301
|
+
/**
|
|
2302
|
+
* Sets the shadow type of the light.
|
|
2303
|
+
* @param value - The shadow type. Can be:
|
|
2304
|
+
*
|
|
2305
|
+
* - `pcf1-16f` - 1-tap percentage-closer filtered shadow map with 16-bit depth.
|
|
2306
|
+
* - `pcf1-32f` - 1-tap percentage-closer filtered shadow map with 32-bit depth.
|
|
2307
|
+
* - `pcf3-16f` - 3-tap percentage-closer filtered shadow map with 16-bit depth.
|
|
2308
|
+
* - `pcf3-32f` - 3-tap percentage-closer filtered shadow map with 32-bit depth.
|
|
2309
|
+
* - `pcf5-16f` - 5-tap percentage-closer filtered shadow map with 16-bit depth.
|
|
2310
|
+
* - `pcf5-32f` - 5-tap percentage-closer filtered shadow map with 32-bit depth.
|
|
2311
|
+
* - `vsm-16f` - Variance shadow map with 16-bit depth.
|
|
2312
|
+
* - `vsm-32f` - Variance shadow map with 32-bit depth.
|
|
2313
|
+
* - `pcss-32f` - Percentage-closer soft shadow with 32-bit depth.
|
|
2314
|
+
*/
|
|
2315
|
+
set shadowType(value) {
|
|
2316
|
+
var _a;
|
|
2317
|
+
this._shadowType = value;
|
|
2318
|
+
if (this.component) {
|
|
2319
|
+
this.component.shadowType = (_a = shadowTypes.get(value)) !== null && _a !== undefined ? _a : playcanvas.SHADOW_PCF3_32F;
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
/**
|
|
2323
|
+
* Gets the shadow type of the light.
|
|
2324
|
+
* @returns The shadow type.
|
|
2325
|
+
*/
|
|
2326
|
+
get shadowType() {
|
|
2327
|
+
return this._shadowType;
|
|
2328
|
+
}
|
|
1954
2329
|
/**
|
|
1955
2330
|
* Sets the type of the light.
|
|
1956
2331
|
* @param value - The type.
|
|
@@ -1972,6 +2347,23 @@ class LightComponentElement extends ComponentElement {
|
|
|
1972
2347
|
get type() {
|
|
1973
2348
|
return this._type;
|
|
1974
2349
|
}
|
|
2350
|
+
/**
|
|
2351
|
+
* Sets the VSM bias of the light.
|
|
2352
|
+
* @param value - The VSM bias.
|
|
2353
|
+
*/
|
|
2354
|
+
set vsmBias(value) {
|
|
2355
|
+
this._vsmBias = value;
|
|
2356
|
+
if (this.component) {
|
|
2357
|
+
this.component.vsmBias = value;
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
/**
|
|
2361
|
+
* Gets the VSM bias of the light.
|
|
2362
|
+
* @returns The VSM bias.
|
|
2363
|
+
*/
|
|
2364
|
+
get vsmBias() {
|
|
2365
|
+
return this._vsmBias;
|
|
2366
|
+
}
|
|
1975
2367
|
static get observedAttributes() {
|
|
1976
2368
|
return [
|
|
1977
2369
|
...super.observedAttributes,
|
|
@@ -1984,8 +2376,11 @@ class LightComponentElement extends ComponentElement {
|
|
|
1984
2376
|
'range',
|
|
1985
2377
|
'shadow-bias',
|
|
1986
2378
|
'shadow-distance',
|
|
2379
|
+
'shadow-intensity',
|
|
1987
2380
|
'shadow-resolution',
|
|
1988
|
-
'type'
|
|
2381
|
+
'shadow-type',
|
|
2382
|
+
'type',
|
|
2383
|
+
'vsm-bias'
|
|
1989
2384
|
];
|
|
1990
2385
|
}
|
|
1991
2386
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
@@ -2021,9 +2416,18 @@ class LightComponentElement extends ComponentElement {
|
|
|
2021
2416
|
case 'shadow-resolution':
|
|
2022
2417
|
this.shadowResolution = Number(newValue);
|
|
2023
2418
|
break;
|
|
2419
|
+
case 'shadow-intensity':
|
|
2420
|
+
this.shadowIntensity = Number(newValue);
|
|
2421
|
+
break;
|
|
2422
|
+
case 'shadow-type':
|
|
2423
|
+
this.shadowType = newValue;
|
|
2424
|
+
break;
|
|
2024
2425
|
case 'type':
|
|
2025
2426
|
this.type = newValue;
|
|
2026
2427
|
break;
|
|
2428
|
+
case 'vsm-bias':
|
|
2429
|
+
this.vsmBias = Number(newValue);
|
|
2430
|
+
break;
|
|
2027
2431
|
}
|
|
2028
2432
|
}
|
|
2029
2433
|
}
|
|
@@ -2046,8 +2450,8 @@ class MaterialElement extends HTMLElement {
|
|
|
2046
2450
|
}
|
|
2047
2451
|
createMaterial() {
|
|
2048
2452
|
this.material = new playcanvas.StandardMaterial();
|
|
2049
|
-
this.material.glossInvert =
|
|
2050
|
-
this.material.useMetalness =
|
|
2453
|
+
this.material.glossInvert = false;
|
|
2454
|
+
this.material.useMetalness = false;
|
|
2051
2455
|
this.material.diffuse = this._diffuse;
|
|
2052
2456
|
this.diffuseMap = this._diffuseMap;
|
|
2053
2457
|
this.metalnessMap = this._metalnessMap;
|
|
@@ -2118,7 +2522,7 @@ class MaterialElement extends HTMLElement {
|
|
|
2118
2522
|
}
|
|
2119
2523
|
static get(id) {
|
|
2120
2524
|
const materialElement = document.querySelector(`pc-material[id="${id}"]`);
|
|
2121
|
-
return materialElement === null || materialElement ===
|
|
2525
|
+
return materialElement === null || materialElement === undefined ? undefined : materialElement.material;
|
|
2122
2526
|
}
|
|
2123
2527
|
static get observedAttributes() {
|
|
2124
2528
|
return ['diffuse', 'diffuse-map', 'metalness-map', 'normal-map', 'roughness-map'];
|
|
@@ -2580,9 +2984,6 @@ class ScreenComponentElement extends ComponentElement {
|
|
|
2580
2984
|
}
|
|
2581
2985
|
customElements.define('pc-screen', ScreenComponentElement);
|
|
2582
2986
|
|
|
2583
|
-
const tmpV2 = new playcanvas.Vec2();
|
|
2584
|
-
const tmpV3 = new playcanvas.Vec3();
|
|
2585
|
-
const tmpV4 = new playcanvas.Vec4();
|
|
2586
2987
|
/**
|
|
2587
2988
|
* The ScriptComponentElement interface provides properties and methods for manipulating
|
|
2588
2989
|
* `<pc-scripts>` elements. The ScriptComponentElement interface also inherits the properties and
|
|
@@ -2626,22 +3027,34 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
2626
3027
|
return;
|
|
2627
3028
|
}
|
|
2628
3029
|
}
|
|
2629
|
-
// Handle
|
|
2630
|
-
if (Array.isArray(value)) {
|
|
2631
|
-
|
|
2632
|
-
|
|
3030
|
+
// Handle arrays
|
|
3031
|
+
if (value && typeof value === 'object' && Array.isArray(value)) {
|
|
3032
|
+
// If it's an array of objects, recursively apply to each object
|
|
3033
|
+
if (value.length > 0 && typeof value[0] === 'object') {
|
|
3034
|
+
target[key] = value.map((item) => {
|
|
3035
|
+
const obj = {};
|
|
3036
|
+
for (const itemKey in item) {
|
|
3037
|
+
applyValue(obj, itemKey, item[itemKey]);
|
|
3038
|
+
}
|
|
3039
|
+
return obj;
|
|
3040
|
+
});
|
|
3041
|
+
return;
|
|
3042
|
+
}
|
|
3043
|
+
// Handle vectors
|
|
3044
|
+
if (value.length === 2 && typeof value[0] === 'number') {
|
|
3045
|
+
target[key] = new playcanvas.Vec2(value[0], value[1]);
|
|
2633
3046
|
return;
|
|
2634
3047
|
}
|
|
2635
|
-
if (
|
|
2636
|
-
target[key] =
|
|
3048
|
+
if (value.length === 3 && typeof value[0] === 'number') {
|
|
3049
|
+
target[key] = new playcanvas.Vec3(value[0], value[1], value[2]);
|
|
2637
3050
|
return;
|
|
2638
3051
|
}
|
|
2639
|
-
if (
|
|
2640
|
-
target[key] =
|
|
3052
|
+
if (value.length === 4 && typeof value[0] === 'number') {
|
|
3053
|
+
target[key] = new playcanvas.Vec4(value[0], value[1], value[2], value[3]);
|
|
2641
3054
|
return;
|
|
2642
3055
|
}
|
|
2643
3056
|
}
|
|
2644
|
-
// Handle nested objects
|
|
3057
|
+
// Handle nested objects (non-array)
|
|
2645
3058
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
2646
3059
|
if (!target[key] || typeof target[key] !== 'object') {
|
|
2647
3060
|
target[key] = {};
|
|
@@ -2721,7 +3134,7 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
2721
3134
|
disconnectedCallback() {
|
|
2722
3135
|
var _a;
|
|
2723
3136
|
this.observer.disconnect();
|
|
2724
|
-
(_a = super.disconnectedCallback) === null || _a ===
|
|
3137
|
+
(_a = super.disconnectedCallback) === null || _a === undefined ? undefined : _a.call(this);
|
|
2725
3138
|
}
|
|
2726
3139
|
/**
|
|
2727
3140
|
* Gets the script component.
|
|
@@ -3035,7 +3448,7 @@ class SoundSlotElement extends AsyncElement {
|
|
|
3035
3448
|
}
|
|
3036
3449
|
async connectedCallback() {
|
|
3037
3450
|
var _a;
|
|
3038
|
-
await ((_a = this.soundElement) === null || _a ===
|
|
3451
|
+
await ((_a = this.soundElement) === null || _a === undefined ? undefined : _a.ready());
|
|
3039
3452
|
const options = {
|
|
3040
3453
|
autoPlay: this._autoPlay,
|
|
3041
3454
|
loop: this._loop,
|
|
@@ -3071,7 +3484,7 @@ class SoundSlotElement extends AsyncElement {
|
|
|
3071
3484
|
var _a;
|
|
3072
3485
|
this._asset = value;
|
|
3073
3486
|
if (this.soundSlot) {
|
|
3074
|
-
const id = (_a = AssetElement.get(value)) === null || _a ===
|
|
3487
|
+
const id = (_a = AssetElement.get(value)) === null || _a === undefined ? undefined : _a.id;
|
|
3075
3488
|
if (id) {
|
|
3076
3489
|
this.soundSlot.asset = id;
|
|
3077
3490
|
}
|
|
@@ -3298,8 +3711,8 @@ class ModelElement extends AsyncElement {
|
|
|
3298
3711
|
async _loadModel() {
|
|
3299
3712
|
var _a;
|
|
3300
3713
|
this._unloadModel();
|
|
3301
|
-
const appElement = await ((_a = this.closestApp) === null || _a ===
|
|
3302
|
-
const app = appElement === null || appElement ===
|
|
3714
|
+
const appElement = await ((_a = this.closestApp) === null || _a === undefined ? undefined : _a.ready());
|
|
3715
|
+
const app = appElement === null || appElement === undefined ? undefined : appElement.app;
|
|
3303
3716
|
const asset = AssetElement.get(this._asset);
|
|
3304
3717
|
if (!asset) {
|
|
3305
3718
|
return;
|
|
@@ -3316,7 +3729,7 @@ class ModelElement extends AsyncElement {
|
|
|
3316
3729
|
}
|
|
3317
3730
|
_unloadModel() {
|
|
3318
3731
|
var _a;
|
|
3319
|
-
(_a = this._entity) === null || _a ===
|
|
3732
|
+
(_a = this._entity) === null || _a === undefined ? undefined : _a.destroy();
|
|
3320
3733
|
this._entity = null;
|
|
3321
3734
|
}
|
|
3322
3735
|
/**
|
|
@@ -3384,7 +3797,7 @@ class SceneElement extends AsyncElement {
|
|
|
3384
3797
|
}
|
|
3385
3798
|
async connectedCallback() {
|
|
3386
3799
|
var _a;
|
|
3387
|
-
await ((_a = this.closestApp) === null || _a ===
|
|
3800
|
+
await ((_a = this.closestApp) === null || _a === undefined ? undefined : _a.ready());
|
|
3388
3801
|
this.scene = this.closestApp.app.scene;
|
|
3389
3802
|
this.updateSceneSettings();
|
|
3390
3803
|
this._onReady();
|
|
@@ -3558,8 +3971,8 @@ class SkyElement extends AsyncElement {
|
|
|
3558
3971
|
}
|
|
3559
3972
|
async _loadSkybox() {
|
|
3560
3973
|
var _a;
|
|
3561
|
-
const appElement = await ((_a = this.closestApp) === null || _a ===
|
|
3562
|
-
const app = appElement === null || appElement ===
|
|
3974
|
+
const appElement = await ((_a = this.closestApp) === null || _a === undefined ? undefined : _a.ready());
|
|
3975
|
+
const app = appElement === null || appElement === undefined ? undefined : appElement.app;
|
|
3563
3976
|
if (!app) {
|
|
3564
3977
|
return;
|
|
3565
3978
|
}
|
|
@@ -3582,10 +3995,10 @@ class SkyElement extends AsyncElement {
|
|
|
3582
3995
|
var _a, _b;
|
|
3583
3996
|
if (!this._scene)
|
|
3584
3997
|
return;
|
|
3585
|
-
(_a = this._scene.skybox) === null || _a ===
|
|
3998
|
+
(_a = this._scene.skybox) === null || _a === undefined ? undefined : _a.destroy();
|
|
3586
3999
|
// @ts-ignore
|
|
3587
4000
|
this._scene.skybox = null;
|
|
3588
|
-
(_b = this._scene.envAtlas) === null || _b ===
|
|
4001
|
+
(_b = this._scene.envAtlas) === null || _b === undefined ? undefined : _b.destroy();
|
|
3589
4002
|
// @ts-ignore
|
|
3590
4003
|
this._scene.envAtlas = null;
|
|
3591
4004
|
this._scene = null;
|