@relu-interactives/spatial-ecs 0.8.0 → 0.9.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/{XRHandPose-G0Dl-F0w.d.ts → XRHandPose-CWSrsnYN.d.ts} +144 -1
- package/dist/{XRHandPose-VQMT1WXj.d.cts → XRHandPose-Dn2yiALk.d.cts} +144 -1
- 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-VYIWOXAY.js} +1377 -480
- package/dist/chunk-VYIWOXAY.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 +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +1 -1
- 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 +1 -1
- package/dist/factories/index.d.ts +1 -1
- package/dist/factories/index.js +3 -3
- package/dist/{index-D9DjrUn3.d.cts → index-CAZHrh0q.d.cts} +5 -2
- package/dist/{index-DppafVu4.d.ts → index-CLtSMf2M.d.ts} +5 -2
- package/dist/{index-C61n65PE.d.ts → index-D5MmJNyj.d.ts} +26 -1
- package/dist/{index-C70N4BYG.d.cts → index-DiIjV2lm.d.cts} +26 -1
- package/dist/index.cjs +1787 -621
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +10 -10
- package/dist/network/index.cjs +177 -4
- package/dist/network/index.cjs.map +1 -1
- package/dist/network/index.js +3 -3
- package/dist/systems/index.cjs +1689 -523
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +1 -1
- package/dist/systems/index.d.ts +1 -1
- package/dist/systems/index.js +4 -4
- 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,96 @@ 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
|
+
image.src = URL.createObjectURL(typed);
|
|
13440
|
+
await image.decode();
|
|
13441
|
+
return image;
|
|
13442
|
+
})()
|
|
13443
|
+
).then((image) => {
|
|
13444
|
+
entry.value = image;
|
|
13445
|
+
}).catch((error) => {
|
|
13446
|
+
console.warn(`[spatial-ecs] Couldn't load UI image ${src}.`, error);
|
|
13447
|
+
}).finally(() => {
|
|
13448
|
+
entry.settled = true;
|
|
13449
|
+
});
|
|
13450
|
+
return null;
|
|
13451
|
+
}
|
|
13452
|
+
__name(uiImage, "uiImage");
|
|
13004
13453
|
|
|
13005
13454
|
// core/ui/uiCanvas.ts
|
|
13006
13455
|
var DEFAULT_PIXELS_PER_METER = 1024;
|
|
@@ -13073,18 +13522,21 @@ function clampLines(measure, lines, maxLines, maxWidthPx) {
|
|
|
13073
13522
|
}
|
|
13074
13523
|
__name(clampLines, "clampLines");
|
|
13075
13524
|
var UI_FONT_STACK = '-apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
|
|
13076
|
-
|
|
13077
|
-
|
|
13525
|
+
var NO_ASSETS = { image: /* @__PURE__ */ __name(() => null, "image") };
|
|
13526
|
+
function tracePath(ctx, x, y, w, h, radii) {
|
|
13527
|
+
const limit = Math.min(w / 2, h / 2);
|
|
13528
|
+
const fit = /* @__PURE__ */ __name((r) => Math.max(0, Math.min(r, limit)), "fit");
|
|
13529
|
+
const [tl, tr, br, bl] = (Array.isArray(radii) ? radii : [radii, radii, radii, radii]).map(fit);
|
|
13078
13530
|
ctx.beginPath();
|
|
13079
13531
|
if (typeof ctx.roundRect === "function") {
|
|
13080
|
-
ctx.roundRect(x, y, w, h,
|
|
13532
|
+
ctx.roundRect(x, y, w, h, [tl, tr, br, bl]);
|
|
13081
13533
|
return;
|
|
13082
13534
|
}
|
|
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,
|
|
13535
|
+
ctx.moveTo(x + tl, y);
|
|
13536
|
+
ctx.arcTo(x + w, y, x + w, y + h, tr);
|
|
13537
|
+
ctx.arcTo(x + w, y + h, x, y + h, br);
|
|
13538
|
+
ctx.arcTo(x, y + h, x, y, bl);
|
|
13539
|
+
ctx.arcTo(x, y, x + w, y, tl);
|
|
13088
13540
|
ctx.closePath();
|
|
13089
13541
|
}
|
|
13090
13542
|
__name(tracePath, "tracePath");
|
|
@@ -13104,108 +13556,244 @@ function withOpacity(ctx, color, opacity) {
|
|
|
13104
13556
|
return parsed;
|
|
13105
13557
|
}
|
|
13106
13558
|
__name(withOpacity, "withOpacity");
|
|
13107
|
-
function
|
|
13108
|
-
|
|
13109
|
-
const
|
|
13110
|
-
const
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
|
|
13116
|
-
|
|
13559
|
+
function fillStyleFor(ctx, paint, box, opacity) {
|
|
13560
|
+
if (paint.kind === "solid") return withOpacity(ctx, paint.color, opacity);
|
|
13561
|
+
const cx = box.x + box.w / 2;
|
|
13562
|
+
const cy = box.y + box.h / 2;
|
|
13563
|
+
let gradient;
|
|
13564
|
+
if (paint.kind === "linear") {
|
|
13565
|
+
const radians = paint.angle * Math.PI / 180;
|
|
13566
|
+
const dx = Math.sin(radians);
|
|
13567
|
+
const dy = -Math.cos(radians);
|
|
13568
|
+
const half = (Math.abs(box.w * dx) + Math.abs(box.h * dy)) / 2;
|
|
13569
|
+
gradient = ctx.createLinearGradient(
|
|
13570
|
+
cx - dx * half,
|
|
13571
|
+
cy - dy * half,
|
|
13572
|
+
cx + dx * half,
|
|
13573
|
+
cy + dy * half
|
|
13574
|
+
);
|
|
13575
|
+
} else {
|
|
13576
|
+
gradient = ctx.createRadialGradient(
|
|
13577
|
+
cx,
|
|
13578
|
+
cy,
|
|
13579
|
+
0,
|
|
13580
|
+
cx,
|
|
13581
|
+
cy,
|
|
13582
|
+
Math.max(box.w, box.h) / 2
|
|
13583
|
+
);
|
|
13584
|
+
}
|
|
13585
|
+
for (const stop of paint.stops) {
|
|
13586
|
+
gradient.addColorStop(stop.at, withOpacity(ctx, stop.color, opacity));
|
|
13587
|
+
}
|
|
13588
|
+
return gradient;
|
|
13589
|
+
}
|
|
13590
|
+
__name(fillStyleFor, "fillStyleFor");
|
|
13591
|
+
function drawImagePaint(ctx, paint, box, assets) {
|
|
13592
|
+
const image = assets.image(paint.src);
|
|
13593
|
+
if (!image) return;
|
|
13594
|
+
const sourceW = image.naturalWidth || box.w;
|
|
13595
|
+
const sourceH = image.naturalHeight || box.h;
|
|
13596
|
+
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);
|
|
13597
|
+
const w = paint.fit === "fill" ? box.w : sourceW * scale;
|
|
13598
|
+
const h = paint.fit === "fill" ? box.h : sourceH * scale;
|
|
13599
|
+
const x = box.x + (box.w - w) / 2;
|
|
13600
|
+
const y = box.y + (box.h - h) / 2;
|
|
13601
|
+
if (!paint.tint) {
|
|
13602
|
+
ctx.drawImage(image, x, y, w, h);
|
|
13603
|
+
return;
|
|
13604
|
+
}
|
|
13605
|
+
const scratch = assets.scratch?.(Math.ceil(w), Math.ceil(h));
|
|
13606
|
+
if (!scratch) {
|
|
13607
|
+
ctx.drawImage(image, x, y, w, h);
|
|
13608
|
+
return;
|
|
13609
|
+
}
|
|
13610
|
+
scratch.drawImage(image, 0, 0, w, h);
|
|
13611
|
+
scratch.globalCompositeOperation = "source-in";
|
|
13612
|
+
scratch.fillStyle = paint.tint;
|
|
13613
|
+
scratch.fillRect(0, 0, w, h);
|
|
13614
|
+
ctx.drawImage(scratch.canvas, x, y, w, h);
|
|
13615
|
+
}
|
|
13616
|
+
__name(drawImagePaint, "drawImagePaint");
|
|
13617
|
+
function pxRadii(radius, density) {
|
|
13618
|
+
return radius.map((r) => r * density);
|
|
13619
|
+
}
|
|
13620
|
+
__name(pxRadii, "pxRadii");
|
|
13621
|
+
function drawBoxShadow(ctx, box, radii, shadow, density) {
|
|
13622
|
+
ctx.save();
|
|
13623
|
+
ctx.shadowColor = shadow.color;
|
|
13624
|
+
ctx.shadowBlur = shadow.blur * density;
|
|
13625
|
+
ctx.shadowOffsetX = shadow.x * density;
|
|
13626
|
+
ctx.shadowOffsetY = -shadow.y * density;
|
|
13627
|
+
ctx.fillStyle = "#000000";
|
|
13628
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13629
|
+
ctx.fill();
|
|
13630
|
+
ctx.restore();
|
|
13631
|
+
ctx.save();
|
|
13632
|
+
ctx.globalCompositeOperation = "destination-out";
|
|
13633
|
+
ctx.fillStyle = "#000000";
|
|
13634
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13117
13635
|
ctx.fill();
|
|
13118
|
-
|
|
13636
|
+
ctx.restore();
|
|
13637
|
+
}
|
|
13638
|
+
__name(drawBoxShadow, "drawBoxShadow");
|
|
13639
|
+
function drawChrome(ctx, box, density, chrome, assets = NO_ASSETS) {
|
|
13640
|
+
const radii = pxRadii(chrome.radius, density);
|
|
13641
|
+
for (const shadow of chrome.shadows) {
|
|
13642
|
+
drawBoxShadow(ctx, box, radii, shadow, density);
|
|
13643
|
+
}
|
|
13644
|
+
const opacity = Math.max(0, Math.min(1, chrome.fillOpacity));
|
|
13645
|
+
if (chrome.fill?.kind === "image") {
|
|
13646
|
+
ctx.save();
|
|
13647
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13648
|
+
ctx.clip();
|
|
13649
|
+
ctx.globalAlpha = opacity;
|
|
13650
|
+
drawImagePaint(ctx, chrome.fill, box, assets);
|
|
13651
|
+
ctx.restore();
|
|
13652
|
+
} else if (chrome.fill) {
|
|
13653
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13654
|
+
ctx.fillStyle = fillStyleFor(ctx, chrome.fill, box, opacity);
|
|
13655
|
+
ctx.fill();
|
|
13656
|
+
}
|
|
13657
|
+
if (chrome.edge) {
|
|
13658
|
+
const width = chrome.edge.width * density;
|
|
13659
|
+
ctx.save();
|
|
13660
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13661
|
+
ctx.clip();
|
|
13662
|
+
const fade = ctx.createLinearGradient(0, box.y, 0, box.y + box.h / 2);
|
|
13663
|
+
fade.addColorStop(0, chrome.edge.color);
|
|
13664
|
+
fade.addColorStop(1, withOpacity(ctx, chrome.edge.color, 0));
|
|
13665
|
+
ctx.strokeStyle = fade;
|
|
13666
|
+
ctx.lineWidth = width * 2;
|
|
13667
|
+
tracePath(ctx, box.x, box.y, box.w, box.h, radii);
|
|
13668
|
+
ctx.stroke();
|
|
13669
|
+
ctx.restore();
|
|
13670
|
+
}
|
|
13671
|
+
if (chrome.border) {
|
|
13672
|
+
const border = chrome.border.width * density;
|
|
13119
13673
|
tracePath(
|
|
13120
13674
|
ctx,
|
|
13121
|
-
border / 2,
|
|
13122
|
-
border / 2,
|
|
13123
|
-
|
|
13124
|
-
|
|
13125
|
-
Math.max(0,
|
|
13675
|
+
box.x + border / 2,
|
|
13676
|
+
box.y + border / 2,
|
|
13677
|
+
box.w - border,
|
|
13678
|
+
box.h - border,
|
|
13679
|
+
radii.map((r) => Math.max(0, r - border / 2))
|
|
13126
13680
|
);
|
|
13127
|
-
ctx.strokeStyle =
|
|
13681
|
+
ctx.strokeStyle = chrome.border.color;
|
|
13128
13682
|
ctx.lineWidth = border;
|
|
13129
13683
|
ctx.stroke();
|
|
13130
13684
|
}
|
|
13131
13685
|
}
|
|
13132
13686
|
__name(drawChrome, "drawChrome");
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
const
|
|
13137
|
-
|
|
13687
|
+
var applyTransform2 = /* @__PURE__ */ __name((text, transform) => transform === "upper" ? text.toUpperCase() : transform === "lower" ? text.toLowerCase() : text, "applyTransform");
|
|
13688
|
+
function fillTracked(ctx, line, x, y, trackingPx, width) {
|
|
13689
|
+
let cursor = ctx.textAlign === "center" ? x - width / 2 : ctx.textAlign === "right" ? x - width : x;
|
|
13690
|
+
const align = ctx.textAlign;
|
|
13691
|
+
ctx.textAlign = "left";
|
|
13692
|
+
for (const glyph of line) {
|
|
13693
|
+
ctx.fillText(glyph, cursor, y);
|
|
13694
|
+
cursor += ctx.measureText(glyph).width + trackingPx;
|
|
13695
|
+
}
|
|
13696
|
+
ctx.textAlign = align;
|
|
13697
|
+
}
|
|
13698
|
+
__name(fillTracked, "fillTracked");
|
|
13699
|
+
function drawTextBlock(ctx, box, density, text, style, family = null, assets = NO_ASSETS) {
|
|
13700
|
+
const fontPx = Math.max(4, style.fontSize * density);
|
|
13701
|
+
const paddingPx = style.padding * density;
|
|
13702
|
+
const contentW = Math.max(1, box.w - paddingPx * 2);
|
|
13703
|
+
const contentH = Math.max(1, box.h - paddingPx * 2);
|
|
13138
13704
|
const lineHeightPx = fontPx * style.lineHeight;
|
|
13139
|
-
|
|
13140
|
-
const
|
|
13141
|
-
|
|
13705
|
+
const trackingPx = style.tracking * density;
|
|
13706
|
+
const stack = family ? `"${family}", ${UI_FONT_STACK}` : UI_FONT_STACK;
|
|
13707
|
+
ctx.font = `${style.fontWeight} ${fontPx}px ${stack}`;
|
|
13708
|
+
const nativeTracking = trackingPx !== 0 && "letterSpacing" in ctx;
|
|
13709
|
+
if (nativeTracking) {
|
|
13710
|
+
ctx.letterSpacing = `${trackingPx}px`;
|
|
13711
|
+
}
|
|
13712
|
+
const manualTracking = trackingPx !== 0 && !nativeTracking;
|
|
13713
|
+
const measure = /* @__PURE__ */ __name((s) => ctx.measureText(s).width + (manualTracking ? trackingPx * s.length : 0), "measure");
|
|
13714
|
+
const fits = Math.max(1, Math.floor(contentH / lineHeightPx));
|
|
13715
|
+
const maxLines = style.maxLines ? Math.min(fits, style.maxLines) : fits;
|
|
13142
13716
|
const lines = clampLines(
|
|
13143
13717
|
measure,
|
|
13144
|
-
wrapText(measure, text, contentW),
|
|
13718
|
+
wrapText(measure, applyTransform2(text, style.transform), contentW),
|
|
13145
13719
|
maxLines,
|
|
13146
13720
|
contentW
|
|
13147
13721
|
);
|
|
13148
13722
|
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" ?
|
|
13723
|
+
const top = style.valign === "top" ? box.y + paddingPx : style.valign === "bottom" ? box.y + box.h - paddingPx - blockH : box.y + (box.h - blockH) / 2;
|
|
13724
|
+
const anchorX = style.align === "left" ? box.x + paddingPx : style.align === "right" ? box.x + box.w - paddingPx : box.x + box.w / 2;
|
|
13151
13725
|
ctx.save();
|
|
13152
|
-
|
|
13153
|
-
|
|
13154
|
-
|
|
13726
|
+
if (style.paint.kind === "image") {
|
|
13727
|
+
ctx.fillStyle = "#ffffff";
|
|
13728
|
+
} else {
|
|
13729
|
+
ctx.fillStyle = fillStyleFor(ctx, style.paint, box, 1);
|
|
13730
|
+
}
|
|
13731
|
+
if (style.shadow) {
|
|
13732
|
+
ctx.shadowColor = style.shadow.color;
|
|
13733
|
+
ctx.shadowBlur = style.shadow.blur * density;
|
|
13734
|
+
ctx.shadowOffsetX = style.shadow.x * density;
|
|
13735
|
+
ctx.shadowOffsetY = -style.shadow.y * density;
|
|
13736
|
+
}
|
|
13155
13737
|
ctx.textAlign = style.align;
|
|
13156
13738
|
ctx.textBaseline = "middle";
|
|
13157
13739
|
for (let i = 0; i < lines.length; i += 1) {
|
|
13158
|
-
|
|
13740
|
+
const y = top + (i + 0.5) * lineHeightPx;
|
|
13741
|
+
if (manualTracking) {
|
|
13742
|
+
fillTracked(ctx, lines[i], anchorX, y, trackingPx, measure(lines[i]));
|
|
13743
|
+
} else {
|
|
13744
|
+
ctx.fillText(lines[i], anchorX, y);
|
|
13745
|
+
}
|
|
13159
13746
|
}
|
|
13160
13747
|
ctx.restore();
|
|
13748
|
+
if (style.paint.kind === "image") {
|
|
13749
|
+
ctx.save();
|
|
13750
|
+
ctx.globalCompositeOperation = "source-atop";
|
|
13751
|
+
drawImagePaint(ctx, style.paint, box, assets);
|
|
13752
|
+
ctx.restore();
|
|
13753
|
+
}
|
|
13754
|
+
if (nativeTracking) {
|
|
13755
|
+
ctx.letterSpacing = "0px";
|
|
13756
|
+
}
|
|
13161
13757
|
}
|
|
13162
13758
|
__name(drawTextBlock, "drawTextBlock");
|
|
13163
|
-
function panelSignature(widthM, heightM, size,
|
|
13759
|
+
function panelSignature(widthM, heightM, size, chrome, loaded = null) {
|
|
13164
13760
|
return JSON.stringify([
|
|
13165
13761
|
widthM,
|
|
13166
13762
|
heightM,
|
|
13167
13763
|
size.pxWidth,
|
|
13168
13764
|
size.pxHeight,
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
style.cornerRadiusMeters,
|
|
13172
|
-
style.borderWidthMeters,
|
|
13173
|
-
style.borderColor
|
|
13765
|
+
chrome,
|
|
13766
|
+
loaded
|
|
13174
13767
|
]);
|
|
13175
13768
|
}
|
|
13176
13769
|
__name(panelSignature, "panelSignature");
|
|
13177
|
-
function textSignature(widthM, heightM, size, text, style) {
|
|
13770
|
+
function textSignature(widthM, heightM, size, text, style, family = null) {
|
|
13178
13771
|
return JSON.stringify([
|
|
13179
13772
|
widthM,
|
|
13180
13773
|
heightM,
|
|
13181
13774
|
size.pxWidth,
|
|
13182
13775
|
size.pxHeight,
|
|
13183
13776
|
text,
|
|
13184
|
-
style
|
|
13185
|
-
|
|
13186
|
-
style.color,
|
|
13187
|
-
style.align,
|
|
13188
|
-
style.valign,
|
|
13189
|
-
style.lineHeight,
|
|
13190
|
-
style.paddingMeters
|
|
13777
|
+
style,
|
|
13778
|
+
family
|
|
13191
13779
|
]);
|
|
13192
13780
|
}
|
|
13193
13781
|
__name(textSignature, "textSignature");
|
|
13194
|
-
function buttonSignature(widthM, heightM, size,
|
|
13782
|
+
function buttonSignature(widthM, heightM, size, chrome, label, text, family = null, loaded = null) {
|
|
13195
13783
|
return JSON.stringify([
|
|
13196
|
-
panelSignature(widthM, heightM, size,
|
|
13784
|
+
panelSignature(widthM, heightM, size, chrome, loaded),
|
|
13197
13785
|
label,
|
|
13198
|
-
text
|
|
13199
|
-
|
|
13200
|
-
text.color
|
|
13786
|
+
text,
|
|
13787
|
+
family
|
|
13201
13788
|
]);
|
|
13202
13789
|
}
|
|
13203
13790
|
__name(buttonSignature, "buttonSignature");
|
|
13204
|
-
function trackSignature(widthM, heightM, size,
|
|
13791
|
+
function trackSignature(widthM, heightM, size, chrome, accentColor, knobColor, variant = null) {
|
|
13205
13792
|
return JSON.stringify([
|
|
13206
|
-
panelSignature(widthM, heightM, size,
|
|
13793
|
+
panelSignature(widthM, heightM, size, chrome),
|
|
13207
13794
|
accentColor,
|
|
13208
|
-
knobColor
|
|
13795
|
+
knobColor,
|
|
13796
|
+
variant
|
|
13209
13797
|
]);
|
|
13210
13798
|
}
|
|
13211
13799
|
__name(trackSignature, "trackSignature");
|
|
@@ -13215,17 +13803,226 @@ function drawRoundedBar(ctx, pxX, pxY, pxW, pxH, color) {
|
|
|
13215
13803
|
ctx.fill();
|
|
13216
13804
|
}
|
|
13217
13805
|
__name(drawRoundedBar, "drawRoundedBar");
|
|
13806
|
+
function drawCheckMark(ctx, box, color) {
|
|
13807
|
+
ctx.beginPath();
|
|
13808
|
+
ctx.moveTo(box.x + box.w * 0.24, box.y + box.h * 0.54);
|
|
13809
|
+
ctx.lineTo(box.x + box.w * 0.43, box.y + box.h * 0.72);
|
|
13810
|
+
ctx.lineTo(box.x + box.w * 0.77, box.y + box.h * 0.3);
|
|
13811
|
+
ctx.strokeStyle = color;
|
|
13812
|
+
ctx.lineWidth = box.h * 0.13;
|
|
13813
|
+
ctx.lineCap = "round";
|
|
13814
|
+
ctx.lineJoin = "round";
|
|
13815
|
+
ctx.stroke();
|
|
13816
|
+
}
|
|
13817
|
+
__name(drawCheckMark, "drawCheckMark");
|
|
13818
|
+
function drawDot(ctx, cx, cy, radius, color) {
|
|
13819
|
+
ctx.beginPath();
|
|
13820
|
+
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
|
|
13821
|
+
ctx.fillStyle = color;
|
|
13822
|
+
ctx.fill();
|
|
13823
|
+
}
|
|
13824
|
+
__name(drawDot, "drawDot");
|
|
13825
|
+
function drawRing(ctx, box, t, trackColor, accentColor) {
|
|
13826
|
+
const thickness = Math.min(box.w, box.h) * 0.14;
|
|
13827
|
+
const radius = Math.min(box.w, box.h) / 2 - thickness / 2;
|
|
13828
|
+
const cx = box.x + box.w / 2;
|
|
13829
|
+
const cy = box.y + box.h / 2;
|
|
13830
|
+
ctx.lineWidth = thickness;
|
|
13831
|
+
ctx.lineCap = "round";
|
|
13832
|
+
ctx.beginPath();
|
|
13833
|
+
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
|
|
13834
|
+
ctx.strokeStyle = trackColor;
|
|
13835
|
+
ctx.stroke();
|
|
13836
|
+
if (t <= 0) return;
|
|
13837
|
+
const start = -Math.PI / 2;
|
|
13838
|
+
ctx.beginPath();
|
|
13839
|
+
ctx.arc(cx, cy, radius, start, start + t * Math.PI * 2);
|
|
13840
|
+
ctx.strokeStyle = accentColor;
|
|
13841
|
+
ctx.stroke();
|
|
13842
|
+
}
|
|
13843
|
+
__name(drawRing, "drawRing");
|
|
13844
|
+
function drawIconLabel(ctx, box, density, label, style, family, icon, position, assets) {
|
|
13845
|
+
const fontPx = style.fontSize * density;
|
|
13846
|
+
const iconPx = fontPx * 1.3;
|
|
13847
|
+
const gapPx = label ? fontPx * 0.5 : 0;
|
|
13848
|
+
const stack = family ? `"${family}", ${UI_FONT_STACK}` : UI_FONT_STACK;
|
|
13849
|
+
ctx.font = `${style.fontWeight} ${fontPx}px ${stack}`;
|
|
13850
|
+
const labelPx = label ? ctx.measureText(label).width : 0;
|
|
13851
|
+
const groupPx = iconPx + gapPx + labelPx;
|
|
13852
|
+
const startX = box.x + (box.w - groupPx) / 2;
|
|
13853
|
+
const iconX = position === "left" ? startX : startX + labelPx + gapPx;
|
|
13854
|
+
const labelX = position === "left" ? startX + iconPx + gapPx : startX;
|
|
13855
|
+
drawImagePaint(
|
|
13856
|
+
ctx,
|
|
13857
|
+
{ src: icon, fit: "contain", tint: style.color },
|
|
13858
|
+
{ x: iconX, y: box.y + (box.h - iconPx) / 2, w: iconPx, h: iconPx },
|
|
13859
|
+
assets
|
|
13860
|
+
);
|
|
13861
|
+
if (label) {
|
|
13862
|
+
drawTextBlock(
|
|
13863
|
+
ctx,
|
|
13864
|
+
{ x: labelX, y: box.y, w: labelPx + 2, h: box.h },
|
|
13865
|
+
density,
|
|
13866
|
+
label,
|
|
13867
|
+
{ ...style, align: "left", padding: 0 },
|
|
13868
|
+
family,
|
|
13869
|
+
assets
|
|
13870
|
+
);
|
|
13871
|
+
}
|
|
13872
|
+
}
|
|
13873
|
+
__name(drawIconLabel, "drawIconLabel");
|
|
13874
|
+
|
|
13875
|
+
// core/ui/uiPaintOrder.ts
|
|
13876
|
+
var BASE_RENDER_ORDER = 10;
|
|
13877
|
+
var MAX_RENDER_ORDER = 890;
|
|
13878
|
+
var MAX_TREE_RANK = MAX_RENDER_ORDER - BASE_RENDER_ORDER - 1;
|
|
13879
|
+
var SLOT_STEP = 1e-4;
|
|
13880
|
+
var SLOTS_PER_WIDGET = 3;
|
|
13881
|
+
var MAX_WIDGET_INDEX = Math.floor(1 / SLOT_STEP / SLOTS_PER_WIDGET) - 1;
|
|
13882
|
+
var PLANE_EPSILON_METERS = 1e-3;
|
|
13883
|
+
var PARALLEL_DOT = 1 - 1e-4;
|
|
13884
|
+
var dot = /* @__PURE__ */ __name((a, b) => a.x * b.x + a.y * b.y + a.z * b.z, "dot");
|
|
13885
|
+
var length = /* @__PURE__ */ __name((a) => Math.sqrt(dot(a, a)), "length");
|
|
13886
|
+
var subtract = /* @__PURE__ */ __name((a, b) => ({
|
|
13887
|
+
x: a.x - b.x,
|
|
13888
|
+
y: a.y - b.y,
|
|
13889
|
+
z: a.z - b.z
|
|
13890
|
+
}), "subtract");
|
|
13891
|
+
function unit(a) {
|
|
13892
|
+
const len = length(a);
|
|
13893
|
+
if (len < 1e-9) return { x: 0, y: 0, z: 0 };
|
|
13894
|
+
return { x: a.x / len, y: a.y / len, z: a.z / len };
|
|
13895
|
+
}
|
|
13896
|
+
__name(unit, "unit");
|
|
13897
|
+
function normalOf(rect) {
|
|
13898
|
+
const { halfX: a, halfY: b } = rect;
|
|
13899
|
+
return unit({
|
|
13900
|
+
x: a.y * b.z - a.z * b.y,
|
|
13901
|
+
y: a.z * b.x - a.x * b.z,
|
|
13902
|
+
z: a.x * b.y - a.y * b.x
|
|
13903
|
+
});
|
|
13904
|
+
}
|
|
13905
|
+
__name(normalOf, "normalOf");
|
|
13906
|
+
var planeDistance = /* @__PURE__ */ __name((rect, normal, eye) => Math.abs(dot(subtract(eye, rect.center), normal)), "planeDistance");
|
|
13907
|
+
function closestPointDistance(rect, eye) {
|
|
13908
|
+
const toEye = subtract(eye, rect.center);
|
|
13909
|
+
const lenX = length(rect.halfX);
|
|
13910
|
+
const lenY = length(rect.halfY);
|
|
13911
|
+
const axisX = unit(rect.halfX);
|
|
13912
|
+
const axisY = unit(rect.halfY);
|
|
13913
|
+
const s = Math.max(-lenX, Math.min(lenX, dot(toEye, axisX)));
|
|
13914
|
+
const t = Math.max(-lenY, Math.min(lenY, dot(toEye, axisY)));
|
|
13915
|
+
return length({
|
|
13916
|
+
x: toEye.x - axisX.x * s - axisY.x * t,
|
|
13917
|
+
y: toEye.y - axisX.y * s - axisY.y * t,
|
|
13918
|
+
z: toEye.z - axisX.z * s - axisY.z * t
|
|
13919
|
+
});
|
|
13920
|
+
}
|
|
13921
|
+
__name(closestPointDistance, "closestPointDistance");
|
|
13922
|
+
var areaOf = /* @__PURE__ */ __name((rect) => length(rect.halfX) * length(rect.halfY), "areaOf");
|
|
13923
|
+
function comparePaintRects(a, b, eye) {
|
|
13924
|
+
const normalA = normalOf(a);
|
|
13925
|
+
const normalB = normalOf(b);
|
|
13926
|
+
const parallel = Math.abs(dot(normalA, normalB)) >= PARALLEL_DOT;
|
|
13927
|
+
const distanceA = parallel ? planeDistance(a, normalA, eye) : closestPointDistance(a, eye);
|
|
13928
|
+
const distanceB = parallel ? planeDistance(b, normalB, eye) : closestPointDistance(b, eye);
|
|
13929
|
+
if (Math.abs(distanceA - distanceB) > PLANE_EPSILON_METERS) {
|
|
13930
|
+
return distanceB - distanceA;
|
|
13931
|
+
}
|
|
13932
|
+
const areaA = areaOf(a);
|
|
13933
|
+
const areaB = areaOf(b);
|
|
13934
|
+
if (areaA !== areaB) return areaB - areaA;
|
|
13935
|
+
return a.id - b.id;
|
|
13936
|
+
}
|
|
13937
|
+
__name(comparePaintRects, "comparePaintRects");
|
|
13938
|
+
function buildPaintTrees(nodes) {
|
|
13939
|
+
const known = new Set(nodes.map((node) => node.id));
|
|
13940
|
+
const children = /* @__PURE__ */ new Map();
|
|
13941
|
+
const roots = [];
|
|
13942
|
+
for (const node of nodes) {
|
|
13943
|
+
if (node.parent !== null && known.has(node.parent)) {
|
|
13944
|
+
const siblings = children.get(node.parent);
|
|
13945
|
+
if (siblings) siblings.push(node.id);
|
|
13946
|
+
else children.set(node.parent, [node.id]);
|
|
13947
|
+
} else {
|
|
13948
|
+
roots.push(node.id);
|
|
13949
|
+
}
|
|
13950
|
+
}
|
|
13951
|
+
const trees = [];
|
|
13952
|
+
const visited = /* @__PURE__ */ new Set();
|
|
13953
|
+
const walk = /* @__PURE__ */ __name((id, order) => {
|
|
13954
|
+
if (visited.has(id)) return;
|
|
13955
|
+
visited.add(id);
|
|
13956
|
+
order.push(id);
|
|
13957
|
+
const kids = children.get(id);
|
|
13958
|
+
if (!kids) return;
|
|
13959
|
+
for (const kid of [...kids].sort((a, b) => a - b)) walk(kid, order);
|
|
13960
|
+
}, "walk");
|
|
13961
|
+
for (const rootId of [...roots].sort((a, b) => a - b)) {
|
|
13962
|
+
const order = [];
|
|
13963
|
+
walk(rootId, order);
|
|
13964
|
+
trees.push({ rootId, order });
|
|
13965
|
+
}
|
|
13966
|
+
return trees;
|
|
13967
|
+
}
|
|
13968
|
+
__name(buildPaintTrees, "buildPaintTrees");
|
|
13969
|
+
function paintSlots(treeRank, widgetIndex) {
|
|
13970
|
+
const base = BASE_RENDER_ORDER + Math.min(treeRank, MAX_TREE_RANK);
|
|
13971
|
+
const index = Math.min(widgetIndex, MAX_WIDGET_INDEX);
|
|
13972
|
+
const slot = /* @__PURE__ */ __name((offset) => base + (index * SLOTS_PER_WIDGET + offset) * SLOT_STEP, "slot");
|
|
13973
|
+
return { face: slot(0), parts: slot(1), descendants: slot(2) };
|
|
13974
|
+
}
|
|
13975
|
+
__name(paintSlots, "paintSlots");
|
|
13976
|
+
function assignPaintOrder(trees, rects, eye) {
|
|
13977
|
+
const sorted = trees.filter((tree) => rects.has(tree.rootId)).sort(
|
|
13978
|
+
(a, b) => comparePaintRects(
|
|
13979
|
+
rects.get(a.rootId),
|
|
13980
|
+
rects.get(b.rootId),
|
|
13981
|
+
eye
|
|
13982
|
+
)
|
|
13983
|
+
);
|
|
13984
|
+
const slots = /* @__PURE__ */ new Map();
|
|
13985
|
+
sorted.forEach((tree, rank) => {
|
|
13986
|
+
tree.order.forEach((id, index) => {
|
|
13987
|
+
slots.set(id, paintSlots(rank, index));
|
|
13988
|
+
});
|
|
13989
|
+
});
|
|
13990
|
+
return slots;
|
|
13991
|
+
}
|
|
13992
|
+
__name(assignPaintOrder, "assignPaintOrder");
|
|
13218
13993
|
|
|
13219
13994
|
// core/systems/UIPanelSystem.ts
|
|
13220
|
-
var FACE_RENDER_ORDER = 10;
|
|
13221
13995
|
var CHILD_Z = 2e-3;
|
|
13996
|
+
var DESCENDANT_WALK_INTERVAL = 30;
|
|
13997
|
+
var METER_STEPS = 200;
|
|
13998
|
+
var CLEAR_CHROME = {
|
|
13999
|
+
backgroundColor: "#000000",
|
|
14000
|
+
backgroundOpacity: 0,
|
|
14001
|
+
cornerRadius: 0,
|
|
14002
|
+
borderWidth: 0,
|
|
14003
|
+
borderColor: "#000000"
|
|
14004
|
+
};
|
|
14005
|
+
var PAINT_STAMP_KEY = "__uiPaintStamp";
|
|
13222
14006
|
var _UIPanelSystem = class _UIPanelSystem {
|
|
13223
14007
|
constructor(options) {
|
|
13224
14008
|
this.entries = /* @__PURE__ */ new Map();
|
|
14009
|
+
this.framesUntilDescendantWalk = 0;
|
|
14010
|
+
/** Whether any panel defines tokens, so plain scenes skip the parent walk. */
|
|
14011
|
+
this.anyTokens = false;
|
|
14012
|
+
this.drawAssets = {
|
|
14013
|
+
image: /* @__PURE__ */ __name((src) => uiImage(src), "image"),
|
|
14014
|
+
scratch: /* @__PURE__ */ __name((width, height) => {
|
|
14015
|
+
const canvas = this.createCanvas();
|
|
14016
|
+
canvas.width = width;
|
|
14017
|
+
canvas.height = height;
|
|
14018
|
+
return canvas.getContext("2d");
|
|
14019
|
+
}, "scratch")
|
|
14020
|
+
};
|
|
13225
14021
|
this.createCanvas = options?.createCanvas ?? (() => document.createElement("canvas"));
|
|
13226
14022
|
}
|
|
13227
14023
|
update(world, deltaTime = 0) {
|
|
13228
14024
|
const live = /* @__PURE__ */ new Set();
|
|
14025
|
+
this.anyTokens = world.query(UIPanelComponent).some((id) => world.getComponent(id, UIPanelComponent)?.tokens);
|
|
13229
14026
|
for (const entityId of world.query(UIPanelComponent, Object3DRef)) {
|
|
13230
14027
|
const panel = world.getComponent(entityId, UIPanelComponent);
|
|
13231
14028
|
if (!panel) continue;
|
|
@@ -13263,6 +14060,7 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13263
14060
|
this.entries.delete(entityId);
|
|
13264
14061
|
}
|
|
13265
14062
|
}
|
|
14063
|
+
this.applyPaintOrder(world);
|
|
13266
14064
|
}
|
|
13267
14065
|
/** All GPU/canvas resources; call on world teardown. */
|
|
13268
14066
|
dispose() {
|
|
@@ -13271,84 +14069,188 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13271
14069
|
}
|
|
13272
14070
|
// ── Widgets ────────────────────────────────────────────────────────────────
|
|
13273
14071
|
syncPanel(world, entityId, panel) {
|
|
13274
|
-
const
|
|
13275
|
-
|
|
13276
|
-
|
|
13277
|
-
|
|
13278
|
-
|
|
13279
|
-
|
|
13280
|
-
|
|
13281
|
-
|
|
13282
|
-
|
|
13283
|
-
|
|
13284
|
-
|
|
13285
|
-
|
|
14072
|
+
const chrome = resolveChrome(
|
|
14073
|
+
panel,
|
|
14074
|
+
panel.style,
|
|
14075
|
+
this.tokensFor(world, entityId)
|
|
14076
|
+
);
|
|
14077
|
+
const bleed = chromeBleed(chrome);
|
|
14078
|
+
const size = resolveCanvasSize(
|
|
14079
|
+
panel.width + bleed * 2,
|
|
14080
|
+
panel.height + bleed * 2,
|
|
14081
|
+
panel.pixelDensity
|
|
14082
|
+
);
|
|
14083
|
+
const signature = panelSignature(
|
|
14084
|
+
panel.width,
|
|
14085
|
+
panel.height,
|
|
14086
|
+
size,
|
|
14087
|
+
chrome,
|
|
14088
|
+
imagesLoaded(chrome)
|
|
14089
|
+
);
|
|
14090
|
+
this.rebuildIfChanged(
|
|
14091
|
+
world,
|
|
14092
|
+
entityId,
|
|
14093
|
+
signature,
|
|
14094
|
+
panel,
|
|
14095
|
+
bleed,
|
|
14096
|
+
size,
|
|
14097
|
+
(ctx) => {
|
|
14098
|
+
drawChrome(
|
|
14099
|
+
ctx,
|
|
14100
|
+
layoutBox(panel, bleed, size.density),
|
|
14101
|
+
size.density,
|
|
14102
|
+
chrome,
|
|
14103
|
+
this.drawAssets
|
|
14104
|
+
);
|
|
14105
|
+
},
|
|
14106
|
+
THREE37__namespace.DoubleSide
|
|
14107
|
+
);
|
|
13286
14108
|
}
|
|
13287
14109
|
syncText(world, entityId, text) {
|
|
13288
|
-
const
|
|
13289
|
-
const
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
|
|
13294
|
-
|
|
13295
|
-
|
|
13296
|
-
|
|
13297
|
-
|
|
13298
|
-
const signature =
|
|
13299
|
-
|
|
13300
|
-
|
|
13301
|
-
|
|
13302
|
-
|
|
14110
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14111
|
+
const chrome = text.style ? resolveChrome(CLEAR_CHROME, text.style, tokens) : null;
|
|
14112
|
+
const bleed = chrome ? chromeBleed(chrome) : 0;
|
|
14113
|
+
const size = resolveCanvasSize(
|
|
14114
|
+
text.width + bleed * 2,
|
|
14115
|
+
text.height + bleed * 2,
|
|
14116
|
+
text.pixelDensity
|
|
14117
|
+
);
|
|
14118
|
+
const style = resolveText(text, text.style, tokens);
|
|
14119
|
+
const family = familyOf(style.font);
|
|
14120
|
+
const signature = JSON.stringify([
|
|
14121
|
+
textSignature(text.width, text.height, size, text.text, style, family),
|
|
14122
|
+
chrome,
|
|
14123
|
+
chrome ? imagesLoaded(chrome) : null
|
|
14124
|
+
]);
|
|
14125
|
+
this.rebuildIfChanged(
|
|
14126
|
+
world,
|
|
14127
|
+
entityId,
|
|
14128
|
+
signature,
|
|
14129
|
+
text,
|
|
14130
|
+
bleed,
|
|
14131
|
+
size,
|
|
14132
|
+
(ctx) => {
|
|
14133
|
+
const box = layoutBox(text, bleed, size.density);
|
|
14134
|
+
if (chrome) {
|
|
14135
|
+
drawChrome(ctx, box, size.density, chrome, this.drawAssets);
|
|
14136
|
+
}
|
|
14137
|
+
drawTextBlock(
|
|
14138
|
+
ctx,
|
|
14139
|
+
box,
|
|
14140
|
+
size.density,
|
|
14141
|
+
text.text,
|
|
14142
|
+
style,
|
|
14143
|
+
family,
|
|
14144
|
+
this.drawAssets
|
|
14145
|
+
);
|
|
14146
|
+
}
|
|
14147
|
+
);
|
|
13303
14148
|
}
|
|
13304
14149
|
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
|
-
|
|
14150
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14151
|
+
const chrome = resolveChrome(button, button.style, tokens);
|
|
14152
|
+
const bleed = chromeBleed(chrome);
|
|
14153
|
+
const size = resolveCanvasSize(
|
|
14154
|
+
button.width + bleed * 2,
|
|
14155
|
+
button.height + bleed * 2,
|
|
14156
|
+
button.pixelDensity
|
|
14157
|
+
);
|
|
14158
|
+
const label = resolveText(
|
|
14159
|
+
{
|
|
14160
|
+
fontSize: button.fontSize,
|
|
14161
|
+
fontWeight: button.fontWeight,
|
|
14162
|
+
color: button.textColor,
|
|
14163
|
+
align: "center",
|
|
14164
|
+
valign: "middle",
|
|
14165
|
+
lineHeight: 1.2,
|
|
14166
|
+
padding: 0.01
|
|
14167
|
+
},
|
|
14168
|
+
button.style,
|
|
14169
|
+
tokens
|
|
14170
|
+
);
|
|
14171
|
+
const family = familyOf(label.font);
|
|
14172
|
+
const icon = button.icon ? resolveToken(button.icon, tokens) : null;
|
|
13322
14173
|
const signature = buttonSignature(
|
|
13323
14174
|
button.width,
|
|
13324
14175
|
button.height,
|
|
13325
14176
|
size,
|
|
13326
14177
|
chrome,
|
|
13327
14178
|
button.label,
|
|
13328
|
-
label
|
|
14179
|
+
label,
|
|
14180
|
+
family,
|
|
14181
|
+
[imagesLoaded(chrome), icon, icon ? !!uiImage(icon) : false]
|
|
14182
|
+
);
|
|
14183
|
+
this.rebuildIfChanged(
|
|
14184
|
+
world,
|
|
14185
|
+
entityId,
|
|
14186
|
+
signature,
|
|
14187
|
+
button,
|
|
14188
|
+
bleed,
|
|
14189
|
+
size,
|
|
14190
|
+
(ctx) => {
|
|
14191
|
+
const box = layoutBox(button, bleed, size.density);
|
|
14192
|
+
drawChrome(ctx, box, size.density, chrome, this.drawAssets);
|
|
14193
|
+
if (icon) {
|
|
14194
|
+
drawIconLabel(
|
|
14195
|
+
ctx,
|
|
14196
|
+
box,
|
|
14197
|
+
size.density,
|
|
14198
|
+
button.label,
|
|
14199
|
+
label,
|
|
14200
|
+
family,
|
|
14201
|
+
icon,
|
|
14202
|
+
button.iconPosition ?? "left",
|
|
14203
|
+
this.drawAssets
|
|
14204
|
+
);
|
|
14205
|
+
} else {
|
|
14206
|
+
drawTextBlock(
|
|
14207
|
+
ctx,
|
|
14208
|
+
box,
|
|
14209
|
+
size.density,
|
|
14210
|
+
button.label,
|
|
14211
|
+
label,
|
|
14212
|
+
family,
|
|
14213
|
+
this.drawAssets
|
|
14214
|
+
);
|
|
14215
|
+
}
|
|
14216
|
+
}
|
|
13329
14217
|
);
|
|
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
14218
|
}
|
|
13335
14219
|
syncToggle(world, entityId, toggle, deltaTime) {
|
|
13336
|
-
const
|
|
13337
|
-
const
|
|
13338
|
-
|
|
13339
|
-
|
|
13340
|
-
|
|
13341
|
-
|
|
13342
|
-
|
|
13343
|
-
|
|
14220
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14221
|
+
const accent = resolveToken(toggle.accentColor, tokens);
|
|
14222
|
+
const track = resolveToken(toggle.trackColor, tokens);
|
|
14223
|
+
const knobColor = resolveToken(toggle.knobColor, tokens);
|
|
14224
|
+
const size = resolveCanvasSize(
|
|
14225
|
+
toggle.width,
|
|
14226
|
+
toggle.height,
|
|
14227
|
+
toggle.pixelDensity
|
|
14228
|
+
);
|
|
14229
|
+
const variant = toggle.variant ?? "switch";
|
|
14230
|
+
if (variant !== "switch") {
|
|
14231
|
+
this.syncMarkToggle(world, entityId, toggle, accent, track, knobColor);
|
|
14232
|
+
return;
|
|
14233
|
+
}
|
|
14234
|
+
const chrome = resolveChrome(
|
|
14235
|
+
{
|
|
14236
|
+
backgroundColor: toggle.value ? accent : track,
|
|
14237
|
+
backgroundOpacity: 1,
|
|
14238
|
+
cornerRadius: toggle.height / 2,
|
|
14239
|
+
borderWidth: 0,
|
|
14240
|
+
borderColor: "#000000"
|
|
14241
|
+
},
|
|
14242
|
+
toggle.style,
|
|
14243
|
+
tokens
|
|
14244
|
+
);
|
|
13344
14245
|
const signature = JSON.stringify([
|
|
13345
14246
|
trackSignature(
|
|
13346
14247
|
toggle.width,
|
|
13347
14248
|
toggle.height,
|
|
13348
14249
|
size,
|
|
13349
14250
|
chrome,
|
|
13350
|
-
|
|
13351
|
-
|
|
14251
|
+
accent,
|
|
14252
|
+
knobColor,
|
|
14253
|
+
variant
|
|
13352
14254
|
),
|
|
13353
14255
|
toggle.value
|
|
13354
14256
|
]);
|
|
@@ -13356,18 +14258,24 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13356
14258
|
world,
|
|
13357
14259
|
entityId,
|
|
13358
14260
|
signature,
|
|
13359
|
-
toggle
|
|
13360
|
-
|
|
14261
|
+
toggle,
|
|
14262
|
+
0,
|
|
13361
14263
|
size,
|
|
13362
14264
|
(ctx) => {
|
|
13363
|
-
drawChrome(
|
|
14265
|
+
drawChrome(
|
|
14266
|
+
ctx,
|
|
14267
|
+
layoutBox(toggle, 0, size.density),
|
|
14268
|
+
size.density,
|
|
14269
|
+
chrome,
|
|
14270
|
+
this.drawAssets
|
|
14271
|
+
);
|
|
13364
14272
|
}
|
|
13365
14273
|
);
|
|
13366
14274
|
if (!entry) return;
|
|
13367
14275
|
if (!entry.knob) {
|
|
13368
14276
|
entry.knob = this.makeDisc(
|
|
13369
14277
|
toggle.height * 0.4,
|
|
13370
|
-
|
|
14278
|
+
knobColor,
|
|
13371
14279
|
entry.face.parent,
|
|
13372
14280
|
CHILD_Z
|
|
13373
14281
|
);
|
|
@@ -13379,35 +14287,95 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13379
14287
|
knob.position.x += (target - knob.position.x) * (deltaTime > 0 ? ease : 1);
|
|
13380
14288
|
knob.position.z = CHILD_Z;
|
|
13381
14289
|
}
|
|
14290
|
+
/** Checkbox and radio: a box or ring at the left of the widget's area. */
|
|
14291
|
+
syncMarkToggle(world, entityId, toggle, accent, track, markColor) {
|
|
14292
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14293
|
+
const radio = toggle.variant === "radio";
|
|
14294
|
+
const size = resolveCanvasSize(
|
|
14295
|
+
toggle.width,
|
|
14296
|
+
toggle.height,
|
|
14297
|
+
toggle.pixelDensity
|
|
14298
|
+
);
|
|
14299
|
+
const side = toggle.height;
|
|
14300
|
+
const chrome = resolveChrome(
|
|
14301
|
+
{
|
|
14302
|
+
backgroundColor: toggle.value ? accent : track,
|
|
14303
|
+
backgroundOpacity: 1,
|
|
14304
|
+
cornerRadius: radio ? side / 2 : side * 0.2,
|
|
14305
|
+
borderWidth: 0,
|
|
14306
|
+
borderColor: "#000000"
|
|
14307
|
+
},
|
|
14308
|
+
toggle.style,
|
|
14309
|
+
tokens
|
|
14310
|
+
);
|
|
14311
|
+
const signature = JSON.stringify([
|
|
14312
|
+
trackSignature(
|
|
14313
|
+
toggle.width,
|
|
14314
|
+
toggle.height,
|
|
14315
|
+
size,
|
|
14316
|
+
chrome,
|
|
14317
|
+
accent,
|
|
14318
|
+
markColor,
|
|
14319
|
+
toggle.variant ?? null
|
|
14320
|
+
),
|
|
14321
|
+
toggle.value
|
|
14322
|
+
]);
|
|
14323
|
+
this.rebuildIfChanged(world, entityId, signature, toggle, 0, size, (ctx) => {
|
|
14324
|
+
const px = side * size.density;
|
|
14325
|
+
const box = { x: 0, y: 0, w: px, h: px };
|
|
14326
|
+
drawChrome(ctx, box, size.density, chrome, this.drawAssets);
|
|
14327
|
+
if (!toggle.value) return;
|
|
14328
|
+
if (radio) drawDot(ctx, px / 2, px / 2, px * 0.24, markColor);
|
|
14329
|
+
else drawCheckMark(ctx, box, markColor);
|
|
14330
|
+
});
|
|
14331
|
+
}
|
|
13382
14332
|
syncSlider(world, entityId, slider) {
|
|
13383
|
-
const
|
|
14333
|
+
const tokens = this.tokensFor(world, entityId);
|
|
14334
|
+
const accent = resolveToken(slider.accentColor, tokens);
|
|
14335
|
+
const track = resolveToken(slider.trackColor, tokens);
|
|
14336
|
+
const knobColor = resolveToken(slider.knobColor, tokens);
|
|
14337
|
+
const size = resolveCanvasSize(
|
|
14338
|
+
slider.width,
|
|
14339
|
+
slider.height,
|
|
14340
|
+
slider.pixelDensity
|
|
14341
|
+
);
|
|
14342
|
+
const range = Math.max(1e-6, slider.max - slider.min);
|
|
14343
|
+
const t = Math.min(1, Math.max(0, (slider.value - slider.min) / range));
|
|
14344
|
+
if (slider.variant === "progress" || slider.variant === "ring") {
|
|
14345
|
+
this.syncMeter(world, entityId, slider, t, accent, track, knobColor);
|
|
14346
|
+
return;
|
|
14347
|
+
}
|
|
13384
14348
|
const trackThickness = slider.height * 0.32;
|
|
13385
14349
|
const knobRadius = slider.height * 0.45;
|
|
13386
14350
|
const usable = Math.max(1e-3, slider.width - slider.height);
|
|
13387
|
-
const chrome =
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
14351
|
+
const chrome = resolveChrome(
|
|
14352
|
+
{
|
|
14353
|
+
backgroundColor: track,
|
|
14354
|
+
backgroundOpacity: 1,
|
|
14355
|
+
cornerRadius: trackThickness / 2,
|
|
14356
|
+
borderWidth: 0,
|
|
14357
|
+
borderColor: "#000000"
|
|
14358
|
+
},
|
|
14359
|
+
void 0,
|
|
14360
|
+
null
|
|
14361
|
+
);
|
|
13394
14362
|
const signature = trackSignature(
|
|
13395
14363
|
slider.width,
|
|
13396
14364
|
slider.height,
|
|
13397
14365
|
size,
|
|
13398
14366
|
chrome,
|
|
13399
|
-
|
|
13400
|
-
|
|
14367
|
+
accent,
|
|
14368
|
+
knobColor,
|
|
14369
|
+
slider.variant ?? null
|
|
13401
14370
|
);
|
|
13402
14371
|
const entry = this.rebuildIfChanged(
|
|
13403
14372
|
world,
|
|
13404
14373
|
entityId,
|
|
13405
14374
|
signature,
|
|
13406
|
-
slider
|
|
13407
|
-
|
|
14375
|
+
slider,
|
|
14376
|
+
0,
|
|
13408
14377
|
size,
|
|
13409
14378
|
(ctx) => {
|
|
13410
|
-
ctx.clearRect(0, 0, size.pxWidth, size.pxHeight);
|
|
13411
14379
|
const trackWidthM = usable + trackThickness;
|
|
13412
14380
|
drawRoundedBar(
|
|
13413
14381
|
ctx,
|
|
@@ -13415,7 +14383,7 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13415
14383
|
(slider.height - trackThickness) / 2 * size.density,
|
|
13416
14384
|
trackWidthM * size.density,
|
|
13417
14385
|
trackThickness * size.density,
|
|
13418
|
-
|
|
14386
|
+
track
|
|
13419
14387
|
);
|
|
13420
14388
|
}
|
|
13421
14389
|
);
|
|
@@ -13424,13 +14392,13 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13424
14392
|
entry.fill = this.makeQuad(
|
|
13425
14393
|
1,
|
|
13426
14394
|
trackThickness,
|
|
13427
|
-
|
|
14395
|
+
accent,
|
|
13428
14396
|
entry.face.parent,
|
|
13429
14397
|
CHILD_Z / 2
|
|
13430
14398
|
);
|
|
13431
14399
|
entry.cap = this.makeDisc(
|
|
13432
14400
|
trackThickness / 2,
|
|
13433
|
-
|
|
14401
|
+
accent,
|
|
13434
14402
|
entry.face.parent,
|
|
13435
14403
|
CHILD_Z / 2,
|
|
13436
14404
|
Math.PI / 2,
|
|
@@ -13441,51 +14409,124 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13441
14409
|
if (!entry.knob) {
|
|
13442
14410
|
entry.knob = this.makeDisc(
|
|
13443
14411
|
knobRadius,
|
|
13444
|
-
|
|
14412
|
+
knobColor,
|
|
13445
14413
|
entry.face.parent,
|
|
13446
14414
|
CHILD_Z
|
|
13447
14415
|
);
|
|
13448
14416
|
}
|
|
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
14417
|
entry.knob.position.x = -usable / 2 + t * usable;
|
|
13452
14418
|
entry.knob.position.z = CHILD_Z;
|
|
13453
14419
|
entry.fill.scale.x = Math.max(1e-4, t * usable);
|
|
13454
14420
|
entry.fill.position.x = -usable / 2 + t * usable / 2;
|
|
13455
14421
|
entry.fill.position.z = CHILD_Z / 2;
|
|
13456
14422
|
}
|
|
14423
|
+
/**
|
|
14424
|
+
* Progress bars and rings. Unlike a slider these change rarely and have no
|
|
14425
|
+
* drag to keep smooth, so the value is drawn, in steps of half a percent.
|
|
14426
|
+
*/
|
|
14427
|
+
syncMeter(world, entityId, slider, t, accent, track, knobColor) {
|
|
14428
|
+
const size = resolveCanvasSize(
|
|
14429
|
+
slider.width,
|
|
14430
|
+
slider.height,
|
|
14431
|
+
slider.pixelDensity
|
|
14432
|
+
);
|
|
14433
|
+
const shown = Math.round(t * METER_STEPS) / METER_STEPS;
|
|
14434
|
+
const signature = JSON.stringify([
|
|
14435
|
+
slider.width,
|
|
14436
|
+
slider.height,
|
|
14437
|
+
size,
|
|
14438
|
+
slider.variant,
|
|
14439
|
+
accent,
|
|
14440
|
+
track,
|
|
14441
|
+
knobColor,
|
|
14442
|
+
shown
|
|
14443
|
+
]);
|
|
14444
|
+
this.rebuildIfChanged(world, entityId, signature, slider, 0, size, (ctx) => {
|
|
14445
|
+
const box = {
|
|
14446
|
+
x: 0,
|
|
14447
|
+
y: 0,
|
|
14448
|
+
w: size.pxWidth,
|
|
14449
|
+
h: size.pxHeight
|
|
14450
|
+
};
|
|
14451
|
+
if (slider.variant === "ring") {
|
|
14452
|
+
drawRing(ctx, box, shown, track, accent);
|
|
14453
|
+
return;
|
|
14454
|
+
}
|
|
14455
|
+
drawRoundedBar(ctx, 0, 0, box.w, box.h, track);
|
|
14456
|
+
if (shown <= 0) return;
|
|
14457
|
+
const fill = Math.max(box.h, box.w * shown);
|
|
14458
|
+
drawRoundedBar(ctx, 0, 0, fill, box.h, accent);
|
|
14459
|
+
});
|
|
14460
|
+
}
|
|
14461
|
+
/** The tokens in scope for a widget, nearest panel first. */
|
|
14462
|
+
tokensFor(world, entityId) {
|
|
14463
|
+
if (!this.anyTokens) return null;
|
|
14464
|
+
let merged = null;
|
|
14465
|
+
const visited = /* @__PURE__ */ new Set();
|
|
14466
|
+
let current = entityId;
|
|
14467
|
+
while (current !== null && !visited.has(current)) {
|
|
14468
|
+
visited.add(current);
|
|
14469
|
+
const tokens = world.getComponent(current, UIPanelComponent)?.tokens;
|
|
14470
|
+
if (tokens) merged = { ...tokens, ...merged ?? {} };
|
|
14471
|
+
const parent = world.getComponent(current, ParentId)?.value;
|
|
14472
|
+
current = typeof parent === "number" ? parent : null;
|
|
14473
|
+
}
|
|
14474
|
+
return merged;
|
|
14475
|
+
}
|
|
13457
14476
|
// ── Machinery ──────────────────────────────────────────────────────────────
|
|
13458
|
-
rebuildIfChanged(world, entityId, signature,
|
|
14477
|
+
rebuildIfChanged(world, entityId, signature, widget, bleed, size, draw, side = THREE37__namespace.FrontSide) {
|
|
13459
14478
|
const root = world.getComponent(entityId, Object3DRef)?.object;
|
|
13460
14479
|
if (!root) return null;
|
|
14480
|
+
const widthM = widget.width;
|
|
14481
|
+
const heightM = widget.height;
|
|
14482
|
+
const faceWidth = widthM + bleed * 2;
|
|
14483
|
+
const faceHeight = heightM + bleed * 2;
|
|
13461
14484
|
let entry = this.entries.get(entityId);
|
|
14485
|
+
if (entry) entry.opacity = widget.style?.opacity ?? 1;
|
|
13462
14486
|
if (entry && entry.signature === signature) return entry;
|
|
13463
14487
|
if (entry) this.disposeMovingParts(entry);
|
|
13464
14488
|
if (!entry) {
|
|
13465
14489
|
const canvas2 = this.createCanvas();
|
|
13466
|
-
const texture = new
|
|
14490
|
+
const texture = new THREE37__namespace.CanvasTexture(
|
|
13467
14491
|
canvas2
|
|
13468
14492
|
);
|
|
13469
14493
|
this.configureTexture(world, texture);
|
|
13470
|
-
const material = new
|
|
14494
|
+
const material = new THREE37__namespace.MeshBasicMaterial({
|
|
13471
14495
|
map: texture,
|
|
13472
14496
|
transparent: true,
|
|
13473
14497
|
depthWrite: false,
|
|
13474
14498
|
// UI colours are authored absolutes; scene tone mapping would shift
|
|
13475
14499
|
// them (the classic "why is my white UI beige" bug).
|
|
13476
14500
|
toneMapped: false,
|
|
13477
|
-
side
|
|
13478
|
-
premultipliedAlpha:
|
|
14501
|
+
side,
|
|
14502
|
+
premultipliedAlpha: false,
|
|
14503
|
+
blending: THREE37__namespace.CustomBlending,
|
|
14504
|
+
blendSrc: THREE37__namespace.OneFactor,
|
|
14505
|
+
blendDst: THREE37__namespace.OneMinusSrcAlphaFactor,
|
|
14506
|
+
blendSrcAlpha: THREE37__namespace.OneFactor,
|
|
14507
|
+
blendDstAlpha: THREE37__namespace.OneMinusSrcAlphaFactor
|
|
13479
14508
|
});
|
|
13480
|
-
const face = new
|
|
13481
|
-
new
|
|
14509
|
+
const face = new THREE37__namespace.Mesh(
|
|
14510
|
+
new THREE37__namespace.PlaneGeometry(faceWidth, faceHeight),
|
|
13482
14511
|
material
|
|
13483
14512
|
);
|
|
13484
|
-
face
|
|
14513
|
+
tagPart(face, 16777215, true);
|
|
14514
|
+
face.raycast = () => {
|
|
14515
|
+
};
|
|
13485
14516
|
root.add(face);
|
|
14517
|
+
const hit = new THREE37__namespace.Mesh(
|
|
14518
|
+
new THREE37__namespace.PlaneGeometry(widthM, heightM),
|
|
14519
|
+
new THREE37__namespace.MeshBasicMaterial({ visible: false, side })
|
|
14520
|
+
);
|
|
14521
|
+
root.add(hit);
|
|
13486
14522
|
entry = {
|
|
13487
14523
|
signature: "",
|
|
14524
|
+
root,
|
|
14525
|
+
width: widthM,
|
|
14526
|
+
height: heightM,
|
|
14527
|
+
opacity: widget.style?.opacity ?? 1,
|
|
13488
14528
|
face,
|
|
14529
|
+
hit,
|
|
13489
14530
|
texture,
|
|
13490
14531
|
material,
|
|
13491
14532
|
canvas: canvas2,
|
|
@@ -13499,23 +14540,26 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13499
14540
|
if (canvas.width !== size.pxWidth || canvas.height !== size.pxHeight) {
|
|
13500
14541
|
canvas.width = size.pxWidth;
|
|
13501
14542
|
canvas.height = size.pxHeight;
|
|
14543
|
+
if (entry.signature) entry.texture.dispose();
|
|
13502
14544
|
}
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
}
|
|
14545
|
+
entry.width = widthM;
|
|
14546
|
+
entry.height = heightM;
|
|
14547
|
+
resizePlane(entry.face, faceWidth, faceHeight);
|
|
14548
|
+
resizePlane(entry.hit, widthM, heightM);
|
|
13508
14549
|
const ctx = canvas.getContext("2d");
|
|
13509
|
-
if (ctx)
|
|
14550
|
+
if (ctx) {
|
|
14551
|
+
ctx.clearRect(0, 0, size.pxWidth, size.pxHeight);
|
|
14552
|
+
draw(ctx);
|
|
14553
|
+
}
|
|
13510
14554
|
entry.texture.needsUpdate = true;
|
|
13511
14555
|
entry.signature = signature;
|
|
13512
14556
|
return entry;
|
|
13513
14557
|
}
|
|
13514
14558
|
configureTexture(world, texture) {
|
|
13515
|
-
texture.colorSpace =
|
|
14559
|
+
texture.colorSpace = THREE37__namespace.SRGBColorSpace;
|
|
13516
14560
|
texture.generateMipmaps = true;
|
|
13517
|
-
texture.minFilter =
|
|
13518
|
-
texture.magFilter =
|
|
14561
|
+
texture.minFilter = THREE37__namespace.LinearMipmapLinearFilter;
|
|
14562
|
+
texture.magFilter = THREE37__namespace.LinearFilter;
|
|
13519
14563
|
texture.premultiplyAlpha = true;
|
|
13520
14564
|
try {
|
|
13521
14565
|
const renderer = world.getRenderer();
|
|
@@ -13526,7 +14570,7 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13526
14570
|
}
|
|
13527
14571
|
makeQuad(widthM, heightM, color, parent, z) {
|
|
13528
14572
|
return this.addPart(
|
|
13529
|
-
new
|
|
14573
|
+
new THREE37__namespace.PlaneGeometry(widthM, heightM),
|
|
13530
14574
|
color,
|
|
13531
14575
|
parent,
|
|
13532
14576
|
z
|
|
@@ -13535,24 +14579,23 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13535
14579
|
/** A filled disc (or arc segment, for the fill's rounded cap). */
|
|
13536
14580
|
makeDisc(radiusM, color, parent, z, thetaStart = 0, thetaLength = Math.PI * 2) {
|
|
13537
14581
|
return this.addPart(
|
|
13538
|
-
new
|
|
14582
|
+
new THREE37__namespace.CircleGeometry(radiusM, 32, thetaStart, thetaLength),
|
|
13539
14583
|
color,
|
|
13540
14584
|
parent,
|
|
13541
14585
|
z
|
|
13542
14586
|
);
|
|
13543
14587
|
}
|
|
13544
14588
|
addPart(geometry, color, parent, z) {
|
|
13545
|
-
const mesh = new
|
|
14589
|
+
const mesh = new THREE37__namespace.Mesh(
|
|
13546
14590
|
geometry,
|
|
13547
|
-
new
|
|
14591
|
+
new THREE37__namespace.MeshBasicMaterial({
|
|
13548
14592
|
color,
|
|
13549
14593
|
transparent: true,
|
|
13550
14594
|
depthWrite: false,
|
|
13551
|
-
toneMapped: false
|
|
13552
|
-
side: THREE30__namespace.DoubleSide
|
|
14595
|
+
toneMapped: false
|
|
13553
14596
|
})
|
|
13554
14597
|
);
|
|
13555
|
-
mesh
|
|
14598
|
+
tagPart(mesh, color);
|
|
13556
14599
|
mesh.position.z = z;
|
|
13557
14600
|
mesh.raycast = () => {
|
|
13558
14601
|
};
|
|
@@ -13583,22 +14626,144 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
13583
14626
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
13584
14627
|
if (!transform || !object) return;
|
|
13585
14628
|
const camera = world.getCamera();
|
|
13586
|
-
const cam = new
|
|
13587
|
-
const self = new
|
|
14629
|
+
const cam = new THREE37__namespace.Vector3();
|
|
14630
|
+
const self = new THREE37__namespace.Vector3();
|
|
13588
14631
|
camera.getWorldPosition(cam);
|
|
13589
14632
|
object.getWorldPosition(self);
|
|
13590
14633
|
transform.rotation.y = Math.atan2(cam.x - self.x, cam.z - self.z);
|
|
13591
14634
|
}
|
|
14635
|
+
/**
|
|
14636
|
+
* Stamp every widget's meshes with this frame's paint order. Written each
|
|
14637
|
+
* frame because the eye moves: the order between trees can change at any
|
|
14638
|
+
* time, and a plain property write costs less than checking it.
|
|
14639
|
+
*/
|
|
14640
|
+
applyPaintOrder(world) {
|
|
14641
|
+
if (this.entries.size === 0) return;
|
|
14642
|
+
const camera = world.getCamera();
|
|
14643
|
+
camera.getWorldPosition(eyeScratch);
|
|
14644
|
+
const nodes = [...this.entries.keys()].map((id) => ({
|
|
14645
|
+
id,
|
|
14646
|
+
parent: nearestWidgetAncestor(world, id)
|
|
14647
|
+
}));
|
|
14648
|
+
const trees = buildPaintTrees(nodes);
|
|
14649
|
+
const rects = /* @__PURE__ */ new Map();
|
|
14650
|
+
for (const tree of trees) {
|
|
14651
|
+
const entry = this.entries.get(tree.rootId);
|
|
14652
|
+
if (entry) rects.set(tree.rootId, rootRect(tree.rootId, entry));
|
|
14653
|
+
}
|
|
14654
|
+
const slots = assignPaintOrder(trees, rects, eyeScratch);
|
|
14655
|
+
this.framesUntilDescendantWalk -= 1;
|
|
14656
|
+
const walkDescendants = this.framesUntilDescendantWalk <= 0;
|
|
14657
|
+
if (walkDescendants) {
|
|
14658
|
+
this.framesUntilDescendantWalk = DESCENDANT_WALK_INTERVAL;
|
|
14659
|
+
}
|
|
14660
|
+
const widgetRoots = /* @__PURE__ */ new Set();
|
|
14661
|
+
if (walkDescendants) {
|
|
14662
|
+
for (const entry of this.entries.values()) widgetRoots.add(entry.root);
|
|
14663
|
+
}
|
|
14664
|
+
for (const [entityId, entry] of this.entries) {
|
|
14665
|
+
const slot = slots.get(entityId);
|
|
14666
|
+
if (!slot) continue;
|
|
14667
|
+
entry.face.renderOrder = slot.face;
|
|
14668
|
+
for (const part of [entry.knob, entry.fill, entry.cap]) {
|
|
14669
|
+
if (part) part.renderOrder = slot.parts;
|
|
14670
|
+
}
|
|
14671
|
+
if (walkDescendants) stampDescendants(entry.root, slot, widgetRoots);
|
|
14672
|
+
}
|
|
14673
|
+
const effective = /* @__PURE__ */ new Map();
|
|
14674
|
+
const parentOf = new Map(nodes.map((node) => [node.id, node.parent]));
|
|
14675
|
+
for (const tree of trees) {
|
|
14676
|
+
for (const id of tree.order) {
|
|
14677
|
+
const entry = this.entries.get(id);
|
|
14678
|
+
if (!entry) continue;
|
|
14679
|
+
const parent = parentOf.get(id);
|
|
14680
|
+
const inherited = parent != null ? effective.get(parent) ?? 1 : 1;
|
|
14681
|
+
const opacity = entry.opacity * inherited;
|
|
14682
|
+
effective.set(id, opacity);
|
|
14683
|
+
for (const mesh of [entry.face, entry.knob, entry.fill, entry.cap]) {
|
|
14684
|
+
if (!mesh) continue;
|
|
14685
|
+
const tag = mesh.userData[UI_PART_KEY];
|
|
14686
|
+
if (tag.opacity === opacity) continue;
|
|
14687
|
+
tag.opacity = opacity;
|
|
14688
|
+
applyPartColor(mesh, tag);
|
|
14689
|
+
}
|
|
14690
|
+
}
|
|
14691
|
+
}
|
|
14692
|
+
}
|
|
13592
14693
|
destroyEntry(entry) {
|
|
13593
14694
|
this.disposeMovingParts(entry);
|
|
13594
14695
|
entry.face.removeFromParent();
|
|
13595
14696
|
entry.face.geometry.dispose();
|
|
13596
14697
|
entry.face.material.dispose();
|
|
14698
|
+
entry.hit.removeFromParent();
|
|
14699
|
+
entry.hit.geometry.dispose();
|
|
14700
|
+
entry.hit.material.dispose();
|
|
13597
14701
|
entry.texture.dispose();
|
|
13598
14702
|
}
|
|
13599
14703
|
};
|
|
13600
14704
|
__name(_UIPanelSystem, "UIPanelSystem");
|
|
13601
14705
|
var UIPanelSystem = _UIPanelSystem;
|
|
14706
|
+
var eyeScratch = new THREE37__namespace.Vector3();
|
|
14707
|
+
function tagPart(mesh, color, premultiplied = false) {
|
|
14708
|
+
const tag = {
|
|
14709
|
+
baseColor: new THREE37__namespace.Color(color),
|
|
14710
|
+
tint: 1,
|
|
14711
|
+
opacity: 1,
|
|
14712
|
+
premultiplied
|
|
14713
|
+
};
|
|
14714
|
+
mesh.userData[UI_PART_KEY] = tag;
|
|
14715
|
+
}
|
|
14716
|
+
__name(tagPart, "tagPart");
|
|
14717
|
+
function resizePlane(mesh, width, height) {
|
|
14718
|
+
const params = mesh.geometry.parameters;
|
|
14719
|
+
if (params.width === width && params.height === height) return;
|
|
14720
|
+
mesh.geometry.dispose();
|
|
14721
|
+
mesh.geometry = new THREE37__namespace.PlaneGeometry(width, height);
|
|
14722
|
+
}
|
|
14723
|
+
__name(resizePlane, "resizePlane");
|
|
14724
|
+
function layoutBox(widget, bleed, density) {
|
|
14725
|
+
return {
|
|
14726
|
+
x: bleed * density,
|
|
14727
|
+
y: bleed * density,
|
|
14728
|
+
w: widget.width * density,
|
|
14729
|
+
h: widget.height * density
|
|
14730
|
+
};
|
|
14731
|
+
}
|
|
14732
|
+
__name(layoutBox, "layoutBox");
|
|
14733
|
+
function familyOf(font) {
|
|
14734
|
+
return font ? uiFontFamily(font) : null;
|
|
14735
|
+
}
|
|
14736
|
+
__name(familyOf, "familyOf");
|
|
14737
|
+
function imagesLoaded(chrome) {
|
|
14738
|
+
return styleAssets(chrome, null).images.map((src) => !!uiImage(src));
|
|
14739
|
+
}
|
|
14740
|
+
__name(imagesLoaded, "imagesLoaded");
|
|
14741
|
+
function rootRect(id, entry) {
|
|
14742
|
+
const e = entry.root.matrixWorld.elements;
|
|
14743
|
+
const halfW = entry.width / 2;
|
|
14744
|
+
const halfH = entry.height / 2;
|
|
14745
|
+
return {
|
|
14746
|
+
id,
|
|
14747
|
+
center: { x: e[12], y: e[13], z: e[14] },
|
|
14748
|
+
halfX: { x: e[0] * halfW, y: e[1] * halfW, z: e[2] * halfW },
|
|
14749
|
+
halfY: { x: e[4] * halfH, y: e[5] * halfH, z: e[6] * halfH }
|
|
14750
|
+
};
|
|
14751
|
+
}
|
|
14752
|
+
__name(rootRect, "rootRect");
|
|
14753
|
+
function stampDescendants(root, slot, widgetRoots) {
|
|
14754
|
+
for (const child of root.children) {
|
|
14755
|
+
if (widgetRoots.has(child) || child.userData[UI_PART_KEY]) continue;
|
|
14756
|
+
const material = child.material;
|
|
14757
|
+
const transparent = Array.isArray(material) ? material.some((m) => m.transparent) : material?.transparent === true;
|
|
14758
|
+
const untouched = child.renderOrder === 0 || child.userData[PAINT_STAMP_KEY] === child.renderOrder;
|
|
14759
|
+
if (transparent && untouched) {
|
|
14760
|
+
child.renderOrder = slot.descendants;
|
|
14761
|
+
child.userData[PAINT_STAMP_KEY] = slot.descendants;
|
|
14762
|
+
}
|
|
14763
|
+
stampDescendants(child, slot, widgetRoots);
|
|
14764
|
+
}
|
|
14765
|
+
}
|
|
14766
|
+
__name(stampDescendants, "stampDescendants");
|
|
13602
14767
|
var _XRHitTestSystem = class _XRHitTestSystem {
|
|
13603
14768
|
constructor() {
|
|
13604
14769
|
this.sources = /* @__PURE__ */ new Map();
|
|
@@ -13635,12 +14800,12 @@ var _XRHitTestSystem = class _XRHitTestSystem {
|
|
|
13635
14800
|
if (!hits || hits.length === 0) continue;
|
|
13636
14801
|
const pose = hits[0].getPose(referenceSpace);
|
|
13637
14802
|
if (!pose) continue;
|
|
13638
|
-
const matrix = new
|
|
14803
|
+
const matrix = new THREE37__namespace.Matrix4().fromArray(
|
|
13639
14804
|
pose.transform.matrix
|
|
13640
14805
|
);
|
|
13641
|
-
const position = new
|
|
13642
|
-
const quaternion = new
|
|
13643
|
-
matrix.decompose(position, quaternion, new
|
|
14806
|
+
const position = new THREE37__namespace.Vector3();
|
|
14807
|
+
const quaternion = new THREE37__namespace.Quaternion();
|
|
14808
|
+
matrix.decompose(position, quaternion, new THREE37__namespace.Vector3());
|
|
13644
14809
|
this.results.set(key, { position, quaternion });
|
|
13645
14810
|
}
|
|
13646
14811
|
}
|
|
@@ -13714,8 +14879,8 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13714
14879
|
/** Per-anchor head-glue gates — see XREnvironmentSystem's TrackedEntry. */
|
|
13715
14880
|
this.gates = /* @__PURE__ */ new Map();
|
|
13716
14881
|
this.presenting = false;
|
|
13717
|
-
this.tmpViewerMatrix = new
|
|
13718
|
-
this.tmpViewPos = new
|
|
14882
|
+
this.tmpViewerMatrix = new THREE37__namespace.Matrix4();
|
|
14883
|
+
this.tmpViewPos = new THREE37__namespace.Vector3();
|
|
13719
14884
|
}
|
|
13720
14885
|
update(world, deltaTime = 0) {
|
|
13721
14886
|
const presenting = world.isXrPresenting();
|
|
@@ -13789,8 +14954,8 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13789
14954
|
if (typeof frame.createAnchor !== "function") return;
|
|
13790
14955
|
const RigidTransform = globalThis.XRRigidTransform;
|
|
13791
14956
|
if (!RigidTransform) return;
|
|
13792
|
-
const quaternion = new
|
|
13793
|
-
new
|
|
14957
|
+
const quaternion = new THREE37__namespace.Quaternion().setFromEuler(
|
|
14958
|
+
new THREE37__namespace.Euler(
|
|
13794
14959
|
transform.rotation.x,
|
|
13795
14960
|
transform.rotation.y,
|
|
13796
14961
|
transform.rotation.z,
|
|
@@ -13833,13 +14998,13 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
13833
14998
|
};
|
|
13834
14999
|
__name(_XRAnchorSystem, "XRAnchorSystem");
|
|
13835
15000
|
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
|
|
15001
|
+
var _q = new THREE37__namespace.Quaternion();
|
|
15002
|
+
var _q2 = new THREE37__namespace.Quaternion();
|
|
15003
|
+
var _s = new THREE37__namespace.Vector3();
|
|
15004
|
+
var _e = new THREE37__namespace.Vector3();
|
|
15005
|
+
var _w = new THREE37__namespace.Vector3();
|
|
15006
|
+
var _v = new THREE37__namespace.Vector3();
|
|
15007
|
+
var _p = new THREE37__namespace.Vector3();
|
|
13843
15008
|
function setWorldQuaternion(o, q) {
|
|
13844
15009
|
if (o.parent) {
|
|
13845
15010
|
o.parent.getWorldQuaternion(_q2).invert();
|
|
@@ -13864,19 +15029,19 @@ function twoBoneIK(upper, lower, end, target, pole) {
|
|
|
13864
15029
|
if (a < 1e-6 || b < 1e-6) return target.distanceTo(_w);
|
|
13865
15030
|
const toT = _v.subVectors(target, _s);
|
|
13866
15031
|
const want = toT.length();
|
|
13867
|
-
const c =
|
|
15032
|
+
const c = THREE37__namespace.MathUtils.clamp(want, Math.abs(a - b) + 1e-4, a + b - 1e-4);
|
|
13868
15033
|
const dir = toT.divideScalar(want || 1).clone();
|
|
13869
15034
|
const pv = _p.subVectors(pole, _s);
|
|
13870
15035
|
pv.addScaledVector(dir, -pv.dot(dir));
|
|
13871
15036
|
if (pv.lengthSq() < 1e-8) pv.set(0, -1, 0).addScaledVector(dir, dir.y);
|
|
13872
15037
|
pv.normalize();
|
|
13873
|
-
const cosA =
|
|
15038
|
+
const cosA = THREE37__namespace.MathUtils.clamp((a * a + c * c - b * b) / (2 * a * c), -1, 1);
|
|
13874
15039
|
const joint = _s.clone().addScaledVector(dir, a * cosA).addScaledVector(pv, a * Math.sqrt(1 - cosA * cosA));
|
|
13875
|
-
turn(upper, new
|
|
15040
|
+
turn(upper, new THREE37__namespace.Quaternion().setFromUnitVectors(_e.clone().sub(_s).normalize(), joint.clone().sub(_s).normalize()));
|
|
13876
15041
|
lower.getWorldPosition(_e);
|
|
13877
15042
|
end.getWorldPosition(_w);
|
|
13878
15043
|
const reach = _s.clone().addScaledVector(dir, c);
|
|
13879
|
-
turn(lower, new
|
|
15044
|
+
turn(lower, new THREE37__namespace.Quaternion().setFromUnitVectors(_w.clone().sub(_e).normalize(), reach.clone().sub(_e).normalize()));
|
|
13880
15045
|
return want - c;
|
|
13881
15046
|
}
|
|
13882
15047
|
__name(twoBoneIK, "twoBoneIK");
|
|
@@ -13888,10 +15053,10 @@ var LIMB_BONES = {
|
|
|
13888
15053
|
leftFoot: ["leftUpperLeg", "leftLowerLeg", "leftFoot"],
|
|
13889
15054
|
rightFoot: ["rightUpperLeg", "rightLowerLeg", "rightFoot"]
|
|
13890
15055
|
};
|
|
13891
|
-
var _t = new
|
|
13892
|
-
var _p2 = new
|
|
13893
|
-
var _q3 = new
|
|
13894
|
-
var _pq = new
|
|
15056
|
+
var _t = new THREE37__namespace.Vector3();
|
|
15057
|
+
var _p2 = new THREE37__namespace.Vector3();
|
|
15058
|
+
var _q3 = new THREE37__namespace.Quaternion();
|
|
15059
|
+
var _pq = new THREE37__namespace.Quaternion();
|
|
13895
15060
|
var _IKSystem = class _IKSystem {
|
|
13896
15061
|
constructor() {
|
|
13897
15062
|
this.runtimes = /* @__PURE__ */ new Map();
|
|
@@ -13952,7 +15117,7 @@ var _IKSystem = class _IKSystem {
|
|
|
13952
15117
|
const [upper, lower, end] = limb.bones;
|
|
13953
15118
|
for (const bone of [upper, lower, end]) {
|
|
13954
15119
|
if (!runtime.written.has(bone)) {
|
|
13955
|
-
runtime.written.set(bone, { before: bone.quaternion.clone(), written: new
|
|
15120
|
+
runtime.written.set(bone, { before: bone.quaternion.clone(), written: new THREE37__namespace.Quaternion() });
|
|
13956
15121
|
}
|
|
13957
15122
|
}
|
|
13958
15123
|
const animated = [upper.quaternion.clone(), lower.quaternion.clone(), end.quaternion.clone()];
|
|
@@ -13990,9 +15155,9 @@ var IKSystem = _IKSystem;
|
|
|
13990
15155
|
function buildGeometry2(area) {
|
|
13991
15156
|
if (area.shape === "circle") {
|
|
13992
15157
|
const radius = Math.max(5e-3, area.width / 2);
|
|
13993
|
-
return new
|
|
15158
|
+
return new THREE37__namespace.CircleGeometry(radius, 48);
|
|
13994
15159
|
}
|
|
13995
|
-
return new
|
|
15160
|
+
return new THREE37__namespace.PlaneGeometry(
|
|
13996
15161
|
Math.max(0.01, area.width),
|
|
13997
15162
|
Math.max(0.01, area.depth)
|
|
13998
15163
|
);
|
|
@@ -14009,13 +15174,13 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
14009
15174
|
update(world) {
|
|
14010
15175
|
const entityIds = world.query(VRTeleportAreaComponent, Object3DRef);
|
|
14011
15176
|
const alive = new Set(entityIds);
|
|
14012
|
-
for (const
|
|
14013
|
-
if (!alive.has(
|
|
15177
|
+
for (const tracked2 of this.signatures.keys()) {
|
|
15178
|
+
if (!alive.has(tracked2)) this.signatures.delete(tracked2);
|
|
14014
15179
|
}
|
|
14015
15180
|
for (const entityId of entityIds) {
|
|
14016
15181
|
const area = world.getComponent(entityId, VRTeleportAreaComponent);
|
|
14017
15182
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
14018
|
-
if (!area || !(object instanceof
|
|
15183
|
+
if (!area || !(object instanceof THREE37__namespace.Mesh)) continue;
|
|
14019
15184
|
const signature = signatureOf(area);
|
|
14020
15185
|
if (this.signatures.get(entityId) === signature) continue;
|
|
14021
15186
|
this.signatures.set(entityId, signature);
|
|
@@ -14027,18 +15192,18 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
14027
15192
|
__name(_VRTeleportAreaSystem, "VRTeleportAreaSystem");
|
|
14028
15193
|
var VRTeleportAreaSystem = _VRTeleportAreaSystem;
|
|
14029
15194
|
function createHandMaterial(preset, options) {
|
|
14030
|
-
const color = new
|
|
15195
|
+
const color = new THREE37__namespace.Color(options.color);
|
|
14031
15196
|
switch (preset) {
|
|
14032
15197
|
case "ghost":
|
|
14033
|
-
return new
|
|
15198
|
+
return new THREE37__namespace.MeshBasicMaterial({
|
|
14034
15199
|
color,
|
|
14035
15200
|
transparent: true,
|
|
14036
15201
|
opacity: Math.min(1, Math.max(0.05, options.opacity * 0.45)),
|
|
14037
15202
|
depthWrite: false,
|
|
14038
|
-
side:
|
|
15203
|
+
side: THREE37__namespace.DoubleSide
|
|
14039
15204
|
});
|
|
14040
15205
|
case "neon":
|
|
14041
|
-
return new
|
|
15206
|
+
return new THREE37__namespace.MeshStandardMaterial({
|
|
14042
15207
|
color,
|
|
14043
15208
|
emissive: color,
|
|
14044
15209
|
emissiveIntensity: Math.max(0.5, options.emissiveIntensity || 2),
|
|
@@ -14048,7 +15213,7 @@ function createHandMaterial(preset, options) {
|
|
|
14048
15213
|
opacity: options.opacity
|
|
14049
15214
|
});
|
|
14050
15215
|
case "skeleton":
|
|
14051
|
-
return new
|
|
15216
|
+
return new THREE37__namespace.MeshBasicMaterial({
|
|
14052
15217
|
color,
|
|
14053
15218
|
wireframe: true,
|
|
14054
15219
|
transparent: true,
|
|
@@ -14056,7 +15221,7 @@ function createHandMaterial(preset, options) {
|
|
|
14056
15221
|
});
|
|
14057
15222
|
case "custom":
|
|
14058
15223
|
case "default":
|
|
14059
|
-
return new
|
|
15224
|
+
return new THREE37__namespace.MeshStandardMaterial({
|
|
14060
15225
|
color,
|
|
14061
15226
|
roughness: 0.85,
|
|
14062
15227
|
metalness: 0,
|
|
@@ -14064,10 +15229,10 @@ function createHandMaterial(preset, options) {
|
|
|
14064
15229
|
emissiveIntensity: Math.max(0, options.emissiveIntensity),
|
|
14065
15230
|
transparent: options.opacity < 1,
|
|
14066
15231
|
opacity: options.opacity,
|
|
14067
|
-
side:
|
|
15232
|
+
side: THREE37__namespace.DoubleSide
|
|
14068
15233
|
});
|
|
14069
15234
|
default: {
|
|
14070
|
-
return new
|
|
15235
|
+
return new THREE37__namespace.MeshStandardMaterial({ color });
|
|
14071
15236
|
}
|
|
14072
15237
|
}
|
|
14073
15238
|
}
|
|
@@ -14092,9 +15257,9 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
14092
15257
|
constructor(options) {
|
|
14093
15258
|
this.controllerModelFactory = new XRControllerModelFactory_js.XRControllerModelFactory();
|
|
14094
15259
|
this.handModelFactory = new XRHandModelFactory_js.XRHandModelFactory();
|
|
14095
|
-
this.group = new
|
|
15260
|
+
this.group = new THREE37__namespace.Group();
|
|
14096
15261
|
/** Reused so a per-frame colour compare allocates nothing. */
|
|
14097
|
-
this.rayColorScratch = new
|
|
15262
|
+
this.rayColorScratch = new THREE37__namespace.Color();
|
|
14098
15263
|
this.slots = /* @__PURE__ */ new Map();
|
|
14099
15264
|
this.attachedTo = null;
|
|
14100
15265
|
/** Last applied preset signature, so materials rebuild only on real change. */
|
|
@@ -14231,8 +15396,8 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
14231
15396
|
*/
|
|
14232
15397
|
fitRayToHover(ray, side) {
|
|
14233
15398
|
const hover = this.interactionSystem?.getHoverFor(side) ?? null;
|
|
14234
|
-
const
|
|
14235
|
-
ray.scale.z =
|
|
15399
|
+
const length2 = hover && Number.isFinite(hover.distance) && hover.distance > 0 ? Math.min(hover.distance, RAY_LENGTH) : RAY_LENGTH;
|
|
15400
|
+
ray.scale.z = length2;
|
|
14236
15401
|
}
|
|
14237
15402
|
/** Lazily build per-slot visuals; the device reports profiles late. */
|
|
14238
15403
|
ensureSlots(world) {
|
|
@@ -14281,17 +15446,17 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
14281
15446
|
* without pulling in a line-rendering extension.
|
|
14282
15447
|
*/
|
|
14283
15448
|
createRay() {
|
|
14284
|
-
const geometry = new
|
|
15449
|
+
const geometry = new THREE37__namespace.CylinderGeometry(RAY_RADIUS, RAY_RADIUS, 1, 8, 1);
|
|
14285
15450
|
geometry.rotateX(-Math.PI / 2);
|
|
14286
15451
|
geometry.translate(0, 0, -0.5);
|
|
14287
|
-
const material = new
|
|
15452
|
+
const material = new THREE37__namespace.MeshBasicMaterial({
|
|
14288
15453
|
color: "#4da3ff",
|
|
14289
15454
|
transparent: true,
|
|
14290
15455
|
opacity: 0.75,
|
|
14291
15456
|
depthTest: false,
|
|
14292
15457
|
depthWrite: false
|
|
14293
15458
|
});
|
|
14294
|
-
const mesh = new
|
|
15459
|
+
const mesh = new THREE37__namespace.Mesh(geometry, material);
|
|
14295
15460
|
mesh.name = "XRPointerRay";
|
|
14296
15461
|
mesh.renderOrder = 999;
|
|
14297
15462
|
mesh.visible = false;
|
|
@@ -14322,14 +15487,14 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
14322
15487
|
__name(_XRControllerVisualSystem, "XRControllerVisualSystem");
|
|
14323
15488
|
var XRControllerVisualSystem = _XRControllerVisualSystem;
|
|
14324
15489
|
var MARKER_RADIUS = 0.28;
|
|
14325
|
-
var ACCENT = new
|
|
14326
|
-
var SEGMENT_AXIS = new
|
|
15490
|
+
var ACCENT = new THREE37__namespace.Color("#4da3ff");
|
|
15491
|
+
var SEGMENT_AXIS = new THREE37__namespace.Vector3(0, 1, 0);
|
|
14327
15492
|
var HEAD_CLEARANCE = 0.25;
|
|
14328
15493
|
var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
14329
15494
|
constructor(locomotionSystem) {
|
|
14330
|
-
this.group = new
|
|
15495
|
+
this.group = new THREE37__namespace.Group();
|
|
14331
15496
|
/** Holds the segment chain that draws the arc. */
|
|
14332
|
-
this.arc = new
|
|
15497
|
+
this.arc = new THREE37__namespace.Group();
|
|
14333
15498
|
/**
|
|
14334
15499
|
* Unit cylinder along +Y, reused by every segment.
|
|
14335
15500
|
*
|
|
@@ -14338,14 +15503,14 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14338
15503
|
* scaled cylinders gives real thickness while rebuilding no geometry: each
|
|
14339
15504
|
* frame only moves, rotates and scales meshes that already exist.
|
|
14340
15505
|
*/
|
|
14341
|
-
this.segmentGeometry = new
|
|
15506
|
+
this.segmentGeometry = new THREE37__namespace.CylinderGeometry(1, 1, 1, 6, 1);
|
|
14342
15507
|
this.segments = [];
|
|
14343
|
-
this.marker = new
|
|
15508
|
+
this.marker = new THREE37__namespace.Group();
|
|
14344
15509
|
this.attached = false;
|
|
14345
|
-
this.scratchDirection = new
|
|
14346
|
-
this.scratchHead = new
|
|
14347
|
-
this.validColor = new
|
|
14348
|
-
this.invalidColor = new
|
|
15510
|
+
this.scratchDirection = new THREE37__namespace.Vector3();
|
|
15511
|
+
this.scratchHead = new THREE37__namespace.Vector3();
|
|
15512
|
+
this.validColor = new THREE37__namespace.Color();
|
|
15513
|
+
this.invalidColor = new THREE37__namespace.Color();
|
|
14349
15514
|
this.locomotionSystem = locomotionSystem;
|
|
14350
15515
|
this.group.name = "XRTeleportVisuals";
|
|
14351
15516
|
this.group.userData.ecsPreviewHidden = true;
|
|
@@ -14403,8 +15568,8 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14403
15568
|
const from = curve[i];
|
|
14404
15569
|
const to = curve[i + 1];
|
|
14405
15570
|
this.scratchDirection.subVectors(to, from);
|
|
14406
|
-
const
|
|
14407
|
-
if (
|
|
15571
|
+
const length2 = this.scratchDirection.length();
|
|
15572
|
+
if (length2 < 1e-6) {
|
|
14408
15573
|
segment.visible = false;
|
|
14409
15574
|
continue;
|
|
14410
15575
|
}
|
|
@@ -14412,9 +15577,9 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14412
15577
|
segment.position.copy(from).addScaledVector(this.scratchDirection, 0.5);
|
|
14413
15578
|
segment.quaternion.setFromUnitVectors(
|
|
14414
15579
|
SEGMENT_AXIS,
|
|
14415
|
-
this.scratchDirection.divideScalar(
|
|
15580
|
+
this.scratchDirection.divideScalar(length2)
|
|
14416
15581
|
);
|
|
14417
|
-
segment.scale.set(radius,
|
|
15582
|
+
segment.scale.set(radius, length2, radius);
|
|
14418
15583
|
const t = needed > 1 ? i / (needed - 1) : 0;
|
|
14419
15584
|
const fade = 1 - t * 0.75;
|
|
14420
15585
|
segment.material.color.copy(tint).multiplyScalar(fade);
|
|
@@ -14423,12 +15588,12 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14423
15588
|
/** Grow the segment pool to cover the current arc. */
|
|
14424
15589
|
ensureSegments(count) {
|
|
14425
15590
|
while (this.segments.length < count) {
|
|
14426
|
-
const material = new
|
|
15591
|
+
const material = new THREE37__namespace.MeshBasicMaterial({
|
|
14427
15592
|
transparent: true,
|
|
14428
15593
|
depthTest: false,
|
|
14429
15594
|
depthWrite: false
|
|
14430
15595
|
});
|
|
14431
|
-
const mesh = new
|
|
15596
|
+
const mesh = new THREE37__namespace.Mesh(this.segmentGeometry, material);
|
|
14432
15597
|
mesh.frustumCulled = false;
|
|
14433
15598
|
mesh.renderOrder = 998;
|
|
14434
15599
|
mesh.raycast = () => {
|
|
@@ -14452,33 +15617,33 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
14452
15617
|
return world.getComponent(entityId, XRRigComponent) ?? null;
|
|
14453
15618
|
}
|
|
14454
15619
|
createRing() {
|
|
14455
|
-
const geometry = new
|
|
15620
|
+
const geometry = new THREE37__namespace.RingGeometry(
|
|
14456
15621
|
MARKER_RADIUS * 0.72,
|
|
14457
15622
|
MARKER_RADIUS,
|
|
14458
15623
|
48
|
|
14459
15624
|
);
|
|
14460
15625
|
geometry.rotateX(-Math.PI / 2);
|
|
14461
|
-
return new
|
|
15626
|
+
return new THREE37__namespace.Mesh(
|
|
14462
15627
|
geometry,
|
|
14463
|
-
new
|
|
15628
|
+
new THREE37__namespace.MeshBasicMaterial({
|
|
14464
15629
|
color: ACCENT,
|
|
14465
15630
|
transparent: true,
|
|
14466
15631
|
opacity: 0.9,
|
|
14467
|
-
side:
|
|
15632
|
+
side: THREE37__namespace.DoubleSide,
|
|
14468
15633
|
depthTest: false
|
|
14469
15634
|
})
|
|
14470
15635
|
);
|
|
14471
15636
|
}
|
|
14472
15637
|
createDot() {
|
|
14473
|
-
const geometry = new
|
|
15638
|
+
const geometry = new THREE37__namespace.CircleGeometry(MARKER_RADIUS * 0.16, 24);
|
|
14474
15639
|
geometry.rotateX(-Math.PI / 2);
|
|
14475
|
-
return new
|
|
15640
|
+
return new THREE37__namespace.Mesh(
|
|
14476
15641
|
geometry,
|
|
14477
|
-
new
|
|
15642
|
+
new THREE37__namespace.MeshBasicMaterial({
|
|
14478
15643
|
color: ACCENT,
|
|
14479
15644
|
transparent: true,
|
|
14480
15645
|
opacity: 0.55,
|
|
14481
|
-
side:
|
|
15646
|
+
side: THREE37__namespace.DoubleSide,
|
|
14482
15647
|
depthTest: false
|
|
14483
15648
|
})
|
|
14484
15649
|
);
|
|
@@ -14589,7 +15754,7 @@ function boneDirections(joints, finger) {
|
|
|
14589
15754
|
const from = joints[chain[i - 1]];
|
|
14590
15755
|
const to = joints[chain[i]];
|
|
14591
15756
|
if (!from || !to) return null;
|
|
14592
|
-
const direction = new
|
|
15757
|
+
const direction = new THREE37__namespace.Vector3().subVectors(to, from);
|
|
14593
15758
|
if (direction.lengthSq() < 1e-12) return null;
|
|
14594
15759
|
directions.push(direction.normalize());
|
|
14595
15760
|
}
|
|
@@ -14662,8 +15827,8 @@ function computeSpread(joints, a, b) {
|
|
|
14662
15827
|
const bBase = joints[METACARPAL_JOINTS[b]];
|
|
14663
15828
|
const bTip = joints[TIP_JOINTS[b]];
|
|
14664
15829
|
if (!aBase || !aTip || !bBase || !bTip) return null;
|
|
14665
|
-
const dirA = new
|
|
14666
|
-
const dirB = new
|
|
15830
|
+
const dirA = new THREE37__namespace.Vector3().subVectors(aTip, aBase);
|
|
15831
|
+
const dirB = new THREE37__namespace.Vector3().subVectors(bTip, bBase);
|
|
14667
15832
|
if (dirA.lengthSq() < 1e-12 || dirB.lengthSq() < 1e-12) return null;
|
|
14668
15833
|
return clamp01((1 - dirA.normalize().dot(dirB.normalize())) / 0.45);
|
|
14669
15834
|
}
|
|
@@ -14673,18 +15838,18 @@ function computePalmPose(joints, handedness) {
|
|
|
14673
15838
|
const indexBase = joints["index-finger-metacarpal"];
|
|
14674
15839
|
const pinkyBase = joints["pinky-finger-metacarpal"];
|
|
14675
15840
|
if (!wrist || !indexBase || !pinkyBase) return null;
|
|
14676
|
-
const u = new
|
|
14677
|
-
const v = new
|
|
14678
|
-
const normal = new
|
|
15841
|
+
const u = new THREE37__namespace.Vector3().subVectors(indexBase, wrist);
|
|
15842
|
+
const v = new THREE37__namespace.Vector3().subVectors(pinkyBase, wrist);
|
|
15843
|
+
const normal = new THREE37__namespace.Vector3().crossVectors(u, v);
|
|
14679
15844
|
if (normal.lengthSq() < 1e-12) return null;
|
|
14680
15845
|
normal.normalize();
|
|
14681
15846
|
if (handedness === "left") normal.multiplyScalar(-1);
|
|
14682
|
-
const right = new
|
|
15847
|
+
const right = new THREE37__namespace.Vector3().subVectors(indexBase, pinkyBase);
|
|
14683
15848
|
if (right.lengthSq() < 1e-12) return null;
|
|
14684
15849
|
right.normalize();
|
|
14685
15850
|
if (handedness === "left") right.multiplyScalar(-1);
|
|
14686
|
-
const up = new
|
|
14687
|
-
const center = new
|
|
15851
|
+
const up = new THREE37__namespace.Vector3().crossVectors(normal, right).normalize();
|
|
15852
|
+
const center = new THREE37__namespace.Vector3().add(wrist).add(indexBase).add(pinkyBase).divideScalar(3);
|
|
14688
15853
|
return {
|
|
14689
15854
|
center,
|
|
14690
15855
|
normal,
|
|
@@ -14696,17 +15861,17 @@ function computePalmPose(joints, handedness) {
|
|
|
14696
15861
|
__name(computePalmPose, "computePalmPose");
|
|
14697
15862
|
function computeHandShape(joints, handedness) {
|
|
14698
15863
|
const fingers2 = {};
|
|
14699
|
-
let
|
|
15864
|
+
let tracked2 = 0;
|
|
14700
15865
|
for (const finger of XR_FINGERS) {
|
|
14701
15866
|
const curl = computeFingerCurl(joints, finger);
|
|
14702
15867
|
if (curl) {
|
|
14703
15868
|
fingers2[finger] = curl;
|
|
14704
|
-
|
|
15869
|
+
tracked2 += 1;
|
|
14705
15870
|
} else {
|
|
14706
15871
|
fingers2[finger] = { baseCurl: 0, tipCurl: 0, curl: 0 };
|
|
14707
15872
|
}
|
|
14708
15873
|
}
|
|
14709
|
-
if (
|
|
15874
|
+
if (tracked2 === 0) return null;
|
|
14710
15875
|
const pinch = {};
|
|
14711
15876
|
for (const finger of PINCH_FINGERS) {
|
|
14712
15877
|
pinch[finger] = computePinch(joints, finger) ?? 0;
|
|
@@ -14715,7 +15880,7 @@ function computeHandShape(joints, handedness) {
|
|
|
14715
15880
|
const thumbTip = joints["thumb-tip"];
|
|
14716
15881
|
let thumbDirection = null;
|
|
14717
15882
|
if (thumbBase && thumbTip) {
|
|
14718
|
-
const direction = new
|
|
15883
|
+
const direction = new THREE37__namespace.Vector3().subVectors(thumbTip, thumbBase);
|
|
14719
15884
|
if (direction.lengthSq() > 1e-12) thumbDirection = direction.normalize();
|
|
14720
15885
|
}
|
|
14721
15886
|
const fingerDirections = {};
|
|
@@ -14726,7 +15891,7 @@ function computeHandShape(joints, handedness) {
|
|
|
14726
15891
|
fingerDirections[finger] = null;
|
|
14727
15892
|
continue;
|
|
14728
15893
|
}
|
|
14729
|
-
const direction = new
|
|
15894
|
+
const direction = new THREE37__namespace.Vector3().subVectors(tip, base);
|
|
14730
15895
|
fingerDirections[finger] = direction.lengthSq() > 1e-12 ? direction.normalize() : null;
|
|
14731
15896
|
}
|
|
14732
15897
|
return {
|
|
@@ -14760,12 +15925,12 @@ function scoreAgainst(actual, target, tolerance) {
|
|
|
14760
15925
|
__name(scoreAgainst, "scoreAgainst");
|
|
14761
15926
|
var DEFAULT_DIRECTION_TOLERANCE = 45;
|
|
14762
15927
|
var WORLD_DIRECTIONS = {
|
|
14763
|
-
up: new
|
|
14764
|
-
down: new
|
|
14765
|
-
forward: new
|
|
14766
|
-
back: new
|
|
14767
|
-
left: new
|
|
14768
|
-
right: new
|
|
15928
|
+
up: new THREE37__namespace.Vector3(0, 1, 0),
|
|
15929
|
+
down: new THREE37__namespace.Vector3(0, -1, 0),
|
|
15930
|
+
forward: new THREE37__namespace.Vector3(0, 0, -1),
|
|
15931
|
+
back: new THREE37__namespace.Vector3(0, 0, 1),
|
|
15932
|
+
left: new THREE37__namespace.Vector3(-1, 0, 0),
|
|
15933
|
+
right: new THREE37__namespace.Vector3(1, 0, 0)
|
|
14769
15934
|
};
|
|
14770
15935
|
function axisVector(shape, axis) {
|
|
14771
15936
|
if (axis === "thumb") return shape.thumbDirection;
|
|
@@ -14780,7 +15945,7 @@ function resolveDirection(direction, shape, context) {
|
|
|
14780
15945
|
const head = context?.headPosition;
|
|
14781
15946
|
const origin = shape.palm?.center;
|
|
14782
15947
|
if (!head || !origin) return null;
|
|
14783
|
-
const toHead = new
|
|
15948
|
+
const toHead = new THREE37__namespace.Vector3().subVectors(head, origin);
|
|
14784
15949
|
if (toHead.lengthSq() < 1e-12) return null;
|
|
14785
15950
|
toHead.normalize();
|
|
14786
15951
|
return direction === "toward-head" ? toHead : toHead.multiplyScalar(-1);
|
|
@@ -14792,8 +15957,8 @@ function scoreDirections(actual, accepted, shape, toleranceDegrees, context) {
|
|
|
14792
15957
|
for (const direction of accepted) {
|
|
14793
15958
|
const wanted = resolveDirection(direction, shape, context);
|
|
14794
15959
|
if (!wanted) continue;
|
|
14795
|
-
const angle =
|
|
14796
|
-
Math.acos(
|
|
15960
|
+
const angle = THREE37__namespace.MathUtils.radToDeg(
|
|
15961
|
+
Math.acos(THREE37__namespace.MathUtils.clamp(actual.dot(wanted), -1, 1))
|
|
14797
15962
|
);
|
|
14798
15963
|
const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
|
|
14799
15964
|
const score = clamp01(1 - normalizedError / MATCH_FALLOFF);
|
|
@@ -14858,8 +16023,8 @@ function matchHandPose(shape, definition, context) {
|
|
|
14858
16023
|
if (!handAxis || !wanted) {
|
|
14859
16024
|
consider(0, "orientation");
|
|
14860
16025
|
} else {
|
|
14861
|
-
const angle =
|
|
14862
|
-
Math.acos(
|
|
16026
|
+
const angle = THREE37__namespace.MathUtils.radToDeg(
|
|
16027
|
+
Math.acos(THREE37__namespace.MathUtils.clamp(handAxis.dot(wanted), -1, 1))
|
|
14863
16028
|
);
|
|
14864
16029
|
const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
|
|
14865
16030
|
consider(clamp01(1 - normalizedError / MATCH_FALLOFF), "orientation");
|
|
@@ -14937,7 +16102,7 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
14937
16102
|
this.trackers = /* @__PURE__ */ new Map();
|
|
14938
16103
|
this.shapes = /* @__PURE__ */ new Map();
|
|
14939
16104
|
/** Reused so head-relative orientation checks allocate nothing per frame. */
|
|
14940
|
-
this.headPosition = new
|
|
16105
|
+
this.headPosition = new THREE37__namespace.Vector3();
|
|
14941
16106
|
this.elapsed = 0;
|
|
14942
16107
|
this.warnedNoHands = false;
|
|
14943
16108
|
this.noHandSeconds = 0;
|
|
@@ -14953,8 +16118,8 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
14953
16118
|
const entries = this.collectEntries(world);
|
|
14954
16119
|
if (entries.length === 0) return;
|
|
14955
16120
|
if (!this.warnedNoHands) {
|
|
14956
|
-
const
|
|
14957
|
-
if (
|
|
16121
|
+
const tracked2 = this.shapes.get("left") !== null || this.shapes.get("right") !== null;
|
|
16122
|
+
if (tracked2) {
|
|
14958
16123
|
this.warnedNoHands = true;
|
|
14959
16124
|
} else {
|
|
14960
16125
|
this.noHandSeconds += deltaTime;
|
|
@@ -15100,6 +16265,7 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
15100
16265
|
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
15101
16266
|
if (!interactable?.enabled) continue;
|
|
15102
16267
|
if (interactable.hoverBehavior === "none") continue;
|
|
16268
|
+
if (isUiWidget(world, entityId)) continue;
|
|
15103
16269
|
this.begin(world, entityId, interactable);
|
|
15104
16270
|
}
|
|
15105
16271
|
for (const [entityId, record] of this.records) {
|
|
@@ -15120,7 +16286,7 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
15120
16286
|
const wantsColor = interactable.hoverBehavior === "color" || interactable.hoverBehavior === "both";
|
|
15121
16287
|
this.records.set(entityId, {
|
|
15122
16288
|
shell: wantsColor ? this.addShell(world, entityId, interactable) : null,
|
|
15123
|
-
baseScale: new
|
|
16289
|
+
baseScale: new THREE37__namespace.Vector3(
|
|
15124
16290
|
transform.scale.x,
|
|
15125
16291
|
transform.scale.y,
|
|
15126
16292
|
transform.scale.z
|
|
@@ -15133,27 +16299,27 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
15133
16299
|
addShell(world, entityId, interactable) {
|
|
15134
16300
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
15135
16301
|
if (!object) return null;
|
|
15136
|
-
const material = new
|
|
15137
|
-
color: new
|
|
16302
|
+
const material = new THREE37__namespace.MeshBasicMaterial({
|
|
16303
|
+
color: new THREE37__namespace.Color(interactable.hoverColor),
|
|
15138
16304
|
// Back faces only, so the shell shows just outside the silhouette instead
|
|
15139
16305
|
// of covering the object.
|
|
15140
|
-
side:
|
|
16306
|
+
side: THREE37__namespace.BackSide,
|
|
15141
16307
|
transparent: true,
|
|
15142
16308
|
opacity: 0.85,
|
|
15143
16309
|
depthWrite: false
|
|
15144
16310
|
});
|
|
15145
|
-
const group = new
|
|
16311
|
+
const group = new THREE37__namespace.Group();
|
|
15146
16312
|
group.name = "XRHoverShell";
|
|
15147
16313
|
group.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
15148
16314
|
group.renderOrder = 998;
|
|
15149
16315
|
object.traverse((child) => {
|
|
15150
|
-
if (!(child instanceof
|
|
16316
|
+
if (!(child instanceof THREE37__namespace.Mesh) || !child.geometry) return;
|
|
15151
16317
|
if (child.userData[XR_HOVER_SHELL_FLAG]) return;
|
|
15152
|
-
const clone = new
|
|
16318
|
+
const clone = new THREE37__namespace.Mesh(child.geometry, material);
|
|
15153
16319
|
child.updateWorldMatrix(true, false);
|
|
15154
16320
|
object.updateWorldMatrix(true, false);
|
|
15155
16321
|
clone.matrixAutoUpdate = false;
|
|
15156
|
-
clone.matrix.copy(object.matrixWorld).invert().multiply(child.matrixWorld).scale(new
|
|
16322
|
+
clone.matrix.copy(object.matrixWorld).invert().multiply(child.matrixWorld).scale(new THREE37__namespace.Vector3(SHELL_INFLATE, SHELL_INFLATE, SHELL_INFLATE));
|
|
15157
16323
|
clone.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
15158
16324
|
clone.raycast = () => {
|
|
15159
16325
|
};
|
|
@@ -15202,7 +16368,7 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
15202
16368
|
if (!shell) return;
|
|
15203
16369
|
shell.parent?.remove(shell);
|
|
15204
16370
|
shell.traverse((child) => {
|
|
15205
|
-
if (child instanceof
|
|
16371
|
+
if (child instanceof THREE37__namespace.Mesh) {
|
|
15206
16372
|
const material = child.material;
|
|
15207
16373
|
if (Array.isArray(material)) {
|
|
15208
16374
|
for (const entry of material) entry.dispose();
|