@relu-interactives/spatial-ecs 0.3.9 → 0.3.11
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-CxPz8VBp.d.ts → XRHandPose-B6I4y1lj.d.ts} +117 -14
- package/dist/{XRHandPose-VuSbe4iz.d.cts → XRHandPose-C-KJeYcJ.d.cts} +117 -14
- package/dist/{chunk-KIKIWCEB.js → chunk-FSHRPY65.js} +4 -4
- package/dist/{chunk-KIKIWCEB.js.map → chunk-FSHRPY65.js.map} +1 -1
- package/dist/{chunk-W5TSYV6Q.js → chunk-KLU2M43M.js} +836 -212
- package/dist/chunk-KLU2M43M.js.map +1 -0
- package/dist/{chunk-KVGGAL5V.js → chunk-TXEGYR76.js} +26 -5
- package/dist/chunk-TXEGYR76.js.map +1 -0
- package/dist/{chunk-L5BP727H.js → chunk-Y3AC3VZ2.js} +3 -3
- package/dist/{chunk-L5BP727H.js.map → chunk-Y3AC3VZ2.js.map} +1 -1
- package/dist/components/index.cjs +23 -2
- 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/vr-and-hand-poses.md +55 -3
- package/dist/factories/index.cjs +22 -2
- 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-C7XQyrgE.d.ts → index-Bi_wIo1o.d.ts} +107 -1
- package/dist/{index-BxdXgqiI.d.ts → index-CEZp7qLL.d.ts} +9 -3
- package/dist/{index-BIQoaKAA.d.cts → index-DPRnnSI-.d.cts} +9 -3
- package/dist/{index-DyN50JZo.d.cts → index-jlgDou9W.d.cts} +107 -1
- package/dist/index.cjs +978 -331
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -5
- package/dist/index.d.ts +14 -5
- package/dist/index.js +8 -8
- package/dist/systems/index.cjs +885 -239
- 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 +3 -3
- package/package.json +1 -1
- package/dist/chunk-KVGGAL5V.js.map +0 -1
- package/dist/chunk-W5TSYV6Q.js.map +0 -1
package/dist/systems/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var THREE26 = require('three');
|
|
4
4
|
require('three/examples/jsm/utils/SkeletonUtils.js');
|
|
5
5
|
var DRACOLoader_js = require('three/examples/jsm/loaders/DRACOLoader.js');
|
|
6
6
|
var FBXLoader_js = require('three/examples/jsm/loaders/FBXLoader.js');
|
|
@@ -40,7 +40,7 @@ function _interopNamespace(e) {
|
|
|
40
40
|
return Object.freeze(n);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
var
|
|
43
|
+
var THREE26__namespace = /*#__PURE__*/_interopNamespace(THREE26);
|
|
44
44
|
|
|
45
45
|
var __defProp = Object.defineProperty;
|
|
46
46
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
@@ -101,14 +101,14 @@ var _TransformComponent = class _TransformComponent extends Component {
|
|
|
101
101
|
z: scale.z ?? 1
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
|
-
toPositionVector3(target = new
|
|
104
|
+
toPositionVector3(target = new THREE26.Vector3()) {
|
|
105
105
|
return target.set(this.position.x, this.position.y, this.position.z);
|
|
106
106
|
}
|
|
107
|
-
toRotationEuler(target = new
|
|
107
|
+
toRotationEuler(target = new THREE26.Euler(), order = "XYZ") {
|
|
108
108
|
return target.set(this.rotation.x, this.rotation.y, this.rotation.z, order);
|
|
109
109
|
}
|
|
110
|
-
toRotationQuaternion(target = new
|
|
111
|
-
const euler = new
|
|
110
|
+
toRotationQuaternion(target = new THREE26.Quaternion(), order = "XYZ") {
|
|
111
|
+
const euler = new THREE26.Euler(
|
|
112
112
|
this.rotation.x,
|
|
113
113
|
this.rotation.y,
|
|
114
114
|
this.rotation.z,
|
|
@@ -116,7 +116,7 @@ var _TransformComponent = class _TransformComponent extends Component {
|
|
|
116
116
|
);
|
|
117
117
|
return target.setFromEuler(euler);
|
|
118
118
|
}
|
|
119
|
-
toScaleVector3(target = new
|
|
119
|
+
toScaleVector3(target = new THREE26.Vector3()) {
|
|
120
120
|
return target.set(this.scale.x, this.scale.y, this.scale.z);
|
|
121
121
|
}
|
|
122
122
|
setPosition(input) {
|
|
@@ -134,8 +134,8 @@ var _TransformComponent = class _TransformComponent extends Component {
|
|
|
134
134
|
return this;
|
|
135
135
|
}
|
|
136
136
|
setRotation(input, order = "XYZ") {
|
|
137
|
-
if (input instanceof
|
|
138
|
-
const euler = new
|
|
137
|
+
if (input instanceof THREE26.Quaternion) {
|
|
138
|
+
const euler = new THREE26.Euler().setFromQuaternion(input, order);
|
|
139
139
|
this.rotation.x = euler.x;
|
|
140
140
|
this.rotation.y = euler.y;
|
|
141
141
|
this.rotation.z = euler.z;
|
|
@@ -184,10 +184,10 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
|
|
|
184
184
|
}
|
|
185
185
|
getOrCreateAudioListener() {
|
|
186
186
|
const existing = this.camera.userData.ecsAudioListener;
|
|
187
|
-
if (existing instanceof
|
|
187
|
+
if (existing instanceof THREE26__namespace.AudioListener) {
|
|
188
188
|
return existing;
|
|
189
189
|
}
|
|
190
|
-
const listener = new
|
|
190
|
+
const listener = new THREE26__namespace.AudioListener();
|
|
191
191
|
this.camera.add(listener);
|
|
192
192
|
this.camera.userData.ecsAudioListener = listener;
|
|
193
193
|
return listener;
|
|
@@ -261,7 +261,7 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
|
|
|
261
261
|
}
|
|
262
262
|
if (dispose && object3d) {
|
|
263
263
|
object3d.traverse((child) => {
|
|
264
|
-
if (child instanceof
|
|
264
|
+
if (child instanceof THREE26__namespace.Mesh) {
|
|
265
265
|
if (!child.geometry?.userData?.[SHARED_MODEL_RESOURCE_FLAG]) {
|
|
266
266
|
child.geometry?.dispose();
|
|
267
267
|
}
|
|
@@ -641,14 +641,14 @@ var _AnimationComponent = class _AnimationComponent extends Component {
|
|
|
641
641
|
return;
|
|
642
642
|
}
|
|
643
643
|
this.importedClips = clips.map((entry) => {
|
|
644
|
-
if (entry instanceof
|
|
644
|
+
if (entry instanceof THREE26__namespace.AnimationClip) {
|
|
645
645
|
return { clip: entry, sourceUrl: null };
|
|
646
646
|
}
|
|
647
647
|
if (!entry || typeof entry !== "object") {
|
|
648
648
|
return null;
|
|
649
649
|
}
|
|
650
650
|
const candidate = entry;
|
|
651
|
-
if (!(candidate.clip instanceof
|
|
651
|
+
if (!(candidate.clip instanceof THREE26__namespace.AnimationClip)) {
|
|
652
652
|
return null;
|
|
653
653
|
}
|
|
654
654
|
return {
|
|
@@ -782,7 +782,7 @@ var DEFAULT_ORTHO_TOP = 5;
|
|
|
782
782
|
var DEFAULT_ORTHO_BOTTOM = -5;
|
|
783
783
|
var DEFAULT_ZOOM = 1;
|
|
784
784
|
function inferProjection(camera) {
|
|
785
|
-
if (camera instanceof
|
|
785
|
+
if (camera instanceof THREE26__namespace.OrthographicCamera) {
|
|
786
786
|
return "orthographic";
|
|
787
787
|
}
|
|
788
788
|
return "perspective";
|
|
@@ -803,7 +803,7 @@ function readCameraFar(camera) {
|
|
|
803
803
|
}
|
|
804
804
|
__name(readCameraFar, "readCameraFar");
|
|
805
805
|
function inferFov(camera) {
|
|
806
|
-
if (camera instanceof
|
|
806
|
+
if (camera instanceof THREE26__namespace.PerspectiveCamera && Number.isFinite(camera.fov)) {
|
|
807
807
|
return camera.fov;
|
|
808
808
|
}
|
|
809
809
|
return DEFAULT_FOV;
|
|
@@ -826,28 +826,28 @@ function inferFar(camera) {
|
|
|
826
826
|
}
|
|
827
827
|
__name(inferFar, "inferFar");
|
|
828
828
|
function inferOrthoLeft(camera) {
|
|
829
|
-
if (camera instanceof
|
|
829
|
+
if (camera instanceof THREE26__namespace.OrthographicCamera && Number.isFinite(camera.left)) {
|
|
830
830
|
return camera.left;
|
|
831
831
|
}
|
|
832
832
|
return DEFAULT_ORTHO_LEFT;
|
|
833
833
|
}
|
|
834
834
|
__name(inferOrthoLeft, "inferOrthoLeft");
|
|
835
835
|
function inferOrthoRight(camera) {
|
|
836
|
-
if (camera instanceof
|
|
836
|
+
if (camera instanceof THREE26__namespace.OrthographicCamera && Number.isFinite(camera.right)) {
|
|
837
837
|
return camera.right;
|
|
838
838
|
}
|
|
839
839
|
return DEFAULT_ORTHO_RIGHT;
|
|
840
840
|
}
|
|
841
841
|
__name(inferOrthoRight, "inferOrthoRight");
|
|
842
842
|
function inferOrthoTop(camera) {
|
|
843
|
-
if (camera instanceof
|
|
843
|
+
if (camera instanceof THREE26__namespace.OrthographicCamera && Number.isFinite(camera.top)) {
|
|
844
844
|
return camera.top;
|
|
845
845
|
}
|
|
846
846
|
return DEFAULT_ORTHO_TOP;
|
|
847
847
|
}
|
|
848
848
|
__name(inferOrthoTop, "inferOrthoTop");
|
|
849
849
|
function inferOrthoBottom(camera) {
|
|
850
|
-
if (camera instanceof
|
|
850
|
+
if (camera instanceof THREE26__namespace.OrthographicCamera && Number.isFinite(camera.bottom)) {
|
|
851
851
|
return camera.bottom;
|
|
852
852
|
}
|
|
853
853
|
return DEFAULT_ORTHO_BOTTOM;
|
|
@@ -863,7 +863,7 @@ __name(inferZoom, "inferZoom");
|
|
|
863
863
|
var _CameraComponent = class _CameraComponent extends Component {
|
|
864
864
|
constructor(payload = {}) {
|
|
865
865
|
super();
|
|
866
|
-
this.camera = payload.camera ?? new
|
|
866
|
+
this.camera = payload.camera ?? new THREE26__namespace.PerspectiveCamera();
|
|
867
867
|
this.type = payload.type ?? "3d";
|
|
868
868
|
this.isDefault = typeof payload.isDefault === "boolean" ? payload.isDefault : false;
|
|
869
869
|
this.projection = payload.projection ?? inferProjection(payload.camera);
|
|
@@ -1666,15 +1666,15 @@ function createValueState(light) {
|
|
|
1666
1666
|
castShadow: light.castShadow ?? false,
|
|
1667
1667
|
frustumCulling: light.frustumCulled
|
|
1668
1668
|
};
|
|
1669
|
-
if (light instanceof
|
|
1669
|
+
if (light instanceof THREE26__namespace.PointLight) {
|
|
1670
1670
|
base.distance = light.distance;
|
|
1671
1671
|
base.decay = light.decay;
|
|
1672
|
-
} else if (light instanceof
|
|
1672
|
+
} else if (light instanceof THREE26__namespace.SpotLight) {
|
|
1673
1673
|
base.distance = light.distance;
|
|
1674
1674
|
base.decay = light.decay;
|
|
1675
1675
|
base.angle = light.angle;
|
|
1676
1676
|
base.penumbra = light.penumbra;
|
|
1677
|
-
} else if (light instanceof
|
|
1677
|
+
} else if (light instanceof THREE26__namespace.RectAreaLight) {
|
|
1678
1678
|
base.width = light.width;
|
|
1679
1679
|
base.height = light.height;
|
|
1680
1680
|
}
|
|
@@ -1709,13 +1709,13 @@ function toHexColor2(value, fallback) {
|
|
|
1709
1709
|
}
|
|
1710
1710
|
__name(toHexColor2, "toHexColor");
|
|
1711
1711
|
function getMaterialType(material) {
|
|
1712
|
-
if (material instanceof
|
|
1712
|
+
if (material instanceof THREE26__namespace.MeshPhysicalMaterial) {
|
|
1713
1713
|
return "physical";
|
|
1714
1714
|
}
|
|
1715
|
-
if (material instanceof
|
|
1715
|
+
if (material instanceof THREE26__namespace.MeshPhongMaterial) {
|
|
1716
1716
|
return "phong";
|
|
1717
1717
|
}
|
|
1718
|
-
if (material instanceof
|
|
1718
|
+
if (material instanceof THREE26__namespace.MeshBasicMaterial) {
|
|
1719
1719
|
return "basic";
|
|
1720
1720
|
}
|
|
1721
1721
|
return "standard";
|
|
@@ -1750,8 +1750,8 @@ function createMaterialValue(material) {
|
|
|
1750
1750
|
opacity: typeof materialRecord.opacity === "number" ? materialRecord.opacity : 1,
|
|
1751
1751
|
emissive: toHexColor2(materialRecord.emissive, "#000000"),
|
|
1752
1752
|
emissiveIntensity: typeof materialRecord.emissiveIntensity === "number" ? materialRecord.emissiveIntensity : 0,
|
|
1753
|
-
side: typeof materialRecord.side === "number" ? materialRecord.side :
|
|
1754
|
-
blending: typeof materialRecord.blending === "number" ? materialRecord.blending :
|
|
1753
|
+
side: typeof materialRecord.side === "number" ? materialRecord.side : THREE26__namespace.FrontSide,
|
|
1754
|
+
blending: typeof materialRecord.blending === "number" ? materialRecord.blending : THREE26__namespace.NormalBlending,
|
|
1755
1755
|
depthTest: materialRecord.depthTest !== false,
|
|
1756
1756
|
depthWrite: materialRecord.depthWrite !== false,
|
|
1757
1757
|
wireframe: Boolean(materialRecord.wireframe),
|
|
@@ -1783,7 +1783,7 @@ function createMaterialValue(material) {
|
|
|
1783
1783
|
materialRecord.lightMap
|
|
1784
1784
|
),
|
|
1785
1785
|
envMap: textureImageSrc(materialRecord.envMap),
|
|
1786
|
-
textureFiltering: map?.magFilter ===
|
|
1786
|
+
textureFiltering: map?.magFilter === THREE26__namespace.NearestFilter ? "sharp" : "smooth",
|
|
1787
1787
|
useMipmaps: map?.generateMipmaps !== false
|
|
1788
1788
|
};
|
|
1789
1789
|
}
|
|
@@ -1798,8 +1798,8 @@ function defaultMaterialValue() {
|
|
|
1798
1798
|
opacity: 1,
|
|
1799
1799
|
emissive: "#000000",
|
|
1800
1800
|
emissiveIntensity: 0,
|
|
1801
|
-
side:
|
|
1802
|
-
blending:
|
|
1801
|
+
side: THREE26__namespace.FrontSide,
|
|
1802
|
+
blending: THREE26__namespace.NormalBlending,
|
|
1803
1803
|
depthTest: true,
|
|
1804
1804
|
depthWrite: true,
|
|
1805
1805
|
wireframe: false,
|
|
@@ -2098,7 +2098,6 @@ var _XRInteractableComponent = class _XRInteractableComponent extends Component
|
|
|
2098
2098
|
this.enabled = options?.enabled ?? true;
|
|
2099
2099
|
this.grabbable = options?.grabbable ?? true;
|
|
2100
2100
|
this.pointable = options?.pointable ?? true;
|
|
2101
|
-
this.grabMode = options?.grabMode ?? "kinematic";
|
|
2102
2101
|
this.grabReach = options?.grabReach ?? "both";
|
|
2103
2102
|
this.distanceBehavior = options?.distanceBehavior ?? "snap";
|
|
2104
2103
|
this.grabGesture = options?.grabGesture ?? "any";
|
|
@@ -2113,13 +2112,34 @@ var _XRInteractableComponent = class _XRInteractableComponent extends Component
|
|
|
2113
2112
|
y: 0,
|
|
2114
2113
|
z: 0
|
|
2115
2114
|
};
|
|
2115
|
+
this.grabHands = options?.grabHands ?? "handOff";
|
|
2116
|
+
this.twoHandRotation = options?.twoHandRotation ?? "align";
|
|
2117
|
+
this.allowTwoHandScale = options?.allowTwoHandScale ?? false;
|
|
2118
|
+
this.minScale = options?.minScale ?? 0.25;
|
|
2119
|
+
this.maxScale = options?.maxScale ?? 4;
|
|
2120
|
+
this.attachPoints = (options?.attachPoints ?? []).map(
|
|
2121
|
+
(point) => createAttachPoint(point)
|
|
2122
|
+
);
|
|
2116
2123
|
this.throwOnRelease = options?.throwOnRelease ?? true;
|
|
2117
2124
|
this.throwStrength = options?.throwStrength ?? 1;
|
|
2118
|
-
this.
|
|
2125
|
+
this.hoverBehavior = options?.hoverBehavior ?? "color";
|
|
2126
|
+
this.hoverColor = options?.hoverColor ?? "#4da3ff";
|
|
2127
|
+
this.hoverScale = options?.hoverScale ?? 1.06;
|
|
2119
2128
|
}
|
|
2120
2129
|
};
|
|
2121
2130
|
__name(_XRInteractableComponent, "XRInteractableComponent");
|
|
2122
2131
|
var XRInteractableComponent = _XRInteractableComponent;
|
|
2132
|
+
function createAttachPoint(partial) {
|
|
2133
|
+
return {
|
|
2134
|
+
id: partial.id,
|
|
2135
|
+
name: partial.name ?? partial.id,
|
|
2136
|
+
position: { x: 0, y: 0, z: 0, ...partial.position },
|
|
2137
|
+
rotation: { x: 0, y: 0, z: 0, ...partial.rotation },
|
|
2138
|
+
hand: partial.hand ?? "any",
|
|
2139
|
+
role: partial.role ?? "any"
|
|
2140
|
+
};
|
|
2141
|
+
}
|
|
2142
|
+
__name(createAttachPoint, "createAttachPoint");
|
|
2123
2143
|
|
|
2124
2144
|
// core/components/XRRig.ts
|
|
2125
2145
|
var _XRRigComponent = class _XRRigComponent extends Component {
|
|
@@ -2525,7 +2545,7 @@ function transitionToClip(runtime, nextClipId, crossFadeDuration) {
|
|
|
2525
2545
|
}
|
|
2526
2546
|
__name(transitionToClip, "transitionToClip");
|
|
2527
2547
|
function applyActionState(action, component, paused, shouldLoop) {
|
|
2528
|
-
const loopMode = shouldLoop ?
|
|
2548
|
+
const loopMode = shouldLoop ? THREE26__namespace.LoopRepeat : THREE26__namespace.LoopOnce;
|
|
2529
2549
|
const repetitions = shouldLoop ? Infinity : 1;
|
|
2530
2550
|
action.setLoop(loopMode, repetitions);
|
|
2531
2551
|
action.clampWhenFinished = !shouldLoop;
|
|
@@ -2698,7 +2718,7 @@ var _AnimationSystem = class _AnimationSystem {
|
|
|
2698
2718
|
if (runtime) {
|
|
2699
2719
|
stopAllActions(runtime);
|
|
2700
2720
|
}
|
|
2701
|
-
const mixer = new
|
|
2721
|
+
const mixer = new THREE26__namespace.AnimationMixer(root);
|
|
2702
2722
|
const entries2 = readRuntimeClipEntries(animation);
|
|
2703
2723
|
const indexedActions = createActions(mixer, entries2);
|
|
2704
2724
|
runtime = {
|
|
@@ -2824,11 +2844,11 @@ function normalizeOrthoBounds(component) {
|
|
|
2824
2844
|
}
|
|
2825
2845
|
__name(normalizeOrthoBounds, "normalizeOrthoBounds");
|
|
2826
2846
|
function isPerspectiveCamera(camera) {
|
|
2827
|
-
return camera instanceof
|
|
2847
|
+
return camera instanceof THREE26__namespace.PerspectiveCamera;
|
|
2828
2848
|
}
|
|
2829
2849
|
__name(isPerspectiveCamera, "isPerspectiveCamera");
|
|
2830
2850
|
function isOrthographicCamera(camera) {
|
|
2831
|
-
return camera instanceof
|
|
2851
|
+
return camera instanceof THREE26__namespace.OrthographicCamera;
|
|
2832
2852
|
}
|
|
2833
2853
|
__name(isOrthographicCamera, "isOrthographicCamera");
|
|
2834
2854
|
function readWindowAspect() {
|
|
@@ -2882,7 +2902,7 @@ var _CameraSyncSystem = class _CameraSyncSystem {
|
|
|
2882
2902
|
continue;
|
|
2883
2903
|
}
|
|
2884
2904
|
const camera = objectRef.object;
|
|
2885
|
-
if (!(camera instanceof
|
|
2905
|
+
if (!(camera instanceof THREE26__namespace.Camera)) {
|
|
2886
2906
|
continue;
|
|
2887
2907
|
}
|
|
2888
2908
|
if (xrCamera !== null && camera === xrCamera) {
|
|
@@ -2949,7 +2969,7 @@ var MIN_DENSITY = 0;
|
|
|
2949
2969
|
function createGradientTexture(effect, colors) {
|
|
2950
2970
|
if (typeof document === "undefined") {
|
|
2951
2971
|
const pixel = new Uint8Array([30, 30, 30, 255]);
|
|
2952
|
-
const fallback = new
|
|
2972
|
+
const fallback = new THREE26__namespace.DataTexture(pixel, 1, 1, THREE26__namespace.RGBAFormat);
|
|
2953
2973
|
fallback.needsUpdate = true;
|
|
2954
2974
|
return fallback;
|
|
2955
2975
|
}
|
|
@@ -2958,7 +2978,7 @@ function createGradientTexture(effect, colors) {
|
|
|
2958
2978
|
canvas.height = 512;
|
|
2959
2979
|
const context = canvas.getContext("2d");
|
|
2960
2980
|
if (!context) {
|
|
2961
|
-
const fallback = new
|
|
2981
|
+
const fallback = new THREE26__namespace.CanvasTexture(canvas);
|
|
2962
2982
|
fallback.needsUpdate = true;
|
|
2963
2983
|
return fallback;
|
|
2964
2984
|
}
|
|
@@ -2986,15 +3006,15 @@ function createGradientTexture(effect, colors) {
|
|
|
2986
3006
|
context.fillRect(0, 0, 512, 512);
|
|
2987
3007
|
context.globalCompositeOperation = "source-over";
|
|
2988
3008
|
}
|
|
2989
|
-
const texture = new
|
|
2990
|
-
texture.colorSpace =
|
|
3009
|
+
const texture = new THREE26__namespace.CanvasTexture(canvas);
|
|
3010
|
+
texture.colorSpace = THREE26__namespace.SRGBColorSpace;
|
|
2991
3011
|
texture.needsUpdate = true;
|
|
2992
3012
|
return texture;
|
|
2993
3013
|
}
|
|
2994
3014
|
__name(createGradientTexture, "createGradientTexture");
|
|
2995
3015
|
var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
2996
3016
|
constructor(scene) {
|
|
2997
|
-
this.textureLoader = new
|
|
3017
|
+
this.textureLoader = new THREE26__namespace.TextureLoader();
|
|
2998
3018
|
this.signature = null;
|
|
2999
3019
|
this.activeTexture = null;
|
|
3000
3020
|
this.pendingImageUrl = null;
|
|
@@ -3017,7 +3037,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
3017
3037
|
if (skybox.type === "color") {
|
|
3018
3038
|
this.disposeActiveTexture();
|
|
3019
3039
|
this.pendingImageUrl = null;
|
|
3020
|
-
this.scene.background = new
|
|
3040
|
+
this.scene.background = new THREE26__namespace.Color(skybox.color || "#1e1e1e");
|
|
3021
3041
|
return;
|
|
3022
3042
|
}
|
|
3023
3043
|
if (skybox.type === "gradient") {
|
|
@@ -3051,7 +3071,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
3051
3071
|
texture.dispose();
|
|
3052
3072
|
return;
|
|
3053
3073
|
}
|
|
3054
|
-
texture.colorSpace =
|
|
3074
|
+
texture.colorSpace = THREE26__namespace.SRGBColorSpace;
|
|
3055
3075
|
this.activeTexture = texture;
|
|
3056
3076
|
this.scene.background = texture;
|
|
3057
3077
|
},
|
|
@@ -3070,16 +3090,16 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
3070
3090
|
this.scene.fog = null;
|
|
3071
3091
|
return;
|
|
3072
3092
|
}
|
|
3073
|
-
const fogColor = new
|
|
3093
|
+
const fogColor = new THREE26__namespace.Color(fog.color || "#1e1e1e");
|
|
3074
3094
|
if (fog.type === "linear") {
|
|
3075
3095
|
const near = Number.isFinite(fog.linear.near) ? fog.linear.near : 1;
|
|
3076
3096
|
const farCandidate = Number.isFinite(fog.linear.far) ? fog.linear.far : near + 10;
|
|
3077
3097
|
const far = Math.max(near + MIN_FOG_DELTA, farCandidate);
|
|
3078
|
-
this.scene.fog = new
|
|
3098
|
+
this.scene.fog = new THREE26__namespace.Fog(fogColor, near, far);
|
|
3079
3099
|
return;
|
|
3080
3100
|
}
|
|
3081
3101
|
const density = Number.isFinite(fog.exponential.density) ? Math.max(MIN_DENSITY, fog.exponential.density) : 2e-3;
|
|
3082
|
-
this.scene.fog = new
|
|
3102
|
+
this.scene.fog = new THREE26__namespace.FogExp2(fogColor, density);
|
|
3083
3103
|
}
|
|
3084
3104
|
update(world) {
|
|
3085
3105
|
const entityIds = world.query(Environment);
|
|
@@ -3161,10 +3181,10 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
3161
3181
|
);
|
|
3162
3182
|
}
|
|
3163
3183
|
if (values.bloom.enabled) {
|
|
3164
|
-
const size = this.renderer.getSize(new
|
|
3184
|
+
const size = this.renderer.getSize(new THREE26__namespace.Vector2());
|
|
3165
3185
|
composer.addPass(
|
|
3166
3186
|
new UnrealBloomPass_js.UnrealBloomPass(
|
|
3167
|
-
new
|
|
3187
|
+
new THREE26__namespace.Vector2(size.width, size.height),
|
|
3168
3188
|
values.bloom.intensity,
|
|
3169
3189
|
values.bloom.radius,
|
|
3170
3190
|
values.bloom.threshold
|
|
@@ -3209,7 +3229,7 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
3209
3229
|
if (values.dotScreen.enabled) {
|
|
3210
3230
|
composer.addPass(
|
|
3211
3231
|
new DotScreenPass_js.DotScreenPass(
|
|
3212
|
-
new
|
|
3232
|
+
new THREE26__namespace.Vector2(0, 0),
|
|
3213
3233
|
values.dotScreen.angle ?? values.dotScreen.dotScreenAngle,
|
|
3214
3234
|
values.dotScreen.scale ?? values.dotScreen.dotScreenScale
|
|
3215
3235
|
)
|
|
@@ -3266,6 +3286,20 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
3266
3286
|
__name(_PostprocessingSyncSystem, "PostprocessingSyncSystem");
|
|
3267
3287
|
var PostprocessingSyncSystem = _PostprocessingSyncSystem;
|
|
3268
3288
|
var MIN_SIZE = 1e-4;
|
|
3289
|
+
function toBodyType(RAPIER, bodyType) {
|
|
3290
|
+
switch (bodyType) {
|
|
3291
|
+
case "fixed":
|
|
3292
|
+
return RAPIER.RigidBodyType.Fixed;
|
|
3293
|
+
case "kinematicPosition":
|
|
3294
|
+
return RAPIER.RigidBodyType.KinematicPositionBased;
|
|
3295
|
+
case "kinematicVelocity":
|
|
3296
|
+
return RAPIER.RigidBodyType.KinematicVelocityBased;
|
|
3297
|
+
case "dynamic":
|
|
3298
|
+
default:
|
|
3299
|
+
return RAPIER.RigidBodyType.Dynamic;
|
|
3300
|
+
}
|
|
3301
|
+
}
|
|
3302
|
+
__name(toBodyType, "toBodyType");
|
|
3269
3303
|
function createRigidBodyDesc(RAPIER, bodyType) {
|
|
3270
3304
|
if (bodyType === "fixed") {
|
|
3271
3305
|
return RAPIER.RigidBodyDesc.fixed();
|
|
@@ -3283,7 +3317,7 @@ function computeColliderState(colliderValues, object) {
|
|
|
3283
3317
|
if (!object) {
|
|
3284
3318
|
return colliderValues;
|
|
3285
3319
|
}
|
|
3286
|
-
const scale = new
|
|
3320
|
+
const scale = new THREE26__namespace.Vector3();
|
|
3287
3321
|
object.getWorldScale(scale);
|
|
3288
3322
|
return {
|
|
3289
3323
|
...colliderValues,
|
|
@@ -3334,8 +3368,8 @@ function createColliderDesc(RAPIER, values, triMeshData) {
|
|
|
3334
3368
|
values.offsetPosition.y,
|
|
3335
3369
|
values.offsetPosition.z
|
|
3336
3370
|
);
|
|
3337
|
-
const offsetQuaternion = new
|
|
3338
|
-
new
|
|
3371
|
+
const offsetQuaternion = new THREE26__namespace.Quaternion().setFromEuler(
|
|
3372
|
+
new THREE26__namespace.Euler(
|
|
3339
3373
|
values.offsetRotation.x,
|
|
3340
3374
|
values.offsetRotation.y,
|
|
3341
3375
|
values.offsetRotation.z
|
|
@@ -3350,17 +3384,17 @@ function collectTriMeshParts(object) {
|
|
|
3350
3384
|
return null;
|
|
3351
3385
|
}
|
|
3352
3386
|
object.updateWorldMatrix(true, true);
|
|
3353
|
-
const worldScale = new
|
|
3387
|
+
const worldScale = new THREE26__namespace.Vector3();
|
|
3354
3388
|
object.getWorldScale(worldScale);
|
|
3355
3389
|
const scale = {
|
|
3356
3390
|
x: Math.abs(worldScale.x) || 1,
|
|
3357
3391
|
y: Math.abs(worldScale.y) || 1,
|
|
3358
3392
|
z: Math.abs(worldScale.z) || 1
|
|
3359
3393
|
};
|
|
3360
|
-
const worldToObject = new
|
|
3394
|
+
const worldToObject = new THREE26__namespace.Matrix4().copy(object.matrixWorld).invert();
|
|
3361
3395
|
const parts = [];
|
|
3362
3396
|
object.traverse((child) => {
|
|
3363
|
-
if (!(child instanceof
|
|
3397
|
+
if (!(child instanceof THREE26__namespace.Mesh) || !child.geometry) {
|
|
3364
3398
|
return;
|
|
3365
3399
|
}
|
|
3366
3400
|
const geometry = child.geometry;
|
|
@@ -3377,7 +3411,7 @@ function collectTriMeshParts(object) {
|
|
|
3377
3411
|
if (indexCount < 3) {
|
|
3378
3412
|
return;
|
|
3379
3413
|
}
|
|
3380
|
-
const relativeMatrix = new
|
|
3414
|
+
const relativeMatrix = new THREE26__namespace.Matrix4().multiplyMatrices(
|
|
3381
3415
|
worldToObject,
|
|
3382
3416
|
child.matrixWorld
|
|
3383
3417
|
);
|
|
@@ -3418,7 +3452,7 @@ function createTriMeshData(collected) {
|
|
|
3418
3452
|
}
|
|
3419
3453
|
const vertices = new Float32Array(vertexTotal * 3);
|
|
3420
3454
|
const indices = new Uint32Array(indexTotal);
|
|
3421
|
-
const point = new
|
|
3455
|
+
const point = new THREE26__namespace.Vector3();
|
|
3422
3456
|
let vertexOffset = 0;
|
|
3423
3457
|
let indexOffset = 0;
|
|
3424
3458
|
for (const part of parts) {
|
|
@@ -3450,8 +3484,8 @@ function createTriMeshData(collected) {
|
|
|
3450
3484
|
}
|
|
3451
3485
|
__name(createTriMeshData, "createTriMeshData");
|
|
3452
3486
|
function syncBodyFromTransform(body, transform) {
|
|
3453
|
-
const quaternion = new
|
|
3454
|
-
new
|
|
3487
|
+
const quaternion = new THREE26__namespace.Quaternion().setFromEuler(
|
|
3488
|
+
new THREE26__namespace.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z)
|
|
3455
3489
|
);
|
|
3456
3490
|
body.setTranslation(
|
|
3457
3491
|
{
|
|
@@ -3478,8 +3512,8 @@ function syncTransformFromBody(transform, body) {
|
|
|
3478
3512
|
transform.position.x = position.x;
|
|
3479
3513
|
transform.position.y = position.y;
|
|
3480
3514
|
transform.position.z = position.z;
|
|
3481
|
-
const euler = new
|
|
3482
|
-
new
|
|
3515
|
+
const euler = new THREE26__namespace.Euler().setFromQuaternion(
|
|
3516
|
+
new THREE26__namespace.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w)
|
|
3483
3517
|
);
|
|
3484
3518
|
transform.rotation.x = euler.x;
|
|
3485
3519
|
transform.rotation.y = euler.y;
|
|
@@ -3564,7 +3598,8 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
|
|
|
3564
3598
|
setPhysicsLiveRef(physics, "collider", null);
|
|
3565
3599
|
continue;
|
|
3566
3600
|
}
|
|
3567
|
-
const
|
|
3601
|
+
const { type: _desiredBodyType, ...rigidBodyRebuildValues } = physics.values.rigidbody;
|
|
3602
|
+
const rigidBodySignature = JSON.stringify(rigidBodyRebuildValues);
|
|
3568
3603
|
const previousRigidBodySignature = this.rigidBodySignatures.get(entityId);
|
|
3569
3604
|
const hasRigidBody = this.rigidBodyHandles.has(entityId);
|
|
3570
3605
|
const shouldRecreateBody = !hasRigidBody || previousRigidBodySignature !== rigidBodySignature;
|
|
@@ -3591,8 +3626,8 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
|
|
|
3591
3626
|
transform.position.y,
|
|
3592
3627
|
transform.position.z
|
|
3593
3628
|
);
|
|
3594
|
-
const quaternion = new
|
|
3595
|
-
new
|
|
3629
|
+
const quaternion = new THREE26__namespace.Quaternion().setFromEuler(
|
|
3630
|
+
new THREE26__namespace.Euler(
|
|
3596
3631
|
transform.rotation.x,
|
|
3597
3632
|
transform.rotation.y,
|
|
3598
3633
|
transform.rotation.z
|
|
@@ -3619,6 +3654,25 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
|
|
|
3619
3654
|
continue;
|
|
3620
3655
|
}
|
|
3621
3656
|
setPhysicsLiveRef(physics, "rigidBody", body);
|
|
3657
|
+
const desiredBodyType = this.isEditorMode ? "fixed" : physics.values.rigidbody.type;
|
|
3658
|
+
const desiredRapierType = toBodyType(this.rapier, desiredBodyType);
|
|
3659
|
+
if (body.bodyType() !== desiredRapierType) {
|
|
3660
|
+
body.setBodyType(desiredRapierType, true);
|
|
3661
|
+
if (!this.isEditorMode && desiredBodyType === "dynamic") {
|
|
3662
|
+
body.setAdditionalMass(physics.values.rigidbody.mass, true);
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
const pending = physics.pendingVelocity;
|
|
3666
|
+
if (pending) {
|
|
3667
|
+
setPhysicsLiveRef(physics, "pendingVelocity", null);
|
|
3668
|
+
if (!this.isEditorMode && desiredBodyType === "dynamic") {
|
|
3669
|
+
try {
|
|
3670
|
+
body.setLinvel(pending.linear, true);
|
|
3671
|
+
body.setAngvel(pending.angular, true);
|
|
3672
|
+
} catch {
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3622
3676
|
if (this.isEditorMode || physics.values.rigidbody.type !== "dynamic") {
|
|
3623
3677
|
syncBodyFromTransform(body, transform);
|
|
3624
3678
|
}
|
|
@@ -4171,7 +4225,7 @@ function applyLightValues(lightComponent) {
|
|
|
4171
4225
|
values.castShadow
|
|
4172
4226
|
);
|
|
4173
4227
|
}
|
|
4174
|
-
if (light instanceof
|
|
4228
|
+
if (light instanceof THREE26__namespace.PointLight) {
|
|
4175
4229
|
if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
|
|
4176
4230
|
light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
|
|
4177
4231
|
}
|
|
@@ -4179,7 +4233,7 @@ function applyLightValues(lightComponent) {
|
|
|
4179
4233
|
light.decay = Math.max(0, values.decay);
|
|
4180
4234
|
}
|
|
4181
4235
|
}
|
|
4182
|
-
if (light instanceof
|
|
4236
|
+
if (light instanceof THREE26__namespace.SpotLight) {
|
|
4183
4237
|
if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
|
|
4184
4238
|
light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
|
|
4185
4239
|
}
|
|
@@ -4193,7 +4247,7 @@ function applyLightValues(lightComponent) {
|
|
|
4193
4247
|
light.penumbra = Math.max(0, Math.min(1, values.penumbra));
|
|
4194
4248
|
}
|
|
4195
4249
|
}
|
|
4196
|
-
if (light instanceof
|
|
4250
|
+
if (light instanceof THREE26__namespace.RectAreaLight) {
|
|
4197
4251
|
if (typeof values.width === "number" && Number.isFinite(values.width)) {
|
|
4198
4252
|
light.width = Math.max(MIN_AREA_SIZE, values.width);
|
|
4199
4253
|
}
|
|
@@ -4254,15 +4308,15 @@ function resolveMaterialPropertyKey(key) {
|
|
|
4254
4308
|
__name(resolveMaterialPropertyKey, "resolveMaterialPropertyKey");
|
|
4255
4309
|
function createMaterialByType(type) {
|
|
4256
4310
|
if (type === "basic") {
|
|
4257
|
-
return new
|
|
4311
|
+
return new THREE26__namespace.MeshBasicMaterial();
|
|
4258
4312
|
}
|
|
4259
4313
|
if (type === "phong") {
|
|
4260
|
-
return new
|
|
4314
|
+
return new THREE26__namespace.MeshPhongMaterial();
|
|
4261
4315
|
}
|
|
4262
4316
|
if (type === "physical") {
|
|
4263
|
-
return new
|
|
4317
|
+
return new THREE26__namespace.MeshPhysicalMaterial();
|
|
4264
4318
|
}
|
|
4265
|
-
return new
|
|
4319
|
+
return new THREE26__namespace.MeshStandardMaterial();
|
|
4266
4320
|
}
|
|
4267
4321
|
__name(createMaterialByType, "createMaterialByType");
|
|
4268
4322
|
function replaceMaterialAcrossObject(object, previous, next) {
|
|
@@ -4321,12 +4375,12 @@ function applyTextureFiltering(material, filtering) {
|
|
|
4321
4375
|
const target = material;
|
|
4322
4376
|
for (const slot of materialTextureSlots) {
|
|
4323
4377
|
const texture = target[slot];
|
|
4324
|
-
if (!texture || !(texture instanceof
|
|
4378
|
+
if (!texture || !(texture instanceof THREE26__namespace.Texture)) {
|
|
4325
4379
|
continue;
|
|
4326
4380
|
}
|
|
4327
4381
|
const useMipmaps = texture.generateMipmaps !== false;
|
|
4328
|
-
texture.magFilter = sharp ?
|
|
4329
|
-
texture.minFilter = useMipmaps ? sharp ?
|
|
4382
|
+
texture.magFilter = sharp ? THREE26__namespace.NearestFilter : THREE26__namespace.LinearFilter;
|
|
4383
|
+
texture.minFilter = useMipmaps ? sharp ? THREE26__namespace.NearestMipmapNearestFilter : THREE26__namespace.LinearMipmapLinearFilter : sharp ? THREE26__namespace.NearestFilter : THREE26__namespace.LinearFilter;
|
|
4330
4384
|
texture.needsUpdate = true;
|
|
4331
4385
|
}
|
|
4332
4386
|
material.needsUpdate = true;
|
|
@@ -4336,12 +4390,12 @@ function setTextureMipmaps(material, enabled) {
|
|
|
4336
4390
|
const target = material;
|
|
4337
4391
|
for (const slot of materialTextureSlots) {
|
|
4338
4392
|
const texture = target[slot];
|
|
4339
|
-
if (!texture || !(texture instanceof
|
|
4393
|
+
if (!texture || !(texture instanceof THREE26__namespace.Texture)) {
|
|
4340
4394
|
continue;
|
|
4341
4395
|
}
|
|
4342
4396
|
texture.generateMipmaps = enabled;
|
|
4343
|
-
const sharp = texture.magFilter ===
|
|
4344
|
-
texture.minFilter = enabled ? sharp ?
|
|
4397
|
+
const sharp = texture.magFilter === THREE26__namespace.NearestFilter;
|
|
4398
|
+
texture.minFilter = enabled ? sharp ? THREE26__namespace.NearestMipmapNearestFilter : THREE26__namespace.LinearMipmapLinearFilter : sharp ? THREE26__namespace.NearestFilter : THREE26__namespace.LinearFilter;
|
|
4345
4399
|
texture.needsUpdate = true;
|
|
4346
4400
|
}
|
|
4347
4401
|
material.needsUpdate = true;
|
|
@@ -4352,7 +4406,7 @@ function assignMaterialTexture(material, rawKey, url, textureCache) {
|
|
|
4352
4406
|
const key = resolveMaterialPropertyKey(rawKey);
|
|
4353
4407
|
let texture = textureCache.get(url);
|
|
4354
4408
|
if (!texture) {
|
|
4355
|
-
texture = new
|
|
4409
|
+
texture = new THREE26__namespace.TextureLoader().load(url);
|
|
4356
4410
|
textureCache.set(url, texture);
|
|
4357
4411
|
}
|
|
4358
4412
|
target[key] = texture;
|
|
@@ -4390,7 +4444,7 @@ function applyMaterialState(material, value, textureCache) {
|
|
|
4390
4444
|
}
|
|
4391
4445
|
target.side = value.side;
|
|
4392
4446
|
target.blending = value.blending;
|
|
4393
|
-
target.premultipliedAlpha = value.blending ===
|
|
4447
|
+
target.premultipliedAlpha = value.blending === THREE26__namespace.MultiplyBlending || value.blending === THREE26__namespace.SubtractiveBlending;
|
|
4394
4448
|
target.depthTest = value.depthTest;
|
|
4395
4449
|
target.depthWrite = value.depthWrite;
|
|
4396
4450
|
target.wireframe = value.wireframe;
|
|
@@ -4551,12 +4605,12 @@ function resolvePrimaryMesh(object) {
|
|
|
4551
4605
|
if (!object) {
|
|
4552
4606
|
return null;
|
|
4553
4607
|
}
|
|
4554
|
-
if (object instanceof
|
|
4608
|
+
if (object instanceof THREE26__namespace.Mesh) {
|
|
4555
4609
|
return object;
|
|
4556
4610
|
}
|
|
4557
4611
|
let found = null;
|
|
4558
4612
|
object.traverse((child) => {
|
|
4559
|
-
if (!found && child instanceof
|
|
4613
|
+
if (!found && child instanceof THREE26__namespace.Mesh) {
|
|
4560
4614
|
found = child;
|
|
4561
4615
|
}
|
|
4562
4616
|
});
|
|
@@ -4577,22 +4631,22 @@ function applyGeometry(component) {
|
|
|
4577
4631
|
switch (component.kind) {
|
|
4578
4632
|
case "cube": {
|
|
4579
4633
|
const params = sanitized;
|
|
4580
|
-
nextGeometry = new
|
|
4634
|
+
nextGeometry = new THREE26__namespace.BoxGeometry(params.width, params.height, params.depth);
|
|
4581
4635
|
break;
|
|
4582
4636
|
}
|
|
4583
4637
|
case "plane": {
|
|
4584
4638
|
const params = sanitized;
|
|
4585
|
-
nextGeometry = new
|
|
4639
|
+
nextGeometry = new THREE26__namespace.PlaneGeometry(params.width, params.height);
|
|
4586
4640
|
break;
|
|
4587
4641
|
}
|
|
4588
4642
|
case "sphere": {
|
|
4589
4643
|
const params = sanitized;
|
|
4590
|
-
nextGeometry = new
|
|
4644
|
+
nextGeometry = new THREE26__namespace.SphereGeometry(params.radius, 24, 24);
|
|
4591
4645
|
break;
|
|
4592
4646
|
}
|
|
4593
4647
|
case "cylinder": {
|
|
4594
4648
|
const params = sanitized;
|
|
4595
|
-
nextGeometry = new
|
|
4649
|
+
nextGeometry = new THREE26__namespace.CylinderGeometry(
|
|
4596
4650
|
params.radius,
|
|
4597
4651
|
params.radius,
|
|
4598
4652
|
params.height,
|
|
@@ -4602,7 +4656,7 @@ function applyGeometry(component) {
|
|
|
4602
4656
|
}
|
|
4603
4657
|
case "capsule": {
|
|
4604
4658
|
const params = sanitized;
|
|
4605
|
-
nextGeometry = new
|
|
4659
|
+
nextGeometry = new THREE26__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
|
|
4606
4660
|
break;
|
|
4607
4661
|
}
|
|
4608
4662
|
default:
|
|
@@ -4618,7 +4672,7 @@ function applyShadowFlags(component) {
|
|
|
4618
4672
|
return;
|
|
4619
4673
|
}
|
|
4620
4674
|
component.object.traverse((child) => {
|
|
4621
|
-
if (child instanceof
|
|
4675
|
+
if (child instanceof THREE26__namespace.Mesh) {
|
|
4622
4676
|
child.castShadow = component.castShadow;
|
|
4623
4677
|
child.receiveShadow = component.receiveShadow;
|
|
4624
4678
|
}
|
|
@@ -4701,35 +4755,35 @@ function buildGeometry(component) {
|
|
|
4701
4755
|
switch (component.meshKind) {
|
|
4702
4756
|
case "cube": {
|
|
4703
4757
|
const params = p;
|
|
4704
|
-
return new
|
|
4758
|
+
return new THREE26__namespace.BoxGeometry(params.width, params.height, params.depth);
|
|
4705
4759
|
}
|
|
4706
4760
|
case "plane": {
|
|
4707
4761
|
const params = p;
|
|
4708
|
-
return new
|
|
4762
|
+
return new THREE26__namespace.PlaneGeometry(params.width, params.height);
|
|
4709
4763
|
}
|
|
4710
4764
|
case "sphere": {
|
|
4711
4765
|
const params = p;
|
|
4712
|
-
return new
|
|
4766
|
+
return new THREE26__namespace.SphereGeometry(params.radius, 24, 24);
|
|
4713
4767
|
}
|
|
4714
4768
|
case "cylinder": {
|
|
4715
4769
|
const params = p;
|
|
4716
|
-
return new
|
|
4770
|
+
return new THREE26__namespace.CylinderGeometry(params.radius, params.radius, params.height, 20);
|
|
4717
4771
|
}
|
|
4718
4772
|
case "capsule": {
|
|
4719
4773
|
const params = p;
|
|
4720
|
-
return new
|
|
4774
|
+
return new THREE26__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
|
|
4721
4775
|
}
|
|
4722
4776
|
default:
|
|
4723
|
-
return new
|
|
4777
|
+
return new THREE26__namespace.BoxGeometry(1, 1, 1);
|
|
4724
4778
|
}
|
|
4725
4779
|
}
|
|
4726
4780
|
__name(buildGeometry, "buildGeometry");
|
|
4727
|
-
var _position = new
|
|
4728
|
-
var _quaternion = new
|
|
4729
|
-
var _euler = new
|
|
4730
|
-
var _scale = new
|
|
4731
|
-
var _matrix = new
|
|
4732
|
-
var _modelMatrix = new
|
|
4781
|
+
var _position = new THREE26__namespace.Vector3();
|
|
4782
|
+
var _quaternion = new THREE26__namespace.Quaternion();
|
|
4783
|
+
var _euler = new THREE26__namespace.Euler();
|
|
4784
|
+
var _scale = new THREE26__namespace.Vector3();
|
|
4785
|
+
var _matrix = new THREE26__namespace.Matrix4();
|
|
4786
|
+
var _modelMatrix = new THREE26__namespace.Matrix4();
|
|
4733
4787
|
function instanceTransformFromComponent(transform, out) {
|
|
4734
4788
|
_position.set(transform.position.x, transform.position.y, transform.position.z);
|
|
4735
4789
|
_euler.set(transform.rotation.x, transform.rotation.y, transform.rotation.z, "XYZ");
|
|
@@ -4882,7 +4936,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
4882
4936
|
const sourceMaterial = Array.isArray(meshChild.material) ? meshChild.material.map((m) => m.clone()) : meshChild.material.clone();
|
|
4883
4937
|
meshChild.updateWorldMatrix(true, false);
|
|
4884
4938
|
const localMatrix = meshChild.matrixWorld.clone();
|
|
4885
|
-
const instancedMesh2 = new
|
|
4939
|
+
const instancedMesh2 = new THREE26__namespace.InstancedMesh(
|
|
4886
4940
|
geometry2,
|
|
4887
4941
|
Array.isArray(sourceMaterial) ? sourceMaterial : sourceMaterial,
|
|
4888
4942
|
count2
|
|
@@ -4907,7 +4961,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
4907
4961
|
this.loadingSignatures.delete(targetEntityId);
|
|
4908
4962
|
return;
|
|
4909
4963
|
}
|
|
4910
|
-
const group = new
|
|
4964
|
+
const group = new THREE26__namespace.Group();
|
|
4911
4965
|
for (const entry of entries) {
|
|
4912
4966
|
group.add(entry.instancedMesh);
|
|
4913
4967
|
}
|
|
@@ -4925,8 +4979,8 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
4925
4979
|
}
|
|
4926
4980
|
const count = instanceCount;
|
|
4927
4981
|
const geometry = buildGeometry(comp);
|
|
4928
|
-
const material = new
|
|
4929
|
-
const instancedMesh = new
|
|
4982
|
+
const material = new THREE26__namespace.MeshStandardMaterial({ color: "#ffffff" });
|
|
4983
|
+
const instancedMesh = new THREE26__namespace.InstancedMesh(geometry, material, count);
|
|
4930
4984
|
instancedMesh.castShadow = comp.castShadow;
|
|
4931
4985
|
instancedMesh.receiveShadow = comp.receiveShadow;
|
|
4932
4986
|
for (let i = 0; i < count; i++) {
|
|
@@ -5346,9 +5400,6 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
5346
5400
|
if (typeof sourceInteractable.pointable === "boolean") {
|
|
5347
5401
|
interactable.pointable = sourceInteractable.pointable;
|
|
5348
5402
|
}
|
|
5349
|
-
if (typeof sourceInteractable.grabMode === "string") {
|
|
5350
|
-
interactable.grabMode = sourceInteractable.grabMode;
|
|
5351
|
-
}
|
|
5352
5403
|
if (typeof sourceInteractable.grabReach === "string") {
|
|
5353
5404
|
interactable.grabReach = sourceInteractable.grabReach;
|
|
5354
5405
|
}
|
|
@@ -5361,6 +5412,30 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
5361
5412
|
if (typeof sourceInteractable.grabRadius === "number") {
|
|
5362
5413
|
interactable.grabRadius = sourceInteractable.grabRadius;
|
|
5363
5414
|
}
|
|
5415
|
+
if (typeof sourceInteractable.grabHands === "string") {
|
|
5416
|
+
interactable.grabHands = sourceInteractable.grabHands;
|
|
5417
|
+
}
|
|
5418
|
+
if (typeof sourceInteractable.twoHandRotation === "string") {
|
|
5419
|
+
interactable.twoHandRotation = sourceInteractable.twoHandRotation;
|
|
5420
|
+
}
|
|
5421
|
+
if (typeof sourceInteractable.allowTwoHandScale === "boolean") {
|
|
5422
|
+
interactable.allowTwoHandScale = sourceInteractable.allowTwoHandScale;
|
|
5423
|
+
}
|
|
5424
|
+
if (typeof sourceInteractable.minScale === "number") {
|
|
5425
|
+
interactable.minScale = sourceInteractable.minScale;
|
|
5426
|
+
}
|
|
5427
|
+
if (typeof sourceInteractable.maxScale === "number") {
|
|
5428
|
+
interactable.maxScale = sourceInteractable.maxScale;
|
|
5429
|
+
}
|
|
5430
|
+
if (Array.isArray(sourceInteractable.attachPoints)) {
|
|
5431
|
+
interactable.attachPoints = sourceInteractable.attachPoints.map((point) => asRecord3(point)).filter(
|
|
5432
|
+
(point) => point !== null && typeof point.id === "string"
|
|
5433
|
+
).map(
|
|
5434
|
+
(point) => createAttachPoint(
|
|
5435
|
+
point
|
|
5436
|
+
)
|
|
5437
|
+
);
|
|
5438
|
+
}
|
|
5364
5439
|
if (typeof sourceInteractable.throwOnRelease === "boolean") {
|
|
5365
5440
|
interactable.throwOnRelease = sourceInteractable.throwOnRelease;
|
|
5366
5441
|
}
|
|
@@ -5383,8 +5458,16 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
5383
5458
|
z: typeof grabRot.z === "number" ? grabRot.z : 0
|
|
5384
5459
|
};
|
|
5385
5460
|
}
|
|
5386
|
-
if (typeof sourceInteractable.
|
|
5387
|
-
interactable.
|
|
5461
|
+
if (typeof sourceInteractable.hoverBehavior === "string") {
|
|
5462
|
+
interactable.hoverBehavior = sourceInteractable.hoverBehavior;
|
|
5463
|
+
} else if (sourceInteractable.highlightOnHover === false) {
|
|
5464
|
+
interactable.hoverBehavior = "none";
|
|
5465
|
+
}
|
|
5466
|
+
if (typeof sourceInteractable.hoverColor === "string") {
|
|
5467
|
+
interactable.hoverColor = sourceInteractable.hoverColor;
|
|
5468
|
+
}
|
|
5469
|
+
if (typeof sourceInteractable.hoverScale === "number") {
|
|
5470
|
+
interactable.hoverScale = sourceInteractable.hoverScale;
|
|
5388
5471
|
}
|
|
5389
5472
|
}
|
|
5390
5473
|
}
|
|
@@ -6569,7 +6652,7 @@ var _Behaviour = class _Behaviour {
|
|
|
6569
6652
|
if (!this.threeRef) {
|
|
6570
6653
|
return null;
|
|
6571
6654
|
}
|
|
6572
|
-
const position = new
|
|
6655
|
+
const position = new THREE26__namespace.Vector3();
|
|
6573
6656
|
this.threeRef.object.getWorldPosition(position);
|
|
6574
6657
|
return position;
|
|
6575
6658
|
}
|
|
@@ -6581,7 +6664,7 @@ var _Behaviour = class _Behaviour {
|
|
|
6581
6664
|
if (!this.threeRef) {
|
|
6582
6665
|
return null;
|
|
6583
6666
|
}
|
|
6584
|
-
const target = new
|
|
6667
|
+
const target = new THREE26__namespace.Vector3();
|
|
6585
6668
|
this.threeRef.object.getWorldDirection(target);
|
|
6586
6669
|
return target;
|
|
6587
6670
|
}
|
|
@@ -6643,7 +6726,7 @@ var _Behaviour = class _Behaviour {
|
|
|
6643
6726
|
if (!this.threeRef) {
|
|
6644
6727
|
return;
|
|
6645
6728
|
}
|
|
6646
|
-
const rotation = new
|
|
6729
|
+
const rotation = new THREE26__namespace.Quaternion();
|
|
6647
6730
|
this.threeRef.object.getWorldQuaternion(rotation);
|
|
6648
6731
|
rotation.slerp(targetRotation, alpha);
|
|
6649
6732
|
this.transform.setRotation(rotation);
|
|
@@ -6660,7 +6743,7 @@ var _Behaviour = class _Behaviour {
|
|
|
6660
6743
|
return;
|
|
6661
6744
|
}
|
|
6662
6745
|
const clone = this.threeRef.object.clone();
|
|
6663
|
-
const rotation = new
|
|
6746
|
+
const rotation = new THREE26__namespace.Quaternion();
|
|
6664
6747
|
clone.lookAt(targetPosition);
|
|
6665
6748
|
clone.getWorldQuaternion(rotation);
|
|
6666
6749
|
this.transform.setRotation(rotation);
|
|
@@ -6798,6 +6881,17 @@ var _Behaviour = class _Behaviour {
|
|
|
6798
6881
|
*
|
|
6799
6882
|
* @param input - The source doing the grabbing.
|
|
6800
6883
|
*/
|
|
6884
|
+
/**
|
|
6885
|
+
* A SECOND hand joined a two-hand grab on this entity.
|
|
6886
|
+
*
|
|
6887
|
+
* The first hand anchors the object and keeps holding it; this fires for the
|
|
6888
|
+
* hand that came second — the foregrip on a rifle, say.
|
|
6889
|
+
*/
|
|
6890
|
+
onSecondaryGrab(_input) {
|
|
6891
|
+
}
|
|
6892
|
+
/** The second hand let go, leaving the object in the first hand alone. */
|
|
6893
|
+
onSecondaryRelease(_input) {
|
|
6894
|
+
}
|
|
6801
6895
|
/**
|
|
6802
6896
|
* A hand pose declared on this entity started being held.
|
|
6803
6897
|
*
|
|
@@ -7015,8 +7109,8 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
7015
7109
|
}, "onPointerUp");
|
|
7016
7110
|
this.moduleLoader = moduleLoader ?? defaultModuleLoader;
|
|
7017
7111
|
this.selectionCtx = selectionContext ?? null;
|
|
7018
|
-
this.raycaster = new
|
|
7019
|
-
this.ndcPointer = new
|
|
7112
|
+
this.raycaster = new THREE26__namespace.Raycaster();
|
|
7113
|
+
this.ndcPointer = new THREE26__namespace.Vector2();
|
|
7020
7114
|
if (this.selectionCtx) {
|
|
7021
7115
|
this.selectionCtx.domElement.addEventListener("pointerdown", this.onPointerDown);
|
|
7022
7116
|
this.selectionCtx.domElement.addEventListener("pointerup", this.onPointerUp);
|
|
@@ -7395,7 +7489,7 @@ function disposeBuiltObject(root) {
|
|
|
7395
7489
|
for (const mat of materials) {
|
|
7396
7490
|
if (mat.userData?.[SHARED_MODEL_RESOURCE_FLAG]) continue;
|
|
7397
7491
|
for (const value of Object.values(mat)) {
|
|
7398
|
-
if (value instanceof
|
|
7492
|
+
if (value instanceof THREE26__namespace.Texture) value.dispose();
|
|
7399
7493
|
}
|
|
7400
7494
|
mat.dispose?.();
|
|
7401
7495
|
}
|
|
@@ -7759,7 +7853,7 @@ var _AudioSystem = class _AudioSystem {
|
|
|
7759
7853
|
if (!prev || prev.volume !== opts.volume) {
|
|
7760
7854
|
sound.setVolume(opts.volume);
|
|
7761
7855
|
}
|
|
7762
|
-
if (opts.positional && sound instanceof
|
|
7856
|
+
if (opts.positional && sound instanceof THREE26__namespace.PositionalAudio) {
|
|
7763
7857
|
if (!prev || prev.refDistance !== opts.refDistance) {
|
|
7764
7858
|
sound.setRefDistance(opts.refDistance);
|
|
7765
7859
|
}
|
|
@@ -7885,7 +7979,7 @@ var _VideoSystem = class _VideoSystem {
|
|
|
7885
7979
|
component.object.scale.set(opts.width, opts.height, 1);
|
|
7886
7980
|
}
|
|
7887
7981
|
const material = component.material;
|
|
7888
|
-
if (material instanceof
|
|
7982
|
+
if (material instanceof THREE26__namespace.ShaderMaterial) {
|
|
7889
7983
|
if (!prev || prev.backgroundColor !== opts.backgroundColor) {
|
|
7890
7984
|
material.uniforms.keyColor.value.set(opts.backgroundColor);
|
|
7891
7985
|
}
|
|
@@ -7899,7 +7993,7 @@ var _VideoSystem = class _VideoSystem {
|
|
|
7899
7993
|
material.uniforms.spill.value = opts.spill;
|
|
7900
7994
|
}
|
|
7901
7995
|
}
|
|
7902
|
-
if (opts.positional && component.audioNode instanceof
|
|
7996
|
+
if (opts.positional && component.audioNode instanceof THREE26__namespace.PositionalAudio) {
|
|
7903
7997
|
const posAudio = component.audioNode;
|
|
7904
7998
|
if (!prev || prev.refDistance !== opts.refDistance) {
|
|
7905
7999
|
posAudio.setRefDistance(opts.refDistance);
|
|
@@ -7939,8 +8033,8 @@ function blankState(source) {
|
|
|
7939
8033
|
handedness: handednessOf(source),
|
|
7940
8034
|
kind: kindOf(source),
|
|
7941
8035
|
connected: true,
|
|
7942
|
-
rayOrigin: new
|
|
7943
|
-
rayDirection: new
|
|
8036
|
+
rayOrigin: new THREE26__namespace.Vector3(),
|
|
8037
|
+
rayDirection: new THREE26__namespace.Vector3(0, 0, -1),
|
|
7944
8038
|
gripPosition: null,
|
|
7945
8039
|
gripQuaternion: null,
|
|
7946
8040
|
select: false,
|
|
@@ -7966,7 +8060,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
7966
8060
|
}
|
|
7967
8061
|
if (spaces.length === 0) return null;
|
|
7968
8062
|
const target = existing ?? {};
|
|
7969
|
-
const matrix = new
|
|
8063
|
+
const matrix = new THREE26__namespace.Matrix4();
|
|
7970
8064
|
const buffer = spaces.length * 16 <= JOINT_MATRIX_BUFFER.length ? JOINT_MATRIX_BUFFER : new Float32Array(spaces.length * 16);
|
|
7971
8065
|
const fillPoses = frame.fillPoses;
|
|
7972
8066
|
if (typeof fillPoses === "function") {
|
|
@@ -7979,7 +8073,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
7979
8073
|
if (filled) {
|
|
7980
8074
|
for (let i = 0; i < names.length; i += 1) {
|
|
7981
8075
|
matrix.fromArray(buffer, i * 16).premultiply(rigMatrix);
|
|
7982
|
-
const vector = target[names[i]] ?? new
|
|
8076
|
+
const vector = target[names[i]] ?? new THREE26__namespace.Vector3();
|
|
7983
8077
|
vector.setFromMatrixPosition(matrix);
|
|
7984
8078
|
target[names[i]] = vector;
|
|
7985
8079
|
}
|
|
@@ -7997,7 +8091,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
7997
8091
|
continue;
|
|
7998
8092
|
}
|
|
7999
8093
|
matrix.fromArray(pose.transform.matrix).premultiply(rigMatrix);
|
|
8000
|
-
const vector = target[names[i]] ?? new
|
|
8094
|
+
const vector = target[names[i]] ?? new THREE26__namespace.Vector3();
|
|
8001
8095
|
vector.setFromMatrixPosition(matrix);
|
|
8002
8096
|
target[names[i]] = vector;
|
|
8003
8097
|
anyTracked = true;
|
|
@@ -8009,7 +8103,7 @@ var _XRInputSystem = class _XRInputSystem {
|
|
|
8009
8103
|
constructor() {
|
|
8010
8104
|
this.records = /* @__PURE__ */ new Map();
|
|
8011
8105
|
/** Reference-space → world matrix, rebuilt each frame from the XR rig. */
|
|
8012
|
-
this.referenceToWorld = new
|
|
8106
|
+
this.referenceToWorld = new THREE26__namespace.Matrix4();
|
|
8013
8107
|
this.session = null;
|
|
8014
8108
|
this.onSelectStart = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectStart"), "onSelectStart");
|
|
8015
8109
|
this.onSelectEnd = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectEnd"), "onSelectEnd");
|
|
@@ -8107,19 +8201,19 @@ var _XRInputSystem = class _XRInputSystem {
|
|
|
8107
8201
|
if (frame && referenceSpace && source.targetRaySpace) {
|
|
8108
8202
|
const pose = frame.getPose(source.targetRaySpace, referenceSpace);
|
|
8109
8203
|
if (pose) {
|
|
8110
|
-
const m = new
|
|
8204
|
+
const m = new THREE26__namespace.Matrix4().fromArray(pose.transform.matrix).premultiply(rigMatrix);
|
|
8111
8205
|
state.rayOrigin.setFromMatrixPosition(m);
|
|
8112
8206
|
state.rayDirection.set(0, 0, -1).applyQuaternion(
|
|
8113
|
-
new
|
|
8207
|
+
new THREE26__namespace.Quaternion().setFromRotationMatrix(m)
|
|
8114
8208
|
).normalize();
|
|
8115
8209
|
}
|
|
8116
8210
|
}
|
|
8117
8211
|
if (frame && referenceSpace && source.gripSpace) {
|
|
8118
8212
|
const gripPose = frame.getPose(source.gripSpace, referenceSpace);
|
|
8119
8213
|
if (gripPose) {
|
|
8120
|
-
const m = new
|
|
8121
|
-
state.gripPosition ?? (state.gripPosition = new
|
|
8122
|
-
state.gripQuaternion ?? (state.gripQuaternion = new
|
|
8214
|
+
const m = new THREE26__namespace.Matrix4().fromArray(gripPose.transform.matrix).premultiply(rigMatrix);
|
|
8215
|
+
state.gripPosition ?? (state.gripPosition = new THREE26__namespace.Vector3());
|
|
8216
|
+
state.gripQuaternion ?? (state.gripQuaternion = new THREE26__namespace.Quaternion());
|
|
8123
8217
|
state.gripPosition.setFromMatrixPosition(m);
|
|
8124
8218
|
state.gripQuaternion.setFromRotationMatrix(m);
|
|
8125
8219
|
}
|
|
@@ -8228,15 +8322,15 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
|
|
|
8228
8322
|
const fresh = this.samples.filter(
|
|
8229
8323
|
(sample) => now - sample.time <= MAX_SAMPLE_AGE_SECONDS
|
|
8230
8324
|
);
|
|
8231
|
-
if (fresh.length < 2) return new
|
|
8232
|
-
let best = new
|
|
8325
|
+
if (fresh.length < 2) return new THREE26__namespace.Vector3();
|
|
8326
|
+
let best = new THREE26__namespace.Vector3();
|
|
8233
8327
|
let bestSpeed = 0;
|
|
8234
8328
|
for (let i = 1; i < fresh.length; i += 1) {
|
|
8235
8329
|
const previous = fresh[i - 1];
|
|
8236
8330
|
const current = fresh[i];
|
|
8237
8331
|
const dt = current.time - previous.time;
|
|
8238
8332
|
if (dt <= 1e-5) continue;
|
|
8239
|
-
const velocity = new
|
|
8333
|
+
const velocity = new THREE26__namespace.Vector3().subVectors(current.position, previous.position).divideScalar(dt);
|
|
8240
8334
|
const speed = velocity.length();
|
|
8241
8335
|
if (speed > MAX_PLAUSIBLE_SPEED) continue;
|
|
8242
8336
|
if (speed > bestSpeed) {
|
|
@@ -8253,25 +8347,79 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
|
|
|
8253
8347
|
__name(_ThrowVelocityTracker, "ThrowVelocityTracker");
|
|
8254
8348
|
var ThrowVelocityTracker = _ThrowVelocityTracker;
|
|
8255
8349
|
function angularVelocityFrom(previous, current, deltaTime) {
|
|
8256
|
-
if (deltaTime <= 1e-5) return new
|
|
8350
|
+
if (deltaTime <= 1e-5) return new THREE26__namespace.Vector3();
|
|
8257
8351
|
const delta = current.clone().multiply(previous.clone().invert());
|
|
8258
8352
|
if (delta.w < 0) {
|
|
8259
8353
|
delta.set(-delta.x, -delta.y, -delta.z, -delta.w);
|
|
8260
8354
|
}
|
|
8261
|
-
const angle = 2 * Math.acos(
|
|
8355
|
+
const angle = 2 * Math.acos(THREE26__namespace.MathUtils.clamp(delta.w, -1, 1));
|
|
8262
8356
|
const sinHalf = Math.sqrt(Math.max(0, 1 - delta.w * delta.w));
|
|
8263
|
-
if (sinHalf < 1e-6 || angle < 1e-6) return new
|
|
8264
|
-
return new
|
|
8357
|
+
if (sinHalf < 1e-6 || angle < 1e-6) return new THREE26__namespace.Vector3();
|
|
8358
|
+
return new THREE26__namespace.Vector3(delta.x, delta.y, delta.z).divideScalar(sinHalf).multiplyScalar(angle / deltaTime);
|
|
8265
8359
|
}
|
|
8266
8360
|
__name(angularVelocityFrom, "angularVelocityFrom");
|
|
8361
|
+
var MIN_HAND_SEPARATION = 0.06;
|
|
8362
|
+
var MIN_ANCHOR_SEPARATION = 1e-3;
|
|
8363
|
+
var SCALE_DEADZONE = 0.05;
|
|
8364
|
+
function solveTwoHandTransform(primary, secondary, basis, options) {
|
|
8365
|
+
const separation = primary.position.distanceTo(secondary.position);
|
|
8366
|
+
const anchorDelta = new THREE26__namespace.Vector3().subVectors(
|
|
8367
|
+
basis.secondaryLocal,
|
|
8368
|
+
basis.primaryLocal
|
|
8369
|
+
);
|
|
8370
|
+
const anchorLength = anchorDelta.length();
|
|
8371
|
+
let factor = 1;
|
|
8372
|
+
if (options.allowScale && basis.initialSeparation > MIN_ANCHOR_SEPARATION && separation > MIN_ANCHOR_SEPARATION) {
|
|
8373
|
+
factor = separation / basis.initialSeparation;
|
|
8374
|
+
if (Math.abs(factor - 1) <= SCALE_DEADZONE) {
|
|
8375
|
+
factor = 1;
|
|
8376
|
+
} else {
|
|
8377
|
+
factor += factor > 1 ? -SCALE_DEADZONE : SCALE_DEADZONE;
|
|
8378
|
+
}
|
|
8379
|
+
factor = Math.min(options.maxScale, Math.max(options.minScale, factor));
|
|
8380
|
+
}
|
|
8381
|
+
const scale = basis.initialScale.clone().multiplyScalar(factor);
|
|
8382
|
+
const degenerate = separation < MIN_HAND_SEPARATION || anchorLength < MIN_ANCHOR_SEPARATION;
|
|
8383
|
+
const base = primary.quaternion.clone().multiply(basis.primaryHandOffset);
|
|
8384
|
+
let quaternion;
|
|
8385
|
+
if (options.rotationMode === "primary" || degenerate) {
|
|
8386
|
+
quaternion = base;
|
|
8387
|
+
} else {
|
|
8388
|
+
const axisLocal = anchorDelta.clone().normalize();
|
|
8389
|
+
const currentAxis = axisLocal.clone().applyQuaternion(base).normalize();
|
|
8390
|
+
const desiredAxis = new THREE26__namespace.Vector3().subVectors(secondary.position, primary.position).normalize();
|
|
8391
|
+
const correction = new THREE26__namespace.Quaternion().setFromUnitVectors(
|
|
8392
|
+
currentAxis,
|
|
8393
|
+
desiredAxis
|
|
8394
|
+
);
|
|
8395
|
+
quaternion = correction.multiply(base);
|
|
8396
|
+
}
|
|
8397
|
+
const anchorOffset = basis.primaryLocal.clone().multiply(scale).applyQuaternion(quaternion);
|
|
8398
|
+
const position = primary.position.clone().sub(anchorOffset);
|
|
8399
|
+
return { position, quaternion, scale, degenerate };
|
|
8400
|
+
}
|
|
8401
|
+
__name(solveTwoHandTransform, "solveTwoHandTransform");
|
|
8267
8402
|
|
|
8268
8403
|
// core/systems/XRInteractionSystem.ts
|
|
8269
8404
|
var RAYLESS_HOLD_DISTANCE = 0.5;
|
|
8405
|
+
function quatFromEulerVec(r) {
|
|
8406
|
+
return new THREE26__namespace.Quaternion().setFromEuler(new THREE26__namespace.Euler(r.x, r.y, r.z));
|
|
8407
|
+
}
|
|
8408
|
+
__name(quatFromEulerVec, "quatFromEulerVec");
|
|
8409
|
+
function writeEuler(target, q) {
|
|
8410
|
+
const euler = new THREE26__namespace.Euler().setFromQuaternion(q);
|
|
8411
|
+
target.x = euler.x;
|
|
8412
|
+
target.y = euler.y;
|
|
8413
|
+
target.z = euler.z;
|
|
8414
|
+
}
|
|
8415
|
+
__name(writeEuler, "writeEuler");
|
|
8270
8416
|
var _XRInteractionSystem = class _XRInteractionSystem {
|
|
8271
8417
|
constructor(inputSystem) {
|
|
8272
|
-
this.raycaster = new
|
|
8418
|
+
this.raycaster = new THREE26__namespace.Raycaster();
|
|
8273
8419
|
this.grabs = /* @__PURE__ */ new Map();
|
|
8274
8420
|
this.hoveredEntityId = null;
|
|
8421
|
+
/** Per-hand hover, with the hit distance so the ray can stop at the surface. */
|
|
8422
|
+
this.hovers = /* @__PURE__ */ new Map();
|
|
8275
8423
|
/** Monotonic seconds, accumulated from deltaTime for velocity sampling. */
|
|
8276
8424
|
this.elapsed = 0;
|
|
8277
8425
|
this.inputSystem = inputSystem;
|
|
@@ -8285,6 +8433,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8285
8433
|
const inputs = this.inputSystem.getInputs();
|
|
8286
8434
|
const interactables = this.collectInteractables(world);
|
|
8287
8435
|
this.hoveredEntityId = null;
|
|
8436
|
+
this.hovers.clear();
|
|
8288
8437
|
for (const input of inputs) {
|
|
8289
8438
|
if (!input.connected) {
|
|
8290
8439
|
this.release(world, input);
|
|
@@ -8292,7 +8441,6 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8292
8441
|
}
|
|
8293
8442
|
const held = this.grabs.get(input);
|
|
8294
8443
|
if (held) {
|
|
8295
|
-
this.moveHeld(world, input, held, deltaTime);
|
|
8296
8444
|
if (this.wantsRelease(world, input, held)) {
|
|
8297
8445
|
this.release(world, input);
|
|
8298
8446
|
}
|
|
@@ -8303,6 +8451,10 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8303
8451
|
if (this.hoveredEntityId === null) {
|
|
8304
8452
|
this.hoveredEntityId = candidate.entityId;
|
|
8305
8453
|
}
|
|
8454
|
+
this.hovers.set(input, {
|
|
8455
|
+
entityId: candidate.entityId,
|
|
8456
|
+
distance: candidate.distance
|
|
8457
|
+
});
|
|
8306
8458
|
const interactable = world.getComponent(
|
|
8307
8459
|
candidate.entityId,
|
|
8308
8460
|
XRInteractableComponent
|
|
@@ -8313,9 +8465,122 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8313
8465
|
/* starting */
|
|
8314
8466
|
true
|
|
8315
8467
|
)) {
|
|
8316
|
-
this.
|
|
8468
|
+
this.tryGrab(world, input, candidate.entityId, candidate.viaDistance);
|
|
8317
8469
|
}
|
|
8318
8470
|
}
|
|
8471
|
+
this.moveAllHeld(world, deltaTime);
|
|
8472
|
+
}
|
|
8473
|
+
/** Hands currently holding an entity. */
|
|
8474
|
+
holdersOf(entityId) {
|
|
8475
|
+
const holders = [];
|
|
8476
|
+
for (const [input, record] of this.grabs) {
|
|
8477
|
+
if (record.entityId === entityId) holders.push({ input, record });
|
|
8478
|
+
}
|
|
8479
|
+
return holders;
|
|
8480
|
+
}
|
|
8481
|
+
/**
|
|
8482
|
+
* Route a new grab: first hand, hand-off, or second hand.
|
|
8483
|
+
*
|
|
8484
|
+
* Which of those happens is the object's choice (`grabHands`), not the
|
|
8485
|
+
* hand's — a ball should pass between hands, a rifle should be held by both,
|
|
8486
|
+
* and a lever should stay with whoever grabbed it first.
|
|
8487
|
+
*/
|
|
8488
|
+
tryGrab(world, input, entityId, viaDistance) {
|
|
8489
|
+
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
8490
|
+
if (!interactable) return;
|
|
8491
|
+
const holders = this.holdersOf(entityId);
|
|
8492
|
+
if (holders.length === 0) {
|
|
8493
|
+
this.grab(world, input, entityId, viaDistance, "primary");
|
|
8494
|
+
return;
|
|
8495
|
+
}
|
|
8496
|
+
if (holders.some((holder) => holder.input === input)) return;
|
|
8497
|
+
if (interactable.grabHands === "single") return;
|
|
8498
|
+
if (interactable.grabHands === "handOff") {
|
|
8499
|
+
const previous = holders[0];
|
|
8500
|
+
this.grabs.delete(previous.input);
|
|
8501
|
+
const record = previous.record;
|
|
8502
|
+
record.role = "primary";
|
|
8503
|
+
record.twoHand = null;
|
|
8504
|
+
this.reanchor(world, input, record, interactable);
|
|
8505
|
+
this.grabs.set(input, record);
|
|
8506
|
+
this.dispatch(world, entityId, (b) => b.onGrab(input));
|
|
8507
|
+
return;
|
|
8508
|
+
}
|
|
8509
|
+
if (holders.length >= 2) return;
|
|
8510
|
+
this.grab(world, input, entityId, viaDistance, "secondary");
|
|
8511
|
+
this.beginTwoHand(world, entityId);
|
|
8512
|
+
}
|
|
8513
|
+
/**
|
|
8514
|
+
* Re-derive a record's hold from where the object is NOW.
|
|
8515
|
+
*
|
|
8516
|
+
* Used on hand-off and on promotion after the primary lets go. Without it the
|
|
8517
|
+
* object snaps to whatever offset the previous hand had, which reads as the
|
|
8518
|
+
* object jumping out of your grip at the moment you take it.
|
|
8519
|
+
*/
|
|
8520
|
+
reanchor(world, input, record, interactable) {
|
|
8521
|
+
const transform = world.getComponent(record.entityId, TransformComponent);
|
|
8522
|
+
if (!transform) return;
|
|
8523
|
+
const hand = this.handPosition(input);
|
|
8524
|
+
const handQuaternion = this.handQuaternion(input);
|
|
8525
|
+
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
8526
|
+
record.offset = new THREE26__namespace.Vector3(
|
|
8527
|
+
transform.position.x - hand.x,
|
|
8528
|
+
transform.position.y - hand.y,
|
|
8529
|
+
transform.position.z - hand.z
|
|
8530
|
+
).applyQuaternion(handQuaternion.clone().invert());
|
|
8531
|
+
record.handRotationOffset = handQuaternion.clone().invert().multiply(objectQuaternion);
|
|
8532
|
+
record.remote = false;
|
|
8533
|
+
record.tracker.clear();
|
|
8534
|
+
record.tracker.record(hand, this.elapsed);
|
|
8535
|
+
record.lastHandQuaternion = handQuaternion.clone();
|
|
8536
|
+
if (record.attachLocal && interactable.attachPoints.length === 0) {
|
|
8537
|
+
record.attachLocal = null;
|
|
8538
|
+
record.attachQuaternion = null;
|
|
8539
|
+
record.attachPointId = null;
|
|
8540
|
+
}
|
|
8541
|
+
}
|
|
8542
|
+
/** Capture the two-hand basis once both hands are on the object. */
|
|
8543
|
+
beginTwoHand(world, entityId) {
|
|
8544
|
+
const holders = this.holdersOf(entityId);
|
|
8545
|
+
if (holders.length !== 2) return;
|
|
8546
|
+
const primary = holders.find((h) => h.record.role === "primary");
|
|
8547
|
+
const secondary = holders.find((h) => h.record.role === "secondary");
|
|
8548
|
+
if (!primary || !secondary) return;
|
|
8549
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
8550
|
+
if (!transform) return;
|
|
8551
|
+
const primaryHand = this.handPosition(primary.input);
|
|
8552
|
+
const secondaryHand = this.handPosition(secondary.input);
|
|
8553
|
+
const primaryLocal = primary.record.attachLocal?.clone() ?? this.objectLocalPoint(transform, primaryHand);
|
|
8554
|
+
const secondaryLocal = secondary.record.attachLocal?.clone() ?? this.objectLocalPoint(transform, secondaryHand);
|
|
8555
|
+
primary.record.twoHand = {
|
|
8556
|
+
primaryLocal,
|
|
8557
|
+
secondaryLocal,
|
|
8558
|
+
initialScale: new THREE26__namespace.Vector3(
|
|
8559
|
+
transform.scale.x,
|
|
8560
|
+
transform.scale.y,
|
|
8561
|
+
transform.scale.z
|
|
8562
|
+
),
|
|
8563
|
+
initialSeparation: primaryHand.distanceTo(secondaryHand),
|
|
8564
|
+
// How the object sits relative to the anchoring hand right now, so the
|
|
8565
|
+
// two-hand solve picks up exactly where the one-hand hold left off.
|
|
8566
|
+
primaryHandOffset: this.handQuaternion(primary.input).invert().multiply(quatFromEulerVec(transform.rotation)),
|
|
8567
|
+
initialQuaternion: quatFromEulerVec(transform.rotation)
|
|
8568
|
+
};
|
|
8569
|
+
this.dispatch(world, entityId, (b) => b.onSecondaryGrab(secondary.input));
|
|
8570
|
+
}
|
|
8571
|
+
/** World point → the object's UNSCALED local space. */
|
|
8572
|
+
objectLocalPoint(transform, worldPoint) {
|
|
8573
|
+
const local = worldPoint.clone().sub(
|
|
8574
|
+
new THREE26__namespace.Vector3(
|
|
8575
|
+
transform.position.x,
|
|
8576
|
+
transform.position.y,
|
|
8577
|
+
transform.position.z
|
|
8578
|
+
)
|
|
8579
|
+
).applyQuaternion(quatFromEulerVec(transform.rotation).invert());
|
|
8580
|
+
local.x /= transform.scale.x || 1;
|
|
8581
|
+
local.y /= transform.scale.y || 1;
|
|
8582
|
+
local.z /= transform.scale.z || 1;
|
|
8583
|
+
return local;
|
|
8319
8584
|
}
|
|
8320
8585
|
/** Whether the grab gesture for this object is currently starting. */
|
|
8321
8586
|
gestureMatches(input, interactable, starting) {
|
|
@@ -8364,7 +8629,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8364
8629
|
);
|
|
8365
8630
|
if (!interactable2) continue;
|
|
8366
8631
|
if (interactable2.grabReach === "distance") continue;
|
|
8367
|
-
const position = new
|
|
8632
|
+
const position = new THREE26__namespace.Vector3();
|
|
8368
8633
|
entry.object.getWorldPosition(position);
|
|
8369
8634
|
const distance = position.distanceTo(hand);
|
|
8370
8635
|
if (distance <= interactable2.grabRadius && distance < nearestDistance) {
|
|
@@ -8373,13 +8638,22 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8373
8638
|
}
|
|
8374
8639
|
}
|
|
8375
8640
|
if (nearestId !== null) {
|
|
8376
|
-
return {
|
|
8641
|
+
return {
|
|
8642
|
+
entityId: nearestId,
|
|
8643
|
+
viaDistance: false,
|
|
8644
|
+
distance: nearestDistance
|
|
8645
|
+
};
|
|
8377
8646
|
}
|
|
8378
|
-
const
|
|
8379
|
-
if (
|
|
8647
|
+
const hit = this.raycast(input, interactables);
|
|
8648
|
+
if (hit === null) return null;
|
|
8649
|
+
const hitId = hit.entityId;
|
|
8380
8650
|
const interactable = world.getComponent(hitId, XRInteractableComponent);
|
|
8381
8651
|
const viaDistanceAllowed = interactable?.grabReach === "distance" || interactable?.grabReach === "both";
|
|
8382
|
-
return {
|
|
8652
|
+
return {
|
|
8653
|
+
entityId: hitId,
|
|
8654
|
+
viaDistance: viaDistanceAllowed,
|
|
8655
|
+
distance: hit.distance
|
|
8656
|
+
};
|
|
8383
8657
|
}
|
|
8384
8658
|
collectInteractables(world) {
|
|
8385
8659
|
const out = [];
|
|
@@ -8410,9 +8684,54 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8410
8684
|
nearestId = entry.entityId;
|
|
8411
8685
|
}
|
|
8412
8686
|
}
|
|
8413
|
-
return nearestId;
|
|
8687
|
+
return nearestId === null ? null : { entityId: nearestId, distance: nearestDistance };
|
|
8414
8688
|
}
|
|
8415
|
-
|
|
8689
|
+
/**
|
|
8690
|
+
* Pick the authored hold this hand should take.
|
|
8691
|
+
*
|
|
8692
|
+
* Filters by hand and by role — that is what makes "the trigger hand goes on
|
|
8693
|
+
* the grip" hold regardless of which hand reaches first — then takes the
|
|
8694
|
+
* nearest remaining one so grabbing near the foregrip picks the foregrip.
|
|
8695
|
+
*/
|
|
8696
|
+
chooseAttachPoint(world, input, entityId, interactable, role) {
|
|
8697
|
+
if (interactable.attachPoints.length === 0) return null;
|
|
8698
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
8699
|
+
if (!transform) return null;
|
|
8700
|
+
const taken = new Set(
|
|
8701
|
+
this.holdersOf(entityId).map((holder) => holder.record.attachPointId).filter((id) => id !== null)
|
|
8702
|
+
);
|
|
8703
|
+
const hand = this.handPosition(input);
|
|
8704
|
+
const objectPosition = new THREE26__namespace.Vector3(
|
|
8705
|
+
transform.position.x,
|
|
8706
|
+
transform.position.y,
|
|
8707
|
+
transform.position.z
|
|
8708
|
+
);
|
|
8709
|
+
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
8710
|
+
const scale = new THREE26__namespace.Vector3(
|
|
8711
|
+
transform.scale.x,
|
|
8712
|
+
transform.scale.y,
|
|
8713
|
+
transform.scale.z
|
|
8714
|
+
);
|
|
8715
|
+
let best = null;
|
|
8716
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
8717
|
+
for (const point of interactable.attachPoints) {
|
|
8718
|
+
if (taken.has(point.id)) continue;
|
|
8719
|
+
if (point.hand !== "any" && point.hand !== input.handedness) continue;
|
|
8720
|
+
if (point.role !== "any" && point.role !== role) continue;
|
|
8721
|
+
const world3 = new THREE26__namespace.Vector3(
|
|
8722
|
+
point.position.x,
|
|
8723
|
+
point.position.y,
|
|
8724
|
+
point.position.z
|
|
8725
|
+
).multiply(scale).applyQuaternion(objectQuaternion).add(objectPosition);
|
|
8726
|
+
const distance = world3.distanceTo(hand);
|
|
8727
|
+
if (distance < bestDistance) {
|
|
8728
|
+
bestDistance = distance;
|
|
8729
|
+
best = point;
|
|
8730
|
+
}
|
|
8731
|
+
}
|
|
8732
|
+
return best;
|
|
8733
|
+
}
|
|
8734
|
+
grab(world, input, entityId, viaDistance, role) {
|
|
8416
8735
|
const transform = world.getComponent(entityId, TransformComponent);
|
|
8417
8736
|
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
8418
8737
|
if (!transform || !interactable) return;
|
|
@@ -8422,25 +8741,25 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8422
8741
|
let offset;
|
|
8423
8742
|
let remoteDistance = 0;
|
|
8424
8743
|
if (remote) {
|
|
8425
|
-
const position = new
|
|
8744
|
+
const position = new THREE26__namespace.Vector3(
|
|
8426
8745
|
transform.position.x,
|
|
8427
8746
|
transform.position.y,
|
|
8428
8747
|
transform.position.z
|
|
8429
8748
|
);
|
|
8430
8749
|
remoteDistance = position.distanceTo(input.rayOrigin);
|
|
8431
|
-
offset = new
|
|
8750
|
+
offset = new THREE26__namespace.Vector3();
|
|
8432
8751
|
} else if (viaDistance) {
|
|
8433
|
-
offset = new
|
|
8752
|
+
offset = new THREE26__namespace.Vector3(
|
|
8434
8753
|
interactable.grabOffsetPosition.x,
|
|
8435
8754
|
interactable.grabOffsetPosition.y,
|
|
8436
8755
|
interactable.grabOffsetPosition.z
|
|
8437
8756
|
);
|
|
8438
8757
|
} else {
|
|
8439
|
-
offset = new
|
|
8758
|
+
offset = new THREE26__namespace.Vector3(
|
|
8440
8759
|
transform.position.x - hand.x,
|
|
8441
8760
|
transform.position.y - hand.y,
|
|
8442
8761
|
transform.position.z - hand.z
|
|
8443
|
-
);
|
|
8762
|
+
).applyQuaternion(handQuaternion.clone().invert());
|
|
8444
8763
|
}
|
|
8445
8764
|
const physics = world.getComponent(entityId, PhysicsComponent);
|
|
8446
8765
|
let restoreBodyType = null;
|
|
@@ -8450,11 +8769,30 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8450
8769
|
}
|
|
8451
8770
|
const tracker = new ThrowVelocityTracker();
|
|
8452
8771
|
tracker.record(hand, this.elapsed);
|
|
8772
|
+
const attachPoint = this.chooseAttachPoint(
|
|
8773
|
+
world,
|
|
8774
|
+
input,
|
|
8775
|
+
entityId,
|
|
8776
|
+
interactable,
|
|
8777
|
+
role
|
|
8778
|
+
);
|
|
8779
|
+
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
8780
|
+
const handRotationOffset = handQuaternion.clone().invert().multiply(objectQuaternion);
|
|
8453
8781
|
this.grabs.set(input, {
|
|
8454
8782
|
entityId,
|
|
8783
|
+
role,
|
|
8784
|
+
attachPointId: attachPoint?.id ?? null,
|
|
8785
|
+
attachLocal: attachPoint ? new THREE26__namespace.Vector3(
|
|
8786
|
+
attachPoint.position.x,
|
|
8787
|
+
attachPoint.position.y,
|
|
8788
|
+
attachPoint.position.z
|
|
8789
|
+
) : null,
|
|
8790
|
+
attachQuaternion: attachPoint ? quatFromEulerVec(attachPoint.rotation) : null,
|
|
8791
|
+
handRotationOffset,
|
|
8792
|
+
twoHand: null,
|
|
8455
8793
|
offset,
|
|
8456
|
-
rotationOffset: new
|
|
8457
|
-
new
|
|
8794
|
+
rotationOffset: new THREE26__namespace.Quaternion().setFromEuler(
|
|
8795
|
+
new THREE26__namespace.Euler(
|
|
8458
8796
|
interactable.grabOffsetRotation.x,
|
|
8459
8797
|
interactable.grabOffsetRotation.y,
|
|
8460
8798
|
interactable.grabOffsetRotation.z
|
|
@@ -8465,33 +8803,111 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8465
8803
|
restoreBodyType,
|
|
8466
8804
|
tracker,
|
|
8467
8805
|
lastHandQuaternion: handQuaternion.clone(),
|
|
8468
|
-
angularVelocity: new
|
|
8806
|
+
angularVelocity: new THREE26__namespace.Vector3()
|
|
8469
8807
|
});
|
|
8470
|
-
|
|
8808
|
+
if (role === "primary") {
|
|
8809
|
+
this.dispatch(world, entityId, (b) => b.onGrab(input));
|
|
8810
|
+
}
|
|
8811
|
+
}
|
|
8812
|
+
/** Drive every held object, once each, after grabs and releases settle. */
|
|
8813
|
+
moveAllHeld(world, deltaTime) {
|
|
8814
|
+
const done = /* @__PURE__ */ new Set();
|
|
8815
|
+
for (const [input, record] of this.grabs) {
|
|
8816
|
+
if (done.has(record.entityId)) continue;
|
|
8817
|
+
done.add(record.entityId);
|
|
8818
|
+
const holders = this.holdersOf(record.entityId);
|
|
8819
|
+
if (holders.length >= 2) {
|
|
8820
|
+
this.moveTwoHand(world, record.entityId, holders, deltaTime);
|
|
8821
|
+
} else {
|
|
8822
|
+
this.moveHeld(world, input, record, deltaTime);
|
|
8823
|
+
}
|
|
8824
|
+
}
|
|
8825
|
+
}
|
|
8826
|
+
/** Solve and apply a two-hand hold. */
|
|
8827
|
+
moveTwoHand(world, entityId, holders, deltaTime) {
|
|
8828
|
+
const primary = holders.find((h) => h.record.role === "primary");
|
|
8829
|
+
const secondary = holders.find((h) => h.record.role === "secondary");
|
|
8830
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
8831
|
+
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
8832
|
+
const basis = primary?.record.twoHand ?? null;
|
|
8833
|
+
if (!primary || !secondary || !transform || !interactable || !basis) {
|
|
8834
|
+
if (primary) {
|
|
8835
|
+
this.moveHeld(world, primary.input, primary.record, deltaTime);
|
|
8836
|
+
}
|
|
8837
|
+
return;
|
|
8838
|
+
}
|
|
8839
|
+
const primaryHand = this.handPosition(primary.input);
|
|
8840
|
+
const primaryQuaternion = this.handQuaternion(primary.input);
|
|
8841
|
+
const solved = solveTwoHandTransform(
|
|
8842
|
+
{ position: primaryHand, quaternion: primaryQuaternion },
|
|
8843
|
+
{
|
|
8844
|
+
position: this.handPosition(secondary.input),
|
|
8845
|
+
quaternion: this.handQuaternion(secondary.input)
|
|
8846
|
+
},
|
|
8847
|
+
basis,
|
|
8848
|
+
{
|
|
8849
|
+
rotationMode: interactable.twoHandRotation,
|
|
8850
|
+
allowScale: interactable.allowTwoHandScale,
|
|
8851
|
+
minScale: interactable.minScale,
|
|
8852
|
+
maxScale: interactable.maxScale
|
|
8853
|
+
}
|
|
8854
|
+
);
|
|
8855
|
+
transform.position.x = solved.position.x;
|
|
8856
|
+
transform.position.y = solved.position.y;
|
|
8857
|
+
transform.position.z = solved.position.z;
|
|
8858
|
+
writeEuler(transform.rotation, solved.quaternion);
|
|
8859
|
+
if (interactable.allowTwoHandScale) {
|
|
8860
|
+
transform.scale.x = solved.scale.x;
|
|
8861
|
+
transform.scale.y = solved.scale.y;
|
|
8862
|
+
transform.scale.z = solved.scale.z;
|
|
8863
|
+
}
|
|
8864
|
+
primary.record.tracker.record(primaryHand, this.elapsed);
|
|
8865
|
+
primary.record.angularVelocity = angularVelocityFrom(
|
|
8866
|
+
primary.record.lastHandQuaternion,
|
|
8867
|
+
primaryQuaternion,
|
|
8868
|
+
deltaTime
|
|
8869
|
+
);
|
|
8870
|
+
primary.record.lastHandQuaternion = primaryQuaternion.clone();
|
|
8471
8871
|
}
|
|
8472
8872
|
moveHeld(world, input, held, deltaTime) {
|
|
8473
8873
|
const transform = world.getComponent(held.entityId, TransformComponent);
|
|
8474
8874
|
if (!transform) return;
|
|
8475
8875
|
const hand = this.handPosition(input);
|
|
8876
|
+
const handQuaternion = this.handQuaternion(input);
|
|
8877
|
+
const objectQuaternion = held.attachQuaternion ? handQuaternion.clone().multiply(held.rotationOffset).multiply(held.attachQuaternion.clone().invert()) : handQuaternion.clone().multiply(held.handRotationOffset);
|
|
8476
8878
|
if (held.remote) {
|
|
8477
|
-
const target = new
|
|
8879
|
+
const target = new THREE26__namespace.Vector3().copy(input.rayDirection).multiplyScalar(held.remoteDistance).add(input.rayOrigin);
|
|
8478
8880
|
transform.position.x = target.x;
|
|
8479
8881
|
transform.position.y = target.y;
|
|
8480
8882
|
transform.position.z = target.z;
|
|
8883
|
+
writeEuler(transform.rotation, objectQuaternion);
|
|
8884
|
+
} else if (held.attachLocal) {
|
|
8885
|
+
const anchor = held.attachLocal.clone().multiply(
|
|
8886
|
+
new THREE26__namespace.Vector3(
|
|
8887
|
+
transform.scale.x,
|
|
8888
|
+
transform.scale.y,
|
|
8889
|
+
transform.scale.z
|
|
8890
|
+
)
|
|
8891
|
+
).applyQuaternion(objectQuaternion);
|
|
8892
|
+
transform.position.x = hand.x - anchor.x;
|
|
8893
|
+
transform.position.y = hand.y - anchor.y;
|
|
8894
|
+
transform.position.z = hand.z - anchor.z;
|
|
8895
|
+
writeEuler(transform.rotation, objectQuaternion);
|
|
8481
8896
|
} else {
|
|
8482
|
-
|
|
8483
|
-
transform.position.
|
|
8484
|
-
transform.position.
|
|
8897
|
+
const carried = held.offset.clone().applyQuaternion(handQuaternion);
|
|
8898
|
+
transform.position.x = hand.x + carried.x;
|
|
8899
|
+
transform.position.y = hand.y + carried.y;
|
|
8900
|
+
transform.position.z = hand.z + carried.z;
|
|
8901
|
+
writeEuler(transform.rotation, objectQuaternion);
|
|
8485
8902
|
}
|
|
8486
8903
|
held.tracker.record(
|
|
8487
|
-
held.remote ? new
|
|
8904
|
+
held.remote ? new THREE26__namespace.Vector3(
|
|
8488
8905
|
transform.position.x,
|
|
8489
8906
|
transform.position.y,
|
|
8490
8907
|
transform.position.z
|
|
8491
8908
|
) : hand,
|
|
8492
8909
|
this.elapsed
|
|
8493
8910
|
);
|
|
8494
|
-
const handQuaternion = this.handQuaternion(input);
|
|
8495
8911
|
held.angularVelocity = angularVelocityFrom(
|
|
8496
8912
|
held.lastHandQuaternion,
|
|
8497
8913
|
handQuaternion,
|
|
@@ -8507,22 +8923,41 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8507
8923
|
held.entityId,
|
|
8508
8924
|
XRInteractableComponent
|
|
8509
8925
|
);
|
|
8926
|
+
const remaining = this.holdersOf(held.entityId);
|
|
8927
|
+
if (remaining.length > 0 && interactable) {
|
|
8928
|
+
if (held.role === "secondary") {
|
|
8929
|
+
const primary = remaining.find((h) => h.record.role === "primary");
|
|
8930
|
+
if (primary) {
|
|
8931
|
+
primary.record.twoHand = null;
|
|
8932
|
+
this.reanchor(world, primary.input, primary.record, interactable);
|
|
8933
|
+
}
|
|
8934
|
+
this.dispatch(
|
|
8935
|
+
world,
|
|
8936
|
+
held.entityId,
|
|
8937
|
+
(b) => b.onSecondaryRelease(input)
|
|
8938
|
+
);
|
|
8939
|
+
} else {
|
|
8940
|
+
const next = remaining[0];
|
|
8941
|
+
next.record.role = "primary";
|
|
8942
|
+
next.record.twoHand = null;
|
|
8943
|
+
next.record.restoreBodyType = held.restoreBodyType;
|
|
8944
|
+
this.reanchor(world, next.input, next.record, interactable);
|
|
8945
|
+
this.dispatch(world, held.entityId, (b) => b.onRelease(input));
|
|
8946
|
+
}
|
|
8947
|
+
held.tracker.clear();
|
|
8948
|
+
return;
|
|
8949
|
+
}
|
|
8510
8950
|
const physics = world.getComponent(held.entityId, PhysicsComponent);
|
|
8511
8951
|
if (held.restoreBodyType !== null && physics) {
|
|
8512
8952
|
physics.values.rigidbody.type = held.restoreBodyType;
|
|
8513
|
-
const body = physics.rigidBody;
|
|
8514
8953
|
const dynamic = held.restoreBodyType === "dynamic";
|
|
8515
|
-
if (
|
|
8954
|
+
if (dynamic && interactable?.throwOnRelease) {
|
|
8516
8955
|
const velocity = held.tracker.computeVelocity(this.elapsed).multiplyScalar(interactable.throwStrength);
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
const spin = held.angularVelocity;
|
|
8523
|
-
body.setAngvel({ x: spin.x, y: spin.y, z: spin.z }, true);
|
|
8524
|
-
} catch {
|
|
8525
|
-
}
|
|
8956
|
+
const spin = held.angularVelocity;
|
|
8957
|
+
setPhysicsLiveRef(physics, "pendingVelocity", {
|
|
8958
|
+
linear: { x: velocity.x, y: velocity.y, z: velocity.z },
|
|
8959
|
+
angular: { x: spin.x, y: spin.y, z: spin.z }
|
|
8960
|
+
});
|
|
8526
8961
|
}
|
|
8527
8962
|
}
|
|
8528
8963
|
held.tracker.clear();
|
|
@@ -8540,7 +8975,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8540
8975
|
*/
|
|
8541
8976
|
handPosition(input) {
|
|
8542
8977
|
if (input.gripPosition) return input.gripPosition;
|
|
8543
|
-
return new
|
|
8978
|
+
return new THREE26__namespace.Vector3().copy(input.rayDirection).multiplyScalar(RAYLESS_HOLD_DISTANCE).add(input.rayOrigin);
|
|
8544
8979
|
}
|
|
8545
8980
|
/**
|
|
8546
8981
|
* Hand orientation. Grip-less sources (gaze / transient-pointer) have none,
|
|
@@ -8548,8 +8983,8 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8548
8983
|
*/
|
|
8549
8984
|
handQuaternion(input) {
|
|
8550
8985
|
if (input.gripQuaternion) return input.gripQuaternion.clone();
|
|
8551
|
-
return new
|
|
8552
|
-
new
|
|
8986
|
+
return new THREE26__namespace.Quaternion().setFromUnitVectors(
|
|
8987
|
+
new THREE26__namespace.Vector3(0, 0, -1),
|
|
8553
8988
|
input.rayDirection.clone().normalize()
|
|
8554
8989
|
);
|
|
8555
8990
|
}
|
|
@@ -8570,10 +9005,57 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
8570
9005
|
getHoveredEntityId() {
|
|
8571
9006
|
return this.hoveredEntityId;
|
|
8572
9007
|
}
|
|
9008
|
+
/**
|
|
9009
|
+
* What this hand is pointing at, with the distance to it.
|
|
9010
|
+
*
|
|
9011
|
+
* The distance is what lets the pointer ray stop at the surface instead of
|
|
9012
|
+
* passing through the object.
|
|
9013
|
+
*/
|
|
9014
|
+
getHoverFor(handedness) {
|
|
9015
|
+
for (const [input, hover] of this.hovers) {
|
|
9016
|
+
if (input.handedness === handedness) return hover;
|
|
9017
|
+
}
|
|
9018
|
+
return null;
|
|
9019
|
+
}
|
|
9020
|
+
/** Every entity under a pointer this frame — drives hover feedback. */
|
|
9021
|
+
getHoveredEntityIds() {
|
|
9022
|
+
const ids = /* @__PURE__ */ new Set();
|
|
9023
|
+
for (const hover of this.hovers.values()) ids.add(hover.entityId);
|
|
9024
|
+
return ids;
|
|
9025
|
+
}
|
|
9026
|
+
/** Entities currently held, so hover feedback can skip them. */
|
|
9027
|
+
getHeldEntityIds() {
|
|
9028
|
+
const ids = /* @__PURE__ */ new Set();
|
|
9029
|
+
for (const record of this.grabs.values()) ids.add(record.entityId);
|
|
9030
|
+
return ids;
|
|
9031
|
+
}
|
|
8573
9032
|
/** True when any source is holding something. */
|
|
8574
9033
|
isGrabbing() {
|
|
8575
9034
|
return this.grabs.size > 0;
|
|
8576
9035
|
}
|
|
9036
|
+
/**
|
|
9037
|
+
* How an entity is currently held.
|
|
9038
|
+
*
|
|
9039
|
+
* Exposed for scripts: a Behaviour can poll this in `onUpdate` to drive
|
|
9040
|
+
* two-hand-specific behaviour — showing a bipod when both hands are on a
|
|
9041
|
+
* weapon, reading the live hand separation to gate a gesture, or reacting to
|
|
9042
|
+
* the scale a pull-apart produced. Returns null when nothing holds it.
|
|
9043
|
+
*/
|
|
9044
|
+
getGrabInfo(entityId) {
|
|
9045
|
+
const holders = this.holdersOf(entityId);
|
|
9046
|
+
if (holders.length === 0) return null;
|
|
9047
|
+
const primary = holders.find((h) => h.record.role === "primary");
|
|
9048
|
+
const secondary = holders.find((h) => h.record.role === "secondary");
|
|
9049
|
+
return {
|
|
9050
|
+
hands: holders.length,
|
|
9051
|
+
primaryHandedness: primary?.input.handedness ?? null,
|
|
9052
|
+
secondaryHandedness: secondary?.input.handedness ?? null,
|
|
9053
|
+
handSeparation: primary && secondary ? this.handPosition(primary.input).distanceTo(
|
|
9054
|
+
this.handPosition(secondary.input)
|
|
9055
|
+
) : null,
|
|
9056
|
+
attachPointIds: holders.map((h) => h.record.attachPointId)
|
|
9057
|
+
};
|
|
9058
|
+
}
|
|
8577
9059
|
};
|
|
8578
9060
|
__name(_XRInteractionSystem, "XRInteractionSystem");
|
|
8579
9061
|
var XRInteractionSystem = _XRInteractionSystem;
|
|
@@ -8591,7 +9073,7 @@ function sampleTeleportArc(origin, direction, out = [], options) {
|
|
|
8591
9073
|
for (let i = 0; i < steps; i += 1) {
|
|
8592
9074
|
const t = i / (steps - 1) * maxTime;
|
|
8593
9075
|
out.push(
|
|
8594
|
-
new
|
|
9076
|
+
new THREE26__namespace.Vector3(
|
|
8595
9077
|
origin.x + velocity.x * t,
|
|
8596
9078
|
origin.y + velocity.y * t - 0.5 * gravity * t * t,
|
|
8597
9079
|
origin.z + velocity.z * t
|
|
@@ -8603,11 +9085,11 @@ function sampleTeleportArc(origin, direction, out = [], options) {
|
|
|
8603
9085
|
__name(sampleTeleportArc, "sampleTeleportArc");
|
|
8604
9086
|
|
|
8605
9087
|
// core/systems/XRLocomotionSystem.ts
|
|
8606
|
-
var UP = new
|
|
9088
|
+
var UP = new THREE26__namespace.Vector3(0, 1, 0);
|
|
8607
9089
|
var AXIS_DEADZONE = 0.5;
|
|
8608
9090
|
var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
8609
9091
|
constructor(inputSystem) {
|
|
8610
|
-
this.raycaster = new
|
|
9092
|
+
this.raycaster = new THREE26__namespace.Raycaster();
|
|
8611
9093
|
/** Per-source latch so one stick push yields exactly one snap turn. */
|
|
8612
9094
|
this.turnLatched = /* @__PURE__ */ new WeakSet();
|
|
8613
9095
|
/** Reused arc buffer — aiming runs every frame. */
|
|
@@ -8716,7 +9198,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
8716
9198
|
}
|
|
8717
9199
|
if (this.turnLatched.has(source)) continue;
|
|
8718
9200
|
this.turnLatched.add(source);
|
|
8719
|
-
transform.rotation.y -= Math.sign(x) *
|
|
9201
|
+
transform.rotation.y -= Math.sign(x) * THREE26__namespace.MathUtils.degToRad(rig.snapTurnDegrees);
|
|
8720
9202
|
}
|
|
8721
9203
|
}
|
|
8722
9204
|
applySmoothMove(world, rig, transform, inputs, deltaTime) {
|
|
@@ -8726,12 +9208,12 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
8726
9208
|
const y = input.axes[1] ?? 0;
|
|
8727
9209
|
if (Math.abs(x) < 0.15 && Math.abs(y) < 0.15) continue;
|
|
8728
9210
|
const camera = world.getCamera();
|
|
8729
|
-
const forward = new
|
|
9211
|
+
const forward = new THREE26__namespace.Vector3();
|
|
8730
9212
|
camera.getWorldDirection(forward);
|
|
8731
9213
|
forward.y = 0;
|
|
8732
9214
|
if (forward.lengthSq() < 1e-6) continue;
|
|
8733
9215
|
forward.normalize();
|
|
8734
|
-
const right = new
|
|
9216
|
+
const right = new THREE26__namespace.Vector3().crossVectors(forward, UP).normalize();
|
|
8735
9217
|
const step = rig.moveSpeed * Math.max(0, deltaTime);
|
|
8736
9218
|
transform.position.x += (forward.x * -y + right.x * x) * step;
|
|
8737
9219
|
transform.position.z += (forward.z * -y + right.z * x) * step;
|
|
@@ -8796,7 +9278,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
8796
9278
|
for (let i = 1; i < points.length; i += 1) {
|
|
8797
9279
|
const from = points[i - 1];
|
|
8798
9280
|
const to = points[i];
|
|
8799
|
-
const delta = new
|
|
9281
|
+
const delta = new THREE26__namespace.Vector3().subVectors(to, from);
|
|
8800
9282
|
const distance = delta.length();
|
|
8801
9283
|
if (distance < 1e-6) continue;
|
|
8802
9284
|
this.raycaster.set(from, delta.divideScalar(distance));
|
|
@@ -9004,9 +9486,9 @@ var XRSessionSystem = _XRSessionSystem;
|
|
|
9004
9486
|
function buildGeometry2(area) {
|
|
9005
9487
|
if (area.shape === "circle") {
|
|
9006
9488
|
const radius = Math.max(5e-3, area.width / 2);
|
|
9007
|
-
return new
|
|
9489
|
+
return new THREE26__namespace.CircleGeometry(radius, 48);
|
|
9008
9490
|
}
|
|
9009
|
-
return new
|
|
9491
|
+
return new THREE26__namespace.PlaneGeometry(
|
|
9010
9492
|
Math.max(0.01, area.width),
|
|
9011
9493
|
Math.max(0.01, area.depth)
|
|
9012
9494
|
);
|
|
@@ -9029,7 +9511,7 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
9029
9511
|
for (const entityId of entityIds) {
|
|
9030
9512
|
const area = world.getComponent(entityId, VRTeleportAreaComponent);
|
|
9031
9513
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
9032
|
-
if (!area || !(object instanceof
|
|
9514
|
+
if (!area || !(object instanceof THREE26__namespace.Mesh)) continue;
|
|
9033
9515
|
const signature = signatureOf(area);
|
|
9034
9516
|
if (this.signatures.get(entityId) === signature) continue;
|
|
9035
9517
|
this.signatures.set(entityId, signature);
|
|
@@ -9041,18 +9523,18 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
9041
9523
|
__name(_VRTeleportAreaSystem, "VRTeleportAreaSystem");
|
|
9042
9524
|
var VRTeleportAreaSystem = _VRTeleportAreaSystem;
|
|
9043
9525
|
function createHandMaterial(preset, options) {
|
|
9044
|
-
const color = new
|
|
9526
|
+
const color = new THREE26__namespace.Color(options.color);
|
|
9045
9527
|
switch (preset) {
|
|
9046
9528
|
case "ghost":
|
|
9047
|
-
return new
|
|
9529
|
+
return new THREE26__namespace.MeshBasicMaterial({
|
|
9048
9530
|
color,
|
|
9049
9531
|
transparent: true,
|
|
9050
9532
|
opacity: Math.min(1, Math.max(0.05, options.opacity * 0.45)),
|
|
9051
9533
|
depthWrite: false,
|
|
9052
|
-
side:
|
|
9534
|
+
side: THREE26__namespace.DoubleSide
|
|
9053
9535
|
});
|
|
9054
9536
|
case "neon":
|
|
9055
|
-
return new
|
|
9537
|
+
return new THREE26__namespace.MeshStandardMaterial({
|
|
9056
9538
|
color,
|
|
9057
9539
|
emissive: color,
|
|
9058
9540
|
emissiveIntensity: Math.max(0.5, options.emissiveIntensity || 2),
|
|
@@ -9062,7 +9544,7 @@ function createHandMaterial(preset, options) {
|
|
|
9062
9544
|
opacity: options.opacity
|
|
9063
9545
|
});
|
|
9064
9546
|
case "skeleton":
|
|
9065
|
-
return new
|
|
9547
|
+
return new THREE26__namespace.MeshBasicMaterial({
|
|
9066
9548
|
color,
|
|
9067
9549
|
wireframe: true,
|
|
9068
9550
|
transparent: true,
|
|
@@ -9070,7 +9552,7 @@ function createHandMaterial(preset, options) {
|
|
|
9070
9552
|
});
|
|
9071
9553
|
case "custom":
|
|
9072
9554
|
case "default":
|
|
9073
|
-
return new
|
|
9555
|
+
return new THREE26__namespace.MeshStandardMaterial({
|
|
9074
9556
|
color,
|
|
9075
9557
|
roughness: 0.85,
|
|
9076
9558
|
metalness: 0,
|
|
@@ -9078,10 +9560,10 @@ function createHandMaterial(preset, options) {
|
|
|
9078
9560
|
emissiveIntensity: Math.max(0, options.emissiveIntensity),
|
|
9079
9561
|
transparent: options.opacity < 1,
|
|
9080
9562
|
opacity: options.opacity,
|
|
9081
|
-
side:
|
|
9563
|
+
side: THREE26__namespace.DoubleSide
|
|
9082
9564
|
});
|
|
9083
9565
|
default: {
|
|
9084
|
-
return new
|
|
9566
|
+
return new THREE26__namespace.MeshStandardMaterial({ color });
|
|
9085
9567
|
}
|
|
9086
9568
|
}
|
|
9087
9569
|
}
|
|
@@ -9094,6 +9576,9 @@ function applyHandMaterial(root, material) {
|
|
|
9094
9576
|
});
|
|
9095
9577
|
}
|
|
9096
9578
|
__name(applyHandMaterial, "applyHandMaterial");
|
|
9579
|
+
|
|
9580
|
+
// core/systems/XRControllerVisualSystem.ts
|
|
9581
|
+
var RAY_LENGTH = 5;
|
|
9097
9582
|
var SLOTS = [
|
|
9098
9583
|
{ index: 0, side: "left" },
|
|
9099
9584
|
{ index: 1, side: "right" }
|
|
@@ -9102,7 +9587,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
9102
9587
|
constructor(options) {
|
|
9103
9588
|
this.controllerModelFactory = new XRControllerModelFactory_js.XRControllerModelFactory();
|
|
9104
9589
|
this.handModelFactory = new XRHandModelFactory_js.XRHandModelFactory();
|
|
9105
|
-
this.group = new
|
|
9590
|
+
this.group = new THREE26__namespace.Group();
|
|
9106
9591
|
this.slots = /* @__PURE__ */ new Map();
|
|
9107
9592
|
this.attachedTo = null;
|
|
9108
9593
|
/** Last applied preset signature, so materials rebuild only on real change. */
|
|
@@ -9132,6 +9617,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
9132
9617
|
visuals.controllerModel.visible = showControllers && hasController;
|
|
9133
9618
|
visuals.handModel.visible = showHands && hasHand;
|
|
9134
9619
|
visuals.ray.visible = this.shouldShowRay(interactor);
|
|
9620
|
+
this.fitRayToHover(visuals.ray, side);
|
|
9135
9621
|
if (showHands && this.handMaterial) {
|
|
9136
9622
|
applyHandMaterial(visuals.handModel, this.handMaterial);
|
|
9137
9623
|
}
|
|
@@ -9212,6 +9698,18 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
9212
9698
|
if (!this.interactionSystem) return true;
|
|
9213
9699
|
return this.interactionSystem.getHoveredEntityId() !== null || this.interactionSystem.isGrabbing();
|
|
9214
9700
|
}
|
|
9701
|
+
/**
|
|
9702
|
+
* Stop the ray at whatever it is pointing at.
|
|
9703
|
+
*
|
|
9704
|
+
* A fixed-length ray drawn with depth testing off punches straight through the
|
|
9705
|
+
* object, so the user cannot tell where the pointer actually lands. Scaling it
|
|
9706
|
+
* to the hit distance turns it into a pointer that meets the surface.
|
|
9707
|
+
*/
|
|
9708
|
+
fitRayToHover(ray, side) {
|
|
9709
|
+
const hover = this.interactionSystem?.getHoverFor(side) ?? null;
|
|
9710
|
+
const length = hover && Number.isFinite(hover.distance) && hover.distance > 0 ? Math.min(hover.distance, RAY_LENGTH) : RAY_LENGTH;
|
|
9711
|
+
ray.scale.z = length / RAY_LENGTH;
|
|
9712
|
+
}
|
|
9215
9713
|
/** Lazily build per-slot visuals; the device reports profiles late. */
|
|
9216
9714
|
ensureSlots(world) {
|
|
9217
9715
|
const renderer = world.getRenderer();
|
|
@@ -9251,17 +9749,17 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
9251
9749
|
this.attachedTo = target;
|
|
9252
9750
|
}
|
|
9253
9751
|
createRay() {
|
|
9254
|
-
const geometry = new
|
|
9255
|
-
new
|
|
9256
|
-
new
|
|
9752
|
+
const geometry = new THREE26__namespace.BufferGeometry().setFromPoints([
|
|
9753
|
+
new THREE26__namespace.Vector3(0, 0, 0),
|
|
9754
|
+
new THREE26__namespace.Vector3(0, 0, -RAY_LENGTH)
|
|
9257
9755
|
]);
|
|
9258
|
-
const material = new
|
|
9756
|
+
const material = new THREE26__namespace.LineBasicMaterial({
|
|
9259
9757
|
color: "#4da3ff",
|
|
9260
9758
|
transparent: true,
|
|
9261
9759
|
opacity: 0.6,
|
|
9262
9760
|
depthTest: false
|
|
9263
9761
|
});
|
|
9264
|
-
const line = new
|
|
9762
|
+
const line = new THREE26__namespace.Line(geometry, material);
|
|
9265
9763
|
line.name = "XRPointerRay";
|
|
9266
9764
|
line.renderOrder = 999;
|
|
9267
9765
|
line.visible = false;
|
|
@@ -9290,23 +9788,23 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
9290
9788
|
__name(_XRControllerVisualSystem, "XRControllerVisualSystem");
|
|
9291
9789
|
var XRControllerVisualSystem = _XRControllerVisualSystem;
|
|
9292
9790
|
var MARKER_RADIUS = 0.28;
|
|
9293
|
-
var ACCENT = new
|
|
9294
|
-
var BLOCKED = new
|
|
9791
|
+
var ACCENT = new THREE26__namespace.Color("#4da3ff");
|
|
9792
|
+
var BLOCKED = new THREE26__namespace.Color("#ff5a5a");
|
|
9295
9793
|
var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
9296
9794
|
constructor(locomotionSystem) {
|
|
9297
|
-
this.group = new
|
|
9298
|
-
this.arcGeometry = new
|
|
9299
|
-
this.marker = new
|
|
9795
|
+
this.group = new THREE26__namespace.Group();
|
|
9796
|
+
this.arcGeometry = new THREE26__namespace.BufferGeometry();
|
|
9797
|
+
this.marker = new THREE26__namespace.Group();
|
|
9300
9798
|
this.attached = false;
|
|
9301
9799
|
this.locomotionSystem = locomotionSystem;
|
|
9302
9800
|
this.group.name = "XRTeleportVisuals";
|
|
9303
9801
|
this.group.userData.ecsPreviewHidden = true;
|
|
9304
|
-
const arcMaterial = new
|
|
9802
|
+
const arcMaterial = new THREE26__namespace.LineBasicMaterial({
|
|
9305
9803
|
vertexColors: true,
|
|
9306
9804
|
transparent: true,
|
|
9307
9805
|
depthTest: false
|
|
9308
9806
|
});
|
|
9309
|
-
this.arc = new
|
|
9807
|
+
this.arc = new THREE26__namespace.Line(this.arcGeometry, arcMaterial);
|
|
9310
9808
|
this.arc.frustumCulled = false;
|
|
9311
9809
|
this.arc.renderOrder = 998;
|
|
9312
9810
|
this.group.add(this.arc);
|
|
@@ -9354,39 +9852,39 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
9354
9852
|
}
|
|
9355
9853
|
this.arcGeometry.setAttribute(
|
|
9356
9854
|
"position",
|
|
9357
|
-
new
|
|
9855
|
+
new THREE26__namespace.BufferAttribute(positions, 3)
|
|
9358
9856
|
);
|
|
9359
|
-
this.arcGeometry.setAttribute("color", new
|
|
9857
|
+
this.arcGeometry.setAttribute("color", new THREE26__namespace.BufferAttribute(colors, 3));
|
|
9360
9858
|
this.arcGeometry.computeBoundingSphere();
|
|
9361
9859
|
}
|
|
9362
9860
|
createRing() {
|
|
9363
|
-
const geometry = new
|
|
9861
|
+
const geometry = new THREE26__namespace.RingGeometry(
|
|
9364
9862
|
MARKER_RADIUS * 0.72,
|
|
9365
9863
|
MARKER_RADIUS,
|
|
9366
9864
|
48
|
|
9367
9865
|
);
|
|
9368
9866
|
geometry.rotateX(-Math.PI / 2);
|
|
9369
|
-
return new
|
|
9867
|
+
return new THREE26__namespace.Mesh(
|
|
9370
9868
|
geometry,
|
|
9371
|
-
new
|
|
9869
|
+
new THREE26__namespace.MeshBasicMaterial({
|
|
9372
9870
|
color: ACCENT,
|
|
9373
9871
|
transparent: true,
|
|
9374
9872
|
opacity: 0.9,
|
|
9375
|
-
side:
|
|
9873
|
+
side: THREE26__namespace.DoubleSide,
|
|
9376
9874
|
depthTest: false
|
|
9377
9875
|
})
|
|
9378
9876
|
);
|
|
9379
9877
|
}
|
|
9380
9878
|
createDot() {
|
|
9381
|
-
const geometry = new
|
|
9879
|
+
const geometry = new THREE26__namespace.CircleGeometry(MARKER_RADIUS * 0.16, 24);
|
|
9382
9880
|
geometry.rotateX(-Math.PI / 2);
|
|
9383
|
-
return new
|
|
9881
|
+
return new THREE26__namespace.Mesh(
|
|
9384
9882
|
geometry,
|
|
9385
|
-
new
|
|
9883
|
+
new THREE26__namespace.MeshBasicMaterial({
|
|
9386
9884
|
color: ACCENT,
|
|
9387
9885
|
transparent: true,
|
|
9388
9886
|
opacity: 0.55,
|
|
9389
|
-
side:
|
|
9887
|
+
side: THREE26__namespace.DoubleSide,
|
|
9390
9888
|
depthTest: false
|
|
9391
9889
|
})
|
|
9392
9890
|
);
|
|
@@ -9488,7 +9986,7 @@ function boneDirections(joints, finger) {
|
|
|
9488
9986
|
const from = joints[chain[i - 1]];
|
|
9489
9987
|
const to = joints[chain[i]];
|
|
9490
9988
|
if (!from || !to) return null;
|
|
9491
|
-
const direction = new
|
|
9989
|
+
const direction = new THREE26__namespace.Vector3().subVectors(to, from);
|
|
9492
9990
|
if (direction.lengthSq() < 1e-12) return null;
|
|
9493
9991
|
directions.push(direction.normalize());
|
|
9494
9992
|
}
|
|
@@ -9561,8 +10059,8 @@ function computeSpread(joints, a, b) {
|
|
|
9561
10059
|
const bBase = joints[METACARPAL_JOINTS[b]];
|
|
9562
10060
|
const bTip = joints[TIP_JOINTS[b]];
|
|
9563
10061
|
if (!aBase || !aTip || !bBase || !bTip) return null;
|
|
9564
|
-
const dirA = new
|
|
9565
|
-
const dirB = new
|
|
10062
|
+
const dirA = new THREE26__namespace.Vector3().subVectors(aTip, aBase);
|
|
10063
|
+
const dirB = new THREE26__namespace.Vector3().subVectors(bTip, bBase);
|
|
9566
10064
|
if (dirA.lengthSq() < 1e-12 || dirB.lengthSq() < 1e-12) return null;
|
|
9567
10065
|
return clamp01((1 - dirA.normalize().dot(dirB.normalize())) / 0.45);
|
|
9568
10066
|
}
|
|
@@ -9572,18 +10070,18 @@ function computePalmPose(joints, handedness) {
|
|
|
9572
10070
|
const indexBase = joints["index-finger-metacarpal"];
|
|
9573
10071
|
const pinkyBase = joints["pinky-finger-metacarpal"];
|
|
9574
10072
|
if (!wrist || !indexBase || !pinkyBase) return null;
|
|
9575
|
-
const u = new
|
|
9576
|
-
const v = new
|
|
9577
|
-
const normal = new
|
|
10073
|
+
const u = new THREE26__namespace.Vector3().subVectors(indexBase, wrist);
|
|
10074
|
+
const v = new THREE26__namespace.Vector3().subVectors(pinkyBase, wrist);
|
|
10075
|
+
const normal = new THREE26__namespace.Vector3().crossVectors(u, v);
|
|
9578
10076
|
if (normal.lengthSq() < 1e-12) return null;
|
|
9579
10077
|
normal.normalize();
|
|
9580
10078
|
if (handedness === "left") normal.multiplyScalar(-1);
|
|
9581
|
-
const right = new
|
|
10079
|
+
const right = new THREE26__namespace.Vector3().subVectors(indexBase, pinkyBase);
|
|
9582
10080
|
if (right.lengthSq() < 1e-12) return null;
|
|
9583
10081
|
right.normalize();
|
|
9584
10082
|
if (handedness === "left") right.multiplyScalar(-1);
|
|
9585
|
-
const up = new
|
|
9586
|
-
const center = new
|
|
10083
|
+
const up = new THREE26__namespace.Vector3().crossVectors(normal, right).normalize();
|
|
10084
|
+
const center = new THREE26__namespace.Vector3().add(wrist).add(indexBase).add(pinkyBase).divideScalar(3);
|
|
9587
10085
|
return {
|
|
9588
10086
|
center,
|
|
9589
10087
|
normal,
|
|
@@ -9614,7 +10112,7 @@ function computeHandShape(joints, handedness) {
|
|
|
9614
10112
|
const thumbTip = joints["thumb-tip"];
|
|
9615
10113
|
let thumbDirection = null;
|
|
9616
10114
|
if (thumbBase && thumbTip) {
|
|
9617
|
-
const direction = new
|
|
10115
|
+
const direction = new THREE26__namespace.Vector3().subVectors(thumbTip, thumbBase);
|
|
9618
10116
|
if (direction.lengthSq() > 1e-12) thumbDirection = direction.normalize();
|
|
9619
10117
|
}
|
|
9620
10118
|
return {
|
|
@@ -9646,12 +10144,12 @@ function scoreAgainst(actual, target, tolerance) {
|
|
|
9646
10144
|
}
|
|
9647
10145
|
__name(scoreAgainst, "scoreAgainst");
|
|
9648
10146
|
var WORLD_DIRECTIONS = {
|
|
9649
|
-
up: new
|
|
9650
|
-
down: new
|
|
9651
|
-
forward: new
|
|
9652
|
-
back: new
|
|
9653
|
-
left: new
|
|
9654
|
-
right: new
|
|
10147
|
+
up: new THREE26__namespace.Vector3(0, 1, 0),
|
|
10148
|
+
down: new THREE26__namespace.Vector3(0, -1, 0),
|
|
10149
|
+
forward: new THREE26__namespace.Vector3(0, 0, -1),
|
|
10150
|
+
back: new THREE26__namespace.Vector3(0, 0, 1),
|
|
10151
|
+
left: new THREE26__namespace.Vector3(-1, 0, 0),
|
|
10152
|
+
right: new THREE26__namespace.Vector3(1, 0, 0)
|
|
9655
10153
|
};
|
|
9656
10154
|
function axisVector(shape, axis) {
|
|
9657
10155
|
if (axis === "thumb") return shape.thumbDirection;
|
|
@@ -9666,7 +10164,7 @@ function resolveDirection(direction, shape, context) {
|
|
|
9666
10164
|
const head = context?.headPosition;
|
|
9667
10165
|
const origin = shape.palm?.center;
|
|
9668
10166
|
if (!head || !origin) return null;
|
|
9669
|
-
const toHead = new
|
|
10167
|
+
const toHead = new THREE26__namespace.Vector3().subVectors(head, origin);
|
|
9670
10168
|
if (toHead.lengthSq() < 1e-12) return null;
|
|
9671
10169
|
toHead.normalize();
|
|
9672
10170
|
return direction === "toward-head" ? toHead : toHead.multiplyScalar(-1);
|
|
@@ -9716,8 +10214,8 @@ function matchHandPose(shape, definition, context) {
|
|
|
9716
10214
|
if (!handAxis || !wanted) {
|
|
9717
10215
|
consider(0, "orientation");
|
|
9718
10216
|
} else {
|
|
9719
|
-
const angle =
|
|
9720
|
-
Math.acos(
|
|
10217
|
+
const angle = THREE26__namespace.MathUtils.radToDeg(
|
|
10218
|
+
Math.acos(THREE26__namespace.MathUtils.clamp(handAxis.dot(wanted), -1, 1))
|
|
9721
10219
|
);
|
|
9722
10220
|
const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
|
|
9723
10221
|
consider(clamp01(1 - normalizedError / MATCH_FALLOFF), "orientation");
|
|
@@ -9795,7 +10293,7 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
9795
10293
|
this.trackers = /* @__PURE__ */ new Map();
|
|
9796
10294
|
this.shapes = /* @__PURE__ */ new Map();
|
|
9797
10295
|
/** Reused so head-relative orientation checks allocate nothing per frame. */
|
|
9798
|
-
this.headPosition = new
|
|
10296
|
+
this.headPosition = new THREE26__namespace.Vector3();
|
|
9799
10297
|
this.elapsed = 0;
|
|
9800
10298
|
this.inputSystem = inputSystem;
|
|
9801
10299
|
}
|
|
@@ -9916,6 +10414,152 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
9916
10414
|
};
|
|
9917
10415
|
__name(_XRHandPoseSystem, "XRHandPoseSystem");
|
|
9918
10416
|
var XRHandPoseSystem = _XRHandPoseSystem;
|
|
10417
|
+
var XR_HOVER_SHELL_FLAG = "__xrHoverShell";
|
|
10418
|
+
var SHELL_INFLATE = 1.04;
|
|
10419
|
+
var SCALE_SMOOTH_SECONDS = 0.09;
|
|
10420
|
+
var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
10421
|
+
constructor(interactionSystem) {
|
|
10422
|
+
this.records = /* @__PURE__ */ new Map();
|
|
10423
|
+
this.interactionSystem = interactionSystem;
|
|
10424
|
+
}
|
|
10425
|
+
update(world, deltaTime) {
|
|
10426
|
+
if (!world.isXrPresenting()) {
|
|
10427
|
+
this.clearAll(world);
|
|
10428
|
+
return;
|
|
10429
|
+
}
|
|
10430
|
+
const hovered = this.interactionSystem.getHoveredEntityIds();
|
|
10431
|
+
const held = this.interactionSystem.getHeldEntityIds();
|
|
10432
|
+
for (const entityId of hovered) {
|
|
10433
|
+
if (held.has(entityId)) continue;
|
|
10434
|
+
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
10435
|
+
if (!interactable?.enabled) continue;
|
|
10436
|
+
if (interactable.hoverBehavior === "none") continue;
|
|
10437
|
+
this.begin(world, entityId, interactable);
|
|
10438
|
+
}
|
|
10439
|
+
for (const [entityId, record] of this.records) {
|
|
10440
|
+
if (!hovered.has(entityId) || held.has(entityId)) {
|
|
10441
|
+
record.active = false;
|
|
10442
|
+
}
|
|
10443
|
+
}
|
|
10444
|
+
this.animate(world, deltaTime);
|
|
10445
|
+
}
|
|
10446
|
+
begin(world, entityId, interactable) {
|
|
10447
|
+
const existing = this.records.get(entityId);
|
|
10448
|
+
if (existing) {
|
|
10449
|
+
existing.active = true;
|
|
10450
|
+
return;
|
|
10451
|
+
}
|
|
10452
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
10453
|
+
if (!transform) return;
|
|
10454
|
+
const wantsColor = interactable.hoverBehavior === "color" || interactable.hoverBehavior === "both";
|
|
10455
|
+
this.records.set(entityId, {
|
|
10456
|
+
shell: wantsColor ? this.addShell(world, entityId, interactable) : null,
|
|
10457
|
+
baseScale: new THREE26__namespace.Vector3(
|
|
10458
|
+
transform.scale.x,
|
|
10459
|
+
transform.scale.y,
|
|
10460
|
+
transform.scale.z
|
|
10461
|
+
),
|
|
10462
|
+
progress: 0,
|
|
10463
|
+
active: true
|
|
10464
|
+
});
|
|
10465
|
+
}
|
|
10466
|
+
/** Build an inflated back-face copy of the object's meshes. */
|
|
10467
|
+
addShell(world, entityId, interactable) {
|
|
10468
|
+
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
10469
|
+
if (!object) return null;
|
|
10470
|
+
const material = new THREE26__namespace.MeshBasicMaterial({
|
|
10471
|
+
color: new THREE26__namespace.Color(interactable.hoverColor),
|
|
10472
|
+
// Back faces only, so the shell shows just outside the silhouette instead
|
|
10473
|
+
// of covering the object.
|
|
10474
|
+
side: THREE26__namespace.BackSide,
|
|
10475
|
+
transparent: true,
|
|
10476
|
+
opacity: 0.85,
|
|
10477
|
+
depthWrite: false
|
|
10478
|
+
});
|
|
10479
|
+
const group = new THREE26__namespace.Group();
|
|
10480
|
+
group.name = "XRHoverShell";
|
|
10481
|
+
group.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
10482
|
+
group.renderOrder = 998;
|
|
10483
|
+
object.traverse((child) => {
|
|
10484
|
+
if (!(child instanceof THREE26__namespace.Mesh) || !child.geometry) return;
|
|
10485
|
+
if (child.userData[XR_HOVER_SHELL_FLAG]) return;
|
|
10486
|
+
const clone = new THREE26__namespace.Mesh(child.geometry, material);
|
|
10487
|
+
child.updateWorldMatrix(true, false);
|
|
10488
|
+
object.updateWorldMatrix(true, false);
|
|
10489
|
+
clone.matrixAutoUpdate = false;
|
|
10490
|
+
clone.matrix.copy(object.matrixWorld).invert().multiply(child.matrixWorld).scale(new THREE26__namespace.Vector3(SHELL_INFLATE, SHELL_INFLATE, SHELL_INFLATE));
|
|
10491
|
+
clone.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
10492
|
+
clone.raycast = () => {
|
|
10493
|
+
};
|
|
10494
|
+
group.add(clone);
|
|
10495
|
+
});
|
|
10496
|
+
if (group.children.length === 0) {
|
|
10497
|
+
material.dispose();
|
|
10498
|
+
return null;
|
|
10499
|
+
}
|
|
10500
|
+
object.add(group);
|
|
10501
|
+
return group;
|
|
10502
|
+
}
|
|
10503
|
+
animate(world, deltaTime) {
|
|
10504
|
+
const step = 1 - Math.exp(-Math.max(0, deltaTime) / SCALE_SMOOTH_SECONDS);
|
|
10505
|
+
for (const [entityId, record] of Array.from(this.records)) {
|
|
10506
|
+
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
10507
|
+
const target = record.active ? 1 : 0;
|
|
10508
|
+
record.progress += (target - record.progress) * step;
|
|
10509
|
+
const wantsScale = interactable?.hoverBehavior === "scale" || interactable?.hoverBehavior === "both";
|
|
10510
|
+
if (wantsScale) {
|
|
10511
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
10512
|
+
if (transform) {
|
|
10513
|
+
const factor = 1 + (interactable.hoverScale - 1) * Math.min(1, record.progress);
|
|
10514
|
+
transform.scale.x = record.baseScale.x * factor;
|
|
10515
|
+
transform.scale.y = record.baseScale.y * factor;
|
|
10516
|
+
transform.scale.z = record.baseScale.z * factor;
|
|
10517
|
+
}
|
|
10518
|
+
}
|
|
10519
|
+
if (!record.active && record.progress < 0.01) {
|
|
10520
|
+
this.finish(world, entityId, record);
|
|
10521
|
+
}
|
|
10522
|
+
}
|
|
10523
|
+
}
|
|
10524
|
+
/** Remove the effect and restore the authored scale exactly. */
|
|
10525
|
+
finish(world, entityId, record) {
|
|
10526
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
10527
|
+
if (transform) {
|
|
10528
|
+
transform.scale.x = record.baseScale.x;
|
|
10529
|
+
transform.scale.y = record.baseScale.y;
|
|
10530
|
+
transform.scale.z = record.baseScale.z;
|
|
10531
|
+
}
|
|
10532
|
+
this.disposeShell(record.shell);
|
|
10533
|
+
this.records.delete(entityId);
|
|
10534
|
+
}
|
|
10535
|
+
disposeShell(shell) {
|
|
10536
|
+
if (!shell) return;
|
|
10537
|
+
shell.parent?.remove(shell);
|
|
10538
|
+
shell.traverse((child) => {
|
|
10539
|
+
if (child instanceof THREE26__namespace.Mesh) {
|
|
10540
|
+
const material = child.material;
|
|
10541
|
+
if (Array.isArray(material)) {
|
|
10542
|
+
for (const entry of material) entry.dispose();
|
|
10543
|
+
} else {
|
|
10544
|
+
material?.dispose();
|
|
10545
|
+
}
|
|
10546
|
+
}
|
|
10547
|
+
});
|
|
10548
|
+
}
|
|
10549
|
+
clearAll(world) {
|
|
10550
|
+
for (const [entityId, record] of Array.from(this.records)) {
|
|
10551
|
+
this.finish(world, entityId, record);
|
|
10552
|
+
}
|
|
10553
|
+
}
|
|
10554
|
+
dispose() {
|
|
10555
|
+
for (const record of this.records.values()) {
|
|
10556
|
+
this.disposeShell(record.shell);
|
|
10557
|
+
}
|
|
10558
|
+
this.records.clear();
|
|
10559
|
+
}
|
|
10560
|
+
};
|
|
10561
|
+
__name(_XRHoverVisualSystem, "XRHoverVisualSystem");
|
|
10562
|
+
var XRHoverVisualSystem = _XRHoverVisualSystem;
|
|
9919
10563
|
|
|
9920
10564
|
exports.AnimationSystem = AnimationSystem;
|
|
9921
10565
|
exports.AudioSystem = AudioSystem;
|
|
@@ -9940,10 +10584,12 @@ exports.VRTeleportAreaSystem = VRTeleportAreaSystem;
|
|
|
9940
10584
|
exports.VideoSystem = VideoSystem;
|
|
9941
10585
|
exports.XRControllerVisualSystem = XRControllerVisualSystem;
|
|
9942
10586
|
exports.XRHandPoseSystem = XRHandPoseSystem;
|
|
10587
|
+
exports.XRHoverVisualSystem = XRHoverVisualSystem;
|
|
9943
10588
|
exports.XRInputSystem = XRInputSystem;
|
|
9944
10589
|
exports.XRInteractionSystem = XRInteractionSystem;
|
|
9945
10590
|
exports.XRLocomotionSystem = XRLocomotionSystem;
|
|
9946
10591
|
exports.XRSessionSystem = XRSessionSystem;
|
|
9947
10592
|
exports.XRTeleportVisualSystem = XRTeleportVisualSystem;
|
|
10593
|
+
exports.XR_HOVER_SHELL_FLAG = XR_HOVER_SHELL_FLAG;
|
|
9948
10594
|
//# sourceMappingURL=index.cjs.map
|
|
9949
10595
|
//# sourceMappingURL=index.cjs.map
|