@playcanvas/web-components 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/app.d.cts +28 -3
- package/dist/app.d.ts +28 -3
- package/dist/asset.d.cts +13 -3
- package/dist/asset.d.ts +13 -3
- package/dist/components/anim-clip.d.cts +3 -1
- package/dist/components/anim-clip.d.ts +3 -1
- package/dist/components/anim-component.d.cts +5 -0
- package/dist/components/anim-component.d.ts +5 -0
- package/dist/components/audio-listener-component.d.cts +4 -0
- package/dist/components/audio-listener-component.d.ts +4 -0
- package/dist/components/button-component.d.cts +5 -0
- package/dist/components/button-component.d.ts +5 -0
- package/dist/components/camera-component.d.cts +35 -1
- package/dist/components/camera-component.d.ts +35 -1
- package/dist/components/collision-component.d.cts +4 -0
- package/dist/components/collision-component.d.ts +4 -0
- package/dist/components/element-component.d.cts +4 -0
- package/dist/components/element-component.d.ts +4 -0
- package/dist/components/gsplat-component.d.cts +4 -0
- package/dist/components/gsplat-component.d.ts +4 -0
- package/dist/components/joint-component.d.cts +12 -2
- package/dist/components/joint-component.d.ts +12 -2
- package/dist/components/layout-child-component.d.cts +4 -0
- package/dist/components/layout-child-component.d.ts +4 -0
- package/dist/components/layout-group-component.d.cts +4 -0
- package/dist/components/layout-group-component.d.ts +4 -0
- package/dist/components/light-component.d.cts +50 -1
- package/dist/components/light-component.d.ts +50 -1
- package/dist/components/particle-system-component.d.cts +4 -0
- package/dist/components/particle-system-component.d.ts +4 -0
- package/dist/components/render-component.d.cts +5 -0
- package/dist/components/render-component.d.ts +5 -0
- package/dist/components/rigid-body-component.d.cts +5 -0
- package/dist/components/rigid-body-component.d.ts +5 -0
- package/dist/components/screen-component.d.cts +4 -0
- package/dist/components/screen-component.d.ts +4 -0
- package/dist/components/script-component.d.cts +3 -0
- package/dist/components/script-component.d.ts +3 -0
- package/dist/components/script-instance.d.cts +4 -0
- package/dist/components/script-instance.d.ts +4 -0
- package/dist/components/scroll-view-component.d.cts +4 -0
- package/dist/components/scroll-view-component.d.ts +4 -0
- package/dist/components/scrollbar-component.d.cts +4 -0
- package/dist/components/scrollbar-component.d.ts +4 -0
- package/dist/components/sound-component.d.cts +4 -0
- package/dist/components/sound-component.d.ts +4 -0
- package/dist/components/sound-slot.d.cts +3 -0
- package/dist/components/sound-slot.d.ts +3 -0
- package/dist/custom-elements.json +338 -7
- package/dist/entity-base.d.cts +5 -4
- package/dist/entity-base.d.ts +5 -4
- package/dist/entity-owner.d.cts +2 -2
- package/dist/entity-owner.d.ts +2 -2
- package/dist/entity.d.cts +13 -2
- package/dist/entity.d.ts +13 -2
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/material.d.cts +18 -7
- package/dist/material.d.ts +18 -7
- package/dist/model.d.cts +11 -0
- package/dist/model.d.ts +11 -0
- package/dist/node.d.cts +12 -1
- package/dist/node.d.ts +12 -1
- package/dist/pwc.cjs +601 -206
- package/dist/pwc.cjs.map +1 -1
- package/dist/pwc.js +601 -206
- 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.min.mjs +1 -1
- package/dist/pwc.min.mjs.map +1 -1
- package/dist/pwc.mjs +602 -207
- package/dist/pwc.mjs.map +1 -1
- package/dist/scene.d.cts +19 -0
- package/dist/scene.d.ts +19 -0
- package/dist/sky.d.cts +4 -0
- package/dist/sky.d.ts +4 -0
- package/dist/vscode.html-custom-data.json +257 -62
- package/dist/wasm.d.cts +4 -0
- package/dist/wasm.d.ts +4 -0
- package/dist/web-types.json +169 -69
- package/package.json +3 -3
- package/src/app.ts +150 -71
- package/src/asset.ts +13 -4
- package/src/components/anim-clip.ts +3 -1
- package/src/components/anim-component.ts +5 -0
- package/src/components/audio-listener-component.ts +4 -0
- package/src/components/button-component.ts +5 -0
- package/src/components/camera-component.ts +63 -6
- package/src/components/collision-component.ts +4 -0
- package/src/components/element-component.ts +4 -0
- package/src/components/gsplat-component.ts +4 -0
- package/src/components/joint-component.ts +12 -2
- package/src/components/layout-child-component.ts +4 -0
- package/src/components/layout-group-component.ts +4 -0
- package/src/components/light-component.ts +108 -17
- package/src/components/particle-system-component.ts +4 -0
- package/src/components/render-component.ts +5 -0
- package/src/components/rigid-body-component.ts +5 -0
- package/src/components/screen-component.ts +4 -0
- package/src/components/script-component.ts +3 -0
- package/src/components/script-instance.ts +4 -0
- package/src/components/scroll-view-component.ts +4 -0
- package/src/components/scrollbar-component.ts +4 -0
- package/src/components/sound-component.ts +4 -0
- package/src/components/sound-slot.ts +3 -0
- package/src/entity-base.ts +28 -16
- package/src/entity-owner.ts +2 -2
- package/src/entity.ts +16 -4
- package/src/index.ts +12 -1
- package/src/material.ts +19 -8
- package/src/model.ts +14 -2
- package/src/node.ts +15 -3
- package/src/scene.ts +35 -1
- package/src/sky.ts +4 -0
- package/src/wasm.ts +4 -0
|
@@ -39,9 +39,17 @@ const shadowTypes = new Map<
|
|
|
39
39
|
*
|
|
40
40
|
* Engine component: {@link LightComponent} (`light`).
|
|
41
41
|
*
|
|
42
|
+
* @elementSummary The `<pc-light>` element lights the scene from its entity — as a directional,
|
|
43
|
+
* omni or spot light — with attributes for color, intensity, range and shadows. Must be a child of
|
|
44
|
+
* a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
45
|
+
*
|
|
42
46
|
* @category Components
|
|
43
47
|
*/
|
|
44
48
|
class LightComponentElement extends ComponentElement {
|
|
49
|
+
private _cascadeBlend = 0;
|
|
50
|
+
|
|
51
|
+
private _cascadeDistribution = 0.5;
|
|
52
|
+
|
|
45
53
|
private _castShadows = false;
|
|
46
54
|
|
|
47
55
|
private _color = new Color(1, 1, 1);
|
|
@@ -50,15 +58,17 @@ class LightComponentElement extends ComponentElement {
|
|
|
50
58
|
|
|
51
59
|
private _intensity = 1;
|
|
52
60
|
|
|
53
|
-
private _normalOffsetBias = 0
|
|
61
|
+
private _normalOffsetBias = 0;
|
|
62
|
+
|
|
63
|
+
private _numCascades = 1;
|
|
54
64
|
|
|
55
65
|
private _outerConeAngle = 45;
|
|
56
66
|
|
|
57
67
|
private _range = 10;
|
|
58
68
|
|
|
59
|
-
private _shadowBias = 0.
|
|
69
|
+
private _shadowBias = 0.05;
|
|
60
70
|
|
|
61
|
-
private _shadowDistance =
|
|
71
|
+
private _shadowDistance = 40;
|
|
62
72
|
|
|
63
73
|
private _shadowIntensity = 1;
|
|
64
74
|
|
|
@@ -77,7 +87,7 @@ class LightComponentElement extends ComponentElement {
|
|
|
77
87
|
|
|
78
88
|
private _type: 'directional' | 'omni' | 'spot' = 'directional';
|
|
79
89
|
|
|
80
|
-
private _vsmBias = 0.
|
|
90
|
+
private _vsmBias = 0.0025;
|
|
81
91
|
|
|
82
92
|
private _vsmBlurSize = 11;
|
|
83
93
|
|
|
@@ -96,11 +106,14 @@ class LightComponentElement extends ComponentElement {
|
|
|
96
106
|
|
|
97
107
|
protected getInitialComponentData() {
|
|
98
108
|
return {
|
|
109
|
+
cascadeBlend: this._cascadeBlend,
|
|
110
|
+
cascadeDistribution: this._cascadeDistribution,
|
|
99
111
|
castShadows: this._castShadows,
|
|
100
112
|
color: this._color,
|
|
101
113
|
innerConeAngle: this._innerConeAngle,
|
|
102
114
|
intensity: this._intensity,
|
|
103
115
|
normalOffsetBias: this._normalOffsetBias,
|
|
116
|
+
numCascades: this._numCascades,
|
|
104
117
|
outerConeAngle: this._outerConeAngle,
|
|
105
118
|
penumbraFalloff: this._penumbraFalloff,
|
|
106
119
|
penumbraSize: this._penumbraSize,
|
|
@@ -111,7 +124,7 @@ class LightComponentElement extends ComponentElement {
|
|
|
111
124
|
shadowIntensity: this._shadowIntensity,
|
|
112
125
|
shadowResolution: this._shadowResolution,
|
|
113
126
|
shadowSamples: this._shadowSamples,
|
|
114
|
-
shadowType: shadowTypes.get(this._shadowType),
|
|
127
|
+
shadowType: shadowTypes.get(this._shadowType) ?? SHADOW_PCF3_32F,
|
|
115
128
|
type: this._type,
|
|
116
129
|
vsmBias: this._vsmBias,
|
|
117
130
|
vsmBlurSize: this._vsmBlurSize
|
|
@@ -126,6 +139,51 @@ class LightComponentElement extends ComponentElement {
|
|
|
126
139
|
return super.component as LightComponent;
|
|
127
140
|
}
|
|
128
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Sets the fraction of each shadow cascade that is blended into the next one, from 0 (no
|
|
144
|
+
* blending) to 1, which applies only to `directional` lights with `num-cascades` greater than
|
|
145
|
+
* 1. Defaults to 0.
|
|
146
|
+
* @param value - The cascade blend factor.
|
|
147
|
+
*/
|
|
148
|
+
set cascadeBlend(value: number) {
|
|
149
|
+
this._cascadeBlend = value;
|
|
150
|
+
if (this.component) {
|
|
151
|
+
this.component.cascadeBlend = value;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Gets the cascade blend factor of the light, from 0 (no blending) to 1, which applies only to
|
|
157
|
+
* `directional` lights with `num-cascades` greater than 1.
|
|
158
|
+
* @returns The cascade blend factor.
|
|
159
|
+
*/
|
|
160
|
+
get cascadeBlend() {
|
|
161
|
+
return this._cascadeBlend;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Sets the distribution of the camera frustum split between shadow cascades, from 0 (linear
|
|
166
|
+
* split) to 1 (logarithmic split, concentrating shadow resolution near the camera), which
|
|
167
|
+
* applies only to `directional` lights with `num-cascades` greater than 1. Defaults to 0.5.
|
|
168
|
+
* @param value - The cascade distribution.
|
|
169
|
+
*/
|
|
170
|
+
set cascadeDistribution(value: number) {
|
|
171
|
+
this._cascadeDistribution = value;
|
|
172
|
+
if (this.component) {
|
|
173
|
+
this.component.cascadeDistribution = value;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Gets the cascade distribution of the light, from 0 (linear split) to 1 (logarithmic split,
|
|
179
|
+
* concentrating shadow resolution near the camera), which applies only to `directional` lights
|
|
180
|
+
* with `num-cascades` greater than 1.
|
|
181
|
+
* @returns The cascade distribution.
|
|
182
|
+
*/
|
|
183
|
+
get cascadeDistribution() {
|
|
184
|
+
return this._cascadeDistribution;
|
|
185
|
+
}
|
|
186
|
+
|
|
129
187
|
/**
|
|
130
188
|
* Sets the cast shadows flag of the light.
|
|
131
189
|
* @param value - The cast shadows flag.
|
|
@@ -221,6 +279,27 @@ class LightComponentElement extends ComponentElement {
|
|
|
221
279
|
return this._normalOffsetBias;
|
|
222
280
|
}
|
|
223
281
|
|
|
282
|
+
/**
|
|
283
|
+
* Sets the number of shadow cascades of the light, an integer from 1 (no cascades) to 4, which
|
|
284
|
+
* applies only to `directional` lights. Defaults to 1.
|
|
285
|
+
* @param value - The number of shadow cascades.
|
|
286
|
+
*/
|
|
287
|
+
set numCascades(value: number) {
|
|
288
|
+
this._numCascades = value;
|
|
289
|
+
if (this.component) {
|
|
290
|
+
this.component.numCascades = value;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Gets the number of shadow cascades of the light, an integer from 1 (no cascades) to 4, which
|
|
296
|
+
* applies only to `directional` lights.
|
|
297
|
+
* @returns The number of shadow cascades.
|
|
298
|
+
*/
|
|
299
|
+
get numCascades() {
|
|
300
|
+
return this._numCascades;
|
|
301
|
+
}
|
|
302
|
+
|
|
224
303
|
/**
|
|
225
304
|
* Sets the outer cone angle of the light.
|
|
226
305
|
* @param value - The outer cone angle.
|
|
@@ -512,11 +591,14 @@ class LightComponentElement extends ComponentElement {
|
|
|
512
591
|
static get observedAttributes() {
|
|
513
592
|
return [
|
|
514
593
|
...super.observedAttributes,
|
|
515
|
-
'
|
|
594
|
+
'cascade-blend',
|
|
595
|
+
'cascade-distribution',
|
|
516
596
|
'cast-shadows',
|
|
517
|
-
'
|
|
597
|
+
'color',
|
|
518
598
|
'inner-cone-angle',
|
|
599
|
+
'intensity',
|
|
519
600
|
'normal-offset-bias',
|
|
601
|
+
'num-cascades',
|
|
520
602
|
'outer-cone-angle',
|
|
521
603
|
'penumbra-falloff',
|
|
522
604
|
'penumbra-size',
|
|
@@ -538,12 +620,18 @@ class LightComponentElement extends ComponentElement {
|
|
|
538
620
|
super.attributeChangedCallback(name, _oldValue, newValue);
|
|
539
621
|
|
|
540
622
|
switch (name) {
|
|
541
|
-
case '
|
|
542
|
-
this.
|
|
623
|
+
case 'cascade-blend':
|
|
624
|
+
this.cascadeBlend = parseNumber(newValue, 0, name);
|
|
625
|
+
break;
|
|
626
|
+
case 'cascade-distribution':
|
|
627
|
+
this.cascadeDistribution = parseNumber(newValue, 0.5, name);
|
|
543
628
|
break;
|
|
544
629
|
case 'cast-shadows':
|
|
545
630
|
this.castShadows = parseBool(newValue, false);
|
|
546
631
|
break;
|
|
632
|
+
case 'color':
|
|
633
|
+
this.color = parseColor(newValue, Color.WHITE, name);
|
|
634
|
+
break;
|
|
547
635
|
case 'inner-cone-angle':
|
|
548
636
|
this.innerConeAngle = parseNumber(newValue, 40, name);
|
|
549
637
|
break;
|
|
@@ -551,7 +639,10 @@ class LightComponentElement extends ComponentElement {
|
|
|
551
639
|
this.intensity = parseNumber(newValue, 1, name);
|
|
552
640
|
break;
|
|
553
641
|
case 'normal-offset-bias':
|
|
554
|
-
this.normalOffsetBias = parseNumber(newValue, 0
|
|
642
|
+
this.normalOffsetBias = parseNumber(newValue, 0, name);
|
|
643
|
+
break;
|
|
644
|
+
case 'num-cascades':
|
|
645
|
+
this.numCascades = parseNumber(newValue, 1, name);
|
|
555
646
|
break;
|
|
556
647
|
case 'outer-cone-angle':
|
|
557
648
|
this.outerConeAngle = parseNumber(newValue, 45, name);
|
|
@@ -566,20 +657,20 @@ class LightComponentElement extends ComponentElement {
|
|
|
566
657
|
this.range = parseNumber(newValue, 10, name);
|
|
567
658
|
break;
|
|
568
659
|
case 'shadow-bias':
|
|
569
|
-
this.shadowBias = parseNumber(newValue, 0.
|
|
570
|
-
break;
|
|
571
|
-
case 'shadow-distance':
|
|
572
|
-
this.shadowDistance = parseNumber(newValue, 16, name);
|
|
660
|
+
this.shadowBias = parseNumber(newValue, 0.05, name);
|
|
573
661
|
break;
|
|
574
662
|
case 'shadow-blocker-samples':
|
|
575
663
|
this.shadowBlockerSamples = parseNumber(newValue, 16, name);
|
|
576
664
|
break;
|
|
577
|
-
case 'shadow-
|
|
578
|
-
this.
|
|
665
|
+
case 'shadow-distance':
|
|
666
|
+
this.shadowDistance = parseNumber(newValue, 40, name);
|
|
579
667
|
break;
|
|
580
668
|
case 'shadow-intensity':
|
|
581
669
|
this.shadowIntensity = parseNumber(newValue, 1, name);
|
|
582
670
|
break;
|
|
671
|
+
case 'shadow-resolution':
|
|
672
|
+
this.shadowResolution = parseNumber(newValue, 1024, name);
|
|
673
|
+
break;
|
|
583
674
|
case 'shadow-samples':
|
|
584
675
|
this.shadowSamples = parseNumber(newValue, 16, name);
|
|
585
676
|
break;
|
|
@@ -590,7 +681,7 @@ class LightComponentElement extends ComponentElement {
|
|
|
590
681
|
this.type = parseEnum(newValue, ['directional', 'omni', 'spot'], 'directional', name);
|
|
591
682
|
break;
|
|
592
683
|
case 'vsm-bias':
|
|
593
|
-
this.vsmBias = parseNumber(newValue, 0.
|
|
684
|
+
this.vsmBias = parseNumber(newValue, 0.0025, name);
|
|
594
685
|
break;
|
|
595
686
|
case 'vsm-blur-size':
|
|
596
687
|
this.vsmBlurSize = parseNumber(newValue, 11, name);
|
|
@@ -12,6 +12,10 @@ import { ComponentElement } from './component';
|
|
|
12
12
|
*
|
|
13
13
|
* Engine component: {@link ParticleSystemComponent} (`particlesystem`).
|
|
14
14
|
*
|
|
15
|
+
* @elementSummary The `<pc-particle-system>` element emits particles from its entity, with
|
|
16
|
+
* attributes for the emitter's shape, rate, lifetime, textures and blending. Must be a child of a
|
|
17
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
18
|
+
*
|
|
15
19
|
* @category Components
|
|
16
20
|
*/
|
|
17
21
|
class ParticleSystemComponentElement extends ComponentElement {
|
|
@@ -17,6 +17,11 @@ import { ComponentElement } from './component';
|
|
|
17
17
|
*
|
|
18
18
|
* Engine component: {@link RenderComponent} (`render`).
|
|
19
19
|
*
|
|
20
|
+
* @elementSummary The `<pc-render>` element renders one of the engine's built-in primitives at its
|
|
21
|
+
* entity — box, sphere, capsule, cone, cylinder or plane — shaded by the `<pc-material>` its
|
|
22
|
+
* `material` attribute names. For glTF content, use `<pc-model>` instead. Must be a child of a
|
|
23
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
24
|
+
*
|
|
20
25
|
* @category Components
|
|
21
26
|
*/
|
|
22
27
|
class RenderComponentElement extends ComponentElement {
|
|
@@ -13,6 +13,11 @@ import { ComponentElement } from './component';
|
|
|
13
13
|
*
|
|
14
14
|
* Engine component: {@link RigidBodyComponent} (`rigidbody`).
|
|
15
15
|
*
|
|
16
|
+
* @elementSummary The `<pc-rigid-body>` element hands its entity to the physics simulation, with
|
|
17
|
+
* attributes for its type, mass, friction and restitution. It needs a sibling `<pc-collision>` for
|
|
18
|
+
* its shape, and `Ammo` loaded through `<pc-wasm>`. Must be a child of a `<pc-entity>`,
|
|
19
|
+
* `<pc-model>` or `<pc-node>`.
|
|
20
|
+
*
|
|
16
21
|
* @category Components
|
|
17
22
|
*/
|
|
18
23
|
class RigidBodyComponentElement extends ComponentElement {
|
|
@@ -22,6 +22,10 @@ const scaleModes = new Map<'none' | 'blend', string>([
|
|
|
22
22
|
*
|
|
23
23
|
* Engine component: {@link ScreenComponent} (`screen`).
|
|
24
24
|
*
|
|
25
|
+
* @elementSummary The `<pc-screen>` element gives its entity a 2D space — in screen space or in the
|
|
26
|
+
* world — that a hierarchy of `<pc-element>` descendants lays out inside. Must be a child of a
|
|
27
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
28
|
+
*
|
|
25
29
|
* @category Components
|
|
26
30
|
*/
|
|
27
31
|
class ScreenComponentElement extends ComponentElement {
|
|
@@ -250,6 +250,9 @@ export type ScriptNameChangeEvent = {
|
|
|
250
250
|
*
|
|
251
251
|
* Engine component: {@link ScriptComponent} (`script`).
|
|
252
252
|
*
|
|
253
|
+
* @elementSummary The `<pc-script>` element holds the `<pc-script-instance>` children that attach
|
|
254
|
+
* scripts to its entity. Must be a child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
255
|
+
*
|
|
253
256
|
* @category Components
|
|
254
257
|
*/
|
|
255
258
|
class ScriptComponentElement extends ComponentElement {
|
|
@@ -29,6 +29,10 @@ import { parseBool } from '../parse';
|
|
|
29
29
|
* The element becomes ready once its script instance has been created by the parent
|
|
30
30
|
* `<pc-script>` element.
|
|
31
31
|
*
|
|
32
|
+
* @elementSummary The `<pc-script-instance>` element attaches one script class, named by `name`, to
|
|
33
|
+
* the entity of its parent `<pc-script>`. Its other attributes set script attributes of the same
|
|
34
|
+
* name, and `attributes` takes a JSON object instead. Must be a direct child of `<pc-script>`.
|
|
35
|
+
*
|
|
32
36
|
* @fires {CustomEvent} scriptattributeschange - Fired when the script's attributes change. The
|
|
33
37
|
* `detail` carries the new `attributes` object. Bubbles.
|
|
34
38
|
* @fires {CustomEvent} scriptenablechange - Fired when the script's enabled state changes. The
|
|
@@ -31,6 +31,10 @@ const visibilities = new Map<'always' | 'when-required', number>([
|
|
|
31
31
|
*
|
|
32
32
|
* Engine component: {@link ScrollViewComponent} (`scrollview`).
|
|
33
33
|
*
|
|
34
|
+
* @elementSummary The `<pc-scroll-view>` element scrolls a larger content entity within a clipped
|
|
35
|
+
* viewport at its entity, optionally driven by the `<pc-scrollbar>` elements it references. Must be
|
|
36
|
+
* a child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
37
|
+
*
|
|
34
38
|
* @category Components
|
|
35
39
|
*/
|
|
36
40
|
class ScrollViewComponentElement extends ComponentElement {
|
|
@@ -18,6 +18,10 @@ const orientations = new Map<'horizontal' | 'vertical', number>([
|
|
|
18
18
|
*
|
|
19
19
|
* Engine component: {@link ScrollbarComponent} (`scrollbar`).
|
|
20
20
|
*
|
|
21
|
+
* @elementSummary The `<pc-scrollbar>` element gives its entity a draggable handle reporting a
|
|
22
|
+
* position from 0 to 1, which a `<pc-scroll-view>` references to scroll its content. Must be a
|
|
23
|
+
* child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
24
|
+
*
|
|
21
25
|
* @category Components
|
|
22
26
|
*/
|
|
23
27
|
class ScrollbarComponentElement extends ComponentElement {
|
|
@@ -12,6 +12,10 @@ import { ComponentElement } from './component';
|
|
|
12
12
|
*
|
|
13
13
|
* Engine component: {@link SoundComponent} (`sound`).
|
|
14
14
|
*
|
|
15
|
+
* @elementSummary The `<pc-sound>` element holds the `<pc-sound-slot>` children that play sounds at
|
|
16
|
+
* its entity, along with the positional audio settings they share. Must be a child of a
|
|
17
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
18
|
+
*
|
|
15
19
|
* @category Components
|
|
16
20
|
*/
|
|
17
21
|
class SoundComponentElement extends ComponentElement {
|
|
@@ -10,6 +10,9 @@ import { SoundComponentElement } from './sound-component';
|
|
|
10
10
|
* The SoundSlotElement interface provides properties and methods for manipulating
|
|
11
11
|
* `<pc-sound-slot>` elements. The SoundSlotElement interface also inherits the properties and
|
|
12
12
|
* methods of the {@link AsyncElement} interface.
|
|
13
|
+
*
|
|
14
|
+
* @elementSummary The `<pc-sound-slot>` element declares one named sound on its parent `<pc-sound>`
|
|
15
|
+
* — its asset, volume, pitch, looping and autoplay. Must be a direct child of `<pc-sound>`.
|
|
13
16
|
*/
|
|
14
17
|
class SoundSlotElement extends AsyncElement {
|
|
15
18
|
private _asset = '';
|
package/src/entity-base.ts
CHANGED
|
@@ -4,18 +4,29 @@ import type { AppElement } from './app';
|
|
|
4
4
|
import { AsyncElement } from './async-element';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* The
|
|
8
|
-
*
|
|
7
|
+
* The event types the containing `<pc-app>` synthesizes on entity-fronting elements via picking:
|
|
8
|
+
* the `pointer*` events, plus `click` — which concludes a primary-button press and release, and
|
|
9
|
+
* is delivered as a `PointerEvent` exactly as modern browsers deliver native clicks.
|
|
9
10
|
* @internal
|
|
10
11
|
*/
|
|
11
|
-
export const
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'
|
|
12
|
+
export const SYNTHESIZED_EVENTS = [
|
|
13
|
+
'pointerenter',
|
|
14
|
+
'pointerleave',
|
|
15
|
+
'pointerdown',
|
|
16
|
+
'pointerup',
|
|
17
|
+
'pointermove',
|
|
18
|
+
'click'
|
|
17
19
|
] as const;
|
|
18
20
|
|
|
21
|
+
const SYNTHESIZED_EVENT_SET: ReadonlySet<string> = new Set(SYNTHESIZED_EVENTS);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The attribute names of the inline event handlers (`onpointerdown`, `onclick`, ...), shared by
|
|
25
|
+
* every element that fronts an engine entity. Spread into `observedAttributes` by subclasses.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export const EVENT_ATTRIBUTES = SYNTHESIZED_EVENTS.map((type) => `on${type}`);
|
|
29
|
+
|
|
19
30
|
/**
|
|
20
31
|
* The base class for elements that front an engine {@link Entity}: `<pc-entity>` and
|
|
21
32
|
* `<pc-model>`, which create one, and `<pc-node>`, which binds to one inside a model's
|
|
@@ -34,12 +45,13 @@ class EntityBaseElement extends AsyncElement {
|
|
|
34
45
|
protected _appElement: AppElement | null = null;
|
|
35
46
|
|
|
36
47
|
/**
|
|
37
|
-
* The
|
|
48
|
+
* The event listeners registered on the element, by type.
|
|
38
49
|
*/
|
|
39
50
|
private _listeners: Record<string, EventListener[]> = {};
|
|
40
51
|
|
|
41
52
|
/**
|
|
42
|
-
* The event types for which an inline
|
|
53
|
+
* The event types for which an inline handler attribute (`onpointerdown`, `onclick`, ...)
|
|
54
|
+
* is currently present.
|
|
43
55
|
*/
|
|
44
56
|
private _inlineHandlerTypes = new Set<string>();
|
|
45
57
|
|
|
@@ -75,10 +87,10 @@ class EntityBaseElement extends AsyncElement {
|
|
|
75
87
|
}
|
|
76
88
|
|
|
77
89
|
/**
|
|
78
|
-
* Tracks whether an inline
|
|
90
|
+
* Tracks whether an inline handler attribute is present. The browser itself compiles and
|
|
79
91
|
* runs these attributes — they are standard `GlobalEventHandlers`, so setting one replaces
|
|
80
92
|
* the previous handler and removing it removes the handler, exactly like `onclick` on any
|
|
81
|
-
* HTML element. But because they bypass {@link addEventListener}, the connect/disconnect
|
|
93
|
+
* HTML element. But because they bypass {@link EventTarget.addEventListener}, the connect/disconnect
|
|
82
94
|
* bookkeeping that lets the application lazily attach its canvas pointer handlers must be
|
|
83
95
|
* kept in sync here.
|
|
84
96
|
*
|
|
@@ -105,7 +117,7 @@ class EntityBaseElement extends AsyncElement {
|
|
|
105
117
|
}
|
|
106
118
|
this._listeners[type].push(listener);
|
|
107
119
|
super.addEventListener(type, listener, options);
|
|
108
|
-
if (
|
|
120
|
+
if (SYNTHESIZED_EVENT_SET.has(type)) {
|
|
109
121
|
this.dispatchEvent(new CustomEvent(`${type}:connect`, { bubbles: true }));
|
|
110
122
|
}
|
|
111
123
|
}
|
|
@@ -115,15 +127,15 @@ class EntityBaseElement extends AsyncElement {
|
|
|
115
127
|
this._listeners[type] = this._listeners[type].filter((l) => l !== listener);
|
|
116
128
|
}
|
|
117
129
|
super.removeEventListener(type, listener, options);
|
|
118
|
-
if (
|
|
130
|
+
if (SYNTHESIZED_EVENT_SET.has(type)) {
|
|
119
131
|
this.dispatchEvent(new CustomEvent(`${type}:disconnect`, { bubbles: true }));
|
|
120
132
|
}
|
|
121
133
|
}
|
|
122
134
|
|
|
123
135
|
/**
|
|
124
136
|
* Whether the element has a listener for an event type, registered either with
|
|
125
|
-
* {@link addEventListener} or with the matching inline
|
|
126
|
-
* containing `<pc-app>` element to gate
|
|
137
|
+
* {@link EventTarget.addEventListener} or with the matching inline handler attribute. Read by the
|
|
138
|
+
* containing `<pc-app>` element to gate event synthesis.
|
|
127
139
|
*
|
|
128
140
|
* @param type - The event type.
|
|
129
141
|
* @returns Whether a listener is registered.
|
package/src/entity-owner.ts
CHANGED
|
@@ -69,7 +69,7 @@ class EntityOwnerElement extends EntityBaseElement {
|
|
|
69
69
|
private _tags: string[] = [];
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
|
-
* Whether the hierarchy has been built for this entity — set once
|
|
72
|
+
* Whether the hierarchy has been built for this entity — set once `_buildHierarchy` has
|
|
73
73
|
* parented it. Read by subclasses that gate work on the entity being in the scene graph.
|
|
74
74
|
*/
|
|
75
75
|
protected _built = false;
|
|
@@ -170,7 +170,7 @@ class EntityOwnerElement extends EntityBaseElement {
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
/**
|
|
173
|
-
* Called by
|
|
173
|
+
* Called by `_buildHierarchy` once the backing entity has been parented — exactly once
|
|
174
174
|
* per build cycle. The default announces readiness, which is what a parented `<pc-entity>`
|
|
175
175
|
* means; `<pc-model>` overrides it to start loading content instead, because its readiness
|
|
176
176
|
* tracks the content settling rather than the host entering the scene graph.
|
package/src/entity.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Vec3 } from 'playcanvas';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { EVENT_ATTRIBUTES } from './entity-base';
|
|
4
4
|
import { buildDescendantEntities, EntityOwnerElement } from './entity-owner';
|
|
5
5
|
import { parseBool, parseTags, parseVec3 } from './parse';
|
|
6
6
|
|
|
@@ -12,8 +12,13 @@ import { parseBool, parseTags, parseVec3 } from './parse';
|
|
|
12
12
|
*
|
|
13
13
|
* The pointer events below are dispatched by the containing `<pc-app>` element when the pointer
|
|
14
14
|
* intersects this entity's geometry. They are only generated while the entity has a listener for
|
|
15
|
-
* them, registered either with {@link addEventListener} or with the matching inline
|
|
16
|
-
* attribute.
|
|
15
|
+
* them, registered either with {@link EventTarget.addEventListener} or with the matching inline
|
|
16
|
+
* attribute (`onpointerdown`, `onclick`, ...).
|
|
17
|
+
*
|
|
18
|
+
* @elementSummary The `<pc-entity>` element creates an entity: a named, transformable node of the
|
|
19
|
+
* scene hierarchy, and the host for component elements such as `<pc-camera>`, `<pc-light>` and
|
|
20
|
+
* `<pc-render>`. Place it in the `<pc-scene>`, or nest it under another `<pc-entity>`, a
|
|
21
|
+
* `<pc-model>` or a `<pc-node>` to parent it there.
|
|
17
22
|
*
|
|
18
23
|
* @attribute {boolean} enabled - The enabled state of the entity.
|
|
19
24
|
* @attribute {string} name - The name of the entity.
|
|
@@ -28,11 +33,17 @@ import { parseBool, parseTags, parseVec3 } from './parse';
|
|
|
28
33
|
* entity.
|
|
29
34
|
* @attribute {string} onpointerup - Script to run when a pointer button is released over the
|
|
30
35
|
* entity.
|
|
36
|
+
* @attribute {string} onclick - Script to run when the entity is clicked: a primary pointer
|
|
37
|
+
* button pressed and then released over it.
|
|
31
38
|
* @fires {PointerEvent} pointerenter - Fired when the pointer moves onto the entity.
|
|
32
39
|
* @fires {PointerEvent} pointerleave - Fired when the pointer moves off the entity.
|
|
33
40
|
* @fires {PointerEvent} pointermove - Fired when the pointer moves over the entity.
|
|
34
41
|
* @fires {PointerEvent} pointerdown - Fired when a pointer button is pressed over the entity.
|
|
35
42
|
* @fires {PointerEvent} pointerup - Fired when a pointer button is released over the entity.
|
|
43
|
+
* @fires {PointerEvent} click - Fired when a primary pointer button is pressed and then released
|
|
44
|
+
* over the entity. A press and release that picked different entities fires on their nearest
|
|
45
|
+
* common ancestor instead, as in the DOM. `detail` carries the click count, so a double click
|
|
46
|
+
* arrives as a click whose `detail` is 2.
|
|
36
47
|
*/
|
|
37
48
|
class EntityElement extends EntityOwnerElement {
|
|
38
49
|
connectedCallback() {
|
|
@@ -72,7 +83,7 @@ class EntityElement extends EntityOwnerElement {
|
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
static get observedAttributes() {
|
|
75
|
-
return ['enabled', 'name', 'position', 'rotation', 'scale', 'tags', ...
|
|
86
|
+
return ['enabled', 'name', 'position', 'rotation', 'scale', 'tags', ...EVENT_ATTRIBUTES];
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null) {
|
|
@@ -100,6 +111,7 @@ class EntityElement extends EntityOwnerElement {
|
|
|
100
111
|
case 'onpointerdown':
|
|
101
112
|
case 'onpointerup':
|
|
102
113
|
case 'onpointermove':
|
|
114
|
+
case 'onclick':
|
|
103
115
|
this._updateInlineHandler(name, newValue);
|
|
104
116
|
break;
|
|
105
117
|
}
|
package/src/index.ts
CHANGED
|
@@ -134,6 +134,17 @@ export {
|
|
|
134
134
|
whenReady
|
|
135
135
|
};
|
|
136
136
|
|
|
137
|
+
export type { AddressMode, MagFilterMode, MinFilterMode } from './asset';
|
|
137
138
|
export type { AsyncElementTagName } from './async-element';
|
|
139
|
+
export type { JointType, MotionMode } from './components/joint-component';
|
|
140
|
+
export type {
|
|
141
|
+
BlendType,
|
|
142
|
+
ColorChannel,
|
|
143
|
+
CullMode,
|
|
144
|
+
FresnelModel,
|
|
145
|
+
OccludeSpecular,
|
|
146
|
+
OpacityDither,
|
|
147
|
+
ScalarChannel
|
|
148
|
+
} from './material';
|
|
138
149
|
export type { HierarchyMaterial, HierarchyNode } from './model';
|
|
139
|
-
export type { MaterialOverrides } from './node';
|
|
150
|
+
export type { MaterialOverrides, NodeBindingState } from './node';
|
package/src/material.ts
CHANGED
|
@@ -29,7 +29,8 @@ import type { AppElement } from './app';
|
|
|
29
29
|
import { useAsset } from './asset';
|
|
30
30
|
import { parseBool, parseColor, parseEnum, parseNumber, parseVec2 } from './parse';
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
/** The blend modes for a material. */
|
|
33
|
+
export type BlendType =
|
|
33
34
|
| 'none'
|
|
34
35
|
| 'normal'
|
|
35
36
|
| 'additive'
|
|
@@ -56,7 +57,8 @@ const blendTypes = new Map<BlendType, number>([
|
|
|
56
57
|
['subtractive', BLEND_SUBTRACTIVE]
|
|
57
58
|
]);
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
/** The face culling modes for a material. */
|
|
61
|
+
export type CullMode = 'none' | 'back' | 'front' | 'front-and-back';
|
|
60
62
|
|
|
61
63
|
const cullModes = new Map<CullMode, number>([
|
|
62
64
|
['none', CULLFACE_NONE],
|
|
@@ -65,14 +67,16 @@ const cullModes = new Map<CullMode, number>([
|
|
|
65
67
|
['front-and-back', CULLFACE_FRONTANDBACK]
|
|
66
68
|
]);
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
/** The Fresnel models for a material. */
|
|
71
|
+
export type FresnelModel = 'none' | 'schlick';
|
|
69
72
|
|
|
70
73
|
const fresnelModels = new Map<FresnelModel, number>([
|
|
71
74
|
['none', FRESNEL_NONE],
|
|
72
75
|
['schlick', FRESNEL_SCHLICK]
|
|
73
76
|
]);
|
|
74
77
|
|
|
75
|
-
|
|
78
|
+
/** The specular occlusion modes for a material. */
|
|
79
|
+
export type OccludeSpecular = 'none' | 'ao' | 'gloss-dependent';
|
|
76
80
|
|
|
77
81
|
const occludeSpeculars = new Map<OccludeSpecular, number>([
|
|
78
82
|
['none', SPECOCC_NONE],
|
|
@@ -80,17 +84,20 @@ const occludeSpeculars = new Map<OccludeSpecular, number>([
|
|
|
80
84
|
['gloss-dependent', SPECOCC_GLOSSDEPENDENT]
|
|
81
85
|
]);
|
|
82
86
|
|
|
87
|
+
/** The opacity dithering modes for a material. */
|
|
88
|
+
export type OpacityDither = 'none' | 'bayer8' | 'bluenoise' | 'ignnoise';
|
|
89
|
+
|
|
83
90
|
// The DITHER_* constants are strings whose values are exactly these names, so a parsed value is
|
|
84
91
|
// assigned to the material unchanged rather than mapped through a table.
|
|
85
|
-
type OpacityDither = 'none' | 'bayer8' | 'bluenoise' | 'ignnoise';
|
|
86
|
-
|
|
87
92
|
const opacityDithers: OpacityDither[] = ['none', 'bayer8', 'bluenoise', 'ignnoise'];
|
|
88
93
|
|
|
89
|
-
|
|
94
|
+
/** The texture channels a color map can sample. */
|
|
95
|
+
export type ColorChannel = 'r' | 'g' | 'b' | 'a' | 'rgb';
|
|
90
96
|
|
|
91
97
|
const colorChannels: ColorChannel[] = ['r', 'g', 'b', 'a', 'rgb'];
|
|
92
98
|
|
|
93
|
-
|
|
99
|
+
/** The texture channels a scalar map can sample. */
|
|
100
|
+
export type ScalarChannel = 'r' | 'g' | 'b' | 'a';
|
|
94
101
|
|
|
95
102
|
const scalarChannels: ScalarChannel[] = ['r', 'g', 'b', 'a'];
|
|
96
103
|
|
|
@@ -136,6 +143,10 @@ type TextureSlot =
|
|
|
136
143
|
* The two aliases are documented here rather than on an accessor, because they resolve to the
|
|
137
144
|
* `gloss` properties and would otherwise inherit gloss's description - which reads inverted.
|
|
138
145
|
*
|
|
146
|
+
* @elementSummary The `<pc-material>` element defines a physically based material, which
|
|
147
|
+
* `<pc-render>` elements apply by naming its `id`. It is metal/rough by default, with `metalness`
|
|
148
|
+
* starting at 0. Must be a direct child of `<pc-app>`.
|
|
149
|
+
*
|
|
139
150
|
* @attribute {number} roughness - The roughness of the material, from 0 (shiny) to 1 (rough). An
|
|
140
151
|
* alias for `gloss` that also inverts it, so do not combine it with the `gloss` attributes.
|
|
141
152
|
* @attribute {string} roughness-map - The id of the `pc-asset` to use as the roughness map. An
|