@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.
Files changed (38) hide show
  1. package/dist/{XRHandPose-CxPz8VBp.d.ts → XRHandPose-CjacJ_16.d.ts} +70 -1
  2. package/dist/{XRHandPose-VuSbe4iz.d.cts → XRHandPose-hAtj9wm-.d.cts} +70 -1
  3. package/dist/{chunk-KIKIWCEB.js → chunk-5UVBEAGW.js} +4 -4
  4. package/dist/{chunk-KIKIWCEB.js.map → chunk-5UVBEAGW.js.map} +1 -1
  5. package/dist/{chunk-KVGGAL5V.js → chunk-ELSZ5U3F.js} +23 -3
  6. package/dist/chunk-ELSZ5U3F.js.map +1 -0
  7. package/dist/{chunk-L5BP727H.js → chunk-NJOO7NO6.js} +3 -3
  8. package/dist/{chunk-L5BP727H.js.map → chunk-NJOO7NO6.js.map} +1 -1
  9. package/dist/{chunk-LMTB4KQ4.js → chunk-O2HSIZFC.js} +591 -195
  10. package/dist/chunk-O2HSIZFC.js.map +1 -0
  11. package/dist/components/index.cjs +20 -0
  12. package/dist/components/index.cjs.map +1 -1
  13. package/dist/components/index.d.cts +2 -2
  14. package/dist/components/index.d.ts +2 -2
  15. package/dist/components/index.js +1 -1
  16. package/dist/docs/guide/vr-and-hand-poses.md +48 -0
  17. package/dist/factories/index.cjs +19 -0
  18. package/dist/factories/index.cjs.map +1 -1
  19. package/dist/factories/index.d.cts +1 -1
  20. package/dist/factories/index.d.ts +1 -1
  21. package/dist/factories/index.js +3 -3
  22. package/dist/{index-C7XQyrgE.d.ts → index-B-KhN8Ox.d.ts} +51 -0
  23. package/dist/{index-BxdXgqiI.d.ts → index-B7JDsx4a.d.ts} +9 -2
  24. package/dist/{index-BIQoaKAA.d.cts → index-B9JqYr3Q.d.cts} +9 -2
  25. package/dist/{index-DyN50JZo.d.cts → index-DU-CF-3m.d.cts} +51 -0
  26. package/dist/index.cjs +729 -312
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +29 -6
  29. package/dist/index.d.ts +29 -6
  30. package/dist/index.js +8 -8
  31. package/dist/systems/index.cjs +635 -220
  32. package/dist/systems/index.cjs.map +1 -1
  33. package/dist/systems/index.d.cts +1 -1
  34. package/dist/systems/index.d.ts +1 -1
  35. package/dist/systems/index.js +3 -3
  36. package/package.json +1 -1
  37. package/dist/chunk-KVGGAL5V.js.map +0 -1
  38. package/dist/chunk-LMTB4KQ4.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var THREE39 = require('three');
3
+ var THREE51 = require('three');
4
4
  var SkeletonUtils_js = require('three/examples/jsm/utils/SkeletonUtils.js');
5
5
  var RectAreaLightHelper_js = require('three/examples/jsm/helpers/RectAreaLightHelper.js');
6
6
  var DRACOLoader_js = require('three/examples/jsm/loaders/DRACOLoader.js');
@@ -41,7 +41,7 @@ function _interopNamespace(e) {
41
41
  return Object.freeze(n);
42
42
  }
43
43
 
44
- var THREE39__namespace = /*#__PURE__*/_interopNamespace(THREE39);
44
+ var THREE51__namespace = /*#__PURE__*/_interopNamespace(THREE51);
45
45
 
46
46
  var __defProp = Object.defineProperty;
47
47
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -605,14 +605,14 @@ var _AnimationComponent = class _AnimationComponent extends Component {
605
605
  return;
606
606
  }
607
607
  this.importedClips = clips.map((entry) => {
608
- if (entry instanceof THREE39__namespace.AnimationClip) {
608
+ if (entry instanceof THREE51__namespace.AnimationClip) {
609
609
  return { clip: entry, sourceUrl: null };
610
610
  }
611
611
  if (!entry || typeof entry !== "object") {
612
612
  return null;
613
613
  }
614
614
  const candidate = entry;
615
- if (!(candidate.clip instanceof THREE39__namespace.AnimationClip)) {
615
+ if (!(candidate.clip instanceof THREE51__namespace.AnimationClip)) {
616
616
  return null;
617
617
  }
618
618
  return {
@@ -820,11 +820,11 @@ function normalizeDistanceModel(distanceModel) {
820
820
  }
821
821
  __name(normalizeDistanceModel, "normalizeDistanceModel");
822
822
  function createConfiguredAudio(listener, options) {
823
- const sound = options.positional ? new THREE39__namespace.PositionalAudio(listener) : new THREE39__namespace.Audio(listener);
823
+ const sound = options.positional ? new THREE51__namespace.PositionalAudio(listener) : new THREE51__namespace.Audio(listener);
824
824
  sound.setLoop(options.loop);
825
825
  sound.setVolume(options.volume);
826
826
  sound.setPlaybackRate(options.pitch);
827
- if (sound instanceof THREE39__namespace.PositionalAudio) {
827
+ if (sound instanceof THREE51__namespace.PositionalAudio) {
828
828
  sound.setRefDistance(options.refDistance);
829
829
  sound.setDistanceModel(normalizeDistanceModel(options.distanceModel));
830
830
  sound.setRolloffFactor(options.rolloffFactor);
@@ -834,16 +834,16 @@ function createConfiguredAudio(listener, options) {
834
834
  __name(createConfiguredAudio, "createConfiguredAudio");
835
835
  function createAudioEditorHelper() {
836
836
  if (typeof document === "undefined") {
837
- const geometry = new THREE39__namespace.EdgesGeometry(
838
- new THREE39__namespace.OctahedronGeometry(0.22, 0)
837
+ const geometry = new THREE51__namespace.EdgesGeometry(
838
+ new THREE51__namespace.OctahedronGeometry(0.22, 0)
839
839
  );
840
- const material2 = new THREE39__namespace.LineBasicMaterial({
840
+ const material2 = new THREE51__namespace.LineBasicMaterial({
841
841
  color: "#8bc8ff",
842
842
  transparent: true,
843
843
  opacity: 0.95,
844
844
  depthTest: false
845
845
  });
846
- const fallback = new THREE39__namespace.LineSegments(geometry, material2);
846
+ const fallback = new THREE51__namespace.LineSegments(geometry, material2);
847
847
  fallback.renderOrder = 10;
848
848
  fallback.userData.ecsHelper = true;
849
849
  fallback.visible = false;
@@ -855,7 +855,7 @@ function createAudioEditorHelper() {
855
855
  canvas.height = size;
856
856
  const ctx = canvas.getContext("2d");
857
857
  if (!ctx) {
858
- return new THREE39__namespace.Object3D();
858
+ return new THREE51__namespace.Object3D();
859
859
  }
860
860
  ctx.clearRect(0, 0, size, size);
861
861
  ctx.fillStyle = "rgba(27, 35, 52, 0.9)";
@@ -886,14 +886,14 @@ function createAudioEditorHelper() {
886
886
  ctx.beginPath();
887
887
  ctx.arc(56, 48, 16, -0.8, 0.8);
888
888
  ctx.stroke();
889
- const texture = new THREE39__namespace.CanvasTexture(canvas);
889
+ const texture = new THREE51__namespace.CanvasTexture(canvas);
890
890
  texture.needsUpdate = true;
891
- const material = new THREE39__namespace.SpriteMaterial({
891
+ const material = new THREE51__namespace.SpriteMaterial({
892
892
  map: texture,
893
893
  transparent: true,
894
894
  depthTest: false
895
895
  });
896
- const helper = new THREE39__namespace.Sprite(material);
896
+ const helper = new THREE51__namespace.Sprite(material);
897
897
  helper.scale.set(0.68, 0.68, 0.68);
898
898
  helper.renderOrder = 10;
899
899
  helper.userData.ecsHelper = true;
@@ -927,7 +927,7 @@ var DEFAULT_ORTHO_TOP = 5;
927
927
  var DEFAULT_ORTHO_BOTTOM = -5;
928
928
  var DEFAULT_ZOOM = 1;
929
929
  function inferProjection(camera) {
930
- if (camera instanceof THREE39__namespace.OrthographicCamera) {
930
+ if (camera instanceof THREE51__namespace.OrthographicCamera) {
931
931
  return "orthographic";
932
932
  }
933
933
  return "perspective";
@@ -948,7 +948,7 @@ function readCameraFar(camera) {
948
948
  }
949
949
  __name(readCameraFar, "readCameraFar");
950
950
  function inferFov(camera) {
951
- if (camera instanceof THREE39__namespace.PerspectiveCamera && Number.isFinite(camera.fov)) {
951
+ if (camera instanceof THREE51__namespace.PerspectiveCamera && Number.isFinite(camera.fov)) {
952
952
  return camera.fov;
953
953
  }
954
954
  return DEFAULT_FOV;
@@ -971,28 +971,28 @@ function inferFar(camera) {
971
971
  }
972
972
  __name(inferFar, "inferFar");
973
973
  function inferOrthoLeft(camera) {
974
- if (camera instanceof THREE39__namespace.OrthographicCamera && Number.isFinite(camera.left)) {
974
+ if (camera instanceof THREE51__namespace.OrthographicCamera && Number.isFinite(camera.left)) {
975
975
  return camera.left;
976
976
  }
977
977
  return DEFAULT_ORTHO_LEFT;
978
978
  }
979
979
  __name(inferOrthoLeft, "inferOrthoLeft");
980
980
  function inferOrthoRight(camera) {
981
- if (camera instanceof THREE39__namespace.OrthographicCamera && Number.isFinite(camera.right)) {
981
+ if (camera instanceof THREE51__namespace.OrthographicCamera && Number.isFinite(camera.right)) {
982
982
  return camera.right;
983
983
  }
984
984
  return DEFAULT_ORTHO_RIGHT;
985
985
  }
986
986
  __name(inferOrthoRight, "inferOrthoRight");
987
987
  function inferOrthoTop(camera) {
988
- if (camera instanceof THREE39__namespace.OrthographicCamera && Number.isFinite(camera.top)) {
988
+ if (camera instanceof THREE51__namespace.OrthographicCamera && Number.isFinite(camera.top)) {
989
989
  return camera.top;
990
990
  }
991
991
  return DEFAULT_ORTHO_TOP;
992
992
  }
993
993
  __name(inferOrthoTop, "inferOrthoTop");
994
994
  function inferOrthoBottom(camera) {
995
- if (camera instanceof THREE39__namespace.OrthographicCamera && Number.isFinite(camera.bottom)) {
995
+ if (camera instanceof THREE51__namespace.OrthographicCamera && Number.isFinite(camera.bottom)) {
996
996
  return camera.bottom;
997
997
  }
998
998
  return DEFAULT_ORTHO_BOTTOM;
@@ -1008,7 +1008,7 @@ __name(inferZoom, "inferZoom");
1008
1008
  var _CameraComponent = class _CameraComponent extends Component {
1009
1009
  constructor(payload = {}) {
1010
1010
  super();
1011
- this.camera = payload.camera ?? new THREE39__namespace.PerspectiveCamera();
1011
+ this.camera = payload.camera ?? new THREE51__namespace.PerspectiveCamera();
1012
1012
  this.type = payload.type ?? "3d";
1013
1013
  this.isDefault = typeof payload.isDefault === "boolean" ? payload.isDefault : false;
1014
1014
  this.projection = payload.projection ?? inferProjection(payload.camera);
@@ -1039,7 +1039,7 @@ var Object3DRef = _Object3DRef;
1039
1039
  // core/factories/components/CameraFactory.ts
1040
1040
  function createCameraComponent(world, entityId, payload = {}) {
1041
1041
  const object = world.getComponent(entityId, Object3DRef)?.object;
1042
- const objectCamera = object instanceof THREE39__namespace.Camera ? object : void 0;
1042
+ const objectCamera = object instanceof THREE51__namespace.Camera ? object : void 0;
1043
1043
  const component = new CameraComponent({
1044
1044
  ...payload,
1045
1045
  camera: payload.camera ?? objectCamera
@@ -1609,15 +1609,15 @@ function createValueState(light) {
1609
1609
  castShadow: light.castShadow ?? false,
1610
1610
  frustumCulling: light.frustumCulled
1611
1611
  };
1612
- if (light instanceof THREE39__namespace.PointLight) {
1612
+ if (light instanceof THREE51__namespace.PointLight) {
1613
1613
  base.distance = light.distance;
1614
1614
  base.decay = light.decay;
1615
- } else if (light instanceof THREE39__namespace.SpotLight) {
1615
+ } else if (light instanceof THREE51__namespace.SpotLight) {
1616
1616
  base.distance = light.distance;
1617
1617
  base.decay = light.decay;
1618
1618
  base.angle = light.angle;
1619
1619
  base.penumbra = light.penumbra;
1620
- } else if (light instanceof THREE39__namespace.RectAreaLight) {
1620
+ } else if (light instanceof THREE51__namespace.RectAreaLight) {
1621
1621
  base.width = light.width;
1622
1622
  base.height = light.height;
1623
1623
  }
@@ -1660,13 +1660,13 @@ function toHexColor2(value, fallback) {
1660
1660
  }
1661
1661
  __name(toHexColor2, "toHexColor");
1662
1662
  function getMaterialType(material) {
1663
- if (material instanceof THREE39__namespace.MeshPhysicalMaterial) {
1663
+ if (material instanceof THREE51__namespace.MeshPhysicalMaterial) {
1664
1664
  return "physical";
1665
1665
  }
1666
- if (material instanceof THREE39__namespace.MeshPhongMaterial) {
1666
+ if (material instanceof THREE51__namespace.MeshPhongMaterial) {
1667
1667
  return "phong";
1668
1668
  }
1669
- if (material instanceof THREE39__namespace.MeshBasicMaterial) {
1669
+ if (material instanceof THREE51__namespace.MeshBasicMaterial) {
1670
1670
  return "basic";
1671
1671
  }
1672
1672
  return "standard";
@@ -1701,8 +1701,8 @@ function createMaterialValue(material) {
1701
1701
  opacity: typeof materialRecord.opacity === "number" ? materialRecord.opacity : 1,
1702
1702
  emissive: toHexColor2(materialRecord.emissive, "#000000"),
1703
1703
  emissiveIntensity: typeof materialRecord.emissiveIntensity === "number" ? materialRecord.emissiveIntensity : 0,
1704
- side: typeof materialRecord.side === "number" ? materialRecord.side : THREE39__namespace.FrontSide,
1705
- blending: typeof materialRecord.blending === "number" ? materialRecord.blending : THREE39__namespace.NormalBlending,
1704
+ side: typeof materialRecord.side === "number" ? materialRecord.side : THREE51__namespace.FrontSide,
1705
+ blending: typeof materialRecord.blending === "number" ? materialRecord.blending : THREE51__namespace.NormalBlending,
1706
1706
  depthTest: materialRecord.depthTest !== false,
1707
1707
  depthWrite: materialRecord.depthWrite !== false,
1708
1708
  wireframe: Boolean(materialRecord.wireframe),
@@ -1734,7 +1734,7 @@ function createMaterialValue(material) {
1734
1734
  materialRecord.lightMap
1735
1735
  ),
1736
1736
  envMap: textureImageSrc(materialRecord.envMap),
1737
- textureFiltering: map?.magFilter === THREE39__namespace.NearestFilter ? "sharp" : "smooth",
1737
+ textureFiltering: map?.magFilter === THREE51__namespace.NearestFilter ? "sharp" : "smooth",
1738
1738
  useMipmaps: map?.generateMipmaps !== false
1739
1739
  };
1740
1740
  }
@@ -1749,8 +1749,8 @@ function defaultMaterialValue() {
1749
1749
  opacity: 1,
1750
1750
  emissive: "#000000",
1751
1751
  emissiveIntensity: 0,
1752
- side: THREE39__namespace.FrontSide,
1753
- blending: THREE39__namespace.NormalBlending,
1752
+ side: THREE51__namespace.FrontSide,
1753
+ blending: THREE51__namespace.NormalBlending,
1754
1754
  depthTest: true,
1755
1755
  depthWrite: true,
1756
1756
  wireframe: false,
@@ -2327,14 +2327,14 @@ var _TransformComponent = class _TransformComponent extends Component {
2327
2327
  z: scale.z ?? 1
2328
2328
  };
2329
2329
  }
2330
- toPositionVector3(target = new THREE39.Vector3()) {
2330
+ toPositionVector3(target = new THREE51.Vector3()) {
2331
2331
  return target.set(this.position.x, this.position.y, this.position.z);
2332
2332
  }
2333
- toRotationEuler(target = new THREE39.Euler(), order = "XYZ") {
2333
+ toRotationEuler(target = new THREE51.Euler(), order = "XYZ") {
2334
2334
  return target.set(this.rotation.x, this.rotation.y, this.rotation.z, order);
2335
2335
  }
2336
- toRotationQuaternion(target = new THREE39.Quaternion(), order = "XYZ") {
2337
- const euler = new THREE39.Euler(
2336
+ toRotationQuaternion(target = new THREE51.Quaternion(), order = "XYZ") {
2337
+ const euler = new THREE51.Euler(
2338
2338
  this.rotation.x,
2339
2339
  this.rotation.y,
2340
2340
  this.rotation.z,
@@ -2342,7 +2342,7 @@ var _TransformComponent = class _TransformComponent extends Component {
2342
2342
  );
2343
2343
  return target.setFromEuler(euler);
2344
2344
  }
2345
- toScaleVector3(target = new THREE39.Vector3()) {
2345
+ toScaleVector3(target = new THREE51.Vector3()) {
2346
2346
  return target.set(this.scale.x, this.scale.y, this.scale.z);
2347
2347
  }
2348
2348
  setPosition(input) {
@@ -2360,8 +2360,8 @@ var _TransformComponent = class _TransformComponent extends Component {
2360
2360
  return this;
2361
2361
  }
2362
2362
  setRotation(input, order = "XYZ") {
2363
- if (input instanceof THREE39.Quaternion) {
2364
- const euler = new THREE39.Euler().setFromQuaternion(input, order);
2363
+ if (input instanceof THREE51.Quaternion) {
2364
+ const euler = new THREE51.Euler().setFromQuaternion(input, order);
2365
2365
  this.rotation.x = euler.x;
2366
2366
  this.rotation.y = euler.y;
2367
2367
  this.rotation.z = euler.z;
@@ -2845,6 +2845,14 @@ var _XRInteractableComponent = class _XRInteractableComponent extends Component
2845
2845
  y: 0,
2846
2846
  z: 0
2847
2847
  };
2848
+ this.grabHands = options?.grabHands ?? "handOff";
2849
+ this.twoHandRotation = options?.twoHandRotation ?? "align";
2850
+ this.allowTwoHandScale = options?.allowTwoHandScale ?? false;
2851
+ this.minScale = options?.minScale ?? 0.25;
2852
+ this.maxScale = options?.maxScale ?? 4;
2853
+ this.attachPoints = (options?.attachPoints ?? []).map(
2854
+ (point) => createAttachPoint(point)
2855
+ );
2848
2856
  this.throwOnRelease = options?.throwOnRelease ?? true;
2849
2857
  this.throwStrength = options?.throwStrength ?? 1;
2850
2858
  this.highlightOnHover = options?.highlightOnHover ?? true;
@@ -2852,6 +2860,17 @@ var _XRInteractableComponent = class _XRInteractableComponent extends Component
2852
2860
  };
2853
2861
  __name(_XRInteractableComponent, "XRInteractableComponent");
2854
2862
  var XRInteractableComponent = _XRInteractableComponent;
2863
+ function createAttachPoint(partial) {
2864
+ return {
2865
+ id: partial.id,
2866
+ name: partial.name ?? partial.id,
2867
+ position: { x: 0, y: 0, z: 0, ...partial.position },
2868
+ rotation: { x: 0, y: 0, z: 0, ...partial.rotation },
2869
+ hand: partial.hand ?? "any",
2870
+ role: partial.role ?? "any"
2871
+ };
2872
+ }
2873
+ __name(createAttachPoint, "createAttachPoint");
2855
2874
 
2856
2875
  // core/factories/components/XRInteractableFactory.ts
2857
2876
  function createXRInteractableComponent(world, entityId, ...args) {
@@ -2958,7 +2977,7 @@ var SHARED_MODEL_RESOURCE_FLAG = "spatialEcsSharedModelResource";
2958
2977
  var modelCache = /* @__PURE__ */ new Map();
2959
2978
  function markSharedResources(root) {
2960
2979
  root.traverse((child) => {
2961
- if (!(child instanceof THREE39__namespace.Mesh)) {
2980
+ if (!(child instanceof THREE51__namespace.Mesh)) {
2962
2981
  return;
2963
2982
  }
2964
2983
  if (child.geometry) {
@@ -3037,10 +3056,10 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
3037
3056
  }
3038
3057
  getOrCreateAudioListener() {
3039
3058
  const existing = this.camera.userData.ecsAudioListener;
3040
- if (existing instanceof THREE39__namespace.AudioListener) {
3059
+ if (existing instanceof THREE51__namespace.AudioListener) {
3041
3060
  return existing;
3042
3061
  }
3043
- const listener = new THREE39__namespace.AudioListener();
3062
+ const listener = new THREE51__namespace.AudioListener();
3044
3063
  this.camera.add(listener);
3045
3064
  this.camera.userData.ecsAudioListener = listener;
3046
3065
  return listener;
@@ -3114,7 +3133,7 @@ var _ObjectManagementSystem = class _ObjectManagementSystem {
3114
3133
  }
3115
3134
  if (dispose && object3d) {
3116
3135
  object3d.traverse((child) => {
3117
- if (child instanceof THREE39__namespace.Mesh) {
3136
+ if (child instanceof THREE51__namespace.Mesh) {
3118
3137
  if (!child.geometry?.userData?.[SHARED_MODEL_RESOURCE_FLAG]) {
3119
3138
  child.geometry?.dispose();
3120
3139
  }
@@ -3251,10 +3270,10 @@ __name(createBaseEntity, "createBaseEntity");
3251
3270
  // core/factories/objects/AudioFactory.ts
3252
3271
  function getOrCreateListener(camera) {
3253
3272
  const existing = camera.userData.ecsAudioListener;
3254
- if (existing instanceof THREE39__namespace.AudioListener) {
3273
+ if (existing instanceof THREE51__namespace.AudioListener) {
3255
3274
  return existing;
3256
3275
  }
3257
- const listener = new THREE39__namespace.AudioListener();
3276
+ const listener = new THREE51__namespace.AudioListener();
3258
3277
  camera.add(listener);
3259
3278
  camera.userData.ecsAudioListener = listener;
3260
3279
  return listener;
@@ -3267,7 +3286,7 @@ function createAudio({
3267
3286
  payload,
3268
3287
  isEditor
3269
3288
  }) {
3270
- const anchor = new THREE39__namespace.Object3D();
3289
+ const anchor = new THREE51__namespace.Object3D();
3271
3290
  const entityId = createBaseEntity(world, anchor, {
3272
3291
  label: payload.name ?? "Audio",
3273
3292
  entityType: "audio",
@@ -3289,7 +3308,7 @@ function createAudio({
3289
3308
  return entityId;
3290
3309
  }
3291
3310
  if (!isEditor) {
3292
- const loader = new THREE39__namespace.AudioLoader();
3311
+ const loader = new THREE51__namespace.AudioLoader();
3293
3312
  loader.load(
3294
3313
  audio.path,
3295
3314
  (buffer) => {
@@ -3364,7 +3383,7 @@ function applyCameraSettings(camera, options) {
3364
3383
  const near = typeof options.near === "number" ? options.near : DEFAULT_NEAR2;
3365
3384
  const far = typeof options.far === "number" ? options.far : DEFAULT_FAR2;
3366
3385
  const projection = options.projection;
3367
- if (camera instanceof THREE39__namespace.PerspectiveCamera) {
3386
+ if (camera instanceof THREE51__namespace.PerspectiveCamera) {
3368
3387
  if (!projection || projection === "perspective") {
3369
3388
  camera.fov = typeof options.fov === "number" ? options.fov : DEFAULT_FOV2;
3370
3389
  }
@@ -3374,7 +3393,7 @@ function applyCameraSettings(camera, options) {
3374
3393
  camera.updateProjectionMatrix();
3375
3394
  return;
3376
3395
  }
3377
- if (camera instanceof THREE39__namespace.OrthographicCamera) {
3396
+ if (camera instanceof THREE51__namespace.OrthographicCamera) {
3378
3397
  camera.left = typeof options.left === "number" ? options.left : -DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
3379
3398
  camera.right = typeof options.right === "number" ? options.right : DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
3380
3399
  camera.top = typeof options.top === "number" ? options.top : DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
@@ -3395,7 +3414,7 @@ function createCameraObject(options) {
3395
3414
  const bottom = options.bottom ?? -DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
3396
3415
  const left = options.left ?? -DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
3397
3416
  const right = options.right ?? DEFAULT_ORTHOGRAPHIC_HALF_HEIGHT;
3398
- const camera = new THREE39__namespace.OrthographicCamera(
3417
+ const camera = new THREE51__namespace.OrthographicCamera(
3399
3418
  left,
3400
3419
  right,
3401
3420
  top,
@@ -3407,7 +3426,7 @@ function createCameraObject(options) {
3407
3426
  camera.updateProjectionMatrix();
3408
3427
  return camera;
3409
3428
  }
3410
- return new THREE39__namespace.PerspectiveCamera(
3429
+ return new THREE51__namespace.PerspectiveCamera(
3411
3430
  options.fov ?? DEFAULT_FOV2,
3412
3431
  readViewportAspect(),
3413
3432
  near,
@@ -3425,7 +3444,7 @@ function createCamera({ world, scene, camera, payload, isEditor }) {
3425
3444
  transformInput: payload.transform
3426
3445
  });
3427
3446
  const objectRef = world.getComponent(entityId, Object3DRef);
3428
- if (objectRef?.object instanceof THREE39__namespace.Camera) {
3447
+ if (objectRef?.object instanceof THREE51__namespace.Camera) {
3429
3448
  objectRef.object.userData.entityId = entityId;
3430
3449
  }
3431
3450
  const componentOptions = {
@@ -3457,9 +3476,9 @@ function createCapsule({
3457
3476
  scene,
3458
3477
  payload
3459
3478
  }) {
3460
- const geometry = new THREE39__namespace.CapsuleGeometry(0.5, 1, 4, 8);
3461
- const material = new THREE39__namespace.MeshStandardMaterial({ color: "#ffffff" });
3462
- const mesh = new THREE39__namespace.Mesh(geometry, material);
3479
+ const geometry = new THREE51__namespace.CapsuleGeometry(0.5, 1, 4, 8);
3480
+ const material = new THREE51__namespace.MeshStandardMaterial({ color: "#ffffff" });
3481
+ const mesh = new THREE51__namespace.Mesh(geometry, material);
3463
3482
  const entityId = createBaseEntity(world, mesh, {
3464
3483
  label: payload.name ?? "Capsule",
3465
3484
  entityType: "capsule",
@@ -3479,9 +3498,9 @@ function createCapsule({
3479
3498
  }
3480
3499
  __name(createCapsule, "createCapsule");
3481
3500
  function createCube({ world, scene, payload }) {
3482
- const geometry = new THREE39__namespace.BoxGeometry(1, 1, 1);
3483
- const material = new THREE39__namespace.MeshStandardMaterial({ color: "#ffffff" });
3484
- const mesh = new THREE39__namespace.Mesh(geometry, material);
3501
+ const geometry = new THREE51__namespace.BoxGeometry(1, 1, 1);
3502
+ const material = new THREE51__namespace.MeshStandardMaterial({ color: "#ffffff" });
3503
+ const mesh = new THREE51__namespace.Mesh(geometry, material);
3485
3504
  const entityId = createBaseEntity(world, mesh, {
3486
3505
  label: payload.name ?? "Cube",
3487
3506
  entityType: "cube",
@@ -3506,9 +3525,9 @@ function createCylinder({
3506
3525
  scene,
3507
3526
  payload
3508
3527
  }) {
3509
- const geometry = new THREE39__namespace.CylinderGeometry(0.5, 0.5, 1, 20);
3510
- const material = new THREE39__namespace.MeshStandardMaterial({ color: "#ffffff" });
3511
- const mesh = new THREE39__namespace.Mesh(geometry, material);
3528
+ const geometry = new THREE51__namespace.CylinderGeometry(0.5, 0.5, 1, 20);
3529
+ const material = new THREE51__namespace.MeshStandardMaterial({ color: "#ffffff" });
3530
+ const mesh = new THREE51__namespace.Mesh(geometry, material);
3512
3531
  const entityId = createBaseEntity(world, mesh, {
3513
3532
  label: payload.name ?? "Cylinder",
3514
3533
  entityType: "cylinder",
@@ -3528,7 +3547,7 @@ function createCylinder({
3528
3547
  }
3529
3548
  __name(createCylinder, "createCylinder");
3530
3549
  function createEmpty({ world, scene, payload, isEditor }) {
3531
- const object = new THREE39__namespace.Group();
3550
+ const object = new THREE51__namespace.Group();
3532
3551
  const entityId = createBaseEntity(world, object, {
3533
3552
  label: payload.name ?? "Empty",
3534
3553
  entityType: "empty",
@@ -3539,7 +3558,7 @@ function createEmpty({ world, scene, payload, isEditor }) {
3539
3558
  }
3540
3559
  __name(createEmpty, "createEmpty");
3541
3560
  function createImage({ world, scene, payload }) {
3542
- const anchor = new THREE39__namespace.Object3D();
3561
+ const anchor = new THREE51__namespace.Object3D();
3543
3562
  const imagePath = payload.path ?? "";
3544
3563
  const entityId = createBaseEntity(world, anchor, {
3545
3564
  label: payload.name ?? "Image",
@@ -3552,7 +3571,7 @@ function createImage({ world, scene, payload }) {
3552
3571
  if (!imagePath) {
3553
3572
  return entityId;
3554
3573
  }
3555
- const loader = new THREE39__namespace.TextureLoader();
3574
+ const loader = new THREE51__namespace.TextureLoader();
3556
3575
  loader.load(
3557
3576
  imagePath,
3558
3577
  (texture) => {
@@ -3560,13 +3579,13 @@ function createImage({ world, scene, payload }) {
3560
3579
  texture.dispose();
3561
3580
  return;
3562
3581
  }
3563
- const material = new THREE39__namespace.MeshBasicMaterial({
3582
+ const material = new THREE51__namespace.MeshBasicMaterial({
3564
3583
  map: texture,
3565
3584
  transparent: true,
3566
- side: THREE39__namespace.DoubleSide
3585
+ side: THREE51__namespace.DoubleSide
3567
3586
  });
3568
- const geometry = new THREE39__namespace.PlaneGeometry(1, 1);
3569
- const plane = new THREE39__namespace.Mesh(geometry, material);
3587
+ const geometry = new THREE51__namespace.PlaneGeometry(1, 1);
3588
+ const plane = new THREE51__namespace.Mesh(geometry, material);
3570
3589
  plane.userData.entityId = entityId;
3571
3590
  const textureImage = texture.image;
3572
3591
  const width = textureImage?.width ?? 1;
@@ -3612,7 +3631,7 @@ function createImageTarget({
3612
3631
  payload,
3613
3632
  isEditor
3614
3633
  }) {
3615
- const anchor = new THREE39__namespace.Object3D();
3634
+ const anchor = new THREE51__namespace.Object3D();
3616
3635
  const imagePath = payload.path ?? "";
3617
3636
  const entityId = createBaseEntity(world, anchor, {
3618
3637
  label: payload.name ?? "Image Target",
@@ -3629,7 +3648,7 @@ function createImageTarget({
3629
3648
  if (!isEditor || !imagePath) {
3630
3649
  return entityId;
3631
3650
  }
3632
- const loader = new THREE39__namespace.TextureLoader();
3651
+ const loader = new THREE51__namespace.TextureLoader();
3633
3652
  loader.load(
3634
3653
  imagePath,
3635
3654
  (texture) => {
@@ -3637,13 +3656,13 @@ function createImageTarget({
3637
3656
  texture.dispose();
3638
3657
  return;
3639
3658
  }
3640
- const material = new THREE39__namespace.MeshBasicMaterial({
3659
+ const material = new THREE51__namespace.MeshBasicMaterial({
3641
3660
  map: texture,
3642
3661
  transparent: true,
3643
- side: THREE39__namespace.DoubleSide
3662
+ side: THREE51__namespace.DoubleSide
3644
3663
  });
3645
- const geometry = new THREE39__namespace.PlaneGeometry(1, 1);
3646
- const plane = new THREE39__namespace.Mesh(geometry, material);
3664
+ const geometry = new THREE51__namespace.PlaneGeometry(1, 1);
3665
+ const plane = new THREE51__namespace.Mesh(geometry, material);
3647
3666
  plane.userData.entityId = entityId;
3648
3667
  const textureImage = texture.image;
3649
3668
  const width = textureImage?.width ?? 1;
@@ -3694,7 +3713,7 @@ function createInstancedMesh({
3694
3713
  scene,
3695
3714
  payload
3696
3715
  }) {
3697
- const anchor = new THREE39__namespace.Object3D();
3716
+ const anchor = new THREE51__namespace.Object3D();
3698
3717
  const opts = payload.options ?? {};
3699
3718
  const meshKind = isInstancedMeshKind(opts.meshKind) ? opts.meshKind : "cube";
3700
3719
  const meshParameters = opts.meshParameters && typeof opts.meshParameters === "object" ? opts.meshParameters : void 0;
@@ -3765,7 +3784,7 @@ function createAmbientLight({
3765
3784
  scene,
3766
3785
  payload
3767
3786
  }) {
3768
- const light = new THREE39__namespace.AmbientLight("#ffffff", 0.6);
3787
+ const light = new THREE51__namespace.AmbientLight("#ffffff", 0.6);
3769
3788
  const entityId = createBaseEntity(world, light, {
3770
3789
  label: payload.name ?? "Ambient Light",
3771
3790
  entityType: "ambientLight",
@@ -3782,7 +3801,7 @@ function createAreaLight({
3782
3801
  payload,
3783
3802
  isEditor
3784
3803
  }) {
3785
- const light = new THREE39__namespace.RectAreaLight("#ffffff", 5, 4, 4);
3804
+ const light = new THREE51__namespace.RectAreaLight("#ffffff", 5, 4, 4);
3786
3805
  light.lookAt(0, 0, 0);
3787
3806
  const entityId = createBaseEntity(world, light, {
3788
3807
  label: payload.name ?? "Area Light",
@@ -3811,7 +3830,7 @@ function createDirectionalLight({
3811
3830
  payload,
3812
3831
  isEditor
3813
3832
  }) {
3814
- const light = new THREE39__namespace.DirectionalLight("#ffffff", 1.5);
3833
+ const light = new THREE51__namespace.DirectionalLight("#ffffff", 1.5);
3815
3834
  light.castShadow = true;
3816
3835
  const entityId = createBaseEntity(world, light, {
3817
3836
  label: payload.name ?? "Directional Light",
@@ -3822,7 +3841,7 @@ function createDirectionalLight({
3822
3841
  });
3823
3842
  createLightComponent(world, entityId, light);
3824
3843
  if (isEditor) {
3825
- const helper = new THREE39__namespace.DirectionalLightHelper(light, 1.8, "#38bdf8");
3844
+ const helper = new THREE51__namespace.DirectionalLightHelper(light, 1.8, "#38bdf8");
3826
3845
  helper.onBeforeRender = () => {
3827
3846
  helper.update();
3828
3847
  };
@@ -3840,7 +3859,7 @@ function createPointLight({
3840
3859
  payload,
3841
3860
  isEditor
3842
3861
  }) {
3843
- const light = new THREE39__namespace.PointLight("#ffffff", 1, 10);
3862
+ const light = new THREE51__namespace.PointLight("#ffffff", 1, 10);
3844
3863
  const entityId = createBaseEntity(world, light, {
3845
3864
  label: payload.name ?? "Point Light",
3846
3865
  entityType: "pointLight",
@@ -3850,7 +3869,7 @@ function createPointLight({
3850
3869
  });
3851
3870
  createLightComponent(world, entityId, light);
3852
3871
  if (isEditor) {
3853
- const helper = new THREE39__namespace.PointLightHelper(light, 0.35, "#fbbf24");
3872
+ const helper = new THREE51__namespace.PointLightHelper(light, 0.35, "#fbbf24");
3854
3873
  helper.onBeforeRender = () => {
3855
3874
  helper.update();
3856
3875
  };
@@ -3868,7 +3887,7 @@ function createSpotLight({
3868
3887
  payload,
3869
3888
  isEditor
3870
3889
  }) {
3871
- const light = new THREE39__namespace.SpotLight("#ffffff", 1, 20, Math.PI / 6, 0.1, 1);
3890
+ const light = new THREE51__namespace.SpotLight("#ffffff", 1, 20, Math.PI / 6, 0.1, 1);
3872
3891
  const entityId = createBaseEntity(world, light, {
3873
3892
  label: payload.name ?? "Spot Light",
3874
3893
  entityType: "spotLight",
@@ -3878,7 +3897,7 @@ function createSpotLight({
3878
3897
  });
3879
3898
  createLightComponent(world, entityId, light);
3880
3899
  if (isEditor) {
3881
- const helper = new THREE39__namespace.SpotLightHelper(light, "#f59e0b");
3900
+ const helper = new THREE51__namespace.SpotLightHelper(light, "#f59e0b");
3882
3901
  helper.onBeforeRender = () => {
3883
3902
  helper.update();
3884
3903
  };
@@ -3969,6 +3988,7 @@ __export(components_exports, {
3969
3988
  XRInteractorComponent: () => XRInteractorComponent,
3970
3989
  XRInteractorSideComponent: () => XRInteractorSideComponent,
3971
3990
  XRRigComponent: () => XRRigComponent,
3991
+ createAttachPoint: () => createAttachPoint,
3972
3992
  createHandPoseEntry: () => createHandPoseEntry,
3973
3993
  defaultMaterialValue: () => defaultMaterialValue,
3974
3994
  handPoseDefinitionFor: () => handPoseDefinitionFor,
@@ -4029,7 +4049,7 @@ function createModel({
4029
4049
  payload,
4030
4050
  isEditor
4031
4051
  }) {
4032
- const anchor = new THREE39__namespace.Object3D();
4052
+ const anchor = new THREE51__namespace.Object3D();
4033
4053
  const modelPath = payload.path ?? "";
4034
4054
  const entityId = createBaseEntity(world, anchor, {
4035
4055
  label: payload.name ?? "Model",
@@ -4095,12 +4115,12 @@ function createModel({
4095
4115
  }
4096
4116
  __name(createModel, "createModel");
4097
4117
  function createPlane({ world, scene, payload }) {
4098
- const geometry = new THREE39__namespace.PlaneGeometry(100, 100);
4099
- const material = new THREE39__namespace.MeshStandardMaterial({
4118
+ const geometry = new THREE51__namespace.PlaneGeometry(100, 100);
4119
+ const material = new THREE51__namespace.MeshStandardMaterial({
4100
4120
  color: "#ffffff",
4101
- side: THREE39__namespace.DoubleSide
4121
+ side: THREE51__namespace.DoubleSide
4102
4122
  });
4103
- const mesh = new THREE39__namespace.Mesh(geometry, material);
4123
+ const mesh = new THREE51__namespace.Mesh(geometry, material);
4104
4124
  const entityId = createBaseEntity(
4105
4125
  world,
4106
4126
  mesh,
@@ -4136,7 +4156,7 @@ function createScriptObject({
4136
4156
  scene,
4137
4157
  payload
4138
4158
  }) {
4139
- const object = new THREE39__namespace.Group();
4159
+ const object = new THREE51__namespace.Group();
4140
4160
  const entityId = createBaseEntity(world, object, {
4141
4161
  label: payload.name ?? "Script Object",
4142
4162
  entityType: "scriptObject",
@@ -4161,15 +4181,15 @@ function createTeleportArea({
4161
4181
  const options = payload.options ?? {};
4162
4182
  const width = typeof options.width === "number" ? options.width : 10;
4163
4183
  const depth = typeof options.depth === "number" ? options.depth : 10;
4164
- const geometry = new THREE39__namespace.PlaneGeometry(width, depth);
4165
- const material = new THREE39__namespace.MeshBasicMaterial({
4184
+ const geometry = new THREE51__namespace.PlaneGeometry(width, depth);
4185
+ const material = new THREE51__namespace.MeshBasicMaterial({
4166
4186
  color: "#4da3ff",
4167
4187
  transparent: true,
4168
4188
  opacity: 0.18,
4169
- side: THREE39__namespace.DoubleSide,
4189
+ side: THREE51__namespace.DoubleSide,
4170
4190
  depthWrite: false
4171
4191
  });
4172
- const object = new THREE39__namespace.Mesh(geometry, material);
4192
+ const object = new THREE51__namespace.Mesh(geometry, material);
4173
4193
  const entityId = createBaseEntity(world, object, {
4174
4194
  label: payload.name ?? "Teleport Area",
4175
4195
  entityType: "teleportArea",
@@ -4197,7 +4217,7 @@ function createXRInteractor({
4197
4217
  scene,
4198
4218
  payload
4199
4219
  }) {
4200
- const root = new THREE39__namespace.Group();
4220
+ const root = new THREE51__namespace.Group();
4201
4221
  const options = payload.options ?? {};
4202
4222
  const entityId = createBaseEntity(world, root, {
4203
4223
  label: payload.name ?? "XR Interactor",
@@ -4207,7 +4227,7 @@ function createXRInteractor({
4207
4227
  world.addComponent(entityId, new XRInteractorComponent(options));
4208
4228
  scene.add(root);
4209
4229
  for (const side of ["left", "right"]) {
4210
- const slot = new THREE39__namespace.Group();
4230
+ const slot = new THREE51__namespace.Group();
4211
4231
  const label = side === "left" ? "Left Interactor" : "Right Interactor";
4212
4232
  const slotEntityId = createBaseEntity(world, slot, {
4213
4233
  label,
@@ -4225,7 +4245,7 @@ function createXRRig({
4225
4245
  scene,
4226
4246
  payload
4227
4247
  }) {
4228
- const object = new THREE39__namespace.Group();
4248
+ const object = new THREE51__namespace.Group();
4229
4249
  const entityId = createBaseEntity(world, object, {
4230
4250
  label: payload.name ?? "XR Rig",
4231
4251
  entityType: "xrRig",
@@ -4238,7 +4258,7 @@ function createXRRig({
4238
4258
  }
4239
4259
  __name(createXRRig, "createXRRig");
4240
4260
  function createSprite({ world, scene, payload }) {
4241
- const anchor = new THREE39__namespace.Object3D();
4261
+ const anchor = new THREE51__namespace.Object3D();
4242
4262
  const imagePath = payload.path ?? "";
4243
4263
  const entityId = createBaseEntity(world, anchor, {
4244
4264
  label: payload.name ?? "Sprite",
@@ -4250,7 +4270,7 @@ function createSprite({ world, scene, payload }) {
4250
4270
  if (!imagePath) {
4251
4271
  return entityId;
4252
4272
  }
4253
- const loader = new THREE39__namespace.TextureLoader();
4273
+ const loader = new THREE51__namespace.TextureLoader();
4254
4274
  loader.load(
4255
4275
  imagePath,
4256
4276
  (texture) => {
@@ -4258,11 +4278,11 @@ function createSprite({ world, scene, payload }) {
4258
4278
  texture.dispose();
4259
4279
  return;
4260
4280
  }
4261
- const material = new THREE39__namespace.SpriteMaterial({
4281
+ const material = new THREE51__namespace.SpriteMaterial({
4262
4282
  map: texture,
4263
4283
  transparent: true
4264
4284
  });
4265
- const sprite = new THREE39__namespace.Sprite(material);
4285
+ const sprite = new THREE51__namespace.Sprite(material);
4266
4286
  sprite.userData.entityId = entityId;
4267
4287
  const textureImage = texture.image;
4268
4288
  spriteComponent.width = textureImage?.width ?? 1;
@@ -4280,9 +4300,9 @@ function createSprite({ world, scene, payload }) {
4280
4300
  }
4281
4301
  __name(createSprite, "createSprite");
4282
4302
  function createSphere({ world, scene, payload }) {
4283
- const geometry = new THREE39__namespace.SphereGeometry(0.5, 24, 24);
4284
- const material = new THREE39__namespace.MeshStandardMaterial({ color: "#ffffff" });
4285
- const mesh = new THREE39__namespace.Mesh(geometry, material);
4303
+ const geometry = new THREE51__namespace.SphereGeometry(0.5, 24, 24);
4304
+ const material = new THREE51__namespace.MeshStandardMaterial({ color: "#ffffff" });
4305
+ const mesh = new THREE51__namespace.Mesh(geometry, material);
4286
4306
  const entityId = createBaseEntity(world, mesh, {
4287
4307
  label: payload.name ?? "Sphere",
4288
4308
  entityType: "sphere",
@@ -4302,10 +4322,10 @@ function createSphere({ world, scene, payload }) {
4302
4322
  __name(createSphere, "createSphere");
4303
4323
  function getOrCreateListener2(camera) {
4304
4324
  const existing = camera.userData.ecsAudioListener;
4305
- if (existing instanceof THREE39__namespace.AudioListener) {
4325
+ if (existing instanceof THREE51__namespace.AudioListener) {
4306
4326
  return existing;
4307
4327
  }
4308
- const listener = new THREE39__namespace.AudioListener();
4328
+ const listener = new THREE51__namespace.AudioListener();
4309
4329
  camera.add(listener);
4310
4330
  camera.userData.ecsAudioListener = listener;
4311
4331
  return listener;
@@ -4355,10 +4375,10 @@ function normalizeOptions(input) {
4355
4375
  }
4356
4376
  __name(normalizeOptions, "normalizeOptions");
4357
4377
  function createChromaMaterial(texture, options) {
4358
- return new THREE39__namespace.ShaderMaterial({
4378
+ return new THREE51__namespace.ShaderMaterial({
4359
4379
  uniforms: {
4360
4380
  tex: { value: texture },
4361
- keyColor: { value: new THREE39__namespace.Color(options.backgroundColor) },
4381
+ keyColor: { value: new THREE51__namespace.Color(options.backgroundColor) },
4362
4382
  similarity: { value: options.similarity },
4363
4383
  smoothness: { value: options.smoothness },
4364
4384
  spill: { value: options.spill }
@@ -4390,22 +4410,22 @@ function createChromaMaterial(texture, options) {
4390
4410
  }
4391
4411
  `,
4392
4412
  transparent: true,
4393
- side: THREE39__namespace.DoubleSide
4413
+ side: THREE51__namespace.DoubleSide
4394
4414
  });
4395
4415
  }
4396
4416
  __name(createChromaMaterial, "createChromaMaterial");
4397
4417
  function createStandardMaterial(texture) {
4398
- return new THREE39__namespace.MeshBasicMaterial({
4418
+ return new THREE51__namespace.MeshBasicMaterial({
4399
4419
  map: texture,
4400
4420
  transparent: true,
4401
- side: THREE39__namespace.DoubleSide
4421
+ side: THREE51__namespace.DoubleSide
4402
4422
  });
4403
4423
  }
4404
4424
  __name(createStandardMaterial, "createStandardMaterial");
4405
4425
  function createVideoMesh(entityId, texture, options) {
4406
- const geometry = new THREE39__namespace.PlaneGeometry(1, 1);
4426
+ const geometry = new THREE51__namespace.PlaneGeometry(1, 1);
4407
4427
  const material = options.isGreenScreen ? createChromaMaterial(texture, options) : createStandardMaterial(texture);
4408
- const mesh = new THREE39__namespace.Mesh(geometry, material);
4428
+ const mesh = new THREE51__namespace.Mesh(geometry, material);
4409
4429
  mesh.userData.entityId = entityId;
4410
4430
  mesh.scale.set(options.width, options.height, 1);
4411
4431
  return { mesh, material };
@@ -4440,7 +4460,7 @@ function createVideo({
4440
4460
  payload,
4441
4461
  isEditor
4442
4462
  }) {
4443
- const anchor = new THREE39__namespace.Object3D();
4463
+ const anchor = new THREE51__namespace.Object3D();
4444
4464
  const path = payload.path ?? "";
4445
4465
  const options = normalizeOptions(payload.options);
4446
4466
  const entityId = createBaseEntity(world, anchor, {
@@ -4455,8 +4475,8 @@ function createVideo({
4455
4475
  return entityId;
4456
4476
  }
4457
4477
  const video = createVideoElement(path, options);
4458
- const texture = new THREE39__namespace.VideoTexture(video);
4459
- texture.colorSpace = THREE39__namespace.SRGBColorSpace;
4478
+ const texture = new THREE51__namespace.VideoTexture(video);
4479
+ texture.colorSpace = THREE51__namespace.SRGBColorSpace;
4460
4480
  texture.needsUpdate = true;
4461
4481
  const { mesh, material } = createVideoMesh(entityId, texture, options);
4462
4482
  anchor.add(mesh);
@@ -4472,7 +4492,7 @@ function createVideo({
4472
4492
  });
4473
4493
  if (!isEditor && options.positional) {
4474
4494
  const listener = getOrCreateListener2(camera);
4475
- const audioNode = new THREE39__namespace.PositionalAudio(listener);
4495
+ const audioNode = new THREE51__namespace.PositionalAudio(listener);
4476
4496
  audioNode.setVolume(options.volume);
4477
4497
  audioNode.setRefDistance(options.refDistance);
4478
4498
  audioNode.setDistanceModel(normalizeDistanceModel2(options.distanceModel));
@@ -4777,13 +4797,9 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
4777
4797
  runtimeMessage: typeof entry.runtimeMessage === "string" ? entry.runtimeMessage : void 0
4778
4798
  };
4779
4799
  }).filter((entry) => entry.className || entry.scriptUrl) : [];
4780
- if (!entries.length) {
4781
- return;
4800
+ if (entries.length) {
4801
+ world.addComponent(targetEntityId, new ScriptComponent(entries));
4782
4802
  }
4783
- world.addComponent(
4784
- targetEntityId,
4785
- new ScriptComponent(entries)
4786
- );
4787
4803
  }
4788
4804
  const sourceScriptObject = asRecord3(values.scriptObjectValues.get(sourceEntityId));
4789
4805
  if (sourceScriptObject) {
@@ -4832,10 +4848,14 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
4832
4848
  const sourceInteractable = asRecord3(
4833
4849
  values.xrInteractableValues.get(sourceEntityId)
4834
4850
  );
4835
- const interactable = world.getComponent(
4851
+ let interactable = world.getComponent(
4836
4852
  targetEntityId,
4837
4853
  XRInteractableComponent
4838
4854
  );
4855
+ if (sourceInteractable && !interactable) {
4856
+ interactable = new XRInteractableComponent();
4857
+ world.addComponent(targetEntityId, interactable);
4858
+ }
4839
4859
  if (sourceInteractable && interactable) {
4840
4860
  if (typeof sourceInteractable.enabled === "boolean") {
4841
4861
  interactable.enabled = sourceInteractable.enabled;
@@ -4861,6 +4881,30 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
4861
4881
  if (typeof sourceInteractable.grabRadius === "number") {
4862
4882
  interactable.grabRadius = sourceInteractable.grabRadius;
4863
4883
  }
4884
+ if (typeof sourceInteractable.grabHands === "string") {
4885
+ interactable.grabHands = sourceInteractable.grabHands;
4886
+ }
4887
+ if (typeof sourceInteractable.twoHandRotation === "string") {
4888
+ interactable.twoHandRotation = sourceInteractable.twoHandRotation;
4889
+ }
4890
+ if (typeof sourceInteractable.allowTwoHandScale === "boolean") {
4891
+ interactable.allowTwoHandScale = sourceInteractable.allowTwoHandScale;
4892
+ }
4893
+ if (typeof sourceInteractable.minScale === "number") {
4894
+ interactable.minScale = sourceInteractable.minScale;
4895
+ }
4896
+ if (typeof sourceInteractable.maxScale === "number") {
4897
+ interactable.maxScale = sourceInteractable.maxScale;
4898
+ }
4899
+ if (Array.isArray(sourceInteractable.attachPoints)) {
4900
+ interactable.attachPoints = sourceInteractable.attachPoints.map((point) => asRecord3(point)).filter(
4901
+ (point) => point !== null && typeof point.id === "string"
4902
+ ).map(
4903
+ (point) => createAttachPoint(
4904
+ point
4905
+ )
4906
+ );
4907
+ }
4864
4908
  if (typeof sourceInteractable.throwOnRelease === "boolean") {
4865
4909
  interactable.throwOnRelease = sourceInteractable.throwOnRelease;
4866
4910
  }
@@ -4892,7 +4936,11 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
4892
4936
  const sourceHandPose = asRecord3(
4893
4937
  values.xrHandPoseValues.get(sourceEntityId)
4894
4938
  );
4895
- const handPose = world.getComponent(targetEntityId, XRHandPoseComponent);
4939
+ let handPose = world.getComponent(targetEntityId, XRHandPoseComponent);
4940
+ if (sourceHandPose && !handPose) {
4941
+ handPose = new XRHandPoseComponent();
4942
+ world.addComponent(targetEntityId, handPose);
4943
+ }
4896
4944
  if (sourceHandPose && handPose) {
4897
4945
  if (typeof sourceHandPose.enabled === "boolean") {
4898
4946
  handPose.enabled = sourceHandPose.enabled;
@@ -6656,7 +6704,7 @@ function transitionToClip(runtime, nextClipId, crossFadeDuration) {
6656
6704
  }
6657
6705
  __name(transitionToClip, "transitionToClip");
6658
6706
  function applyActionState(action, component, paused, shouldLoop) {
6659
- const loopMode = shouldLoop ? THREE39__namespace.LoopRepeat : THREE39__namespace.LoopOnce;
6707
+ const loopMode = shouldLoop ? THREE51__namespace.LoopRepeat : THREE51__namespace.LoopOnce;
6660
6708
  const repetitions = shouldLoop ? Infinity : 1;
6661
6709
  action.setLoop(loopMode, repetitions);
6662
6710
  action.clampWhenFinished = !shouldLoop;
@@ -6829,7 +6877,7 @@ var _AnimationSystem = class _AnimationSystem {
6829
6877
  if (runtime) {
6830
6878
  stopAllActions(runtime);
6831
6879
  }
6832
- const mixer = new THREE39__namespace.AnimationMixer(root);
6880
+ const mixer = new THREE51__namespace.AnimationMixer(root);
6833
6881
  const entries2 = readRuntimeClipEntries(animation);
6834
6882
  const indexedActions = createActions(mixer, entries2);
6835
6883
  runtime = {
@@ -6955,11 +7003,11 @@ function normalizeOrthoBounds(component) {
6955
7003
  }
6956
7004
  __name(normalizeOrthoBounds, "normalizeOrthoBounds");
6957
7005
  function isPerspectiveCamera(camera) {
6958
- return camera instanceof THREE39__namespace.PerspectiveCamera;
7006
+ return camera instanceof THREE51__namespace.PerspectiveCamera;
6959
7007
  }
6960
7008
  __name(isPerspectiveCamera, "isPerspectiveCamera");
6961
7009
  function isOrthographicCamera(camera) {
6962
- return camera instanceof THREE39__namespace.OrthographicCamera;
7010
+ return camera instanceof THREE51__namespace.OrthographicCamera;
6963
7011
  }
6964
7012
  __name(isOrthographicCamera, "isOrthographicCamera");
6965
7013
  function readWindowAspect() {
@@ -7013,7 +7061,7 @@ var _CameraSyncSystem = class _CameraSyncSystem {
7013
7061
  continue;
7014
7062
  }
7015
7063
  const camera = objectRef.object;
7016
- if (!(camera instanceof THREE39__namespace.Camera)) {
7064
+ if (!(camera instanceof THREE51__namespace.Camera)) {
7017
7065
  continue;
7018
7066
  }
7019
7067
  if (xrCamera !== null && camera === xrCamera) {
@@ -7080,7 +7128,7 @@ var MIN_DENSITY = 0;
7080
7128
  function createGradientTexture(effect, colors) {
7081
7129
  if (typeof document === "undefined") {
7082
7130
  const pixel = new Uint8Array([30, 30, 30, 255]);
7083
- const fallback = new THREE39__namespace.DataTexture(pixel, 1, 1, THREE39__namespace.RGBAFormat);
7131
+ const fallback = new THREE51__namespace.DataTexture(pixel, 1, 1, THREE51__namespace.RGBAFormat);
7084
7132
  fallback.needsUpdate = true;
7085
7133
  return fallback;
7086
7134
  }
@@ -7089,7 +7137,7 @@ function createGradientTexture(effect, colors) {
7089
7137
  canvas.height = 512;
7090
7138
  const context = canvas.getContext("2d");
7091
7139
  if (!context) {
7092
- const fallback = new THREE39__namespace.CanvasTexture(canvas);
7140
+ const fallback = new THREE51__namespace.CanvasTexture(canvas);
7093
7141
  fallback.needsUpdate = true;
7094
7142
  return fallback;
7095
7143
  }
@@ -7117,15 +7165,15 @@ function createGradientTexture(effect, colors) {
7117
7165
  context.fillRect(0, 0, 512, 512);
7118
7166
  context.globalCompositeOperation = "source-over";
7119
7167
  }
7120
- const texture = new THREE39__namespace.CanvasTexture(canvas);
7121
- texture.colorSpace = THREE39__namespace.SRGBColorSpace;
7168
+ const texture = new THREE51__namespace.CanvasTexture(canvas);
7169
+ texture.colorSpace = THREE51__namespace.SRGBColorSpace;
7122
7170
  texture.needsUpdate = true;
7123
7171
  return texture;
7124
7172
  }
7125
7173
  __name(createGradientTexture, "createGradientTexture");
7126
7174
  var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
7127
7175
  constructor(scene) {
7128
- this.textureLoader = new THREE39__namespace.TextureLoader();
7176
+ this.textureLoader = new THREE51__namespace.TextureLoader();
7129
7177
  this.signature = null;
7130
7178
  this.activeTexture = null;
7131
7179
  this.pendingImageUrl = null;
@@ -7148,7 +7196,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
7148
7196
  if (skybox.type === "color") {
7149
7197
  this.disposeActiveTexture();
7150
7198
  this.pendingImageUrl = null;
7151
- this.scene.background = new THREE39__namespace.Color(skybox.color || "#1e1e1e");
7199
+ this.scene.background = new THREE51__namespace.Color(skybox.color || "#1e1e1e");
7152
7200
  return;
7153
7201
  }
7154
7202
  if (skybox.type === "gradient") {
@@ -7182,7 +7230,7 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
7182
7230
  texture.dispose();
7183
7231
  return;
7184
7232
  }
7185
- texture.colorSpace = THREE39__namespace.SRGBColorSpace;
7233
+ texture.colorSpace = THREE51__namespace.SRGBColorSpace;
7186
7234
  this.activeTexture = texture;
7187
7235
  this.scene.background = texture;
7188
7236
  },
@@ -7201,16 +7249,16 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
7201
7249
  this.scene.fog = null;
7202
7250
  return;
7203
7251
  }
7204
- const fogColor = new THREE39__namespace.Color(fog.color || "#1e1e1e");
7252
+ const fogColor = new THREE51__namespace.Color(fog.color || "#1e1e1e");
7205
7253
  if (fog.type === "linear") {
7206
7254
  const near = Number.isFinite(fog.linear.near) ? fog.linear.near : 1;
7207
7255
  const farCandidate = Number.isFinite(fog.linear.far) ? fog.linear.far : near + 10;
7208
7256
  const far = Math.max(near + MIN_FOG_DELTA, farCandidate);
7209
- this.scene.fog = new THREE39__namespace.Fog(fogColor, near, far);
7257
+ this.scene.fog = new THREE51__namespace.Fog(fogColor, near, far);
7210
7258
  return;
7211
7259
  }
7212
7260
  const density = Number.isFinite(fog.exponential.density) ? Math.max(MIN_DENSITY, fog.exponential.density) : 2e-3;
7213
- this.scene.fog = new THREE39__namespace.FogExp2(fogColor, density);
7261
+ this.scene.fog = new THREE51__namespace.FogExp2(fogColor, density);
7214
7262
  }
7215
7263
  update(world) {
7216
7264
  const entityIds = world.query(Environment);
@@ -7292,10 +7340,10 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
7292
7340
  );
7293
7341
  }
7294
7342
  if (values.bloom.enabled) {
7295
- const size = this.renderer.getSize(new THREE39__namespace.Vector2());
7343
+ const size = this.renderer.getSize(new THREE51__namespace.Vector2());
7296
7344
  composer.addPass(
7297
7345
  new UnrealBloomPass_js.UnrealBloomPass(
7298
- new THREE39__namespace.Vector2(size.width, size.height),
7346
+ new THREE51__namespace.Vector2(size.width, size.height),
7299
7347
  values.bloom.intensity,
7300
7348
  values.bloom.radius,
7301
7349
  values.bloom.threshold
@@ -7340,7 +7388,7 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
7340
7388
  if (values.dotScreen.enabled) {
7341
7389
  composer.addPass(
7342
7390
  new DotScreenPass_js.DotScreenPass(
7343
- new THREE39__namespace.Vector2(0, 0),
7391
+ new THREE51__namespace.Vector2(0, 0),
7344
7392
  values.dotScreen.angle ?? values.dotScreen.dotScreenAngle,
7345
7393
  values.dotScreen.scale ?? values.dotScreen.dotScreenScale
7346
7394
  )
@@ -7414,7 +7462,7 @@ function computeColliderState(colliderValues, object) {
7414
7462
  if (!object) {
7415
7463
  return colliderValues;
7416
7464
  }
7417
- const scale = new THREE39__namespace.Vector3();
7465
+ const scale = new THREE51__namespace.Vector3();
7418
7466
  object.getWorldScale(scale);
7419
7467
  return {
7420
7468
  ...colliderValues,
@@ -7465,8 +7513,8 @@ function createColliderDesc(RAPIER, values, triMeshData) {
7465
7513
  values.offsetPosition.y,
7466
7514
  values.offsetPosition.z
7467
7515
  );
7468
- const offsetQuaternion = new THREE39__namespace.Quaternion().setFromEuler(
7469
- new THREE39__namespace.Euler(
7516
+ const offsetQuaternion = new THREE51__namespace.Quaternion().setFromEuler(
7517
+ new THREE51__namespace.Euler(
7470
7518
  values.offsetRotation.x,
7471
7519
  values.offsetRotation.y,
7472
7520
  values.offsetRotation.z
@@ -7481,17 +7529,17 @@ function collectTriMeshParts(object) {
7481
7529
  return null;
7482
7530
  }
7483
7531
  object.updateWorldMatrix(true, true);
7484
- const worldScale = new THREE39__namespace.Vector3();
7532
+ const worldScale = new THREE51__namespace.Vector3();
7485
7533
  object.getWorldScale(worldScale);
7486
7534
  const scale = {
7487
7535
  x: Math.abs(worldScale.x) || 1,
7488
7536
  y: Math.abs(worldScale.y) || 1,
7489
7537
  z: Math.abs(worldScale.z) || 1
7490
7538
  };
7491
- const worldToObject = new THREE39__namespace.Matrix4().copy(object.matrixWorld).invert();
7539
+ const worldToObject = new THREE51__namespace.Matrix4().copy(object.matrixWorld).invert();
7492
7540
  const parts = [];
7493
7541
  object.traverse((child) => {
7494
- if (!(child instanceof THREE39__namespace.Mesh) || !child.geometry) {
7542
+ if (!(child instanceof THREE51__namespace.Mesh) || !child.geometry) {
7495
7543
  return;
7496
7544
  }
7497
7545
  const geometry = child.geometry;
@@ -7508,7 +7556,7 @@ function collectTriMeshParts(object) {
7508
7556
  if (indexCount < 3) {
7509
7557
  return;
7510
7558
  }
7511
- const relativeMatrix = new THREE39__namespace.Matrix4().multiplyMatrices(
7559
+ const relativeMatrix = new THREE51__namespace.Matrix4().multiplyMatrices(
7512
7560
  worldToObject,
7513
7561
  child.matrixWorld
7514
7562
  );
@@ -7549,7 +7597,7 @@ function createTriMeshData(collected) {
7549
7597
  }
7550
7598
  const vertices = new Float32Array(vertexTotal * 3);
7551
7599
  const indices = new Uint32Array(indexTotal);
7552
- const point = new THREE39__namespace.Vector3();
7600
+ const point = new THREE51__namespace.Vector3();
7553
7601
  let vertexOffset = 0;
7554
7602
  let indexOffset = 0;
7555
7603
  for (const part of parts) {
@@ -7581,8 +7629,8 @@ function createTriMeshData(collected) {
7581
7629
  }
7582
7630
  __name(createTriMeshData, "createTriMeshData");
7583
7631
  function syncBodyFromTransform(body, transform) {
7584
- const quaternion = new THREE39__namespace.Quaternion().setFromEuler(
7585
- new THREE39__namespace.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z)
7632
+ const quaternion = new THREE51__namespace.Quaternion().setFromEuler(
7633
+ new THREE51__namespace.Euler(transform.rotation.x, transform.rotation.y, transform.rotation.z)
7586
7634
  );
7587
7635
  body.setTranslation(
7588
7636
  {
@@ -7609,8 +7657,8 @@ function syncTransformFromBody(transform, body) {
7609
7657
  transform.position.x = position.x;
7610
7658
  transform.position.y = position.y;
7611
7659
  transform.position.z = position.z;
7612
- const euler = new THREE39__namespace.Euler().setFromQuaternion(
7613
- new THREE39__namespace.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w)
7660
+ const euler = new THREE51__namespace.Euler().setFromQuaternion(
7661
+ new THREE51__namespace.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w)
7614
7662
  );
7615
7663
  transform.rotation.x = euler.x;
7616
7664
  transform.rotation.y = euler.y;
@@ -7722,8 +7770,8 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
7722
7770
  transform.position.y,
7723
7771
  transform.position.z
7724
7772
  );
7725
- const quaternion = new THREE39__namespace.Quaternion().setFromEuler(
7726
- new THREE39__namespace.Euler(
7773
+ const quaternion = new THREE51__namespace.Quaternion().setFromEuler(
7774
+ new THREE51__namespace.Euler(
7727
7775
  transform.rotation.x,
7728
7776
  transform.rotation.y,
7729
7777
  transform.rotation.z
@@ -8302,7 +8350,7 @@ function applyLightValues(lightComponent) {
8302
8350
  values.castShadow
8303
8351
  );
8304
8352
  }
8305
- if (light instanceof THREE39__namespace.PointLight) {
8353
+ if (light instanceof THREE51__namespace.PointLight) {
8306
8354
  if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
8307
8355
  light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
8308
8356
  }
@@ -8310,7 +8358,7 @@ function applyLightValues(lightComponent) {
8310
8358
  light.decay = Math.max(0, values.decay);
8311
8359
  }
8312
8360
  }
8313
- if (light instanceof THREE39__namespace.SpotLight) {
8361
+ if (light instanceof THREE51__namespace.SpotLight) {
8314
8362
  if (typeof values.distance === "number" && Number.isFinite(values.distance)) {
8315
8363
  light.distance = Math.max(MIN_LIGHT_DISTANCE, values.distance);
8316
8364
  }
@@ -8324,7 +8372,7 @@ function applyLightValues(lightComponent) {
8324
8372
  light.penumbra = Math.max(0, Math.min(1, values.penumbra));
8325
8373
  }
8326
8374
  }
8327
- if (light instanceof THREE39__namespace.RectAreaLight) {
8375
+ if (light instanceof THREE51__namespace.RectAreaLight) {
8328
8376
  if (typeof values.width === "number" && Number.isFinite(values.width)) {
8329
8377
  light.width = Math.max(MIN_AREA_SIZE, values.width);
8330
8378
  }
@@ -8385,15 +8433,15 @@ function resolveMaterialPropertyKey(key) {
8385
8433
  __name(resolveMaterialPropertyKey, "resolveMaterialPropertyKey");
8386
8434
  function createMaterialByType(type) {
8387
8435
  if (type === "basic") {
8388
- return new THREE39__namespace.MeshBasicMaterial();
8436
+ return new THREE51__namespace.MeshBasicMaterial();
8389
8437
  }
8390
8438
  if (type === "phong") {
8391
- return new THREE39__namespace.MeshPhongMaterial();
8439
+ return new THREE51__namespace.MeshPhongMaterial();
8392
8440
  }
8393
8441
  if (type === "physical") {
8394
- return new THREE39__namespace.MeshPhysicalMaterial();
8442
+ return new THREE51__namespace.MeshPhysicalMaterial();
8395
8443
  }
8396
- return new THREE39__namespace.MeshStandardMaterial();
8444
+ return new THREE51__namespace.MeshStandardMaterial();
8397
8445
  }
8398
8446
  __name(createMaterialByType, "createMaterialByType");
8399
8447
  function replaceMaterialAcrossObject(object, previous, next) {
@@ -8452,12 +8500,12 @@ function applyTextureFiltering(material, filtering) {
8452
8500
  const target = material;
8453
8501
  for (const slot of materialTextureSlots) {
8454
8502
  const texture = target[slot];
8455
- if (!texture || !(texture instanceof THREE39__namespace.Texture)) {
8503
+ if (!texture || !(texture instanceof THREE51__namespace.Texture)) {
8456
8504
  continue;
8457
8505
  }
8458
8506
  const useMipmaps = texture.generateMipmaps !== false;
8459
- texture.magFilter = sharp ? THREE39__namespace.NearestFilter : THREE39__namespace.LinearFilter;
8460
- texture.minFilter = useMipmaps ? sharp ? THREE39__namespace.NearestMipmapNearestFilter : THREE39__namespace.LinearMipmapLinearFilter : sharp ? THREE39__namespace.NearestFilter : THREE39__namespace.LinearFilter;
8507
+ texture.magFilter = sharp ? THREE51__namespace.NearestFilter : THREE51__namespace.LinearFilter;
8508
+ texture.minFilter = useMipmaps ? sharp ? THREE51__namespace.NearestMipmapNearestFilter : THREE51__namespace.LinearMipmapLinearFilter : sharp ? THREE51__namespace.NearestFilter : THREE51__namespace.LinearFilter;
8461
8509
  texture.needsUpdate = true;
8462
8510
  }
8463
8511
  material.needsUpdate = true;
@@ -8467,12 +8515,12 @@ function setTextureMipmaps(material, enabled) {
8467
8515
  const target = material;
8468
8516
  for (const slot of materialTextureSlots) {
8469
8517
  const texture = target[slot];
8470
- if (!texture || !(texture instanceof THREE39__namespace.Texture)) {
8518
+ if (!texture || !(texture instanceof THREE51__namespace.Texture)) {
8471
8519
  continue;
8472
8520
  }
8473
8521
  texture.generateMipmaps = enabled;
8474
- const sharp = texture.magFilter === THREE39__namespace.NearestFilter;
8475
- texture.minFilter = enabled ? sharp ? THREE39__namespace.NearestMipmapNearestFilter : THREE39__namespace.LinearMipmapLinearFilter : sharp ? THREE39__namespace.NearestFilter : THREE39__namespace.LinearFilter;
8522
+ const sharp = texture.magFilter === THREE51__namespace.NearestFilter;
8523
+ texture.minFilter = enabled ? sharp ? THREE51__namespace.NearestMipmapNearestFilter : THREE51__namespace.LinearMipmapLinearFilter : sharp ? THREE51__namespace.NearestFilter : THREE51__namespace.LinearFilter;
8476
8524
  texture.needsUpdate = true;
8477
8525
  }
8478
8526
  material.needsUpdate = true;
@@ -8483,7 +8531,7 @@ function assignMaterialTexture(material, rawKey, url, textureCache) {
8483
8531
  const key = resolveMaterialPropertyKey(rawKey);
8484
8532
  let texture = textureCache.get(url);
8485
8533
  if (!texture) {
8486
- texture = new THREE39__namespace.TextureLoader().load(url);
8534
+ texture = new THREE51__namespace.TextureLoader().load(url);
8487
8535
  textureCache.set(url, texture);
8488
8536
  }
8489
8537
  target[key] = texture;
@@ -8521,7 +8569,7 @@ function applyMaterialState(material, value, textureCache) {
8521
8569
  }
8522
8570
  target.side = value.side;
8523
8571
  target.blending = value.blending;
8524
- target.premultipliedAlpha = value.blending === THREE39__namespace.MultiplyBlending || value.blending === THREE39__namespace.SubtractiveBlending;
8572
+ target.premultipliedAlpha = value.blending === THREE51__namespace.MultiplyBlending || value.blending === THREE51__namespace.SubtractiveBlending;
8525
8573
  target.depthTest = value.depthTest;
8526
8574
  target.depthWrite = value.depthWrite;
8527
8575
  target.wireframe = value.wireframe;
@@ -8682,12 +8730,12 @@ function resolvePrimaryMesh(object) {
8682
8730
  if (!object) {
8683
8731
  return null;
8684
8732
  }
8685
- if (object instanceof THREE39__namespace.Mesh) {
8733
+ if (object instanceof THREE51__namespace.Mesh) {
8686
8734
  return object;
8687
8735
  }
8688
8736
  let found = null;
8689
8737
  object.traverse((child) => {
8690
- if (!found && child instanceof THREE39__namespace.Mesh) {
8738
+ if (!found && child instanceof THREE51__namespace.Mesh) {
8691
8739
  found = child;
8692
8740
  }
8693
8741
  });
@@ -8708,22 +8756,22 @@ function applyGeometry(component) {
8708
8756
  switch (component.kind) {
8709
8757
  case "cube": {
8710
8758
  const params = sanitized;
8711
- nextGeometry = new THREE39__namespace.BoxGeometry(params.width, params.height, params.depth);
8759
+ nextGeometry = new THREE51__namespace.BoxGeometry(params.width, params.height, params.depth);
8712
8760
  break;
8713
8761
  }
8714
8762
  case "plane": {
8715
8763
  const params = sanitized;
8716
- nextGeometry = new THREE39__namespace.PlaneGeometry(params.width, params.height);
8764
+ nextGeometry = new THREE51__namespace.PlaneGeometry(params.width, params.height);
8717
8765
  break;
8718
8766
  }
8719
8767
  case "sphere": {
8720
8768
  const params = sanitized;
8721
- nextGeometry = new THREE39__namespace.SphereGeometry(params.radius, 24, 24);
8769
+ nextGeometry = new THREE51__namespace.SphereGeometry(params.radius, 24, 24);
8722
8770
  break;
8723
8771
  }
8724
8772
  case "cylinder": {
8725
8773
  const params = sanitized;
8726
- nextGeometry = new THREE39__namespace.CylinderGeometry(
8774
+ nextGeometry = new THREE51__namespace.CylinderGeometry(
8727
8775
  params.radius,
8728
8776
  params.radius,
8729
8777
  params.height,
@@ -8733,7 +8781,7 @@ function applyGeometry(component) {
8733
8781
  }
8734
8782
  case "capsule": {
8735
8783
  const params = sanitized;
8736
- nextGeometry = new THREE39__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
8784
+ nextGeometry = new THREE51__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
8737
8785
  break;
8738
8786
  }
8739
8787
  default:
@@ -8749,7 +8797,7 @@ function applyShadowFlags(component) {
8749
8797
  return;
8750
8798
  }
8751
8799
  component.object.traverse((child) => {
8752
- if (child instanceof THREE39__namespace.Mesh) {
8800
+ if (child instanceof THREE51__namespace.Mesh) {
8753
8801
  child.castShadow = component.castShadow;
8754
8802
  child.receiveShadow = component.receiveShadow;
8755
8803
  }
@@ -8832,35 +8880,35 @@ function buildGeometry(component) {
8832
8880
  switch (component.meshKind) {
8833
8881
  case "cube": {
8834
8882
  const params = p;
8835
- return new THREE39__namespace.BoxGeometry(params.width, params.height, params.depth);
8883
+ return new THREE51__namespace.BoxGeometry(params.width, params.height, params.depth);
8836
8884
  }
8837
8885
  case "plane": {
8838
8886
  const params = p;
8839
- return new THREE39__namespace.PlaneGeometry(params.width, params.height);
8887
+ return new THREE51__namespace.PlaneGeometry(params.width, params.height);
8840
8888
  }
8841
8889
  case "sphere": {
8842
8890
  const params = p;
8843
- return new THREE39__namespace.SphereGeometry(params.radius, 24, 24);
8891
+ return new THREE51__namespace.SphereGeometry(params.radius, 24, 24);
8844
8892
  }
8845
8893
  case "cylinder": {
8846
8894
  const params = p;
8847
- return new THREE39__namespace.CylinderGeometry(params.radius, params.radius, params.height, 20);
8895
+ return new THREE51__namespace.CylinderGeometry(params.radius, params.radius, params.height, 20);
8848
8896
  }
8849
8897
  case "capsule": {
8850
8898
  const params = p;
8851
- return new THREE39__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
8899
+ return new THREE51__namespace.CapsuleGeometry(params.radius, params.height, 4, 8);
8852
8900
  }
8853
8901
  default:
8854
- return new THREE39__namespace.BoxGeometry(1, 1, 1);
8902
+ return new THREE51__namespace.BoxGeometry(1, 1, 1);
8855
8903
  }
8856
8904
  }
8857
8905
  __name(buildGeometry, "buildGeometry");
8858
- var _position = new THREE39__namespace.Vector3();
8859
- var _quaternion = new THREE39__namespace.Quaternion();
8860
- var _euler = new THREE39__namespace.Euler();
8861
- var _scale = new THREE39__namespace.Vector3();
8862
- var _matrix = new THREE39__namespace.Matrix4();
8863
- var _modelMatrix = new THREE39__namespace.Matrix4();
8906
+ var _position = new THREE51__namespace.Vector3();
8907
+ var _quaternion = new THREE51__namespace.Quaternion();
8908
+ var _euler = new THREE51__namespace.Euler();
8909
+ var _scale = new THREE51__namespace.Vector3();
8910
+ var _matrix = new THREE51__namespace.Matrix4();
8911
+ var _modelMatrix = new THREE51__namespace.Matrix4();
8864
8912
  function instanceTransformFromComponent(transform, out) {
8865
8913
  _position.set(transform.position.x, transform.position.y, transform.position.z);
8866
8914
  _euler.set(transform.rotation.x, transform.rotation.y, transform.rotation.z, "XYZ");
@@ -9013,7 +9061,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
9013
9061
  const sourceMaterial = Array.isArray(meshChild.material) ? meshChild.material.map((m) => m.clone()) : meshChild.material.clone();
9014
9062
  meshChild.updateWorldMatrix(true, false);
9015
9063
  const localMatrix = meshChild.matrixWorld.clone();
9016
- const instancedMesh2 = new THREE39__namespace.InstancedMesh(
9064
+ const instancedMesh2 = new THREE51__namespace.InstancedMesh(
9017
9065
  geometry2,
9018
9066
  Array.isArray(sourceMaterial) ? sourceMaterial : sourceMaterial,
9019
9067
  count2
@@ -9038,7 +9086,7 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
9038
9086
  this.loadingSignatures.delete(targetEntityId);
9039
9087
  return;
9040
9088
  }
9041
- const group = new THREE39__namespace.Group();
9089
+ const group = new THREE51__namespace.Group();
9042
9090
  for (const entry of entries) {
9043
9091
  group.add(entry.instancedMesh);
9044
9092
  }
@@ -9056,8 +9104,8 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
9056
9104
  }
9057
9105
  const count = instanceCount;
9058
9106
  const geometry = buildGeometry(comp);
9059
- const material = new THREE39__namespace.MeshStandardMaterial({ color: "#ffffff" });
9060
- const instancedMesh = new THREE39__namespace.InstancedMesh(geometry, material, count);
9107
+ const material = new THREE51__namespace.MeshStandardMaterial({ color: "#ffffff" });
9108
+ const instancedMesh = new THREE51__namespace.InstancedMesh(geometry, material, count);
9061
9109
  instancedMesh.castShadow = comp.castShadow;
9062
9110
  instancedMesh.receiveShadow = comp.receiveShadow;
9063
9111
  for (let i = 0; i < count; i++) {
@@ -9240,7 +9288,7 @@ var _Behaviour = class _Behaviour {
9240
9288
  if (!this.threeRef) {
9241
9289
  return null;
9242
9290
  }
9243
- const position = new THREE39__namespace.Vector3();
9291
+ const position = new THREE51__namespace.Vector3();
9244
9292
  this.threeRef.object.getWorldPosition(position);
9245
9293
  return position;
9246
9294
  }
@@ -9252,7 +9300,7 @@ var _Behaviour = class _Behaviour {
9252
9300
  if (!this.threeRef) {
9253
9301
  return null;
9254
9302
  }
9255
- const target = new THREE39__namespace.Vector3();
9303
+ const target = new THREE51__namespace.Vector3();
9256
9304
  this.threeRef.object.getWorldDirection(target);
9257
9305
  return target;
9258
9306
  }
@@ -9314,7 +9362,7 @@ var _Behaviour = class _Behaviour {
9314
9362
  if (!this.threeRef) {
9315
9363
  return;
9316
9364
  }
9317
- const rotation = new THREE39__namespace.Quaternion();
9365
+ const rotation = new THREE51__namespace.Quaternion();
9318
9366
  this.threeRef.object.getWorldQuaternion(rotation);
9319
9367
  rotation.slerp(targetRotation, alpha);
9320
9368
  this.transform.setRotation(rotation);
@@ -9331,7 +9379,7 @@ var _Behaviour = class _Behaviour {
9331
9379
  return;
9332
9380
  }
9333
9381
  const clone3 = this.threeRef.object.clone();
9334
- const rotation = new THREE39__namespace.Quaternion();
9382
+ const rotation = new THREE51__namespace.Quaternion();
9335
9383
  clone3.lookAt(targetPosition);
9336
9384
  clone3.getWorldQuaternion(rotation);
9337
9385
  this.transform.setRotation(rotation);
@@ -9469,6 +9517,17 @@ var _Behaviour = class _Behaviour {
9469
9517
  *
9470
9518
  * @param input - The source doing the grabbing.
9471
9519
  */
9520
+ /**
9521
+ * A SECOND hand joined a two-hand grab on this entity.
9522
+ *
9523
+ * The first hand anchors the object and keeps holding it; this fires for the
9524
+ * hand that came second — the foregrip on a rifle, say.
9525
+ */
9526
+ onSecondaryGrab(_input) {
9527
+ }
9528
+ /** The second hand let go, leaving the object in the first hand alone. */
9529
+ onSecondaryRelease(_input) {
9530
+ }
9472
9531
  /**
9473
9532
  * A hand pose declared on this entity started being held.
9474
9533
  *
@@ -9686,8 +9745,8 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
9686
9745
  }, "onPointerUp");
9687
9746
  this.moduleLoader = moduleLoader ?? defaultModuleLoader;
9688
9747
  this.selectionCtx = selectionContext ?? null;
9689
- this.raycaster = new THREE39__namespace.Raycaster();
9690
- this.ndcPointer = new THREE39__namespace.Vector2();
9748
+ this.raycaster = new THREE51__namespace.Raycaster();
9749
+ this.ndcPointer = new THREE51__namespace.Vector2();
9691
9750
  if (this.selectionCtx) {
9692
9751
  this.selectionCtx.domElement.addEventListener("pointerdown", this.onPointerDown);
9693
9752
  this.selectionCtx.domElement.addEventListener("pointerup", this.onPointerUp);
@@ -10066,7 +10125,7 @@ function disposeBuiltObject(root) {
10066
10125
  for (const mat of materials) {
10067
10126
  if (mat.userData?.[SHARED_MODEL_RESOURCE_FLAG]) continue;
10068
10127
  for (const value of Object.values(mat)) {
10069
- if (value instanceof THREE39__namespace.Texture) value.dispose();
10128
+ if (value instanceof THREE51__namespace.Texture) value.dispose();
10070
10129
  }
10071
10130
  mat.dispose?.();
10072
10131
  }
@@ -10430,7 +10489,7 @@ var _AudioSystem = class _AudioSystem {
10430
10489
  if (!prev || prev.volume !== opts.volume) {
10431
10490
  sound.setVolume(opts.volume);
10432
10491
  }
10433
- if (opts.positional && sound instanceof THREE39__namespace.PositionalAudio) {
10492
+ if (opts.positional && sound instanceof THREE51__namespace.PositionalAudio) {
10434
10493
  if (!prev || prev.refDistance !== opts.refDistance) {
10435
10494
  sound.setRefDistance(opts.refDistance);
10436
10495
  }
@@ -10556,7 +10615,7 @@ var _VideoSystem = class _VideoSystem {
10556
10615
  component.object.scale.set(opts.width, opts.height, 1);
10557
10616
  }
10558
10617
  const material = component.material;
10559
- if (material instanceof THREE39__namespace.ShaderMaterial) {
10618
+ if (material instanceof THREE51__namespace.ShaderMaterial) {
10560
10619
  if (!prev || prev.backgroundColor !== opts.backgroundColor) {
10561
10620
  material.uniforms.keyColor.value.set(opts.backgroundColor);
10562
10621
  }
@@ -10570,7 +10629,7 @@ var _VideoSystem = class _VideoSystem {
10570
10629
  material.uniforms.spill.value = opts.spill;
10571
10630
  }
10572
10631
  }
10573
- if (opts.positional && component.audioNode instanceof THREE39__namespace.PositionalAudio) {
10632
+ if (opts.positional && component.audioNode instanceof THREE51__namespace.PositionalAudio) {
10574
10633
  const posAudio = component.audioNode;
10575
10634
  if (!prev || prev.refDistance !== opts.refDistance) {
10576
10635
  posAudio.setRefDistance(opts.refDistance);
@@ -10610,8 +10669,8 @@ function blankState(source) {
10610
10669
  handedness: handednessOf(source),
10611
10670
  kind: kindOf(source),
10612
10671
  connected: true,
10613
- rayOrigin: new THREE39__namespace.Vector3(),
10614
- rayDirection: new THREE39__namespace.Vector3(0, 0, -1),
10672
+ rayOrigin: new THREE51__namespace.Vector3(),
10673
+ rayDirection: new THREE51__namespace.Vector3(0, 0, -1),
10615
10674
  gripPosition: null,
10616
10675
  gripQuaternion: null,
10617
10676
  select: false,
@@ -10637,7 +10696,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
10637
10696
  }
10638
10697
  if (spaces.length === 0) return null;
10639
10698
  const target = existing ?? {};
10640
- const matrix = new THREE39__namespace.Matrix4();
10699
+ const matrix = new THREE51__namespace.Matrix4();
10641
10700
  const buffer = spaces.length * 16 <= JOINT_MATRIX_BUFFER.length ? JOINT_MATRIX_BUFFER : new Float32Array(spaces.length * 16);
10642
10701
  const fillPoses = frame.fillPoses;
10643
10702
  if (typeof fillPoses === "function") {
@@ -10650,7 +10709,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
10650
10709
  if (filled) {
10651
10710
  for (let i = 0; i < names.length; i += 1) {
10652
10711
  matrix.fromArray(buffer, i * 16).premultiply(rigMatrix);
10653
- const vector = target[names[i]] ?? new THREE39__namespace.Vector3();
10712
+ const vector = target[names[i]] ?? new THREE51__namespace.Vector3();
10654
10713
  vector.setFromMatrixPosition(matrix);
10655
10714
  target[names[i]] = vector;
10656
10715
  }
@@ -10668,7 +10727,7 @@ function readHandJoints(frame, hand, referenceSpace, rigMatrix, existing) {
10668
10727
  continue;
10669
10728
  }
10670
10729
  matrix.fromArray(pose.transform.matrix).premultiply(rigMatrix);
10671
- const vector = target[names[i]] ?? new THREE39__namespace.Vector3();
10730
+ const vector = target[names[i]] ?? new THREE51__namespace.Vector3();
10672
10731
  vector.setFromMatrixPosition(matrix);
10673
10732
  target[names[i]] = vector;
10674
10733
  anyTracked = true;
@@ -10680,7 +10739,7 @@ var _XRInputSystem = class _XRInputSystem {
10680
10739
  constructor() {
10681
10740
  this.records = /* @__PURE__ */ new Map();
10682
10741
  /** Reference-space → world matrix, rebuilt each frame from the XR rig. */
10683
- this.referenceToWorld = new THREE39__namespace.Matrix4();
10742
+ this.referenceToWorld = new THREE51__namespace.Matrix4();
10684
10743
  this.session = null;
10685
10744
  this.onSelectStart = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectStart"), "onSelectStart");
10686
10745
  this.onSelectEnd = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectEnd"), "onSelectEnd");
@@ -10778,19 +10837,19 @@ var _XRInputSystem = class _XRInputSystem {
10778
10837
  if (frame && referenceSpace && source.targetRaySpace) {
10779
10838
  const pose = frame.getPose(source.targetRaySpace, referenceSpace);
10780
10839
  if (pose) {
10781
- const m = new THREE39__namespace.Matrix4().fromArray(pose.transform.matrix).premultiply(rigMatrix);
10840
+ const m = new THREE51__namespace.Matrix4().fromArray(pose.transform.matrix).premultiply(rigMatrix);
10782
10841
  state.rayOrigin.setFromMatrixPosition(m);
10783
10842
  state.rayDirection.set(0, 0, -1).applyQuaternion(
10784
- new THREE39__namespace.Quaternion().setFromRotationMatrix(m)
10843
+ new THREE51__namespace.Quaternion().setFromRotationMatrix(m)
10785
10844
  ).normalize();
10786
10845
  }
10787
10846
  }
10788
10847
  if (frame && referenceSpace && source.gripSpace) {
10789
10848
  const gripPose = frame.getPose(source.gripSpace, referenceSpace);
10790
10849
  if (gripPose) {
10791
- const m = new THREE39__namespace.Matrix4().fromArray(gripPose.transform.matrix).premultiply(rigMatrix);
10792
- state.gripPosition ?? (state.gripPosition = new THREE39__namespace.Vector3());
10793
- state.gripQuaternion ?? (state.gripQuaternion = new THREE39__namespace.Quaternion());
10850
+ const m = new THREE51__namespace.Matrix4().fromArray(gripPose.transform.matrix).premultiply(rigMatrix);
10851
+ state.gripPosition ?? (state.gripPosition = new THREE51__namespace.Vector3());
10852
+ state.gripQuaternion ?? (state.gripQuaternion = new THREE51__namespace.Quaternion());
10794
10853
  state.gripPosition.setFromMatrixPosition(m);
10795
10854
  state.gripQuaternion.setFromRotationMatrix(m);
10796
10855
  }
@@ -10875,6 +10934,7 @@ __name(_XRInputSystem, "XRInputSystem");
10875
10934
  var XRInputSystem = _XRInputSystem;
10876
10935
  var VELOCITY_SAMPLES = 5;
10877
10936
  var MAX_SAMPLE_AGE_SECONDS = 0.2;
10937
+ var MAX_PLAUSIBLE_SPEED = 20;
10878
10938
  var _ThrowVelocityTracker = class _ThrowVelocityTracker {
10879
10939
  constructor() {
10880
10940
  this.samples = [];
@@ -10898,16 +10958,17 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
10898
10958
  const fresh = this.samples.filter(
10899
10959
  (sample) => now - sample.time <= MAX_SAMPLE_AGE_SECONDS
10900
10960
  );
10901
- if (fresh.length < 2) return new THREE39__namespace.Vector3();
10902
- let best = new THREE39__namespace.Vector3();
10961
+ if (fresh.length < 2) return new THREE51__namespace.Vector3();
10962
+ let best = new THREE51__namespace.Vector3();
10903
10963
  let bestSpeed = 0;
10904
10964
  for (let i = 1; i < fresh.length; i += 1) {
10905
10965
  const previous = fresh[i - 1];
10906
10966
  const current = fresh[i];
10907
10967
  const dt = current.time - previous.time;
10908
10968
  if (dt <= 1e-5) continue;
10909
- const velocity = new THREE39__namespace.Vector3().subVectors(current.position, previous.position).divideScalar(dt);
10969
+ const velocity = new THREE51__namespace.Vector3().subVectors(current.position, previous.position).divideScalar(dt);
10910
10970
  const speed = velocity.length();
10971
+ if (speed > MAX_PLAUSIBLE_SPEED) continue;
10911
10972
  if (speed > bestSpeed) {
10912
10973
  bestSpeed = speed;
10913
10974
  best = velocity;
@@ -10922,23 +10983,75 @@ var _ThrowVelocityTracker = class _ThrowVelocityTracker {
10922
10983
  __name(_ThrowVelocityTracker, "ThrowVelocityTracker");
10923
10984
  var ThrowVelocityTracker = _ThrowVelocityTracker;
10924
10985
  function angularVelocityFrom(previous, current, deltaTime) {
10925
- if (deltaTime <= 1e-5) return new THREE39__namespace.Vector3();
10986
+ if (deltaTime <= 1e-5) return new THREE51__namespace.Vector3();
10926
10987
  const delta = current.clone().multiply(previous.clone().invert());
10927
10988
  if (delta.w < 0) {
10928
10989
  delta.set(-delta.x, -delta.y, -delta.z, -delta.w);
10929
10990
  }
10930
- const angle = 2 * Math.acos(THREE39__namespace.MathUtils.clamp(delta.w, -1, 1));
10991
+ const angle = 2 * Math.acos(THREE51__namespace.MathUtils.clamp(delta.w, -1, 1));
10931
10992
  const sinHalf = Math.sqrt(Math.max(0, 1 - delta.w * delta.w));
10932
- if (sinHalf < 1e-6 || angle < 1e-6) return new THREE39__namespace.Vector3();
10933
- return new THREE39__namespace.Vector3(delta.x, delta.y, delta.z).divideScalar(sinHalf).multiplyScalar(angle / deltaTime);
10993
+ if (sinHalf < 1e-6 || angle < 1e-6) return new THREE51__namespace.Vector3();
10994
+ return new THREE51__namespace.Vector3(delta.x, delta.y, delta.z).divideScalar(sinHalf).multiplyScalar(angle / deltaTime);
10934
10995
  }
10935
10996
  __name(angularVelocityFrom, "angularVelocityFrom");
10997
+ var MIN_HAND_SEPARATION = 0.06;
10998
+ var MIN_ANCHOR_SEPARATION = 1e-3;
10999
+ var SCALE_DEADZONE = 0.05;
11000
+ function solveTwoHandTransform(primary, secondary, basis, options) {
11001
+ const separation = primary.position.distanceTo(secondary.position);
11002
+ const anchorDelta = new THREE51__namespace.Vector3().subVectors(
11003
+ basis.secondaryLocal,
11004
+ basis.primaryLocal
11005
+ );
11006
+ const anchorLength = anchorDelta.length();
11007
+ let factor = 1;
11008
+ if (options.allowScale && basis.initialSeparation > MIN_ANCHOR_SEPARATION && separation > MIN_ANCHOR_SEPARATION) {
11009
+ factor = separation / basis.initialSeparation;
11010
+ if (Math.abs(factor - 1) <= SCALE_DEADZONE) {
11011
+ factor = 1;
11012
+ } else {
11013
+ factor += factor > 1 ? -SCALE_DEADZONE : SCALE_DEADZONE;
11014
+ }
11015
+ factor = Math.min(options.maxScale, Math.max(options.minScale, factor));
11016
+ }
11017
+ const scale = basis.initialScale.clone().multiplyScalar(factor);
11018
+ const degenerate = separation < MIN_HAND_SEPARATION || anchorLength < MIN_ANCHOR_SEPARATION;
11019
+ const base = primary.quaternion.clone().multiply(basis.primaryHandOffset);
11020
+ let quaternion;
11021
+ if (options.rotationMode === "primary" || degenerate) {
11022
+ quaternion = base;
11023
+ } else {
11024
+ const axisLocal = anchorDelta.clone().normalize();
11025
+ const currentAxis = axisLocal.clone().applyQuaternion(base).normalize();
11026
+ const desiredAxis = new THREE51__namespace.Vector3().subVectors(secondary.position, primary.position).normalize();
11027
+ const correction = new THREE51__namespace.Quaternion().setFromUnitVectors(
11028
+ currentAxis,
11029
+ desiredAxis
11030
+ );
11031
+ quaternion = correction.multiply(base);
11032
+ }
11033
+ const anchorOffset = basis.primaryLocal.clone().multiply(scale).applyQuaternion(quaternion);
11034
+ const position = primary.position.clone().sub(anchorOffset);
11035
+ return { position, quaternion, scale, degenerate };
11036
+ }
11037
+ __name(solveTwoHandTransform, "solveTwoHandTransform");
10936
11038
 
10937
11039
  // core/systems/XRInteractionSystem.ts
10938
11040
  var RAYLESS_HOLD_DISTANCE = 0.5;
11041
+ function quatFromEulerVec(r) {
11042
+ return new THREE51__namespace.Quaternion().setFromEuler(new THREE51__namespace.Euler(r.x, r.y, r.z));
11043
+ }
11044
+ __name(quatFromEulerVec, "quatFromEulerVec");
11045
+ function writeEuler(target, q) {
11046
+ const euler = new THREE51__namespace.Euler().setFromQuaternion(q);
11047
+ target.x = euler.x;
11048
+ target.y = euler.y;
11049
+ target.z = euler.z;
11050
+ }
11051
+ __name(writeEuler, "writeEuler");
10939
11052
  var _XRInteractionSystem = class _XRInteractionSystem {
10940
11053
  constructor(inputSystem) {
10941
- this.raycaster = new THREE39__namespace.Raycaster();
11054
+ this.raycaster = new THREE51__namespace.Raycaster();
10942
11055
  this.grabs = /* @__PURE__ */ new Map();
10943
11056
  this.hoveredEntityId = null;
10944
11057
  /** Monotonic seconds, accumulated from deltaTime for velocity sampling. */
@@ -10961,7 +11074,6 @@ var _XRInteractionSystem = class _XRInteractionSystem {
10961
11074
  }
10962
11075
  const held = this.grabs.get(input);
10963
11076
  if (held) {
10964
- this.moveHeld(world, input, held, deltaTime);
10965
11077
  if (this.wantsRelease(world, input, held)) {
10966
11078
  this.release(world, input);
10967
11079
  }
@@ -10982,9 +11094,122 @@ var _XRInteractionSystem = class _XRInteractionSystem {
10982
11094
  /* starting */
10983
11095
  true
10984
11096
  )) {
10985
- this.grab(world, input, candidate.entityId, candidate.viaDistance);
11097
+ this.tryGrab(world, input, candidate.entityId, candidate.viaDistance);
10986
11098
  }
10987
11099
  }
11100
+ this.moveAllHeld(world, deltaTime);
11101
+ }
11102
+ /** Hands currently holding an entity. */
11103
+ holdersOf(entityId) {
11104
+ const holders = [];
11105
+ for (const [input, record] of this.grabs) {
11106
+ if (record.entityId === entityId) holders.push({ input, record });
11107
+ }
11108
+ return holders;
11109
+ }
11110
+ /**
11111
+ * Route a new grab: first hand, hand-off, or second hand.
11112
+ *
11113
+ * Which of those happens is the object's choice (`grabHands`), not the
11114
+ * hand's — a ball should pass between hands, a rifle should be held by both,
11115
+ * and a lever should stay with whoever grabbed it first.
11116
+ */
11117
+ tryGrab(world, input, entityId, viaDistance) {
11118
+ const interactable = world.getComponent(entityId, XRInteractableComponent);
11119
+ if (!interactable) return;
11120
+ const holders = this.holdersOf(entityId);
11121
+ if (holders.length === 0) {
11122
+ this.grab(world, input, entityId, viaDistance, "primary");
11123
+ return;
11124
+ }
11125
+ if (holders.some((holder) => holder.input === input)) return;
11126
+ if (interactable.grabHands === "single") return;
11127
+ if (interactable.grabHands === "handOff") {
11128
+ const previous = holders[0];
11129
+ this.grabs.delete(previous.input);
11130
+ const record = previous.record;
11131
+ record.role = "primary";
11132
+ record.twoHand = null;
11133
+ this.reanchor(world, input, record, interactable);
11134
+ this.grabs.set(input, record);
11135
+ this.dispatch(world, entityId, (b) => b.onGrab(input));
11136
+ return;
11137
+ }
11138
+ if (holders.length >= 2) return;
11139
+ this.grab(world, input, entityId, viaDistance, "secondary");
11140
+ this.beginTwoHand(world, entityId);
11141
+ }
11142
+ /**
11143
+ * Re-derive a record's hold from where the object is NOW.
11144
+ *
11145
+ * Used on hand-off and on promotion after the primary lets go. Without it the
11146
+ * object snaps to whatever offset the previous hand had, which reads as the
11147
+ * object jumping out of your grip at the moment you take it.
11148
+ */
11149
+ reanchor(world, input, record, interactable) {
11150
+ const transform = world.getComponent(record.entityId, TransformComponent);
11151
+ if (!transform) return;
11152
+ const hand = this.handPosition(input);
11153
+ const handQuaternion = this.handQuaternion(input);
11154
+ const objectQuaternion = quatFromEulerVec(transform.rotation);
11155
+ record.offset = new THREE51__namespace.Vector3(
11156
+ transform.position.x - hand.x,
11157
+ transform.position.y - hand.y,
11158
+ transform.position.z - hand.z
11159
+ );
11160
+ record.handRotationOffset = handQuaternion.clone().invert().multiply(objectQuaternion);
11161
+ record.remote = false;
11162
+ record.tracker.clear();
11163
+ record.tracker.record(hand, this.elapsed);
11164
+ record.lastHandQuaternion = handQuaternion.clone();
11165
+ if (record.attachLocal && interactable.attachPoints.length === 0) {
11166
+ record.attachLocal = null;
11167
+ record.attachQuaternion = null;
11168
+ record.attachPointId = null;
11169
+ }
11170
+ }
11171
+ /** Capture the two-hand basis once both hands are on the object. */
11172
+ beginTwoHand(world, entityId) {
11173
+ const holders = this.holdersOf(entityId);
11174
+ if (holders.length !== 2) return;
11175
+ const primary = holders.find((h) => h.record.role === "primary");
11176
+ const secondary = holders.find((h) => h.record.role === "secondary");
11177
+ if (!primary || !secondary) return;
11178
+ const transform = world.getComponent(entityId, TransformComponent);
11179
+ if (!transform) return;
11180
+ const primaryHand = this.handPosition(primary.input);
11181
+ const secondaryHand = this.handPosition(secondary.input);
11182
+ const primaryLocal = primary.record.attachLocal?.clone() ?? this.objectLocalPoint(transform, primaryHand);
11183
+ const secondaryLocal = secondary.record.attachLocal?.clone() ?? this.objectLocalPoint(transform, secondaryHand);
11184
+ primary.record.twoHand = {
11185
+ primaryLocal,
11186
+ secondaryLocal,
11187
+ initialScale: new THREE51__namespace.Vector3(
11188
+ transform.scale.x,
11189
+ transform.scale.y,
11190
+ transform.scale.z
11191
+ ),
11192
+ initialSeparation: primaryHand.distanceTo(secondaryHand),
11193
+ // How the object sits relative to the anchoring hand right now, so the
11194
+ // two-hand solve picks up exactly where the one-hand hold left off.
11195
+ primaryHandOffset: this.handQuaternion(primary.input).invert().multiply(quatFromEulerVec(transform.rotation)),
11196
+ initialQuaternion: quatFromEulerVec(transform.rotation)
11197
+ };
11198
+ this.dispatch(world, entityId, (b) => b.onSecondaryGrab(secondary.input));
11199
+ }
11200
+ /** World point → the object's UNSCALED local space. */
11201
+ objectLocalPoint(transform, worldPoint) {
11202
+ const local = worldPoint.clone().sub(
11203
+ new THREE51__namespace.Vector3(
11204
+ transform.position.x,
11205
+ transform.position.y,
11206
+ transform.position.z
11207
+ )
11208
+ ).applyQuaternion(quatFromEulerVec(transform.rotation).invert());
11209
+ local.x /= transform.scale.x || 1;
11210
+ local.y /= transform.scale.y || 1;
11211
+ local.z /= transform.scale.z || 1;
11212
+ return local;
10988
11213
  }
10989
11214
  /** Whether the grab gesture for this object is currently starting. */
10990
11215
  gestureMatches(input, interactable, starting) {
@@ -11033,7 +11258,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11033
11258
  );
11034
11259
  if (!interactable2) continue;
11035
11260
  if (interactable2.grabReach === "distance") continue;
11036
- const position = new THREE39__namespace.Vector3();
11261
+ const position = new THREE51__namespace.Vector3();
11037
11262
  entry.object.getWorldPosition(position);
11038
11263
  const distance = position.distanceTo(hand);
11039
11264
  if (distance <= interactable2.grabRadius && distance < nearestDistance) {
@@ -11057,7 +11282,9 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11057
11282
  if (!interactable?.enabled) continue;
11058
11283
  if (!world.isEntityVisible(entityId)) continue;
11059
11284
  const object = world.getComponent(entityId, Object3DRef)?.object;
11060
- if (object) out.push({ entityId, object });
11285
+ if (object) {
11286
+ out.push({ entityId, object, pointable: interactable.pointable });
11287
+ }
11061
11288
  }
11062
11289
  return out;
11063
11290
  }
@@ -11069,6 +11296,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11069
11296
  let nearestId = null;
11070
11297
  let nearestDistance = Number.POSITIVE_INFINITY;
11071
11298
  for (const entry of interactables) {
11299
+ if (!entry.pointable) continue;
11072
11300
  const hit = this.raycaster.intersectObject(entry.object, true)[0];
11073
11301
  if (!hit) continue;
11074
11302
  if (hit.distance < nearestDistance) {
@@ -11078,7 +11306,52 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11078
11306
  }
11079
11307
  return nearestId;
11080
11308
  }
11081
- grab(world, input, entityId, viaDistance) {
11309
+ /**
11310
+ * Pick the authored hold this hand should take.
11311
+ *
11312
+ * Filters by hand and by role — that is what makes "the trigger hand goes on
11313
+ * the grip" hold regardless of which hand reaches first — then takes the
11314
+ * nearest remaining one so grabbing near the foregrip picks the foregrip.
11315
+ */
11316
+ chooseAttachPoint(world, input, entityId, interactable, role) {
11317
+ if (interactable.attachPoints.length === 0) return null;
11318
+ const transform = world.getComponent(entityId, TransformComponent);
11319
+ if (!transform) return null;
11320
+ const taken = new Set(
11321
+ this.holdersOf(entityId).map((holder) => holder.record.attachPointId).filter((id) => id !== null)
11322
+ );
11323
+ const hand = this.handPosition(input);
11324
+ const objectPosition = new THREE51__namespace.Vector3(
11325
+ transform.position.x,
11326
+ transform.position.y,
11327
+ transform.position.z
11328
+ );
11329
+ const objectQuaternion = quatFromEulerVec(transform.rotation);
11330
+ const scale = new THREE51__namespace.Vector3(
11331
+ transform.scale.x,
11332
+ transform.scale.y,
11333
+ transform.scale.z
11334
+ );
11335
+ let best = null;
11336
+ let bestDistance = Number.POSITIVE_INFINITY;
11337
+ for (const point of interactable.attachPoints) {
11338
+ if (taken.has(point.id)) continue;
11339
+ if (point.hand !== "any" && point.hand !== input.handedness) continue;
11340
+ if (point.role !== "any" && point.role !== role) continue;
11341
+ const world3 = new THREE51__namespace.Vector3(
11342
+ point.position.x,
11343
+ point.position.y,
11344
+ point.position.z
11345
+ ).multiply(scale).applyQuaternion(objectQuaternion).add(objectPosition);
11346
+ const distance = world3.distanceTo(hand);
11347
+ if (distance < bestDistance) {
11348
+ bestDistance = distance;
11349
+ best = point;
11350
+ }
11351
+ }
11352
+ return best;
11353
+ }
11354
+ grab(world, input, entityId, viaDistance, role) {
11082
11355
  const transform = world.getComponent(entityId, TransformComponent);
11083
11356
  const interactable = world.getComponent(entityId, XRInteractableComponent);
11084
11357
  if (!transform || !interactable) return;
@@ -11088,21 +11361,21 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11088
11361
  let offset;
11089
11362
  let remoteDistance = 0;
11090
11363
  if (remote) {
11091
- const position = new THREE39__namespace.Vector3(
11364
+ const position = new THREE51__namespace.Vector3(
11092
11365
  transform.position.x,
11093
11366
  transform.position.y,
11094
11367
  transform.position.z
11095
11368
  );
11096
11369
  remoteDistance = position.distanceTo(input.rayOrigin);
11097
- offset = new THREE39__namespace.Vector3();
11370
+ offset = new THREE51__namespace.Vector3();
11098
11371
  } else if (viaDistance) {
11099
- offset = new THREE39__namespace.Vector3(
11372
+ offset = new THREE51__namespace.Vector3(
11100
11373
  interactable.grabOffsetPosition.x,
11101
11374
  interactable.grabOffsetPosition.y,
11102
11375
  interactable.grabOffsetPosition.z
11103
11376
  );
11104
11377
  } else {
11105
- offset = new THREE39__namespace.Vector3(
11378
+ offset = new THREE51__namespace.Vector3(
11106
11379
  transform.position.x - hand.x,
11107
11380
  transform.position.y - hand.y,
11108
11381
  transform.position.z - hand.z
@@ -11116,11 +11389,30 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11116
11389
  }
11117
11390
  const tracker = new ThrowVelocityTracker();
11118
11391
  tracker.record(hand, this.elapsed);
11392
+ const attachPoint = this.chooseAttachPoint(
11393
+ world,
11394
+ input,
11395
+ entityId,
11396
+ interactable,
11397
+ role
11398
+ );
11399
+ const objectQuaternion = quatFromEulerVec(transform.rotation);
11400
+ const handRotationOffset = handQuaternion.clone().invert().multiply(objectQuaternion);
11119
11401
  this.grabs.set(input, {
11120
11402
  entityId,
11403
+ role,
11404
+ attachPointId: attachPoint?.id ?? null,
11405
+ attachLocal: attachPoint ? new THREE51__namespace.Vector3(
11406
+ attachPoint.position.x,
11407
+ attachPoint.position.y,
11408
+ attachPoint.position.z
11409
+ ) : null,
11410
+ attachQuaternion: attachPoint ? quatFromEulerVec(attachPoint.rotation) : null,
11411
+ handRotationOffset,
11412
+ twoHand: null,
11121
11413
  offset,
11122
- rotationOffset: new THREE39__namespace.Quaternion().setFromEuler(
11123
- new THREE39__namespace.Euler(
11414
+ rotationOffset: new THREE51__namespace.Quaternion().setFromEuler(
11415
+ new THREE51__namespace.Euler(
11124
11416
  interactable.grabOffsetRotation.x,
11125
11417
  interactable.grabOffsetRotation.y,
11126
11418
  interactable.grabOffsetRotation.z
@@ -11131,33 +11423,110 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11131
11423
  restoreBodyType,
11132
11424
  tracker,
11133
11425
  lastHandQuaternion: handQuaternion.clone(),
11134
- angularVelocity: new THREE39__namespace.Vector3()
11426
+ angularVelocity: new THREE51__namespace.Vector3()
11135
11427
  });
11136
- this.dispatch(world, entityId, (b) => b.onGrab(input));
11428
+ if (role === "primary") {
11429
+ this.dispatch(world, entityId, (b) => b.onGrab(input));
11430
+ }
11431
+ }
11432
+ /** Drive every held object, once each, after grabs and releases settle. */
11433
+ moveAllHeld(world, deltaTime) {
11434
+ const done = /* @__PURE__ */ new Set();
11435
+ for (const [input, record] of this.grabs) {
11436
+ if (done.has(record.entityId)) continue;
11437
+ done.add(record.entityId);
11438
+ const holders = this.holdersOf(record.entityId);
11439
+ if (holders.length >= 2) {
11440
+ this.moveTwoHand(world, record.entityId, holders, deltaTime);
11441
+ } else {
11442
+ this.moveHeld(world, input, record, deltaTime);
11443
+ }
11444
+ }
11445
+ }
11446
+ /** Solve and apply a two-hand hold. */
11447
+ moveTwoHand(world, entityId, holders, deltaTime) {
11448
+ const primary = holders.find((h) => h.record.role === "primary");
11449
+ const secondary = holders.find((h) => h.record.role === "secondary");
11450
+ const transform = world.getComponent(entityId, TransformComponent);
11451
+ const interactable = world.getComponent(entityId, XRInteractableComponent);
11452
+ const basis = primary?.record.twoHand ?? null;
11453
+ if (!primary || !secondary || !transform || !interactable || !basis) {
11454
+ if (primary) {
11455
+ this.moveHeld(world, primary.input, primary.record, deltaTime);
11456
+ }
11457
+ return;
11458
+ }
11459
+ const primaryHand = this.handPosition(primary.input);
11460
+ const primaryQuaternion = this.handQuaternion(primary.input);
11461
+ const solved = solveTwoHandTransform(
11462
+ { position: primaryHand, quaternion: primaryQuaternion },
11463
+ {
11464
+ position: this.handPosition(secondary.input),
11465
+ quaternion: this.handQuaternion(secondary.input)
11466
+ },
11467
+ basis,
11468
+ {
11469
+ rotationMode: interactable.twoHandRotation,
11470
+ allowScale: interactable.allowTwoHandScale,
11471
+ minScale: interactable.minScale,
11472
+ maxScale: interactable.maxScale
11473
+ }
11474
+ );
11475
+ transform.position.x = solved.position.x;
11476
+ transform.position.y = solved.position.y;
11477
+ transform.position.z = solved.position.z;
11478
+ writeEuler(transform.rotation, solved.quaternion);
11479
+ if (interactable.allowTwoHandScale) {
11480
+ transform.scale.x = solved.scale.x;
11481
+ transform.scale.y = solved.scale.y;
11482
+ transform.scale.z = solved.scale.z;
11483
+ }
11484
+ primary.record.tracker.record(primaryHand, this.elapsed);
11485
+ primary.record.angularVelocity = angularVelocityFrom(
11486
+ primary.record.lastHandQuaternion,
11487
+ primaryQuaternion,
11488
+ deltaTime
11489
+ );
11490
+ primary.record.lastHandQuaternion = primaryQuaternion.clone();
11137
11491
  }
11138
11492
  moveHeld(world, input, held, deltaTime) {
11139
11493
  const transform = world.getComponent(held.entityId, TransformComponent);
11140
11494
  if (!transform) return;
11141
11495
  const hand = this.handPosition(input);
11496
+ const handQuaternion = this.handQuaternion(input);
11497
+ const objectQuaternion = held.attachQuaternion ? handQuaternion.clone().multiply(held.rotationOffset).multiply(held.attachQuaternion.clone().invert()) : handQuaternion.clone().multiply(held.handRotationOffset);
11142
11498
  if (held.remote) {
11143
- const target = new THREE39__namespace.Vector3().copy(input.rayDirection).multiplyScalar(held.remoteDistance).add(input.rayOrigin);
11499
+ const target = new THREE51__namespace.Vector3().copy(input.rayDirection).multiplyScalar(held.remoteDistance).add(input.rayOrigin);
11144
11500
  transform.position.x = target.x;
11145
11501
  transform.position.y = target.y;
11146
11502
  transform.position.z = target.z;
11503
+ writeEuler(transform.rotation, objectQuaternion);
11504
+ } else if (held.attachLocal) {
11505
+ const anchor = held.attachLocal.clone().multiply(
11506
+ new THREE51__namespace.Vector3(
11507
+ transform.scale.x,
11508
+ transform.scale.y,
11509
+ transform.scale.z
11510
+ )
11511
+ ).applyQuaternion(objectQuaternion);
11512
+ transform.position.x = hand.x - anchor.x;
11513
+ transform.position.y = hand.y - anchor.y;
11514
+ transform.position.z = hand.z - anchor.z;
11515
+ writeEuler(transform.rotation, objectQuaternion);
11147
11516
  } else {
11148
11517
  transform.position.x = hand.x + held.offset.x;
11149
11518
  transform.position.y = hand.y + held.offset.y;
11150
11519
  transform.position.z = hand.z + held.offset.z;
11520
+ writeEuler(transform.rotation, objectQuaternion);
11151
11521
  }
11152
11522
  held.tracker.record(
11153
- held.remote ? new THREE39__namespace.Vector3(
11523
+ held.remote ? new THREE51__namespace.Vector3(
11154
11524
  transform.position.x,
11155
11525
  transform.position.y,
11156
11526
  transform.position.z
11157
11527
  ) : hand,
11158
11528
  this.elapsed
11159
11529
  );
11160
- const handQuaternion = this.handQuaternion(input);
11161
11530
  held.angularVelocity = angularVelocityFrom(
11162
11531
  held.lastHandQuaternion,
11163
11532
  handQuaternion,
@@ -11173,6 +11542,30 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11173
11542
  held.entityId,
11174
11543
  XRInteractableComponent
11175
11544
  );
11545
+ const remaining = this.holdersOf(held.entityId);
11546
+ if (remaining.length > 0 && interactable) {
11547
+ if (held.role === "secondary") {
11548
+ const primary = remaining.find((h) => h.record.role === "primary");
11549
+ if (primary) {
11550
+ primary.record.twoHand = null;
11551
+ this.reanchor(world, primary.input, primary.record, interactable);
11552
+ }
11553
+ this.dispatch(
11554
+ world,
11555
+ held.entityId,
11556
+ (b) => b.onSecondaryRelease(input)
11557
+ );
11558
+ } else {
11559
+ const next = remaining[0];
11560
+ next.record.role = "primary";
11561
+ next.record.twoHand = null;
11562
+ next.record.restoreBodyType = held.restoreBodyType;
11563
+ this.reanchor(world, next.input, next.record, interactable);
11564
+ this.dispatch(world, held.entityId, (b) => b.onRelease(input));
11565
+ }
11566
+ held.tracker.clear();
11567
+ return;
11568
+ }
11176
11569
  const physics = world.getComponent(held.entityId, PhysicsComponent);
11177
11570
  if (held.restoreBodyType !== null && physics) {
11178
11571
  physics.values.rigidbody.type = held.restoreBodyType;
@@ -11206,7 +11599,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11206
11599
  */
11207
11600
  handPosition(input) {
11208
11601
  if (input.gripPosition) return input.gripPosition;
11209
- return new THREE39__namespace.Vector3().copy(input.rayDirection).multiplyScalar(RAYLESS_HOLD_DISTANCE).add(input.rayOrigin);
11602
+ return new THREE51__namespace.Vector3().copy(input.rayDirection).multiplyScalar(RAYLESS_HOLD_DISTANCE).add(input.rayOrigin);
11210
11603
  }
11211
11604
  /**
11212
11605
  * Hand orientation. Grip-less sources (gaze / transient-pointer) have none,
@@ -11214,8 +11607,8 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11214
11607
  */
11215
11608
  handQuaternion(input) {
11216
11609
  if (input.gripQuaternion) return input.gripQuaternion.clone();
11217
- return new THREE39__namespace.Quaternion().setFromUnitVectors(
11218
- new THREE39__namespace.Vector3(0, 0, -1),
11610
+ return new THREE51__namespace.Quaternion().setFromUnitVectors(
11611
+ new THREE51__namespace.Vector3(0, 0, -1),
11219
11612
  input.rayDirection.clone().normalize()
11220
11613
  );
11221
11614
  }
@@ -11240,6 +11633,29 @@ var _XRInteractionSystem = class _XRInteractionSystem {
11240
11633
  isGrabbing() {
11241
11634
  return this.grabs.size > 0;
11242
11635
  }
11636
+ /**
11637
+ * How an entity is currently held.
11638
+ *
11639
+ * Exposed for scripts: a Behaviour can poll this in `onUpdate` to drive
11640
+ * two-hand-specific behaviour — showing a bipod when both hands are on a
11641
+ * weapon, reading the live hand separation to gate a gesture, or reacting to
11642
+ * the scale a pull-apart produced. Returns null when nothing holds it.
11643
+ */
11644
+ getGrabInfo(entityId) {
11645
+ const holders = this.holdersOf(entityId);
11646
+ if (holders.length === 0) return null;
11647
+ const primary = holders.find((h) => h.record.role === "primary");
11648
+ const secondary = holders.find((h) => h.record.role === "secondary");
11649
+ return {
11650
+ hands: holders.length,
11651
+ primaryHandedness: primary?.input.handedness ?? null,
11652
+ secondaryHandedness: secondary?.input.handedness ?? null,
11653
+ handSeparation: primary && secondary ? this.handPosition(primary.input).distanceTo(
11654
+ this.handPosition(secondary.input)
11655
+ ) : null,
11656
+ attachPointIds: holders.map((h) => h.record.attachPointId)
11657
+ };
11658
+ }
11243
11659
  };
11244
11660
  __name(_XRInteractionSystem, "XRInteractionSystem");
11245
11661
  var XRInteractionSystem = _XRInteractionSystem;
@@ -11257,7 +11673,7 @@ function sampleTeleportArc(origin, direction, out = [], options) {
11257
11673
  for (let i = 0; i < steps; i += 1) {
11258
11674
  const t = i / (steps - 1) * maxTime;
11259
11675
  out.push(
11260
- new THREE39__namespace.Vector3(
11676
+ new THREE51__namespace.Vector3(
11261
11677
  origin.x + velocity.x * t,
11262
11678
  origin.y + velocity.y * t - 0.5 * gravity * t * t,
11263
11679
  origin.z + velocity.z * t
@@ -11274,7 +11690,7 @@ function arcGroundCrossing(points, groundY) {
11274
11690
  if (previous.y >= groundY && current.y <= groundY) {
11275
11691
  const span = previous.y - current.y;
11276
11692
  const alpha = span > 1e-6 ? (previous.y - groundY) / span : 0;
11277
- return new THREE39__namespace.Vector3().lerpVectors(previous, current, alpha);
11693
+ return new THREE51__namespace.Vector3().lerpVectors(previous, current, alpha);
11278
11694
  }
11279
11695
  }
11280
11696
  return null;
@@ -11282,11 +11698,11 @@ function arcGroundCrossing(points, groundY) {
11282
11698
  __name(arcGroundCrossing, "arcGroundCrossing");
11283
11699
 
11284
11700
  // core/systems/XRLocomotionSystem.ts
11285
- var UP = new THREE39__namespace.Vector3(0, 1, 0);
11701
+ var UP = new THREE51__namespace.Vector3(0, 1, 0);
11286
11702
  var AXIS_DEADZONE = 0.5;
11287
11703
  var _XRLocomotionSystem = class _XRLocomotionSystem {
11288
11704
  constructor(inputSystem) {
11289
- this.raycaster = new THREE39__namespace.Raycaster();
11705
+ this.raycaster = new THREE51__namespace.Raycaster();
11290
11706
  /** Per-source latch so one stick push yields exactly one snap turn. */
11291
11707
  this.turnLatched = /* @__PURE__ */ new WeakSet();
11292
11708
  /** Reused arc buffer — aiming runs every frame. */
@@ -11395,7 +11811,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
11395
11811
  }
11396
11812
  if (this.turnLatched.has(source)) continue;
11397
11813
  this.turnLatched.add(source);
11398
- transform.rotation.y -= Math.sign(x) * THREE39__namespace.MathUtils.degToRad(rig.snapTurnDegrees);
11814
+ transform.rotation.y -= Math.sign(x) * THREE51__namespace.MathUtils.degToRad(rig.snapTurnDegrees);
11399
11815
  }
11400
11816
  }
11401
11817
  applySmoothMove(world, rig, transform, inputs, deltaTime) {
@@ -11405,12 +11821,12 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
11405
11821
  const y = input.axes[1] ?? 0;
11406
11822
  if (Math.abs(x) < 0.15 && Math.abs(y) < 0.15) continue;
11407
11823
  const camera = world.getCamera();
11408
- const forward = new THREE39__namespace.Vector3();
11824
+ const forward = new THREE51__namespace.Vector3();
11409
11825
  camera.getWorldDirection(forward);
11410
11826
  forward.y = 0;
11411
11827
  if (forward.lengthSq() < 1e-6) continue;
11412
11828
  forward.normalize();
11413
- const right = new THREE39__namespace.Vector3().crossVectors(forward, UP).normalize();
11829
+ const right = new THREE51__namespace.Vector3().crossVectors(forward, UP).normalize();
11414
11830
  const step = rig.moveSpeed * Math.max(0, deltaTime);
11415
11831
  transform.position.x += (forward.x * -y + right.x * x) * step;
11416
11832
  transform.position.z += (forward.z * -y + right.z * x) * step;
@@ -11475,7 +11891,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
11475
11891
  for (let i = 1; i < points.length; i += 1) {
11476
11892
  const from = points[i - 1];
11477
11893
  const to = points[i];
11478
- const delta = new THREE39__namespace.Vector3().subVectors(to, from);
11894
+ const delta = new THREE51__namespace.Vector3().subVectors(to, from);
11479
11895
  const distance = delta.length();
11480
11896
  if (distance < 1e-6) continue;
11481
11897
  this.raycaster.set(from, delta.divideScalar(distance));
@@ -11683,9 +12099,9 @@ var XRSessionSystem = _XRSessionSystem;
11683
12099
  function buildGeometry2(area) {
11684
12100
  if (area.shape === "circle") {
11685
12101
  const radius = Math.max(5e-3, area.width / 2);
11686
- return new THREE39__namespace.CircleGeometry(radius, 48);
12102
+ return new THREE51__namespace.CircleGeometry(radius, 48);
11687
12103
  }
11688
- return new THREE39__namespace.PlaneGeometry(
12104
+ return new THREE51__namespace.PlaneGeometry(
11689
12105
  Math.max(0.01, area.width),
11690
12106
  Math.max(0.01, area.depth)
11691
12107
  );
@@ -11708,7 +12124,7 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
11708
12124
  for (const entityId of entityIds) {
11709
12125
  const area = world.getComponent(entityId, VRTeleportAreaComponent);
11710
12126
  const object = world.getComponent(entityId, Object3DRef)?.object;
11711
- if (!area || !(object instanceof THREE39__namespace.Mesh)) continue;
12127
+ if (!area || !(object instanceof THREE51__namespace.Mesh)) continue;
11712
12128
  const signature = signatureOf(area);
11713
12129
  if (this.signatures.get(entityId) === signature) continue;
11714
12130
  this.signatures.set(entityId, signature);
@@ -11720,18 +12136,18 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
11720
12136
  __name(_VRTeleportAreaSystem, "VRTeleportAreaSystem");
11721
12137
  var VRTeleportAreaSystem = _VRTeleportAreaSystem;
11722
12138
  function createHandMaterial(preset, options) {
11723
- const color = new THREE39__namespace.Color(options.color);
12139
+ const color = new THREE51__namespace.Color(options.color);
11724
12140
  switch (preset) {
11725
12141
  case "ghost":
11726
- return new THREE39__namespace.MeshBasicMaterial({
12142
+ return new THREE51__namespace.MeshBasicMaterial({
11727
12143
  color,
11728
12144
  transparent: true,
11729
12145
  opacity: Math.min(1, Math.max(0.05, options.opacity * 0.45)),
11730
12146
  depthWrite: false,
11731
- side: THREE39__namespace.DoubleSide
12147
+ side: THREE51__namespace.DoubleSide
11732
12148
  });
11733
12149
  case "neon":
11734
- return new THREE39__namespace.MeshStandardMaterial({
12150
+ return new THREE51__namespace.MeshStandardMaterial({
11735
12151
  color,
11736
12152
  emissive: color,
11737
12153
  emissiveIntensity: Math.max(0.5, options.emissiveIntensity || 2),
@@ -11741,7 +12157,7 @@ function createHandMaterial(preset, options) {
11741
12157
  opacity: options.opacity
11742
12158
  });
11743
12159
  case "skeleton":
11744
- return new THREE39__namespace.MeshBasicMaterial({
12160
+ return new THREE51__namespace.MeshBasicMaterial({
11745
12161
  color,
11746
12162
  wireframe: true,
11747
12163
  transparent: true,
@@ -11749,7 +12165,7 @@ function createHandMaterial(preset, options) {
11749
12165
  });
11750
12166
  case "custom":
11751
12167
  case "default":
11752
- return new THREE39__namespace.MeshStandardMaterial({
12168
+ return new THREE51__namespace.MeshStandardMaterial({
11753
12169
  color,
11754
12170
  roughness: 0.85,
11755
12171
  metalness: 0,
@@ -11757,10 +12173,10 @@ function createHandMaterial(preset, options) {
11757
12173
  emissiveIntensity: Math.max(0, options.emissiveIntensity),
11758
12174
  transparent: options.opacity < 1,
11759
12175
  opacity: options.opacity,
11760
- side: THREE39__namespace.DoubleSide
12176
+ side: THREE51__namespace.DoubleSide
11761
12177
  });
11762
12178
  default: {
11763
- return new THREE39__namespace.MeshStandardMaterial({ color });
12179
+ return new THREE51__namespace.MeshStandardMaterial({ color });
11764
12180
  }
11765
12181
  }
11766
12182
  }
@@ -11781,7 +12197,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
11781
12197
  constructor(options) {
11782
12198
  this.controllerModelFactory = new XRControllerModelFactory_js.XRControllerModelFactory();
11783
12199
  this.handModelFactory = new XRHandModelFactory_js.XRHandModelFactory();
11784
- this.group = new THREE39__namespace.Group();
12200
+ this.group = new THREE51__namespace.Group();
11785
12201
  this.slots = /* @__PURE__ */ new Map();
11786
12202
  this.attachedTo = null;
11787
12203
  /** Last applied preset signature, so materials rebuild only on real change. */
@@ -11930,17 +12346,17 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
11930
12346
  this.attachedTo = target;
11931
12347
  }
11932
12348
  createRay() {
11933
- const geometry = new THREE39__namespace.BufferGeometry().setFromPoints([
11934
- new THREE39__namespace.Vector3(0, 0, 0),
11935
- new THREE39__namespace.Vector3(0, 0, -5)
12349
+ const geometry = new THREE51__namespace.BufferGeometry().setFromPoints([
12350
+ new THREE51__namespace.Vector3(0, 0, 0),
12351
+ new THREE51__namespace.Vector3(0, 0, -5)
11936
12352
  ]);
11937
- const material = new THREE39__namespace.LineBasicMaterial({
12353
+ const material = new THREE51__namespace.LineBasicMaterial({
11938
12354
  color: "#4da3ff",
11939
12355
  transparent: true,
11940
12356
  opacity: 0.6,
11941
12357
  depthTest: false
11942
12358
  });
11943
- const line = new THREE39__namespace.Line(geometry, material);
12359
+ const line = new THREE51__namespace.Line(geometry, material);
11944
12360
  line.name = "XRPointerRay";
11945
12361
  line.renderOrder = 999;
11946
12362
  line.visible = false;
@@ -11969,23 +12385,23 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
11969
12385
  __name(_XRControllerVisualSystem, "XRControllerVisualSystem");
11970
12386
  var XRControllerVisualSystem = _XRControllerVisualSystem;
11971
12387
  var MARKER_RADIUS = 0.28;
11972
- var ACCENT = new THREE39__namespace.Color("#4da3ff");
11973
- var BLOCKED = new THREE39__namespace.Color("#ff5a5a");
12388
+ var ACCENT = new THREE51__namespace.Color("#4da3ff");
12389
+ var BLOCKED = new THREE51__namespace.Color("#ff5a5a");
11974
12390
  var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
11975
12391
  constructor(locomotionSystem) {
11976
- this.group = new THREE39__namespace.Group();
11977
- this.arcGeometry = new THREE39__namespace.BufferGeometry();
11978
- this.marker = new THREE39__namespace.Group();
12392
+ this.group = new THREE51__namespace.Group();
12393
+ this.arcGeometry = new THREE51__namespace.BufferGeometry();
12394
+ this.marker = new THREE51__namespace.Group();
11979
12395
  this.attached = false;
11980
12396
  this.locomotionSystem = locomotionSystem;
11981
12397
  this.group.name = "XRTeleportVisuals";
11982
12398
  this.group.userData.ecsPreviewHidden = true;
11983
- const arcMaterial = new THREE39__namespace.LineBasicMaterial({
12399
+ const arcMaterial = new THREE51__namespace.LineBasicMaterial({
11984
12400
  vertexColors: true,
11985
12401
  transparent: true,
11986
12402
  depthTest: false
11987
12403
  });
11988
- this.arc = new THREE39__namespace.Line(this.arcGeometry, arcMaterial);
12404
+ this.arc = new THREE51__namespace.Line(this.arcGeometry, arcMaterial);
11989
12405
  this.arc.frustumCulled = false;
11990
12406
  this.arc.renderOrder = 998;
11991
12407
  this.group.add(this.arc);
@@ -12033,39 +12449,39 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
12033
12449
  }
12034
12450
  this.arcGeometry.setAttribute(
12035
12451
  "position",
12036
- new THREE39__namespace.BufferAttribute(positions, 3)
12452
+ new THREE51__namespace.BufferAttribute(positions, 3)
12037
12453
  );
12038
- this.arcGeometry.setAttribute("color", new THREE39__namespace.BufferAttribute(colors, 3));
12454
+ this.arcGeometry.setAttribute("color", new THREE51__namespace.BufferAttribute(colors, 3));
12039
12455
  this.arcGeometry.computeBoundingSphere();
12040
12456
  }
12041
12457
  createRing() {
12042
- const geometry = new THREE39__namespace.RingGeometry(
12458
+ const geometry = new THREE51__namespace.RingGeometry(
12043
12459
  MARKER_RADIUS * 0.72,
12044
12460
  MARKER_RADIUS,
12045
12461
  48
12046
12462
  );
12047
12463
  geometry.rotateX(-Math.PI / 2);
12048
- return new THREE39__namespace.Mesh(
12464
+ return new THREE51__namespace.Mesh(
12049
12465
  geometry,
12050
- new THREE39__namespace.MeshBasicMaterial({
12466
+ new THREE51__namespace.MeshBasicMaterial({
12051
12467
  color: ACCENT,
12052
12468
  transparent: true,
12053
12469
  opacity: 0.9,
12054
- side: THREE39__namespace.DoubleSide,
12470
+ side: THREE51__namespace.DoubleSide,
12055
12471
  depthTest: false
12056
12472
  })
12057
12473
  );
12058
12474
  }
12059
12475
  createDot() {
12060
- const geometry = new THREE39__namespace.CircleGeometry(MARKER_RADIUS * 0.16, 24);
12476
+ const geometry = new THREE51__namespace.CircleGeometry(MARKER_RADIUS * 0.16, 24);
12061
12477
  geometry.rotateX(-Math.PI / 2);
12062
- return new THREE39__namespace.Mesh(
12478
+ return new THREE51__namespace.Mesh(
12063
12479
  geometry,
12064
- new THREE39__namespace.MeshBasicMaterial({
12480
+ new THREE51__namespace.MeshBasicMaterial({
12065
12481
  color: ACCENT,
12066
12482
  transparent: true,
12067
12483
  opacity: 0.55,
12068
- side: THREE39__namespace.DoubleSide,
12484
+ side: THREE51__namespace.DoubleSide,
12069
12485
  depthTest: false
12070
12486
  })
12071
12487
  );
@@ -12167,7 +12583,7 @@ function boneDirections(joints, finger) {
12167
12583
  const from = joints[chain[i - 1]];
12168
12584
  const to = joints[chain[i]];
12169
12585
  if (!from || !to) return null;
12170
- const direction = new THREE39__namespace.Vector3().subVectors(to, from);
12586
+ const direction = new THREE51__namespace.Vector3().subVectors(to, from);
12171
12587
  if (direction.lengthSq() < 1e-12) return null;
12172
12588
  directions.push(direction.normalize());
12173
12589
  }
@@ -12240,8 +12656,8 @@ function computeSpread(joints, a, b) {
12240
12656
  const bBase = joints[METACARPAL_JOINTS[b]];
12241
12657
  const bTip = joints[TIP_JOINTS[b]];
12242
12658
  if (!aBase || !aTip || !bBase || !bTip) return null;
12243
- const dirA = new THREE39__namespace.Vector3().subVectors(aTip, aBase);
12244
- const dirB = new THREE39__namespace.Vector3().subVectors(bTip, bBase);
12659
+ const dirA = new THREE51__namespace.Vector3().subVectors(aTip, aBase);
12660
+ const dirB = new THREE51__namespace.Vector3().subVectors(bTip, bBase);
12245
12661
  if (dirA.lengthSq() < 1e-12 || dirB.lengthSq() < 1e-12) return null;
12246
12662
  return clamp01((1 - dirA.normalize().dot(dirB.normalize())) / 0.45);
12247
12663
  }
@@ -12251,18 +12667,18 @@ function computePalmPose(joints, handedness) {
12251
12667
  const indexBase = joints["index-finger-metacarpal"];
12252
12668
  const pinkyBase = joints["pinky-finger-metacarpal"];
12253
12669
  if (!wrist || !indexBase || !pinkyBase) return null;
12254
- const u = new THREE39__namespace.Vector3().subVectors(indexBase, wrist);
12255
- const v = new THREE39__namespace.Vector3().subVectors(pinkyBase, wrist);
12256
- const normal = new THREE39__namespace.Vector3().crossVectors(u, v);
12670
+ const u = new THREE51__namespace.Vector3().subVectors(indexBase, wrist);
12671
+ const v = new THREE51__namespace.Vector3().subVectors(pinkyBase, wrist);
12672
+ const normal = new THREE51__namespace.Vector3().crossVectors(u, v);
12257
12673
  if (normal.lengthSq() < 1e-12) return null;
12258
12674
  normal.normalize();
12259
12675
  if (handedness === "left") normal.multiplyScalar(-1);
12260
- const right = new THREE39__namespace.Vector3().subVectors(indexBase, pinkyBase);
12676
+ const right = new THREE51__namespace.Vector3().subVectors(indexBase, pinkyBase);
12261
12677
  if (right.lengthSq() < 1e-12) return null;
12262
12678
  right.normalize();
12263
12679
  if (handedness === "left") right.multiplyScalar(-1);
12264
- const up = new THREE39__namespace.Vector3().crossVectors(normal, right).normalize();
12265
- const center = new THREE39__namespace.Vector3().add(wrist).add(indexBase).add(pinkyBase).divideScalar(3);
12680
+ const up = new THREE51__namespace.Vector3().crossVectors(normal, right).normalize();
12681
+ const center = new THREE51__namespace.Vector3().add(wrist).add(indexBase).add(pinkyBase).divideScalar(3);
12266
12682
  return {
12267
12683
  center,
12268
12684
  normal,
@@ -12293,7 +12709,7 @@ function computeHandShape(joints, handedness) {
12293
12709
  const thumbTip = joints["thumb-tip"];
12294
12710
  let thumbDirection = null;
12295
12711
  if (thumbBase && thumbTip) {
12296
- const direction = new THREE39__namespace.Vector3().subVectors(thumbTip, thumbBase);
12712
+ const direction = new THREE51__namespace.Vector3().subVectors(thumbTip, thumbBase);
12297
12713
  if (direction.lengthSq() > 1e-12) thumbDirection = direction.normalize();
12298
12714
  }
12299
12715
  return {
@@ -12325,12 +12741,12 @@ function scoreAgainst(actual, target, tolerance) {
12325
12741
  }
12326
12742
  __name(scoreAgainst, "scoreAgainst");
12327
12743
  var WORLD_DIRECTIONS = {
12328
- up: new THREE39__namespace.Vector3(0, 1, 0),
12329
- down: new THREE39__namespace.Vector3(0, -1, 0),
12330
- forward: new THREE39__namespace.Vector3(0, 0, -1),
12331
- back: new THREE39__namespace.Vector3(0, 0, 1),
12332
- left: new THREE39__namespace.Vector3(-1, 0, 0),
12333
- right: new THREE39__namespace.Vector3(1, 0, 0)
12744
+ up: new THREE51__namespace.Vector3(0, 1, 0),
12745
+ down: new THREE51__namespace.Vector3(0, -1, 0),
12746
+ forward: new THREE51__namespace.Vector3(0, 0, -1),
12747
+ back: new THREE51__namespace.Vector3(0, 0, 1),
12748
+ left: new THREE51__namespace.Vector3(-1, 0, 0),
12749
+ right: new THREE51__namespace.Vector3(1, 0, 0)
12334
12750
  };
12335
12751
  function axisVector(shape, axis) {
12336
12752
  if (axis === "thumb") return shape.thumbDirection;
@@ -12345,7 +12761,7 @@ function resolveDirection(direction, shape, context) {
12345
12761
  const head = context?.headPosition;
12346
12762
  const origin = shape.palm?.center;
12347
12763
  if (!head || !origin) return null;
12348
- const toHead = new THREE39__namespace.Vector3().subVectors(head, origin);
12764
+ const toHead = new THREE51__namespace.Vector3().subVectors(head, origin);
12349
12765
  if (toHead.lengthSq() < 1e-12) return null;
12350
12766
  toHead.normalize();
12351
12767
  return direction === "toward-head" ? toHead : toHead.multiplyScalar(-1);
@@ -12395,8 +12811,8 @@ function matchHandPose(shape, definition, context) {
12395
12811
  if (!handAxis || !wanted) {
12396
12812
  consider(0, "orientation");
12397
12813
  } else {
12398
- const angle = THREE39__namespace.MathUtils.radToDeg(
12399
- Math.acos(THREE39__namespace.MathUtils.clamp(handAxis.dot(wanted), -1, 1))
12814
+ const angle = THREE51__namespace.MathUtils.radToDeg(
12815
+ Math.acos(THREE51__namespace.MathUtils.clamp(handAxis.dot(wanted), -1, 1))
12400
12816
  );
12401
12817
  const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
12402
12818
  consider(clamp01(1 - normalizedError / MATCH_FALLOFF), "orientation");
@@ -12474,7 +12890,7 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
12474
12890
  this.trackers = /* @__PURE__ */ new Map();
12475
12891
  this.shapes = /* @__PURE__ */ new Map();
12476
12892
  /** Reused so head-relative orientation checks allocate nothing per frame. */
12477
- this.headPosition = new THREE39__namespace.Vector3();
12893
+ this.headPosition = new THREE51__namespace.Vector3();
12478
12894
  this.elapsed = 0;
12479
12895
  this.inputSystem = inputSystem;
12480
12896
  }
@@ -13265,8 +13681,8 @@ var _World = class _World {
13265
13681
  * ```
13266
13682
  */
13267
13683
  raycast(origin, direction, near = 0, far = Infinity) {
13268
- const rayOrigin = new THREE39__namespace.Vector3(origin.x, origin.y, origin.z);
13269
- const rayDirection = new THREE39__namespace.Vector3(
13684
+ const rayOrigin = new THREE51__namespace.Vector3(origin.x, origin.y, origin.z);
13685
+ const rayDirection = new THREE51__namespace.Vector3(
13270
13686
  direction.x,
13271
13687
  direction.y,
13272
13688
  direction.z
@@ -13275,7 +13691,7 @@ var _World = class _World {
13275
13691
  return [];
13276
13692
  }
13277
13693
  rayDirection.normalize();
13278
- const raycaster = new THREE39__namespace.Raycaster(rayOrigin, rayDirection, near, far);
13694
+ const raycaster = new THREE51__namespace.Raycaster(rayOrigin, rayDirection, near, far);
13279
13695
  const intersections = raycaster.intersectObjects(
13280
13696
  this.scene.children,
13281
13697
  true
@@ -13309,14 +13725,14 @@ var _World = class _World {
13309
13725
  if (!sourceObject) {
13310
13726
  return [];
13311
13727
  }
13312
- const rayOrigin = new THREE39__namespace.Vector3();
13313
- const rayDirection = new THREE39__namespace.Vector3();
13728
+ const rayOrigin = new THREE51__namespace.Vector3();
13729
+ const rayDirection = new THREE51__namespace.Vector3();
13314
13730
  sourceObject.getWorldPosition(rayOrigin);
13315
13731
  sourceObject.getWorldDirection(rayDirection);
13316
13732
  if (rayDirection.lengthSq() === 0) {
13317
13733
  return [];
13318
13734
  }
13319
- const raycaster = new THREE39__namespace.Raycaster(rayOrigin, rayDirection, near, far);
13735
+ const raycaster = new THREE51__namespace.Raycaster(rayOrigin, rayDirection, near, far);
13320
13736
  const intersections = raycaster.intersectObjects(
13321
13737
  this.scene.children,
13322
13738
  true
@@ -13997,6 +14413,7 @@ exports.InstancedMeshSystem = InstancedMeshSystem;
13997
14413
  exports.KeyboardKeys = KeyboardKeys;
13998
14414
  exports.LightSyncSystem = LightSyncSystem;
13999
14415
  exports.MATCH_FALLOFF = MATCH_FALLOFF;
14416
+ exports.MAX_PLAUSIBLE_SPEED = MAX_PLAUSIBLE_SPEED;
14000
14417
  exports.MAX_SAMPLE_AGE_SECONDS = MAX_SAMPLE_AGE_SECONDS;
14001
14418
  exports.MaterialSyncSystem = MaterialSyncSystem;
14002
14419
  exports.MeshGeometrySystem = MeshGeometrySystem;