@relu-interactives/spatial-ecs 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{System-8D-XBDKZ.d.cts → System-BldSHxZV.d.cts} +214 -81
- package/dist/{System-DPMAW30g.d.ts → System-CADhPyQs.d.ts} +214 -81
- package/dist/{XRHandPose-G0Dl-F0w.d.ts → XRHandPose-BNSwd1y9.d.ts} +145 -2
- package/dist/{XRHandPose-VQMT1WXj.d.cts → XRHandPose-D3Ab1Dfs.d.cts} +145 -2
- package/dist/{chunk-G4XJ53LS.js → chunk-JEPUCLZX.js} +3 -3
- package/dist/{chunk-G4XJ53LS.js.map → chunk-JEPUCLZX.js.map} +1 -1
- package/dist/{chunk-NNDUOQ7O.js → chunk-JNYPJB55.js} +250 -3
- package/dist/chunk-JNYPJB55.js.map +1 -0
- package/dist/{chunk-SGF73YTF.js → chunk-NXASMBDS.js} +4 -4
- package/dist/{chunk-SGF73YTF.js.map → chunk-NXASMBDS.js.map} +1 -1
- package/dist/{chunk-JIJQFW6P.js → chunk-TY3XCHOR.js} +1390 -485
- package/dist/chunk-TY3XCHOR.js.map +1 -0
- package/dist/{chunk-U727NTWQ.js → chunk-WWP46AEF.js} +26 -4
- package/dist/chunk-WWP46AEF.js.map +1 -0
- package/dist/components/index.cjs +151 -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/bone-attachments-and-ik.md +1 -1
- package/dist/docs/guide/multiplayer.md +65 -0
- package/dist/docs/guide/spatial-ui.md +83 -7
- package/dist/factories/index.cjs +151 -0
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +2 -2
- package/dist/factories/index.d.ts +2 -2
- package/dist/factories/index.js +3 -3
- package/dist/{index-C61n65PE.d.ts → index-6pZO_gV7.d.ts} +27 -2
- package/dist/{index-D9DjrUn3.d.cts → index-BXjwEdNq.d.cts} +6 -3
- package/dist/{index-C70N4BYG.d.cts → index-BdghvXKE.d.cts} +27 -2
- package/dist/{index-DppafVu4.d.ts → index-CVG-hREM.d.ts} +6 -3
- package/dist/index.cjs +1800 -626
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -30
- package/dist/index.d.ts +8 -30
- package/dist/index.js +10 -10
- package/dist/network/index.cjs +858 -8
- package/dist/network/index.cjs.map +1 -1
- package/dist/network/index.d.cts +126 -5
- package/dist/network/index.d.ts +126 -5
- package/dist/network/index.js +683 -8
- package/dist/network/index.js.map +1 -1
- package/dist/systems/index.cjs +1702 -528
- 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 +4 -4
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/webgpu/index.d.ts +2 -2
- package/dist/worldSnapshotUtils.d.cts +1 -1
- package/dist/worldSnapshotUtils.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-JIJQFW6P.js.map +0 -1
- package/dist/chunk-NNDUOQ7O.js.map +0 -1
- package/dist/chunk-U727NTWQ.js.map +0 -1
package/dist/systems/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var THREE37 = require('three');
|
|
4
4
|
var DRACOLoader_js = require('three/examples/jsm/loaders/DRACOLoader.js');
|
|
5
5
|
var GLTFLoader_js = require('three/examples/jsm/loaders/GLTFLoader.js');
|
|
6
6
|
var meshopt_decoder_module_js = require('three/examples/jsm/libs/meshopt_decoder.module.js');
|
|
@@ -43,7 +43,7 @@ function _interopNamespace(e) {
|
|
|
43
43
|
return Object.freeze(n);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
var
|
|
46
|
+
var THREE37__namespace = /*#__PURE__*/_interopNamespace(THREE37);
|
|
47
47
|
|
|
48
48
|
var __defProp = Object.defineProperty;
|
|
49
49
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
@@ -320,7 +320,7 @@ function findModelBone(root, ref) {
|
|
|
320
320
|
for (const b of bones) if (!byName.has(b.name)) byName.set(b.name, b);
|
|
321
321
|
const name = ref.bone ?? "";
|
|
322
322
|
if (name) {
|
|
323
|
-
const hit = byName.get(name) ?? byName.get(
|
|
323
|
+
const hit = byName.get(name) ?? byName.get(THREE37__namespace.PropertyBinding.sanitizeNodeName(name));
|
|
324
324
|
if (hit) return hit;
|
|
325
325
|
}
|
|
326
326
|
if (ref.humanoid) {
|
|
@@ -373,7 +373,7 @@ var SHARED_MODEL_RESOURCE_FLAG = "spatialEcsSharedModelResource";
|
|
|
373
373
|
var modelCache = /* @__PURE__ */ new Map();
|
|
374
374
|
function markSharedResources(root) {
|
|
375
375
|
root.traverse((child) => {
|
|
376
|
-
if (!(child instanceof
|
|
376
|
+
if (!(child instanceof THREE37__namespace.Mesh)) {
|
|
377
377
|
return;
|
|
378
378
|
}
|
|
379
379
|
if (child.geometry) {
|
|
@@ -676,14 +676,14 @@ var _AnimationComponent = class _AnimationComponent extends Component {
|
|
|
676
676
|
return;
|
|
677
677
|
}
|
|
678
678
|
this.importedClips = clips.map((entry) => {
|
|
679
|
-
if (entry instanceof
|
|
679
|
+
if (entry instanceof THREE37__namespace.AnimationClip) {
|
|
680
680
|
return { clip: entry, sourceUrl: null };
|
|
681
681
|
}
|
|
682
682
|
if (!entry || typeof entry !== "object") {
|
|
683
683
|
return null;
|
|
684
684
|
}
|
|
685
685
|
const candidate = entry;
|
|
686
|
-
if (!(candidate.clip instanceof
|
|
686
|
+
if (!(candidate.clip instanceof THREE37__namespace.AnimationClip)) {
|
|
687
687
|
return null;
|
|
688
688
|
}
|
|
689
689
|
return {
|
|
@@ -890,7 +890,7 @@ var DEFAULT_ORTHO_TOP = 5;
|
|
|
890
890
|
var DEFAULT_ORTHO_BOTTOM = -5;
|
|
891
891
|
var DEFAULT_ZOOM = 1;
|
|
892
892
|
function inferProjection(camera) {
|
|
893
|
-
if (camera instanceof
|
|
893
|
+
if (camera instanceof THREE37__namespace.OrthographicCamera) {
|
|
894
894
|
return "orthographic";
|
|
895
895
|
}
|
|
896
896
|
return "perspective";
|
|
@@ -911,7 +911,7 @@ function readCameraFar(camera) {
|
|
|
911
911
|
}
|
|
912
912
|
__name(readCameraFar, "readCameraFar");
|
|
913
913
|
function inferFov(camera) {
|
|
914
|
-
if (camera instanceof
|
|
914
|
+
if (camera instanceof THREE37__namespace.PerspectiveCamera && Number.isFinite(camera.fov)) {
|
|
915
915
|
return camera.fov;
|
|
916
916
|
}
|
|
917
917
|
return DEFAULT_FOV;
|
|
@@ -934,28 +934,28 @@ function inferFar(camera) {
|
|
|
934
934
|
}
|
|
935
935
|
__name(inferFar, "inferFar");
|
|
936
936
|
function inferOrthoLeft(camera) {
|
|
937
|
-
if (camera instanceof
|
|
937
|
+
if (camera instanceof THREE37__namespace.OrthographicCamera && Number.isFinite(camera.left)) {
|
|
938
938
|
return camera.left;
|
|
939
939
|
}
|
|
940
940
|
return DEFAULT_ORTHO_LEFT;
|
|
941
941
|
}
|
|
942
942
|
__name(inferOrthoLeft, "inferOrthoLeft");
|
|
943
943
|
function inferOrthoRight(camera) {
|
|
944
|
-
if (camera instanceof
|
|
944
|
+
if (camera instanceof THREE37__namespace.OrthographicCamera && Number.isFinite(camera.right)) {
|
|
945
945
|
return camera.right;
|
|
946
946
|
}
|
|
947
947
|
return DEFAULT_ORTHO_RIGHT;
|
|
948
948
|
}
|
|
949
949
|
__name(inferOrthoRight, "inferOrthoRight");
|
|
950
950
|
function inferOrthoTop(camera) {
|
|
951
|
-
if (camera instanceof
|
|
951
|
+
if (camera instanceof THREE37__namespace.OrthographicCamera && Number.isFinite(camera.top)) {
|
|
952
952
|
return camera.top;
|
|
953
953
|
}
|
|
954
954
|
return DEFAULT_ORTHO_TOP;
|
|
955
955
|
}
|
|
956
956
|
__name(inferOrthoTop, "inferOrthoTop");
|
|
957
957
|
function inferOrthoBottom(camera) {
|
|
958
|
-
if (camera instanceof
|
|
958
|
+
if (camera instanceof THREE37__namespace.OrthographicCamera && Number.isFinite(camera.bottom)) {
|
|
959
959
|
return camera.bottom;
|
|
960
960
|
}
|
|
961
961
|
return DEFAULT_ORTHO_BOTTOM;
|
|
@@ -971,7 +971,7 @@ __name(inferZoom, "inferZoom");
|
|
|
971
971
|
var _CameraComponent = class _CameraComponent extends Component {
|
|
972
972
|
constructor(payload = {}) {
|
|
973
973
|
super();
|
|
974
|
-
this.camera = payload.camera ?? new
|
|
974
|
+
this.camera = payload.camera ?? new THREE37__namespace.PerspectiveCamera();
|
|
975
975
|
this.type = payload.type ?? "3d";
|
|
976
976
|
this.isDefault = typeof payload.isDefault === "boolean" ? payload.isDefault : false;
|
|
977
977
|
this.projection = payload.projection ?? inferProjection(payload.camera);
|
|
@@ -1475,15 +1475,15 @@ function createValueState(light) {
|
|
|
1475
1475
|
castShadow: light.castShadow ?? false,
|
|
1476
1476
|
frustumCulling: light.frustumCulled
|
|
1477
1477
|
};
|
|
1478
|
-
if (light instanceof
|
|
1478
|
+
if (light instanceof THREE37__namespace.PointLight) {
|
|
1479
1479
|
base.distance = light.distance;
|
|
1480
1480
|
base.decay = light.decay;
|
|
1481
|
-
} else if (light instanceof
|
|
1481
|
+
} else if (light instanceof THREE37__namespace.SpotLight) {
|
|
1482
1482
|
base.distance = light.distance;
|
|
1483
1483
|
base.decay = light.decay;
|
|
1484
1484
|
base.angle = light.angle;
|
|
1485
1485
|
base.penumbra = light.penumbra;
|
|
1486
|
-
} else if (light instanceof
|
|
1486
|
+
} else if (light instanceof THREE37__namespace.RectAreaLight) {
|
|
1487
1487
|
base.width = light.width;
|
|
1488
1488
|
base.height = light.height;
|
|
1489
1489
|
}
|
|
@@ -1518,13 +1518,13 @@ function toHexColor2(value, fallback) {
|
|
|
1518
1518
|
}
|
|
1519
1519
|
__name(toHexColor2, "toHexColor");
|
|
1520
1520
|
function getMaterialType(material) {
|
|
1521
|
-
if (material instanceof
|
|
1521
|
+
if (material instanceof THREE37__namespace.MeshPhysicalMaterial) {
|
|
1522
1522
|
return "physical";
|
|
1523
1523
|
}
|
|
1524
|
-
if (material instanceof
|
|
1524
|
+
if (material instanceof THREE37__namespace.MeshPhongMaterial) {
|
|
1525
1525
|
return "phong";
|
|
1526
1526
|
}
|
|
1527
|
-
if (material instanceof
|
|
1527
|
+
if (material instanceof THREE37__namespace.MeshBasicMaterial) {
|
|
1528
1528
|
return "basic";
|
|
1529
1529
|
}
|
|
1530
1530
|
return "standard";
|
|
@@ -1559,8 +1559,8 @@ function createMaterialValue(material) {
|
|
|
1559
1559
|
opacity: typeof materialRecord.opacity === "number" ? materialRecord.opacity : 1,
|
|
1560
1560
|
emissive: toHexColor2(materialRecord.emissive, "#000000"),
|
|
1561
1561
|
emissiveIntensity: typeof materialRecord.emissiveIntensity === "number" ? materialRecord.emissiveIntensity : 0,
|
|
1562
|
-
side: typeof materialRecord.side === "number" ? materialRecord.side :
|
|
1563
|
-
blending: typeof materialRecord.blending === "number" ? materialRecord.blending :
|
|
1562
|
+
side: typeof materialRecord.side === "number" ? materialRecord.side : THREE37__namespace.FrontSide,
|
|
1563
|
+
blending: typeof materialRecord.blending === "number" ? materialRecord.blending : THREE37__namespace.NormalBlending,
|
|
1564
1564
|
depthTest: materialRecord.depthTest !== false,
|
|
1565
1565
|
depthWrite: materialRecord.depthWrite !== false,
|
|
1566
1566
|
wireframe: Boolean(materialRecord.wireframe),
|
|
@@ -1592,7 +1592,7 @@ function createMaterialValue(material) {
|
|
|
1592
1592
|
materialRecord.lightMap
|
|
1593
1593
|
),
|
|
1594
1594
|
envMap: textureImageSrc(materialRecord.envMap),
|
|
1595
|
-
textureFiltering: map?.magFilter ===
|
|
1595
|
+
textureFiltering: map?.magFilter === THREE37__namespace.NearestFilter ? "sharp" : "smooth",
|
|
1596
1596
|
useMipmaps: map?.generateMipmaps !== false
|
|
1597
1597
|
};
|
|
1598
1598
|
}
|
|
@@ -1607,8 +1607,8 @@ function defaultMaterialValue() {
|
|
|
1607
1607
|
opacity: 1,
|
|
1608
1608
|
emissive: "#000000",
|
|
1609
1609
|
emissiveIntensity: 0,
|
|
1610
|
-
side:
|
|
1611
|
-
blending:
|
|
1610
|
+
side: THREE37__namespace.FrontSide,
|
|
1611
|
+
blending: THREE37__namespace.NormalBlending,
|
|
1612
1612
|
depthTest: true,
|
|
1613
1613
|
depthWrite: true,
|
|
1614
1614
|
wireframe: false,
|
|
@@ -2065,14 +2065,14 @@ var _TransformComponent = class _TransformComponent extends Component {
|
|
|
2065
2065
|
z: scale.z ?? 1
|
|
2066
2066
|
};
|
|
2067
2067
|
}
|
|
2068
|
-
toPositionVector3(target = new
|
|
2068
|
+
toPositionVector3(target = new THREE37.Vector3()) {
|
|
2069
2069
|
return target.set(this.position.x, this.position.y, this.position.z);
|
|
2070
2070
|
}
|
|
2071
|
-
toRotationEuler(target = new
|
|
2071
|
+
toRotationEuler(target = new THREE37.Euler(), order = "XYZ") {
|
|
2072
2072
|
return target.set(this.rotation.x, this.rotation.y, this.rotation.z, order);
|
|
2073
2073
|
}
|
|
2074
|
-
toRotationQuaternion(target = new
|
|
2075
|
-
const euler = new
|
|
2074
|
+
toRotationQuaternion(target = new THREE37.Quaternion(), order = "XYZ") {
|
|
2075
|
+
const euler = new THREE37.Euler(
|
|
2076
2076
|
this.rotation.x,
|
|
2077
2077
|
this.rotation.y,
|
|
2078
2078
|
this.rotation.z,
|
|
@@ -2080,7 +2080,7 @@ var _TransformComponent = class _TransformComponent extends Component {
|
|
|
2080
2080
|
);
|
|
2081
2081
|
return target.setFromEuler(euler);
|
|
2082
2082
|
}
|
|
2083
|
-
toScaleVector3(target = new
|
|
2083
|
+
toScaleVector3(target = new THREE37.Vector3()) {
|
|
2084
2084
|
return target.set(this.scale.x, this.scale.y, this.scale.z);
|
|
2085
2085
|
}
|
|
2086
2086
|
setPosition(input) {
|
|
@@ -2098,8 +2098,8 @@ var _TransformComponent = class _TransformComponent extends Component {
|
|
|
2098
2098
|
return this;
|
|
2099
2099
|
}
|
|
2100
2100
|
setRotation(input, order = "XYZ") {
|
|
2101
|
-
if (input instanceof
|
|
2102
|
-
const euler = new
|
|
2101
|
+
if (input instanceof THREE37.Quaternion) {
|
|
2102
|
+
const euler = new THREE37.Euler().setFromQuaternion(input, order);
|
|
2103
2103
|
this.rotation.x = euler.x;
|
|
2104
2104
|
this.rotation.y = euler.y;
|
|
2105
2105
|
this.rotation.z = euler.z;
|
|
@@ -2701,6 +2701,223 @@ var _XRInteractorSideComponent = class _XRInteractorSideComponent extends Compon
|
|
|
2701
2701
|
__name(_XRInteractorSideComponent, "XRInteractorSideComponent");
|
|
2702
2702
|
var XRInteractorSideComponent = _XRInteractorSideComponent;
|
|
2703
2703
|
|
|
2704
|
+
// core/ui/uiStyle.ts
|
|
2705
|
+
var isRecord = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null && !Array.isArray(value), "isRecord");
|
|
2706
|
+
var finite = /* @__PURE__ */ __name((value) => typeof value === "number" && Number.isFinite(value), "finite");
|
|
2707
|
+
var nonEmpty = /* @__PURE__ */ __name((value) => typeof value === "string" && value.length > 0, "nonEmpty");
|
|
2708
|
+
function normalizeStops(value) {
|
|
2709
|
+
if (!Array.isArray(value)) return null;
|
|
2710
|
+
const stops = [];
|
|
2711
|
+
for (const stop of value) {
|
|
2712
|
+
if (isRecord(stop) && finite(stop.at) && nonEmpty(stop.color)) {
|
|
2713
|
+
stops.push({ at: Math.min(1, Math.max(0, stop.at)), color: stop.color });
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
return stops.length >= 2 ? stops : null;
|
|
2717
|
+
}
|
|
2718
|
+
__name(normalizeStops, "normalizeStops");
|
|
2719
|
+
function normalizePaint(value) {
|
|
2720
|
+
if (!isRecord(value)) return void 0;
|
|
2721
|
+
if (value.kind === "solid" && nonEmpty(value.color)) {
|
|
2722
|
+
return { kind: "solid", color: value.color };
|
|
2723
|
+
}
|
|
2724
|
+
if (value.kind === "linear") {
|
|
2725
|
+
const stops = normalizeStops(value.stops);
|
|
2726
|
+
if (stops) {
|
|
2727
|
+
return {
|
|
2728
|
+
kind: "linear",
|
|
2729
|
+
angle: finite(value.angle) ? value.angle : 180,
|
|
2730
|
+
stops
|
|
2731
|
+
};
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
if (value.kind === "radial") {
|
|
2735
|
+
const stops = normalizeStops(value.stops);
|
|
2736
|
+
if (stops) return { kind: "radial", stops };
|
|
2737
|
+
}
|
|
2738
|
+
if (value.kind === "image" && nonEmpty(value.src)) {
|
|
2739
|
+
const fit = value.fit === "contain" || value.fit === "fill" ? value.fit : "cover";
|
|
2740
|
+
return {
|
|
2741
|
+
kind: "image",
|
|
2742
|
+
src: value.src,
|
|
2743
|
+
fit,
|
|
2744
|
+
...nonEmpty(value.tint) ? { tint: value.tint } : {}
|
|
2745
|
+
};
|
|
2746
|
+
}
|
|
2747
|
+
return void 0;
|
|
2748
|
+
}
|
|
2749
|
+
__name(normalizePaint, "normalizePaint");
|
|
2750
|
+
function normalizeShadow(value) {
|
|
2751
|
+
if (!isRecord(value) || !nonEmpty(value.color)) return void 0;
|
|
2752
|
+
return {
|
|
2753
|
+
x: finite(value.x) ? value.x : 0,
|
|
2754
|
+
y: finite(value.y) ? value.y : 0,
|
|
2755
|
+
blur: finite(value.blur) ? Math.max(0, value.blur) : 0,
|
|
2756
|
+
color: value.color
|
|
2757
|
+
};
|
|
2758
|
+
}
|
|
2759
|
+
__name(normalizeShadow, "normalizeShadow");
|
|
2760
|
+
function normalizeText(value) {
|
|
2761
|
+
if (!isRecord(value)) return void 0;
|
|
2762
|
+
const text = {};
|
|
2763
|
+
if (nonEmpty(value.font)) text.font = value.font;
|
|
2764
|
+
if (finite(value.weight)) text.weight = value.weight;
|
|
2765
|
+
if (finite(value.tracking)) text.tracking = value.tracking;
|
|
2766
|
+
if (value.transform === "upper" || value.transform === "lower") {
|
|
2767
|
+
text.transform = value.transform;
|
|
2768
|
+
}
|
|
2769
|
+
const paint = normalizePaint(value.paint);
|
|
2770
|
+
if (paint) text.paint = paint;
|
|
2771
|
+
if (finite(value.maxLines) && value.maxLines >= 1) {
|
|
2772
|
+
text.maxLines = Math.floor(value.maxLines);
|
|
2773
|
+
}
|
|
2774
|
+
const shadow = normalizeShadow(value.shadow);
|
|
2775
|
+
if (shadow) text.shadow = shadow;
|
|
2776
|
+
return Object.keys(text).length > 0 ? text : void 0;
|
|
2777
|
+
}
|
|
2778
|
+
__name(normalizeText, "normalizeText");
|
|
2779
|
+
function normalizeUiStyle(value) {
|
|
2780
|
+
if (!isRecord(value)) return void 0;
|
|
2781
|
+
const style = {};
|
|
2782
|
+
const fill = normalizePaint(value.fill);
|
|
2783
|
+
if (fill) style.fill = fill;
|
|
2784
|
+
if (isRecord(value.border) && finite(value.border.width)) {
|
|
2785
|
+
const paint = normalizePaint(value.border.paint);
|
|
2786
|
+
if (paint) {
|
|
2787
|
+
style.border = { width: Math.max(0, value.border.width), paint };
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
if (finite(value.radius)) {
|
|
2791
|
+
style.radius = Math.max(0, value.radius);
|
|
2792
|
+
} else if (Array.isArray(value.radius) && value.radius.length === 4 && value.radius.every(finite)) {
|
|
2793
|
+
style.radius = value.radius.map((r) => Math.max(0, r));
|
|
2794
|
+
}
|
|
2795
|
+
if (Array.isArray(value.shadows)) {
|
|
2796
|
+
const shadows = value.shadows.map(normalizeShadow).filter((s) => !!s);
|
|
2797
|
+
if (shadows.length > 0) style.shadows = shadows;
|
|
2798
|
+
}
|
|
2799
|
+
if (isRecord(value.edge) && finite(value.edge.width) && nonEmpty(value.edge.color)) {
|
|
2800
|
+
style.edge = {
|
|
2801
|
+
width: Math.max(0, value.edge.width),
|
|
2802
|
+
color: value.edge.color
|
|
2803
|
+
};
|
|
2804
|
+
}
|
|
2805
|
+
if (finite(value.opacity)) {
|
|
2806
|
+
style.opacity = Math.min(1, Math.max(0, value.opacity));
|
|
2807
|
+
}
|
|
2808
|
+
const text = normalizeText(value.text);
|
|
2809
|
+
if (text) style.text = text;
|
|
2810
|
+
return Object.keys(style).length > 0 ? style : void 0;
|
|
2811
|
+
}
|
|
2812
|
+
__name(normalizeUiStyle, "normalizeUiStyle");
|
|
2813
|
+
function normalizeUiTokens(value) {
|
|
2814
|
+
if (!isRecord(value)) return void 0;
|
|
2815
|
+
const tokens = {};
|
|
2816
|
+
for (const [key, token] of Object.entries(value)) {
|
|
2817
|
+
if (nonEmpty(token) && key.length > 0 && !key.includes("/")) {
|
|
2818
|
+
tokens[key] = token;
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
return Object.keys(tokens).length > 0 ? tokens : void 0;
|
|
2822
|
+
}
|
|
2823
|
+
__name(normalizeUiTokens, "normalizeUiTokens");
|
|
2824
|
+
function resolveToken(value, tokens, fallback = value) {
|
|
2825
|
+
if (!value.startsWith("$")) return value;
|
|
2826
|
+
return tokens?.[value.slice(1)] ?? fallback;
|
|
2827
|
+
}
|
|
2828
|
+
__name(resolveToken, "resolveToken");
|
|
2829
|
+
function resolvePaint(paint, tokens) {
|
|
2830
|
+
switch (paint.kind) {
|
|
2831
|
+
case "solid":
|
|
2832
|
+
return { kind: "solid", color: resolveToken(paint.color, tokens) };
|
|
2833
|
+
case "linear":
|
|
2834
|
+
case "radial":
|
|
2835
|
+
return {
|
|
2836
|
+
...paint,
|
|
2837
|
+
stops: paint.stops.map((stop) => ({
|
|
2838
|
+
at: stop.at,
|
|
2839
|
+
color: resolveToken(stop.color, tokens)
|
|
2840
|
+
}))
|
|
2841
|
+
};
|
|
2842
|
+
case "image":
|
|
2843
|
+
return {
|
|
2844
|
+
...paint,
|
|
2845
|
+
src: resolveToken(paint.src, tokens),
|
|
2846
|
+
...paint.tint ? { tint: resolveToken(paint.tint, tokens) } : {}
|
|
2847
|
+
};
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2850
|
+
__name(resolvePaint, "resolvePaint");
|
|
2851
|
+
function solidOf(paint) {
|
|
2852
|
+
if (paint.kind === "solid") return paint.color;
|
|
2853
|
+
if (paint.kind === "image") return paint.tint ?? "#ffffff";
|
|
2854
|
+
return paint.stops[0].color;
|
|
2855
|
+
}
|
|
2856
|
+
__name(solidOf, "solidOf");
|
|
2857
|
+
function radiusOf(radius, fallback) {
|
|
2858
|
+
if (Array.isArray(radius)) return radius;
|
|
2859
|
+
const r = radius ?? fallback;
|
|
2860
|
+
return [r, r, r, r];
|
|
2861
|
+
}
|
|
2862
|
+
__name(radiusOf, "radiusOf");
|
|
2863
|
+
function resolveChrome(flat, style, tokens) {
|
|
2864
|
+
const borderWidth = style?.border?.width ?? flat.borderWidth;
|
|
2865
|
+
const border = borderWidth > 0 ? {
|
|
2866
|
+
width: borderWidth,
|
|
2867
|
+
color: style?.border ? solidOf(resolvePaint(style.border.paint, tokens)) : resolveToken(flat.borderColor, tokens)
|
|
2868
|
+
} : null;
|
|
2869
|
+
return {
|
|
2870
|
+
fill: style?.fill ? resolvePaint(style.fill, tokens) : { kind: "solid", color: resolveToken(flat.backgroundColor, tokens) },
|
|
2871
|
+
fillOpacity: style?.fill ? 1 : flat.backgroundOpacity,
|
|
2872
|
+
radius: radiusOf(style?.radius, flat.cornerRadius),
|
|
2873
|
+
border,
|
|
2874
|
+
shadows: (style?.shadows ?? []).map((shadow) => ({
|
|
2875
|
+
...shadow,
|
|
2876
|
+
color: resolveToken(shadow.color, tokens)
|
|
2877
|
+
})),
|
|
2878
|
+
edge: style?.edge ? { ...style.edge, color: resolveToken(style.edge.color, tokens) } : null
|
|
2879
|
+
};
|
|
2880
|
+
}
|
|
2881
|
+
__name(resolveChrome, "resolveChrome");
|
|
2882
|
+
function resolveText(flat, style, tokens) {
|
|
2883
|
+
const text = style?.text;
|
|
2884
|
+
return {
|
|
2885
|
+
...flat,
|
|
2886
|
+
color: resolveToken(flat.color, tokens),
|
|
2887
|
+
fontWeight: text?.weight ?? flat.fontWeight,
|
|
2888
|
+
paint: text?.paint ? resolvePaint(text.paint, tokens) : { kind: "solid", color: resolveToken(flat.color, tokens) },
|
|
2889
|
+
font: text?.font ? resolveToken(text.font, tokens) : null,
|
|
2890
|
+
tracking: text?.tracking ?? 0,
|
|
2891
|
+
transform: text?.transform ?? null,
|
|
2892
|
+
maxLines: text?.maxLines ?? null,
|
|
2893
|
+
shadow: text?.shadow ? {
|
|
2894
|
+
...text.shadow,
|
|
2895
|
+
color: resolveToken(text.shadow.color, tokens)
|
|
2896
|
+
} : null
|
|
2897
|
+
};
|
|
2898
|
+
}
|
|
2899
|
+
__name(resolveText, "resolveText");
|
|
2900
|
+
function chromeBleed(chrome) {
|
|
2901
|
+
let bleed = 0;
|
|
2902
|
+
for (const shadow of chrome.shadows) {
|
|
2903
|
+
bleed = Math.max(
|
|
2904
|
+
bleed,
|
|
2905
|
+
shadow.blur + Math.max(Math.abs(shadow.x), Math.abs(shadow.y))
|
|
2906
|
+
);
|
|
2907
|
+
}
|
|
2908
|
+
return bleed;
|
|
2909
|
+
}
|
|
2910
|
+
__name(chromeBleed, "chromeBleed");
|
|
2911
|
+
function styleAssets(chrome, text) {
|
|
2912
|
+
const images2 = [];
|
|
2913
|
+
const fonts2 = [];
|
|
2914
|
+
if (chrome?.fill?.kind === "image") images2.push(chrome.fill.src);
|
|
2915
|
+
if (text?.paint.kind === "image") images2.push(text.paint.src);
|
|
2916
|
+
if (text?.font) fonts2.push(text.font);
|
|
2917
|
+
return { images: images2, fonts: fonts2 };
|
|
2918
|
+
}
|
|
2919
|
+
__name(styleAssets, "styleAssets");
|
|
2920
|
+
|
|
2704
2921
|
// core/components/UIButton.ts
|
|
2705
2922
|
var _UIButtonComponent = class _UIButtonComponent extends Component {
|
|
2706
2923
|
constructor(options) {
|
|
@@ -2717,6 +2934,13 @@ var _UIButtonComponent = class _UIButtonComponent extends Component {
|
|
|
2717
2934
|
this.cornerRadius = options?.cornerRadius ?? 0.02;
|
|
2718
2935
|
this.borderWidth = options?.borderWidth ?? 2e-3;
|
|
2719
2936
|
this.borderColor = options?.borderColor ?? "#3a3a3a";
|
|
2937
|
+
if (options?.pixelDensity !== void 0) {
|
|
2938
|
+
this.pixelDensity = options.pixelDensity;
|
|
2939
|
+
}
|
|
2940
|
+
const style = normalizeUiStyle(options?.style);
|
|
2941
|
+
if (style) this.style = style;
|
|
2942
|
+
if (options?.icon) this.icon = options.icon;
|
|
2943
|
+
if (options?.iconPosition) this.iconPosition = options.iconPosition;
|
|
2720
2944
|
}
|
|
2721
2945
|
};
|
|
2722
2946
|
__name(_UIButtonComponent, "UIButtonComponent");
|
|
@@ -2735,6 +2959,10 @@ var _UIPanelComponent = class _UIPanelComponent extends Component {
|
|
|
2735
2959
|
this.borderColor = options?.borderColor ?? "#333333";
|
|
2736
2960
|
this.pixelDensity = options?.pixelDensity ?? 1024;
|
|
2737
2961
|
this.follow = options?.follow ?? "world";
|
|
2962
|
+
const style = normalizeUiStyle(options?.style);
|
|
2963
|
+
if (style) this.style = style;
|
|
2964
|
+
const tokens = normalizeUiTokens(options?.tokens);
|
|
2965
|
+
if (tokens) this.tokens = tokens;
|
|
2738
2966
|
}
|
|
2739
2967
|
};
|
|
2740
2968
|
__name(_UIPanelComponent, "UIPanelComponent");
|
|
@@ -2755,6 +2983,14 @@ var _UISliderComponent = class _UISliderComponent extends Component {
|
|
|
2755
2983
|
this.trackColor = options?.trackColor ?? "#2a2a2a";
|
|
2756
2984
|
this.accentColor = options?.accentColor ?? "#ff6b35";
|
|
2757
2985
|
this.knobColor = options?.knobColor ?? "#ffffff";
|
|
2986
|
+
if (options?.pixelDensity !== void 0) {
|
|
2987
|
+
this.pixelDensity = options.pixelDensity;
|
|
2988
|
+
}
|
|
2989
|
+
const style = normalizeUiStyle(options?.style);
|
|
2990
|
+
if (style) this.style = style;
|
|
2991
|
+
if (options?.variant) this.variant = options.variant;
|
|
2992
|
+
if (options?.step !== void 0) this.step = options.step;
|
|
2993
|
+
if (options?.readOnly !== void 0) this.readOnly = options.readOnly;
|
|
2758
2994
|
}
|
|
2759
2995
|
};
|
|
2760
2996
|
__name(_UISliderComponent, "UISliderComponent");
|
|
@@ -2774,6 +3010,11 @@ var _UITextComponent = class _UITextComponent extends Component {
|
|
|
2774
3010
|
this.valign = options?.valign ?? "middle";
|
|
2775
3011
|
this.lineHeight = options?.lineHeight ?? 1.25;
|
|
2776
3012
|
this.padding = options?.padding ?? 0.01;
|
|
3013
|
+
if (options?.pixelDensity !== void 0) {
|
|
3014
|
+
this.pixelDensity = options.pixelDensity;
|
|
3015
|
+
}
|
|
3016
|
+
const style = normalizeUiStyle(options?.style);
|
|
3017
|
+
if (style) this.style = style;
|
|
2777
3018
|
}
|
|
2778
3019
|
};
|
|
2779
3020
|
__name(_UITextComponent, "UITextComponent");
|
|
@@ -2790,6 +3031,12 @@ var _UIToggleComponent = class _UIToggleComponent extends Component {
|
|
|
2790
3031
|
this.trackColor = options?.trackColor ?? "#2a2a2a";
|
|
2791
3032
|
this.accentColor = options?.accentColor ?? "#ff6b35";
|
|
2792
3033
|
this.knobColor = options?.knobColor ?? "#ffffff";
|
|
3034
|
+
if (options?.pixelDensity !== void 0) {
|
|
3035
|
+
this.pixelDensity = options.pixelDensity;
|
|
3036
|
+
}
|
|
3037
|
+
const style = normalizeUiStyle(options?.style);
|
|
3038
|
+
if (style) this.style = style;
|
|
3039
|
+
if (options?.variant) this.variant = options.variant;
|
|
2793
3040
|
}
|
|
2794
3041
|
};
|
|
2795
3042
|
__name(_UIToggleComponent, "UIToggleComponent");
|
|
@@ -2923,8 +3170,8 @@ __name(reloadModelEntity, "reloadModelEntity");
|
|
|
2923
3170
|
|
|
2924
3171
|
// core/systems/ObjectManagementSystem.ts
|
|
2925
3172
|
var BONE_SOCKET_FLAG = "__reluBoneSocket";
|
|
2926
|
-
var _boneScale = new
|
|
2927
|
-
var _anchorScale = new
|
|
3173
|
+
var _boneScale = new THREE37__namespace.Vector3();
|
|
3174
|
+
var _anchorScale = new THREE37__namespace.Vector3();
|
|
2928
3175
|
function applyTransform(object, transform) {
|
|
2929
3176
|
object.position.set(
|
|
2930
3177
|
transform.position.x,
|
|
@@ -2959,10 +3206,10 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
|
|
|
2959
3206
|
}
|
|
2960
3207
|
getOrCreateAudioListener() {
|
|
2961
3208
|
const existing = this.camera.userData.ecsAudioListener;
|
|
2962
|
-
if (existing instanceof
|
|
3209
|
+
if (existing instanceof THREE37__namespace.AudioListener) {
|
|
2963
3210
|
return existing;
|
|
2964
3211
|
}
|
|
2965
|
-
const listener = new
|
|
3212
|
+
const listener = new THREE37__namespace.AudioListener();
|
|
2966
3213
|
this.camera.add(listener);
|
|
2967
3214
|
this.camera.userData.ecsAudioListener = listener;
|
|
2968
3215
|
return listener;
|
|
@@ -3036,7 +3283,7 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
|
|
|
3036
3283
|
}
|
|
3037
3284
|
if (dispose && object3d) {
|
|
3038
3285
|
object3d.traverse((child) => {
|
|
3039
|
-
if (child instanceof
|
|
3286
|
+
if (child instanceof THREE37__namespace.Mesh) {
|
|
3040
3287
|
if (!child.geometry?.userData?.[SHARED_MODEL_RESOURCE_FLAG]) {
|
|
3041
3288
|
child.geometry?.dispose();
|
|
3042
3289
|
}
|
|
@@ -3188,7 +3435,7 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
|
|
|
3188
3435
|
return null;
|
|
3189
3436
|
}
|
|
3190
3437
|
this.boneMisses.delete(entityId);
|
|
3191
|
-
const socket = new
|
|
3438
|
+
const socket = new THREE37__namespace.Object3D();
|
|
3192
3439
|
socket.name = `socket:${bone.name}`;
|
|
3193
3440
|
socket.userData[BONE_SOCKET_FLAG] = entityId;
|
|
3194
3441
|
bone.add(socket);
|
|
@@ -3473,7 +3720,7 @@ function transitionToClip(runtime, nextClipId, crossFadeDuration) {
|
|
|
3473
3720
|
}
|
|
3474
3721
|
__name(transitionToClip, "transitionToClip");
|
|
3475
3722
|
function applyActionState(action, component, paused, shouldLoop) {
|
|
3476
|
-
const loopMode = shouldLoop ?
|
|
3723
|
+
const loopMode = shouldLoop ? THREE37__namespace.LoopRepeat : THREE37__namespace.LoopOnce;
|
|
3477
3724
|
const repetitions = shouldLoop ? Infinity : 1;
|
|
3478
3725
|
action.setLoop(loopMode, repetitions);
|
|
3479
3726
|
action.clampWhenFinished = !shouldLoop;
|
|
@@ -3646,7 +3893,7 @@ var _AnimationSystem = class _AnimationSystem {
|
|
|
3646
3893
|
if (runtime) {
|
|
3647
3894
|
stopAllActions(runtime);
|
|
3648
3895
|
}
|
|
3649
|
-
const mixer = new
|
|
3896
|
+
const mixer = new THREE37__namespace.AnimationMixer(root);
|
|
3650
3897
|
const entries2 = readRuntimeClipEntries(animation);
|
|
3651
3898
|
const indexedActions = createActions(mixer, entries2);
|
|
3652
3899
|
runtime = {
|
|
@@ -3772,11 +4019,11 @@ function normalizeOrthoBounds(component) {
|
|
|
3772
4019
|
}
|
|
3773
4020
|
__name(normalizeOrthoBounds, "normalizeOrthoBounds");
|
|
3774
4021
|
function isPerspectiveCamera(camera) {
|
|
3775
|
-
return camera instanceof
|
|
4022
|
+
return camera instanceof THREE37__namespace.PerspectiveCamera;
|
|
3776
4023
|
}
|
|
3777
4024
|
__name(isPerspectiveCamera, "isPerspectiveCamera");
|
|
3778
4025
|
function isOrthographicCamera(camera) {
|
|
3779
|
-
return camera instanceof
|
|
4026
|
+
return camera instanceof THREE37__namespace.OrthographicCamera;
|
|
3780
4027
|
}
|
|
3781
4028
|
__name(isOrthographicCamera, "isOrthographicCamera");
|
|
3782
4029
|
function readWindowAspect() {
|
|
@@ -3830,7 +4077,7 @@ var _CameraSyncSystem = class _CameraSyncSystem {
|
|
|
3830
4077
|
continue;
|
|
3831
4078
|
}
|
|
3832
4079
|
const camera = objectRef.object;
|
|
3833
|
-
if (!(camera instanceof
|
|
4080
|
+
if (!(camera instanceof THREE37__namespace.Camera)) {
|
|
3834
4081
|
continue;
|
|
3835
4082
|
}
|
|
3836
4083
|
if (xrCamera !== null && camera === xrCamera) {
|
|
@@ -3895,8 +4142,8 @@ var ObjectVisibilitySystem = _ObjectVisibilitySystem;
|
|
|
3895
4142
|
function getUrlExtension(url) {
|
|
3896
4143
|
const path = url.split(/[?#]/)[0] ?? "";
|
|
3897
4144
|
const lastSegment = path.split("/").pop() ?? "";
|
|
3898
|
-
const
|
|
3899
|
-
return
|
|
4145
|
+
const dot2 = lastSegment.lastIndexOf(".");
|
|
4146
|
+
return dot2 >= 0 ? lastSegment.slice(dot2 + 1).toLowerCase() : "";
|
|
3900
4147
|
}
|
|
3901
4148
|
__name(getUrlExtension, "getUrlExtension");
|
|
3902
4149
|
async function loadEquirectTexture(url) {
|
|
@@ -3909,10 +4156,10 @@ async function loadEquirectTexture(url) {
|
|
|
3909
4156
|
const { EXRLoader } = await import('three/examples/jsm/loaders/EXRLoader.js');
|
|
3910
4157
|
texture = await new EXRLoader().loadAsync(url);
|
|
3911
4158
|
} else {
|
|
3912
|
-
texture = await new
|
|
3913
|
-
texture.colorSpace =
|
|
4159
|
+
texture = await new THREE37__namespace.TextureLoader().loadAsync(url);
|
|
4160
|
+
texture.colorSpace = THREE37__namespace.SRGBColorSpace;
|
|
3914
4161
|
}
|
|
3915
|
-
texture.mapping =
|
|
4162
|
+
texture.mapping = THREE37__namespace.EquirectangularReflectionMapping;
|
|
3916
4163
|
texture.needsUpdate = true;
|
|
3917
4164
|
return texture;
|
|
3918
4165
|
}
|
|
@@ -3921,13 +4168,13 @@ var rendererStates = /* @__PURE__ */ new WeakMap();
|
|
|
3921
4168
|
function toThreeToneMapping(mode) {
|
|
3922
4169
|
switch (mode) {
|
|
3923
4170
|
case "aces":
|
|
3924
|
-
return
|
|
4171
|
+
return THREE37__namespace.ACESFilmicToneMapping;
|
|
3925
4172
|
case "agx":
|
|
3926
|
-
return
|
|
4173
|
+
return THREE37__namespace.AgXToneMapping;
|
|
3927
4174
|
case "neutral":
|
|
3928
|
-
return
|
|
4175
|
+
return THREE37__namespace.NeutralToneMapping;
|
|
3929
4176
|
default:
|
|
3930
|
-
return
|
|
4177
|
+
return THREE37__namespace.NoToneMapping;
|
|
3931
4178
|
}
|
|
3932
4179
|
}
|
|
3933
4180
|
__name(toThreeToneMapping, "toThreeToneMapping");
|
|
@@ -3948,7 +4195,7 @@ function setRendererToneMappingSource(renderer, source, request) {
|
|
|
3948
4195
|
if (request === null) return;
|
|
3949
4196
|
state = {
|
|
3950
4197
|
baseline: {
|
|
3951
|
-
toneMapping: target.toneMapping ??
|
|
4198
|
+
toneMapping: target.toneMapping ?? THREE37__namespace.NoToneMapping,
|
|
3952
4199
|
exposure: typeof target.toneMappingExposure === "number" ? target.toneMappingExposure : 1
|
|
3953
4200
|
},
|
|
3954
4201
|
environment: null,
|
|
@@ -4000,7 +4247,7 @@ var MIN_DENSITY = 0;
|
|
|
4000
4247
|
function createGradientTexture(effect, colors) {
|
|
4001
4248
|
if (typeof document === "undefined") {
|
|
4002
4249
|
const pixel = new Uint8Array([30, 30, 30, 255]);
|
|
4003
|
-
const fallback = new
|
|
4250
|
+
const fallback = new THREE37__namespace.DataTexture(pixel, 1, 1, THREE37__namespace.RGBAFormat);
|
|
4004
4251
|
fallback.needsUpdate = true;
|
|
4005
4252
|
return fallback;
|
|
4006
4253
|
}
|
|
@@ -4009,7 +4256,7 @@ function createGradientTexture(effect, colors) {
|
|
|
4009
4256
|
canvas.height = 512;
|
|
4010
4257
|
const context = canvas.getContext("2d");
|
|
4011
4258
|
if (!context) {
|
|
4012
|
-
const fallback = new
|
|
4259
|
+
const fallback = new THREE37__namespace.CanvasTexture(canvas);
|
|
4013
4260
|
fallback.needsUpdate = true;
|
|
4014
4261
|
return fallback;
|
|
4015
4262
|
}
|
|
@@ -4037,8 +4284,8 @@ function createGradientTexture(effect, colors) {
|
|
|
4037
4284
|
context.fillRect(0, 0, 512, 512);
|
|
4038
4285
|
context.globalCompositeOperation = "source-over";
|
|
4039
4286
|
}
|
|
4040
|
-
const texture = new
|
|
4041
|
-
texture.colorSpace =
|
|
4287
|
+
const texture = new THREE37__namespace.CanvasTexture(canvas);
|
|
4288
|
+
texture.colorSpace = THREE37__namespace.SRGBColorSpace;
|
|
4042
4289
|
texture.needsUpdate = true;
|
|
4043
4290
|
return texture;
|
|
4044
4291
|
}
|
|
@@ -4055,7 +4302,7 @@ function readRenderer(world) {
|
|
|
4055
4302
|
__name(readRenderer, "readRenderer");
|
|
4056
4303
|
var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
4057
4304
|
constructor(scene) {
|
|
4058
|
-
this.textureLoader = new
|
|
4305
|
+
this.textureLoader = new THREE37__namespace.TextureLoader();
|
|
4059
4306
|
/** `true` once an Environment entity has been seen (drives the reset path). */
|
|
4060
4307
|
this.hasEnvironment = false;
|
|
4061
4308
|
this.skyboxSignature = null;
|
|
@@ -4139,7 +4386,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
4139
4386
|
if (skybox.type === "color") {
|
|
4140
4387
|
this.disposeActiveTexture();
|
|
4141
4388
|
this.pendingImageUrl = null;
|
|
4142
|
-
this.setSkyboxBackground(new
|
|
4389
|
+
this.setSkyboxBackground(new THREE37__namespace.Color(skybox.color || "#1e1e1e"));
|
|
4143
4390
|
return;
|
|
4144
4391
|
}
|
|
4145
4392
|
if (skybox.type === "gradient") {
|
|
@@ -4174,7 +4421,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
4174
4421
|
return;
|
|
4175
4422
|
}
|
|
4176
4423
|
if (!equirect) {
|
|
4177
|
-
texture.colorSpace =
|
|
4424
|
+
texture.colorSpace = THREE37__namespace.SRGBColorSpace;
|
|
4178
4425
|
}
|
|
4179
4426
|
this.activeTexture = texture;
|
|
4180
4427
|
this.setSkyboxBackground(texture);
|
|
@@ -4202,16 +4449,16 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
4202
4449
|
this.scene.fog = null;
|
|
4203
4450
|
return;
|
|
4204
4451
|
}
|
|
4205
|
-
const fogColor = new
|
|
4452
|
+
const fogColor = new THREE37__namespace.Color(fog.color || "#1e1e1e");
|
|
4206
4453
|
if (fog.type === "linear") {
|
|
4207
4454
|
const near = Number.isFinite(fog.linear.near) ? fog.linear.near : 1;
|
|
4208
4455
|
const farCandidate = Number.isFinite(fog.linear.far) ? fog.linear.far : near + 10;
|
|
4209
4456
|
const far = Math.max(near + MIN_FOG_DELTA, farCandidate);
|
|
4210
|
-
this.scene.fog = new
|
|
4457
|
+
this.scene.fog = new THREE37__namespace.Fog(fogColor, near, far);
|
|
4211
4458
|
return;
|
|
4212
4459
|
}
|
|
4213
4460
|
const density = Number.isFinite(fog.exponential.density) ? Math.max(MIN_DENSITY, fog.exponential.density) : 2e-3;
|
|
4214
|
-
this.scene.fog = new
|
|
4461
|
+
this.scene.fog = new THREE37__namespace.FogExp2(fogColor, density);
|
|
4215
4462
|
}
|
|
4216
4463
|
// ── Image-based lighting ────────────────────────────────────────────────
|
|
4217
4464
|
disposeEnvResources() {
|
|
@@ -4273,7 +4520,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
4273
4520
|
if (!renderer || getRendererKindOf(renderer) === "webgpu") return null;
|
|
4274
4521
|
let generator = null;
|
|
4275
4522
|
try {
|
|
4276
|
-
generator = new
|
|
4523
|
+
generator = new THREE37__namespace.PMREMGenerator(renderer);
|
|
4277
4524
|
return generator.fromEquirectangular(texture);
|
|
4278
4525
|
} catch (error) {
|
|
4279
4526
|
console.warn(
|
|
@@ -4413,7 +4660,7 @@ var PixelationShader = {
|
|
|
4413
4660
|
name: "PixelationShader",
|
|
4414
4661
|
uniforms: {
|
|
4415
4662
|
tDiffuse: { value: null },
|
|
4416
|
-
resolution: { value: new
|
|
4663
|
+
resolution: { value: new THREE37__namespace.Vector2(1, 1) },
|
|
4417
4664
|
pixelSize: { value: 6 }
|
|
4418
4665
|
},
|
|
4419
4666
|
vertexShader: (
|
|
@@ -4483,10 +4730,10 @@ function createWebglPostprocessing({
|
|
|
4483
4730
|
);
|
|
4484
4731
|
}
|
|
4485
4732
|
if (values.bloom.enabled) {
|
|
4486
|
-
const size = renderer.getSize(new
|
|
4733
|
+
const size = renderer.getSize(new THREE37__namespace.Vector2());
|
|
4487
4734
|
composer.addPass(
|
|
4488
4735
|
new UnrealBloomPass_js.UnrealBloomPass(
|
|
4489
|
-
new
|
|
4736
|
+
new THREE37__namespace.Vector2(size.width, size.height),
|
|
4490
4737
|
values.bloom.intensity,
|
|
4491
4738
|
values.bloom.radius,
|
|
4492
4739
|
values.bloom.threshold
|
|
@@ -4531,7 +4778,7 @@ function createWebglPostprocessing({
|
|
|
4531
4778
|
if (values.dotScreen.enabled) {
|
|
4532
4779
|
composer.addPass(
|
|
4533
4780
|
new DotScreenPass_js.DotScreenPass(
|
|
4534
|
-
new
|
|
4781
|
+
new THREE37__namespace.Vector2(0, 0),
|
|
4535
4782
|
values.dotScreen.angle ?? values.dotScreen.dotScreenAngle,
|
|
4536
4783
|
values.dotScreen.scale ?? values.dotScreen.dotScreenScale
|
|
4537
4784
|
)
|
|
@@ -4580,10 +4827,10 @@ function createWebglPostprocessing({
|
|
|
4580
4827
|
__name(createWebglPostprocessing, "createWebglPostprocessing");
|
|
4581
4828
|
var CHROMA_KEY_FLAG = "ecsChromaKey";
|
|
4582
4829
|
function createWebglChromaKeyMaterial(texture, options) {
|
|
4583
|
-
const material = new
|
|
4830
|
+
const material = new THREE37__namespace.ShaderMaterial({
|
|
4584
4831
|
uniforms: {
|
|
4585
4832
|
tex: { value: texture },
|
|
4586
|
-
keyColor: { value: new
|
|
4833
|
+
keyColor: { value: new THREE37__namespace.Color(options.keyColor) },
|
|
4587
4834
|
similarity: { value: options.similarity },
|
|
4588
4835
|
smoothness: { value: options.smoothness },
|
|
4589
4836
|
spill: { value: options.spill }
|
|
@@ -4615,14 +4862,14 @@ function createWebglChromaKeyMaterial(texture, options) {
|
|
|
4615
4862
|
}
|
|
4616
4863
|
`,
|
|
4617
4864
|
transparent: true,
|
|
4618
|
-
side:
|
|
4865
|
+
side: THREE37__namespace.DoubleSide
|
|
4619
4866
|
});
|
|
4620
4867
|
material.userData[CHROMA_KEY_FLAG] = true;
|
|
4621
4868
|
return material;
|
|
4622
4869
|
}
|
|
4623
4870
|
__name(createWebglChromaKeyMaterial, "createWebglChromaKeyMaterial");
|
|
4624
4871
|
function updateWebglChromaKeyMaterial(material, options) {
|
|
4625
|
-
if (!(material instanceof
|
|
4872
|
+
if (!(material instanceof THREE37__namespace.ShaderMaterial)) return false;
|
|
4626
4873
|
const { keyColor, similarity, smoothness, spill } = material.uniforms;
|
|
4627
4874
|
if (!keyColor || !similarity || !smoothness || !spill) return false;
|
|
4628
4875
|
keyColor.value.set(options.keyColor);
|
|
@@ -4824,7 +5071,7 @@ function computeColliderState(colliderValues, object) {
|
|
|
4824
5071
|
if (!object) {
|
|
4825
5072
|
return colliderValues;
|
|
4826
5073
|
}
|
|
4827
|
-
const scale = new
|
|
5074
|
+
const scale = new THREE37__namespace.Vector3();
|
|
4828
5075
|
object.getWorldScale(scale);
|
|
4829
5076
|
return {
|
|
4830
5077
|
...colliderValues,
|
|
@@ -4875,8 +5122,8 @@ function createColliderDesc(RAPIER, values, triMeshData) {
|
|
|
4875
5122
|
values.offsetPosition.y,
|
|
4876
5123
|
values.offsetPosition.z
|
|
4877
5124
|
);
|
|
4878
|
-
const offsetQuaternion = new
|
|
4879
|
-
new
|
|
5125
|
+
const offsetQuaternion = new THREE37__namespace.Quaternion().setFromEuler(
|
|
5126
|
+
new THREE37__namespace.Euler(
|
|
4880
5127
|
values.offsetRotation.x,
|
|
4881
5128
|
values.offsetRotation.y,
|
|
4882
5129
|
values.offsetRotation.z
|
|
@@ -4891,17 +5138,17 @@ function collectTriMeshParts(object) {
|
|
|
4891
5138
|
return null;
|
|
4892
5139
|
}
|
|
4893
5140
|
object.updateWorldMatrix(true, true);
|
|
4894
|
-
const worldScale = new
|
|
5141
|
+
const worldScale = new THREE37__namespace.Vector3();
|
|
4895
5142
|
object.getWorldScale(worldScale);
|
|
4896
5143
|
const scale = {
|
|
4897
5144
|
x: Math.abs(worldScale.x) || 1,
|
|
4898
5145
|
y: Math.abs(worldScale.y) || 1,
|
|
4899
5146
|
z: Math.abs(worldScale.z) || 1
|
|
4900
5147
|
};
|
|
4901
|
-
const worldToObject = new
|
|
5148
|
+
const worldToObject = new THREE37__namespace.Matrix4().copy(object.matrixWorld).invert();
|
|
4902
5149
|
const parts = [];
|
|
4903
5150
|
object.traverse((child) => {
|
|
4904
|
-
if (!(child instanceof
|
|
5151
|
+
if (!(child instanceof THREE37__namespace.Mesh) || !child.geometry) {
|
|
4905
5152
|
return;
|
|
4906
5153
|
}
|
|
4907
5154
|
const geometry = child.geometry;
|
|
@@ -4918,7 +5165,7 @@ function collectTriMeshParts(object) {
|
|
|
4918
5165
|
if (indexCount < 3) {
|
|
4919
5166
|
return;
|
|
4920
5167
|
}
|
|
4921
|
-
const relativeMatrix = new
|
|
5168
|
+
const relativeMatrix = new THREE37__namespace.Matrix4().multiplyMatrices(
|
|
4922
5169
|
worldToObject,
|
|
4923
5170
|
child.matrixWorld
|
|
4924
5171
|
);
|
|
@@ -4959,7 +5206,7 @@ function createTriMeshData(collected) {
|
|
|
4959
5206
|
}
|
|
4960
5207
|
const vertices = new Float32Array(vertexTotal * 3);
|
|
4961
5208
|
const indices = new Uint32Array(indexTotal);
|
|
4962
|
-
const point = new
|
|
5209
|
+
const point = new THREE37__namespace.Vector3();
|
|
4963
5210
|
let vertexOffset = 0;
|
|
4964
5211
|
let indexOffset = 0;
|
|
4965
5212
|
for (const part of parts) {
|
|
@@ -4991,8 +5238,8 @@ function createTriMeshData(collected) {
|
|
|
4991
5238
|
}
|
|
4992
5239
|
__name(createTriMeshData, "createTriMeshData");
|
|
4993
5240
|
function syncBodyFromTransform(body, transform) {
|
|
4994
|
-
const quaternion = new
|
|
4995
|
-
new
|
|
5241
|
+
const quaternion = new THREE37__namespace.Quaternion().setFromEuler(
|
|
5242
|
+
new THREE37__namespace.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z)
|
|
4996
5243
|
);
|
|
4997
5244
|
body.setTranslation(
|
|
4998
5245
|
{
|
|
@@ -5019,8 +5266,8 @@ function syncTransformFromBody(transform, body) {
|
|
|
5019
5266
|
transform.position.x = position.x;
|
|
5020
5267
|
transform.position.y = position.y;
|
|
5021
5268
|
transform.position.z = position.z;
|
|
5022
|
-
const euler = new
|
|
5023
|
-
new
|
|
5269
|
+
const euler = new THREE37__namespace.Euler().setFromQuaternion(
|
|
5270
|
+
new THREE37__namespace.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w)
|
|
5024
5271
|
);
|
|
5025
5272
|
transform.rotation.x = euler.x;
|
|
5026
5273
|
transform.rotation.y = euler.y;
|
|
@@ -5133,8 +5380,8 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
|
|
|
5133
5380
|
transform.position.y,
|
|
5134
5381
|
transform.position.z
|
|
5135
5382
|
);
|
|
5136
|
-
const quaternion = new
|
|
5137
|
-
new
|
|
5383
|
+
const quaternion = new THREE37__namespace.Quaternion().setFromEuler(
|
|
5384
|
+
new THREE37__namespace.Euler(
|
|
5138
5385
|
transform.rotation.x,
|
|
5139
5386
|
transform.rotation.y,
|
|
5140
5387
|
transform.rotation.z
|
|
@@ -5865,7 +6112,7 @@ function applyLightValues(lightComponent, rendererKind) {
|
|
|
5865
6112
|
values.castShadow
|
|
5866
6113
|
);
|
|
5867
6114
|
}
|
|
5868
|
-
if (light instanceof
|
|
6115
|
+
if (light instanceof THREE37__namespace.PointLight) {
|
|
5869
6116
|
if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
|
|
5870
6117
|
light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
|
|
5871
6118
|
}
|
|
@@ -5873,7 +6120,7 @@ function applyLightValues(lightComponent, rendererKind) {
|
|
|
5873
6120
|
light.decay = Math.max(0, values.decay);
|
|
5874
6121
|
}
|
|
5875
6122
|
}
|
|
5876
|
-
if (light instanceof
|
|
6123
|
+
if (light instanceof THREE37__namespace.SpotLight) {
|
|
5877
6124
|
if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
|
|
5878
6125
|
light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
|
|
5879
6126
|
}
|
|
@@ -5887,7 +6134,7 @@ function applyLightValues(lightComponent, rendererKind) {
|
|
|
5887
6134
|
light.penumbra = Math.max(0, Math.min(1, values.penumbra));
|
|
5888
6135
|
}
|
|
5889
6136
|
}
|
|
5890
|
-
if (light instanceof
|
|
6137
|
+
if (light instanceof THREE37__namespace.RectAreaLight) {
|
|
5891
6138
|
if (typeof values.width === "number" && Number.isFinite(values.width)) {
|
|
5892
6139
|
light.width = Math.max(MIN_AREA_SIZE, values.width);
|
|
5893
6140
|
}
|
|
@@ -5951,15 +6198,15 @@ function resolveMaterialPropertyKey(key) {
|
|
|
5951
6198
|
__name(resolveMaterialPropertyKey, "resolveMaterialPropertyKey");
|
|
5952
6199
|
function createMaterialByType(type) {
|
|
5953
6200
|
if (type === "basic") {
|
|
5954
|
-
return new
|
|
6201
|
+
return new THREE37__namespace.MeshBasicMaterial();
|
|
5955
6202
|
}
|
|
5956
6203
|
if (type === "phong") {
|
|
5957
|
-
return new
|
|
6204
|
+
return new THREE37__namespace.MeshPhongMaterial();
|
|
5958
6205
|
}
|
|
5959
6206
|
if (type === "physical") {
|
|
5960
|
-
return new
|
|
6207
|
+
return new THREE37__namespace.MeshPhysicalMaterial();
|
|
5961
6208
|
}
|
|
5962
|
-
return new
|
|
6209
|
+
return new THREE37__namespace.MeshStandardMaterial();
|
|
5963
6210
|
}
|
|
5964
6211
|
__name(createMaterialByType, "createMaterialByType");
|
|
5965
6212
|
function replaceMaterialAcrossObject(object, previous, next) {
|
|
@@ -6018,12 +6265,12 @@ function applyTextureFiltering(material, filtering) {
|
|
|
6018
6265
|
const target = material;
|
|
6019
6266
|
for (const slot of materialTextureSlots) {
|
|
6020
6267
|
const texture = target[slot];
|
|
6021
|
-
if (!texture || !(texture instanceof
|
|
6268
|
+
if (!texture || !(texture instanceof THREE37__namespace.Texture)) {
|
|
6022
6269
|
continue;
|
|
6023
6270
|
}
|
|
6024
6271
|
const useMipmaps = texture.generateMipmaps !== false;
|
|
6025
|
-
texture.magFilter = sharp ?
|
|
6026
|
-
texture.minFilter = useMipmaps ? sharp ?
|
|
6272
|
+
texture.magFilter = sharp ? THREE37__namespace.NearestFilter : THREE37__namespace.LinearFilter;
|
|
6273
|
+
texture.minFilter = useMipmaps ? sharp ? THREE37__namespace.NearestMipmapNearestFilter : THREE37__namespace.LinearMipmapLinearFilter : sharp ? THREE37__namespace.NearestFilter : THREE37__namespace.LinearFilter;
|
|
6027
6274
|
texture.needsUpdate = true;
|
|
6028
6275
|
}
|
|
6029
6276
|
material.needsUpdate = true;
|
|
@@ -6033,12 +6280,12 @@ function setTextureMipmaps(material, enabled) {
|
|
|
6033
6280
|
const target = material;
|
|
6034
6281
|
for (const slot of materialTextureSlots) {
|
|
6035
6282
|
const texture = target[slot];
|
|
6036
|
-
if (!texture || !(texture instanceof
|
|
6283
|
+
if (!texture || !(texture instanceof THREE37__namespace.Texture)) {
|
|
6037
6284
|
continue;
|
|
6038
6285
|
}
|
|
6039
6286
|
texture.generateMipmaps = enabled;
|
|
6040
|
-
const sharp = texture.magFilter ===
|
|
6041
|
-
texture.minFilter = enabled ? sharp ?
|
|
6287
|
+
const sharp = texture.magFilter === THREE37__namespace.NearestFilter;
|
|
6288
|
+
texture.minFilter = enabled ? sharp ? THREE37__namespace.NearestMipmapNearestFilter : THREE37__namespace.LinearMipmapLinearFilter : sharp ? THREE37__namespace.NearestFilter : THREE37__namespace.LinearFilter;
|
|
6042
6289
|
texture.needsUpdate = true;
|
|
6043
6290
|
}
|
|
6044
6291
|
material.needsUpdate = true;
|
|
@@ -6049,7 +6296,7 @@ function assignMaterialTexture(material, rawKey, url, textureCache) {
|
|
|
6049
6296
|
const key = resolveMaterialPropertyKey(rawKey);
|
|
6050
6297
|
let texture = textureCache.get(url);
|
|
6051
6298
|
if (!texture) {
|
|
6052
|
-
texture = new
|
|
6299
|
+
texture = new THREE37__namespace.TextureLoader().load(url);
|
|
6053
6300
|
textureCache.set(url, texture);
|
|
6054
6301
|
}
|
|
6055
6302
|
target[key] = texture;
|
|
@@ -6087,7 +6334,7 @@ function applyMaterialState(material, value, textureCache) {
|
|
|
6087
6334
|
}
|
|
6088
6335
|
target.side = value.side;
|
|
6089
6336
|
target.blending = value.blending;
|
|
6090
|
-
target.premultipliedAlpha = value.blending ===
|
|
6337
|
+
target.premultipliedAlpha = value.blending === THREE37__namespace.MultiplyBlending || value.blending === THREE37__namespace.SubtractiveBlending;
|
|
6091
6338
|
target.depthTest = value.depthTest;
|
|
6092
6339
|
target.depthWrite = value.depthWrite;
|
|
6093
6340
|
target.wireframe = value.wireframe;
|
|
@@ -6248,12 +6495,12 @@ function resolvePrimaryMesh(object) {
|
|
|
6248
6495
|
if (!object) {
|
|
6249
6496
|
return null;
|
|
6250
6497
|
}
|
|
6251
|
-
if (object instanceof
|
|
6498
|
+
if (object instanceof THREE37__namespace.Mesh) {
|
|
6252
6499
|
return object;
|
|
6253
6500
|
}
|
|
6254
6501
|
let found = null;
|
|
6255
6502
|
object.traverse((child) => {
|
|
6256
|
-
if (!found && child instanceof
|
|
6503
|
+
if (!found && child instanceof THREE37__namespace.Mesh) {
|
|
6257
6504
|
found = child;
|
|
6258
6505
|
}
|
|
6259
6506
|
});
|
|
@@ -6274,22 +6521,22 @@ function applyGeometry(component) {
|
|
|
6274
6521
|
switch (component.kind) {
|
|
6275
6522
|
case "cube": {
|
|
6276
6523
|
const params = sanitized;
|
|
6277
|
-
nextGeometry = new
|
|
6524
|
+
nextGeometry = new THREE37__namespace.BoxGeometry(params.width, params.height, params.depth);
|
|
6278
6525
|
break;
|
|
6279
6526
|
}
|
|
6280
6527
|
case "plane": {
|
|
6281
6528
|
const params = sanitized;
|
|
6282
|
-
nextGeometry = new
|
|
6529
|
+
nextGeometry = new THREE37__namespace.PlaneGeometry(params.width, params.height);
|
|
6283
6530
|
break;
|
|
6284
6531
|
}
|
|
6285
6532
|
case "sphere": {
|
|
6286
6533
|
const params = sanitized;
|
|
6287
|
-
nextGeometry = new
|
|
6534
|
+
nextGeometry = new THREE37__namespace.SphereGeometry(params.radius, 24, 24);
|
|
6288
6535
|
break;
|
|
6289
6536
|
}
|
|
6290
6537
|
case "cylinder": {
|
|
6291
6538
|
const params = sanitized;
|
|
6292
|
-
nextGeometry = new
|
|
6539
|
+
nextGeometry = new THREE37__namespace.CylinderGeometry(
|
|
6293
6540
|
params.radius,
|
|
6294
6541
|
params.radius,
|
|
6295
6542
|
params.height,
|
|
@@ -6299,7 +6546,7 @@ function applyGeometry(component) {
|
|
|
6299
6546
|
}
|
|
6300
6547
|
case "capsule": {
|
|
6301
6548
|
const params = sanitized;
|
|
6302
|
-
nextGeometry = new
|
|
6549
|
+
nextGeometry = new THREE37__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
|
|
6303
6550
|
break;
|
|
6304
6551
|
}
|
|
6305
6552
|
default:
|
|
@@ -6315,7 +6562,7 @@ function applyShadowFlags(component) {
|
|
|
6315
6562
|
return;
|
|
6316
6563
|
}
|
|
6317
6564
|
component.object.traverse((child) => {
|
|
6318
|
-
if (child instanceof
|
|
6565
|
+
if (child instanceof THREE37__namespace.Mesh) {
|
|
6319
6566
|
child.castShadow = component.castShadow;
|
|
6320
6567
|
child.receiveShadow = component.receiveShadow;
|
|
6321
6568
|
}
|
|
@@ -6391,35 +6638,35 @@ function buildGeometry(component) {
|
|
|
6391
6638
|
switch (component.meshKind) {
|
|
6392
6639
|
case "cube": {
|
|
6393
6640
|
const params = p;
|
|
6394
|
-
return new
|
|
6641
|
+
return new THREE37__namespace.BoxGeometry(params.width, params.height, params.depth);
|
|
6395
6642
|
}
|
|
6396
6643
|
case "plane": {
|
|
6397
6644
|
const params = p;
|
|
6398
|
-
return new
|
|
6645
|
+
return new THREE37__namespace.PlaneGeometry(params.width, params.height);
|
|
6399
6646
|
}
|
|
6400
6647
|
case "sphere": {
|
|
6401
6648
|
const params = p;
|
|
6402
|
-
return new
|
|
6649
|
+
return new THREE37__namespace.SphereGeometry(params.radius, 24, 24);
|
|
6403
6650
|
}
|
|
6404
6651
|
case "cylinder": {
|
|
6405
6652
|
const params = p;
|
|
6406
|
-
return new
|
|
6653
|
+
return new THREE37__namespace.CylinderGeometry(params.radius, params.radius, params.height, 20);
|
|
6407
6654
|
}
|
|
6408
6655
|
case "capsule": {
|
|
6409
6656
|
const params = p;
|
|
6410
|
-
return new
|
|
6657
|
+
return new THREE37__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
|
|
6411
6658
|
}
|
|
6412
6659
|
default:
|
|
6413
|
-
return new
|
|
6660
|
+
return new THREE37__namespace.BoxGeometry(1, 1, 1);
|
|
6414
6661
|
}
|
|
6415
6662
|
}
|
|
6416
6663
|
__name(buildGeometry, "buildGeometry");
|
|
6417
|
-
var _position = new
|
|
6418
|
-
var _quaternion = new
|
|
6419
|
-
var _euler = new
|
|
6420
|
-
var _scale = new
|
|
6421
|
-
var _matrix = new
|
|
6422
|
-
var _modelMatrix = new
|
|
6664
|
+
var _position = new THREE37__namespace.Vector3();
|
|
6665
|
+
var _quaternion = new THREE37__namespace.Quaternion();
|
|
6666
|
+
var _euler = new THREE37__namespace.Euler();
|
|
6667
|
+
var _scale = new THREE37__namespace.Vector3();
|
|
6668
|
+
var _matrix = new THREE37__namespace.Matrix4();
|
|
6669
|
+
var _modelMatrix = new THREE37__namespace.Matrix4();
|
|
6423
6670
|
function instanceTransformFromComponent(transform, out) {
|
|
6424
6671
|
_position.set(transform.position.x, transform.position.y, transform.position.z);
|
|
6425
6672
|
_euler.set(transform.rotation.x, transform.rotation.y, transform.rotation.z, "XYZ");
|
|
@@ -6501,9 +6748,9 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
6501
6748
|
const instanceCount = comp.instanceEntityIds.length;
|
|
6502
6749
|
const geometrySignature = comp.meshKind === "model" ? `model:${comp.modelPath}:${instanceCount}` : `${comp.meshKind}:${JSON.stringify(comp.meshParameters)}:${instanceCount}`;
|
|
6503
6750
|
if (comp.instancedMesh === null) {
|
|
6504
|
-
const
|
|
6505
|
-
if (
|
|
6506
|
-
comp.instancedMesh =
|
|
6751
|
+
const tracked2 = this.trackedMeshes.get(entityId);
|
|
6752
|
+
if (tracked2) {
|
|
6753
|
+
comp.instancedMesh = tracked2;
|
|
6507
6754
|
}
|
|
6508
6755
|
}
|
|
6509
6756
|
const pendingLoadSignature = this.loadingSignatures.get(entityId);
|
|
@@ -6572,7 +6819,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
6572
6819
|
const sourceMaterial = Array.isArray(meshChild.material) ? meshChild.material.map((m) => m.clone()) : meshChild.material.clone();
|
|
6573
6820
|
meshChild.updateWorldMatrix(true, false);
|
|
6574
6821
|
const localMatrix = meshChild.matrixWorld.clone();
|
|
6575
|
-
const instancedMesh2 = new
|
|
6822
|
+
const instancedMesh2 = new THREE37__namespace.InstancedMesh(
|
|
6576
6823
|
geometry2,
|
|
6577
6824
|
Array.isArray(sourceMaterial) ? sourceMaterial : sourceMaterial,
|
|
6578
6825
|
count2
|
|
@@ -6597,7 +6844,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
6597
6844
|
this.loadingSignatures.delete(targetEntityId);
|
|
6598
6845
|
return;
|
|
6599
6846
|
}
|
|
6600
|
-
const group = new
|
|
6847
|
+
const group = new THREE37__namespace.Group();
|
|
6601
6848
|
for (const entry of entries) {
|
|
6602
6849
|
group.add(entry.instancedMesh);
|
|
6603
6850
|
}
|
|
@@ -6615,8 +6862,8 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
6615
6862
|
}
|
|
6616
6863
|
const count = instanceCount;
|
|
6617
6864
|
const geometry = buildGeometry(comp);
|
|
6618
|
-
const material = new
|
|
6619
|
-
const instancedMesh = new
|
|
6865
|
+
const material = new THREE37__namespace.MeshStandardMaterial({ color: "#ffffff" });
|
|
6866
|
+
const instancedMesh = new THREE37__namespace.InstancedMesh(geometry, material, count);
|
|
6620
6867
|
instancedMesh.castShadow = comp.castShadow;
|
|
6621
6868
|
instancedMesh.receiveShadow = comp.receiveShadow;
|
|
6622
6869
|
for (let i = 0; i < count; i++) {
|
|
@@ -6952,6 +7199,14 @@ function applyParentLinks(snapshot, idMap, objectManagementSystem, world) {
|
|
|
6952
7199
|
__name(applyParentLinks, "applyParentLinks");
|
|
6953
7200
|
|
|
6954
7201
|
// core/hydration/postCreateComponents.ts
|
|
7202
|
+
var OPTIONAL_UI_FIELDS = {
|
|
7203
|
+
pixelDensity: "number",
|
|
7204
|
+
icon: "string",
|
|
7205
|
+
iconPosition: "string",
|
|
7206
|
+
variant: "string",
|
|
7207
|
+
step: "number",
|
|
7208
|
+
readOnly: "boolean"
|
|
7209
|
+
};
|
|
6955
7210
|
function remapEntityRefsInScriptData(data, idMap) {
|
|
6956
7211
|
const result = {};
|
|
6957
7212
|
for (const [key, value] of Object.entries(data)) {
|
|
@@ -7335,6 +7590,20 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
7335
7590
|
const target = component;
|
|
7336
7591
|
for (const [key, value] of Object.entries(source)) {
|
|
7337
7592
|
const current = target[key];
|
|
7593
|
+
if (key === "style") {
|
|
7594
|
+
const style = normalizeUiStyle(value);
|
|
7595
|
+
if (style) target.style = style;
|
|
7596
|
+
continue;
|
|
7597
|
+
}
|
|
7598
|
+
if (key === "tokens") {
|
|
7599
|
+
const tokens = normalizeUiTokens(value);
|
|
7600
|
+
if (tokens) target.tokens = tokens;
|
|
7601
|
+
continue;
|
|
7602
|
+
}
|
|
7603
|
+
if (OPTIONAL_UI_FIELDS[key] === typeof value) {
|
|
7604
|
+
target[key] = value;
|
|
7605
|
+
continue;
|
|
7606
|
+
}
|
|
7338
7607
|
if ((typeof value === "string" || typeof value === "number" || typeof value === "boolean") && typeof current === typeof value) {
|
|
7339
7608
|
target[key] = value;
|
|
7340
7609
|
}
|
|
@@ -8297,16 +8566,16 @@ function instantiateSubtree(world, objectManagementSystem, snapshot) {
|
|
|
8297
8566
|
__name(instantiateSubtree, "instantiateSubtree");
|
|
8298
8567
|
|
|
8299
8568
|
// core/prefab/types.ts
|
|
8300
|
-
var
|
|
8569
|
+
var isRecord2 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isRecord");
|
|
8301
8570
|
function parsePrefabAsset(json) {
|
|
8302
|
-
if (!
|
|
8571
|
+
if (!isRecord2(json)) {
|
|
8303
8572
|
return null;
|
|
8304
8573
|
}
|
|
8305
8574
|
if (typeof json.version !== "number" || json.version < 1) {
|
|
8306
8575
|
return null;
|
|
8307
8576
|
}
|
|
8308
8577
|
const snapshot = json.snapshot;
|
|
8309
|
-
if (!
|
|
8578
|
+
if (!isRecord2(snapshot)) {
|
|
8310
8579
|
return null;
|
|
8311
8580
|
}
|
|
8312
8581
|
const entities = snapshot.entities;
|
|
@@ -8318,7 +8587,7 @@ function parsePrefabAsset(json) {
|
|
|
8318
8587
|
return null;
|
|
8319
8588
|
}
|
|
8320
8589
|
if (!components.every(
|
|
8321
|
-
(block) =>
|
|
8590
|
+
(block) => isRecord2(block) && typeof block.component === "string" && Array.isArray(block.entries)
|
|
8322
8591
|
)) {
|
|
8323
8592
|
return null;
|
|
8324
8593
|
}
|
|
@@ -8576,7 +8845,7 @@ var _Behaviour = class _Behaviour {
|
|
|
8576
8845
|
if (!this.threeRef) {
|
|
8577
8846
|
return null;
|
|
8578
8847
|
}
|
|
8579
|
-
const position = new
|
|
8848
|
+
const position = new THREE37__namespace.Vector3();
|
|
8580
8849
|
this.threeRef.object.getWorldPosition(position);
|
|
8581
8850
|
return position;
|
|
8582
8851
|
}
|
|
@@ -8588,7 +8857,7 @@ var _Behaviour = class _Behaviour {
|
|
|
8588
8857
|
if (!this.threeRef) {
|
|
8589
8858
|
return null;
|
|
8590
8859
|
}
|
|
8591
|
-
const target = new
|
|
8860
|
+
const target = new THREE37__namespace.Vector3();
|
|
8592
8861
|
this.threeRef.object.getWorldDirection(target);
|
|
8593
8862
|
return target;
|
|
8594
8863
|
}
|
|
@@ -8650,7 +8919,7 @@ var _Behaviour = class _Behaviour {
|
|
|
8650
8919
|
if (!this.threeRef) {
|
|
8651
8920
|
return;
|
|
8652
8921
|
}
|
|
8653
|
-
const rotation = new
|
|
8922
|
+
const rotation = new THREE37__namespace.Quaternion();
|
|
8654
8923
|
this.threeRef.object.getWorldQuaternion(rotation);
|
|
8655
8924
|
rotation.slerp(targetRotation, alpha);
|
|
8656
8925
|
this.transform.setRotation(rotation);
|
|
@@ -8667,7 +8936,7 @@ var _Behaviour = class _Behaviour {
|
|
|
8667
8936
|
return;
|
|
8668
8937
|
}
|
|
8669
8938
|
const clone = this.threeRef.object.clone();
|
|
8670
|
-
const rotation = new
|
|
8939
|
+
const rotation = new THREE37__namespace.Quaternion();
|
|
8671
8940
|
clone.lookAt(targetPosition);
|
|
8672
8941
|
clone.getWorldQuaternion(rotation);
|
|
8673
8942
|
this.transform.setRotation(rotation);
|
|
@@ -9113,8 +9382,8 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
9113
9382
|
const retryDelay = options?.errorRetryDelay;
|
|
9114
9383
|
this.errorRetryDelay = typeof retryDelay === "number" && Number.isFinite(retryDelay) ? Math.max(0, retryDelay) : DEFAULT_SCRIPT_ERROR_RETRY_DELAY;
|
|
9115
9384
|
this.selectionCtx = selectionContext ?? null;
|
|
9116
|
-
this.raycaster = new
|
|
9117
|
-
this.ndcPointer = new
|
|
9385
|
+
this.raycaster = new THREE37__namespace.Raycaster();
|
|
9386
|
+
this.ndcPointer = new THREE37__namespace.Vector2();
|
|
9118
9387
|
if (this.selectionCtx) {
|
|
9119
9388
|
this.selectionCtx.domElement.addEventListener("pointerdown", this.onPointerDown);
|
|
9120
9389
|
this.selectionCtx.domElement.addEventListener("pointerup", this.onPointerUp);
|
|
@@ -9558,7 +9827,7 @@ function disposeBuiltObject(root) {
|
|
|
9558
9827
|
for (const mat of materials) {
|
|
9559
9828
|
if (mat.userData?.[SHARED_MODEL_RESOURCE_FLAG]) continue;
|
|
9560
9829
|
for (const value of Object.values(mat)) {
|
|
9561
|
-
if (value instanceof
|
|
9830
|
+
if (value instanceof THREE37__namespace.Texture) value.dispose();
|
|
9562
9831
|
}
|
|
9563
9832
|
mat.dispose?.();
|
|
9564
9833
|
}
|
|
@@ -10159,7 +10428,7 @@ var _AudioSystem = class _AudioSystem {
|
|
|
10159
10428
|
if (!prev || prev.volume !== opts.volume) {
|
|
10160
10429
|
sound.setVolume(opts.volume);
|
|
10161
10430
|
}
|
|
10162
|
-
if (opts.positional && sound instanceof
|
|
10431
|
+
if (opts.positional && sound instanceof THREE37__namespace.PositionalAudio) {
|
|
10163
10432
|
if (!prev || prev.refDistance !== opts.refDistance) {
|
|
10164
10433
|
sound.setRefDistance(opts.refDistance);
|
|
10165
10434
|
}
|
|
@@ -10299,7 +10568,7 @@ var _VideoSystem = class _VideoSystem {
|
|
|
10299
10568
|
spill: opts.spill
|
|
10300
10569
|
});
|
|
10301
10570
|
}
|
|
10302
|
-
if (opts.positional && component.audioNode instanceof
|
|
10571
|
+
if (opts.positional && component.audioNode instanceof THREE37__namespace.PositionalAudio) {
|
|
10303
10572
|
const posAudio = component.audioNode;
|
|
10304
10573
|
if (!prev || prev.refDistance !== opts.refDistance) {
|
|
10305
10574
|
posAudio.setRefDistance(opts.refDistance);
|
|
@@ -10339,8 +10608,8 @@ function blankState(source) {
|
|
|
10339
10608
|
handedness: handednessOf(source),
|
|
10340
10609
|
kind: kindOf(source),
|
|
10341
10610
|
connected: true,
|
|
10342
|
-
rayOrigin: new
|
|
10343
|
-
rayDirection: new
|
|
10611
|
+
rayOrigin: new THREE37__namespace.Vector3(),
|
|
10612
|
+
rayDirection: new THREE37__namespace.Vector3(0, 0, -1),
|
|
10344
10613
|
gripPosition: null,
|
|
10345
10614
|
gripQuaternion: null,
|
|
10346
10615
|
select: false,
|
|
@@ -10366,7 +10635,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
10366
10635
|
}
|
|
10367
10636
|
if (spaces.length === 0) return null;
|
|
10368
10637
|
const target = existing ?? {};
|
|
10369
|
-
const matrix = new
|
|
10638
|
+
const matrix = new THREE37__namespace.Matrix4();
|
|
10370
10639
|
const buffer = spaces.length * 16 <= JOINT_MATRIX_BUFFER.length ? JOINT_MATRIX_BUFFER : new Float32Array(spaces.length * 16);
|
|
10371
10640
|
const fillPoses = frame.fillPoses;
|
|
10372
10641
|
if (typeof fillPoses === "function") {
|
|
@@ -10379,7 +10648,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
10379
10648
|
if (filled) {
|
|
10380
10649
|
for (let i = 0; i < names.length; i += 1) {
|
|
10381
10650
|
matrix.fromArray(buffer, i * 16).premultiply(rigMatrix);
|
|
10382
|
-
const vector = target[names[i]] ?? new
|
|
10651
|
+
const vector = target[names[i]] ?? new THREE37__namespace.Vector3();
|
|
10383
10652
|
vector.setFromMatrixPosition(matrix);
|
|
10384
10653
|
target[names[i]] = vector;
|
|
10385
10654
|
}
|
|
@@ -10397,7 +10666,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
10397
10666
|
continue;
|
|
10398
10667
|
}
|
|
10399
10668
|
matrix.fromArray(pose.transform.matrix).premultiply(rigMatrix);
|
|
10400
|
-
const vector = target[names[i]] ?? new
|
|
10669
|
+
const vector = target[names[i]] ?? new THREE37__namespace.Vector3();
|
|
10401
10670
|
vector.setFromMatrixPosition(matrix);
|
|
10402
10671
|
target[names[i]] = vector;
|
|
10403
10672
|
anyTracked = true;
|
|
@@ -10409,7 +10678,7 @@ var _XRInputSystem = class _XRInputSystem {
|
|
|
10409
10678
|
constructor() {
|
|
10410
10679
|
this.records = /* @__PURE__ */ new Map();
|
|
10411
10680
|
/** Reference-space → world matrix, rebuilt each frame from the XR rig. */
|
|
10412
|
-
this.referenceToWorld = new
|
|
10681
|
+
this.referenceToWorld = new THREE37__namespace.Matrix4();
|
|
10413
10682
|
this.session = null;
|
|
10414
10683
|
this.onSelectStart = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectStart"), "onSelectStart");
|
|
10415
10684
|
this.onSelectEnd = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectEnd"), "onSelectEnd");
|
|
@@ -10507,19 +10776,19 @@ var _XRInputSystem = class _XRInputSystem {
|
|
|
10507
10776
|
if (frame && referenceSpace && source.targetRaySpace) {
|
|
10508
10777
|
const pose = frame.getPose(source.targetRaySpace, referenceSpace);
|
|
10509
10778
|
if (pose) {
|
|
10510
|
-
const m = new
|
|
10779
|
+
const m = new THREE37__namespace.Matrix4().fromArray(pose.transform.matrix).premultiply(rigMatrix);
|
|
10511
10780
|
state.rayOrigin.setFromMatrixPosition(m);
|
|
10512
10781
|
state.rayDirection.set(0, 0, -1).applyQuaternion(
|
|
10513
|
-
new
|
|
10782
|
+
new THREE37__namespace.Quaternion().setFromRotationMatrix(m)
|
|
10514
10783
|
).normalize();
|
|
10515
10784
|
}
|
|
10516
10785
|
}
|
|
10517
10786
|
if (frame && referenceSpace && source.gripSpace) {
|
|
10518
10787
|
const gripPose = frame.getPose(source.gripSpace, referenceSpace);
|
|
10519
10788
|
if (gripPose) {
|
|
10520
|
-
const m = new
|
|
10521
|
-
state.gripPosition ?? (state.gripPosition = new
|
|
10522
|
-
state.gripQuaternion ?? (state.gripQuaternion = new
|
|
10789
|
+
const m = new THREE37__namespace.Matrix4().fromArray(gripPose.transform.matrix).premultiply(rigMatrix);
|
|
10790
|
+
state.gripPosition ?? (state.gripPosition = new THREE37__namespace.Vector3());
|
|
10791
|
+
state.gripQuaternion ?? (state.gripQuaternion = new THREE37__namespace.Quaternion());
|
|
10523
10792
|
state.gripPosition.setFromMatrixPosition(m);
|
|
10524
10793
|
state.gripQuaternion.setFromRotationMatrix(m);
|
|
10525
10794
|
}
|
|
@@ -10621,6 +10890,51 @@ var _XRInputSystem = class _XRInputSystem {
|
|
|
10621
10890
|
};
|
|
10622
10891
|
__name(_XRInputSystem, "XRInputSystem");
|
|
10623
10892
|
var XRInputSystem = _XRInputSystem;
|
|
10893
|
+
|
|
10894
|
+
// core/ui/uiWidgetTree.ts
|
|
10895
|
+
var UI_PART_KEY = "__uiPart";
|
|
10896
|
+
function applyPartColor(mesh, tag) {
|
|
10897
|
+
const material = mesh.material;
|
|
10898
|
+
material.color.copy(tag.baseColor).multiplyScalar(tag.premultiplied ? tag.tint * tag.opacity : tag.tint);
|
|
10899
|
+
material.opacity = tag.opacity;
|
|
10900
|
+
}
|
|
10901
|
+
__name(applyPartColor, "applyPartColor");
|
|
10902
|
+
function isUiWidget(world, entityId) {
|
|
10903
|
+
return !!world.getComponent(entityId, UIPanelComponent) || !!world.getComponent(entityId, UITextComponent) || !!world.getComponent(entityId, UIButtonComponent) || !!world.getComponent(entityId, UIToggleComponent) || !!world.getComponent(entityId, UISliderComponent);
|
|
10904
|
+
}
|
|
10905
|
+
__name(isUiWidget, "isUiWidget");
|
|
10906
|
+
function isShownInScene(world, entityId) {
|
|
10907
|
+
let object = world.getComponent(entityId, Object3DRef)?.object ?? null;
|
|
10908
|
+
while (object) {
|
|
10909
|
+
if (!object.visible) return false;
|
|
10910
|
+
object = object.parent;
|
|
10911
|
+
}
|
|
10912
|
+
return true;
|
|
10913
|
+
}
|
|
10914
|
+
__name(isShownInScene, "isShownInScene");
|
|
10915
|
+
function nearestWidgetAncestor(world, entityId) {
|
|
10916
|
+
const visited = /* @__PURE__ */ new Set([entityId]);
|
|
10917
|
+
let current = entityId;
|
|
10918
|
+
for (; ; ) {
|
|
10919
|
+
const parentId = world.getComponent(current, ParentId)?.value;
|
|
10920
|
+
if (typeof parentId !== "number" || visited.has(parentId)) return null;
|
|
10921
|
+
if (isUiWidget(world, parentId)) return parentId;
|
|
10922
|
+
visited.add(parentId);
|
|
10923
|
+
current = parentId;
|
|
10924
|
+
}
|
|
10925
|
+
}
|
|
10926
|
+
__name(nearestWidgetAncestor, "nearestWidgetAncestor");
|
|
10927
|
+
function widgetTreeRoot(world, entityId) {
|
|
10928
|
+
const visited = /* @__PURE__ */ new Set([entityId]);
|
|
10929
|
+
let root = entityId;
|
|
10930
|
+
for (; ; ) {
|
|
10931
|
+
const parent = nearestWidgetAncestor(world, root);
|
|
10932
|
+
if (parent === null || visited.has(parent)) return root;
|
|
10933
|
+
visited.add(parent);
|
|
10934
|
+
root = parent;
|
|
10935
|
+
}
|
|
10936
|
+
}
|
|
10937
|
+
__name(widgetTreeRoot, "widgetTreeRoot");
|
|
10624
10938
|
var VELOCITY_SAMPLES = 5;
|
|
10625
10939
|
var MAX_SAMPLE_AGE_SECONDS = 0.2;
|
|
10626
10940
|
var MAX_PLAUSIBLE_SPEED = 20;
|
|
@@ -10647,15 +10961,15 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
|
|
|
10647
10961
|
const fresh = this.samples.filter(
|
|
10648
10962
|
(sample) => now - sample.time <= MAX_SAMPLE_AGE_SECONDS
|
|
10649
10963
|
);
|
|
10650
|
-
if (fresh.length < 2) return new
|
|
10651
|
-
let best = new
|
|
10964
|
+
if (fresh.length < 2) return new THREE37__namespace.Vector3();
|
|
10965
|
+
let best = new THREE37__namespace.Vector3();
|
|
10652
10966
|
let bestSpeed = 0;
|
|
10653
10967
|
for (let i = 1; i < fresh.length; i += 1) {
|
|
10654
10968
|
const previous = fresh[i - 1];
|
|
10655
10969
|
const current = fresh[i];
|
|
10656
10970
|
const dt = current.time - previous.time;
|
|
10657
10971
|
if (dt <= 1e-5) continue;
|
|
10658
|
-
const velocity = new
|
|
10972
|
+
const velocity = new THREE37__namespace.Vector3().subVectors(current.position, previous.position).divideScalar(dt);
|
|
10659
10973
|
const speed = velocity.length();
|
|
10660
10974
|
if (speed > MAX_PLAUSIBLE_SPEED) continue;
|
|
10661
10975
|
if (speed > bestSpeed) {
|
|
@@ -10672,15 +10986,15 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
|
|
|
10672
10986
|
__name(_ThrowVelocityTracker, "ThrowVelocityTracker");
|
|
10673
10987
|
var ThrowVelocityTracker = _ThrowVelocityTracker;
|
|
10674
10988
|
function angularVelocityFrom(previous, current, deltaTime) {
|
|
10675
|
-
if (deltaTime <= 1e-5) return new
|
|
10989
|
+
if (deltaTime <= 1e-5) return new THREE37__namespace.Vector3();
|
|
10676
10990
|
const delta = current.clone().multiply(previous.clone().invert());
|
|
10677
10991
|
if (delta.w < 0) {
|
|
10678
10992
|
delta.set(-delta.x, -delta.y, -delta.z, -delta.w);
|
|
10679
10993
|
}
|
|
10680
|
-
const angle = 2 * Math.acos(
|
|
10994
|
+
const angle = 2 * Math.acos(THREE37__namespace.MathUtils.clamp(delta.w, -1, 1));
|
|
10681
10995
|
const sinHalf = Math.sqrt(Math.max(0, 1 - delta.w * delta.w));
|
|
10682
|
-
if (sinHalf < 1e-6 || angle < 1e-6) return new
|
|
10683
|
-
return new
|
|
10996
|
+
if (sinHalf < 1e-6 || angle < 1e-6) return new THREE37__namespace.Vector3();
|
|
10997
|
+
return new THREE37__namespace.Vector3(delta.x, delta.y, delta.z).divideScalar(sinHalf).multiplyScalar(angle / deltaTime);
|
|
10684
10998
|
}
|
|
10685
10999
|
__name(angularVelocityFrom, "angularVelocityFrom");
|
|
10686
11000
|
var MIN_HAND_SEPARATION = 0.06;
|
|
@@ -10688,7 +11002,7 @@ var MIN_ANCHOR_SEPARATION = 1e-3;
|
|
|
10688
11002
|
var SCALE_DEADZONE = 0.05;
|
|
10689
11003
|
function solveTwoHandTransform(primary, secondary, basis, options) {
|
|
10690
11004
|
const separation = primary.position.distanceTo(secondary.position);
|
|
10691
|
-
const anchorDelta = new
|
|
11005
|
+
const anchorDelta = new THREE37__namespace.Vector3().subVectors(
|
|
10692
11006
|
basis.secondaryLocal,
|
|
10693
11007
|
basis.primaryLocal
|
|
10694
11008
|
);
|
|
@@ -10712,8 +11026,8 @@ function solveTwoHandTransform(primary, secondary, basis, options) {
|
|
|
10712
11026
|
} else {
|
|
10713
11027
|
const axisLocal = anchorDelta.clone().normalize();
|
|
10714
11028
|
const currentAxis = axisLocal.clone().applyQuaternion(base).normalize();
|
|
10715
|
-
const desiredAxis = new
|
|
10716
|
-
const correction = new
|
|
11029
|
+
const desiredAxis = new THREE37__namespace.Vector3().subVectors(secondary.position, primary.position).normalize();
|
|
11030
|
+
const correction = new THREE37__namespace.Quaternion().setFromUnitVectors(
|
|
10717
11031
|
currentAxis,
|
|
10718
11032
|
desiredAxis
|
|
10719
11033
|
);
|
|
@@ -10728,11 +11042,11 @@ __name(solveTwoHandTransform, "solveTwoHandTransform");
|
|
|
10728
11042
|
// core/systems/XRInteractionSystem.ts
|
|
10729
11043
|
var RAYLESS_HOLD_DISTANCE = 0.5;
|
|
10730
11044
|
function quatFromEulerVec(r) {
|
|
10731
|
-
return new
|
|
11045
|
+
return new THREE37__namespace.Quaternion().setFromEuler(new THREE37__namespace.Euler(r.x, r.y, r.z));
|
|
10732
11046
|
}
|
|
10733
11047
|
__name(quatFromEulerVec, "quatFromEulerVec");
|
|
10734
11048
|
function writeEuler(target, q) {
|
|
10735
|
-
const euler = new
|
|
11049
|
+
const euler = new THREE37__namespace.Euler().setFromQuaternion(q);
|
|
10736
11050
|
target.x = euler.x;
|
|
10737
11051
|
target.y = euler.y;
|
|
10738
11052
|
target.z = euler.z;
|
|
@@ -10740,7 +11054,7 @@ function writeEuler(target, q) {
|
|
|
10740
11054
|
__name(writeEuler, "writeEuler");
|
|
10741
11055
|
var _XRInteractionSystem = class _XRInteractionSystem {
|
|
10742
11056
|
constructor(inputSystem) {
|
|
10743
|
-
this.raycaster = new
|
|
11057
|
+
this.raycaster = new THREE37__namespace.Raycaster();
|
|
10744
11058
|
this.grabs = /* @__PURE__ */ new Map();
|
|
10745
11059
|
this.hoveredEntityId = null;
|
|
10746
11060
|
/** Per-hand hover, with the hit distance so the ray can stop at the surface. */
|
|
@@ -10851,7 +11165,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
10851
11165
|
const hand = this.handPosition(input);
|
|
10852
11166
|
const handQuaternion = this.handQuaternion(input);
|
|
10853
11167
|
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
10854
|
-
record.offset = new
|
|
11168
|
+
record.offset = new THREE37__namespace.Vector3(
|
|
10855
11169
|
transform.position.x - hand.x,
|
|
10856
11170
|
transform.position.y - hand.y,
|
|
10857
11171
|
transform.position.z - hand.z
|
|
@@ -10883,7 +11197,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
10883
11197
|
primary.record.twoHand = {
|
|
10884
11198
|
primaryLocal,
|
|
10885
11199
|
secondaryLocal,
|
|
10886
|
-
initialScale: new
|
|
11200
|
+
initialScale: new THREE37__namespace.Vector3(
|
|
10887
11201
|
transform.scale.x,
|
|
10888
11202
|
transform.scale.y,
|
|
10889
11203
|
transform.scale.z
|
|
@@ -10904,7 +11218,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
10904
11218
|
/** World point → the object's UNSCALED local space. */
|
|
10905
11219
|
objectLocalPoint(transform, worldPoint) {
|
|
10906
11220
|
const local = worldPoint.clone().sub(
|
|
10907
|
-
new
|
|
11221
|
+
new THREE37__namespace.Vector3(
|
|
10908
11222
|
transform.position.x,
|
|
10909
11223
|
transform.position.y,
|
|
10910
11224
|
transform.position.z
|
|
@@ -10962,7 +11276,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
10962
11276
|
);
|
|
10963
11277
|
if (!interactable2) continue;
|
|
10964
11278
|
if (interactable2.grabReach === "distance") continue;
|
|
10965
|
-
const position = new
|
|
11279
|
+
const position = new THREE37__namespace.Vector3();
|
|
10966
11280
|
entry.object.getWorldPosition(position);
|
|
10967
11281
|
const distance = position.distanceTo(hand);
|
|
10968
11282
|
if (distance <= interactable2.grabRadius && distance < nearestDistance) {
|
|
@@ -10994,6 +11308,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
10994
11308
|
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
10995
11309
|
if (!interactable?.enabled) continue;
|
|
10996
11310
|
if (!world.isEntityVisible(entityId)) continue;
|
|
11311
|
+
if (!isShownInScene(world, entityId)) continue;
|
|
10997
11312
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
10998
11313
|
if (object) {
|
|
10999
11314
|
out.push({ entityId, object, pointable: interactable.pointable });
|
|
@@ -11034,13 +11349,13 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11034
11349
|
this.holdersOf(entityId).map((holder) => holder.record.attachPointId).filter((id) => id !== null)
|
|
11035
11350
|
);
|
|
11036
11351
|
const hand = this.handPosition(input);
|
|
11037
|
-
const objectPosition = new
|
|
11352
|
+
const objectPosition = new THREE37__namespace.Vector3(
|
|
11038
11353
|
transform.position.x,
|
|
11039
11354
|
transform.position.y,
|
|
11040
11355
|
transform.position.z
|
|
11041
11356
|
);
|
|
11042
11357
|
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
11043
|
-
const scale = new
|
|
11358
|
+
const scale = new THREE37__namespace.Vector3(
|
|
11044
11359
|
transform.scale.x,
|
|
11045
11360
|
transform.scale.y,
|
|
11046
11361
|
transform.scale.z
|
|
@@ -11051,7 +11366,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11051
11366
|
if (taken.has(point.id)) continue;
|
|
11052
11367
|
if (point.hand !== "any" && point.hand !== input.handedness) continue;
|
|
11053
11368
|
if (point.role !== "any" && point.role !== role) continue;
|
|
11054
|
-
const world3 = new
|
|
11369
|
+
const world3 = new THREE37__namespace.Vector3(
|
|
11055
11370
|
point.position.x,
|
|
11056
11371
|
point.position.y,
|
|
11057
11372
|
point.position.z
|
|
@@ -11074,21 +11389,21 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11074
11389
|
let offset;
|
|
11075
11390
|
let remoteDistance = 0;
|
|
11076
11391
|
if (remote) {
|
|
11077
|
-
const position = new
|
|
11392
|
+
const position = new THREE37__namespace.Vector3(
|
|
11078
11393
|
transform.position.x,
|
|
11079
11394
|
transform.position.y,
|
|
11080
11395
|
transform.position.z
|
|
11081
11396
|
);
|
|
11082
11397
|
remoteDistance = position.distanceTo(input.rayOrigin);
|
|
11083
|
-
offset = new
|
|
11398
|
+
offset = new THREE37__namespace.Vector3();
|
|
11084
11399
|
} else if (viaDistance) {
|
|
11085
|
-
offset = new
|
|
11400
|
+
offset = new THREE37__namespace.Vector3(
|
|
11086
11401
|
interactable.grabOffsetPosition.x,
|
|
11087
11402
|
interactable.grabOffsetPosition.y,
|
|
11088
11403
|
interactable.grabOffsetPosition.z
|
|
11089
11404
|
);
|
|
11090
11405
|
} else {
|
|
11091
|
-
offset = new
|
|
11406
|
+
offset = new THREE37__namespace.Vector3(
|
|
11092
11407
|
transform.position.x - hand.x,
|
|
11093
11408
|
transform.position.y - hand.y,
|
|
11094
11409
|
transform.position.z - hand.z
|
|
@@ -11115,7 +11430,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11115
11430
|
entityId,
|
|
11116
11431
|
role,
|
|
11117
11432
|
attachPointId: attachPoint?.id ?? null,
|
|
11118
|
-
attachLocal: attachPoint ? new
|
|
11433
|
+
attachLocal: attachPoint ? new THREE37__namespace.Vector3(
|
|
11119
11434
|
attachPoint.position.x,
|
|
11120
11435
|
attachPoint.position.y,
|
|
11121
11436
|
attachPoint.position.z
|
|
@@ -11124,8 +11439,8 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11124
11439
|
handRotationOffset,
|
|
11125
11440
|
twoHand: null,
|
|
11126
11441
|
offset,
|
|
11127
|
-
rotationOffset: new
|
|
11128
|
-
new
|
|
11442
|
+
rotationOffset: new THREE37__namespace.Quaternion().setFromEuler(
|
|
11443
|
+
new THREE37__namespace.Euler(
|
|
11129
11444
|
interactable.grabOffsetRotation.x,
|
|
11130
11445
|
interactable.grabOffsetRotation.y,
|
|
11131
11446
|
interactable.grabOffsetRotation.z
|
|
@@ -11136,7 +11451,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11136
11451
|
restoreBodyType,
|
|
11137
11452
|
tracker,
|
|
11138
11453
|
lastHandQuaternion: handQuaternion.clone(),
|
|
11139
|
-
angularVelocity: new
|
|
11454
|
+
angularVelocity: new THREE37__namespace.Vector3()
|
|
11140
11455
|
});
|
|
11141
11456
|
if (role === "primary") {
|
|
11142
11457
|
this.dispatch(world, entityId, "onGrab", (b) => b.onGrab(input));
|
|
@@ -11209,14 +11524,14 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11209
11524
|
const handQuaternion = this.handQuaternion(input);
|
|
11210
11525
|
const objectQuaternion = held.attachQuaternion ? handQuaternion.clone().multiply(held.rotationOffset).multiply(held.attachQuaternion.clone().invert()) : handQuaternion.clone().multiply(held.handRotationOffset);
|
|
11211
11526
|
if (held.remote) {
|
|
11212
|
-
const target = new
|
|
11527
|
+
const target = new THREE37__namespace.Vector3().copy(input.rayDirection).multiplyScalar(held.remoteDistance).add(input.rayOrigin);
|
|
11213
11528
|
transform.position.x = target.x;
|
|
11214
11529
|
transform.position.y = target.y;
|
|
11215
11530
|
transform.position.z = target.z;
|
|
11216
11531
|
writeEuler(transform.rotation, objectQuaternion);
|
|
11217
11532
|
} else if (held.attachLocal) {
|
|
11218
11533
|
const anchor = held.attachLocal.clone().multiply(
|
|
11219
|
-
new
|
|
11534
|
+
new THREE37__namespace.Vector3(
|
|
11220
11535
|
transform.scale.x,
|
|
11221
11536
|
transform.scale.y,
|
|
11222
11537
|
transform.scale.z
|
|
@@ -11234,7 +11549,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11234
11549
|
writeEuler(transform.rotation, objectQuaternion);
|
|
11235
11550
|
}
|
|
11236
11551
|
held.tracker.record(
|
|
11237
|
-
held.remote ? new
|
|
11552
|
+
held.remote ? new THREE37__namespace.Vector3(
|
|
11238
11553
|
transform.position.x,
|
|
11239
11554
|
transform.position.y,
|
|
11240
11555
|
transform.position.z
|
|
@@ -11309,7 +11624,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11309
11624
|
*/
|
|
11310
11625
|
handPosition(input) {
|
|
11311
11626
|
if (input.gripPosition) return input.gripPosition;
|
|
11312
|
-
return new
|
|
11627
|
+
return new THREE37__namespace.Vector3().copy(input.rayDirection).multiplyScalar(RAYLESS_HOLD_DISTANCE).add(input.rayOrigin);
|
|
11313
11628
|
}
|
|
11314
11629
|
/**
|
|
11315
11630
|
* Hand orientation. Grip-less sources (gaze / transient-pointer) have none,
|
|
@@ -11317,8 +11632,8 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11317
11632
|
*/
|
|
11318
11633
|
handQuaternion(input) {
|
|
11319
11634
|
if (input.gripQuaternion) return input.gripQuaternion.clone();
|
|
11320
|
-
return new
|
|
11321
|
-
new
|
|
11635
|
+
return new THREE37__namespace.Quaternion().setFromUnitVectors(
|
|
11636
|
+
new THREE37__namespace.Vector3(0, 0, -1),
|
|
11322
11637
|
input.rayDirection.clone().normalize()
|
|
11323
11638
|
);
|
|
11324
11639
|
}
|
|
@@ -11455,7 +11770,7 @@ function sampleTeleportArc(origin, direction, out = [], options) {
|
|
|
11455
11770
|
for (let i = 0; i < steps; i += 1) {
|
|
11456
11771
|
const t = i / (steps - 1) * maxTime;
|
|
11457
11772
|
out.push(
|
|
11458
|
-
new
|
|
11773
|
+
new THREE37__namespace.Vector3(
|
|
11459
11774
|
origin.x + velocity.x * t,
|
|
11460
11775
|
origin.y + velocity.y * t - 0.5 * gravity * t * t,
|
|
11461
11776
|
origin.z + velocity.z * t
|
|
@@ -11503,11 +11818,11 @@ __name(_TeleportAimGate, "TeleportAimGate");
|
|
|
11503
11818
|
var TeleportAimGate = _TeleportAimGate;
|
|
11504
11819
|
|
|
11505
11820
|
// core/systems/XRLocomotionSystem.ts
|
|
11506
|
-
var UP = new
|
|
11821
|
+
var UP = new THREE37__namespace.Vector3(0, 1, 0);
|
|
11507
11822
|
var AXIS_DEADZONE = 0.5;
|
|
11508
11823
|
var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
11509
11824
|
constructor(inputSystem) {
|
|
11510
|
-
this.raycaster = new
|
|
11825
|
+
this.raycaster = new THREE37__namespace.Raycaster();
|
|
11511
11826
|
/** Per-source latch so one stick push yields exactly one snap turn. */
|
|
11512
11827
|
this.turnLatched = /* @__PURE__ */ new WeakSet();
|
|
11513
11828
|
/** Reused arc buffer — aiming runs every frame. */
|
|
@@ -11633,7 +11948,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
11633
11948
|
}
|
|
11634
11949
|
if (this.turnLatched.has(source)) continue;
|
|
11635
11950
|
this.turnLatched.add(source);
|
|
11636
|
-
transform.rotation.y -= Math.sign(x) *
|
|
11951
|
+
transform.rotation.y -= Math.sign(x) * THREE37__namespace.MathUtils.degToRad(rig.snapTurnDegrees);
|
|
11637
11952
|
}
|
|
11638
11953
|
}
|
|
11639
11954
|
applySmoothMove(world, rig, transform, inputs, deltaTime) {
|
|
@@ -11643,12 +11958,12 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
11643
11958
|
const y = input.axes[1] ?? 0;
|
|
11644
11959
|
if (Math.abs(x) < 0.15 && Math.abs(y) < 0.15) continue;
|
|
11645
11960
|
const camera = world.getCamera();
|
|
11646
|
-
const forward = new
|
|
11961
|
+
const forward = new THREE37__namespace.Vector3();
|
|
11647
11962
|
camera.getWorldDirection(forward);
|
|
11648
11963
|
forward.y = 0;
|
|
11649
11964
|
if (forward.lengthSq() < 1e-6) continue;
|
|
11650
11965
|
forward.normalize();
|
|
11651
|
-
const right = new
|
|
11966
|
+
const right = new THREE37__namespace.Vector3().crossVectors(forward, UP).normalize();
|
|
11652
11967
|
const step = rig.moveSpeed * Math.max(0, deltaTime);
|
|
11653
11968
|
transform.position.x += (forward.x * -y + right.x * x) * step;
|
|
11654
11969
|
transform.position.z += (forward.z * -y + right.z * x) * step;
|
|
@@ -11729,7 +12044,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
11729
12044
|
for (let i = 1; i < points.length; i += 1) {
|
|
11730
12045
|
const from = points[i - 1];
|
|
11731
12046
|
const to = points[i];
|
|
11732
|
-
const delta = new
|
|
12047
|
+
const delta = new THREE37__namespace.Vector3().subVectors(to, from);
|
|
11733
12048
|
const distance = delta.length();
|
|
11734
12049
|
if (distance < 1e-6) continue;
|
|
11735
12050
|
this.raycaster.set(from, delta.divideScalar(distance));
|
|
@@ -12002,12 +12317,12 @@ function planeColliderFromPolygon(polygon) {
|
|
|
12002
12317
|
}
|
|
12003
12318
|
__name(planeColliderFromPolygon, "planeColliderFromPolygon");
|
|
12004
12319
|
function writeXrMeshGeometry(vertices, indices, existing) {
|
|
12005
|
-
const geometry = existing ?? new
|
|
12320
|
+
const geometry = existing ?? new THREE37__namespace.BufferGeometry();
|
|
12006
12321
|
geometry.setAttribute(
|
|
12007
12322
|
"position",
|
|
12008
|
-
new
|
|
12323
|
+
new THREE37__namespace.BufferAttribute(vertices.slice(), 3)
|
|
12009
12324
|
);
|
|
12010
|
-
geometry.setIndex(new
|
|
12325
|
+
geometry.setIndex(new THREE37__namespace.BufferAttribute(indices.slice(), 1));
|
|
12011
12326
|
geometry.deleteAttribute("normal");
|
|
12012
12327
|
geometry.computeBoundingSphere();
|
|
12013
12328
|
geometry.computeVertexNormals();
|
|
@@ -12015,14 +12330,14 @@ function writeXrMeshGeometry(vertices, indices, existing) {
|
|
|
12015
12330
|
}
|
|
12016
12331
|
__name(writeXrMeshGeometry, "writeXrMeshGeometry");
|
|
12017
12332
|
function decomposeXrPose(matrixElements, target) {
|
|
12018
|
-
const matrix = new
|
|
12333
|
+
const matrix = new THREE37__namespace.Matrix4().fromArray(
|
|
12019
12334
|
matrixElements
|
|
12020
12335
|
);
|
|
12021
|
-
const position = new
|
|
12022
|
-
const quaternion = new
|
|
12023
|
-
const scale = new
|
|
12336
|
+
const position = new THREE37__namespace.Vector3();
|
|
12337
|
+
const quaternion = new THREE37__namespace.Quaternion();
|
|
12338
|
+
const scale = new THREE37__namespace.Vector3();
|
|
12024
12339
|
matrix.decompose(position, quaternion, scale);
|
|
12025
|
-
const euler = new
|
|
12340
|
+
const euler = new THREE37__namespace.Euler().setFromQuaternion(quaternion, "XYZ");
|
|
12026
12341
|
target.position.x = position.x;
|
|
12027
12342
|
target.position.y = position.y;
|
|
12028
12343
|
target.position.z = position.z;
|
|
@@ -12184,8 +12499,8 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12184
12499
|
this.viewerPos = null;
|
|
12185
12500
|
/** The ONE global room mesh currently allowed to spawn. */
|
|
12186
12501
|
this.electedGlobalMesh = null;
|
|
12187
|
-
this.tmpViewerMatrix = new
|
|
12188
|
-
this.tmpViewPos = new
|
|
12502
|
+
this.tmpViewerMatrix = new THREE37__namespace.Matrix4();
|
|
12503
|
+
this.tmpViewPos = new THREE37__namespace.Vector3();
|
|
12189
12504
|
}
|
|
12190
12505
|
update(world, deltaTime = 0) {
|
|
12191
12506
|
const presenting = world.isXrPresenting();
|
|
@@ -12544,7 +12859,7 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12544
12859
|
const geometry = writeXrMeshGeometry(mesh.vertices, mesh.indices);
|
|
12545
12860
|
const label = mesh.semanticLabel ?? null;
|
|
12546
12861
|
const isGlobalMesh = label === "global mesh";
|
|
12547
|
-
const material = new
|
|
12862
|
+
const material = new THREE37__namespace.MeshBasicMaterial({
|
|
12548
12863
|
color: debugColorFor("mesh", label),
|
|
12549
12864
|
wireframe: true,
|
|
12550
12865
|
// The global scan is a coarse triangle soup of the whole room; at full
|
|
@@ -12565,8 +12880,8 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12565
12880
|
depthTest: true,
|
|
12566
12881
|
depthWrite: false
|
|
12567
12882
|
});
|
|
12568
|
-
const root = new
|
|
12569
|
-
const child = new
|
|
12883
|
+
const root = new THREE37__namespace.Group();
|
|
12884
|
+
const child = new THREE37__namespace.Mesh(geometry, material);
|
|
12570
12885
|
child.visible = this.debugVisible;
|
|
12571
12886
|
child.renderOrder = DEBUG_RENDER_ORDER;
|
|
12572
12887
|
root.add(child);
|
|
@@ -12592,21 +12907,21 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
|
|
|
12592
12907
|
}
|
|
12593
12908
|
/** A thin box so a detected plane can be SEEN, not just collided with. */
|
|
12594
12909
|
attachPlaneDebug(world, entry, collider, semanticLabel) {
|
|
12595
|
-
const box = new
|
|
12910
|
+
const box = new THREE37__namespace.BoxGeometry(
|
|
12596
12911
|
collider.size.x,
|
|
12597
12912
|
collider.size.y,
|
|
12598
12913
|
collider.size.z
|
|
12599
12914
|
);
|
|
12600
|
-
const geometry = new
|
|
12915
|
+
const geometry = new THREE37__namespace.EdgesGeometry(box);
|
|
12601
12916
|
box.dispose();
|
|
12602
|
-
const material = new
|
|
12917
|
+
const material = new THREE37__namespace.LineBasicMaterial({
|
|
12603
12918
|
color: debugColorFor("plane", semanticLabel),
|
|
12604
12919
|
// Same depth policy as the mesh overlay — see createMeshEntity.
|
|
12605
12920
|
depthTest: true,
|
|
12606
12921
|
depthWrite: false
|
|
12607
12922
|
});
|
|
12608
|
-
const root = new
|
|
12609
|
-
const child = new
|
|
12923
|
+
const root = new THREE37__namespace.Group();
|
|
12924
|
+
const child = new THREE37__namespace.LineSegments(geometry, material);
|
|
12610
12925
|
child.renderOrder = DEBUG_RENDER_ORDER;
|
|
12611
12926
|
child.position.set(collider.offset.x, collider.offset.y, collider.offset.z);
|
|
12612
12927
|
child.visible = this.debugVisible;
|
|
@@ -12682,6 +12997,14 @@ function normalizeOrientation(value) {
|
|
|
12682
12997
|
return value === "horizontal" || value === "vertical" ? value : null;
|
|
12683
12998
|
}
|
|
12684
12999
|
__name(normalizeOrientation, "normalizeOrientation");
|
|
13000
|
+
var isDisplayOnlySlider = /* @__PURE__ */ __name((slider) => slider.readOnly === true || slider.variant !== void 0 && slider.variant !== "slider", "isDisplayOnlySlider");
|
|
13001
|
+
function snapToStep(value, slider) {
|
|
13002
|
+
const { step, min, max } = slider;
|
|
13003
|
+
if (!step || step <= 0) return value;
|
|
13004
|
+
const snapped = min + Math.round((value - min) / step) * step;
|
|
13005
|
+
return Math.min(max, Math.max(min, snapped));
|
|
13006
|
+
}
|
|
13007
|
+
__name(snapToStep, "snapToStep");
|
|
12685
13008
|
var MOUSE_CLICK_TRAVEL_PX = 6;
|
|
12686
13009
|
var PRESS_TINT_MIN_SECONDS = 0.1;
|
|
12687
13010
|
var PRESS_TINT = 0.72;
|
|
@@ -12695,11 +13018,12 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12695
13018
|
constructor(interaction, options) {
|
|
12696
13019
|
this.xrPresses = /* @__PURE__ */ new Map();
|
|
12697
13020
|
this.mousePress = null;
|
|
12698
|
-
|
|
13021
|
+
/** What each pointer is on. Two hands can rest on one widget. */
|
|
13022
|
+
this.hovers = /* @__PURE__ */ new Map();
|
|
12699
13023
|
/** entityId → seconds of pressed-tint left to display. */
|
|
12700
13024
|
this.tintFloors = /* @__PURE__ */ new Map();
|
|
12701
13025
|
this.tinted = /* @__PURE__ */ new Set();
|
|
12702
|
-
this.raycaster = new
|
|
13026
|
+
this.raycaster = new THREE37__namespace.Raycaster();
|
|
12703
13027
|
this.interaction = interaction;
|
|
12704
13028
|
this.inputSystem = options?.inputSystem ?? null;
|
|
12705
13029
|
interaction?.registerBusyContributor(
|
|
@@ -12709,8 +13033,10 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12709
13033
|
update(world, deltaTime = 0) {
|
|
12710
13034
|
if (world.isEditorMode()) return;
|
|
12711
13035
|
if (world.isXrPresenting()) {
|
|
13036
|
+
this.setHover(world, "mouse", null, null);
|
|
12712
13037
|
this.updateXr(world);
|
|
12713
13038
|
} else {
|
|
13039
|
+
this.dropGoneXrHovers(world, []);
|
|
12714
13040
|
this.updateMouse(world);
|
|
12715
13041
|
}
|
|
12716
13042
|
this.updateTints(world, deltaTime);
|
|
@@ -12724,6 +13050,7 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12724
13050
|
for (const input of inputs) {
|
|
12725
13051
|
const hover = interaction.getHoverForInput(input);
|
|
12726
13052
|
const hovered = hover ? this.widgetKind(world, hover.entityId) : null;
|
|
13053
|
+
this.setHover(world, input, hover && hovered ? hover.entityId : null, input);
|
|
12727
13054
|
if (input.selectStart && hover && hovered) {
|
|
12728
13055
|
this.xrPresses.set(input, {
|
|
12729
13056
|
entityId: hover.entityId,
|
|
@@ -12752,6 +13079,15 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12752
13079
|
for (const [input] of this.xrPresses) {
|
|
12753
13080
|
if (!inputs.includes(input)) this.xrPresses.delete(input);
|
|
12754
13081
|
}
|
|
13082
|
+
this.dropGoneXrHovers(world, inputs);
|
|
13083
|
+
}
|
|
13084
|
+
/** A transient source leaves with no select edge to clear its hover. */
|
|
13085
|
+
dropGoneXrHovers(world, inputs) {
|
|
13086
|
+
for (const source of [...this.hovers.keys()]) {
|
|
13087
|
+
if (source !== "mouse" && !inputs.includes(source)) {
|
|
13088
|
+
this.setHover(world, source, null, source);
|
|
13089
|
+
}
|
|
13090
|
+
}
|
|
12755
13091
|
}
|
|
12756
13092
|
// ── Mouse path (flat preview) ──────────────────────────────────────────────
|
|
12757
13093
|
updateMouse(world) {
|
|
@@ -12759,22 +13095,7 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12759
13095
|
if (!input) return;
|
|
12760
13096
|
const hit = this.raycastMouse(world);
|
|
12761
13097
|
const hovered = hit && this.widgetKind(world, hit) ? hit : null;
|
|
12762
|
-
|
|
12763
|
-
if (this.mouseHover !== null) {
|
|
12764
|
-
this.setTint(world, this.mouseHover, 1);
|
|
12765
|
-
this.dispatchBubbling(
|
|
12766
|
-
world,
|
|
12767
|
-
this.mouseHover,
|
|
12768
|
-
"onUiHoverEnd",
|
|
12769
|
-
(b, e) => b.onUiHoverEnd(e)
|
|
12770
|
-
);
|
|
12771
|
-
}
|
|
12772
|
-
if (hovered !== null) {
|
|
12773
|
-
this.setTint(world, hovered, HOVER_TINT);
|
|
12774
|
-
this.dispatchBubbling(world, hovered, "onUiHoverStart", (b, e) => b.onUiHoverStart(e));
|
|
12775
|
-
}
|
|
12776
|
-
this.mouseHover = hovered;
|
|
12777
|
-
}
|
|
13098
|
+
this.setHover(world, "mouse", hovered, null);
|
|
12778
13099
|
if (input.getMouseDown("left") && hovered) {
|
|
12779
13100
|
const kind = this.widgetKind(world, hovered);
|
|
12780
13101
|
if (kind) {
|
|
@@ -12782,12 +13103,12 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12782
13103
|
this.beginPressTint(world, hovered);
|
|
12783
13104
|
}
|
|
12784
13105
|
}
|
|
12785
|
-
if (this.mousePress) {
|
|
13106
|
+
if (this.mousePress && !input.getMouseDown("left")) {
|
|
12786
13107
|
const delta = input.getMouseDelta();
|
|
12787
13108
|
this.mousePress.travelPx += Math.hypot(delta.x, delta.y);
|
|
12788
|
-
|
|
12789
|
-
|
|
12790
|
-
|
|
13109
|
+
}
|
|
13110
|
+
if (this.mousePress?.kind === "slider") {
|
|
13111
|
+
this.dragSliderMouse(world, this.mousePress.entityId);
|
|
12791
13112
|
}
|
|
12792
13113
|
if (input.getMouseUp("left") && this.mousePress) {
|
|
12793
13114
|
const press = this.mousePress;
|
|
@@ -12816,15 +13137,24 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12816
13137
|
ndcY = -((pos.y - rect.top) / Math.max(1, rect.height) * 2 - 1);
|
|
12817
13138
|
if (ndcX < -1 || ndcX > 1 || ndcY < -1 || ndcY > 1) return null;
|
|
12818
13139
|
}
|
|
12819
|
-
this.raycaster.setFromCamera(new
|
|
13140
|
+
this.raycaster.setFromCamera(new THREE37__namespace.Vector2(ndcX, ndcY), world.getCamera());
|
|
12820
13141
|
const hits = world.raycast(
|
|
12821
13142
|
this.raycaster.ray.origin,
|
|
12822
13143
|
this.raycaster.ray.direction
|
|
12823
13144
|
);
|
|
13145
|
+
let surfaceTree = null;
|
|
12824
13146
|
for (const hit of hits) {
|
|
12825
|
-
|
|
12826
|
-
if (
|
|
12827
|
-
|
|
13147
|
+
const entityId = hit.entityId;
|
|
13148
|
+
if (typeof entityId !== "number") continue;
|
|
13149
|
+
if (!isShownInScene(world, entityId)) continue;
|
|
13150
|
+
if (this.widgetKind(world, entityId)) {
|
|
13151
|
+
const sameSurface = surfaceTree === null || widgetTreeRoot(world, entityId) === surfaceTree;
|
|
13152
|
+
return sameSurface ? entityId : null;
|
|
13153
|
+
}
|
|
13154
|
+
if (!isUiWidget(world, entityId)) return null;
|
|
13155
|
+
const tree = widgetTreeRoot(world, entityId);
|
|
13156
|
+
if (surfaceTree !== null && tree !== surfaceTree) return null;
|
|
13157
|
+
surfaceTree = tree;
|
|
12828
13158
|
}
|
|
12829
13159
|
return null;
|
|
12830
13160
|
}
|
|
@@ -12832,7 +13162,8 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12832
13162
|
widgetKind(world, entityId) {
|
|
12833
13163
|
if (world.getComponent(entityId, UIButtonComponent)) return "button";
|
|
12834
13164
|
if (world.getComponent(entityId, UIToggleComponent)) return "toggle";
|
|
12835
|
-
|
|
13165
|
+
const slider = world.getComponent(entityId, UISliderComponent);
|
|
13166
|
+
if (slider && !isDisplayOnlySlider(slider)) return "slider";
|
|
12836
13167
|
return null;
|
|
12837
13168
|
}
|
|
12838
13169
|
fire(world, press, input) {
|
|
@@ -12883,7 +13214,10 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12883
13214
|
const inset = slider.height / 2;
|
|
12884
13215
|
const usable = Math.max(1e-3, slider.width - inset * 2);
|
|
12885
13216
|
const t = Math.min(1, Math.max(0, local.x / usable + 0.5));
|
|
12886
|
-
const next =
|
|
13217
|
+
const next = snapToStep(
|
|
13218
|
+
slider.min + t * (slider.max - slider.min),
|
|
13219
|
+
slider
|
|
13220
|
+
);
|
|
12887
13221
|
if (Math.abs(next - slider.value) < 1e-4) return;
|
|
12888
13222
|
slider.value = next;
|
|
12889
13223
|
this.dispatchBubbling(
|
|
@@ -12961,6 +13295,43 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12961
13295
|
const name = world.getComponent(entityId, Name)?.value;
|
|
12962
13296
|
return typeof name === "string" ? name : String(entityId);
|
|
12963
13297
|
}
|
|
13298
|
+
// ── Hover ──────────────────────────────────────────────────────────────────
|
|
13299
|
+
setHover(world, source, next, input) {
|
|
13300
|
+
const previous = this.hovers.get(source) ?? null;
|
|
13301
|
+
if (previous === next) return;
|
|
13302
|
+
if (next === null) this.hovers.delete(source);
|
|
13303
|
+
else this.hovers.set(source, next);
|
|
13304
|
+
if (previous !== null && !this.isHovered(previous)) {
|
|
13305
|
+
if (!this.tintFloors.has(previous)) this.setTint(world, previous, 1);
|
|
13306
|
+
this.dispatchBubbling(
|
|
13307
|
+
world,
|
|
13308
|
+
previous,
|
|
13309
|
+
"onUiHoverEnd",
|
|
13310
|
+
(b, e) => b.onUiHoverEnd(e),
|
|
13311
|
+
input
|
|
13312
|
+
);
|
|
13313
|
+
}
|
|
13314
|
+
if (next !== null && this.hoverCount(next) === 1) {
|
|
13315
|
+
if (!this.tintFloors.has(next)) this.setTint(world, next, HOVER_TINT);
|
|
13316
|
+
this.dispatchBubbling(
|
|
13317
|
+
world,
|
|
13318
|
+
next,
|
|
13319
|
+
"onUiHoverStart",
|
|
13320
|
+
(b, e) => b.onUiHoverStart(e),
|
|
13321
|
+
input
|
|
13322
|
+
);
|
|
13323
|
+
}
|
|
13324
|
+
}
|
|
13325
|
+
hoverCount(entityId) {
|
|
13326
|
+
let count = 0;
|
|
13327
|
+
for (const hovered of this.hovers.values()) {
|
|
13328
|
+
if (hovered === entityId) count += 1;
|
|
13329
|
+
}
|
|
13330
|
+
return count;
|
|
13331
|
+
}
|
|
13332
|
+
isHovered(entityId) {
|
|
13333
|
+
return this.hoverCount(entityId) > 0;
|
|
13334
|
+
}
|
|
12964
13335
|
// ── Pressed/hover tint ─────────────────────────────────────────────────────
|
|
12965
13336
|
beginPressTint(world, entityId) {
|
|
12966
13337
|
this.setTint(world, entityId, PRESS_TINT);
|
|
@@ -12978,11 +13349,7 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12978
13349
|
if (stillHeld) continue;
|
|
12979
13350
|
if (next <= 0) {
|
|
12980
13351
|
this.tintFloors.delete(entityId);
|
|
12981
|
-
this.setTint(
|
|
12982
|
-
world,
|
|
12983
|
-
entityId,
|
|
12984
|
-
this.mouseHover === entityId ? HOVER_TINT : 1
|
|
12985
|
-
);
|
|
13352
|
+
this.setTint(world, entityId, this.isHovered(entityId) ? HOVER_TINT : 1);
|
|
12986
13353
|
} else {
|
|
12987
13354
|
this.tintFloors.set(entityId, next);
|
|
12988
13355
|
}
|
|
@@ -12993,14 +13360,101 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
12993
13360
|
if (!object) return;
|
|
12994
13361
|
if (scalar === 1) this.tinted.delete(entityId);
|
|
12995
13362
|
else this.tinted.add(entityId);
|
|
12996
|
-
object.
|
|
12997
|
-
const
|
|
12998
|
-
if (
|
|
12999
|
-
|
|
13363
|
+
for (const child of object.children) {
|
|
13364
|
+
const tag = child.userData[UI_PART_KEY];
|
|
13365
|
+
if (!tag) continue;
|
|
13366
|
+
tag.tint = scalar;
|
|
13367
|
+
applyPartColor(child, tag);
|
|
13368
|
+
}
|
|
13000
13369
|
}
|
|
13001
13370
|
};
|
|
13002
13371
|
__name(_UIInteractionSystem, "UIInteractionSystem");
|
|
13003
13372
|
var UIInteractionSystem = _UIInteractionSystem;
|
|
13373
|
+
var fonts = /* @__PURE__ */ new Map();
|
|
13374
|
+
var images = /* @__PURE__ */ new Map();
|
|
13375
|
+
function hash(text) {
|
|
13376
|
+
let value = 5381;
|
|
13377
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
13378
|
+
value = (value * 33 ^ text.charCodeAt(i)) >>> 0;
|
|
13379
|
+
}
|
|
13380
|
+
return value.toString(36);
|
|
13381
|
+
}
|
|
13382
|
+
__name(hash, "hash");
|
|
13383
|
+
function tracked(url, work) {
|
|
13384
|
+
const manager = THREE37__namespace.DefaultLoadingManager;
|
|
13385
|
+
manager.itemStart(url);
|
|
13386
|
+
return work.catch((error) => {
|
|
13387
|
+
manager.itemError(url);
|
|
13388
|
+
throw error;
|
|
13389
|
+
}).finally(() => manager.itemEnd(url));
|
|
13390
|
+
}
|
|
13391
|
+
__name(tracked, "tracked");
|
|
13392
|
+
function uiFontFamily(src) {
|
|
13393
|
+
if (typeof FontFace === "undefined" || typeof document === "undefined") {
|
|
13394
|
+
return null;
|
|
13395
|
+
}
|
|
13396
|
+
const known = fonts.get(src);
|
|
13397
|
+
if (known) return known.value;
|
|
13398
|
+
const entry = { value: null, settled: false };
|
|
13399
|
+
fonts.set(src, entry);
|
|
13400
|
+
const url = resolvePrefabAssetUrl(src);
|
|
13401
|
+
const family = `relu-ui-${hash(url)}`;
|
|
13402
|
+
tracked(
|
|
13403
|
+
url,
|
|
13404
|
+
(async () => {
|
|
13405
|
+
const response = await fetch(url);
|
|
13406
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
13407
|
+
const buffer = await response.arrayBuffer();
|
|
13408
|
+
const face = new FontFace(family, buffer, { weight: "100 900" });
|
|
13409
|
+
await face.load();
|
|
13410
|
+
document.fonts.add(face);
|
|
13411
|
+
})()
|
|
13412
|
+
).then(() => {
|
|
13413
|
+
entry.value = family;
|
|
13414
|
+
}).catch((error) => {
|
|
13415
|
+
console.warn(`[spatial-ecs] Couldn't load UI font ${src}.`, error);
|
|
13416
|
+
}).finally(() => {
|
|
13417
|
+
entry.settled = true;
|
|
13418
|
+
});
|
|
13419
|
+
return null;
|
|
13420
|
+
}
|
|
13421
|
+
__name(uiFontFamily, "uiFontFamily");
|
|
13422
|
+
function uiImage(src) {
|
|
13423
|
+
if (typeof Image === "undefined" || typeof fetch === "undefined") {
|
|
13424
|
+
return null;
|
|
13425
|
+
}
|
|
13426
|
+
const known = images.get(src);
|
|
13427
|
+
if (known) return known.value;
|
|
13428
|
+
const entry = { value: null, settled: false };
|
|
13429
|
+
images.set(src, entry);
|
|
13430
|
+
const url = resolvePrefabAssetUrl(src);
|
|
13431
|
+
tracked(
|
|
13432
|
+
url,
|
|
13433
|
+
(async () => {
|
|
13434
|
+
const response = await fetch(url);
|
|
13435
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
13436
|
+
const blob = await response.blob();
|
|
13437
|
+
const typed = /\.svg(\?|#|$)/i.test(url) ? new Blob([blob], { type: "image/svg+xml" }) : blob;
|
|
13438
|
+
const image = new Image();
|
|
13439
|
+
const objectUrl = URL.createObjectURL(typed);
|
|
13440
|
+
try {
|
|
13441
|
+
image.src = objectUrl;
|
|
13442
|
+
await image.decode();
|
|
13443
|
+
return image;
|
|
13444
|
+
} finally {
|
|
13445
|
+
URL.revokeObjectURL(objectUrl);
|
|
13446
|
+
}
|
|
13447
|
+
})()
|
|
13448
|
+
).then((image) => {
|
|
13449
|
+
entry.value = image;
|
|
13450
|
+
}).catch((error) => {
|
|
13451
|
+
console.warn(`[spatial-ecs] Couldn't load UI image ${src}.`, error);
|
|
13452
|
+
}).finally(() => {
|
|
13453
|
+
entry.settled = true;
|
|
13454
|
+
});
|
|
13455
|
+
return null;
|
|
13456
|
+
}
|
|
13457
|
+
__name(uiImage, "uiImage");
|
|
13004
13458
|
|
|
13005
13459
|
// core/ui/uiCanvas.ts
|
|
13006
13460
|
var DEFAULT_PIXELS_PER_METER = 1024;
|
|
@@ -13073,18 +13527,21 @@ function clampLines(measure, lines, maxLines, maxWidthPx) {
|
|
|
13073
13527
|
}
|
|
13074
13528
|
__name(clampLines, "clampLines");
|
|
13075
13529
|
var UI_FONT_STACK = '-apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
|
|
13076
|
-
|
|
13077
|
-
|
|
13530
|
+
var NO_ASSETS = { image: /* @__PURE__ */ __name(() => null, "image") };
|
|
13531
|
+
function tracePath(ctx, x, y, w, h, radii) {
|
|
13532
|
+
const limit = Math.min(w / 2, h / 2);
|
|
13533
|
+
const fit = /* @__PURE__ */ __name((r) => Math.max(0, Math.min(r, limit)), "fit");
|
|
13534
|
+
const [tl, tr, br, bl] = (Array.isArray(radii) ? radii : [radii, radii, radii, radii]).map(fit);
|
|
13078
13535
|
ctx.beginPath();
|
|
13079
13536
|
if (typeof ctx.roundRect === "function") {
|
|
13080
|
-
ctx.roundRect(x, y, w, h,
|
|
13537
|
+
ctx.roundRect(x, y, w, h, [tl, tr, br, bl]);
|
|
13081
13538
|
return;
|
|
13082
13539
|
}
|
|
13083
|
-
ctx.moveTo(x +
|
|
13084
|
-
ctx.arcTo(x + w, y, x + w, y + h,
|
|
13085
|
-
ctx.arcTo(x + w, y + h, x, y + h,
|
|
13086
|
-
ctx.arcTo(x, y + h, x, y,
|
|
13087
|
-
ctx.arcTo(x, y, x + w, y,
|
|
13540
|
+
ctx.moveTo(x + tl, y);
|
|
13541
|
+
ctx.arcTo(x + w, y, x + w, y + h, tr);
|
|
13542
|
+
ctx.arcTo(x + w, y + h, x, y + h, br);
|
|
13543
|
+
ctx.arcTo(x, y + h, x, y, bl);
|
|
13544
|
+
ctx.arcTo(x, y, x + w, y, tl);
|
|
13088
13545
|
ctx.closePath();
|
|
13089
13546
|
}
|
|
13090
13547
|
__name(tracePath, "tracePath");
|
|
@@ -13104,108 +13561,244 @@ function withOpacity(ctx, color, opacity) {
|
|
|
13104
13561
|
return parsed;
|
|
13105
13562
|
}
|
|
13106
13563
|
__name(withOpacity, "withOpacity");
|
|
13107
|
-
function
|
|
13108
|
-
|
|
13109
|
-
const
|
|
13110
|
-
const
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
|
|
13116
|
-
|
|
13564
|
+
function fillStyleFor(ctx, paint, box, opacity) {
|
|
13565
|
+
if (paint.kind === "solid") return withOpacity(ctx, paint.color, opacity);
|
|
13566
|
+
const cx = box.x + box.w / 2;
|
|
13567
|
+
const cy = box.y + box.h / 2;
|
|
13568
|
+
let gradient;
|
|
13569
|
+
if (paint.kind === "linear") {
|
|
13570
|
+
const radians = paint.angle * Math.PI / 180;
|
|
13571
|
+
const dx = Math.sin(radians);
|
|
13572
|
+
const dy = -Math.cos(radians);
|
|
13573
|
+
const half = (Math.abs(box.w * dx) + Math.abs(box.h * dy)) / 2;
|
|
13574
|
+
gradient = ctx.createLinearGradient(
|
|
13575
|
+
cx - dx * half,
|
|
13576
|
+
cy - dy * half,
|
|
13577
|
+
cx + dx * half,
|
|
13578
|
+
cy + dy * half
|
|
13579
|
+
);
|
|
13580
|
+
} else {
|
|
13581
|
+
gradient = ctx.createRadialGradient(
|
|
13582
|
+
cx,
|
|
13583
|
+
cy,
|
|
13584
|
+
0,
|
|
13585
|
+
cx,
|
|
13586
|
+
cy,
|
|
13587
|
+
Math.max(box.w, box.h) / 2
|
|
13588
|
+
);
|
|
13589
|
+
}
|
|
13590
|
+
for (const stop of paint.stops) {
|
|
13591
|
+
gradient.addColorStop(stop.at, withOpacity(ctx, stop.color, opacity));
|
|
13592
|
+
}
|
|
13593
|
+
return gradient;
|
|
13594
|
+
}
|
|
13595
|
+
__name(fillStyleFor, "fillStyleFor");
|
|
13596
|
+
function drawImagePaint(ctx, paint, box, assets) {
|
|
13597
|
+
const image = assets.image(paint.src);
|
|
13598
|
+
if (!image) return;
|
|
13599
|
+
const sourceW = image.naturalWidth || box.w;
|
|
13600
|
+
const sourceH = image.naturalHeight || box.h;
|
|
13601
|
+
const scale = paint.fit === "fill" ? 1 : paint.fit === "cover" ? Math.max(box.w / sourceW, box.h / sourceH) : Math.min(box.w / sourceW, box.h / sourceH);
|
|
13602
|
+
const w = paint.fit === "fill" ? box.w : sourceW * scale;
|
|
13603
|
+
const h = paint.fit === "fill" ? box.h : sourceH * scale;
|
|
13604
|
+
const x = box.x + (box.w - w) / 2;
|
|
13605
|
+
const y = box.y + (box.h - h) / 2;
|
|
13606
|
+
if (!paint.tint) {
|
|
13607
|
+
ctx.drawImage(image, x, y, w, h);
|
|
13608
|
+
return;
|
|
13609
|
+
}
|
|
13610
|
+
const scratch = assets.scratch?.(Math.ceil(w), Math.ceil(h));
|
|
13611
|
+
if (!scratch) {
|
|
13612
|
+
ctx.drawImage(image, x, y, w, h);
|
|
13613
|
+
return;
|
|
13614
|
+
}
|
|
13615
|
+
scratch.drawImage(image, 0, 0, w, h);
|
|
13616
|
+
scratch.globalCompositeOperation = "source-in";
|
|
13617
|
+
scratch.fillStyle = paint.tint;
|
|
13618
|
+
scratch.fillRect(0, 0, w, h);
|
|
13619
|
+
ctx.drawImage(scratch.canvas, x, y, w, h);
|
|
13620
|
+
}
|
|
13621
|
+
__name(drawImagePaint, "drawImagePaint");
|
|
13622
|
+
function pxRadii(radius, density) {
|
|
13623
|
+
return radius.map((r) => r * density);
|
|
13624
|
+
}
|
|
13625
|
+
__name(pxRadii, "pxRadii");
|
|
13626
|
+
function drawBoxShadow(ctx, box, radii, shadow, density) {
|
|
13627
|
+
ctx.save();
|
|
13628
|
+
ctx.shadowColor = shadow.color;
|
|
13629
|
+
ctx.shadowBlur = shadow.blur * density;
|
|
13630
|
+
ctx.shadowOffsetX = shadow.x * density;
|
|
13631
|
+
ctx.shadowOffsetY = -shadow.y * density;
|
|
13632
|
+
ctx.fillStyle = "#000000";
|
|
13633
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13117
13634
|
ctx.fill();
|
|
13118
|
-
|
|
13635
|
+
ctx.restore();
|
|
13636
|
+
ctx.save();
|
|
13637
|
+
ctx.globalCompositeOperation = "destination-out";
|
|
13638
|
+
ctx.fillStyle = "#000000";
|
|
13639
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13640
|
+
ctx.fill();
|
|
13641
|
+
ctx.restore();
|
|
13642
|
+
}
|
|
13643
|
+
__name(drawBoxShadow, "drawBoxShadow");
|
|
13644
|
+
function drawChrome(ctx, box, density, chrome, assets = NO_ASSETS) {
|
|
13645
|
+
const radii = pxRadii(chrome.radius, density);
|
|
13646
|
+
for (const shadow of chrome.shadows) {
|
|
13647
|
+
drawBoxShadow(ctx, box, radii, shadow, density);
|
|
13648
|
+
}
|
|
13649
|
+
const opacity = Math.max(0, Math.min(1, chrome.fillOpacity));
|
|
13650
|
+
if (chrome.fill?.kind === "image") {
|
|
13651
|
+
ctx.save();
|
|
13652
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13653
|
+
ctx.clip();
|
|
13654
|
+
ctx.globalAlpha = opacity;
|
|
13655
|
+
drawImagePaint(ctx, chrome.fill, box, assets);
|
|
13656
|
+
ctx.restore();
|
|
13657
|
+
} else if (chrome.fill) {
|
|
13658
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13659
|
+
ctx.fillStyle = fillStyleFor(ctx, chrome.fill, box, opacity);
|
|
13660
|
+
ctx.fill();
|
|
13661
|
+
}
|
|
13662
|
+
if (chrome.edge) {
|
|
13663
|
+
const width = chrome.edge.width * density;
|
|
13664
|
+
ctx.save();
|
|
13665
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13666
|
+
ctx.clip();
|
|
13667
|
+
const fade = ctx.createLinearGradient(0, box.y, 0, box.y + box.h / 2);
|
|
13668
|
+
fade.addColorStop(0, chrome.edge.color);
|
|
13669
|
+
fade.addColorStop(1, withOpacity(ctx, chrome.edge.color, 0));
|
|
13670
|
+
ctx.strokeStyle = fade;
|
|
13671
|
+
ctx.lineWidth = width * 2;
|
|
13672
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13673
|
+
ctx.stroke();
|
|
13674
|
+
ctx.restore();
|
|
13675
|
+
}
|
|
13676
|
+
if (chrome.border) {
|
|
13677
|
+
const border = chrome.border.width * density;
|
|
13119
13678
|
tracePath(
|
|
13120
13679
|
ctx,
|
|
13121
|
-
border / 2,
|
|
13122
|
-
border / 2,
|
|
13123
|
-
|
|
13124
|
-
|
|
13125
|
-
Math.max(0,
|
|
13680
|
+
box.x + border / 2,
|
|
13681
|
+
box.y + border / 2,
|
|
13682
|
+
box.w - border,
|
|
13683
|
+
box.h - border,
|
|
13684
|
+
radii.map((r) => Math.max(0, r - border / 2))
|
|
13126
13685
|
);
|
|
13127
|
-
ctx.strokeStyle =
|
|
13686
|
+
ctx.strokeStyle = chrome.border.color;
|
|
13128
13687
|
ctx.lineWidth = border;
|
|
13129
13688
|
ctx.stroke();
|
|
13130
13689
|
}
|
|
13131
13690
|
}
|
|
13132
13691
|
__name(drawChrome, "drawChrome");
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
const
|
|
13137
|
-
|
|
13692
|
+
var applyTransform2 = /* @__PURE__ */ __name((text, transform) => transform === "upper" ? text.toUpperCase() : transform === "lower" ? text.toLowerCase() : text, "applyTransform");
|
|
13693
|
+
function fillTracked(ctx, line, x, y, trackingPx, width) {
|
|
13694
|
+
let cursor = ctx.textAlign === "center" ? x - width / 2 : ctx.textAlign === "right" ? x - width : x;
|
|
13695
|
+
const align = ctx.textAlign;
|
|
13696
|
+
ctx.textAlign = "left";
|
|
13697
|
+
for (const glyph of line) {
|
|
13698
|
+
ctx.fillText(glyph, cursor, y);
|
|
13699
|
+
cursor += ctx.measureText(glyph).width + trackingPx;
|
|
13700
|
+
}
|
|
13701
|
+
ctx.textAlign = align;
|
|
13702
|
+
}
|
|
13703
|
+
__name(fillTracked, "fillTracked");
|
|
13704
|
+
function drawTextBlock(ctx, box, density, text, style, family = null, assets = NO_ASSETS) {
|
|
13705
|
+
const fontPx = Math.max(4, style.fontSize * density);
|
|
13706
|
+
const paddingPx = style.padding * density;
|
|
13707
|
+
const contentW = Math.max(1, box.w - paddingPx * 2);
|
|
13708
|
+
const contentH = Math.max(1, box.h - paddingPx * 2);
|
|
13138
13709
|
const lineHeightPx = fontPx * style.lineHeight;
|
|
13139
|
-
|
|
13140
|
-
const
|
|
13141
|
-
|
|
13710
|
+
const trackingPx = style.tracking * density;
|
|
13711
|
+
const stack = family ? `"${family}", ${UI_FONT_STACK}` : UI_FONT_STACK;
|
|
13712
|
+
ctx.font = `${style.fontWeight} ${fontPx}px ${stack}`;
|
|
13713
|
+
const nativeTracking = trackingPx !== 0 && "letterSpacing" in ctx;
|
|
13714
|
+
if (nativeTracking) {
|
|
13715
|
+
ctx.letterSpacing = `${trackingPx}px`;
|
|
13716
|
+
}
|
|
13717
|
+
const manualTracking = trackingPx !== 0 && !nativeTracking;
|
|
13718
|
+
const measure = /* @__PURE__ */ __name((s) => ctx.measureText(s).width + (manualTracking ? trackingPx * s.length : 0), "measure");
|
|
13719
|
+
const fits = Math.max(1, Math.floor(contentH / lineHeightPx));
|
|
13720
|
+
const maxLines = style.maxLines ? Math.min(fits, style.maxLines) : fits;
|
|
13142
13721
|
const lines = clampLines(
|
|
13143
13722
|
measure,
|
|
13144
|
-
wrapText(measure, text, contentW),
|
|
13723
|
+
wrapText(measure, applyTransform2(text, style.transform), contentW),
|
|
13145
13724
|
maxLines,
|
|
13146
13725
|
contentW
|
|
13147
13726
|
);
|
|
13148
13727
|
const blockH = lines.length * lineHeightPx;
|
|
13149
|
-
const top = style.valign === "top" ? paddingPx : style.valign === "bottom" ?
|
|
13150
|
-
const anchorX = style.align === "left" ? paddingPx : style.align === "right" ?
|
|
13728
|
+
const top = style.valign === "top" ? box.y + paddingPx : style.valign === "bottom" ? box.y + box.h - paddingPx - blockH : box.y + (box.h - blockH) / 2;
|
|
13729
|
+
const anchorX = style.align === "left" ? box.x + paddingPx : style.align === "right" ? box.x + box.w - paddingPx : box.x + box.w / 2;
|
|
13151
13730
|
ctx.save();
|
|
13152
|
-
|
|
13153
|
-
|
|
13154
|
-
|
|
13731
|
+
if (style.paint.kind === "image") {
|
|
13732
|
+
ctx.fillStyle = "#ffffff";
|
|
13733
|
+
} else {
|
|
13734
|
+
ctx.fillStyle = fillStyleFor(ctx, style.paint, box, 1);
|
|
13735
|
+
}
|
|
13736
|
+
if (style.shadow) {
|
|
13737
|
+
ctx.shadowColor = style.shadow.color;
|
|
13738
|
+
ctx.shadowBlur = style.shadow.blur * density;
|
|
13739
|
+
ctx.shadowOffsetX = style.shadow.x * density;
|
|
13740
|
+
ctx.shadowOffsetY = -style.shadow.y * density;
|
|
13741
|
+
}
|
|
13155
13742
|
ctx.textAlign = style.align;
|
|
13156
13743
|
ctx.textBaseline = "middle";
|
|
13157
13744
|
for (let i = 0; i < lines.length; i += 1) {
|
|
13158
|
-
|
|
13745
|
+
const y = top + (i + 0.5) * lineHeightPx;
|
|
13746
|
+
if (manualTracking) {
|
|
13747
|
+
fillTracked(ctx, lines[i], anchorX, y, trackingPx, measure(lines[i]));
|
|
13748
|
+
} else {
|
|
13749
|
+
ctx.fillText(lines[i], anchorX, y);
|
|
13750
|
+
}
|
|
13159
13751
|
}
|
|
13160
13752
|
ctx.restore();
|
|
13753
|
+
if (style.paint.kind === "image") {
|
|
13754
|
+
ctx.save();
|
|
13755
|
+
ctx.globalCompositeOperation = "source-atop";
|
|
13756
|
+
drawImagePaint(ctx, style.paint, box, assets);
|
|
13757
|
+
ctx.restore();
|
|
13758
|
+
}
|
|
13759
|
+
if (nativeTracking) {
|
|
13760
|
+
ctx.letterSpacing = "0px";
|
|
13761
|
+
}
|
|
13161
13762
|
}
|
|
13162
13763
|
__name(drawTextBlock, "drawTextBlock");
|
|
13163
|
-
function panelSignature(widthM, heightM, size,
|
|
13764
|
+
function panelSignature(widthM, heightM, size, chrome, loaded = null) {
|
|
13164
13765
|
return JSON.stringify([
|
|
13165
13766
|
widthM,
|
|
13166
13767
|
heightM,
|
|
13167
13768
|
size.pxWidth,
|
|
13168
13769
|
size.pxHeight,
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
style.cornerRadiusMeters,
|
|
13172
|
-
style.borderWidthMeters,
|
|
13173
|
-
style.borderColor
|
|
13770
|
+
chrome,
|
|
13771
|
+
loaded
|
|
13174
13772
|
]);
|
|
13175
13773
|
}
|
|
13176
13774
|
__name(panelSignature, "panelSignature");
|
|
13177
|
-
function textSignature(widthM, heightM, size, text, style) {
|
|
13775
|
+
function textSignature(widthM, heightM, size, text, style, family = null) {
|
|
13178
13776
|
return JSON.stringify([
|
|
13179
13777
|
widthM,
|
|
13180
13778
|
heightM,
|
|
13181
13779
|
size.pxWidth,
|
|
13182
13780
|
size.pxHeight,
|
|
13183
13781
|
text,
|
|
13184
|
-
style
|
|
13185
|
-
|
|
13186
|
-
style.color,
|
|
13187
|
-
style.align,
|
|
13188
|
-
style.valign,
|
|
13189
|
-
style.lineHeight,
|
|
13190
|
-
style.paddingMeters
|
|
13782
|
+
style,
|
|
13783
|
+
family
|
|
13191
13784
|
]);
|
|
13192
13785
|
}
|
|
13193
13786
|
__name(textSignature, "textSignature");
|
|
13194
|
-
function buttonSignature(widthM, heightM, size,
|
|
13787
|
+
function buttonSignature(widthM, heightM, size, chrome, label, text, family = null, loaded = null) {
|
|
13195
13788
|
return JSON.stringify([
|
|
13196
|
-
panelSignature(widthM, heightM, size,
|
|
13789
|
+
panelSignature(widthM, heightM, size, chrome, loaded),
|
|
13197
13790
|
label,
|
|
13198
|
-
text
|
|
13199
|
-
|
|
13200
|
-
text.color
|
|
13791
|
+
text,
|
|
13792
|
+
family
|
|
13201
13793
|
]);
|
|
13202
13794
|
}
|
|
13203
13795
|
__name(buttonSignature, "buttonSignature");
|
|
13204
|
-
function trackSignature(widthM, heightM, size,
|
|
13796
|
+
function trackSignature(widthM, heightM, size, chrome, accentColor, knobColor, variant = null) {
|
|
13205
13797
|
return JSON.stringify([
|
|
13206
|
-
panelSignature(widthM, heightM, size,
|
|
13798
|
+
panelSignature(widthM, heightM, size, chrome),
|
|
13207
13799
|
accentColor,
|
|
13208
|
-
knobColor
|
|
13800
|
+
knobColor,
|
|
13801
|
+
variant
|
|
13209
13802
|
]);
|
|
13210
13803
|
}
|
|
13211
13804
|
__name(trackSignature, "trackSignature");
|
|
@@ -13215,17 +13808,226 @@ function drawRoundedBar(ctx, pxX, pxY, pxW, pxH, color) {
|
|
|
13215
13808
|
ctx.fill();
|
|
13216
13809
|
}
|
|
13217
13810
|
__name(drawRoundedBar, "drawRoundedBar");
|
|
13811
|
+
function drawCheckMark(ctx, box, color) {
|
|
13812
|
+
ctx.beginPath();
|
|
13813
|
+
ctx.moveTo(box.x + box.w * 0.24, box.y + box.h * 0.54);
|
|
13814
|
+
ctx.lineTo(box.x + box.w * 0.43, box.y + box.h * 0.72);
|
|
13815
|
+
ctx.lineTo(box.x + box.w * 0.77, box.y + box.h * 0.3);
|
|
13816
|
+
ctx.strokeStyle = color;
|
|
13817
|
+
ctx.lineWidth = box.h * 0.13;
|
|
13818
|
+
ctx.lineCap = "round";
|
|
13819
|
+
ctx.lineJoin = "round";
|
|
13820
|
+
ctx.stroke();
|
|
13821
|
+
}
|
|
13822
|
+
__name(drawCheckMark, "drawCheckMark");
|
|
13823
|
+
function drawDot(ctx, cx, cy, radius, color) {
|
|
13824
|
+
ctx.beginPath();
|
|
13825
|
+
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
|
|
13826
|
+
ctx.fillStyle = color;
|
|
13827
|
+
ctx.fill();
|
|
13828
|
+
}
|
|
13829
|
+
__name(drawDot, "drawDot");
|
|
13830
|
+
function drawRing(ctx, box, t, trackColor, accentColor) {
|
|
13831
|
+
const thickness = Math.min(box.w, box.h) * 0.14;
|
|
13832
|
+
const radius = Math.min(box.w, box.h) / 2 - thickness / 2;
|
|
13833
|
+
const cx = box.x + box.w / 2;
|
|
13834
|
+
const cy = box.y + box.h / 2;
|
|
13835
|
+
ctx.lineWidth = thickness;
|
|
13836
|
+
ctx.lineCap = "round";
|
|
13837
|
+
ctx.beginPath();
|
|
13838
|
+
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
|
|
13839
|
+
ctx.strokeStyle = trackColor;
|
|
13840
|
+
ctx.stroke();
|
|
13841
|
+
if (t <= 0) return;
|
|
13842
|
+
const start = -Math.PI / 2;
|
|
13843
|
+
ctx.beginPath();
|
|
13844
|
+
ctx.arc(cx, cy, radius, start, start + t * Math.PI * 2);
|
|
13845
|
+
ctx.strokeStyle = accentColor;
|
|
13846
|
+
ctx.stroke();
|
|
13847
|
+
}
|
|
13848
|
+
__name(drawRing, "drawRing");
|
|
13849
|
+
function drawIconLabel(ctx, box, density, label, style, family, icon, position, assets) {
|
|
13850
|
+
const fontPx = style.fontSize * density;
|
|
13851
|
+
const iconPx = fontPx * 1.3;
|
|
13852
|
+
const gapPx = label ? fontPx * 0.5 : 0;
|
|
13853
|
+
const stack = family ? `"${family}", ${UI_FONT_STACK}` : UI_FONT_STACK;
|
|
13854
|
+
ctx.font = `${style.fontWeight} ${fontPx}px ${stack}`;
|
|
13855
|
+
const labelPx = label ? ctx.measureText(label).width : 0;
|
|
13856
|
+
const groupPx = iconPx + gapPx + labelPx;
|
|
13857
|
+
const startX = box.x + (box.w - groupPx) / 2;
|
|
13858
|
+
const iconX = position === "left" ? startX : startX + labelPx + gapPx;
|
|
13859
|
+
const labelX = position === "left" ? startX + iconPx + gapPx : startX;
|
|
13860
|
+
drawImagePaint(
|
|
13861
|
+
ctx,
|
|
13862
|
+
{ src: icon, fit: "contain", tint: style.color },
|
|
13863
|
+
{ x: iconX, y: box.y + (box.h - iconPx) / 2, w: iconPx, h: iconPx },
|
|
13864
|
+
assets
|
|
13865
|
+
);
|
|
13866
|
+
if (label) {
|
|
13867
|
+
drawTextBlock(
|
|
13868
|
+
ctx,
|
|
13869
|
+
{ x: labelX, y: box.y, w: labelPx + 2, h: box.h },
|
|
13870
|
+
density,
|
|
13871
|
+
label,
|
|
13872
|
+
{ ...style, align: "left", padding: 0 },
|
|
13873
|
+
family,
|
|
13874
|
+
assets
|
|
13875
|
+
);
|
|
13876
|
+
}
|
|
13877
|
+
}
|
|
13878
|
+
__name(drawIconLabel, "drawIconLabel");
|
|
13879
|
+
|
|
13880
|
+
// core/ui/uiPaintOrder.ts
|
|
13881
|
+
var BASE_RENDER_ORDER = 10;
|
|
13882
|
+
var MAX_RENDER_ORDER = 890;
|
|
13883
|
+
var MAX_TREE_RANK = MAX_RENDER_ORDER - BASE_RENDER_ORDER - 1;
|
|
13884
|
+
var SLOT_STEP = 1e-4;
|
|
13885
|
+
var SLOTS_PER_WIDGET = 3;
|
|
13886
|
+
var MAX_WIDGET_INDEX = Math.floor(1 / SLOT_STEP / SLOTS_PER_WIDGET) - 1;
|
|
13887
|
+
var PLANE_EPSILON_METERS = 1e-3;
|
|
13888
|
+
var PARALLEL_DOT = 1 - 1e-4;
|
|
13889
|
+
var dot = /* @__PURE__ */ __name((a, b) => a.x * b.x + a.y * b.y + a.z * b.z, "dot");
|
|
13890
|
+
var length = /* @__PURE__ */ __name((a) => Math.sqrt(dot(a, a)), "length");
|
|
13891
|
+
var subtract = /* @__PURE__ */ __name((a, b) => ({
|
|
13892
|
+
x: a.x - b.x,
|
|
13893
|
+
y: a.y - b.y,
|
|
13894
|
+
z: a.z - b.z
|
|
13895
|
+
}), "subtract");
|
|
13896
|
+
function unit(a) {
|
|
13897
|
+
const len = length(a);
|
|
13898
|
+
if (len < 1e-9) return { x: 0, y: 0, z: 0 };
|
|
13899
|
+
return { x: a.x / len, y: a.y / len, z: a.z / len };
|
|
13900
|
+
}
|
|
13901
|
+
__name(unit, "unit");
|
|
13902
|
+
function normalOf(rect) {
|
|
13903
|
+
const { halfX: a, halfY: b } = rect;
|
|
13904
|
+
return unit({
|
|
13905
|
+
x: a.y * b.z - a.z * b.y,
|
|
13906
|
+
y: a.z * b.x - a.x * b.z,
|
|
13907
|
+
z: a.x * b.y - a.y * b.x
|
|
13908
|
+
});
|
|
13909
|
+
}
|
|
13910
|
+
__name(normalOf, "normalOf");
|
|
13911
|
+
var planeDistance = /* @__PURE__ */ __name((rect, normal, eye) => Math.abs(dot(subtract(eye, rect.center), normal)), "planeDistance");
|
|
13912
|
+
function closestPointDistance(rect, eye) {
|
|
13913
|
+
const toEye = subtract(eye, rect.center);
|
|
13914
|
+
const lenX = length(rect.halfX);
|
|
13915
|
+
const lenY = length(rect.halfY);
|
|
13916
|
+
const axisX = unit(rect.halfX);
|
|
13917
|
+
const axisY = unit(rect.halfY);
|
|
13918
|
+
const s = Math.max(-lenX, Math.min(lenX, dot(toEye, axisX)));
|
|
13919
|
+
const t = Math.max(-lenY, Math.min(lenY, dot(toEye, axisY)));
|
|
13920
|
+
return length({
|
|
13921
|
+
x: toEye.x - axisX.x * s - axisY.x * t,
|
|
13922
|
+
y: toEye.y - axisX.y * s - axisY.y * t,
|
|
13923
|
+
z: toEye.z - axisX.z * s - axisY.z * t
|
|
13924
|
+
});
|
|
13925
|
+
}
|
|
13926
|
+
__name(closestPointDistance, "closestPointDistance");
|
|
13927
|
+
var areaOf = /* @__PURE__ */ __name((rect) => length(rect.halfX) * length(rect.halfY), "areaOf");
|
|
13928
|
+
function comparePaintRects(a, b, eye) {
|
|
13929
|
+
const normalA = normalOf(a);
|
|
13930
|
+
const normalB = normalOf(b);
|
|
13931
|
+
const parallel = Math.abs(dot(normalA, normalB)) >= PARALLEL_DOT;
|
|
13932
|
+
const distanceA = parallel ? planeDistance(a, normalA, eye) : closestPointDistance(a, eye);
|
|
13933
|
+
const distanceB = parallel ? planeDistance(b, normalB, eye) : closestPointDistance(b, eye);
|
|
13934
|
+
if (Math.abs(distanceA - distanceB) > PLANE_EPSILON_METERS) {
|
|
13935
|
+
return distanceB - distanceA;
|
|
13936
|
+
}
|
|
13937
|
+
const areaA = areaOf(a);
|
|
13938
|
+
const areaB = areaOf(b);
|
|
13939
|
+
if (areaA !== areaB) return areaB - areaA;
|
|
13940
|
+
return a.id - b.id;
|
|
13941
|
+
}
|
|
13942
|
+
__name(comparePaintRects, "comparePaintRects");
|
|
13943
|
+
function buildPaintTrees(nodes) {
|
|
13944
|
+
const known = new Set(nodes.map((node) => node.id));
|
|
13945
|
+
const children = /* @__PURE__ */ new Map();
|
|
13946
|
+
const roots = [];
|
|
13947
|
+
for (const node of nodes) {
|
|
13948
|
+
if (node.parent !== null && known.has(node.parent)) {
|
|
13949
|
+
const siblings = children.get(node.parent);
|
|
13950
|
+
if (siblings) siblings.push(node.id);
|
|
13951
|
+
else children.set(node.parent, [node.id]);
|
|
13952
|
+
} else {
|
|
13953
|
+
roots.push(node.id);
|
|
13954
|
+
}
|
|
13955
|
+
}
|
|
13956
|
+
const trees = [];
|
|
13957
|
+
const visited = /* @__PURE__ */ new Set();
|
|
13958
|
+
const walk = /* @__PURE__ */ __name((id, order) => {
|
|
13959
|
+
if (visited.has(id)) return;
|
|
13960
|
+
visited.add(id);
|
|
13961
|
+
order.push(id);
|
|
13962
|
+
const kids = children.get(id);
|
|
13963
|
+
if (!kids) return;
|
|
13964
|
+
for (const kid of [...kids].sort((a, b) => a - b)) walk(kid, order);
|
|
13965
|
+
}, "walk");
|
|
13966
|
+
for (const rootId of [...roots].sort((a, b) => a - b)) {
|
|
13967
|
+
const order = [];
|
|
13968
|
+
walk(rootId, order);
|
|
13969
|
+
trees.push({ rootId, order });
|
|
13970
|
+
}
|
|
13971
|
+
return trees;
|
|
13972
|
+
}
|
|
13973
|
+
__name(buildPaintTrees, "buildPaintTrees");
|
|
13974
|
+
function paintSlots(treeRank, widgetIndex) {
|
|
13975
|
+
const base = BASE_RENDER_ORDER + Math.min(treeRank, MAX_TREE_RANK);
|
|
13976
|
+
const index = Math.min(widgetIndex, MAX_WIDGET_INDEX);
|
|
13977
|
+
const slot = /* @__PURE__ */ __name((offset) => base + (index * SLOTS_PER_WIDGET + offset) * SLOT_STEP, "slot");
|
|
13978
|
+
return { face: slot(0), parts: slot(1), descendants: slot(2) };
|
|
13979
|
+
}
|
|
13980
|
+
__name(paintSlots, "paintSlots");
|
|
13981
|
+
function assignPaintOrder(trees, rects, eye) {
|
|
13982
|
+
const sorted = trees.filter((tree) => rects.has(tree.rootId)).sort(
|
|
13983
|
+
(a, b) => comparePaintRects(
|
|
13984
|
+
rects.get(a.rootId),
|
|
13985
|
+
rects.get(b.rootId),
|
|
13986
|
+
eye
|
|
13987
|
+
)
|
|
13988
|
+
);
|
|
13989
|
+
const slots = /* @__PURE__ */ new Map();
|
|
13990
|
+
sorted.forEach((tree, rank) => {
|
|
13991
|
+
tree.order.forEach((id, index) => {
|
|
13992
|
+
slots.set(id, paintSlots(rank, index));
|
|
13993
|
+
});
|
|
13994
|
+
});
|
|
13995
|
+
return slots;
|
|
13996
|
+
}
|
|
13997
|
+
__name(assignPaintOrder, "assignPaintOrder");
|
|
13218
13998
|
|
|
13219
13999
|
// core/systems/UIPanelSystem.ts
|
|
13220
|
-
var FACE_RENDER_ORDER = 10;
|
|
13221
14000
|
var CHILD_Z = 2e-3;
|
|
14001
|
+
var DESCENDANT_WALK_INTERVAL = 30;
|
|
14002
|
+
var METER_STEPS = 200;
|
|
14003
|
+
var CLEAR_CHROME = {
|
|
14004
|
+
backgroundColor: "#000000",
|
|
14005
|
+
backgroundOpacity: 0,
|
|
14006
|
+
cornerRadius: 0,
|
|
14007
|
+
borderWidth: 0,
|
|
14008
|
+
borderColor: "#000000"
|
|
14009
|
+
};
|
|
14010
|
+
var PAINT_STAMP_KEY = "__uiPaintStamp";
|
|
13222
14011
|
var _UIPanelSystem = class _UIPanelSystem {
|
|
13223
14012
|
constructor(options) {
|
|
13224
14013
|
this.entries = /* @__PURE__ */ new Map();
|
|
14014
|
+
this.framesUntilDescendantWalk = 0;
|
|
14015
|
+
/** Whether any panel defines tokens, so plain scenes skip the parent walk. */
|
|
14016
|
+
this.anyTokens = false;
|
|
14017
|
+
this.drawAssets = {
|
|
14018
|
+
image: /* @__PURE__ */ __name((src) => uiImage(src), "image"),
|
|
14019
|
+
scratch: /* @__PURE__ */ __name((width, height) => {
|
|
14020
|
+
const canvas = this.createCanvas();
|
|
14021
|
+
canvas.width = width;
|
|
14022
|
+
canvas.height = height;
|
|
14023
|
+
return canvas.getContext("2d");
|
|
14024
|
+
}, "scratch")
|
|
14025
|
+
};
|
|
13225
14026
|
this.createCanvas = options?.createCanvas ?? (() => document.createElement("canvas"));
|
|
13226
14027
|
}
|
|
13227
14028
|
update(world, deltaTime = 0) {
|
|
13228
14029
|
const live = /* @__PURE__ */ new Set();
|
|
14030
|
+
this.anyTokens = world.query(UIPanelComponent).some((id) => world.getComponent(id, UIPanelComponent)?.tokens);
|
|
13229
14031
|
for (const entityId of world.query(UIPanelComponent, Object3DRef)) {
|
|
13230
14032
|
const panel = world.getComponent(entityId, UIPanelComponent);
|
|
13231
14033
|
if (!panel) continue;
|
|
@@ -13263,6 +14065,7 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13263
14065
|
this.entries.delete(entityId);
|
|
13264
14066
|
}
|
|
13265
14067
|
}
|
|
14068
|
+
this.applyPaintOrder(world);
|
|
13266
14069
|
}
|
|
13267
14070
|
/** All GPU/canvas resources; call on world teardown. */
|
|
13268
14071
|
dispose() {
|
|
@@ -13271,84 +14074,188 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13271
14074
|
}
|
|
13272
14075
|
// ── Widgets ────────────────────────────────────────────────────────────────
|
|
13273
14076
|
syncPanel(world, entityId, panel) {
|
|
13274
|
-
const
|
|
13275
|
-
|
|
13276
|
-
|
|
13277
|
-
|
|
13278
|
-
|
|
13279
|
-
|
|
13280
|
-
|
|
13281
|
-
|
|
13282
|
-
|
|
13283
|
-
|
|
13284
|
-
|
|
13285
|
-
|
|
14077
|
+
const chrome = resolveChrome(
|
|
14078
|
+
panel,
|
|
14079
|
+
panel.style,
|
|
14080
|
+
this.tokensFor(world, entityId)
|
|
14081
|
+
);
|
|
14082
|
+
const bleed = chromeBleed(chrome);
|
|
14083
|
+
const size = resolveCanvasSize(
|
|
14084
|
+
panel.width + bleed * 2,
|
|
14085
|
+
panel.height + bleed * 2,
|
|
14086
|
+
panel.pixelDensity
|
|
14087
|
+
);
|
|
14088
|
+
const signature = panelSignature(
|
|
14089
|
+
panel.width,
|
|
14090
|
+
panel.height,
|
|
14091
|
+
size,
|
|
14092
|
+
chrome,
|
|
14093
|
+
imagesLoaded(chrome)
|
|
14094
|
+
);
|
|
14095
|
+
this.rebuildIfChanged(
|
|
14096
|
+
world,
|
|
14097
|
+
entityId,
|
|
14098
|
+
signature,
|
|
14099
|
+
panel,
|
|
14100
|
+
bleed,
|
|
14101
|
+
size,
|
|
14102
|
+
(ctx) => {
|
|
14103
|
+
drawChrome(
|
|
14104
|
+
ctx,
|
|
14105
|
+
layoutBox(panel, bleed, size.density),
|
|
14106
|
+
size.density,
|
|
14107
|
+
chrome,
|
|
14108
|
+
this.drawAssets
|
|
14109
|
+
);
|
|
14110
|
+
},
|
|
14111
|
+
THREE37__namespace.DoubleSide
|
|
14112
|
+
);
|
|
13286
14113
|
}
|
|
13287
14114
|
syncText(world, entityId, text) {
|
|
13288
|
-
const
|
|
13289
|
-
const
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
|
|
13294
|
-
|
|
13295
|
-
|
|
13296
|
-
|
|
13297
|
-
|
|
13298
|
-
const signature =
|
|
13299
|
-
|
|
13300
|
-
|
|
13301
|
-
|
|
13302
|
-
|
|
14115
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14116
|
+
const chrome = text.style ? resolveChrome(CLEAR_CHROME, text.style, tokens) : null;
|
|
14117
|
+
const bleed = chrome ? chromeBleed(chrome) : 0;
|
|
14118
|
+
const size = resolveCanvasSize(
|
|
14119
|
+
text.width + bleed * 2,
|
|
14120
|
+
text.height + bleed * 2,
|
|
14121
|
+
text.pixelDensity
|
|
14122
|
+
);
|
|
14123
|
+
const style = resolveText(text, text.style, tokens);
|
|
14124
|
+
const family = familyOf(style.font);
|
|
14125
|
+
const signature = JSON.stringify([
|
|
14126
|
+
textSignature(text.width, text.height, size, text.text, style, family),
|
|
14127
|
+
chrome,
|
|
14128
|
+
chrome ? imagesLoaded(chrome) : null
|
|
14129
|
+
]);
|
|
14130
|
+
this.rebuildIfChanged(
|
|
14131
|
+
world,
|
|
14132
|
+
entityId,
|
|
14133
|
+
signature,
|
|
14134
|
+
text,
|
|
14135
|
+
bleed,
|
|
14136
|
+
size,
|
|
14137
|
+
(ctx) => {
|
|
14138
|
+
const box = layoutBox(text, bleed, size.density);
|
|
14139
|
+
if (chrome) {
|
|
14140
|
+
drawChrome(ctx, box, size.density, chrome, this.drawAssets);
|
|
14141
|
+
}
|
|
14142
|
+
drawTextBlock(
|
|
14143
|
+
ctx,
|
|
14144
|
+
box,
|
|
14145
|
+
size.density,
|
|
14146
|
+
text.text,
|
|
14147
|
+
style,
|
|
14148
|
+
family,
|
|
14149
|
+
this.drawAssets
|
|
14150
|
+
);
|
|
14151
|
+
}
|
|
14152
|
+
);
|
|
13303
14153
|
}
|
|
13304
14154
|
syncButton(world, entityId, button) {
|
|
13305
|
-
const
|
|
13306
|
-
const chrome =
|
|
13307
|
-
|
|
13308
|
-
|
|
13309
|
-
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
const label =
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13317
|
-
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
14155
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14156
|
+
const chrome = resolveChrome(button, button.style, tokens);
|
|
14157
|
+
const bleed = chromeBleed(chrome);
|
|
14158
|
+
const size = resolveCanvasSize(
|
|
14159
|
+
button.width + bleed * 2,
|
|
14160
|
+
button.height + bleed * 2,
|
|
14161
|
+
button.pixelDensity
|
|
14162
|
+
);
|
|
14163
|
+
const label = resolveText(
|
|
14164
|
+
{
|
|
14165
|
+
fontSize: button.fontSize,
|
|
14166
|
+
fontWeight: button.fontWeight,
|
|
14167
|
+
color: button.textColor,
|
|
14168
|
+
align: "center",
|
|
14169
|
+
valign: "middle",
|
|
14170
|
+
lineHeight: 1.2,
|
|
14171
|
+
padding: 0.01
|
|
14172
|
+
},
|
|
14173
|
+
button.style,
|
|
14174
|
+
tokens
|
|
14175
|
+
);
|
|
14176
|
+
const family = familyOf(label.font);
|
|
14177
|
+
const icon = button.icon ? resolveToken(button.icon, tokens) : null;
|
|
13322
14178
|
const signature = buttonSignature(
|
|
13323
14179
|
button.width,
|
|
13324
14180
|
button.height,
|
|
13325
14181
|
size,
|
|
13326
14182
|
chrome,
|
|
13327
14183
|
button.label,
|
|
13328
|
-
label
|
|
14184
|
+
label,
|
|
14185
|
+
family,
|
|
14186
|
+
[imagesLoaded(chrome), icon, icon ? !!uiImage(icon) : false]
|
|
14187
|
+
);
|
|
14188
|
+
this.rebuildIfChanged(
|
|
14189
|
+
world,
|
|
14190
|
+
entityId,
|
|
14191
|
+
signature,
|
|
14192
|
+
button,
|
|
14193
|
+
bleed,
|
|
14194
|
+
size,
|
|
14195
|
+
(ctx) => {
|
|
14196
|
+
const box = layoutBox(button, bleed, size.density);
|
|
14197
|
+
drawChrome(ctx, box, size.density, chrome, this.drawAssets);
|
|
14198
|
+
if (icon) {
|
|
14199
|
+
drawIconLabel(
|
|
14200
|
+
ctx,
|
|
14201
|
+
box,
|
|
14202
|
+
size.density,
|
|
14203
|
+
button.label,
|
|
14204
|
+
label,
|
|
14205
|
+
family,
|
|
14206
|
+
icon,
|
|
14207
|
+
button.iconPosition ?? "left",
|
|
14208
|
+
this.drawAssets
|
|
14209
|
+
);
|
|
14210
|
+
} else {
|
|
14211
|
+
drawTextBlock(
|
|
14212
|
+
ctx,
|
|
14213
|
+
box,
|
|
14214
|
+
size.density,
|
|
14215
|
+
button.label,
|
|
14216
|
+
label,
|
|
14217
|
+
family,
|
|
14218
|
+
this.drawAssets
|
|
14219
|
+
);
|
|
14220
|
+
}
|
|
14221
|
+
}
|
|
13329
14222
|
);
|
|
13330
|
-
this.rebuildIfChanged(world, entityId, signature, button.width, button.height, size, (ctx) => {
|
|
13331
|
-
drawChrome(ctx, size.pxWidth, size.pxHeight, size.density, chrome);
|
|
13332
|
-
drawTextBlock(ctx, size.pxWidth, size.pxHeight, size.density, button.label, label);
|
|
13333
|
-
});
|
|
13334
14223
|
}
|
|
13335
14224
|
syncToggle(world, entityId, toggle, deltaTime) {
|
|
13336
|
-
const
|
|
13337
|
-
const
|
|
13338
|
-
|
|
13339
|
-
|
|
13340
|
-
|
|
13341
|
-
|
|
13342
|
-
|
|
13343
|
-
|
|
14225
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14226
|
+
const accent = resolveToken(toggle.accentColor, tokens);
|
|
14227
|
+
const track = resolveToken(toggle.trackColor, tokens);
|
|
14228
|
+
const knobColor = resolveToken(toggle.knobColor, tokens);
|
|
14229
|
+
const size = resolveCanvasSize(
|
|
14230
|
+
toggle.width,
|
|
14231
|
+
toggle.height,
|
|
14232
|
+
toggle.pixelDensity
|
|
14233
|
+
);
|
|
14234
|
+
const variant = toggle.variant ?? "switch";
|
|
14235
|
+
if (variant !== "switch") {
|
|
14236
|
+
this.syncMarkToggle(world, entityId, toggle, accent, track, knobColor);
|
|
14237
|
+
return;
|
|
14238
|
+
}
|
|
14239
|
+
const chrome = resolveChrome(
|
|
14240
|
+
{
|
|
14241
|
+
backgroundColor: toggle.value ? accent : track,
|
|
14242
|
+
backgroundOpacity: 1,
|
|
14243
|
+
cornerRadius: toggle.height / 2,
|
|
14244
|
+
borderWidth: 0,
|
|
14245
|
+
borderColor: "#000000"
|
|
14246
|
+
},
|
|
14247
|
+
toggle.style,
|
|
14248
|
+
tokens
|
|
14249
|
+
);
|
|
13344
14250
|
const signature = JSON.stringify([
|
|
13345
14251
|
trackSignature(
|
|
13346
14252
|
toggle.width,
|
|
13347
14253
|
toggle.height,
|
|
13348
14254
|
size,
|
|
13349
14255
|
chrome,
|
|
13350
|
-
|
|
13351
|
-
|
|
14256
|
+
accent,
|
|
14257
|
+
knobColor,
|
|
14258
|
+
variant
|
|
13352
14259
|
),
|
|
13353
14260
|
toggle.value
|
|
13354
14261
|
]);
|
|
@@ -13356,18 +14263,24 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13356
14263
|
world,
|
|
13357
14264
|
entityId,
|
|
13358
14265
|
signature,
|
|
13359
|
-
toggle
|
|
13360
|
-
|
|
14266
|
+
toggle,
|
|
14267
|
+
0,
|
|
13361
14268
|
size,
|
|
13362
14269
|
(ctx) => {
|
|
13363
|
-
drawChrome(
|
|
14270
|
+
drawChrome(
|
|
14271
|
+
ctx,
|
|
14272
|
+
layoutBox(toggle, 0, size.density),
|
|
14273
|
+
size.density,
|
|
14274
|
+
chrome,
|
|
14275
|
+
this.drawAssets
|
|
14276
|
+
);
|
|
13364
14277
|
}
|
|
13365
14278
|
);
|
|
13366
14279
|
if (!entry) return;
|
|
13367
14280
|
if (!entry.knob) {
|
|
13368
14281
|
entry.knob = this.makeDisc(
|
|
13369
14282
|
toggle.height * 0.4,
|
|
13370
|
-
|
|
14283
|
+
knobColor,
|
|
13371
14284
|
entry.face.parent,
|
|
13372
14285
|
CHILD_Z
|
|
13373
14286
|
);
|
|
@@ -13379,35 +14292,95 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13379
14292
|
knob.position.x += (target - knob.position.x) * (deltaTime > 0 ? ease : 1);
|
|
13380
14293
|
knob.position.z = CHILD_Z;
|
|
13381
14294
|
}
|
|
14295
|
+
/** Checkbox and radio: a box or ring at the left of the widget's area. */
|
|
14296
|
+
syncMarkToggle(world, entityId, toggle, accent, track, markColor) {
|
|
14297
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14298
|
+
const radio = toggle.variant === "radio";
|
|
14299
|
+
const size = resolveCanvasSize(
|
|
14300
|
+
toggle.width,
|
|
14301
|
+
toggle.height,
|
|
14302
|
+
toggle.pixelDensity
|
|
14303
|
+
);
|
|
14304
|
+
const side = toggle.height;
|
|
14305
|
+
const chrome = resolveChrome(
|
|
14306
|
+
{
|
|
14307
|
+
backgroundColor: toggle.value ? accent : track,
|
|
14308
|
+
backgroundOpacity: 1,
|
|
14309
|
+
cornerRadius: radio ? side / 2 : side * 0.2,
|
|
14310
|
+
borderWidth: 0,
|
|
14311
|
+
borderColor: "#000000"
|
|
14312
|
+
},
|
|
14313
|
+
toggle.style,
|
|
14314
|
+
tokens
|
|
14315
|
+
);
|
|
14316
|
+
const signature = JSON.stringify([
|
|
14317
|
+
trackSignature(
|
|
14318
|
+
toggle.width,
|
|
14319
|
+
toggle.height,
|
|
14320
|
+
size,
|
|
14321
|
+
chrome,
|
|
14322
|
+
accent,
|
|
14323
|
+
markColor,
|
|
14324
|
+
toggle.variant ?? null
|
|
14325
|
+
),
|
|
14326
|
+
toggle.value
|
|
14327
|
+
]);
|
|
14328
|
+
this.rebuildIfChanged(world, entityId, signature, toggle, 0, size, (ctx) => {
|
|
14329
|
+
const px = side * size.density;
|
|
14330
|
+
const box = { x: 0, y: 0, w: px, h: px };
|
|
14331
|
+
drawChrome(ctx, box, size.density, chrome, this.drawAssets);
|
|
14332
|
+
if (!toggle.value) return;
|
|
14333
|
+
if (radio) drawDot(ctx, px / 2, px / 2, px * 0.24, markColor);
|
|
14334
|
+
else drawCheckMark(ctx, box, markColor);
|
|
14335
|
+
});
|
|
14336
|
+
}
|
|
13382
14337
|
syncSlider(world, entityId, slider) {
|
|
13383
|
-
const
|
|
14338
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14339
|
+
const accent = resolveToken(slider.accentColor, tokens);
|
|
14340
|
+
const track = resolveToken(slider.trackColor, tokens);
|
|
14341
|
+
const knobColor = resolveToken(slider.knobColor, tokens);
|
|
14342
|
+
const size = resolveCanvasSize(
|
|
14343
|
+
slider.width,
|
|
14344
|
+
slider.height,
|
|
14345
|
+
slider.pixelDensity
|
|
14346
|
+
);
|
|
14347
|
+
const range = Math.max(1e-6, slider.max - slider.min);
|
|
14348
|
+
const t = Math.min(1, Math.max(0, (slider.value - slider.min) / range));
|
|
14349
|
+
if (slider.variant === "progress" || slider.variant === "ring") {
|
|
14350
|
+
this.syncMeter(world, entityId, slider, t, accent, track, knobColor);
|
|
14351
|
+
return;
|
|
14352
|
+
}
|
|
13384
14353
|
const trackThickness = slider.height * 0.32;
|
|
13385
14354
|
const knobRadius = slider.height * 0.45;
|
|
13386
14355
|
const usable = Math.max(1e-3, slider.width - slider.height);
|
|
13387
|
-
const chrome =
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
14356
|
+
const chrome = resolveChrome(
|
|
14357
|
+
{
|
|
14358
|
+
backgroundColor: track,
|
|
14359
|
+
backgroundOpacity: 1,
|
|
14360
|
+
cornerRadius: trackThickness / 2,
|
|
14361
|
+
borderWidth: 0,
|
|
14362
|
+
borderColor: "#000000"
|
|
14363
|
+
},
|
|
14364
|
+
void 0,
|
|
14365
|
+
null
|
|
14366
|
+
);
|
|
13394
14367
|
const signature = trackSignature(
|
|
13395
14368
|
slider.width,
|
|
13396
14369
|
slider.height,
|
|
13397
14370
|
size,
|
|
13398
14371
|
chrome,
|
|
13399
|
-
|
|
13400
|
-
|
|
14372
|
+
accent,
|
|
14373
|
+
knobColor,
|
|
14374
|
+
slider.variant ?? null
|
|
13401
14375
|
);
|
|
13402
14376
|
const entry = this.rebuildIfChanged(
|
|
13403
14377
|
world,
|
|
13404
14378
|
entityId,
|
|
13405
14379
|
signature,
|
|
13406
|
-
slider
|
|
13407
|
-
|
|
14380
|
+
slider,
|
|
14381
|
+
0,
|
|
13408
14382
|
size,
|
|
13409
14383
|
(ctx) => {
|
|
13410
|
-
ctx.clearRect(0, 0, size.pxWidth, size.pxHeight);
|
|
13411
14384
|
const trackWidthM = usable + trackThickness;
|
|
13412
14385
|
drawRoundedBar(
|
|
13413
14386
|
ctx,
|
|
@@ -13415,7 +14388,7 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13415
14388
|
(slider.height - trackThickness) / 2 * size.density,
|
|
13416
14389
|
trackWidthM * size.density,
|
|
13417
14390
|
trackThickness * size.density,
|
|
13418
|
-
|
|
14391
|
+
track
|
|
13419
14392
|
);
|
|
13420
14393
|
}
|
|
13421
14394
|
);
|
|
@@ -13424,13 +14397,13 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13424
14397
|
entry.fill = this.makeQuad(
|
|
13425
14398
|
1,
|
|
13426
14399
|
trackThickness,
|
|
13427
|
-
|
|
14400
|
+
accent,
|
|
13428
14401
|
entry.face.parent,
|
|
13429
14402
|
CHILD_Z / 2
|
|
13430
14403
|
);
|
|
13431
14404
|
entry.cap = this.makeDisc(
|
|
13432
14405
|
trackThickness / 2,
|
|
13433
|
-
|
|
14406
|
+
accent,
|
|
13434
14407
|
entry.face.parent,
|
|
13435
14408
|
CHILD_Z / 2,
|
|
13436
14409
|
Math.PI / 2,
|
|
@@ -13441,51 +14414,124 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13441
14414
|
if (!entry.knob) {
|
|
13442
14415
|
entry.knob = this.makeDisc(
|
|
13443
14416
|
knobRadius,
|
|
13444
|
-
|
|
14417
|
+
knobColor,
|
|
13445
14418
|
entry.face.parent,
|
|
13446
14419
|
CHILD_Z
|
|
13447
14420
|
);
|
|
13448
14421
|
}
|
|
13449
|
-
const range = Math.max(1e-6, slider.max - slider.min);
|
|
13450
|
-
const t = Math.min(1, Math.max(0, (slider.value - slider.min) / range));
|
|
13451
14422
|
entry.knob.position.x = -usable / 2 + t * usable;
|
|
13452
14423
|
entry.knob.position.z = CHILD_Z;
|
|
13453
14424
|
entry.fill.scale.x = Math.max(1e-4, t * usable);
|
|
13454
14425
|
entry.fill.position.x = -usable / 2 + t * usable / 2;
|
|
13455
14426
|
entry.fill.position.z = CHILD_Z / 2;
|
|
13456
14427
|
}
|
|
14428
|
+
/**
|
|
14429
|
+
* Progress bars and rings. Unlike a slider these change rarely and have no
|
|
14430
|
+
* drag to keep smooth, so the value is drawn, in steps of half a percent.
|
|
14431
|
+
*/
|
|
14432
|
+
syncMeter(world, entityId, slider, t, accent, track, knobColor) {
|
|
14433
|
+
const size = resolveCanvasSize(
|
|
14434
|
+
slider.width,
|
|
14435
|
+
slider.height,
|
|
14436
|
+
slider.pixelDensity
|
|
14437
|
+
);
|
|
14438
|
+
const shown = Math.round(t * METER_STEPS) / METER_STEPS;
|
|
14439
|
+
const signature = JSON.stringify([
|
|
14440
|
+
slider.width,
|
|
14441
|
+
slider.height,
|
|
14442
|
+
size,
|
|
14443
|
+
slider.variant,
|
|
14444
|
+
accent,
|
|
14445
|
+
track,
|
|
14446
|
+
knobColor,
|
|
14447
|
+
shown
|
|
14448
|
+
]);
|
|
14449
|
+
this.rebuildIfChanged(world, entityId, signature, slider, 0, size, (ctx) => {
|
|
14450
|
+
const box = {
|
|
14451
|
+
x: 0,
|
|
14452
|
+
y: 0,
|
|
14453
|
+
w: size.pxWidth,
|
|
14454
|
+
h: size.pxHeight
|
|
14455
|
+
};
|
|
14456
|
+
if (slider.variant === "ring") {
|
|
14457
|
+
drawRing(ctx, box, shown, track, accent);
|
|
14458
|
+
return;
|
|
14459
|
+
}
|
|
14460
|
+
drawRoundedBar(ctx, 0, 0, box.w, box.h, track);
|
|
14461
|
+
if (shown <= 0) return;
|
|
14462
|
+
const fill = Math.max(box.h, box.w * shown);
|
|
14463
|
+
drawRoundedBar(ctx, 0, 0, fill, box.h, accent);
|
|
14464
|
+
});
|
|
14465
|
+
}
|
|
14466
|
+
/** The tokens in scope for a widget, nearest panel first. */
|
|
14467
|
+
tokensFor(world, entityId) {
|
|
14468
|
+
if (!this.anyTokens) return null;
|
|
14469
|
+
let merged = null;
|
|
14470
|
+
const visited = /* @__PURE__ */ new Set();
|
|
14471
|
+
let current = entityId;
|
|
14472
|
+
while (current !== null && !visited.has(current)) {
|
|
14473
|
+
visited.add(current);
|
|
14474
|
+
const tokens = world.getComponent(current, UIPanelComponent)?.tokens;
|
|
14475
|
+
if (tokens) merged = { ...tokens, ...merged ?? {} };
|
|
14476
|
+
const parent = world.getComponent(current, ParentId)?.value;
|
|
14477
|
+
current = typeof parent === "number" ? parent : null;
|
|
14478
|
+
}
|
|
14479
|
+
return merged;
|
|
14480
|
+
}
|
|
13457
14481
|
// ── Machinery ──────────────────────────────────────────────────────────────
|
|
13458
|
-
rebuildIfChanged(world, entityId, signature,
|
|
14482
|
+
rebuildIfChanged(world, entityId, signature, widget, bleed, size, draw, side = THREE37__namespace.FrontSide) {
|
|
13459
14483
|
const root = world.getComponent(entityId, Object3DRef)?.object;
|
|
13460
14484
|
if (!root) return null;
|
|
14485
|
+
const widthM = widget.width;
|
|
14486
|
+
const heightM = widget.height;
|
|
14487
|
+
const faceWidth = widthM + bleed * 2;
|
|
14488
|
+
const faceHeight = heightM + bleed * 2;
|
|
13461
14489
|
let entry = this.entries.get(entityId);
|
|
14490
|
+
if (entry) entry.opacity = widget.style?.opacity ?? 1;
|
|
13462
14491
|
if (entry && entry.signature === signature) return entry;
|
|
13463
14492
|
if (entry) this.disposeMovingParts(entry);
|
|
13464
14493
|
if (!entry) {
|
|
13465
14494
|
const canvas2 = this.createCanvas();
|
|
13466
|
-
const texture = new
|
|
14495
|
+
const texture = new THREE37__namespace.CanvasTexture(
|
|
13467
14496
|
canvas2
|
|
13468
14497
|
);
|
|
13469
14498
|
this.configureTexture(world, texture);
|
|
13470
|
-
const material = new
|
|
14499
|
+
const material = new THREE37__namespace.MeshBasicMaterial({
|
|
13471
14500
|
map: texture,
|
|
13472
14501
|
transparent: true,
|
|
13473
14502
|
depthWrite: false,
|
|
13474
14503
|
// UI colours are authored absolutes; scene tone mapping would shift
|
|
13475
14504
|
// them (the classic "why is my white UI beige" bug).
|
|
13476
14505
|
toneMapped: false,
|
|
13477
|
-
side
|
|
13478
|
-
premultipliedAlpha:
|
|
14506
|
+
side,
|
|
14507
|
+
premultipliedAlpha: false,
|
|
14508
|
+
blending: THREE37__namespace.CustomBlending,
|
|
14509
|
+
blendSrc: THREE37__namespace.OneFactor,
|
|
14510
|
+
blendDst: THREE37__namespace.OneMinusSrcAlphaFactor,
|
|
14511
|
+
blendSrcAlpha: THREE37__namespace.OneFactor,
|
|
14512
|
+
blendDstAlpha: THREE37__namespace.OneMinusSrcAlphaFactor
|
|
13479
14513
|
});
|
|
13480
|
-
const face = new
|
|
13481
|
-
new
|
|
14514
|
+
const face = new THREE37__namespace.Mesh(
|
|
14515
|
+
new THREE37__namespace.PlaneGeometry(faceWidth, faceHeight),
|
|
13482
14516
|
material
|
|
13483
14517
|
);
|
|
13484
|
-
face
|
|
14518
|
+
tagPart(face, 16777215, true);
|
|
14519
|
+
face.raycast = () => {
|
|
14520
|
+
};
|
|
13485
14521
|
root.add(face);
|
|
14522
|
+
const hit = new THREE37__namespace.Mesh(
|
|
14523
|
+
new THREE37__namespace.PlaneGeometry(widthM, heightM),
|
|
14524
|
+
new THREE37__namespace.MeshBasicMaterial({ visible: false, side })
|
|
14525
|
+
);
|
|
14526
|
+
root.add(hit);
|
|
13486
14527
|
entry = {
|
|
13487
14528
|
signature: "",
|
|
14529
|
+
root,
|
|
14530
|
+
width: widthM,
|
|
14531
|
+
height: heightM,
|
|
14532
|
+
opacity: widget.style?.opacity ?? 1,
|
|
13488
14533
|
face,
|
|
14534
|
+
hit,
|
|
13489
14535
|
texture,
|
|
13490
14536
|
material,
|
|
13491
14537
|
canvas: canvas2,
|
|
@@ -13499,23 +14545,26 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13499
14545
|
if (canvas.width !== size.pxWidth || canvas.height !== size.pxHeight) {
|
|
13500
14546
|
canvas.width = size.pxWidth;
|
|
13501
14547
|
canvas.height = size.pxHeight;
|
|
14548
|
+
if (entry.signature) entry.texture.dispose();
|
|
13502
14549
|
}
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
}
|
|
14550
|
+
entry.width = widthM;
|
|
14551
|
+
entry.height = heightM;
|
|
14552
|
+
resizePlane(entry.face, faceWidth, faceHeight);
|
|
14553
|
+
resizePlane(entry.hit, widthM, heightM);
|
|
13508
14554
|
const ctx = canvas.getContext("2d");
|
|
13509
|
-
if (ctx)
|
|
14555
|
+
if (ctx) {
|
|
14556
|
+
ctx.clearRect(0, 0, size.pxWidth, size.pxHeight);
|
|
14557
|
+
draw(ctx);
|
|
14558
|
+
}
|
|
13510
14559
|
entry.texture.needsUpdate = true;
|
|
13511
14560
|
entry.signature = signature;
|
|
13512
14561
|
return entry;
|
|
13513
14562
|
}
|
|
13514
14563
|
configureTexture(world, texture) {
|
|
13515
|
-
texture.colorSpace =
|
|
14564
|
+
texture.colorSpace = THREE37__namespace.SRGBColorSpace;
|
|
13516
14565
|
texture.generateMipmaps = true;
|
|
13517
|
-
texture.minFilter =
|
|
13518
|
-
texture.magFilter =
|
|
14566
|
+
texture.minFilter = THREE37__namespace.LinearMipmapLinearFilter;
|
|
14567
|
+
texture.magFilter = THREE37__namespace.LinearFilter;
|
|
13519
14568
|
texture.premultiplyAlpha = true;
|
|
13520
14569
|
try {
|
|
13521
14570
|
const renderer = world.getRenderer();
|
|
@@ -13526,7 +14575,7 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13526
14575
|
}
|
|
13527
14576
|
makeQuad(widthM, heightM, color, parent, z) {
|
|
13528
14577
|
return this.addPart(
|
|
13529
|
-
new
|
|
14578
|
+
new THREE37__namespace.PlaneGeometry(widthM, heightM),
|
|
13530
14579
|
color,
|
|
13531
14580
|
parent,
|
|
13532
14581
|
z
|
|
@@ -13535,24 +14584,23 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13535
14584
|
/** A filled disc (or arc segment, for the fill's rounded cap). */
|
|
13536
14585
|
makeDisc(radiusM, color, parent, z, thetaStart = 0, thetaLength = Math.PI * 2) {
|
|
13537
14586
|
return this.addPart(
|
|
13538
|
-
new
|
|
14587
|
+
new THREE37__namespace.CircleGeometry(radiusM, 32, thetaStart, thetaLength),
|
|
13539
14588
|
color,
|
|
13540
14589
|
parent,
|
|
13541
14590
|
z
|
|
13542
14591
|
);
|
|
13543
14592
|
}
|
|
13544
14593
|
addPart(geometry, color, parent, z) {
|
|
13545
|
-
const mesh = new
|
|
14594
|
+
const mesh = new THREE37__namespace.Mesh(
|
|
13546
14595
|
geometry,
|
|
13547
|
-
new
|
|
14596
|
+
new THREE37__namespace.MeshBasicMaterial({
|
|
13548
14597
|
color,
|
|
13549
14598
|
transparent: true,
|
|
13550
14599
|
depthWrite: false,
|
|
13551
|
-
toneMapped: false
|
|
13552
|
-
side: THREE30__namespace.DoubleSide
|
|
14600
|
+
toneMapped: false
|
|
13553
14601
|
})
|
|
13554
14602
|
);
|
|
13555
|
-
mesh
|
|
14603
|
+
tagPart(mesh, color);
|
|
13556
14604
|
mesh.position.z = z;
|
|
13557
14605
|
mesh.raycast = () => {
|
|
13558
14606
|
};
|
|
@@ -13583,22 +14631,144 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13583
14631
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
13584
14632
|
if (!transform || !object) return;
|
|
13585
14633
|
const camera = world.getCamera();
|
|
13586
|
-
const cam = new
|
|
13587
|
-
const self = new
|
|
14634
|
+
const cam = new THREE37__namespace.Vector3();
|
|
14635
|
+
const self = new THREE37__namespace.Vector3();
|
|
13588
14636
|
camera.getWorldPosition(cam);
|
|
13589
14637
|
object.getWorldPosition(self);
|
|
13590
14638
|
transform.rotation.y = Math.atan2(cam.x - self.x, cam.z - self.z);
|
|
13591
14639
|
}
|
|
14640
|
+
/**
|
|
14641
|
+
* Stamp every widget's meshes with this frame's paint order. Written each
|
|
14642
|
+
* frame because the eye moves: the order between trees can change at any
|
|
14643
|
+
* time, and a plain property write costs less than checking it.
|
|
14644
|
+
*/
|
|
14645
|
+
applyPaintOrder(world) {
|
|
14646
|
+
if (this.entries.size === 0) return;
|
|
14647
|
+
const camera = world.getCamera();
|
|
14648
|
+
camera.getWorldPosition(eyeScratch);
|
|
14649
|
+
const nodes = [...this.entries.keys()].map((id) => ({
|
|
14650
|
+
id,
|
|
14651
|
+
parent: nearestWidgetAncestor(world, id)
|
|
14652
|
+
}));
|
|
14653
|
+
const trees = buildPaintTrees(nodes);
|
|
14654
|
+
const rects = /* @__PURE__ */ new Map();
|
|
14655
|
+
for (const tree of trees) {
|
|
14656
|
+
const entry = this.entries.get(tree.rootId);
|
|
14657
|
+
if (entry) rects.set(tree.rootId, rootRect(tree.rootId, entry));
|
|
14658
|
+
}
|
|
14659
|
+
const slots = assignPaintOrder(trees, rects, eyeScratch);
|
|
14660
|
+
this.framesUntilDescendantWalk -= 1;
|
|
14661
|
+
const walkDescendants = this.framesUntilDescendantWalk <= 0;
|
|
14662
|
+
if (walkDescendants) {
|
|
14663
|
+
this.framesUntilDescendantWalk = DESCENDANT_WALK_INTERVAL;
|
|
14664
|
+
}
|
|
14665
|
+
const widgetRoots = /* @__PURE__ */ new Set();
|
|
14666
|
+
if (walkDescendants) {
|
|
14667
|
+
for (const entry of this.entries.values()) widgetRoots.add(entry.root);
|
|
14668
|
+
}
|
|
14669
|
+
for (const [entityId, entry] of this.entries) {
|
|
14670
|
+
const slot = slots.get(entityId);
|
|
14671
|
+
if (!slot) continue;
|
|
14672
|
+
entry.face.renderOrder = slot.face;
|
|
14673
|
+
for (const part of [entry.knob, entry.fill, entry.cap]) {
|
|
14674
|
+
if (part) part.renderOrder = slot.parts;
|
|
14675
|
+
}
|
|
14676
|
+
if (walkDescendants) stampDescendants(entry.root, slot, widgetRoots);
|
|
14677
|
+
}
|
|
14678
|
+
const effective = /* @__PURE__ */ new Map();
|
|
14679
|
+
const parentOf = new Map(nodes.map((node) => [node.id, node.parent]));
|
|
14680
|
+
for (const tree of trees) {
|
|
14681
|
+
for (const id of tree.order) {
|
|
14682
|
+
const entry = this.entries.get(id);
|
|
14683
|
+
if (!entry) continue;
|
|
14684
|
+
const parent = parentOf.get(id);
|
|
14685
|
+
const inherited = parent != null ? effective.get(parent) ?? 1 : 1;
|
|
14686
|
+
const opacity = entry.opacity * inherited;
|
|
14687
|
+
effective.set(id, opacity);
|
|
14688
|
+
for (const mesh of [entry.face, entry.knob, entry.fill, entry.cap]) {
|
|
14689
|
+
if (!mesh) continue;
|
|
14690
|
+
const tag = mesh.userData[UI_PART_KEY];
|
|
14691
|
+
if (tag.opacity === opacity) continue;
|
|
14692
|
+
tag.opacity = opacity;
|
|
14693
|
+
applyPartColor(mesh, tag);
|
|
14694
|
+
}
|
|
14695
|
+
}
|
|
14696
|
+
}
|
|
14697
|
+
}
|
|
13592
14698
|
destroyEntry(entry) {
|
|
13593
14699
|
this.disposeMovingParts(entry);
|
|
13594
14700
|
entry.face.removeFromParent();
|
|
13595
14701
|
entry.face.geometry.dispose();
|
|
13596
14702
|
entry.face.material.dispose();
|
|
14703
|
+
entry.hit.removeFromParent();
|
|
14704
|
+
entry.hit.geometry.dispose();
|
|
14705
|
+
entry.hit.material.dispose();
|
|
13597
14706
|
entry.texture.dispose();
|
|
13598
14707
|
}
|
|
13599
14708
|
};
|
|
13600
14709
|
__name(_UIPanelSystem, "UIPanelSystem");
|
|
13601
14710
|
var UIPanelSystem = _UIPanelSystem;
|
|
14711
|
+
var eyeScratch = new THREE37__namespace.Vector3();
|
|
14712
|
+
function tagPart(mesh, color, premultiplied = false) {
|
|
14713
|
+
const tag = {
|
|
14714
|
+
baseColor: new THREE37__namespace.Color(color),
|
|
14715
|
+
tint: 1,
|
|
14716
|
+
opacity: 1,
|
|
14717
|
+
premultiplied
|
|
14718
|
+
};
|
|
14719
|
+
mesh.userData[UI_PART_KEY] = tag;
|
|
14720
|
+
}
|
|
14721
|
+
__name(tagPart, "tagPart");
|
|
14722
|
+
function resizePlane(mesh, width, height) {
|
|
14723
|
+
const params = mesh.geometry.parameters;
|
|
14724
|
+
if (params.width === width && params.height === height) return;
|
|
14725
|
+
mesh.geometry.dispose();
|
|
14726
|
+
mesh.geometry = new THREE37__namespace.PlaneGeometry(width, height);
|
|
14727
|
+
}
|
|
14728
|
+
__name(resizePlane, "resizePlane");
|
|
14729
|
+
function layoutBox(widget, bleed, density) {
|
|
14730
|
+
return {
|
|
14731
|
+
x: bleed * density,
|
|
14732
|
+
y: bleed * density,
|
|
14733
|
+
w: widget.width * density,
|
|
14734
|
+
h: widget.height * density
|
|
14735
|
+
};
|
|
14736
|
+
}
|
|
14737
|
+
__name(layoutBox, "layoutBox");
|
|
14738
|
+
function familyOf(font) {
|
|
14739
|
+
return font ? uiFontFamily(font) : null;
|
|
14740
|
+
}
|
|
14741
|
+
__name(familyOf, "familyOf");
|
|
14742
|
+
function imagesLoaded(chrome) {
|
|
14743
|
+
return styleAssets(chrome, null).images.map((src) => !!uiImage(src));
|
|
14744
|
+
}
|
|
14745
|
+
__name(imagesLoaded, "imagesLoaded");
|
|
14746
|
+
function rootRect(id, entry) {
|
|
14747
|
+
const e = entry.root.matrixWorld.elements;
|
|
14748
|
+
const halfW = entry.width / 2;
|
|
14749
|
+
const halfH = entry.height / 2;
|
|
14750
|
+
return {
|
|
14751
|
+
id,
|
|
14752
|
+
center: { x: e[12], y: e[13], z: e[14] },
|
|
14753
|
+
halfX: { x: e[0] * halfW, y: e[1] * halfW, z: e[2] * halfW },
|
|
14754
|
+
halfY: { x: e[4] * halfH, y: e[5] * halfH, z: e[6] * halfH }
|
|
14755
|
+
};
|
|
14756
|
+
}
|
|
14757
|
+
__name(rootRect, "rootRect");
|
|
14758
|
+
function stampDescendants(root, slot, widgetRoots) {
|
|
14759
|
+
for (const child of root.children) {
|
|
14760
|
+
if (widgetRoots.has(child) || child.userData[UI_PART_KEY]) continue;
|
|
14761
|
+
const material = child.material;
|
|
14762
|
+
const transparent = Array.isArray(material) ? material.some((m) => m.transparent) : material?.transparent === true;
|
|
14763
|
+
const untouched = child.renderOrder === 0 || child.userData[PAINT_STAMP_KEY] === child.renderOrder;
|
|
14764
|
+
if (transparent && untouched) {
|
|
14765
|
+
child.renderOrder = slot.descendants;
|
|
14766
|
+
child.userData[PAINT_STAMP_KEY] = slot.descendants;
|
|
14767
|
+
}
|
|
14768
|
+
stampDescendants(child, slot, widgetRoots);
|
|
14769
|
+
}
|
|
14770
|
+
}
|
|
14771
|
+
__name(stampDescendants, "stampDescendants");
|
|
13602
14772
|
var _XRHitTestSystem = class _XRHitTestSystem {
|
|
13603
14773
|
constructor() {
|
|
13604
14774
|
this.sources = /* @__PURE__ */ new Map();
|
|
@@ -13635,12 +14805,12 @@ var _XRHitTestSystem = class _XRHitTestSystem {
|
|
|
13635
14805
|
if (!hits || hits.length === 0) continue;
|
|
13636
14806
|
const pose = hits[0].getPose(referenceSpace);
|
|
13637
14807
|
if (!pose) continue;
|
|
13638
|
-
const matrix = new
|
|
14808
|
+
const matrix = new THREE37__namespace.Matrix4().fromArray(
|
|
13639
14809
|
pose.transform.matrix
|
|
13640
14810
|
);
|
|
13641
|
-
const position = new
|
|
13642
|
-
const quaternion = new
|
|
13643
|
-
matrix.decompose(position, quaternion, new
|
|
14811
|
+
const position = new THREE37__namespace.Vector3();
|
|
14812
|
+
const quaternion = new THREE37__namespace.Quaternion();
|
|
14813
|
+
matrix.decompose(position, quaternion, new THREE37__namespace.Vector3());
|
|
13644
14814
|
this.results.set(key, { position, quaternion });
|
|
13645
14815
|
}
|
|
13646
14816
|
}
|
|
@@ -13714,8 +14884,8 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13714
14884
|
/** Per-anchor head-glue gates — see XREnvironmentSystem's TrackedEntry. */
|
|
13715
14885
|
this.gates = /* @__PURE__ */ new Map();
|
|
13716
14886
|
this.presenting = false;
|
|
13717
|
-
this.tmpViewerMatrix = new
|
|
13718
|
-
this.tmpViewPos = new
|
|
14887
|
+
this.tmpViewerMatrix = new THREE37__namespace.Matrix4();
|
|
14888
|
+
this.tmpViewPos = new THREE37__namespace.Vector3();
|
|
13719
14889
|
}
|
|
13720
14890
|
update(world, deltaTime = 0) {
|
|
13721
14891
|
const presenting = world.isXrPresenting();
|
|
@@ -13789,8 +14959,8 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13789
14959
|
if (typeof frame.createAnchor !== "function") return;
|
|
13790
14960
|
const RigidTransform = globalThis.XRRigidTransform;
|
|
13791
14961
|
if (!RigidTransform) return;
|
|
13792
|
-
const quaternion = new
|
|
13793
|
-
new
|
|
14962
|
+
const quaternion = new THREE37__namespace.Quaternion().setFromEuler(
|
|
14963
|
+
new THREE37__namespace.Euler(
|
|
13794
14964
|
transform.rotation.x,
|
|
13795
14965
|
transform.rotation.y,
|
|
13796
14966
|
transform.rotation.z,
|
|
@@ -13833,13 +15003,13 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13833
15003
|
};
|
|
13834
15004
|
__name(_XRAnchorSystem, "XRAnchorSystem");
|
|
13835
15005
|
var XRAnchorSystem = _XRAnchorSystem;
|
|
13836
|
-
var _q = new
|
|
13837
|
-
var _q2 = new
|
|
13838
|
-
var _s = new
|
|
13839
|
-
var _e = new
|
|
13840
|
-
var _w = new
|
|
13841
|
-
var _v = new
|
|
13842
|
-
var _p = new
|
|
15006
|
+
var _q = new THREE37__namespace.Quaternion();
|
|
15007
|
+
var _q2 = new THREE37__namespace.Quaternion();
|
|
15008
|
+
var _s = new THREE37__namespace.Vector3();
|
|
15009
|
+
var _e = new THREE37__namespace.Vector3();
|
|
15010
|
+
var _w = new THREE37__namespace.Vector3();
|
|
15011
|
+
var _v = new THREE37__namespace.Vector3();
|
|
15012
|
+
var _p = new THREE37__namespace.Vector3();
|
|
13843
15013
|
function setWorldQuaternion(o, q) {
|
|
13844
15014
|
if (o.parent) {
|
|
13845
15015
|
o.parent.getWorldQuaternion(_q2).invert();
|
|
@@ -13864,19 +15034,19 @@ function twoBoneIK(upper, lower, end, target, pole) {
|
|
|
13864
15034
|
if (a < 1e-6 || b < 1e-6) return target.distanceTo(_w);
|
|
13865
15035
|
const toT = _v.subVectors(target, _s);
|
|
13866
15036
|
const want = toT.length();
|
|
13867
|
-
const c =
|
|
15037
|
+
const c = THREE37__namespace.MathUtils.clamp(want, Math.abs(a - b) + 1e-4, a + b - 1e-4);
|
|
13868
15038
|
const dir = toT.divideScalar(want || 1).clone();
|
|
13869
15039
|
const pv = _p.subVectors(pole, _s);
|
|
13870
15040
|
pv.addScaledVector(dir, -pv.dot(dir));
|
|
13871
15041
|
if (pv.lengthSq() < 1e-8) pv.set(0, -1, 0).addScaledVector(dir, dir.y);
|
|
13872
15042
|
pv.normalize();
|
|
13873
|
-
const cosA =
|
|
15043
|
+
const cosA = THREE37__namespace.MathUtils.clamp((a * a + c * c - b * b) / (2 * a * c), -1, 1);
|
|
13874
15044
|
const joint = _s.clone().addScaledVector(dir, a * cosA).addScaledVector(pv, a * Math.sqrt(1 - cosA * cosA));
|
|
13875
|
-
turn(upper, new
|
|
15045
|
+
turn(upper, new THREE37__namespace.Quaternion().setFromUnitVectors(_e.clone().sub(_s).normalize(), joint.clone().sub(_s).normalize()));
|
|
13876
15046
|
lower.getWorldPosition(_e);
|
|
13877
15047
|
end.getWorldPosition(_w);
|
|
13878
15048
|
const reach = _s.clone().addScaledVector(dir, c);
|
|
13879
|
-
turn(lower, new
|
|
15049
|
+
turn(lower, new THREE37__namespace.Quaternion().setFromUnitVectors(_w.clone().sub(_e).normalize(), reach.clone().sub(_e).normalize()));
|
|
13880
15050
|
return want - c;
|
|
13881
15051
|
}
|
|
13882
15052
|
__name(twoBoneIK, "twoBoneIK");
|
|
@@ -13888,18 +15058,20 @@ var LIMB_BONES = {
|
|
|
13888
15058
|
leftFoot: ["leftUpperLeg", "leftLowerLeg", "leftFoot"],
|
|
13889
15059
|
rightFoot: ["rightUpperLeg", "rightLowerLeg", "rightFoot"]
|
|
13890
15060
|
};
|
|
13891
|
-
var _t = new
|
|
13892
|
-
var _p2 = new
|
|
13893
|
-
var _q3 = new
|
|
13894
|
-
var _pq = new
|
|
15061
|
+
var _t = new THREE37__namespace.Vector3();
|
|
15062
|
+
var _p2 = new THREE37__namespace.Vector3();
|
|
15063
|
+
var _q3 = new THREE37__namespace.Quaternion();
|
|
15064
|
+
var _pq = new THREE37__namespace.Quaternion();
|
|
13895
15065
|
var _IKSystem = class _IKSystem {
|
|
13896
15066
|
constructor() {
|
|
13897
15067
|
this.runtimes = /* @__PURE__ */ new Map();
|
|
13898
|
-
this.reach = /* @__PURE__ */ new Map();
|
|
13899
15068
|
}
|
|
13900
|
-
/**
|
|
15069
|
+
/**
|
|
15070
|
+
* How far a limb's end stayed from its target last frame, in metres
|
|
15071
|
+
* (0 = reached), or null if the limb's chain didn't run.
|
|
15072
|
+
*/
|
|
13901
15073
|
getReachError(entityId, limb) {
|
|
13902
|
-
return this.reach.get(
|
|
15074
|
+
return this.runtimes.get(entityId)?.reach.get(limb) ?? null;
|
|
13903
15075
|
}
|
|
13904
15076
|
restore(runtime) {
|
|
13905
15077
|
for (const [bone, w] of runtime.written) {
|
|
@@ -13925,13 +15097,14 @@ var _IKSystem = class _IKSystem {
|
|
|
13925
15097
|
let runtime = this.runtimes.get(id);
|
|
13926
15098
|
if (!runtime || runtime.rootUuid !== root.uuid) {
|
|
13927
15099
|
if (runtime) this.restore(runtime);
|
|
13928
|
-
runtime = { rootUuid: root.uuid, limbs: /* @__PURE__ */ new Map(), written: /* @__PURE__ */ new Map() };
|
|
15100
|
+
runtime = { rootUuid: root.uuid, limbs: /* @__PURE__ */ new Map(), written: /* @__PURE__ */ new Map(), reach: /* @__PURE__ */ new Map() };
|
|
13929
15101
|
this.runtimes.set(id, runtime);
|
|
13930
15102
|
}
|
|
13931
15103
|
for (const [bone, w] of runtime.written) {
|
|
13932
15104
|
if (bone.quaternion.equals(w.written)) bone.quaternion.copy(w.before);
|
|
13933
15105
|
}
|
|
13934
15106
|
runtime.written.clear();
|
|
15107
|
+
runtime.reach.clear();
|
|
13935
15108
|
if (!ik.enabled) continue;
|
|
13936
15109
|
const active = ik.chains.filter((c) => c.enabled && c.weight > 0 && typeof c.target === "number");
|
|
13937
15110
|
if (active.length === 0) continue;
|
|
@@ -13952,7 +15125,7 @@ var _IKSystem = class _IKSystem {
|
|
|
13952
15125
|
const [upper, lower, end] = limb.bones;
|
|
13953
15126
|
for (const bone of [upper, lower, end]) {
|
|
13954
15127
|
if (!runtime.written.has(bone)) {
|
|
13955
|
-
runtime.written.set(bone, { before: bone.quaternion.clone(), written: new
|
|
15128
|
+
runtime.written.set(bone, { before: bone.quaternion.clone(), written: new THREE37__namespace.Quaternion() });
|
|
13956
15129
|
}
|
|
13957
15130
|
}
|
|
13958
15131
|
const animated = [upper.quaternion.clone(), lower.quaternion.clone(), end.quaternion.clone()];
|
|
@@ -13961,7 +15134,7 @@ var _IKSystem = class _IKSystem {
|
|
|
13961
15134
|
if (poleObject) poleObject.getWorldPosition(_p2);
|
|
13962
15135
|
else lower.getWorldPosition(_p2);
|
|
13963
15136
|
const miss = twoBoneIK(upper, lower, end, _t, _p2);
|
|
13964
|
-
|
|
15137
|
+
runtime.reach.set(chain.limb, Math.max(0, miss));
|
|
13965
15138
|
if (chain.matchRotation) {
|
|
13966
15139
|
target.getWorldQuaternion(_q3);
|
|
13967
15140
|
end.parent?.getWorldQuaternion(_pq);
|
|
@@ -13990,9 +15163,9 @@ var IKSystem = _IKSystem;
|
|
|
13990
15163
|
function buildGeometry2(area) {
|
|
13991
15164
|
if (area.shape === "circle") {
|
|
13992
15165
|
const radius = Math.max(5e-3, area.width / 2);
|
|
13993
|
-
return new
|
|
15166
|
+
return new THREE37__namespace.CircleGeometry(radius, 48);
|
|
13994
15167
|
}
|
|
13995
|
-
return new
|
|
15168
|
+
return new THREE37__namespace.PlaneGeometry(
|
|
13996
15169
|
Math.max(0.01, area.width),
|
|
13997
15170
|
Math.max(0.01, area.depth)
|
|
13998
15171
|
);
|
|
@@ -14009,13 +15182,13 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
14009
15182
|
update(world) {
|
|
14010
15183
|
const entityIds = world.query(VRTeleportAreaComponent, Object3DRef);
|
|
14011
15184
|
const alive = new Set(entityIds);
|
|
14012
|
-
for (const
|
|
14013
|
-
if (!alive.has(
|
|
15185
|
+
for (const tracked2 of this.signatures.keys()) {
|
|
15186
|
+
if (!alive.has(tracked2)) this.signatures.delete(tracked2);
|
|
14014
15187
|
}
|
|
14015
15188
|
for (const entityId of entityIds) {
|
|
14016
15189
|
const area = world.getComponent(entityId, VRTeleportAreaComponent);
|
|
14017
15190
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
14018
|
-
if (!area || !(object instanceof
|
|
15191
|
+
if (!area || !(object instanceof THREE37__namespace.Mesh)) continue;
|
|
14019
15192
|
const signature = signatureOf(area);
|
|
14020
15193
|
if (this.signatures.get(entityId) === signature) continue;
|
|
14021
15194
|
this.signatures.set(entityId, signature);
|
|
@@ -14027,18 +15200,18 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
14027
15200
|
__name(_VRTeleportAreaSystem, "VRTeleportAreaSystem");
|
|
14028
15201
|
var VRTeleportAreaSystem = _VRTeleportAreaSystem;
|
|
14029
15202
|
function createHandMaterial(preset, options) {
|
|
14030
|
-
const color = new
|
|
15203
|
+
const color = new THREE37__namespace.Color(options.color);
|
|
14031
15204
|
switch (preset) {
|
|
14032
15205
|
case "ghost":
|
|
14033
|
-
return new
|
|
15206
|
+
return new THREE37__namespace.MeshBasicMaterial({
|
|
14034
15207
|
color,
|
|
14035
15208
|
transparent: true,
|
|
14036
15209
|
opacity: Math.min(1, Math.max(0.05, options.opacity * 0.45)),
|
|
14037
15210
|
depthWrite: false,
|
|
14038
|
-
side:
|
|
15211
|
+
side: THREE37__namespace.DoubleSide
|
|
14039
15212
|
});
|
|
14040
15213
|
case "neon":
|
|
14041
|
-
return new
|
|
15214
|
+
return new THREE37__namespace.MeshStandardMaterial({
|
|
14042
15215
|
color,
|
|
14043
15216
|
emissive: color,
|
|
14044
15217
|
emissiveIntensity: Math.max(0.5, options.emissiveIntensity || 2),
|
|
@@ -14048,7 +15221,7 @@ function createHandMaterial(preset, options) {
|
|
|
14048
15221
|
opacity: options.opacity
|
|
14049
15222
|
});
|
|
14050
15223
|
case "skeleton":
|
|
14051
|
-
return new
|
|
15224
|
+
return new THREE37__namespace.MeshBasicMaterial({
|
|
14052
15225
|
color,
|
|
14053
15226
|
wireframe: true,
|
|
14054
15227
|
transparent: true,
|
|
@@ -14056,7 +15229,7 @@ function createHandMaterial(preset, options) {
|
|
|
14056
15229
|
});
|
|
14057
15230
|
case "custom":
|
|
14058
15231
|
case "default":
|
|
14059
|
-
return new
|
|
15232
|
+
return new THREE37__namespace.MeshStandardMaterial({
|
|
14060
15233
|
color,
|
|
14061
15234
|
roughness: 0.85,
|
|
14062
15235
|
metalness: 0,
|
|
@@ -14064,10 +15237,10 @@ function createHandMaterial(preset, options) {
|
|
|
14064
15237
|
emissiveIntensity: Math.max(0, options.emissiveIntensity),
|
|
14065
15238
|
transparent: options.opacity < 1,
|
|
14066
15239
|
opacity: options.opacity,
|
|
14067
|
-
side:
|
|
15240
|
+
side: THREE37__namespace.DoubleSide
|
|
14068
15241
|
});
|
|
14069
15242
|
default: {
|
|
14070
|
-
return new
|
|
15243
|
+
return new THREE37__namespace.MeshStandardMaterial({ color });
|
|
14071
15244
|
}
|
|
14072
15245
|
}
|
|
14073
15246
|
}
|
|
@@ -14092,9 +15265,9 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
14092
15265
|
constructor(options) {
|
|
14093
15266
|
this.controllerModelFactory = new XRControllerModelFactory_js.XRControllerModelFactory();
|
|
14094
15267
|
this.handModelFactory = new XRHandModelFactory_js.XRHandModelFactory();
|
|
14095
|
-
this.group = new
|
|
15268
|
+
this.group = new THREE37__namespace.Group();
|
|
14096
15269
|
/** Reused so a per-frame colour compare allocates nothing. */
|
|
14097
|
-
this.rayColorScratch = new
|
|
15270
|
+
this.rayColorScratch = new THREE37__namespace.Color();
|
|
14098
15271
|
this.slots = /* @__PURE__ */ new Map();
|
|
14099
15272
|
this.attachedTo = null;
|
|
14100
15273
|
/** Last applied preset signature, so materials rebuild only on real change. */
|
|
@@ -14231,8 +15404,8 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
14231
15404
|
*/
|
|
14232
15405
|
fitRayToHover(ray, side) {
|
|
14233
15406
|
const hover = this.interactionSystem?.getHoverFor(side) ?? null;
|
|
14234
|
-
const
|
|
14235
|
-
ray.scale.z =
|
|
15407
|
+
const length2 = hover && Number.isFinite(hover.distance) && hover.distance > 0 ? Math.min(hover.distance, RAY_LENGTH) : RAY_LENGTH;
|
|
15408
|
+
ray.scale.z = length2;
|
|
14236
15409
|
}
|
|
14237
15410
|
/** Lazily build per-slot visuals; the device reports profiles late. */
|
|
14238
15411
|
ensureSlots(world) {
|
|
@@ -14281,17 +15454,17 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
14281
15454
|
* without pulling in a line-rendering extension.
|
|
14282
15455
|
*/
|
|
14283
15456
|
createRay() {
|
|
14284
|
-
const geometry = new
|
|
15457
|
+
const geometry = new THREE37__namespace.CylinderGeometry(RAY_RADIUS, RAY_RADIUS, 1, 8, 1);
|
|
14285
15458
|
geometry.rotateX(-Math.PI / 2);
|
|
14286
15459
|
geometry.translate(0, 0, -0.5);
|
|
14287
|
-
const material = new
|
|
15460
|
+
const material = new THREE37__namespace.MeshBasicMaterial({
|
|
14288
15461
|
color: "#4da3ff",
|
|
14289
15462
|
transparent: true,
|
|
14290
15463
|
opacity: 0.75,
|
|
14291
15464
|
depthTest: false,
|
|
14292
15465
|
depthWrite: false
|
|
14293
15466
|
});
|
|
14294
|
-
const mesh = new
|
|
15467
|
+
const mesh = new THREE37__namespace.Mesh(geometry, material);
|
|
14295
15468
|
mesh.name = "XRPointerRay";
|
|
14296
15469
|
mesh.renderOrder = 999;
|
|
14297
15470
|
mesh.visible = false;
|
|
@@ -14322,14 +15495,14 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
14322
15495
|
__name(_XRControllerVisualSystem, "XRControllerVisualSystem");
|
|
14323
15496
|
var XRControllerVisualSystem = _XRControllerVisualSystem;
|
|
14324
15497
|
var MARKER_RADIUS = 0.28;
|
|
14325
|
-
var ACCENT = new
|
|
14326
|
-
var SEGMENT_AXIS = new
|
|
15498
|
+
var ACCENT = new THREE37__namespace.Color("#4da3ff");
|
|
15499
|
+
var SEGMENT_AXIS = new THREE37__namespace.Vector3(0, 1, 0);
|
|
14327
15500
|
var HEAD_CLEARANCE = 0.25;
|
|
14328
15501
|
var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
14329
15502
|
constructor(locomotionSystem) {
|
|
14330
|
-
this.group = new
|
|
15503
|
+
this.group = new THREE37__namespace.Group();
|
|
14331
15504
|
/** Holds the segment chain that draws the arc. */
|
|
14332
|
-
this.arc = new
|
|
15505
|
+
this.arc = new THREE37__namespace.Group();
|
|
14333
15506
|
/**
|
|
14334
15507
|
* Unit cylinder along +Y, reused by every segment.
|
|
14335
15508
|
*
|
|
@@ -14338,14 +15511,14 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14338
15511
|
* scaled cylinders gives real thickness while rebuilding no geometry: each
|
|
14339
15512
|
* frame only moves, rotates and scales meshes that already exist.
|
|
14340
15513
|
*/
|
|
14341
|
-
this.segmentGeometry = new
|
|
15514
|
+
this.segmentGeometry = new THREE37__namespace.CylinderGeometry(1, 1, 1, 6, 1);
|
|
14342
15515
|
this.segments = [];
|
|
14343
|
-
this.marker = new
|
|
15516
|
+
this.marker = new THREE37__namespace.Group();
|
|
14344
15517
|
this.attached = false;
|
|
14345
|
-
this.scratchDirection = new
|
|
14346
|
-
this.scratchHead = new
|
|
14347
|
-
this.validColor = new
|
|
14348
|
-
this.invalidColor = new
|
|
15518
|
+
this.scratchDirection = new THREE37__namespace.Vector3();
|
|
15519
|
+
this.scratchHead = new THREE37__namespace.Vector3();
|
|
15520
|
+
this.validColor = new THREE37__namespace.Color();
|
|
15521
|
+
this.invalidColor = new THREE37__namespace.Color();
|
|
14349
15522
|
this.locomotionSystem = locomotionSystem;
|
|
14350
15523
|
this.group.name = "XRTeleportVisuals";
|
|
14351
15524
|
this.group.userData.ecsPreviewHidden = true;
|
|
@@ -14403,8 +15576,8 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14403
15576
|
const from = curve[i];
|
|
14404
15577
|
const to = curve[i + 1];
|
|
14405
15578
|
this.scratchDirection.subVectors(to, from);
|
|
14406
|
-
const
|
|
14407
|
-
if (
|
|
15579
|
+
const length2 = this.scratchDirection.length();
|
|
15580
|
+
if (length2 < 1e-6) {
|
|
14408
15581
|
segment.visible = false;
|
|
14409
15582
|
continue;
|
|
14410
15583
|
}
|
|
@@ -14412,9 +15585,9 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14412
15585
|
segment.position.copy(from).addScaledVector(this.scratchDirection, 0.5);
|
|
14413
15586
|
segment.quaternion.setFromUnitVectors(
|
|
14414
15587
|
SEGMENT_AXIS,
|
|
14415
|
-
this.scratchDirection.divideScalar(
|
|
15588
|
+
this.scratchDirection.divideScalar(length2)
|
|
14416
15589
|
);
|
|
14417
|
-
segment.scale.set(radius,
|
|
15590
|
+
segment.scale.set(radius, length2, radius);
|
|
14418
15591
|
const t = needed > 1 ? i / (needed - 1) : 0;
|
|
14419
15592
|
const fade = 1 - t * 0.75;
|
|
14420
15593
|
segment.material.color.copy(tint).multiplyScalar(fade);
|
|
@@ -14423,12 +15596,12 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14423
15596
|
/** Grow the segment pool to cover the current arc. */
|
|
14424
15597
|
ensureSegments(count) {
|
|
14425
15598
|
while (this.segments.length < count) {
|
|
14426
|
-
const material = new
|
|
15599
|
+
const material = new THREE37__namespace.MeshBasicMaterial({
|
|
14427
15600
|
transparent: true,
|
|
14428
15601
|
depthTest: false,
|
|
14429
15602
|
depthWrite: false
|
|
14430
15603
|
});
|
|
14431
|
-
const mesh = new
|
|
15604
|
+
const mesh = new THREE37__namespace.Mesh(this.segmentGeometry, material);
|
|
14432
15605
|
mesh.frustumCulled = false;
|
|
14433
15606
|
mesh.renderOrder = 998;
|
|
14434
15607
|
mesh.raycast = () => {
|
|
@@ -14452,33 +15625,33 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14452
15625
|
return world.getComponent(entityId, XRRigComponent) ?? null;
|
|
14453
15626
|
}
|
|
14454
15627
|
createRing() {
|
|
14455
|
-
const geometry = new
|
|
15628
|
+
const geometry = new THREE37__namespace.RingGeometry(
|
|
14456
15629
|
MARKER_RADIUS * 0.72,
|
|
14457
15630
|
MARKER_RADIUS,
|
|
14458
15631
|
48
|
|
14459
15632
|
);
|
|
14460
15633
|
geometry.rotateX(-Math.PI / 2);
|
|
14461
|
-
return new
|
|
15634
|
+
return new THREE37__namespace.Mesh(
|
|
14462
15635
|
geometry,
|
|
14463
|
-
new
|
|
15636
|
+
new THREE37__namespace.MeshBasicMaterial({
|
|
14464
15637
|
color: ACCENT,
|
|
14465
15638
|
transparent: true,
|
|
14466
15639
|
opacity: 0.9,
|
|
14467
|
-
side:
|
|
15640
|
+
side: THREE37__namespace.DoubleSide,
|
|
14468
15641
|
depthTest: false
|
|
14469
15642
|
})
|
|
14470
15643
|
);
|
|
14471
15644
|
}
|
|
14472
15645
|
createDot() {
|
|
14473
|
-
const geometry = new
|
|
15646
|
+
const geometry = new THREE37__namespace.CircleGeometry(MARKER_RADIUS * 0.16, 24);
|
|
14474
15647
|
geometry.rotateX(-Math.PI / 2);
|
|
14475
|
-
return new
|
|
15648
|
+
return new THREE37__namespace.Mesh(
|
|
14476
15649
|
geometry,
|
|
14477
|
-
new
|
|
15650
|
+
new THREE37__namespace.MeshBasicMaterial({
|
|
14478
15651
|
color: ACCENT,
|
|
14479
15652
|
transparent: true,
|
|
14480
15653
|
opacity: 0.55,
|
|
14481
|
-
side:
|
|
15654
|
+
side: THREE37__namespace.DoubleSide,
|
|
14482
15655
|
depthTest: false
|
|
14483
15656
|
})
|
|
14484
15657
|
);
|
|
@@ -14589,7 +15762,7 @@ function boneDirections(joints, finger) {
|
|
|
14589
15762
|
const from = joints[chain[i - 1]];
|
|
14590
15763
|
const to = joints[chain[i]];
|
|
14591
15764
|
if (!from || !to) return null;
|
|
14592
|
-
const direction = new
|
|
15765
|
+
const direction = new THREE37__namespace.Vector3().subVectors(to, from);
|
|
14593
15766
|
if (direction.lengthSq() < 1e-12) return null;
|
|
14594
15767
|
directions.push(direction.normalize());
|
|
14595
15768
|
}
|
|
@@ -14662,8 +15835,8 @@ function computeSpread(joints, a, b) {
|
|
|
14662
15835
|
const bBase = joints[METACARPAL_JOINTS[b]];
|
|
14663
15836
|
const bTip = joints[TIP_JOINTS[b]];
|
|
14664
15837
|
if (!aBase || !aTip || !bBase || !bTip) return null;
|
|
14665
|
-
const dirA = new
|
|
14666
|
-
const dirB = new
|
|
15838
|
+
const dirA = new THREE37__namespace.Vector3().subVectors(aTip, aBase);
|
|
15839
|
+
const dirB = new THREE37__namespace.Vector3().subVectors(bTip, bBase);
|
|
14667
15840
|
if (dirA.lengthSq() < 1e-12 || dirB.lengthSq() < 1e-12) return null;
|
|
14668
15841
|
return clamp01((1 - dirA.normalize().dot(dirB.normalize())) / 0.45);
|
|
14669
15842
|
}
|
|
@@ -14673,18 +15846,18 @@ function computePalmPose(joints, handedness) {
|
|
|
14673
15846
|
const indexBase = joints["index-finger-metacarpal"];
|
|
14674
15847
|
const pinkyBase = joints["pinky-finger-metacarpal"];
|
|
14675
15848
|
if (!wrist || !indexBase || !pinkyBase) return null;
|
|
14676
|
-
const u = new
|
|
14677
|
-
const v = new
|
|
14678
|
-
const normal = new
|
|
15849
|
+
const u = new THREE37__namespace.Vector3().subVectors(indexBase, wrist);
|
|
15850
|
+
const v = new THREE37__namespace.Vector3().subVectors(pinkyBase, wrist);
|
|
15851
|
+
const normal = new THREE37__namespace.Vector3().crossVectors(u, v);
|
|
14679
15852
|
if (normal.lengthSq() < 1e-12) return null;
|
|
14680
15853
|
normal.normalize();
|
|
14681
15854
|
if (handedness === "left") normal.multiplyScalar(-1);
|
|
14682
|
-
const right = new
|
|
15855
|
+
const right = new THREE37__namespace.Vector3().subVectors(indexBase, pinkyBase);
|
|
14683
15856
|
if (right.lengthSq() < 1e-12) return null;
|
|
14684
15857
|
right.normalize();
|
|
14685
15858
|
if (handedness === "left") right.multiplyScalar(-1);
|
|
14686
|
-
const up = new
|
|
14687
|
-
const center = new
|
|
15859
|
+
const up = new THREE37__namespace.Vector3().crossVectors(normal, right).normalize();
|
|
15860
|
+
const center = new THREE37__namespace.Vector3().add(wrist).add(indexBase).add(pinkyBase).divideScalar(3);
|
|
14688
15861
|
return {
|
|
14689
15862
|
center,
|
|
14690
15863
|
normal,
|
|
@@ -14696,17 +15869,17 @@ function computePalmPose(joints, handedness) {
|
|
|
14696
15869
|
__name(computePalmPose, "computePalmPose");
|
|
14697
15870
|
function computeHandShape(joints, handedness) {
|
|
14698
15871
|
const fingers2 = {};
|
|
14699
|
-
let
|
|
15872
|
+
let tracked2 = 0;
|
|
14700
15873
|
for (const finger of XR_FINGERS) {
|
|
14701
15874
|
const curl = computeFingerCurl(joints, finger);
|
|
14702
15875
|
if (curl) {
|
|
14703
15876
|
fingers2[finger] = curl;
|
|
14704
|
-
|
|
15877
|
+
tracked2 += 1;
|
|
14705
15878
|
} else {
|
|
14706
15879
|
fingers2[finger] = { baseCurl: 0, tipCurl: 0, curl: 0 };
|
|
14707
15880
|
}
|
|
14708
15881
|
}
|
|
14709
|
-
if (
|
|
15882
|
+
if (tracked2 === 0) return null;
|
|
14710
15883
|
const pinch = {};
|
|
14711
15884
|
for (const finger of PINCH_FINGERS) {
|
|
14712
15885
|
pinch[finger] = computePinch(joints, finger) ?? 0;
|
|
@@ -14715,7 +15888,7 @@ function computeHandShape(joints, handedness) {
|
|
|
14715
15888
|
const thumbTip = joints["thumb-tip"];
|
|
14716
15889
|
let thumbDirection = null;
|
|
14717
15890
|
if (thumbBase && thumbTip) {
|
|
14718
|
-
const direction = new
|
|
15891
|
+
const direction = new THREE37__namespace.Vector3().subVectors(thumbTip, thumbBase);
|
|
14719
15892
|
if (direction.lengthSq() > 1e-12) thumbDirection = direction.normalize();
|
|
14720
15893
|
}
|
|
14721
15894
|
const fingerDirections = {};
|
|
@@ -14726,7 +15899,7 @@ function computeHandShape(joints, handedness) {
|
|
|
14726
15899
|
fingerDirections[finger] = null;
|
|
14727
15900
|
continue;
|
|
14728
15901
|
}
|
|
14729
|
-
const direction = new
|
|
15902
|
+
const direction = new THREE37__namespace.Vector3().subVectors(tip, base);
|
|
14730
15903
|
fingerDirections[finger] = direction.lengthSq() > 1e-12 ? direction.normalize() : null;
|
|
14731
15904
|
}
|
|
14732
15905
|
return {
|
|
@@ -14760,12 +15933,12 @@ function scoreAgainst(actual, target, tolerance) {
|
|
|
14760
15933
|
__name(scoreAgainst, "scoreAgainst");
|
|
14761
15934
|
var DEFAULT_DIRECTION_TOLERANCE = 45;
|
|
14762
15935
|
var WORLD_DIRECTIONS = {
|
|
14763
|
-
up: new
|
|
14764
|
-
down: new
|
|
14765
|
-
forward: new
|
|
14766
|
-
back: new
|
|
14767
|
-
left: new
|
|
14768
|
-
right: new
|
|
15936
|
+
up: new THREE37__namespace.Vector3(0, 1, 0),
|
|
15937
|
+
down: new THREE37__namespace.Vector3(0, -1, 0),
|
|
15938
|
+
forward: new THREE37__namespace.Vector3(0, 0, -1),
|
|
15939
|
+
back: new THREE37__namespace.Vector3(0, 0, 1),
|
|
15940
|
+
left: new THREE37__namespace.Vector3(-1, 0, 0),
|
|
15941
|
+
right: new THREE37__namespace.Vector3(1, 0, 0)
|
|
14769
15942
|
};
|
|
14770
15943
|
function axisVector(shape, axis) {
|
|
14771
15944
|
if (axis === "thumb") return shape.thumbDirection;
|
|
@@ -14780,7 +15953,7 @@ function resolveDirection(direction, shape, context) {
|
|
|
14780
15953
|
const head = context?.headPosition;
|
|
14781
15954
|
const origin = shape.palm?.center;
|
|
14782
15955
|
if (!head || !origin) return null;
|
|
14783
|
-
const toHead = new
|
|
15956
|
+
const toHead = new THREE37__namespace.Vector3().subVectors(head, origin);
|
|
14784
15957
|
if (toHead.lengthSq() < 1e-12) return null;
|
|
14785
15958
|
toHead.normalize();
|
|
14786
15959
|
return direction === "toward-head" ? toHead : toHead.multiplyScalar(-1);
|
|
@@ -14792,8 +15965,8 @@ function scoreDirections(actual, accepted, shape, toleranceDegrees, context) {
|
|
|
14792
15965
|
for (const direction of accepted) {
|
|
14793
15966
|
const wanted = resolveDirection(direction, shape, context);
|
|
14794
15967
|
if (!wanted) continue;
|
|
14795
|
-
const angle =
|
|
14796
|
-
Math.acos(
|
|
15968
|
+
const angle = THREE37__namespace.MathUtils.radToDeg(
|
|
15969
|
+
Math.acos(THREE37__namespace.MathUtils.clamp(actual.dot(wanted), -1, 1))
|
|
14797
15970
|
);
|
|
14798
15971
|
const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
|
|
14799
15972
|
const score = clamp01(1 - normalizedError / MATCH_FALLOFF);
|
|
@@ -14858,8 +16031,8 @@ function matchHandPose(shape, definition, context) {
|
|
|
14858
16031
|
if (!handAxis || !wanted) {
|
|
14859
16032
|
consider(0, "orientation");
|
|
14860
16033
|
} else {
|
|
14861
|
-
const angle =
|
|
14862
|
-
Math.acos(
|
|
16034
|
+
const angle = THREE37__namespace.MathUtils.radToDeg(
|
|
16035
|
+
Math.acos(THREE37__namespace.MathUtils.clamp(handAxis.dot(wanted), -1, 1))
|
|
14863
16036
|
);
|
|
14864
16037
|
const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
|
|
14865
16038
|
consider(clamp01(1 - normalizedError / MATCH_FALLOFF), "orientation");
|
|
@@ -14937,7 +16110,7 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
14937
16110
|
this.trackers = /* @__PURE__ */ new Map();
|
|
14938
16111
|
this.shapes = /* @__PURE__ */ new Map();
|
|
14939
16112
|
/** Reused so head-relative orientation checks allocate nothing per frame. */
|
|
14940
|
-
this.headPosition = new
|
|
16113
|
+
this.headPosition = new THREE37__namespace.Vector3();
|
|
14941
16114
|
this.elapsed = 0;
|
|
14942
16115
|
this.warnedNoHands = false;
|
|
14943
16116
|
this.noHandSeconds = 0;
|
|
@@ -14953,8 +16126,8 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
14953
16126
|
const entries = this.collectEntries(world);
|
|
14954
16127
|
if (entries.length === 0) return;
|
|
14955
16128
|
if (!this.warnedNoHands) {
|
|
14956
|
-
const
|
|
14957
|
-
if (
|
|
16129
|
+
const tracked2 = this.shapes.get("left") !== null || this.shapes.get("right") !== null;
|
|
16130
|
+
if (tracked2) {
|
|
14958
16131
|
this.warnedNoHands = true;
|
|
14959
16132
|
} else {
|
|
14960
16133
|
this.noHandSeconds += deltaTime;
|
|
@@ -15100,6 +16273,7 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
15100
16273
|
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
15101
16274
|
if (!interactable?.enabled) continue;
|
|
15102
16275
|
if (interactable.hoverBehavior === "none") continue;
|
|
16276
|
+
if (isUiWidget(world, entityId)) continue;
|
|
15103
16277
|
this.begin(world, entityId, interactable);
|
|
15104
16278
|
}
|
|
15105
16279
|
for (const [entityId, record] of this.records) {
|
|
@@ -15120,7 +16294,7 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
15120
16294
|
const wantsColor = interactable.hoverBehavior === "color" || interactable.hoverBehavior === "both";
|
|
15121
16295
|
this.records.set(entityId, {
|
|
15122
16296
|
shell: wantsColor ? this.addShell(world, entityId, interactable) : null,
|
|
15123
|
-
baseScale: new
|
|
16297
|
+
baseScale: new THREE37__namespace.Vector3(
|
|
15124
16298
|
transform.scale.x,
|
|
15125
16299
|
transform.scale.y,
|
|
15126
16300
|
transform.scale.z
|
|
@@ -15133,27 +16307,27 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
15133
16307
|
addShell(world, entityId, interactable) {
|
|
15134
16308
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
15135
16309
|
if (!object) return null;
|
|
15136
|
-
const material = new
|
|
15137
|
-
color: new
|
|
16310
|
+
const material = new THREE37__namespace.MeshBasicMaterial({
|
|
16311
|
+
color: new THREE37__namespace.Color(interactable.hoverColor),
|
|
15138
16312
|
// Back faces only, so the shell shows just outside the silhouette instead
|
|
15139
16313
|
// of covering the object.
|
|
15140
|
-
side:
|
|
16314
|
+
side: THREE37__namespace.BackSide,
|
|
15141
16315
|
transparent: true,
|
|
15142
16316
|
opacity: 0.85,
|
|
15143
16317
|
depthWrite: false
|
|
15144
16318
|
});
|
|
15145
|
-
const group = new
|
|
16319
|
+
const group = new THREE37__namespace.Group();
|
|
15146
16320
|
group.name = "XRHoverShell";
|
|
15147
16321
|
group.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
15148
16322
|
group.renderOrder = 998;
|
|
15149
16323
|
object.traverse((child) => {
|
|
15150
|
-
if (!(child instanceof
|
|
16324
|
+
if (!(child instanceof THREE37__namespace.Mesh) || !child.geometry) return;
|
|
15151
16325
|
if (child.userData[XR_HOVER_SHELL_FLAG]) return;
|
|
15152
|
-
const clone = new
|
|
16326
|
+
const clone = new THREE37__namespace.Mesh(child.geometry, material);
|
|
15153
16327
|
child.updateWorldMatrix(true, false);
|
|
15154
16328
|
object.updateWorldMatrix(true, false);
|
|
15155
16329
|
clone.matrixAutoUpdate = false;
|
|
15156
|
-
clone.matrix.copy(object.matrixWorld).invert().multiply(child.matrixWorld).scale(new
|
|
16330
|
+
clone.matrix.copy(object.matrixWorld).invert().multiply(child.matrixWorld).scale(new THREE37__namespace.Vector3(SHELL_INFLATE, SHELL_INFLATE, SHELL_INFLATE));
|
|
15157
16331
|
clone.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
15158
16332
|
clone.raycast = () => {
|
|
15159
16333
|
};
|
|
@@ -15202,7 +16376,7 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
15202
16376
|
if (!shell) return;
|
|
15203
16377
|
shell.parent?.remove(shell);
|
|
15204
16378
|
shell.traverse((child) => {
|
|
15205
|
-
if (child instanceof
|
|
16379
|
+
if (child instanceof THREE37__namespace.Mesh) {
|
|
15206
16380
|
const material = child.material;
|
|
15207
16381
|
if (Array.isArray(material)) {
|
|
15208
16382
|
for (const entry of material) entry.dispose();
|