@needle-tools/engine 4.3.0-alpha → 4.3.0-alpha.1

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 (101) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/needle-engine.bundle.js +1467 -222
  3. package/dist/needle-engine.bundle.light.js +1467 -222
  4. package/dist/needle-engine.bundle.light.min.js +32 -32
  5. package/dist/needle-engine.bundle.light.umd.cjs +3 -3
  6. package/dist/needle-engine.bundle.min.js +3 -3
  7. package/dist/needle-engine.bundle.umd.cjs +3 -3
  8. package/dist/needle-engine.light.d.ts +9 -9
  9. package/lib/engine/engine_types.d.ts +162 -17
  10. package/lib/engine-components/Animator.d.ts +129 -21
  11. package/lib/engine-components/Animator.js +115 -21
  12. package/lib/engine-components/Animator.js.map +1 -1
  13. package/lib/engine-components/AnimatorController.d.ts +161 -32
  14. package/lib/engine-components/AnimatorController.js +176 -29
  15. package/lib/engine-components/AnimatorController.js.map +1 -1
  16. package/lib/engine-components/AudioListener.d.ts +16 -5
  17. package/lib/engine-components/AudioListener.js +16 -5
  18. package/lib/engine-components/AudioListener.js.map +1 -1
  19. package/lib/engine-components/AudioSource.d.ts +120 -28
  20. package/lib/engine-components/AudioSource.js +120 -37
  21. package/lib/engine-components/AudioSource.js.map +1 -1
  22. package/lib/engine-components/AvatarLoader.d.ts +61 -0
  23. package/lib/engine-components/AvatarLoader.js +61 -1
  24. package/lib/engine-components/AvatarLoader.js.map +1 -1
  25. package/lib/engine-components/AxesHelper.d.ts +19 -1
  26. package/lib/engine-components/AxesHelper.js +19 -1
  27. package/lib/engine-components/AxesHelper.js.map +1 -1
  28. package/lib/engine-components/BoxHelperComponent.d.ts +26 -0
  29. package/lib/engine-components/BoxHelperComponent.js +26 -0
  30. package/lib/engine-components/BoxHelperComponent.js.map +1 -1
  31. package/lib/engine-components/Camera.d.ts +126 -37
  32. package/lib/engine-components/Camera.js +139 -37
  33. package/lib/engine-components/Camera.js.map +1 -1
  34. package/lib/engine-components/CameraUtils.js +20 -0
  35. package/lib/engine-components/CameraUtils.js.map +1 -1
  36. package/lib/engine-components/Collider.d.ts +95 -21
  37. package/lib/engine-components/Collider.js +100 -23
  38. package/lib/engine-components/Collider.js.map +1 -1
  39. package/lib/engine-components/Component.d.ts +554 -106
  40. package/lib/engine-components/Component.js +352 -81
  41. package/lib/engine-components/Component.js.map +1 -1
  42. package/lib/engine-components/DragControls.d.ts +95 -21
  43. package/lib/engine-components/DragControls.js +126 -32
  44. package/lib/engine-components/DragControls.js.map +1 -1
  45. package/lib/engine-components/DropListener.d.ts +99 -16
  46. package/lib/engine-components/DropListener.js +119 -14
  47. package/lib/engine-components/DropListener.js.map +1 -1
  48. package/lib/engine-components/Light.d.ts +102 -5
  49. package/lib/engine-components/Light.js +102 -44
  50. package/lib/engine-components/Light.js.map +1 -1
  51. package/lib/engine-components/NeedleMenu.d.ts +28 -11
  52. package/lib/engine-components/NeedleMenu.js +28 -11
  53. package/lib/engine-components/NeedleMenu.js.map +1 -1
  54. package/lib/engine-components/Networking.d.ts +37 -5
  55. package/lib/engine-components/Networking.js +37 -5
  56. package/lib/engine-components/Networking.js.map +1 -1
  57. package/lib/engine-components/SceneSwitcher.js +44 -0
  58. package/lib/engine-components/SceneSwitcher.js.map +1 -1
  59. package/lib/engine-components/SpatialTrigger.d.ts +66 -1
  60. package/lib/engine-components/SpatialTrigger.js +74 -2
  61. package/lib/engine-components/SpatialTrigger.js.map +1 -1
  62. package/lib/engine-components/SpectatorCamera.d.ts +66 -4
  63. package/lib/engine-components/SpectatorCamera.js +132 -6
  64. package/lib/engine-components/SpectatorCamera.js.map +1 -1
  65. package/lib/engine-components/SyncedTransform.d.ts +45 -6
  66. package/lib/engine-components/SyncedTransform.js +45 -6
  67. package/lib/engine-components/SyncedTransform.js.map +1 -1
  68. package/lib/engine-components/TransformGizmo.d.ts +49 -3
  69. package/lib/engine-components/TransformGizmo.js +49 -3
  70. package/lib/engine-components/TransformGizmo.js.map +1 -1
  71. package/lib/engine-components/webxr/WebXR.d.ts +131 -22
  72. package/lib/engine-components/webxr/WebXR.js +132 -23
  73. package/lib/engine-components/webxr/WebXR.js.map +1 -1
  74. package/lib/engine-components-experimental/networking/PlayerSync.d.ts +82 -9
  75. package/lib/engine-components-experimental/networking/PlayerSync.js +76 -11
  76. package/lib/engine-components-experimental/networking/PlayerSync.js.map +1 -1
  77. package/package.json +1 -1
  78. package/src/engine/engine_types.ts +179 -18
  79. package/src/engine-components/Animator.ts +142 -22
  80. package/src/engine-components/AnimatorController.ts +184 -34
  81. package/src/engine-components/AudioListener.ts +16 -5
  82. package/src/engine-components/AudioSource.ts +126 -37
  83. package/src/engine-components/AvatarLoader.ts +61 -2
  84. package/src/engine-components/AxesHelper.ts +21 -1
  85. package/src/engine-components/BoxHelperComponent.ts +26 -0
  86. package/src/engine-components/Camera.ts +147 -41
  87. package/src/engine-components/CameraUtils.ts +20 -0
  88. package/src/engine-components/Collider.ts +102 -27
  89. package/src/engine-components/Component.ts +605 -129
  90. package/src/engine-components/DragControls.ts +134 -38
  91. package/src/engine-components/DropListener.ts +143 -23
  92. package/src/engine-components/Light.ts +105 -44
  93. package/src/engine-components/NeedleMenu.ts +29 -11
  94. package/src/engine-components/Networking.ts +37 -6
  95. package/src/engine-components/SceneSwitcher.ts +48 -1
  96. package/src/engine-components/SpatialTrigger.ts +80 -3
  97. package/src/engine-components/SpectatorCamera.ts +136 -18
  98. package/src/engine-components/SyncedTransform.ts +50 -7
  99. package/src/engine-components/TransformGizmo.ts +49 -4
  100. package/src/engine-components/webxr/WebXR.ts +144 -27
  101. package/src/engine-components-experimental/networking/PlayerSync.ts +85 -13
@@ -1760,15 +1760,15 @@ function AC() {
1760
1760
  return n || null;
1761
1761
  }
1762
1762
  const V0 = S("debugdefines");
1763
- ko('if(!globalThis[""4.3.0-alpha""]) globalThis[""4.3.0-alpha""] = "0.0.0";');
1763
+ ko('if(!globalThis[""4.3.0-alpha.1""]) globalThis[""4.3.0-alpha.1""] = "0.0.0";');
1764
1764
  ko('if(!globalThis[""undefined""]) globalThis[""undefined""] = "unknown";');
1765
- ko('if(!globalThis[""Fri Feb 28 2025 13:27:32 GMT+0100 (Central European Standard Time)""]) globalThis[""Fri Feb 28 2025 13:27:32 GMT+0100 (Central European Standard Time)""] = "unknown";');
1765
+ ko('if(!globalThis[""Mon Mar 03 2025 10:04:15 GMT+0100 (Central European Standard Time)""]) globalThis[""Mon Mar 03 2025 10:04:15 GMT+0100 (Central European Standard Time)""] = "unknown";');
1766
1766
  ko('if(!globalThis[""npk_74222a9fbd1b42572cdd3bf7f639eeb17a07d07f40a6185fac5f722e8fd34df9""]) globalThis[""npk_74222a9fbd1b42572cdd3bf7f639eeb17a07d07f40a6185fac5f722e8fd34df9""] = "unknown";');
1767
- ko('globalThis["__NEEDLE_ENGINE_VERSION__"] = "4.3.0-alpha";');
1767
+ ko('globalThis["__NEEDLE_ENGINE_VERSION__"] = "4.3.0-alpha.1";');
1768
1768
  ko('globalThis["__NEEDLE_ENGINE_GENERATOR__"] = "undefined";');
1769
- ko('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Fri Feb 28 2025 13:27:32 GMT+0100 (Central European Standard Time)";');
1769
+ ko('globalThis["__NEEDLE_PROJECT_BUILD_TIME__"] = "Mon Mar 03 2025 10:04:15 GMT+0100 (Central European Standard Time)";');
1770
1770
  ko('globalThis["__NEEDLE_PUBLIC_KEY__"] = "npk_74222a9fbd1b42572cdd3bf7f639eeb17a07d07f40a6185fac5f722e8fd34df9";');
1771
- const Ns = "4.3.0-alpha", bg = "undefined", H0 = "Fri Feb 28 2025 13:27:32 GMT+0100 (Central European Standard Time)";
1771
+ const Ns = "4.3.0-alpha.1", bg = "undefined", H0 = "Mon Mar 03 2025 10:04:15 GMT+0100 (Central European Standard Time)";
1772
1772
  V0 && console.log(`Engine version: ${Ns} (generator: ${bg})
1773
1773
  Project built at ${H0}`);
1774
1774
  const ud = "npk_74222a9fbd1b42572cdd3bf7f639eeb17a07d07f40a6185fac5f722e8fd34df9", yo = "needle_isActiveInHierarchy", fa = "builtin_components", fd = "needle_editor_guid";
@@ -11791,42 +11791,75 @@ function sb(n) {
11791
11791
  class C extends D {
11792
11792
  constructor() {
11793
11793
  super(...arguments);
11794
+ /**
11795
+ * Unique identifier for this GameObject
11796
+ */
11794
11797
  r(this, "guid");
11795
11798
  }
11799
+ /**
11800
+ * Checks if a GameObject has been destroyed
11801
+ * @param go The GameObject to check
11802
+ * @returns True if the GameObject has been destroyed
11803
+ */
11796
11804
  static isDestroyed(e) {
11797
11805
  return Qa(e);
11798
11806
  }
11807
+ /**
11808
+ * Sets the active state of a GameObject
11809
+ * @param go The GameObject to modify
11810
+ * @param active Whether the GameObject should be active
11811
+ * @param processStart Whether to process the start callbacks if being activated
11812
+ */
11799
11813
  static setActive(e, i, s = !0) {
11800
11814
  e && (bd(e, i), pd(e), i && s && cv(ee.Current, e));
11801
11815
  }
11802
- /** If the object is active (same as go.visible) */
11816
+ /**
11817
+ * Checks if the GameObject itself is active (same as go.visible)
11818
+ * @param go The GameObject to check
11819
+ * @returns True if the GameObject is active
11820
+ */
11803
11821
  static isActiveSelf(e) {
11804
11822
  return Zc(e);
11805
11823
  }
11806
- /** If the object is active in the hierarchy (e.g. if any parent is invisible or not in the scene it will be false)
11807
- * @param go object to check
11808
- */
11824
+ /**
11825
+ * Checks if the GameObject is active in the hierarchy (e.g. if any parent is invisible or not in the scene it will be false)
11826
+ * @param go The GameObject to check
11827
+ * @returns True if the GameObject is active in the hierarchy
11828
+ */
11809
11829
  static isActiveInHierarchy(e) {
11810
11830
  return pO(e);
11811
11831
  }
11832
+ /**
11833
+ * Marks a GameObject to be rendered using instancing
11834
+ * @param go The GameObject to mark
11835
+ * @param instanced Whether the GameObject should use instanced rendering
11836
+ */
11812
11837
  static markAsInstancedRendered(e, i) {
11813
11838
  mO(e, i);
11814
11839
  }
11840
+ /**
11841
+ * Checks if a GameObject is using instanced rendering
11842
+ * @param instance The GameObject to check
11843
+ * @returns True if the GameObject is using instanced rendering
11844
+ */
11815
11845
  static isUsingInstancing(e) {
11816
11846
  return Ig(e);
11817
11847
  }
11818
- /** Run a callback for all components of the provided type on the provided object and its children (if recursive is true)
11819
- * @param instance object to run the method on
11820
- * @param cb callback to run on each component, "return undefined;" to continue and "return <anything>;" to break the loop
11821
- * @param recursive if true, the method will be run on all children as well
11822
- * @returns the last return value of the callback
11848
+ /**
11849
+ * Executes a callback for all components of the provided type on the provided object and its children
11850
+ * @param instance Object to run the method on
11851
+ * @param cb Callback to run on each component, "return undefined;" to continue and "return <anything>;" to break the loop
11852
+ * @param recursive If true, the method will be run on all children as well
11853
+ * @returns The last return value of the callback
11823
11854
  */
11824
11855
  static foreachComponent(e, i, s = !0) {
11825
11856
  return Ya(e, i, s);
11826
11857
  }
11827
- /** Creates a new instance of the provided object. The new instance will be created on all connected clients
11828
- * @param instance object to instantiate
11829
- * @param opts options for the instantiation
11858
+ /**
11859
+ * Creates a new instance of the provided object that will be replicated to all connected clients
11860
+ * @param instance Object to instantiate
11861
+ * @param opts Options for the instantiation
11862
+ * @returns The newly created instance or null if creation failed
11830
11863
  */
11831
11864
  static instantiateSynced(e, i) {
11832
11865
  return e ? fv(e, i) : null;
@@ -11834,24 +11867,31 @@ class C extends D {
11834
11867
  static instantiate(e, i = null) {
11835
11868
  return "isAssetReference" in e, Ka(e, i);
11836
11869
  }
11837
- /** Destroys a object on all connected clients (if you are in a networked session)
11838
- * @param instance object to destroy
11839
- */
11870
+ /**
11871
+ * Destroys an object on all connected clients (if in a networked session)
11872
+ * @param instance Object to destroy
11873
+ * @param context Optional context to use
11874
+ * @param recursive If true, all children will be destroyed as well
11875
+ */
11840
11876
  static destroySynced(e, i, s = !0) {
11841
11877
  if (!e)
11842
11878
  return;
11843
11879
  const o = e;
11844
11880
  i = i ?? ee.Current, ju(o, i.connection, s);
11845
11881
  }
11846
- /** Destroys a object
11847
- * @param instance object to destroy
11848
- * @param recursive if true, all children will be destroyed as well. true by default
11882
+ /**
11883
+ * Destroys an object
11884
+ * @param instance Object to destroy
11885
+ * @param recursive If true, all children will be destroyed as well. Default: true
11849
11886
  */
11850
11887
  static destroy(e, i = !0) {
11851
11888
  return ss(e, i);
11852
11889
  }
11853
11890
  /**
11854
- * Add an object to parent and also ensure all components are being registered
11891
+ * Adds an object to parent and ensures all components are properly registered
11892
+ * @param instance Object to add
11893
+ * @param parent Parent to add the object to
11894
+ * @param context Optional context to use
11855
11895
  */
11856
11896
  static add(e, i, s) {
11857
11897
  if (!(!e || !i)) {
@@ -11866,6 +11906,7 @@ class C extends D {
11866
11906
  }
11867
11907
  /**
11868
11908
  * Removes the object from its parent and deactivates all of its components
11909
+ * @param instance Object to remove
11869
11910
  */
11870
11911
  static remove(e) {
11871
11912
  var i;
@@ -11873,13 +11914,21 @@ class C extends D {
11873
11914
  kP(s);
11874
11915
  }, !0));
11875
11916
  }
11876
- /** Invokes a method on all components including children (if a method with that name exists) */
11917
+ /**
11918
+ * Invokes a method on all components including children (if a method with that name exists)
11919
+ * @param go GameObject to invoke the method on
11920
+ * @param functionName Name of the method to invoke
11921
+ * @param args Arguments to pass to the method
11922
+ */
11877
11923
  static invokeOnChildren(e, i, ...s) {
11878
11924
  this.invoke(e, i, !0, s);
11879
11925
  }
11880
- /** Invokes a method on all components that have a method matching the provided name
11881
- * @param go object to invoke the method on all components
11882
- * @param functionName name of the method to invoke
11926
+ /**
11927
+ * Invokes a method on all components that have a method matching the provided name
11928
+ * @param go GameObject to invoke the method on
11929
+ * @param functionName Name of the method to invoke
11930
+ * @param children Whether to invoke on children as well
11931
+ * @param args Arguments to pass to the method
11883
11932
  */
11884
11933
  static invoke(e, i, s = !1, ...o) {
11885
11934
  e && this.foreachComponent(e, (a) => {
@@ -11893,66 +11942,143 @@ class C extends D {
11893
11942
  return Ji(e, i, s, { callAwake: o });
11894
11943
  }
11895
11944
  /**
11896
- * Add a new component (or move an existing component) to the provided object
11897
- * @param go object to add the component to
11898
- * @param instanceOrType if an instance is provided it will be moved to the new object, if a type is provided a new instance will be created and moved to the new object
11899
- * @param init optional init object to initialize the component with
11900
- * @param callAwake if true, the component will be added and awake will be called immediately
11945
+ * Adds a new component (or moves an existing component) to the provided object
11946
+ * @param go Object to add the component to
11947
+ * @param instanceOrType If an instance is provided it will be moved to the new object, if a type is provided a new instance will be created
11948
+ * @param init Optional init object to initialize the component with
11949
+ * @param opts Optional options for adding the component
11950
+ * @returns The added or moved component
11901
11951
  */
11902
11952
  static addComponent(e, i, s, o) {
11903
11953
  return Ji(e, i, s, o);
11904
11954
  }
11905
11955
  /**
11906
- * Moves a component to a new object
11907
- * @param go component to move the component to
11908
- * @param instance component to move to the GO
11956
+ * Moves a component to a new object
11957
+ * @param go GameObject to move the component to
11958
+ * @param instance Component to move
11959
+ * @returns The moved component
11909
11960
  */
11910
11961
  static moveComponent(e, i) {
11911
11962
  return Ji(e, i);
11912
11963
  }
11913
- /** Removes a component from its object
11914
- * @param instance component to remove
11964
+ /**
11965
+ * Removes a component from its object
11966
+ * @param instance Component to remove
11967
+ * @returns The removed component
11915
11968
  */
11916
11969
  static removeComponent(e) {
11917
11970
  return wv(e.gameObject, e), e;
11918
11971
  }
11972
+ /**
11973
+ * Gets or adds a component of the specified type
11974
+ * @param go GameObject to get or add the component to
11975
+ * @param typeName Constructor of the component type
11976
+ * @returns The existing or newly added component
11977
+ */
11919
11978
  static getOrAddComponent(e, i) {
11920
11979
  return Bu(e, i);
11921
11980
  }
11922
- /** Gets a component on the provided object */
11981
+ /**
11982
+ * Gets a component on the provided object
11983
+ * @param go GameObject to get the component from
11984
+ * @param typeName Constructor of the component type
11985
+ * @returns The component if found, otherwise null
11986
+ */
11923
11987
  static getComponent(e, i) {
11924
11988
  return e === null ? null : il(e, i);
11925
11989
  }
11990
+ /**
11991
+ * Gets all components of the specified type on the provided object
11992
+ * @param go GameObject to get the components from
11993
+ * @param typeName Constructor of the component type
11994
+ * @param arr Optional array to populate with the components
11995
+ * @returns Array of components
11996
+ */
11926
11997
  static getComponents(e, i, s = null) {
11927
11998
  return e === null ? s ?? [] : Fu(e, i, s);
11928
11999
  }
12000
+ /**
12001
+ * Finds an object or component by its unique identifier
12002
+ * @param guid Unique identifier to search for
12003
+ * @param hierarchy Root object to search in
12004
+ * @returns The found GameObject or Component, or null/undefined if not found
12005
+ */
11929
12006
  static findByGuid(e, i) {
11930
12007
  return Cv(e, i);
11931
12008
  }
12009
+ /**
12010
+ * Finds the first object of the specified component type in the scene
12011
+ * @param typeName Constructor of the component type
12012
+ * @param context Context or root object to search in
12013
+ * @param includeInactive Whether to include inactive objects in the search
12014
+ * @returns The first matching component if found, otherwise null
12015
+ */
11932
12016
  static findObjectOfType(e, i, s = !0) {
11933
12017
  return Ag(e, i ?? ee.Current, s);
11934
12018
  }
12019
+ /**
12020
+ * Finds all objects of the specified component type in the scene
12021
+ * @param typeName Constructor of the component type
12022
+ * @param context Context or root object to search in
12023
+ * @returns Array of matching components
12024
+ */
11935
12025
  static findObjectsOfType(e, i) {
11936
12026
  const s = [];
11937
12027
  return fO(e, s, i), s;
11938
12028
  }
12029
+ /**
12030
+ * Gets a component of the specified type in the gameObject's children hierarchy
12031
+ * @param go GameObject to search in
12032
+ * @param typeName Constructor of the component type
12033
+ * @returns The first matching component if found, otherwise null
12034
+ */
11939
12035
  static getComponentInChildren(e, i) {
11940
12036
  return zu(e, i);
11941
12037
  }
12038
+ /**
12039
+ * Gets all components of the specified type in the gameObject's children hierarchy
12040
+ * @param go GameObject to search in
12041
+ * @param typeName Constructor of the component type
12042
+ * @param arr Optional array to populate with the components
12043
+ * @returns Array of components
12044
+ */
11942
12045
  static getComponentsInChildren(e, i, s = null) {
11943
12046
  return Kc(e, i, s ?? void 0);
11944
12047
  }
12048
+ /**
12049
+ * Gets a component of the specified type in the gameObject's parent hierarchy
12050
+ * @param go GameObject to search in
12051
+ * @param typeName Constructor of the component type
12052
+ * @returns The first matching component if found, otherwise null
12053
+ */
11945
12054
  static getComponentInParent(e, i) {
11946
12055
  return Wd(e, i);
11947
12056
  }
12057
+ /**
12058
+ * Gets all components of the specified type in the gameObject's parent hierarchy
12059
+ * @param go GameObject to search in
12060
+ * @param typeName Constructor of the component type
12061
+ * @param arr Optional array to populate with the components
12062
+ * @returns Array of components
12063
+ */
11948
12064
  static getComponentsInParent(e, i, s = null) {
11949
12065
  return Tg(e, i, s);
11950
12066
  }
12067
+ /**
12068
+ * Gets all components on the gameObject
12069
+ * @param go GameObject to get components from
12070
+ * @returns Array of all components
12071
+ */
11951
12072
  static getAllComponents(e) {
11952
12073
  var o;
11953
12074
  const i = (o = e.userData) == null ? void 0 : o.components;
11954
12075
  return i ? [...i] : [];
11955
12076
  }
12077
+ /**
12078
+ * Iterates through all components on the gameObject
12079
+ * @param go GameObject to iterate components on
12080
+ * @returns Generator yielding each component
12081
+ */
11956
12082
  static *iterateComponents(e) {
11957
12083
  var s;
11958
12084
  const i = (s = e == null ? void 0 : e.userData) == null ? void 0 : s.components;
@@ -11966,11 +12092,20 @@ const Mc = class {
11966
12092
  constructor(t) {
11967
12093
  r(this, "__context");
11968
12094
  r(this, "__name");
11969
- /** the object this component is attached to. Note that this is a threejs Object3D with some additional features */
12095
+ /**
12096
+ * Reference to the GameObject this component is attached to
12097
+ * This is a three.js Object3D with additional GameObject functionality
12098
+ */
11970
12099
  r(this, "gameObject");
11971
- /** the unique identifier for this component */
12100
+ /**
12101
+ * Unique identifier for this component instance,
12102
+ * used for finding and tracking components
12103
+ */
11972
12104
  r(this, "guid", "invalid");
11973
- /** holds the source identifier this object was created with/from (e.g. if it was part of a glTF file the sourceId holds the url to the glTF) */
12105
+ /**
12106
+ * Identifier for the source asset that created this component.
12107
+ * For example, URL to the glTF file this component was loaded from
12108
+ */
11974
12109
  r(this, "sourceId");
11975
12110
  /** @internal */
11976
12111
  r(this, "__didAwake", !1);
@@ -11983,31 +12118,49 @@ const Mc = class {
11983
12118
  /** @internal */
11984
12119
  r(this, "__destroyed", !1);
11985
12120
  // EventTarget implementation:
12121
+ /**
12122
+ * Storage for event listeners registered to this component
12123
+ * @private
12124
+ */
11986
12125
  r(this, "_eventListeners", /* @__PURE__ */ new Map());
11987
12126
  this.__didAwake = !1, this.__didStart = !1, this.__didEnable = !1, this.__isEnabled = void 0, this.__destroyed = !1, this._internalInit(t);
11988
12127
  }
11989
- /** @internal */
12128
+ /**
12129
+ * Indicates whether this object is a component
12130
+ * @internal
12131
+ */
11990
12132
  get isComponent() {
11991
12133
  return !0;
11992
12134
  }
11993
- /** Use the context to get access to many Needle Engine features and use physics, timing, access the camera or scene */
12135
+ /**
12136
+ * The context this component belongs to, providing access to the runtime environment
12137
+ * including physics, timing utilities, camera, and scene
12138
+ */
11994
12139
  get context() {
11995
12140
  return this.__context ?? ee.Current;
11996
12141
  }
11997
12142
  set context(t) {
11998
12143
  this.__context = t;
11999
12144
  }
12000
- /** shorthand for `this.context.scene`
12001
- * @returns the scene of the context */
12145
+ /**
12146
+ * Shorthand accessor for the current scene from the context
12147
+ * @returns The scene this component belongs to
12148
+ */
12002
12149
  get scene() {
12003
12150
  return this.context.scene;
12004
12151
  }
12005
- /** @returns the layer of the gameObject this component is attached to */
12152
+ /**
12153
+ * The layer value of the GameObject this component is attached to
12154
+ * Used for visibility and physics filtering
12155
+ */
12006
12156
  get layer() {
12007
12157
  var t, e;
12008
12158
  return (e = (t = this.gameObject) == null ? void 0 : t.userData) == null ? void 0 : e.layer;
12009
12159
  }
12010
- /** @returns the name of the gameObject this component is attached to */
12160
+ /**
12161
+ * The name of the GameObject this component is attached to
12162
+ * Used for debugging and finding objects
12163
+ */
12011
12164
  get name() {
12012
12165
  var t, e;
12013
12166
  return (t = this.gameObject) != null && t.name ? this.gameObject.name : (e = this.gameObject) == null ? void 0 : e.userData.name;
@@ -12015,7 +12168,10 @@ const Mc = class {
12015
12168
  set name(t) {
12016
12169
  this.gameObject ? (this.gameObject.userData || (this.gameObject.userData = {}), this.gameObject.userData.name = t, this.__name = t) : this.__name = t;
12017
12170
  }
12018
- /** @returns the tag of the gameObject this component is attached to */
12171
+ /**
12172
+ * The tag of the GameObject this component is attached to
12173
+ * Used for categorizing objects and efficient lookup
12174
+ */
12019
12175
  get tag() {
12020
12176
  var t;
12021
12177
  return (t = this.gameObject) == null ? void 0 : t.userData.tag;
@@ -12023,7 +12179,10 @@ const Mc = class {
12023
12179
  set tag(t) {
12024
12180
  this.gameObject && (this.gameObject.userData || (this.gameObject.userData = {}), this.gameObject.userData.tag = t);
12025
12181
  }
12026
- /** Is the gameObject marked as static */
12182
+ /**
12183
+ * Indicates whether the GameObject is marked as static
12184
+ * Static objects typically don't move and can be optimized by the engine
12185
+ */
12027
12186
  get static() {
12028
12187
  var t;
12029
12188
  return (t = this.gameObject) == null ? void 0 : t.userData.static;
@@ -12034,7 +12193,11 @@ const Mc = class {
12034
12193
  // get hideFlags(): HideFlags {
12035
12194
  // return this.gameObject?.hideFlags;
12036
12195
  // }
12037
- /** @returns true if the object is enabled and active in the hierarchy */
12196
+ /**
12197
+ * Checks if this component is currently active (enabled and part of an active GameObject hierarchy)
12198
+ * Components that are inactive won't receive lifecycle method calls
12199
+ * @returns True if the component is enabled and all parent GameObjects are active
12200
+ */
12038
12201
  get activeAndEnabled() {
12039
12202
  return !(this.destroyed || this.__isEnabled === !1 || !this.__isActiveInHierarchy);
12040
12203
  }
@@ -12050,39 +12213,60 @@ const Mc = class {
12050
12213
  set __isActiveInHierarchy(t) {
12051
12214
  this.gameObject && (this.gameObject[yo] = t);
12052
12215
  }
12053
- /** called once when the component becomes active for the first time (once per component)
12054
- * This is the first callback to be called */
12216
+ /**
12217
+ * Called once when the component becomes active for the first time.
12218
+ * This is the first lifecycle callback to be invoked
12219
+ */
12055
12220
  awake() {
12056
12221
  }
12057
- /** called every time when the component gets enabled (this is invoked after awake and before start)
12058
- * or when it becomes active in the hierarchy (e.g. if a parent object or this.gameObject gets set to visible)
12059
- */
12222
+ /**
12223
+ * Called every time the component becomes enabled or active in the hierarchy.
12224
+ * Invoked after {@link awake} and before {@link start}.
12225
+ */
12060
12226
  onEnable() {
12061
12227
  }
12062
- /** called every time the component gets disabled or if a parent object (or this.gameObject) gets set to invisible */
12228
+ /**
12229
+ * Called every time the component becomes disabled or inactive in the hierarchy.
12230
+ * Invoked when the component or any parent GameObject becomes invisible
12231
+ */
12063
12232
  onDisable() {
12064
12233
  }
12065
- /** Called when the component gets destroyed */
12234
+ /**
12235
+ * Called when the component is destroyed.
12236
+ * Use for cleanup operations like removing event listeners
12237
+ */
12066
12238
  onDestroy() {
12067
12239
  this.__destroyed = !0;
12068
12240
  }
12069
- /** starts a coroutine (javascript generator function)
12070
- * `yield` will wait for the next frame:
12071
- * - Use `yield WaitForSeconds(1)` to wait for 1 second.
12072
- * - Use `yield WaitForFrames(10)` to wait for 10 frames.
12073
- * - Use `yield new Promise(...)` to wait for a promise to resolve.
12074
- * @param routine generator function to start
12075
- * @param evt event to register the coroutine for (default: FrameEvent.Update). Note that all coroutine FrameEvent callbacks are invoked after the matching regular component callbacks. For example `FrameEvent.Update` will be called after regular component `update()` methods)
12076
- * @returns the generator function (use it to stop the coroutine with `stopCoroutine`)
12077
- * @example
12241
+ /**
12242
+ * Starts a coroutine that can yield to wait for events.
12243
+ * Coroutines allow for time-based sequencing of operations without blocking.
12244
+ * Coroutines are based on generator functions, a JavaScript language feature.
12245
+ *
12246
+ * @param routine Generator function to start
12247
+ * @param evt Event to register the coroutine for (default: FrameEvent.Update)
12248
+ * @returns The generator function that can be used to stop the coroutine
12249
+ * @example
12250
+ * Time-based sequencing of operations
12251
+ * ```ts
12252
+ * *myCoroutine() {
12253
+ * yield WaitForSeconds(1); // wait for 1 second
12254
+ * yield WaitForFrames(10); // wait for 10 frames
12255
+ * yield new Promise(resolve => setTimeout(resolve, 1000)); // wait for a promise to resolve
12256
+ * }
12257
+ * ```
12258
+ * @example
12259
+ * Coroutine that logs a message every 5 frames
12078
12260
  * ```ts
12079
- * onEnable() { this.startCoroutine(this.myCoroutine()); }
12261
+ * onEnable() {
12262
+ * this.startCoroutine(this.myCoroutine());
12263
+ * }
12080
12264
  * private *myCoroutine() {
12081
- * while(this.activeAndEnabled) {
12082
- * console.log("Hello World", this.context.time.frame);
12083
- * // wait for 5 frames
12084
- * for(let i = 0; i < 5; i++) yield;
12085
- * }
12265
+ * while(this.activeAndEnabled) {
12266
+ * console.log("Hello World", this.context.time.frame);
12267
+ * // wait for 5 frames
12268
+ * for(let i = 0; i < 5; i++) yield;
12269
+ * }
12086
12270
  * }
12087
12271
  * ```
12088
12272
  */
@@ -12090,19 +12274,23 @@ const Mc = class {
12090
12274
  return this.context.registerCoroutineUpdate(this, t, e);
12091
12275
  }
12092
12276
  /**
12093
- * Stop a coroutine that was previously started with `startCoroutine`
12094
- * @param routine the routine to be stopped
12095
- * @param evt the frame event to unregister the routine from (default: FrameEvent.Update)
12277
+ * Stops a coroutine that was previously started with startCoroutine
12278
+ * @param routine The routine to be stopped
12279
+ * @param evt The frame event the routine was registered with
12096
12280
  */
12097
12281
  stopCoroutine(t, e = Me.Update) {
12098
12282
  this.context.unregisterCoroutineUpdate(t, e);
12099
12283
  }
12100
- /** @returns true if this component was destroyed (`this.destroy()`) or the whole object this component was part of */
12284
+ /**
12285
+ * Checks if this component has been destroyed
12286
+ * @returns True if the component or its GameObject has been destroyed
12287
+ */
12101
12288
  get destroyed() {
12102
12289
  return this.__destroyed;
12103
12290
  }
12104
12291
  /**
12105
- * Destroys this component (and removes it from the object)
12292
+ * Destroys this component and removes it from its GameObject
12293
+ * After destruction, the component will no longer receive lifecycle callbacks
12106
12294
  */
12107
12295
  destroy() {
12108
12296
  this.__destroyed || this.__internalDestroy();
@@ -12115,6 +12303,11 @@ const Mc = class {
12115
12303
  __internalNewInstanceCreated(t) {
12116
12304
  return this.__didAwake = !1, this.__didStart = !1, this.__didEnable = !1, this.__isEnabled = void 0, this.__destroyed = !1, this._internalInit(t), this;
12117
12305
  }
12306
+ /**
12307
+ * Initializes component properties from an initialization object
12308
+ * @param init Object with properties to copy to this component
12309
+ * @internal
12310
+ */
12118
12311
  _internalInit(t) {
12119
12312
  if (typeof t == "object")
12120
12313
  for (const e of Object.keys(t)) {
@@ -12149,6 +12342,10 @@ const Mc = class {
12149
12342
  var t;
12150
12343
  this.__destroyed || (this.__destroyed = !0, this.__didAwake && ((t = this.onDestroy) == null || t.call(this), this.dispatchEvent(new CustomEvent("destroyed", { detail: this }))), uO(this));
12151
12344
  }
12345
+ /**
12346
+ * Controls whether this component is enabled
12347
+ * Disabled components don't receive lifecycle callbacks
12348
+ */
12152
12349
  get enabled() {
12153
12350
  return typeof this.__isEnabled == "boolean" ? this.__isEnabled : !0;
12154
12351
  }
@@ -12163,63 +12360,129 @@ const Mc = class {
12163
12360
  }
12164
12361
  t ? this.__internalEnable() : this.__internalDisable();
12165
12362
  }
12363
+ /**
12364
+ * Gets the position of this component's GameObject in world space
12365
+ */
12166
12366
  get worldPosition() {
12167
12367
  return te(this.gameObject);
12168
12368
  }
12369
+ /**
12370
+ * Sets the position of this component's GameObject in world space
12371
+ * @param val The world position vector to set
12372
+ */
12169
12373
  set worldPosition(t) {
12170
12374
  yt(this.gameObject, t);
12171
12375
  }
12376
+ /**
12377
+ * Sets the position of this component's GameObject in world space using individual coordinates
12378
+ * @param x X-coordinate in world space
12379
+ * @param y Y-coordinate in world space
12380
+ * @param z Z-coordinate in world space
12381
+ */
12172
12382
  setWorldPosition(t, e, i) {
12173
12383
  Va(this.gameObject, t, e, i);
12174
12384
  }
12385
+ /**
12386
+ * Gets the rotation of this component's GameObject in world space as a quaternion
12387
+ */
12175
12388
  get worldQuaternion() {
12176
12389
  return Pe(this.gameObject);
12177
12390
  }
12391
+ /**
12392
+ * Sets the rotation of this component's GameObject in world space using a quaternion
12393
+ * @param val The world rotation quaternion to set
12394
+ */
12178
12395
  set worldQuaternion(t) {
12179
12396
  vs(this.gameObject, t);
12180
12397
  }
12398
+ /**
12399
+ * Sets the rotation of this component's GameObject in world space using quaternion components
12400
+ * @param x X component of the quaternion
12401
+ * @param y Y component of the quaternion
12402
+ * @param z Z component of the quaternion
12403
+ * @param w W component of the quaternion
12404
+ */
12181
12405
  setWorldQuaternion(t, e, i, s) {
12182
12406
  I0(this.gameObject, t, e, i, s);
12183
12407
  }
12184
- // world euler (in radians)
12408
+ /**
12409
+ * Gets the rotation of this component's GameObject in world space as Euler angles (in radians)
12410
+ */
12185
12411
  get worldEuler() {
12186
12412
  return D0(this.gameObject);
12187
12413
  }
12188
- // world euler (in radians)
12414
+ /**
12415
+ * Sets the rotation of this component's GameObject in world space using Euler angles (in radians)
12416
+ * @param val The world rotation Euler angles to set
12417
+ */
12189
12418
  set worldEuler(t) {
12190
12419
  L0(this.gameObject, t);
12191
12420
  }
12192
- // returns rotation in degrees
12421
+ /**
12422
+ * Gets the rotation of this component's GameObject in world space as Euler angles (in degrees)
12423
+ */
12193
12424
  get worldRotation() {
12194
12425
  return this.gameObject.worldRotation;
12195
12426
  }
12427
+ /**
12428
+ * Sets the rotation of this component's GameObject in world space using Euler angles (in degrees)
12429
+ * @param val The world rotation vector to set (in degrees)
12430
+ */
12196
12431
  set worldRotation(t) {
12197
12432
  this.setWorldRotation(t.x, t.y, t.z, !0);
12198
12433
  }
12434
+ /**
12435
+ * Sets the rotation of this component's GameObject in world space using individual Euler angles
12436
+ * @param x X-axis rotation
12437
+ * @param y Y-axis rotation
12438
+ * @param z Z-axis rotation
12439
+ * @param degrees Whether the values are in degrees (true) or radians (false)
12440
+ */
12199
12441
  setWorldRotation(t, e, i, s = !0) {
12200
12442
  Eu(this.gameObject, t, e, i, s);
12201
12443
  }
12202
- /** Forward (0,0,-1) vector in world space */
12444
+ /**
12445
+ * Gets the forward direction vector (0,0,-1) of this component's GameObject in world space
12446
+ */
12203
12447
  get forward() {
12204
12448
  return Mc._forward.set(0, 0, -1).applyQuaternion(this.worldQuaternion);
12205
12449
  }
12206
- /** Right (1,0,0) vector in world space */
12450
+ /**
12451
+ * Gets the right direction vector (1,0,0) of this component's GameObject in world space
12452
+ */
12207
12453
  get right() {
12208
12454
  return Mc._right.set(1, 0, 0).applyQuaternion(this.worldQuaternion);
12209
12455
  }
12210
- /** Up (0,1,0) vector in world space */
12456
+ /**
12457
+ * Gets the up direction vector (0,1,0) of this component's GameObject in world space
12458
+ */
12211
12459
  get up() {
12212
12460
  return Mc._up.set(0, 1, 0).applyQuaternion(this.worldQuaternion);
12213
12461
  }
12462
+ /**
12463
+ * Registers an event listener for the specified event type
12464
+ * @param type The event type to listen for
12465
+ * @param listener The callback function to execute when the event occurs
12466
+ */
12214
12467
  addEventListener(t, e) {
12215
12468
  this._eventListeners[t] = this._eventListeners[t] || [], this._eventListeners[t].push(e);
12216
12469
  }
12470
+ /**
12471
+ * Removes a previously registered event listener
12472
+ * @param type The event type the listener was registered for
12473
+ * @param listener The callback function to remove
12474
+ */
12217
12475
  removeEventListener(t, e) {
12218
12476
  if (!this._eventListeners[t])
12219
12477
  return;
12220
12478
  const i = this._eventListeners[t].indexOf(e);
12221
12479
  i >= 0 && this._eventListeners[t].splice(i, 1);
12222
12480
  }
12481
+ /**
12482
+ * Dispatches an event to all registered listeners
12483
+ * @param evt The event object to dispatch
12484
+ * @returns Always returns false (standard implementation of EventTarget)
12485
+ */
12223
12486
  dispatchEvent(t) {
12224
12487
  if (!t || !this._eventListeners[t.type])
12225
12488
  return !1;
@@ -12758,11 +13021,18 @@ const rt = S("debuganimatorcontroller"), zh = S("debugrootmotion");
12758
13021
  class es {
12759
13022
  constructor(t) {
12760
13023
  r(this, "_speed", 1);
12761
- /** The normalized time of the start state. This is used to determine the start time of the first state. */
13024
+ /**
13025
+ * The normalized time (0-1) to start playing the first state at.
13026
+ * This affects the initial state when the animator is first enabled.
13027
+ */
12762
13028
  r(this, "normalizedStartOffset", 0);
12763
- /** the animator that this controller is bound to */
13029
+ /**
13030
+ * The Animator component this controller is bound to.
13031
+ */
12764
13032
  r(this, "animator");
12765
- /** the model that this controller is based on */
13033
+ /**
13034
+ * The data model describing the animation states and transitions.
13035
+ */
12766
13036
  r(this, "model");
12767
13037
  r(this, "_mixer");
12768
13038
  r(this, "_activeState");
@@ -12775,11 +13045,14 @@ class es {
12775
13045
  r(this, "rootMotionHandler");
12776
13046
  this.model = t, rt && console.log(this);
12777
13047
  }
12778
- /** Create an animatorcontroller. States are created from the clips array.
12779
- * @param clips the clips to assign to the controller
12780
- * @param options options to control the creation of the controller.
12781
- * @returns the created animator controller
12782
- */
13048
+ /**
13049
+ * Creates an AnimatorController from a set of animation clips.
13050
+ * Each clip becomes a state in the controller's state machine.
13051
+ *
13052
+ * @param clips - The animation clips to use for creating states
13053
+ * @param options - Configuration options for the controller including looping behavior and transitions
13054
+ * @returns A new AnimatorController instance
13055
+ */
12783
13056
  static createFromClips(t, e = { looping: !1, autoTransition: !0, transitionDuration: 0 }) {
12784
13057
  const i = [];
12785
13058
  for (let a = 0; a < t.length; a++) {
@@ -12824,6 +13097,14 @@ class es {
12824
13097
  };
12825
13098
  return new es(s);
12826
13099
  }
13100
+ /**
13101
+ * Plays an animation state by name or hash.
13102
+ *
13103
+ * @param name - The name or hash identifier of the state to play
13104
+ * @param layerIndex - The layer index (defaults to 0)
13105
+ * @param normalizedTime - The normalized time to start the animation from (0-1)
13106
+ * @param durationInSec - Transition duration in seconds
13107
+ */
12827
13108
  play(t, e = -1, i = Number.NEGATIVE_INFINITY, s = 0) {
12828
13109
  if (e < 0)
12829
13110
  e = 0;
@@ -12839,55 +13120,117 @@ class es {
12839
13120
  }
12840
13121
  console.warn("Could not find " + t + " to play");
12841
13122
  }
13123
+ /**
13124
+ * Resets the controller to its initial state.
13125
+ */
12842
13126
  reset() {
12843
13127
  this.setStartTransition();
12844
13128
  }
13129
+ /**
13130
+ * Sets a boolean parameter value by name or hash.
13131
+ *
13132
+ * @param name - The name or hash identifier of the parameter
13133
+ * @param value - The boolean value to set
13134
+ */
12845
13135
  setBool(t, e) {
12846
13136
  var s, o;
12847
13137
  const i = typeof t == "string" ? "name" : "hash";
12848
13138
  return (o = (s = this.model) == null ? void 0 : s.parameters) == null ? void 0 : o.filter((a) => a[i] === t).forEach((a) => a.value = e);
12849
13139
  }
13140
+ /**
13141
+ * Gets a boolean parameter value by name or hash.
13142
+ *
13143
+ * @param name - The name or hash identifier of the parameter
13144
+ * @returns The boolean value of the parameter, or false if not found
13145
+ */
12850
13146
  getBool(t) {
12851
13147
  var i, s, o;
12852
13148
  const e = typeof t == "string" ? "name" : "hash";
12853
13149
  return ((o = (s = (i = this.model) == null ? void 0 : i.parameters) == null ? void 0 : s.find((a) => a[e] === t)) == null ? void 0 : o.value) ?? !1;
12854
13150
  }
13151
+ /**
13152
+ * Sets a float parameter value by name or hash.
13153
+ *
13154
+ * @param name - The name or hash identifier of the parameter
13155
+ * @param val - The float value to set
13156
+ * @returns True if the parameter was found and set, false otherwise
13157
+ */
12855
13158
  setFloat(t, e) {
12856
13159
  var o, a;
12857
13160
  const i = typeof t == "string" ? "name" : "hash", s = (a = (o = this.model) == null ? void 0 : o.parameters) == null ? void 0 : a.filter((l) => l[i] === t);
12858
13161
  return s.forEach((l) => l.value = e), (s == null ? void 0 : s.length) > 0;
12859
13162
  }
13163
+ /**
13164
+ * Gets a float parameter value by name or hash.
13165
+ *
13166
+ * @param name - The name or hash identifier of the parameter
13167
+ * @returns The float value of the parameter, or 0 if not found
13168
+ */
12860
13169
  getFloat(t) {
12861
13170
  var i, s, o;
12862
13171
  const e = typeof t == "string" ? "name" : "hash";
12863
13172
  return ((o = (s = (i = this.model) == null ? void 0 : i.parameters) == null ? void 0 : s.find((a) => a[e] === t)) == null ? void 0 : o.value) ?? 0;
12864
13173
  }
13174
+ /**
13175
+ * Sets an integer parameter value by name or hash.
13176
+ *
13177
+ * @param name - The name or hash identifier of the parameter
13178
+ * @param val - The integer value to set
13179
+ */
12865
13180
  setInteger(t, e) {
12866
13181
  var s, o;
12867
13182
  const i = typeof t == "string" ? "name" : "hash";
12868
13183
  return (o = (s = this.model) == null ? void 0 : s.parameters) == null ? void 0 : o.filter((a) => a[i] === t).forEach((a) => a.value = e);
12869
13184
  }
13185
+ /**
13186
+ * Gets an integer parameter value by name or hash.
13187
+ *
13188
+ * @param name - The name or hash identifier of the parameter
13189
+ * @returns The integer value of the parameter, or 0 if not found
13190
+ */
12870
13191
  getInteger(t) {
12871
13192
  var i, s, o;
12872
13193
  const e = typeof t == "string" ? "name" : "hash";
12873
13194
  return ((o = (s = (i = this.model) == null ? void 0 : i.parameters) == null ? void 0 : s.find((a) => a[e] === t)) == null ? void 0 : o.value) ?? 0;
12874
13195
  }
13196
+ /**
13197
+ * Sets a trigger parameter to active (true).
13198
+ * Trigger parameters are automatically reset after they are consumed by a transition.
13199
+ *
13200
+ * @param name - The name or hash identifier of the trigger parameter
13201
+ */
12875
13202
  setTrigger(t) {
12876
13203
  var i, s;
12877
13204
  rt && console.log("SET TRIGGER", t);
12878
13205
  const e = typeof t == "string" ? "name" : "hash";
12879
13206
  return (s = (i = this.model) == null ? void 0 : i.parameters) == null ? void 0 : s.filter((o) => o[e] === t).forEach((o) => o.value = !0);
12880
13207
  }
13208
+ /**
13209
+ * Resets a trigger parameter to inactive (false).
13210
+ *
13211
+ * @param name - The name or hash identifier of the trigger parameter
13212
+ */
12881
13213
  resetTrigger(t) {
12882
13214
  var i, s;
12883
13215
  const e = typeof t == "string" ? "name" : "hash";
12884
13216
  return (s = (i = this.model) == null ? void 0 : i.parameters) == null ? void 0 : s.filter((o) => o[e] === t).forEach((o) => o.value = !1);
12885
13217
  }
13218
+ /**
13219
+ * Gets the current state of a trigger parameter.
13220
+ *
13221
+ * @param name - The name or hash identifier of the trigger parameter
13222
+ * @returns The boolean state of the trigger, or false if not found
13223
+ */
12886
13224
  getTrigger(t) {
12887
13225
  var i, s, o;
12888
13226
  const e = typeof t == "string" ? "name" : "hash";
12889
13227
  return ((o = (s = (i = this.model) == null ? void 0 : i.parameters) == null ? void 0 : s.find((a) => a[e] === t)) == null ? void 0 : o.value) ?? !1;
12890
13228
  }
13229
+ /**
13230
+ * Checks if the controller is currently in a transition between states.
13231
+ *
13232
+ * @returns True if a transition is in progress, false otherwise
13233
+ */
12891
13234
  isInTransition() {
12892
13235
  return this._activeStates.length > 1;
12893
13236
  }
@@ -12895,10 +13238,22 @@ class es {
12895
13238
  setSpeed(t) {
12896
13239
  this._speed = t;
12897
13240
  }
12898
- /**@deprecated use findState */
13241
+ /**
13242
+ * Finds an animation state by name or hash.
13243
+ * @deprecated Use findState instead
13244
+ *
13245
+ * @param name - The name or hash identifier of the state to find
13246
+ * @returns The found state or null if not found
13247
+ */
12899
13248
  FindState(t) {
12900
13249
  return this.findState(t);
12901
13250
  }
13251
+ /**
13252
+ * Finds an animation state by name or hash.
13253
+ *
13254
+ * @param name - The name or hash identifier of the state to find
13255
+ * @returns The found state or null if not found
13256
+ */
12902
13257
  findState(t) {
12903
13258
  if (!t)
12904
13259
  return null;
@@ -12910,9 +13265,11 @@ class es {
12910
13265
  }
12911
13266
  return null;
12912
13267
  }
12913
- /** Get the current state info
12914
- * @returns the current state info or null if no state is active
12915
- */
13268
+ /**
13269
+ * Gets information about the current playing animation state.
13270
+ *
13271
+ * @returns An AnimatorStateInfo object with data about the current state, or null if no state is active
13272
+ */
12916
13273
  getCurrentStateInfo() {
12917
13274
  if (!this._activeState)
12918
13275
  return null;
@@ -12922,27 +13279,33 @@ class es {
12922
13279
  const e = this._activeState.motion.clip.duration, i = e <= 0 ? 0 : Math.abs(t.time / e);
12923
13280
  return new Fh(this._activeState, i, e, this._speed);
12924
13281
  }
12925
- /** Get the current action (shorthand for activeState.motion.action)
12926
- * @returns the current action that is playing. This is the action that is currently transitioning to or playing.
12927
- * If no action is playing null is returned.
12928
- **/
13282
+ /**
13283
+ * Gets the animation action currently playing.
13284
+ *
13285
+ * @returns The current animation action, or null if no action is playing
13286
+ */
12929
13287
  get currentAction() {
12930
13288
  if (!this._activeState)
12931
13289
  return null;
12932
13290
  const t = this._activeState.motion.action;
12933
13291
  return t || null;
12934
13292
  }
12935
- /** Get the context of the animator */
13293
+ /**
13294
+ * Gets the engine context from the bound animator.
13295
+ */
12936
13296
  get context() {
12937
13297
  var t;
12938
13298
  return (t = this.animator) == null ? void 0 : t.context;
12939
13299
  }
12940
- /** Get the animation mixer that is used to play the animations */
13300
+ /**
13301
+ * Gets the animation mixer used by this controller.
13302
+ */
12941
13303
  get mixer() {
12942
13304
  return this._mixer;
12943
13305
  }
12944
13306
  /**
12945
- * Clears the animation mixer and unregisters it from the context.
13307
+ * Cleans up resources used by this controller.
13308
+ * Stops all animations and unregisters the mixer from the animation system.
12946
13309
  */
12947
13310
  dispose() {
12948
13311
  var t;
@@ -12956,12 +13319,22 @@ class es {
12956
13319
  // applyRootMotion(obj: Object3D) {
12957
13320
  // // this.internalApplyRootMotion(obj);
12958
13321
  // }
12959
- /** Bind the animator to the controller. Only one animator can be bound to a controller at a time. */
13322
+ /**
13323
+ * Binds this controller to an animator component.
13324
+ * Creates a new animation mixer and sets up animation actions.
13325
+ *
13326
+ * @param animator - The animator to bind this controller to
13327
+ */
12960
13328
  bind(t) {
12961
13329
  var e, i;
12962
13330
  t ? this.animator !== t && (this._mixer && (this._mixer.stopAllAction(), (e = this.context) == null || e.animations.unregisterAnimationMixer(this._mixer)), this.animator = t, this._mixer = new rg(this.animator.gameObject), (i = this.context) == null || i.animations.registerAnimationMixer(this._mixer), this.createActions(this.animator)) : console.error("AnimatorController.bind: animator is null");
12963
13331
  }
12964
- /** Create a clone of the controller. This will clone the model but not the runtime state. */
13332
+ /**
13333
+ * Creates a deep copy of this controller.
13334
+ * Clones the model data but does not copy runtime state.
13335
+ *
13336
+ * @returns A new AnimatorController instance with the same configuration
13337
+ */
12965
13338
  clone() {
12966
13339
  if (typeof this.model == "string")
12967
13340
  return console.warn("AnimatorController has not been resolved, can not create model from string", this.model), null;
@@ -12969,7 +13342,12 @@ class es {
12969
13342
  const t = Ru(this.model, (i, s, o) => o == null ? !0 : !(o.type === "Object3D" || o.isObject3D === !0 || uC(o) || o.tracks !== void 0 || o instanceof es));
12970
13343
  return console.assert(t !== this.model), new es(t);
12971
13344
  }
12972
- /** Called by the animator. This will update the active states and transitions as well as the animation mixer. */
13345
+ /**
13346
+ * Updates the controller's state machine and animations.
13347
+ * Called each frame by the animator component.
13348
+ *
13349
+ * @param weight - The weight to apply to the animations (for blending)
13350
+ */
12973
13351
  update(t) {
12974
13352
  var i, s;
12975
13353
  if (!this.animator)
@@ -12978,9 +13356,11 @@ class es {
12978
13356
  const e = this.animator.context.time.deltaTime;
12979
13357
  this.animator.applyRootMotion && ((i = this.rootMotionHandler) == null || i.onBeforeUpdate(t)), this._mixer.update(e), this.animator.applyRootMotion && ((s = this.rootMotionHandler) == null || s.onAfterUpdate(t));
12980
13358
  }
12981
- /** Get the currently active state playing
12982
- * @returns the currently active state or undefined if no state is active
12983
- **/
13359
+ /**
13360
+ * Gets the currently active animation state.
13361
+ *
13362
+ * @returns The active state or undefined if no state is active
13363
+ */
12984
13364
  get activeState() {
12985
13365
  return this._activeState;
12986
13366
  }
@@ -13185,6 +13565,10 @@ Exit Time: ` + d, a.hasExitTime);
13185
13565
  }
13186
13566
  }
13187
13567
  }
13568
+ /**
13569
+ * Yields all animation actions managed by this controller.
13570
+ * Iterates through all states in all layers and returns their actions.
13571
+ */
13188
13572
  *enumerateActions() {
13189
13573
  if (this.model.layers)
13190
13574
  for (const t of this.model.layers) {
@@ -13382,6 +13766,9 @@ class zt extends I {
13382
13766
  // so they effectively share the same mixer. There might be cases still where not the same mixer is being used but then the animation track prints an error in dev
13383
13767
  r(this, "_initializeWithRuntimeAnimatorController");
13384
13768
  }
13769
+ /**
13770
+ * Identifies this component as an animation component in the engine
13771
+ */
13385
13772
  get isAnimationComponent() {
13386
13773
  return !0;
13387
13774
  }
@@ -13389,29 +13776,40 @@ class zt extends I {
13389
13776
  var i;
13390
13777
  this._animatorController && this._animatorController.model === e || (e ? e instanceof es ? (e.animator && e.animator !== this && (console.warn("AnimatorController can not be bound to multiple animators", (i = e.model) == null ? void 0 : i.name), e.model || console.error("AnimatorController has no model"), e = new es(e.model)), this._animatorController = e, this._animatorController.bind(this)) : (zi && console.log("Assign animator controller", e, this), this._animatorController = new es(e), this.__didAwake && this._animatorController.bind(this)) : this._animatorController = null);
13391
13778
  }
13779
+ /**
13780
+ * Gets the current animator controller instance
13781
+ * @returns The current animator controller or null if none is assigned
13782
+ */
13392
13783
  get runtimeAnimatorController() {
13393
13784
  return this._animatorController;
13394
13785
  }
13395
- /** The current state info of the animator.
13396
- * If you just want to access the currently playing animation action you can use currentAction
13397
- * @returns {AnimatorStateInfo} The current state info of the animator or null if no state is playing
13398
- */
13786
+ /**
13787
+ * Retrieves information about the current animation state
13788
+ * @returns The current state information, or undefined if no state is playing
13789
+ */
13399
13790
  getCurrentStateInfo() {
13400
13791
  var e;
13401
13792
  return (e = this.runtimeAnimatorController) == null ? void 0 : e.getCurrentStateInfo();
13402
13793
  }
13403
- /** The current action playing. It can be used to modify the action
13404
- * @returns {AnimationAction | null} The current action playing or null if no state is playing
13405
- */
13794
+ /**
13795
+ * The currently playing animation action that can be used to modify animation properties
13796
+ * @returns The current animation action, or null if no animation is playing
13797
+ */
13406
13798
  get currentAction() {
13407
13799
  var e;
13408
13800
  return ((e = this.runtimeAnimatorController) == null ? void 0 : e.currentAction) || null;
13409
13801
  }
13410
- /** @returns {boolean} True if parameters have been changed */
13802
+ /**
13803
+ * Indicates whether animation parameters have been modified since the last update
13804
+ * @returns True if parameters have been changed
13805
+ */
13411
13806
  get parametersAreDirty() {
13412
13807
  return this._parametersAreDirty;
13413
13808
  }
13414
- /** @returns {boolean} True if the animator has been changed */
13809
+ /**
13810
+ * Indicates whether the animator state has changed since the last update
13811
+ * @returns True if the animator has been changed
13812
+ */
13415
13813
  get isDirty() {
13416
13814
  return this._isDirty;
13417
13815
  }
@@ -13419,13 +13817,13 @@ class zt extends I {
13419
13817
  Play(e, i = -1, s = Number.NEGATIVE_INFINITY, o = 0) {
13420
13818
  this.play(e, i, s, o);
13421
13819
  }
13422
- /** Plays an animation on the animator
13423
- * @param {string | number} name The name of the animation to play. Can also be the hash of the animation
13424
- * @param {number} layer The layer to play the animation on. Default is -1
13425
- * @param {number} normalizedTime The normalized time to start the animation at. Default is Number.NEGATIVE_INFINITY
13426
- * @param {number} transitionDurationInSec The duration of the transition to the new animation. Default is 0
13427
- * @returns {void}
13428
- * */
13820
+ /**
13821
+ * Plays an animation on the animator
13822
+ * @param name The name or hash of the animation to play
13823
+ * @param layer The layer to play the animation on (-1 for default layer)
13824
+ * @param normalizedTime The time position to start playing (0-1 range, NEGATIVE_INFINITY for current position)
13825
+ * @param transitionDurationInSec The duration of the blend transition in seconds
13826
+ */
13429
13827
  play(e, i = -1, s = Number.NEGATIVE_INFINITY, o = 0) {
13430
13828
  var a;
13431
13829
  (a = this.runtimeAnimatorController) == null || a.play(e, i, s, o), this._isDirty = !0;
@@ -13434,7 +13832,9 @@ class zt extends I {
13434
13832
  Reset() {
13435
13833
  this.reset();
13436
13834
  }
13437
- /** Resets the animatorcontroller */
13835
+ /**
13836
+ * Resets the animator controller to its initial state
13837
+ */
13438
13838
  reset() {
13439
13839
  var e;
13440
13840
  (e = this._animatorController) == null || e.reset(), this._isDirty = !0;
@@ -13443,6 +13843,11 @@ class zt extends I {
13443
13843
  SetBool(e, i) {
13444
13844
  this.setBool(e, i);
13445
13845
  }
13846
+ /**
13847
+ * Sets a boolean parameter in the animator
13848
+ * @param name The name or hash of the parameter
13849
+ * @param value The boolean value to set
13850
+ */
13446
13851
  setBool(e, i) {
13447
13852
  var s, o;
13448
13853
  zi && console.log("setBool", e, i), ((s = this.runtimeAnimatorController) == null ? void 0 : s.getBool(e)) !== i && (this._parametersAreDirty = !0), (o = this.runtimeAnimatorController) == null || o.setBool(e, i);
@@ -13451,11 +13856,20 @@ class zt extends I {
13451
13856
  GetBool(e) {
13452
13857
  return this.getBool(e);
13453
13858
  }
13859
+ /**
13860
+ * Gets a boolean parameter from the animator
13861
+ * @param name The name or hash of the parameter
13862
+ * @returns The value of the boolean parameter, or false if not found
13863
+ */
13454
13864
  getBool(e) {
13455
13865
  var s;
13456
13866
  const i = ((s = this.runtimeAnimatorController) == null ? void 0 : s.getBool(e)) ?? !1;
13457
13867
  return zi && console.log("getBool", e, i), i;
13458
13868
  }
13869
+ /**
13870
+ * Toggles a boolean parameter between true and false
13871
+ * @param name The name or hash of the parameter
13872
+ */
13459
13873
  toggleBool(e) {
13460
13874
  this.setBool(e, !this.getBool(e));
13461
13875
  }
@@ -13463,6 +13877,11 @@ class zt extends I {
13463
13877
  SetFloat(e, i) {
13464
13878
  this.setFloat(e, i);
13465
13879
  }
13880
+ /**
13881
+ * Sets a float parameter in the animator
13882
+ * @param name The name or hash of the parameter
13883
+ * @param val The float value to set
13884
+ */
13466
13885
  setFloat(e, i) {
13467
13886
  var s, o;
13468
13887
  ((s = this.runtimeAnimatorController) == null ? void 0 : s.getFloat(e)) !== i && (this._parametersAreDirty = !0), zi && console.log("setFloat", e, i), (o = this.runtimeAnimatorController) == null || o.setFloat(e, i);
@@ -13471,6 +13890,11 @@ class zt extends I {
13471
13890
  GetFloat(e) {
13472
13891
  return this.getFloat(e);
13473
13892
  }
13893
+ /**
13894
+ * Gets a float parameter from the animator
13895
+ * @param name The name or hash of the parameter
13896
+ * @returns The value of the float parameter, or -1 if not found
13897
+ */
13474
13898
  getFloat(e) {
13475
13899
  var s;
13476
13900
  const i = ((s = this.runtimeAnimatorController) == null ? void 0 : s.getFloat(e)) ?? -1;
@@ -13480,6 +13904,11 @@ class zt extends I {
13480
13904
  SetInteger(e, i) {
13481
13905
  this.setInteger(e, i);
13482
13906
  }
13907
+ /**
13908
+ * Sets an integer parameter in the animator
13909
+ * @param name The name or hash of the parameter
13910
+ * @param val The integer value to set
13911
+ */
13483
13912
  setInteger(e, i) {
13484
13913
  var s, o;
13485
13914
  ((s = this.runtimeAnimatorController) == null ? void 0 : s.getInteger(e)) !== i && (this._parametersAreDirty = !0), zi && console.log("setInteger", e, i), (o = this.runtimeAnimatorController) == null || o.setInteger(e, i);
@@ -13488,6 +13917,11 @@ class zt extends I {
13488
13917
  GetInteger(e) {
13489
13918
  return this.getInteger(e);
13490
13919
  }
13920
+ /**
13921
+ * Gets an integer parameter from the animator
13922
+ * @param name The name or hash of the parameter
13923
+ * @returns The value of the integer parameter, or -1 if not found
13924
+ */
13491
13925
  getInteger(e) {
13492
13926
  var s;
13493
13927
  const i = ((s = this.runtimeAnimatorController) == null ? void 0 : s.getInteger(e)) ?? -1;
@@ -13497,6 +13931,10 @@ class zt extends I {
13497
13931
  SetTrigger(e) {
13498
13932
  this.setTrigger(e);
13499
13933
  }
13934
+ /**
13935
+ * Activates a trigger parameter in the animator
13936
+ * @param name The name or hash of the trigger parameter
13937
+ */
13500
13938
  setTrigger(e) {
13501
13939
  var i;
13502
13940
  this._parametersAreDirty = !0, zi && console.log("setTrigger", e), (i = this.runtimeAnimatorController) == null || i.setTrigger(e);
@@ -13505,6 +13943,10 @@ class zt extends I {
13505
13943
  ResetTrigger(e) {
13506
13944
  this.resetTrigger(e);
13507
13945
  }
13946
+ /**
13947
+ * Resets a trigger parameter in the animator
13948
+ * @param name The name or hash of the trigger parameter
13949
+ */
13508
13950
  resetTrigger(e) {
13509
13951
  var i;
13510
13952
  this._parametersAreDirty = !0, zi && console.log("resetTrigger", e), (i = this.runtimeAnimatorController) == null || i.resetTrigger(e);
@@ -13513,6 +13955,11 @@ class zt extends I {
13513
13955
  GetTrigger(e) {
13514
13956
  this.getTrigger(e);
13515
13957
  }
13958
+ /**
13959
+ * Gets the state of a trigger parameter from the animator
13960
+ * @param name The name or hash of the trigger parameter
13961
+ * @returns The state of the trigger parameter
13962
+ */
13516
13963
  getTrigger(e) {
13517
13964
  var s;
13518
13965
  const i = (s = this.runtimeAnimatorController) == null ? void 0 : s.getTrigger(e);
@@ -13522,7 +13969,10 @@ class zt extends I {
13522
13969
  IsInTransition() {
13523
13970
  return this.isInTransition();
13524
13971
  }
13525
- /** @returns `true` if the animator is currently in a transition */
13972
+ /**
13973
+ * Checks if the animator is currently in a transition between states
13974
+ * @returns True if the animator is currently blending between animations
13975
+ */
13526
13976
  isInTransition() {
13527
13977
  var e;
13528
13978
  return ((e = this.runtimeAnimatorController) == null ? void 0 : e.isInTransition()) ?? !1;
@@ -13531,15 +13981,26 @@ class zt extends I {
13531
13981
  SetSpeed(e) {
13532
13982
  return this.setSpeed(e);
13533
13983
  }
13984
+ /**
13985
+ * Sets the playback speed of the animator
13986
+ * @param speed The new playback speed multiplier
13987
+ */
13534
13988
  setSpeed(e) {
13535
13989
  var i;
13536
13990
  e !== this._speed && (zi && console.log("setSpeed", e), this._speed = e, ((i = this._animatorController) == null ? void 0 : i.animator) == this && this._animatorController.setSpeed(e));
13537
13991
  }
13538
- /** Will generate a random speed between the min and max values and set it to the animatorcontroller */
13992
+ /**
13993
+ * Sets a random playback speed between the min and max values
13994
+ * @param minMax Object with x (minimum) and y (maximum) speed values
13995
+ */
13539
13996
  set minMaxSpeed(e) {
13540
13997
  var i;
13541
13998
  this._speed = $.lerp(e.x, e.y, Math.random()), ((i = this._animatorController) == null ? void 0 : i.animator) == this && this._animatorController.setSpeed(this._speed);
13542
13999
  }
14000
+ /**
14001
+ * Sets a random normalized time offset for animations between min (x) and max (y) values
14002
+ * @param minMax Object with x (min) and y (max) values for the offset range
14003
+ */
13543
14004
  set minMaxOffsetNormalized(e) {
13544
14005
  var i;
13545
14006
  this._normalizedStartOffset = $.lerp(e.x, e.y, Math.random()), ((i = this.runtimeAnimatorController) == null ? void 0 : i.animator) == this && (this.runtimeAnimatorController.normalizedStartOffset = this._normalizedStartOffset);
@@ -14488,10 +14949,15 @@ class In extends I {
14488
14949
  constructor() {
14489
14950
  super(...arguments);
14490
14951
  // public autoOwnership: boolean = true;
14952
+ /** When true, overrides physics behavior when this object is owned by the local user */
14491
14953
  r(this, "overridePhysics", !0);
14954
+ /** Whether to smoothly interpolate position changes when receiving updates */
14492
14955
  r(this, "interpolatePosition", !0);
14956
+ /** Whether to smoothly interpolate rotation changes when receiving updates */
14493
14957
  r(this, "interpolateRotation", !0);
14958
+ /** When true, sends updates at a higher frequency, useful for fast-moving objects */
14494
14959
  r(this, "fastMode", !1);
14960
+ /** When true, notifies other clients when this object is destroyed */
14495
14961
  r(this, "syncDestroy", !1);
14496
14962
  // private _state!: SyncedTransformModel;
14497
14963
  r(this, "_model", null);
@@ -14510,14 +14976,25 @@ class In extends I {
14510
14976
  r(this, "lastWorldPos");
14511
14977
  r(this, "lastWorldRotation");
14512
14978
  }
14513
- /** Request ownership of an object - you need to be connected to a room */
14979
+ /**
14980
+ * Requests ownership of this object on the network.
14981
+ * You need to be connected to a room for this to work.
14982
+ */
14514
14983
  requestOwnership() {
14515
14984
  eo && console.log("Request ownership"), this._model ? this._model.requestOwnership() : (this._shouldRequestOwnership = !0, this._needsUpdate = !0);
14516
14985
  }
14986
+ /**
14987
+ * Checks if this client has ownership of the object
14988
+ * @returns true if this client has ownership, false if not, undefined if ownership state is unknown
14989
+ */
14517
14990
  hasOwnership() {
14518
14991
  var e;
14519
14992
  return ((e = this._model) == null ? void 0 : e.hasOwnership) ?? void 0;
14520
14993
  }
14994
+ /**
14995
+ * Checks if the object is owned by any client
14996
+ * @returns true if the object is owned, false if not, undefined if ownership state is unknown
14997
+ */
14521
14998
  isOwned() {
14522
14999
  var e;
14523
15000
  return (e = this._model) == null ? void 0 : e.isOwned;
@@ -14530,10 +15007,17 @@ class In extends I {
14530
15007
  onDestroy() {
14531
15008
  this.syncDestroy && uv(this.guid, this.context.connection), this._model = null, this.context.connection.stopListen(ie.JoinedRoom, this.joinedRoomCallback), this.context.connection.stopListenBinary($c, this.receivedDataCallback);
14532
15009
  }
15010
+ /**
15011
+ * Attempts to retrieve and apply the last known network state for this transform
15012
+ */
14533
15013
  tryGetLastState() {
14534
15014
  const e = this.context.connection.tryGetState(this.guid);
14535
15015
  e && this.onReceivedData(e);
14536
15016
  }
15017
+ /**
15018
+ * Handles incoming network data for this transform
15019
+ * @param data The model containing transform information
15020
+ */
14537
15021
  onReceivedData(e) {
14538
15022
  var i;
14539
15023
  if (!this.destroyed && typeof e.guid == "function" && e.guid() === this.guid) {
@@ -14549,15 +15033,25 @@ class In extends I {
14549
15033
  this._receivedDataBefore = !0;
14550
15034
  }
14551
15035
  }
14552
- /** @internal */
15036
+ /**
15037
+ * @internal
15038
+ * Initializes tracking of position and rotation when component is enabled
15039
+ */
14553
15040
  onEnable() {
14554
15041
  this.lastWorldPos.copy(this.worldPosition), this.lastWorldRotation.copy(this.worldQuaternion), this._needsUpdate = !0, this._model && this._model.updateIsOwned();
14555
15042
  }
14556
- /** @internal */
15043
+ /**
15044
+ * @internal
15045
+ * Releases ownership when component is disabled
15046
+ */
14557
15047
  onDisable() {
14558
15048
  this._model && this._model.freeOwnership();
14559
15049
  }
14560
- /** @internal */
15050
+ /**
15051
+ * @internal
15052
+ * Handles transform synchronization before each render frame
15053
+ * Sends updates when owner, receives and applies updates when not owner
15054
+ */
14561
15055
  onBeforeRender() {
14562
15056
  if (!this.activeAndEnabled || !this.context.connection.isConnected)
14563
15057
  return;
@@ -16313,17 +16807,28 @@ const Jl = (od = class extends I {
16313
16807
  r(this, "_frustum");
16314
16808
  r(this, "_projScreenMatrix", new ne());
16315
16809
  }
16810
+ /**
16811
+ * Returns whether this component is a camera
16812
+ * @returns {boolean} Always returns true
16813
+ */
16316
16814
  get isCamera() {
16317
16815
  return !0;
16318
16816
  }
16319
- /** The camera's aspect ratio (width divided by height) if it is a perspective camera */
16817
+ /**
16818
+ * Gets or sets the camera's aspect ratio (width divided by height).
16819
+ * For perspective cameras, this directly affects the camera's projection matrix.
16820
+ * When set, automatically updates the projection matrix.
16821
+ */
16320
16822
  get aspect() {
16321
16823
  return this._cam instanceof ye ? this._cam.aspect : this.context.domWidth / this.context.domHeight;
16322
16824
  }
16323
16825
  set aspect(t) {
16324
16826
  this._cam instanceof ye && this._cam.aspect !== t && (this._cam.aspect = t, this._cam.updateProjectionMatrix());
16325
16827
  }
16326
- /** The camera's field of view in degrees if it is a perspective camera. Calls updateProjectionMatrix when set */
16828
+ /**
16829
+ * Gets or sets the camera's field of view in degrees for perspective cameras.
16830
+ * When set, automatically updates the projection matrix.
16831
+ */
16327
16832
  get fieldOfView() {
16328
16833
  return this._cam instanceof ye ? this._cam.fov : this._fov;
16329
16834
  }
@@ -16337,7 +16842,11 @@ const Jl = (od = class extends I {
16337
16842
  this._cam.fov = this._fov, this._cam.updateProjectionMatrix();
16338
16843
  }
16339
16844
  }
16340
- /** The camera's near clipping plane. Calls updateProjectionMatrix when set */
16845
+ /**
16846
+ * Gets or sets the camera's near clipping plane distance.
16847
+ * Objects closer than this distance won't be rendered.
16848
+ * When set, automatically updates the projection matrix.
16849
+ */
16341
16850
  get nearClipPlane() {
16342
16851
  return this._nearClipPlane;
16343
16852
  }
@@ -16345,7 +16854,11 @@ const Jl = (od = class extends I {
16345
16854
  const e = this._nearClipPlane != t;
16346
16855
  this._nearClipPlane = t, this._cam && (e || this._cam.near != t) && (this._cam.near = t, this._cam.updateProjectionMatrix());
16347
16856
  }
16348
- /** The camera's far clipping plane. Calls updateProjectionMatrix when set */
16857
+ /**
16858
+ * Gets or sets the camera's far clipping plane distance.
16859
+ * Objects farther than this distance won't be rendered.
16860
+ * When set, automatically updates the projection matrix.
16861
+ */
16349
16862
  get farClipPlane() {
16350
16863
  return this._farClipPlane;
16351
16864
  }
@@ -16354,7 +16867,8 @@ const Jl = (od = class extends I {
16354
16867
  this._farClipPlane = t, this._cam && (e || this._cam.far != t) && (this._cam.far = t, this._cam.updateProjectionMatrix());
16355
16868
  }
16356
16869
  /**
16357
- * Applys both the camera's near and far plane and calls updateProjectionMatrix on the camera.
16870
+ * Applies both the camera's near and far clipping planes and updates the projection matrix.
16871
+ * This ensures rendering occurs only within the specified distance range.
16358
16872
  */
16359
16873
  applyClippingPlane() {
16360
16874
  this._cam && (this._cam.near = this._nearClipPlane, this._cam.far = this._farClipPlane, this._cam.updateProjectionMatrix());
@@ -16371,9 +16885,11 @@ const Jl = (od = class extends I {
16371
16885
  get cullingMask() {
16372
16886
  return this._cam ? this._cam.layers.mask : this._cullingMask;
16373
16887
  }
16374
- /** Set only a specific layer active to be rendered by the camera.
16375
- * This is equivalent to calling `layers.set(val)`
16376
- **/
16888
+ /**
16889
+ * Sets only a specific layer to be active for rendering by this camera.
16890
+ * This is equivalent to calling `layers.set(val)` on the three.js camera object.
16891
+ * @param val The layer index to set active
16892
+ */
16377
16893
  set cullingLayer(t) {
16378
16894
  this.cullingMask = (1 << t | 0) >>> 0;
16379
16895
  }
@@ -16423,20 +16939,29 @@ const Jl = (od = class extends I {
16423
16939
  return this._targetTexture;
16424
16940
  }
16425
16941
  /**
16426
- * Get the three.js camera object. This will create a camera if it does not exist yet.
16427
- * @returns {PerspectiveCamera | OrthographicCamera} the three camera
16428
- * @deprecated use {@link threeCamera} instead
16942
+ * Gets the three.js camera object. Creates one if it doesn't exist yet.
16943
+ * @returns {PerspectiveCamera | OrthographicCamera} The three.js camera object
16944
+ * @deprecated Use {@link threeCamera} instead
16429
16945
  */
16430
16946
  get cam() {
16431
16947
  return this.threeCamera;
16432
16948
  }
16433
16949
  /**
16434
- * Get the three.js camera object. This will create a camera if it does not exist yet.
16435
- * @returns {PerspectiveCamera | OrthographicCamera} the three camera
16950
+ * Gets the three.js camera object. Creates one if it doesn't exist yet.
16951
+ * @returns {PerspectiveCamera | OrthographicCamera} The three.js camera object
16436
16952
  */
16437
16953
  get threeCamera() {
16438
16954
  return this.activeAndEnabled && this.buildCamera(), this._cam;
16439
16955
  }
16956
+ /**
16957
+ * Converts screen coordinates to a ray in world space.
16958
+ * Useful for implementing picking or raycasting from screen to world.
16959
+ *
16960
+ * @param x The x screen coordinate
16961
+ * @param y The y screen coordinate
16962
+ * @param ray Optional ray object to reuse instead of creating a new one
16963
+ * @returns {Ray} A ray originating from the camera position pointing through the screen point
16964
+ */
16440
16965
  screenPointToRay(t, e, i) {
16441
16966
  const s = this.threeCamera, o = Jl._origin;
16442
16967
  o.set(t, e, -1), this.context.input.convertScreenspaceToRaycastSpace(o), lb && console.log("screenPointToRay", t.toFixed(2), e.toFixed(2), "now:", o.x.toFixed(2), o.y.toFixed(2), "isInXR:" + this.context.isInXR), o.z = -1, o.unproject(s);
@@ -16444,18 +16969,27 @@ const Jl = (od = class extends I {
16444
16969
  return a.sub(l), a.normalize(), i ? (i.set(l, a), i) : new Co(l.clone(), a.clone());
16445
16970
  }
16446
16971
  /**
16447
- * Get a frustum - it will be created the first time this method is called and updated every frame in onBeforeRender when it exists.
16448
- * You can also manually update it using the updateFrustum method.
16972
+ * Gets the camera's view frustum for culling and visibility checks.
16973
+ * Creates the frustum if it doesn't exist and returns it.
16974
+ *
16975
+ * @returns {Frustum} The camera's view frustum
16449
16976
  */
16450
16977
  getFrustum() {
16451
16978
  return this._frustum || (this._frustum = new z_(), this.updateFrustum()), this._frustum;
16452
16979
  }
16453
- /** Force frustum update - note that this also happens automatically every frame in onBeforeRender */
16980
+ /**
16981
+ * Forces an update of the camera's frustum.
16982
+ * This is automatically called every frame in onBeforeRender.
16983
+ */
16454
16984
  updateFrustum() {
16455
16985
  this._frustum || (this._frustum = new z_()), this._frustum.setFromProjectionMatrix(this.getProjectionScreenMatrix(this._projScreenMatrix, !0), this.context.renderer.coordinateSystem);
16456
16986
  }
16457
16987
  /**
16458
- * @returns {Matrix4} this camera's projection screen matrix.
16988
+ * Gets this camera's projection-screen matrix.
16989
+ *
16990
+ * @param target Matrix4 object to store the result in
16991
+ * @param forceUpdate Whether to force recalculation of the matrix
16992
+ * @returns {Matrix4} The requested projection screen matrix
16459
16993
  */
16460
16994
  getProjectionScreenMatrix(t, e) {
16461
16995
  return e && this._projScreenMatrix.multiplyMatrices(this.threeCamera.projectionMatrix, this.threeCamera.matrixWorldInverse), t === this._projScreenMatrix ? t : t.copy(this._projScreenMatrix);
@@ -16489,8 +17023,9 @@ const Jl = (od = class extends I {
16489
17023
  }
16490
17024
  }
16491
17025
  /**
16492
- * Creates a {@link PerspectiveCamera} if it does not exist yet and set the camera's properties. This is internally also called when accessing the {@link cam} property.
16493
- **/
17026
+ * Creates a three.js camera object if it doesn't exist yet and sets its properties.
17027
+ * This is called internally when accessing the {@link threeCamera} property.
17028
+ */
16494
17029
  buildCamera() {
16495
17030
  if (this._cam)
16496
17031
  return;
@@ -16506,10 +17041,18 @@ const Jl = (od = class extends I {
16506
17041
  }
16507
17042
  this._cam = e, this._cam.layers.mask = this._cullingMask, this.tag == "MainCamera" && this.context.setCurrentCamera(this);
16508
17043
  }
17044
+ /**
17045
+ * Applies clear flags if this is the active main camera.
17046
+ * @param opts Options for applying clear flags
17047
+ */
16509
17048
  applyClearFlagsIfIsActiveCamera(t) {
16510
17049
  this.context.mainCameraComponent === this && this.applyClearFlags(t);
16511
17050
  }
16512
- /** Apply this camera's clear flags and related settings to the renderer */
17051
+ /**
17052
+ * Applies this camera's clear flags and related settings to the renderer.
17053
+ * This controls how the background is rendered (skybox, solid color, transparent).
17054
+ * @param opts Options for applying clear flags
17055
+ */
16513
17056
  applyClearFlags(t) {
16514
17057
  var e;
16515
17058
  if (!this._cam) {
@@ -16543,14 +17086,17 @@ const Jl = (od = class extends I {
16543
17086
  }
16544
17087
  }
16545
17088
  /**
16546
- * Apply the skybox to the scene
17089
+ * Applies the skybox texture to the scene background.
16547
17090
  */
16548
17091
  applySceneSkybox() {
16549
17092
  this._skybox || (this._skybox = new sR(this)), this._skybox.apply();
16550
17093
  }
16551
- /** Used to determine if the background should be transparent when in pass through AR
16552
- * @returns true when in XR on a pass through device where the background shouldbe invisible
16553
- **/
17094
+ /**
17095
+ * Determines if the background should be transparent when in passthrough AR mode.
17096
+ *
17097
+ * @param context The current rendering context
17098
+ * @returns {boolean} True when in XR on a pass through device where the background should be invisible
17099
+ */
16554
17100
  static backgroundShouldBeTransparent(t) {
16555
17101
  var o, a, l, c;
16556
17102
  const e = (o = t.renderer.xr) == null ? void 0 : o.getSession();
@@ -16620,6 +17166,10 @@ class sR {
16620
17166
  var t;
16621
17167
  return (t = this._camera) == null ? void 0 : t.context;
16622
17168
  }
17169
+ /**
17170
+ * Applies the skybox texture to the scene background.
17171
+ * Retrieves the texture based on the camera's source ID.
17172
+ */
16623
17173
  apply() {
16624
17174
  this._skybox = this.context.lightmaps.tryGetSkybox(this._camera.sourceId), this._skybox ? this.context.scene.background !== this._skybox && (io && console.log(`Camera "${this._camera.name}" set skybox`, this._camera, this._skybox), this._skybox.mapping = Rn, this.context.scene.background = this._skybox) : this._did_log_failed_to_find_skybox || (this._did_log_failed_to_find_skybox = !0, console.warn(`Camera "${this._camera.name}" has no skybox texture. ${this._camera.sourceId}`));
16625
17175
  }
@@ -16636,17 +17186,26 @@ class br extends I {
16636
17186
  });
16637
17187
  }
16638
17188
  /**
16639
- * Gets the existing or creates a new {@link ThreeAudioListener} instance
16640
- * @returns The {@link ThreeAudioListener} instance
17189
+ * Gets the existing Three.js {@link three#AudioListener} instance or creates a new one if it doesn't exist.
17190
+ * This listener is responsible for capturing audio in the 3D scene.
17191
+ * @returns The {@link three#AudioListener} instance
16641
17192
  */
16642
17193
  get listener() {
16643
17194
  return this._listener == null && (this._listener = new Kx()), this._listener;
16644
17195
  }
16645
- /** @internal */
17196
+ /**
17197
+ * Registers for interaction events and initializes the audio listener
17198
+ * when this component is enabled.
17199
+ * @internal
17200
+ */
16646
17201
  onEnable() {
16647
17202
  $s.registerWaitForInteraction(this.onInteraction), this.addListenerIfItExists();
16648
17203
  }
16649
- /** @internal */
17204
+ /**
17205
+ * Cleans up event registrations and removes the audio listener
17206
+ * when this component is disabled.
17207
+ * @internal
17208
+ */
16650
17209
  onDisable() {
16651
17210
  $s.unregisterWaitForInteraction(this.onInteraction), this.removeListenerIfItExists();
16652
17211
  }
@@ -16719,31 +17278,48 @@ const It = S("debugaudio"), so = class extends I {
16719
17278
  r(this, "_hasEnded", !0);
16720
17279
  r(this, "_needUpdateSpatialDistanceSettings", !1);
16721
17280
  }
16722
- /** Check if the user has interacted with the page to allow audio playback.
16723
- * Internally calling {@link Application.userInteractionRegistered}
17281
+ /**
17282
+ * Checks if the user has interacted with the page to allow audio playback.
17283
+ * Audio playback often requires a user gesture first due to browser autoplay policies.
17284
+ * This is the same as calling {@link Application.userInteractionRegistered}.
17285
+ *
17286
+ * @returns Whether user interaction has been registered to allow audio playback
16724
17287
  */
16725
17288
  static get userInteractionRegistered() {
16726
17289
  return $s.userInteractionRegistered;
16727
17290
  }
16728
- /** Register a callback that is called when the user has interacted with the page to allow audio playback.
16729
- * Internally calling {@link Application.registerWaitForInteraction}
17291
+ /**
17292
+ * Registers a callback that will be executed once the user has interacted with the page,
17293
+ * allowing audio playback to begin.
17294
+ * This is the same as calling {@link Application.registerWaitForInteraction}.
17295
+ *
17296
+ * @param cb - The callback function to execute when user interaction is registered
16730
17297
  */
16731
17298
  static registerWaitForAllowAudio(t) {
16732
17299
  $s.registerWaitForInteraction(t);
16733
17300
  }
16734
17301
  /**
16735
- * If true, the audio is currently playing.
17302
+ * Indicates whether the audio is currently playing.
17303
+ *
17304
+ * @returns True if the audio is playing, false otherwise
16736
17305
  */
16737
17306
  get isPlaying() {
16738
17307
  var t;
16739
17308
  return ((t = this.sound) == null ? void 0 : t.isPlaying) ?? !1;
16740
17309
  }
16741
- /** The duration of the audio clip in seconds. */
17310
+ /**
17311
+ * The total duration of the current audio clip in seconds.
17312
+ *
17313
+ * @returns Duration in seconds or undefined if no clip is loaded
17314
+ */
16742
17315
  get duration() {
16743
17316
  var t, e;
16744
17317
  return (e = (t = this.sound) == null ? void 0 : t.buffer) == null ? void 0 : e.duration;
16745
17318
  }
16746
- /** The current time of the audio clip in 0-1 range. */
17319
+ /**
17320
+ * The current playback position as a normalized value between 0 and 1.
17321
+ * Can be set to seek to a specific position in the audio.
17322
+ */
16747
17323
  get time01() {
16748
17324
  var e;
16749
17325
  const t = this.duration;
@@ -16754,7 +17330,8 @@ const It = S("debugaudio"), so = class extends I {
16754
17330
  e && this.sound && (this.time = t * e);
16755
17331
  }
16756
17332
  /**
16757
- * The current time of the audio clip in seconds.
17333
+ * The current playback position in seconds.
17334
+ * Can be set to seek to a specific time in the audio.
16758
17335
  */
16759
17336
  get time() {
16760
17337
  var t, e;
@@ -16804,6 +17381,12 @@ const It = S("debugaudio"), so = class extends I {
16804
17381
  get pitch() {
16805
17382
  return this.sound ? this.sound.getPlaybackRate() : 1;
16806
17383
  }
17384
+ /**
17385
+ * Returns the underlying {@link PositionalAudio} object, creating it if necessary.
17386
+ * The audio source needs a user interaction to be initialized due to browser autoplay policies.
17387
+ *
17388
+ * @returns The three.js PositionalAudio object or null if unavailable
17389
+ */
16807
17390
  get Sound() {
16808
17391
  var t;
16809
17392
  if (!this.sound && so.userInteractionRegistered) {
@@ -16840,10 +17423,20 @@ const It = S("debugaudio"), so = class extends I {
16840
17423
  // }
16841
17424
  // }
16842
17425
  // }
17426
+ /**
17427
+ * Indicates whether the audio source is queued to play when possible.
17428
+ * This may be true before user interaction has been registered.
17429
+ *
17430
+ * @returns Whether the audio source intends to play
17431
+ */
16843
17432
  get ShouldPlay() {
16844
17433
  return this.shouldPlay;
16845
17434
  }
16846
- /** Get the audio context from the Sound */
17435
+ /**
17436
+ * Returns the Web Audio API context associated with this audio source.
17437
+ *
17438
+ * @returns The {@link AudioContext} or null if not available
17439
+ */
16847
17440
  get audioContext() {
16848
17441
  var t;
16849
17442
  return (t = this.sound) == null ? void 0 : t.context;
@@ -16897,7 +17490,12 @@ const It = S("debugaudio"), so = class extends I {
16897
17490
  else
16898
17491
  this.shouldPlay = !0, this.createAudio();
16899
17492
  }
16900
- /** Play a audioclip or mediastream */
17493
+ /**
17494
+ * Plays the audio clip or media stream.
17495
+ * If no argument is provided, plays the currently assigned clip.
17496
+ *
17497
+ * @param clip - Optional audio clip or {@link MediaStream} to play
17498
+ */
16901
17499
  play(t = void 0) {
16902
17500
  var i, s, o;
16903
17501
  !t && this.clip && (t = this.clip), t !== void 0 && typeof t != "string" && !(t instanceof MediaStream) && (z() && console.warn("Called play on AudioSource with unknown argument type:", t + `
@@ -16913,14 +17511,16 @@ Using the assigned clip instead:`, this.clip), t = this.clip);
16913
17511
  }
16914
17512
  }
16915
17513
  /**
16916
- * Pause the audio
17514
+ * Pauses audio playback while maintaining the current position.
17515
+ * Use play() to resume from the paused position.
16917
17516
  */
16918
17517
  pause() {
16919
17518
  var t, e;
16920
17519
  It && console.log("Pause", this), this._hasEnded = !0, this.shouldPlay = !1, this.sound && this.sound.isPlaying && this.sound.source && (this._lastContextTime = (t = this.sound) == null ? void 0 : t.context.currentTime, this.sound.pause()), (e = this._audioElement) == null || e.remove();
16921
17520
  }
16922
17521
  /**
16923
- * Stop the audio and reset the time to 0
17522
+ * Stops audio playback completely and resets the playback position to the beginning.
17523
+ * Unlike pause(), calling play() after stop() will start from the beginning.
16924
17524
  */
16925
17525
  stop() {
16926
17526
  var t, e;
@@ -17976,14 +18576,30 @@ Hg([
17976
18576
  ], sh.prototype, "target", 2);
17977
18577
  const Ll = S("debugavatar");
17978
18578
  class Gg {
18579
+ /**
18580
+ * Creates a new avatar model.
18581
+ * @param root The root object of the avatar
18582
+ * @param head The head object of the avatar
18583
+ * @param leftHand The left hand object of the avatar
18584
+ * @param rigthHand The right hand object of the avatar
18585
+ */
17979
18586
  constructor(t, e, i, s) {
18587
+ /** The root object of the avatar model */
17980
18588
  r(this, "root");
18589
+ /** The head object of the avatar model */
17981
18590
  r(this, "head");
18591
+ /** The left hand object of the avatar model, if available */
17982
18592
  r(this, "leftHand");
18593
+ /** The right hand object of the avatar model, if available */
17983
18594
  r(this, "rigthHand");
17984
18595
  var o;
17985
18596
  this.root = t, this.head = e, this.leftHand = i, this.rigthHand = s, (o = this.root) == null || o.traverse((a) => a.layers.set(2));
17986
18597
  }
18598
+ /**
18599
+ * Checks if the avatar model has a valid configuration.
18600
+ * An avatar is considered valid if it has a head.
18601
+ * @returns Whether the avatar has a valid setup
18602
+ */
17987
18603
  get isValid() {
17988
18604
  return this.head !== null && this.head !== void 0;
17989
18605
  }
@@ -17994,6 +18610,12 @@ class Gv {
17994
18610
  }
17995
18611
  // private loader: GLTFLoader | null;
17996
18612
  // private avatarModelCache: Map<string, AvatarModel | null> = new Map<string, AvatarModel | null>();
18613
+ /**
18614
+ * Retrieves or creates a new avatar instance from an ID or existing Object3D.
18615
+ * @param context The application context
18616
+ * @param avatarId Either a string ID to load an avatar or an existing Object3D to use as avatar
18617
+ * @returns Promise resolving to an AvatarModel if successful, or null if failed
18618
+ */
17997
18619
  async getOrCreateNewAvatarInstance(t, e) {
17998
18620
  if (!e)
17999
18621
  return console.error("Can not create avatar: failed to provide id or root object"), null;
@@ -18010,6 +18632,12 @@ class Gv {
18010
18632
  const s = this.findAvatar(i);
18011
18633
  return s.isValid ? (Ll && console.log("[Custom Avatar] valid config", e, Ll ? s : ""), s) : (console.warn("[Custom Avatar] config isn't valid", e, Ll ? s : ""), null);
18012
18634
  }
18635
+ /**
18636
+ * Loads an avatar model from a file or registry using the provided ID.
18637
+ * @param context The engine context
18638
+ * @param avatarId The ID of the avatar to load
18639
+ * @returns Promise resolving to the loaded avatar's Object3D, or null if failed
18640
+ */
18013
18641
  async loadAvatar(t, e) {
18014
18642
  if (console.assert(e != null && typeof e == "string", "Avatar id must not be null"), e.length <= 0 || !e)
18015
18643
  return null;
@@ -18042,9 +18670,18 @@ class Gv {
18042
18670
  );
18043
18671
  });
18044
18672
  }
18673
+ /**
18674
+ * Caches an avatar model for reuse.
18675
+ * @param _id The ID to associate with the model
18676
+ * @param _model The avatar model to cache
18677
+ */
18045
18678
  cacheModel(t, e) {
18046
18679
  }
18047
- // TODO this should be burned to the ground once 🤞 we have proper extras that define object relations.
18680
+ /**
18681
+ * Analyzes an Object3D to find avatar parts (head, hands) based on naming conventions.
18682
+ * @param obj The Object3D to search for avatar parts
18683
+ * @returns A structured AvatarModel with references to found parts
18684
+ */
18048
18685
  findAvatar(t) {
18049
18686
  const e = t;
18050
18687
  let i = e;
@@ -18060,6 +18697,12 @@ class Gv {
18060
18697
  }
18061
18698
  return new Gg(e, s, o, a);
18062
18699
  }
18700
+ /**
18701
+ * Recursively searches for an avatar part by name within an Object3D hierarchy.
18702
+ * @param obj The Object3D to search within
18703
+ * @param searchString Array of strings that should all be present in the object name
18704
+ * @returns The found Object3D part or null if not found
18705
+ */
18063
18706
  findAvatarPart(t, e) {
18064
18707
  const i = t.name.toLowerCase();
18065
18708
  let s = !0;
@@ -18078,6 +18721,12 @@ class Gv {
18078
18721
  }
18079
18722
  return null;
18080
18723
  }
18724
+ /**
18725
+ * Handles HTTP response errors from avatar loading operations.
18726
+ * @param response The fetch API response to check
18727
+ * @returns The response if it was ok
18728
+ * @throws Error with status text if response was not ok
18729
+ */
18081
18730
  handleCustomAvatarErrors(t) {
18082
18731
  if (!t.ok)
18083
18732
  throw Error(t.statusText);
@@ -18097,6 +18746,10 @@ class nh extends I {
18097
18746
  r(this, "isGizmo", !1);
18098
18747
  r(this, "_axes", null);
18099
18748
  }
18749
+ /**
18750
+ * Creates and adds the axes visualization to the scene when the component is enabled.
18751
+ * If marked as a gizmo, it will only be shown when gizmos are enabled in the global parameters.
18752
+ */
18100
18753
  onEnable() {
18101
18754
  if (this.isGizmo && !Yc)
18102
18755
  return;
@@ -18104,6 +18757,9 @@ class nh extends I {
18104
18757
  const e = this._axes.material;
18105
18758
  e && e.depthTest !== void 0 && (e.depthTest = this.depthTest);
18106
18759
  }
18760
+ /**
18761
+ * Removes the axes visualization from the scene when the component is disabled.
18762
+ */
18107
18763
  onDisable() {
18108
18764
  this._axes && this.gameObject.remove(this._axes);
18109
18765
  }
@@ -18147,11 +18803,17 @@ class qv extends I {
18147
18803
  const IR = S("gizmos"), DR = S("debugboxhelper"), ps = class extends I {
18148
18804
  constructor() {
18149
18805
  super(...arguments);
18806
+ /** The bounding box for this component */
18150
18807
  r(this, "box", null);
18151
18808
  r(this, "_lastMatrixUpdateFrame", -1);
18152
18809
  r(this, "_helper", null);
18153
18810
  r(this, "_color", null);
18154
18811
  }
18812
+ /**
18813
+ * Tests if an object intersects with this helper's bounding box
18814
+ * @param obj The object to test for intersection
18815
+ * @returns True if objects intersect, false if not, undefined if the provided object is invalid
18816
+ */
18155
18817
  isInBox(e) {
18156
18818
  var s;
18157
18819
  if (!e)
@@ -18164,9 +18826,19 @@ const IR = S("gizmos"), DR = S("debugboxhelper"), ps = class extends I {
18164
18826
  const i = (s = this.box) == null ? void 0 : s.intersectsBox(ps.testBox);
18165
18827
  return i && DR && V.DrawWireBox3(ps.testBox, 16711680, 5), i;
18166
18828
  }
18829
+ /**
18830
+ * Tests if this helper's bounding box intersects with another box
18831
+ * @param box The {@link Box3} to test for intersection
18832
+ * @returns True if boxes intersect, false otherwise
18833
+ */
18167
18834
  intersects(e) {
18168
18835
  return e ? this.updateBox(!1).intersectsBox(e) : !1;
18169
18836
  }
18837
+ /**
18838
+ * Updates the helper's bounding box based on the gameObject's position and scale
18839
+ * @param force Whether to force an update regardless of frame count
18840
+ * @returns The updated {@link Box3}
18841
+ */
18170
18842
  updateBox(e = !1) {
18171
18843
  if (this.box || (this.box = new Mi()), e || this.context.time.frameCount != this._lastMatrixUpdateFrame) {
18172
18844
  const i = this._lastMatrixUpdateFrame < 0;
@@ -18179,6 +18851,11 @@ const IR = S("gizmos"), DR = S("debugboxhelper"), ps = class extends I {
18179
18851
  awake() {
18180
18852
  this._helper = null, this._color = null, this.box = null;
18181
18853
  }
18854
+ /**
18855
+ * Creates and displays a visual wireframe representation of this box helper
18856
+ * @param col Optional color for the wireframe. If not provided, uses default color
18857
+ * @param force If true, shows the helper even if gizmos are disabled
18858
+ */
18182
18859
  showHelper(e = null, i = !1) {
18183
18860
  var s;
18184
18861
  if (!(!IR && !i)) {
@@ -18206,14 +18883,18 @@ class Ei extends I {
18206
18883
  r(this, "membership", [0]);
18207
18884
  r(this, "filter");
18208
18885
  /**
18209
- * Apply the collider properties to the physics engine.
18886
+ * Updates the collider's properties in the physics engine.
18887
+ * Use this when you've changed collider properties and need to sync with the physics engine.
18210
18888
  */
18211
18889
  r(this, "updateProperties", () => {
18212
18890
  var e;
18213
18891
  (e = this.context.physics.engine) == null || e.updateProperties(this);
18214
18892
  });
18215
18893
  }
18216
- /** @internal */
18894
+ /**
18895
+ * Identifies this component as a collider.
18896
+ * @internal
18897
+ */
18217
18898
  get isCollider() {
18218
18899
  return !0;
18219
18900
  }
@@ -18234,12 +18915,18 @@ class Ei extends I {
18234
18915
  var e;
18235
18916
  (e = this.context.physics.engine) == null || e.removeBody(this);
18236
18917
  }
18237
- /** Returns the underlying physics body from the physics engine (if any) - the component must be enabled and active in the scene */
18918
+ /**
18919
+ * Returns the underlying physics body from the physics engine.
18920
+ * Only available if the component is enabled and active in the scene.
18921
+ */
18238
18922
  get body() {
18239
18923
  var e;
18240
18924
  return (e = this.context.physics.engine) == null ? void 0 : e.getBody(this);
18241
18925
  }
18242
- /** Requests an update of the physics material in the physics engine */
18926
+ /**
18927
+ * Updates the physics material in the physics engine.
18928
+ * Call this after changing the sharedMaterial property.
18929
+ */
18243
18930
  updatePhysicsMaterial() {
18244
18931
  var e;
18245
18932
  (e = this.context.physics.engine) == null || e.updatePhysicsMaterial(this);
@@ -18266,13 +18953,22 @@ class oh extends Ei {
18266
18953
  r(this, "radius", 0.5);
18267
18954
  r(this, "center", new v(0, 0, 0));
18268
18955
  }
18956
+ /**
18957
+ * Registers the sphere collider with the physics engine and sets up scale change monitoring.
18958
+ */
18269
18959
  onEnable() {
18270
18960
  var e;
18271
18961
  super.onEnable(), (e = this.context.physics.engine) == null || e.addSphereCollider(this), mg(this.gameObject.scale, this.updateProperties);
18272
18962
  }
18963
+ /**
18964
+ * Removes scale change monitoring when the collider is disabled.
18965
+ */
18273
18966
  onDisable() {
18274
18967
  super.onDisable(), P0(this.gameObject.scale, this.updateProperties);
18275
18968
  }
18969
+ /**
18970
+ * Updates collider properties when validated in the editor or inspector.
18971
+ */
18276
18972
  onValidate() {
18277
18973
  this.updateProperties();
18278
18974
  }
@@ -18290,23 +18986,43 @@ const Xv = class extends Ei {
18290
18986
  r(this, "size", new v(1, 1, 1));
18291
18987
  r(this, "center", new v(0, 0, 0));
18292
18988
  }
18989
+ /**
18990
+ * Creates and adds a BoxCollider to the given object.
18991
+ * @param obj The object to add the collider to
18992
+ * @param opts Configuration options for the collider and optional rigidbody
18993
+ * @returns The newly created BoxCollider
18994
+ */
18293
18995
  static add(t, e) {
18294
18996
  const i = Ji(t, Xv);
18295
18997
  return i.autoFit(), (e == null ? void 0 : e.rigidbody) === !0 && Ji(t, _e, { isKinematic: !1 }), i;
18296
18998
  }
18297
- /** @internal */
18999
+ /**
19000
+ * Registers the box collider with the physics engine and sets up scale change monitoring.
19001
+ * @internal
19002
+ */
18298
19003
  onEnable() {
18299
19004
  var t;
18300
19005
  super.onEnable(), (t = this.context.physics.engine) == null || t.addBoxCollider(this, this.size), mg(this.gameObject.scale, this.updateProperties);
18301
19006
  }
18302
- /** @internal */
19007
+ /**
19008
+ * Removes scale change monitoring when the collider is disabled.
19009
+ * @internal
19010
+ */
18303
19011
  onDisable() {
18304
19012
  super.onDisable(), P0(this.gameObject.scale, this.updateProperties);
18305
19013
  }
18306
- /** @internal */
19014
+ /**
19015
+ * Updates collider properties when validated in the editor or inspector.
19016
+ * @internal
19017
+ */
18307
19018
  onValidate() {
18308
19019
  this.updateProperties();
18309
19020
  }
19021
+ /**
19022
+ * Automatically fits the collider to the geometry of the object.
19023
+ * Sets the size and center based on the object's bounding box.
19024
+ * @param opts Options object with a debug flag to visualize the bounding box
19025
+ */
18310
19026
  autoFit(t) {
18311
19027
  const e = this.gameObject, i = e.position.clone(), s = e.quaternion.clone(), o = e.scale.clone(), a = e.parent;
18312
19028
  e.position.set(0, 0, 0), e.quaternion.set(0, 0, 0, 1), e.scale.set(1, 1, 1), e.parent = null, e.updateMatrix();
@@ -18328,6 +19044,10 @@ class Fr extends Ei {
18328
19044
  r(this, "sharedMesh");
18329
19045
  r(this, "convex", !1);
18330
19046
  }
19047
+ /**
19048
+ * Creates and registers the mesh collider with the physics engine.
19049
+ * Handles both individual meshes and mesh groups.
19050
+ */
18331
19051
  onEnable() {
18332
19052
  var i, s, o;
18333
19053
  if (super.onEnable(), !this.context.physics.engine)
@@ -18357,7 +19077,7 @@ class Fr extends Ei {
18357
19077
  p && this.activeAndEnabled && (h.geometry = p, (u = this.context.physics.engine) == null || u.addMeshCollider(this, h, this.convex));
18358
19078
  });
18359
19079
  } else
18360
- console.warn("A MeshCollider mesh is assigned, but it's neither a Mesh nor a Group. Please report a bug!", this, this.sharedMesh);
19080
+ (z() || S("showcolliders")) && console.warn(`[MeshCollider] A MeshCollider mesh is assigned to an unknown object on "${this.gameObject.name}", but it's neither a Mesh nor a Group. Please double check that you attached the collider component to the right object and report a bug otherwise!`, this);
18361
19081
  }
18362
19082
  }
18363
19083
  }
@@ -18374,6 +19094,9 @@ class Mo extends Ei {
18374
19094
  r(this, "radius", 0.5);
18375
19095
  r(this, "height", 2);
18376
19096
  }
19097
+ /**
19098
+ * Registers the capsule collider with the physics engine.
19099
+ */
18377
19100
  onEnable() {
18378
19101
  var e;
18379
19102
  super.onEnable(), (e = this.context.physics.engine) == null || e.addCapsuleCollider(this, this.height, this.radius);
@@ -18828,24 +19551,33 @@ const Ui = (Hl = class extends I {
18828
19551
  r(this, "_didDrag", !1);
18829
19552
  }
18830
19553
  /**
19554
+ * Checks if any DragControls component is currently active with selected objects
18831
19555
  * @returns True if any DragControls component is currently active
18832
19556
  */
18833
19557
  static get HasAnySelected() {
18834
19558
  return this._active > 0;
18835
19559
  }
18836
- /** @returns a list of DragControl components that are currently active */
19560
+ /**
19561
+ * Retrieves a list of all DragControl components that are currently dragging objects.
19562
+ * @returns Array of currently active DragControls components
19563
+ */
18837
19564
  static get CurrentlySelected() {
18838
19565
  rp.length = 0;
18839
19566
  for (const t of this._instances)
18840
19567
  t._isDragging && rp.push(t);
18841
19568
  return rp;
18842
19569
  }
18843
- /** The currently dragged object (if any) */
19570
+ /**
19571
+ * Returns the object currently being dragged by this DragControls component, if any.
19572
+ * @returns The object being dragged or null if no object is currently dragged
19573
+ */
18844
19574
  get draggedObject() {
18845
19575
  return this._targetObject;
18846
19576
  }
18847
19577
  /**
18848
- * Use to update the object that is being dragged by the DragControls
19578
+ * Updates the object that is being dragged by the DragControls.
19579
+ * This can be used to change the target during a drag operation.
19580
+ * @param obj The new object to drag, or null to stop dragging
18849
19581
  */
18850
19582
  setTargetObject(t) {
18851
19583
  var i, s;
@@ -18871,25 +19603,46 @@ const Ui = (Hl = class extends I {
18871
19603
  onDisable() {
18872
19604
  Ui._instances = Ui._instances.filter((t) => t !== this);
18873
19605
  }
19606
+ /**
19607
+ * Checks if editing is allowed for the current networking connection.
19608
+ * @param _obj Optional object to check edit permissions for
19609
+ * @returns True if editing is allowed
19610
+ */
18874
19611
  allowEdit(t = null) {
18875
19612
  return this.context.connection.allowEditing;
18876
19613
  }
18877
- /** @internal */
19614
+ /**
19615
+ * Handles pointer enter events. Sets the cursor style and tracks the hovered object.
19616
+ * @param evt Pointer event data containing information about the interaction
19617
+ * @internal
19618
+ */
18878
19619
  onPointerEnter(t) {
18879
19620
  if (!this.allowEdit(this.gameObject) || t.mode !== "screen" || (t.event.mode === "tracked-pointer" || t.event.mode === "transient-pointer" ? this.xrDragMode : this.dragMode) === 5)
18880
19621
  return;
18881
19622
  const s = C.getComponentInParent(t.object, Ui);
18882
19623
  !s || s !== this || (Ui.lastHovered = t.object, this.context.domElement.style.cursor = "pointer");
18883
19624
  }
18884
- /** @internal */
19625
+ /**
19626
+ * Handles pointer movement events. Marks the event as used if dragging is active.
19627
+ * @param args Pointer event data containing information about the movement
19628
+ * @internal
19629
+ */
18885
19630
  onPointerMove(t) {
18886
19631
  (this._isDragging || this._potentialDragStartEvt !== null) && t.use();
18887
19632
  }
18888
- /** @internal */
19633
+ /**
19634
+ * Handles pointer exit events. Resets the cursor style when the pointer leaves a draggable object.
19635
+ * @param evt Pointer event data containing information about the interaction
19636
+ * @internal
19637
+ */
18889
19638
  onPointerExit(t) {
18890
19639
  this.allowEdit(this.gameObject) && t.mode === "screen" && Ui.lastHovered === t.object && (this.context.domElement.style.cursor = "auto");
18891
19640
  }
18892
- /** @internal */
19641
+ /**
19642
+ * Handles pointer down events. Initiates the potential drag operation if conditions are met.
19643
+ * @param args Pointer event data containing information about the interaction
19644
+ * @internal
19645
+ */
18893
19646
  onPointerDown(t) {
18894
19647
  if (!(!this.allowEdit(this.gameObject) || t.used || (t.mode === "tracked-pointer" || t.mode === "transient-pointer" ? this.xrDragMode : this.dragMode) === 5) && (Ui.lastHovered = t.object, t.button === 0)) {
18895
19648
  this._dragHandlers.size === 0 && (this._didDrag = !1, this._totalMovement.set(0, 0, 0), this._potentialDragStartEvt = t), this._targetObject || this.setTargetObject(this.gameObject), Ui._active += 1;
@@ -18905,7 +19658,11 @@ const Ui = (Hl = class extends I {
18905
19658
  t.use();
18906
19659
  }
18907
19660
  }
18908
- /** @internal */
19661
+ /**
19662
+ * Handles pointer up events. Finalizes or cancels the drag operation.
19663
+ * @param args Pointer event data containing information about the interaction
19664
+ * @internal
19665
+ */
18909
19666
  onPointerUp(t) {
18910
19667
  if (zs && V.DrawLabel(t.point ?? this.gameObject.worldPosition, "POINTERUP:" + t.pointerId + ", " + t.button, 0.03, 3), !this.allowEdit(this.gameObject) || t.button !== 0)
18911
19668
  return;
@@ -18913,7 +19670,11 @@ const Ui = (Hl = class extends I {
18913
19670
  const e = this._dragHandlers.get(t.event.space), i = this._dragHandlers.get(this.gameObject);
18914
19671
  i && (i.handlerA === e || i.handlerB === e) && (this._dragHandlers.delete(this.gameObject), i.onDragEnd(t)), e && (Ui._active > 0 && (Ui._active -= 1), this.setTargetObject(null), e.onDragEnd && e.onDragEnd(t), this._dragHandlers.delete(t.event.space), this._dragHandlers.size === 0 && this.onLastDragEnd(t), t.use());
18915
19672
  }
18916
- /** @internal */
19673
+ /**
19674
+ * Updates the drag operation every frame. Processes pointer movement, accumulates drag distance
19675
+ * and triggers drag start once there's enough movement.
19676
+ * @internal
19677
+ */
18917
19678
  update() {
18918
19679
  for (const t of this._dragHandlers.values())
18919
19680
  t.collectMovementInfo && t.collectMovementInfo(), t.getTotalMovement && this._totalMovement.add(t.getTotalMovement());
@@ -18930,7 +19691,12 @@ const Ui = (Hl = class extends I {
18930
19691
  t.onDragUpdate && t.onDragUpdate(this._dragHandlers.size);
18931
19692
  this._dragHelper && this._dragHelper.hasSelected && this.onAnyDragUpdate();
18932
19693
  }
18933
- /** Called when the first pointer starts dragging on this object. Not called for subsequent pointers on the same object. */
19694
+ /**
19695
+ * Called when the first pointer starts dragging on this object.
19696
+ * Sets up network synchronization and marks rigidbodies for dragging.
19697
+ * Not called for subsequent pointers on the same object.
19698
+ * @param evt Pointer event data that initiated the drag
19699
+ */
18934
19700
  onFirstDragStart(t) {
18935
19701
  if (!t || !t.object)
18936
19702
  return;
@@ -18946,7 +19712,10 @@ const Ui = (Hl = class extends I {
18946
19712
  const o = C.getComponentsInChildren(i, _e);
18947
19713
  o && this._draggingRigidbodies.push(...o);
18948
19714
  }
18949
- /** Called each frame as long as any pointer is dragging this object. */
19715
+ /**
19716
+ * Called each frame as long as any pointer is dragging this object.
19717
+ * Updates visuals and keeps rigidbodies awake during the drag.
19718
+ */
18950
19719
  onAnyDragUpdate() {
18951
19720
  if (!this._dragHelper)
18952
19721
  return;
@@ -18956,7 +19725,11 @@ const Ui = (Hl = class extends I {
18956
19725
  const t = this._targetObject || this.gameObject;
18957
19726
  _s.markDirty(t);
18958
19727
  }
18959
- /** Called when the last pointer has been removed from this object. */
19728
+ /**
19729
+ * Called when the last pointer has been removed from this object.
19730
+ * Cleans up drag state and applies final velocities to rigidbodies.
19731
+ * @param evt Pointer event data for the last pointer that was lifted
19732
+ */
18960
19733
  onLastDragEnd(t) {
18961
19734
  if (!this || !this._isDragging)
18962
19735
  return;
@@ -18972,7 +19745,7 @@ const Ui = (Hl = class extends I {
18972
19745
  const e = this._dragHelper.selected;
18973
19746
  zs && console.log("DRAG END", e, e == null ? void 0 : e.visible), this._dragHelper.setSelected(null, this.context);
18974
19747
  }
18975
- }, r(Hl, "_active", 0), /** Currently active and enabled DragControls components */
19748
+ }, r(Hl, "_active", 0), /** Registry of currently active and enabled DragControls components */
18976
19749
  r(Hl, "_instances", []), r(Hl, "lastHovered"), Hl);
18977
19750
  let Oi = Ui;
18978
19751
  zr([
@@ -19121,14 +19894,22 @@ class ap {
19121
19894
  r(this, "_lastSurfaceHitPoint", new v());
19122
19895
  this.settings = t, this.context = t.context, this.gameObject = e, this._followObject = new D();
19123
19896
  }
19124
- /** Absolute movement of the pointer. Used for determining if a motion/drag is happening.
19125
- * This is in world units, so very small for screens (near-plane space change) */
19897
+ /**
19898
+ * Returns the accumulated movement of the pointer in world units.
19899
+ * Used for determining if enough motion has occurred to start a drag.
19900
+ */
19126
19901
  getTotalMovement() {
19127
19902
  return this._totalMovement;
19128
19903
  }
19904
+ /**
19905
+ * Returns the object that follows the pointer during dragging operations.
19906
+ */
19129
19907
  get followObject() {
19130
19908
  return this._followObject;
19131
19909
  }
19910
+ /**
19911
+ * Returns the point where the pointer initially hit the object in local space.
19912
+ */
19132
19913
  get hitPointInLocalSpace() {
19133
19914
  return this._hitPointInLocalSpace;
19134
19915
  }
@@ -19309,7 +20090,9 @@ class ap {
19309
20090
  }
19310
20091
  const D_ = class {
19311
20092
  constructor(t) {
20093
+ /** Controls whether visual helpers like lines and markers are displayed */
19312
20094
  r(this, "showGizmo", !0);
20095
+ /** When true, drag plane alignment changes based on view angle */
19313
20096
  r(this, "useViewAngle", !0);
19314
20097
  r(this, "_selected", null);
19315
20098
  r(this, "_context", null);
@@ -19338,9 +20121,15 @@ const D_ = class {
19338
20121
  const s = new wu(0.5, 22, 22), o = new Te({ color: i.color }), a = new q(s, o);
19339
20122
  a.visible = !1, a.layers.set(2), this._groundMarker = a;
19340
20123
  }
20124
+ /**
20125
+ * Checks if there is a currently selected object being visualized
20126
+ */
19341
20127
  get hasSelected() {
19342
20128
  return this._selected !== null && this._selected !== void 0;
19343
20129
  }
20130
+ /**
20131
+ * Returns the currently selected object being visualized, if any
20132
+ */
19344
20133
  get selected() {
19345
20134
  return this._selected;
19346
20135
  }
@@ -19473,6 +20262,10 @@ var QR = Object.defineProperty, YR = Object.getOwnPropertyDescriptor, ll = (n, t
19473
20262
  };
19474
20263
  const gs = S("debugdroplistener");
19475
20264
  class KR extends CustomEvent {
20265
+ /**
20266
+ * Creates a new added event with the provided details
20267
+ * @param detail Information about the added object
20268
+ */
19476
20269
  constructor(t) {
19477
20270
  super("object-added", { detail: t });
19478
20271
  }
@@ -19487,6 +20280,10 @@ class Io extends I {
19487
20280
  r(this, "fitVolumeSize", new v(1, 1, 1));
19488
20281
  r(this, "placeAtHitPosition", !0);
19489
20282
  r(this, "onDropped", new be());
20283
+ /**
20284
+ * Handles network events received from other clients containing information about dropped objects
20285
+ * @param evt Network event data containing object information, position, and content URL
20286
+ */
19490
20287
  r(this, "onNetworkEvent", (e) => {
19491
20288
  var i;
19492
20289
  if (!this.useNetworking) {
@@ -19503,6 +20300,11 @@ class Io extends I {
19503
20300
  this.addFromUrl(s, { screenposition: new oe(), point: e.point, size: e.size }, !0);
19504
20301
  }
19505
20302
  });
20303
+ /**
20304
+ * Handles clipboard paste events and processes them as potential URL drops
20305
+ * Only URLs are processed by this handler, and only when editing is allowed
20306
+ * @param evt The paste event
20307
+ */
19506
20308
  r(this, "handlePaste", (e) => {
19507
20309
  if (this.context.connection.allowEditing === !1 || e.defaultPrevented)
19508
20310
  return;
@@ -19513,9 +20315,19 @@ class Io extends I {
19513
20315
  }
19514
20316
  }).catch(console.warn);
19515
20317
  });
20318
+ /**
20319
+ * Handles drag events over the renderer's canvas
20320
+ * Prevents default behavior to enable drop events
20321
+ * @param evt The drag event
20322
+ */
19516
20323
  r(this, "onDrag", (e) => {
19517
20324
  this.context.connection.allowEditing !== !1 && e.preventDefault();
19518
20325
  });
20326
+ /**
20327
+ * Processes drop events to add files to the scene
20328
+ * Handles both file drops and text/URL drops
20329
+ * @param evt The drop event
20330
+ */
19519
20331
  r(this, "onDrop", async (e) => {
19520
20332
  if (this.context.connection.allowEditing === !1 || (gs && console.log(e), !(e != null && e.dataTransfer)) || e["droplistener:handled"])
19521
20333
  return;
@@ -19568,6 +20380,14 @@ class Io extends I {
19568
20380
  forgetObjects() {
19569
20381
  this.removePreviouslyAddedObjects(!1);
19570
20382
  }
20383
+ /**
20384
+ * Processes a dropped or pasted URL and tries to load it as a 3D model
20385
+ * Handles special cases like GitHub URLs and Polyhaven asset URLs
20386
+ * @param url The URL to process
20387
+ * @param ctx Context information about where the drop occurred
20388
+ * @param isRemote Whether this URL was shared from a remote client
20389
+ * @returns The added object or null if loading failed
20390
+ */
19571
20391
  async addFromUrl(e, i, s) {
19572
20392
  gs && console.log("dropped url", e);
19573
20393
  try {
@@ -19596,6 +20416,12 @@ class Io extends I {
19596
20416
  }
19597
20417
  return null;
19598
20418
  }
20419
+ /**
20420
+ * Processes dropped files, loads them as 3D models, and handles networking if enabled
20421
+ * Creates an abort controller to cancel previous uploads if new files are dropped
20422
+ * @param fileList Array of dropped files
20423
+ * @param ctx Context information about where the drop occurred
20424
+ */
19599
20425
  async addDroppedFiles(e, i) {
19600
20426
  var s, o;
19601
20427
  if (gs && console.log("Add files", e), !!Array.isArray(e) && e.length) {
@@ -19616,7 +20442,10 @@ class Io extends I {
19616
20442
  }
19617
20443
  }
19618
20444
  }
19619
- /** Removes all previously added objects from the scene and removes those object references */
20445
+ /**
20446
+ * Removes all previously added objects from the scene
20447
+ * @param doDestroy When true, destroys the objects; when false, just clears the references
20448
+ */
19620
20449
  removePreviouslyAddedObjects(e = !0) {
19621
20450
  if (e)
19622
20451
  for (const i of this._addedObjects)
@@ -19624,7 +20453,13 @@ class Io extends I {
19624
20453
  this._addedObjects.length = 0, this._addedModels.length = 0;
19625
20454
  }
19626
20455
  /**
19627
- * Adds the object to the scene and fits it into the volume if {@link fitIntoVolume} is enabled.
20456
+ * Adds a loaded model to the scene with proper positioning and scaling.
20457
+ * Handles placement based on component settings and raycasting.
20458
+ * If {@link fitIntoVolume} is enabled, the object will be scaled to fit within the volume defined by {@link fitVolumeSize}.
20459
+ * @param data The loaded model data and content hash
20460
+ * @param ctx Context information about where the drop occurred
20461
+ * @param isRemote Whether this object was shared from a remote client
20462
+ * @returns The added object or null if adding failed
19628
20463
  */
19629
20464
  addObject(e, i, s) {
19630
20465
  var d, u;
@@ -19660,6 +20495,13 @@ class Io extends I {
19660
20495
  });
19661
20496
  return this.dispatchEvent(h), (d = this.onDropped) == null || d.invoke(h.detail), !s && ((u = i.url) != null && u.startsWith("http")) && this.context.connection.isConnected && l && this.sendDropEvent(i.url, l, a), l;
19662
20497
  }
20498
+ /**
20499
+ * Sends a network event to other clients about a dropped object
20500
+ * Only triggered when networking is enabled and the connection is established
20501
+ * @param url The URL to the content that was dropped
20502
+ * @param obj The object that was added to the scene
20503
+ * @param contentmd5 The content hash for verification
20504
+ */
19663
20505
  async sendDropEvent(e, i, s) {
19664
20506
  if (!this.useNetworking) {
19665
20507
  gs && console.debug("[DropListener] Ignoring networked event because networking is disabled", e);
@@ -19678,9 +20520,18 @@ class Io extends I {
19678
20520
  this.context.connection.send("droplistener", a);
19679
20521
  }
19680
20522
  }
20523
+ /**
20524
+ * Deletes remote state for this DropListener's objects
20525
+ * Called when new files are dropped to clean up previous state
20526
+ */
19681
20527
  deleteDropEvent() {
19682
20528
  this.context.connection.sendDeleteRemoteState(this.guid);
19683
20529
  }
20530
+ /**
20531
+ * Tests if a drop event occurred within the designated drop area if one is specified
20532
+ * @param ctx The drop context containing screen position information
20533
+ * @returns True if the drop is valid (either no drop area is set or the drop occurred inside it)
20534
+ */
19684
20535
  testIfIsInDropArea(e) {
19685
20536
  if (this.dropArea) {
19686
20537
  const i = this.context.input.convertScreenspaceToRaycastSpace(e.screenposition.clone());
@@ -27405,6 +28256,9 @@ const Kt = S("debugplayersync"), $w = class extends I {
27405
28256
  r(this, "onJoinedRoom", () => {
27406
28257
  Kt && console.log("PlayerSync.joinedRoom. autoSync is set to " + this.autoSync), this.autoSync && this.getInstance();
27407
28258
  });
28259
+ /**
28260
+ * Destroys the current player instance and cleans up networking state
28261
+ */
27408
28262
  r(this, "destroyInstance", () => {
27409
28263
  var t;
27410
28264
  (t = this._localInstance) == null || t.then((e) => {
@@ -27414,7 +28268,10 @@ const Kt = S("debugplayersync"), $w = class extends I {
27414
28268
  }
27415
28269
  /**
27416
28270
  * This API is experimental and may change or be removed in the future.
27417
- * Create a PlayerSync instance at runtime from a given URL
28271
+ * Creates a PlayerSync instance at runtime from a given URL and sets it up for networking
28272
+ * @param url Path to the asset that should be instantiated for each player
28273
+ * @param init Optional initialization parameters for the PlayerSync component
28274
+ * @returns Promise resolving to a PlayerSync instance with a guaranteed asset property
27418
28275
  * @example
27419
28276
  * ```typescript
27420
28277
  * const res = await PlayerSync.setupFrom("/assets/demo.glb");
@@ -27443,6 +28300,10 @@ const Kt = S("debugplayersync"), $w = class extends I {
27443
28300
  onDisable() {
27444
28301
  this.context.connection.stopListen(ie.RoomStateSent, this.onJoinedRoom), this.context.connection.stopListen(ie.JoinedRoom, this.onJoinedRoom), this.context.connection.stopListen(ie.LeftRoom, this.destroyInstance);
27445
28302
  }
28303
+ /**
28304
+ * Gets or creates an instance of the assigned asset for the local player
28305
+ * @returns Promise resolving to the instantiated player object or null if creation failed
28306
+ */
27446
28307
  async getInstance() {
27447
28308
  var e, i, s, o, a, l;
27448
28309
  if (this._localInstance)
@@ -27463,6 +28324,9 @@ const Kt = S("debugplayersync"), $w = class extends I {
27463
28324
  this._localInstance = void 0, console.warn("PlayerSync: failed instantiating asset!");
27464
28325
  return this._localInstance;
27465
28326
  }
28327
+ /**
28328
+ * Sets up visibility change listeners to handle player cleanup when browser tab visibility changes
28329
+ */
27466
28330
  watchTabVisible() {
27467
28331
  window.addEventListener("visibilitychange", (t) => {
27468
28332
  if (document.visibilityState === "visible")
@@ -27487,12 +28351,21 @@ var AT = /* @__PURE__ */ ((n) => (n.OwnerChanged = "ownerChanged", n))(AT || {})
27487
28351
  const Mt = (Gl = class extends I {
27488
28352
  constructor() {
27489
28353
  super(...arguments);
28354
+ /** Event triggered when the owner of this PlayerState changes */
27490
28355
  r(this, "onOwnerChangeEvent", new be());
28356
+ /** Event triggered the first time an owner is assigned to this PlayerState */
27491
28357
  r(this, "onFirstOwnerChangeEvent", new be());
28358
+ /** Indicates if this PlayerState has an owner assigned */
27492
28359
  r(this, "hasOwner", !1);
27493
28360
  r(this, "owner");
27494
- /** when enabled PlayerSync will not destroy itself when not connected anymore */
28361
+ /**
28362
+ * When enabled, PlayerState will not destroy itself when the owner is not connected anymore
28363
+ */
27495
28364
  r(this, "dontDestroy", !1);
28365
+ /**
28366
+ * Handler for when a user leaves the networked room
28367
+ * @param model Object containing the ID of the user who left
28368
+ */
27496
28369
  r(this, "onUserLeftRoom", (t) => {
27497
28370
  if (t.userId === this.owner) {
27498
28371
  Kt && console.log("PLAYERSYNC LEFT", this.owner), this.doDestroy();
@@ -27500,31 +28373,48 @@ const Mt = (Gl = class extends I {
27500
28373
  }
27501
28374
  });
27502
28375
  }
27503
- /** all instances for all players */
28376
+ /** All PlayerState instances for all players in the scene */
27504
28377
  static get all() {
27505
28378
  return Mt._all;
27506
28379
  }
27507
- /** all instances for the local player */
28380
+ /** All PlayerState instances that belong to the local player */
27508
28381
  static get local() {
27509
28382
  return Mt._local;
27510
28383
  }
28384
+ /**
28385
+ * Gets the PlayerState component for a given object or component
28386
+ * @param obj Object3D or Component to find the PlayerState for
28387
+ * @returns The PlayerState component if found, undefined otherwise
28388
+ */
27511
28389
  static getFor(t) {
27512
28390
  if (t instanceof D)
27513
28391
  return C.getComponentInParent(t, Mt);
27514
28392
  if (t instanceof I)
27515
28393
  return C.getComponentInParent(t.gameObject, Mt);
27516
28394
  }
27517
- //** use to check if a component or gameobject is part of a instance owned by the local player */
28395
+ /**
28396
+ * Checks if a given object or component belongs to the local player
28397
+ * @param obj Object3D or Component to check
28398
+ * @returns True if the object belongs to the local player, false otherwise
28399
+ */
27518
28400
  static isLocalPlayer(t) {
27519
28401
  const e = Mt.getFor(t);
27520
28402
  return (e == null ? void 0 : e.isLocalPlayer) ?? !1;
27521
28403
  }
27522
28404
  /**
27523
- * Add a callback for a PlayerStateEvent
28405
+ * Registers a callback for a specific PlayerState event
28406
+ * @param event The event to listen for
28407
+ * @param cb Callback function that will be invoked when the event occurs
28408
+ * @returns The provided callback function for chaining
27524
28409
  */
27525
28410
  static addEventListener(t, e) {
27526
28411
  return this._callbacks[t] || (this._callbacks[t] = []), this._callbacks[t].push(e), e;
27527
28412
  }
28413
+ /**
28414
+ * Removes a previously registered event callback
28415
+ * @param event The event type to remove the callback from
28416
+ * @param cb The callback function to remove
28417
+ */
27528
28418
  static removeEventListener(t, e) {
27529
28419
  if (!this._callbacks[t])
27530
28420
  return;
@@ -27536,9 +28426,17 @@ const Mt = (Gl = class extends I {
27536
28426
  for (const i of this._callbacks[t])
27537
28427
  i(e);
27538
28428
  }
28429
+ /**
28430
+ * Indicates if this PlayerState belongs to the local player
28431
+ */
27539
28432
  get isLocalPlayer() {
27540
28433
  return this.owner === this.context.connection.connectionId;
27541
28434
  }
28435
+ /**
28436
+ * Handles owner change events and updates relevant state
28437
+ * @param newOwner The new owner's connection ID
28438
+ * @param oldOwner The previous owner's connection ID
28439
+ */
27542
28440
  onOwnerChange(t, e) {
27543
28441
  var a, l;
27544
28442
  Kt && console.log(`PlayerSync.onOwnerChange: ${e} → ${t} (me: ${this.context.connection.connectionId})`);
@@ -27567,7 +28465,7 @@ const Mt = (Gl = class extends I {
27567
28465
  !this.destroyed && !this.owner ? this.dontDestroy ? Kt && console.warn("PlayerState.start → owner is still undefined but dontDestroy is set to true", this.name) : (Kt && console.warn(`PlayerState.start → owner is still undefined: destroying "${this.name}" instance now`), this.doDestroy()) : Kt && console.log("PlayerState.start → owner is assigned", this.owner);
27568
28466
  }, 2e3));
27569
28467
  }
27570
- /** this tells the server that this client has been destroyed and the networking message for the instantiate will be removed */
28468
+ /** Tells the server that this client has been destroyed, and the networking message for the instantiate will be removed */
27571
28469
  doDestroy() {
27572
28470
  Kt && console.log("PlayerSync.doDestroy → syncDestroy", this.name), ju(this.gameObject, this.context.connection, !0, { saveInRoom: !1 });
27573
28471
  }
@@ -27578,8 +28476,7 @@ const Mt = (Gl = class extends I {
27578
28476
  t >= 0 && Mt._local.splice(t, 1);
27579
28477
  }
27580
28478
  }
27581
- }, r(Gl, "_all", []), r(Gl, "_local", []), // static Callback
27582
- r(Gl, "_callbacks", {}), Gl);
28479
+ }, r(Gl, "_all", []), r(Gl, "_local", []), r(Gl, "_callbacks", {}), Gl);
27583
28480
  let Zi = Mt;
27584
28481
  sf([
27585
28482
  Nw(Zi.prototype.onOwnerChange)
@@ -27599,11 +28496,16 @@ class $n extends I {
27599
28496
  r(this, "createMuteButton");
27600
28497
  r(this, "createQRCodeButton");
27601
28498
  }
27602
- /** @hidden */
28499
+ /**
28500
+ * Applies the configured menu options when the component is enabled
28501
+ * @hidden
28502
+ */
27603
28503
  onEnable() {
27604
28504
  this.applyOptions();
27605
28505
  }
27606
- /** applies the options to `this.context.menu` */
28506
+ /**
28507
+ * Applies all configured options to the active {@link Context.menu}.
28508
+ */
27607
28509
  applyOptions() {
27608
28510
  this.context.menu.setPosition(this.position), this.context.menu.showNeedleLogo(this.showNeedleLogo), this.createFullscreenButton === !0 && this.context.menu.showFullscreenOption(!0), this.createMuteButton === !0 && this.context.menu.showAudioPlaybackOption(!0), this.showSpatialMenu === !0 && this.context.menu.showSpatialMenu(this.showSpatialMenu), this.createQRCodeButton === !0 && (X.isMobileDevice() || this.context.menu.showQRCodeButton(!0));
27609
28511
  }
@@ -28203,7 +29105,7 @@ const va = (Hp = class extends I {
28203
29105
  r(this, "usePlacementAdjustment", !0);
28204
29106
  r(this, "arScale", 1);
28205
29107
  r(this, "useXRAnchor", !1);
28206
- r(this, "autoPlace", !0);
29108
+ r(this, "autoPlace", !1);
28207
29109
  r(this, "autoCenter", !1);
28208
29110
  r(this, "useQuicklookExport", !1);
28209
29111
  r(this, "useDepthSensing", !1);
@@ -28216,23 +29118,50 @@ const va = (Hp = class extends I {
28216
29118
  r(this, "_exitXRMenuButton");
28217
29119
  r(this, "_previousXRState", 0);
28218
29120
  r(this, "_spatialGrabRaycaster");
29121
+ /**
29122
+ * Event handler called when a player avatar is spawned.
29123
+ * Ensures the avatar has the necessary Avatar component.
29124
+ * @param instance The spawned avatar 3D object
29125
+ */
28219
29126
  r(this, "onAvatarSpawned", (t) => {
28220
29127
  zl && console.log("WebXR.onAvatarSpawned", t), C.getComponentInChildren(t, Rr) ?? (e = C.addComponent(t, Rr));
28221
29128
  });
29129
+ /**
29130
+ * Reference to the WebXR button factory used by this component.
29131
+ */
28222
29132
  r(this, "_buttonFactory");
29133
+ /**
29134
+ * Storage for UI buttons created by this component.
29135
+ */
28223
29136
  r(this, "_buttons", []);
28224
29137
  }
29138
+ /**
29139
+ * Initializes the WebXR component by obtaining the XR sync object for this context.
29140
+ */
28225
29141
  awake() {
28226
29142
  J.getXRSync(this.context);
28227
29143
  }
29144
+ /**
29145
+ * Sets up the WebXR component when it's enabled. Checks for HTTPS connection,
29146
+ * sets up USDZ export if enabled, creates UI buttons, and configures avatar settings.
29147
+ */
28228
29148
  onEnable() {
28229
29149
  var t, e;
28230
29150
  window.location.protocol !== "https:" && we('<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API" target="_blank">WebXR</a> only works on secure connections (https).'), this.useQuicklookExport && (C.findObjectOfType(qe) || (zl && console.log("WebXR: Adding USDZExporter"), this._usdzExporter = C.addComponent(this.gameObject, qe), this._usdzExporter.objectToExport = this.context.scene, this._usdzExporter.autoExportAnimations = !0, this._usdzExporter.autoExportAudioSources = !0)), this.handleCreatingHTML(), this.handleOfferSession(), this.defaultAvatar === !0 && (zl && console.warn("WebXR: No default avatar set, using static default avatar"), this.defaultAvatar = new re("https://cdn.needle.tools/static/avatars/DefaultAvatar.glb")), this.defaultAvatar && (this._playerSync = this.gameObject.getOrAddComponent(ph), this._playerSync.autoSync = !1), this._playerSync && typeof this.defaultAvatar != "boolean" && (this._playerSync.asset = this.defaultAvatar, (t = this._playerSync.onPlayerSpawned) == null || t.removeEventListener(this.onAvatarSpawned), (e = this._playerSync.onPlayerSpawned) == null || e.addEventListener(this.onAvatarSpawned));
28231
29151
  }
29152
+ /**
29153
+ * Cleans up resources when the component is disabled.
29154
+ * Destroys the USDZ exporter if one was created and removes UI buttons.
29155
+ */
28232
29156
  onDisable() {
28233
29157
  var t;
28234
29158
  (t = this._usdzExporter) == null || t.destroy(), this.removeButtons();
28235
29159
  }
29160
+ /**
29161
+ * Checks if WebXR is supported and offers an appropriate session.
29162
+ * This is used to show the WebXR session joining prompt in browsers that support it.
29163
+ * @returns A Promise that resolves to true if a session was offered, false otherwise
29164
+ */
28236
29165
  async handleOfferSession() {
28237
29166
  return this.createVRButton && await J.isVRSupported() && this.createVRButton ? J.offerSession("immersive-vr", "default", this.context) : this.createARButton && await J.isARSupported() && this.createARButton ? J.offerSession("immersive-ar", "default", this.context) : !1;
28238
29167
  }
@@ -28259,6 +29188,11 @@ const va = (Hp = class extends I {
28259
29188
  get isActiveWebXR() {
28260
29189
  return !va.activeWebXRComponent || va.activeWebXRComponent === this;
28261
29190
  }
29191
+ /**
29192
+ * Called before entering a WebXR session. Sets up optional features like depth sensing, if needed.
29193
+ * @param _mode The XR session mode being requested (immersive-ar or immersive-vr)
29194
+ * @param args The XRSessionInit object that will be passed to the WebXR API
29195
+ */
28262
29196
  onBeforeXR(t, e) {
28263
29197
  var i;
28264
29198
  if (!this.isActiveWebXR) {
@@ -28267,6 +29201,11 @@ const va = (Hp = class extends I {
28267
29201
  }
28268
29202
  va.activeWebXRComponent = this, t == "immersive-ar" && this.useDepthSensing && (e.optionalFeatures = e.optionalFeatures || [], e.optionalFeatures.push("depth-sensing"));
28269
29203
  }
29204
+ /**
29205
+ * Called when a WebXR session begins. Sets up the scene for XR by configuring controllers,
29206
+ * AR placement, and other features based on component settings.
29207
+ * @param args Event arguments containing information about the started XR session
29208
+ */
28270
29209
  async onEnterXR(t) {
28271
29210
  if (!this.isActiveWebXR)
28272
29211
  return;
@@ -28291,9 +29230,19 @@ const va = (Hp = class extends I {
28291
29230
  priority: 2e4
28292
29231
  }));
28293
29232
  }
29233
+ /**
29234
+ * Called every frame during an active WebXR session.
29235
+ * Updates components that depend on the current XR state.
29236
+ * @param _args Event arguments containing information about the current XR session frame
29237
+ */
28294
29238
  onUpdateXR(t) {
28295
29239
  this.isActiveWebXR && this._spatialGrabRaycaster && (this._spatialGrabRaycaster.enabled = this.useSpatialGrab);
28296
29240
  }
29241
+ /**
29242
+ * Called when a WebXR session ends. Restores pre-session state,
29243
+ * removes temporary components, and cleans up resources.
29244
+ * @param _ Event arguments containing information about the ended XR session
29245
+ */
28297
29246
  onLeaveXR(t) {
28298
29247
  var e, i;
28299
29248
  if ((e = this._exitXRMenuButton) == null || e.remove(), !!this.isActiveWebXR) {
@@ -28313,19 +29262,30 @@ const va = (Hp = class extends I {
28313
29262
  let e = this.gameObject.getComponent(Dn);
28314
29263
  return !e && t && (e = this.gameObject.addComponent(Dn), this._createdComponentsInSession.push(e), e.createControllerModel = this.showControllerModels, e.createHandModel == this.showHandModels), e && (e.enabled = t), e;
28315
29264
  }
29265
+ /**
29266
+ * Creates and instantiates the user's avatar representation in the WebXR session.
29267
+ * @param xr The active session
29268
+ */
28316
29269
  async createLocalAvatar(t) {
28317
29270
  this._playerSync && t.running && typeof this.defaultAvatar != "boolean" && (this._playerSync.asset = this.defaultAvatar, await this._playerSync.getInstance());
28318
29271
  }
28319
29272
  // HTML UI
28320
- /** @deprecated use `getButtonsFactory()` or access `WebXRButtonFactory.getOrCreate()` directory */
29273
+ /** @deprecated use {@link getButtonsFactory} or directly access {@link WebXRButtonFactory.getOrCreate} */
28321
29274
  getButtonsContainer() {
28322
29275
  return this.getButtonsFactory();
28323
29276
  }
28324
- /** Calling this function will get the Needle WebXR button factory (it will be created if it doesnt exist yet)
28325
- * @returns the Needle WebXR button factory */
29277
+ /**
29278
+ * Returns the WebXR button factory, creating one if it doesn't exist.
29279
+ * Use this to access and modify WebXR UI buttons.
29280
+ * @returns The WebXRButtonFactory instance
29281
+ */
28326
29282
  getButtonsFactory() {
28327
29283
  return this._buttonFactory || (this._buttonFactory = vo.getOrCreate()), this._buttonFactory;
28328
29284
  }
29285
+ /**
29286
+ * Creates and sets up UI elements for WebXR interaction based on component settings
29287
+ * and device capabilities. Handles creating AR, VR, QuickLook buttons and utility buttons like QR codes.
29288
+ */
28329
29289
  handleCreatingHTML() {
28330
29290
  if (this.createARButton || this.createVRButton || this.useQuicklookExport) {
28331
29291
  if ((X.isiOS() && X.isSafari() || WT) && this.useQuicklookExport) {
@@ -28359,9 +29319,17 @@ const va = (Hp = class extends I {
28359
29319
  }
28360
29320
  }
28361
29321
  }
29322
+ /**
29323
+ * Adds a button to the UI with the specified priority.
29324
+ * @param button The HTML element to add
29325
+ * @param priority The button's priority value (lower numbers appear first)
29326
+ */
28362
29327
  addButton(t, e) {
28363
29328
  this._buttons.push(t), t.setAttribute("priority", e.toString()), this.context.menu.appendChild(t);
28364
29329
  }
29330
+ /**
29331
+ * Removes all buttons created by this component from the UI.
29332
+ */
28365
29333
  removeButtons() {
28366
29334
  for (const t of this._buttons)
28367
29335
  t.remove();
@@ -29004,8 +29972,17 @@ class Li extends I {
29004
29972
  constructor() {
29005
29973
  super(...arguments);
29006
29974
  r(this, "type", 0);
29975
+ /**
29976
+ * The maximum distance the light affects
29977
+ */
29007
29978
  r(this, "range", 1);
29979
+ /**
29980
+ * The full outer angle of the spotlight cone in degrees
29981
+ */
29008
29982
  r(this, "spotAngle", 1);
29983
+ /**
29984
+ * The angle of the inner cone in degrees for soft-edge spotlights
29985
+ */
29009
29986
  r(this, "innerSpotAngle", 1);
29010
29987
  r(this, "_color", new le(16777215));
29011
29988
  r(this, "_shadowNearPlane", 0.1);
@@ -29021,6 +29998,9 @@ class Li extends I {
29021
29998
  r(this, "shadowWidth");
29022
29999
  r(this, "shadowHeight");
29023
30000
  r(this, "_shadowResolution");
30001
+ /**
30002
+ * The underlying three.js {@link ThreeLight} instance
30003
+ */
29024
30004
  r(this, "light");
29025
30005
  r(this, "_webXRStartedListener");
29026
30006
  r(this, "_webXREndedListener");
@@ -29100,9 +30080,15 @@ class Li extends I {
29100
30080
  const i = this.light;
29101
30081
  i != null && i.shadow && (i.shadow.mapSize.set(e, e), i.shadow.needsUpdate = !0);
29102
30082
  }
30083
+ /**
30084
+ * Whether this light's illumination is entirely baked into lightmaps
30085
+ */
29103
30086
  get isBaked() {
29104
30087
  return this.lightmapBakeType === 2;
29105
30088
  }
30089
+ /**
30090
+ * Checks if the GameObject itself is a {@link ThreeLight} object
30091
+ */
29106
30092
  get selfIsLight() {
29107
30093
  if (this.gameObject.isLight === !0)
29108
30094
  return !0;
@@ -29114,6 +30100,11 @@ class Li extends I {
29114
30100
  }
29115
30101
  return !1;
29116
30102
  }
30103
+ /**
30104
+ * Gets the world position of the light
30105
+ * @param vec Vector3 to store the result
30106
+ * @returns The world position as a Vector3
30107
+ */
29117
30108
  getWorldPosition(e) {
29118
30109
  return this.light ? this.type === 1 ? this.light.getWorldPosition(e).multiplyScalar(1) : this.light.getWorldPosition(e) : e;
29119
30110
  }
@@ -29141,6 +30132,10 @@ class Li extends I {
29141
30132
  // }
29142
30133
  onLeaveXR(e) {
29143
30134
  }
30135
+ /**
30136
+ * Creates the appropriate three.js light based on the configured light type
30137
+ * and applies all settings like shadows, intensity, and color.
30138
+ */
29144
30139
  createLight() {
29145
30140
  const e = this.selfIsLight;
29146
30141
  if (e && !this.light)
@@ -29190,19 +30185,33 @@ class Li extends I {
29190
30185
  this.isBaked ? this.light.removeFromParent() : e || this.gameObject.add(this.light);
29191
30186
  }
29192
30187
  }
30188
+ /**
30189
+ * Coroutine that updates the main light reference in the context
30190
+ * if this directional light should be the main light
30191
+ */
29193
30192
  *updateMainLightRoutine() {
29194
30193
  for (; ; ) {
29195
30194
  this.type === 1 && ((!this.context.mainLight || this.intensity > this.context.mainLight.intensity) && (this.context.mainLight = this), yield);
29196
30195
  break;
29197
30196
  }
29198
30197
  }
30198
+ /**
30199
+ * Updates shadow settings based on whether the shadows are set to hard or soft
30200
+ */
29199
30201
  updateShadowSoftHard() {
29200
30202
  this.light && this.light.shadow && (this.shadows === 2 || (this.light.shadow.radius = 1, this.light.shadow.blurSamples = 1));
29201
30203
  }
30204
+ /**
30205
+ * Configures a directional light by adding and positioning its target
30206
+ * @param dirLight The directional light to set up
30207
+ */
29202
30208
  setDirectionalLight(e) {
29203
30209
  e.add(e.target), e.target.position.set(0, 0, -1);
29204
30210
  }
29205
30211
  }
30212
+ /**
30213
+ * Controls whether the renderer's shadow map type can be changed when soft shadows are used
30214
+ */
29206
30215
  r(Li, "allowChangingRendererShadowMapType", !0);
29207
30216
  Ks([
29208
30217
  f()
@@ -29422,7 +30431,13 @@ const m2 = S("debugnet"), Vm = class extends I {
29422
30431
  awake() {
29423
30432
  m2 && console.log(this), this.context.connection.registerProvider(this);
29424
30433
  }
29425
- /** @internal */
30434
+ /**
30435
+ * Determines the websocket URL to use for networking connections.
30436
+ * Processes the configured URL, applying localhost fallbacks when appropriate and
30437
+ * handling URL parameter overrides if specified.
30438
+ * @returns The formatted websocket URL string or null if no valid URL could be determined
30439
+ * @internal
30440
+ */
29426
30441
  getWebsocketUrl() {
29427
30442
  let t = this.url ? Vm.GetUrl(this.url, this.localhost) : null;
29428
30443
  if (this.urlParameterName) {
@@ -29434,6 +30449,13 @@ const m2 = S("debugnet"), Vm = class extends I {
29434
30449
  const i = new RegExp("(((https?)|(?<socket_prefix>wss?))://)?(www.)?(?<url>.+)", "gm").exec(t);
29435
30450
  return i != null && i.groups ? (i == null ? void 0 : i.groups.socket_prefix) ? t : "wss://" + (i == null ? void 0 : i.groups.url) : null;
29436
30451
  }
30452
+ /**
30453
+ * Processes a URL string applying various transformations based on network environment.
30454
+ * Handles relative paths and localhost fallbacks for local network environments.
30455
+ * @param url The original URL to process
30456
+ * @param localhostFallback Alternative URL to use when on a local network
30457
+ * @returns The processed URL string or null/undefined if input was invalid
30458
+ */
29437
30459
  static GetUrl(t, e) {
29438
30460
  let i = t;
29439
30461
  const s = Vm.IsLocalNetwork() && e;
@@ -29443,6 +30465,13 @@ const m2 = S("debugnet"), Vm = class extends I {
29443
30465
  }
29444
30466
  return i;
29445
30467
  }
30468
+ /**
30469
+ * Determines if the current connection is on a local network.
30470
+ * Useful for applying different networking configurations in local development environments.
30471
+ * This is the same as calling {@link isLocalNetwork}.
30472
+ * @param hostname Optional hostname to check instead of the current window location
30473
+ * @returns True if the connection is on a local network, false otherwise
30474
+ */
29446
30475
  static IsLocalNetwork(t = window.location.hostname) {
29447
30476
  return pi(t);
29448
30477
  }
@@ -33625,9 +34654,19 @@ function Ub(n) {
33625
34654
  return e != null && e.length ? e : n;
33626
34655
  }
33627
34656
  class DA {
34657
+ /**
34658
+ * Creates a new PreLoadScheduler instance
34659
+ * @param rooms The SceneSwitcher that this scheduler belongs to
34660
+ * @param ahead Number of scenes to preload ahead of current scene
34661
+ * @param behind Number of scenes to preload behind current scene
34662
+ * @param maxConcurrent Maximum number of concurrent preloads allowed
34663
+ */
33628
34664
  constructor(t, e = 1, i = 1, s = 2) {
34665
+ /** Maximum number of scenes to preload ahead of the current scene */
33629
34666
  r(this, "maxLoadAhead");
34667
+ /** Maximum number of scenes to preload behind the current scene */
33630
34668
  r(this, "maxLoadBehind");
34669
+ /** Maximum number of scenes that can be preloaded concurrently */
33631
34670
  r(this, "maxConcurrent");
33632
34671
  r(this, "_isRunning", !1);
33633
34672
  r(this, "_switcher");
@@ -33635,6 +34674,10 @@ class DA {
33635
34674
  r(this, "_maxConcurrentLoads", 1);
33636
34675
  this._switcher = t, this.maxLoadAhead = e, this.maxLoadBehind = i, this.maxConcurrent = s;
33637
34676
  }
34677
+ /**
34678
+ * Starts the preloading process after a specified delay
34679
+ * @param delay Time in milliseconds to wait before starting preload
34680
+ */
33638
34681
  begin(t) {
33639
34682
  if (this._isRunning)
33640
34683
  return;
@@ -33660,12 +34703,23 @@ class DA {
33660
34703
  }
33661
34704
  }, 200);
33662
34705
  }
34706
+ /**
34707
+ * Stops the preloading process
34708
+ */
33663
34709
  stop() {
33664
34710
  this._isRunning = !1;
33665
34711
  }
34712
+ /**
34713
+ * Checks if a new scene can be loaded based on current load limits
34714
+ * @returns True if a new scene can be loaded, false otherwise
34715
+ */
33666
34716
  canLoadNewScene() {
33667
34717
  return this._loadTasks.length < this._maxConcurrentLoads;
33668
34718
  }
34719
+ /**
34720
+ * Checks if all scenes in the SceneSwitcher have been loaded
34721
+ * @returns True if all scenes are loaded, false otherwise
34722
+ */
33669
34723
  allLoaded() {
33670
34724
  if (this._switcher.scenes) {
33671
34725
  for (const t of this._switcher.scenes)
@@ -33676,12 +34730,24 @@ class DA {
33676
34730
  }
33677
34731
  }
33678
34732
  class LA {
34733
+ /**
34734
+ * Creates a new LoadTask and begins loading immediately
34735
+ * @param index The index of the scene in the scenes array
34736
+ * @param asset The AssetReference to preload
34737
+ * @param tasks The collection of active load tasks
34738
+ */
33679
34739
  constructor(t, e, i) {
34740
+ /** The index of the scene in the scenes array */
33680
34741
  r(this, "index");
34742
+ /** The AssetReference to be loaded */
33681
34743
  r(this, "asset");
34744
+ /** The collection of active load tasks this task belongs to */
33682
34745
  r(this, "tasks");
33683
34746
  this.index = t, this.asset = e, this.tasks = i, i.push(this), this.awaitLoading();
33684
34747
  }
34748
+ /**
34749
+ * Asynchronously loads the asset and removes this task from the active tasks list when complete
34750
+ */
33685
34751
  async awaitLoading() {
33686
34752
  this.asset && !this.asset.isLoaded() && (Zt && console.log("Preload start: " + this.asset.url, this.index), await this.asset.preload(), Zt && console.log("Preload finished: " + this.asset.url, this.index));
33687
34753
  const t = this.tasks.indexOf(this);
@@ -35005,12 +36071,23 @@ class An extends I {
35005
36071
  r(this, "onEnter");
35006
36072
  r(this, "onStay");
35007
36073
  r(this, "onExit");
36074
+ /** Array of triggers currently intersecting with this receiver */
35008
36075
  r(this, "currentIntersected", []);
36076
+ /** Array of triggers that intersected with this receiver in the previous frame */
35009
36077
  r(this, "lastIntersected", []);
35010
36078
  }
36079
+ /**
36080
+ * Initializes the receiver and logs debug info if enabled
36081
+ * @internal
36082
+ */
35011
36083
  start() {
35012
36084
  wc && console.log(this.name, this.triggerMask, this);
35013
36085
  }
36086
+ /**
36087
+ * Checks for intersections with spatial triggers and fires appropriate events
36088
+ * Handles enter, stay, and exit events for all relevant triggers
36089
+ * @internal
36090
+ */
35014
36091
  update() {
35015
36092
  this.currentIntersected.length = 0;
35016
36093
  for (const e of yf.triggers)
@@ -35023,14 +36100,26 @@ class An extends I {
35023
36100
  this.lastIntersected.indexOf(e) < 0 && this.onEnterTrigger(e), this.onStayTrigger(e);
35024
36101
  this.lastIntersected.length = 0, this.lastIntersected.push(...this.currentIntersected);
35025
36102
  }
36103
+ /**
36104
+ * Handles trigger enter events.
36105
+ * @param trigger The spatial trigger that was entered
36106
+ */
35026
36107
  onEnterTrigger(e) {
35027
36108
  var i;
35028
36109
  wc && console.log("ENTER TRIGGER", this.name, e.name, this, e), e.raiseOnEnterEvent(this), (i = this.onEnter) == null || i.invoke();
35029
36110
  }
36111
+ /**
36112
+ * Handles trigger exit events.
36113
+ * @param trigger The spatial trigger that was exited
36114
+ */
35030
36115
  onExitTrigger(e) {
35031
36116
  var i;
35032
36117
  wc && console.log("EXIT TRIGGER", this.name, e.name), e.raiseOnExitEvent(this), (i = this.onExit) == null || i.invoke();
35033
36118
  }
36119
+ /**
36120
+ * Handles trigger stay events.
36121
+ * @param trigger The spatial trigger that the receiver is staying in
36122
+ */
35034
36123
  onStayTrigger(e) {
35035
36124
  var i;
35036
36125
  e.raiseOnStayEvent(this), (i = this.onStay) == null || i.invoke();
@@ -35053,38 +36142,66 @@ const Td = (Xp = class extends I {
35053
36142
  constructor() {
35054
36143
  super(...arguments);
35055
36144
  r(this, "triggerMask");
36145
+ /** Box helper component used to visualize and calculate the trigger area */
35056
36146
  r(this, "boxHelper");
35057
36147
  }
36148
+ /**
36149
+ * Initializes the trigger and logs debug info if enabled
36150
+ */
35058
36151
  start() {
35059
36152
  wc && console.log(this.name, this.triggerMask, this);
35060
36153
  }
36154
+ /**
36155
+ * Registers this trigger in the global registry and sets up debug visualization if enabled
36156
+ */
35061
36157
  onEnable() {
35062
36158
  var t;
35063
36159
  Td.triggers.push(this), this.boxHelper || (this.boxHelper = C.addComponent(this.gameObject, Ci), (t = this.boxHelper) == null || t.showHelper(null, wc));
35064
36160
  }
36161
+ /**
36162
+ * Removes this trigger from the global registry when disabled
36163
+ */
35065
36164
  onDisable() {
35066
36165
  Td.triggers.splice(Td.triggers.indexOf(this), 1);
35067
36166
  }
36167
+ /**
36168
+ * Tests if an object is inside this trigger's box
36169
+ * @param obj The object to test against this trigger
36170
+ * @returns True if the object is inside the trigger box
36171
+ */
35068
36172
  test(t) {
35069
36173
  return this.boxHelper ? this.boxHelper.isInBox(t) ?? !1 : !1;
35070
36174
  }
35071
36175
  // private args: SpatialTriggerEventArgs = new SpatialTriggerEventArgs();
36176
+ /**
36177
+ * Raises the onEnter event on any SpatialTriggerReceiver components attached to this trigger's GameObject
36178
+ * @param rec The receiver that entered this trigger
36179
+ */
35072
36180
  raiseOnEnterEvent(t) {
35073
36181
  C.foreachComponent(this.gameObject, (e) => {
35074
36182
  e !== t && e instanceof An && e.onEnterTrigger(this);
35075
36183
  }, !1);
35076
36184
  }
36185
+ /**
36186
+ * Raises the onStay event on any SpatialTriggerReceiver components attached to this trigger's GameObject
36187
+ * @param rec The receiver that is staying in this trigger
36188
+ */
35077
36189
  raiseOnStayEvent(t) {
35078
36190
  C.foreachComponent(this.gameObject, (e) => {
35079
36191
  e !== t && e instanceof An && e.onStayTrigger(this);
35080
36192
  }, !1);
35081
36193
  }
36194
+ /**
36195
+ * Raises the onExit event on any SpatialTriggerReceiver components attached to this trigger's GameObject
36196
+ * @param rec The receiver that exited this trigger
36197
+ */
35082
36198
  raiseOnExitEvent(t) {
35083
36199
  C.foreachComponent(this.gameObject, (e) => {
35084
36200
  e !== t && e instanceof An && e.onExitTrigger(this);
35085
36201
  }, !1);
35086
36202
  }
35087
- }, r(Xp, "triggers", []), Xp);
36203
+ }, /** Global registry of all active spatial triggers in the scene */
36204
+ r(Xp, "triggers", []), Xp);
35088
36205
  let yf = Td;
35089
36206
  xh([
35090
36207
  f()
@@ -35098,6 +36215,7 @@ const Pi = S("debugspectator");
35098
36215
  class w_ extends I {
35099
36216
  constructor() {
35100
36217
  super(...arguments);
36218
+ /** Reference to the Camera component on this GameObject */
35101
36219
  r(this, "cam", null);
35102
36220
  r(this, "useKeys", !0);
35103
36221
  r(this, "_mode", 0);
@@ -35112,29 +36230,42 @@ class w_ extends I {
35112
36230
  r(this, "_debug");
35113
36231
  r(this, "_networking");
35114
36232
  }
36233
+ /** Gets the current spectator perspective mode */
35115
36234
  get mode() {
35116
36235
  return this._mode;
35117
36236
  }
36237
+ /** Sets the current spectator perspective mode */
35118
36238
  set mode(e) {
35119
36239
  this._mode = e;
35120
36240
  }
35121
- /** if this user is currently spectating someone else */
36241
+ /** Returns whether this user is currently spectating another user */
35122
36242
  get isSpectating() {
35123
36243
  var e;
35124
36244
  return ((e = this._handler) == null ? void 0 : e.currentTarget) !== void 0;
35125
36245
  }
36246
+ /**
36247
+ * Checks if this instance is spectating the user with the given ID
36248
+ * @param userId The user ID to check
36249
+ * @returns True if spectating the specified user, false otherwise
36250
+ */
35126
36251
  isSpectatingUser(e) {
35127
36252
  var i;
35128
36253
  return ((i = this.target) == null ? void 0 : i.userId) === e;
35129
36254
  }
36255
+ /**
36256
+ * Checks if the user with the specified ID is following this user
36257
+ * @param userId The user ID to check
36258
+ * @returns True if the specified user is following this user, false otherwise
36259
+ */
35130
36260
  isFollowedBy(e) {
35131
36261
  var i;
35132
36262
  return (i = this.followers) == null ? void 0 : i.includes(e);
35133
36263
  }
35134
- /** list of other users that are following me */
36264
+ /** List of user IDs that are currently following the user */
35135
36265
  get followers() {
35136
36266
  return this._networking.followers;
35137
36267
  }
36268
+ /** Stops the current spectating session */
35138
36269
  stopSpectating() {
35139
36270
  if (this.context.isInXR) {
35140
36271
  this.followSelf();
@@ -35142,10 +36273,14 @@ class w_ extends I {
35142
36273
  }
35143
36274
  this.target = void 0;
35144
36275
  }
36276
+ /** Gets the local player's connection ID */
35145
36277
  get localId() {
35146
36278
  return this.context.connection.connectionId ?? "local";
35147
36279
  }
35148
- /** player view to follow */
36280
+ /**
36281
+ * Sets the player view to follow
36282
+ * @param target The PlayerView to follow, or undefined to stop spectating
36283
+ */
35149
36284
  set target(e) {
35150
36285
  var i;
35151
36286
  if (this._handler) {
@@ -35153,13 +36288,16 @@ class w_ extends I {
35153
36288
  e === void 0 || this.context.isInXR === !1 && (o == null ? void 0 : o.currentObject) === e.currentObject ? this._handler.currentTarget !== void 0 && (this._handler.disable(), C.setActive(this.gameObject, !1), this.orbit && (this.orbit.enabled = !0), this._networking.onSpectatedObjectChanged(e, s)) : this._handler.currentTarget !== e && (this._handler.set(e), C.setActive(this.gameObject, !0), this.orbit && (this.orbit.enabled = !1), this._networking.onSpectatedObjectChanged(e, s));
35154
36289
  }
35155
36290
  }
36291
+ /** Gets the currently followed player view */
35156
36292
  get target() {
35157
36293
  var e;
35158
36294
  return (e = this._handler) == null ? void 0 : e.currentTarget;
35159
36295
  }
36296
+ /** Sends a network request for all users to follow this player */
35160
36297
  requestAllFollowMe() {
35161
36298
  this._networking.onRequestFollowMe();
35162
36299
  }
36300
+ /** Determines if the camera is spectating the local player */
35163
36301
  get isSpectatingSelf() {
35164
36302
  var e, i;
35165
36303
  return this.isSpectating && ((e = this.target) == null ? void 0 : e.currentObject) === ((i = this.context.players.getPlayerView(this.localId)) == null ? void 0 : i.currentObject);
@@ -35175,26 +36313,48 @@ class w_ extends I {
35175
36313
  var e, i;
35176
36314
  this.stopSpectating(), (e = this._handler) == null || e.destroy(), (i = this._networking) == null || i.destroy();
35177
36315
  }
36316
+ /**
36317
+ * Checks if the current platform supports spectator mode
36318
+ * @returns True if the platform is supported, false otherwise
36319
+ */
35178
36320
  isSupportedPlatform() {
35179
36321
  const e = window.navigator.userAgent, i = /Windows|MacOS/.test(e), s = /Windows NT/.test(e) && /Edg/.test(e) && !/Win64/.test(e);
35180
36322
  return i && !s;
35181
36323
  }
36324
+ /**
36325
+ * Called before entering WebXR mode
36326
+ * @param _evt The WebXR event
36327
+ */
35182
36328
  onBeforeXR(e) {
35183
36329
  this.isSupportedPlatform() && C.setActive(this.gameObject, !0);
35184
36330
  }
36331
+ /**
36332
+ * Called when entering WebXR mode
36333
+ * @param _evt The WebXR event
36334
+ */
35185
36335
  onEnterXR(e) {
35186
36336
  this.isSupportedPlatform() && (Pi && console.log(this.context.mainCamera), this.context.mainCamera && this.followSelf());
35187
36337
  }
36338
+ /**
36339
+ * Called when exiting WebXR mode
36340
+ * @param _evt The WebXR event
36341
+ */
35188
36342
  onLeaveXR(e) {
35189
36343
  var i, s;
35190
36344
  this.context.removeCamera(this.cam), C.setActive(this.gameObject, !1), this.orbit && (this.orbit.enabled = !0), (i = this._handler) == null || i.set(void 0), (s = this._handler) == null || s.disable(), this.isSpectatingSelf && this.stopSpectating();
35191
36345
  }
36346
+ /**
36347
+ * Sets the target to follow the local player
36348
+ */
35192
36349
  followSelf() {
35193
36350
  this.target = this.context.players.getPlayerView(this.context.connection.connectionId), this.target || (this.context.players.setPlayerView(this.localId, this.context.mainCamera, ur.Headset), this.target = this.context.players.getPlayerView(this.localId)), Pi && console.log("Follow self", this.target);
35194
36351
  }
35195
36352
  // TODO: only show Spectator cam for DesktopVR;
35196
36353
  // don't show for AR, don't show on Quest
35197
36354
  // TODO: properly align cameras on enter/exit VR, seems currently spectator cam breaks alignment
36355
+ /**
36356
+ * Called after the main rendering pass to render the spectator view
36357
+ */
35198
36358
  onAfterRender() {
35199
36359
  var d, u, p;
35200
36360
  if (!this.cam)
@@ -35224,6 +36384,9 @@ class w_ extends I {
35224
36384
  const h = e.xr.isPresenting;
35225
36385
  e.xr.isPresenting = !1, e.setSize(this.context.domWidth, this.context.domHeight), e.render(this.context.scene, c), e.xr.isPresenting = h, e.xr.enabled = i, s ? e.setRenderTarget(s) : a.bindXRFramebuffer && a.bindXRFramebuffer(o), this.resetAvatarFlags();
35226
36386
  }
36387
+ /**
36388
+ * Updates avatar visibility flags for rendering in spectator mode
36389
+ */
35227
36390
  setAvatarFlagsBeforeRender() {
35228
36391
  const e = this._mode === 0;
35229
36392
  for (const i of _t.instances)
@@ -35237,6 +36400,9 @@ class w_ extends I {
35237
36400
  a.UpdateVisible(s);
35238
36401
  }
35239
36402
  }
36403
+ /**
36404
+ * Restores avatar visibility flags after spectator rendering
36405
+ */
35240
36406
  resetAvatarFlags() {
35241
36407
  var e;
35242
36408
  for (const i of _t.instances)
@@ -35263,9 +36429,14 @@ class rE {
35263
36429
  r(this, "currentObject");
35264
36430
  this.context = t, this.cam = e, this.spectator = i;
35265
36431
  }
36432
+ /** Gets the currently targeted player view */
35266
36433
  get currentTarget() {
35267
36434
  return this.view;
35268
36435
  }
36436
+ /**
36437
+ * Sets the target player view to follow
36438
+ * @param view The PlayerView to follow
36439
+ */
35269
36440
  set(t) {
35270
36441
  const e = t == null ? void 0 : t.currentObject;
35271
36442
  if (!e) {
@@ -35274,13 +36445,19 @@ class rE {
35274
36445
  }
35275
36446
  e !== this.currentObject && (this.currentObject = e, this.view = t, this.follow || (this.follow = C.addComponent(this.cam.gameObject, Kr)), this.target || (this.target = new D()), e.add(this.target), this.follow.enabled = !0, this.follow.target = this.target, Pi && console.log("FOLLOW", e), this.context.isInXR ? this.context.removeCamera(this.cam) : this.context.setCurrentCamera(this.cam));
35276
36447
  }
36448
+ /** Disables the spectator following behavior */
35277
36449
  disable() {
35278
36450
  Pi && console.log("STOP FOLLOW", this.currentObject), this.view = void 0, this.currentObject = void 0, this.context.removeCamera(this.cam), this.follow && (this.follow.enabled = !1);
35279
36451
  }
36452
+ /** Cleans up resources used by the handler */
35280
36453
  destroy() {
35281
36454
  var t;
35282
36455
  (t = this.target) == null || t.removeFromParent(), this.follow && C.destroy(this.follow);
35283
36456
  }
36457
+ /**
36458
+ * Updates the camera position and orientation based on the spectator mode
36459
+ * @param mode The current spectator mode (first or third person)
36460
+ */
35284
36461
  update(t) {
35285
36462
  var s, o, a, l, c, h;
35286
36463
  if (((s = this.currentTarget) == null ? void 0 : s.isConnected) === !1 || ((o = this.currentTarget) == null ? void 0 : o.removed) === !0) {
@@ -35325,6 +36502,9 @@ class lE {
35325
36502
  o > 1 ? this.spectator.stopSpectating() : this.context.input.getPointerClicked(0) && o < 0.3 && this.trySelectObject();
35326
36503
  });
35327
36504
  }
36505
+ /**
36506
+ * Attempts to select an avatar to spectate through raycasting
36507
+ */
35328
36508
  trySelectObject() {
35329
36509
  const t = new En();
35330
36510
  t.setMask(16777215);
@@ -35344,11 +36524,12 @@ class lE {
35344
36524
  }
35345
36525
  class cE {
35346
36526
  constructor(t, e, i) {
35347
- /** the user that is following */
36527
+ /** The user ID that is following */
35348
36528
  r(this, "guid");
35349
36529
  r(this, "dontSave", !0);
35350
- /** the user being followed */
36530
+ /** The user ID being followed */
35351
36531
  r(this, "targetUserId");
36532
+ /** Indicates if the user stopped following */
35352
36533
  r(this, "stoppedFollowing");
35353
36534
  this.guid = t, this.targetUserId = e, this.stoppedFollowing = i;
35354
36535
  }
@@ -35362,6 +36543,7 @@ class hE {
35362
36543
  }
35363
36544
  class dE {
35364
36545
  constructor(t, e) {
36546
+ /** List of user IDs currently following this player */
35365
36547
  r(this, "followers", []);
35366
36548
  r(this, "context");
35367
36549
  r(this, "spectator");
@@ -35372,20 +36554,35 @@ class dE {
35372
36554
  r(this, "_enforceFollowInterval");
35373
36555
  this.context = t, this.spectator = e, this._followerEventMethod = this.onFollowerEvent.bind(this), this._requestFollowMethod = this.onRequestFollowEvent.bind(this), this._joinedRoomMethod = this.onUserJoinedRoom.bind(this);
35374
36556
  }
36557
+ /**
36558
+ * Initializes network event listeners
36559
+ */
35375
36560
  awake() {
35376
36561
  this.context.connection.beginListen("spectator-follower-changed", this._followerEventMethod), this.context.connection.beginListen("spectator-request-follow", this._requestFollowMethod), this.context.connection.beginListen(ie.JoinedRoom, this._joinedRoomMethod), this.context.domElement.addEventListener("keydown", (t) => {
35377
36562
  this.spectator.useKeys && (t.key === "f" ? this.onRequestFollowMe() : t.key === "Escape" && this.onRequestFollowMe(!0));
35378
36563
  });
35379
36564
  }
36565
+ /**
36566
+ * Removes network event listeners
36567
+ */
35380
36568
  destroy() {
35381
36569
  this.context.connection.stopListen("spectator-follower-changed", this._followerEventMethod), this.context.connection.stopListen("spectator-request-follow", this._requestFollowMethod), this.context.connection.stopListen(ie.JoinedRoom, this._joinedRoomMethod);
35382
36570
  }
36571
+ /**
36572
+ * Notifies other users about spectating target changes
36573
+ * @param target The new target being spectated
36574
+ * @param _prevId The previous target's user ID
36575
+ */
35383
36576
  onSpectatedObjectChanged(t, e) {
35384
36577
  if (Pi && console.log(this.context.connection.connectionId, "onSpectatedObjectChanged", t, e), this.context.connection.connectionId) {
35385
36578
  const i = (t == null ? void 0 : t.userId) === void 0, s = i ? e : t == null ? void 0 : t.userId, o = new cE(this.context.connection.connectionId, s, i);
35386
36579
  this.context.connection.send("spectator-follower-changed", o);
35387
36580
  }
35388
36581
  }
36582
+ /**
36583
+ * Requests other users to follow this player or stop following
36584
+ * @param stop Whether to request users to stop following
36585
+ */
35389
36586
  onRequestFollowMe(t = !1) {
35390
36587
  if (Pi && console.log("Request follow", this.context.connection.connectionId), this.context.connection.connectionId) {
35391
36588
  this.spectator.stopSpectating();
@@ -35393,9 +36590,16 @@ class dE {
35393
36590
  this.context.connection.send("spectator-request-follow", i);
35394
36591
  }
35395
36592
  }
36593
+ /**
36594
+ * Handles room join events
36595
+ */
35396
36596
  onUserJoinedRoom() {
35397
36597
  S("followme") && this.onRequestFollowMe();
35398
36598
  }
36599
+ /**
36600
+ * Processes follower status change events from the network
36601
+ * @param evt The follower change event data
36602
+ */
35399
36603
  onFollowerEvent(t) {
35400
36604
  const e = t.targetUserId, i = t.guid;
35401
36605
  if (Pi && console.log(t), e === this.context.connection.connectionId)
@@ -35405,12 +36609,20 @@ class dE {
35405
36609
  } else
35406
36610
  this.followers.includes(i) || (this.followers.push(i), this.removeDisconnectedFollowers(), console.log(i, "follows you", this.followers.length));
35407
36611
  }
36612
+ /**
36613
+ * Removes followers that are no longer connected to the room
36614
+ */
35408
36615
  removeDisconnectedFollowers() {
35409
36616
  for (let t = this.followers.length - 1; t >= 0; t--) {
35410
36617
  const e = this.followers[t];
35411
36618
  this.context.connection.userIsInRoom(e) === !1 && this.followers.splice(t, 1);
35412
36619
  }
35413
36620
  }
36621
+ /**
36622
+ * Handles follow requests from other users
36623
+ * @param evt The follow request event
36624
+ * @returns True if the request was handled successfully
36625
+ */
35414
36626
  onRequestFollowEvent(t) {
35415
36627
  if (this._lastRequestFollowUser = t, t.userId === this.context.connection.connectionId)
35416
36628
  this.spectator.stopSpectating();
@@ -35425,6 +36637,9 @@ class dE {
35425
36637
  }
35426
36638
  return !0;
35427
36639
  }
36640
+ /**
36641
+ * Periodically retries following a user if the initial attempt failed
36642
+ */
35428
36643
  enforceFollow() {
35429
36644
  this._enforceFollowInterval || (this._enforceFollowInterval = setInterval(() => {
35430
36645
  this._lastRequestFollowUser === void 0 || this._lastRequestFollowUser.userId && this.spectator.isFollowedBy(this._lastRequestFollowUser.userId) ? (clearInterval(this._enforceFollowInterval), this._enforceFollowInterval = void 0) : (Pi && console.log("REQUEST FOLLOW AGAIN", this._lastRequestFollowUser.userId), this.onRequestFollowEvent(this._lastRequestFollowUser));
@@ -36934,6 +38149,11 @@ class wl extends I {
36934
38149
  r(this, "scaleSnap", 0.25);
36935
38150
  r(this, "_control");
36936
38151
  r(this, "orbit");
38152
+ /**
38153
+ * Event handler for when dragging state changes.
38154
+ * Disables orbit controls during dragging and requests ownership of the transform if it's synchronized.
38155
+ * @param event The drag change event
38156
+ */
36937
38157
  r(this, "onControlChangedEvent", (e) => {
36938
38158
  const i = this.orbit;
36939
38159
  if (i && (i.enabled = !e.value), e.value) {
@@ -36941,6 +38161,18 @@ class wl extends I {
36941
38161
  s && s.requestOwnership();
36942
38162
  }
36943
38163
  });
38164
+ /**
38165
+ * Handles keyboard shortcuts for transform operations:
38166
+ * - Q: Toggle local/world space
38167
+ * - W: Translation mode
38168
+ * - E: Rotation mode
38169
+ * - R: Scale mode
38170
+ * - Shift: Enable snapping (while held)
38171
+ * - +/-: Adjust gizmo size
38172
+ * - X/Y/Z: Toggle visibility of respective axis
38173
+ * - Spacebar: Toggle controls enabled state
38174
+ * @param event The keyboard event
38175
+ */
36944
38176
  r(this, "windowKeyDownListener", (e) => {
36945
38177
  if (this.enabled && this._control)
36946
38178
  switch (e.keyCode) {
@@ -36981,6 +38213,11 @@ class wl extends I {
36981
38213
  break;
36982
38214
  }
36983
38215
  });
38216
+ /**
38217
+ * Handles keyboard key release events.
38218
+ * Currently only handles releasing Shift key to disable snapping.
38219
+ * @param event The keyboard event
38220
+ */
36984
38221
  r(this, "windowKeyUpListener", (e) => {
36985
38222
  if (this.enabled)
36986
38223
  switch (e.keyCode) {
@@ -36991,8 +38228,8 @@ class wl extends I {
36991
38228
  });
36992
38229
  }
36993
38230
  /**
36994
- * Get the underlying three.js TransformControls instance.
36995
- * @returns The TransformControls instance.
38231
+ * Gets the underlying three.js {@link TransformControls} instance.
38232
+ * @returns The TransformControls instance or undefined if not initialized.
36996
38233
  */
36997
38234
  get control() {
36998
38235
  return this._control;
@@ -37016,9 +38253,17 @@ class wl extends I {
37016
38253
  var e, i, s;
37017
38254
  (i = (e = this._control) == null ? void 0 : e.getHelper()) == null || i.removeFromParent(), (s = this._control) == null || s.removeEventListener("dragging-changed", this.onControlChangedEvent), window.removeEventListener("keydown", this.windowKeyDownListener), window.removeEventListener("keyup", this.windowKeyUpListener);
37018
38255
  }
38256
+ /**
38257
+ * Enables grid snapping for transform operations according to set snap values.
38258
+ * This applies the translationSnap, rotationSnapAngle, and scaleSnap properties to the controls.
38259
+ */
37019
38260
  enableSnapping() {
37020
38261
  this._control && (this._control.setTranslationSnap(this.translationSnap), this._control.setRotationSnap(Pn.degToRad(this.rotationSnapAngle)), this._control.setScaleSnap(this.scaleSnap));
37021
38262
  }
38263
+ /**
38264
+ * Disables grid snapping for transform operations.
38265
+ * Removes all snapping constraints from the transform controls.
38266
+ */
37022
38267
  disableSnapping() {
37023
38268
  this._control && (this._control.setTranslationSnap(null), this._control.setRotationSnap(null), this._control.setScaleSnap(null));
37024
38269
  }