@relu-interactives/spatial-ecs 0.4.5 → 0.5.1
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/dist/{System-ln4Q7Eot.d.cts → System-V_mv07le.d.cts} +2 -2
- package/dist/{System-ln4Q7Eot.d.ts → System-V_mv07le.d.ts} +2 -2
- package/dist/{XRHandPose-CxPv-LBo.d.cts → XRHandPose-CQTLGxFC.d.cts} +218 -2
- package/dist/{XRHandPose-BImIa4ZS.d.ts → XRHandPose-CU3vNFuS.d.ts} +218 -2
- package/dist/{chunk-4AK4I3QF.js → chunk-BUEKOSR5.js} +102 -3
- package/dist/chunk-BUEKOSR5.js.map +1 -0
- package/dist/{chunk-QIIWFP3V.js → chunk-Q52ADLF7.js} +1255 -18
- package/dist/chunk-Q52ADLF7.js.map +1 -0
- package/dist/{chunk-SGADE55G.js → chunk-RXBLOO5B.js} +249 -90
- package/dist/chunk-RXBLOO5B.js.map +1 -0
- package/dist/{chunk-4DWZK4X4.js → chunk-WJD2VKEH.js} +3 -3
- package/dist/chunk-WJD2VKEH.js.map +1 -0
- package/dist/components/index.cjs +99 -0
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +3 -3
- package/dist/components/index.d.ts +3 -3
- package/dist/components/index.js +1 -1
- package/dist/docs/guide/spatial-ui.md +165 -0
- package/dist/factories/index.cjs +372 -114
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +13 -3
- package/dist/factories/index.d.ts +13 -3
- package/dist/factories/index.js +3 -3
- package/dist/{index-CuGqxuk-.d.ts → index-C3ik3sA1.d.ts} +16 -3
- package/dist/{index-BphKHaV-.d.ts → index-D2Jt_JzH.d.ts} +156 -3
- package/dist/{index-CH7qMsQT.d.cts → index-DaG03vyN.d.cts} +156 -3
- package/dist/{index-CQsHUez3.d.cts → index-Dlr-7-4m.d.cts} +16 -3
- package/dist/index.cjs +1864 -360
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -9
- package/dist/index.d.ts +42 -9
- package/dist/index.js +10 -8
- package/dist/index.js.map +1 -1
- package/dist/systems/index.cjs +1346 -13
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +2 -2
- package/dist/systems/index.d.ts +2 -2
- package/dist/systems/index.js +3 -3
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/worldSnapshotUtils.d.cts +1 -1
- package/dist/worldSnapshotUtils.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-4AK4I3QF.js.map +0 -1
- package/dist/chunk-4DWZK4X4.js.map +0 -1
- package/dist/chunk-QIIWFP3V.js.map +0 -1
- package/dist/chunk-SGADE55G.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var THREE56 = require('three');
|
|
4
4
|
var SkeletonUtils_js = require('three/examples/jsm/utils/SkeletonUtils.js');
|
|
5
5
|
var RectAreaLightHelper_js = require('three/examples/jsm/helpers/RectAreaLightHelper.js');
|
|
6
6
|
var DRACOLoader_js = require('three/examples/jsm/loaders/DRACOLoader.js');
|
|
@@ -41,7 +41,7 @@ function _interopNamespace(e) {
|
|
|
41
41
|
return Object.freeze(n);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
var
|
|
44
|
+
var THREE56__namespace = /*#__PURE__*/_interopNamespace(THREE56);
|
|
45
45
|
|
|
46
46
|
var __defProp = Object.defineProperty;
|
|
47
47
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
@@ -605,14 +605,14 @@ var _AnimationComponent = class _AnimationComponent extends Component {
|
|
|
605
605
|
return;
|
|
606
606
|
}
|
|
607
607
|
this.importedClips = clips.map((entry) => {
|
|
608
|
-
if (entry instanceof
|
|
608
|
+
if (entry instanceof THREE56__namespace.AnimationClip) {
|
|
609
609
|
return { clip: entry, sourceUrl: null };
|
|
610
610
|
}
|
|
611
611
|
if (!entry || typeof entry !== "object") {
|
|
612
612
|
return null;
|
|
613
613
|
}
|
|
614
614
|
const candidate = entry;
|
|
615
|
-
if (!(candidate.clip instanceof
|
|
615
|
+
if (!(candidate.clip instanceof THREE56__namespace.AnimationClip)) {
|
|
616
616
|
return null;
|
|
617
617
|
}
|
|
618
618
|
return {
|
|
@@ -820,11 +820,11 @@ function normalizeDistanceModel(distanceModel) {
|
|
|
820
820
|
}
|
|
821
821
|
__name(normalizeDistanceModel, "normalizeDistanceModel");
|
|
822
822
|
function createConfiguredAudio(listener, options) {
|
|
823
|
-
const sound = options.positional ? new
|
|
823
|
+
const sound = options.positional ? new THREE56__namespace.PositionalAudio(listener) : new THREE56__namespace.Audio(listener);
|
|
824
824
|
sound.setLoop(options.loop);
|
|
825
825
|
sound.setVolume(options.volume);
|
|
826
826
|
sound.setPlaybackRate(options.pitch);
|
|
827
|
-
if (sound instanceof
|
|
827
|
+
if (sound instanceof THREE56__namespace.PositionalAudio) {
|
|
828
828
|
sound.setRefDistance(options.refDistance);
|
|
829
829
|
sound.setDistanceModel(normalizeDistanceModel(options.distanceModel));
|
|
830
830
|
sound.setRolloffFactor(options.rolloffFactor);
|
|
@@ -834,16 +834,16 @@ function createConfiguredAudio(listener, options) {
|
|
|
834
834
|
__name(createConfiguredAudio, "createConfiguredAudio");
|
|
835
835
|
function createAudioEditorHelper() {
|
|
836
836
|
if (typeof document === "undefined") {
|
|
837
|
-
const geometry = new
|
|
838
|
-
new
|
|
837
|
+
const geometry = new THREE56__namespace.EdgesGeometry(
|
|
838
|
+
new THREE56__namespace.OctahedronGeometry(0.22, 0)
|
|
839
839
|
);
|
|
840
|
-
const material2 = new
|
|
840
|
+
const material2 = new THREE56__namespace.LineBasicMaterial({
|
|
841
841
|
color: "#8bc8ff",
|
|
842
842
|
transparent: true,
|
|
843
843
|
opacity: 0.95,
|
|
844
844
|
depthTest: false
|
|
845
845
|
});
|
|
846
|
-
const fallback = new
|
|
846
|
+
const fallback = new THREE56__namespace.LineSegments(geometry, material2);
|
|
847
847
|
fallback.renderOrder = 10;
|
|
848
848
|
fallback.userData.ecsHelper = true;
|
|
849
849
|
fallback.visible = false;
|
|
@@ -855,7 +855,7 @@ function createAudioEditorHelper() {
|
|
|
855
855
|
canvas.height = size;
|
|
856
856
|
const ctx = canvas.getContext("2d");
|
|
857
857
|
if (!ctx) {
|
|
858
|
-
return new
|
|
858
|
+
return new THREE56__namespace.Object3D();
|
|
859
859
|
}
|
|
860
860
|
ctx.clearRect(0, 0, size, size);
|
|
861
861
|
ctx.fillStyle = "rgba(27, 35, 52, 0.9)";
|
|
@@ -886,14 +886,14 @@ function createAudioEditorHelper() {
|
|
|
886
886
|
ctx.beginPath();
|
|
887
887
|
ctx.arc(56, 48, 16, -0.8, 0.8);
|
|
888
888
|
ctx.stroke();
|
|
889
|
-
const texture = new
|
|
889
|
+
const texture = new THREE56__namespace.CanvasTexture(canvas);
|
|
890
890
|
texture.needsUpdate = true;
|
|
891
|
-
const material = new
|
|
891
|
+
const material = new THREE56__namespace.SpriteMaterial({
|
|
892
892
|
map: texture,
|
|
893
893
|
transparent: true,
|
|
894
894
|
depthTest: false
|
|
895
895
|
});
|
|
896
|
-
const helper = new
|
|
896
|
+
const helper = new THREE56__namespace.Sprite(material);
|
|
897
897
|
helper.scale.set(0.68, 0.68, 0.68);
|
|
898
898
|
helper.renderOrder = 10;
|
|
899
899
|
helper.userData.ecsHelper = true;
|
|
@@ -927,7 +927,7 @@ var DEFAULT_ORTHO_TOP = 5;
|
|
|
927
927
|
var DEFAULT_ORTHO_BOTTOM = -5;
|
|
928
928
|
var DEFAULT_ZOOM = 1;
|
|
929
929
|
function inferProjection(camera) {
|
|
930
|
-
if (camera instanceof
|
|
930
|
+
if (camera instanceof THREE56__namespace.OrthographicCamera) {
|
|
931
931
|
return "orthographic";
|
|
932
932
|
}
|
|
933
933
|
return "perspective";
|
|
@@ -948,7 +948,7 @@ function readCameraFar(camera) {
|
|
|
948
948
|
}
|
|
949
949
|
__name(readCameraFar, "readCameraFar");
|
|
950
950
|
function inferFov(camera) {
|
|
951
|
-
if (camera instanceof
|
|
951
|
+
if (camera instanceof THREE56__namespace.PerspectiveCamera && Number.isFinite(camera.fov)) {
|
|
952
952
|
return camera.fov;
|
|
953
953
|
}
|
|
954
954
|
return DEFAULT_FOV;
|
|
@@ -971,28 +971,28 @@ function inferFar(camera) {
|
|
|
971
971
|
}
|
|
972
972
|
__name(inferFar, "inferFar");
|
|
973
973
|
function inferOrthoLeft(camera) {
|
|
974
|
-
if (camera instanceof
|
|
974
|
+
if (camera instanceof THREE56__namespace.OrthographicCamera && Number.isFinite(camera.left)) {
|
|
975
975
|
return camera.left;
|
|
976
976
|
}
|
|
977
977
|
return DEFAULT_ORTHO_LEFT;
|
|
978
978
|
}
|
|
979
979
|
__name(inferOrthoLeft, "inferOrthoLeft");
|
|
980
980
|
function inferOrthoRight(camera) {
|
|
981
|
-
if (camera instanceof
|
|
981
|
+
if (camera instanceof THREE56__namespace.OrthographicCamera && Number.isFinite(camera.right)) {
|
|
982
982
|
return camera.right;
|
|
983
983
|
}
|
|
984
984
|
return DEFAULT_ORTHO_RIGHT;
|
|
985
985
|
}
|
|
986
986
|
__name(inferOrthoRight, "inferOrthoRight");
|
|
987
987
|
function inferOrthoTop(camera) {
|
|
988
|
-
if (camera instanceof
|
|
988
|
+
if (camera instanceof THREE56__namespace.OrthographicCamera && Number.isFinite(camera.top)) {
|
|
989
989
|
return camera.top;
|
|
990
990
|
}
|
|
991
991
|
return DEFAULT_ORTHO_TOP;
|
|
992
992
|
}
|
|
993
993
|
__name(inferOrthoTop, "inferOrthoTop");
|
|
994
994
|
function inferOrthoBottom(camera) {
|
|
995
|
-
if (camera instanceof
|
|
995
|
+
if (camera instanceof THREE56__namespace.OrthographicCamera && Number.isFinite(camera.bottom)) {
|
|
996
996
|
return camera.bottom;
|
|
997
997
|
}
|
|
998
998
|
return DEFAULT_ORTHO_BOTTOM;
|
|
@@ -1008,7 +1008,7 @@ __name(inferZoom, "inferZoom");
|
|
|
1008
1008
|
var _CameraComponent = class _CameraComponent extends Component {
|
|
1009
1009
|
constructor(payload = {}) {
|
|
1010
1010
|
super();
|
|
1011
|
-
this.camera = payload.camera ?? new
|
|
1011
|
+
this.camera = payload.camera ?? new THREE56__namespace.PerspectiveCamera();
|
|
1012
1012
|
this.type = payload.type ?? "3d";
|
|
1013
1013
|
this.isDefault = typeof payload.isDefault === "boolean" ? payload.isDefault : false;
|
|
1014
1014
|
this.projection = payload.projection ?? inferProjection(payload.camera);
|
|
@@ -1039,7 +1039,7 @@ var Object3DRef = _Object3DRef;
|
|
|
1039
1039
|
// core/factories/components/CameraFactory.ts
|
|
1040
1040
|
function createCameraComponent(world, entityId, payload = {}) {
|
|
1041
1041
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
1042
|
-
const objectCamera = object instanceof
|
|
1042
|
+
const objectCamera = object instanceof THREE56__namespace.Camera ? object : void 0;
|
|
1043
1043
|
const component = new CameraComponent({
|
|
1044
1044
|
...payload,
|
|
1045
1045
|
camera: payload.camera ?? objectCamera
|
|
@@ -1609,15 +1609,15 @@ function createValueState(light) {
|
|
|
1609
1609
|
castShadow: light.castShadow ?? false,
|
|
1610
1610
|
frustumCulling: light.frustumCulled
|
|
1611
1611
|
};
|
|
1612
|
-
if (light instanceof
|
|
1612
|
+
if (light instanceof THREE56__namespace.PointLight) {
|
|
1613
1613
|
base.distance = light.distance;
|
|
1614
1614
|
base.decay = light.decay;
|
|
1615
|
-
} else if (light instanceof
|
|
1615
|
+
} else if (light instanceof THREE56__namespace.SpotLight) {
|
|
1616
1616
|
base.distance = light.distance;
|
|
1617
1617
|
base.decay = light.decay;
|
|
1618
1618
|
base.angle = light.angle;
|
|
1619
1619
|
base.penumbra = light.penumbra;
|
|
1620
|
-
} else if (light instanceof
|
|
1620
|
+
} else if (light instanceof THREE56__namespace.RectAreaLight) {
|
|
1621
1621
|
base.width = light.width;
|
|
1622
1622
|
base.height = light.height;
|
|
1623
1623
|
}
|
|
@@ -1660,13 +1660,13 @@ function toHexColor2(value, fallback) {
|
|
|
1660
1660
|
}
|
|
1661
1661
|
__name(toHexColor2, "toHexColor");
|
|
1662
1662
|
function getMaterialType(material) {
|
|
1663
|
-
if (material instanceof
|
|
1663
|
+
if (material instanceof THREE56__namespace.MeshPhysicalMaterial) {
|
|
1664
1664
|
return "physical";
|
|
1665
1665
|
}
|
|
1666
|
-
if (material instanceof
|
|
1666
|
+
if (material instanceof THREE56__namespace.MeshPhongMaterial) {
|
|
1667
1667
|
return "phong";
|
|
1668
1668
|
}
|
|
1669
|
-
if (material instanceof
|
|
1669
|
+
if (material instanceof THREE56__namespace.MeshBasicMaterial) {
|
|
1670
1670
|
return "basic";
|
|
1671
1671
|
}
|
|
1672
1672
|
return "standard";
|
|
@@ -1701,8 +1701,8 @@ function createMaterialValue(material) {
|
|
|
1701
1701
|
opacity: typeof materialRecord.opacity === "number" ? materialRecord.opacity : 1,
|
|
1702
1702
|
emissive: toHexColor2(materialRecord.emissive, "#000000"),
|
|
1703
1703
|
emissiveIntensity: typeof materialRecord.emissiveIntensity === "number" ? materialRecord.emissiveIntensity : 0,
|
|
1704
|
-
side: typeof materialRecord.side === "number" ? materialRecord.side :
|
|
1705
|
-
blending: typeof materialRecord.blending === "number" ? materialRecord.blending :
|
|
1704
|
+
side: typeof materialRecord.side === "number" ? materialRecord.side : THREE56__namespace.FrontSide,
|
|
1705
|
+
blending: typeof materialRecord.blending === "number" ? materialRecord.blending : THREE56__namespace.NormalBlending,
|
|
1706
1706
|
depthTest: materialRecord.depthTest !== false,
|
|
1707
1707
|
depthWrite: materialRecord.depthWrite !== false,
|
|
1708
1708
|
wireframe: Boolean(materialRecord.wireframe),
|
|
@@ -1734,7 +1734,7 @@ function createMaterialValue(material) {
|
|
|
1734
1734
|
materialRecord.lightMap
|
|
1735
1735
|
),
|
|
1736
1736
|
envMap: textureImageSrc(materialRecord.envMap),
|
|
1737
|
-
textureFiltering: map?.magFilter ===
|
|
1737
|
+
textureFiltering: map?.magFilter === THREE56__namespace.NearestFilter ? "sharp" : "smooth",
|
|
1738
1738
|
useMipmaps: map?.generateMipmaps !== false
|
|
1739
1739
|
};
|
|
1740
1740
|
}
|
|
@@ -1749,8 +1749,8 @@ function defaultMaterialValue() {
|
|
|
1749
1749
|
opacity: 1,
|
|
1750
1750
|
emissive: "#000000",
|
|
1751
1751
|
emissiveIntensity: 0,
|
|
1752
|
-
side:
|
|
1753
|
-
blending:
|
|
1752
|
+
side: THREE56__namespace.FrontSide,
|
|
1753
|
+
blending: THREE56__namespace.NormalBlending,
|
|
1754
1754
|
depthTest: true,
|
|
1755
1755
|
depthWrite: true,
|
|
1756
1756
|
wireframe: false,
|
|
@@ -2327,14 +2327,14 @@ var _TransformComponent = class _TransformComponent extends Component {
|
|
|
2327
2327
|
z: scale.z ?? 1
|
|
2328
2328
|
};
|
|
2329
2329
|
}
|
|
2330
|
-
toPositionVector3(target = new
|
|
2330
|
+
toPositionVector3(target = new THREE56.Vector3()) {
|
|
2331
2331
|
return target.set(this.position.x, this.position.y, this.position.z);
|
|
2332
2332
|
}
|
|
2333
|
-
toRotationEuler(target = new
|
|
2333
|
+
toRotationEuler(target = new THREE56.Euler(), order = "XYZ") {
|
|
2334
2334
|
return target.set(this.rotation.x, this.rotation.y, this.rotation.z, order);
|
|
2335
2335
|
}
|
|
2336
|
-
toRotationQuaternion(target = new
|
|
2337
|
-
const euler = new
|
|
2336
|
+
toRotationQuaternion(target = new THREE56.Quaternion(), order = "XYZ") {
|
|
2337
|
+
const euler = new THREE56.Euler(
|
|
2338
2338
|
this.rotation.x,
|
|
2339
2339
|
this.rotation.y,
|
|
2340
2340
|
this.rotation.z,
|
|
@@ -2342,7 +2342,7 @@ var _TransformComponent = class _TransformComponent extends Component {
|
|
|
2342
2342
|
);
|
|
2343
2343
|
return target.setFromEuler(euler);
|
|
2344
2344
|
}
|
|
2345
|
-
toScaleVector3(target = new
|
|
2345
|
+
toScaleVector3(target = new THREE56.Vector3()) {
|
|
2346
2346
|
return target.set(this.scale.x, this.scale.y, this.scale.z);
|
|
2347
2347
|
}
|
|
2348
2348
|
setPosition(input) {
|
|
@@ -2360,8 +2360,8 @@ var _TransformComponent = class _TransformComponent extends Component {
|
|
|
2360
2360
|
return this;
|
|
2361
2361
|
}
|
|
2362
2362
|
setRotation(input, order = "XYZ") {
|
|
2363
|
-
if (input instanceof
|
|
2364
|
-
const euler = new
|
|
2363
|
+
if (input instanceof THREE56.Quaternion) {
|
|
2364
|
+
const euler = new THREE56.Euler().setFromQuaternion(input, order);
|
|
2365
2365
|
this.rotation.x = euler.x;
|
|
2366
2366
|
this.rotation.y = euler.y;
|
|
2367
2367
|
this.rotation.z = euler.z;
|
|
@@ -2978,6 +2978,140 @@ function createXRInteractorSideComponent(world, entityId, ...args) {
|
|
|
2978
2978
|
}
|
|
2979
2979
|
__name(createXRInteractorSideComponent, "createXRInteractorSideComponent");
|
|
2980
2980
|
|
|
2981
|
+
// core/components/UIButton.ts
|
|
2982
|
+
var _UIButtonComponent = class _UIButtonComponent extends Component {
|
|
2983
|
+
constructor(options) {
|
|
2984
|
+
super();
|
|
2985
|
+
this.label = options?.label ?? "Button";
|
|
2986
|
+
this.actionId = options?.actionId ?? "";
|
|
2987
|
+
this.width = options?.width ?? 0.3;
|
|
2988
|
+
this.height = options?.height ?? 0.1;
|
|
2989
|
+
this.fontSize = options?.fontSize ?? 0.03;
|
|
2990
|
+
this.fontWeight = options?.fontWeight ?? 600;
|
|
2991
|
+
this.textColor = options?.textColor ?? "#ffffff";
|
|
2992
|
+
this.backgroundColor = options?.backgroundColor ?? "#2a2a2a";
|
|
2993
|
+
this.backgroundOpacity = options?.backgroundOpacity ?? 1;
|
|
2994
|
+
this.cornerRadius = options?.cornerRadius ?? 0.02;
|
|
2995
|
+
this.borderWidth = options?.borderWidth ?? 2e-3;
|
|
2996
|
+
this.borderColor = options?.borderColor ?? "#3a3a3a";
|
|
2997
|
+
}
|
|
2998
|
+
};
|
|
2999
|
+
__name(_UIButtonComponent, "UIButtonComponent");
|
|
3000
|
+
var UIButtonComponent = _UIButtonComponent;
|
|
3001
|
+
|
|
3002
|
+
// core/factories/components/UIButtonComponentFactory.ts
|
|
3003
|
+
function createUIButtonComponent(world, entityId, ...args) {
|
|
3004
|
+
const component = new UIButtonComponent(...args);
|
|
3005
|
+
world.addComponent(entityId, component);
|
|
3006
|
+
return component;
|
|
3007
|
+
}
|
|
3008
|
+
__name(createUIButtonComponent, "createUIButtonComponent");
|
|
3009
|
+
|
|
3010
|
+
// core/components/UIPanel.ts
|
|
3011
|
+
var _UIPanelComponent = class _UIPanelComponent extends Component {
|
|
3012
|
+
constructor(options) {
|
|
3013
|
+
super();
|
|
3014
|
+
this.width = options?.width ?? 0.6;
|
|
3015
|
+
this.height = options?.height ?? 0.4;
|
|
3016
|
+
this.backgroundColor = options?.backgroundColor ?? "#1c1c1c";
|
|
3017
|
+
this.backgroundOpacity = options?.backgroundOpacity ?? 0.92;
|
|
3018
|
+
this.cornerRadius = options?.cornerRadius ?? 0.02;
|
|
3019
|
+
this.borderWidth = options?.borderWidth ?? 0;
|
|
3020
|
+
this.borderColor = options?.borderColor ?? "#333333";
|
|
3021
|
+
this.pixelDensity = options?.pixelDensity ?? 1024;
|
|
3022
|
+
this.follow = options?.follow ?? "world";
|
|
3023
|
+
}
|
|
3024
|
+
};
|
|
3025
|
+
__name(_UIPanelComponent, "UIPanelComponent");
|
|
3026
|
+
var UIPanelComponent = _UIPanelComponent;
|
|
3027
|
+
|
|
3028
|
+
// core/factories/components/UIPanelComponentFactory.ts
|
|
3029
|
+
function createUIPanelComponent(world, entityId, ...args) {
|
|
3030
|
+
const component = new UIPanelComponent(...args);
|
|
3031
|
+
world.addComponent(entityId, component);
|
|
3032
|
+
return component;
|
|
3033
|
+
}
|
|
3034
|
+
__name(createUIPanelComponent, "createUIPanelComponent");
|
|
3035
|
+
|
|
3036
|
+
// core/components/UISlider.ts
|
|
3037
|
+
var _UISliderComponent = class _UISliderComponent extends Component {
|
|
3038
|
+
constructor(options) {
|
|
3039
|
+
super();
|
|
3040
|
+
this.min = options?.min ?? 0;
|
|
3041
|
+
this.max = options?.max ?? Math.max(1, this.min + 1);
|
|
3042
|
+
if (this.max <= this.min) this.max = this.min + 1;
|
|
3043
|
+
const v = options?.value ?? (this.min + this.max) / 2;
|
|
3044
|
+
this.value = Math.min(this.max, Math.max(this.min, v));
|
|
3045
|
+
this.actionId = options?.actionId ?? "";
|
|
3046
|
+
this.width = options?.width ?? 0.4;
|
|
3047
|
+
this.height = options?.height ?? 0.06;
|
|
3048
|
+
this.trackColor = options?.trackColor ?? "#2a2a2a";
|
|
3049
|
+
this.accentColor = options?.accentColor ?? "#ff6b35";
|
|
3050
|
+
this.knobColor = options?.knobColor ?? "#ffffff";
|
|
3051
|
+
}
|
|
3052
|
+
};
|
|
3053
|
+
__name(_UISliderComponent, "UISliderComponent");
|
|
3054
|
+
var UISliderComponent = _UISliderComponent;
|
|
3055
|
+
|
|
3056
|
+
// core/factories/components/UISliderComponentFactory.ts
|
|
3057
|
+
function createUISliderComponent(world, entityId, ...args) {
|
|
3058
|
+
const component = new UISliderComponent(...args);
|
|
3059
|
+
world.addComponent(entityId, component);
|
|
3060
|
+
return component;
|
|
3061
|
+
}
|
|
3062
|
+
__name(createUISliderComponent, "createUISliderComponent");
|
|
3063
|
+
|
|
3064
|
+
// core/components/UIText.ts
|
|
3065
|
+
var _UITextComponent = class _UITextComponent extends Component {
|
|
3066
|
+
constructor(options) {
|
|
3067
|
+
super();
|
|
3068
|
+
this.text = options?.text ?? "Text";
|
|
3069
|
+
this.width = options?.width ?? 0.5;
|
|
3070
|
+
this.height = options?.height ?? 0.12;
|
|
3071
|
+
this.fontSize = options?.fontSize ?? 0.035;
|
|
3072
|
+
this.fontWeight = options?.fontWeight ?? 500;
|
|
3073
|
+
this.color = options?.color ?? "#ffffff";
|
|
3074
|
+
this.align = options?.align ?? "center";
|
|
3075
|
+
this.valign = options?.valign ?? "middle";
|
|
3076
|
+
this.lineHeight = options?.lineHeight ?? 1.25;
|
|
3077
|
+
this.padding = options?.padding ?? 0.01;
|
|
3078
|
+
}
|
|
3079
|
+
};
|
|
3080
|
+
__name(_UITextComponent, "UITextComponent");
|
|
3081
|
+
var UITextComponent = _UITextComponent;
|
|
3082
|
+
|
|
3083
|
+
// core/factories/components/UITextComponentFactory.ts
|
|
3084
|
+
function createUITextComponent(world, entityId, ...args) {
|
|
3085
|
+
const component = new UITextComponent(...args);
|
|
3086
|
+
world.addComponent(entityId, component);
|
|
3087
|
+
return component;
|
|
3088
|
+
}
|
|
3089
|
+
__name(createUITextComponent, "createUITextComponent");
|
|
3090
|
+
|
|
3091
|
+
// core/components/UIToggle.ts
|
|
3092
|
+
var _UIToggleComponent = class _UIToggleComponent extends Component {
|
|
3093
|
+
constructor(options) {
|
|
3094
|
+
super();
|
|
3095
|
+
this.value = options?.value ?? false;
|
|
3096
|
+
this.actionId = options?.actionId ?? "";
|
|
3097
|
+
this.width = options?.width ?? 0.14;
|
|
3098
|
+
this.height = options?.height ?? 0.07;
|
|
3099
|
+
this.trackColor = options?.trackColor ?? "#2a2a2a";
|
|
3100
|
+
this.accentColor = options?.accentColor ?? "#ff6b35";
|
|
3101
|
+
this.knobColor = options?.knobColor ?? "#ffffff";
|
|
3102
|
+
}
|
|
3103
|
+
};
|
|
3104
|
+
__name(_UIToggleComponent, "UIToggleComponent");
|
|
3105
|
+
var UIToggleComponent = _UIToggleComponent;
|
|
3106
|
+
|
|
3107
|
+
// core/factories/components/UIToggleComponentFactory.ts
|
|
3108
|
+
function createUIToggleComponent(world, entityId, ...args) {
|
|
3109
|
+
const component = new UIToggleComponent(...args);
|
|
3110
|
+
world.addComponent(entityId, component);
|
|
3111
|
+
return component;
|
|
3112
|
+
}
|
|
3113
|
+
__name(createUIToggleComponent, "createUIToggleComponent");
|
|
3114
|
+
|
|
2981
3115
|
// core/factories/registerDefaultComponentFactories.ts
|
|
2982
3116
|
function registerDefaultComponentFactories(objectManagementSystem) {
|
|
2983
3117
|
objectManagementSystem.registerComponentFactory("animation", createAnimationComponent);
|
|
@@ -2991,6 +3125,11 @@ function registerDefaultComponentFactories(objectManagementSystem) {
|
|
|
2991
3125
|
objectManagementSystem.registerComponentFactory("vrTeleportArea", createVRTeleportAreaComponent);
|
|
2992
3126
|
objectManagementSystem.registerComponentFactory("xrHandPose", createXRHandPoseComponent);
|
|
2993
3127
|
objectManagementSystem.registerComponentFactory("xrAnchor", createXRAnchorComponent);
|
|
3128
|
+
objectManagementSystem.registerComponentFactory("uiPanel", createUIPanelComponent);
|
|
3129
|
+
objectManagementSystem.registerComponentFactory("uiText", createUITextComponent);
|
|
3130
|
+
objectManagementSystem.registerComponentFactory("uiButton", createUIButtonComponent);
|
|
3131
|
+
objectManagementSystem.registerComponentFactory("uiToggle", createUIToggleComponent);
|
|
3132
|
+
objectManagementSystem.registerComponentFactory("uiSlider", createUISliderComponent);
|
|
2994
3133
|
objectManagementSystem.registerComponentFactory("xrInteractable", createXRInteractableComponent);
|
|
2995
3134
|
objectManagementSystem.registerComponentFactory("xrInteractor", createXRInteractorComponent);
|
|
2996
3135
|
objectManagementSystem.registerComponentFactory("xrInteractorSide", createXRInteractorSideComponent);
|
|
@@ -3037,7 +3176,7 @@ var SHARED_MODEL_RESOURCE_FLAG = "spatialEcsSharedModelResource";
|
|
|
3037
3176
|
var modelCache = /* @__PURE__ */ new Map();
|
|
3038
3177
|
function markSharedResources(root) {
|
|
3039
3178
|
root.traverse((child) => {
|
|
3040
|
-
if (!(child instanceof
|
|
3179
|
+
if (!(child instanceof THREE56__namespace.Mesh)) {
|
|
3041
3180
|
return;
|
|
3042
3181
|
}
|
|
3043
3182
|
if (child.geometry) {
|
|
@@ -3116,10 +3255,10 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
|
|
|
3116
3255
|
}
|
|
3117
3256
|
getOrCreateAudioListener() {
|
|
3118
3257
|
const existing = this.camera.userData.ecsAudioListener;
|
|
3119
|
-
if (existing instanceof
|
|
3258
|
+
if (existing instanceof THREE56__namespace.AudioListener) {
|
|
3120
3259
|
return existing;
|
|
3121
3260
|
}
|
|
3122
|
-
const listener = new
|
|
3261
|
+
const listener = new THREE56__namespace.AudioListener();
|
|
3123
3262
|
this.camera.add(listener);
|
|
3124
3263
|
this.camera.userData.ecsAudioListener = listener;
|
|
3125
3264
|
return listener;
|
|
@@ -3193,7 +3332,7 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
|
|
|
3193
3332
|
}
|
|
3194
3333
|
if (dispose && object3d) {
|
|
3195
3334
|
object3d.traverse((child) => {
|
|
3196
|
-
if (child instanceof
|
|
3335
|
+
if (child instanceof THREE56__namespace.Mesh) {
|
|
3197
3336
|
if (!child.geometry?.userData?.[SHARED_MODEL_RESOURCE_FLAG]) {
|
|
3198
3337
|
child.geometry?.dispose();
|
|
3199
3338
|
}
|
|
@@ -3330,10 +3469,10 @@ __name(createBaseEntity, "createBaseEntity");
|
|
|
3330
3469
|
// core/factories/objects/AudioFactory.ts
|
|
3331
3470
|
function getOrCreateListener(camera) {
|
|
3332
3471
|
const existing = camera.userData.ecsAudioListener;
|
|
3333
|
-
if (existing instanceof
|
|
3472
|
+
if (existing instanceof THREE56__namespace.AudioListener) {
|
|
3334
3473
|
return existing;
|
|
3335
3474
|
}
|
|
3336
|
-
const listener = new
|
|
3475
|
+
const listener = new THREE56__namespace.AudioListener();
|
|
3337
3476
|
camera.add(listener);
|
|
3338
3477
|
camera.userData.ecsAudioListener = listener;
|
|
3339
3478
|
return listener;
|
|
@@ -3346,7 +3485,7 @@ function createAudio({
|
|
|
3346
3485
|
payload,
|
|
3347
3486
|
isEditor
|
|
3348
3487
|
}) {
|
|
3349
|
-
const anchor = new
|
|
3488
|
+
const anchor = new THREE56__namespace.Object3D();
|
|
3350
3489
|
const entityId = createBaseEntity(world, anchor, {
|
|
3351
3490
|
label: payload.name ?? "Audio",
|
|
3352
3491
|
entityType: "audio",
|
|
@@ -3368,7 +3507,7 @@ function createAudio({
|
|
|
3368
3507
|
return entityId;
|
|
3369
3508
|
}
|
|
3370
3509
|
if (!isEditor) {
|
|
3371
|
-
const loader = new
|
|
3510
|
+
const loader = new THREE56__namespace.AudioLoader();
|
|
3372
3511
|
loader.load(
|
|
3373
3512
|
audio.path,
|
|
3374
3513
|
(buffer) => {
|
|
@@ -3443,7 +3582,7 @@ function applyCameraSettings(camera, options) {
|
|
|
3443
3582
|
const near = typeof options.near === "number" ? options.near : DEFAULT_NEAR2;
|
|
3444
3583
|
const far = typeof options.far === "number" ? options.far : DEFAULT_FAR2;
|
|
3445
3584
|
const projection = options.projection;
|
|
3446
|
-
if (camera instanceof
|
|
3585
|
+
if (camera instanceof THREE56__namespace.PerspectiveCamera) {
|
|
3447
3586
|
if (!projection || projection === "perspective") {
|
|
3448
3587
|
camera.fov = typeof options.fov === "number" ? options.fov : DEFAULT_FOV2;
|
|
3449
3588
|
}
|
|
@@ -3453,7 +3592,7 @@ function applyCameraSettings(camera, options) {
|
|
|
3453
3592
|
camera.updateProjectionMatrix();
|
|
3454
3593
|
return;
|
|
3455
3594
|
}
|
|
3456
|
-
if (camera instanceof
|
|
3595
|
+
if (camera instanceof THREE56__namespace.OrthographicCamera) {
|
|
3457
3596
|
camera.left = typeof options.left === "number" ? options.left : -DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
|
|
3458
3597
|
camera.right = typeof options.right === "number" ? options.right : DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
|
|
3459
3598
|
camera.top = typeof options.top === "number" ? options.top : DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
|
|
@@ -3474,7 +3613,7 @@ function createCameraObject(options) {
|
|
|
3474
3613
|
const bottom = options.bottom ?? -DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
|
|
3475
3614
|
const left = options.left ?? -DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
|
|
3476
3615
|
const right = options.right ?? DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
|
|
3477
|
-
const camera = new
|
|
3616
|
+
const camera = new THREE56__namespace.OrthographicCamera(
|
|
3478
3617
|
left,
|
|
3479
3618
|
right,
|
|
3480
3619
|
top,
|
|
@@ -3486,7 +3625,7 @@ function createCameraObject(options) {
|
|
|
3486
3625
|
camera.updateProjectionMatrix();
|
|
3487
3626
|
return camera;
|
|
3488
3627
|
}
|
|
3489
|
-
return new
|
|
3628
|
+
return new THREE56__namespace.PerspectiveCamera(
|
|
3490
3629
|
options.fov ?? DEFAULT_FOV2,
|
|
3491
3630
|
readViewportAspect(),
|
|
3492
3631
|
near,
|
|
@@ -3504,7 +3643,7 @@ function createCamera({ world, scene, camera, payload, isEditor }) {
|
|
|
3504
3643
|
transformInput: payload.transform
|
|
3505
3644
|
});
|
|
3506
3645
|
const objectRef = world.getComponent(entityId, Object3DRef);
|
|
3507
|
-
if (objectRef?.object instanceof
|
|
3646
|
+
if (objectRef?.object instanceof THREE56__namespace.Camera) {
|
|
3508
3647
|
objectRef.object.userData.entityId = entityId;
|
|
3509
3648
|
}
|
|
3510
3649
|
const componentOptions = {
|
|
@@ -3536,9 +3675,9 @@ function createCapsule({
|
|
|
3536
3675
|
scene,
|
|
3537
3676
|
payload
|
|
3538
3677
|
}) {
|
|
3539
|
-
const geometry = new
|
|
3540
|
-
const material = new
|
|
3541
|
-
const mesh = new
|
|
3678
|
+
const geometry = new THREE56__namespace.CapsuleGeometry(0.5, 1, 4, 8);
|
|
3679
|
+
const material = new THREE56__namespace.MeshStandardMaterial({ color: "#ffffff" });
|
|
3680
|
+
const mesh = new THREE56__namespace.Mesh(geometry, material);
|
|
3542
3681
|
const entityId = createBaseEntity(world, mesh, {
|
|
3543
3682
|
label: payload.name ?? "Capsule",
|
|
3544
3683
|
entityType: "capsule",
|
|
@@ -3558,9 +3697,9 @@ function createCapsule({
|
|
|
3558
3697
|
}
|
|
3559
3698
|
__name(createCapsule, "createCapsule");
|
|
3560
3699
|
function createCube({ world, scene, payload }) {
|
|
3561
|
-
const geometry = new
|
|
3562
|
-
const material = new
|
|
3563
|
-
const mesh = new
|
|
3700
|
+
const geometry = new THREE56__namespace.BoxGeometry(1, 1, 1);
|
|
3701
|
+
const material = new THREE56__namespace.MeshStandardMaterial({ color: "#ffffff" });
|
|
3702
|
+
const mesh = new THREE56__namespace.Mesh(geometry, material);
|
|
3564
3703
|
const entityId = createBaseEntity(world, mesh, {
|
|
3565
3704
|
label: payload.name ?? "Cube",
|
|
3566
3705
|
entityType: "cube",
|
|
@@ -3585,9 +3724,9 @@ function createCylinder({
|
|
|
3585
3724
|
scene,
|
|
3586
3725
|
payload
|
|
3587
3726
|
}) {
|
|
3588
|
-
const geometry = new
|
|
3589
|
-
const material = new
|
|
3590
|
-
const mesh = new
|
|
3727
|
+
const geometry = new THREE56__namespace.CylinderGeometry(0.5, 0.5, 1, 20);
|
|
3728
|
+
const material = new THREE56__namespace.MeshStandardMaterial({ color: "#ffffff" });
|
|
3729
|
+
const mesh = new THREE56__namespace.Mesh(geometry, material);
|
|
3591
3730
|
const entityId = createBaseEntity(world, mesh, {
|
|
3592
3731
|
label: payload.name ?? "Cylinder",
|
|
3593
3732
|
entityType: "cylinder",
|
|
@@ -3607,7 +3746,7 @@ function createCylinder({
|
|
|
3607
3746
|
}
|
|
3608
3747
|
__name(createCylinder, "createCylinder");
|
|
3609
3748
|
function createEmpty({ world, scene, payload, isEditor }) {
|
|
3610
|
-
const object = new
|
|
3749
|
+
const object = new THREE56__namespace.Group();
|
|
3611
3750
|
const entityId = createBaseEntity(world, object, {
|
|
3612
3751
|
label: payload.name ?? "Empty",
|
|
3613
3752
|
entityType: "empty",
|
|
@@ -3618,7 +3757,7 @@ function createEmpty({ world, scene, payload, isEditor }) {
|
|
|
3618
3757
|
}
|
|
3619
3758
|
__name(createEmpty, "createEmpty");
|
|
3620
3759
|
function createImage({ world, scene, payload }) {
|
|
3621
|
-
const anchor = new
|
|
3760
|
+
const anchor = new THREE56__namespace.Object3D();
|
|
3622
3761
|
const imagePath = payload.path ?? "";
|
|
3623
3762
|
const entityId = createBaseEntity(world, anchor, {
|
|
3624
3763
|
label: payload.name ?? "Image",
|
|
@@ -3631,7 +3770,7 @@ function createImage({ world, scene, payload }) {
|
|
|
3631
3770
|
if (!imagePath) {
|
|
3632
3771
|
return entityId;
|
|
3633
3772
|
}
|
|
3634
|
-
const loader = new
|
|
3773
|
+
const loader = new THREE56__namespace.TextureLoader();
|
|
3635
3774
|
loader.load(
|
|
3636
3775
|
imagePath,
|
|
3637
3776
|
(texture) => {
|
|
@@ -3639,13 +3778,13 @@ function createImage({ world, scene, payload }) {
|
|
|
3639
3778
|
texture.dispose();
|
|
3640
3779
|
return;
|
|
3641
3780
|
}
|
|
3642
|
-
const material = new
|
|
3781
|
+
const material = new THREE56__namespace.MeshBasicMaterial({
|
|
3643
3782
|
map: texture,
|
|
3644
3783
|
transparent: true,
|
|
3645
|
-
side:
|
|
3784
|
+
side: THREE56__namespace.DoubleSide
|
|
3646
3785
|
});
|
|
3647
|
-
const geometry = new
|
|
3648
|
-
const plane = new
|
|
3786
|
+
const geometry = new THREE56__namespace.PlaneGeometry(1, 1);
|
|
3787
|
+
const plane = new THREE56__namespace.Mesh(geometry, material);
|
|
3649
3788
|
plane.userData.entityId = entityId;
|
|
3650
3789
|
const textureImage = texture.image;
|
|
3651
3790
|
const width = textureImage?.width ?? 1;
|
|
@@ -3691,7 +3830,7 @@ function createImageTarget({
|
|
|
3691
3830
|
payload,
|
|
3692
3831
|
isEditor
|
|
3693
3832
|
}) {
|
|
3694
|
-
const anchor = new
|
|
3833
|
+
const anchor = new THREE56__namespace.Object3D();
|
|
3695
3834
|
const imagePath = payload.path ?? "";
|
|
3696
3835
|
const entityId = createBaseEntity(world, anchor, {
|
|
3697
3836
|
label: payload.name ?? "Image Target",
|
|
@@ -3708,7 +3847,7 @@ function createImageTarget({
|
|
|
3708
3847
|
if (!isEditor || !imagePath) {
|
|
3709
3848
|
return entityId;
|
|
3710
3849
|
}
|
|
3711
|
-
const loader = new
|
|
3850
|
+
const loader = new THREE56__namespace.TextureLoader();
|
|
3712
3851
|
loader.load(
|
|
3713
3852
|
imagePath,
|
|
3714
3853
|
(texture) => {
|
|
@@ -3716,13 +3855,13 @@ function createImageTarget({
|
|
|
3716
3855
|
texture.dispose();
|
|
3717
3856
|
return;
|
|
3718
3857
|
}
|
|
3719
|
-
const material = new
|
|
3858
|
+
const material = new THREE56__namespace.MeshBasicMaterial({
|
|
3720
3859
|
map: texture,
|
|
3721
3860
|
transparent: true,
|
|
3722
|
-
side:
|
|
3861
|
+
side: THREE56__namespace.DoubleSide
|
|
3723
3862
|
});
|
|
3724
|
-
const geometry = new
|
|
3725
|
-
const plane = new
|
|
3863
|
+
const geometry = new THREE56__namespace.PlaneGeometry(1, 1);
|
|
3864
|
+
const plane = new THREE56__namespace.Mesh(geometry, material);
|
|
3726
3865
|
plane.userData.entityId = entityId;
|
|
3727
3866
|
const textureImage = texture.image;
|
|
3728
3867
|
const width = textureImage?.width ?? 1;
|
|
@@ -3773,7 +3912,7 @@ function createInstancedMesh({
|
|
|
3773
3912
|
scene,
|
|
3774
3913
|
payload
|
|
3775
3914
|
}) {
|
|
3776
|
-
const anchor = new
|
|
3915
|
+
const anchor = new THREE56__namespace.Object3D();
|
|
3777
3916
|
const opts = payload.options ?? {};
|
|
3778
3917
|
const meshKind = isInstancedMeshKind(opts.meshKind) ? opts.meshKind : "cube";
|
|
3779
3918
|
const meshParameters = opts.meshParameters && typeof opts.meshParameters === "object" ? opts.meshParameters : void 0;
|
|
@@ -3844,7 +3983,7 @@ function createAmbientLight({
|
|
|
3844
3983
|
scene,
|
|
3845
3984
|
payload
|
|
3846
3985
|
}) {
|
|
3847
|
-
const light = new
|
|
3986
|
+
const light = new THREE56__namespace.AmbientLight("#ffffff", 0.6);
|
|
3848
3987
|
const entityId = createBaseEntity(world, light, {
|
|
3849
3988
|
label: payload.name ?? "Ambient Light",
|
|
3850
3989
|
entityType: "ambientLight",
|
|
@@ -3861,7 +4000,7 @@ function createAreaLight({
|
|
|
3861
4000
|
payload,
|
|
3862
4001
|
isEditor
|
|
3863
4002
|
}) {
|
|
3864
|
-
const light = new
|
|
4003
|
+
const light = new THREE56__namespace.RectAreaLight("#ffffff", 5, 4, 4);
|
|
3865
4004
|
light.lookAt(0, 0, 0);
|
|
3866
4005
|
const entityId = createBaseEntity(world, light, {
|
|
3867
4006
|
label: payload.name ?? "Area Light",
|
|
@@ -3890,7 +4029,7 @@ function createDirectionalLight({
|
|
|
3890
4029
|
payload,
|
|
3891
4030
|
isEditor
|
|
3892
4031
|
}) {
|
|
3893
|
-
const light = new
|
|
4032
|
+
const light = new THREE56__namespace.DirectionalLight("#ffffff", 1.5);
|
|
3894
4033
|
light.castShadow = true;
|
|
3895
4034
|
const entityId = createBaseEntity(world, light, {
|
|
3896
4035
|
label: payload.name ?? "Directional Light",
|
|
@@ -3901,7 +4040,7 @@ function createDirectionalLight({
|
|
|
3901
4040
|
});
|
|
3902
4041
|
createLightComponent(world, entityId, light);
|
|
3903
4042
|
if (isEditor) {
|
|
3904
|
-
const helper = new
|
|
4043
|
+
const helper = new THREE56__namespace.DirectionalLightHelper(light, 1.8, "#38bdf8");
|
|
3905
4044
|
helper.onBeforeRender = () => {
|
|
3906
4045
|
helper.update();
|
|
3907
4046
|
};
|
|
@@ -3919,7 +4058,7 @@ function createPointLight({
|
|
|
3919
4058
|
payload,
|
|
3920
4059
|
isEditor
|
|
3921
4060
|
}) {
|
|
3922
|
-
const light = new
|
|
4061
|
+
const light = new THREE56__namespace.PointLight("#ffffff", 1, 10);
|
|
3923
4062
|
const entityId = createBaseEntity(world, light, {
|
|
3924
4063
|
label: payload.name ?? "Point Light",
|
|
3925
4064
|
entityType: "pointLight",
|
|
@@ -3929,7 +4068,7 @@ function createPointLight({
|
|
|
3929
4068
|
});
|
|
3930
4069
|
createLightComponent(world, entityId, light);
|
|
3931
4070
|
if (isEditor) {
|
|
3932
|
-
const helper = new
|
|
4071
|
+
const helper = new THREE56__namespace.PointLightHelper(light, 0.35, "#fbbf24");
|
|
3933
4072
|
helper.onBeforeRender = () => {
|
|
3934
4073
|
helper.update();
|
|
3935
4074
|
};
|
|
@@ -3947,7 +4086,7 @@ function createSpotLight({
|
|
|
3947
4086
|
payload,
|
|
3948
4087
|
isEditor
|
|
3949
4088
|
}) {
|
|
3950
|
-
const light = new
|
|
4089
|
+
const light = new THREE56__namespace.SpotLight("#ffffff", 1, 20, Math.PI / 6, 0.1, 1);
|
|
3951
4090
|
const entityId = createBaseEntity(world, light, {
|
|
3952
4091
|
label: payload.name ?? "Spot Light",
|
|
3953
4092
|
entityType: "spotLight",
|
|
@@ -3957,7 +4096,7 @@ function createSpotLight({
|
|
|
3957
4096
|
});
|
|
3958
4097
|
createLightComponent(world, entityId, light);
|
|
3959
4098
|
if (isEditor) {
|
|
3960
|
-
const helper = new
|
|
4099
|
+
const helper = new THREE56__namespace.SpotLightHelper(light, "#f59e0b");
|
|
3961
4100
|
helper.onBeforeRender = () => {
|
|
3962
4101
|
helper.update();
|
|
3963
4102
|
};
|
|
@@ -4042,6 +4181,11 @@ __export(components_exports, {
|
|
|
4042
4181
|
SelectionTransformState: () => SelectionTransformState,
|
|
4043
4182
|
SpriteComponent: () => SpriteComponent,
|
|
4044
4183
|
TransformComponent: () => TransformComponent,
|
|
4184
|
+
UIButtonComponent: () => UIButtonComponent,
|
|
4185
|
+
UIPanelComponent: () => UIPanelComponent,
|
|
4186
|
+
UISliderComponent: () => UISliderComponent,
|
|
4187
|
+
UITextComponent: () => UITextComponent,
|
|
4188
|
+
UIToggleComponent: () => UIToggleComponent,
|
|
4045
4189
|
VRTeleportAreaComponent: () => VRTeleportAreaComponent,
|
|
4046
4190
|
VideoComponent: () => VideoComponent,
|
|
4047
4191
|
XRAnchorComponent: () => XRAnchorComponent,
|
|
@@ -4124,7 +4268,7 @@ function createModel({
|
|
|
4124
4268
|
payload,
|
|
4125
4269
|
isEditor
|
|
4126
4270
|
}) {
|
|
4127
|
-
const anchor = new
|
|
4271
|
+
const anchor = new THREE56__namespace.Object3D();
|
|
4128
4272
|
const modelPath = payload.path ?? "";
|
|
4129
4273
|
const entityId = createBaseEntity(world, anchor, {
|
|
4130
4274
|
label: payload.name ?? "Model",
|
|
@@ -4190,12 +4334,12 @@ function createModel({
|
|
|
4190
4334
|
}
|
|
4191
4335
|
__name(createModel, "createModel");
|
|
4192
4336
|
function createPlane({ world, scene, payload }) {
|
|
4193
|
-
const geometry = new
|
|
4194
|
-
const material = new
|
|
4337
|
+
const geometry = new THREE56__namespace.PlaneGeometry(100, 100);
|
|
4338
|
+
const material = new THREE56__namespace.MeshStandardMaterial({
|
|
4195
4339
|
color: "#ffffff",
|
|
4196
|
-
side:
|
|
4340
|
+
side: THREE56__namespace.DoubleSide
|
|
4197
4341
|
});
|
|
4198
|
-
const mesh = new
|
|
4342
|
+
const mesh = new THREE56__namespace.Mesh(geometry, material);
|
|
4199
4343
|
const entityId = createBaseEntity(
|
|
4200
4344
|
world,
|
|
4201
4345
|
mesh,
|
|
@@ -4231,7 +4375,7 @@ function createScriptObject({
|
|
|
4231
4375
|
scene,
|
|
4232
4376
|
payload
|
|
4233
4377
|
}) {
|
|
4234
|
-
const object = new
|
|
4378
|
+
const object = new THREE56__namespace.Group();
|
|
4235
4379
|
const entityId = createBaseEntity(world, object, {
|
|
4236
4380
|
label: payload.name ?? "Script Object",
|
|
4237
4381
|
entityType: "scriptObject",
|
|
@@ -4256,15 +4400,15 @@ function createTeleportArea({
|
|
|
4256
4400
|
const options = payload.options ?? {};
|
|
4257
4401
|
const width = typeof options.width === "number" ? options.width : 10;
|
|
4258
4402
|
const depth = typeof options.depth === "number" ? options.depth : 10;
|
|
4259
|
-
const geometry = new
|
|
4260
|
-
const material = new
|
|
4403
|
+
const geometry = new THREE56__namespace.PlaneGeometry(width, depth);
|
|
4404
|
+
const material = new THREE56__namespace.MeshBasicMaterial({
|
|
4261
4405
|
color: "#4da3ff",
|
|
4262
4406
|
transparent: true,
|
|
4263
4407
|
opacity: 0.18,
|
|
4264
|
-
side:
|
|
4408
|
+
side: THREE56__namespace.DoubleSide,
|
|
4265
4409
|
depthWrite: false
|
|
4266
4410
|
});
|
|
4267
|
-
const object = new
|
|
4411
|
+
const object = new THREE56__namespace.Mesh(geometry, material);
|
|
4268
4412
|
const entityId = createBaseEntity(world, object, {
|
|
4269
4413
|
label: payload.name ?? "Teleport Area",
|
|
4270
4414
|
entityType: "teleportArea",
|
|
@@ -4292,7 +4436,7 @@ function createXRInteractor({
|
|
|
4292
4436
|
scene,
|
|
4293
4437
|
payload
|
|
4294
4438
|
}) {
|
|
4295
|
-
const root = new
|
|
4439
|
+
const root = new THREE56__namespace.Group();
|
|
4296
4440
|
const options = payload.options ?? {};
|
|
4297
4441
|
const entityId = createBaseEntity(world, root, {
|
|
4298
4442
|
label: payload.name ?? "XR Interactor",
|
|
@@ -4305,7 +4449,7 @@ function createXRInteractor({
|
|
|
4305
4449
|
return entityId;
|
|
4306
4450
|
}
|
|
4307
4451
|
for (const side of ["left", "right"]) {
|
|
4308
|
-
const slot = new
|
|
4452
|
+
const slot = new THREE56__namespace.Group();
|
|
4309
4453
|
const label = side === "left" ? "Left Interactor" : "Right Interactor";
|
|
4310
4454
|
const slotEntityId = createBaseEntity(world, slot, {
|
|
4311
4455
|
label,
|
|
@@ -4318,12 +4462,121 @@ function createXRInteractor({
|
|
|
4318
4462
|
return entityId;
|
|
4319
4463
|
}
|
|
4320
4464
|
__name(createXRInteractor, "createXRInteractor");
|
|
4465
|
+
function createUIButton({
|
|
4466
|
+
world,
|
|
4467
|
+
scene,
|
|
4468
|
+
payload
|
|
4469
|
+
}) {
|
|
4470
|
+
const object = new THREE56__namespace.Group();
|
|
4471
|
+
const entityId = createBaseEntity(world, object, {
|
|
4472
|
+
label: payload.name ?? "UI Button",
|
|
4473
|
+
entityType: "uiButton",
|
|
4474
|
+
transformInput: payload.transform
|
|
4475
|
+
});
|
|
4476
|
+
const options = payload.options ?? {};
|
|
4477
|
+
world.addComponent(entityId, new UIButtonComponent(options));
|
|
4478
|
+
world.addComponent(
|
|
4479
|
+
entityId,
|
|
4480
|
+
new XRInteractableComponent({
|
|
4481
|
+
grabbable: false,
|
|
4482
|
+
pointable: true,
|
|
4483
|
+
hoverBehavior: "color"
|
|
4484
|
+
})
|
|
4485
|
+
);
|
|
4486
|
+
scene.add(object);
|
|
4487
|
+
return entityId;
|
|
4488
|
+
}
|
|
4489
|
+
__name(createUIButton, "createUIButton");
|
|
4490
|
+
function createUIPanel({
|
|
4491
|
+
world,
|
|
4492
|
+
scene,
|
|
4493
|
+
payload
|
|
4494
|
+
}) {
|
|
4495
|
+
const object = new THREE56__namespace.Group();
|
|
4496
|
+
const entityId = createBaseEntity(world, object, {
|
|
4497
|
+
label: payload.name ?? "UI Panel",
|
|
4498
|
+
entityType: "uiPanel",
|
|
4499
|
+
transformInput: payload.transform
|
|
4500
|
+
});
|
|
4501
|
+
const options = payload.options ?? {};
|
|
4502
|
+
world.addComponent(entityId, new UIPanelComponent(options));
|
|
4503
|
+
scene.add(object);
|
|
4504
|
+
return entityId;
|
|
4505
|
+
}
|
|
4506
|
+
__name(createUIPanel, "createUIPanel");
|
|
4507
|
+
function createUISlider({
|
|
4508
|
+
world,
|
|
4509
|
+
scene,
|
|
4510
|
+
payload
|
|
4511
|
+
}) {
|
|
4512
|
+
const object = new THREE56__namespace.Group();
|
|
4513
|
+
const entityId = createBaseEntity(world, object, {
|
|
4514
|
+
label: payload.name ?? "UI Slider",
|
|
4515
|
+
entityType: "uiSlider",
|
|
4516
|
+
transformInput: payload.transform
|
|
4517
|
+
});
|
|
4518
|
+
const options = payload.options ?? {};
|
|
4519
|
+
world.addComponent(entityId, new UISliderComponent(options));
|
|
4520
|
+
world.addComponent(
|
|
4521
|
+
entityId,
|
|
4522
|
+
new XRInteractableComponent({
|
|
4523
|
+
grabbable: false,
|
|
4524
|
+
pointable: true,
|
|
4525
|
+
hoverBehavior: "none"
|
|
4526
|
+
})
|
|
4527
|
+
);
|
|
4528
|
+
scene.add(object);
|
|
4529
|
+
return entityId;
|
|
4530
|
+
}
|
|
4531
|
+
__name(createUISlider, "createUISlider");
|
|
4532
|
+
function createUIText({
|
|
4533
|
+
world,
|
|
4534
|
+
scene,
|
|
4535
|
+
payload
|
|
4536
|
+
}) {
|
|
4537
|
+
const object = new THREE56__namespace.Group();
|
|
4538
|
+
const entityId = createBaseEntity(world, object, {
|
|
4539
|
+
label: payload.name ?? "UI Text",
|
|
4540
|
+
entityType: "uiText",
|
|
4541
|
+
transformInput: payload.transform
|
|
4542
|
+
});
|
|
4543
|
+
const options = payload.options ?? {};
|
|
4544
|
+
world.addComponent(entityId, new UITextComponent(options));
|
|
4545
|
+
scene.add(object);
|
|
4546
|
+
return entityId;
|
|
4547
|
+
}
|
|
4548
|
+
__name(createUIText, "createUIText");
|
|
4549
|
+
function createUIToggle({
|
|
4550
|
+
world,
|
|
4551
|
+
scene,
|
|
4552
|
+
payload
|
|
4553
|
+
}) {
|
|
4554
|
+
const object = new THREE56__namespace.Group();
|
|
4555
|
+
const entityId = createBaseEntity(world, object, {
|
|
4556
|
+
label: payload.name ?? "UI Toggle",
|
|
4557
|
+
entityType: "uiToggle",
|
|
4558
|
+
transformInput: payload.transform
|
|
4559
|
+
});
|
|
4560
|
+
const options = payload.options ?? {};
|
|
4561
|
+
world.addComponent(entityId, new UIToggleComponent(options));
|
|
4562
|
+
world.addComponent(
|
|
4563
|
+
entityId,
|
|
4564
|
+
new XRInteractableComponent({
|
|
4565
|
+
grabbable: false,
|
|
4566
|
+
pointable: true,
|
|
4567
|
+
hoverBehavior: "color"
|
|
4568
|
+
})
|
|
4569
|
+
);
|
|
4570
|
+
scene.add(object);
|
|
4571
|
+
return entityId;
|
|
4572
|
+
}
|
|
4573
|
+
__name(createUIToggle, "createUIToggle");
|
|
4321
4574
|
function createXRRig({
|
|
4322
4575
|
world,
|
|
4323
4576
|
scene,
|
|
4324
4577
|
payload
|
|
4325
4578
|
}) {
|
|
4326
|
-
const object = new
|
|
4579
|
+
const object = new THREE56__namespace.Group();
|
|
4327
4580
|
const entityId = createBaseEntity(world, object, {
|
|
4328
4581
|
label: payload.name ?? "XR Rig",
|
|
4329
4582
|
entityType: "xrRig",
|
|
@@ -4336,7 +4589,7 @@ function createXRRig({
|
|
|
4336
4589
|
}
|
|
4337
4590
|
__name(createXRRig, "createXRRig");
|
|
4338
4591
|
function createSprite({ world, scene, payload }) {
|
|
4339
|
-
const anchor = new
|
|
4592
|
+
const anchor = new THREE56__namespace.Object3D();
|
|
4340
4593
|
const imagePath = payload.path ?? "";
|
|
4341
4594
|
const entityId = createBaseEntity(world, anchor, {
|
|
4342
4595
|
label: payload.name ?? "Sprite",
|
|
@@ -4348,7 +4601,7 @@ function createSprite({ world, scene, payload }) {
|
|
|
4348
4601
|
if (!imagePath) {
|
|
4349
4602
|
return entityId;
|
|
4350
4603
|
}
|
|
4351
|
-
const loader = new
|
|
4604
|
+
const loader = new THREE56__namespace.TextureLoader();
|
|
4352
4605
|
loader.load(
|
|
4353
4606
|
imagePath,
|
|
4354
4607
|
(texture) => {
|
|
@@ -4356,11 +4609,11 @@ function createSprite({ world, scene, payload }) {
|
|
|
4356
4609
|
texture.dispose();
|
|
4357
4610
|
return;
|
|
4358
4611
|
}
|
|
4359
|
-
const material = new
|
|
4612
|
+
const material = new THREE56__namespace.SpriteMaterial({
|
|
4360
4613
|
map: texture,
|
|
4361
4614
|
transparent: true
|
|
4362
4615
|
});
|
|
4363
|
-
const sprite = new
|
|
4616
|
+
const sprite = new THREE56__namespace.Sprite(material);
|
|
4364
4617
|
sprite.userData.entityId = entityId;
|
|
4365
4618
|
const textureImage = texture.image;
|
|
4366
4619
|
spriteComponent.width = textureImage?.width ?? 1;
|
|
@@ -4378,9 +4631,9 @@ function createSprite({ world, scene, payload }) {
|
|
|
4378
4631
|
}
|
|
4379
4632
|
__name(createSprite, "createSprite");
|
|
4380
4633
|
function createSphere({ world, scene, payload }) {
|
|
4381
|
-
const geometry = new
|
|
4382
|
-
const material = new
|
|
4383
|
-
const mesh = new
|
|
4634
|
+
const geometry = new THREE56__namespace.SphereGeometry(0.5, 24, 24);
|
|
4635
|
+
const material = new THREE56__namespace.MeshStandardMaterial({ color: "#ffffff" });
|
|
4636
|
+
const mesh = new THREE56__namespace.Mesh(geometry, material);
|
|
4384
4637
|
const entityId = createBaseEntity(world, mesh, {
|
|
4385
4638
|
label: payload.name ?? "Sphere",
|
|
4386
4639
|
entityType: "sphere",
|
|
@@ -4400,10 +4653,10 @@ function createSphere({ world, scene, payload }) {
|
|
|
4400
4653
|
__name(createSphere, "createSphere");
|
|
4401
4654
|
function getOrCreateListener2(camera) {
|
|
4402
4655
|
const existing = camera.userData.ecsAudioListener;
|
|
4403
|
-
if (existing instanceof
|
|
4656
|
+
if (existing instanceof THREE56__namespace.AudioListener) {
|
|
4404
4657
|
return existing;
|
|
4405
4658
|
}
|
|
4406
|
-
const listener = new
|
|
4659
|
+
const listener = new THREE56__namespace.AudioListener();
|
|
4407
4660
|
camera.add(listener);
|
|
4408
4661
|
camera.userData.ecsAudioListener = listener;
|
|
4409
4662
|
return listener;
|
|
@@ -4453,10 +4706,10 @@ function normalizeOptions(input) {
|
|
|
4453
4706
|
}
|
|
4454
4707
|
__name(normalizeOptions, "normalizeOptions");
|
|
4455
4708
|
function createChromaMaterial(texture, options) {
|
|
4456
|
-
return new
|
|
4709
|
+
return new THREE56__namespace.ShaderMaterial({
|
|
4457
4710
|
uniforms: {
|
|
4458
4711
|
tex: { value: texture },
|
|
4459
|
-
keyColor: { value: new
|
|
4712
|
+
keyColor: { value: new THREE56__namespace.Color(options.backgroundColor) },
|
|
4460
4713
|
similarity: { value: options.similarity },
|
|
4461
4714
|
smoothness: { value: options.smoothness },
|
|
4462
4715
|
spill: { value: options.spill }
|
|
@@ -4488,22 +4741,22 @@ function createChromaMaterial(texture, options) {
|
|
|
4488
4741
|
}
|
|
4489
4742
|
`,
|
|
4490
4743
|
transparent: true,
|
|
4491
|
-
side:
|
|
4744
|
+
side: THREE56__namespace.DoubleSide
|
|
4492
4745
|
});
|
|
4493
4746
|
}
|
|
4494
4747
|
__name(createChromaMaterial, "createChromaMaterial");
|
|
4495
4748
|
function createStandardMaterial(texture) {
|
|
4496
|
-
return new
|
|
4749
|
+
return new THREE56__namespace.MeshBasicMaterial({
|
|
4497
4750
|
map: texture,
|
|
4498
4751
|
transparent: true,
|
|
4499
|
-
side:
|
|
4752
|
+
side: THREE56__namespace.DoubleSide
|
|
4500
4753
|
});
|
|
4501
4754
|
}
|
|
4502
4755
|
__name(createStandardMaterial, "createStandardMaterial");
|
|
4503
4756
|
function createVideoMesh(entityId, texture, options) {
|
|
4504
|
-
const geometry = new
|
|
4757
|
+
const geometry = new THREE56__namespace.PlaneGeometry(1, 1);
|
|
4505
4758
|
const material = options.isGreenScreen ? createChromaMaterial(texture, options) : createStandardMaterial(texture);
|
|
4506
|
-
const mesh = new
|
|
4759
|
+
const mesh = new THREE56__namespace.Mesh(geometry, material);
|
|
4507
4760
|
mesh.userData.entityId = entityId;
|
|
4508
4761
|
mesh.scale.set(options.width, options.height, 1);
|
|
4509
4762
|
return { mesh, material };
|
|
@@ -4538,7 +4791,7 @@ function createVideo({
|
|
|
4538
4791
|
payload,
|
|
4539
4792
|
isEditor
|
|
4540
4793
|
}) {
|
|
4541
|
-
const anchor = new
|
|
4794
|
+
const anchor = new THREE56__namespace.Object3D();
|
|
4542
4795
|
const path = payload.path ?? "";
|
|
4543
4796
|
const options = normalizeOptions(payload.options);
|
|
4544
4797
|
const entityId = createBaseEntity(world, anchor, {
|
|
@@ -4553,8 +4806,8 @@ function createVideo({
|
|
|
4553
4806
|
return entityId;
|
|
4554
4807
|
}
|
|
4555
4808
|
const video = createVideoElement(path, options);
|
|
4556
|
-
const texture = new
|
|
4557
|
-
texture.colorSpace =
|
|
4809
|
+
const texture = new THREE56__namespace.VideoTexture(video);
|
|
4810
|
+
texture.colorSpace = THREE56__namespace.SRGBColorSpace;
|
|
4558
4811
|
texture.needsUpdate = true;
|
|
4559
4812
|
const { mesh, material } = createVideoMesh(entityId, texture, options);
|
|
4560
4813
|
anchor.add(mesh);
|
|
@@ -4570,7 +4823,7 @@ function createVideo({
|
|
|
4570
4823
|
});
|
|
4571
4824
|
if (!isEditor && options.positional) {
|
|
4572
4825
|
const listener = getOrCreateListener2(camera);
|
|
4573
|
-
const audioNode = new
|
|
4826
|
+
const audioNode = new THREE56__namespace.PositionalAudio(listener);
|
|
4574
4827
|
audioNode.setVolume(options.volume);
|
|
4575
4828
|
audioNode.setRefDistance(options.refDistance);
|
|
4576
4829
|
audioNode.setDistanceModel(normalizeDistanceModel2(options.distanceModel));
|
|
@@ -4613,6 +4866,11 @@ function registerDefaultFactories(objectManagementSystem) {
|
|
|
4613
4866
|
objectManagementSystem.register("xrRig", createXRRig);
|
|
4614
4867
|
objectManagementSystem.register("xrInteractor", createXRInteractor);
|
|
4615
4868
|
objectManagementSystem.register("teleportArea", createTeleportArea);
|
|
4869
|
+
objectManagementSystem.register("uiPanel", createUIPanel);
|
|
4870
|
+
objectManagementSystem.register("uiText", createUIText);
|
|
4871
|
+
objectManagementSystem.register("uiButton", createUIButton);
|
|
4872
|
+
objectManagementSystem.register("uiToggle", createUIToggle);
|
|
4873
|
+
objectManagementSystem.register("uiSlider", createUISlider);
|
|
4616
4874
|
registerDefaultComponentFactories(objectManagementSystem);
|
|
4617
4875
|
}
|
|
4618
4876
|
__name(registerDefaultFactories, "registerDefaultFactories");
|
|
@@ -4763,6 +5021,11 @@ function buildComponentValueMaps(snapshot) {
|
|
|
4763
5021
|
"XRHandPoseComponent"
|
|
4764
5022
|
),
|
|
4765
5023
|
xrAnchorValues: readByComponent(snapshot.components, "XRAnchorComponent"),
|
|
5024
|
+
uiPanelValues: readByComponent(snapshot.components, "UIPanelComponent"),
|
|
5025
|
+
uiTextValues: readByComponent(snapshot.components, "UITextComponent"),
|
|
5026
|
+
uiButtonValues: readByComponent(snapshot.components, "UIButtonComponent"),
|
|
5027
|
+
uiToggleValues: readByComponent(snapshot.components, "UIToggleComponent"),
|
|
5028
|
+
uiSliderValues: readByComponent(snapshot.components, "UISliderComponent"),
|
|
4766
5029
|
xrInteractorSideValues: readByComponent(
|
|
4767
5030
|
snapshot.components,
|
|
4768
5031
|
"XRInteractorSideComponent"
|
|
@@ -5084,6 +5347,49 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
5084
5347
|
}
|
|
5085
5348
|
}
|
|
5086
5349
|
}
|
|
5350
|
+
{
|
|
5351
|
+
const restoreUi = /* @__PURE__ */ __name((map, Ctor, existing) => {
|
|
5352
|
+
const source = asRecord3(map.get(sourceEntityId));
|
|
5353
|
+
if (!source) return;
|
|
5354
|
+
let component = existing;
|
|
5355
|
+
if (!component) {
|
|
5356
|
+
component = new Ctor();
|
|
5357
|
+
world.addComponent(targetEntityId, component);
|
|
5358
|
+
}
|
|
5359
|
+
const target = component;
|
|
5360
|
+
for (const [key, value] of Object.entries(source)) {
|
|
5361
|
+
const current = target[key];
|
|
5362
|
+
if ((typeof value === "string" || typeof value === "number" || typeof value === "boolean") && typeof current === typeof value) {
|
|
5363
|
+
target[key] = value;
|
|
5364
|
+
}
|
|
5365
|
+
}
|
|
5366
|
+
}, "restoreUi");
|
|
5367
|
+
restoreUi(
|
|
5368
|
+
values.uiPanelValues,
|
|
5369
|
+
UIPanelComponent,
|
|
5370
|
+
world.getComponent(targetEntityId, UIPanelComponent)
|
|
5371
|
+
);
|
|
5372
|
+
restoreUi(
|
|
5373
|
+
values.uiTextValues,
|
|
5374
|
+
UITextComponent,
|
|
5375
|
+
world.getComponent(targetEntityId, UITextComponent)
|
|
5376
|
+
);
|
|
5377
|
+
restoreUi(
|
|
5378
|
+
values.uiButtonValues,
|
|
5379
|
+
UIButtonComponent,
|
|
5380
|
+
world.getComponent(targetEntityId, UIButtonComponent)
|
|
5381
|
+
);
|
|
5382
|
+
restoreUi(
|
|
5383
|
+
values.uiToggleValues,
|
|
5384
|
+
UIToggleComponent,
|
|
5385
|
+
world.getComponent(targetEntityId, UIToggleComponent)
|
|
5386
|
+
);
|
|
5387
|
+
restoreUi(
|
|
5388
|
+
values.uiSliderValues,
|
|
5389
|
+
UISliderComponent,
|
|
5390
|
+
world.getComponent(targetEntityId, UISliderComponent)
|
|
5391
|
+
);
|
|
5392
|
+
}
|
|
5087
5393
|
{
|
|
5088
5394
|
const sourceInteractor = asRecord3(
|
|
5089
5395
|
values.xrInteractorValues.get(sourceEntityId)
|
|
@@ -6841,7 +7147,7 @@ function transitionToClip(runtime, nextClipId, crossFadeDuration) {
|
|
|
6841
7147
|
}
|
|
6842
7148
|
__name(transitionToClip, "transitionToClip");
|
|
6843
7149
|
function applyActionState(action, component, paused, shouldLoop) {
|
|
6844
|
-
const loopMode = shouldLoop ?
|
|
7150
|
+
const loopMode = shouldLoop ? THREE56__namespace.LoopRepeat : THREE56__namespace.LoopOnce;
|
|
6845
7151
|
const repetitions = shouldLoop ? Infinity : 1;
|
|
6846
7152
|
action.setLoop(loopMode, repetitions);
|
|
6847
7153
|
action.clampWhenFinished = !shouldLoop;
|
|
@@ -7014,7 +7320,7 @@ var _AnimationSystem = class _AnimationSystem {
|
|
|
7014
7320
|
if (runtime) {
|
|
7015
7321
|
stopAllActions(runtime);
|
|
7016
7322
|
}
|
|
7017
|
-
const mixer = new
|
|
7323
|
+
const mixer = new THREE56__namespace.AnimationMixer(root);
|
|
7018
7324
|
const entries2 = readRuntimeClipEntries(animation);
|
|
7019
7325
|
const indexedActions = createActions(mixer, entries2);
|
|
7020
7326
|
runtime = {
|
|
@@ -7140,11 +7446,11 @@ function normalizeOrthoBounds(component) {
|
|
|
7140
7446
|
}
|
|
7141
7447
|
__name(normalizeOrthoBounds, "normalizeOrthoBounds");
|
|
7142
7448
|
function isPerspectiveCamera(camera) {
|
|
7143
|
-
return camera instanceof
|
|
7449
|
+
return camera instanceof THREE56__namespace.PerspectiveCamera;
|
|
7144
7450
|
}
|
|
7145
7451
|
__name(isPerspectiveCamera, "isPerspectiveCamera");
|
|
7146
7452
|
function isOrthographicCamera(camera) {
|
|
7147
|
-
return camera instanceof
|
|
7453
|
+
return camera instanceof THREE56__namespace.OrthographicCamera;
|
|
7148
7454
|
}
|
|
7149
7455
|
__name(isOrthographicCamera, "isOrthographicCamera");
|
|
7150
7456
|
function readWindowAspect() {
|
|
@@ -7198,7 +7504,7 @@ var _CameraSyncSystem = class _CameraSyncSystem {
|
|
|
7198
7504
|
continue;
|
|
7199
7505
|
}
|
|
7200
7506
|
const camera = objectRef.object;
|
|
7201
|
-
if (!(camera instanceof
|
|
7507
|
+
if (!(camera instanceof THREE56__namespace.Camera)) {
|
|
7202
7508
|
continue;
|
|
7203
7509
|
}
|
|
7204
7510
|
if (xrCamera !== null && camera === xrCamera) {
|
|
@@ -7265,7 +7571,7 @@ var MIN_DENSITY = 0;
|
|
|
7265
7571
|
function createGradientTexture(effect, colors) {
|
|
7266
7572
|
if (typeof document === "undefined") {
|
|
7267
7573
|
const pixel = new Uint8Array([30, 30, 30, 255]);
|
|
7268
|
-
const fallback = new
|
|
7574
|
+
const fallback = new THREE56__namespace.DataTexture(pixel, 1, 1, THREE56__namespace.RGBAFormat);
|
|
7269
7575
|
fallback.needsUpdate = true;
|
|
7270
7576
|
return fallback;
|
|
7271
7577
|
}
|
|
@@ -7274,7 +7580,7 @@ function createGradientTexture(effect, colors) {
|
|
|
7274
7580
|
canvas.height = 512;
|
|
7275
7581
|
const context = canvas.getContext("2d");
|
|
7276
7582
|
if (!context) {
|
|
7277
|
-
const fallback = new
|
|
7583
|
+
const fallback = new THREE56__namespace.CanvasTexture(canvas);
|
|
7278
7584
|
fallback.needsUpdate = true;
|
|
7279
7585
|
return fallback;
|
|
7280
7586
|
}
|
|
@@ -7302,15 +7608,15 @@ function createGradientTexture(effect, colors) {
|
|
|
7302
7608
|
context.fillRect(0, 0, 512, 512);
|
|
7303
7609
|
context.globalCompositeOperation = "source-over";
|
|
7304
7610
|
}
|
|
7305
|
-
const texture = new
|
|
7306
|
-
texture.colorSpace =
|
|
7611
|
+
const texture = new THREE56__namespace.CanvasTexture(canvas);
|
|
7612
|
+
texture.colorSpace = THREE56__namespace.SRGBColorSpace;
|
|
7307
7613
|
texture.needsUpdate = true;
|
|
7308
7614
|
return texture;
|
|
7309
7615
|
}
|
|
7310
7616
|
__name(createGradientTexture, "createGradientTexture");
|
|
7311
7617
|
var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
7312
7618
|
constructor(scene) {
|
|
7313
|
-
this.textureLoader = new
|
|
7619
|
+
this.textureLoader = new THREE56__namespace.TextureLoader();
|
|
7314
7620
|
this.signature = null;
|
|
7315
7621
|
this.activeTexture = null;
|
|
7316
7622
|
this.pendingImageUrl = null;
|
|
@@ -7335,7 +7641,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
7335
7641
|
if (skybox.type === "color") {
|
|
7336
7642
|
this.disposeActiveTexture();
|
|
7337
7643
|
this.pendingImageUrl = null;
|
|
7338
|
-
this.scene.background = new
|
|
7644
|
+
this.scene.background = new THREE56__namespace.Color(skybox.color || "#1e1e1e");
|
|
7339
7645
|
return;
|
|
7340
7646
|
}
|
|
7341
7647
|
if (skybox.type === "gradient") {
|
|
@@ -7369,7 +7675,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
7369
7675
|
texture.dispose();
|
|
7370
7676
|
return;
|
|
7371
7677
|
}
|
|
7372
|
-
texture.colorSpace =
|
|
7678
|
+
texture.colorSpace = THREE56__namespace.SRGBColorSpace;
|
|
7373
7679
|
this.activeTexture = texture;
|
|
7374
7680
|
this.scene.background = texture;
|
|
7375
7681
|
},
|
|
@@ -7388,16 +7694,16 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
7388
7694
|
this.scene.fog = null;
|
|
7389
7695
|
return;
|
|
7390
7696
|
}
|
|
7391
|
-
const fogColor = new
|
|
7697
|
+
const fogColor = new THREE56__namespace.Color(fog.color || "#1e1e1e");
|
|
7392
7698
|
if (fog.type === "linear") {
|
|
7393
7699
|
const near = Number.isFinite(fog.linear.near) ? fog.linear.near : 1;
|
|
7394
7700
|
const farCandidate = Number.isFinite(fog.linear.far) ? fog.linear.far : near + 10;
|
|
7395
7701
|
const far = Math.max(near + MIN_FOG_DELTA, farCandidate);
|
|
7396
|
-
this.scene.fog = new
|
|
7702
|
+
this.scene.fog = new THREE56__namespace.Fog(fogColor, near, far);
|
|
7397
7703
|
return;
|
|
7398
7704
|
}
|
|
7399
7705
|
const density = Number.isFinite(fog.exponential.density) ? Math.max(MIN_DENSITY, fog.exponential.density) : 2e-3;
|
|
7400
|
-
this.scene.fog = new
|
|
7706
|
+
this.scene.fog = new THREE56__namespace.FogExp2(fogColor, density);
|
|
7401
7707
|
}
|
|
7402
7708
|
update(world) {
|
|
7403
7709
|
const passthrough = world.isXrPassthrough();
|
|
@@ -7491,10 +7797,10 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
7491
7797
|
);
|
|
7492
7798
|
}
|
|
7493
7799
|
if (values.bloom.enabled) {
|
|
7494
|
-
const size = this.renderer.getSize(new
|
|
7800
|
+
const size = this.renderer.getSize(new THREE56__namespace.Vector2());
|
|
7495
7801
|
composer.addPass(
|
|
7496
7802
|
new UnrealBloomPass_js.UnrealBloomPass(
|
|
7497
|
-
new
|
|
7803
|
+
new THREE56__namespace.Vector2(size.width, size.height),
|
|
7498
7804
|
values.bloom.intensity,
|
|
7499
7805
|
values.bloom.radius,
|
|
7500
7806
|
values.bloom.threshold
|
|
@@ -7539,7 +7845,7 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
7539
7845
|
if (values.dotScreen.enabled) {
|
|
7540
7846
|
composer.addPass(
|
|
7541
7847
|
new DotScreenPass_js.DotScreenPass(
|
|
7542
|
-
new
|
|
7848
|
+
new THREE56__namespace.Vector2(0, 0),
|
|
7543
7849
|
values.dotScreen.angle ?? values.dotScreen.dotScreenAngle,
|
|
7544
7850
|
values.dotScreen.scale ?? values.dotScreen.dotScreenScale
|
|
7545
7851
|
)
|
|
@@ -7627,7 +7933,7 @@ function computeColliderState(colliderValues, object) {
|
|
|
7627
7933
|
if (!object) {
|
|
7628
7934
|
return colliderValues;
|
|
7629
7935
|
}
|
|
7630
|
-
const scale = new
|
|
7936
|
+
const scale = new THREE56__namespace.Vector3();
|
|
7631
7937
|
object.getWorldScale(scale);
|
|
7632
7938
|
return {
|
|
7633
7939
|
...colliderValues,
|
|
@@ -7678,8 +7984,8 @@ function createColliderDesc(RAPIER, values, triMeshData) {
|
|
|
7678
7984
|
values.offsetPosition.y,
|
|
7679
7985
|
values.offsetPosition.z
|
|
7680
7986
|
);
|
|
7681
|
-
const offsetQuaternion = new
|
|
7682
|
-
new
|
|
7987
|
+
const offsetQuaternion = new THREE56__namespace.Quaternion().setFromEuler(
|
|
7988
|
+
new THREE56__namespace.Euler(
|
|
7683
7989
|
values.offsetRotation.x,
|
|
7684
7990
|
values.offsetRotation.y,
|
|
7685
7991
|
values.offsetRotation.z
|
|
@@ -7694,17 +8000,17 @@ function collectTriMeshParts(object) {
|
|
|
7694
8000
|
return null;
|
|
7695
8001
|
}
|
|
7696
8002
|
object.updateWorldMatrix(true, true);
|
|
7697
|
-
const worldScale = new
|
|
8003
|
+
const worldScale = new THREE56__namespace.Vector3();
|
|
7698
8004
|
object.getWorldScale(worldScale);
|
|
7699
8005
|
const scale = {
|
|
7700
8006
|
x: Math.abs(worldScale.x) || 1,
|
|
7701
8007
|
y: Math.abs(worldScale.y) || 1,
|
|
7702
8008
|
z: Math.abs(worldScale.z) || 1
|
|
7703
8009
|
};
|
|
7704
|
-
const worldToObject = new
|
|
8010
|
+
const worldToObject = new THREE56__namespace.Matrix4().copy(object.matrixWorld).invert();
|
|
7705
8011
|
const parts = [];
|
|
7706
8012
|
object.traverse((child) => {
|
|
7707
|
-
if (!(child instanceof
|
|
8013
|
+
if (!(child instanceof THREE56__namespace.Mesh) || !child.geometry) {
|
|
7708
8014
|
return;
|
|
7709
8015
|
}
|
|
7710
8016
|
const geometry = child.geometry;
|
|
@@ -7721,7 +8027,7 @@ function collectTriMeshParts(object) {
|
|
|
7721
8027
|
if (indexCount < 3) {
|
|
7722
8028
|
return;
|
|
7723
8029
|
}
|
|
7724
|
-
const relativeMatrix = new
|
|
8030
|
+
const relativeMatrix = new THREE56__namespace.Matrix4().multiplyMatrices(
|
|
7725
8031
|
worldToObject,
|
|
7726
8032
|
child.matrixWorld
|
|
7727
8033
|
);
|
|
@@ -7762,7 +8068,7 @@ function createTriMeshData(collected) {
|
|
|
7762
8068
|
}
|
|
7763
8069
|
const vertices = new Float32Array(vertexTotal * 3);
|
|
7764
8070
|
const indices = new Uint32Array(indexTotal);
|
|
7765
|
-
const point = new
|
|
8071
|
+
const point = new THREE56__namespace.Vector3();
|
|
7766
8072
|
let vertexOffset = 0;
|
|
7767
8073
|
let indexOffset = 0;
|
|
7768
8074
|
for (const part of parts) {
|
|
@@ -7794,8 +8100,8 @@ function createTriMeshData(collected) {
|
|
|
7794
8100
|
}
|
|
7795
8101
|
__name(createTriMeshData, "createTriMeshData");
|
|
7796
8102
|
function syncBodyFromTransform(body, transform) {
|
|
7797
|
-
const quaternion = new
|
|
7798
|
-
new
|
|
8103
|
+
const quaternion = new THREE56__namespace.Quaternion().setFromEuler(
|
|
8104
|
+
new THREE56__namespace.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z)
|
|
7799
8105
|
);
|
|
7800
8106
|
body.setTranslation(
|
|
7801
8107
|
{
|
|
@@ -7822,8 +8128,8 @@ function syncTransformFromBody(transform, body) {
|
|
|
7822
8128
|
transform.position.x = position.x;
|
|
7823
8129
|
transform.position.y = position.y;
|
|
7824
8130
|
transform.position.z = position.z;
|
|
7825
|
-
const euler = new
|
|
7826
|
-
new
|
|
8131
|
+
const euler = new THREE56__namespace.Euler().setFromQuaternion(
|
|
8132
|
+
new THREE56__namespace.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w)
|
|
7827
8133
|
);
|
|
7828
8134
|
transform.rotation.x = euler.x;
|
|
7829
8135
|
transform.rotation.y = euler.y;
|
|
@@ -7936,8 +8242,8 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
|
|
|
7936
8242
|
transform.position.y,
|
|
7937
8243
|
transform.position.z
|
|
7938
8244
|
);
|
|
7939
|
-
const quaternion = new
|
|
7940
|
-
new
|
|
8245
|
+
const quaternion = new THREE56__namespace.Quaternion().setFromEuler(
|
|
8246
|
+
new THREE56__namespace.Euler(
|
|
7941
8247
|
transform.rotation.x,
|
|
7942
8248
|
transform.rotation.y,
|
|
7943
8249
|
transform.rotation.z
|
|
@@ -8535,7 +8841,7 @@ function applyLightValues(lightComponent) {
|
|
|
8535
8841
|
values.castShadow
|
|
8536
8842
|
);
|
|
8537
8843
|
}
|
|
8538
|
-
if (light instanceof
|
|
8844
|
+
if (light instanceof THREE56__namespace.PointLight) {
|
|
8539
8845
|
if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
|
|
8540
8846
|
light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
|
|
8541
8847
|
}
|
|
@@ -8543,7 +8849,7 @@ function applyLightValues(lightComponent) {
|
|
|
8543
8849
|
light.decay = Math.max(0, values.decay);
|
|
8544
8850
|
}
|
|
8545
8851
|
}
|
|
8546
|
-
if (light instanceof
|
|
8852
|
+
if (light instanceof THREE56__namespace.SpotLight) {
|
|
8547
8853
|
if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
|
|
8548
8854
|
light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
|
|
8549
8855
|
}
|
|
@@ -8557,7 +8863,7 @@ function applyLightValues(lightComponent) {
|
|
|
8557
8863
|
light.penumbra = Math.max(0, Math.min(1, values.penumbra));
|
|
8558
8864
|
}
|
|
8559
8865
|
}
|
|
8560
|
-
if (light instanceof
|
|
8866
|
+
if (light instanceof THREE56__namespace.RectAreaLight) {
|
|
8561
8867
|
if (typeof values.width === "number" && Number.isFinite(values.width)) {
|
|
8562
8868
|
light.width = Math.max(MIN_AREA_SIZE, values.width);
|
|
8563
8869
|
}
|
|
@@ -8618,15 +8924,15 @@ function resolveMaterialPropertyKey(key) {
|
|
|
8618
8924
|
__name(resolveMaterialPropertyKey, "resolveMaterialPropertyKey");
|
|
8619
8925
|
function createMaterialByType(type) {
|
|
8620
8926
|
if (type === "basic") {
|
|
8621
|
-
return new
|
|
8927
|
+
return new THREE56__namespace.MeshBasicMaterial();
|
|
8622
8928
|
}
|
|
8623
8929
|
if (type === "phong") {
|
|
8624
|
-
return new
|
|
8930
|
+
return new THREE56__namespace.MeshPhongMaterial();
|
|
8625
8931
|
}
|
|
8626
8932
|
if (type === "physical") {
|
|
8627
|
-
return new
|
|
8933
|
+
return new THREE56__namespace.MeshPhysicalMaterial();
|
|
8628
8934
|
}
|
|
8629
|
-
return new
|
|
8935
|
+
return new THREE56__namespace.MeshStandardMaterial();
|
|
8630
8936
|
}
|
|
8631
8937
|
__name(createMaterialByType, "createMaterialByType");
|
|
8632
8938
|
function replaceMaterialAcrossObject(object, previous, next) {
|
|
@@ -8685,12 +8991,12 @@ function applyTextureFiltering(material, filtering) {
|
|
|
8685
8991
|
const target = material;
|
|
8686
8992
|
for (const slot of materialTextureSlots) {
|
|
8687
8993
|
const texture = target[slot];
|
|
8688
|
-
if (!texture || !(texture instanceof
|
|
8994
|
+
if (!texture || !(texture instanceof THREE56__namespace.Texture)) {
|
|
8689
8995
|
continue;
|
|
8690
8996
|
}
|
|
8691
8997
|
const useMipmaps = texture.generateMipmaps !== false;
|
|
8692
|
-
texture.magFilter = sharp ?
|
|
8693
|
-
texture.minFilter = useMipmaps ? sharp ?
|
|
8998
|
+
texture.magFilter = sharp ? THREE56__namespace.NearestFilter : THREE56__namespace.LinearFilter;
|
|
8999
|
+
texture.minFilter = useMipmaps ? sharp ? THREE56__namespace.NearestMipmapNearestFilter : THREE56__namespace.LinearMipmapLinearFilter : sharp ? THREE56__namespace.NearestFilter : THREE56__namespace.LinearFilter;
|
|
8694
9000
|
texture.needsUpdate = true;
|
|
8695
9001
|
}
|
|
8696
9002
|
material.needsUpdate = true;
|
|
@@ -8700,12 +9006,12 @@ function setTextureMipmaps(material, enabled) {
|
|
|
8700
9006
|
const target = material;
|
|
8701
9007
|
for (const slot of materialTextureSlots) {
|
|
8702
9008
|
const texture = target[slot];
|
|
8703
|
-
if (!texture || !(texture instanceof
|
|
9009
|
+
if (!texture || !(texture instanceof THREE56__namespace.Texture)) {
|
|
8704
9010
|
continue;
|
|
8705
9011
|
}
|
|
8706
9012
|
texture.generateMipmaps = enabled;
|
|
8707
|
-
const sharp = texture.magFilter ===
|
|
8708
|
-
texture.minFilter = enabled ? sharp ?
|
|
9013
|
+
const sharp = texture.magFilter === THREE56__namespace.NearestFilter;
|
|
9014
|
+
texture.minFilter = enabled ? sharp ? THREE56__namespace.NearestMipmapNearestFilter : THREE56__namespace.LinearMipmapLinearFilter : sharp ? THREE56__namespace.NearestFilter : THREE56__namespace.LinearFilter;
|
|
8709
9015
|
texture.needsUpdate = true;
|
|
8710
9016
|
}
|
|
8711
9017
|
material.needsUpdate = true;
|
|
@@ -8716,7 +9022,7 @@ function assignMaterialTexture(material, rawKey, url, textureCache) {
|
|
|
8716
9022
|
const key = resolveMaterialPropertyKey(rawKey);
|
|
8717
9023
|
let texture = textureCache.get(url);
|
|
8718
9024
|
if (!texture) {
|
|
8719
|
-
texture = new
|
|
9025
|
+
texture = new THREE56__namespace.TextureLoader().load(url);
|
|
8720
9026
|
textureCache.set(url, texture);
|
|
8721
9027
|
}
|
|
8722
9028
|
target[key] = texture;
|
|
@@ -8754,7 +9060,7 @@ function applyMaterialState(material, value, textureCache) {
|
|
|
8754
9060
|
}
|
|
8755
9061
|
target.side = value.side;
|
|
8756
9062
|
target.blending = value.blending;
|
|
8757
|
-
target.premultipliedAlpha = value.blending ===
|
|
9063
|
+
target.premultipliedAlpha = value.blending === THREE56__namespace.MultiplyBlending || value.blending === THREE56__namespace.SubtractiveBlending;
|
|
8758
9064
|
target.depthTest = value.depthTest;
|
|
8759
9065
|
target.depthWrite = value.depthWrite;
|
|
8760
9066
|
target.wireframe = value.wireframe;
|
|
@@ -8915,12 +9221,12 @@ function resolvePrimaryMesh(object) {
|
|
|
8915
9221
|
if (!object) {
|
|
8916
9222
|
return null;
|
|
8917
9223
|
}
|
|
8918
|
-
if (object instanceof
|
|
9224
|
+
if (object instanceof THREE56__namespace.Mesh) {
|
|
8919
9225
|
return object;
|
|
8920
9226
|
}
|
|
8921
9227
|
let found = null;
|
|
8922
9228
|
object.traverse((child) => {
|
|
8923
|
-
if (!found && child instanceof
|
|
9229
|
+
if (!found && child instanceof THREE56__namespace.Mesh) {
|
|
8924
9230
|
found = child;
|
|
8925
9231
|
}
|
|
8926
9232
|
});
|
|
@@ -8941,22 +9247,22 @@ function applyGeometry(component) {
|
|
|
8941
9247
|
switch (component.kind) {
|
|
8942
9248
|
case "cube": {
|
|
8943
9249
|
const params = sanitized;
|
|
8944
|
-
nextGeometry = new
|
|
9250
|
+
nextGeometry = new THREE56__namespace.BoxGeometry(params.width, params.height, params.depth);
|
|
8945
9251
|
break;
|
|
8946
9252
|
}
|
|
8947
9253
|
case "plane": {
|
|
8948
9254
|
const params = sanitized;
|
|
8949
|
-
nextGeometry = new
|
|
9255
|
+
nextGeometry = new THREE56__namespace.PlaneGeometry(params.width, params.height);
|
|
8950
9256
|
break;
|
|
8951
9257
|
}
|
|
8952
9258
|
case "sphere": {
|
|
8953
9259
|
const params = sanitized;
|
|
8954
|
-
nextGeometry = new
|
|
9260
|
+
nextGeometry = new THREE56__namespace.SphereGeometry(params.radius, 24, 24);
|
|
8955
9261
|
break;
|
|
8956
9262
|
}
|
|
8957
9263
|
case "cylinder": {
|
|
8958
9264
|
const params = sanitized;
|
|
8959
|
-
nextGeometry = new
|
|
9265
|
+
nextGeometry = new THREE56__namespace.CylinderGeometry(
|
|
8960
9266
|
params.radius,
|
|
8961
9267
|
params.radius,
|
|
8962
9268
|
params.height,
|
|
@@ -8966,7 +9272,7 @@ function applyGeometry(component) {
|
|
|
8966
9272
|
}
|
|
8967
9273
|
case "capsule": {
|
|
8968
9274
|
const params = sanitized;
|
|
8969
|
-
nextGeometry = new
|
|
9275
|
+
nextGeometry = new THREE56__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
|
|
8970
9276
|
break;
|
|
8971
9277
|
}
|
|
8972
9278
|
default:
|
|
@@ -8982,7 +9288,7 @@ function applyShadowFlags(component) {
|
|
|
8982
9288
|
return;
|
|
8983
9289
|
}
|
|
8984
9290
|
component.object.traverse((child) => {
|
|
8985
|
-
if (child instanceof
|
|
9291
|
+
if (child instanceof THREE56__namespace.Mesh) {
|
|
8986
9292
|
child.castShadow = component.castShadow;
|
|
8987
9293
|
child.receiveShadow = component.receiveShadow;
|
|
8988
9294
|
}
|
|
@@ -9065,35 +9371,35 @@ function buildGeometry(component) {
|
|
|
9065
9371
|
switch (component.meshKind) {
|
|
9066
9372
|
case "cube": {
|
|
9067
9373
|
const params = p;
|
|
9068
|
-
return new
|
|
9374
|
+
return new THREE56__namespace.BoxGeometry(params.width, params.height, params.depth);
|
|
9069
9375
|
}
|
|
9070
9376
|
case "plane": {
|
|
9071
9377
|
const params = p;
|
|
9072
|
-
return new
|
|
9378
|
+
return new THREE56__namespace.PlaneGeometry(params.width, params.height);
|
|
9073
9379
|
}
|
|
9074
9380
|
case "sphere": {
|
|
9075
9381
|
const params = p;
|
|
9076
|
-
return new
|
|
9382
|
+
return new THREE56__namespace.SphereGeometry(params.radius, 24, 24);
|
|
9077
9383
|
}
|
|
9078
9384
|
case "cylinder": {
|
|
9079
9385
|
const params = p;
|
|
9080
|
-
return new
|
|
9386
|
+
return new THREE56__namespace.CylinderGeometry(params.radius, params.radius, params.height, 20);
|
|
9081
9387
|
}
|
|
9082
9388
|
case "capsule": {
|
|
9083
9389
|
const params = p;
|
|
9084
|
-
return new
|
|
9390
|
+
return new THREE56__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
|
|
9085
9391
|
}
|
|
9086
9392
|
default:
|
|
9087
|
-
return new
|
|
9393
|
+
return new THREE56__namespace.BoxGeometry(1, 1, 1);
|
|
9088
9394
|
}
|
|
9089
9395
|
}
|
|
9090
9396
|
__name(buildGeometry, "buildGeometry");
|
|
9091
|
-
var _position = new
|
|
9092
|
-
var _quaternion = new
|
|
9093
|
-
var _euler = new
|
|
9094
|
-
var _scale = new
|
|
9095
|
-
var _matrix = new
|
|
9096
|
-
var _modelMatrix = new
|
|
9397
|
+
var _position = new THREE56__namespace.Vector3();
|
|
9398
|
+
var _quaternion = new THREE56__namespace.Quaternion();
|
|
9399
|
+
var _euler = new THREE56__namespace.Euler();
|
|
9400
|
+
var _scale = new THREE56__namespace.Vector3();
|
|
9401
|
+
var _matrix = new THREE56__namespace.Matrix4();
|
|
9402
|
+
var _modelMatrix = new THREE56__namespace.Matrix4();
|
|
9097
9403
|
function instanceTransformFromComponent(transform, out) {
|
|
9098
9404
|
_position.set(transform.position.x, transform.position.y, transform.position.z);
|
|
9099
9405
|
_euler.set(transform.rotation.x, transform.rotation.y, transform.rotation.z, "XYZ");
|
|
@@ -9246,7 +9552,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
9246
9552
|
const sourceMaterial = Array.isArray(meshChild.material) ? meshChild.material.map((m) => m.clone()) : meshChild.material.clone();
|
|
9247
9553
|
meshChild.updateWorldMatrix(true, false);
|
|
9248
9554
|
const localMatrix = meshChild.matrixWorld.clone();
|
|
9249
|
-
const instancedMesh2 = new
|
|
9555
|
+
const instancedMesh2 = new THREE56__namespace.InstancedMesh(
|
|
9250
9556
|
geometry2,
|
|
9251
9557
|
Array.isArray(sourceMaterial) ? sourceMaterial : sourceMaterial,
|
|
9252
9558
|
count2
|
|
@@ -9271,7 +9577,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
9271
9577
|
this.loadingSignatures.delete(targetEntityId);
|
|
9272
9578
|
return;
|
|
9273
9579
|
}
|
|
9274
|
-
const group = new
|
|
9580
|
+
const group = new THREE56__namespace.Group();
|
|
9275
9581
|
for (const entry of entries) {
|
|
9276
9582
|
group.add(entry.instancedMesh);
|
|
9277
9583
|
}
|
|
@@ -9289,8 +9595,8 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
9289
9595
|
}
|
|
9290
9596
|
const count = instanceCount;
|
|
9291
9597
|
const geometry = buildGeometry(comp);
|
|
9292
|
-
const material = new
|
|
9293
|
-
const instancedMesh = new
|
|
9598
|
+
const material = new THREE56__namespace.MeshStandardMaterial({ color: "#ffffff" });
|
|
9599
|
+
const instancedMesh = new THREE56__namespace.InstancedMesh(geometry, material, count);
|
|
9294
9600
|
instancedMesh.castShadow = comp.castShadow;
|
|
9295
9601
|
instancedMesh.receiveShadow = comp.receiveShadow;
|
|
9296
9602
|
for (let i = 0; i < count; i++) {
|
|
@@ -9473,7 +9779,7 @@ var _Behaviour = class _Behaviour {
|
|
|
9473
9779
|
if (!this.threeRef) {
|
|
9474
9780
|
return null;
|
|
9475
9781
|
}
|
|
9476
|
-
const position = new
|
|
9782
|
+
const position = new THREE56__namespace.Vector3();
|
|
9477
9783
|
this.threeRef.object.getWorldPosition(position);
|
|
9478
9784
|
return position;
|
|
9479
9785
|
}
|
|
@@ -9485,7 +9791,7 @@ var _Behaviour = class _Behaviour {
|
|
|
9485
9791
|
if (!this.threeRef) {
|
|
9486
9792
|
return null;
|
|
9487
9793
|
}
|
|
9488
|
-
const target = new
|
|
9794
|
+
const target = new THREE56__namespace.Vector3();
|
|
9489
9795
|
this.threeRef.object.getWorldDirection(target);
|
|
9490
9796
|
return target;
|
|
9491
9797
|
}
|
|
@@ -9547,7 +9853,7 @@ var _Behaviour = class _Behaviour {
|
|
|
9547
9853
|
if (!this.threeRef) {
|
|
9548
9854
|
return;
|
|
9549
9855
|
}
|
|
9550
|
-
const rotation = new
|
|
9856
|
+
const rotation = new THREE56__namespace.Quaternion();
|
|
9551
9857
|
this.threeRef.object.getWorldQuaternion(rotation);
|
|
9552
9858
|
rotation.slerp(targetRotation, alpha);
|
|
9553
9859
|
this.transform.setRotation(rotation);
|
|
@@ -9564,7 +9870,7 @@ var _Behaviour = class _Behaviour {
|
|
|
9564
9870
|
return;
|
|
9565
9871
|
}
|
|
9566
9872
|
const clone3 = this.threeRef.object.clone();
|
|
9567
|
-
const rotation = new
|
|
9873
|
+
const rotation = new THREE56__namespace.Quaternion();
|
|
9568
9874
|
clone3.lookAt(targetPosition);
|
|
9569
9875
|
clone3.getWorldQuaternion(rotation);
|
|
9570
9876
|
this.transform.setRotation(rotation);
|
|
@@ -9729,6 +10035,23 @@ var _Behaviour = class _Behaviour {
|
|
|
9729
10035
|
/** Called when this entity is released. Optional XR hook. */
|
|
9730
10036
|
onRelease(input) {
|
|
9731
10037
|
}
|
|
10038
|
+
/** A UI button on this entity (or a descendant) was clicked. Clicks fire on
|
|
10039
|
+
* RELEASE while still pointing at the widget — sliding off cancels. */
|
|
10040
|
+
onUiPress(_event) {
|
|
10041
|
+
}
|
|
10042
|
+
/** A pointer began hovering a UI widget on this entity (or a descendant). */
|
|
10043
|
+
onUiHoverStart(_event) {
|
|
10044
|
+
}
|
|
10045
|
+
/** The pointer left the widget. */
|
|
10046
|
+
onUiHoverEnd(_event) {
|
|
10047
|
+
}
|
|
10048
|
+
/** A UI toggle flipped; `event.value` is the new boolean. */
|
|
10049
|
+
onUiToggle(_event) {
|
|
10050
|
+
}
|
|
10051
|
+
/** A UI slider moved; `event.value` is the new number. Fires on real value
|
|
10052
|
+
* changes during the drag and once more on release. */
|
|
10053
|
+
onUiChange(_event) {
|
|
10054
|
+
}
|
|
9732
10055
|
};
|
|
9733
10056
|
__name(_Behaviour, "Behaviour");
|
|
9734
10057
|
/**
|
|
@@ -9930,8 +10253,8 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
9930
10253
|
}, "onPointerUp");
|
|
9931
10254
|
this.moduleLoader = moduleLoader ?? defaultModuleLoader;
|
|
9932
10255
|
this.selectionCtx = selectionContext ?? null;
|
|
9933
|
-
this.raycaster = new
|
|
9934
|
-
this.ndcPointer = new
|
|
10256
|
+
this.raycaster = new THREE56__namespace.Raycaster();
|
|
10257
|
+
this.ndcPointer = new THREE56__namespace.Vector2();
|
|
9935
10258
|
if (this.selectionCtx) {
|
|
9936
10259
|
this.selectionCtx.domElement.addEventListener("pointerdown", this.onPointerDown);
|
|
9937
10260
|
this.selectionCtx.domElement.addEventListener("pointerup", this.onPointerUp);
|
|
@@ -10310,7 +10633,7 @@ function disposeBuiltObject(root) {
|
|
|
10310
10633
|
for (const mat of materials) {
|
|
10311
10634
|
if (mat.userData?.[SHARED_MODEL_RESOURCE_FLAG]) continue;
|
|
10312
10635
|
for (const value of Object.values(mat)) {
|
|
10313
|
-
if (value instanceof
|
|
10636
|
+
if (value instanceof THREE56__namespace.Texture) value.dispose();
|
|
10314
10637
|
}
|
|
10315
10638
|
mat.dispose?.();
|
|
10316
10639
|
}
|
|
@@ -10674,7 +10997,7 @@ var _AudioSystem = class _AudioSystem {
|
|
|
10674
10997
|
if (!prev || prev.volume !== opts.volume) {
|
|
10675
10998
|
sound.setVolume(opts.volume);
|
|
10676
10999
|
}
|
|
10677
|
-
if (opts.positional && sound instanceof
|
|
11000
|
+
if (opts.positional && sound instanceof THREE56__namespace.PositionalAudio) {
|
|
10678
11001
|
if (!prev || prev.refDistance !== opts.refDistance) {
|
|
10679
11002
|
sound.setRefDistance(opts.refDistance);
|
|
10680
11003
|
}
|
|
@@ -10800,7 +11123,7 @@ var _VideoSystem = class _VideoSystem {
|
|
|
10800
11123
|
component.object.scale.set(opts.width, opts.height, 1);
|
|
10801
11124
|
}
|
|
10802
11125
|
const material = component.material;
|
|
10803
|
-
if (material instanceof
|
|
11126
|
+
if (material instanceof THREE56__namespace.ShaderMaterial) {
|
|
10804
11127
|
if (!prev || prev.backgroundColor !== opts.backgroundColor) {
|
|
10805
11128
|
material.uniforms.keyColor.value.set(opts.backgroundColor);
|
|
10806
11129
|
}
|
|
@@ -10814,7 +11137,7 @@ var _VideoSystem = class _VideoSystem {
|
|
|
10814
11137
|
material.uniforms.spill.value = opts.spill;
|
|
10815
11138
|
}
|
|
10816
11139
|
}
|
|
10817
|
-
if (opts.positional && component.audioNode instanceof
|
|
11140
|
+
if (opts.positional && component.audioNode instanceof THREE56__namespace.PositionalAudio) {
|
|
10818
11141
|
const posAudio = component.audioNode;
|
|
10819
11142
|
if (!prev || prev.refDistance !== opts.refDistance) {
|
|
10820
11143
|
posAudio.setRefDistance(opts.refDistance);
|
|
@@ -10854,8 +11177,8 @@ function blankState(source) {
|
|
|
10854
11177
|
handedness: handednessOf(source),
|
|
10855
11178
|
kind: kindOf(source),
|
|
10856
11179
|
connected: true,
|
|
10857
|
-
rayOrigin: new
|
|
10858
|
-
rayDirection: new
|
|
11180
|
+
rayOrigin: new THREE56__namespace.Vector3(),
|
|
11181
|
+
rayDirection: new THREE56__namespace.Vector3(0, 0, -1),
|
|
10859
11182
|
gripPosition: null,
|
|
10860
11183
|
gripQuaternion: null,
|
|
10861
11184
|
select: false,
|
|
@@ -10881,7 +11204,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
10881
11204
|
}
|
|
10882
11205
|
if (spaces.length === 0) return null;
|
|
10883
11206
|
const target = existing ?? {};
|
|
10884
|
-
const matrix = new
|
|
11207
|
+
const matrix = new THREE56__namespace.Matrix4();
|
|
10885
11208
|
const buffer = spaces.length * 16 <= JOINT_MATRIX_BUFFER.length ? JOINT_MATRIX_BUFFER : new Float32Array(spaces.length * 16);
|
|
10886
11209
|
const fillPoses = frame.fillPoses;
|
|
10887
11210
|
if (typeof fillPoses === "function") {
|
|
@@ -10894,7 +11217,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
10894
11217
|
if (filled) {
|
|
10895
11218
|
for (let i = 0; i < names.length; i += 1) {
|
|
10896
11219
|
matrix.fromArray(buffer, i * 16).premultiply(rigMatrix);
|
|
10897
|
-
const vector = target[names[i]] ?? new
|
|
11220
|
+
const vector = target[names[i]] ?? new THREE56__namespace.Vector3();
|
|
10898
11221
|
vector.setFromMatrixPosition(matrix);
|
|
10899
11222
|
target[names[i]] = vector;
|
|
10900
11223
|
}
|
|
@@ -10912,7 +11235,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
10912
11235
|
continue;
|
|
10913
11236
|
}
|
|
10914
11237
|
matrix.fromArray(pose.transform.matrix).premultiply(rigMatrix);
|
|
10915
|
-
const vector = target[names[i]] ?? new
|
|
11238
|
+
const vector = target[names[i]] ?? new THREE56__namespace.Vector3();
|
|
10916
11239
|
vector.setFromMatrixPosition(matrix);
|
|
10917
11240
|
target[names[i]] = vector;
|
|
10918
11241
|
anyTracked = true;
|
|
@@ -10924,7 +11247,7 @@ var _XRInputSystem = class _XRInputSystem {
|
|
|
10924
11247
|
constructor() {
|
|
10925
11248
|
this.records = /* @__PURE__ */ new Map();
|
|
10926
11249
|
/** Reference-space → world matrix, rebuilt each frame from the XR rig. */
|
|
10927
|
-
this.referenceToWorld = new
|
|
11250
|
+
this.referenceToWorld = new THREE56__namespace.Matrix4();
|
|
10928
11251
|
this.session = null;
|
|
10929
11252
|
this.onSelectStart = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectStart"), "onSelectStart");
|
|
10930
11253
|
this.onSelectEnd = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectEnd"), "onSelectEnd");
|
|
@@ -11022,19 +11345,19 @@ var _XRInputSystem = class _XRInputSystem {
|
|
|
11022
11345
|
if (frame && referenceSpace && source.targetRaySpace) {
|
|
11023
11346
|
const pose = frame.getPose(source.targetRaySpace, referenceSpace);
|
|
11024
11347
|
if (pose) {
|
|
11025
|
-
const m = new
|
|
11348
|
+
const m = new THREE56__namespace.Matrix4().fromArray(pose.transform.matrix).premultiply(rigMatrix);
|
|
11026
11349
|
state.rayOrigin.setFromMatrixPosition(m);
|
|
11027
11350
|
state.rayDirection.set(0, 0, -1).applyQuaternion(
|
|
11028
|
-
new
|
|
11351
|
+
new THREE56__namespace.Quaternion().setFromRotationMatrix(m)
|
|
11029
11352
|
).normalize();
|
|
11030
11353
|
}
|
|
11031
11354
|
}
|
|
11032
11355
|
if (frame && referenceSpace && source.gripSpace) {
|
|
11033
11356
|
const gripPose = frame.getPose(source.gripSpace, referenceSpace);
|
|
11034
11357
|
if (gripPose) {
|
|
11035
|
-
const m = new
|
|
11036
|
-
state.gripPosition ?? (state.gripPosition = new
|
|
11037
|
-
state.gripQuaternion ?? (state.gripQuaternion = new
|
|
11358
|
+
const m = new THREE56__namespace.Matrix4().fromArray(gripPose.transform.matrix).premultiply(rigMatrix);
|
|
11359
|
+
state.gripPosition ?? (state.gripPosition = new THREE56__namespace.Vector3());
|
|
11360
|
+
state.gripQuaternion ?? (state.gripQuaternion = new THREE56__namespace.Quaternion());
|
|
11038
11361
|
state.gripPosition.setFromMatrixPosition(m);
|
|
11039
11362
|
state.gripQuaternion.setFromRotationMatrix(m);
|
|
11040
11363
|
}
|
|
@@ -11162,15 +11485,15 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
|
|
|
11162
11485
|
const fresh = this.samples.filter(
|
|
11163
11486
|
(sample) => now - sample.time <= MAX_SAMPLE_AGE_SECONDS
|
|
11164
11487
|
);
|
|
11165
|
-
if (fresh.length < 2) return new
|
|
11166
|
-
let best = new
|
|
11488
|
+
if (fresh.length < 2) return new THREE56__namespace.Vector3();
|
|
11489
|
+
let best = new THREE56__namespace.Vector3();
|
|
11167
11490
|
let bestSpeed = 0;
|
|
11168
11491
|
for (let i = 1; i < fresh.length; i += 1) {
|
|
11169
11492
|
const previous = fresh[i - 1];
|
|
11170
11493
|
const current = fresh[i];
|
|
11171
11494
|
const dt = current.time - previous.time;
|
|
11172
11495
|
if (dt <= 1e-5) continue;
|
|
11173
|
-
const velocity = new
|
|
11496
|
+
const velocity = new THREE56__namespace.Vector3().subVectors(current.position, previous.position).divideScalar(dt);
|
|
11174
11497
|
const speed = velocity.length();
|
|
11175
11498
|
if (speed > MAX_PLAUSIBLE_SPEED) continue;
|
|
11176
11499
|
if (speed > bestSpeed) {
|
|
@@ -11187,15 +11510,15 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
|
|
|
11187
11510
|
__name(_ThrowVelocityTracker, "ThrowVelocityTracker");
|
|
11188
11511
|
var ThrowVelocityTracker = _ThrowVelocityTracker;
|
|
11189
11512
|
function angularVelocityFrom(previous, current, deltaTime) {
|
|
11190
|
-
if (deltaTime <= 1e-5) return new
|
|
11513
|
+
if (deltaTime <= 1e-5) return new THREE56__namespace.Vector3();
|
|
11191
11514
|
const delta = current.clone().multiply(previous.clone().invert());
|
|
11192
11515
|
if (delta.w < 0) {
|
|
11193
11516
|
delta.set(-delta.x, -delta.y, -delta.z, -delta.w);
|
|
11194
11517
|
}
|
|
11195
|
-
const angle = 2 * Math.acos(
|
|
11518
|
+
const angle = 2 * Math.acos(THREE56__namespace.MathUtils.clamp(delta.w, -1, 1));
|
|
11196
11519
|
const sinHalf = Math.sqrt(Math.max(0, 1 - delta.w * delta.w));
|
|
11197
|
-
if (sinHalf < 1e-6 || angle < 1e-6) return new
|
|
11198
|
-
return new
|
|
11520
|
+
if (sinHalf < 1e-6 || angle < 1e-6) return new THREE56__namespace.Vector3();
|
|
11521
|
+
return new THREE56__namespace.Vector3(delta.x, delta.y, delta.z).divideScalar(sinHalf).multiplyScalar(angle / deltaTime);
|
|
11199
11522
|
}
|
|
11200
11523
|
__name(angularVelocityFrom, "angularVelocityFrom");
|
|
11201
11524
|
var MIN_HAND_SEPARATION = 0.06;
|
|
@@ -11203,7 +11526,7 @@ var MIN_ANCHOR_SEPARATION = 1e-3;
|
|
|
11203
11526
|
var SCALE_DEADZONE = 0.05;
|
|
11204
11527
|
function solveTwoHandTransform(primary, secondary, basis, options) {
|
|
11205
11528
|
const separation = primary.position.distanceTo(secondary.position);
|
|
11206
|
-
const anchorDelta = new
|
|
11529
|
+
const anchorDelta = new THREE56__namespace.Vector3().subVectors(
|
|
11207
11530
|
basis.secondaryLocal,
|
|
11208
11531
|
basis.primaryLocal
|
|
11209
11532
|
);
|
|
@@ -11227,8 +11550,8 @@ function solveTwoHandTransform(primary, secondary, basis, options) {
|
|
|
11227
11550
|
} else {
|
|
11228
11551
|
const axisLocal = anchorDelta.clone().normalize();
|
|
11229
11552
|
const currentAxis = axisLocal.clone().applyQuaternion(base).normalize();
|
|
11230
|
-
const desiredAxis = new
|
|
11231
|
-
const correction = new
|
|
11553
|
+
const desiredAxis = new THREE56__namespace.Vector3().subVectors(secondary.position, primary.position).normalize();
|
|
11554
|
+
const correction = new THREE56__namespace.Quaternion().setFromUnitVectors(
|
|
11232
11555
|
currentAxis,
|
|
11233
11556
|
desiredAxis
|
|
11234
11557
|
);
|
|
@@ -11243,11 +11566,11 @@ __name(solveTwoHandTransform, "solveTwoHandTransform");
|
|
|
11243
11566
|
// core/systems/XRInteractionSystem.ts
|
|
11244
11567
|
var RAYLESS_HOLD_DISTANCE = 0.5;
|
|
11245
11568
|
function quatFromEulerVec(r) {
|
|
11246
|
-
return new
|
|
11569
|
+
return new THREE56__namespace.Quaternion().setFromEuler(new THREE56__namespace.Euler(r.x, r.y, r.z));
|
|
11247
11570
|
}
|
|
11248
11571
|
__name(quatFromEulerVec, "quatFromEulerVec");
|
|
11249
11572
|
function writeEuler(target, q) {
|
|
11250
|
-
const euler = new
|
|
11573
|
+
const euler = new THREE56__namespace.Euler().setFromQuaternion(q);
|
|
11251
11574
|
target.x = euler.x;
|
|
11252
11575
|
target.y = euler.y;
|
|
11253
11576
|
target.z = euler.z;
|
|
@@ -11255,10 +11578,11 @@ function writeEuler(target, q) {
|
|
|
11255
11578
|
__name(writeEuler, "writeEuler");
|
|
11256
11579
|
var _XRInteractionSystem = class _XRInteractionSystem {
|
|
11257
11580
|
constructor(inputSystem) {
|
|
11258
|
-
this.raycaster = new
|
|
11581
|
+
this.raycaster = new THREE56__namespace.Raycaster();
|
|
11259
11582
|
this.grabs = /* @__PURE__ */ new Map();
|
|
11260
11583
|
this.hoveredEntityId = null;
|
|
11261
11584
|
/** Per-hand hover, with the hit distance so the ray can stop at the surface. */
|
|
11585
|
+
this.busyContributors = [];
|
|
11262
11586
|
this.hovers = /* @__PURE__ */ new Map();
|
|
11263
11587
|
/** Monotonic seconds, accumulated from deltaTime for velocity sampling. */
|
|
11264
11588
|
this.elapsed = 0;
|
|
@@ -11267,6 +11591,8 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11267
11591
|
update(world, deltaTime) {
|
|
11268
11592
|
if (!world.isXrPresenting()) {
|
|
11269
11593
|
this.releaseAll(world);
|
|
11594
|
+
this.hovers.clear();
|
|
11595
|
+
this.hoveredEntityId = null;
|
|
11270
11596
|
return;
|
|
11271
11597
|
}
|
|
11272
11598
|
this.elapsed += Math.max(0, deltaTime);
|
|
@@ -11363,7 +11689,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11363
11689
|
const hand = this.handPosition(input);
|
|
11364
11690
|
const handQuaternion = this.handQuaternion(input);
|
|
11365
11691
|
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
11366
|
-
record.offset = new
|
|
11692
|
+
record.offset = new THREE56__namespace.Vector3(
|
|
11367
11693
|
transform.position.x - hand.x,
|
|
11368
11694
|
transform.position.y - hand.y,
|
|
11369
11695
|
transform.position.z - hand.z
|
|
@@ -11395,7 +11721,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11395
11721
|
primary.record.twoHand = {
|
|
11396
11722
|
primaryLocal,
|
|
11397
11723
|
secondaryLocal,
|
|
11398
|
-
initialScale: new
|
|
11724
|
+
initialScale: new THREE56__namespace.Vector3(
|
|
11399
11725
|
transform.scale.x,
|
|
11400
11726
|
transform.scale.y,
|
|
11401
11727
|
transform.scale.z
|
|
@@ -11411,7 +11737,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11411
11737
|
/** World point → the object's UNSCALED local space. */
|
|
11412
11738
|
objectLocalPoint(transform, worldPoint) {
|
|
11413
11739
|
const local = worldPoint.clone().sub(
|
|
11414
|
-
new
|
|
11740
|
+
new THREE56__namespace.Vector3(
|
|
11415
11741
|
transform.position.x,
|
|
11416
11742
|
transform.position.y,
|
|
11417
11743
|
transform.position.z
|
|
@@ -11469,7 +11795,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11469
11795
|
);
|
|
11470
11796
|
if (!interactable2) continue;
|
|
11471
11797
|
if (interactable2.grabReach === "distance") continue;
|
|
11472
|
-
const position = new
|
|
11798
|
+
const position = new THREE56__namespace.Vector3();
|
|
11473
11799
|
entry.object.getWorldPosition(position);
|
|
11474
11800
|
const distance = position.distanceTo(hand);
|
|
11475
11801
|
if (distance <= interactable2.grabRadius && distance < nearestDistance) {
|
|
@@ -11541,13 +11867,13 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11541
11867
|
this.holdersOf(entityId).map((holder) => holder.record.attachPointId).filter((id) => id !== null)
|
|
11542
11868
|
);
|
|
11543
11869
|
const hand = this.handPosition(input);
|
|
11544
|
-
const objectPosition = new
|
|
11870
|
+
const objectPosition = new THREE56__namespace.Vector3(
|
|
11545
11871
|
transform.position.x,
|
|
11546
11872
|
transform.position.y,
|
|
11547
11873
|
transform.position.z
|
|
11548
11874
|
);
|
|
11549
11875
|
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
11550
|
-
const scale = new
|
|
11876
|
+
const scale = new THREE56__namespace.Vector3(
|
|
11551
11877
|
transform.scale.x,
|
|
11552
11878
|
transform.scale.y,
|
|
11553
11879
|
transform.scale.z
|
|
@@ -11558,7 +11884,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11558
11884
|
if (taken.has(point.id)) continue;
|
|
11559
11885
|
if (point.hand !== "any" && point.hand !== input.handedness) continue;
|
|
11560
11886
|
if (point.role !== "any" && point.role !== role) continue;
|
|
11561
|
-
const world3 = new
|
|
11887
|
+
const world3 = new THREE56__namespace.Vector3(
|
|
11562
11888
|
point.position.x,
|
|
11563
11889
|
point.position.y,
|
|
11564
11890
|
point.position.z
|
|
@@ -11581,21 +11907,21 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11581
11907
|
let offset;
|
|
11582
11908
|
let remoteDistance = 0;
|
|
11583
11909
|
if (remote) {
|
|
11584
|
-
const position = new
|
|
11910
|
+
const position = new THREE56__namespace.Vector3(
|
|
11585
11911
|
transform.position.x,
|
|
11586
11912
|
transform.position.y,
|
|
11587
11913
|
transform.position.z
|
|
11588
11914
|
);
|
|
11589
11915
|
remoteDistance = position.distanceTo(input.rayOrigin);
|
|
11590
|
-
offset = new
|
|
11916
|
+
offset = new THREE56__namespace.Vector3();
|
|
11591
11917
|
} else if (viaDistance) {
|
|
11592
|
-
offset = new
|
|
11918
|
+
offset = new THREE56__namespace.Vector3(
|
|
11593
11919
|
interactable.grabOffsetPosition.x,
|
|
11594
11920
|
interactable.grabOffsetPosition.y,
|
|
11595
11921
|
interactable.grabOffsetPosition.z
|
|
11596
11922
|
);
|
|
11597
11923
|
} else {
|
|
11598
|
-
offset = new
|
|
11924
|
+
offset = new THREE56__namespace.Vector3(
|
|
11599
11925
|
transform.position.x - hand.x,
|
|
11600
11926
|
transform.position.y - hand.y,
|
|
11601
11927
|
transform.position.z - hand.z
|
|
@@ -11622,7 +11948,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11622
11948
|
entityId,
|
|
11623
11949
|
role,
|
|
11624
11950
|
attachPointId: attachPoint?.id ?? null,
|
|
11625
|
-
attachLocal: attachPoint ? new
|
|
11951
|
+
attachLocal: attachPoint ? new THREE56__namespace.Vector3(
|
|
11626
11952
|
attachPoint.position.x,
|
|
11627
11953
|
attachPoint.position.y,
|
|
11628
11954
|
attachPoint.position.z
|
|
@@ -11631,8 +11957,8 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11631
11957
|
handRotationOffset,
|
|
11632
11958
|
twoHand: null,
|
|
11633
11959
|
offset,
|
|
11634
|
-
rotationOffset: new
|
|
11635
|
-
new
|
|
11960
|
+
rotationOffset: new THREE56__namespace.Quaternion().setFromEuler(
|
|
11961
|
+
new THREE56__namespace.Euler(
|
|
11636
11962
|
interactable.grabOffsetRotation.x,
|
|
11637
11963
|
interactable.grabOffsetRotation.y,
|
|
11638
11964
|
interactable.grabOffsetRotation.z
|
|
@@ -11643,7 +11969,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11643
11969
|
restoreBodyType,
|
|
11644
11970
|
tracker,
|
|
11645
11971
|
lastHandQuaternion: handQuaternion.clone(),
|
|
11646
|
-
angularVelocity: new
|
|
11972
|
+
angularVelocity: new THREE56__namespace.Vector3()
|
|
11647
11973
|
});
|
|
11648
11974
|
if (role === "primary") {
|
|
11649
11975
|
this.dispatch(world, entityId, (b) => b.onGrab(input));
|
|
@@ -11716,14 +12042,14 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11716
12042
|
const handQuaternion = this.handQuaternion(input);
|
|
11717
12043
|
const objectQuaternion = held.attachQuaternion ? handQuaternion.clone().multiply(held.rotationOffset).multiply(held.attachQuaternion.clone().invert()) : handQuaternion.clone().multiply(held.handRotationOffset);
|
|
11718
12044
|
if (held.remote) {
|
|
11719
|
-
const target = new
|
|
12045
|
+
const target = new THREE56__namespace.Vector3().copy(input.rayDirection).multiplyScalar(held.remoteDistance).add(input.rayOrigin);
|
|
11720
12046
|
transform.position.x = target.x;
|
|
11721
12047
|
transform.position.y = target.y;
|
|
11722
12048
|
transform.position.z = target.z;
|
|
11723
12049
|
writeEuler(transform.rotation, objectQuaternion);
|
|
11724
12050
|
} else if (held.attachLocal) {
|
|
11725
12051
|
const anchor = held.attachLocal.clone().multiply(
|
|
11726
|
-
new
|
|
12052
|
+
new THREE56__namespace.Vector3(
|
|
11727
12053
|
transform.scale.x,
|
|
11728
12054
|
transform.scale.y,
|
|
11729
12055
|
transform.scale.z
|
|
@@ -11741,7 +12067,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11741
12067
|
writeEuler(transform.rotation, objectQuaternion);
|
|
11742
12068
|
}
|
|
11743
12069
|
held.tracker.record(
|
|
11744
|
-
held.remote ? new
|
|
12070
|
+
held.remote ? new THREE56__namespace.Vector3(
|
|
11745
12071
|
transform.position.x,
|
|
11746
12072
|
transform.position.y,
|
|
11747
12073
|
transform.position.z
|
|
@@ -11815,7 +12141,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11815
12141
|
*/
|
|
11816
12142
|
handPosition(input) {
|
|
11817
12143
|
if (input.gripPosition) return input.gripPosition;
|
|
11818
|
-
return new
|
|
12144
|
+
return new THREE56__namespace.Vector3().copy(input.rayDirection).multiplyScalar(RAYLESS_HOLD_DISTANCE).add(input.rayOrigin);
|
|
11819
12145
|
}
|
|
11820
12146
|
/**
|
|
11821
12147
|
* Hand orientation. Grip-less sources (gaze / transient-pointer) have none,
|
|
@@ -11823,8 +12149,8 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11823
12149
|
*/
|
|
11824
12150
|
handQuaternion(input) {
|
|
11825
12151
|
if (input.gripQuaternion) return input.gripQuaternion.clone();
|
|
11826
|
-
return new
|
|
11827
|
-
new
|
|
12152
|
+
return new THREE56__namespace.Quaternion().setFromUnitVectors(
|
|
12153
|
+
new THREE56__namespace.Vector3(0, 0, -1),
|
|
11828
12154
|
input.rayDirection.clone().normalize()
|
|
11829
12155
|
);
|
|
11830
12156
|
}
|
|
@@ -11889,13 +12215,30 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11889
12215
|
*/
|
|
11890
12216
|
isSourceBusy(world, input) {
|
|
11891
12217
|
if (this.grabs.has(input)) return true;
|
|
12218
|
+
for (const contributor of this.busyContributors) {
|
|
12219
|
+
try {
|
|
12220
|
+
if (contributor(world, input)) return true;
|
|
12221
|
+
} catch {
|
|
12222
|
+
}
|
|
12223
|
+
}
|
|
11892
12224
|
const hover = this.hovers.get(input);
|
|
11893
12225
|
if (!hover) return false;
|
|
11894
12226
|
const interactable = world.getComponent(
|
|
11895
12227
|
hover.entityId,
|
|
11896
12228
|
XRInteractableComponent
|
|
11897
12229
|
);
|
|
11898
|
-
return Boolean(
|
|
12230
|
+
return Boolean(
|
|
12231
|
+
interactable?.enabled && (interactable.grabbable || interactable.pointable)
|
|
12232
|
+
);
|
|
12233
|
+
}
|
|
12234
|
+
/** OR-ed into isSourceBusy; see the comment there. */
|
|
12235
|
+
registerBusyContributor(contributor) {
|
|
12236
|
+
this.busyContributors.push(contributor);
|
|
12237
|
+
}
|
|
12238
|
+
/** Hover for a specific input source (handedness-free — Vision Pro's
|
|
12239
|
+
* transient pointers all report handedness "none"). */
|
|
12240
|
+
getHoverForInput(input) {
|
|
12241
|
+
return this.hovers.get(input) ?? null;
|
|
11899
12242
|
}
|
|
11900
12243
|
/** True when THIS hand is holding something. */
|
|
11901
12244
|
isGrabbingWith(handedness) {
|
|
@@ -11944,7 +12287,7 @@ function sampleTeleportArc(origin, direction, out = [], options) {
|
|
|
11944
12287
|
for (let i = 0; i < steps; i += 1) {
|
|
11945
12288
|
const t = i / (steps - 1) * maxTime;
|
|
11946
12289
|
out.push(
|
|
11947
|
-
new
|
|
12290
|
+
new THREE56__namespace.Vector3(
|
|
11948
12291
|
origin.x + velocity.x * t,
|
|
11949
12292
|
origin.y + velocity.y * t - 0.5 * gravity * t * t,
|
|
11950
12293
|
origin.z + velocity.z * t
|
|
@@ -11961,7 +12304,7 @@ function arcGroundCrossing(points, groundY) {
|
|
|
11961
12304
|
if (previous.y >= groundY && current.y <= groundY) {
|
|
11962
12305
|
const span = previous.y - current.y;
|
|
11963
12306
|
const alpha = span > 1e-6 ? (previous.y - groundY) / span : 0;
|
|
11964
|
-
return new
|
|
12307
|
+
return new THREE56__namespace.Vector3().lerpVectors(previous, current, alpha);
|
|
11965
12308
|
}
|
|
11966
12309
|
}
|
|
11967
12310
|
return null;
|
|
@@ -12005,11 +12348,11 @@ __name(_TeleportAimGate, "TeleportAimGate");
|
|
|
12005
12348
|
var TeleportAimGate = _TeleportAimGate;
|
|
12006
12349
|
|
|
12007
12350
|
// core/systems/XRLocomotionSystem.ts
|
|
12008
|
-
var UP = new
|
|
12351
|
+
var UP = new THREE56__namespace.Vector3(0, 1, 0);
|
|
12009
12352
|
var AXIS_DEADZONE = 0.5;
|
|
12010
12353
|
var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
12011
12354
|
constructor(inputSystem) {
|
|
12012
|
-
this.raycaster = new
|
|
12355
|
+
this.raycaster = new THREE56__namespace.Raycaster();
|
|
12013
12356
|
/** Per-source latch so one stick push yields exactly one snap turn. */
|
|
12014
12357
|
this.turnLatched = /* @__PURE__ */ new WeakSet();
|
|
12015
12358
|
/** Reused arc buffer — aiming runs every frame. */
|
|
@@ -12135,7 +12478,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
12135
12478
|
}
|
|
12136
12479
|
if (this.turnLatched.has(source)) continue;
|
|
12137
12480
|
this.turnLatched.add(source);
|
|
12138
|
-
transform.rotation.y -= Math.sign(x) *
|
|
12481
|
+
transform.rotation.y -= Math.sign(x) * THREE56__namespace.MathUtils.degToRad(rig.snapTurnDegrees);
|
|
12139
12482
|
}
|
|
12140
12483
|
}
|
|
12141
12484
|
applySmoothMove(world, rig, transform, inputs, deltaTime) {
|
|
@@ -12145,12 +12488,12 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
12145
12488
|
const y = input.axes[1] ?? 0;
|
|
12146
12489
|
if (Math.abs(x) < 0.15 && Math.abs(y) < 0.15) continue;
|
|
12147
12490
|
const camera = world.getCamera();
|
|
12148
|
-
const forward = new
|
|
12491
|
+
const forward = new THREE56__namespace.Vector3();
|
|
12149
12492
|
camera.getWorldDirection(forward);
|
|
12150
12493
|
forward.y = 0;
|
|
12151
12494
|
if (forward.lengthSq() < 1e-6) continue;
|
|
12152
12495
|
forward.normalize();
|
|
12153
|
-
const right = new
|
|
12496
|
+
const right = new THREE56__namespace.Vector3().crossVectors(forward, UP).normalize();
|
|
12154
12497
|
const step = rig.moveSpeed * Math.max(0, deltaTime);
|
|
12155
12498
|
transform.position.x += (forward.x * -y + right.x * x) * step;
|
|
12156
12499
|
transform.position.z += (forward.z * -y + right.z * x) * step;
|
|
@@ -12231,7 +12574,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
12231
12574
|
for (let i = 1; i < points.length; i += 1) {
|
|
12232
12575
|
const from = points[i - 1];
|
|
12233
12576
|
const to = points[i];
|
|
12234
|
-
const delta = new
|
|
12577
|
+
const delta = new THREE56__namespace.Vector3().subVectors(to, from);
|
|
12235
12578
|
const distance = delta.length();
|
|
12236
12579
|
if (distance < 1e-6) continue;
|
|
12237
12580
|
this.raycaster.set(from, delta.divideScalar(distance));
|
|
@@ -12500,12 +12843,12 @@ function planeColliderFromPolygon(polygon) {
|
|
|
12500
12843
|
}
|
|
12501
12844
|
__name(planeColliderFromPolygon, "planeColliderFromPolygon");
|
|
12502
12845
|
function writeXrMeshGeometry(vertices, indices, existing) {
|
|
12503
|
-
const geometry = existing ?? new
|
|
12846
|
+
const geometry = existing ?? new THREE56__namespace.BufferGeometry();
|
|
12504
12847
|
geometry.setAttribute(
|
|
12505
12848
|
"position",
|
|
12506
|
-
new
|
|
12849
|
+
new THREE56__namespace.BufferAttribute(vertices.slice(), 3)
|
|
12507
12850
|
);
|
|
12508
|
-
geometry.setIndex(new
|
|
12851
|
+
geometry.setIndex(new THREE56__namespace.BufferAttribute(indices.slice(), 1));
|
|
12509
12852
|
geometry.deleteAttribute("normal");
|
|
12510
12853
|
geometry.computeBoundingSphere();
|
|
12511
12854
|
geometry.computeVertexNormals();
|
|
@@ -12513,14 +12856,14 @@ function writeXrMeshGeometry(vertices, indices, existing) {
|
|
|
12513
12856
|
}
|
|
12514
12857
|
__name(writeXrMeshGeometry, "writeXrMeshGeometry");
|
|
12515
12858
|
function decomposeXrPose(matrixElements, target) {
|
|
12516
|
-
const matrix = new
|
|
12859
|
+
const matrix = new THREE56__namespace.Matrix4().fromArray(
|
|
12517
12860
|
matrixElements
|
|
12518
12861
|
);
|
|
12519
|
-
const position = new
|
|
12520
|
-
const quaternion = new
|
|
12521
|
-
const scale = new
|
|
12862
|
+
const position = new THREE56__namespace.Vector3();
|
|
12863
|
+
const quaternion = new THREE56__namespace.Quaternion();
|
|
12864
|
+
const scale = new THREE56__namespace.Vector3();
|
|
12522
12865
|
matrix.decompose(position, quaternion, scale);
|
|
12523
|
-
const euler = new
|
|
12866
|
+
const euler = new THREE56__namespace.Euler().setFromQuaternion(quaternion, "XYZ");
|
|
12524
12867
|
target.position.x = position.x;
|
|
12525
12868
|
target.position.y = position.y;
|
|
12526
12869
|
target.position.z = position.z;
|
|
@@ -12530,6 +12873,88 @@ function decomposeXrPose(matrixElements, target) {
|
|
|
12530
12873
|
}
|
|
12531
12874
|
__name(decomposeXrPose, "decomposeXrPose");
|
|
12532
12875
|
|
|
12876
|
+
// core/xr/poseStability.ts
|
|
12877
|
+
var GLUED_REF_SPEED = 0.12;
|
|
12878
|
+
var STILL_SPEED = 0.05;
|
|
12879
|
+
var GLUED_FRAMES_TO_FREEZE = 3;
|
|
12880
|
+
var STATIC_FRAMES_TO_RECOVER = 10;
|
|
12881
|
+
var SNAP_SPEED = 3;
|
|
12882
|
+
var dist = /* @__PURE__ */ __name((a, b) => Math.hypot(a.x - b.x, a.y - b.y, a.z - b.z), "dist");
|
|
12883
|
+
var _SurfacePoseGate = class _SurfacePoseGate {
|
|
12884
|
+
constructor() {
|
|
12885
|
+
this.prevRef = null;
|
|
12886
|
+
this.prevView = null;
|
|
12887
|
+
this.gluedStreak = 0;
|
|
12888
|
+
this.staticStreak = 0;
|
|
12889
|
+
this.suspect = false;
|
|
12890
|
+
this.deltas = 0;
|
|
12891
|
+
}
|
|
12892
|
+
/** True while poses are being rejected as head-glued. */
|
|
12893
|
+
get frozen() {
|
|
12894
|
+
return this.suspect;
|
|
12895
|
+
}
|
|
12896
|
+
/**
|
|
12897
|
+
* True once enough motion has been observed to classify the pose at all.
|
|
12898
|
+
* Surface CREATION waits for this: an entity spawned from a glued pose
|
|
12899
|
+
* materializes wherever the head happens to be — a rotated ghost copy of
|
|
12900
|
+
* the room — and freezing it there is barely better than letting it follow.
|
|
12901
|
+
*/
|
|
12902
|
+
get warmedUp() {
|
|
12903
|
+
return this.deltas >= GLUED_FRAMES_TO_FREEZE;
|
|
12904
|
+
}
|
|
12905
|
+
/**
|
|
12906
|
+
* Feed this frame's surface position in reference space and in view
|
|
12907
|
+
* (viewer-relative) space. Returns true when the pose should be APPLIED,
|
|
12908
|
+
* false when it should be frozen out.
|
|
12909
|
+
*
|
|
12910
|
+
* `viewPos` may be null when the viewer pose is unavailable (older
|
|
12911
|
+
* runtimes) — the gate then passes everything through, degrading to the
|
|
12912
|
+
* flag-only behavior.
|
|
12913
|
+
*/
|
|
12914
|
+
update(refPos, viewPos, deltaTime) {
|
|
12915
|
+
if (!viewPos || deltaTime <= 0) {
|
|
12916
|
+
this.prevRef = { ...refPos };
|
|
12917
|
+
this.prevView = viewPos ? { ...viewPos } : null;
|
|
12918
|
+
return !this.suspect;
|
|
12919
|
+
}
|
|
12920
|
+
const prevRef = this.prevRef;
|
|
12921
|
+
const prevView = this.prevView;
|
|
12922
|
+
this.prevRef = { ...refPos };
|
|
12923
|
+
this.prevView = { ...viewPos };
|
|
12924
|
+
if (!prevRef || !prevView) return !this.suspect;
|
|
12925
|
+
this.deltas += 1;
|
|
12926
|
+
const refSpeed = dist(refPos, prevRef) / deltaTime;
|
|
12927
|
+
const viewSpeed = dist(viewPos, prevView) / deltaTime;
|
|
12928
|
+
const glued = refSpeed > GLUED_REF_SPEED && viewSpeed < STILL_SPEED;
|
|
12929
|
+
const worldStatic = refSpeed < STILL_SPEED && viewSpeed > GLUED_REF_SPEED;
|
|
12930
|
+
if (this.suspect) {
|
|
12931
|
+
if (refSpeed > SNAP_SPEED && viewSpeed > SNAP_SPEED) {
|
|
12932
|
+
this.suspect = false;
|
|
12933
|
+
this.gluedStreak = 0;
|
|
12934
|
+
this.staticStreak = 0;
|
|
12935
|
+
return true;
|
|
12936
|
+
}
|
|
12937
|
+
this.staticStreak = worldStatic ? this.staticStreak + 1 : 0;
|
|
12938
|
+
if (this.staticStreak >= STATIC_FRAMES_TO_RECOVER) {
|
|
12939
|
+
this.suspect = false;
|
|
12940
|
+
this.gluedStreak = 0;
|
|
12941
|
+
this.staticStreak = 0;
|
|
12942
|
+
return true;
|
|
12943
|
+
}
|
|
12944
|
+
return false;
|
|
12945
|
+
}
|
|
12946
|
+
this.gluedStreak = glued ? this.gluedStreak + 1 : 0;
|
|
12947
|
+
if (this.gluedStreak >= GLUED_FRAMES_TO_FREEZE) {
|
|
12948
|
+
this.suspect = true;
|
|
12949
|
+
this.staticStreak = 0;
|
|
12950
|
+
return false;
|
|
12951
|
+
}
|
|
12952
|
+
return true;
|
|
12953
|
+
}
|
|
12954
|
+
};
|
|
12955
|
+
__name(_SurfacePoseGate, "SurfacePoseGate");
|
|
12956
|
+
var SurfacePoseGate = _SurfacePoseGate;
|
|
12957
|
+
|
|
12533
12958
|
// core/systems/XREnvironmentSystem.ts
|
|
12534
12959
|
var DEBUG_COLOR = 5088255;
|
|
12535
12960
|
function debugColorFor(kind, semanticLabel) {
|
|
@@ -12553,6 +12978,11 @@ function debugColorFor(kind, semanticLabel) {
|
|
|
12553
12978
|
}
|
|
12554
12979
|
__name(debugColorFor, "debugColorFor");
|
|
12555
12980
|
var GLOBAL_MESH_DEBUG_OPACITY = 0.35;
|
|
12981
|
+
var GLOBAL_MESH_SWITCH_MARGIN = 1.5;
|
|
12982
|
+
function isGlobalMeshSurface(mesh) {
|
|
12983
|
+
return (mesh.semanticLabel ?? null) === "global mesh";
|
|
12984
|
+
}
|
|
12985
|
+
__name(isGlobalMeshSurface, "isGlobalMeshSurface");
|
|
12556
12986
|
var DEBUG_RENDER_ORDER = 900;
|
|
12557
12987
|
var ROOM_CAPTURE_DELAY_SECONDS = 3;
|
|
12558
12988
|
var SYNTHETIC_FLOOR_EXTENT = 50;
|
|
@@ -12573,12 +13003,30 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12573
13003
|
/** Keyed by the XRPlane/XRMesh object itself — the runtime's own identity. */
|
|
12574
13004
|
this.planes = /* @__PURE__ */ new Map();
|
|
12575
13005
|
this.meshes = /* @__PURE__ */ new Map();
|
|
13006
|
+
/**
|
|
13007
|
+
* Surfaces observed but not yet SPAWNED — their gate is still proving the
|
|
13008
|
+
* pose is world-anchored. Creating from an unflagged head-glued pose (seen
|
|
13009
|
+
* on-device after a suspend/resume regenerated the scan identities) plants
|
|
13010
|
+
* a rotated ghost copy of the room wherever the head happens to be, which
|
|
13011
|
+
* the apply-gate then freezes there — wrong forever. So admission itself
|
|
13012
|
+
* is gated: a few frames of world-anchored behavior first.
|
|
13013
|
+
*/
|
|
13014
|
+
this.pendingPlanes = /* @__PURE__ */ new Map();
|
|
13015
|
+
this.pendingMeshes = /* @__PURE__ */ new Map();
|
|
12576
13016
|
this.presenting = false;
|
|
12577
13017
|
this.debugVisible = false;
|
|
12578
13018
|
/** Seconds presenting, used to decide the room has genuinely nothing in it. */
|
|
12579
13019
|
this.elapsed = 0;
|
|
12580
13020
|
/** `initiateRoomCapture` may be called only ONCE per session. */
|
|
12581
13021
|
this.roomCaptureRequested = false;
|
|
13022
|
+
/** This frame's inverse viewer matrix, or null when unavailable. */
|
|
13023
|
+
this.viewerInverse = null;
|
|
13024
|
+
/** This frame's viewer position in reference space, for room election. */
|
|
13025
|
+
this.viewerPos = null;
|
|
13026
|
+
/** The ONE global room mesh currently allowed to spawn. */
|
|
13027
|
+
this.electedGlobalMesh = null;
|
|
13028
|
+
this.tmpViewerMatrix = new THREE56__namespace.Matrix4();
|
|
13029
|
+
this.tmpViewPos = new THREE56__namespace.Vector3();
|
|
12582
13030
|
}
|
|
12583
13031
|
update(world, deltaTime = 0) {
|
|
12584
13032
|
const presenting = world.isXrPresenting();
|
|
@@ -12616,13 +13064,22 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12616
13064
|
const meshesAvailable = Boolean(frame.detectedMeshes);
|
|
12617
13065
|
const useMesh = (mode === "mesh" || mode === "auto") && meshesAvailable;
|
|
12618
13066
|
const usePlanes = mode === "planes" || mode === "auto" && !useMesh;
|
|
13067
|
+
const viewer = frame.getViewerPose?.(referenceSpace);
|
|
13068
|
+
if (viewer) {
|
|
13069
|
+
const vm = viewer.transform.matrix;
|
|
13070
|
+
this.viewerPos = { x: vm[12], y: vm[13], z: vm[14] };
|
|
13071
|
+
this.viewerInverse = this.tmpViewerMatrix.fromArray(vm).invert();
|
|
13072
|
+
} else {
|
|
13073
|
+
this.viewerPos = null;
|
|
13074
|
+
this.viewerInverse = null;
|
|
13075
|
+
}
|
|
12619
13076
|
if (usePlanes) {
|
|
12620
|
-
this.syncPlanes(world, frame, referenceSpace);
|
|
13077
|
+
this.syncPlanes(world, frame, referenceSpace, deltaTime);
|
|
12621
13078
|
} else if (this.planes.size > 0) {
|
|
12622
13079
|
this.clearMap(world, this.planes);
|
|
12623
13080
|
}
|
|
12624
13081
|
if (useMesh) {
|
|
12625
|
-
this.syncMeshes(world, frame, referenceSpace);
|
|
13082
|
+
this.syncMeshes(world, frame, referenceSpace, deltaTime);
|
|
12626
13083
|
} else if (this.meshes.size > 0) {
|
|
12627
13084
|
this.clearMap(world, this.meshes);
|
|
12628
13085
|
}
|
|
@@ -12709,7 +13166,7 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12709
13166
|
if (ids.length === 0) return null;
|
|
12710
13167
|
return world.getComponent(ids[0], XRRigComponent) ?? null;
|
|
12711
13168
|
}
|
|
12712
|
-
syncPlanes(world, frame, referenceSpace) {
|
|
13169
|
+
syncPlanes(world, frame, referenceSpace, deltaTime) {
|
|
12713
13170
|
const detected = frame.detectedPlanes;
|
|
12714
13171
|
if (!detected) return;
|
|
12715
13172
|
for (const [plane, entry] of this.planes) {
|
|
@@ -12718,6 +13175,9 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12718
13175
|
this.planes.delete(plane);
|
|
12719
13176
|
}
|
|
12720
13177
|
}
|
|
13178
|
+
for (const plane of this.pendingPlanes.keys()) {
|
|
13179
|
+
if (!detected.has(plane)) this.pendingPlanes.delete(plane);
|
|
13180
|
+
}
|
|
12721
13181
|
for (const plane of detected) {
|
|
12722
13182
|
const pose = frame.getPose(plane.planeSpace, referenceSpace);
|
|
12723
13183
|
if (!pose) continue;
|
|
@@ -12726,8 +13186,11 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12726
13186
|
const changed = plane.lastChangedTime ?? 0;
|
|
12727
13187
|
if (!entry) {
|
|
12728
13188
|
if (emulated) continue;
|
|
13189
|
+
const gate = this.admit(this.pendingPlanes, plane, pose, deltaTime);
|
|
13190
|
+
if (!gate) continue;
|
|
12729
13191
|
const created = this.createPlaneEntity(world, plane);
|
|
12730
13192
|
if (!created) continue;
|
|
13193
|
+
created.gate = gate;
|
|
12731
13194
|
entry = created;
|
|
12732
13195
|
this.planes.set(plane, entry);
|
|
12733
13196
|
} else if (changed !== entry.lastChangedTime) {
|
|
@@ -12747,11 +13210,12 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12747
13210
|
}
|
|
12748
13211
|
}
|
|
12749
13212
|
}
|
|
12750
|
-
entry.
|
|
12751
|
-
|
|
13213
|
+
const allowed = !emulated && this.gateAllows(entry.gate, pose, deltaTime);
|
|
13214
|
+
entry.emulated = emulated || entry.gate.frozen;
|
|
13215
|
+
if (allowed) this.applyPose(world, entry.entityId, pose);
|
|
12752
13216
|
}
|
|
12753
13217
|
}
|
|
12754
|
-
syncMeshes(world, frame, referenceSpace) {
|
|
13218
|
+
syncMeshes(world, frame, referenceSpace, deltaTime) {
|
|
12755
13219
|
const detected = frame.detectedMeshes;
|
|
12756
13220
|
if (!detected) return;
|
|
12757
13221
|
for (const [mesh, entry] of this.meshes) {
|
|
@@ -12760,7 +13224,20 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12760
13224
|
this.meshes.delete(mesh);
|
|
12761
13225
|
}
|
|
12762
13226
|
}
|
|
13227
|
+
for (const mesh of this.pendingMeshes.keys()) {
|
|
13228
|
+
if (!detected.has(mesh)) this.pendingMeshes.delete(mesh);
|
|
13229
|
+
}
|
|
13230
|
+
const electedGlobal = this.electGlobalMesh(frame, detected, referenceSpace);
|
|
12763
13231
|
for (const mesh of detected) {
|
|
13232
|
+
if (isGlobalMeshSurface(mesh) && mesh !== electedGlobal) {
|
|
13233
|
+
const stale = this.meshes.get(mesh);
|
|
13234
|
+
if (stale) {
|
|
13235
|
+
this.destroyEntry(world, stale);
|
|
13236
|
+
this.meshes.delete(mesh);
|
|
13237
|
+
}
|
|
13238
|
+
this.pendingMeshes.delete(mesh);
|
|
13239
|
+
continue;
|
|
13240
|
+
}
|
|
12764
13241
|
const pose = frame.getPose(mesh.meshSpace, referenceSpace);
|
|
12765
13242
|
if (!pose) continue;
|
|
12766
13243
|
const emulated = pose.emulatedPosition === true;
|
|
@@ -12768,17 +13245,95 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12768
13245
|
const changed = mesh.lastChangedTime ?? 0;
|
|
12769
13246
|
if (!entry) {
|
|
12770
13247
|
if (emulated) continue;
|
|
13248
|
+
const gate = this.admit(this.pendingMeshes, mesh, pose, deltaTime);
|
|
13249
|
+
if (!gate) continue;
|
|
12771
13250
|
const created = this.createMeshEntity(world, mesh);
|
|
12772
13251
|
if (!created) continue;
|
|
13252
|
+
created.gate = gate;
|
|
12773
13253
|
entry = created;
|
|
12774
13254
|
this.meshes.set(mesh, entry);
|
|
12775
13255
|
} else if (changed !== entry.lastChangedTime) {
|
|
12776
13256
|
entry.lastChangedTime = changed;
|
|
12777
13257
|
writeXrMeshGeometry(mesh.vertices, mesh.indices, entry.geometry);
|
|
12778
13258
|
}
|
|
12779
|
-
entry.
|
|
12780
|
-
|
|
13259
|
+
const allowed = !emulated && this.gateAllows(entry.gate, pose, deltaTime);
|
|
13260
|
+
entry.emulated = emulated || entry.gate.frozen;
|
|
13261
|
+
if (allowed) this.applyPose(world, entry.entityId, pose);
|
|
13262
|
+
}
|
|
13263
|
+
}
|
|
13264
|
+
/**
|
|
13265
|
+
* Pick THE room's global mesh: the one whose scan origin is nearest the
|
|
13266
|
+
* viewer, sticky to the current choice within a margin so origin jitter
|
|
13267
|
+
* can't flap the room. Without a viewer pose (or with a single candidate)
|
|
13268
|
+
* the first candidate stands; ties are impossible to break anyway.
|
|
13269
|
+
*/
|
|
13270
|
+
electGlobalMesh(frame, detected, referenceSpace) {
|
|
13271
|
+
let nearest = null;
|
|
13272
|
+
let nearestDist = Number.POSITIVE_INFINITY;
|
|
13273
|
+
let currentDist = Number.POSITIVE_INFINITY;
|
|
13274
|
+
let currentStillDetected = false;
|
|
13275
|
+
for (const mesh of detected) {
|
|
13276
|
+
if (!isGlobalMeshSurface(mesh)) continue;
|
|
13277
|
+
if (!this.viewerPos) {
|
|
13278
|
+
return this.electedGlobalMesh && detected.has(this.electedGlobalMesh) ? this.electedGlobalMesh : mesh;
|
|
13279
|
+
}
|
|
13280
|
+
const pose = frame.getPose(mesh.meshSpace, referenceSpace);
|
|
13281
|
+
if (!pose) continue;
|
|
13282
|
+
const m = pose.transform.matrix;
|
|
13283
|
+
const d = Math.hypot(
|
|
13284
|
+
m[12] - this.viewerPos.x,
|
|
13285
|
+
m[13] - this.viewerPos.y,
|
|
13286
|
+
m[14] - this.viewerPos.z
|
|
13287
|
+
);
|
|
13288
|
+
if (mesh === this.electedGlobalMesh) {
|
|
13289
|
+
currentDist = d;
|
|
13290
|
+
currentStillDetected = true;
|
|
13291
|
+
}
|
|
13292
|
+
if (d < nearestDist) {
|
|
13293
|
+
nearestDist = d;
|
|
13294
|
+
nearest = mesh;
|
|
13295
|
+
}
|
|
13296
|
+
}
|
|
13297
|
+
if (currentStillDetected && currentDist < nearestDist + GLOBAL_MESH_SWITCH_MARGIN) {
|
|
13298
|
+
return this.electedGlobalMesh;
|
|
13299
|
+
}
|
|
13300
|
+
this.electedGlobalMesh = nearest;
|
|
13301
|
+
return nearest;
|
|
13302
|
+
}
|
|
13303
|
+
/**
|
|
13304
|
+
* Admission control for a NOT-yet-spawned surface. With a viewer pose
|
|
13305
|
+
* available, the surface must behave world-anchored for a few frames before
|
|
13306
|
+
* an entity is created for it; without one (older runtimes, tests) it is
|
|
13307
|
+
* admitted immediately — the gate can't classify anyway. Returns the
|
|
13308
|
+
* warmed-up gate (carried into the entry so its motion history survives),
|
|
13309
|
+
* or null while the surface must keep waiting.
|
|
13310
|
+
*/
|
|
13311
|
+
admit(pending, key, pose, deltaTime) {
|
|
13312
|
+
if (!this.viewerInverse) return new SurfacePoseGate();
|
|
13313
|
+
let gate = pending.get(key);
|
|
13314
|
+
if (!gate) {
|
|
13315
|
+
gate = new SurfacePoseGate();
|
|
13316
|
+
pending.set(key, gate);
|
|
13317
|
+
}
|
|
13318
|
+
const allowed = this.gateAllows(gate, pose, deltaTime);
|
|
13319
|
+
if (!allowed || !gate.warmedUp) return null;
|
|
13320
|
+
pending.delete(key);
|
|
13321
|
+
return gate;
|
|
13322
|
+
}
|
|
13323
|
+
/**
|
|
13324
|
+
* Run a surface's pose through its head-glue gate: position in reference
|
|
13325
|
+
* space vs position relative to the viewer. Without a viewer pose the gate
|
|
13326
|
+
* passes everything, degrading to the flag-only behavior.
|
|
13327
|
+
*/
|
|
13328
|
+
gateAllows(gate, pose, deltaTime) {
|
|
13329
|
+
const m = pose.transform.matrix;
|
|
13330
|
+
const refPos = { x: m[12], y: m[13], z: m[14] };
|
|
13331
|
+
let viewPos = null;
|
|
13332
|
+
if (this.viewerInverse) {
|
|
13333
|
+
const v = this.tmpViewPos.set(refPos.x, refPos.y, refPos.z).applyMatrix4(this.viewerInverse);
|
|
13334
|
+
viewPos = { x: v.x, y: v.y, z: v.z };
|
|
12781
13335
|
}
|
|
13336
|
+
return gate.update(refPos, viewPos, deltaTime);
|
|
12782
13337
|
}
|
|
12783
13338
|
createPlaneEntity(world, plane) {
|
|
12784
13339
|
const collider = planeColliderFromPolygon(plane.polygon);
|
|
@@ -12798,7 +13353,8 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12798
13353
|
lastChangedTime: plane.lastChangedTime ?? 0,
|
|
12799
13354
|
geometry: null,
|
|
12800
13355
|
material: null,
|
|
12801
|
-
emulated: false
|
|
13356
|
+
emulated: false,
|
|
13357
|
+
gate: new SurfacePoseGate()
|
|
12802
13358
|
};
|
|
12803
13359
|
if (this.debugVisible) {
|
|
12804
13360
|
this.attachPlaneDebug(world, entry, collider, plane.semanticLabel ?? null);
|
|
@@ -12829,7 +13385,7 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12829
13385
|
const geometry = writeXrMeshGeometry(mesh.vertices, mesh.indices);
|
|
12830
13386
|
const label = mesh.semanticLabel ?? null;
|
|
12831
13387
|
const isGlobalMesh = label === "global mesh";
|
|
12832
|
-
const material = new
|
|
13388
|
+
const material = new THREE56__namespace.MeshBasicMaterial({
|
|
12833
13389
|
color: debugColorFor("mesh", label),
|
|
12834
13390
|
wireframe: true,
|
|
12835
13391
|
// The global scan is a coarse triangle soup of the whole room; at full
|
|
@@ -12850,8 +13406,8 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12850
13406
|
depthTest: true,
|
|
12851
13407
|
depthWrite: false
|
|
12852
13408
|
});
|
|
12853
|
-
const root = new
|
|
12854
|
-
const child = new
|
|
13409
|
+
const root = new THREE56__namespace.Group();
|
|
13410
|
+
const child = new THREE56__namespace.Mesh(geometry, material);
|
|
12855
13411
|
child.visible = this.debugVisible;
|
|
12856
13412
|
child.renderOrder = DEBUG_RENDER_ORDER;
|
|
12857
13413
|
root.add(child);
|
|
@@ -12871,26 +13427,27 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12871
13427
|
lastChangedTime: mesh.lastChangedTime ?? 0,
|
|
12872
13428
|
geometry,
|
|
12873
13429
|
material,
|
|
12874
|
-
emulated: false
|
|
13430
|
+
emulated: false,
|
|
13431
|
+
gate: new SurfacePoseGate()
|
|
12875
13432
|
};
|
|
12876
13433
|
}
|
|
12877
13434
|
/** A thin box so a detected plane can be SEEN, not just collided with. */
|
|
12878
13435
|
attachPlaneDebug(world, entry, collider, semanticLabel) {
|
|
12879
|
-
const box = new
|
|
13436
|
+
const box = new THREE56__namespace.BoxGeometry(
|
|
12880
13437
|
collider.size.x,
|
|
12881
13438
|
collider.size.y,
|
|
12882
13439
|
collider.size.z
|
|
12883
13440
|
);
|
|
12884
|
-
const geometry = new
|
|
13441
|
+
const geometry = new THREE56__namespace.EdgesGeometry(box);
|
|
12885
13442
|
box.dispose();
|
|
12886
|
-
const material = new
|
|
13443
|
+
const material = new THREE56__namespace.LineBasicMaterial({
|
|
12887
13444
|
color: debugColorFor("plane", semanticLabel),
|
|
12888
13445
|
// Same depth policy as the mesh overlay — see createMeshEntity.
|
|
12889
13446
|
depthTest: true,
|
|
12890
13447
|
depthWrite: false
|
|
12891
13448
|
});
|
|
12892
|
-
const root = new
|
|
12893
|
-
const child = new
|
|
13449
|
+
const root = new THREE56__namespace.Group();
|
|
13450
|
+
const child = new THREE56__namespace.LineSegments(geometry, material);
|
|
12894
13451
|
child.renderOrder = DEBUG_RENDER_ORDER;
|
|
12895
13452
|
child.position.set(collider.offset.x, collider.offset.y, collider.offset.z);
|
|
12896
13453
|
child.visible = this.debugVisible;
|
|
@@ -12952,6 +13509,9 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12952
13509
|
clearAll(world) {
|
|
12953
13510
|
this.clearMap(world, this.planes);
|
|
12954
13511
|
this.clearMap(world, this.meshes);
|
|
13512
|
+
this.pendingPlanes.clear();
|
|
13513
|
+
this.pendingMeshes.clear();
|
|
13514
|
+
this.electedGlobalMesh = null;
|
|
12955
13515
|
}
|
|
12956
13516
|
dispose(world) {
|
|
12957
13517
|
this.clearAll(world);
|
|
@@ -12963,6 +13523,918 @@ function normalizeOrientation(value) {
|
|
|
12963
13523
|
return value === "horizontal" || value === "vertical" ? value : null;
|
|
12964
13524
|
}
|
|
12965
13525
|
__name(normalizeOrientation, "normalizeOrientation");
|
|
13526
|
+
var MOUSE_CLICK_TRAVEL_PX = 6;
|
|
13527
|
+
var PRESS_TINT_MIN_SECONDS = 0.1;
|
|
13528
|
+
var PRESS_TINT = 0.72;
|
|
13529
|
+
var HOVER_TINT = 0.9;
|
|
13530
|
+
var _UIInteractionSystem = class _UIInteractionSystem {
|
|
13531
|
+
/**
|
|
13532
|
+
* @param interaction The XR interaction system, or null in a world with no
|
|
13533
|
+
* XR (flat 3D experiences) — the mouse path still works via
|
|
13534
|
+
* `options.inputSystem`.
|
|
13535
|
+
*/
|
|
13536
|
+
constructor(interaction, options) {
|
|
13537
|
+
this.xrPresses = /* @__PURE__ */ new Map();
|
|
13538
|
+
this.mousePress = null;
|
|
13539
|
+
this.mouseHover = null;
|
|
13540
|
+
/** entityId → seconds of pressed-tint left to display. */
|
|
13541
|
+
this.tintFloors = /* @__PURE__ */ new Map();
|
|
13542
|
+
this.tinted = /* @__PURE__ */ new Set();
|
|
13543
|
+
this.raycaster = new THREE56__namespace.Raycaster();
|
|
13544
|
+
this.interaction = interaction;
|
|
13545
|
+
this.inputSystem = options?.inputSystem ?? null;
|
|
13546
|
+
interaction?.registerBusyContributor(
|
|
13547
|
+
(_world, input) => this.xrPresses.has(input)
|
|
13548
|
+
);
|
|
13549
|
+
}
|
|
13550
|
+
update(world, deltaTime = 0) {
|
|
13551
|
+
if (world.isEditorMode()) return;
|
|
13552
|
+
if (world.isXrPresenting()) {
|
|
13553
|
+
this.updateXr(world);
|
|
13554
|
+
} else {
|
|
13555
|
+
this.updateMouse(world);
|
|
13556
|
+
}
|
|
13557
|
+
this.updateTints(world, deltaTime);
|
|
13558
|
+
}
|
|
13559
|
+
// ── XR path ────────────────────────────────────────────────────────────────
|
|
13560
|
+
updateXr(world) {
|
|
13561
|
+
const interaction = this.interaction;
|
|
13562
|
+
if (!interaction) return;
|
|
13563
|
+
const xrInput = interaction.inputSystem;
|
|
13564
|
+
const inputs = xrInput.getInputs();
|
|
13565
|
+
for (const input of inputs) {
|
|
13566
|
+
const hover = interaction.getHoverForInput(input);
|
|
13567
|
+
const hovered = hover ? this.widgetKind(world, hover.entityId) : null;
|
|
13568
|
+
if (input.selectStart && hover && hovered) {
|
|
13569
|
+
this.xrPresses.set(input, {
|
|
13570
|
+
entityId: hover.entityId,
|
|
13571
|
+
kind: hovered,
|
|
13572
|
+
travelPx: 0
|
|
13573
|
+
});
|
|
13574
|
+
this.beginPressTint(world, hover.entityId);
|
|
13575
|
+
}
|
|
13576
|
+
const press = this.xrPresses.get(input);
|
|
13577
|
+
if (press && press.kind === "slider") {
|
|
13578
|
+
this.dragSlider(world, press.entityId, input);
|
|
13579
|
+
}
|
|
13580
|
+
if (input.selectEnd || !input.connected) {
|
|
13581
|
+
if (press) {
|
|
13582
|
+
this.xrPresses.delete(input);
|
|
13583
|
+
const stillOn = hover?.entityId === press.entityId || // Vision Pro: the transient source is gone from the hover map on
|
|
13584
|
+
// its release frame — confirm against the last latched ray.
|
|
13585
|
+
this.rayHitsWidget(world, press.entityId, input);
|
|
13586
|
+
if (stillOn || press.kind === "slider") {
|
|
13587
|
+
this.fire(world, press, input);
|
|
13588
|
+
}
|
|
13589
|
+
this.endPressTint(press.entityId);
|
|
13590
|
+
}
|
|
13591
|
+
}
|
|
13592
|
+
}
|
|
13593
|
+
for (const [input] of this.xrPresses) {
|
|
13594
|
+
if (!inputs.includes(input)) this.xrPresses.delete(input);
|
|
13595
|
+
}
|
|
13596
|
+
}
|
|
13597
|
+
// ── Mouse path (flat preview) ──────────────────────────────────────────────
|
|
13598
|
+
updateMouse(world) {
|
|
13599
|
+
const input = this.inputSystem;
|
|
13600
|
+
if (!input) return;
|
|
13601
|
+
const hit = this.raycastMouse(world);
|
|
13602
|
+
const hovered = hit && this.widgetKind(world, hit) ? hit : null;
|
|
13603
|
+
if (hovered !== this.mouseHover) {
|
|
13604
|
+
if (this.mouseHover !== null) {
|
|
13605
|
+
this.setTint(world, this.mouseHover, 1);
|
|
13606
|
+
this.dispatchBubbling(
|
|
13607
|
+
world,
|
|
13608
|
+
this.mouseHover,
|
|
13609
|
+
(b, e) => b.onUiHoverEnd(e)
|
|
13610
|
+
);
|
|
13611
|
+
}
|
|
13612
|
+
if (hovered !== null) {
|
|
13613
|
+
this.setTint(world, hovered, HOVER_TINT);
|
|
13614
|
+
this.dispatchBubbling(world, hovered, (b, e) => b.onUiHoverStart(e));
|
|
13615
|
+
}
|
|
13616
|
+
this.mouseHover = hovered;
|
|
13617
|
+
}
|
|
13618
|
+
if (input.getMouseDown("left") && hovered) {
|
|
13619
|
+
const kind = this.widgetKind(world, hovered);
|
|
13620
|
+
if (kind) {
|
|
13621
|
+
this.mousePress = { entityId: hovered, kind, travelPx: 0 };
|
|
13622
|
+
this.beginPressTint(world, hovered);
|
|
13623
|
+
}
|
|
13624
|
+
}
|
|
13625
|
+
if (this.mousePress) {
|
|
13626
|
+
const delta = input.getMouseDelta();
|
|
13627
|
+
this.mousePress.travelPx += Math.hypot(delta.x, delta.y);
|
|
13628
|
+
if (this.mousePress.kind === "slider") {
|
|
13629
|
+
this.dragSliderMouse(world, this.mousePress.entityId);
|
|
13630
|
+
}
|
|
13631
|
+
}
|
|
13632
|
+
if (input.getMouseUp("left") && this.mousePress) {
|
|
13633
|
+
const press = this.mousePress;
|
|
13634
|
+
this.mousePress = null;
|
|
13635
|
+
const stillOn = hovered === press.entityId;
|
|
13636
|
+
const withinTravel = press.travelPx <= MOUSE_CLICK_TRAVEL_PX;
|
|
13637
|
+
if (press.kind === "slider" || stillOn && withinTravel) {
|
|
13638
|
+
this.fire(world, press, null);
|
|
13639
|
+
}
|
|
13640
|
+
this.endPressTint(press.entityId);
|
|
13641
|
+
}
|
|
13642
|
+
}
|
|
13643
|
+
raycastMouse(world) {
|
|
13644
|
+
const input = this.inputSystem;
|
|
13645
|
+
if (!input) return null;
|
|
13646
|
+
const dom = world.getRenderer().domElement;
|
|
13647
|
+
const rect = dom.getBoundingClientRect();
|
|
13648
|
+
let ndcX = 0;
|
|
13649
|
+
let ndcY = 0;
|
|
13650
|
+
if (input.isMousePointerLocked()) {
|
|
13651
|
+
ndcX = 0;
|
|
13652
|
+
ndcY = 0;
|
|
13653
|
+
} else {
|
|
13654
|
+
const pos = input.getMousePosition();
|
|
13655
|
+
ndcX = (pos.x - rect.left) / Math.max(1, rect.width) * 2 - 1;
|
|
13656
|
+
ndcY = -((pos.y - rect.top) / Math.max(1, rect.height) * 2 - 1);
|
|
13657
|
+
if (ndcX < -1 || ndcX > 1 || ndcY < -1 || ndcY > 1) return null;
|
|
13658
|
+
}
|
|
13659
|
+
this.raycaster.setFromCamera(new THREE56__namespace.Vector2(ndcX, ndcY), world.getCamera());
|
|
13660
|
+
const hits = world.raycast(
|
|
13661
|
+
this.raycaster.ray.origin,
|
|
13662
|
+
this.raycaster.ray.direction
|
|
13663
|
+
);
|
|
13664
|
+
for (const hit of hits) {
|
|
13665
|
+
if (typeof hit.entityId !== "number") continue;
|
|
13666
|
+
if (this.widgetKind(world, hit.entityId)) return hit.entityId;
|
|
13667
|
+
return null;
|
|
13668
|
+
}
|
|
13669
|
+
return null;
|
|
13670
|
+
}
|
|
13671
|
+
// ── Shared machinery ───────────────────────────────────────────────────────
|
|
13672
|
+
widgetKind(world, entityId) {
|
|
13673
|
+
if (world.getComponent(entityId, UIButtonComponent)) return "button";
|
|
13674
|
+
if (world.getComponent(entityId, UIToggleComponent)) return "toggle";
|
|
13675
|
+
if (world.getComponent(entityId, UISliderComponent)) return "slider";
|
|
13676
|
+
return null;
|
|
13677
|
+
}
|
|
13678
|
+
fire(world, press, input) {
|
|
13679
|
+
if (press.kind === "button") {
|
|
13680
|
+
this.dispatchBubbling(world, press.entityId, (b, e) => b.onUiPress(e), input);
|
|
13681
|
+
return;
|
|
13682
|
+
}
|
|
13683
|
+
if (press.kind === "toggle") {
|
|
13684
|
+
const toggle = world.getComponent(press.entityId, UIToggleComponent);
|
|
13685
|
+
if (!toggle) return;
|
|
13686
|
+
toggle.value = !toggle.value;
|
|
13687
|
+
this.dispatchBubbling(
|
|
13688
|
+
world,
|
|
13689
|
+
press.entityId,
|
|
13690
|
+
(b, e) => b.onUiToggle(e),
|
|
13691
|
+
input,
|
|
13692
|
+
toggle.value
|
|
13693
|
+
);
|
|
13694
|
+
return;
|
|
13695
|
+
}
|
|
13696
|
+
const slider = world.getComponent(press.entityId, UISliderComponent);
|
|
13697
|
+
if (!slider) return;
|
|
13698
|
+
this.dispatchBubbling(
|
|
13699
|
+
world,
|
|
13700
|
+
press.entityId,
|
|
13701
|
+
(b, e) => b.onUiChange(e),
|
|
13702
|
+
input,
|
|
13703
|
+
slider.value
|
|
13704
|
+
);
|
|
13705
|
+
}
|
|
13706
|
+
dragSlider(world, entityId, input) {
|
|
13707
|
+
const point = this.rayPointOnWidget(world, entityId, input);
|
|
13708
|
+
if (point) this.applySliderPoint(world, entityId, point, input);
|
|
13709
|
+
}
|
|
13710
|
+
dragSliderMouse(world, entityId) {
|
|
13711
|
+
const object = this.widgetObject(world, entityId);
|
|
13712
|
+
if (!object) return;
|
|
13713
|
+
const hits = this.raycaster.intersectObject(object, true);
|
|
13714
|
+
if (hits.length > 0) this.applySliderPoint(world, entityId, hits[0].point, null);
|
|
13715
|
+
}
|
|
13716
|
+
applySliderPoint(world, entityId, worldPoint, input) {
|
|
13717
|
+
const slider = world.getComponent(entityId, UISliderComponent);
|
|
13718
|
+
const object = this.widgetObject(world, entityId);
|
|
13719
|
+
if (!slider || !object) return;
|
|
13720
|
+
const local = object.worldToLocal(worldPoint.clone());
|
|
13721
|
+
const inset = slider.height / 2;
|
|
13722
|
+
const usable = Math.max(1e-3, slider.width - inset * 2);
|
|
13723
|
+
const t = Math.min(1, Math.max(0, local.x / usable + 0.5));
|
|
13724
|
+
const next = slider.min + t * (slider.max - slider.min);
|
|
13725
|
+
if (Math.abs(next - slider.value) < 1e-4) return;
|
|
13726
|
+
slider.value = next;
|
|
13727
|
+
this.dispatchBubbling(
|
|
13728
|
+
world,
|
|
13729
|
+
entityId,
|
|
13730
|
+
(b, e) => b.onUiChange(e),
|
|
13731
|
+
input,
|
|
13732
|
+
next
|
|
13733
|
+
);
|
|
13734
|
+
}
|
|
13735
|
+
widgetObject(world, entityId) {
|
|
13736
|
+
return world.getComponent(entityId, Object3DRef)?.object;
|
|
13737
|
+
}
|
|
13738
|
+
rayHitsWidget(world, entityId, input) {
|
|
13739
|
+
const object = this.widgetObject(world, entityId);
|
|
13740
|
+
if (!object) return false;
|
|
13741
|
+
this.raycaster.set(
|
|
13742
|
+
input.rayOrigin.clone(),
|
|
13743
|
+
input.rayDirection.clone().normalize()
|
|
13744
|
+
);
|
|
13745
|
+
return this.raycaster.intersectObject(object, true).length > 0;
|
|
13746
|
+
}
|
|
13747
|
+
rayPointOnWidget(world, entityId, input) {
|
|
13748
|
+
const object = this.widgetObject(world, entityId);
|
|
13749
|
+
if (!object) return null;
|
|
13750
|
+
this.raycaster.set(
|
|
13751
|
+
input.rayOrigin.clone(),
|
|
13752
|
+
input.rayDirection.clone().normalize()
|
|
13753
|
+
);
|
|
13754
|
+
const hits = this.raycaster.intersectObject(object, true);
|
|
13755
|
+
return hits.length > 0 ? hits[0].point : null;
|
|
13756
|
+
}
|
|
13757
|
+
/**
|
|
13758
|
+
* Dispatch to the widget's Behaviours, then BUBBLE up the parent chain so a
|
|
13759
|
+
* panel script hears its children. Bubbling (not a world broadcast) keeps
|
|
13760
|
+
* two spawned copies of the same menu prefab independent.
|
|
13761
|
+
*/
|
|
13762
|
+
dispatchBubbling(world, entityId, visit, input = null, value) {
|
|
13763
|
+
const event = {
|
|
13764
|
+
targetEntityId: entityId,
|
|
13765
|
+
actionId: this.actionIdOf(world, entityId),
|
|
13766
|
+
input,
|
|
13767
|
+
...value === void 0 ? {} : { value }
|
|
13768
|
+
};
|
|
13769
|
+
const visited = /* @__PURE__ */ new Set();
|
|
13770
|
+
let current = entityId;
|
|
13771
|
+
for (; ; ) {
|
|
13772
|
+
if (visited.has(current)) break;
|
|
13773
|
+
visited.add(current);
|
|
13774
|
+
const script = world.getComponent(current, ScriptComponent);
|
|
13775
|
+
const instances = script?.scriptInstances;
|
|
13776
|
+
if (instances) {
|
|
13777
|
+
for (const instance of instances.values()) {
|
|
13778
|
+
if (!(instance instanceof Behaviour)) continue;
|
|
13779
|
+
try {
|
|
13780
|
+
visit(instance, event);
|
|
13781
|
+
} catch (error) {
|
|
13782
|
+
console.error("[UIInteractionSystem] hook failed:", error);
|
|
13783
|
+
}
|
|
13784
|
+
}
|
|
13785
|
+
}
|
|
13786
|
+
const parentId = world.getComponent(current, ParentId)?.value;
|
|
13787
|
+
if (typeof parentId !== "number") break;
|
|
13788
|
+
current = parentId;
|
|
13789
|
+
}
|
|
13790
|
+
}
|
|
13791
|
+
actionIdOf(world, entityId) {
|
|
13792
|
+
const button = world.getComponent(entityId, UIButtonComponent);
|
|
13793
|
+
if (button?.actionId) return button.actionId;
|
|
13794
|
+
const toggle = world.getComponent(entityId, UIToggleComponent);
|
|
13795
|
+
if (toggle?.actionId) return toggle.actionId;
|
|
13796
|
+
const slider = world.getComponent(entityId, UISliderComponent);
|
|
13797
|
+
if (slider?.actionId) return slider.actionId;
|
|
13798
|
+
const name = world.getComponent(entityId, Name)?.value;
|
|
13799
|
+
return typeof name === "string" ? name : String(entityId);
|
|
13800
|
+
}
|
|
13801
|
+
// ── Pressed/hover tint ─────────────────────────────────────────────────────
|
|
13802
|
+
beginPressTint(world, entityId) {
|
|
13803
|
+
this.setTint(world, entityId, PRESS_TINT);
|
|
13804
|
+
this.tintFloors.set(entityId, PRESS_TINT_MIN_SECONDS);
|
|
13805
|
+
}
|
|
13806
|
+
endPressTint(entityId) {
|
|
13807
|
+
if (!this.tintFloors.has(entityId)) {
|
|
13808
|
+
this.tintFloors.set(entityId, 0);
|
|
13809
|
+
}
|
|
13810
|
+
}
|
|
13811
|
+
updateTints(world, deltaTime) {
|
|
13812
|
+
for (const [entityId, remaining] of this.tintFloors) {
|
|
13813
|
+
const next = remaining - deltaTime;
|
|
13814
|
+
const stillHeld = [...this.xrPresses.values()].some((p) => p.entityId === entityId) || this.mousePress?.entityId === entityId;
|
|
13815
|
+
if (stillHeld) continue;
|
|
13816
|
+
if (next <= 0) {
|
|
13817
|
+
this.tintFloors.delete(entityId);
|
|
13818
|
+
this.setTint(
|
|
13819
|
+
world,
|
|
13820
|
+
entityId,
|
|
13821
|
+
this.mouseHover === entityId ? HOVER_TINT : 1
|
|
13822
|
+
);
|
|
13823
|
+
} else {
|
|
13824
|
+
this.tintFloors.set(entityId, next);
|
|
13825
|
+
}
|
|
13826
|
+
}
|
|
13827
|
+
}
|
|
13828
|
+
setTint(world, entityId, scalar) {
|
|
13829
|
+
const object = this.widgetObject(world, entityId);
|
|
13830
|
+
if (!object) return;
|
|
13831
|
+
if (scalar === 1) this.tinted.delete(entityId);
|
|
13832
|
+
else this.tinted.add(entityId);
|
|
13833
|
+
object.traverse((child) => {
|
|
13834
|
+
const material = child.material;
|
|
13835
|
+
if (material?.color) material.color.setScalar(scalar);
|
|
13836
|
+
});
|
|
13837
|
+
}
|
|
13838
|
+
};
|
|
13839
|
+
__name(_UIInteractionSystem, "UIInteractionSystem");
|
|
13840
|
+
var UIInteractionSystem = _UIInteractionSystem;
|
|
13841
|
+
|
|
13842
|
+
// core/ui/uiCanvas.ts
|
|
13843
|
+
var DEFAULT_PIXELS_PER_METER = 1024;
|
|
13844
|
+
var MIN_PIXELS_PER_METER = 256;
|
|
13845
|
+
var MAX_PIXELS_PER_METER = 2048;
|
|
13846
|
+
var MAX_CANVAS_SIDE = 2048;
|
|
13847
|
+
function resolveCanvasSize(widthMeters, heightMeters, pixelDensity = DEFAULT_PIXELS_PER_METER) {
|
|
13848
|
+
const w = Math.max(0.01, widthMeters);
|
|
13849
|
+
const h = Math.max(0.01, heightMeters);
|
|
13850
|
+
const authored = Math.min(
|
|
13851
|
+
MAX_PIXELS_PER_METER,
|
|
13852
|
+
Math.max(MIN_PIXELS_PER_METER, pixelDensity)
|
|
13853
|
+
);
|
|
13854
|
+
const density = Math.min(authored, MAX_CANVAS_SIDE / Math.max(w, h));
|
|
13855
|
+
const even = /* @__PURE__ */ __name((v) => Math.max(2, 2 * Math.round(v * density / 2)), "even");
|
|
13856
|
+
return { pxWidth: even(w), pxHeight: even(h), density };
|
|
13857
|
+
}
|
|
13858
|
+
__name(resolveCanvasSize, "resolveCanvasSize");
|
|
13859
|
+
function wrapText(measure, text, maxWidthPx) {
|
|
13860
|
+
const lines = [];
|
|
13861
|
+
for (const paragraph of text.split("\n")) {
|
|
13862
|
+
const words = paragraph.split(/\s+/).filter((w) => w.length > 0);
|
|
13863
|
+
if (words.length === 0) {
|
|
13864
|
+
lines.push("");
|
|
13865
|
+
continue;
|
|
13866
|
+
}
|
|
13867
|
+
let line = "";
|
|
13868
|
+
for (const word of words) {
|
|
13869
|
+
const candidate = line ? `${line} ${word}` : word;
|
|
13870
|
+
if (measure(candidate) <= maxWidthPx) {
|
|
13871
|
+
line = candidate;
|
|
13872
|
+
continue;
|
|
13873
|
+
}
|
|
13874
|
+
if (line) {
|
|
13875
|
+
lines.push(line);
|
|
13876
|
+
line = "";
|
|
13877
|
+
}
|
|
13878
|
+
if (measure(word) <= maxWidthPx) {
|
|
13879
|
+
line = word;
|
|
13880
|
+
continue;
|
|
13881
|
+
}
|
|
13882
|
+
let chunk = "";
|
|
13883
|
+
for (const char of word) {
|
|
13884
|
+
const next = chunk + char;
|
|
13885
|
+
if (measure(next) <= maxWidthPx || chunk.length === 0) {
|
|
13886
|
+
chunk = next;
|
|
13887
|
+
} else {
|
|
13888
|
+
lines.push(chunk);
|
|
13889
|
+
chunk = char;
|
|
13890
|
+
}
|
|
13891
|
+
}
|
|
13892
|
+
line = chunk;
|
|
13893
|
+
}
|
|
13894
|
+
lines.push(line);
|
|
13895
|
+
}
|
|
13896
|
+
return lines;
|
|
13897
|
+
}
|
|
13898
|
+
__name(wrapText, "wrapText");
|
|
13899
|
+
var ELLIPSIS = "\u2026";
|
|
13900
|
+
function clampLines(measure, lines, maxLines, maxWidthPx) {
|
|
13901
|
+
if (maxLines <= 0) return [];
|
|
13902
|
+
if (lines.length <= maxLines) return lines;
|
|
13903
|
+
const kept = lines.slice(0, maxLines);
|
|
13904
|
+
let last = kept[maxLines - 1];
|
|
13905
|
+
while (last.length > 0 && measure(last + ELLIPSIS) > maxWidthPx) {
|
|
13906
|
+
last = last.slice(0, -1);
|
|
13907
|
+
}
|
|
13908
|
+
kept[maxLines - 1] = last + ELLIPSIS;
|
|
13909
|
+
return kept;
|
|
13910
|
+
}
|
|
13911
|
+
__name(clampLines, "clampLines");
|
|
13912
|
+
var UI_FONT_STACK = '-apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
|
|
13913
|
+
function tracePath(ctx, x, y, w, h, r) {
|
|
13914
|
+
const radius = Math.max(0, Math.min(r, w / 2, h / 2));
|
|
13915
|
+
ctx.beginPath();
|
|
13916
|
+
if (typeof ctx.roundRect === "function") {
|
|
13917
|
+
ctx.roundRect(x, y, w, h, radius);
|
|
13918
|
+
return;
|
|
13919
|
+
}
|
|
13920
|
+
ctx.moveTo(x + radius, y);
|
|
13921
|
+
ctx.arcTo(x + w, y, x + w, y + h, radius);
|
|
13922
|
+
ctx.arcTo(x + w, y + h, x, y + h, radius);
|
|
13923
|
+
ctx.arcTo(x, y + h, x, y, radius);
|
|
13924
|
+
ctx.arcTo(x, y, x + w, y, radius);
|
|
13925
|
+
ctx.closePath();
|
|
13926
|
+
}
|
|
13927
|
+
__name(tracePath, "tracePath");
|
|
13928
|
+
function withOpacity(ctx, color, opacity) {
|
|
13929
|
+
if (opacity >= 1) return color;
|
|
13930
|
+
ctx.save();
|
|
13931
|
+
ctx.fillStyle = color;
|
|
13932
|
+
const parsed = ctx.fillStyle;
|
|
13933
|
+
ctx.restore();
|
|
13934
|
+
if (parsed.startsWith("#") && (parsed.length === 7 || parsed.length === 4)) {
|
|
13935
|
+
const hex = parsed.length === 4 ? `#${parsed[1]}${parsed[1]}${parsed[2]}${parsed[2]}${parsed[3]}${parsed[3]}` : parsed;
|
|
13936
|
+
const r = Number.parseInt(hex.slice(1, 3), 16);
|
|
13937
|
+
const g = Number.parseInt(hex.slice(3, 5), 16);
|
|
13938
|
+
const b = Number.parseInt(hex.slice(5, 7), 16);
|
|
13939
|
+
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
13940
|
+
}
|
|
13941
|
+
return parsed;
|
|
13942
|
+
}
|
|
13943
|
+
__name(withOpacity, "withOpacity");
|
|
13944
|
+
function drawChrome(ctx, pxWidth, pxHeight, density, style) {
|
|
13945
|
+
ctx.clearRect(0, 0, pxWidth, pxHeight);
|
|
13946
|
+
const border = Math.max(0, style.borderWidthMeters * density);
|
|
13947
|
+
const radius = style.cornerRadiusMeters * density;
|
|
13948
|
+
tracePath(ctx, 0, 0, pxWidth, pxHeight, radius);
|
|
13949
|
+
ctx.fillStyle = withOpacity(
|
|
13950
|
+
ctx,
|
|
13951
|
+
style.backgroundColor,
|
|
13952
|
+
Math.max(0, Math.min(1, style.backgroundOpacity))
|
|
13953
|
+
);
|
|
13954
|
+
ctx.fill();
|
|
13955
|
+
if (border > 0) {
|
|
13956
|
+
tracePath(
|
|
13957
|
+
ctx,
|
|
13958
|
+
border / 2,
|
|
13959
|
+
border / 2,
|
|
13960
|
+
pxWidth - border,
|
|
13961
|
+
pxHeight - border,
|
|
13962
|
+
Math.max(0, radius - border / 2)
|
|
13963
|
+
);
|
|
13964
|
+
ctx.strokeStyle = style.borderColor;
|
|
13965
|
+
ctx.lineWidth = border;
|
|
13966
|
+
ctx.stroke();
|
|
13967
|
+
}
|
|
13968
|
+
}
|
|
13969
|
+
__name(drawChrome, "drawChrome");
|
|
13970
|
+
function drawTextBlock(ctx, pxWidth, pxHeight, density, text, style) {
|
|
13971
|
+
const fontPx = Math.max(4, style.fontSizeMeters * density);
|
|
13972
|
+
const paddingPx = style.paddingMeters * density;
|
|
13973
|
+
const contentW = Math.max(1, pxWidth - paddingPx * 2);
|
|
13974
|
+
const contentH = Math.max(1, pxHeight - paddingPx * 2);
|
|
13975
|
+
const lineHeightPx = fontPx * style.lineHeight;
|
|
13976
|
+
ctx.font = `${style.fontWeight} ${fontPx}px ${UI_FONT_STACK}`;
|
|
13977
|
+
const measure = /* @__PURE__ */ __name((s) => ctx.measureText(s).width, "measure");
|
|
13978
|
+
const maxLines = Math.max(1, Math.floor(contentH / lineHeightPx));
|
|
13979
|
+
const lines = clampLines(
|
|
13980
|
+
measure,
|
|
13981
|
+
wrapText(measure, text, contentW),
|
|
13982
|
+
maxLines,
|
|
13983
|
+
contentW
|
|
13984
|
+
);
|
|
13985
|
+
const blockH = lines.length * lineHeightPx;
|
|
13986
|
+
const top = style.valign === "top" ? paddingPx : style.valign === "bottom" ? pxHeight - paddingPx - blockH : (pxHeight - blockH) / 2;
|
|
13987
|
+
const anchorX = style.align === "left" ? paddingPx : style.align === "right" ? pxWidth - paddingPx : pxWidth / 2;
|
|
13988
|
+
ctx.save();
|
|
13989
|
+
tracePath(ctx, 0, 0, pxWidth, pxHeight, 0);
|
|
13990
|
+
ctx.clip();
|
|
13991
|
+
ctx.fillStyle = style.color;
|
|
13992
|
+
ctx.textAlign = style.align;
|
|
13993
|
+
ctx.textBaseline = "middle";
|
|
13994
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
13995
|
+
ctx.fillText(lines[i], anchorX, top + (i + 0.5) * lineHeightPx);
|
|
13996
|
+
}
|
|
13997
|
+
ctx.restore();
|
|
13998
|
+
}
|
|
13999
|
+
__name(drawTextBlock, "drawTextBlock");
|
|
14000
|
+
function panelSignature(widthM, heightM, size, style) {
|
|
14001
|
+
return JSON.stringify([
|
|
14002
|
+
widthM,
|
|
14003
|
+
heightM,
|
|
14004
|
+
size.pxWidth,
|
|
14005
|
+
size.pxHeight,
|
|
14006
|
+
style.backgroundColor,
|
|
14007
|
+
style.backgroundOpacity,
|
|
14008
|
+
style.cornerRadiusMeters,
|
|
14009
|
+
style.borderWidthMeters,
|
|
14010
|
+
style.borderColor
|
|
14011
|
+
]);
|
|
14012
|
+
}
|
|
14013
|
+
__name(panelSignature, "panelSignature");
|
|
14014
|
+
function textSignature(widthM, heightM, size, text, style) {
|
|
14015
|
+
return JSON.stringify([
|
|
14016
|
+
widthM,
|
|
14017
|
+
heightM,
|
|
14018
|
+
size.pxWidth,
|
|
14019
|
+
size.pxHeight,
|
|
14020
|
+
text,
|
|
14021
|
+
style.fontSizeMeters,
|
|
14022
|
+
style.fontWeight,
|
|
14023
|
+
style.color,
|
|
14024
|
+
style.align,
|
|
14025
|
+
style.valign,
|
|
14026
|
+
style.lineHeight,
|
|
14027
|
+
style.paddingMeters
|
|
14028
|
+
]);
|
|
14029
|
+
}
|
|
14030
|
+
__name(textSignature, "textSignature");
|
|
14031
|
+
function buttonSignature(widthM, heightM, size, panel, label, text) {
|
|
14032
|
+
return JSON.stringify([
|
|
14033
|
+
panelSignature(widthM, heightM, size, panel),
|
|
14034
|
+
label,
|
|
14035
|
+
text.fontSizeMeters,
|
|
14036
|
+
text.fontWeight,
|
|
14037
|
+
text.color
|
|
14038
|
+
]);
|
|
14039
|
+
}
|
|
14040
|
+
__name(buttonSignature, "buttonSignature");
|
|
14041
|
+
function trackSignature(widthM, heightM, size, panel, accentColor, knobColor) {
|
|
14042
|
+
return JSON.stringify([
|
|
14043
|
+
panelSignature(widthM, heightM, size, panel),
|
|
14044
|
+
accentColor,
|
|
14045
|
+
knobColor
|
|
14046
|
+
]);
|
|
14047
|
+
}
|
|
14048
|
+
__name(trackSignature, "trackSignature");
|
|
14049
|
+
function drawRoundedBar(ctx, pxX, pxY, pxW, pxH, color) {
|
|
14050
|
+
tracePath(ctx, pxX, pxY, pxW, pxH, pxH / 2);
|
|
14051
|
+
ctx.fillStyle = color;
|
|
14052
|
+
ctx.fill();
|
|
14053
|
+
}
|
|
14054
|
+
__name(drawRoundedBar, "drawRoundedBar");
|
|
14055
|
+
|
|
14056
|
+
// core/systems/UIPanelSystem.ts
|
|
14057
|
+
var FACE_RENDER_ORDER = 10;
|
|
14058
|
+
var CHILD_Z = 2e-3;
|
|
14059
|
+
var _UIPanelSystem = class _UIPanelSystem {
|
|
14060
|
+
constructor(options) {
|
|
14061
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
14062
|
+
this.createCanvas = options?.createCanvas ?? (() => document.createElement("canvas"));
|
|
14063
|
+
}
|
|
14064
|
+
update(world, deltaTime = 0) {
|
|
14065
|
+
const live = /* @__PURE__ */ new Set();
|
|
14066
|
+
for (const entityId of world.query(UIPanelComponent, Object3DRef)) {
|
|
14067
|
+
const panel = world.getComponent(entityId, UIPanelComponent);
|
|
14068
|
+
if (!panel) continue;
|
|
14069
|
+
live.add(entityId);
|
|
14070
|
+
this.syncPanel(world, entityId, panel);
|
|
14071
|
+
this.applyFollow(world, entityId, panel);
|
|
14072
|
+
}
|
|
14073
|
+
for (const entityId of world.query(UITextComponent, Object3DRef)) {
|
|
14074
|
+
const text = world.getComponent(entityId, UITextComponent);
|
|
14075
|
+
if (!text) continue;
|
|
14076
|
+
live.add(entityId);
|
|
14077
|
+
this.syncText(world, entityId, text);
|
|
14078
|
+
}
|
|
14079
|
+
for (const entityId of world.query(UIButtonComponent, Object3DRef)) {
|
|
14080
|
+
const button = world.getComponent(entityId, UIButtonComponent);
|
|
14081
|
+
if (!button) continue;
|
|
14082
|
+
live.add(entityId);
|
|
14083
|
+
this.syncButton(world, entityId, button);
|
|
14084
|
+
}
|
|
14085
|
+
for (const entityId of world.query(UIToggleComponent, Object3DRef)) {
|
|
14086
|
+
const toggle = world.getComponent(entityId, UIToggleComponent);
|
|
14087
|
+
if (!toggle) continue;
|
|
14088
|
+
live.add(entityId);
|
|
14089
|
+
this.syncToggle(world, entityId, toggle, deltaTime);
|
|
14090
|
+
}
|
|
14091
|
+
for (const entityId of world.query(UISliderComponent, Object3DRef)) {
|
|
14092
|
+
const slider = world.getComponent(entityId, UISliderComponent);
|
|
14093
|
+
if (!slider) continue;
|
|
14094
|
+
live.add(entityId);
|
|
14095
|
+
this.syncSlider(world, entityId, slider);
|
|
14096
|
+
}
|
|
14097
|
+
for (const [entityId, entry] of this.entries) {
|
|
14098
|
+
if (!live.has(entityId)) {
|
|
14099
|
+
this.destroyEntry(entry);
|
|
14100
|
+
this.entries.delete(entityId);
|
|
14101
|
+
}
|
|
14102
|
+
}
|
|
14103
|
+
}
|
|
14104
|
+
/** All GPU/canvas resources; call on world teardown. */
|
|
14105
|
+
dispose() {
|
|
14106
|
+
for (const entry of this.entries.values()) this.destroyEntry(entry);
|
|
14107
|
+
this.entries.clear();
|
|
14108
|
+
}
|
|
14109
|
+
// ── Widgets ────────────────────────────────────────────────────────────────
|
|
14110
|
+
syncPanel(world, entityId, panel) {
|
|
14111
|
+
const size = resolveCanvasSize(panel.width, panel.height, panel.pixelDensity);
|
|
14112
|
+
const style = {
|
|
14113
|
+
backgroundColor: panel.backgroundColor,
|
|
14114
|
+
backgroundOpacity: panel.backgroundOpacity,
|
|
14115
|
+
cornerRadiusMeters: panel.cornerRadius,
|
|
14116
|
+
borderWidthMeters: panel.borderWidth,
|
|
14117
|
+
borderColor: panel.borderColor
|
|
14118
|
+
};
|
|
14119
|
+
const signature = panelSignature(panel.width, panel.height, size, style);
|
|
14120
|
+
this.rebuildIfChanged(world, entityId, signature, panel.width, panel.height, size, (ctx) => {
|
|
14121
|
+
drawChrome(ctx, size.pxWidth, size.pxHeight, size.density, style);
|
|
14122
|
+
});
|
|
14123
|
+
}
|
|
14124
|
+
syncText(world, entityId, text) {
|
|
14125
|
+
const size = resolveCanvasSize(text.width, text.height);
|
|
14126
|
+
const style = {
|
|
14127
|
+
fontSizeMeters: text.fontSize,
|
|
14128
|
+
fontWeight: text.fontWeight,
|
|
14129
|
+
color: text.color,
|
|
14130
|
+
align: text.align,
|
|
14131
|
+
valign: text.valign,
|
|
14132
|
+
lineHeight: text.lineHeight,
|
|
14133
|
+
paddingMeters: text.padding
|
|
14134
|
+
};
|
|
14135
|
+
const signature = textSignature(text.width, text.height, size, text.text, style);
|
|
14136
|
+
this.rebuildIfChanged(world, entityId, signature, text.width, text.height, size, (ctx) => {
|
|
14137
|
+
ctx.clearRect(0, 0, size.pxWidth, size.pxHeight);
|
|
14138
|
+
drawTextBlock(ctx, size.pxWidth, size.pxHeight, size.density, text.text, style);
|
|
14139
|
+
});
|
|
14140
|
+
}
|
|
14141
|
+
syncButton(world, entityId, button) {
|
|
14142
|
+
const size = resolveCanvasSize(button.width, button.height);
|
|
14143
|
+
const chrome = {
|
|
14144
|
+
backgroundColor: button.backgroundColor,
|
|
14145
|
+
backgroundOpacity: button.backgroundOpacity,
|
|
14146
|
+
cornerRadiusMeters: button.cornerRadius,
|
|
14147
|
+
borderWidthMeters: button.borderWidth,
|
|
14148
|
+
borderColor: button.borderColor
|
|
14149
|
+
};
|
|
14150
|
+
const label = {
|
|
14151
|
+
fontSizeMeters: button.fontSize,
|
|
14152
|
+
fontWeight: button.fontWeight,
|
|
14153
|
+
color: button.textColor,
|
|
14154
|
+
align: "center",
|
|
14155
|
+
valign: "middle",
|
|
14156
|
+
lineHeight: 1.2,
|
|
14157
|
+
paddingMeters: 0.01
|
|
14158
|
+
};
|
|
14159
|
+
const signature = buttonSignature(
|
|
14160
|
+
button.width,
|
|
14161
|
+
button.height,
|
|
14162
|
+
size,
|
|
14163
|
+
chrome,
|
|
14164
|
+
button.label,
|
|
14165
|
+
label
|
|
14166
|
+
);
|
|
14167
|
+
this.rebuildIfChanged(world, entityId, signature, button.width, button.height, size, (ctx) => {
|
|
14168
|
+
drawChrome(ctx, size.pxWidth, size.pxHeight, size.density, chrome);
|
|
14169
|
+
drawTextBlock(ctx, size.pxWidth, size.pxHeight, size.density, button.label, label);
|
|
14170
|
+
});
|
|
14171
|
+
}
|
|
14172
|
+
syncToggle(world, entityId, toggle, deltaTime) {
|
|
14173
|
+
const size = resolveCanvasSize(toggle.width, toggle.height);
|
|
14174
|
+
const chrome = {
|
|
14175
|
+
backgroundColor: toggle.value ? toggle.accentColor : toggle.trackColor,
|
|
14176
|
+
backgroundOpacity: 1,
|
|
14177
|
+
cornerRadiusMeters: toggle.height / 2,
|
|
14178
|
+
borderWidthMeters: 0,
|
|
14179
|
+
borderColor: "#000000"
|
|
14180
|
+
};
|
|
14181
|
+
const signature = JSON.stringify([
|
|
14182
|
+
trackSignature(
|
|
14183
|
+
toggle.width,
|
|
14184
|
+
toggle.height,
|
|
14185
|
+
size,
|
|
14186
|
+
chrome,
|
|
14187
|
+
toggle.accentColor,
|
|
14188
|
+
toggle.knobColor
|
|
14189
|
+
),
|
|
14190
|
+
toggle.value
|
|
14191
|
+
]);
|
|
14192
|
+
const entry = this.rebuildIfChanged(
|
|
14193
|
+
world,
|
|
14194
|
+
entityId,
|
|
14195
|
+
signature,
|
|
14196
|
+
toggle.width,
|
|
14197
|
+
toggle.height,
|
|
14198
|
+
size,
|
|
14199
|
+
(ctx) => {
|
|
14200
|
+
drawChrome(ctx, size.pxWidth, size.pxHeight, size.density, chrome);
|
|
14201
|
+
}
|
|
14202
|
+
);
|
|
14203
|
+
if (!entry) return;
|
|
14204
|
+
if (!entry.knob) {
|
|
14205
|
+
entry.knob = this.makeDisc(
|
|
14206
|
+
toggle.height * 0.4,
|
|
14207
|
+
toggle.knobColor,
|
|
14208
|
+
entry.face.parent,
|
|
14209
|
+
CHILD_Z
|
|
14210
|
+
);
|
|
14211
|
+
}
|
|
14212
|
+
const inset = toggle.height / 2;
|
|
14213
|
+
const target = toggle.value ? toggle.width / 2 - inset : -(toggle.width / 2 - inset);
|
|
14214
|
+
const knob = entry.knob;
|
|
14215
|
+
const ease = Math.min(1, deltaTime * 14);
|
|
14216
|
+
knob.position.x += (target - knob.position.x) * (deltaTime > 0 ? ease : 1);
|
|
14217
|
+
knob.position.z = CHILD_Z;
|
|
14218
|
+
}
|
|
14219
|
+
syncSlider(world, entityId, slider) {
|
|
14220
|
+
const size = resolveCanvasSize(slider.width, slider.height);
|
|
14221
|
+
const trackThickness = slider.height * 0.32;
|
|
14222
|
+
const knobRadius = slider.height * 0.45;
|
|
14223
|
+
const usable = Math.max(1e-3, slider.width - slider.height);
|
|
14224
|
+
const chrome = {
|
|
14225
|
+
backgroundColor: slider.trackColor,
|
|
14226
|
+
backgroundOpacity: 1,
|
|
14227
|
+
cornerRadiusMeters: trackThickness / 2,
|
|
14228
|
+
borderWidthMeters: 0,
|
|
14229
|
+
borderColor: "#000000"
|
|
14230
|
+
};
|
|
14231
|
+
const signature = trackSignature(
|
|
14232
|
+
slider.width,
|
|
14233
|
+
slider.height,
|
|
14234
|
+
size,
|
|
14235
|
+
chrome,
|
|
14236
|
+
slider.accentColor,
|
|
14237
|
+
slider.knobColor
|
|
14238
|
+
);
|
|
14239
|
+
const entry = this.rebuildIfChanged(
|
|
14240
|
+
world,
|
|
14241
|
+
entityId,
|
|
14242
|
+
signature,
|
|
14243
|
+
slider.width,
|
|
14244
|
+
slider.height,
|
|
14245
|
+
size,
|
|
14246
|
+
(ctx) => {
|
|
14247
|
+
ctx.clearRect(0, 0, size.pxWidth, size.pxHeight);
|
|
14248
|
+
const trackWidthM = usable + trackThickness;
|
|
14249
|
+
drawRoundedBar(
|
|
14250
|
+
ctx,
|
|
14251
|
+
(slider.width - trackWidthM) / 2 * size.density,
|
|
14252
|
+
(slider.height - trackThickness) / 2 * size.density,
|
|
14253
|
+
trackWidthM * size.density,
|
|
14254
|
+
trackThickness * size.density,
|
|
14255
|
+
slider.trackColor
|
|
14256
|
+
);
|
|
14257
|
+
}
|
|
14258
|
+
);
|
|
14259
|
+
if (!entry) return;
|
|
14260
|
+
if (!entry.fill) {
|
|
14261
|
+
entry.fill = this.makeQuad(
|
|
14262
|
+
1,
|
|
14263
|
+
trackThickness,
|
|
14264
|
+
slider.accentColor,
|
|
14265
|
+
entry.face.parent,
|
|
14266
|
+
CHILD_Z / 2
|
|
14267
|
+
);
|
|
14268
|
+
entry.cap = this.makeDisc(
|
|
14269
|
+
trackThickness / 2,
|
|
14270
|
+
slider.accentColor,
|
|
14271
|
+
entry.face.parent,
|
|
14272
|
+
CHILD_Z / 2,
|
|
14273
|
+
Math.PI / 2,
|
|
14274
|
+
Math.PI
|
|
14275
|
+
);
|
|
14276
|
+
entry.cap.position.x = -usable / 2;
|
|
14277
|
+
}
|
|
14278
|
+
if (!entry.knob) {
|
|
14279
|
+
entry.knob = this.makeDisc(
|
|
14280
|
+
knobRadius,
|
|
14281
|
+
slider.knobColor,
|
|
14282
|
+
entry.face.parent,
|
|
14283
|
+
CHILD_Z
|
|
14284
|
+
);
|
|
14285
|
+
}
|
|
14286
|
+
const range = Math.max(1e-6, slider.max - slider.min);
|
|
14287
|
+
const t = Math.min(1, Math.max(0, (slider.value - slider.min) / range));
|
|
14288
|
+
entry.knob.position.x = -usable / 2 + t * usable;
|
|
14289
|
+
entry.knob.position.z = CHILD_Z;
|
|
14290
|
+
entry.fill.scale.x = Math.max(1e-4, t * usable);
|
|
14291
|
+
entry.fill.position.x = -usable / 2 + t * usable / 2;
|
|
14292
|
+
entry.fill.position.z = CHILD_Z / 2;
|
|
14293
|
+
}
|
|
14294
|
+
// ── Machinery ──────────────────────────────────────────────────────────────
|
|
14295
|
+
rebuildIfChanged(world, entityId, signature, widthM, heightM, size, draw) {
|
|
14296
|
+
const root = world.getComponent(entityId, Object3DRef)?.object;
|
|
14297
|
+
if (!root) return null;
|
|
14298
|
+
let entry = this.entries.get(entityId);
|
|
14299
|
+
if (entry && entry.signature === signature) return entry;
|
|
14300
|
+
if (entry) this.disposeMovingParts(entry);
|
|
14301
|
+
if (!entry) {
|
|
14302
|
+
const canvas2 = this.createCanvas();
|
|
14303
|
+
const texture = new THREE56__namespace.CanvasTexture(
|
|
14304
|
+
canvas2
|
|
14305
|
+
);
|
|
14306
|
+
this.configureTexture(world, texture);
|
|
14307
|
+
const material = new THREE56__namespace.MeshBasicMaterial({
|
|
14308
|
+
map: texture,
|
|
14309
|
+
transparent: true,
|
|
14310
|
+
depthWrite: false,
|
|
14311
|
+
// UI colours are authored absolutes; scene tone mapping would shift
|
|
14312
|
+
// them (the classic "why is my white UI beige" bug).
|
|
14313
|
+
toneMapped: false,
|
|
14314
|
+
side: THREE56__namespace.DoubleSide,
|
|
14315
|
+
premultipliedAlpha: true
|
|
14316
|
+
});
|
|
14317
|
+
const face = new THREE56__namespace.Mesh(
|
|
14318
|
+
new THREE56__namespace.PlaneGeometry(widthM, heightM),
|
|
14319
|
+
material
|
|
14320
|
+
);
|
|
14321
|
+
face.renderOrder = FACE_RENDER_ORDER;
|
|
14322
|
+
root.add(face);
|
|
14323
|
+
entry = {
|
|
14324
|
+
signature: "",
|
|
14325
|
+
face,
|
|
14326
|
+
texture,
|
|
14327
|
+
material,
|
|
14328
|
+
canvas: canvas2,
|
|
14329
|
+
knob: null,
|
|
14330
|
+
fill: null,
|
|
14331
|
+
cap: null
|
|
14332
|
+
};
|
|
14333
|
+
this.entries.set(entityId, entry);
|
|
14334
|
+
}
|
|
14335
|
+
const { canvas } = entry;
|
|
14336
|
+
if (canvas.width !== size.pxWidth || canvas.height !== size.pxHeight) {
|
|
14337
|
+
canvas.width = size.pxWidth;
|
|
14338
|
+
canvas.height = size.pxHeight;
|
|
14339
|
+
}
|
|
14340
|
+
const params = entry.face.geometry.parameters;
|
|
14341
|
+
if (params.width !== widthM || params.height !== heightM) {
|
|
14342
|
+
entry.face.geometry.dispose();
|
|
14343
|
+
entry.face.geometry = new THREE56__namespace.PlaneGeometry(widthM, heightM);
|
|
14344
|
+
}
|
|
14345
|
+
const ctx = canvas.getContext("2d");
|
|
14346
|
+
if (ctx) draw(ctx);
|
|
14347
|
+
entry.texture.needsUpdate = true;
|
|
14348
|
+
entry.signature = signature;
|
|
14349
|
+
return entry;
|
|
14350
|
+
}
|
|
14351
|
+
configureTexture(world, texture) {
|
|
14352
|
+
texture.colorSpace = THREE56__namespace.SRGBColorSpace;
|
|
14353
|
+
texture.generateMipmaps = true;
|
|
14354
|
+
texture.minFilter = THREE56__namespace.LinearMipmapLinearFilter;
|
|
14355
|
+
texture.magFilter = THREE56__namespace.LinearFilter;
|
|
14356
|
+
texture.premultiplyAlpha = true;
|
|
14357
|
+
try {
|
|
14358
|
+
const max = world.getRenderer().capabilities?.getMaxAnisotropy?.();
|
|
14359
|
+
if (typeof max === "number") texture.anisotropy = Math.min(8, max);
|
|
14360
|
+
} catch {
|
|
14361
|
+
}
|
|
14362
|
+
}
|
|
14363
|
+
makeQuad(widthM, heightM, color, parent, z) {
|
|
14364
|
+
return this.addPart(
|
|
14365
|
+
new THREE56__namespace.PlaneGeometry(widthM, heightM),
|
|
14366
|
+
color,
|
|
14367
|
+
parent,
|
|
14368
|
+
z
|
|
14369
|
+
);
|
|
14370
|
+
}
|
|
14371
|
+
/** A filled disc (or arc segment, for the fill's rounded cap). */
|
|
14372
|
+
makeDisc(radiusM, color, parent, z, thetaStart = 0, thetaLength = Math.PI * 2) {
|
|
14373
|
+
return this.addPart(
|
|
14374
|
+
new THREE56__namespace.CircleGeometry(radiusM, 32, thetaStart, thetaLength),
|
|
14375
|
+
color,
|
|
14376
|
+
parent,
|
|
14377
|
+
z
|
|
14378
|
+
);
|
|
14379
|
+
}
|
|
14380
|
+
addPart(geometry, color, parent, z) {
|
|
14381
|
+
const mesh = new THREE56__namespace.Mesh(
|
|
14382
|
+
geometry,
|
|
14383
|
+
new THREE56__namespace.MeshBasicMaterial({
|
|
14384
|
+
color,
|
|
14385
|
+
transparent: true,
|
|
14386
|
+
depthWrite: false,
|
|
14387
|
+
toneMapped: false,
|
|
14388
|
+
side: THREE56__namespace.DoubleSide
|
|
14389
|
+
})
|
|
14390
|
+
);
|
|
14391
|
+
mesh.renderOrder = FACE_RENDER_ORDER + 1;
|
|
14392
|
+
mesh.position.z = z;
|
|
14393
|
+
mesh.raycast = () => {
|
|
14394
|
+
};
|
|
14395
|
+
parent?.add(mesh);
|
|
14396
|
+
return mesh;
|
|
14397
|
+
}
|
|
14398
|
+
/** Remove + dispose knob/fill/cap so a sync pass rebuilds them fresh. */
|
|
14399
|
+
disposeMovingParts(entry) {
|
|
14400
|
+
for (const key of ["knob", "fill", "cap"]) {
|
|
14401
|
+
const mesh = entry[key];
|
|
14402
|
+
if (!mesh) continue;
|
|
14403
|
+
mesh.removeFromParent();
|
|
14404
|
+
mesh.geometry.dispose();
|
|
14405
|
+
mesh.material.dispose();
|
|
14406
|
+
entry[key] = null;
|
|
14407
|
+
}
|
|
14408
|
+
}
|
|
14409
|
+
/**
|
|
14410
|
+
* Billboard: yaw the ENTITY TRANSFORM toward the camera. Writing the
|
|
14411
|
+
* Object3D directly would be overwritten by `TransformSyncSystem` (which
|
|
14412
|
+
* runs after this system, before render) — the same reason locomotion
|
|
14413
|
+
* writes the rig transform. Skipped in the editor so the gizmo and the
|
|
14414
|
+
* authored rotation stay in charge while authoring.
|
|
14415
|
+
*/
|
|
14416
|
+
applyFollow(world, entityId, panel) {
|
|
14417
|
+
if (panel.follow !== "billboard" || world.isEditorMode()) return;
|
|
14418
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
14419
|
+
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
14420
|
+
if (!transform || !object) return;
|
|
14421
|
+
const camera = world.getCamera();
|
|
14422
|
+
const cam = new THREE56__namespace.Vector3();
|
|
14423
|
+
const self = new THREE56__namespace.Vector3();
|
|
14424
|
+
camera.getWorldPosition(cam);
|
|
14425
|
+
object.getWorldPosition(self);
|
|
14426
|
+
transform.rotation.y = Math.atan2(cam.x - self.x, cam.z - self.z);
|
|
14427
|
+
}
|
|
14428
|
+
destroyEntry(entry) {
|
|
14429
|
+
this.disposeMovingParts(entry);
|
|
14430
|
+
entry.face.removeFromParent();
|
|
14431
|
+
entry.face.geometry.dispose();
|
|
14432
|
+
entry.face.material.dispose();
|
|
14433
|
+
entry.texture.dispose();
|
|
14434
|
+
}
|
|
14435
|
+
};
|
|
14436
|
+
__name(_UIPanelSystem, "UIPanelSystem");
|
|
14437
|
+
var UIPanelSystem = _UIPanelSystem;
|
|
12966
14438
|
var _XRHitTestSystem = class _XRHitTestSystem {
|
|
12967
14439
|
constructor() {
|
|
12968
14440
|
this.sources = /* @__PURE__ */ new Map();
|
|
@@ -12999,12 +14471,12 @@ var _XRHitTestSystem = class _XRHitTestSystem {
|
|
|
12999
14471
|
if (!hits || hits.length === 0) continue;
|
|
13000
14472
|
const pose = hits[0].getPose(referenceSpace);
|
|
13001
14473
|
if (!pose) continue;
|
|
13002
|
-
const matrix = new
|
|
14474
|
+
const matrix = new THREE56__namespace.Matrix4().fromArray(
|
|
13003
14475
|
pose.transform.matrix
|
|
13004
14476
|
);
|
|
13005
|
-
const position = new
|
|
13006
|
-
const quaternion = new
|
|
13007
|
-
matrix.decompose(position, quaternion, new
|
|
14477
|
+
const position = new THREE56__namespace.Vector3();
|
|
14478
|
+
const quaternion = new THREE56__namespace.Quaternion();
|
|
14479
|
+
matrix.decompose(position, quaternion, new THREE56__namespace.Vector3());
|
|
13008
14480
|
this.results.set(key, { position, quaternion });
|
|
13009
14481
|
}
|
|
13010
14482
|
}
|
|
@@ -13075,9 +14547,13 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13075
14547
|
this.anchors = /* @__PURE__ */ new Map();
|
|
13076
14548
|
/** In-flight creations, so one entity is not anchored twice. */
|
|
13077
14549
|
this.pending = /* @__PURE__ */ new Set();
|
|
14550
|
+
/** Per-anchor head-glue gates — see XREnvironmentSystem's TrackedEntry. */
|
|
14551
|
+
this.gates = /* @__PURE__ */ new Map();
|
|
13078
14552
|
this.presenting = false;
|
|
14553
|
+
this.tmpViewerMatrix = new THREE56__namespace.Matrix4();
|
|
14554
|
+
this.tmpViewPos = new THREE56__namespace.Vector3();
|
|
13079
14555
|
}
|
|
13080
|
-
update(world) {
|
|
14556
|
+
update(world, deltaTime = 0) {
|
|
13081
14557
|
const presenting = world.isXrPresenting();
|
|
13082
14558
|
if (!presenting) {
|
|
13083
14559
|
if (this.presenting) {
|
|
@@ -13097,8 +14573,11 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13097
14573
|
if (!live.has(entityId)) {
|
|
13098
14574
|
anchor.delete?.();
|
|
13099
14575
|
this.anchors.delete(entityId);
|
|
14576
|
+
this.gates.delete(entityId);
|
|
13100
14577
|
}
|
|
13101
14578
|
}
|
|
14579
|
+
const viewer = frame.getViewerPose?.(referenceSpace);
|
|
14580
|
+
const viewerInverse = viewer ? this.tmpViewerMatrix.fromArray(viewer.transform.matrix).invert() : null;
|
|
13102
14581
|
for (const entityId of entityIds) {
|
|
13103
14582
|
const component = world.getComponent(entityId, XRAnchorComponent);
|
|
13104
14583
|
const transform = world.getComponent(entityId, TransformComponent);
|
|
@@ -13108,6 +14587,7 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13108
14587
|
if (existing) {
|
|
13109
14588
|
existing.delete?.();
|
|
13110
14589
|
this.anchors.delete(entityId);
|
|
14590
|
+
this.gates.delete(entityId);
|
|
13111
14591
|
}
|
|
13112
14592
|
continue;
|
|
13113
14593
|
}
|
|
@@ -13118,7 +14598,21 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13118
14598
|
}
|
|
13119
14599
|
const pose = frame.getPose(anchor.anchorSpace, referenceSpace);
|
|
13120
14600
|
if (pose && pose.emulatedPosition !== true) {
|
|
13121
|
-
|
|
14601
|
+
let gate = this.gates.get(entityId);
|
|
14602
|
+
if (!gate) {
|
|
14603
|
+
gate = new SurfacePoseGate();
|
|
14604
|
+
this.gates.set(entityId, gate);
|
|
14605
|
+
}
|
|
14606
|
+
const m = pose.transform.matrix;
|
|
14607
|
+
const refPos = { x: m[12], y: m[13], z: m[14] };
|
|
14608
|
+
let viewPos = null;
|
|
14609
|
+
if (viewerInverse) {
|
|
14610
|
+
const v = this.tmpViewPos.set(refPos.x, refPos.y, refPos.z).applyMatrix4(viewerInverse);
|
|
14611
|
+
viewPos = { x: v.x, y: v.y, z: v.z };
|
|
14612
|
+
}
|
|
14613
|
+
if (gate.update(refPos, viewPos, deltaTime)) {
|
|
14614
|
+
decomposeXrPose(pose.transform.matrix, transform);
|
|
14615
|
+
}
|
|
13122
14616
|
}
|
|
13123
14617
|
}
|
|
13124
14618
|
}
|
|
@@ -13131,8 +14625,8 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13131
14625
|
if (typeof frame.createAnchor !== "function") return;
|
|
13132
14626
|
const RigidTransform = globalThis.XRRigidTransform;
|
|
13133
14627
|
if (!RigidTransform) return;
|
|
13134
|
-
const quaternion = new
|
|
13135
|
-
new
|
|
14628
|
+
const quaternion = new THREE56__namespace.Quaternion().setFromEuler(
|
|
14629
|
+
new THREE56__namespace.Euler(
|
|
13136
14630
|
transform.rotation.x,
|
|
13137
14631
|
transform.rotation.y,
|
|
13138
14632
|
transform.rotation.z,
|
|
@@ -13163,6 +14657,7 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13163
14657
|
}).finally(() => this.pending.delete(entityId));
|
|
13164
14658
|
}
|
|
13165
14659
|
releaseAll() {
|
|
14660
|
+
this.gates.clear();
|
|
13166
14661
|
for (const anchor of this.anchors.values()) anchor.delete?.();
|
|
13167
14662
|
this.anchors.clear();
|
|
13168
14663
|
this.pending.clear();
|
|
@@ -13177,9 +14672,9 @@ var XRAnchorSystem = _XRAnchorSystem;
|
|
|
13177
14672
|
function buildGeometry2(area) {
|
|
13178
14673
|
if (area.shape === "circle") {
|
|
13179
14674
|
const radius = Math.max(5e-3, area.width / 2);
|
|
13180
|
-
return new
|
|
14675
|
+
return new THREE56__namespace.CircleGeometry(radius, 48);
|
|
13181
14676
|
}
|
|
13182
|
-
return new
|
|
14677
|
+
return new THREE56__namespace.PlaneGeometry(
|
|
13183
14678
|
Math.max(0.01, area.width),
|
|
13184
14679
|
Math.max(0.01, area.depth)
|
|
13185
14680
|
);
|
|
@@ -13202,7 +14697,7 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
13202
14697
|
for (const entityId of entityIds) {
|
|
13203
14698
|
const area = world.getComponent(entityId, VRTeleportAreaComponent);
|
|
13204
14699
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
13205
|
-
if (!area || !(object instanceof
|
|
14700
|
+
if (!area || !(object instanceof THREE56__namespace.Mesh)) continue;
|
|
13206
14701
|
const signature = signatureOf(area);
|
|
13207
14702
|
if (this.signatures.get(entityId) === signature) continue;
|
|
13208
14703
|
this.signatures.set(entityId, signature);
|
|
@@ -13214,18 +14709,18 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
13214
14709
|
__name(_VRTeleportAreaSystem, "VRTeleportAreaSystem");
|
|
13215
14710
|
var VRTeleportAreaSystem = _VRTeleportAreaSystem;
|
|
13216
14711
|
function createHandMaterial(preset, options) {
|
|
13217
|
-
const color = new
|
|
14712
|
+
const color = new THREE56__namespace.Color(options.color);
|
|
13218
14713
|
switch (preset) {
|
|
13219
14714
|
case "ghost":
|
|
13220
|
-
return new
|
|
14715
|
+
return new THREE56__namespace.MeshBasicMaterial({
|
|
13221
14716
|
color,
|
|
13222
14717
|
transparent: true,
|
|
13223
14718
|
opacity: Math.min(1, Math.max(0.05, options.opacity * 0.45)),
|
|
13224
14719
|
depthWrite: false,
|
|
13225
|
-
side:
|
|
14720
|
+
side: THREE56__namespace.DoubleSide
|
|
13226
14721
|
});
|
|
13227
14722
|
case "neon":
|
|
13228
|
-
return new
|
|
14723
|
+
return new THREE56__namespace.MeshStandardMaterial({
|
|
13229
14724
|
color,
|
|
13230
14725
|
emissive: color,
|
|
13231
14726
|
emissiveIntensity: Math.max(0.5, options.emissiveIntensity || 2),
|
|
@@ -13235,7 +14730,7 @@ function createHandMaterial(preset, options) {
|
|
|
13235
14730
|
opacity: options.opacity
|
|
13236
14731
|
});
|
|
13237
14732
|
case "skeleton":
|
|
13238
|
-
return new
|
|
14733
|
+
return new THREE56__namespace.MeshBasicMaterial({
|
|
13239
14734
|
color,
|
|
13240
14735
|
wireframe: true,
|
|
13241
14736
|
transparent: true,
|
|
@@ -13243,7 +14738,7 @@ function createHandMaterial(preset, options) {
|
|
|
13243
14738
|
});
|
|
13244
14739
|
case "custom":
|
|
13245
14740
|
case "default":
|
|
13246
|
-
return new
|
|
14741
|
+
return new THREE56__namespace.MeshStandardMaterial({
|
|
13247
14742
|
color,
|
|
13248
14743
|
roughness: 0.85,
|
|
13249
14744
|
metalness: 0,
|
|
@@ -13251,10 +14746,10 @@ function createHandMaterial(preset, options) {
|
|
|
13251
14746
|
emissiveIntensity: Math.max(0, options.emissiveIntensity),
|
|
13252
14747
|
transparent: options.opacity < 1,
|
|
13253
14748
|
opacity: options.opacity,
|
|
13254
|
-
side:
|
|
14749
|
+
side: THREE56__namespace.DoubleSide
|
|
13255
14750
|
});
|
|
13256
14751
|
default: {
|
|
13257
|
-
return new
|
|
14752
|
+
return new THREE56__namespace.MeshStandardMaterial({ color });
|
|
13258
14753
|
}
|
|
13259
14754
|
}
|
|
13260
14755
|
}
|
|
@@ -13279,9 +14774,9 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
13279
14774
|
constructor(options) {
|
|
13280
14775
|
this.controllerModelFactory = new XRControllerModelFactory_js.XRControllerModelFactory();
|
|
13281
14776
|
this.handModelFactory = new XRHandModelFactory_js.XRHandModelFactory();
|
|
13282
|
-
this.group = new
|
|
14777
|
+
this.group = new THREE56__namespace.Group();
|
|
13283
14778
|
/** Reused so a per-frame colour compare allocates nothing. */
|
|
13284
|
-
this.rayColorScratch = new
|
|
14779
|
+
this.rayColorScratch = new THREE56__namespace.Color();
|
|
13285
14780
|
this.slots = /* @__PURE__ */ new Map();
|
|
13286
14781
|
this.attachedTo = null;
|
|
13287
14782
|
/** Last applied preset signature, so materials rebuild only on real change. */
|
|
@@ -13468,17 +14963,17 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
13468
14963
|
* without pulling in a line-rendering extension.
|
|
13469
14964
|
*/
|
|
13470
14965
|
createRay() {
|
|
13471
|
-
const geometry = new
|
|
14966
|
+
const geometry = new THREE56__namespace.CylinderGeometry(RAY_RADIUS, RAY_RADIUS, 1, 8, 1);
|
|
13472
14967
|
geometry.rotateX(-Math.PI / 2);
|
|
13473
14968
|
geometry.translate(0, 0, -0.5);
|
|
13474
|
-
const material = new
|
|
14969
|
+
const material = new THREE56__namespace.MeshBasicMaterial({
|
|
13475
14970
|
color: "#4da3ff",
|
|
13476
14971
|
transparent: true,
|
|
13477
14972
|
opacity: 0.75,
|
|
13478
14973
|
depthTest: false,
|
|
13479
14974
|
depthWrite: false
|
|
13480
14975
|
});
|
|
13481
|
-
const mesh = new
|
|
14976
|
+
const mesh = new THREE56__namespace.Mesh(geometry, material);
|
|
13482
14977
|
mesh.name = "XRPointerRay";
|
|
13483
14978
|
mesh.renderOrder = 999;
|
|
13484
14979
|
mesh.visible = false;
|
|
@@ -13509,14 +15004,14 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
13509
15004
|
__name(_XRControllerVisualSystem, "XRControllerVisualSystem");
|
|
13510
15005
|
var XRControllerVisualSystem = _XRControllerVisualSystem;
|
|
13511
15006
|
var MARKER_RADIUS = 0.28;
|
|
13512
|
-
var ACCENT = new
|
|
13513
|
-
var SEGMENT_AXIS = new
|
|
15007
|
+
var ACCENT = new THREE56__namespace.Color("#4da3ff");
|
|
15008
|
+
var SEGMENT_AXIS = new THREE56__namespace.Vector3(0, 1, 0);
|
|
13514
15009
|
var HEAD_CLEARANCE = 0.25;
|
|
13515
15010
|
var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
13516
15011
|
constructor(locomotionSystem) {
|
|
13517
|
-
this.group = new
|
|
15012
|
+
this.group = new THREE56__namespace.Group();
|
|
13518
15013
|
/** Holds the segment chain that draws the arc. */
|
|
13519
|
-
this.arc = new
|
|
15014
|
+
this.arc = new THREE56__namespace.Group();
|
|
13520
15015
|
/**
|
|
13521
15016
|
* Unit cylinder along +Y, reused by every segment.
|
|
13522
15017
|
*
|
|
@@ -13525,14 +15020,14 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
13525
15020
|
* scaled cylinders gives real thickness while rebuilding no geometry: each
|
|
13526
15021
|
* frame only moves, rotates and scales meshes that already exist.
|
|
13527
15022
|
*/
|
|
13528
|
-
this.segmentGeometry = new
|
|
15023
|
+
this.segmentGeometry = new THREE56__namespace.CylinderGeometry(1, 1, 1, 6, 1);
|
|
13529
15024
|
this.segments = [];
|
|
13530
|
-
this.marker = new
|
|
15025
|
+
this.marker = new THREE56__namespace.Group();
|
|
13531
15026
|
this.attached = false;
|
|
13532
|
-
this.scratchDirection = new
|
|
13533
|
-
this.scratchHead = new
|
|
13534
|
-
this.validColor = new
|
|
13535
|
-
this.invalidColor = new
|
|
15027
|
+
this.scratchDirection = new THREE56__namespace.Vector3();
|
|
15028
|
+
this.scratchHead = new THREE56__namespace.Vector3();
|
|
15029
|
+
this.validColor = new THREE56__namespace.Color();
|
|
15030
|
+
this.invalidColor = new THREE56__namespace.Color();
|
|
13536
15031
|
this.locomotionSystem = locomotionSystem;
|
|
13537
15032
|
this.group.name = "XRTeleportVisuals";
|
|
13538
15033
|
this.group.userData.ecsPreviewHidden = true;
|
|
@@ -13610,12 +15105,12 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
13610
15105
|
/** Grow the segment pool to cover the current arc. */
|
|
13611
15106
|
ensureSegments(count) {
|
|
13612
15107
|
while (this.segments.length < count) {
|
|
13613
|
-
const material = new
|
|
15108
|
+
const material = new THREE56__namespace.MeshBasicMaterial({
|
|
13614
15109
|
transparent: true,
|
|
13615
15110
|
depthTest: false,
|
|
13616
15111
|
depthWrite: false
|
|
13617
15112
|
});
|
|
13618
|
-
const mesh = new
|
|
15113
|
+
const mesh = new THREE56__namespace.Mesh(this.segmentGeometry, material);
|
|
13619
15114
|
mesh.frustumCulled = false;
|
|
13620
15115
|
mesh.renderOrder = 998;
|
|
13621
15116
|
mesh.raycast = () => {
|
|
@@ -13639,33 +15134,33 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
13639
15134
|
return world.getComponent(entityId, XRRigComponent) ?? null;
|
|
13640
15135
|
}
|
|
13641
15136
|
createRing() {
|
|
13642
|
-
const geometry = new
|
|
15137
|
+
const geometry = new THREE56__namespace.RingGeometry(
|
|
13643
15138
|
MARKER_RADIUS * 0.72,
|
|
13644
15139
|
MARKER_RADIUS,
|
|
13645
15140
|
48
|
|
13646
15141
|
);
|
|
13647
15142
|
geometry.rotateX(-Math.PI / 2);
|
|
13648
|
-
return new
|
|
15143
|
+
return new THREE56__namespace.Mesh(
|
|
13649
15144
|
geometry,
|
|
13650
|
-
new
|
|
15145
|
+
new THREE56__namespace.MeshBasicMaterial({
|
|
13651
15146
|
color: ACCENT,
|
|
13652
15147
|
transparent: true,
|
|
13653
15148
|
opacity: 0.9,
|
|
13654
|
-
side:
|
|
15149
|
+
side: THREE56__namespace.DoubleSide,
|
|
13655
15150
|
depthTest: false
|
|
13656
15151
|
})
|
|
13657
15152
|
);
|
|
13658
15153
|
}
|
|
13659
15154
|
createDot() {
|
|
13660
|
-
const geometry = new
|
|
15155
|
+
const geometry = new THREE56__namespace.CircleGeometry(MARKER_RADIUS * 0.16, 24);
|
|
13661
15156
|
geometry.rotateX(-Math.PI / 2);
|
|
13662
|
-
return new
|
|
15157
|
+
return new THREE56__namespace.Mesh(
|
|
13663
15158
|
geometry,
|
|
13664
|
-
new
|
|
15159
|
+
new THREE56__namespace.MeshBasicMaterial({
|
|
13665
15160
|
color: ACCENT,
|
|
13666
15161
|
transparent: true,
|
|
13667
15162
|
opacity: 0.55,
|
|
13668
|
-
side:
|
|
15163
|
+
side: THREE56__namespace.DoubleSide,
|
|
13669
15164
|
depthTest: false
|
|
13670
15165
|
})
|
|
13671
15166
|
);
|
|
@@ -13776,7 +15271,7 @@ function boneDirections(joints, finger) {
|
|
|
13776
15271
|
const from = joints[chain[i - 1]];
|
|
13777
15272
|
const to = joints[chain[i]];
|
|
13778
15273
|
if (!from || !to) return null;
|
|
13779
|
-
const direction = new
|
|
15274
|
+
const direction = new THREE56__namespace.Vector3().subVectors(to, from);
|
|
13780
15275
|
if (direction.lengthSq() < 1e-12) return null;
|
|
13781
15276
|
directions.push(direction.normalize());
|
|
13782
15277
|
}
|
|
@@ -13849,8 +15344,8 @@ function computeSpread(joints, a, b) {
|
|
|
13849
15344
|
const bBase = joints[METACARPAL_JOINTS[b]];
|
|
13850
15345
|
const bTip = joints[TIP_JOINTS[b]];
|
|
13851
15346
|
if (!aBase || !aTip || !bBase || !bTip) return null;
|
|
13852
|
-
const dirA = new
|
|
13853
|
-
const dirB = new
|
|
15347
|
+
const dirA = new THREE56__namespace.Vector3().subVectors(aTip, aBase);
|
|
15348
|
+
const dirB = new THREE56__namespace.Vector3().subVectors(bTip, bBase);
|
|
13854
15349
|
if (dirA.lengthSq() < 1e-12 || dirB.lengthSq() < 1e-12) return null;
|
|
13855
15350
|
return clamp01((1 - dirA.normalize().dot(dirB.normalize())) / 0.45);
|
|
13856
15351
|
}
|
|
@@ -13860,18 +15355,18 @@ function computePalmPose(joints, handedness) {
|
|
|
13860
15355
|
const indexBase = joints["index-finger-metacarpal"];
|
|
13861
15356
|
const pinkyBase = joints["pinky-finger-metacarpal"];
|
|
13862
15357
|
if (!wrist || !indexBase || !pinkyBase) return null;
|
|
13863
|
-
const u = new
|
|
13864
|
-
const v = new
|
|
13865
|
-
const normal = new
|
|
15358
|
+
const u = new THREE56__namespace.Vector3().subVectors(indexBase, wrist);
|
|
15359
|
+
const v = new THREE56__namespace.Vector3().subVectors(pinkyBase, wrist);
|
|
15360
|
+
const normal = new THREE56__namespace.Vector3().crossVectors(u, v);
|
|
13866
15361
|
if (normal.lengthSq() < 1e-12) return null;
|
|
13867
15362
|
normal.normalize();
|
|
13868
15363
|
if (handedness === "left") normal.multiplyScalar(-1);
|
|
13869
|
-
const right = new
|
|
15364
|
+
const right = new THREE56__namespace.Vector3().subVectors(indexBase, pinkyBase);
|
|
13870
15365
|
if (right.lengthSq() < 1e-12) return null;
|
|
13871
15366
|
right.normalize();
|
|
13872
15367
|
if (handedness === "left") right.multiplyScalar(-1);
|
|
13873
|
-
const up = new
|
|
13874
|
-
const center = new
|
|
15368
|
+
const up = new THREE56__namespace.Vector3().crossVectors(normal, right).normalize();
|
|
15369
|
+
const center = new THREE56__namespace.Vector3().add(wrist).add(indexBase).add(pinkyBase).divideScalar(3);
|
|
13875
15370
|
return {
|
|
13876
15371
|
center,
|
|
13877
15372
|
normal,
|
|
@@ -13902,7 +15397,7 @@ function computeHandShape(joints, handedness) {
|
|
|
13902
15397
|
const thumbTip = joints["thumb-tip"];
|
|
13903
15398
|
let thumbDirection = null;
|
|
13904
15399
|
if (thumbBase && thumbTip) {
|
|
13905
|
-
const direction = new
|
|
15400
|
+
const direction = new THREE56__namespace.Vector3().subVectors(thumbTip, thumbBase);
|
|
13906
15401
|
if (direction.lengthSq() > 1e-12) thumbDirection = direction.normalize();
|
|
13907
15402
|
}
|
|
13908
15403
|
const fingerDirections = {};
|
|
@@ -13913,7 +15408,7 @@ function computeHandShape(joints, handedness) {
|
|
|
13913
15408
|
fingerDirections[finger] = null;
|
|
13914
15409
|
continue;
|
|
13915
15410
|
}
|
|
13916
|
-
const direction = new
|
|
15411
|
+
const direction = new THREE56__namespace.Vector3().subVectors(tip, base);
|
|
13917
15412
|
fingerDirections[finger] = direction.lengthSq() > 1e-12 ? direction.normalize() : null;
|
|
13918
15413
|
}
|
|
13919
15414
|
return {
|
|
@@ -13947,12 +15442,12 @@ function scoreAgainst(actual, target, tolerance) {
|
|
|
13947
15442
|
__name(scoreAgainst, "scoreAgainst");
|
|
13948
15443
|
var DEFAULT_DIRECTION_TOLERANCE = 45;
|
|
13949
15444
|
var WORLD_DIRECTIONS = {
|
|
13950
|
-
up: new
|
|
13951
|
-
down: new
|
|
13952
|
-
forward: new
|
|
13953
|
-
back: new
|
|
13954
|
-
left: new
|
|
13955
|
-
right: new
|
|
15445
|
+
up: new THREE56__namespace.Vector3(0, 1, 0),
|
|
15446
|
+
down: new THREE56__namespace.Vector3(0, -1, 0),
|
|
15447
|
+
forward: new THREE56__namespace.Vector3(0, 0, -1),
|
|
15448
|
+
back: new THREE56__namespace.Vector3(0, 0, 1),
|
|
15449
|
+
left: new THREE56__namespace.Vector3(-1, 0, 0),
|
|
15450
|
+
right: new THREE56__namespace.Vector3(1, 0, 0)
|
|
13956
15451
|
};
|
|
13957
15452
|
function axisVector(shape, axis) {
|
|
13958
15453
|
if (axis === "thumb") return shape.thumbDirection;
|
|
@@ -13967,7 +15462,7 @@ function resolveDirection(direction, shape, context) {
|
|
|
13967
15462
|
const head = context?.headPosition;
|
|
13968
15463
|
const origin = shape.palm?.center;
|
|
13969
15464
|
if (!head || !origin) return null;
|
|
13970
|
-
const toHead = new
|
|
15465
|
+
const toHead = new THREE56__namespace.Vector3().subVectors(head, origin);
|
|
13971
15466
|
if (toHead.lengthSq() < 1e-12) return null;
|
|
13972
15467
|
toHead.normalize();
|
|
13973
15468
|
return direction === "toward-head" ? toHead : toHead.multiplyScalar(-1);
|
|
@@ -13979,8 +15474,8 @@ function scoreDirections(actual, accepted, shape, toleranceDegrees, context) {
|
|
|
13979
15474
|
for (const direction of accepted) {
|
|
13980
15475
|
const wanted = resolveDirection(direction, shape, context);
|
|
13981
15476
|
if (!wanted) continue;
|
|
13982
|
-
const angle =
|
|
13983
|
-
Math.acos(
|
|
15477
|
+
const angle = THREE56__namespace.MathUtils.radToDeg(
|
|
15478
|
+
Math.acos(THREE56__namespace.MathUtils.clamp(actual.dot(wanted), -1, 1))
|
|
13984
15479
|
);
|
|
13985
15480
|
const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
|
|
13986
15481
|
const score = clamp01(1 - normalizedError / MATCH_FALLOFF);
|
|
@@ -14045,8 +15540,8 @@ function matchHandPose(shape, definition, context) {
|
|
|
14045
15540
|
if (!handAxis || !wanted) {
|
|
14046
15541
|
consider(0, "orientation");
|
|
14047
15542
|
} else {
|
|
14048
|
-
const angle =
|
|
14049
|
-
Math.acos(
|
|
15543
|
+
const angle = THREE56__namespace.MathUtils.radToDeg(
|
|
15544
|
+
Math.acos(THREE56__namespace.MathUtils.clamp(handAxis.dot(wanted), -1, 1))
|
|
14050
15545
|
);
|
|
14051
15546
|
const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
|
|
14052
15547
|
consider(clamp01(1 - normalizedError / MATCH_FALLOFF), "orientation");
|
|
@@ -14124,7 +15619,7 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
14124
15619
|
this.trackers = /* @__PURE__ */ new Map();
|
|
14125
15620
|
this.shapes = /* @__PURE__ */ new Map();
|
|
14126
15621
|
/** Reused so head-relative orientation checks allocate nothing per frame. */
|
|
14127
|
-
this.headPosition = new
|
|
15622
|
+
this.headPosition = new THREE56__namespace.Vector3();
|
|
14128
15623
|
this.elapsed = 0;
|
|
14129
15624
|
this.warnedNoHands = false;
|
|
14130
15625
|
this.noHandSeconds = 0;
|
|
@@ -14301,7 +15796,7 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
14301
15796
|
const wantsColor = interactable.hoverBehavior === "color" || interactable.hoverBehavior === "both";
|
|
14302
15797
|
this.records.set(entityId, {
|
|
14303
15798
|
shell: wantsColor ? this.addShell(world, entityId, interactable) : null,
|
|
14304
|
-
baseScale: new
|
|
15799
|
+
baseScale: new THREE56__namespace.Vector3(
|
|
14305
15800
|
transform.scale.x,
|
|
14306
15801
|
transform.scale.y,
|
|
14307
15802
|
transform.scale.z
|
|
@@ -14314,27 +15809,27 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
14314
15809
|
addShell(world, entityId, interactable) {
|
|
14315
15810
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
14316
15811
|
if (!object) return null;
|
|
14317
|
-
const material = new
|
|
14318
|
-
color: new
|
|
15812
|
+
const material = new THREE56__namespace.MeshBasicMaterial({
|
|
15813
|
+
color: new THREE56__namespace.Color(interactable.hoverColor),
|
|
14319
15814
|
// Back faces only, so the shell shows just outside the silhouette instead
|
|
14320
15815
|
// of covering the object.
|
|
14321
|
-
side:
|
|
15816
|
+
side: THREE56__namespace.BackSide,
|
|
14322
15817
|
transparent: true,
|
|
14323
15818
|
opacity: 0.85,
|
|
14324
15819
|
depthWrite: false
|
|
14325
15820
|
});
|
|
14326
|
-
const group = new
|
|
15821
|
+
const group = new THREE56__namespace.Group();
|
|
14327
15822
|
group.name = "XRHoverShell";
|
|
14328
15823
|
group.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
14329
15824
|
group.renderOrder = 998;
|
|
14330
15825
|
object.traverse((child) => {
|
|
14331
|
-
if (!(child instanceof
|
|
15826
|
+
if (!(child instanceof THREE56__namespace.Mesh) || !child.geometry) return;
|
|
14332
15827
|
if (child.userData[XR_HOVER_SHELL_FLAG]) return;
|
|
14333
|
-
const clone3 = new
|
|
15828
|
+
const clone3 = new THREE56__namespace.Mesh(child.geometry, material);
|
|
14334
15829
|
child.updateWorldMatrix(true, false);
|
|
14335
15830
|
object.updateWorldMatrix(true, false);
|
|
14336
15831
|
clone3.matrixAutoUpdate = false;
|
|
14337
|
-
clone3.matrix.copy(object.matrixWorld).invert().multiply(child.matrixWorld).scale(new
|
|
15832
|
+
clone3.matrix.copy(object.matrixWorld).invert().multiply(child.matrixWorld).scale(new THREE56__namespace.Vector3(SHELL_INFLATE, SHELL_INFLATE, SHELL_INFLATE));
|
|
14338
15833
|
clone3.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
14339
15834
|
clone3.raycast = () => {
|
|
14340
15835
|
};
|
|
@@ -14383,7 +15878,7 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
14383
15878
|
if (!shell) return;
|
|
14384
15879
|
shell.parent?.remove(shell);
|
|
14385
15880
|
shell.traverse((child) => {
|
|
14386
|
-
if (child instanceof
|
|
15881
|
+
if (child instanceof THREE56__namespace.Mesh) {
|
|
14387
15882
|
const material = child.material;
|
|
14388
15883
|
if (Array.isArray(material)) {
|
|
14389
15884
|
for (const entry of material) entry.dispose();
|
|
@@ -14753,6 +16248,7 @@ var _World = class _World {
|
|
|
14753
16248
|
const lightSyncSystem = new LightSyncSystem();
|
|
14754
16249
|
const materialSyncSystem = new MaterialSyncSystem();
|
|
14755
16250
|
const vrTeleportAreaSystem = new VRTeleportAreaSystem();
|
|
16251
|
+
const uiPanelSystem = new UIPanelSystem();
|
|
14756
16252
|
const physicsSyncSystem = new PhysicsSyncSystem({
|
|
14757
16253
|
isEditor: isEditor ?? false
|
|
14758
16254
|
});
|
|
@@ -14783,6 +16279,7 @@ var _World = class _World {
|
|
|
14783
16279
|
this.addSystems([
|
|
14784
16280
|
...coreSystems,
|
|
14785
16281
|
vrTeleportAreaSystem,
|
|
16282
|
+
uiPanelSystem,
|
|
14786
16283
|
physicsSyncSystem,
|
|
14787
16284
|
...systems,
|
|
14788
16285
|
objectVisibilitySystem,
|
|
@@ -15095,8 +16592,8 @@ var _World = class _World {
|
|
|
15095
16592
|
* ```
|
|
15096
16593
|
*/
|
|
15097
16594
|
raycast(origin, direction, near = 0, far = Infinity) {
|
|
15098
|
-
const rayOrigin = new
|
|
15099
|
-
const rayDirection = new
|
|
16595
|
+
const rayOrigin = new THREE56__namespace.Vector3(origin.x, origin.y, origin.z);
|
|
16596
|
+
const rayDirection = new THREE56__namespace.Vector3(
|
|
15100
16597
|
direction.x,
|
|
15101
16598
|
direction.y,
|
|
15102
16599
|
direction.z
|
|
@@ -15105,7 +16602,7 @@ var _World = class _World {
|
|
|
15105
16602
|
return [];
|
|
15106
16603
|
}
|
|
15107
16604
|
rayDirection.normalize();
|
|
15108
|
-
const raycaster = new
|
|
16605
|
+
const raycaster = new THREE56__namespace.Raycaster(rayOrigin, rayDirection, near, far);
|
|
15109
16606
|
const intersections = raycaster.intersectObjects(
|
|
15110
16607
|
this.scene.children,
|
|
15111
16608
|
true
|
|
@@ -15139,14 +16636,14 @@ var _World = class _World {
|
|
|
15139
16636
|
if (!sourceObject) {
|
|
15140
16637
|
return [];
|
|
15141
16638
|
}
|
|
15142
|
-
const rayOrigin = new
|
|
15143
|
-
const rayDirection = new
|
|
16639
|
+
const rayOrigin = new THREE56__namespace.Vector3();
|
|
16640
|
+
const rayDirection = new THREE56__namespace.Vector3();
|
|
15144
16641
|
sourceObject.getWorldPosition(rayOrigin);
|
|
15145
16642
|
sourceObject.getWorldDirection(rayDirection);
|
|
15146
16643
|
if (rayDirection.lengthSq() === 0) {
|
|
15147
16644
|
return [];
|
|
15148
16645
|
}
|
|
15149
|
-
const raycaster = new
|
|
16646
|
+
const raycaster = new THREE56__namespace.Raycaster(rayOrigin, rayDirection, near, far);
|
|
15150
16647
|
const intersections = raycaster.intersectObjects(
|
|
15151
16648
|
this.scene.children,
|
|
15152
16649
|
true
|
|
@@ -15853,6 +17350,8 @@ exports.ScriptObjectSystem = ScriptObjectSystem;
|
|
|
15853
17350
|
exports.TeleportAimGate = TeleportAimGate;
|
|
15854
17351
|
exports.ThrowVelocityTracker = ThrowVelocityTracker;
|
|
15855
17352
|
exports.TransformSyncSystem = TransformSyncSystem;
|
|
17353
|
+
exports.UIInteractionSystem = UIInteractionSystem;
|
|
17354
|
+
exports.UIPanelSystem = UIPanelSystem;
|
|
15856
17355
|
exports.VELOCITY_SAMPLES = VELOCITY_SAMPLES;
|
|
15857
17356
|
exports.VRTeleportAreaSystem = VRTeleportAreaSystem;
|
|
15858
17357
|
exports.VideoSystem = VideoSystem;
|
|
@@ -15919,6 +17418,11 @@ exports.createSelectableComponent = createSelectableComponent;
|
|
|
15919
17418
|
exports.createSelectionTransformStateComponent = createSelectionTransformStateComponent;
|
|
15920
17419
|
exports.createSpriteComponent = createSpriteComponent;
|
|
15921
17420
|
exports.createTransformComponent = createTransformComponent;
|
|
17421
|
+
exports.createUIButtonComponent = createUIButtonComponent;
|
|
17422
|
+
exports.createUIPanelComponent = createUIPanelComponent;
|
|
17423
|
+
exports.createUISliderComponent = createUISliderComponent;
|
|
17424
|
+
exports.createUITextComponent = createUITextComponent;
|
|
17425
|
+
exports.createUIToggleComponent = createUIToggleComponent;
|
|
15922
17426
|
exports.createVRTeleportAreaComponent = createVRTeleportAreaComponent;
|
|
15923
17427
|
exports.createVideoComponent = createVideoComponent;
|
|
15924
17428
|
exports.createXRAnchorComponent = createXRAnchorComponent;
|