@relu-interactives/spatial-ecs 0.3.8 → 0.3.10
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-CjacJ_16.d.ts} +70 -1
- package/dist/{XRHandPose-VuSbe4iz.d.cts → XRHandPose-hAtj9wm-.d.cts} +70 -1
- package/dist/{chunk-KIKIWCEB.js → chunk-5UVBEAGW.js} +4 -4
- package/dist/{chunk-KIKIWCEB.js.map → chunk-5UVBEAGW.js.map} +1 -1
- package/dist/{chunk-KVGGAL5V.js → chunk-ELSZ5U3F.js} +23 -3
- package/dist/chunk-ELSZ5U3F.js.map +1 -0
- package/dist/{chunk-L5BP727H.js → chunk-NJOO7NO6.js} +3 -3
- package/dist/{chunk-L5BP727H.js.map → chunk-NJOO7NO6.js.map} +1 -1
- package/dist/{chunk-LMTB4KQ4.js → chunk-O2HSIZFC.js} +591 -195
- package/dist/chunk-O2HSIZFC.js.map +1 -0
- package/dist/components/index.cjs +20 -0
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +1 -1
- package/dist/docs/guide/vr-and-hand-poses.md +48 -0
- package/dist/factories/index.cjs +19 -0
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +1 -1
- package/dist/factories/index.d.ts +1 -1
- package/dist/factories/index.js +3 -3
- package/dist/{index-C7XQyrgE.d.ts → index-B-KhN8Ox.d.ts} +51 -0
- package/dist/{index-BxdXgqiI.d.ts → index-B7JDsx4a.d.ts} +9 -2
- package/dist/{index-BIQoaKAA.d.cts → index-B9JqYr3Q.d.cts} +9 -2
- package/dist/{index-DyN50JZo.d.cts → index-DU-CF-3m.d.cts} +51 -0
- package/dist/index.cjs +729 -312
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -6
- package/dist/index.d.ts +29 -6
- package/dist/index.js +8 -8
- package/dist/systems/index.cjs +635 -220
- 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-LMTB4KQ4.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { resolveDracoDecoderPath, applyTransform, SHARED_MODEL_RESOURCE_FLAG } from './chunk-
|
|
2
|
-
import { AnimationComponent, ModelComponent, CameraComponent, Object3DRef, Environment, Postprocessing, TransformComponent, PhysicsComponent, setPhysicsLiveRef, LightComponent, MaterialComponent, DEFAULT_MESH_GEOMETRY_PARAMETERS, MeshGeometryComponent, InstancedMeshComponent, ParentId, ScriptComponent, ScriptObjectComponent, XRRigComponent, VRTeleportAreaComponent, XRInteractableComponent, XRHandPoseComponent, createHandPoseEntry, XRInteractorComponent, XRInteractorSideComponent, InstanceSlotComponent, Name, ImageComponent, SpriteComponent, VideoComponent, AudioComponent, ImageTarget, Selectable, PrefabNode, PrefabInstance, handPoseDefinitionFor, getHandPosePreset } from './chunk-
|
|
1
|
+
import { resolveDracoDecoderPath, applyTransform, SHARED_MODEL_RESOURCE_FLAG } from './chunk-NJOO7NO6.js';
|
|
2
|
+
import { AnimationComponent, ModelComponent, CameraComponent, Object3DRef, Environment, Postprocessing, TransformComponent, PhysicsComponent, setPhysicsLiveRef, LightComponent, MaterialComponent, DEFAULT_MESH_GEOMETRY_PARAMETERS, MeshGeometryComponent, InstancedMeshComponent, ParentId, ScriptComponent, ScriptObjectComponent, XRRigComponent, VRTeleportAreaComponent, XRInteractableComponent, createAttachPoint, XRHandPoseComponent, createHandPoseEntry, XRInteractorComponent, XRInteractorSideComponent, InstanceSlotComponent, Name, ImageComponent, SpriteComponent, VideoComponent, AudioComponent, ImageTarget, Selectable, PrefabNode, PrefabInstance, handPoseDefinitionFor, getHandPosePreset } from './chunk-ELSZ5U3F.js';
|
|
3
3
|
import { __name } from './chunk-OY7ZODZP.js';
|
|
4
|
-
import * as
|
|
4
|
+
import * as THREE19 from 'three';
|
|
5
5
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
6
6
|
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
|
|
7
7
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
@@ -160,7 +160,7 @@ function transitionToClip(runtime, nextClipId, crossFadeDuration) {
|
|
|
160
160
|
}
|
|
161
161
|
__name(transitionToClip, "transitionToClip");
|
|
162
162
|
function applyActionState(action, component, paused, shouldLoop) {
|
|
163
|
-
const loopMode = shouldLoop ?
|
|
163
|
+
const loopMode = shouldLoop ? THREE19.LoopRepeat : THREE19.LoopOnce;
|
|
164
164
|
const repetitions = shouldLoop ? Infinity : 1;
|
|
165
165
|
action.setLoop(loopMode, repetitions);
|
|
166
166
|
action.clampWhenFinished = !shouldLoop;
|
|
@@ -333,7 +333,7 @@ var _AnimationSystem = class _AnimationSystem {
|
|
|
333
333
|
if (runtime) {
|
|
334
334
|
stopAllActions(runtime);
|
|
335
335
|
}
|
|
336
|
-
const mixer = new
|
|
336
|
+
const mixer = new THREE19.AnimationMixer(root);
|
|
337
337
|
const entries2 = readRuntimeClipEntries(animation);
|
|
338
338
|
const indexedActions = createActions(mixer, entries2);
|
|
339
339
|
runtime = {
|
|
@@ -459,11 +459,11 @@ function normalizeOrthoBounds(component) {
|
|
|
459
459
|
}
|
|
460
460
|
__name(normalizeOrthoBounds, "normalizeOrthoBounds");
|
|
461
461
|
function isPerspectiveCamera(camera) {
|
|
462
|
-
return camera instanceof
|
|
462
|
+
return camera instanceof THREE19.PerspectiveCamera;
|
|
463
463
|
}
|
|
464
464
|
__name(isPerspectiveCamera, "isPerspectiveCamera");
|
|
465
465
|
function isOrthographicCamera(camera) {
|
|
466
|
-
return camera instanceof
|
|
466
|
+
return camera instanceof THREE19.OrthographicCamera;
|
|
467
467
|
}
|
|
468
468
|
__name(isOrthographicCamera, "isOrthographicCamera");
|
|
469
469
|
function readWindowAspect() {
|
|
@@ -517,7 +517,7 @@ var _CameraSyncSystem = class _CameraSyncSystem {
|
|
|
517
517
|
continue;
|
|
518
518
|
}
|
|
519
519
|
const camera = objectRef.object;
|
|
520
|
-
if (!(camera instanceof
|
|
520
|
+
if (!(camera instanceof THREE19.Camera)) {
|
|
521
521
|
continue;
|
|
522
522
|
}
|
|
523
523
|
if (xrCamera !== null && camera === xrCamera) {
|
|
@@ -584,7 +584,7 @@ var MIN_DENSITY = 0;
|
|
|
584
584
|
function createGradientTexture(effect, colors) {
|
|
585
585
|
if (typeof document === "undefined") {
|
|
586
586
|
const pixel = new Uint8Array([30, 30, 30, 255]);
|
|
587
|
-
const fallback = new
|
|
587
|
+
const fallback = new THREE19.DataTexture(pixel, 1, 1, THREE19.RGBAFormat);
|
|
588
588
|
fallback.needsUpdate = true;
|
|
589
589
|
return fallback;
|
|
590
590
|
}
|
|
@@ -593,7 +593,7 @@ function createGradientTexture(effect, colors) {
|
|
|
593
593
|
canvas.height = 512;
|
|
594
594
|
const context = canvas.getContext("2d");
|
|
595
595
|
if (!context) {
|
|
596
|
-
const fallback = new
|
|
596
|
+
const fallback = new THREE19.CanvasTexture(canvas);
|
|
597
597
|
fallback.needsUpdate = true;
|
|
598
598
|
return fallback;
|
|
599
599
|
}
|
|
@@ -621,15 +621,15 @@ function createGradientTexture(effect, colors) {
|
|
|
621
621
|
context.fillRect(0, 0, 512, 512);
|
|
622
622
|
context.globalCompositeOperation = "source-over";
|
|
623
623
|
}
|
|
624
|
-
const texture = new
|
|
625
|
-
texture.colorSpace =
|
|
624
|
+
const texture = new THREE19.CanvasTexture(canvas);
|
|
625
|
+
texture.colorSpace = THREE19.SRGBColorSpace;
|
|
626
626
|
texture.needsUpdate = true;
|
|
627
627
|
return texture;
|
|
628
628
|
}
|
|
629
629
|
__name(createGradientTexture, "createGradientTexture");
|
|
630
630
|
var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
631
631
|
constructor(scene) {
|
|
632
|
-
this.textureLoader = new
|
|
632
|
+
this.textureLoader = new THREE19.TextureLoader();
|
|
633
633
|
this.signature = null;
|
|
634
634
|
this.activeTexture = null;
|
|
635
635
|
this.pendingImageUrl = null;
|
|
@@ -652,7 +652,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
652
652
|
if (skybox.type === "color") {
|
|
653
653
|
this.disposeActiveTexture();
|
|
654
654
|
this.pendingImageUrl = null;
|
|
655
|
-
this.scene.background = new
|
|
655
|
+
this.scene.background = new THREE19.Color(skybox.color || "#1e1e1e");
|
|
656
656
|
return;
|
|
657
657
|
}
|
|
658
658
|
if (skybox.type === "gradient") {
|
|
@@ -686,7 +686,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
686
686
|
texture.dispose();
|
|
687
687
|
return;
|
|
688
688
|
}
|
|
689
|
-
texture.colorSpace =
|
|
689
|
+
texture.colorSpace = THREE19.SRGBColorSpace;
|
|
690
690
|
this.activeTexture = texture;
|
|
691
691
|
this.scene.background = texture;
|
|
692
692
|
},
|
|
@@ -705,16 +705,16 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
705
705
|
this.scene.fog = null;
|
|
706
706
|
return;
|
|
707
707
|
}
|
|
708
|
-
const fogColor = new
|
|
708
|
+
const fogColor = new THREE19.Color(fog.color || "#1e1e1e");
|
|
709
709
|
if (fog.type === "linear") {
|
|
710
710
|
const near = Number.isFinite(fog.linear.near) ? fog.linear.near : 1;
|
|
711
711
|
const farCandidate = Number.isFinite(fog.linear.far) ? fog.linear.far : near + 10;
|
|
712
712
|
const far = Math.max(near + MIN_FOG_DELTA, farCandidate);
|
|
713
|
-
this.scene.fog = new
|
|
713
|
+
this.scene.fog = new THREE19.Fog(fogColor, near, far);
|
|
714
714
|
return;
|
|
715
715
|
}
|
|
716
716
|
const density = Number.isFinite(fog.exponential.density) ? Math.max(MIN_DENSITY, fog.exponential.density) : 2e-3;
|
|
717
|
-
this.scene.fog = new
|
|
717
|
+
this.scene.fog = new THREE19.FogExp2(fogColor, density);
|
|
718
718
|
}
|
|
719
719
|
update(world) {
|
|
720
720
|
const entityIds = world.query(Environment);
|
|
@@ -796,10 +796,10 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
796
796
|
);
|
|
797
797
|
}
|
|
798
798
|
if (values.bloom.enabled) {
|
|
799
|
-
const size = this.renderer.getSize(new
|
|
799
|
+
const size = this.renderer.getSize(new THREE19.Vector2());
|
|
800
800
|
composer.addPass(
|
|
801
801
|
new UnrealBloomPass(
|
|
802
|
-
new
|
|
802
|
+
new THREE19.Vector2(size.width, size.height),
|
|
803
803
|
values.bloom.intensity,
|
|
804
804
|
values.bloom.radius,
|
|
805
805
|
values.bloom.threshold
|
|
@@ -844,7 +844,7 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
844
844
|
if (values.dotScreen.enabled) {
|
|
845
845
|
composer.addPass(
|
|
846
846
|
new DotScreenPass(
|
|
847
|
-
new
|
|
847
|
+
new THREE19.Vector2(0, 0),
|
|
848
848
|
values.dotScreen.angle ?? values.dotScreen.dotScreenAngle,
|
|
849
849
|
values.dotScreen.scale ?? values.dotScreen.dotScreenScale
|
|
850
850
|
)
|
|
@@ -918,7 +918,7 @@ function computeColliderState(colliderValues, object) {
|
|
|
918
918
|
if (!object) {
|
|
919
919
|
return colliderValues;
|
|
920
920
|
}
|
|
921
|
-
const scale = new
|
|
921
|
+
const scale = new THREE19.Vector3();
|
|
922
922
|
object.getWorldScale(scale);
|
|
923
923
|
return {
|
|
924
924
|
...colliderValues,
|
|
@@ -969,8 +969,8 @@ function createColliderDesc(RAPIER, values, triMeshData) {
|
|
|
969
969
|
values.offsetPosition.y,
|
|
970
970
|
values.offsetPosition.z
|
|
971
971
|
);
|
|
972
|
-
const offsetQuaternion = new
|
|
973
|
-
new
|
|
972
|
+
const offsetQuaternion = new THREE19.Quaternion().setFromEuler(
|
|
973
|
+
new THREE19.Euler(
|
|
974
974
|
values.offsetRotation.x,
|
|
975
975
|
values.offsetRotation.y,
|
|
976
976
|
values.offsetRotation.z
|
|
@@ -985,17 +985,17 @@ function collectTriMeshParts(object) {
|
|
|
985
985
|
return null;
|
|
986
986
|
}
|
|
987
987
|
object.updateWorldMatrix(true, true);
|
|
988
|
-
const worldScale = new
|
|
988
|
+
const worldScale = new THREE19.Vector3();
|
|
989
989
|
object.getWorldScale(worldScale);
|
|
990
990
|
const scale = {
|
|
991
991
|
x: Math.abs(worldScale.x) || 1,
|
|
992
992
|
y: Math.abs(worldScale.y) || 1,
|
|
993
993
|
z: Math.abs(worldScale.z) || 1
|
|
994
994
|
};
|
|
995
|
-
const worldToObject = new
|
|
995
|
+
const worldToObject = new THREE19.Matrix4().copy(object.matrixWorld).invert();
|
|
996
996
|
const parts = [];
|
|
997
997
|
object.traverse((child) => {
|
|
998
|
-
if (!(child instanceof
|
|
998
|
+
if (!(child instanceof THREE19.Mesh) || !child.geometry) {
|
|
999
999
|
return;
|
|
1000
1000
|
}
|
|
1001
1001
|
const geometry = child.geometry;
|
|
@@ -1012,7 +1012,7 @@ function collectTriMeshParts(object) {
|
|
|
1012
1012
|
if (indexCount < 3) {
|
|
1013
1013
|
return;
|
|
1014
1014
|
}
|
|
1015
|
-
const relativeMatrix = new
|
|
1015
|
+
const relativeMatrix = new THREE19.Matrix4().multiplyMatrices(
|
|
1016
1016
|
worldToObject,
|
|
1017
1017
|
child.matrixWorld
|
|
1018
1018
|
);
|
|
@@ -1053,7 +1053,7 @@ function createTriMeshData(collected) {
|
|
|
1053
1053
|
}
|
|
1054
1054
|
const vertices = new Float32Array(vertexTotal * 3);
|
|
1055
1055
|
const indices = new Uint32Array(indexTotal);
|
|
1056
|
-
const point = new
|
|
1056
|
+
const point = new THREE19.Vector3();
|
|
1057
1057
|
let vertexOffset = 0;
|
|
1058
1058
|
let indexOffset = 0;
|
|
1059
1059
|
for (const part of parts) {
|
|
@@ -1085,8 +1085,8 @@ function createTriMeshData(collected) {
|
|
|
1085
1085
|
}
|
|
1086
1086
|
__name(createTriMeshData, "createTriMeshData");
|
|
1087
1087
|
function syncBodyFromTransform(body, transform) {
|
|
1088
|
-
const quaternion = new
|
|
1089
|
-
new
|
|
1088
|
+
const quaternion = new THREE19.Quaternion().setFromEuler(
|
|
1089
|
+
new THREE19.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z)
|
|
1090
1090
|
);
|
|
1091
1091
|
body.setTranslation(
|
|
1092
1092
|
{
|
|
@@ -1113,8 +1113,8 @@ function syncTransformFromBody(transform, body) {
|
|
|
1113
1113
|
transform.position.x = position.x;
|
|
1114
1114
|
transform.position.y = position.y;
|
|
1115
1115
|
transform.position.z = position.z;
|
|
1116
|
-
const euler = new
|
|
1117
|
-
new
|
|
1116
|
+
const euler = new THREE19.Euler().setFromQuaternion(
|
|
1117
|
+
new THREE19.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w)
|
|
1118
1118
|
);
|
|
1119
1119
|
transform.rotation.x = euler.x;
|
|
1120
1120
|
transform.rotation.y = euler.y;
|
|
@@ -1226,8 +1226,8 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
|
|
|
1226
1226
|
transform.position.y,
|
|
1227
1227
|
transform.position.z
|
|
1228
1228
|
);
|
|
1229
|
-
const quaternion = new
|
|
1230
|
-
new
|
|
1229
|
+
const quaternion = new THREE19.Quaternion().setFromEuler(
|
|
1230
|
+
new THREE19.Euler(
|
|
1231
1231
|
transform.rotation.x,
|
|
1232
1232
|
transform.rotation.y,
|
|
1233
1233
|
transform.rotation.z
|
|
@@ -1806,7 +1806,7 @@ function applyLightValues(lightComponent) {
|
|
|
1806
1806
|
values.castShadow
|
|
1807
1807
|
);
|
|
1808
1808
|
}
|
|
1809
|
-
if (light instanceof
|
|
1809
|
+
if (light instanceof THREE19.PointLight) {
|
|
1810
1810
|
if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
|
|
1811
1811
|
light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
|
|
1812
1812
|
}
|
|
@@ -1814,7 +1814,7 @@ function applyLightValues(lightComponent) {
|
|
|
1814
1814
|
light.decay = Math.max(0, values.decay);
|
|
1815
1815
|
}
|
|
1816
1816
|
}
|
|
1817
|
-
if (light instanceof
|
|
1817
|
+
if (light instanceof THREE19.SpotLight) {
|
|
1818
1818
|
if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
|
|
1819
1819
|
light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
|
|
1820
1820
|
}
|
|
@@ -1828,7 +1828,7 @@ function applyLightValues(lightComponent) {
|
|
|
1828
1828
|
light.penumbra = Math.max(0, Math.min(1, values.penumbra));
|
|
1829
1829
|
}
|
|
1830
1830
|
}
|
|
1831
|
-
if (light instanceof
|
|
1831
|
+
if (light instanceof THREE19.RectAreaLight) {
|
|
1832
1832
|
if (typeof values.width === "number" && Number.isFinite(values.width)) {
|
|
1833
1833
|
light.width = Math.max(MIN_AREA_SIZE, values.width);
|
|
1834
1834
|
}
|
|
@@ -1889,15 +1889,15 @@ function resolveMaterialPropertyKey(key) {
|
|
|
1889
1889
|
__name(resolveMaterialPropertyKey, "resolveMaterialPropertyKey");
|
|
1890
1890
|
function createMaterialByType(type) {
|
|
1891
1891
|
if (type === "basic") {
|
|
1892
|
-
return new
|
|
1892
|
+
return new THREE19.MeshBasicMaterial();
|
|
1893
1893
|
}
|
|
1894
1894
|
if (type === "phong") {
|
|
1895
|
-
return new
|
|
1895
|
+
return new THREE19.MeshPhongMaterial();
|
|
1896
1896
|
}
|
|
1897
1897
|
if (type === "physical") {
|
|
1898
|
-
return new
|
|
1898
|
+
return new THREE19.MeshPhysicalMaterial();
|
|
1899
1899
|
}
|
|
1900
|
-
return new
|
|
1900
|
+
return new THREE19.MeshStandardMaterial();
|
|
1901
1901
|
}
|
|
1902
1902
|
__name(createMaterialByType, "createMaterialByType");
|
|
1903
1903
|
function replaceMaterialAcrossObject(object, previous, next) {
|
|
@@ -1956,12 +1956,12 @@ function applyTextureFiltering(material, filtering) {
|
|
|
1956
1956
|
const target = material;
|
|
1957
1957
|
for (const slot of materialTextureSlots) {
|
|
1958
1958
|
const texture = target[slot];
|
|
1959
|
-
if (!texture || !(texture instanceof
|
|
1959
|
+
if (!texture || !(texture instanceof THREE19.Texture)) {
|
|
1960
1960
|
continue;
|
|
1961
1961
|
}
|
|
1962
1962
|
const useMipmaps = texture.generateMipmaps !== false;
|
|
1963
|
-
texture.magFilter = sharp ?
|
|
1964
|
-
texture.minFilter = useMipmaps ? sharp ?
|
|
1963
|
+
texture.magFilter = sharp ? THREE19.NearestFilter : THREE19.LinearFilter;
|
|
1964
|
+
texture.minFilter = useMipmaps ? sharp ? THREE19.NearestMipmapNearestFilter : THREE19.LinearMipmapLinearFilter : sharp ? THREE19.NearestFilter : THREE19.LinearFilter;
|
|
1965
1965
|
texture.needsUpdate = true;
|
|
1966
1966
|
}
|
|
1967
1967
|
material.needsUpdate = true;
|
|
@@ -1971,12 +1971,12 @@ function setTextureMipmaps(material, enabled) {
|
|
|
1971
1971
|
const target = material;
|
|
1972
1972
|
for (const slot of materialTextureSlots) {
|
|
1973
1973
|
const texture = target[slot];
|
|
1974
|
-
if (!texture || !(texture instanceof
|
|
1974
|
+
if (!texture || !(texture instanceof THREE19.Texture)) {
|
|
1975
1975
|
continue;
|
|
1976
1976
|
}
|
|
1977
1977
|
texture.generateMipmaps = enabled;
|
|
1978
|
-
const sharp = texture.magFilter ===
|
|
1979
|
-
texture.minFilter = enabled ? sharp ?
|
|
1978
|
+
const sharp = texture.magFilter === THREE19.NearestFilter;
|
|
1979
|
+
texture.minFilter = enabled ? sharp ? THREE19.NearestMipmapNearestFilter : THREE19.LinearMipmapLinearFilter : sharp ? THREE19.NearestFilter : THREE19.LinearFilter;
|
|
1980
1980
|
texture.needsUpdate = true;
|
|
1981
1981
|
}
|
|
1982
1982
|
material.needsUpdate = true;
|
|
@@ -1987,7 +1987,7 @@ function assignMaterialTexture(material, rawKey, url, textureCache) {
|
|
|
1987
1987
|
const key = resolveMaterialPropertyKey(rawKey);
|
|
1988
1988
|
let texture = textureCache.get(url);
|
|
1989
1989
|
if (!texture) {
|
|
1990
|
-
texture = new
|
|
1990
|
+
texture = new THREE19.TextureLoader().load(url);
|
|
1991
1991
|
textureCache.set(url, texture);
|
|
1992
1992
|
}
|
|
1993
1993
|
target[key] = texture;
|
|
@@ -2025,7 +2025,7 @@ function applyMaterialState(material, value, textureCache) {
|
|
|
2025
2025
|
}
|
|
2026
2026
|
target.side = value.side;
|
|
2027
2027
|
target.blending = value.blending;
|
|
2028
|
-
target.premultipliedAlpha = value.blending ===
|
|
2028
|
+
target.premultipliedAlpha = value.blending === THREE19.MultiplyBlending || value.blending === THREE19.SubtractiveBlending;
|
|
2029
2029
|
target.depthTest = value.depthTest;
|
|
2030
2030
|
target.depthWrite = value.depthWrite;
|
|
2031
2031
|
target.wireframe = value.wireframe;
|
|
@@ -2186,12 +2186,12 @@ function resolvePrimaryMesh(object) {
|
|
|
2186
2186
|
if (!object) {
|
|
2187
2187
|
return null;
|
|
2188
2188
|
}
|
|
2189
|
-
if (object instanceof
|
|
2189
|
+
if (object instanceof THREE19.Mesh) {
|
|
2190
2190
|
return object;
|
|
2191
2191
|
}
|
|
2192
2192
|
let found = null;
|
|
2193
2193
|
object.traverse((child) => {
|
|
2194
|
-
if (!found && child instanceof
|
|
2194
|
+
if (!found && child instanceof THREE19.Mesh) {
|
|
2195
2195
|
found = child;
|
|
2196
2196
|
}
|
|
2197
2197
|
});
|
|
@@ -2212,22 +2212,22 @@ function applyGeometry(component) {
|
|
|
2212
2212
|
switch (component.kind) {
|
|
2213
2213
|
case "cube": {
|
|
2214
2214
|
const params = sanitized;
|
|
2215
|
-
nextGeometry = new
|
|
2215
|
+
nextGeometry = new THREE19.BoxGeometry(params.width, params.height, params.depth);
|
|
2216
2216
|
break;
|
|
2217
2217
|
}
|
|
2218
2218
|
case "plane": {
|
|
2219
2219
|
const params = sanitized;
|
|
2220
|
-
nextGeometry = new
|
|
2220
|
+
nextGeometry = new THREE19.PlaneGeometry(params.width, params.height);
|
|
2221
2221
|
break;
|
|
2222
2222
|
}
|
|
2223
2223
|
case "sphere": {
|
|
2224
2224
|
const params = sanitized;
|
|
2225
|
-
nextGeometry = new
|
|
2225
|
+
nextGeometry = new THREE19.SphereGeometry(params.radius, 24, 24);
|
|
2226
2226
|
break;
|
|
2227
2227
|
}
|
|
2228
2228
|
case "cylinder": {
|
|
2229
2229
|
const params = sanitized;
|
|
2230
|
-
nextGeometry = new
|
|
2230
|
+
nextGeometry = new THREE19.CylinderGeometry(
|
|
2231
2231
|
params.radius,
|
|
2232
2232
|
params.radius,
|
|
2233
2233
|
params.height,
|
|
@@ -2237,7 +2237,7 @@ function applyGeometry(component) {
|
|
|
2237
2237
|
}
|
|
2238
2238
|
case "capsule": {
|
|
2239
2239
|
const params = sanitized;
|
|
2240
|
-
nextGeometry = new
|
|
2240
|
+
nextGeometry = new THREE19.CapsuleGeometry(params.radius, params.height, 4, 8);
|
|
2241
2241
|
break;
|
|
2242
2242
|
}
|
|
2243
2243
|
default:
|
|
@@ -2253,7 +2253,7 @@ function applyShadowFlags(component) {
|
|
|
2253
2253
|
return;
|
|
2254
2254
|
}
|
|
2255
2255
|
component.object.traverse((child) => {
|
|
2256
|
-
if (child instanceof
|
|
2256
|
+
if (child instanceof THREE19.Mesh) {
|
|
2257
2257
|
child.castShadow = component.castShadow;
|
|
2258
2258
|
child.receiveShadow = component.receiveShadow;
|
|
2259
2259
|
}
|
|
@@ -2336,35 +2336,35 @@ function buildGeometry(component) {
|
|
|
2336
2336
|
switch (component.meshKind) {
|
|
2337
2337
|
case "cube": {
|
|
2338
2338
|
const params = p;
|
|
2339
|
-
return new
|
|
2339
|
+
return new THREE19.BoxGeometry(params.width, params.height, params.depth);
|
|
2340
2340
|
}
|
|
2341
2341
|
case "plane": {
|
|
2342
2342
|
const params = p;
|
|
2343
|
-
return new
|
|
2343
|
+
return new THREE19.PlaneGeometry(params.width, params.height);
|
|
2344
2344
|
}
|
|
2345
2345
|
case "sphere": {
|
|
2346
2346
|
const params = p;
|
|
2347
|
-
return new
|
|
2347
|
+
return new THREE19.SphereGeometry(params.radius, 24, 24);
|
|
2348
2348
|
}
|
|
2349
2349
|
case "cylinder": {
|
|
2350
2350
|
const params = p;
|
|
2351
|
-
return new
|
|
2351
|
+
return new THREE19.CylinderGeometry(params.radius, params.radius, params.height, 20);
|
|
2352
2352
|
}
|
|
2353
2353
|
case "capsule": {
|
|
2354
2354
|
const params = p;
|
|
2355
|
-
return new
|
|
2355
|
+
return new THREE19.CapsuleGeometry(params.radius, params.height, 4, 8);
|
|
2356
2356
|
}
|
|
2357
2357
|
default:
|
|
2358
|
-
return new
|
|
2358
|
+
return new THREE19.BoxGeometry(1, 1, 1);
|
|
2359
2359
|
}
|
|
2360
2360
|
}
|
|
2361
2361
|
__name(buildGeometry, "buildGeometry");
|
|
2362
|
-
var _position = new
|
|
2363
|
-
var _quaternion = new
|
|
2364
|
-
var _euler = new
|
|
2365
|
-
var _scale = new
|
|
2366
|
-
var _matrix = new
|
|
2367
|
-
var _modelMatrix = new
|
|
2362
|
+
var _position = new THREE19.Vector3();
|
|
2363
|
+
var _quaternion = new THREE19.Quaternion();
|
|
2364
|
+
var _euler = new THREE19.Euler();
|
|
2365
|
+
var _scale = new THREE19.Vector3();
|
|
2366
|
+
var _matrix = new THREE19.Matrix4();
|
|
2367
|
+
var _modelMatrix = new THREE19.Matrix4();
|
|
2368
2368
|
function instanceTransformFromComponent(transform, out) {
|
|
2369
2369
|
_position.set(transform.position.x, transform.position.y, transform.position.z);
|
|
2370
2370
|
_euler.set(transform.rotation.x, transform.rotation.y, transform.rotation.z, "XYZ");
|
|
@@ -2517,7 +2517,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
2517
2517
|
const sourceMaterial = Array.isArray(meshChild.material) ? meshChild.material.map((m) => m.clone()) : meshChild.material.clone();
|
|
2518
2518
|
meshChild.updateWorldMatrix(true, false);
|
|
2519
2519
|
const localMatrix = meshChild.matrixWorld.clone();
|
|
2520
|
-
const instancedMesh2 = new
|
|
2520
|
+
const instancedMesh2 = new THREE19.InstancedMesh(
|
|
2521
2521
|
geometry2,
|
|
2522
2522
|
Array.isArray(sourceMaterial) ? sourceMaterial : sourceMaterial,
|
|
2523
2523
|
count2
|
|
@@ -2542,7 +2542,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
2542
2542
|
this.loadingSignatures.delete(targetEntityId);
|
|
2543
2543
|
return;
|
|
2544
2544
|
}
|
|
2545
|
-
const group = new
|
|
2545
|
+
const group = new THREE19.Group();
|
|
2546
2546
|
for (const entry of entries) {
|
|
2547
2547
|
group.add(entry.instancedMesh);
|
|
2548
2548
|
}
|
|
@@ -2560,8 +2560,8 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
2560
2560
|
}
|
|
2561
2561
|
const count = instanceCount;
|
|
2562
2562
|
const geometry = buildGeometry(comp);
|
|
2563
|
-
const material = new
|
|
2564
|
-
const instancedMesh = new
|
|
2563
|
+
const material = new THREE19.MeshStandardMaterial({ color: "#ffffff" });
|
|
2564
|
+
const instancedMesh = new THREE19.InstancedMesh(geometry, material, count);
|
|
2565
2565
|
instancedMesh.castShadow = comp.castShadow;
|
|
2566
2566
|
instancedMesh.receiveShadow = comp.receiveShadow;
|
|
2567
2567
|
for (let i = 0; i < count; i++) {
|
|
@@ -2912,13 +2912,9 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
2912
2912
|
runtimeMessage: typeof entry.runtimeMessage === "string" ? entry.runtimeMessage : void 0
|
|
2913
2913
|
};
|
|
2914
2914
|
}).filter((entry) => entry.className || entry.scriptUrl) : [];
|
|
2915
|
-
if (
|
|
2916
|
-
|
|
2915
|
+
if (entries.length) {
|
|
2916
|
+
world.addComponent(targetEntityId, new ScriptComponent(entries));
|
|
2917
2917
|
}
|
|
2918
|
-
world.addComponent(
|
|
2919
|
-
targetEntityId,
|
|
2920
|
-
new ScriptComponent(entries)
|
|
2921
|
-
);
|
|
2922
2918
|
}
|
|
2923
2919
|
const sourceScriptObject = asRecord(values.scriptObjectValues.get(sourceEntityId));
|
|
2924
2920
|
if (sourceScriptObject) {
|
|
@@ -2967,10 +2963,14 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
2967
2963
|
const sourceInteractable = asRecord(
|
|
2968
2964
|
values.xrInteractableValues.get(sourceEntityId)
|
|
2969
2965
|
);
|
|
2970
|
-
|
|
2966
|
+
let interactable = world.getComponent(
|
|
2971
2967
|
targetEntityId,
|
|
2972
2968
|
XRInteractableComponent
|
|
2973
2969
|
);
|
|
2970
|
+
if (sourceInteractable && !interactable) {
|
|
2971
|
+
interactable = new XRInteractableComponent();
|
|
2972
|
+
world.addComponent(targetEntityId, interactable);
|
|
2973
|
+
}
|
|
2974
2974
|
if (sourceInteractable && interactable) {
|
|
2975
2975
|
if (typeof sourceInteractable.enabled === "boolean") {
|
|
2976
2976
|
interactable.enabled = sourceInteractable.enabled;
|
|
@@ -2996,6 +2996,30 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
2996
2996
|
if (typeof sourceInteractable.grabRadius === "number") {
|
|
2997
2997
|
interactable.grabRadius = sourceInteractable.grabRadius;
|
|
2998
2998
|
}
|
|
2999
|
+
if (typeof sourceInteractable.grabHands === "string") {
|
|
3000
|
+
interactable.grabHands = sourceInteractable.grabHands;
|
|
3001
|
+
}
|
|
3002
|
+
if (typeof sourceInteractable.twoHandRotation === "string") {
|
|
3003
|
+
interactable.twoHandRotation = sourceInteractable.twoHandRotation;
|
|
3004
|
+
}
|
|
3005
|
+
if (typeof sourceInteractable.allowTwoHandScale === "boolean") {
|
|
3006
|
+
interactable.allowTwoHandScale = sourceInteractable.allowTwoHandScale;
|
|
3007
|
+
}
|
|
3008
|
+
if (typeof sourceInteractable.minScale === "number") {
|
|
3009
|
+
interactable.minScale = sourceInteractable.minScale;
|
|
3010
|
+
}
|
|
3011
|
+
if (typeof sourceInteractable.maxScale === "number") {
|
|
3012
|
+
interactable.maxScale = sourceInteractable.maxScale;
|
|
3013
|
+
}
|
|
3014
|
+
if (Array.isArray(sourceInteractable.attachPoints)) {
|
|
3015
|
+
interactable.attachPoints = sourceInteractable.attachPoints.map((point) => asRecord(point)).filter(
|
|
3016
|
+
(point) => point !== null && typeof point.id === "string"
|
|
3017
|
+
).map(
|
|
3018
|
+
(point) => createAttachPoint(
|
|
3019
|
+
point
|
|
3020
|
+
)
|
|
3021
|
+
);
|
|
3022
|
+
}
|
|
2999
3023
|
if (typeof sourceInteractable.throwOnRelease === "boolean") {
|
|
3000
3024
|
interactable.throwOnRelease = sourceInteractable.throwOnRelease;
|
|
3001
3025
|
}
|
|
@@ -3027,7 +3051,11 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
3027
3051
|
const sourceHandPose = asRecord(
|
|
3028
3052
|
values.xrHandPoseValues.get(sourceEntityId)
|
|
3029
3053
|
);
|
|
3030
|
-
|
|
3054
|
+
let handPose = world.getComponent(targetEntityId, XRHandPoseComponent);
|
|
3055
|
+
if (sourceHandPose && !handPose) {
|
|
3056
|
+
handPose = new XRHandPoseComponent();
|
|
3057
|
+
world.addComponent(targetEntityId, handPose);
|
|
3058
|
+
}
|
|
3031
3059
|
if (sourceHandPose && handPose) {
|
|
3032
3060
|
if (typeof sourceHandPose.enabled === "boolean") {
|
|
3033
3061
|
handPose.enabled = sourceHandPose.enabled;
|
|
@@ -4743,7 +4771,7 @@ var _Behaviour = class _Behaviour {
|
|
|
4743
4771
|
if (!this.threeRef) {
|
|
4744
4772
|
return null;
|
|
4745
4773
|
}
|
|
4746
|
-
const position = new
|
|
4774
|
+
const position = new THREE19.Vector3();
|
|
4747
4775
|
this.threeRef.object.getWorldPosition(position);
|
|
4748
4776
|
return position;
|
|
4749
4777
|
}
|
|
@@ -4755,7 +4783,7 @@ var _Behaviour = class _Behaviour {
|
|
|
4755
4783
|
if (!this.threeRef) {
|
|
4756
4784
|
return null;
|
|
4757
4785
|
}
|
|
4758
|
-
const target = new
|
|
4786
|
+
const target = new THREE19.Vector3();
|
|
4759
4787
|
this.threeRef.object.getWorldDirection(target);
|
|
4760
4788
|
return target;
|
|
4761
4789
|
}
|
|
@@ -4817,7 +4845,7 @@ var _Behaviour = class _Behaviour {
|
|
|
4817
4845
|
if (!this.threeRef) {
|
|
4818
4846
|
return;
|
|
4819
4847
|
}
|
|
4820
|
-
const rotation = new
|
|
4848
|
+
const rotation = new THREE19.Quaternion();
|
|
4821
4849
|
this.threeRef.object.getWorldQuaternion(rotation);
|
|
4822
4850
|
rotation.slerp(targetRotation, alpha);
|
|
4823
4851
|
this.transform.setRotation(rotation);
|
|
@@ -4834,7 +4862,7 @@ var _Behaviour = class _Behaviour {
|
|
|
4834
4862
|
return;
|
|
4835
4863
|
}
|
|
4836
4864
|
const clone2 = this.threeRef.object.clone();
|
|
4837
|
-
const rotation = new
|
|
4865
|
+
const rotation = new THREE19.Quaternion();
|
|
4838
4866
|
clone2.lookAt(targetPosition);
|
|
4839
4867
|
clone2.getWorldQuaternion(rotation);
|
|
4840
4868
|
this.transform.setRotation(rotation);
|
|
@@ -4972,6 +5000,17 @@ var _Behaviour = class _Behaviour {
|
|
|
4972
5000
|
*
|
|
4973
5001
|
* @param input - The source doing the grabbing.
|
|
4974
5002
|
*/
|
|
5003
|
+
/**
|
|
5004
|
+
* A SECOND hand joined a two-hand grab on this entity.
|
|
5005
|
+
*
|
|
5006
|
+
* The first hand anchors the object and keeps holding it; this fires for the
|
|
5007
|
+
* hand that came second — the foregrip on a rifle, say.
|
|
5008
|
+
*/
|
|
5009
|
+
onSecondaryGrab(_input) {
|
|
5010
|
+
}
|
|
5011
|
+
/** The second hand let go, leaving the object in the first hand alone. */
|
|
5012
|
+
onSecondaryRelease(_input) {
|
|
5013
|
+
}
|
|
4975
5014
|
/**
|
|
4976
5015
|
* A hand pose declared on this entity started being held.
|
|
4977
5016
|
*
|
|
@@ -5189,8 +5228,8 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5189
5228
|
}, "onPointerUp");
|
|
5190
5229
|
this.moduleLoader = moduleLoader ?? defaultModuleLoader;
|
|
5191
5230
|
this.selectionCtx = selectionContext ?? null;
|
|
5192
|
-
this.raycaster = new
|
|
5193
|
-
this.ndcPointer = new
|
|
5231
|
+
this.raycaster = new THREE19.Raycaster();
|
|
5232
|
+
this.ndcPointer = new THREE19.Vector2();
|
|
5194
5233
|
if (this.selectionCtx) {
|
|
5195
5234
|
this.selectionCtx.domElement.addEventListener("pointerdown", this.onPointerDown);
|
|
5196
5235
|
this.selectionCtx.domElement.addEventListener("pointerup", this.onPointerUp);
|
|
@@ -5569,7 +5608,7 @@ function disposeBuiltObject(root) {
|
|
|
5569
5608
|
for (const mat of materials) {
|
|
5570
5609
|
if (mat.userData?.[SHARED_MODEL_RESOURCE_FLAG]) continue;
|
|
5571
5610
|
for (const value of Object.values(mat)) {
|
|
5572
|
-
if (value instanceof
|
|
5611
|
+
if (value instanceof THREE19.Texture) value.dispose();
|
|
5573
5612
|
}
|
|
5574
5613
|
mat.dispose?.();
|
|
5575
5614
|
}
|
|
@@ -5933,7 +5972,7 @@ var _AudioSystem = class _AudioSystem {
|
|
|
5933
5972
|
if (!prev || prev.volume !== opts.volume) {
|
|
5934
5973
|
sound.setVolume(opts.volume);
|
|
5935
5974
|
}
|
|
5936
|
-
if (opts.positional && sound instanceof
|
|
5975
|
+
if (opts.positional && sound instanceof THREE19.PositionalAudio) {
|
|
5937
5976
|
if (!prev || prev.refDistance !== opts.refDistance) {
|
|
5938
5977
|
sound.setRefDistance(opts.refDistance);
|
|
5939
5978
|
}
|
|
@@ -6059,7 +6098,7 @@ var _VideoSystem = class _VideoSystem {
|
|
|
6059
6098
|
component.object.scale.set(opts.width, opts.height, 1);
|
|
6060
6099
|
}
|
|
6061
6100
|
const material = component.material;
|
|
6062
|
-
if (material instanceof
|
|
6101
|
+
if (material instanceof THREE19.ShaderMaterial) {
|
|
6063
6102
|
if (!prev || prev.backgroundColor !== opts.backgroundColor) {
|
|
6064
6103
|
material.uniforms.keyColor.value.set(opts.backgroundColor);
|
|
6065
6104
|
}
|
|
@@ -6073,7 +6112,7 @@ var _VideoSystem = class _VideoSystem {
|
|
|
6073
6112
|
material.uniforms.spill.value = opts.spill;
|
|
6074
6113
|
}
|
|
6075
6114
|
}
|
|
6076
|
-
if (opts.positional && component.audioNode instanceof
|
|
6115
|
+
if (opts.positional && component.audioNode instanceof THREE19.PositionalAudio) {
|
|
6077
6116
|
const posAudio = component.audioNode;
|
|
6078
6117
|
if (!prev || prev.refDistance !== opts.refDistance) {
|
|
6079
6118
|
posAudio.setRefDistance(opts.refDistance);
|
|
@@ -6113,8 +6152,8 @@ function blankState(source) {
|
|
|
6113
6152
|
handedness: handednessOf(source),
|
|
6114
6153
|
kind: kindOf(source),
|
|
6115
6154
|
connected: true,
|
|
6116
|
-
rayOrigin: new
|
|
6117
|
-
rayDirection: new
|
|
6155
|
+
rayOrigin: new THREE19.Vector3(),
|
|
6156
|
+
rayDirection: new THREE19.Vector3(0, 0, -1),
|
|
6118
6157
|
gripPosition: null,
|
|
6119
6158
|
gripQuaternion: null,
|
|
6120
6159
|
select: false,
|
|
@@ -6140,7 +6179,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
6140
6179
|
}
|
|
6141
6180
|
if (spaces.length === 0) return null;
|
|
6142
6181
|
const target = existing ?? {};
|
|
6143
|
-
const matrix = new
|
|
6182
|
+
const matrix = new THREE19.Matrix4();
|
|
6144
6183
|
const buffer = spaces.length * 16 <= JOINT_MATRIX_BUFFER.length ? JOINT_MATRIX_BUFFER : new Float32Array(spaces.length * 16);
|
|
6145
6184
|
const fillPoses = frame.fillPoses;
|
|
6146
6185
|
if (typeof fillPoses === "function") {
|
|
@@ -6153,7 +6192,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
6153
6192
|
if (filled) {
|
|
6154
6193
|
for (let i = 0; i < names.length; i += 1) {
|
|
6155
6194
|
matrix.fromArray(buffer, i * 16).premultiply(rigMatrix);
|
|
6156
|
-
const vector = target[names[i]] ?? new
|
|
6195
|
+
const vector = target[names[i]] ?? new THREE19.Vector3();
|
|
6157
6196
|
vector.setFromMatrixPosition(matrix);
|
|
6158
6197
|
target[names[i]] = vector;
|
|
6159
6198
|
}
|
|
@@ -6171,7 +6210,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
|
|
|
6171
6210
|
continue;
|
|
6172
6211
|
}
|
|
6173
6212
|
matrix.fromArray(pose.transform.matrix).premultiply(rigMatrix);
|
|
6174
|
-
const vector = target[names[i]] ?? new
|
|
6213
|
+
const vector = target[names[i]] ?? new THREE19.Vector3();
|
|
6175
6214
|
vector.setFromMatrixPosition(matrix);
|
|
6176
6215
|
target[names[i]] = vector;
|
|
6177
6216
|
anyTracked = true;
|
|
@@ -6183,7 +6222,7 @@ var _XRInputSystem = class _XRInputSystem {
|
|
|
6183
6222
|
constructor() {
|
|
6184
6223
|
this.records = /* @__PURE__ */ new Map();
|
|
6185
6224
|
/** Reference-space → world matrix, rebuilt each frame from the XR rig. */
|
|
6186
|
-
this.referenceToWorld = new
|
|
6225
|
+
this.referenceToWorld = new THREE19.Matrix4();
|
|
6187
6226
|
this.session = null;
|
|
6188
6227
|
this.onSelectStart = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectStart"), "onSelectStart");
|
|
6189
6228
|
this.onSelectEnd = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectEnd"), "onSelectEnd");
|
|
@@ -6281,19 +6320,19 @@ var _XRInputSystem = class _XRInputSystem {
|
|
|
6281
6320
|
if (frame && referenceSpace && source.targetRaySpace) {
|
|
6282
6321
|
const pose = frame.getPose(source.targetRaySpace, referenceSpace);
|
|
6283
6322
|
if (pose) {
|
|
6284
|
-
const m = new
|
|
6323
|
+
const m = new THREE19.Matrix4().fromArray(pose.transform.matrix).premultiply(rigMatrix);
|
|
6285
6324
|
state.rayOrigin.setFromMatrixPosition(m);
|
|
6286
6325
|
state.rayDirection.set(0, 0, -1).applyQuaternion(
|
|
6287
|
-
new
|
|
6326
|
+
new THREE19.Quaternion().setFromRotationMatrix(m)
|
|
6288
6327
|
).normalize();
|
|
6289
6328
|
}
|
|
6290
6329
|
}
|
|
6291
6330
|
if (frame && referenceSpace && source.gripSpace) {
|
|
6292
6331
|
const gripPose = frame.getPose(source.gripSpace, referenceSpace);
|
|
6293
6332
|
if (gripPose) {
|
|
6294
|
-
const m = new
|
|
6295
|
-
state.gripPosition ?? (state.gripPosition = new
|
|
6296
|
-
state.gripQuaternion ?? (state.gripQuaternion = new
|
|
6333
|
+
const m = new THREE19.Matrix4().fromArray(gripPose.transform.matrix).premultiply(rigMatrix);
|
|
6334
|
+
state.gripPosition ?? (state.gripPosition = new THREE19.Vector3());
|
|
6335
|
+
state.gripQuaternion ?? (state.gripQuaternion = new THREE19.Quaternion());
|
|
6297
6336
|
state.gripPosition.setFromMatrixPosition(m);
|
|
6298
6337
|
state.gripQuaternion.setFromRotationMatrix(m);
|
|
6299
6338
|
}
|
|
@@ -6378,6 +6417,7 @@ __name(_XRInputSystem, "XRInputSystem");
|
|
|
6378
6417
|
var XRInputSystem = _XRInputSystem;
|
|
6379
6418
|
var VELOCITY_SAMPLES = 5;
|
|
6380
6419
|
var MAX_SAMPLE_AGE_SECONDS = 0.2;
|
|
6420
|
+
var MAX_PLAUSIBLE_SPEED = 20;
|
|
6381
6421
|
var _ThrowVelocityTracker = class _ThrowVelocityTracker {
|
|
6382
6422
|
constructor() {
|
|
6383
6423
|
this.samples = [];
|
|
@@ -6401,16 +6441,17 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
|
|
|
6401
6441
|
const fresh = this.samples.filter(
|
|
6402
6442
|
(sample) => now - sample.time <= MAX_SAMPLE_AGE_SECONDS
|
|
6403
6443
|
);
|
|
6404
|
-
if (fresh.length < 2) return new
|
|
6405
|
-
let best = new
|
|
6444
|
+
if (fresh.length < 2) return new THREE19.Vector3();
|
|
6445
|
+
let best = new THREE19.Vector3();
|
|
6406
6446
|
let bestSpeed = 0;
|
|
6407
6447
|
for (let i = 1; i < fresh.length; i += 1) {
|
|
6408
6448
|
const previous = fresh[i - 1];
|
|
6409
6449
|
const current = fresh[i];
|
|
6410
6450
|
const dt = current.time - previous.time;
|
|
6411
6451
|
if (dt <= 1e-5) continue;
|
|
6412
|
-
const velocity = new
|
|
6452
|
+
const velocity = new THREE19.Vector3().subVectors(current.position, previous.position).divideScalar(dt);
|
|
6413
6453
|
const speed = velocity.length();
|
|
6454
|
+
if (speed > MAX_PLAUSIBLE_SPEED) continue;
|
|
6414
6455
|
if (speed > bestSpeed) {
|
|
6415
6456
|
bestSpeed = speed;
|
|
6416
6457
|
best = velocity;
|
|
@@ -6425,23 +6466,75 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
|
|
|
6425
6466
|
__name(_ThrowVelocityTracker, "ThrowVelocityTracker");
|
|
6426
6467
|
var ThrowVelocityTracker = _ThrowVelocityTracker;
|
|
6427
6468
|
function angularVelocityFrom(previous, current, deltaTime) {
|
|
6428
|
-
if (deltaTime <= 1e-5) return new
|
|
6469
|
+
if (deltaTime <= 1e-5) return new THREE19.Vector3();
|
|
6429
6470
|
const delta = current.clone().multiply(previous.clone().invert());
|
|
6430
6471
|
if (delta.w < 0) {
|
|
6431
6472
|
delta.set(-delta.x, -delta.y, -delta.z, -delta.w);
|
|
6432
6473
|
}
|
|
6433
|
-
const angle = 2 * Math.acos(
|
|
6474
|
+
const angle = 2 * Math.acos(THREE19.MathUtils.clamp(delta.w, -1, 1));
|
|
6434
6475
|
const sinHalf = Math.sqrt(Math.max(0, 1 - delta.w * delta.w));
|
|
6435
|
-
if (sinHalf < 1e-6 || angle < 1e-6) return new
|
|
6436
|
-
return new
|
|
6476
|
+
if (sinHalf < 1e-6 || angle < 1e-6) return new THREE19.Vector3();
|
|
6477
|
+
return new THREE19.Vector3(delta.x, delta.y, delta.z).divideScalar(sinHalf).multiplyScalar(angle / deltaTime);
|
|
6437
6478
|
}
|
|
6438
6479
|
__name(angularVelocityFrom, "angularVelocityFrom");
|
|
6480
|
+
var MIN_HAND_SEPARATION = 0.06;
|
|
6481
|
+
var MIN_ANCHOR_SEPARATION = 1e-3;
|
|
6482
|
+
var SCALE_DEADZONE = 0.05;
|
|
6483
|
+
function solveTwoHandTransform(primary, secondary, basis, options) {
|
|
6484
|
+
const separation = primary.position.distanceTo(secondary.position);
|
|
6485
|
+
const anchorDelta = new THREE19.Vector3().subVectors(
|
|
6486
|
+
basis.secondaryLocal,
|
|
6487
|
+
basis.primaryLocal
|
|
6488
|
+
);
|
|
6489
|
+
const anchorLength = anchorDelta.length();
|
|
6490
|
+
let factor = 1;
|
|
6491
|
+
if (options.allowScale && basis.initialSeparation > MIN_ANCHOR_SEPARATION && separation > MIN_ANCHOR_SEPARATION) {
|
|
6492
|
+
factor = separation / basis.initialSeparation;
|
|
6493
|
+
if (Math.abs(factor - 1) <= SCALE_DEADZONE) {
|
|
6494
|
+
factor = 1;
|
|
6495
|
+
} else {
|
|
6496
|
+
factor += factor > 1 ? -SCALE_DEADZONE : SCALE_DEADZONE;
|
|
6497
|
+
}
|
|
6498
|
+
factor = Math.min(options.maxScale, Math.max(options.minScale, factor));
|
|
6499
|
+
}
|
|
6500
|
+
const scale = basis.initialScale.clone().multiplyScalar(factor);
|
|
6501
|
+
const degenerate = separation < MIN_HAND_SEPARATION || anchorLength < MIN_ANCHOR_SEPARATION;
|
|
6502
|
+
const base = primary.quaternion.clone().multiply(basis.primaryHandOffset);
|
|
6503
|
+
let quaternion;
|
|
6504
|
+
if (options.rotationMode === "primary" || degenerate) {
|
|
6505
|
+
quaternion = base;
|
|
6506
|
+
} else {
|
|
6507
|
+
const axisLocal = anchorDelta.clone().normalize();
|
|
6508
|
+
const currentAxis = axisLocal.clone().applyQuaternion(base).normalize();
|
|
6509
|
+
const desiredAxis = new THREE19.Vector3().subVectors(secondary.position, primary.position).normalize();
|
|
6510
|
+
const correction = new THREE19.Quaternion().setFromUnitVectors(
|
|
6511
|
+
currentAxis,
|
|
6512
|
+
desiredAxis
|
|
6513
|
+
);
|
|
6514
|
+
quaternion = correction.multiply(base);
|
|
6515
|
+
}
|
|
6516
|
+
const anchorOffset = basis.primaryLocal.clone().multiply(scale).applyQuaternion(quaternion);
|
|
6517
|
+
const position = primary.position.clone().sub(anchorOffset);
|
|
6518
|
+
return { position, quaternion, scale, degenerate };
|
|
6519
|
+
}
|
|
6520
|
+
__name(solveTwoHandTransform, "solveTwoHandTransform");
|
|
6439
6521
|
|
|
6440
6522
|
// core/systems/XRInteractionSystem.ts
|
|
6441
6523
|
var RAYLESS_HOLD_DISTANCE = 0.5;
|
|
6524
|
+
function quatFromEulerVec(r) {
|
|
6525
|
+
return new THREE19.Quaternion().setFromEuler(new THREE19.Euler(r.x, r.y, r.z));
|
|
6526
|
+
}
|
|
6527
|
+
__name(quatFromEulerVec, "quatFromEulerVec");
|
|
6528
|
+
function writeEuler(target, q) {
|
|
6529
|
+
const euler = new THREE19.Euler().setFromQuaternion(q);
|
|
6530
|
+
target.x = euler.x;
|
|
6531
|
+
target.y = euler.y;
|
|
6532
|
+
target.z = euler.z;
|
|
6533
|
+
}
|
|
6534
|
+
__name(writeEuler, "writeEuler");
|
|
6442
6535
|
var _XRInteractionSystem = class _XRInteractionSystem {
|
|
6443
6536
|
constructor(inputSystem) {
|
|
6444
|
-
this.raycaster = new
|
|
6537
|
+
this.raycaster = new THREE19.Raycaster();
|
|
6445
6538
|
this.grabs = /* @__PURE__ */ new Map();
|
|
6446
6539
|
this.hoveredEntityId = null;
|
|
6447
6540
|
/** Monotonic seconds, accumulated from deltaTime for velocity sampling. */
|
|
@@ -6464,7 +6557,6 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6464
6557
|
}
|
|
6465
6558
|
const held = this.grabs.get(input);
|
|
6466
6559
|
if (held) {
|
|
6467
|
-
this.moveHeld(world, input, held, deltaTime);
|
|
6468
6560
|
if (this.wantsRelease(world, input, held)) {
|
|
6469
6561
|
this.release(world, input);
|
|
6470
6562
|
}
|
|
@@ -6485,9 +6577,122 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6485
6577
|
/* starting */
|
|
6486
6578
|
true
|
|
6487
6579
|
)) {
|
|
6488
|
-
this.
|
|
6580
|
+
this.tryGrab(world, input, candidate.entityId, candidate.viaDistance);
|
|
6489
6581
|
}
|
|
6490
6582
|
}
|
|
6583
|
+
this.moveAllHeld(world, deltaTime);
|
|
6584
|
+
}
|
|
6585
|
+
/** Hands currently holding an entity. */
|
|
6586
|
+
holdersOf(entityId) {
|
|
6587
|
+
const holders = [];
|
|
6588
|
+
for (const [input, record] of this.grabs) {
|
|
6589
|
+
if (record.entityId === entityId) holders.push({ input, record });
|
|
6590
|
+
}
|
|
6591
|
+
return holders;
|
|
6592
|
+
}
|
|
6593
|
+
/**
|
|
6594
|
+
* Route a new grab: first hand, hand-off, or second hand.
|
|
6595
|
+
*
|
|
6596
|
+
* Which of those happens is the object's choice (`grabHands`), not the
|
|
6597
|
+
* hand's — a ball should pass between hands, a rifle should be held by both,
|
|
6598
|
+
* and a lever should stay with whoever grabbed it first.
|
|
6599
|
+
*/
|
|
6600
|
+
tryGrab(world, input, entityId, viaDistance) {
|
|
6601
|
+
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
6602
|
+
if (!interactable) return;
|
|
6603
|
+
const holders = this.holdersOf(entityId);
|
|
6604
|
+
if (holders.length === 0) {
|
|
6605
|
+
this.grab(world, input, entityId, viaDistance, "primary");
|
|
6606
|
+
return;
|
|
6607
|
+
}
|
|
6608
|
+
if (holders.some((holder) => holder.input === input)) return;
|
|
6609
|
+
if (interactable.grabHands === "single") return;
|
|
6610
|
+
if (interactable.grabHands === "handOff") {
|
|
6611
|
+
const previous = holders[0];
|
|
6612
|
+
this.grabs.delete(previous.input);
|
|
6613
|
+
const record = previous.record;
|
|
6614
|
+
record.role = "primary";
|
|
6615
|
+
record.twoHand = null;
|
|
6616
|
+
this.reanchor(world, input, record, interactable);
|
|
6617
|
+
this.grabs.set(input, record);
|
|
6618
|
+
this.dispatch(world, entityId, (b) => b.onGrab(input));
|
|
6619
|
+
return;
|
|
6620
|
+
}
|
|
6621
|
+
if (holders.length >= 2) return;
|
|
6622
|
+
this.grab(world, input, entityId, viaDistance, "secondary");
|
|
6623
|
+
this.beginTwoHand(world, entityId);
|
|
6624
|
+
}
|
|
6625
|
+
/**
|
|
6626
|
+
* Re-derive a record's hold from where the object is NOW.
|
|
6627
|
+
*
|
|
6628
|
+
* Used on hand-off and on promotion after the primary lets go. Without it the
|
|
6629
|
+
* object snaps to whatever offset the previous hand had, which reads as the
|
|
6630
|
+
* object jumping out of your grip at the moment you take it.
|
|
6631
|
+
*/
|
|
6632
|
+
reanchor(world, input, record, interactable) {
|
|
6633
|
+
const transform = world.getComponent(record.entityId, TransformComponent);
|
|
6634
|
+
if (!transform) return;
|
|
6635
|
+
const hand = this.handPosition(input);
|
|
6636
|
+
const handQuaternion = this.handQuaternion(input);
|
|
6637
|
+
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
6638
|
+
record.offset = new THREE19.Vector3(
|
|
6639
|
+
transform.position.x - hand.x,
|
|
6640
|
+
transform.position.y - hand.y,
|
|
6641
|
+
transform.position.z - hand.z
|
|
6642
|
+
);
|
|
6643
|
+
record.handRotationOffset = handQuaternion.clone().invert().multiply(objectQuaternion);
|
|
6644
|
+
record.remote = false;
|
|
6645
|
+
record.tracker.clear();
|
|
6646
|
+
record.tracker.record(hand, this.elapsed);
|
|
6647
|
+
record.lastHandQuaternion = handQuaternion.clone();
|
|
6648
|
+
if (record.attachLocal && interactable.attachPoints.length === 0) {
|
|
6649
|
+
record.attachLocal = null;
|
|
6650
|
+
record.attachQuaternion = null;
|
|
6651
|
+
record.attachPointId = null;
|
|
6652
|
+
}
|
|
6653
|
+
}
|
|
6654
|
+
/** Capture the two-hand basis once both hands are on the object. */
|
|
6655
|
+
beginTwoHand(world, entityId) {
|
|
6656
|
+
const holders = this.holdersOf(entityId);
|
|
6657
|
+
if (holders.length !== 2) return;
|
|
6658
|
+
const primary = holders.find((h) => h.record.role === "primary");
|
|
6659
|
+
const secondary = holders.find((h) => h.record.role === "secondary");
|
|
6660
|
+
if (!primary || !secondary) return;
|
|
6661
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
6662
|
+
if (!transform) return;
|
|
6663
|
+
const primaryHand = this.handPosition(primary.input);
|
|
6664
|
+
const secondaryHand = this.handPosition(secondary.input);
|
|
6665
|
+
const primaryLocal = primary.record.attachLocal?.clone() ?? this.objectLocalPoint(transform, primaryHand);
|
|
6666
|
+
const secondaryLocal = secondary.record.attachLocal?.clone() ?? this.objectLocalPoint(transform, secondaryHand);
|
|
6667
|
+
primary.record.twoHand = {
|
|
6668
|
+
primaryLocal,
|
|
6669
|
+
secondaryLocal,
|
|
6670
|
+
initialScale: new THREE19.Vector3(
|
|
6671
|
+
transform.scale.x,
|
|
6672
|
+
transform.scale.y,
|
|
6673
|
+
transform.scale.z
|
|
6674
|
+
),
|
|
6675
|
+
initialSeparation: primaryHand.distanceTo(secondaryHand),
|
|
6676
|
+
// How the object sits relative to the anchoring hand right now, so the
|
|
6677
|
+
// two-hand solve picks up exactly where the one-hand hold left off.
|
|
6678
|
+
primaryHandOffset: this.handQuaternion(primary.input).invert().multiply(quatFromEulerVec(transform.rotation)),
|
|
6679
|
+
initialQuaternion: quatFromEulerVec(transform.rotation)
|
|
6680
|
+
};
|
|
6681
|
+
this.dispatch(world, entityId, (b) => b.onSecondaryGrab(secondary.input));
|
|
6682
|
+
}
|
|
6683
|
+
/** World point → the object's UNSCALED local space. */
|
|
6684
|
+
objectLocalPoint(transform, worldPoint) {
|
|
6685
|
+
const local = worldPoint.clone().sub(
|
|
6686
|
+
new THREE19.Vector3(
|
|
6687
|
+
transform.position.x,
|
|
6688
|
+
transform.position.y,
|
|
6689
|
+
transform.position.z
|
|
6690
|
+
)
|
|
6691
|
+
).applyQuaternion(quatFromEulerVec(transform.rotation).invert());
|
|
6692
|
+
local.x /= transform.scale.x || 1;
|
|
6693
|
+
local.y /= transform.scale.y || 1;
|
|
6694
|
+
local.z /= transform.scale.z || 1;
|
|
6695
|
+
return local;
|
|
6491
6696
|
}
|
|
6492
6697
|
/** Whether the grab gesture for this object is currently starting. */
|
|
6493
6698
|
gestureMatches(input, interactable, starting) {
|
|
@@ -6536,7 +6741,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6536
6741
|
);
|
|
6537
6742
|
if (!interactable2) continue;
|
|
6538
6743
|
if (interactable2.grabReach === "distance") continue;
|
|
6539
|
-
const position = new
|
|
6744
|
+
const position = new THREE19.Vector3();
|
|
6540
6745
|
entry.object.getWorldPosition(position);
|
|
6541
6746
|
const distance = position.distanceTo(hand);
|
|
6542
6747
|
if (distance <= interactable2.grabRadius && distance < nearestDistance) {
|
|
@@ -6560,7 +6765,9 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6560
6765
|
if (!interactable?.enabled) continue;
|
|
6561
6766
|
if (!world.isEntityVisible(entityId)) continue;
|
|
6562
6767
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
6563
|
-
if (object)
|
|
6768
|
+
if (object) {
|
|
6769
|
+
out.push({ entityId, object, pointable: interactable.pointable });
|
|
6770
|
+
}
|
|
6564
6771
|
}
|
|
6565
6772
|
return out;
|
|
6566
6773
|
}
|
|
@@ -6572,6 +6779,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6572
6779
|
let nearestId = null;
|
|
6573
6780
|
let nearestDistance = Number.POSITIVE_INFINITY;
|
|
6574
6781
|
for (const entry of interactables) {
|
|
6782
|
+
if (!entry.pointable) continue;
|
|
6575
6783
|
const hit = this.raycaster.intersectObject(entry.object, true)[0];
|
|
6576
6784
|
if (!hit) continue;
|
|
6577
6785
|
if (hit.distance < nearestDistance) {
|
|
@@ -6581,7 +6789,52 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6581
6789
|
}
|
|
6582
6790
|
return nearestId;
|
|
6583
6791
|
}
|
|
6584
|
-
|
|
6792
|
+
/**
|
|
6793
|
+
* Pick the authored hold this hand should take.
|
|
6794
|
+
*
|
|
6795
|
+
* Filters by hand and by role — that is what makes "the trigger hand goes on
|
|
6796
|
+
* the grip" hold regardless of which hand reaches first — then takes the
|
|
6797
|
+
* nearest remaining one so grabbing near the foregrip picks the foregrip.
|
|
6798
|
+
*/
|
|
6799
|
+
chooseAttachPoint(world, input, entityId, interactable, role) {
|
|
6800
|
+
if (interactable.attachPoints.length === 0) return null;
|
|
6801
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
6802
|
+
if (!transform) return null;
|
|
6803
|
+
const taken = new Set(
|
|
6804
|
+
this.holdersOf(entityId).map((holder) => holder.record.attachPointId).filter((id) => id !== null)
|
|
6805
|
+
);
|
|
6806
|
+
const hand = this.handPosition(input);
|
|
6807
|
+
const objectPosition = new THREE19.Vector3(
|
|
6808
|
+
transform.position.x,
|
|
6809
|
+
transform.position.y,
|
|
6810
|
+
transform.position.z
|
|
6811
|
+
);
|
|
6812
|
+
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
6813
|
+
const scale = new THREE19.Vector3(
|
|
6814
|
+
transform.scale.x,
|
|
6815
|
+
transform.scale.y,
|
|
6816
|
+
transform.scale.z
|
|
6817
|
+
);
|
|
6818
|
+
let best = null;
|
|
6819
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
6820
|
+
for (const point of interactable.attachPoints) {
|
|
6821
|
+
if (taken.has(point.id)) continue;
|
|
6822
|
+
if (point.hand !== "any" && point.hand !== input.handedness) continue;
|
|
6823
|
+
if (point.role !== "any" && point.role !== role) continue;
|
|
6824
|
+
const world3 = new THREE19.Vector3(
|
|
6825
|
+
point.position.x,
|
|
6826
|
+
point.position.y,
|
|
6827
|
+
point.position.z
|
|
6828
|
+
).multiply(scale).applyQuaternion(objectQuaternion).add(objectPosition);
|
|
6829
|
+
const distance = world3.distanceTo(hand);
|
|
6830
|
+
if (distance < bestDistance) {
|
|
6831
|
+
bestDistance = distance;
|
|
6832
|
+
best = point;
|
|
6833
|
+
}
|
|
6834
|
+
}
|
|
6835
|
+
return best;
|
|
6836
|
+
}
|
|
6837
|
+
grab(world, input, entityId, viaDistance, role) {
|
|
6585
6838
|
const transform = world.getComponent(entityId, TransformComponent);
|
|
6586
6839
|
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
6587
6840
|
if (!transform || !interactable) return;
|
|
@@ -6591,21 +6844,21 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6591
6844
|
let offset;
|
|
6592
6845
|
let remoteDistance = 0;
|
|
6593
6846
|
if (remote) {
|
|
6594
|
-
const position = new
|
|
6847
|
+
const position = new THREE19.Vector3(
|
|
6595
6848
|
transform.position.x,
|
|
6596
6849
|
transform.position.y,
|
|
6597
6850
|
transform.position.z
|
|
6598
6851
|
);
|
|
6599
6852
|
remoteDistance = position.distanceTo(input.rayOrigin);
|
|
6600
|
-
offset = new
|
|
6853
|
+
offset = new THREE19.Vector3();
|
|
6601
6854
|
} else if (viaDistance) {
|
|
6602
|
-
offset = new
|
|
6855
|
+
offset = new THREE19.Vector3(
|
|
6603
6856
|
interactable.grabOffsetPosition.x,
|
|
6604
6857
|
interactable.grabOffsetPosition.y,
|
|
6605
6858
|
interactable.grabOffsetPosition.z
|
|
6606
6859
|
);
|
|
6607
6860
|
} else {
|
|
6608
|
-
offset = new
|
|
6861
|
+
offset = new THREE19.Vector3(
|
|
6609
6862
|
transform.position.x - hand.x,
|
|
6610
6863
|
transform.position.y - hand.y,
|
|
6611
6864
|
transform.position.z - hand.z
|
|
@@ -6619,11 +6872,30 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6619
6872
|
}
|
|
6620
6873
|
const tracker = new ThrowVelocityTracker();
|
|
6621
6874
|
tracker.record(hand, this.elapsed);
|
|
6875
|
+
const attachPoint = this.chooseAttachPoint(
|
|
6876
|
+
world,
|
|
6877
|
+
input,
|
|
6878
|
+
entityId,
|
|
6879
|
+
interactable,
|
|
6880
|
+
role
|
|
6881
|
+
);
|
|
6882
|
+
const objectQuaternion = quatFromEulerVec(transform.rotation);
|
|
6883
|
+
const handRotationOffset = handQuaternion.clone().invert().multiply(objectQuaternion);
|
|
6622
6884
|
this.grabs.set(input, {
|
|
6623
6885
|
entityId,
|
|
6886
|
+
role,
|
|
6887
|
+
attachPointId: attachPoint?.id ?? null,
|
|
6888
|
+
attachLocal: attachPoint ? new THREE19.Vector3(
|
|
6889
|
+
attachPoint.position.x,
|
|
6890
|
+
attachPoint.position.y,
|
|
6891
|
+
attachPoint.position.z
|
|
6892
|
+
) : null,
|
|
6893
|
+
attachQuaternion: attachPoint ? quatFromEulerVec(attachPoint.rotation) : null,
|
|
6894
|
+
handRotationOffset,
|
|
6895
|
+
twoHand: null,
|
|
6624
6896
|
offset,
|
|
6625
|
-
rotationOffset: new
|
|
6626
|
-
new
|
|
6897
|
+
rotationOffset: new THREE19.Quaternion().setFromEuler(
|
|
6898
|
+
new THREE19.Euler(
|
|
6627
6899
|
interactable.grabOffsetRotation.x,
|
|
6628
6900
|
interactable.grabOffsetRotation.y,
|
|
6629
6901
|
interactable.grabOffsetRotation.z
|
|
@@ -6634,33 +6906,110 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6634
6906
|
restoreBodyType,
|
|
6635
6907
|
tracker,
|
|
6636
6908
|
lastHandQuaternion: handQuaternion.clone(),
|
|
6637
|
-
angularVelocity: new
|
|
6909
|
+
angularVelocity: new THREE19.Vector3()
|
|
6638
6910
|
});
|
|
6639
|
-
|
|
6911
|
+
if (role === "primary") {
|
|
6912
|
+
this.dispatch(world, entityId, (b) => b.onGrab(input));
|
|
6913
|
+
}
|
|
6914
|
+
}
|
|
6915
|
+
/** Drive every held object, once each, after grabs and releases settle. */
|
|
6916
|
+
moveAllHeld(world, deltaTime) {
|
|
6917
|
+
const done = /* @__PURE__ */ new Set();
|
|
6918
|
+
for (const [input, record] of this.grabs) {
|
|
6919
|
+
if (done.has(record.entityId)) continue;
|
|
6920
|
+
done.add(record.entityId);
|
|
6921
|
+
const holders = this.holdersOf(record.entityId);
|
|
6922
|
+
if (holders.length >= 2) {
|
|
6923
|
+
this.moveTwoHand(world, record.entityId, holders, deltaTime);
|
|
6924
|
+
} else {
|
|
6925
|
+
this.moveHeld(world, input, record, deltaTime);
|
|
6926
|
+
}
|
|
6927
|
+
}
|
|
6928
|
+
}
|
|
6929
|
+
/** Solve and apply a two-hand hold. */
|
|
6930
|
+
moveTwoHand(world, entityId, holders, deltaTime) {
|
|
6931
|
+
const primary = holders.find((h) => h.record.role === "primary");
|
|
6932
|
+
const secondary = holders.find((h) => h.record.role === "secondary");
|
|
6933
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
6934
|
+
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
6935
|
+
const basis = primary?.record.twoHand ?? null;
|
|
6936
|
+
if (!primary || !secondary || !transform || !interactable || !basis) {
|
|
6937
|
+
if (primary) {
|
|
6938
|
+
this.moveHeld(world, primary.input, primary.record, deltaTime);
|
|
6939
|
+
}
|
|
6940
|
+
return;
|
|
6941
|
+
}
|
|
6942
|
+
const primaryHand = this.handPosition(primary.input);
|
|
6943
|
+
const primaryQuaternion = this.handQuaternion(primary.input);
|
|
6944
|
+
const solved = solveTwoHandTransform(
|
|
6945
|
+
{ position: primaryHand, quaternion: primaryQuaternion },
|
|
6946
|
+
{
|
|
6947
|
+
position: this.handPosition(secondary.input),
|
|
6948
|
+
quaternion: this.handQuaternion(secondary.input)
|
|
6949
|
+
},
|
|
6950
|
+
basis,
|
|
6951
|
+
{
|
|
6952
|
+
rotationMode: interactable.twoHandRotation,
|
|
6953
|
+
allowScale: interactable.allowTwoHandScale,
|
|
6954
|
+
minScale: interactable.minScale,
|
|
6955
|
+
maxScale: interactable.maxScale
|
|
6956
|
+
}
|
|
6957
|
+
);
|
|
6958
|
+
transform.position.x = solved.position.x;
|
|
6959
|
+
transform.position.y = solved.position.y;
|
|
6960
|
+
transform.position.z = solved.position.z;
|
|
6961
|
+
writeEuler(transform.rotation, solved.quaternion);
|
|
6962
|
+
if (interactable.allowTwoHandScale) {
|
|
6963
|
+
transform.scale.x = solved.scale.x;
|
|
6964
|
+
transform.scale.y = solved.scale.y;
|
|
6965
|
+
transform.scale.z = solved.scale.z;
|
|
6966
|
+
}
|
|
6967
|
+
primary.record.tracker.record(primaryHand, this.elapsed);
|
|
6968
|
+
primary.record.angularVelocity = angularVelocityFrom(
|
|
6969
|
+
primary.record.lastHandQuaternion,
|
|
6970
|
+
primaryQuaternion,
|
|
6971
|
+
deltaTime
|
|
6972
|
+
);
|
|
6973
|
+
primary.record.lastHandQuaternion = primaryQuaternion.clone();
|
|
6640
6974
|
}
|
|
6641
6975
|
moveHeld(world, input, held, deltaTime) {
|
|
6642
6976
|
const transform = world.getComponent(held.entityId, TransformComponent);
|
|
6643
6977
|
if (!transform) return;
|
|
6644
6978
|
const hand = this.handPosition(input);
|
|
6979
|
+
const handQuaternion = this.handQuaternion(input);
|
|
6980
|
+
const objectQuaternion = held.attachQuaternion ? handQuaternion.clone().multiply(held.rotationOffset).multiply(held.attachQuaternion.clone().invert()) : handQuaternion.clone().multiply(held.handRotationOffset);
|
|
6645
6981
|
if (held.remote) {
|
|
6646
|
-
const target = new
|
|
6982
|
+
const target = new THREE19.Vector3().copy(input.rayDirection).multiplyScalar(held.remoteDistance).add(input.rayOrigin);
|
|
6647
6983
|
transform.position.x = target.x;
|
|
6648
6984
|
transform.position.y = target.y;
|
|
6649
6985
|
transform.position.z = target.z;
|
|
6986
|
+
writeEuler(transform.rotation, objectQuaternion);
|
|
6987
|
+
} else if (held.attachLocal) {
|
|
6988
|
+
const anchor = held.attachLocal.clone().multiply(
|
|
6989
|
+
new THREE19.Vector3(
|
|
6990
|
+
transform.scale.x,
|
|
6991
|
+
transform.scale.y,
|
|
6992
|
+
transform.scale.z
|
|
6993
|
+
)
|
|
6994
|
+
).applyQuaternion(objectQuaternion);
|
|
6995
|
+
transform.position.x = hand.x - anchor.x;
|
|
6996
|
+
transform.position.y = hand.y - anchor.y;
|
|
6997
|
+
transform.position.z = hand.z - anchor.z;
|
|
6998
|
+
writeEuler(transform.rotation, objectQuaternion);
|
|
6650
6999
|
} else {
|
|
6651
7000
|
transform.position.x = hand.x + held.offset.x;
|
|
6652
7001
|
transform.position.y = hand.y + held.offset.y;
|
|
6653
7002
|
transform.position.z = hand.z + held.offset.z;
|
|
7003
|
+
writeEuler(transform.rotation, objectQuaternion);
|
|
6654
7004
|
}
|
|
6655
7005
|
held.tracker.record(
|
|
6656
|
-
held.remote ? new
|
|
7006
|
+
held.remote ? new THREE19.Vector3(
|
|
6657
7007
|
transform.position.x,
|
|
6658
7008
|
transform.position.y,
|
|
6659
7009
|
transform.position.z
|
|
6660
7010
|
) : hand,
|
|
6661
7011
|
this.elapsed
|
|
6662
7012
|
);
|
|
6663
|
-
const handQuaternion = this.handQuaternion(input);
|
|
6664
7013
|
held.angularVelocity = angularVelocityFrom(
|
|
6665
7014
|
held.lastHandQuaternion,
|
|
6666
7015
|
handQuaternion,
|
|
@@ -6676,6 +7025,30 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6676
7025
|
held.entityId,
|
|
6677
7026
|
XRInteractableComponent
|
|
6678
7027
|
);
|
|
7028
|
+
const remaining = this.holdersOf(held.entityId);
|
|
7029
|
+
if (remaining.length > 0 && interactable) {
|
|
7030
|
+
if (held.role === "secondary") {
|
|
7031
|
+
const primary = remaining.find((h) => h.record.role === "primary");
|
|
7032
|
+
if (primary) {
|
|
7033
|
+
primary.record.twoHand = null;
|
|
7034
|
+
this.reanchor(world, primary.input, primary.record, interactable);
|
|
7035
|
+
}
|
|
7036
|
+
this.dispatch(
|
|
7037
|
+
world,
|
|
7038
|
+
held.entityId,
|
|
7039
|
+
(b) => b.onSecondaryRelease(input)
|
|
7040
|
+
);
|
|
7041
|
+
} else {
|
|
7042
|
+
const next = remaining[0];
|
|
7043
|
+
next.record.role = "primary";
|
|
7044
|
+
next.record.twoHand = null;
|
|
7045
|
+
next.record.restoreBodyType = held.restoreBodyType;
|
|
7046
|
+
this.reanchor(world, next.input, next.record, interactable);
|
|
7047
|
+
this.dispatch(world, held.entityId, (b) => b.onRelease(input));
|
|
7048
|
+
}
|
|
7049
|
+
held.tracker.clear();
|
|
7050
|
+
return;
|
|
7051
|
+
}
|
|
6679
7052
|
const physics = world.getComponent(held.entityId, PhysicsComponent);
|
|
6680
7053
|
if (held.restoreBodyType !== null && physics) {
|
|
6681
7054
|
physics.values.rigidbody.type = held.restoreBodyType;
|
|
@@ -6709,7 +7082,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6709
7082
|
*/
|
|
6710
7083
|
handPosition(input) {
|
|
6711
7084
|
if (input.gripPosition) return input.gripPosition;
|
|
6712
|
-
return new
|
|
7085
|
+
return new THREE19.Vector3().copy(input.rayDirection).multiplyScalar(RAYLESS_HOLD_DISTANCE).add(input.rayOrigin);
|
|
6713
7086
|
}
|
|
6714
7087
|
/**
|
|
6715
7088
|
* Hand orientation. Grip-less sources (gaze / transient-pointer) have none,
|
|
@@ -6717,8 +7090,8 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6717
7090
|
*/
|
|
6718
7091
|
handQuaternion(input) {
|
|
6719
7092
|
if (input.gripQuaternion) return input.gripQuaternion.clone();
|
|
6720
|
-
return new
|
|
6721
|
-
new
|
|
7093
|
+
return new THREE19.Quaternion().setFromUnitVectors(
|
|
7094
|
+
new THREE19.Vector3(0, 0, -1),
|
|
6722
7095
|
input.rayDirection.clone().normalize()
|
|
6723
7096
|
);
|
|
6724
7097
|
}
|
|
@@ -6743,6 +7116,29 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6743
7116
|
isGrabbing() {
|
|
6744
7117
|
return this.grabs.size > 0;
|
|
6745
7118
|
}
|
|
7119
|
+
/**
|
|
7120
|
+
* How an entity is currently held.
|
|
7121
|
+
*
|
|
7122
|
+
* Exposed for scripts: a Behaviour can poll this in `onUpdate` to drive
|
|
7123
|
+
* two-hand-specific behaviour — showing a bipod when both hands are on a
|
|
7124
|
+
* weapon, reading the live hand separation to gate a gesture, or reacting to
|
|
7125
|
+
* the scale a pull-apart produced. Returns null when nothing holds it.
|
|
7126
|
+
*/
|
|
7127
|
+
getGrabInfo(entityId) {
|
|
7128
|
+
const holders = this.holdersOf(entityId);
|
|
7129
|
+
if (holders.length === 0) return null;
|
|
7130
|
+
const primary = holders.find((h) => h.record.role === "primary");
|
|
7131
|
+
const secondary = holders.find((h) => h.record.role === "secondary");
|
|
7132
|
+
return {
|
|
7133
|
+
hands: holders.length,
|
|
7134
|
+
primaryHandedness: primary?.input.handedness ?? null,
|
|
7135
|
+
secondaryHandedness: secondary?.input.handedness ?? null,
|
|
7136
|
+
handSeparation: primary && secondary ? this.handPosition(primary.input).distanceTo(
|
|
7137
|
+
this.handPosition(secondary.input)
|
|
7138
|
+
) : null,
|
|
7139
|
+
attachPointIds: holders.map((h) => h.record.attachPointId)
|
|
7140
|
+
};
|
|
7141
|
+
}
|
|
6746
7142
|
};
|
|
6747
7143
|
__name(_XRInteractionSystem, "XRInteractionSystem");
|
|
6748
7144
|
var XRInteractionSystem = _XRInteractionSystem;
|
|
@@ -6760,7 +7156,7 @@ function sampleTeleportArc(origin, direction, out = [], options) {
|
|
|
6760
7156
|
for (let i = 0; i < steps; i += 1) {
|
|
6761
7157
|
const t = i / (steps - 1) * maxTime;
|
|
6762
7158
|
out.push(
|
|
6763
|
-
new
|
|
7159
|
+
new THREE19.Vector3(
|
|
6764
7160
|
origin.x + velocity.x * t,
|
|
6765
7161
|
origin.y + velocity.y * t - 0.5 * gravity * t * t,
|
|
6766
7162
|
origin.z + velocity.z * t
|
|
@@ -6777,7 +7173,7 @@ function arcGroundCrossing(points, groundY) {
|
|
|
6777
7173
|
if (previous.y >= groundY && current.y <= groundY) {
|
|
6778
7174
|
const span = previous.y - current.y;
|
|
6779
7175
|
const alpha = span > 1e-6 ? (previous.y - groundY) / span : 0;
|
|
6780
|
-
return new
|
|
7176
|
+
return new THREE19.Vector3().lerpVectors(previous, current, alpha);
|
|
6781
7177
|
}
|
|
6782
7178
|
}
|
|
6783
7179
|
return null;
|
|
@@ -6785,11 +7181,11 @@ function arcGroundCrossing(points, groundY) {
|
|
|
6785
7181
|
__name(arcGroundCrossing, "arcGroundCrossing");
|
|
6786
7182
|
|
|
6787
7183
|
// core/systems/XRLocomotionSystem.ts
|
|
6788
|
-
var UP = new
|
|
7184
|
+
var UP = new THREE19.Vector3(0, 1, 0);
|
|
6789
7185
|
var AXIS_DEADZONE = 0.5;
|
|
6790
7186
|
var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
6791
7187
|
constructor(inputSystem) {
|
|
6792
|
-
this.raycaster = new
|
|
7188
|
+
this.raycaster = new THREE19.Raycaster();
|
|
6793
7189
|
/** Per-source latch so one stick push yields exactly one snap turn. */
|
|
6794
7190
|
this.turnLatched = /* @__PURE__ */ new WeakSet();
|
|
6795
7191
|
/** Reused arc buffer — aiming runs every frame. */
|
|
@@ -6898,7 +7294,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
6898
7294
|
}
|
|
6899
7295
|
if (this.turnLatched.has(source)) continue;
|
|
6900
7296
|
this.turnLatched.add(source);
|
|
6901
|
-
transform.rotation.y -= Math.sign(x) *
|
|
7297
|
+
transform.rotation.y -= Math.sign(x) * THREE19.MathUtils.degToRad(rig.snapTurnDegrees);
|
|
6902
7298
|
}
|
|
6903
7299
|
}
|
|
6904
7300
|
applySmoothMove(world, rig, transform, inputs, deltaTime) {
|
|
@@ -6908,12 +7304,12 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
6908
7304
|
const y = input.axes[1] ?? 0;
|
|
6909
7305
|
if (Math.abs(x) < 0.15 && Math.abs(y) < 0.15) continue;
|
|
6910
7306
|
const camera = world.getCamera();
|
|
6911
|
-
const forward = new
|
|
7307
|
+
const forward = new THREE19.Vector3();
|
|
6912
7308
|
camera.getWorldDirection(forward);
|
|
6913
7309
|
forward.y = 0;
|
|
6914
7310
|
if (forward.lengthSq() < 1e-6) continue;
|
|
6915
7311
|
forward.normalize();
|
|
6916
|
-
const right = new
|
|
7312
|
+
const right = new THREE19.Vector3().crossVectors(forward, UP).normalize();
|
|
6917
7313
|
const step = rig.moveSpeed * Math.max(0, deltaTime);
|
|
6918
7314
|
transform.position.x += (forward.x * -y + right.x * x) * step;
|
|
6919
7315
|
transform.position.z += (forward.z * -y + right.z * x) * step;
|
|
@@ -6978,7 +7374,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
6978
7374
|
for (let i = 1; i < points.length; i += 1) {
|
|
6979
7375
|
const from = points[i - 1];
|
|
6980
7376
|
const to = points[i];
|
|
6981
|
-
const delta = new
|
|
7377
|
+
const delta = new THREE19.Vector3().subVectors(to, from);
|
|
6982
7378
|
const distance = delta.length();
|
|
6983
7379
|
if (distance < 1e-6) continue;
|
|
6984
7380
|
this.raycaster.set(from, delta.divideScalar(distance));
|
|
@@ -7186,9 +7582,9 @@ var XRSessionSystem = _XRSessionSystem;
|
|
|
7186
7582
|
function buildGeometry2(area) {
|
|
7187
7583
|
if (area.shape === "circle") {
|
|
7188
7584
|
const radius = Math.max(5e-3, area.width / 2);
|
|
7189
|
-
return new
|
|
7585
|
+
return new THREE19.CircleGeometry(radius, 48);
|
|
7190
7586
|
}
|
|
7191
|
-
return new
|
|
7587
|
+
return new THREE19.PlaneGeometry(
|
|
7192
7588
|
Math.max(0.01, area.width),
|
|
7193
7589
|
Math.max(0.01, area.depth)
|
|
7194
7590
|
);
|
|
@@ -7211,7 +7607,7 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
7211
7607
|
for (const entityId of entityIds) {
|
|
7212
7608
|
const area = world.getComponent(entityId, VRTeleportAreaComponent);
|
|
7213
7609
|
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
7214
|
-
if (!area || !(object instanceof
|
|
7610
|
+
if (!area || !(object instanceof THREE19.Mesh)) continue;
|
|
7215
7611
|
const signature = signatureOf(area);
|
|
7216
7612
|
if (this.signatures.get(entityId) === signature) continue;
|
|
7217
7613
|
this.signatures.set(entityId, signature);
|
|
@@ -7223,18 +7619,18 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
7223
7619
|
__name(_VRTeleportAreaSystem, "VRTeleportAreaSystem");
|
|
7224
7620
|
var VRTeleportAreaSystem = _VRTeleportAreaSystem;
|
|
7225
7621
|
function createHandMaterial(preset, options) {
|
|
7226
|
-
const color = new
|
|
7622
|
+
const color = new THREE19.Color(options.color);
|
|
7227
7623
|
switch (preset) {
|
|
7228
7624
|
case "ghost":
|
|
7229
|
-
return new
|
|
7625
|
+
return new THREE19.MeshBasicMaterial({
|
|
7230
7626
|
color,
|
|
7231
7627
|
transparent: true,
|
|
7232
7628
|
opacity: Math.min(1, Math.max(0.05, options.opacity * 0.45)),
|
|
7233
7629
|
depthWrite: false,
|
|
7234
|
-
side:
|
|
7630
|
+
side: THREE19.DoubleSide
|
|
7235
7631
|
});
|
|
7236
7632
|
case "neon":
|
|
7237
|
-
return new
|
|
7633
|
+
return new THREE19.MeshStandardMaterial({
|
|
7238
7634
|
color,
|
|
7239
7635
|
emissive: color,
|
|
7240
7636
|
emissiveIntensity: Math.max(0.5, options.emissiveIntensity || 2),
|
|
@@ -7244,7 +7640,7 @@ function createHandMaterial(preset, options) {
|
|
|
7244
7640
|
opacity: options.opacity
|
|
7245
7641
|
});
|
|
7246
7642
|
case "skeleton":
|
|
7247
|
-
return new
|
|
7643
|
+
return new THREE19.MeshBasicMaterial({
|
|
7248
7644
|
color,
|
|
7249
7645
|
wireframe: true,
|
|
7250
7646
|
transparent: true,
|
|
@@ -7252,7 +7648,7 @@ function createHandMaterial(preset, options) {
|
|
|
7252
7648
|
});
|
|
7253
7649
|
case "custom":
|
|
7254
7650
|
case "default":
|
|
7255
|
-
return new
|
|
7651
|
+
return new THREE19.MeshStandardMaterial({
|
|
7256
7652
|
color,
|
|
7257
7653
|
roughness: 0.85,
|
|
7258
7654
|
metalness: 0,
|
|
@@ -7260,10 +7656,10 @@ function createHandMaterial(preset, options) {
|
|
|
7260
7656
|
emissiveIntensity: Math.max(0, options.emissiveIntensity),
|
|
7261
7657
|
transparent: options.opacity < 1,
|
|
7262
7658
|
opacity: options.opacity,
|
|
7263
|
-
side:
|
|
7659
|
+
side: THREE19.DoubleSide
|
|
7264
7660
|
});
|
|
7265
7661
|
default: {
|
|
7266
|
-
return new
|
|
7662
|
+
return new THREE19.MeshStandardMaterial({ color });
|
|
7267
7663
|
}
|
|
7268
7664
|
}
|
|
7269
7665
|
}
|
|
@@ -7284,7 +7680,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
7284
7680
|
constructor(options) {
|
|
7285
7681
|
this.controllerModelFactory = new XRControllerModelFactory();
|
|
7286
7682
|
this.handModelFactory = new XRHandModelFactory();
|
|
7287
|
-
this.group = new
|
|
7683
|
+
this.group = new THREE19.Group();
|
|
7288
7684
|
this.slots = /* @__PURE__ */ new Map();
|
|
7289
7685
|
this.attachedTo = null;
|
|
7290
7686
|
/** Last applied preset signature, so materials rebuild only on real change. */
|
|
@@ -7433,17 +7829,17 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
7433
7829
|
this.attachedTo = target;
|
|
7434
7830
|
}
|
|
7435
7831
|
createRay() {
|
|
7436
|
-
const geometry = new
|
|
7437
|
-
new
|
|
7438
|
-
new
|
|
7832
|
+
const geometry = new THREE19.BufferGeometry().setFromPoints([
|
|
7833
|
+
new THREE19.Vector3(0, 0, 0),
|
|
7834
|
+
new THREE19.Vector3(0, 0, -5)
|
|
7439
7835
|
]);
|
|
7440
|
-
const material = new
|
|
7836
|
+
const material = new THREE19.LineBasicMaterial({
|
|
7441
7837
|
color: "#4da3ff",
|
|
7442
7838
|
transparent: true,
|
|
7443
7839
|
opacity: 0.6,
|
|
7444
7840
|
depthTest: false
|
|
7445
7841
|
});
|
|
7446
|
-
const line = new
|
|
7842
|
+
const line = new THREE19.Line(geometry, material);
|
|
7447
7843
|
line.name = "XRPointerRay";
|
|
7448
7844
|
line.renderOrder = 999;
|
|
7449
7845
|
line.visible = false;
|
|
@@ -7472,23 +7868,23 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
7472
7868
|
__name(_XRControllerVisualSystem, "XRControllerVisualSystem");
|
|
7473
7869
|
var XRControllerVisualSystem = _XRControllerVisualSystem;
|
|
7474
7870
|
var MARKER_RADIUS = 0.28;
|
|
7475
|
-
var ACCENT = new
|
|
7476
|
-
var BLOCKED = new
|
|
7871
|
+
var ACCENT = new THREE19.Color("#4da3ff");
|
|
7872
|
+
var BLOCKED = new THREE19.Color("#ff5a5a");
|
|
7477
7873
|
var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
7478
7874
|
constructor(locomotionSystem) {
|
|
7479
|
-
this.group = new
|
|
7480
|
-
this.arcGeometry = new
|
|
7481
|
-
this.marker = new
|
|
7875
|
+
this.group = new THREE19.Group();
|
|
7876
|
+
this.arcGeometry = new THREE19.BufferGeometry();
|
|
7877
|
+
this.marker = new THREE19.Group();
|
|
7482
7878
|
this.attached = false;
|
|
7483
7879
|
this.locomotionSystem = locomotionSystem;
|
|
7484
7880
|
this.group.name = "XRTeleportVisuals";
|
|
7485
7881
|
this.group.userData.ecsPreviewHidden = true;
|
|
7486
|
-
const arcMaterial = new
|
|
7882
|
+
const arcMaterial = new THREE19.LineBasicMaterial({
|
|
7487
7883
|
vertexColors: true,
|
|
7488
7884
|
transparent: true,
|
|
7489
7885
|
depthTest: false
|
|
7490
7886
|
});
|
|
7491
|
-
this.arc = new
|
|
7887
|
+
this.arc = new THREE19.Line(this.arcGeometry, arcMaterial);
|
|
7492
7888
|
this.arc.frustumCulled = false;
|
|
7493
7889
|
this.arc.renderOrder = 998;
|
|
7494
7890
|
this.group.add(this.arc);
|
|
@@ -7536,39 +7932,39 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
7536
7932
|
}
|
|
7537
7933
|
this.arcGeometry.setAttribute(
|
|
7538
7934
|
"position",
|
|
7539
|
-
new
|
|
7935
|
+
new THREE19.BufferAttribute(positions, 3)
|
|
7540
7936
|
);
|
|
7541
|
-
this.arcGeometry.setAttribute("color", new
|
|
7937
|
+
this.arcGeometry.setAttribute("color", new THREE19.BufferAttribute(colors, 3));
|
|
7542
7938
|
this.arcGeometry.computeBoundingSphere();
|
|
7543
7939
|
}
|
|
7544
7940
|
createRing() {
|
|
7545
|
-
const geometry = new
|
|
7941
|
+
const geometry = new THREE19.RingGeometry(
|
|
7546
7942
|
MARKER_RADIUS * 0.72,
|
|
7547
7943
|
MARKER_RADIUS,
|
|
7548
7944
|
48
|
|
7549
7945
|
);
|
|
7550
7946
|
geometry.rotateX(-Math.PI / 2);
|
|
7551
|
-
return new
|
|
7947
|
+
return new THREE19.Mesh(
|
|
7552
7948
|
geometry,
|
|
7553
|
-
new
|
|
7949
|
+
new THREE19.MeshBasicMaterial({
|
|
7554
7950
|
color: ACCENT,
|
|
7555
7951
|
transparent: true,
|
|
7556
7952
|
opacity: 0.9,
|
|
7557
|
-
side:
|
|
7953
|
+
side: THREE19.DoubleSide,
|
|
7558
7954
|
depthTest: false
|
|
7559
7955
|
})
|
|
7560
7956
|
);
|
|
7561
7957
|
}
|
|
7562
7958
|
createDot() {
|
|
7563
|
-
const geometry = new
|
|
7959
|
+
const geometry = new THREE19.CircleGeometry(MARKER_RADIUS * 0.16, 24);
|
|
7564
7960
|
geometry.rotateX(-Math.PI / 2);
|
|
7565
|
-
return new
|
|
7961
|
+
return new THREE19.Mesh(
|
|
7566
7962
|
geometry,
|
|
7567
|
-
new
|
|
7963
|
+
new THREE19.MeshBasicMaterial({
|
|
7568
7964
|
color: ACCENT,
|
|
7569
7965
|
transparent: true,
|
|
7570
7966
|
opacity: 0.55,
|
|
7571
|
-
side:
|
|
7967
|
+
side: THREE19.DoubleSide,
|
|
7572
7968
|
depthTest: false
|
|
7573
7969
|
})
|
|
7574
7970
|
);
|
|
@@ -7670,7 +8066,7 @@ function boneDirections(joints, finger) {
|
|
|
7670
8066
|
const from = joints[chain[i - 1]];
|
|
7671
8067
|
const to = joints[chain[i]];
|
|
7672
8068
|
if (!from || !to) return null;
|
|
7673
|
-
const direction = new
|
|
8069
|
+
const direction = new THREE19.Vector3().subVectors(to, from);
|
|
7674
8070
|
if (direction.lengthSq() < 1e-12) return null;
|
|
7675
8071
|
directions.push(direction.normalize());
|
|
7676
8072
|
}
|
|
@@ -7743,8 +8139,8 @@ function computeSpread(joints, a, b) {
|
|
|
7743
8139
|
const bBase = joints[METACARPAL_JOINTS[b]];
|
|
7744
8140
|
const bTip = joints[TIP_JOINTS[b]];
|
|
7745
8141
|
if (!aBase || !aTip || !bBase || !bTip) return null;
|
|
7746
|
-
const dirA = new
|
|
7747
|
-
const dirB = new
|
|
8142
|
+
const dirA = new THREE19.Vector3().subVectors(aTip, aBase);
|
|
8143
|
+
const dirB = new THREE19.Vector3().subVectors(bTip, bBase);
|
|
7748
8144
|
if (dirA.lengthSq() < 1e-12 || dirB.lengthSq() < 1e-12) return null;
|
|
7749
8145
|
return clamp01((1 - dirA.normalize().dot(dirB.normalize())) / 0.45);
|
|
7750
8146
|
}
|
|
@@ -7754,18 +8150,18 @@ function computePalmPose(joints, handedness) {
|
|
|
7754
8150
|
const indexBase = joints["index-finger-metacarpal"];
|
|
7755
8151
|
const pinkyBase = joints["pinky-finger-metacarpal"];
|
|
7756
8152
|
if (!wrist || !indexBase || !pinkyBase) return null;
|
|
7757
|
-
const u = new
|
|
7758
|
-
const v = new
|
|
7759
|
-
const normal = new
|
|
8153
|
+
const u = new THREE19.Vector3().subVectors(indexBase, wrist);
|
|
8154
|
+
const v = new THREE19.Vector3().subVectors(pinkyBase, wrist);
|
|
8155
|
+
const normal = new THREE19.Vector3().crossVectors(u, v);
|
|
7760
8156
|
if (normal.lengthSq() < 1e-12) return null;
|
|
7761
8157
|
normal.normalize();
|
|
7762
8158
|
if (handedness === "left") normal.multiplyScalar(-1);
|
|
7763
|
-
const right = new
|
|
8159
|
+
const right = new THREE19.Vector3().subVectors(indexBase, pinkyBase);
|
|
7764
8160
|
if (right.lengthSq() < 1e-12) return null;
|
|
7765
8161
|
right.normalize();
|
|
7766
8162
|
if (handedness === "left") right.multiplyScalar(-1);
|
|
7767
|
-
const up = new
|
|
7768
|
-
const center = new
|
|
8163
|
+
const up = new THREE19.Vector3().crossVectors(normal, right).normalize();
|
|
8164
|
+
const center = new THREE19.Vector3().add(wrist).add(indexBase).add(pinkyBase).divideScalar(3);
|
|
7769
8165
|
return {
|
|
7770
8166
|
center,
|
|
7771
8167
|
normal,
|
|
@@ -7796,7 +8192,7 @@ function computeHandShape(joints, handedness) {
|
|
|
7796
8192
|
const thumbTip = joints["thumb-tip"];
|
|
7797
8193
|
let thumbDirection = null;
|
|
7798
8194
|
if (thumbBase && thumbTip) {
|
|
7799
|
-
const direction = new
|
|
8195
|
+
const direction = new THREE19.Vector3().subVectors(thumbTip, thumbBase);
|
|
7800
8196
|
if (direction.lengthSq() > 1e-12) thumbDirection = direction.normalize();
|
|
7801
8197
|
}
|
|
7802
8198
|
return {
|
|
@@ -7828,12 +8224,12 @@ function scoreAgainst(actual, target, tolerance) {
|
|
|
7828
8224
|
}
|
|
7829
8225
|
__name(scoreAgainst, "scoreAgainst");
|
|
7830
8226
|
var WORLD_DIRECTIONS = {
|
|
7831
|
-
up: new
|
|
7832
|
-
down: new
|
|
7833
|
-
forward: new
|
|
7834
|
-
back: new
|
|
7835
|
-
left: new
|
|
7836
|
-
right: new
|
|
8227
|
+
up: new THREE19.Vector3(0, 1, 0),
|
|
8228
|
+
down: new THREE19.Vector3(0, -1, 0),
|
|
8229
|
+
forward: new THREE19.Vector3(0, 0, -1),
|
|
8230
|
+
back: new THREE19.Vector3(0, 0, 1),
|
|
8231
|
+
left: new THREE19.Vector3(-1, 0, 0),
|
|
8232
|
+
right: new THREE19.Vector3(1, 0, 0)
|
|
7837
8233
|
};
|
|
7838
8234
|
function axisVector(shape, axis) {
|
|
7839
8235
|
if (axis === "thumb") return shape.thumbDirection;
|
|
@@ -7848,7 +8244,7 @@ function resolveDirection(direction, shape, context) {
|
|
|
7848
8244
|
const head = context?.headPosition;
|
|
7849
8245
|
const origin = shape.palm?.center;
|
|
7850
8246
|
if (!head || !origin) return null;
|
|
7851
|
-
const toHead = new
|
|
8247
|
+
const toHead = new THREE19.Vector3().subVectors(head, origin);
|
|
7852
8248
|
if (toHead.lengthSq() < 1e-12) return null;
|
|
7853
8249
|
toHead.normalize();
|
|
7854
8250
|
return direction === "toward-head" ? toHead : toHead.multiplyScalar(-1);
|
|
@@ -7898,8 +8294,8 @@ function matchHandPose(shape, definition, context) {
|
|
|
7898
8294
|
if (!handAxis || !wanted) {
|
|
7899
8295
|
consider(0, "orientation");
|
|
7900
8296
|
} else {
|
|
7901
|
-
const angle =
|
|
7902
|
-
Math.acos(
|
|
8297
|
+
const angle = THREE19.MathUtils.radToDeg(
|
|
8298
|
+
Math.acos(THREE19.MathUtils.clamp(handAxis.dot(wanted), -1, 1))
|
|
7903
8299
|
);
|
|
7904
8300
|
const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
|
|
7905
8301
|
consider(clamp01(1 - normalizedError / MATCH_FALLOFF), "orientation");
|
|
@@ -7977,7 +8373,7 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
7977
8373
|
this.trackers = /* @__PURE__ */ new Map();
|
|
7978
8374
|
this.shapes = /* @__PURE__ */ new Map();
|
|
7979
8375
|
/** Reused so head-relative orientation checks allocate nothing per frame. */
|
|
7980
|
-
this.headPosition = new
|
|
8376
|
+
this.headPosition = new THREE19.Vector3();
|
|
7981
8377
|
this.elapsed = 0;
|
|
7982
8378
|
this.inputSystem = inputSystem;
|
|
7983
8379
|
}
|
|
@@ -8099,6 +8495,6 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
8099
8495
|
__name(_XRHandPoseSystem, "XRHandPoseSystem");
|
|
8100
8496
|
var XRHandPoseSystem = _XRHandPoseSystem;
|
|
8101
8497
|
|
|
8102
|
-
export { ADDED_NODE_MARKER_COMPONENT, ARC_GRAVITY, ARC_MAX_TIME, ARC_SPEED, ARC_STEPS, AnimationSystem, AudioSystem, Behaviour, CURLED_COS, CameraSyncSystem, DEFAULT_ENTER_CONFIDENCE, DEFAULT_EXIT_CONFIDENCE, DEFAULT_LOST_GRACE_SECONDS, DEFAULT_MIN_HOLD_SECONDS, EnvironmentSyncSystem, FALLBACK_HAND_SCALE, HYDRATABLE_ENTITY_KINDS, HandPoseTracker, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MATCH_FALLOFF, MAX_SAMPLE_AGE_SECONDS, MaterialSyncSystem, MeshGeometrySystem, NODE_KEY_SEPARATOR, NO_XR_CAPABILITIES, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, ObjectVisibilitySystem, PINCH_FINGERS, PREFAB_FILE_VERSION, PREFAB_FILE_VERSION_NESTED, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, STRAIGHT_COS, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, ThrowVelocityTracker, TransformSyncSystem, VELOCITY_SAMPLES, VRTeleportAreaSystem, VideoSystem, XRControllerVisualSystem, XRHandPoseSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, XRTeleportVisualSystem, XR_FINGERS, angularVelocityFrom, applyHandMaterial, arcGroundCrossing, buildComponentValueMaps, buildNodeKeyMapsFromSnapshot, buildNodeMapsFromSnapshot, canonicalizeComponentValue, clearPrefabCache, collectDiffPaths, collectEntitySubtree, collectSnapshotSubtreeIds, computeFingerCurl, computeHandShape, computeInstanceOverrides, computePalmPose, computePalmWidth, computePinch, computeSpread, createHandMaterial, decanonicalizeComponentValue, despawnPrefab, encodeOverride, estimateHandScale, findSnapshotRootEntityIds, findTopLevelNestedRegions, groupOverridePaths, hydrateWorldFromSnapshot, hydrateWorldFromSnapshotDetailed, indexSnapshotByEntity, instantiateSubtree, loadPrefab, matchHandPose, mergeComponentValue, parseOverride, parsePrefabAsset, prefabFileVersionFor, readXrCapabilities, restoreComponentState, restorePostCreateComponents, sampleTeleportArc, setPrefabAssetUrlResolver, spawnPrefab };
|
|
8103
|
-
//# sourceMappingURL=chunk-
|
|
8104
|
-
//# sourceMappingURL=chunk-
|
|
8498
|
+
export { ADDED_NODE_MARKER_COMPONENT, ARC_GRAVITY, ARC_MAX_TIME, ARC_SPEED, ARC_STEPS, AnimationSystem, AudioSystem, Behaviour, CURLED_COS, CameraSyncSystem, DEFAULT_ENTER_CONFIDENCE, DEFAULT_EXIT_CONFIDENCE, DEFAULT_LOST_GRACE_SECONDS, DEFAULT_MIN_HOLD_SECONDS, EnvironmentSyncSystem, FALLBACK_HAND_SCALE, HYDRATABLE_ENTITY_KINDS, HandPoseTracker, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MATCH_FALLOFF, MAX_PLAUSIBLE_SPEED, MAX_SAMPLE_AGE_SECONDS, MaterialSyncSystem, MeshGeometrySystem, NODE_KEY_SEPARATOR, NO_XR_CAPABILITIES, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, ObjectVisibilitySystem, PINCH_FINGERS, PREFAB_FILE_VERSION, PREFAB_FILE_VERSION_NESTED, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, STRAIGHT_COS, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, ThrowVelocityTracker, TransformSyncSystem, VELOCITY_SAMPLES, VRTeleportAreaSystem, VideoSystem, XRControllerVisualSystem, XRHandPoseSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, XRTeleportVisualSystem, XR_FINGERS, angularVelocityFrom, applyHandMaterial, arcGroundCrossing, buildComponentValueMaps, buildNodeKeyMapsFromSnapshot, buildNodeMapsFromSnapshot, canonicalizeComponentValue, clearPrefabCache, collectDiffPaths, collectEntitySubtree, collectSnapshotSubtreeIds, computeFingerCurl, computeHandShape, computeInstanceOverrides, computePalmPose, computePalmWidth, computePinch, computeSpread, createHandMaterial, decanonicalizeComponentValue, despawnPrefab, encodeOverride, estimateHandScale, findSnapshotRootEntityIds, findTopLevelNestedRegions, groupOverridePaths, hydrateWorldFromSnapshot, hydrateWorldFromSnapshotDetailed, indexSnapshotByEntity, instantiateSubtree, loadPrefab, matchHandPose, mergeComponentValue, parseOverride, parsePrefabAsset, prefabFileVersionFor, readXrCapabilities, restoreComponentState, restorePostCreateComponents, sampleTeleportArc, setPrefabAssetUrlResolver, spawnPrefab };
|
|
8499
|
+
//# sourceMappingURL=chunk-O2HSIZFC.js.map
|
|
8500
|
+
//# sourceMappingURL=chunk-O2HSIZFC.js.map
|