@playcanvas/web-components 0.1.8 → 0.1.10
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 +2 -2
- package/dist/app.d.ts +21 -1
- package/dist/asset.d.ts +3 -1
- package/dist/async-element.d.ts +2 -1
- package/dist/components/camera-component.d.ts +28 -4
- package/dist/components/collision-component.d.ts +4 -4
- package/dist/components/component.d.ts +3 -1
- package/dist/components/element-component.d.ts +4 -1
- package/dist/components/gsplat-component.d.ts +4 -1
- package/dist/components/light-component.d.ts +50 -4
- package/dist/components/listener-component.d.ts +4 -1
- package/dist/components/render-component.d.ts +4 -1
- package/dist/components/rigidbody-component.d.ts +4 -4
- package/dist/components/screen-component.d.ts +4 -1
- package/dist/components/script-component.d.ts +4 -1
- package/dist/components/script.d.ts +3 -1
- package/dist/components/sound-component.d.ts +5 -2
- package/dist/components/sound-slot.d.ts +3 -1
- package/dist/entity.d.ts +14 -3
- package/dist/fog.d.ts +28 -0
- package/dist/material.d.ts +3 -1
- package/dist/model.d.ts +3 -1
- package/dist/module.d.ts +6 -0
- package/dist/pwc.cjs +569 -96
- package/dist/pwc.cjs.map +1 -1
- package/dist/pwc.js +569 -96
- 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 +570 -97
- package/dist/pwc.mjs.map +1 -1
- package/dist/scene.d.ts +3 -1
- package/dist/sky.d.ts +3 -1
- package/package.json +10 -9
- package/src/app.ts +208 -2
- package/src/asset.ts +3 -1
- package/src/async-element.ts +2 -1
- package/src/components/camera-component.ts +69 -7
- package/src/components/collision-component.ts +4 -4
- package/src/components/component.ts +3 -1
- package/src/components/element-component.ts +4 -2
- package/src/components/gsplat-component.ts +4 -1
- package/src/components/light-component.ts +107 -7
- package/src/components/listener-component.ts +4 -1
- package/src/components/render-component.ts +4 -1
- package/src/components/rigidbody-component.ts +4 -4
- package/src/components/screen-component.ts +4 -1
- package/src/components/script-component.ts +26 -14
- package/src/components/script.ts +3 -1
- package/src/components/sound-component.ts +4 -1
- package/src/components/sound-slot.ts +3 -1
- package/src/entity.ts +149 -32
- package/src/fog.ts +121 -0
- package/src/material.ts +5 -3
- package/src/model.ts +3 -1
- package/src/module.ts +6 -0
- package/src/scene.ts +13 -11
- package/src/sky.ts +3 -1
package/src/app.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Application, FILLMODE_FILL_WINDOW, Keyboard, Mouse, RESOLUTION_AUTO } from 'playcanvas';
|
|
1
|
+
import { Application, CameraComponent, FILLMODE_FILL_WINDOW, Keyboard, Mouse, Picker, RESOLUTION_AUTO } from 'playcanvas';
|
|
2
2
|
|
|
3
3
|
import { AssetElement } from './asset';
|
|
4
4
|
import { AsyncElement } from './async-element';
|
|
5
|
+
import { EntityElement } from './entity';
|
|
5
6
|
import { MaterialElement } from './material';
|
|
6
7
|
import { ModuleElement } from './module';
|
|
7
8
|
|
|
@@ -24,13 +25,35 @@ class AppElement extends AsyncElement {
|
|
|
24
25
|
|
|
25
26
|
private _highResolution = false;
|
|
26
27
|
|
|
28
|
+
private _hierarchyReady = false;
|
|
29
|
+
|
|
30
|
+
private _picker: Picker | null = null;
|
|
31
|
+
|
|
32
|
+
private _hasPointerListeners: { [key: string]: boolean } = {
|
|
33
|
+
pointerenter: false,
|
|
34
|
+
pointerleave: false,
|
|
35
|
+
pointerdown: false,
|
|
36
|
+
pointerup: false,
|
|
37
|
+
pointermove: false
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
private _hoveredEntity: EntityElement | null = null;
|
|
41
|
+
|
|
42
|
+
private _pointerHandlers: { [key: string]: EventListener | null } = {
|
|
43
|
+
pointermove: null,
|
|
44
|
+
pointerdown: null,
|
|
45
|
+
pointerup: null
|
|
46
|
+
};
|
|
47
|
+
|
|
27
48
|
/**
|
|
28
49
|
* The PlayCanvas application instance.
|
|
29
50
|
*/
|
|
30
51
|
app: Application | null = null;
|
|
31
52
|
|
|
32
53
|
/**
|
|
33
|
-
* Creates a new AppElement.
|
|
54
|
+
* Creates a new AppElement instance.
|
|
55
|
+
*
|
|
56
|
+
* @ignore
|
|
34
57
|
*/
|
|
35
58
|
constructor() {
|
|
36
59
|
super();
|
|
@@ -66,6 +89,8 @@ class AppElement extends AsyncElement {
|
|
|
66
89
|
this.app.setCanvasFillMode(FILLMODE_FILL_WINDOW);
|
|
67
90
|
this.app.setCanvasResolution(RESOLUTION_AUTO);
|
|
68
91
|
|
|
92
|
+
this._pickerCreate();
|
|
93
|
+
|
|
69
94
|
// Get all pc-asset elements that are direct children of the pc-app element
|
|
70
95
|
const assetElements = this.querySelectorAll<AssetElement>(':scope > pc-asset');
|
|
71
96
|
Array.from(assetElements).forEach((assetElement) => {
|
|
@@ -82,6 +107,19 @@ class AppElement extends AsyncElement {
|
|
|
82
107
|
materialElement.createMaterial();
|
|
83
108
|
});
|
|
84
109
|
|
|
110
|
+
// Create all entities
|
|
111
|
+
const entityElements = this.querySelectorAll<EntityElement>('pc-entity');
|
|
112
|
+
Array.from(entityElements).forEach((entityElement) => {
|
|
113
|
+
entityElement.createEntity(this.app!);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Build hierarchy
|
|
117
|
+
entityElements.forEach((entityElement) => {
|
|
118
|
+
entityElement.buildHierarchy(this.app!);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
this._hierarchyReady = true;
|
|
122
|
+
|
|
85
123
|
// Load assets before starting the application
|
|
86
124
|
this.app.preload(() => {
|
|
87
125
|
// Start the application
|
|
@@ -95,6 +133,8 @@ class AppElement extends AsyncElement {
|
|
|
95
133
|
}
|
|
96
134
|
|
|
97
135
|
disconnectedCallback() {
|
|
136
|
+
this._pickerDestroy();
|
|
137
|
+
|
|
98
138
|
// Clean up the application
|
|
99
139
|
if (this.app) {
|
|
100
140
|
this.app.destroy();
|
|
@@ -117,6 +157,163 @@ class AppElement extends AsyncElement {
|
|
|
117
157
|
}
|
|
118
158
|
}
|
|
119
159
|
|
|
160
|
+
_pickerCreate() {
|
|
161
|
+
const { width, height } = this.app!.graphicsDevice;
|
|
162
|
+
this._picker = new Picker(this.app!, width, height);
|
|
163
|
+
|
|
164
|
+
// Create bound handlers but don't attach them yet
|
|
165
|
+
this._pointerHandlers.pointermove = this._onPointerMove.bind(this) as EventListener;
|
|
166
|
+
this._pointerHandlers.pointerdown = this._onPointerDown.bind(this) as EventListener;
|
|
167
|
+
this._pointerHandlers.pointerup = this._onPointerUp.bind(this) as EventListener;
|
|
168
|
+
|
|
169
|
+
// Listen for pointer listeners being added/removed
|
|
170
|
+
['pointermove', 'pointerdown', 'pointerup', 'pointerenter', 'pointerleave'].forEach((type) => {
|
|
171
|
+
this.addEventListener(`${type}:connect`, () => this._onPointerListenerAdded(type));
|
|
172
|
+
this.addEventListener(`${type}:disconnect`, () => this._onPointerListenerRemoved(type));
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
_pickerDestroy() {
|
|
177
|
+
if (this._canvas) {
|
|
178
|
+
Object.entries(this._pointerHandlers).forEach(([type, handler]) => {
|
|
179
|
+
if (handler) {
|
|
180
|
+
this._canvas!.removeEventListener(type, handler);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
this._picker = null;
|
|
186
|
+
this._pointerHandlers = {
|
|
187
|
+
pointermove: null,
|
|
188
|
+
pointerdown: null,
|
|
189
|
+
pointerup: null
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
_onPointerMove(event: PointerEvent) {
|
|
194
|
+
if (!this._picker || !this.app) return;
|
|
195
|
+
|
|
196
|
+
const camera = this.app!.root.findComponent('camera') as CameraComponent;
|
|
197
|
+
if (!camera) return;
|
|
198
|
+
|
|
199
|
+
const canvasRect = this._canvas!.getBoundingClientRect();
|
|
200
|
+
const x = event.clientX - canvasRect.left;
|
|
201
|
+
const y = event.clientY - canvasRect.top;
|
|
202
|
+
|
|
203
|
+
this._picker.prepare(camera, this.app!.scene);
|
|
204
|
+
const selection = this._picker.getSelection(x, y);
|
|
205
|
+
|
|
206
|
+
// Get the currently hovered entity by walking up the hierarchy
|
|
207
|
+
let newHoverEntity = null;
|
|
208
|
+
if (selection.length > 0) {
|
|
209
|
+
let node = selection[0].node;
|
|
210
|
+
while (node && !newHoverEntity) {
|
|
211
|
+
const entityElement = this.querySelector(`pc-entity[name="${node.name}"]`) as EntityElement;
|
|
212
|
+
if (entityElement) {
|
|
213
|
+
newHoverEntity = entityElement;
|
|
214
|
+
}
|
|
215
|
+
node = node.parent;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Handle enter/leave events
|
|
220
|
+
if (this._hoveredEntity !== newHoverEntity) {
|
|
221
|
+
if (this._hoveredEntity && this._hoveredEntity.hasListeners('pointerleave')) {
|
|
222
|
+
this._hoveredEntity.dispatchEvent(new PointerEvent('pointerleave', event));
|
|
223
|
+
}
|
|
224
|
+
if (newHoverEntity && newHoverEntity.hasListeners('pointerenter')) {
|
|
225
|
+
newHoverEntity.dispatchEvent(new PointerEvent('pointerenter', event));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Update hover state
|
|
230
|
+
this._hoveredEntity = newHoverEntity;
|
|
231
|
+
|
|
232
|
+
// Handle pointermove event
|
|
233
|
+
if (newHoverEntity && newHoverEntity.hasListeners('pointermove')) {
|
|
234
|
+
newHoverEntity.dispatchEvent(new PointerEvent('pointermove', event));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
_onPointerDown(event: PointerEvent) {
|
|
239
|
+
if (!this._picker || !this.app) return;
|
|
240
|
+
|
|
241
|
+
const camera = this.app!.root.findComponent('camera') as CameraComponent;
|
|
242
|
+
if (!camera) return;
|
|
243
|
+
|
|
244
|
+
const canvasRect = this._canvas!.getBoundingClientRect();
|
|
245
|
+
const x = event.clientX - canvasRect.left;
|
|
246
|
+
const y = event.clientY - canvasRect.top;
|
|
247
|
+
|
|
248
|
+
this._picker.prepare(camera, this.app!.scene);
|
|
249
|
+
const selection = this._picker.getSelection(x, y);
|
|
250
|
+
|
|
251
|
+
if (selection.length > 0) {
|
|
252
|
+
let node = selection[0].node;
|
|
253
|
+
while (node) {
|
|
254
|
+
const entityElement = this.querySelector(`pc-entity[name="${node.name}"]`) as EntityElement;
|
|
255
|
+
if (entityElement && entityElement.hasListeners('pointerdown')) {
|
|
256
|
+
entityElement.dispatchEvent(new PointerEvent('pointerdown', event));
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
node = node.parent;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
_onPointerUp(event: PointerEvent) {
|
|
265
|
+
if (!this._picker || !this.app) return;
|
|
266
|
+
|
|
267
|
+
const camera = this.app!.root.findComponent('camera') as CameraComponent;
|
|
268
|
+
if (!camera) return;
|
|
269
|
+
|
|
270
|
+
const canvasRect = this._canvas!.getBoundingClientRect();
|
|
271
|
+
const x = event.clientX - canvasRect.left;
|
|
272
|
+
const y = event.clientY - canvasRect.top;
|
|
273
|
+
|
|
274
|
+
this._picker.prepare(camera, this.app!.scene);
|
|
275
|
+
const selection = this._picker.getSelection(x, y);
|
|
276
|
+
|
|
277
|
+
if (selection.length > 0) {
|
|
278
|
+
const entityElement = this.querySelector(`pc-entity[name="${selection[0].node.name}"]`) as EntityElement;
|
|
279
|
+
if (entityElement && entityElement.hasListeners('pointerup')) {
|
|
280
|
+
entityElement.dispatchEvent(new PointerEvent('pointerup', event));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
_onPointerListenerAdded(type: string) {
|
|
286
|
+
if (!this._hasPointerListeners[type] && this._canvas) {
|
|
287
|
+
this._hasPointerListeners[type] = true;
|
|
288
|
+
|
|
289
|
+
// For enter/leave events, we need the move handler
|
|
290
|
+
const handler = (type === 'pointerenter' || type === 'pointerleave') ?
|
|
291
|
+
this._pointerHandlers.pointermove :
|
|
292
|
+
this._pointerHandlers[type];
|
|
293
|
+
|
|
294
|
+
if (handler) {
|
|
295
|
+
this._canvas.addEventListener(type === 'pointerenter' || type === 'pointerleave' ? 'pointermove' : type, handler);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
_onPointerListenerRemoved(type: string) {
|
|
301
|
+
const hasListeners = Array.from(this.querySelectorAll<EntityElement>('pc-entity'))
|
|
302
|
+
.some(entity => entity.hasListeners(type));
|
|
303
|
+
|
|
304
|
+
if (!hasListeners && this._canvas) {
|
|
305
|
+
this._hasPointerListeners[type] = false;
|
|
306
|
+
|
|
307
|
+
const handler = (type === 'pointerenter' || type === 'pointerleave') ?
|
|
308
|
+
this._pointerHandlers.pointermove :
|
|
309
|
+
this._pointerHandlers[type];
|
|
310
|
+
|
|
311
|
+
if (handler) {
|
|
312
|
+
this._canvas.removeEventListener(type === 'pointerenter' || type === 'pointerleave' ? 'pointermove' : type, handler);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
120
317
|
/**
|
|
121
318
|
* Sets the alpha flag.
|
|
122
319
|
* @param value - The alpha flag.
|
|
@@ -165,6 +362,15 @@ class AppElement extends AsyncElement {
|
|
|
165
362
|
return this._depth;
|
|
166
363
|
}
|
|
167
364
|
|
|
365
|
+
/**
|
|
366
|
+
* Gets the hierarchy ready flag.
|
|
367
|
+
* @returns The hierarchy ready flag.
|
|
368
|
+
* @ignore
|
|
369
|
+
*/
|
|
370
|
+
get hierarchyReady() {
|
|
371
|
+
return this._hierarchyReady;
|
|
372
|
+
}
|
|
373
|
+
|
|
168
374
|
/**
|
|
169
375
|
* Sets the high resolution flag. When true, the application will render at the device's
|
|
170
376
|
* physical resolution. When false, the application will render at CSS resolution.
|
package/src/asset.ts
CHANGED
|
@@ -21,7 +21,9 @@ const extToType = new Map([
|
|
|
21
21
|
]);
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* The AssetElement interface provides properties and methods for manipulating
|
|
25
|
+
* `<pc-asset>` elements. The AssetElement interface also inherits the properties and
|
|
26
|
+
* methods of the {@link HTMLElement} interface.
|
|
25
27
|
*/
|
|
26
28
|
class AssetElement extends HTMLElement {
|
|
27
29
|
private _preload: boolean = false;
|
package/src/async-element.ts
CHANGED
|
@@ -2,13 +2,14 @@ import { AppElement } from './app';
|
|
|
2
2
|
import { EntityElement } from './entity';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Base class for all PlayCanvas
|
|
5
|
+
* Base class for all PlayCanvas Web Components that initialize asynchronously.
|
|
6
6
|
*/
|
|
7
7
|
class AsyncElement extends HTMLElement {
|
|
8
8
|
private _readyPromise: Promise<void>;
|
|
9
9
|
|
|
10
10
|
private _readyResolve!: () => void;
|
|
11
11
|
|
|
12
|
+
/** @ignore */
|
|
12
13
|
constructor() {
|
|
13
14
|
super();
|
|
14
15
|
this._readyPromise = new Promise<void>((resolve) => {
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
import { PROJECTION_ORTHOGRAPHIC, PROJECTION_PERSPECTIVE,
|
|
1
|
+
import { CameraComponent, Color, Vec4, GAMMA_NONE, GAMMA_SRGB, PROJECTION_ORTHOGRAPHIC, PROJECTION_PERSPECTIVE, TONEMAP_LINEAR, TONEMAP_FILMIC, TONEMAP_NEUTRAL, TONEMAP_ACES2, TONEMAP_ACES, TONEMAP_HEJL, TONEMAP_NONE, XRTYPE_VR } from 'playcanvas';
|
|
2
2
|
|
|
3
3
|
import { ComponentElement } from './component';
|
|
4
4
|
import { parseColor, parseVec4 } from '../utils';
|
|
5
5
|
|
|
6
|
+
const tonemaps = new Map([
|
|
7
|
+
['none', TONEMAP_NONE],
|
|
8
|
+
['linear', TONEMAP_LINEAR],
|
|
9
|
+
['filmic', TONEMAP_FILMIC],
|
|
10
|
+
['hejl', TONEMAP_HEJL],
|
|
11
|
+
['aces', TONEMAP_ACES],
|
|
12
|
+
['aces2', TONEMAP_ACES2],
|
|
13
|
+
['neutral', TONEMAP_NEUTRAL]
|
|
14
|
+
]);
|
|
15
|
+
|
|
6
16
|
/**
|
|
7
|
-
*
|
|
17
|
+
* The CameraComponentElement interface provides properties and methods for manipulating
|
|
18
|
+
* `<pc-camera>` elements. The CameraComponentElement interface also inherits the properties and
|
|
19
|
+
* methods of the {@link HTMLElement} interface.
|
|
8
20
|
*
|
|
9
21
|
* @category Components
|
|
10
22
|
*/
|
|
@@ -27,6 +39,8 @@ class CameraComponentElement extends ComponentElement {
|
|
|
27
39
|
|
|
28
40
|
private _frustumCulling = true;
|
|
29
41
|
|
|
42
|
+
private _gamma: 'none' | 'srgb' = 'srgb';
|
|
43
|
+
|
|
30
44
|
private _nearClip = 0.1;
|
|
31
45
|
|
|
32
46
|
private _orthographic = false;
|
|
@@ -39,9 +53,9 @@ class CameraComponentElement extends ComponentElement {
|
|
|
39
53
|
|
|
40
54
|
private _scissorRect = new Vec4(0, 0, 1, 1);
|
|
41
55
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
private _tonemap: 'none' | 'linear' | 'filmic' | 'hejl' | 'aces' | 'aces2' | 'neutral' = 'none';
|
|
57
|
+
|
|
58
|
+
/** @ignore */
|
|
45
59
|
constructor() {
|
|
46
60
|
super('camera');
|
|
47
61
|
}
|
|
@@ -57,12 +71,14 @@ class CameraComponentElement extends ComponentElement {
|
|
|
57
71
|
flipFaces: this._flipFaces,
|
|
58
72
|
fov: this._fov,
|
|
59
73
|
frustumCulling: this._frustumCulling,
|
|
74
|
+
gammaCorrection: this._gamma === 'srgb' ? GAMMA_SRGB : GAMMA_NONE,
|
|
60
75
|
nearClip: this._nearClip,
|
|
61
76
|
orthographic: this._orthographic,
|
|
62
77
|
orthoHeight: this._orthoHeight,
|
|
63
78
|
priority: this._priority,
|
|
64
79
|
rect: this._rect,
|
|
65
|
-
scissorRect: this._scissorRect
|
|
80
|
+
scissorRect: this._scissorRect,
|
|
81
|
+
toneMapping: tonemaps.get(this._tonemap)
|
|
66
82
|
};
|
|
67
83
|
}
|
|
68
84
|
|
|
@@ -266,6 +282,25 @@ class CameraComponentElement extends ComponentElement {
|
|
|
266
282
|
return this._frustumCulling;
|
|
267
283
|
}
|
|
268
284
|
|
|
285
|
+
/**
|
|
286
|
+
* Sets the gamma correction of the camera.
|
|
287
|
+
* @param value - The gamma correction.
|
|
288
|
+
*/
|
|
289
|
+
set gamma(value: 'none' | 'srgb') {
|
|
290
|
+
this._gamma = value;
|
|
291
|
+
if (this.component) {
|
|
292
|
+
this.component.gammaCorrection = value === 'srgb' ? GAMMA_SRGB : GAMMA_NONE;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Gets the gamma correction of the camera.
|
|
298
|
+
* @returns The gamma correction.
|
|
299
|
+
*/
|
|
300
|
+
get gamma(): 'none' | 'srgb' {
|
|
301
|
+
return this._gamma;
|
|
302
|
+
}
|
|
303
|
+
|
|
269
304
|
/**
|
|
270
305
|
* Sets the near clip distance of the camera.
|
|
271
306
|
* @param value - The near clip distance.
|
|
@@ -380,6 +415,25 @@ class CameraComponentElement extends ComponentElement {
|
|
|
380
415
|
return this._scissorRect;
|
|
381
416
|
}
|
|
382
417
|
|
|
418
|
+
/**
|
|
419
|
+
* Sets the tone mapping of the camera.
|
|
420
|
+
* @param value - The tone mapping.
|
|
421
|
+
*/
|
|
422
|
+
set tonemap(value: 'none' | 'linear' | 'filmic' | 'hejl' | 'aces' | 'aces2' | 'neutral') {
|
|
423
|
+
this._tonemap = value;
|
|
424
|
+
if (this.component) {
|
|
425
|
+
this.component.toneMapping = tonemaps.get(value) ?? TONEMAP_NONE;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Gets the tone mapping of the camera.
|
|
431
|
+
* @returns The tone mapping.
|
|
432
|
+
*/
|
|
433
|
+
get tonemap(): 'none' | 'linear' | 'filmic' | 'hejl' | 'aces' | 'aces2' | 'neutral' {
|
|
434
|
+
return this._tonemap;
|
|
435
|
+
}
|
|
436
|
+
|
|
383
437
|
static get observedAttributes() {
|
|
384
438
|
return [
|
|
385
439
|
...super.observedAttributes,
|
|
@@ -392,12 +446,14 @@ class CameraComponentElement extends ComponentElement {
|
|
|
392
446
|
'flip-faces',
|
|
393
447
|
'fov',
|
|
394
448
|
'frustum-culling',
|
|
449
|
+
'gamma',
|
|
395
450
|
'near-clip',
|
|
396
451
|
'orthographic',
|
|
397
452
|
'ortho-height',
|
|
398
453
|
'priority',
|
|
399
454
|
'rect',
|
|
400
|
-
'scissor-rect'
|
|
455
|
+
'scissor-rect',
|
|
456
|
+
'tonemap'
|
|
401
457
|
];
|
|
402
458
|
}
|
|
403
459
|
|
|
@@ -432,6 +488,9 @@ class CameraComponentElement extends ComponentElement {
|
|
|
432
488
|
case 'frustum-culling':
|
|
433
489
|
this.frustumCulling = newValue !== 'false';
|
|
434
490
|
break;
|
|
491
|
+
case 'gamma':
|
|
492
|
+
this.gamma = newValue as 'none' | 'srgb';
|
|
493
|
+
break;
|
|
435
494
|
case 'near-clip':
|
|
436
495
|
this.nearClip = parseFloat(newValue);
|
|
437
496
|
break;
|
|
@@ -450,6 +509,9 @@ class CameraComponentElement extends ComponentElement {
|
|
|
450
509
|
case 'scissor-rect':
|
|
451
510
|
this.scissorRect = parseVec4(newValue);
|
|
452
511
|
break;
|
|
512
|
+
case 'tonemap':
|
|
513
|
+
this.tonemap = newValue as 'none' | 'linear' | 'filmic' | 'hejl' | 'aces' | 'aces2' | 'neutral';
|
|
514
|
+
break;
|
|
453
515
|
}
|
|
454
516
|
}
|
|
455
517
|
}
|
|
@@ -4,7 +4,9 @@ import { ComponentElement } from './component';
|
|
|
4
4
|
import { parseQuat, parseVec3 } from '../utils';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* The CollisionComponentElement interface provides properties and methods for manipulating
|
|
8
|
+
* `<pc-collision>` elements. The CollisionComponentElement interface also inherits the properties
|
|
9
|
+
* and methods of the {@link HTMLElement} interface.
|
|
8
10
|
*
|
|
9
11
|
* @category Components
|
|
10
12
|
*/
|
|
@@ -25,9 +27,7 @@ class CollisionComponentElement extends ComponentElement {
|
|
|
25
27
|
|
|
26
28
|
private _type: string = 'box';
|
|
27
29
|
|
|
28
|
-
/**
|
|
29
|
-
* Creates a new CollisionComponentElement.
|
|
30
|
-
*/
|
|
30
|
+
/** @ignore */
|
|
31
31
|
constructor() {
|
|
32
32
|
super('collision');
|
|
33
33
|
}
|
|
@@ -15,8 +15,10 @@ class ComponentElement extends AsyncElement {
|
|
|
15
15
|
private _component: Component | null = null;
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Creates a new ComponentElement instance.
|
|
19
|
+
*
|
|
19
20
|
* @param componentName - The name of the component.
|
|
21
|
+
* @ignore
|
|
20
22
|
*/
|
|
21
23
|
constructor(componentName: string) {
|
|
22
24
|
super();
|
|
@@ -4,9 +4,10 @@ import { AssetElement } from '../asset';
|
|
|
4
4
|
import { ComponentElement } from './component';
|
|
5
5
|
import { parseColor, parseVec2, parseVec4 } from '../utils';
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
|
-
*
|
|
8
|
+
* The ElementComponentElement interface provides properties and methods for manipulating
|
|
9
|
+
* `<pc-element>` elements. The ElementComponentElement interface also inherits the properties and
|
|
10
|
+
* methods of the {@link HTMLElement} interface.
|
|
10
11
|
*
|
|
11
12
|
* @category Components
|
|
12
13
|
*/
|
|
@@ -33,6 +34,7 @@ class ElementComponentElement extends ComponentElement {
|
|
|
33
34
|
|
|
34
35
|
private _wrapLines: boolean = false;
|
|
35
36
|
|
|
37
|
+
/** @ignore */
|
|
36
38
|
constructor() {
|
|
37
39
|
super('element');
|
|
38
40
|
}
|
|
@@ -4,13 +4,16 @@ import { ComponentElement } from './component';
|
|
|
4
4
|
import { AssetElement } from '../asset';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* The GSplatComponentElement interface provides properties and methods for manipulating
|
|
8
|
+
* `<pc-splat>` elements. The GSplatComponentElement interface also inherits the properties and
|
|
9
|
+
* methods of the {@link HTMLElement} interface.
|
|
8
10
|
*
|
|
9
11
|
* @category Components
|
|
10
12
|
*/
|
|
11
13
|
class GSplatComponentElement extends ComponentElement {
|
|
12
14
|
private _asset: string = '';
|
|
13
15
|
|
|
16
|
+
/** @ignore */
|
|
14
17
|
constructor() {
|
|
15
18
|
super('gsplat');
|
|
16
19
|
}
|
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
import { Color, LightComponent } from 'playcanvas';
|
|
1
|
+
import { Color, LightComponent, SHADOW_PCF1_16F, SHADOW_PCF1_32F, SHADOW_PCF3_16F, SHADOW_PCF3_32F, SHADOW_PCF5_16F, SHADOW_PCF5_32F, SHADOW_PCSS_32F, SHADOW_VSM_16F, SHADOW_VSM_32F } from 'playcanvas';
|
|
2
2
|
|
|
3
3
|
import { ComponentElement } from './component';
|
|
4
4
|
import { parseColor } from '../utils';
|
|
5
5
|
|
|
6
|
+
const shadowTypes = new Map([
|
|
7
|
+
['pcf1-16f', SHADOW_PCF1_16F],
|
|
8
|
+
['pcf1-32f', SHADOW_PCF1_32F],
|
|
9
|
+
['pcf3-16f', SHADOW_PCF3_16F],
|
|
10
|
+
['pcf3-32f', SHADOW_PCF3_32F],
|
|
11
|
+
['pcf5-16f', SHADOW_PCF5_16F],
|
|
12
|
+
['pcf5-32f', SHADOW_PCF5_32F],
|
|
13
|
+
['vsm-16f', SHADOW_VSM_16F],
|
|
14
|
+
['vsm-32f', SHADOW_VSM_32F],
|
|
15
|
+
['pcss-32f', SHADOW_PCSS_32F]
|
|
16
|
+
]);
|
|
17
|
+
|
|
6
18
|
/**
|
|
7
|
-
*
|
|
19
|
+
* The LightComponentElement interface provides properties and methods for manipulating
|
|
20
|
+
* `<pc-light>` elements. The LightComponentElement interface also inherits the properties and
|
|
21
|
+
* methods of the {@link HTMLElement} interface.
|
|
8
22
|
*
|
|
9
23
|
* @category Components
|
|
10
24
|
*/
|
|
@@ -27,13 +41,17 @@ class LightComponentElement extends ComponentElement {
|
|
|
27
41
|
|
|
28
42
|
private _shadowDistance = 16;
|
|
29
43
|
|
|
44
|
+
private _shadowIntensity = 1;
|
|
45
|
+
|
|
30
46
|
private _shadowResolution = 1024;
|
|
31
47
|
|
|
48
|
+
private _shadowType: 'pcf1-16f' | 'pcf1-32f' | 'pcf3-16f' | 'pcf3-32f' | 'pcf5-16f' | 'pcf5-32f' | 'vsm-16f' | 'vsm-32f' | 'pcss-32f' = 'pcf3-32f';
|
|
49
|
+
|
|
32
50
|
private _type = 'directional';
|
|
33
51
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
52
|
+
private _vsmBias = 0.01;
|
|
53
|
+
|
|
54
|
+
/** @ignore */
|
|
37
55
|
constructor() {
|
|
38
56
|
super('light');
|
|
39
57
|
}
|
|
@@ -49,8 +67,11 @@ class LightComponentElement extends ComponentElement {
|
|
|
49
67
|
range: this._range,
|
|
50
68
|
shadowBias: this._shadowBias,
|
|
51
69
|
shadowDistance: this._shadowDistance,
|
|
70
|
+
shadowIntensity: this._shadowIntensity,
|
|
52
71
|
shadowResolution: this._shadowResolution,
|
|
53
|
-
|
|
72
|
+
shadowType: shadowTypes.get(this._shadowType),
|
|
73
|
+
type: this._type,
|
|
74
|
+
vsmBias: this._vsmBias
|
|
54
75
|
};
|
|
55
76
|
}
|
|
56
77
|
|
|
@@ -233,6 +254,25 @@ class LightComponentElement extends ComponentElement {
|
|
|
233
254
|
return this._shadowDistance;
|
|
234
255
|
}
|
|
235
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Sets the shadow intensity of the light.
|
|
259
|
+
* @param value - The shadow intensity.
|
|
260
|
+
*/
|
|
261
|
+
set shadowIntensity(value: number) {
|
|
262
|
+
this._shadowIntensity = value;
|
|
263
|
+
if (this.component) {
|
|
264
|
+
this.component.shadowIntensity = value;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Gets the shadow intensity of the light.
|
|
270
|
+
* @returns The shadow intensity.
|
|
271
|
+
*/
|
|
272
|
+
get shadowIntensity() {
|
|
273
|
+
return this._shadowIntensity;
|
|
274
|
+
}
|
|
275
|
+
|
|
236
276
|
/**
|
|
237
277
|
* Sets the shadow resolution of the light.
|
|
238
278
|
* @param value - The shadow resolution.
|
|
@@ -252,6 +292,35 @@ class LightComponentElement extends ComponentElement {
|
|
|
252
292
|
return this._shadowResolution;
|
|
253
293
|
}
|
|
254
294
|
|
|
295
|
+
/**
|
|
296
|
+
* Sets the shadow type of the light.
|
|
297
|
+
* @param value - The shadow type. Can be:
|
|
298
|
+
*
|
|
299
|
+
* - `pcf1-16f` - 1-tap percentage-closer filtered shadow map with 16-bit depth.
|
|
300
|
+
* - `pcf1-32f` - 1-tap percentage-closer filtered shadow map with 32-bit depth.
|
|
301
|
+
* - `pcf3-16f` - 3-tap percentage-closer filtered shadow map with 16-bit depth.
|
|
302
|
+
* - `pcf3-32f` - 3-tap percentage-closer filtered shadow map with 32-bit depth.
|
|
303
|
+
* - `pcf5-16f` - 5-tap percentage-closer filtered shadow map with 16-bit depth.
|
|
304
|
+
* - `pcf5-32f` - 5-tap percentage-closer filtered shadow map with 32-bit depth.
|
|
305
|
+
* - `vsm-16f` - Variance shadow map with 16-bit depth.
|
|
306
|
+
* - `vsm-32f` - Variance shadow map with 32-bit depth.
|
|
307
|
+
* - `pcss-32f` - Percentage-closer soft shadow with 32-bit depth.
|
|
308
|
+
*/
|
|
309
|
+
set shadowType(value: 'pcf1-16f' | 'pcf1-32f' | 'pcf3-16f' | 'pcf3-32f' | 'pcf5-16f' | 'pcf5-32f' | 'vsm-16f' | 'vsm-32f' | 'pcss-32f') {
|
|
310
|
+
this._shadowType = value;
|
|
311
|
+
if (this.component) {
|
|
312
|
+
this.component.shadowType = shadowTypes.get(value) ?? SHADOW_PCF3_32F;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Gets the shadow type of the light.
|
|
318
|
+
* @returns The shadow type.
|
|
319
|
+
*/
|
|
320
|
+
get shadowType() {
|
|
321
|
+
return this._shadowType;
|
|
322
|
+
}
|
|
323
|
+
|
|
255
324
|
/**
|
|
256
325
|
* Sets the type of the light.
|
|
257
326
|
* @param value - The type.
|
|
@@ -276,6 +345,25 @@ class LightComponentElement extends ComponentElement {
|
|
|
276
345
|
return this._type;
|
|
277
346
|
}
|
|
278
347
|
|
|
348
|
+
/**
|
|
349
|
+
* Sets the VSM bias of the light.
|
|
350
|
+
* @param value - The VSM bias.
|
|
351
|
+
*/
|
|
352
|
+
set vsmBias(value: number) {
|
|
353
|
+
this._vsmBias = value;
|
|
354
|
+
if (this.component) {
|
|
355
|
+
this.component.vsmBias = value;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Gets the VSM bias of the light.
|
|
361
|
+
* @returns The VSM bias.
|
|
362
|
+
*/
|
|
363
|
+
get vsmBias() {
|
|
364
|
+
return this._vsmBias;
|
|
365
|
+
}
|
|
366
|
+
|
|
279
367
|
static get observedAttributes() {
|
|
280
368
|
return [
|
|
281
369
|
...super.observedAttributes,
|
|
@@ -288,8 +376,11 @@ class LightComponentElement extends ComponentElement {
|
|
|
288
376
|
'range',
|
|
289
377
|
'shadow-bias',
|
|
290
378
|
'shadow-distance',
|
|
379
|
+
'shadow-intensity',
|
|
291
380
|
'shadow-resolution',
|
|
292
|
-
'type'
|
|
381
|
+
'shadow-type',
|
|
382
|
+
'type',
|
|
383
|
+
'vsm-bias'
|
|
293
384
|
];
|
|
294
385
|
}
|
|
295
386
|
|
|
@@ -327,9 +418,18 @@ class LightComponentElement extends ComponentElement {
|
|
|
327
418
|
case 'shadow-resolution':
|
|
328
419
|
this.shadowResolution = Number(newValue);
|
|
329
420
|
break;
|
|
421
|
+
case 'shadow-intensity':
|
|
422
|
+
this.shadowIntensity = Number(newValue);
|
|
423
|
+
break;
|
|
424
|
+
case 'shadow-type':
|
|
425
|
+
this.shadowType = newValue as 'pcf1-16f' | 'pcf1-32f' | 'pcf3-16f' | 'pcf3-32f' | 'pcf5-16f' | 'pcf5-32f' | 'vsm-16f' | 'vsm-32f' | 'pcss-32f';
|
|
426
|
+
break;
|
|
330
427
|
case 'type':
|
|
331
428
|
this.type = newValue;
|
|
332
429
|
break;
|
|
430
|
+
case 'vsm-bias':
|
|
431
|
+
this.vsmBias = Number(newValue);
|
|
432
|
+
break;
|
|
333
433
|
}
|
|
334
434
|
}
|
|
335
435
|
}
|