@playcanvas/web-components 0.16.0 → 0.18.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 +18 -13
- package/dist/app.d.ts +18 -13
- package/dist/asset.d.cts +13 -3
- package/dist/asset.d.ts +13 -3
- package/dist/async-element.d.cts +13 -13
- package/dist/async-element.d.ts +13 -13
- package/dist/components/anim-clip.d.cts +4 -0
- package/dist/components/anim-clip.d.ts +4 -0
- package/dist/components/anim-component.d.cts +38 -5
- package/dist/components/anim-component.d.ts +38 -5
- package/dist/components/audio-listener-component.d.cts +26 -0
- package/dist/components/audio-listener-component.d.ts +26 -0
- package/dist/components/button-component.d.cts +10 -1
- package/dist/components/button-component.d.ts +10 -1
- package/dist/components/camera-component.d.cts +37 -1
- package/dist/components/camera-component.d.ts +37 -1
- package/dist/components/collision-component.d.cts +9 -1
- package/dist/components/collision-component.d.ts +9 -1
- package/dist/components/component.d.cts +3 -2
- package/dist/components/component.d.ts +3 -2
- package/dist/components/element-component.d.cts +11 -0
- package/dist/components/element-component.d.ts +11 -0
- package/dist/components/gsplat-component.d.cts +6 -0
- package/dist/components/gsplat-component.d.ts +6 -0
- package/dist/components/joint-component.d.cts +14 -2
- package/dist/components/joint-component.d.ts +14 -2
- package/dist/components/{layoutchild-component.d.cts → layout-child-component.d.cts} +7 -1
- package/dist/components/{layoutchild-component.d.ts → layout-child-component.d.ts} +7 -1
- package/dist/components/{layoutgroup-component.d.cts → layout-group-component.d.cts} +7 -1
- package/dist/components/{layoutgroup-component.d.ts → layout-group-component.d.ts} +7 -1
- package/dist/components/light-component.d.cts +52 -1
- package/dist/components/light-component.d.ts +52 -1
- package/dist/components/{particlesystem-component.d.cts → particle-system-component.d.cts} +7 -1
- package/dist/components/{particlesystem-component.d.ts → particle-system-component.d.ts} +7 -1
- package/dist/components/render-component.d.cts +7 -0
- package/dist/components/render-component.d.ts +7 -0
- package/dist/components/{rigidbody-component.d.cts → rigid-body-component.d.cts} +8 -1
- package/dist/components/{rigidbody-component.d.ts → rigid-body-component.d.ts} +8 -1
- package/dist/components/screen-component.d.cts +6 -0
- package/dist/components/screen-component.d.ts +6 -0
- package/dist/components/script-component.d.cts +26 -12
- package/dist/components/script-component.d.ts +26 -12
- package/dist/components/{script.d.cts → script-instance.d.cts} +11 -7
- package/dist/components/{script.d.ts → script-instance.d.ts} +11 -7
- package/dist/components/{scrollview-component.d.cts → scroll-view-component.d.cts} +7 -1
- package/dist/components/{scrollview-component.d.ts → scroll-view-component.d.ts} +7 -1
- package/dist/components/scrollbar-component.d.cts +6 -0
- package/dist/components/scrollbar-component.d.ts +6 -0
- package/dist/components/sound-component.d.cts +7 -1
- package/dist/components/sound-component.d.ts +7 -1
- package/dist/components/sound-slot.d.cts +5 -2
- package/dist/components/sound-slot.d.ts +5 -2
- package/dist/custom-elements.json +1852 -974
- package/dist/entity-base.d.cts +7 -6
- package/dist/entity-base.d.ts +7 -6
- package/dist/entity-owner.d.cts +118 -0
- package/dist/entity-owner.d.ts +118 -0
- package/dist/entity.d.cts +14 -102
- package/dist/entity.d.ts +14 -102
- package/dist/index.d.cts +26 -22
- package/dist/index.d.ts +26 -22
- package/dist/material.d.cts +18 -7
- package/dist/material.d.ts +18 -7
- package/dist/model.d.cts +72 -24
- package/dist/model.d.ts +72 -24
- package/dist/node.d.cts +6 -1
- package/dist/node.d.ts +6 -1
- package/dist/pwc.cjs +807 -293
- package/dist/pwc.cjs.map +1 -1
- package/dist/pwc.js +807 -293
- 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 +805 -292
- package/dist/pwc.mjs.map +1 -1
- package/dist/scene.d.cts +3 -0
- package/dist/scene.d.ts +3 -0
- package/dist/sky.d.cts +4 -0
- package/dist/sky.d.ts +4 -0
- package/dist/vscode.html-custom-data.json +351 -121
- package/dist/{module.d.cts → wasm.d.cts} +10 -6
- package/dist/{module.d.ts → wasm.d.ts} +10 -6
- package/dist/web-types.json +465 -291
- package/package.json +7 -7
- package/src/app.ts +49 -35
- package/src/asset.ts +13 -4
- package/src/async-element.ts +14 -14
- package/src/components/anim-clip.ts +4 -0
- package/src/components/anim-component.ts +89 -14
- package/src/components/audio-listener-component.ts +36 -0
- package/src/components/button-component.ts +10 -1
- package/src/components/camera-component.ts +65 -6
- package/src/components/collision-component.ts +9 -1
- package/src/components/component.ts +4 -3
- package/src/components/element-component.ts +11 -0
- package/src/components/gsplat-component.ts +6 -0
- package/src/components/joint-component.ts +14 -2
- package/src/components/{layoutchild-component.ts → layout-child-component.ts} +8 -2
- package/src/components/{layoutgroup-component.ts → layout-group-component.ts} +8 -2
- package/src/components/light-component.ts +110 -17
- package/src/components/{particlesystem-component.ts → particle-system-component.ts} +8 -2
- package/src/components/render-component.ts +7 -0
- package/src/components/{rigidbody-component.ts → rigid-body-component.ts} +9 -2
- package/src/components/screen-component.ts +6 -0
- package/src/components/script-component.ts +66 -42
- package/src/components/{script.ts → script-instance.ts} +18 -14
- package/src/components/{scrollview-component.ts → scroll-view-component.ts} +8 -2
- package/src/components/scrollbar-component.ts +6 -0
- package/src/components/sound-component.ts +8 -2
- package/src/components/sound-slot.ts +7 -4
- package/src/entity-base.ts +8 -7
- package/src/entity-owner.ts +298 -0
- package/src/entity.ts +21 -271
- package/src/index.ts +38 -25
- package/src/material.ts +19 -8
- package/src/model.ts +164 -72
- package/src/node.ts +15 -6
- package/src/scene.ts +3 -0
- package/src/sky.ts +4 -0
- package/src/{module.ts → wasm.ts} +12 -8
- package/dist/components/listener-component.d.cts +0 -20
- package/dist/components/listener-component.d.ts +0 -20
- package/src/components/listener-component.ts +0 -30
package/dist/pwc.cjs
CHANGED
|
@@ -29,13 +29,13 @@ class AsyncElement extends HTMLElement {
|
|
|
29
29
|
return this.parentElement?.closest('pc-app') ?? null;
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
|
-
* The nearest ancestor element that fronts an entity — `<pc-entity
|
|
33
|
-
* `null` if this element has no such ancestor. The search starts at the
|
|
34
|
-
* never resolves to itself.
|
|
32
|
+
* The nearest ancestor element that fronts an entity — `<pc-entity>`, `<pc-model>` or
|
|
33
|
+
* `<pc-node>` — or `null` if this element has no such ancestor. The search starts at the
|
|
34
|
+
* parent, so an element never resolves to itself.
|
|
35
35
|
* @returns The closest entity-fronting element, or `null`.
|
|
36
36
|
*/
|
|
37
37
|
get closestEntity() {
|
|
38
|
-
return this.parentElement?.closest('pc-entity, pc-node') ?? null;
|
|
38
|
+
return this.parentElement?.closest('pc-entity, pc-model, pc-node') ?? null;
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* Called when the element is fully initialized and ready. Subclasses should call this when
|
|
@@ -109,9 +109,9 @@ async function whenReady(target) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
|
-
* The
|
|
113
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-
|
|
114
|
-
* elements. The
|
|
112
|
+
* The WasmElement interface provides properties and methods for manipulating
|
|
113
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-wasm/ | `<pc-wasm>`}
|
|
114
|
+
* elements. The WasmElement interface also inherits the properties and methods of the
|
|
115
115
|
* {@link AsyncElement} interface.
|
|
116
116
|
*
|
|
117
117
|
* The attributes are read once, when the module starts loading - on the element's first
|
|
@@ -120,9 +120,13 @@ async function whenReady(target) {
|
|
|
120
120
|
* modules configure engine-global state that never unloads, so readiness is not re-armed by
|
|
121
121
|
* removing the element, and a re-inserted element does not load again.
|
|
122
122
|
*
|
|
123
|
-
* A `<pc-
|
|
123
|
+
* A `<pc-wasm>` without a `name` warns and never becomes ready; a containing `<pc-app>` still
|
|
124
124
|
* boots.
|
|
125
125
|
*
|
|
126
|
+
* @elementSummary The `<pc-wasm>` element loads a WebAssembly module the engine needs before the
|
|
127
|
+
* application starts — `Ammo` for physics, `Basis` or `DracoDecoderModule` for compressed assets.
|
|
128
|
+
* Must be a direct child of `<pc-app>`.
|
|
129
|
+
*
|
|
126
130
|
* @attribute {string} name - The name of the WebAssembly module to configure, e.g. `Basis` or
|
|
127
131
|
* `Ammo`.
|
|
128
132
|
* @attribute {string} glue - The URL of the module's glue script.
|
|
@@ -130,7 +134,7 @@ async function whenReady(target) {
|
|
|
130
134
|
* @attribute {string} fallback - The URL of the module's asm.js fallback script, used when
|
|
131
135
|
* WebAssembly is unavailable.
|
|
132
136
|
*/
|
|
133
|
-
class
|
|
137
|
+
class WasmElement extends AsyncElement {
|
|
134
138
|
_loadPromise = null;
|
|
135
139
|
connectedCallback() {
|
|
136
140
|
this._getLoadPromise();
|
|
@@ -138,7 +142,7 @@ class ModuleElement extends AsyncElement {
|
|
|
138
142
|
async _loadModule() {
|
|
139
143
|
const name = this.getAttribute('name');
|
|
140
144
|
if (!name) {
|
|
141
|
-
console.warn("pc-
|
|
145
|
+
console.warn("pc-wasm requires a 'name' attribute - no module was configured");
|
|
142
146
|
return;
|
|
143
147
|
}
|
|
144
148
|
const config = {
|
|
@@ -173,7 +177,7 @@ class ModuleElement extends AsyncElement {
|
|
|
173
177
|
return this._loadPromise;
|
|
174
178
|
}
|
|
175
179
|
}
|
|
176
|
-
customElements.define('pc-
|
|
180
|
+
customElements.define('pc-wasm', WasmElement);
|
|
177
181
|
|
|
178
182
|
/** Covers the 0.2s opacity transition; jsdom never fires transitionend, so removal is timed. */
|
|
179
183
|
const REMOVAL_DELAY_MS = 250;
|
|
@@ -730,6 +734,12 @@ const getEntity = (ref) => {
|
|
|
730
734
|
|
|
731
735
|
/** The pointer event types the application synthesizes on `<pc-entity>` elements via picking. */
|
|
732
736
|
const pointerEventTypes = ['pointermove', 'pointerdown', 'pointerup', 'pointerenter', 'pointerleave'];
|
|
737
|
+
/**
|
|
738
|
+
* The event types whose listeners make an element a hover target. Hover resolution walks past
|
|
739
|
+
* elements listening for none of them, so a silent element never swallows an ancestor's
|
|
740
|
+
* enter/leave pair.
|
|
741
|
+
*/
|
|
742
|
+
const hoverEventTypes = ['pointerenter', 'pointerleave', 'pointermove'];
|
|
733
743
|
/**
|
|
734
744
|
* Gives `pc-app` the sizing contract of a replaced element (`<video>`, `<img>`): a block-level
|
|
735
745
|
* box that the page's CSS sizes, defaulting to the canvas's own 300x150 intrinsic size, with the
|
|
@@ -758,6 +768,10 @@ const ensureBaseStyles = () => {
|
|
|
758
768
|
* tracked live via a ResizeObserver — so the element can be embedded at any size, resized by
|
|
759
769
|
* its container, or made fullscreen with ordinary CSS such as `width: 100vw; height: 100dvh`.
|
|
760
770
|
*
|
|
771
|
+
* @elementSummary The `<pc-app>` element creates a PlayCanvas application and the canvas it renders
|
|
772
|
+
* into, and is the root of every scene. It holds the `<pc-asset>`, `<pc-material>`, `<pc-wasm>` and
|
|
773
|
+
* `<pc-scene>` elements, and the page's CSS sizes it, as it would a `<video>`.
|
|
774
|
+
*
|
|
761
775
|
* @fires {ProgressEvent} progress - Fired while the application preloads its assets. `loaded` and
|
|
762
776
|
* `total` are asset counts, not bytes, and an asset that fails to load still counts as loaded.
|
|
763
777
|
* Fired at least once per boot, and the final event always has `loaded` equal to `total`. Does
|
|
@@ -804,9 +818,9 @@ class AppElement extends AsyncElement {
|
|
|
804
818
|
_bootGeneration = 0;
|
|
805
819
|
/**
|
|
806
820
|
* The elements backing this application's entities, keyed by the entity itself. Registered
|
|
807
|
-
* by
|
|
808
|
-
*
|
|
809
|
-
* identity - never by name.
|
|
821
|
+
* by entity-owning elements at creation (pc-entity, and pc-model for its host) and by
|
|
822
|
+
* NodeElement at binding, and removed when an entity is destroyed or unbound, this joins
|
|
823
|
+
* engine scene nodes back to their owning elements by identity - never by name.
|
|
810
824
|
*/
|
|
811
825
|
_entityElements = new Map();
|
|
812
826
|
_picker = null;
|
|
@@ -885,7 +899,7 @@ class AppElement extends AsyncElement {
|
|
|
885
899
|
// there, leaving the element permanently unready: no canvas, no entities, no application.
|
|
886
900
|
//
|
|
887
901
|
// Upgrading is the fix here rather than skipping whatever has not upgraded, because a
|
|
888
|
-
// <pc-
|
|
902
|
+
// <pc-wasm> is the one child that nothing else ever builds on its own behalf - skipping
|
|
889
903
|
// it would drop the wasm module the app asked for, silently and only for cloned apps.
|
|
890
904
|
// Upgrading runs each descendant's connectedCallback synchronously, a few lines earlier
|
|
891
905
|
// than the parser's path runs them but into the same state they see there: no application
|
|
@@ -894,10 +908,10 @@ class AppElement extends AsyncElement {
|
|
|
894
908
|
// as any other disconnect is. An already-upgraded subtree - every other insertion path -
|
|
895
909
|
// is left completely untouched.
|
|
896
910
|
customElements.upgrade(this);
|
|
897
|
-
// Get all pc-
|
|
898
|
-
const
|
|
911
|
+
// Get all pc-wasm elements that are direct children of the pc-app element
|
|
912
|
+
const wasmElements = this.querySelectorAll(':scope > pc-wasm');
|
|
899
913
|
// Wait for all modules to load
|
|
900
|
-
await Promise.all(Array.from(
|
|
914
|
+
await Promise.all(Array.from(wasmElements).map((element) => element._getLoadPromise()));
|
|
901
915
|
// The element may have been removed while the modules loaded. Nothing beyond the loading
|
|
902
916
|
// bar exists yet, and disconnectedCallback has already destroyed that.
|
|
903
917
|
if (generation !== this._bootGeneration) {
|
|
@@ -1067,14 +1081,15 @@ class AppElement extends AsyncElement {
|
|
|
1067
1081
|
Array.from(materialElements).forEach((materialElement) => {
|
|
1068
1082
|
materialElement._createMaterial();
|
|
1069
1083
|
});
|
|
1070
|
-
// Create all entities
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1084
|
+
// Create all entities. pc-model joins the sweep because it owns a host entity of its
|
|
1085
|
+
// own; its instantiated content arrives later, beneath that host.
|
|
1086
|
+
const ownerElements = this.querySelectorAll('pc-entity, pc-model');
|
|
1087
|
+
Array.from(ownerElements).forEach((ownerElement) => {
|
|
1088
|
+
ownerElement._createEntity(app);
|
|
1074
1089
|
});
|
|
1075
1090
|
// Build hierarchy
|
|
1076
|
-
|
|
1077
|
-
|
|
1091
|
+
ownerElements.forEach((ownerElement) => {
|
|
1092
|
+
ownerElement._buildHierarchy(app);
|
|
1078
1093
|
});
|
|
1079
1094
|
// Building the hierarchy dispatched each entity's ready event synchronously, and a
|
|
1080
1095
|
// listener may have removed the element. The sweep itself degrades safely - destroying
|
|
@@ -1185,7 +1200,7 @@ class AppElement extends AsyncElement {
|
|
|
1185
1200
|
// created from onpointer* attributes when their elements were first upgraded, or
|
|
1186
1201
|
// listeners carried over from before a re-boot)
|
|
1187
1202
|
pointerEventTypes.forEach((type) => {
|
|
1188
|
-
const anyListeners = Array.from(this.querySelectorAll('pc-entity, pc-node')).some((entity) => entity._hasListeners(type));
|
|
1203
|
+
const anyListeners = Array.from(this.querySelectorAll('pc-entity, pc-model, pc-node')).some((entity) => entity._hasListeners(type));
|
|
1189
1204
|
if (anyListeners) {
|
|
1190
1205
|
this._onPointerListenerAdded(type);
|
|
1191
1206
|
}
|
|
@@ -1235,10 +1250,10 @@ class AppElement extends AsyncElement {
|
|
|
1235
1250
|
this._entityElements.delete(entity);
|
|
1236
1251
|
}
|
|
1237
1252
|
/**
|
|
1238
|
-
* Returns the `<pc-entity>` or `<pc-node>` element whose backing entity is
|
|
1239
|
-
* `null` if the entity is not fronted by an element of this application - for
|
|
1240
|
-
* unbound node inside a model's instantiated hierarchy, or an entity created
|
|
1241
|
-
* engine API.
|
|
1253
|
+
* Returns the `<pc-entity>`, `<pc-model>` or `<pc-node>` element whose backing entity is
|
|
1254
|
+
* `entity`, or `null` if the entity is not fronted by an element of this application - for
|
|
1255
|
+
* example, an unbound node inside a model's instantiated hierarchy, or an entity created
|
|
1256
|
+
* through the engine API.
|
|
1242
1257
|
*
|
|
1243
1258
|
* @param entity - The entity to look up.
|
|
1244
1259
|
* @returns The element fronting the entity, or `null`.
|
|
@@ -1247,18 +1262,19 @@ class AppElement extends AsyncElement {
|
|
|
1247
1262
|
return this._entityElements.get(entity) ?? null;
|
|
1248
1263
|
}
|
|
1249
1264
|
/**
|
|
1250
|
-
* Resolves the element that owns a picked node: the nearest node up the parent
|
|
1251
|
-
* starting with the node itself -
|
|
1252
|
-
*
|
|
1253
|
-
*
|
|
1265
|
+
* Resolves the element that owns hover for a picked node: the nearest node up the parent
|
|
1266
|
+
* chain - starting with the node itself - whose element listens for any of the hover event
|
|
1267
|
+
* types. Skipping silent elements matches {@link _elementWithListener}, so a registered
|
|
1268
|
+
* element with no hover listeners (a `<pc-model>` host, a plain child entity) is transparent
|
|
1269
|
+
* to hover rather than swallowing a listening ancestor's enter/leave pair.
|
|
1254
1270
|
*
|
|
1255
1271
|
* @param node - The picked node, or `null`.
|
|
1256
|
-
* @returns The owning element, or `null`.
|
|
1272
|
+
* @returns The hover-owning element, or `null`.
|
|
1257
1273
|
*/
|
|
1258
|
-
|
|
1274
|
+
_hoverTarget(node) {
|
|
1259
1275
|
while (node !== null) {
|
|
1260
1276
|
const element = this._entityElements.get(node);
|
|
1261
|
-
if (element) {
|
|
1277
|
+
if (element && hoverEventTypes.some((type) => element._hasListeners(type))) {
|
|
1262
1278
|
return element;
|
|
1263
1279
|
}
|
|
1264
1280
|
node = node.parent;
|
|
@@ -1394,9 +1410,10 @@ class AppElement extends AsyncElement {
|
|
|
1394
1410
|
const node = await this._pickNode(event);
|
|
1395
1411
|
if (token !== this._pickToken || !this._picker)
|
|
1396
1412
|
return;
|
|
1397
|
-
// The hovered element is the nearest one up the node's parent chain
|
|
1398
|
-
//
|
|
1399
|
-
|
|
1413
|
+
// The hovered element is the nearest one up the node's parent chain with a hover
|
|
1414
|
+
// listener - the nearest-listener rule down/up use. Dispatch is still gated per event
|
|
1415
|
+
// type below: having any hover listener selects the target, each event needs its own.
|
|
1416
|
+
const newHoverEntity = this._hoverTarget(node);
|
|
1400
1417
|
// Handle enter/leave events
|
|
1401
1418
|
if (this._hoveredEntity !== newHoverEntity) {
|
|
1402
1419
|
if (this._hoveredEntity && this._hoveredEntity._hasListeners('pointerleave')) {
|
|
@@ -1448,7 +1465,7 @@ class AppElement extends AsyncElement {
|
|
|
1448
1465
|
}
|
|
1449
1466
|
}
|
|
1450
1467
|
_onPointerListenerRemoved(type) {
|
|
1451
|
-
const hasListeners = Array.from(this.querySelectorAll('pc-entity, pc-node')).some((entity) => entity._hasListeners(type));
|
|
1468
|
+
const hasListeners = Array.from(this.querySelectorAll('pc-entity, pc-model, pc-node')).some((entity) => entity._hasListeners(type));
|
|
1452
1469
|
if (!hasListeners && this._canvas) {
|
|
1453
1470
|
this._hasPointerListeners[type] = false;
|
|
1454
1471
|
const handler = type === 'pointerenter' || type === 'pointerleave'
|
|
@@ -1639,11 +1656,12 @@ const POINTER_ATTRIBUTES = [
|
|
|
1639
1656
|
'onpointermove'
|
|
1640
1657
|
];
|
|
1641
1658
|
/**
|
|
1642
|
-
* The base class for elements that front an engine {@link Entity}: `<pc-entity
|
|
1643
|
-
* one, and `<pc-node>`, which binds to one inside a model's
|
|
1644
|
-
* what
|
|
1645
|
-
* picked scene nodes back to elements by identity,
|
|
1646
|
-
* bookkeeping that lets the application lazily attach
|
|
1659
|
+
* The base class for elements that front an engine {@link Entity}: `<pc-entity>` and
|
|
1660
|
+
* `<pc-model>`, which create one, and `<pc-node>`, which binds to one inside a model's
|
|
1661
|
+
* instantiated hierarchy. It carries what all of them need — the `entity` contract, registration
|
|
1662
|
+
* with the owning application (which joins picked scene nodes back to elements by identity,
|
|
1663
|
+
* never by name), and the pointer listener bookkeeping that lets the application lazily attach
|
|
1664
|
+
* its canvas handlers.
|
|
1647
1665
|
*/
|
|
1648
1666
|
class EntityBaseElement extends AsyncElement {
|
|
1649
1667
|
_entity = null;
|
|
@@ -1692,7 +1710,7 @@ class EntityBaseElement extends AsyncElement {
|
|
|
1692
1710
|
* Tracks whether an inline `onpointer*` attribute is present. The browser itself compiles and
|
|
1693
1711
|
* runs these attributes — they are standard `GlobalEventHandlers`, so setting one replaces
|
|
1694
1712
|
* the previous handler and removing it removes the handler, exactly like `onclick` on any
|
|
1695
|
-
* HTML element. But because they bypass {@link addEventListener}, the connect/disconnect
|
|
1713
|
+
* HTML element. But because they bypass {@link EventTarget.addEventListener}, the connect/disconnect
|
|
1696
1714
|
* bookkeeping that lets the application lazily attach its canvas pointer handlers must be
|
|
1697
1715
|
* kept in sync here.
|
|
1698
1716
|
*
|
|
@@ -1733,7 +1751,7 @@ class EntityBaseElement extends AsyncElement {
|
|
|
1733
1751
|
}
|
|
1734
1752
|
/**
|
|
1735
1753
|
* Whether the element has a listener for an event type, registered either with
|
|
1736
|
-
* {@link addEventListener} or with the matching inline `onpointer*` attribute. Read by the
|
|
1754
|
+
* {@link EventTarget.addEventListener} or with the matching inline `onpointer*` attribute. Read by the
|
|
1737
1755
|
* containing `<pc-app>` element to gate pointer event synthesis.
|
|
1738
1756
|
*
|
|
1739
1757
|
* @param type - The event type.
|
|
@@ -1746,17 +1764,17 @@ class EntityBaseElement extends AsyncElement {
|
|
|
1746
1764
|
}
|
|
1747
1765
|
|
|
1748
1766
|
/**
|
|
1749
|
-
* Creates and parents the entities of every descendant
|
|
1750
|
-
* that no parent's existence depends on document order. Called wherever a subtree could
|
|
1751
|
-
* itself: an element inserted into an application that is already running, and a
|
|
1752
|
-
* children waited for it to bind.
|
|
1767
|
+
* Creates and parents the entities of every descendant entity-owning element of `root`, in two
|
|
1768
|
+
* passes so that no parent's existence depends on document order. Called wherever a subtree could
|
|
1769
|
+
* not build itself: an element inserted into an application that is already running, and a
|
|
1770
|
+
* `<pc-node>` whose children waited for it to bind.
|
|
1753
1771
|
*
|
|
1754
1772
|
* Descendants that are not yet custom elements are skipped, because there is nothing useful to do
|
|
1755
1773
|
* for them and reaching for `_createEntity` would throw. A subtree cloned from a `<template>`
|
|
1756
1774
|
* arrives entirely unupgraded — template content lives in an inert document, where custom element
|
|
1757
1775
|
* definitions are never looked up — and appending the clone upgrades its elements in tree order,
|
|
1758
1776
|
* an element before its descendants. So a sweep from an element's own `connectedCallback` sees
|
|
1759
|
-
* plain `HTMLElement`s below it. Each becomes an
|
|
1777
|
+
* plain `HTMLElement`s below it. Each becomes an entity-owning element moments later and its own
|
|
1760
1778
|
* `connectedCallback` creates and parents it, by which time the ancestor it parents under has its
|
|
1761
1779
|
* entity — the same guarantee tree order gives this sweep.
|
|
1762
1780
|
*
|
|
@@ -1765,35 +1783,18 @@ class EntityBaseElement extends AsyncElement {
|
|
|
1765
1783
|
* @internal
|
|
1766
1784
|
*/
|
|
1767
1785
|
const buildDescendantEntities = (root, app) => {
|
|
1768
|
-
const children = Array.from(root.querySelectorAll('pc-entity')).filter((child) => child instanceof
|
|
1786
|
+
const children = Array.from(root.querySelectorAll('pc-entity, pc-model')).filter((child) => child instanceof EntityOwnerElement);
|
|
1769
1787
|
children.forEach((child) => child._createEntity(app));
|
|
1770
1788
|
children.forEach((child) => child._buildHierarchy(app));
|
|
1771
1789
|
};
|
|
1772
1790
|
/**
|
|
1773
|
-
* The
|
|
1774
|
-
*
|
|
1775
|
-
*
|
|
1776
|
-
*
|
|
1777
|
-
*
|
|
1778
|
-
* The pointer events below are dispatched by the containing `<pc-app>` element when the pointer
|
|
1779
|
-
* intersects this entity's geometry. They are only generated while the entity has a listener for
|
|
1780
|
-
* them, registered either with {@link addEventListener} or with the matching inline `onpointer*`
|
|
1781
|
-
* attribute.
|
|
1782
|
-
*
|
|
1783
|
-
* @attribute {string} onpointerenter - Script to run when the pointer moves onto the entity.
|
|
1784
|
-
* @attribute {string} onpointerleave - Script to run when the pointer moves off the entity.
|
|
1785
|
-
* @attribute {string} onpointermove - Script to run when the pointer moves over the entity.
|
|
1786
|
-
* @attribute {string} onpointerdown - Script to run when a pointer button is pressed over the
|
|
1787
|
-
* entity.
|
|
1788
|
-
* @attribute {string} onpointerup - Script to run when a pointer button is released over the
|
|
1789
|
-
* entity.
|
|
1790
|
-
* @fires {PointerEvent} pointerenter - Fired when the pointer moves onto the entity.
|
|
1791
|
-
* @fires {PointerEvent} pointerleave - Fired when the pointer moves off the entity.
|
|
1792
|
-
* @fires {PointerEvent} pointermove - Fired when the pointer moves over the entity.
|
|
1793
|
-
* @fires {PointerEvent} pointerdown - Fired when a pointer button is pressed over the entity.
|
|
1794
|
-
* @fires {PointerEvent} pointerup - Fired when a pointer button is released over the entity.
|
|
1791
|
+
* The base class for elements that create and own their backing entity: `<pc-entity>` and
|
|
1792
|
+
* `<pc-model>`, whose host entity carries the same authored properties. It carries the cached
|
|
1793
|
+
* property state, entity creation and parenting, and the reset that follows the entity's
|
|
1794
|
+
* destruction. `<pc-node>` sits outside this class: it borrows an entity a model instantiated,
|
|
1795
|
+
* and its properties are nullable overrides rather than owned values.
|
|
1795
1796
|
*/
|
|
1796
|
-
class
|
|
1797
|
+
class EntityOwnerElement extends EntityBaseElement {
|
|
1797
1798
|
/**
|
|
1798
1799
|
* Whether the entity is enabled.
|
|
1799
1800
|
*/
|
|
@@ -1819,7 +1820,8 @@ class EntityElement extends EntityBaseElement {
|
|
|
1819
1820
|
*/
|
|
1820
1821
|
_tags = [];
|
|
1821
1822
|
/**
|
|
1822
|
-
* Whether the hierarchy has been built for this entity
|
|
1823
|
+
* Whether the hierarchy has been built for this entity — set once `_buildHierarchy` has
|
|
1824
|
+
* parented it. Read by subclasses that gate work on the entity being in the scene graph.
|
|
1823
1825
|
*/
|
|
1824
1826
|
_built = false;
|
|
1825
1827
|
/**
|
|
@@ -1872,10 +1874,10 @@ class EntityElement extends EntityBaseElement {
|
|
|
1872
1874
|
this._resetReady();
|
|
1873
1875
|
}
|
|
1874
1876
|
/**
|
|
1875
|
-
* Parents the backing entity: under the entity of the nearest ancestor `<pc-entity
|
|
1876
|
-
* `<pc-node>` when there is one, and under the application root otherwise.
|
|
1877
|
-
* containing `<pc-app>` element once a sweep has created every entity, so a
|
|
1878
|
-
* existence never depends on document order.
|
|
1877
|
+
* Parents the backing entity: under the entity of the nearest ancestor `<pc-entity>`,
|
|
1878
|
+
* `<pc-model>` or `<pc-node>` when there is one, and under the application root otherwise.
|
|
1879
|
+
* Called by the containing `<pc-app>` element once a sweep has created every entity, so a
|
|
1880
|
+
* parent's existence never depends on document order.
|
|
1879
1881
|
*
|
|
1880
1882
|
* @param app - The application whose root adopts parentless entities.
|
|
1881
1883
|
* @internal
|
|
@@ -1890,6 +1892,13 @@ class EntityElement extends EntityBaseElement {
|
|
|
1890
1892
|
if (closestEntity && !closestEntity.entity) {
|
|
1891
1893
|
return;
|
|
1892
1894
|
}
|
|
1895
|
+
// An owner that exists but is not yet parented is itself deferred behind an unresolved
|
|
1896
|
+
// node further up. Building beneath it would announce readiness for an entity that is
|
|
1897
|
+
// not in the scene graph; stay unbuilt with it - the node's bind sweeps the whole
|
|
1898
|
+
// subtree, ancestors before descendants.
|
|
1899
|
+
if (closestEntity instanceof EntityOwnerElement && !closestEntity._built) {
|
|
1900
|
+
return;
|
|
1901
|
+
}
|
|
1893
1902
|
this._built = true;
|
|
1894
1903
|
if (closestEntity?.entity) {
|
|
1895
1904
|
closestEntity.entity.addChild(this.entity);
|
|
@@ -1897,35 +1906,16 @@ class EntityElement extends EntityBaseElement {
|
|
|
1897
1906
|
else {
|
|
1898
1907
|
app.root.addChild(this.entity);
|
|
1899
1908
|
}
|
|
1900
|
-
this.
|
|
1909
|
+
this._onBuilt();
|
|
1901
1910
|
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
const label = name ? ` '${name}'` : '';
|
|
1911
|
-
console.warn(`pc-entity${label} must be a descendant of pc-app - entity not created`);
|
|
1912
|
-
return;
|
|
1913
|
-
}
|
|
1914
|
-
// If app is already running, create entity immediately
|
|
1915
|
-
if (closestApp._hierarchyReady) {
|
|
1916
|
-
const app = closestApp.app;
|
|
1917
|
-
this._createEntity(app);
|
|
1918
|
-
this._buildHierarchy(app);
|
|
1919
|
-
// Handle any child entities that might exist
|
|
1920
|
-
buildDescendantEntities(this, app);
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
disconnectedCallback() {
|
|
1924
|
-
// Destroying the entity destroys its whole subtree, and the engine fires 'destroy' for
|
|
1925
|
-
// every entity in it - so _onEntityDestroy resets this element AND every descendant
|
|
1926
|
-
// element before the descendants' own disconnectedCallbacks run. Their entities are null
|
|
1927
|
-
// by then, making this call a no-op for them.
|
|
1928
|
-
this._entity?.destroy();
|
|
1911
|
+
/**
|
|
1912
|
+
* Called by `_buildHierarchy` once the backing entity has been parented — exactly once
|
|
1913
|
+
* per build cycle. The default announces readiness, which is what a parented `<pc-entity>`
|
|
1914
|
+
* means; `<pc-model>` overrides it to start loading content instead, because its readiness
|
|
1915
|
+
* tracks the content settling rather than the host entering the scene graph.
|
|
1916
|
+
*/
|
|
1917
|
+
_onBuilt() {
|
|
1918
|
+
this._onReady();
|
|
1929
1919
|
}
|
|
1930
1920
|
/**
|
|
1931
1921
|
* Sets the enabled state of the entity.
|
|
@@ -2030,6 +2020,75 @@ class EntityElement extends EntityBaseElement {
|
|
|
2030
2020
|
get tags() {
|
|
2031
2021
|
return this._tags;
|
|
2032
2022
|
}
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
/**
|
|
2026
|
+
* The EntityElement interface provides properties and methods for manipulating
|
|
2027
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-entity/ | `<pc-entity>`} elements.
|
|
2028
|
+
* The EntityElement interface also inherits the properties and methods of the
|
|
2029
|
+
* {@link HTMLElement} interface.
|
|
2030
|
+
*
|
|
2031
|
+
* The pointer events below are dispatched by the containing `<pc-app>` element when the pointer
|
|
2032
|
+
* intersects this entity's geometry. They are only generated while the entity has a listener for
|
|
2033
|
+
* them, registered either with {@link EventTarget.addEventListener} or with the matching inline `onpointer*`
|
|
2034
|
+
* attribute.
|
|
2035
|
+
*
|
|
2036
|
+
* @elementSummary The `<pc-entity>` element creates an entity: a named, transformable node of the
|
|
2037
|
+
* scene hierarchy, and the host for component elements such as `<pc-camera>`, `<pc-light>` and
|
|
2038
|
+
* `<pc-render>`. Place it in the `<pc-scene>`, or nest it under another `<pc-entity>`, a
|
|
2039
|
+
* `<pc-model>` or a `<pc-node>` to parent it there.
|
|
2040
|
+
*
|
|
2041
|
+
* @attribute {boolean} enabled - The enabled state of the entity.
|
|
2042
|
+
* @attribute {string} name - The name of the entity.
|
|
2043
|
+
* @attribute {string} position - The position of the entity.
|
|
2044
|
+
* @attribute {string} rotation - The rotation of the entity.
|
|
2045
|
+
* @attribute {string} scale - The scale of the entity.
|
|
2046
|
+
* @attribute {string} tags - The tags of the entity.
|
|
2047
|
+
* @attribute {string} onpointerenter - Script to run when the pointer moves onto the entity.
|
|
2048
|
+
* @attribute {string} onpointerleave - Script to run when the pointer moves off the entity.
|
|
2049
|
+
* @attribute {string} onpointermove - Script to run when the pointer moves over the entity.
|
|
2050
|
+
* @attribute {string} onpointerdown - Script to run when a pointer button is pressed over the
|
|
2051
|
+
* entity.
|
|
2052
|
+
* @attribute {string} onpointerup - Script to run when a pointer button is released over the
|
|
2053
|
+
* entity.
|
|
2054
|
+
* @fires {PointerEvent} pointerenter - Fired when the pointer moves onto the entity.
|
|
2055
|
+
* @fires {PointerEvent} pointerleave - Fired when the pointer moves off the entity.
|
|
2056
|
+
* @fires {PointerEvent} pointermove - Fired when the pointer moves over the entity.
|
|
2057
|
+
* @fires {PointerEvent} pointerdown - Fired when a pointer button is pressed over the entity.
|
|
2058
|
+
* @fires {PointerEvent} pointerup - Fired when a pointer button is released over the entity.
|
|
2059
|
+
*/
|
|
2060
|
+
class EntityElement extends EntityOwnerElement {
|
|
2061
|
+
connectedCallback() {
|
|
2062
|
+
// Wait for app to be ready
|
|
2063
|
+
const closestApp = this.closestApp;
|
|
2064
|
+
if (!closestApp) {
|
|
2065
|
+
// An entity outside an application is inert and never becomes ready, so awaiting it
|
|
2066
|
+
// hangs. Warn rather than fail silently, naming the parent it requires, as every other
|
|
2067
|
+
// misplaced element does.
|
|
2068
|
+
const name = this.getAttribute('name');
|
|
2069
|
+
const label = name ? ` '${name}'` : '';
|
|
2070
|
+
console.warn(`pc-entity${label} must be a descendant of pc-app - entity not created`);
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
// If app is already running, create entity immediately
|
|
2074
|
+
if (closestApp._hierarchyReady) {
|
|
2075
|
+
const app = closestApp.app;
|
|
2076
|
+
this._createEntity(app);
|
|
2077
|
+
this._buildHierarchy(app);
|
|
2078
|
+
// Handle any child entities that might exist. A build that deferred (an unresolved
|
|
2079
|
+
// pc-node above) defers the whole subtree with it - the node's bind sweeps it.
|
|
2080
|
+
if (this._built) {
|
|
2081
|
+
buildDescendantEntities(this, app);
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
disconnectedCallback() {
|
|
2086
|
+
// Destroying the entity destroys its whole subtree, and the engine fires 'destroy' for
|
|
2087
|
+
// every entity in it - so _onEntityDestroy resets this element AND every descendant
|
|
2088
|
+
// element before the descendants' own disconnectedCallbacks run. Their entities are null
|
|
2089
|
+
// by then, making this call a no-op for them.
|
|
2090
|
+
this._entity?.destroy();
|
|
2091
|
+
}
|
|
2033
2092
|
static get observedAttributes() {
|
|
2034
2093
|
return ['enabled', 'name', 'position', 'rotation', 'scale', 'tags', ...POINTER_ATTRIBUTES];
|
|
2035
2094
|
}
|
|
@@ -2359,6 +2418,10 @@ const processBufferView = (gltfBuffer, buffers, continuation) => {
|
|
|
2359
2418
|
* Apart from `lazy` and the texture options, these attributes are read once when the asset is
|
|
2360
2419
|
* created, so changing them later has no effect.
|
|
2361
2420
|
*
|
|
2421
|
+
* @elementSummary The `<pc-asset>` element declares an asset for the application to load — a model,
|
|
2422
|
+
* texture, font, sound, script or JSON file — under an `id` that other elements reference. Must be
|
|
2423
|
+
* a direct child of `<pc-app>`.
|
|
2424
|
+
*
|
|
2362
2425
|
* @attribute {string} id - The identifier used to reference the asset from other elements.
|
|
2363
2426
|
* @attribute {string} src - The URL of the asset to load.
|
|
2364
2427
|
* @attribute {string} type - The asset type. Inferred from the `src` file extension when omitted.
|
|
@@ -2967,14 +3030,47 @@ const formatHierarchy = (root, counts) => {
|
|
|
2967
3030
|
* The ModelElement interface also inherits the properties and methods of the
|
|
2968
3031
|
* {@link HTMLElement} interface.
|
|
2969
3032
|
*
|
|
2970
|
-
* The element
|
|
2971
|
-
*
|
|
2972
|
-
*
|
|
2973
|
-
*
|
|
2974
|
-
*
|
|
2975
|
-
*
|
|
2976
|
-
* becomes ready
|
|
3033
|
+
* The element creates and fronts a stable host entity: `entity` is that host, created when the
|
|
3034
|
+
* application builds its hierarchy and kept across `asset` changes, so the element's transform
|
|
3035
|
+
* and tags are instance placement that composes with whatever transform the asset authored on
|
|
3036
|
+
* its root. The instantiated content is parented beneath the host and exposed as
|
|
3037
|
+
* {@link contentEntity}.
|
|
3038
|
+
*
|
|
3039
|
+
* The element becomes ready once its current asset selection has settled: the container asset
|
|
3040
|
+
* has loaded and its content root has been parented beneath the host, the load has failed
|
|
3041
|
+
* (`contentEntity` stays `null` — listen for `error`, or check `contentEntity`, to tell the
|
|
3042
|
+
* outcomes apart), or no asset is assigned at all. Changing `asset` re-arms readiness and
|
|
3043
|
+
* instantiates anew, so a `ready()` obtained after the change resolves against the new content.
|
|
3044
|
+
* A `pc-model` outside a `pc-app`, or referencing an unknown asset id, warns and never becomes
|
|
3045
|
+
* ready.
|
|
3046
|
+
*
|
|
3047
|
+
* The pointer events below are dispatched by the containing `<pc-app>` element when the pointer
|
|
3048
|
+
* intersects the model's geometry, exactly as for `<pc-entity>` — a hit on a content node that no
|
|
3049
|
+
* `pc-node` fronts resolves to this element.
|
|
3050
|
+
*
|
|
3051
|
+
* @elementSummary The `<pc-model>` element instantiates a 3D model from a container asset
|
|
3052
|
+
* (typically a GLB) beneath an entity of its own, so the element's transform and tags place the
|
|
3053
|
+
* instance in the scene. Its `<pc-node>` children override what the asset authored. Place it in the
|
|
3054
|
+
* `<pc-scene>`, or nest it under a `<pc-entity>`, another `<pc-model>` or a `<pc-node>`.
|
|
2977
3055
|
*
|
|
3056
|
+
* @attribute {boolean} enabled - The enabled state of the model.
|
|
3057
|
+
* @attribute {string} name - The name of the model.
|
|
3058
|
+
* @attribute {string} position - The position of the model.
|
|
3059
|
+
* @attribute {string} rotation - The rotation of the model.
|
|
3060
|
+
* @attribute {string} scale - The scale of the model.
|
|
3061
|
+
* @attribute {string} tags - The tags of the model.
|
|
3062
|
+
* @attribute {string} onpointerenter - Script to run when the pointer moves onto the model.
|
|
3063
|
+
* @attribute {string} onpointerleave - Script to run when the pointer moves off the model.
|
|
3064
|
+
* @attribute {string} onpointermove - Script to run when the pointer moves over the model.
|
|
3065
|
+
* @attribute {string} onpointerdown - Script to run when a pointer button is pressed over the
|
|
3066
|
+
* model.
|
|
3067
|
+
* @attribute {string} onpointerup - Script to run when a pointer button is released over the
|
|
3068
|
+
* model.
|
|
3069
|
+
* @fires {PointerEvent} pointerenter - Fired when the pointer moves onto the model.
|
|
3070
|
+
* @fires {PointerEvent} pointerleave - Fired when the pointer moves off the model.
|
|
3071
|
+
* @fires {PointerEvent} pointermove - Fired when the pointer moves over the model.
|
|
3072
|
+
* @fires {PointerEvent} pointerdown - Fired when a pointer button is pressed over the model.
|
|
3073
|
+
* @fires {PointerEvent} pointerup - Fired when a pointer button is released over the model.
|
|
2978
3074
|
* @fires {Event} load - Fired each time a container asset finishes instantiating, including
|
|
2979
3075
|
* re-instantiation after `asset` changes. Does not bubble — listen on this element, or use a
|
|
2980
3076
|
* capture-phase listener on an ancestor.
|
|
@@ -2982,14 +3078,14 @@ const formatHierarchy = (root, counts) => {
|
|
|
2982
3078
|
* error in `message`. Does not bubble. The element still becomes ready — readiness means the load
|
|
2983
3079
|
* settled, not that it succeeded.
|
|
2984
3080
|
*/
|
|
2985
|
-
class ModelElement extends
|
|
3081
|
+
class ModelElement extends EntityOwnerElement {
|
|
2986
3082
|
_asset = '';
|
|
2987
|
-
|
|
3083
|
+
_contentEntity = null;
|
|
2988
3084
|
/**
|
|
2989
|
-
* Incremented on every new load
|
|
2990
|
-
* load that resumes from an await or a load callback abandons
|
|
2991
|
-
* on, so a superseded load can neither instantiate a second
|
|
2992
|
-
*
|
|
3085
|
+
* Incremented on every new load, on disconnect, and when the host entity dies, and captured
|
|
3086
|
+
* by a load when it starts. A load that resumes from an await or a load callback abandons
|
|
3087
|
+
* itself if the value has moved on, so a superseded load can neither instantiate a second
|
|
3088
|
+
* content root nor parent one under a host a newer cycle has already replaced.
|
|
2993
3089
|
*/
|
|
2994
3090
|
_loadGeneration = 0;
|
|
2995
3091
|
/**
|
|
@@ -3000,12 +3096,13 @@ class ModelElement extends AsyncElement {
|
|
|
3000
3096
|
_loadHandle = null;
|
|
3001
3097
|
_errorHandle = null;
|
|
3002
3098
|
/**
|
|
3003
|
-
* The root entity of the instantiated model
|
|
3004
|
-
*
|
|
3005
|
-
*
|
|
3099
|
+
* The root entity of the instantiated model content, parented beneath the host entity.
|
|
3100
|
+
* `null` until the container asset has loaded and been instantiated, after a failed load,
|
|
3101
|
+
* and again once the element has been removed from the document.
|
|
3102
|
+
* @returns The content root entity, or `null`.
|
|
3006
3103
|
*/
|
|
3007
|
-
get
|
|
3008
|
-
return this.
|
|
3104
|
+
get contentEntity() {
|
|
3105
|
+
return this._contentEntity;
|
|
3009
3106
|
}
|
|
3010
3107
|
/**
|
|
3011
3108
|
* Returns a snapshot of the instantiated node tree, or `null` while there is none (the
|
|
@@ -3017,12 +3114,13 @@ class ModelElement extends AsyncElement {
|
|
|
3017
3114
|
* is the printable form.
|
|
3018
3115
|
*
|
|
3019
3116
|
* The snapshot is plain data, computed afresh each call: it does not follow later changes
|
|
3020
|
-
* to the hierarchy, and mutating it changes nothing.
|
|
3117
|
+
* to the hierarchy, and mutating it changes nothing. It covers the instantiated content
|
|
3118
|
+
* only — the host entity the element fronts is not part of the asset's node tree.
|
|
3021
3119
|
*
|
|
3022
3120
|
* @returns The root of the instantiated node tree, or `null`.
|
|
3023
3121
|
*/
|
|
3024
3122
|
hierarchy() {
|
|
3025
|
-
const root = this.
|
|
3123
|
+
const root = this._contentEntity;
|
|
3026
3124
|
if (!root) {
|
|
3027
3125
|
return null;
|
|
3028
3126
|
}
|
|
@@ -3062,18 +3160,53 @@ class ModelElement extends AsyncElement {
|
|
|
3062
3160
|
// A model outside an application is inert and never becomes ready, so awaiting it hangs.
|
|
3063
3161
|
// Warn rather than fail silently, naming the parent it requires, as every other misplaced
|
|
3064
3162
|
// element does.
|
|
3065
|
-
|
|
3163
|
+
const closestApp = this.closestApp;
|
|
3164
|
+
if (!closestApp) {
|
|
3066
3165
|
const label = this._asset ? ` '${this._asset}'` : '';
|
|
3067
3166
|
console.warn(`pc-model${label} must be a descendant of pc-app - model not created`);
|
|
3068
3167
|
return;
|
|
3069
3168
|
}
|
|
3070
|
-
|
|
3169
|
+
// If the app is already running, create the host immediately; during a boot, the app's
|
|
3170
|
+
// own sweep does it. Either way, _onBuilt starts the content load once the host is
|
|
3171
|
+
// parented.
|
|
3172
|
+
if (closestApp._hierarchyReady) {
|
|
3173
|
+
const app = closestApp.app;
|
|
3174
|
+
this._createEntity(app);
|
|
3175
|
+
this._buildHierarchy(app);
|
|
3176
|
+
// A build that deferred (an unresolved pc-node above) defers the whole subtree with
|
|
3177
|
+
// it - the node's bind sweeps it.
|
|
3178
|
+
if (this._built) {
|
|
3179
|
+
buildDescendantEntities(this, app);
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3071
3182
|
}
|
|
3072
3183
|
disconnectedCallback() {
|
|
3184
|
+
// Destroying the host destroys the instantiated content with it, and the destroy hook
|
|
3185
|
+
// resets the element. The generation guard comes first so a load suspended on an await
|
|
3186
|
+
// cannot resume against the torn-down element.
|
|
3073
3187
|
this._loadGeneration++;
|
|
3074
3188
|
this._detachLoadHandlers();
|
|
3075
|
-
this.
|
|
3076
|
-
|
|
3189
|
+
this._entity?.destroy();
|
|
3190
|
+
}
|
|
3191
|
+
/**
|
|
3192
|
+
* Starts (or restarts) the content load once the host has been parented. Readiness is not
|
|
3193
|
+
* announced here — it tracks the content settling, not the host entering the scene graph.
|
|
3194
|
+
*/
|
|
3195
|
+
_onBuilt() {
|
|
3196
|
+
this._loadContent();
|
|
3197
|
+
}
|
|
3198
|
+
/**
|
|
3199
|
+
* Extends the owner reset for the content: the engine's destroy cascade has already taken
|
|
3200
|
+
* the content root down with the host subtree, so only the reference and the in-flight load
|
|
3201
|
+
* are dropped here. The next build re-creates the host and re-instantiates the content.
|
|
3202
|
+
*
|
|
3203
|
+
* @param entity - The host entity that was destroyed.
|
|
3204
|
+
*/
|
|
3205
|
+
_onEntityDestroy(entity) {
|
|
3206
|
+
this._loadGeneration++;
|
|
3207
|
+
this._detachLoadHandlers();
|
|
3208
|
+
this._contentEntity = null;
|
|
3209
|
+
super._onEntityDestroy(entity);
|
|
3077
3210
|
}
|
|
3078
3211
|
_detachLoadHandlers() {
|
|
3079
3212
|
this._loadHandle?.off();
|
|
@@ -3082,51 +3215,34 @@ class ModelElement extends AsyncElement {
|
|
|
3082
3215
|
this._errorHandle = null;
|
|
3083
3216
|
}
|
|
3084
3217
|
/**
|
|
3085
|
-
* Resolves readiness and dispatches the `load` event. Called once the instantiated
|
|
3086
|
-
* has been parented —
|
|
3087
|
-
* model's
|
|
3218
|
+
* Resolves readiness and dispatches the `load` event. Called once the instantiated content
|
|
3219
|
+
* has been parented beneath the host — the host itself is already in the scene graph by
|
|
3220
|
+
* then, so a ready model's content always has world transforms.
|
|
3088
3221
|
*/
|
|
3089
3222
|
_announceLoad() {
|
|
3090
3223
|
this._onReady();
|
|
3091
3224
|
this.dispatchEvent(new Event('load'));
|
|
3092
3225
|
}
|
|
3093
3226
|
_instantiate(container) {
|
|
3094
|
-
const
|
|
3095
|
-
|
|
3096
|
-
this._entity
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
});
|
|
3109
|
-
}
|
|
3110
|
-
else {
|
|
3111
|
-
const appElement = this.closestApp;
|
|
3112
|
-
if (appElement) {
|
|
3113
|
-
appElement.ready().then(() => {
|
|
3114
|
-
if (generation !== this._loadGeneration) {
|
|
3115
|
-
return;
|
|
3116
|
-
}
|
|
3117
|
-
appElement.app.root.addChild(entity);
|
|
3118
|
-
this._announceLoad();
|
|
3119
|
-
});
|
|
3120
|
-
}
|
|
3121
|
-
}
|
|
3122
|
-
}
|
|
3123
|
-
async _loadModel() {
|
|
3124
|
-
this._unloadModel();
|
|
3227
|
+
const content = container.instantiateRenderEntity();
|
|
3228
|
+
this._contentEntity = content;
|
|
3229
|
+
this._entity.addChild(content);
|
|
3230
|
+
this._announceLoad();
|
|
3231
|
+
}
|
|
3232
|
+
_destroyContent() {
|
|
3233
|
+
this._contentEntity?.destroy();
|
|
3234
|
+
this._contentEntity = null;
|
|
3235
|
+
}
|
|
3236
|
+
async _loadContent() {
|
|
3237
|
+
// The old content goes down synchronously, so a reader that checks after an asset change
|
|
3238
|
+
// never sees the outgoing hierarchy. The host survives - components and child entities
|
|
3239
|
+
// attached to it carry over to the new content.
|
|
3240
|
+
this._destroyContent();
|
|
3125
3241
|
// Supersede any load already in flight - only the newest load may instantiate
|
|
3126
3242
|
const generation = ++this._loadGeneration;
|
|
3127
3243
|
this._detachLoadHandlers();
|
|
3128
3244
|
// Re-arm readiness so a waiter obtained after an asset change resolves against the new
|
|
3129
|
-
//
|
|
3245
|
+
// content. A no-op on first connection, where readiness is still pending.
|
|
3130
3246
|
this._resetReady();
|
|
3131
3247
|
const appElement = this.closestApp;
|
|
3132
3248
|
if (!appElement) {
|
|
@@ -3138,14 +3254,23 @@ class ModelElement extends AsyncElement {
|
|
|
3138
3254
|
if (generation !== this._loadGeneration) {
|
|
3139
3255
|
return;
|
|
3140
3256
|
}
|
|
3257
|
+
// The host may not be parented yet - a model under a pc-node that has not bound, reached
|
|
3258
|
+
// through the asset setter. Nothing settles here: _onBuilt re-runs this load once the
|
|
3259
|
+
// host builds.
|
|
3260
|
+
if (!this._entity || !this._built) {
|
|
3261
|
+
return;
|
|
3262
|
+
}
|
|
3263
|
+
if (this._asset === '') {
|
|
3264
|
+
// No asset assigned is a settled selection: the element is a usable host (components
|
|
3265
|
+
// attach, waiters resolve) with no content. Assigning an asset later re-arms.
|
|
3266
|
+
this._onReady();
|
|
3267
|
+
return;
|
|
3268
|
+
}
|
|
3141
3269
|
const asset = useAsset(this._asset);
|
|
3142
3270
|
if (!asset) {
|
|
3143
|
-
//
|
|
3144
|
-
// non-empty one that resolves to nothing is a dead end - say so rather than staying
|
|
3271
|
+
// A non-empty id that resolves to nothing is a dead end - say so rather than staying
|
|
3145
3272
|
// silently pending.
|
|
3146
|
-
|
|
3147
|
-
console.warn(`pc-model could not find asset '${this._asset}' - model not created`);
|
|
3148
|
-
}
|
|
3273
|
+
console.warn(`pc-model could not find asset '${this._asset}' - model not created`);
|
|
3149
3274
|
return;
|
|
3150
3275
|
}
|
|
3151
3276
|
if (asset.loaded) {
|
|
@@ -3167,7 +3292,7 @@ class ModelElement extends AsyncElement {
|
|
|
3167
3292
|
if (generation !== this._loadGeneration) {
|
|
3168
3293
|
return;
|
|
3169
3294
|
}
|
|
3170
|
-
// A failed load settles readiness with a null
|
|
3295
|
+
// A failed load settles readiness with a null contentEntity, mirroring pc-asset:
|
|
3171
3296
|
// readiness means the load settled, not that it succeeded.
|
|
3172
3297
|
this.dispatchEvent(new ErrorEvent('error', {
|
|
3173
3298
|
message: err instanceof Error ? err.message : String(err)
|
|
@@ -3176,10 +3301,6 @@ class ModelElement extends AsyncElement {
|
|
|
3176
3301
|
});
|
|
3177
3302
|
}
|
|
3178
3303
|
}
|
|
3179
|
-
_unloadModel() {
|
|
3180
|
-
this._entity?.destroy();
|
|
3181
|
-
this._entity = null;
|
|
3182
|
-
}
|
|
3183
3304
|
/**
|
|
3184
3305
|
* Sets the id of the `pc-asset` to use for the model.
|
|
3185
3306
|
* @param value - The asset ID.
|
|
@@ -3187,7 +3308,7 @@ class ModelElement extends AsyncElement {
|
|
|
3187
3308
|
set asset(value) {
|
|
3188
3309
|
this._asset = value;
|
|
3189
3310
|
if (this.isConnected) {
|
|
3190
|
-
this.
|
|
3311
|
+
this._loadContent();
|
|
3191
3312
|
}
|
|
3192
3313
|
}
|
|
3193
3314
|
/**
|
|
@@ -3198,13 +3319,38 @@ class ModelElement extends AsyncElement {
|
|
|
3198
3319
|
return this._asset;
|
|
3199
3320
|
}
|
|
3200
3321
|
static get observedAttributes() {
|
|
3201
|
-
return ['asset'];
|
|
3322
|
+
return ['asset', 'enabled', 'name', 'position', 'rotation', 'scale', 'tags', ...POINTER_ATTRIBUTES];
|
|
3202
3323
|
}
|
|
3203
3324
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
3204
3325
|
switch (name) {
|
|
3205
3326
|
case 'asset':
|
|
3206
3327
|
this.asset = newValue ?? '';
|
|
3207
3328
|
break;
|
|
3329
|
+
case 'enabled':
|
|
3330
|
+
this.enabled = parseBool(newValue, true);
|
|
3331
|
+
break;
|
|
3332
|
+
case 'name':
|
|
3333
|
+
this.name = newValue ?? 'Untitled';
|
|
3334
|
+
break;
|
|
3335
|
+
case 'position':
|
|
3336
|
+
this.position = parseVec3(newValue, playcanvas.Vec3.ZERO, name);
|
|
3337
|
+
break;
|
|
3338
|
+
case 'rotation':
|
|
3339
|
+
this.rotation = parseVec3(newValue, playcanvas.Vec3.ZERO, name);
|
|
3340
|
+
break;
|
|
3341
|
+
case 'scale':
|
|
3342
|
+
this.scale = parseVec3(newValue, playcanvas.Vec3.ONE, name);
|
|
3343
|
+
break;
|
|
3344
|
+
case 'tags':
|
|
3345
|
+
this.tags = parseTags(newValue);
|
|
3346
|
+
break;
|
|
3347
|
+
case 'onpointerenter':
|
|
3348
|
+
case 'onpointerleave':
|
|
3349
|
+
case 'onpointerdown':
|
|
3350
|
+
case 'onpointerup':
|
|
3351
|
+
case 'onpointermove':
|
|
3352
|
+
this._updateInlineHandler(name, newValue);
|
|
3353
|
+
break;
|
|
3208
3354
|
}
|
|
3209
3355
|
}
|
|
3210
3356
|
}
|
|
@@ -3295,7 +3441,7 @@ class ComponentElement extends AsyncElement {
|
|
|
3295
3441
|
// A component can only exist on an entity, so an element placed outside one is inert.
|
|
3296
3442
|
// It still becomes ready (with a null `component`), so warn rather than fail silently
|
|
3297
3443
|
const label = this.id ? ` '${this.id}'` : '';
|
|
3298
|
-
console.warn(`${this.tagName.toLowerCase()}${label} must be a descendant of pc-entity - component not added`);
|
|
3444
|
+
console.warn(`${this.tagName.toLowerCase()}${label} must be a descendant of pc-entity, pc-model or pc-node - component not added`);
|
|
3299
3445
|
return;
|
|
3300
3446
|
}
|
|
3301
3447
|
await entityElement.ready();
|
|
@@ -3383,8 +3529,9 @@ class ComponentElement extends AsyncElement {
|
|
|
3383
3529
|
}
|
|
3384
3530
|
/**
|
|
3385
3531
|
* The PlayCanvas component instance. `null` until the element is ready, and also for an
|
|
3386
|
-
* element that is not a descendant of
|
|
3387
|
-
* element's `ready()` promise
|
|
3532
|
+
* element that is not a descendant of an entity-fronting element (`<pc-entity>`,
|
|
3533
|
+
* `<pc-model>` or `<pc-node>`) — await {@link whenReady} or the element's `ready()` promise
|
|
3534
|
+
* before accessing it.
|
|
3388
3535
|
* @returns The component instance, or `null`.
|
|
3389
3536
|
*/
|
|
3390
3537
|
get component() {
|
|
@@ -3437,6 +3584,13 @@ class ComponentElement extends AsyncElement {
|
|
|
3437
3584
|
* the underlying {@link AnimComponent} (via {@link component}) for playback state beyond what
|
|
3438
3585
|
* this element exposes.
|
|
3439
3586
|
*
|
|
3587
|
+
* Engine component: {@link AnimComponent} (`anim`).
|
|
3588
|
+
*
|
|
3589
|
+
* @elementSummary The `<pc-anim>` element plays animation clips over its entity's hierarchy, taken
|
|
3590
|
+
* from `<pc-anim-clip>` children or from the enclosing `<pc-model>`'s own animations. The first
|
|
3591
|
+
* clip plays automatically, and the `clip` attribute switches between them. Must be a child of a
|
|
3592
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
3593
|
+
*
|
|
3440
3594
|
* @category Components
|
|
3441
3595
|
*/
|
|
3442
3596
|
class AnimComponentElement extends ComponentElement {
|
|
@@ -3458,6 +3612,11 @@ class AnimComponentElement extends ComponentElement {
|
|
|
3458
3612
|
* The name of the active clip.
|
|
3459
3613
|
*/
|
|
3460
3614
|
_clip = '';
|
|
3615
|
+
/**
|
|
3616
|
+
* The binding root this element last assigned through {@link _applyRootBone}, distinguishing
|
|
3617
|
+
* its own writes from a `rootBone` assigned through the engine API — which is left alone.
|
|
3618
|
+
*/
|
|
3619
|
+
_managedRootBone = null;
|
|
3461
3620
|
/**
|
|
3462
3621
|
* The element the model-readiness listener is attached to, held so disconnection can detach
|
|
3463
3622
|
* it after `closestEntity` no longer resolves.
|
|
@@ -3483,27 +3642,71 @@ class AnimComponentElement extends ComponentElement {
|
|
|
3483
3642
|
*/
|
|
3484
3643
|
_warnedClip = null;
|
|
3485
3644
|
/**
|
|
3486
|
-
* Rebinds when a model
|
|
3487
|
-
*
|
|
3645
|
+
* Rebinds when a model that is not this component's host announces readiness — a sibling or
|
|
3646
|
+
* deeper model whose content changed under the assigned clips. The engine resolves each
|
|
3647
|
+
* curve once, at the first tick after assignment, and never retries — and its mesh-instance
|
|
3488
3648
|
* broadcast fires before an instantiated hierarchy is parented, so a model that loads after
|
|
3489
|
-
* the clips were assigned would otherwise stay silently unbound.
|
|
3490
|
-
*
|
|
3491
|
-
*
|
|
3649
|
+
* the clips were assigned would otherwise stay silently unbound. The host model's own cycles
|
|
3650
|
+
* are excluded: those re-enter through {@link initComponent}, which refreshes the whole clip
|
|
3651
|
+
* set against the new container.
|
|
3492
3652
|
*/
|
|
3493
3653
|
_onModelReady = (event) => {
|
|
3494
3654
|
if (!(event.target instanceof ModelElement) || !this.component) {
|
|
3495
3655
|
return;
|
|
3496
3656
|
}
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
}
|
|
3657
|
+
// The host model's own readiness cycle already re-initialized this component through
|
|
3658
|
+
// ComponentElement's host-ready listener, which is attached first and so has run by now.
|
|
3659
|
+
// Acting here too would resolve every track twice and capture the playhead-restore
|
|
3660
|
+
// snapshot mid-rebuild.
|
|
3661
|
+
if (event.target === this._modelListenerTarget) {
|
|
3662
|
+
return;
|
|
3504
3663
|
}
|
|
3664
|
+
// A model cycle can replace the skeleton source's host entity (a rebuild under a
|
|
3665
|
+
// retargeting pc-node), so the binding root is re-asserted before the rebind.
|
|
3666
|
+
this._applyRootBone();
|
|
3505
3667
|
this.component.rebind();
|
|
3506
3668
|
};
|
|
3669
|
+
/**
|
|
3670
|
+
* The model whose host entity scopes this component's curve binding: the parent `pc-model`,
|
|
3671
|
+
* or the sole `pc-model` among the parent's direct children (the arrangement where clips
|
|
3672
|
+
* live in a library asset beside the skeleton). `null` when there is no such model, or more
|
|
3673
|
+
* than one — an ambiguous skeleton is left to the engine's name-based resolution.
|
|
3674
|
+
*/
|
|
3675
|
+
_skeletonSource() {
|
|
3676
|
+
const parent = this.parentElement;
|
|
3677
|
+
if (parent instanceof ModelElement) {
|
|
3678
|
+
return parent;
|
|
3679
|
+
}
|
|
3680
|
+
const models = parent ? parent.querySelectorAll(':scope > pc-model') : null;
|
|
3681
|
+
return models?.length === 1 && models[0] instanceof ModelElement ? models[0] : null;
|
|
3682
|
+
}
|
|
3683
|
+
/**
|
|
3684
|
+
* Keeps the component's binding root pointing at the skeleton source's host entity. The host
|
|
3685
|
+
* wraps the instantiated content, so left at its default — the component's own entity — the
|
|
3686
|
+
* engine binder mis-resolves curves that target the asset's root node: its fallback treats
|
|
3687
|
+
* the graph as the asset root once the root is no longer a direct child.
|
|
3688
|
+
*
|
|
3689
|
+
* Authoritative in both directions for values this element assigned: a source appearing pins
|
|
3690
|
+
* its host, and a source dissolving (the model gone, or a second model making the skeleton
|
|
3691
|
+
* ambiguous) clears the pin rather than leaving it on a stale host. A root assigned through
|
|
3692
|
+
* the engine API is never overwritten — the user's choice outranks the managed default.
|
|
3693
|
+
* Writes are skipped while unchanged, because the engine setter itself triggers a rebind.
|
|
3694
|
+
*/
|
|
3695
|
+
_applyRootBone() {
|
|
3696
|
+
const component = this.component;
|
|
3697
|
+
// A non-null root this element did not assign came through the engine API. A fresh
|
|
3698
|
+
// component starts at null, which is always reclaimable.
|
|
3699
|
+
if (component.rootBone !== null && component.rootBone !== this._managedRootBone) {
|
|
3700
|
+
return;
|
|
3701
|
+
}
|
|
3702
|
+
const host = this._skeletonSource()?.entity ?? null;
|
|
3703
|
+
if (component.rootBone !== host) {
|
|
3704
|
+
// The engine setter accepts null - restoring the component's own entity as the
|
|
3705
|
+
// binding graph - but its declared type does not
|
|
3706
|
+
component.rootBone = host;
|
|
3707
|
+
}
|
|
3708
|
+
this._managedRootBone = host;
|
|
3709
|
+
}
|
|
3507
3710
|
/** @ignore */
|
|
3508
3711
|
constructor() {
|
|
3509
3712
|
super('anim');
|
|
@@ -3528,7 +3731,16 @@ class AnimComponentElement extends ComponentElement {
|
|
|
3528
3731
|
host.addEventListener('ready', this._onModelReady);
|
|
3529
3732
|
this._modelListenerTarget = host;
|
|
3530
3733
|
}
|
|
3531
|
-
this.
|
|
3734
|
+
this._applyRootBone();
|
|
3735
|
+
if (this.component.baseLayer) {
|
|
3736
|
+
// The component survived the host's readiness cycle (a pc-model reloading content on
|
|
3737
|
+
// its stable host entity). A loaded graph cannot be reassigned in place, so drop it
|
|
3738
|
+
// and reassign from the current source, restoring the active clip and playhead.
|
|
3739
|
+
this._refreshClips();
|
|
3740
|
+
}
|
|
3741
|
+
else {
|
|
3742
|
+
this._applyClips();
|
|
3743
|
+
}
|
|
3532
3744
|
}
|
|
3533
3745
|
disconnectedCallback() {
|
|
3534
3746
|
this._modelListenerTarget?.removeEventListener('ready', this._onModelReady);
|
|
@@ -3538,6 +3750,7 @@ class AnimComponentElement extends ComponentElement {
|
|
|
3538
3750
|
this._sourceGeneration++;
|
|
3539
3751
|
this._assignedClips.clear();
|
|
3540
3752
|
this._autoAssigned = false;
|
|
3753
|
+
this._managedRootBone = null;
|
|
3541
3754
|
super.disconnectedCallback();
|
|
3542
3755
|
}
|
|
3543
3756
|
/**
|
|
@@ -3706,6 +3919,10 @@ class AnimComponentElement extends ComponentElement {
|
|
|
3706
3919
|
if (!component) {
|
|
3707
3920
|
return;
|
|
3708
3921
|
}
|
|
3922
|
+
// A clip-set change is also a chance for the skeleton source to have changed shape (a
|
|
3923
|
+
// clip child appearing or leaving can accompany a model coming or going) - re-derive the
|
|
3924
|
+
// binding root before the reassignment binds against it.
|
|
3925
|
+
this._applyRootBone();
|
|
3709
3926
|
const layer = component.baseLayer;
|
|
3710
3927
|
const restore = layer ? {
|
|
3711
3928
|
state: layer.activeState,
|
|
@@ -3992,6 +4209,10 @@ customElements.define('pc-anim', AnimComponentElement);
|
|
|
3992
4209
|
* named; in a multi-track source the track named `name` is chosen, falling back to the first
|
|
3993
4210
|
* with a warning. The element becomes ready once its resolved track is assigned.
|
|
3994
4211
|
*
|
|
4212
|
+
* @elementSummary The `<pc-anim-clip>` element declares one named animation clip on its parent
|
|
4213
|
+
* `<pc-anim>`, taken from the `asset` it names or, without one, from the enclosing `<pc-model>`'s
|
|
4214
|
+
* own animations. Must be a direct child of `<pc-anim>`.
|
|
4215
|
+
*
|
|
3995
4216
|
* @category Components
|
|
3996
4217
|
*/
|
|
3997
4218
|
class AnimClipElement extends AsyncElement {
|
|
@@ -4313,14 +4534,20 @@ class AnimClipElement extends AsyncElement {
|
|
|
4313
4534
|
customElements.define('pc-anim-clip', AnimClipElement);
|
|
4314
4535
|
|
|
4315
4536
|
/**
|
|
4316
|
-
* The
|
|
4317
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-listener/ | `<pc-listener>`} elements.
|
|
4318
|
-
* The
|
|
4537
|
+
* The AudioListenerComponentElement interface provides properties and methods for manipulating
|
|
4538
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-audio-listener/ | `<pc-audio-listener>`} elements.
|
|
4539
|
+
* The AudioListenerComponentElement interface also inherits the properties and methods of the
|
|
4319
4540
|
* {@link HTMLElement} interface.
|
|
4320
4541
|
*
|
|
4542
|
+
* Engine component: {@link AudioListenerComponent} (`audiolistener`).
|
|
4543
|
+
*
|
|
4544
|
+
* @elementSummary The `<pc-audio-listener>` element makes its entity the point from which
|
|
4545
|
+
* positional sounds are heard, typically the entity holding the `<pc-camera>`. Must be a child of a
|
|
4546
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
4547
|
+
*
|
|
4321
4548
|
* @category Components
|
|
4322
4549
|
*/
|
|
4323
|
-
class
|
|
4550
|
+
class AudioListenerComponentElement extends ComponentElement {
|
|
4324
4551
|
/** @ignore */
|
|
4325
4552
|
constructor() {
|
|
4326
4553
|
super('audiolistener');
|
|
@@ -4333,7 +4560,7 @@ class ListenerComponentElement extends ComponentElement {
|
|
|
4333
4560
|
return super.component;
|
|
4334
4561
|
}
|
|
4335
4562
|
}
|
|
4336
|
-
customElements.define('pc-listener',
|
|
4563
|
+
customElements.define('pc-audio-listener', AudioListenerComponentElement);
|
|
4337
4564
|
|
|
4338
4565
|
const transitionModes = new Map([
|
|
4339
4566
|
['tint', playcanvas.BUTTON_TRANSITION_MODE_TINT],
|
|
@@ -4345,6 +4572,13 @@ const transitionModes = new Map([
|
|
|
4345
4572
|
* The ButtonComponentElement interface also inherits the properties and methods of the
|
|
4346
4573
|
* {@link HTMLElement} interface.
|
|
4347
4574
|
*
|
|
4575
|
+
* Engine component: {@link ButtonComponent} (`button`).
|
|
4576
|
+
*
|
|
4577
|
+
* @elementSummary The `<pc-button>` element makes its entity respond to pointer input, tinting or
|
|
4578
|
+
* swapping its image as the pointer hovers, presses and releases it. The entity also needs a
|
|
4579
|
+
* `<pc-element>` with `use-input` set. Must be a child of a `<pc-entity>`, `<pc-model>` or
|
|
4580
|
+
* `<pc-node>`.
|
|
4581
|
+
*
|
|
4348
4582
|
* @category Components
|
|
4349
4583
|
*/
|
|
4350
4584
|
class ButtonComponentElement extends ComponentElement {
|
|
@@ -4425,7 +4659,9 @@ class ButtonComponentElement extends ComponentElement {
|
|
|
4425
4659
|
}
|
|
4426
4660
|
/**
|
|
4427
4661
|
* Sets the reference (CSS selector, element id or entity name) to the `<pc-entity>` whose image
|
|
4428
|
-
* element is used for visual transitions. Defaults to the button's own entity
|
|
4662
|
+
* element is used for visual transitions. Defaults to the button's own entity — inside a
|
|
4663
|
+
* `<pc-model>`, that is the model's host entity, so supply an explicit reference to target a
|
|
4664
|
+
* UI entity instead.
|
|
4429
4665
|
* @param value - The image entity reference.
|
|
4430
4666
|
*/
|
|
4431
4667
|
set image(value) {
|
|
@@ -4744,13 +4980,20 @@ const tonemaps = new Map([
|
|
|
4744
4980
|
* The CameraComponentElement interface also inherits the properties and methods of the
|
|
4745
4981
|
* {@link HTMLElement} interface.
|
|
4746
4982
|
*
|
|
4983
|
+
* Engine component: {@link CameraComponent} (`camera`).
|
|
4984
|
+
*
|
|
4985
|
+
* @elementSummary The `<pc-camera>` element renders the scene from its entity's transform, with
|
|
4986
|
+
* attributes for the projection, field of view, clip planes, clear color and tonemapping. Must be a
|
|
4987
|
+
* child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
4988
|
+
*
|
|
4747
4989
|
* @category Components
|
|
4748
4990
|
*/
|
|
4749
4991
|
class CameraComponentElement extends ComponentElement {
|
|
4750
4992
|
_clearColor = new playcanvas.Color(0.75, 0.75, 0.75, 1);
|
|
4751
4993
|
_clearColorBuffer = true;
|
|
4994
|
+
_clearDepth = 1;
|
|
4752
4995
|
_clearDepthBuffer = true;
|
|
4753
|
-
_clearStencilBuffer =
|
|
4996
|
+
_clearStencilBuffer = true;
|
|
4754
4997
|
_cullFaces = true;
|
|
4755
4998
|
_farClip = 1000;
|
|
4756
4999
|
_flipFaces = false;
|
|
@@ -4773,6 +5016,7 @@ class CameraComponentElement extends ComponentElement {
|
|
|
4773
5016
|
return {
|
|
4774
5017
|
clearColor: this._clearColor,
|
|
4775
5018
|
clearColorBuffer: this._clearColorBuffer,
|
|
5019
|
+
clearDepth: this._clearDepth,
|
|
4776
5020
|
clearDepthBuffer: this._clearDepthBuffer,
|
|
4777
5021
|
clearStencilBuffer: this._clearStencilBuffer,
|
|
4778
5022
|
cullFaces: this._cullFaces,
|
|
@@ -4791,9 +5035,31 @@ class CameraComponentElement extends ComponentElement {
|
|
|
4791
5035
|
toneMapping: tonemaps.get(this._tonemap) ?? playcanvas.TONEMAP_NONE
|
|
4792
5036
|
};
|
|
4793
5037
|
}
|
|
4794
|
-
|
|
5038
|
+
/**
|
|
5039
|
+
* Whether immersive AR is available. Independent of {@link vrAvailable}: a device can offer
|
|
5040
|
+
* either mode without the other.
|
|
5041
|
+
* @returns Whether immersive AR is available.
|
|
5042
|
+
*/
|
|
5043
|
+
get arAvailable() {
|
|
5044
|
+
return this._available(playcanvas.XRTYPE_AR);
|
|
5045
|
+
}
|
|
5046
|
+
/**
|
|
5047
|
+
* Whether immersive VR is available. Independent of {@link arAvailable}: a device can offer
|
|
5048
|
+
* either mode without the other.
|
|
5049
|
+
* @returns Whether immersive VR is available.
|
|
5050
|
+
*/
|
|
5051
|
+
get vrAvailable() {
|
|
5052
|
+
return this._available(playcanvas.XRTYPE_VR);
|
|
5053
|
+
}
|
|
5054
|
+
/**
|
|
5055
|
+
* Whether one XR session type is available on this device.
|
|
5056
|
+
*
|
|
5057
|
+
* @param type - The XR session type to test.
|
|
5058
|
+
* @returns Whether that type is available.
|
|
5059
|
+
*/
|
|
5060
|
+
_available(type) {
|
|
4795
5061
|
const xrManager = this.component?.system.app.xr;
|
|
4796
|
-
return xrManager
|
|
5062
|
+
return Boolean(xrManager?.supported && xrManager.isAvailable(type));
|
|
4797
5063
|
}
|
|
4798
5064
|
/**
|
|
4799
5065
|
* Starts the camera in XR mode.
|
|
@@ -4801,11 +5067,13 @@ class CameraComponentElement extends ComponentElement {
|
|
|
4801
5067
|
* @param space - The space to start the camera in.
|
|
4802
5068
|
*/
|
|
4803
5069
|
startXr(type, space) {
|
|
4804
|
-
|
|
5070
|
+
// Gated on the mode being started, not on XR in general: a device that offers only
|
|
5071
|
+
// one of the two would otherwise accept a session it cannot serve
|
|
5072
|
+
if (this.component && this._available(type)) {
|
|
4805
5073
|
this.component.startXr(type, space, {
|
|
4806
5074
|
callback: (err) => {
|
|
4807
5075
|
if (err)
|
|
4808
|
-
console.error(`WebXR
|
|
5076
|
+
console.error(`WebXR ${type} failed to start: ${err.message}`);
|
|
4809
5077
|
}
|
|
4810
5078
|
});
|
|
4811
5079
|
}
|
|
@@ -4859,6 +5127,23 @@ class CameraComponentElement extends ComponentElement {
|
|
|
4859
5127
|
get clearColorBuffer() {
|
|
4860
5128
|
return this._clearColorBuffer;
|
|
4861
5129
|
}
|
|
5130
|
+
/**
|
|
5131
|
+
* Sets the depth value the depth buffer is cleared to. Defaults to 1.
|
|
5132
|
+
* @param value - The clear depth value.
|
|
5133
|
+
*/
|
|
5134
|
+
set clearDepth(value) {
|
|
5135
|
+
this._clearDepth = value;
|
|
5136
|
+
if (this.component) {
|
|
5137
|
+
this.component.clearDepth = value;
|
|
5138
|
+
}
|
|
5139
|
+
}
|
|
5140
|
+
/**
|
|
5141
|
+
* Gets the depth value the depth buffer is cleared to.
|
|
5142
|
+
* @returns The clear depth value.
|
|
5143
|
+
*/
|
|
5144
|
+
get clearDepth() {
|
|
5145
|
+
return this._clearDepth;
|
|
5146
|
+
}
|
|
4862
5147
|
/**
|
|
4863
5148
|
* Sets the clear depth buffer of the camera.
|
|
4864
5149
|
* @param value - The clear depth buffer.
|
|
@@ -5137,6 +5422,7 @@ class CameraComponentElement extends ComponentElement {
|
|
|
5137
5422
|
...super.observedAttributes,
|
|
5138
5423
|
'clear-color',
|
|
5139
5424
|
'clear-color-buffer',
|
|
5425
|
+
'clear-depth',
|
|
5140
5426
|
'clear-depth-buffer',
|
|
5141
5427
|
'clear-stencil-buffer',
|
|
5142
5428
|
'cull-faces',
|
|
@@ -5164,11 +5450,14 @@ class CameraComponentElement extends ComponentElement {
|
|
|
5164
5450
|
case 'clear-color-buffer':
|
|
5165
5451
|
this.clearColorBuffer = parseBool(newValue, true);
|
|
5166
5452
|
break;
|
|
5453
|
+
case 'clear-depth':
|
|
5454
|
+
this.clearDepth = parseNumber(newValue, 1, name);
|
|
5455
|
+
break;
|
|
5167
5456
|
case 'clear-depth-buffer':
|
|
5168
5457
|
this.clearDepthBuffer = parseBool(newValue, true);
|
|
5169
5458
|
break;
|
|
5170
5459
|
case 'clear-stencil-buffer':
|
|
5171
|
-
this.clearStencilBuffer = parseBool(newValue,
|
|
5460
|
+
this.clearStencilBuffer = parseBool(newValue, true);
|
|
5172
5461
|
break;
|
|
5173
5462
|
case 'cull-faces':
|
|
5174
5463
|
this.cullFaces = parseBool(newValue, true);
|
|
@@ -5229,6 +5518,12 @@ customElements.define('pc-camera', CameraComponentElement);
|
|
|
5229
5518
|
* retargets or rebinds picks up the new node's geometry. An entity with no asset-backed render
|
|
5230
5519
|
* component warns, and the collider has no shape.
|
|
5231
5520
|
*
|
|
5521
|
+
* Engine component: {@link CollisionComponent} (`collision`).
|
|
5522
|
+
*
|
|
5523
|
+
* @elementSummary The `<pc-collision>` element gives its entity a collision shape — a box, sphere,
|
|
5524
|
+
* capsule, cone, cylinder or mesh — for the physics simulation to collide against. Pair it with a
|
|
5525
|
+
* `<pc-rigid-body>`. Must be a child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
5526
|
+
*
|
|
5232
5527
|
* @category Components
|
|
5233
5528
|
*/
|
|
5234
5529
|
class CollisionComponentElement extends ComponentElement {
|
|
@@ -5265,7 +5560,9 @@ class CollisionComponentElement extends ComponentElement {
|
|
|
5265
5560
|
* no attribute to supply it - so the host's visible geometry, the meaning a mesh collider
|
|
5266
5561
|
* on a glTF node carries, fills the gap. Runs on every application (so a rebound `pc-node`
|
|
5267
5562
|
* recomputes it) and on a runtime switch to `type="mesh"`; an explicitly assigned
|
|
5268
|
-
* `renderAsset` is never overwritten.
|
|
5563
|
+
* `renderAsset` is never overwritten. A `pc-model` host entity never carries a render
|
|
5564
|
+
* component (the instantiated content beneath it does), so a mesh collider that should take
|
|
5565
|
+
* an asset's geometry belongs on a bound `pc-node`.
|
|
5269
5566
|
*/
|
|
5270
5567
|
_applyMeshGeometryDefault() {
|
|
5271
5568
|
const component = this.component;
|
|
@@ -5410,6 +5707,17 @@ customElements.define('pc-collision', CollisionComponentElement);
|
|
|
5410
5707
|
* The ElementComponentElement interface also inherits the properties and methods of the
|
|
5411
5708
|
* {@link HTMLElement} interface.
|
|
5412
5709
|
*
|
|
5710
|
+
* Despite the name, this is not a base class or a generic wrapper: it is the engine's 2D UI
|
|
5711
|
+
* component, which gives its host entity a rectangle in a `<pc-screen>` hierarchy that draws
|
|
5712
|
+
* either an image, a line of text or nothing (`type="image"`, `"text"` or `"group"`). The tag
|
|
5713
|
+
* spells the engine component it adds, as every component element does.
|
|
5714
|
+
*
|
|
5715
|
+
* Engine component: {@link ElementComponent} (`element`).
|
|
5716
|
+
*
|
|
5717
|
+
* @elementSummary The `<pc-element>` element gives its entity a 2D UI rectangle inside a
|
|
5718
|
+
* `<pc-screen>` hierarchy, drawing an image, a line of text or nothing (`type="image"`, `"text"` or
|
|
5719
|
+
* `"group"`). Must be a child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
5720
|
+
*
|
|
5413
5721
|
* @category Components
|
|
5414
5722
|
*/
|
|
5415
5723
|
class ElementComponentElement extends ComponentElement {
|
|
@@ -6094,10 +6402,17 @@ customElements.define('pc-element', ElementComponentElement);
|
|
|
6094
6402
|
* a rigid body component; leaving `entity-b` empty constrains `entity-a` to a fixed point in world
|
|
6095
6403
|
* space. The underlying engine component is in alpha, so its API may change.
|
|
6096
6404
|
*
|
|
6405
|
+
* @elementSummary The `<pc-joint>` element constrains two rigid bodies to each other — a hinged
|
|
6406
|
+
* door, a swinging chain, a sliding drawer. Its entity's transform is the joint frame, and
|
|
6407
|
+
* `entity-a` and `entity-b` name the bodies. Must be a child of a `<pc-entity>`, `<pc-model>` or
|
|
6408
|
+
* `<pc-node>`.
|
|
6409
|
+
*
|
|
6097
6410
|
* @fires {CustomEvent} break - Fired when the impulse on the joint exceeds `break-impulse` and the
|
|
6098
6411
|
* constraint breaks. A broken joint no longer constrains its bodies; calling `refreshFrames()` on
|
|
6099
6412
|
* the underlying component re-attaches it. Bubbles and is composed.
|
|
6100
6413
|
*
|
|
6414
|
+
* Engine component: {@link JointComponent} (`joint`).
|
|
6415
|
+
*
|
|
6101
6416
|
* @category Components
|
|
6102
6417
|
*/
|
|
6103
6418
|
class JointComponentElement extends ComponentElement {
|
|
@@ -6956,10 +7271,16 @@ customElements.define('pc-joint', JointComponentElement);
|
|
|
6956
7271
|
|
|
6957
7272
|
/**
|
|
6958
7273
|
* The LayoutChildComponentElement interface provides properties and methods for manipulating
|
|
6959
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-
|
|
7274
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-layout-child/ | `<pc-layout-child>`} elements.
|
|
6960
7275
|
* The LayoutChildComponentElement interface also inherits the properties and methods of the
|
|
6961
7276
|
* {@link HTMLElement} interface.
|
|
6962
7277
|
*
|
|
7278
|
+
* Engine component: {@link LayoutChildComponent} (`layoutchild`).
|
|
7279
|
+
*
|
|
7280
|
+
* @elementSummary The `<pc-layout-child>` element controls how its entity is sized by the
|
|
7281
|
+
* `<pc-layout-group>` above it, through minimum and maximum sizes and fit proportions. Must be a
|
|
7282
|
+
* child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
7283
|
+
*
|
|
6963
7284
|
* @category Components
|
|
6964
7285
|
*/
|
|
6965
7286
|
class LayoutChildComponentElement extends ComponentElement {
|
|
@@ -7152,7 +7473,7 @@ class LayoutChildComponentElement extends ComponentElement {
|
|
|
7152
7473
|
}
|
|
7153
7474
|
}
|
|
7154
7475
|
}
|
|
7155
|
-
customElements.define('pc-
|
|
7476
|
+
customElements.define('pc-layout-child', LayoutChildComponentElement);
|
|
7156
7477
|
|
|
7157
7478
|
const orientations$1 = new Map([
|
|
7158
7479
|
['horizontal', playcanvas.ORIENTATION_HORIZONTAL],
|
|
@@ -7166,10 +7487,16 @@ const fittings = new Map([
|
|
|
7166
7487
|
]);
|
|
7167
7488
|
/**
|
|
7168
7489
|
* The LayoutGroupComponentElement interface provides properties and methods for manipulating
|
|
7169
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-
|
|
7490
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-layout-group/ | `<pc-layout-group>`} elements.
|
|
7170
7491
|
* The LayoutGroupComponentElement interface also inherits the properties and methods of the
|
|
7171
7492
|
* {@link HTMLElement} interface.
|
|
7172
7493
|
*
|
|
7494
|
+
* Engine component: {@link LayoutGroupComponent} (`layoutgroup`).
|
|
7495
|
+
*
|
|
7496
|
+
* @elementSummary The `<pc-layout-group>` element arranges its entity's children in a row or
|
|
7497
|
+
* column, with spacing, padding, alignment and fitting. Must be a child of a `<pc-entity>`,
|
|
7498
|
+
* `<pc-model>` or `<pc-node>`.
|
|
7499
|
+
*
|
|
7173
7500
|
* @category Components
|
|
7174
7501
|
*/
|
|
7175
7502
|
class LayoutGroupComponentElement extends ComponentElement {
|
|
@@ -7409,7 +7736,7 @@ class LayoutGroupComponentElement extends ComponentElement {
|
|
|
7409
7736
|
}
|
|
7410
7737
|
}
|
|
7411
7738
|
}
|
|
7412
|
-
customElements.define('pc-
|
|
7739
|
+
customElements.define('pc-layout-group', LayoutGroupComponentElement);
|
|
7413
7740
|
|
|
7414
7741
|
const shadowTypes = new Map([
|
|
7415
7742
|
['pcf1-16f', playcanvas.SHADOW_PCF1_16F],
|
|
@@ -7428,23 +7755,32 @@ const shadowTypes = new Map([
|
|
|
7428
7755
|
* The LightComponentElement interface also inherits the properties and methods of the
|
|
7429
7756
|
* {@link HTMLElement} interface.
|
|
7430
7757
|
*
|
|
7758
|
+
* Engine component: {@link LightComponent} (`light`).
|
|
7759
|
+
*
|
|
7760
|
+
* @elementSummary The `<pc-light>` element lights the scene from its entity — as a directional,
|
|
7761
|
+
* omni or spot light — with attributes for color, intensity, range and shadows. Must be a child of
|
|
7762
|
+
* a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
7763
|
+
*
|
|
7431
7764
|
* @category Components
|
|
7432
7765
|
*/
|
|
7433
7766
|
class LightComponentElement extends ComponentElement {
|
|
7767
|
+
_cascadeBlend = 0;
|
|
7768
|
+
_cascadeDistribution = 0.5;
|
|
7434
7769
|
_castShadows = false;
|
|
7435
7770
|
_color = new playcanvas.Color(1, 1, 1);
|
|
7436
7771
|
_innerConeAngle = 40;
|
|
7437
7772
|
_intensity = 1;
|
|
7438
|
-
_normalOffsetBias = 0
|
|
7773
|
+
_normalOffsetBias = 0;
|
|
7774
|
+
_numCascades = 1;
|
|
7439
7775
|
_outerConeAngle = 45;
|
|
7440
7776
|
_range = 10;
|
|
7441
|
-
_shadowBias = 0.
|
|
7442
|
-
_shadowDistance =
|
|
7777
|
+
_shadowBias = 0.05;
|
|
7778
|
+
_shadowDistance = 40;
|
|
7443
7779
|
_shadowIntensity = 1;
|
|
7444
7780
|
_shadowResolution = 1024;
|
|
7445
7781
|
_shadowType = 'pcf3-32f';
|
|
7446
7782
|
_type = 'directional';
|
|
7447
|
-
_vsmBias = 0.
|
|
7783
|
+
_vsmBias = 0.0025;
|
|
7448
7784
|
_vsmBlurSize = 11;
|
|
7449
7785
|
_penumbraSize = 1;
|
|
7450
7786
|
_penumbraFalloff = 1;
|
|
@@ -7456,11 +7792,14 @@ class LightComponentElement extends ComponentElement {
|
|
|
7456
7792
|
}
|
|
7457
7793
|
getInitialComponentData() {
|
|
7458
7794
|
return {
|
|
7795
|
+
cascadeBlend: this._cascadeBlend,
|
|
7796
|
+
cascadeDistribution: this._cascadeDistribution,
|
|
7459
7797
|
castShadows: this._castShadows,
|
|
7460
7798
|
color: this._color,
|
|
7461
7799
|
innerConeAngle: this._innerConeAngle,
|
|
7462
7800
|
intensity: this._intensity,
|
|
7463
7801
|
normalOffsetBias: this._normalOffsetBias,
|
|
7802
|
+
numCascades: this._numCascades,
|
|
7464
7803
|
outerConeAngle: this._outerConeAngle,
|
|
7465
7804
|
penumbraFalloff: this._penumbraFalloff,
|
|
7466
7805
|
penumbraSize: this._penumbraSize,
|
|
@@ -7471,7 +7810,7 @@ class LightComponentElement extends ComponentElement {
|
|
|
7471
7810
|
shadowIntensity: this._shadowIntensity,
|
|
7472
7811
|
shadowResolution: this._shadowResolution,
|
|
7473
7812
|
shadowSamples: this._shadowSamples,
|
|
7474
|
-
shadowType: shadowTypes.get(this._shadowType),
|
|
7813
|
+
shadowType: shadowTypes.get(this._shadowType) ?? playcanvas.SHADOW_PCF3_32F,
|
|
7475
7814
|
type: this._type,
|
|
7476
7815
|
vsmBias: this._vsmBias,
|
|
7477
7816
|
vsmBlurSize: this._vsmBlurSize
|
|
@@ -7484,6 +7823,47 @@ class LightComponentElement extends ComponentElement {
|
|
|
7484
7823
|
get component() {
|
|
7485
7824
|
return super.component;
|
|
7486
7825
|
}
|
|
7826
|
+
/**
|
|
7827
|
+
* Sets the fraction of each shadow cascade that is blended into the next one, from 0 (no
|
|
7828
|
+
* blending) to 1, which applies only to `directional` lights with `num-cascades` greater than
|
|
7829
|
+
* 1. Defaults to 0.
|
|
7830
|
+
* @param value - The cascade blend factor.
|
|
7831
|
+
*/
|
|
7832
|
+
set cascadeBlend(value) {
|
|
7833
|
+
this._cascadeBlend = value;
|
|
7834
|
+
if (this.component) {
|
|
7835
|
+
this.component.cascadeBlend = value;
|
|
7836
|
+
}
|
|
7837
|
+
}
|
|
7838
|
+
/**
|
|
7839
|
+
* Gets the cascade blend factor of the light, from 0 (no blending) to 1, which applies only to
|
|
7840
|
+
* `directional` lights with `num-cascades` greater than 1.
|
|
7841
|
+
* @returns The cascade blend factor.
|
|
7842
|
+
*/
|
|
7843
|
+
get cascadeBlend() {
|
|
7844
|
+
return this._cascadeBlend;
|
|
7845
|
+
}
|
|
7846
|
+
/**
|
|
7847
|
+
* Sets the distribution of the camera frustum split between shadow cascades, from 0 (linear
|
|
7848
|
+
* split) to 1 (logarithmic split, concentrating shadow resolution near the camera), which
|
|
7849
|
+
* applies only to `directional` lights with `num-cascades` greater than 1. Defaults to 0.5.
|
|
7850
|
+
* @param value - The cascade distribution.
|
|
7851
|
+
*/
|
|
7852
|
+
set cascadeDistribution(value) {
|
|
7853
|
+
this._cascadeDistribution = value;
|
|
7854
|
+
if (this.component) {
|
|
7855
|
+
this.component.cascadeDistribution = value;
|
|
7856
|
+
}
|
|
7857
|
+
}
|
|
7858
|
+
/**
|
|
7859
|
+
* Gets the cascade distribution of the light, from 0 (linear split) to 1 (logarithmic split,
|
|
7860
|
+
* concentrating shadow resolution near the camera), which applies only to `directional` lights
|
|
7861
|
+
* with `num-cascades` greater than 1.
|
|
7862
|
+
* @returns The cascade distribution.
|
|
7863
|
+
*/
|
|
7864
|
+
get cascadeDistribution() {
|
|
7865
|
+
return this._cascadeDistribution;
|
|
7866
|
+
}
|
|
7487
7867
|
/**
|
|
7488
7868
|
* Sets the cast shadows flag of the light.
|
|
7489
7869
|
* @param value - The cast shadows flag.
|
|
@@ -7569,6 +7949,25 @@ class LightComponentElement extends ComponentElement {
|
|
|
7569
7949
|
get normalOffsetBias() {
|
|
7570
7950
|
return this._normalOffsetBias;
|
|
7571
7951
|
}
|
|
7952
|
+
/**
|
|
7953
|
+
* Sets the number of shadow cascades of the light, an integer from 1 (no cascades) to 4, which
|
|
7954
|
+
* applies only to `directional` lights. Defaults to 1.
|
|
7955
|
+
* @param value - The number of shadow cascades.
|
|
7956
|
+
*/
|
|
7957
|
+
set numCascades(value) {
|
|
7958
|
+
this._numCascades = value;
|
|
7959
|
+
if (this.component) {
|
|
7960
|
+
this.component.numCascades = value;
|
|
7961
|
+
}
|
|
7962
|
+
}
|
|
7963
|
+
/**
|
|
7964
|
+
* Gets the number of shadow cascades of the light, an integer from 1 (no cascades) to 4, which
|
|
7965
|
+
* applies only to `directional` lights.
|
|
7966
|
+
* @returns The number of shadow cascades.
|
|
7967
|
+
*/
|
|
7968
|
+
get numCascades() {
|
|
7969
|
+
return this._numCascades;
|
|
7970
|
+
}
|
|
7572
7971
|
/**
|
|
7573
7972
|
* Sets the outer cone angle of the light.
|
|
7574
7973
|
* @param value - The outer cone angle.
|
|
@@ -7821,11 +8220,14 @@ class LightComponentElement extends ComponentElement {
|
|
|
7821
8220
|
static get observedAttributes() {
|
|
7822
8221
|
return [
|
|
7823
8222
|
...super.observedAttributes,
|
|
7824
|
-
'
|
|
8223
|
+
'cascade-blend',
|
|
8224
|
+
'cascade-distribution',
|
|
7825
8225
|
'cast-shadows',
|
|
7826
|
-
'
|
|
8226
|
+
'color',
|
|
7827
8227
|
'inner-cone-angle',
|
|
8228
|
+
'intensity',
|
|
7828
8229
|
'normal-offset-bias',
|
|
8230
|
+
'num-cascades',
|
|
7829
8231
|
'outer-cone-angle',
|
|
7830
8232
|
'penumbra-falloff',
|
|
7831
8233
|
'penumbra-size',
|
|
@@ -7845,12 +8247,18 @@ class LightComponentElement extends ComponentElement {
|
|
|
7845
8247
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
7846
8248
|
super.attributeChangedCallback(name, _oldValue, newValue);
|
|
7847
8249
|
switch (name) {
|
|
7848
|
-
case '
|
|
7849
|
-
this.
|
|
8250
|
+
case 'cascade-blend':
|
|
8251
|
+
this.cascadeBlend = parseNumber(newValue, 0, name);
|
|
8252
|
+
break;
|
|
8253
|
+
case 'cascade-distribution':
|
|
8254
|
+
this.cascadeDistribution = parseNumber(newValue, 0.5, name);
|
|
7850
8255
|
break;
|
|
7851
8256
|
case 'cast-shadows':
|
|
7852
8257
|
this.castShadows = parseBool(newValue, false);
|
|
7853
8258
|
break;
|
|
8259
|
+
case 'color':
|
|
8260
|
+
this.color = parseColor(newValue, playcanvas.Color.WHITE, name);
|
|
8261
|
+
break;
|
|
7854
8262
|
case 'inner-cone-angle':
|
|
7855
8263
|
this.innerConeAngle = parseNumber(newValue, 40, name);
|
|
7856
8264
|
break;
|
|
@@ -7858,7 +8266,10 @@ class LightComponentElement extends ComponentElement {
|
|
|
7858
8266
|
this.intensity = parseNumber(newValue, 1, name);
|
|
7859
8267
|
break;
|
|
7860
8268
|
case 'normal-offset-bias':
|
|
7861
|
-
this.normalOffsetBias = parseNumber(newValue, 0
|
|
8269
|
+
this.normalOffsetBias = parseNumber(newValue, 0, name);
|
|
8270
|
+
break;
|
|
8271
|
+
case 'num-cascades':
|
|
8272
|
+
this.numCascades = parseNumber(newValue, 1, name);
|
|
7862
8273
|
break;
|
|
7863
8274
|
case 'outer-cone-angle':
|
|
7864
8275
|
this.outerConeAngle = parseNumber(newValue, 45, name);
|
|
@@ -7873,20 +8284,20 @@ class LightComponentElement extends ComponentElement {
|
|
|
7873
8284
|
this.range = parseNumber(newValue, 10, name);
|
|
7874
8285
|
break;
|
|
7875
8286
|
case 'shadow-bias':
|
|
7876
|
-
this.shadowBias = parseNumber(newValue, 0.
|
|
7877
|
-
break;
|
|
7878
|
-
case 'shadow-distance':
|
|
7879
|
-
this.shadowDistance = parseNumber(newValue, 16, name);
|
|
8287
|
+
this.shadowBias = parseNumber(newValue, 0.05, name);
|
|
7880
8288
|
break;
|
|
7881
8289
|
case 'shadow-blocker-samples':
|
|
7882
8290
|
this.shadowBlockerSamples = parseNumber(newValue, 16, name);
|
|
7883
8291
|
break;
|
|
7884
|
-
case 'shadow-
|
|
7885
|
-
this.
|
|
8292
|
+
case 'shadow-distance':
|
|
8293
|
+
this.shadowDistance = parseNumber(newValue, 40, name);
|
|
7886
8294
|
break;
|
|
7887
8295
|
case 'shadow-intensity':
|
|
7888
8296
|
this.shadowIntensity = parseNumber(newValue, 1, name);
|
|
7889
8297
|
break;
|
|
8298
|
+
case 'shadow-resolution':
|
|
8299
|
+
this.shadowResolution = parseNumber(newValue, 1024, name);
|
|
8300
|
+
break;
|
|
7890
8301
|
case 'shadow-samples':
|
|
7891
8302
|
this.shadowSamples = parseNumber(newValue, 16, name);
|
|
7892
8303
|
break;
|
|
@@ -7897,7 +8308,7 @@ class LightComponentElement extends ComponentElement {
|
|
|
7897
8308
|
this.type = parseEnum(newValue, ['directional', 'omni', 'spot'], 'directional', name);
|
|
7898
8309
|
break;
|
|
7899
8310
|
case 'vsm-bias':
|
|
7900
|
-
this.vsmBias = parseNumber(newValue, 0.
|
|
8311
|
+
this.vsmBias = parseNumber(newValue, 0.0025, name);
|
|
7901
8312
|
break;
|
|
7902
8313
|
case 'vsm-blur-size':
|
|
7903
8314
|
this.vsmBlurSize = parseNumber(newValue, 11, name);
|
|
@@ -7909,10 +8320,16 @@ customElements.define('pc-light', LightComponentElement);
|
|
|
7909
8320
|
|
|
7910
8321
|
/**
|
|
7911
8322
|
* The ParticleSystemComponentElement interface provides properties and methods for manipulating
|
|
7912
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-
|
|
8323
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-particle-system/ | `<pc-particle-system>`} elements.
|
|
7913
8324
|
* The ParticleSystemComponentElement interface also inherits the properties and methods of the
|
|
7914
8325
|
* {@link HTMLElement} interface.
|
|
7915
8326
|
*
|
|
8327
|
+
* Engine component: {@link ParticleSystemComponent} (`particlesystem`).
|
|
8328
|
+
*
|
|
8329
|
+
* @elementSummary The `<pc-particle-system>` element emits particles from its entity, with
|
|
8330
|
+
* attributes for the emitter's shape, rate, lifetime, textures and blending. Must be a child of a
|
|
8331
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
8332
|
+
*
|
|
7916
8333
|
* @category Components
|
|
7917
8334
|
*/
|
|
7918
8335
|
class ParticleSystemComponentElement extends ComponentElement {
|
|
@@ -8031,7 +8448,7 @@ class ParticleSystemComponentElement extends ComponentElement {
|
|
|
8031
8448
|
}
|
|
8032
8449
|
}
|
|
8033
8450
|
}
|
|
8034
|
-
customElements.define('pc-
|
|
8451
|
+
customElements.define('pc-particle-system', ParticleSystemComponentElement);
|
|
8035
8452
|
|
|
8036
8453
|
const blendTypes = new Map([
|
|
8037
8454
|
['none', playcanvas.BLEND_NONE],
|
|
@@ -8061,6 +8478,8 @@ const occludeSpeculars = new Map([
|
|
|
8061
8478
|
['ao', playcanvas.SPECOCC_AO],
|
|
8062
8479
|
['gloss-dependent', playcanvas.SPECOCC_GLOSSDEPENDENT]
|
|
8063
8480
|
]);
|
|
8481
|
+
// The DITHER_* constants are strings whose values are exactly these names, so a parsed value is
|
|
8482
|
+
// assigned to the material unchanged rather than mapped through a table.
|
|
8064
8483
|
const opacityDithers = ['none', 'bayer8', 'bluenoise', 'ignnoise'];
|
|
8065
8484
|
const colorChannels = ['r', 'g', 'b', 'a', 'rgb'];
|
|
8066
8485
|
const scalarChannels = ['r', 'g', 'b', 'a'];
|
|
@@ -8097,6 +8516,10 @@ const roughnessAliases = ['roughness', 'roughness-map'];
|
|
|
8097
8516
|
* The two aliases are documented here rather than on an accessor, because they resolve to the
|
|
8098
8517
|
* `gloss` properties and would otherwise inherit gloss's description - which reads inverted.
|
|
8099
8518
|
*
|
|
8519
|
+
* @elementSummary The `<pc-material>` element defines a physically based material, which
|
|
8520
|
+
* `<pc-render>` elements apply by naming its `id`. It is metal/rough by default, with `metalness`
|
|
8521
|
+
* starting at 0. Must be a direct child of `<pc-app>`.
|
|
8522
|
+
*
|
|
8100
8523
|
* @attribute {number} roughness - The roughness of the material, from 0 (shiny) to 1 (rough). An
|
|
8101
8524
|
* alias for `gloss` that also inverts it, so do not combine it with the `gloss` attributes.
|
|
8102
8525
|
* @attribute {string} roughness-map - The id of the `pc-asset` to use as the roughness map. An
|
|
@@ -10263,6 +10686,13 @@ customElements.define('pc-material', MaterialElement);
|
|
|
10263
10686
|
* to `box`). It does not cover the engine's `asset` render type, since there is no way to supply
|
|
10264
10687
|
* a render asset here — use `pc-model` for glTF content instead.
|
|
10265
10688
|
*
|
|
10689
|
+
* Engine component: {@link RenderComponent} (`render`).
|
|
10690
|
+
*
|
|
10691
|
+
* @elementSummary The `<pc-render>` element renders one of the engine's built-in primitives at its
|
|
10692
|
+
* entity — box, sphere, capsule, cone, cylinder or plane — shaded by the `<pc-material>` its
|
|
10693
|
+
* `material` attribute names. For glTF content, use `<pc-model>` instead. Must be a child of a
|
|
10694
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
10695
|
+
*
|
|
10266
10696
|
* @category Components
|
|
10267
10697
|
*/
|
|
10268
10698
|
class RenderComponentElement extends ComponentElement {
|
|
@@ -10387,10 +10817,17 @@ customElements.define('pc-render', RenderComponentElement);
|
|
|
10387
10817
|
|
|
10388
10818
|
/**
|
|
10389
10819
|
* The RigidBodyComponentElement interface provides properties and methods for manipulating
|
|
10390
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-
|
|
10820
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-rigid-body/ | `<pc-rigid-body>`} elements.
|
|
10391
10821
|
* The RigidBodyComponentElement interface also inherits the properties and methods of the
|
|
10392
10822
|
* {@link HTMLElement} interface.
|
|
10393
10823
|
*
|
|
10824
|
+
* Engine component: {@link RigidBodyComponent} (`rigidbody`).
|
|
10825
|
+
*
|
|
10826
|
+
* @elementSummary The `<pc-rigid-body>` element hands its entity to the physics simulation, with
|
|
10827
|
+
* attributes for its type, mass, friction and restitution. It needs a sibling `<pc-collision>` for
|
|
10828
|
+
* its shape, and `Ammo` loaded through `<pc-wasm>`. Must be a child of a `<pc-entity>`,
|
|
10829
|
+
* `<pc-model>` or `<pc-node>`.
|
|
10830
|
+
*
|
|
10394
10831
|
* @category Components
|
|
10395
10832
|
*/
|
|
10396
10833
|
class RigidBodyComponentElement extends ComponentElement {
|
|
@@ -10582,7 +11019,7 @@ class RigidBodyComponentElement extends ComponentElement {
|
|
|
10582
11019
|
}
|
|
10583
11020
|
}
|
|
10584
11021
|
}
|
|
10585
|
-
customElements.define('pc-
|
|
11022
|
+
customElements.define('pc-rigid-body', RigidBodyComponentElement);
|
|
10586
11023
|
|
|
10587
11024
|
// The engine's SCALEMODE_* constants are the strings 'none' and 'blend', so this map happens to be
|
|
10588
11025
|
// an identity. It is still the right shape: it supplies parseEnum's valid-name list, it is what the
|
|
@@ -10598,6 +11035,12 @@ const scaleModes = new Map([
|
|
|
10598
11035
|
* The ScreenComponentElement interface also inherits the properties and methods of the
|
|
10599
11036
|
* {@link HTMLElement} interface.
|
|
10600
11037
|
*
|
|
11038
|
+
* Engine component: {@link ScreenComponent} (`screen`).
|
|
11039
|
+
*
|
|
11040
|
+
* @elementSummary The `<pc-screen>` element gives its entity a 2D space — in screen space or in the
|
|
11041
|
+
* world — that a hierarchy of `<pc-element>` descendants lays out inside. Must be a child of a
|
|
11042
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
11043
|
+
*
|
|
10601
11044
|
* @category Components
|
|
10602
11045
|
*/
|
|
10603
11046
|
class ScreenComponentElement extends ComponentElement {
|
|
@@ -10750,6 +11193,12 @@ const orientations = new Map([
|
|
|
10750
11193
|
* The ScrollbarComponentElement interface also inherits the properties and methods of the
|
|
10751
11194
|
* {@link HTMLElement} interface.
|
|
10752
11195
|
*
|
|
11196
|
+
* Engine component: {@link ScrollbarComponent} (`scrollbar`).
|
|
11197
|
+
*
|
|
11198
|
+
* @elementSummary The `<pc-scrollbar>` element gives its entity a draggable handle reporting a
|
|
11199
|
+
* position from 0 to 1, which a `<pc-scroll-view>` references to scroll its content. Must be a
|
|
11200
|
+
* child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
11201
|
+
*
|
|
10753
11202
|
* @category Components
|
|
10754
11203
|
*/
|
|
10755
11204
|
class ScrollbarComponentElement extends ComponentElement {
|
|
@@ -10885,10 +11334,16 @@ const visibilities = new Map([
|
|
|
10885
11334
|
]);
|
|
10886
11335
|
/**
|
|
10887
11336
|
* The ScrollViewComponentElement interface provides properties and methods for manipulating
|
|
10888
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-
|
|
11337
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-scroll-view/ | `<pc-scroll-view>`} elements.
|
|
10889
11338
|
* The ScrollViewComponentElement interface also inherits the properties and methods of the
|
|
10890
11339
|
* {@link HTMLElement} interface.
|
|
10891
11340
|
*
|
|
11341
|
+
* Engine component: {@link ScrollViewComponent} (`scrollview`).
|
|
11342
|
+
*
|
|
11343
|
+
* @elementSummary The `<pc-scroll-view>` element scrolls a larger content entity within a clipped
|
|
11344
|
+
* viewport at its entity, optionally driven by the `<pc-scrollbar>` elements it references. Must be
|
|
11345
|
+
* a child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
11346
|
+
*
|
|
10892
11347
|
* @category Components
|
|
10893
11348
|
*/
|
|
10894
11349
|
class ScrollViewComponentElement extends ComponentElement {
|
|
@@ -11247,11 +11702,11 @@ class ScrollViewComponentElement extends ComponentElement {
|
|
|
11247
11702
|
}
|
|
11248
11703
|
}
|
|
11249
11704
|
}
|
|
11250
|
-
customElements.define('pc-
|
|
11705
|
+
customElements.define('pc-scroll-view', ScrollViewComponentElement);
|
|
11251
11706
|
|
|
11252
11707
|
/**
|
|
11253
|
-
* The
|
|
11254
|
-
* `<pc-script>` elements. The
|
|
11708
|
+
* The ScriptInstanceElement interface provides properties and methods for manipulating
|
|
11709
|
+
* `<pc-script-instance>` elements. The ScriptInstanceElement interface also inherits the properties and
|
|
11255
11710
|
* methods of the {@link AsyncElement} interface.
|
|
11256
11711
|
*
|
|
11257
11712
|
* Script attributes can be supplied through two channels:
|
|
@@ -11273,7 +11728,11 @@ customElements.define('pc-scrollview', ScrollViewComponentElement);
|
|
|
11273
11728
|
* new-name one, re-applying both attribute channels to it.
|
|
11274
11729
|
*
|
|
11275
11730
|
* The element becomes ready once its script instance has been created by the parent
|
|
11276
|
-
* `<pc-
|
|
11731
|
+
* `<pc-script>` element.
|
|
11732
|
+
*
|
|
11733
|
+
* @elementSummary The `<pc-script-instance>` element attaches one script class, named by `name`, to
|
|
11734
|
+
* the entity of its parent `<pc-script>`. Its other attributes set script attributes of the same
|
|
11735
|
+
* name, and `attributes` takes a JSON object instead. Must be a direct child of `<pc-script>`.
|
|
11277
11736
|
*
|
|
11278
11737
|
* @fires {CustomEvent} scriptattributeschange - Fired when the script's attributes change. The
|
|
11279
11738
|
* `detail` carries the new `attributes` object. Bubbles.
|
|
@@ -11282,11 +11741,11 @@ customElements.define('pc-scrollview', ScrollViewComponentElement);
|
|
|
11282
11741
|
* @fires {CustomEvent} scriptnamechange - Fired when the script is renamed on a live element. The
|
|
11283
11742
|
* `detail` carries `oldName` and `newName`. Bubbles.
|
|
11284
11743
|
*/
|
|
11285
|
-
class
|
|
11744
|
+
class ScriptInstanceElement extends AsyncElement {
|
|
11286
11745
|
_attributes = {};
|
|
11287
11746
|
_enabled = true;
|
|
11288
11747
|
/**
|
|
11289
|
-
* The Script instance created for this element by its parent `<pc-
|
|
11748
|
+
* The Script instance created for this element by its parent `<pc-script>` element.
|
|
11290
11749
|
* @internal
|
|
11291
11750
|
*/
|
|
11292
11751
|
_script = null;
|
|
@@ -11332,11 +11791,11 @@ class ScriptElement extends AsyncElement {
|
|
|
11332
11791
|
}
|
|
11333
11792
|
/**
|
|
11334
11793
|
* Sets the name of the script to create. The `name` attribute is the single source of truth
|
|
11335
|
-
* (it is what the parent `<pc-
|
|
11794
|
+
* (it is what the parent `<pc-script>` element reads when creating the instance), so the
|
|
11336
11795
|
* property writes through to it — assigning before insertion works as expected:
|
|
11337
11796
|
*
|
|
11338
11797
|
* ```js
|
|
11339
|
-
* const script = document.createElement('pc-script');
|
|
11798
|
+
* const script = document.createElement('pc-script-instance');
|
|
11340
11799
|
* script.name = 'rotate';
|
|
11341
11800
|
* scriptsElement.appendChild(script);
|
|
11342
11801
|
* await script.ready();
|
|
@@ -11363,10 +11822,10 @@ class ScriptElement extends AsyncElement {
|
|
|
11363
11822
|
return this._script;
|
|
11364
11823
|
}
|
|
11365
11824
|
connectedCallback() {
|
|
11366
|
-
// Script instances are created by the parent pc-
|
|
11825
|
+
// Script instances are created by the parent pc-script element, so an element placed
|
|
11367
11826
|
// anywhere else is inert and never becomes ready - warn rather than hang silently
|
|
11368
|
-
if (this.parentElement?.tagName !== 'PC-
|
|
11369
|
-
console.warn(`pc-script '${this.getAttribute('name')}' must be a direct child of pc-
|
|
11827
|
+
if (this.parentElement?.tagName !== 'PC-SCRIPT') {
|
|
11828
|
+
console.warn(`pc-script-instance '${this.getAttribute('name')}' must be a direct child of pc-script - script not created`);
|
|
11370
11829
|
}
|
|
11371
11830
|
}
|
|
11372
11831
|
disconnectedCallback() {
|
|
@@ -11377,7 +11836,7 @@ class ScriptElement extends AsyncElement {
|
|
|
11377
11836
|
this._resetReady();
|
|
11378
11837
|
}
|
|
11379
11838
|
/**
|
|
11380
|
-
* Called by the parent `<pc-
|
|
11839
|
+
* Called by the parent `<pc-script>` element when the script instance has been created.
|
|
11381
11840
|
* Creation can happen more than once per connection (a runtime `name` change recreates the
|
|
11382
11841
|
* instance), but `_onReady` signals readiness at most once per cycle.
|
|
11383
11842
|
* @internal
|
|
@@ -11399,7 +11858,7 @@ class ScriptElement extends AsyncElement {
|
|
|
11399
11858
|
this.scriptAttributes = JSON.parse(newValue);
|
|
11400
11859
|
}
|
|
11401
11860
|
catch (error) {
|
|
11402
|
-
console.warn(`Invalid 'attributes' JSON on pc-script '${this.getAttribute('name')}': ${error.message}`);
|
|
11861
|
+
console.warn(`Invalid 'attributes' JSON on pc-script-instance '${this.getAttribute('name')}': ${error.message}`);
|
|
11403
11862
|
}
|
|
11404
11863
|
break;
|
|
11405
11864
|
case 'enabled':
|
|
@@ -11419,14 +11878,14 @@ class ScriptElement extends AsyncElement {
|
|
|
11419
11878
|
}
|
|
11420
11879
|
}
|
|
11421
11880
|
}
|
|
11422
|
-
customElements.define('pc-script',
|
|
11881
|
+
customElements.define('pc-script-instance', ScriptInstanceElement);
|
|
11423
11882
|
|
|
11424
11883
|
/**
|
|
11425
|
-
* Attributes on `pc-script` that never map to script attributes: the element's own API (derived
|
|
11884
|
+
* Attributes on `pc-script-instance` that never map to script attributes: the element's own API (derived
|
|
11426
11885
|
* from its observed attributes) plus reserved and global HTML attribute names.
|
|
11427
11886
|
*/
|
|
11428
11887
|
const RESERVED_ATTRIBUTES = new Set([
|
|
11429
|
-
...
|
|
11888
|
+
...ScriptInstanceElement.observedAttributes,
|
|
11430
11889
|
'accesskey',
|
|
11431
11890
|
'autocapitalize',
|
|
11432
11891
|
'autofocus',
|
|
@@ -11457,7 +11916,7 @@ const RESERVED_ATTRIBUTES = new Set([
|
|
|
11457
11916
|
'translate'
|
|
11458
11917
|
]);
|
|
11459
11918
|
/**
|
|
11460
|
-
* Checks whether a `pc-script` attribute name is reserved (and so never maps to a script
|
|
11919
|
+
* Checks whether a `pc-script-instance` attribute name is reserved (and so never maps to a script
|
|
11461
11920
|
* attribute). Reserved names are the element's own API, global HTML attribute names, `data-*`
|
|
11462
11921
|
* and `aria-*` attributes, names starting with `_` (framework-stamped attributes), and real
|
|
11463
11922
|
* inline event handler names (`onclick` etc. — detected via the platform, so script attributes
|
|
@@ -11613,10 +12072,15 @@ const findCaseMatch = (script, key) => {
|
|
|
11613
12072
|
};
|
|
11614
12073
|
/**
|
|
11615
12074
|
* The ScriptComponentElement interface provides properties and methods for manipulating
|
|
11616
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-
|
|
12075
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-script/ | `<pc-script>`} elements.
|
|
11617
12076
|
* The ScriptComponentElement interface also inherits the properties and methods of the
|
|
11618
12077
|
* {@link HTMLElement} interface.
|
|
11619
12078
|
*
|
|
12079
|
+
* Engine component: {@link ScriptComponent} (`script`).
|
|
12080
|
+
*
|
|
12081
|
+
* @elementSummary The `<pc-script>` element holds the `<pc-script-instance>` children that attach
|
|
12082
|
+
* scripts to its entity. Must be a child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
12083
|
+
*
|
|
11620
12084
|
* @category Components
|
|
11621
12085
|
*/
|
|
11622
12086
|
class ScriptComponentElement extends ComponentElement {
|
|
@@ -11633,14 +12097,23 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11633
12097
|
}
|
|
11634
12098
|
connectedCallback() {
|
|
11635
12099
|
// (Re-)observe on every connection - disconnectedCallback disconnects the observer.
|
|
11636
|
-
// Attribute changes on child pc-script elements are watched here too: per-property
|
|
12100
|
+
// Attribute changes on child pc-script-instance elements are watched here too: per-property
|
|
11637
12101
|
// script attributes are not statically known, so they cannot use observedAttributes.
|
|
11638
12102
|
this.observer.observe(this, { childList: true, subtree: true, attributes: true });
|
|
11639
12103
|
return super.connectedCallback();
|
|
11640
12104
|
}
|
|
11641
12105
|
initComponent() {
|
|
11642
|
-
|
|
11643
|
-
|
|
12106
|
+
this.querySelectorAll(':scope > pc-script-instance').forEach((scriptElement) => {
|
|
12107
|
+
// A host readiness cycle re-runs this against a component that can have survived it
|
|
12108
|
+
// (a pc-model reloading content on its stable host entity). The engine rejects a
|
|
12109
|
+
// duplicate create - returning null, silently in production builds - which would
|
|
12110
|
+
// skip attribute application entirely. A surviving instance is re-asserted instead,
|
|
12111
|
+
// so both cycle outcomes leave the component reflecting the element's declared state.
|
|
12112
|
+
const script = this.scriptFor(scriptElement);
|
|
12113
|
+
if (script) {
|
|
12114
|
+
this.applyDeclaredState(script, scriptElement);
|
|
12115
|
+
return;
|
|
12116
|
+
}
|
|
11644
12117
|
this.createScript(scriptElement);
|
|
11645
12118
|
});
|
|
11646
12119
|
}
|
|
@@ -11774,9 +12247,9 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11774
12247
|
this.mergeDeep(script, converted);
|
|
11775
12248
|
}
|
|
11776
12249
|
/**
|
|
11777
|
-
* Returns the camelCase keys of the per-property attributes present on a `pc-script`
|
|
12250
|
+
* Returns the camelCase keys of the per-property attributes present on a `pc-script-instance`
|
|
11778
12251
|
* element.
|
|
11779
|
-
* @param scriptElement - The `pc-script` element.
|
|
12252
|
+
* @param scriptElement - The `pc-script-instance` element.
|
|
11780
12253
|
* @returns The camelCase keys.
|
|
11781
12254
|
*/
|
|
11782
12255
|
inlineKeys(scriptElement) {
|
|
@@ -11789,10 +12262,10 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11789
12262
|
return keys;
|
|
11790
12263
|
}
|
|
11791
12264
|
/**
|
|
11792
|
-
* Resolves the script instance owned by a `pc-script` element. Returns `null` when the
|
|
12265
|
+
* Resolves the script instance owned by a `pc-script-instance` element. Returns `null` when the
|
|
11793
12266
|
* element has no created script, or when its name resolves to a script created by a
|
|
11794
12267
|
* different element (e.g. a duplicate-named sibling).
|
|
11795
|
-
* @param scriptElement - The `pc-script` element.
|
|
12268
|
+
* @param scriptElement - The `pc-script-instance` element.
|
|
11796
12269
|
* @returns The owned script, or `null`.
|
|
11797
12270
|
*/
|
|
11798
12271
|
scriptFor(scriptElement) {
|
|
@@ -11821,7 +12294,7 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11821
12294
|
}
|
|
11822
12295
|
}
|
|
11823
12296
|
/**
|
|
11824
|
-
* Handles a runtime `name` change on a child `pc-script`, swapping the engine script instance
|
|
12297
|
+
* Handles a runtime `name` change on a child `pc-script-instance`, swapping the engine script instance
|
|
11825
12298
|
* to match. Without this the element would keep pointing at the old-name instance: the old
|
|
11826
12299
|
* script would go on running while every subsequent update (attribute changes, enable
|
|
11827
12300
|
* changes, destruction on removal) resolved the new name and silently no-opped.
|
|
@@ -11832,8 +12305,8 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11832
12305
|
*/
|
|
11833
12306
|
handleScriptNameChange(event) {
|
|
11834
12307
|
const scriptElement = event.target;
|
|
11835
|
-
// Only direct children are managed, matching initComponent's ':scope > pc-script'
|
|
11836
|
-
// contract - the event bubbles, so a deeper pc-script must not be created here
|
|
12308
|
+
// Only direct children are managed, matching initComponent's ':scope > pc-script-instance'
|
|
12309
|
+
// contract - the event bubbles, so a deeper pc-script-instance must not be created here
|
|
11837
12310
|
if (scriptElement.parentElement !== this)
|
|
11838
12311
|
return;
|
|
11839
12312
|
// Before the component exists there is nothing to swap: initComponent creates from
|
|
@@ -11850,11 +12323,11 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11850
12323
|
this.createScript(scriptElement);
|
|
11851
12324
|
}
|
|
11852
12325
|
/**
|
|
11853
|
-
* Creates the script instance for a `pc-script` element. The instance is created disabled,
|
|
12326
|
+
* Creates the script instance for a `pc-script-instance` element. The instance is created disabled,
|
|
11854
12327
|
* the element's converted attributes are merged over the instance's defaults (which is what
|
|
11855
12328
|
* allows plain numeric arrays to be typed against those defaults), and only then is the
|
|
11856
12329
|
* declared enabled state applied — so `initialize()` runs with every attribute in place.
|
|
11857
|
-
* @param scriptElement - The `pc-script` element to create the script instance for.
|
|
12330
|
+
* @param scriptElement - The `pc-script-instance` element to create the script instance for.
|
|
11858
12331
|
* @returns The created script, or `null`.
|
|
11859
12332
|
*/
|
|
11860
12333
|
createScript(scriptElement) {
|
|
@@ -11865,21 +12338,30 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11865
12338
|
if (!script)
|
|
11866
12339
|
return null;
|
|
11867
12340
|
scriptElement._script = script;
|
|
11868
|
-
|
|
11869
|
-
|
|
12341
|
+
this.applyDeclaredState(script, scriptElement);
|
|
12342
|
+
scriptElement._onScriptCreated();
|
|
12343
|
+
return script;
|
|
12344
|
+
}
|
|
12345
|
+
/**
|
|
12346
|
+
* Applies a `pc-script-instance` element's declared state to a script instance: the `attributes` JSON
|
|
12347
|
+
* first with per-property-shadowed keys stripped, then the per-property attributes — each
|
|
12348
|
+
* property is written exactly once and individual attributes win — and finally the declared
|
|
12349
|
+
* enabled state, so `initialize()` runs with every attribute in place.
|
|
12350
|
+
* @param script - The script instance.
|
|
12351
|
+
* @param scriptElement - The `pc-script-instance` element holding the declared state.
|
|
12352
|
+
*/
|
|
12353
|
+
applyDeclaredState(script, scriptElement) {
|
|
11870
12354
|
this.applyAttributes(script, scriptElement.scriptAttributes, this.inlineKeys(scriptElement));
|
|
11871
12355
|
this.applyInlineAttributes(script, scriptElement);
|
|
11872
12356
|
script.enabled = scriptElement.enabled;
|
|
11873
|
-
scriptElement._onScriptCreated();
|
|
11874
|
-
return script;
|
|
11875
12357
|
}
|
|
11876
12358
|
/**
|
|
11877
|
-
* Applies the per-property attributes present on a `pc-script` element — any attribute that
|
|
12359
|
+
* Applies the per-property attributes present on a `pc-script-instance` element — any attribute that
|
|
11878
12360
|
* is not part of the element's own API or a reserved HTML attribute name. These are applied
|
|
11879
12361
|
* after the `attributes` JSON, so an individual attribute always takes precedence over the
|
|
11880
12362
|
* blob.
|
|
11881
12363
|
* @param script - The script to apply the attributes to.
|
|
11882
|
-
* @param scriptElement - The `pc-script` element holding the attributes.
|
|
12364
|
+
* @param scriptElement - The `pc-script-instance` element holding the attributes.
|
|
11883
12365
|
*/
|
|
11884
12366
|
applyInlineAttributes(script, scriptElement) {
|
|
11885
12367
|
const scriptName = scriptElement.getAttribute('name') ?? '';
|
|
@@ -11890,10 +12372,10 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11890
12372
|
}
|
|
11891
12373
|
}
|
|
11892
12374
|
/**
|
|
11893
|
-
* Applies a single per-property attribute change to the script of a `pc-script` element.
|
|
12375
|
+
* Applies a single per-property attribute change to the script of a `pc-script-instance` element.
|
|
11894
12376
|
* When the attribute has been removed, the value from the `attributes` JSON (if any) takes
|
|
11895
12377
|
* effect again.
|
|
11896
|
-
* @param scriptElement - The `pc-script` element whose attribute changed.
|
|
12378
|
+
* @param scriptElement - The `pc-script-instance` element whose attribute changed.
|
|
11897
12379
|
* @param attributeName - The name of the changed attribute.
|
|
11898
12380
|
*/
|
|
11899
12381
|
applyScriptProperty(scriptElement, attributeName) {
|
|
@@ -11929,7 +12411,7 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11929
12411
|
try {
|
|
11930
12412
|
const current = script[key];
|
|
11931
12413
|
if (typeof current === 'function' || SCRIPT_API_MEMBERS.has(key)) {
|
|
11932
|
-
console.warn(`Ignoring attribute '${attributeName}' on pc-script '${scriptName}' - '${key}' is part of the Script API.`);
|
|
12414
|
+
console.warn(`Ignoring attribute '${attributeName}' on pc-script-instance '${scriptName}' - '${key}' is part of the Script API.`);
|
|
11933
12415
|
return;
|
|
11934
12416
|
}
|
|
11935
12417
|
if (typeof current === 'string') {
|
|
@@ -11985,10 +12467,10 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11985
12467
|
}
|
|
11986
12468
|
handleMutations(mutations) {
|
|
11987
12469
|
for (const mutation of mutations) {
|
|
11988
|
-
// Handle per-property attribute changes on child pc-script elements
|
|
12470
|
+
// Handle per-property attribute changes on child pc-script-instance elements
|
|
11989
12471
|
if (mutation.type === 'attributes') {
|
|
11990
12472
|
const target = mutation.target;
|
|
11991
|
-
if (target instanceof
|
|
12473
|
+
if (target instanceof ScriptInstanceElement &&
|
|
11992
12474
|
target.parentElement === this &&
|
|
11993
12475
|
mutation.attributeName &&
|
|
11994
12476
|
!isReservedAttribute(mutation.attributeName)) {
|
|
@@ -11998,16 +12480,16 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
11998
12480
|
}
|
|
11999
12481
|
// Only direct children are managed - the observer watches the subtree for attribute
|
|
12000
12482
|
// changes, but deeper childList records must not create or destroy scripts
|
|
12001
|
-
// (matching initComponent's ':scope > pc-script' contract)
|
|
12483
|
+
// (matching initComponent's ':scope > pc-script-instance' contract)
|
|
12002
12484
|
if (mutation.target !== this) {
|
|
12003
12485
|
continue;
|
|
12004
12486
|
}
|
|
12005
|
-
// Handle removed nodes first, so that replacing a pc-script with a same-named one
|
|
12487
|
+
// Handle removed nodes first, so that replacing a pc-script-instance with a same-named one
|
|
12006
12488
|
// destroys the old script before the replacement is created. Only destroy a script
|
|
12007
12489
|
// this element actually owns - a duplicate-named element whose own create() failed
|
|
12008
12490
|
// must not take down the live script on removal.
|
|
12009
12491
|
mutation.removedNodes.forEach((node) => {
|
|
12010
|
-
if (node instanceof
|
|
12492
|
+
if (node instanceof ScriptInstanceElement) {
|
|
12011
12493
|
const scriptName = node.getAttribute('name');
|
|
12012
12494
|
if (scriptName &&
|
|
12013
12495
|
node._script &&
|
|
@@ -12020,7 +12502,7 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
12020
12502
|
});
|
|
12021
12503
|
// Handle added nodes
|
|
12022
12504
|
mutation.addedNodes.forEach((node) => {
|
|
12023
|
-
if (node instanceof
|
|
12505
|
+
if (node instanceof ScriptInstanceElement) {
|
|
12024
12506
|
this.createScript(node);
|
|
12025
12507
|
}
|
|
12026
12508
|
});
|
|
@@ -12038,14 +12520,20 @@ class ScriptComponentElement extends ComponentElement {
|
|
|
12038
12520
|
return super.component;
|
|
12039
12521
|
}
|
|
12040
12522
|
}
|
|
12041
|
-
customElements.define('pc-
|
|
12523
|
+
customElements.define('pc-script', ScriptComponentElement);
|
|
12042
12524
|
|
|
12043
12525
|
/**
|
|
12044
12526
|
* The SoundComponentElement interface provides properties and methods for manipulating
|
|
12045
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-
|
|
12527
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-sound/ | `<pc-sound>`} elements.
|
|
12046
12528
|
* The SoundComponentElement interface also inherits the properties and methods of the
|
|
12047
12529
|
* {@link HTMLElement} interface.
|
|
12048
12530
|
*
|
|
12531
|
+
* Engine component: {@link SoundComponent} (`sound`).
|
|
12532
|
+
*
|
|
12533
|
+
* @elementSummary The `<pc-sound>` element holds the `<pc-sound-slot>` children that play sounds at
|
|
12534
|
+
* its entity, along with the positional audio settings they share. Must be a child of a
|
|
12535
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
12536
|
+
*
|
|
12049
12537
|
* @category Components
|
|
12050
12538
|
*/
|
|
12051
12539
|
class SoundComponentElement extends ComponentElement {
|
|
@@ -12236,12 +12724,15 @@ class SoundComponentElement extends ComponentElement {
|
|
|
12236
12724
|
}
|
|
12237
12725
|
}
|
|
12238
12726
|
}
|
|
12239
|
-
customElements.define('pc-
|
|
12727
|
+
customElements.define('pc-sound', SoundComponentElement);
|
|
12240
12728
|
|
|
12241
12729
|
/**
|
|
12242
12730
|
* The SoundSlotElement interface provides properties and methods for manipulating
|
|
12243
|
-
* `<pc-sound>` elements. The SoundSlotElement interface also inherits the properties and
|
|
12731
|
+
* `<pc-sound-slot>` elements. The SoundSlotElement interface also inherits the properties and
|
|
12244
12732
|
* methods of the {@link AsyncElement} interface.
|
|
12733
|
+
*
|
|
12734
|
+
* @elementSummary The `<pc-sound-slot>` element declares one named sound on its parent `<pc-sound>`
|
|
12735
|
+
* — its asset, volume, pitch, looping and autoplay. Must be a direct child of `<pc-sound>`.
|
|
12245
12736
|
*/
|
|
12246
12737
|
class SoundSlotElement extends AsyncElement {
|
|
12247
12738
|
_asset = '';
|
|
@@ -12254,7 +12745,7 @@ class SoundSlotElement extends AsyncElement {
|
|
|
12254
12745
|
_startTime = 0;
|
|
12255
12746
|
_volume = 1;
|
|
12256
12747
|
/**
|
|
12257
|
-
* The `<pc-
|
|
12748
|
+
* The `<pc-sound>` this slot was added to, captured at connect time.
|
|
12258
12749
|
*
|
|
12259
12750
|
* `disconnectedCallback` cannot rediscover it: by the time the element is disconnected its
|
|
12260
12751
|
* `parentElement` is already `null`, so a lookup would both fail to find the component and
|
|
@@ -12317,7 +12808,7 @@ class SoundSlotElement extends AsyncElement {
|
|
|
12317
12808
|
get soundElement() {
|
|
12318
12809
|
const soundElement = this.parentElement;
|
|
12319
12810
|
if (!(soundElement instanceof SoundComponentElement)) {
|
|
12320
|
-
console.warn('pc-sound must be a direct child of a pc-
|
|
12811
|
+
console.warn('pc-sound-slot must be a direct child of a pc-sound element');
|
|
12321
12812
|
return null;
|
|
12322
12813
|
}
|
|
12323
12814
|
return soundElement;
|
|
@@ -12513,7 +13004,7 @@ class SoundSlotElement extends AsyncElement {
|
|
|
12513
13004
|
}
|
|
12514
13005
|
}
|
|
12515
13006
|
}
|
|
12516
|
-
customElements.define('pc-sound', SoundSlotElement);
|
|
13007
|
+
customElements.define('pc-sound-slot', SoundSlotElement);
|
|
12517
13008
|
|
|
12518
13009
|
/**
|
|
12519
13010
|
* The GSplatComponentElement interface provides properties and methods for manipulating
|
|
@@ -12521,6 +13012,12 @@ customElements.define('pc-sound', SoundSlotElement);
|
|
|
12521
13012
|
* The GSplatComponentElement interface also inherits the properties and methods of the
|
|
12522
13013
|
* {@link HTMLElement} interface.
|
|
12523
13014
|
*
|
|
13015
|
+
* Engine component: {@link GSplatComponent} (`gsplat`).
|
|
13016
|
+
*
|
|
13017
|
+
* @elementSummary The `<pc-gsplat>` element renders the 3D Gaussian splats of a `gsplat` asset at
|
|
13018
|
+
* its entity, with attributes for shadow casting and level of detail. Must be a child of a
|
|
13019
|
+
* `<pc-entity>`, `<pc-model>` or `<pc-node>`.
|
|
13020
|
+
*
|
|
12524
13021
|
* @category Components
|
|
12525
13022
|
*/
|
|
12526
13023
|
class GSplatComponentElement extends ComponentElement {
|
|
@@ -12816,6 +13313,11 @@ const levenshtein = (a, b) => {
|
|
|
12816
13313
|
* The pointer events below are dispatched by the containing `<pc-app>` element when the pointer
|
|
12817
13314
|
* intersects the bound node's geometry, exactly as for `<pc-entity>`.
|
|
12818
13315
|
*
|
|
13316
|
+
* @elementSummary The `<pc-node>` element binds to a node inside the hierarchy a `<pc-model>`
|
|
13317
|
+
* instantiated and declares overrides against it: a transform, an enabled state, tags, components
|
|
13318
|
+
* to add, or content to attach. Its `name` is a lookup, never a rename. Must be a descendant of
|
|
13319
|
+
* `<pc-model>`.
|
|
13320
|
+
*
|
|
12819
13321
|
* @attribute {string} name - The name of the node to bind, resolved within the nearest ancestor
|
|
12820
13322
|
* `pc-model` (or `pc-node`) once it has instantiated.
|
|
12821
13323
|
* @attribute {number} index - Which match to bind when `name` matches more than one node,
|
|
@@ -12942,7 +13444,10 @@ class NodeElement extends EntityBaseElement {
|
|
|
12942
13444
|
* is retained untouched — a redundant edit must not flicker overrides through a revert.
|
|
12943
13445
|
*/
|
|
12944
13446
|
_rebind() {
|
|
12945
|
-
|
|
13447
|
+
// A model fronts a host entity of its own; the names this element resolves are the
|
|
13448
|
+
// asset's, so the search starts at the instantiated content root, not the wrapper.
|
|
13449
|
+
const host = this._host;
|
|
13450
|
+
const hostEntity = (host instanceof ModelElement ? host.contentEntity : host?.entity) ?? null;
|
|
12946
13451
|
if (!hostEntity || !this._name) {
|
|
12947
13452
|
// Host not instantiated (or nothing to look up yet): return to pending. An assigned
|
|
12948
13453
|
// name arriving later, or the host's next cycle, resolves it.
|
|
@@ -13039,8 +13544,9 @@ class NodeElement extends EntityBaseElement {
|
|
|
13039
13544
|
}
|
|
13040
13545
|
this._revertOverrides();
|
|
13041
13546
|
// Attachment points anchor to the bound node, so they cannot outlive the binding. Each
|
|
13042
|
-
// destroyed entity resets its element, which the next _buildChildren re-creates
|
|
13043
|
-
|
|
13547
|
+
// destroyed entity resets its element, which the next _buildChildren re-creates - a
|
|
13548
|
+
// model host among them re-instantiates its content when it rebuilds.
|
|
13549
|
+
this.querySelectorAll('pc-entity, pc-model').forEach((child) => {
|
|
13044
13550
|
if (child.closestEntity === this) {
|
|
13045
13551
|
child.entity?.destroy();
|
|
13046
13552
|
}
|
|
@@ -13552,6 +14058,9 @@ customElements.define('pc-node', NodeElement);
|
|
|
13552
14058
|
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-scene/ | `<pc-scene>`} elements.
|
|
13553
14059
|
* The SceneElement interface also inherits the properties and methods of the
|
|
13554
14060
|
* {@link HTMLElement} interface.
|
|
14061
|
+
*
|
|
14062
|
+
* @elementSummary The `<pc-scene>` element holds the entity hierarchy the application renders,
|
|
14063
|
+
* along with the scene-wide fog and gravity settings. Must be a direct child of `<pc-app>`.
|
|
13555
14064
|
*/
|
|
13556
14065
|
class SceneElement extends AsyncElement {
|
|
13557
14066
|
/**
|
|
@@ -13775,6 +14284,10 @@ customElements.define('pc-scene', SceneElement);
|
|
|
13775
14284
|
* The SkyElement interface provides properties and methods for manipulating
|
|
13776
14285
|
* `<pc-sky>` elements. The SkyElement interface also inherits the properties and
|
|
13777
14286
|
* methods of the {@link HTMLElement} interface.
|
|
14287
|
+
*
|
|
14288
|
+
* @elementSummary The `<pc-sky>` element renders a skybox from a texture asset, projected as an
|
|
14289
|
+
* infinite background, a box or a dome, and optionally lights the scene from it. Must be a direct
|
|
14290
|
+
* child of `<pc-scene>`.
|
|
13778
14291
|
*/
|
|
13779
14292
|
class SkyElement extends AsyncElement {
|
|
13780
14293
|
_asset = '';
|
|
@@ -14071,6 +14584,7 @@ exports.AnimComponentElement = AnimComponentElement;
|
|
|
14071
14584
|
exports.AppElement = AppElement;
|
|
14072
14585
|
exports.AssetElement = AssetElement;
|
|
14073
14586
|
exports.AsyncElement = AsyncElement;
|
|
14587
|
+
exports.AudioListenerComponentElement = AudioListenerComponentElement;
|
|
14074
14588
|
exports.ButtonComponentElement = ButtonComponentElement;
|
|
14075
14589
|
exports.CameraComponentElement = CameraComponentElement;
|
|
14076
14590
|
exports.CollisionComponentElement = CollisionComponentElement;
|
|
@@ -14078,15 +14592,14 @@ exports.ComponentElement = ComponentElement;
|
|
|
14078
14592
|
exports.ElementComponentElement = ElementComponentElement;
|
|
14079
14593
|
exports.EntityBaseElement = EntityBaseElement;
|
|
14080
14594
|
exports.EntityElement = EntityElement;
|
|
14595
|
+
exports.EntityOwnerElement = EntityOwnerElement;
|
|
14081
14596
|
exports.GSplatComponentElement = GSplatComponentElement;
|
|
14082
14597
|
exports.JointComponentElement = JointComponentElement;
|
|
14083
14598
|
exports.LayoutChildComponentElement = LayoutChildComponentElement;
|
|
14084
14599
|
exports.LayoutGroupComponentElement = LayoutGroupComponentElement;
|
|
14085
14600
|
exports.LightComponentElement = LightComponentElement;
|
|
14086
|
-
exports.ListenerComponentElement = ListenerComponentElement;
|
|
14087
14601
|
exports.MaterialElement = MaterialElement;
|
|
14088
14602
|
exports.ModelElement = ModelElement;
|
|
14089
|
-
exports.ModuleElement = ModuleElement;
|
|
14090
14603
|
exports.NodeElement = NodeElement;
|
|
14091
14604
|
exports.ParticleSystemComponentElement = ParticleSystemComponentElement;
|
|
14092
14605
|
exports.RenderComponentElement = RenderComponentElement;
|
|
@@ -14094,11 +14607,12 @@ exports.RigidBodyComponentElement = RigidBodyComponentElement;
|
|
|
14094
14607
|
exports.SceneElement = SceneElement;
|
|
14095
14608
|
exports.ScreenComponentElement = ScreenComponentElement;
|
|
14096
14609
|
exports.ScriptComponentElement = ScriptComponentElement;
|
|
14097
|
-
exports.
|
|
14610
|
+
exports.ScriptInstanceElement = ScriptInstanceElement;
|
|
14098
14611
|
exports.ScrollViewComponentElement = ScrollViewComponentElement;
|
|
14099
14612
|
exports.ScrollbarComponentElement = ScrollbarComponentElement;
|
|
14100
14613
|
exports.SkyElement = SkyElement;
|
|
14101
14614
|
exports.SoundComponentElement = SoundComponentElement;
|
|
14102
14615
|
exports.SoundSlotElement = SoundSlotElement;
|
|
14616
|
+
exports.WasmElement = WasmElement;
|
|
14103
14617
|
exports.whenReady = whenReady;
|
|
14104
14618
|
//# sourceMappingURL=pwc.cjs.map
|