@babylonjs/inspector 9.2.0 → 9.2.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 (126) hide show
  1. package/lib/components/debug/debugPane.d.ts +1 -1
  2. package/lib/components/properties/propertiesPane.d.ts +1 -1
  3. package/lib/components/properties/textures/texturePreview.d.ts +38 -0
  4. package/lib/components/scene/sceneExplorer.d.ts +5 -0
  5. package/lib/components/stats/statsPane.d.ts +1 -1
  6. package/lib/components/tools/toolsPane.d.ts +1 -1
  7. package/lib/extensibility/defaultInspectorExtensionFeed.d.ts +1 -1
  8. package/lib/extensions/quickCreate/quickCreateToolsService.d.ts +2 -2
  9. package/lib/{extensionsListService-eRZtqcfj.js → extensionsListService-CBQwBhYh.js} +2 -2
  10. package/lib/extensionsListService-CBQwBhYh.js.map +1 -0
  11. package/lib/hooks/settingsHooks.d.ts +0 -8
  12. package/lib/{index-FWuITINA.js → index-DmfAhsIm.js} +296 -146
  13. package/lib/index-DmfAhsIm.js.map +1 -0
  14. package/lib/index.d.ts +25 -21
  15. package/lib/index.js +1 -1
  16. package/lib/inspectable.d.ts +1 -1
  17. package/lib/inspector.d.ts +1 -1
  18. package/lib/legacy/inspectableCustomPropertiesService.d.ts +1 -1
  19. package/lib/misc/textureTools.d.ts +2 -1
  20. package/lib/{quickCreateToolsService-MzZbVrvr.js → quickCreateToolsService-C38aK2nP.js} +2 -2
  21. package/lib/{quickCreateToolsService-MzZbVrvr.js.map → quickCreateToolsService-C38aK2nP.js.map} +1 -1
  22. package/lib/{reflectorService-DdPEZLjO.js → reflectorService-Bs9E2OMh.js} +2 -2
  23. package/lib/reflectorService-Bs9E2OMh.js.map +1 -0
  24. package/lib/services/cli/cliConnectionStatus.d.ts +1 -1
  25. package/lib/services/cli/entityQueryService.d.ts +1 -1
  26. package/lib/services/cli/inspectableBridgeService.d.ts +1 -1
  27. package/lib/services/cli/inspectableCommandRegistry.d.ts +1 -1
  28. package/lib/services/cli/perfTraceCommandService.d.ts +1 -1
  29. package/lib/services/cli/screenshotCommandService.d.ts +1 -1
  30. package/lib/services/cli/shaderCommandService.d.ts +1 -1
  31. package/lib/services/cli/statsCommandService.d.ts +1 -1
  32. package/lib/services/cliConnectionStatusService.d.ts +2 -2
  33. package/lib/services/gizmoService.d.ts +1 -1
  34. package/lib/services/gizmoToolbarService.d.ts +2 -2
  35. package/lib/services/globalSettings.d.ts +2 -3
  36. package/lib/services/highlightService.d.ts +3 -3
  37. package/lib/services/inspectorSettingsService.d.ts +3 -0
  38. package/lib/services/miniStatsService.d.ts +2 -2
  39. package/lib/services/panes/debugService.d.ts +3 -3
  40. package/lib/services/panes/properties/animationGroupPropertiesService.d.ts +1 -1
  41. package/lib/services/panes/properties/animationPropertiesService.d.ts +1 -1
  42. package/lib/services/panes/properties/atmospherePropertiesService.d.ts +1 -1
  43. package/lib/services/panes/properties/audioPropertiesService.d.ts +1 -1
  44. package/lib/services/panes/properties/cameraPropertiesService.d.ts +1 -1
  45. package/lib/services/panes/properties/commonPropertiesService.d.ts +1 -1
  46. package/lib/services/panes/properties/effectLayerPropertiesService.d.ts +1 -1
  47. package/lib/services/panes/properties/frameGraphPropertiesService.d.ts +1 -1
  48. package/lib/services/panes/properties/lightPropertiesServices.d.ts +1 -1
  49. package/lib/services/panes/properties/materialPropertiesService.d.ts +1 -1
  50. package/lib/services/panes/properties/metadataPropertiesService.d.ts +1 -1
  51. package/lib/services/panes/properties/nodePropertiesService.d.ts +1 -1
  52. package/lib/services/panes/properties/particleSystemPropertiesService.d.ts +1 -1
  53. package/lib/services/panes/properties/physicsPropertiesService.d.ts +1 -1
  54. package/lib/services/panes/properties/postProcessPropertiesService.d.ts +1 -1
  55. package/lib/services/panes/properties/propertiesService.d.ts +3 -3
  56. package/lib/services/panes/properties/renderingPipelinePropertiesService.d.ts +1 -1
  57. package/lib/services/panes/properties/scenePropertiesService.d.ts +1 -1
  58. package/lib/services/panes/properties/skeletonPropertiesService.d.ts +1 -1
  59. package/lib/services/panes/properties/spritePropertiesService.d.ts +1 -1
  60. package/lib/services/panes/properties/texturePropertiesService.d.ts +1 -1
  61. package/lib/services/panes/properties/transformPropertiesService.d.ts +1 -1
  62. package/lib/services/panes/scene/animationGroupExplorerService.d.ts +1 -1
  63. package/lib/services/panes/scene/atmosphereExplorerService.d.ts +1 -1
  64. package/lib/services/panes/scene/disposableCommandService.d.ts +1 -1
  65. package/lib/services/panes/scene/effectLayersExplorerService.d.ts +1 -1
  66. package/lib/services/panes/scene/frameGraphExplorerService.d.ts +1 -1
  67. package/lib/services/panes/scene/guiExplorerService.d.ts +1 -1
  68. package/lib/services/panes/scene/materialExplorerService.d.ts +1 -1
  69. package/lib/services/panes/scene/nodeExplorerService.d.ts +1 -1
  70. package/lib/services/panes/scene/particleSystemExplorerService.d.ts +1 -1
  71. package/lib/services/panes/scene/postProcessExplorerService.d.ts +1 -1
  72. package/lib/services/panes/scene/renderingPipelinesExplorerService.d.ts +1 -1
  73. package/lib/services/panes/scene/sceneExplorerService.d.ts +2 -2
  74. package/lib/services/panes/scene/skeletonExplorerService.d.ts +1 -1
  75. package/lib/services/panes/scene/soundExplorerService.d.ts +1 -1
  76. package/lib/services/panes/scene/spriteManagerExplorerService.d.ts +1 -1
  77. package/lib/services/panes/scene/texturesExplorerService.d.ts +1 -1
  78. package/lib/services/panes/statsService.d.ts +3 -3
  79. package/lib/services/panes/tools/captureService.d.ts +1 -1
  80. package/lib/services/panes/tools/exportService.d.ts +1 -1
  81. package/lib/services/panes/tools/import/gltfAnimationImportService.d.ts +1 -1
  82. package/lib/services/panes/tools/import/gltfLoaderOptionsService.d.ts +1 -1
  83. package/lib/services/panes/tools/import/gltfValidationService.d.ts +1 -1
  84. package/lib/services/panes/tools/reflectorService.d.ts +1 -1
  85. package/lib/services/panes/toolsService.d.ts +3 -3
  86. package/lib/services/pickingService.d.ts +3 -3
  87. package/lib/services/sceneContext.d.ts +1 -1
  88. package/lib/services/selectionService.d.ts +4 -4
  89. package/lib/services/textureEditor/textureEditorService.d.ts +1 -1
  90. package/lib/services/userFeedbackService.d.ts +2 -2
  91. package/lib/services/watcherService.d.ts +5 -5
  92. package/package.json +1 -1
  93. package/lib/components/errorBoundary.d.ts +0 -31
  94. package/lib/components/extensibleAccordion.d.ts +0 -67
  95. package/lib/components/pane.d.ts +0 -4
  96. package/lib/components/teachingMoment.d.ts +0 -20
  97. package/lib/components/theme.d.ts +0 -10
  98. package/lib/components/uxContextProvider.d.ts +0 -2
  99. package/lib/contexts/extensionManagerContext.d.ts +0 -6
  100. package/lib/contexts/settingsContext.d.ts +0 -3
  101. package/lib/extensibility/builtInsExtensionFeed.d.ts +0 -21
  102. package/lib/extensibility/extensionFeed.d.ts +0 -113
  103. package/lib/extensibility/extensionManager.d.ts +0 -111
  104. package/lib/extensionsListService-eRZtqcfj.js.map +0 -1
  105. package/lib/hooks/observableHooks.d.ts +0 -35
  106. package/lib/hooks/resourceHooks.d.ts +0 -20
  107. package/lib/hooks/teachingMomentHooks.d.ts +0 -34
  108. package/lib/hooks/themeHooks.d.ts +0 -17
  109. package/lib/hooks/useResizeHandle.d.ts +0 -35
  110. package/lib/index-FWuITINA.js.map +0 -1
  111. package/lib/misc/assert.d.ts +0 -5
  112. package/lib/misc/graphUtils.d.ts +0 -44
  113. package/lib/misc/observableCollection.d.ts +0 -23
  114. package/lib/modularTool.d.ts +0 -42
  115. package/lib/modularity/serviceContainer.d.ts +0 -64
  116. package/lib/modularity/serviceDefinition.d.ts +0 -64
  117. package/lib/reflectorService-DdPEZLjO.js.map +0 -1
  118. package/lib/services/extensionsListService.d.ts +0 -3
  119. package/lib/services/panes/settingsService.d.ts +0 -25
  120. package/lib/services/reactContextService.d.ts +0 -18
  121. package/lib/services/settingsStore.d.ts +0 -55
  122. package/lib/services/shellService.d.ts +0 -256
  123. package/lib/services/shellSettingsService.d.ts +0 -3
  124. package/lib/services/themeSelectorService.d.ts +0 -3
  125. package/lib/services/themeService.d.ts +0 -60
  126. package/lib/themes/babylonTheme.d.ts +0 -3
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { createContext, forwardRef, useContext, useState, useCallback, Component, useMemo, useEffect, useRef, useReducer, Children, isValidElement, useLayoutEffect, useImperativeHandle, cloneElement, createElement, Suspense, memo, Fragment as Fragment$1, lazy } from 'react';
3
3
  import { tokens, makeStyles, Tooltip as Tooltip$1, Button as Button$1, Spinner, Link as Link$1, Caption1, Body1, useFluent, Accordion as Accordion$1, AccordionHeader, Subtitle2Stronger, AccordionPanel, Divider, MessageBar as MessageBar$1, MessageBarBody, AccordionItem, SearchBox as SearchBox$1, Portal, ToggleButton as ToggleButton$1, InfoLabel as InfoLabel$1, Body1Strong, mergeClasses, useId, useToastController, Toast, ToastTitle, FluentProvider, Toaster, Checkbox as Checkbox$1, createLightTheme, createDarkTheme, TeachingPopover, TeachingPopoverSurface, TeachingPopoverHeader, TeachingPopoverBody, createDOMRenderer, RendererProvider, Menu, MenuTrigger, SplitButton, MenuPopover, MenuList, MenuItem, Toolbar as Toolbar$1, ToolbarRadioButton, MenuGroup, MenuGroupHeader, Switch as Switch$1, treeItemLevelToken, FlatTree, FlatTreeItem, TreeItemLayout, MenuDivider, MenuItemCheckbox, useMergedRefs, Input, Dropdown as Dropdown$1, Option, Popover as Popover$1, PopoverTrigger, PopoverSurface, ColorPicker, ColorArea, ColorSlider, AlphaSlider, ColorSwatch, PresenceBadge, Slider as Slider$1, MenuItemRadio, Dialog, DialogSurface, DialogBody, DialogTitle, DialogContent, DialogActions, List as List$1, ListItem, Badge, Label, MessageBarTitle, useComboboxFilter, Combobox, Subtitle2, Textarea as Textarea$1, ToolbarButton, ToolbarDivider, Field } from '@fluentui/react-components';
4
- import { ErrorCircleRegular, EyeFilled, EyeOffRegular, CheckmarkFilled, EditRegular, FilterRegular, PinFilled, PinRegular, ArrowCircleUpRegular, ChevronCircleRight16Regular, ChevronCircleRight20Regular, ChevronCircleDown16Regular, ChevronCircleDown20Regular, Copy16Regular, CopyRegular, PanelLeftExpandRegular, PanelRightExpandRegular, PanelLeftContractRegular, PanelRightContractRegular, PictureInPictureEnterRegular, MoreHorizontalRegular, LayoutColumnTwoFocusLeftFilled, LayoutColumnTwoSplitLeftFocusTopLeftFilled, LayoutColumnTwoSplitLeftFocusBottomLeftFilled, LayoutColumnTwoFocusRightFilled, LayoutColumnTwoSplitRightFocusTopRightFilled, LayoutColumnTwoSplitRightFocusBottomRightFilled, SettingsRegular, DocumentTextRegular, createFluentIcon, TextSortAscendingRegular, GlobeRegular, ArrowExpandAllRegular, ArrowCollapseAllRegular, CubeTreeRegular, BugRegular, ArrowUploadRegular, ArrowBidirectionalUpDownFilled, ArrowDownloadRegular, StopRegular, RecordRegular, DataBarHorizontalRegular, WrenchRegular, ArrowClockwiseRegular, WeatherSunnyRegular, WeatherMoonRegular, PlugConnectedRegular, PlugDisconnectedRegular, ArrowRotateClockwiseRegular, ArrowExpandRegular, SelectObjectRegular, CubeRegular, CameraRegular, AddRegular, DeleteRegular, FullScreenMaximizeRegular, ChevronDownRegular, ChevronRightRegular, CircleSmallFilled, SaveRegular, PreviousRegular, ArrowPreviousRegular, TriangleLeftRegular, RecordStopRegular, PlayRegular, ArrowNextRegular, NextRegular, PauseRegular, LinkDismissRegular, LinkEditRegular, ArrowUndoRegular, BracesRegular, BracesDismiss16Regular, EyeRegular, CloudArrowUpRegular, CloudArrowDownRegular, EyeOffFilled, ArrowMoveFilled, StopFilled, PlayFilled, LockOpenRegular, LockClosedRegular, ResizeRegular, ChevronUpRegular, ArrowResetRegular, CircleHalfFillRegular, EyedropperRegular, PaintBucketRegular, InkStrokeRegular, StackRegular, FilmstripRegular, PauseFilled, WeatherSunnyLowFilled, LayerRegular, FrameRegular, AppGenericRegular, RectangleLandscapeRegular, BorderOutsideRegular, BorderNoneRegular, MyLocationRegular, BubbleMultipleRegular, LightbulbRegular, VideoFilled, VideoRegular, FlashlightRegular, FlashlightOffRegular, DropRegular, BlurRegular, PipelineRegular, PersonWalkingRegular, DataLineRegular, SoundWaveCircleRegular, PersonSquareRegular, LayerDiagonalPersonRegular, ImageEditRegular, ImageRegular, TargetRegular, PersonFeedbackRegular, BranchRegular, DeleteFilled } from '@fluentui/react-icons';
4
+ import { ErrorCircleRegular, EyeFilled, EyeOffRegular, CheckmarkFilled, EditRegular, FilterRegular, PinFilled, PinRegular, ArrowCircleUpRegular, ChevronCircleRight16Regular, ChevronCircleRight20Regular, ChevronCircleDown16Regular, ChevronCircleDown20Regular, Copy16Regular, CopyRegular, PanelLeftExpandRegular, PanelRightExpandRegular, PanelLeftContractRegular, PanelRightContractRegular, PictureInPictureEnterRegular, MoreHorizontalRegular, LayoutColumnTwoFocusLeftFilled, LayoutColumnTwoSplitLeftFocusTopLeftFilled, LayoutColumnTwoSplitLeftFocusBottomLeftFilled, LayoutColumnTwoFocusRightFilled, LayoutColumnTwoSplitRightFocusTopRightFilled, LayoutColumnTwoSplitRightFocusBottomRightFilled, SettingsRegular, DocumentTextRegular, createFluentIcon, TextSortAscendingRegular, GlobeRegular, WarningRegular, ArrowExpandAllRegular, ArrowCollapseAllRegular, CubeTreeRegular, BugRegular, ArrowUploadRegular, ArrowBidirectionalUpDownFilled, ArrowDownloadRegular, StopRegular, RecordRegular, DataBarHorizontalRegular, WrenchRegular, ArrowClockwiseRegular, WeatherSunnyRegular, WeatherMoonRegular, PlugConnectedRegular, PlugDisconnectedRegular, ArrowRotateClockwiseRegular, ArrowExpandRegular, SelectObjectRegular, CubeRegular, CameraRegular, AddRegular, DeleteRegular, FullScreenMaximizeRegular, ChevronDownRegular, ChevronRightRegular, CircleSmallFilled, SaveRegular, PreviousRegular, ArrowPreviousRegular, TriangleLeftRegular, RecordStopRegular, PlayRegular, ArrowNextRegular, NextRegular, PauseRegular, LinkDismissRegular, LinkEditRegular, ArrowUndoRegular, BracesRegular, BracesDismiss16Regular, EyeRegular, CloudArrowUpRegular, CloudArrowDownRegular, EyeOffFilled, ArrowMoveFilled, StopFilled, PlayFilled, LockOpenRegular, LockClosedRegular, ResizeRegular, ChevronUpRegular, ArrowResetRegular, CircleHalfFillRegular, EyedropperRegular, PaintBucketRegular, InkStrokeRegular, StackRegular, FilmstripRegular, PauseFilled, WeatherSunnyLowFilled, LayerRegular, FrameRegular, AppGenericRegular, RectangleLandscapeRegular, BorderOutsideRegular, BorderNoneRegular, MyLocationRegular, BubbleMultipleRegular, LightbulbRegular, VideoFilled, VideoRegular, FlashlightRegular, FlashlightOffRegular, DropRegular, BlurRegular, PipelineRegular, PersonWalkingRegular, DataLineRegular, SoundWaveCircleRegular, PersonSquareRegular, LayerDiagonalPersonRegular, ImageEditRegular, ImageRegular, TargetRegular, PersonFeedbackRegular, BranchRegular, DeleteFilled } from '@fluentui/react-icons';
5
5
  import { Color3, Color4 } from '@babylonjs/core/Maths/math.color.js';
6
6
  import { Vector3, Quaternion, Matrix, Vector2, Vector4, TmpVectors } from '@babylonjs/core/Maths/math.vector.js';
7
7
  import { Observable } from '@babylonjs/core/Misc/observable.js';
@@ -1936,25 +1936,6 @@ function useSettingsStore() {
1936
1936
  return useContext(SettingsStoreContext);
1937
1937
  }
1938
1938
 
1939
- // These are all "global" settings that aren't produced/owned by a specific service,
1940
- // so we just add them by default directly in the SettingsService.
1941
- const CompactModeSettingDescriptor = {
1942
- key: "CompactMode",
1943
- defaultValue: !matchMedia("(pointer: coarse)").matches,
1944
- };
1945
- const UseDegreesSettingDescriptor = {
1946
- key: "UseDegrees",
1947
- defaultValue: true,
1948
- };
1949
- const UseEulerSettingDescriptor = {
1950
- key: "UseEuler",
1951
- defaultValue: true,
1952
- };
1953
- const DisableCopySettingDescriptor = {
1954
- key: "DisableCopy",
1955
- defaultValue: false,
1956
- };
1957
-
1958
1939
  /**
1959
1940
  * Hook that reads and writes a setting from the settings store.
1960
1941
  * @param descriptor The setting descriptor that identifies the setting and its default value.
@@ -1990,35 +1971,15 @@ function useSetting(descriptor) {
1990
1971
  }
1991
1972
  return [value, setValue, resetValue];
1992
1973
  }
1993
- const RadiansToDegrees = 180 / Math.PI;
1994
- function WrapAngle(angle) {
1995
- angle %= Math.PI * 2;
1996
- if (angle < 0) {
1997
- angle += Math.PI * 2;
1998
- }
1999
- return angle;
2000
- }
2001
- /**
2002
- * Gets functions used to convert to/from display values for angles based on the current settings.
2003
- * @returns A tuple containing the functions to convert to and from display values.
2004
- */
2005
- function useAngleConverters() {
2006
- const [useDegrees] = useSetting(UseDegreesSettingDescriptor);
2007
- const toDisplayValue = useCallback((angle, wrap = false) => {
2008
- if (wrap) {
2009
- angle = WrapAngle(angle);
2010
- }
2011
- return useDegrees ? angle * RadiansToDegrees : angle;
2012
- }, [useDegrees]);
2013
- const fromDisplayValue = useCallback((angle, wrap = false) => {
2014
- angle = useDegrees ? angle / RadiansToDegrees : angle;
2015
- if (wrap) {
2016
- angle = WrapAngle(angle);
2017
- }
2018
- return angle;
2019
- }, [useDegrees]);
2020
- return [toDisplayValue, fromDisplayValue, useDegrees];
2021
- }
1974
+
1975
+ const CompactModeSettingDescriptor = {
1976
+ key: "CompactMode",
1977
+ defaultValue: !matchMedia("(pointer: coarse)").matches,
1978
+ };
1979
+ const DisableCopySettingDescriptor = {
1980
+ key: "DisableCopy",
1981
+ defaultValue: false,
1982
+ };
2022
1983
 
2023
1984
  const UXContextProvider = (props) => {
2024
1985
  const [compactMode] = useSetting(CompactModeSettingDescriptor);
@@ -2540,6 +2501,47 @@ function usePollingObservable(delay) {
2540
2501
  return observable;
2541
2502
  }
2542
2503
 
2504
+ // These are all "global" settings that aren't produced/owned by a specific service,
2505
+ // so we just add them by default directly in the SettingsService.
2506
+ const UseDegreesSettingDescriptor = {
2507
+ key: "UseDegrees",
2508
+ defaultValue: true,
2509
+ };
2510
+ const UseEulerSettingDescriptor = {
2511
+ key: "UseEuler",
2512
+ defaultValue: true,
2513
+ };
2514
+
2515
+ const RadiansToDegrees = 180 / Math.PI;
2516
+ function WrapAngle(angle) {
2517
+ angle %= Math.PI * 2;
2518
+ if (angle < 0) {
2519
+ angle += Math.PI * 2;
2520
+ }
2521
+ return angle;
2522
+ }
2523
+ /**
2524
+ * Gets functions used to convert to/from display values for angles based on the current settings.
2525
+ * @returns A tuple containing the functions to convert to and from display values.
2526
+ */
2527
+ function useAngleConverters() {
2528
+ const [useDegrees] = useSetting(UseDegreesSettingDescriptor);
2529
+ const toDisplayValue = useCallback((angle, wrap = false) => {
2530
+ if (wrap) {
2531
+ angle = WrapAngle(angle);
2532
+ }
2533
+ return useDegrees ? angle * RadiansToDegrees : angle;
2534
+ }, [useDegrees]);
2535
+ const fromDisplayValue = useCallback((angle, wrap = false) => {
2536
+ angle = useDegrees ? angle / RadiansToDegrees : angle;
2537
+ if (wrap) {
2538
+ angle = WrapAngle(angle);
2539
+ }
2540
+ return angle;
2541
+ }, [useDegrees]);
2542
+ return [toDisplayValue, fromDisplayValue, useDegrees];
2543
+ }
2544
+
2543
2545
  const SequencerLock = new AsyncLock();
2544
2546
  /**
2545
2547
  * Creates a hook for managing teaching moment state.
@@ -2676,11 +2678,6 @@ function ConstructorFactory(constructor) {
2676
2678
  return (...args) => new constructor(...args);
2677
2679
  }
2678
2680
 
2679
- /**
2680
- * The unique identity symbol for the scene context service.
2681
- */
2682
- const SceneContextIdentity = Symbol("SceneContext");
2683
-
2684
2681
  function ToFeaturesString(options) {
2685
2682
  const { defaultWidth, defaultHeight, defaultLeft, defaultTop } = options;
2686
2683
  const features = [];
@@ -3617,6 +3614,46 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
3617
3614
  };
3618
3615
  }
3619
3616
 
3617
+ /**
3618
+ * The unique identity symbol for the settings service.
3619
+ */
3620
+ const SettingsServiceIdentity = Symbol("SettingsService");
3621
+ const SettingsServiceDefinition = {
3622
+ friendlyName: "Settings",
3623
+ consumes: [ShellServiceIdentity],
3624
+ produces: [SettingsServiceIdentity],
3625
+ factory: (shellService) => {
3626
+ const sectionsCollection = new ObservableCollection();
3627
+ const sectionContentCollection = new ObservableCollection();
3628
+ const registration = shellService.addSidePane({
3629
+ key: "Settings",
3630
+ title: "Settings",
3631
+ icon: SettingsRegular,
3632
+ horizontalLocation: "right",
3633
+ verticalLocation: "top",
3634
+ order: 500,
3635
+ teachingMoment: false,
3636
+ content: () => {
3637
+ const sections = useOrderedObservableCollection(sectionsCollection);
3638
+ const sectionContent = useObservableCollection(sectionContentCollection);
3639
+ return jsx(ExtensibleAccordion, { sections: sections, sectionContent: sectionContent, context: true });
3640
+ },
3641
+ });
3642
+ return {
3643
+ addSection: (section) => sectionsCollection.add(section),
3644
+ addSectionContent: (content) => sectionContentCollection.add(content),
3645
+ dispose: () => {
3646
+ registration.dispose();
3647
+ },
3648
+ };
3649
+ },
3650
+ };
3651
+
3652
+ /**
3653
+ * The unique identity symbol for the scene context service.
3654
+ */
3655
+ const SceneContextIdentity = Symbol("SceneContext");
3656
+
3620
3657
  const useSwitchStyles = makeStyles({
3621
3658
  switch: {
3622
3659
  marginLeft: "auto",
@@ -3664,54 +3701,6 @@ const SwitchPropertyLine = (props) => {
3664
3701
  return (jsx(PropertyLine, { ...props, children: jsx(Switch, { ...switchProps }) }));
3665
3702
  };
3666
3703
 
3667
- /**
3668
- * The unique identity symbol for the settings service.
3669
- */
3670
- const SettingsServiceIdentity = Symbol("SettingsService");
3671
- const SettingsServiceDefinition = {
3672
- friendlyName: "Settings",
3673
- consumes: [ShellServiceIdentity, SceneContextIdentity],
3674
- produces: [SettingsServiceIdentity],
3675
- factory: (shellService, sceneContext) => {
3676
- const sectionsCollection = new ObservableCollection();
3677
- const sectionContentCollection = new ObservableCollection();
3678
- const registration = shellService.addSidePane({
3679
- key: "Settings",
3680
- title: "Settings",
3681
- icon: SettingsRegular,
3682
- horizontalLocation: "right",
3683
- verticalLocation: "top",
3684
- order: 500,
3685
- teachingMoment: false,
3686
- content: () => {
3687
- const sections = useOrderedObservableCollection(sectionsCollection);
3688
- const sectionContent = useObservableCollection(sectionContentCollection);
3689
- const scene = useObservableState(() => sceneContext.currentScene, sceneContext.currentSceneObservable);
3690
- const [compactMode, setCompactMode] = useSetting(CompactModeSettingDescriptor);
3691
- const [useDegrees, setUseDegrees] = useSetting(UseDegreesSettingDescriptor);
3692
- const [useEuler, setUseEuler] = useSetting(UseEulerSettingDescriptor);
3693
- const [disableCopy, setDisableCopy] = useSetting(DisableCopySettingDescriptor);
3694
- return (jsx(Fragment, { children: scene && (jsx(ExtensibleAccordion, { sections: sections, sectionContent: sectionContent, context: scene, children: jsxs(AccordionSection, { title: "UI", children: [jsx(SwitchPropertyLine, { label: "Compact Mode", description: "Use a more compact UI with less spacing.", value: compactMode, onChange: (checked) => {
3695
- setCompactMode(checked);
3696
- } }), jsx(SwitchPropertyLine, { label: "Use Degrees", description: "Using degrees instead of radians.", value: useDegrees, onChange: (checked) => {
3697
- setUseDegrees(checked);
3698
- } }), jsx(SwitchPropertyLine, { label: "Only Show Euler Angles", description: "Only show Euler angles in rotation properties, rather than quaternions.", value: useEuler, onChange: (checked) => {
3699
- setUseEuler(checked);
3700
- } }), jsx(SwitchPropertyLine, { label: "Disable Copy Button", description: "Disables the copy to clipboard button on property lines. You can still Ctrl+Click on the label to copy.", value: disableCopy, onChange: (checked) => {
3701
- setDisableCopy(checked);
3702
- } })] }) })) }));
3703
- },
3704
- });
3705
- return {
3706
- addSection: (section) => sectionsCollection.add(section),
3707
- addSectionContent: (content) => sectionContentCollection.add(content),
3708
- dispose: () => {
3709
- registration.dispose();
3710
- },
3711
- };
3712
- },
3713
- };
3714
-
3715
3704
  /**
3716
3705
  * The unique identity symbol for the selection service.
3717
3706
  */
@@ -4477,7 +4466,7 @@ const EntityTreeItem = (props) => {
4477
4466
  }, [commands]);
4478
4467
  return (jsxs(Menu, { openOnContext: true, checkedValues: checkedContextMenuItems, onCheckedValueChange: onContextMenuCheckedValueChange, children: [jsx(MenuTrigger, { disableButtonEnhancement: true, children: jsx(FlatTreeItem, { className: mergeClasses(classes.treeItem, isDragging && classes.treeItemDragging, isDropTarget && classes.treeItemDropTarget), value: GetEntityId$1(entityItem.entity),
4479
4468
  // Disable manual expand/collapse when a filter is active.
4480
- itemType: !isFiltering && hasChildren ? "branch" : "leaf", parentValue: entityItem.parent.type === "section" ? entityItem.parent.sectionName : GetEntityId$1(entityItem.parent.entity), "aria-level": entityItem.depth, "aria-setsize": 1, "aria-posinset": 1, onClick: select, onKeyDown: onKeyDown, style: { [treeItemLevelToken]: entityItem.depth }, ...dragProps, children: jsx(TreeItemLayout, { iconBefore: entityItem.icon ? jsx(entityItem.icon, { entity: entityItem.entity }) : null, className: mergeClasses(hasChildren ? classes.treeItemLayoutBranch : classes.treeItemLayoutLeaf, compactMode ? classes.treeItemLayoutCompact : undefined, isDropTarget && classes.treeItemDropTarget), style: isSelected ? { backgroundColor: tokens.colorNeutralBackground1Selected } : undefined, actions: actions, aside: {
4469
+ itemType: !isFiltering && hasChildren ? "branch" : "leaf", parentValue: entityItem.parent.type === "section" ? entityItem.parent.sectionName : GetEntityId$1(entityItem.parent.entity), "aria-level": entityItem.depth, "aria-setsize": 1, "aria-posinset": 1, onClick: select, onKeyDown: onKeyDown, style: { [treeItemLevelToken]: entityItem.depth }, ...dragProps, children: jsx(TreeItemLayout, { iconBefore: displayInfo.validationError ? (jsx(Tooltip$1, { content: displayInfo.validationError, relationship: "description", children: jsx(WarningRegular, {}) })) : entityItem.icon ? (jsx(entityItem.icon, { entity: entityItem.entity })) : null, className: mergeClasses(hasChildren ? classes.treeItemLayoutBranch : classes.treeItemLayoutLeaf, compactMode ? classes.treeItemLayoutCompact : undefined, isDropTarget && classes.treeItemDropTarget), style: isSelected ? { backgroundColor: tokens.colorNeutralBackground1Selected } : undefined, actions: actions, aside: {
4481
4470
  // Match the gap and padding of the actions.
4482
4471
  className: classes.treeItemLayoutAside,
4483
4472
  children: aside,
@@ -5037,7 +5026,8 @@ const FrameStepsStats = ({ context: scene }) => {
5037
5026
  */
5038
5027
  const ButtonLine = (props) => {
5039
5028
  ButtonLine.displayName = "ButtonLine";
5040
- return (jsx(LineContainer, { uniqueId: props.uniqueId ?? props.label, children: jsx(Button, { ...props }) }));
5029
+ const { uniqueId, ...buttonProps } = props;
5030
+ return (jsx(LineContainer, { uniqueId: uniqueId ?? props.label, children: jsx(Button, { ...buttonProps }) }));
5041
5031
  };
5042
5032
 
5043
5033
  /**
@@ -8462,7 +8452,7 @@ function MakeModularTool(options) {
8462
8452
  }
8463
8453
  // Register the extension list service (for browsing/installing extensions) if extension feeds are provided.
8464
8454
  if (extensionFeeds.length > 0) {
8465
- const { ExtensionListServiceDefinition } = await import('./extensionsListService-eRZtqcfj.js');
8455
+ const { ExtensionListServiceDefinition } = await import('./extensionsListService-CBQwBhYh.js');
8466
8456
  await serviceContainer.addServiceAsync(ExtensionListServiceDefinition);
8467
8457
  }
8468
8458
  // Register all external services (that make up a unique tool).
@@ -8578,14 +8568,14 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
8578
8568
  description: "Adds a new panel for easy creation of various Babylon assets. This is a WIP extension...expect changes!",
8579
8569
  keywords: ["creation", "tools"],
8580
8570
  ...BabylonWebResources,
8581
- getExtensionModuleAsync: async () => await import('./quickCreateToolsService-MzZbVrvr.js'),
8571
+ getExtensionModuleAsync: async () => await import('./quickCreateToolsService-C38aK2nP.js'),
8582
8572
  },
8583
8573
  {
8584
8574
  name: "Reflector",
8585
8575
  description: "Connects to the Reflector Bridge for real-time scene synchronization with the Babylon.js Sandbox.",
8586
8576
  keywords: ["reflector", "bridge", "sync", "sandbox", "tools"],
8587
8577
  ...BabylonWebResources,
8588
- getExtensionModuleAsync: async () => await import('./reflectorService-DdPEZLjO.js'),
8578
+ getExtensionModuleAsync: async () => await import('./reflectorService-Bs9E2OMh.js'),
8589
8579
  },
8590
8580
  ]);
8591
8581
 
@@ -17050,6 +17040,8 @@ const ParticleSystemEmitterProperties = (props) => {
17050
17040
  useProperty(emitterVector, "_y");
17051
17041
  useProperty(emitterVector, "_z");
17052
17042
  const particleEmitterType = useProperty(system, "particleEmitterType");
17043
+ const meshEmitter = particleEmitterType instanceof MeshParticleEmitter ? particleEmitterType : undefined;
17044
+ const useMeshNormalsForDirection = useProperty(meshEmitter, "useMeshNormalsForDirection");
17053
17045
  // Derive the current dropdown value from the current instance to stay in sync with external changes.
17054
17046
  const derivedEmitterTypeKey = (() => {
17055
17047
  if (particleEmitterType instanceof SphereParticleEmitter) {
@@ -17153,21 +17145,21 @@ const ParticleSystemEmitterProperties = (props) => {
17153
17145
  break;
17154
17146
  }
17155
17147
  }
17156
- } }), particleEmitterType instanceof MeshParticleEmitter && (jsx(Fragment, { children: scene && scene.meshes.length > 0 ? (jsx(Property, { component: StringDropdownPropertyLine, propertyPath: "source", label: "Source", value: particleEmitterType.mesh ? `mesh:${particleEmitterType.mesh.uniqueId}` : `mesh:${scene.meshes[0].uniqueId}`, options: scene.meshes.map((mesh) => {
17157
- const uniqueId = mesh.uniqueId;
17158
- const name = mesh.name ?? "(unnamed)";
17159
- const label = `${name} (#${uniqueId})`;
17160
- return {
17161
- label,
17162
- value: `mesh:${uniqueId}`,
17163
- };
17164
- }), onChange: (value) => {
17165
- const next = String(value);
17166
- const uniqueIdText = next.replace("mesh:", "");
17167
- const uniqueId = Number(uniqueIdText);
17168
- const mesh = scene.meshes.find((candidate) => candidate.uniqueId === uniqueId) ?? null;
17169
- particleEmitterType.mesh = mesh;
17170
- } })) : (jsx(Property, { component: TextPropertyLine, propertyPath: "source", label: "Source", value: "No meshes in scene." })) })), particleEmitterType instanceof BoxParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction1", target: particleEmitterType, propertyKey: "direction1" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction2", target: particleEmitterType, propertyKey: "direction2" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Min emit box", target: particleEmitterType, propertyKey: "minEmitBox" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Max emit box", target: particleEmitterType, propertyKey: "maxEmitBox" })] })), particleEmitterType instanceof ConeParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Height range", target: particleEmitterType, propertyKey: "heightRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Emit from spawn point only", target: particleEmitterType, propertyKey: "emitFromSpawnPointOnly" }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof SphereParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius", target: particleEmitterType, propertyKey: "radius", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof CylinderParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius", target: particleEmitterType, propertyKey: "radius", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Height", target: particleEmitterType, propertyKey: "height", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof HemisphericParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius", target: particleEmitterType, propertyKey: "radius", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof PointParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction1", target: particleEmitterType, propertyKey: "direction1" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction2", target: particleEmitterType, propertyKey: "direction2" })] }))] })), !scene && jsx(TextPropertyLine, { label: "Emitter", value: "No scene available." })] }));
17148
+ } }), particleEmitterType instanceof MeshParticleEmitter && (jsxs(Fragment, { children: [scene && scene.meshes.length > 0 ? (jsx(Property, { component: StringDropdownPropertyLine, propertyPath: "source", label: "Source", value: particleEmitterType.mesh ? `mesh:${particleEmitterType.mesh.uniqueId}` : `mesh:${scene.meshes[0].uniqueId}`, options: scene.meshes.map((mesh) => {
17149
+ const uniqueId = mesh.uniqueId;
17150
+ const name = mesh.name ?? "(unnamed)";
17151
+ const label = `${name} (#${uniqueId})`;
17152
+ return {
17153
+ label,
17154
+ value: `mesh:${uniqueId}`,
17155
+ };
17156
+ }), onChange: (value) => {
17157
+ const next = String(value);
17158
+ const uniqueIdText = next.replace("mesh:", "");
17159
+ const uniqueId = Number(uniqueIdText);
17160
+ const mesh = scene.meshes.find((candidate) => candidate.uniqueId === uniqueId) ?? null;
17161
+ particleEmitterType.mesh = mesh;
17162
+ } })) : (jsx(Property, { component: TextPropertyLine, propertyPath: "source", label: "Source", value: "No meshes in scene." })), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use normals for direction", target: particleEmitterType, propertyKey: "useMeshNormalsForDirection" }), !useMeshNormalsForDirection && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction1", target: particleEmitterType, propertyKey: "direction1" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction2", target: particleEmitterType, propertyKey: "direction2" })] }))] })), particleEmitterType instanceof BoxParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction1", target: particleEmitterType, propertyKey: "direction1" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction2", target: particleEmitterType, propertyKey: "direction2" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Min emit box", target: particleEmitterType, propertyKey: "minEmitBox" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Max emit box", target: particleEmitterType, propertyKey: "maxEmitBox" })] })), particleEmitterType instanceof ConeParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Height range", target: particleEmitterType, propertyKey: "heightRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Emit from spawn point only", target: particleEmitterType, propertyKey: "emitFromSpawnPointOnly" }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof SphereParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius", target: particleEmitterType, propertyKey: "radius", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof CylinderParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius", target: particleEmitterType, propertyKey: "radius", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Height", target: particleEmitterType, propertyKey: "height", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof HemisphericParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius", target: particleEmitterType, propertyKey: "radius", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof PointParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction1", target: particleEmitterType, propertyKey: "direction1" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction2", target: particleEmitterType, propertyKey: "direction2" })] }))] })), !scene && jsx(TextPropertyLine, { label: "Emitter", value: "No scene available." })] }));
17171
17163
  };
17172
17164
 
17173
17165
  const useStyles$h = makeStyles({
@@ -18238,7 +18230,7 @@ const IblShadowsRenderPipelineScreenspaceProperties = (props) => {
18238
18230
  const IblShadowsRenderPipelineDebugProperties = (props) => {
18239
18231
  const { pipeline } = props;
18240
18232
  const allowDebugPasses = useProperty(pipeline, "allowDebugPasses");
18241
- return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "Allow Debug Passes", target: pipeline, propertyKey: "allowDebugPasses" }), allowDebugPasses && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "Voxel Debug Enabled", target: pipeline, propertyKey: "voxelDebugEnabled" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "CDF Debug Enabled", target: pipeline, propertyKey: "cdfDebugEnabled" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Voxel Tracing Debug Enabled", target: pipeline, propertyKey: "voxelTracingDebugEnabled" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Spatial Blur Debug Enabled", target: pipeline, propertyKey: "spatialBlurPassDebugEnabled" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Accumulation Pass Debug Enabled", target: pipeline, propertyKey: "accumulationPassDebugEnabled" })] }))] }));
18233
+ return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "Allow Debug Passes", target: pipeline, propertyKey: "allowDebugPasses" }), allowDebugPasses && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "CDF Debug Enabled", target: pipeline, propertyKey: "cdfDebugEnabled" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Voxel Tracing Debug Enabled", target: pipeline, propertyKey: "voxelTracingDebugEnabled" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Spatial Blur Debug Enabled", target: pipeline, propertyKey: "spatialBlurPassDebugEnabled" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Accumulation Pass Debug Enabled", target: pipeline, propertyKey: "accumulationPassDebugEnabled" })] }))] }));
18242
18234
  };
18243
18235
 
18244
18236
  const RenderingPipelinePropertiesServiceDefinition = {
@@ -18771,12 +18763,42 @@ const SpriteManagerActionsProperties = (props) => {
18771
18763
  * @param faceOrLayer if the texture has multiple faces, the face index to use for the source. For 2D array textures, this is the layer index.
18772
18764
  * @param channels a filter for which of the RGBA channels to return in the result
18773
18765
  * @param lod if the texture has multiple LODs, the lod index to use for the source
18766
+ * @param slice if the texture is 3D, the depth slice index to use for the source
18774
18767
  * @returns the 8-bit texture data
18775
18768
  */
18776
- async function ApplyChannelsToTextureDataAsync(texture, width, height, faceOrLayer, channels, lod = 0) {
18769
+ async function ApplyChannelsToTextureDataAsync(texture, width, height, faceOrLayer, channels, lod = 0, slice = 0) {
18770
+ const internalTexture = texture.getInternalTexture();
18771
+ const is3DTexture = texture.is3D || !!internalTexture?.is3D;
18772
+ const textureFormat = internalTexture?.format ?? texture.textureFormat;
18777
18773
  // For cube maps, force RTT path to ensure correct face orientation and gamma correction
18778
18774
  // For 2D array textures, face is reinterpreted as the layer index for direct pixel readback
18779
- const data = await GetTextureDataAsync(texture, width, height, faceOrLayer, lod, texture.isCube);
18775
+ const data = await GetTextureDataAsync(texture, width, height, faceOrLayer, lod, texture.isCube || is3DTexture, slice);
18776
+ const forceOpaqueAlpha = is3DTexture || _TextureFormatHasNoAlpha(textureFormat);
18777
+ if (forceOpaqueAlpha) {
18778
+ for (let i = 3; i < width * height * 4; i += 4) {
18779
+ data[i] = 255;
18780
+ }
18781
+ }
18782
+ else if (texture.getScene()?.getEngine().isWebGPU) {
18783
+ let alphaAllZero = true;
18784
+ let hasNonZeroColor = false;
18785
+ for (let i = 0; i < width * height * 4; i += 4) {
18786
+ if (data[i] !== 0 || data[i + 1] !== 0 || data[i + 2] !== 0) {
18787
+ hasNonZeroColor = true;
18788
+ }
18789
+ if (data[i + 3] !== 0) {
18790
+ alphaAllZero = false;
18791
+ break;
18792
+ }
18793
+ }
18794
+ // Some WebGPU RTT readback paths can return zeroed alpha for textures that
18795
+ // are effectively opaque in source data. In that case, force opaque preview.
18796
+ if (alphaAllZero && hasNonZeroColor) {
18797
+ for (let i = 3; i < width * height * 4; i += 4) {
18798
+ data[i] = 255;
18799
+ }
18800
+ }
18801
+ }
18780
18802
  if (!channels.R || !channels.G || !channels.B || !channels.A) {
18781
18803
  for (let i = 0; i < width * height * 4; i += 4) {
18782
18804
  // If alpha is the only channel, just display alpha across all channels
@@ -18849,6 +18871,40 @@ async function ApplyChannelsToTextureDataAsync(texture, width, height, faceOrLay
18849
18871
  }
18850
18872
  return data;
18851
18873
  }
18874
+ function _TextureFormatHasNoAlpha(format) {
18875
+ switch (format) {
18876
+ case Constants.TEXTUREFORMAT_LUMINANCE:
18877
+ case Constants.TEXTUREFORMAT_R:
18878
+ case Constants.TEXTUREFORMAT_R16_UNORM:
18879
+ case Constants.TEXTUREFORMAT_R16_SNORM:
18880
+ case Constants.TEXTUREFORMAT_RG:
18881
+ case Constants.TEXTUREFORMAT_RG16_UNORM:
18882
+ case Constants.TEXTUREFORMAT_RG16_SNORM:
18883
+ case Constants.TEXTUREFORMAT_RGB:
18884
+ case Constants.TEXTUREFORMAT_RGB16_UNORM:
18885
+ case Constants.TEXTUREFORMAT_RGB16_SNORM:
18886
+ case Constants.TEXTUREFORMAT_DEPTH16:
18887
+ case Constants.TEXTUREFORMAT_DEPTH24:
18888
+ case Constants.TEXTUREFORMAT_DEPTH24_STENCIL8:
18889
+ case Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8:
18890
+ case Constants.TEXTUREFORMAT_DEPTH32_FLOAT:
18891
+ case Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8:
18892
+ case Constants.TEXTUREFORMAT_STENCIL8:
18893
+ case Constants.TEXTUREFORMAT_RED_INTEGER:
18894
+ case Constants.TEXTUREFORMAT_RG_INTEGER:
18895
+ case Constants.TEXTUREFORMAT_RGB_INTEGER:
18896
+ case Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1:
18897
+ case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_S3TC_DXT1_EXT:
18898
+ case Constants.TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL:
18899
+ case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_ETC2:
18900
+ case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ETC2:
18901
+ case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
18902
+ case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
18903
+ return true;
18904
+ default:
18905
+ return false;
18906
+ }
18907
+ }
18852
18908
 
18853
18909
  const useStyles$9 = makeStyles({
18854
18910
  root: {
@@ -18860,6 +18916,10 @@ const useStyles$9 = makeStyles({
18860
18916
  gap: tokens.spacingHorizontalXS,
18861
18917
  padding: 0,
18862
18918
  },
18919
+ sliderContainer: {
18920
+ marginTop: tokens.spacingVerticalXS,
18921
+ marginBottom: tokens.spacingVerticalXS,
18922
+ },
18863
18923
  controlButton: {
18864
18924
  minWidth: "auto",
18865
18925
  flex: "1 1 0", // Equal flex grow/shrink with 0 basis
@@ -18891,15 +18951,28 @@ const TextureChannelStates = {
18891
18951
  A: { R: false, G: false, B: false, A: true },
18892
18952
  ALL: { R: true, G: true, B: true, A: true },
18893
18953
  };
18954
+ /**
18955
+ * Displays a 2D preview for a texture, including channels/cube face controls.
18956
+ * @param props The component properties.
18957
+ * @returns The rendered component.
18958
+ */
18894
18959
  const TexturePreview = (props) => {
18895
18960
  const { texture, disableToolbar = false, maxWidth = "100%", maxHeight = "384px", offsetX = 0, offsetY = 0, width, height, imperativeRef } = props;
18896
18961
  const classes = useStyles$9();
18897
18962
  const canvasRef = useRef(null);
18898
18963
  const [channels, setChannels] = useState(TextureChannelStates.ALL);
18899
18964
  const [face, setFace] = useState(0);
18965
+ const [slice, setSlice] = useState(0);
18966
+ const [lod, setLod] = useState(0);
18900
18967
  const [layer, setLayer] = useState(0);
18901
18968
  const [canvasStyle, setCanvasStyle] = useState();
18902
18969
  const internalTexture = useProperty(texture, "_texture");
18970
+ const is3DTexture = !!internalTexture?.is3D;
18971
+ const baseDepth = Math.max(internalTexture?.depth ?? 1, 1);
18972
+ const lodDepth = Math.max(1, Math.floor(baseDepth / Math.pow(2, lod)));
18973
+ const maxSlice = lodDepth - 1;
18974
+ const lodBaseSize = Math.max(1, Math.min(internalTexture?.width ?? 1, internalTexture?.height ?? 1, is3DTexture ? (internalTexture?.depth ?? 1) : Number.MAX_SAFE_INTEGER));
18975
+ const maxLod = internalTexture?.generateMipMaps ? Math.max(0, Math.floor(Math.log2(lodBaseSize))) : 0;
18903
18976
  const showLayerDropdown = texture.is2DArray;
18904
18977
  const layerCount = texture.is2DArray && internalTexture ? internalTexture.depth : 0;
18905
18978
  useEffect(() => {
@@ -18916,7 +18989,14 @@ const TexturePreview = (props) => {
18916
18989
  }
18917
18990
  try {
18918
18991
  await WhenTextureReadyAsync(texture); // Ensure texture is loaded before grabbing size
18919
- const { width: textureWidth, height: textureHeight } = texture.getSize();
18992
+ const size = texture.getSize();
18993
+ let textureWidth = size.width || internalTexture?.width || 1;
18994
+ let textureHeight = size.height || internalTexture?.height || textureWidth;
18995
+ if (is3DTexture) {
18996
+ const squareSize = Math.max(1, Math.min(textureWidth, textureHeight));
18997
+ textureWidth = squareSize;
18998
+ textureHeight = squareSize;
18999
+ }
18920
19000
  // Calculate canvas dimensions
18921
19001
  const canvasWidth = width ?? textureWidth;
18922
19002
  const canvasHeight = height ?? textureHeight;
@@ -18926,7 +19006,7 @@ const TexturePreview = (props) => {
18926
19006
  const imageWidth = `min(${maxWidth}, calc(${maxHeight} * ${aspectRatio}))`;
18927
19007
  setCanvasStyle({ width: imageWidth });
18928
19008
  // Fetch texture data BEFORE clearing the canvas to avoid flicker
18929
- const data = await ApplyChannelsToTextureDataAsync(texture, textureWidth, textureHeight, texture.is2DArray ? layer : face, channels);
19009
+ const data = await ApplyChannelsToTextureDataAsync(texture, textureWidth, textureHeight, texture.is2DArray ? layer : face, channels, lod, slice);
18930
19010
  // Now set canvas dimensions (this clears the canvas) and draw immediately
18931
19011
  canvas.width = canvasWidth;
18932
19012
  canvas.height = canvasHeight;
@@ -18941,7 +19021,19 @@ const TexturePreview = (props) => {
18941
19021
  catch {
18942
19022
  // If we fail, leave the canvas empty
18943
19023
  }
18944
- }, [texture, face, channels, offsetX, offsetY, width, height, internalTexture, layer]);
19024
+ }, [texture, face, channels, lod, slice, offsetX, offsetY, width, height, internalTexture, layer]);
19025
+ useEffect(() => {
19026
+ if (!is3DTexture || slice <= maxSlice) {
19027
+ return;
19028
+ }
19029
+ setSlice(maxSlice);
19030
+ }, [is3DTexture, maxSlice, slice]);
19031
+ useEffect(() => {
19032
+ if (lod <= maxLod) {
19033
+ return;
19034
+ }
19035
+ setLod(maxLod);
19036
+ }, [lod, maxLod]);
18945
19037
  useImperativeHandle(imperativeRef, () => ({ refresh: updatePreviewAsync }), [updatePreviewAsync]);
18946
19038
  useEffect(() => {
18947
19039
  void updatePreviewAsync();
@@ -18950,7 +19042,7 @@ const TexturePreview = (props) => {
18950
19042
  useEffect(() => {
18951
19043
  void updatePreviewAsync();
18952
19044
  }, [isPinned]);
18953
- return (jsx(LineContainer, { uniqueId: "TexturePreview", children: jsxs("div", { className: classes.root, children: [disableToolbar ? null : texture.isCube ? (jsx(Toolbar$1, { className: classes.controls, size: size, "aria-label": "Cube Faces", children: ["+X", "-X", "+Y", "-Y", "+Z", "-Z"].map((label, idx) => (jsx(ToolbarButton, { className: classes.controlButton, appearance: face === idx ? "primary" : "subtle", onClick: () => setFace(idx), children: label }, label))) })) : (jsx(Toolbar$1, { className: classes.controls, size: size, "aria-label": "Channels", children: ["R", "G", "B", "A", "ALL"].map((ch) => (jsx(ToolbarButton, { className: classes.controlButton, appearance: channels === TextureChannelStates[ch] ? "primary" : "subtle", onClick: () => setChannels(TextureChannelStates[ch]), children: ch }, ch))) })), jsx("div", { className: classes.previewContainer, children: jsx("canvas", { ref: canvasRef, className: classes.preview, style: canvasStyle }) }), !disableToolbar && showLayerDropdown && layerCount > 0 && (jsx(SyncedSliderPropertyLine, { label: "Layer", value: layer, onChange: setLayer, min: 0, max: layerCount - 1, step: 1 })), texture.isRenderTarget && (jsx(Button$1, { appearance: "outline", onClick: () => {
19045
+ return (jsx(LineContainer, { uniqueId: "TexturePreview", children: jsxs("div", { className: classes.root, children: [disableToolbar ? null : texture.isCube ? (jsx(Toolbar$1, { className: classes.controls, size: size, "aria-label": "Cube Faces", children: ["+X", "-X", "+Y", "-Y", "+Z", "-Z"].map((label, idx) => (jsx(ToolbarButton, { className: classes.controlButton, appearance: face === idx ? "primary" : "subtle", onClick: () => setFace(idx), children: label }, label))) })) : (jsx(Toolbar$1, { className: classes.controls, size: size, "aria-label": "Channels", children: ["R", "G", "B", "A", "ALL"].map((ch) => (jsx(ToolbarButton, { className: classes.controlButton, appearance: channels === TextureChannelStates[ch] ? "primary" : "subtle", onClick: () => setChannels(TextureChannelStates[ch]), children: ch }, ch))) })), is3DTexture && (jsxs("div", { className: classes.sliderContainer, children: [jsxs(Label, { children: ["Slice: ", slice, " / ", maxSlice] }), jsx(Slider$1, { min: 0, max: maxSlice, step: 1, value: slice, onChange: (_, data) => setSlice(data.value) })] })), maxLod > 0 && (jsxs("div", { className: classes.sliderContainer, children: [jsxs(Label, { children: ["LOD: ", lod] }), jsx(Slider$1, { min: 0, max: maxLod, step: 1, value: lod, onChange: (_, data) => setLod(data.value) })] })), jsx("div", { className: classes.previewContainer, children: jsx("canvas", { ref: canvasRef, className: classes.preview, style: canvasStyle }) }), !disableToolbar && showLayerDropdown && layerCount > 0 && (jsx(SyncedSliderPropertyLine, { label: "Layer", value: layer, onChange: setLayer, min: 0, max: layerCount - 1, step: 1 })), texture.isRenderTarget && (jsx(Button$1, { appearance: "outline", onClick: () => {
18954
19046
  void updatePreviewAsync();
18955
19047
  }, children: "Refresh" }))] }) }));
18956
19048
  };
@@ -21543,6 +21635,9 @@ const MaterialExplorerServiceDefinition = {
21543
21635
  function IsCameraFrameGraphTask(task) {
21544
21636
  return task.camera instanceof Camera;
21545
21637
  }
21638
+ function IsNodesSectionType(node) {
21639
+ return node instanceof TransformNode || node instanceof Camera || node instanceof Light;
21640
+ }
21546
21641
  const NodeExplorerServiceDefinition = {
21547
21642
  friendlyName: "Node Explorer",
21548
21643
  consumes: [SceneExplorerServiceIdentity, SceneContextIdentity, GizmoServiceIdentity, WatcherServiceIdentity],
@@ -21552,21 +21647,36 @@ const NodeExplorerServiceDefinition = {
21552
21647
  return undefined;
21553
21648
  }
21554
21649
  const nodeMovedObservable = new Observable();
21650
+ // Set of all nodes known to be in the scene, rebuilt each time getRootEntities
21651
+ // is called. Used by getEntityDisplayInfo to detect orphaned ancestor nodes.
21652
+ const knownSceneNodes = new Set();
21555
21653
  const sectionRegistration = sceneExplorerService.addSection({
21556
21654
  displayName: "Nodes",
21557
21655
  order: 100 /* DefaultSectionsOrder.Nodes */,
21558
21656
  getRootEntities: () => {
21559
- const rootNodes = [...scene.rootNodes];
21560
- // If any non-root node has a parent and that parent is not one of the node types shown in the Nodes section,
21561
- // then we should treat it as a root node, otherwise it won't show up anywhere in scene explorer.
21562
- // An example of this is when a Mesh or a TransformNode is parented under a Bone.
21657
+ const rootNodes = new Set(scene.rootNodes);
21658
+ knownSceneNodes.clear();
21659
+ // Ensure all nodes in the scene are reachable in the explorer, even if their
21660
+ // parent was removed from the scene or is not a type shown in the Nodes section.
21563
21661
  for (const node of [...scene.meshes, ...scene.transformNodes, ...scene.cameras, ...scene.lights]) {
21564
- if (node.parent &&
21565
- !(node.parent instanceof AbstractMesh) &&
21566
- !(node.parent instanceof TransformNode) &&
21567
- !(node.parent instanceof Camera) &&
21568
- !(node.parent instanceof Light)) {
21569
- rootNodes.push(node);
21662
+ knownSceneNodes.add(node);
21663
+ if (!node.parent) {
21664
+ continue;
21665
+ }
21666
+ if (!IsNodesSectionType(node.parent)) {
21667
+ // Parent is not a type shown in the Nodes section (e.g. a Bone).
21668
+ // Treat this node as a root so it still appears in the explorer.
21669
+ rootNodes.add(node);
21670
+ }
21671
+ else {
21672
+ // Walk up through Nodes-section-type parents to find the topmost ancestor.
21673
+ // If that ancestor was removed from the scene (not in rootNodes), add it
21674
+ // so the entire subtree remains visible in the explorer.
21675
+ let ancestor = node.parent;
21676
+ while (ancestor.parent && IsNodesSectionType(ancestor.parent)) {
21677
+ ancestor = ancestor.parent;
21678
+ }
21679
+ rootNodes.add(ancestor);
21570
21680
  }
21571
21681
  }
21572
21682
  // Lights within a clustered light container are not included in Scene.lights or Scene.rootNodes.
@@ -21574,23 +21684,32 @@ const NodeExplorerServiceDefinition = {
21574
21684
  for (const light of scene.lights) {
21575
21685
  if (light instanceof ClusteredLightContainer) {
21576
21686
  for (const childLight of light.lights) {
21577
- if (!childLight.parent && !rootNodes.includes(childLight)) {
21578
- rootNodes.push(childLight);
21687
+ knownSceneNodes.add(childLight);
21688
+ if (!childLight.parent) {
21689
+ rootNodes.add(childLight);
21579
21690
  }
21580
21691
  }
21581
21692
  }
21582
21693
  }
21583
- return rootNodes;
21694
+ return [...rootNodes];
21584
21695
  },
21585
21696
  getEntityChildren: (node) => node.getChildren(),
21586
21697
  getEntityDisplayInfo: (node) => {
21587
21698
  const onChangeObservable = new Observable();
21588
21699
  const nameHookToken = watcherService.watchProperty(node, "name", () => onChangeObservable.notifyObservers());
21589
21700
  const parentHookToken = watcherService.watchProperty(node, "parent", () => nodeMovedObservable.notifyObservers(node));
21701
+ // A node is "not in the scene" if it is a Nodes-section type but is not
21702
+ // a known scene node. This handles nodes that were removed from the scene
21703
+ // but still appear because a descendant is in the scene. Nodes from the
21704
+ // !IsNodesSectionType(parent) branch are unaffected because they always
21705
+ // come from the scene's tracking lists. Clustered light children are also
21706
+ // unaffected because they are added to knownSceneNodes explicitly.
21707
+ const validationError = IsNodesSectionType(node) && !knownSceneNodes.has(node) ? "This entity is not in the scene but is shown because a descendant is still in the scene." : undefined;
21590
21708
  return {
21591
21709
  get name() {
21592
21710
  return node.name || `Unnamed ${node.getClassName()}`;
21593
21711
  },
21712
+ validationError,
21594
21713
  onChange: onChangeObservable,
21595
21714
  dispose: () => {
21596
21715
  nameHookToken.dispose();
@@ -22608,7 +22727,7 @@ const CoordinateSystemModeOptions = [
22608
22727
  { label: "Right Handed", value: GLTFLoaderCoordinateSystemMode.FORCE_RIGHT_HANDED },
22609
22728
  ];
22610
22729
  const GLTFLoaderOptionsTool = ({ loaderOptions }) => {
22611
- return (jsx(PropertyLine, { label: "Loader Options", expandByDefault: false, expandedContent: jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always compute bounding box", target: loaderOptions, propertyKey: "alwaysComputeBoundingBox", nullable: true, defaultValue: LoaderOptionDefaults.alwaysComputeBoundingBox }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always compute skeleton root node", target: loaderOptions, propertyKey: "alwaysComputeSkeletonRootNode", nullable: true, defaultValue: LoaderOptionDefaults.alwaysComputeSkeletonRootNode }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Animation start mode", options: AnimationStartModeOptions, target: loaderOptions, propertyKey: "animationStartMode", nullable: true, defaultValue: LoaderOptionDefaults.animationStartMode }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Capture performance counters", target: loaderOptions, propertyKey: "capturePerformanceCounters", nullable: true, defaultValue: LoaderOptionDefaults.capturePerformanceCounters }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile materials", target: loaderOptions, propertyKey: "compileMaterials", nullable: true, defaultValue: LoaderOptionDefaults.compileMaterials }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile shadow generators", target: loaderOptions, propertyKey: "compileShadowGenerators", nullable: true, defaultValue: LoaderOptionDefaults.compileShadowGenerators }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Coordinate system", options: CoordinateSystemModeOptions, target: loaderOptions, propertyKey: "coordinateSystemMode", nullable: true, defaultValue: LoaderOptionDefaults.coordinateSystemMode }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Create instances", target: loaderOptions, propertyKey: "createInstances", nullable: true, defaultValue: LoaderOptionDefaults.createInstances }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Enable logging", target: loaderOptions, propertyKey: "loggingEnabled", nullable: true, defaultValue: LoaderOptionDefaults.loggingEnabled }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load all materials", target: loaderOptions, propertyKey: "loadAllMaterials", nullable: true, defaultValue: LoaderOptionDefaults.loadAllMaterials }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Target FPS", target: loaderOptions, propertyKey: "targetFps", min: 1, max: 120, step: 1, nullable: true, defaultValue: LoaderOptionDefaults.targetFps }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Transparency as coverage", target: loaderOptions, propertyKey: "transparencyAsCoverage", nullable: true, defaultValue: LoaderOptionDefaults.transparencyAsCoverage }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use clip plane", target: loaderOptions, propertyKey: "useClipPlane", nullable: true, defaultValue: LoaderOptionDefaults.useClipPlane }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use sRGB buffers", target: loaderOptions, propertyKey: "useSRGBBuffers", nullable: true, defaultValue: LoaderOptionDefaults.useSRGBBuffers })] }) }));
22730
+ return (jsx(PropertyLine, { label: "Loader Options", expandByDefault: false, expandedContent: jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always Compute Bounding Box", target: loaderOptions, propertyKey: "alwaysComputeBoundingBox", nullable: true, defaultValue: LoaderOptionDefaults.alwaysComputeBoundingBox }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always Compute Skeleton Root Node", target: loaderOptions, propertyKey: "alwaysComputeSkeletonRootNode", nullable: true, defaultValue: LoaderOptionDefaults.alwaysComputeSkeletonRootNode }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Animation Start Mode", options: AnimationStartModeOptions, target: loaderOptions, propertyKey: "animationStartMode", nullable: true, defaultValue: LoaderOptionDefaults.animationStartMode }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Capture Performance Counters", target: loaderOptions, propertyKey: "capturePerformanceCounters", nullable: true, defaultValue: LoaderOptionDefaults.capturePerformanceCounters }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile Materials", target: loaderOptions, propertyKey: "compileMaterials", nullable: true, defaultValue: LoaderOptionDefaults.compileMaterials }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile Shadow Generators", target: loaderOptions, propertyKey: "compileShadowGenerators", nullable: true, defaultValue: LoaderOptionDefaults.compileShadowGenerators }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Coordinate System", options: CoordinateSystemModeOptions, target: loaderOptions, propertyKey: "coordinateSystemMode", nullable: true, defaultValue: LoaderOptionDefaults.coordinateSystemMode }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Create Instances", target: loaderOptions, propertyKey: "createInstances", nullable: true, defaultValue: LoaderOptionDefaults.createInstances }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Don't Use Transmission Helper", target: loaderOptions, propertyKey: "dontUseTransmissionHelper", nullable: true, defaultValue: LoaderOptionDefaults.dontUseTransmissionHelper }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Enable Logging", target: loaderOptions, propertyKey: "loggingEnabled", nullable: true, defaultValue: LoaderOptionDefaults.loggingEnabled }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load All Materials", target: loaderOptions, propertyKey: "loadAllMaterials", nullable: true, defaultValue: LoaderOptionDefaults.loadAllMaterials }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load Morph Targets", target: loaderOptions, propertyKey: "loadMorphTargets", nullable: true, defaultValue: LoaderOptionDefaults.loadMorphTargets }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load Node Animations", target: loaderOptions, propertyKey: "loadNodeAnimations", nullable: true, defaultValue: LoaderOptionDefaults.loadNodeAnimations }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load Only Materials", target: loaderOptions, propertyKey: "loadOnlyMaterials", nullable: true, defaultValue: LoaderOptionDefaults.loadOnlyMaterials }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load Skins", target: loaderOptions, propertyKey: "loadSkins", nullable: true, defaultValue: LoaderOptionDefaults.loadSkins }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Skip Materials", target: loaderOptions, propertyKey: "skipMaterials", nullable: true, defaultValue: LoaderOptionDefaults.skipMaterials }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Target FPS", target: loaderOptions, propertyKey: "targetFps", min: 1, max: 120, step: 1, nullable: true, defaultValue: LoaderOptionDefaults.targetFps }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Transparency As Coverage", target: loaderOptions, propertyKey: "transparencyAsCoverage", nullable: true, defaultValue: LoaderOptionDefaults.transparencyAsCoverage }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use Clip Plane", target: loaderOptions, propertyKey: "useClipPlane", nullable: true, defaultValue: LoaderOptionDefaults.useClipPlane }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use glTF Texture Names", target: loaderOptions, propertyKey: "useGltfTextureNames", nullable: true, defaultValue: LoaderOptionDefaults.useGltfTextureNames }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use OpenPBR", target: loaderOptions, propertyKey: "useOpenPBR", nullable: true, defaultValue: LoaderOptionDefaults.useOpenPBR }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use Range Requests", target: loaderOptions, propertyKey: "useRangeRequests", nullable: true, defaultValue: LoaderOptionDefaults.useRangeRequests }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use sRGB Buffers", target: loaderOptions, propertyKey: "useSRGBBuffers", nullable: true, defaultValue: LoaderOptionDefaults.useSRGBBuffers })] }) }));
22612
22731
  };
22613
22732
  const GLTFExtensionOptionsTool = ({ extensionOptions }) => {
22614
22733
  return (jsx(PropertyLine, { label: "Extension Options", expandByDefault: false, expandedContent: jsx(Fragment, { children: Object.entries(extensionOptions)
@@ -22861,6 +22980,37 @@ const ShellSettingsServiceDefinition = {
22861
22980
  },
22862
22981
  };
22863
22982
 
22983
+ const InspectorSettingsServiceDefinition = {
22984
+ friendlyName: "Inspector Settings",
22985
+ consumes: [SettingsServiceIdentity],
22986
+ factory: (settingsService) => {
22987
+ const settingRegistration = settingsService.addSectionContent({
22988
+ key: "Inspector Settings",
22989
+ section: "UI",
22990
+ component: () => {
22991
+ const [compactMode, setCompactMode] = useSetting(CompactModeSettingDescriptor);
22992
+ const [useDegrees, setUseDegrees] = useSetting(UseDegreesSettingDescriptor);
22993
+ const [useEuler, setUseEuler] = useSetting(UseEulerSettingDescriptor);
22994
+ const [disableCopy, setDisableCopy] = useSetting(DisableCopySettingDescriptor);
22995
+ return (jsxs(Fragment, { children: [jsx(SwitchPropertyLine, { label: "Compact Mode", description: "Use a more compact UI with less spacing.", value: compactMode, onChange: (checked) => {
22996
+ setCompactMode(checked);
22997
+ } }), jsx(SwitchPropertyLine, { label: "Use Degrees", description: "Using degrees instead of radians.", value: useDegrees, onChange: (checked) => {
22998
+ setUseDegrees(checked);
22999
+ } }), jsx(SwitchPropertyLine, { label: "Only Show Euler Angles", description: "Only show Euler angles in rotation properties, rather than quaternions.", value: useEuler, onChange: (checked) => {
23000
+ setUseEuler(checked);
23001
+ } }), jsx(SwitchPropertyLine, { label: "Disable Copy Button", description: "Disables the copy to clipboard button on property lines. You can still Ctrl+Click on the label to copy.", value: disableCopy, onChange: (checked) => {
23002
+ setDisableCopy(checked);
23003
+ } })] }));
23004
+ },
23005
+ });
23006
+ return {
23007
+ dispose: () => {
23008
+ settingRegistration.dispose();
23009
+ },
23010
+ };
23011
+ },
23012
+ };
23013
+
22864
23014
  const UserFeedbackServiceDefinition = {
22865
23015
  friendlyName: "User Feedback",
22866
23016
  consumes: [ShellServiceIdentity],
@@ -23065,7 +23215,7 @@ function ShowInspector(scene, options = {}) {
23065
23215
  // Tools pane tab and related services.
23066
23216
  ToolsServiceDefinition, ExportServiceDefinition, GLTFAnimationImportServiceDefinition, GLTFLoaderOptionsServiceDefinition, GLTFValidationServiceDefinition, CaptureToolsDefinition,
23067
23217
  // Settings pane tab and related services.
23068
- SettingsServiceDefinition, WatcherSettingsServiceDefinition, ShellSettingsServiceDefinition,
23218
+ SettingsServiceDefinition, InspectorSettingsServiceDefinition, WatcherSettingsServiceDefinition, ShellSettingsServiceDefinition,
23069
23219
  // Adds a button to refresh all properties manually (when watcher is in "manual" mode).
23070
23220
  WatcherRefreshToolbarServiceDefinition,
23071
23221
  // Tracks entity selection state (e.g. which Mesh or Material or other entity is currently selected in scene explorer and bound to the properties pane, etc.).
@@ -23922,5 +24072,5 @@ const TextAreaPropertyLine = (props) => {
23922
24072
  // Attach Inspector v2 to Scene.debugLayer as a side effect for back compat.
23923
24073
  AttachDebugLayer();
23924
24074
 
23925
- export { GizmoServiceIdentity as $, Accordion as A, Button as B, CheckboxPropertyLine as C, ColorPickerPopup as D, ColorStepGradientComponent as E, ComboBox as F, ComboBoxPropertyLine as G, ConstructorFactory as H, ConvertOptions as I, DebugServiceIdentity as J, DetachDebugLayer as K, Link as L, MessageBar as M, NumberInputPropertyLine as N, DraggableLine as O, Popover as P, Dropdown as Q, EntitySelector as R, ShellServiceIdentity as S, TextInputPropertyLine as T, ErrorBoundary as U, Vector3PropertyLine as V, ExtensibleAccordion as W, FactorGradientComponent as X, FactorGradientList as Y, FileUploadLine as Z, GetPropertyDescriptor as _, useToast as a, Tooltip as a$, HexPropertyLine as a0, InfoLabel as a1, InputHexField as a2, InputHsvField as a3, InspectableCommandRegistryIdentity as a4, Inspector as a5, InterceptFunction as a6, InterceptProperty as a7, IsPropertyReadonly as a8, LineContainer as a9, SettingsServiceIdentity as aA, SettingsStoreIdentity as aB, ShowInspector as aC, SidePaneContainer as aD, SkeletonSelector as aE, Slider as aF, SpinButton as aG, StartInspectable as aH, StatsServiceIdentity as aI, StringDropdown as aJ, StringDropdownPropertyLine as aK, StringifiedPropertyLine as aL, Switch as aM, SwitchPropertyLine as aN, SyncedSliderInput as aO, SyncedSliderPropertyLine as aP, TeachingMoment as aQ, TextAreaPropertyLine as aR, TextInput as aS, TextPropertyLine as aT, Textarea as aU, TextureSelector as aV, TextureUpload as aW, Theme as aX, ThemeServiceIdentity as aY, ToastProvider as aZ, ToggleButton as a_, LinkPropertyLine as aa, LinkToEntityPropertyLine as ab, List as ac, MakeDialogTeachingMoment as ad, MakeLazyComponent as ae, MakePopoverTeachingMoment as af, MakePropertyHook as ag, MakeTeachingMoment as ah, MaterialSelector as ai, NodeSelector as aj, NumberDropdown as ak, NumberDropdownPropertyLine as al, ObservableCollection as am, Pane as an, PlaceholderPropertyLine as ao, PositionedPopover as ap, PropertiesServiceIdentity as aq, Property as ar, PropertyContext as as, PropertyLine as at, QuaternionPropertyLine as au, RotationVectorPropertyLine as av, SceneExplorerServiceIdentity as aw, SearchBar as ax, SearchBox as ay, SelectionServiceDefinition as az, useInterceptObservable as b, UploadButton as b0, Vector2PropertyLine as b1, Vector4PropertyLine as b2, WatcherServiceIdentity as b3, useAngleConverters as b4, useAsyncResource as b5, useColor3Property as b6, useColor4Property as b7, useEventListener as b8, useEventfulState as b9, useKeyListener as ba, useKeyState as bb, useObservableCollection as bc, useOrderedObservableCollection as bd, usePollingObservable as be, usePropertyChangedNotifier as bf, useQuaternionProperty as bg, useResource as bh, useSetting as bi, useTheme as bj, useThemeMode as bk, useVector3Property as bl, LinkToEntity as c, SpinButtonPropertyLine as d, useProperty as e, SceneContextIdentity as f, SelectionServiceIdentity as g, useObservableState as h, AccordionSection as i, ButtonLine as j, ToolsServiceIdentity as k, AccordionSectionItem as l, AttachDebugLayer as m, BooleanBadgePropertyLine as n, BoundProperty as o, BuiltInsExtensionFeed as p, Checkbox as q, ChildWindow as r, Collapse as s, Color3GradientComponent as t, useExtensionManager as u, Color3GradientList as v, Color3PropertyLine as w, Color4GradientComponent as x, Color4GradientList as y, Color4PropertyLine as z };
23926
- //# sourceMappingURL=index-FWuITINA.js.map
24075
+ export { GizmoServiceIdentity as $, Accordion as A, Button as B, CheckboxPropertyLine as C, ColorPickerPopup as D, ColorStepGradientComponent as E, ComboBox as F, ComboBoxPropertyLine as G, ConstructorFactory as H, ConvertOptions as I, DebugServiceIdentity as J, DetachDebugLayer as K, Link as L, MessageBar as M, NumberInputPropertyLine as N, DraggableLine as O, Popover as P, Dropdown as Q, EntitySelector as R, ShellServiceIdentity as S, TextInputPropertyLine as T, ErrorBoundary as U, Vector3PropertyLine as V, ExtensibleAccordion as W, FactorGradientComponent as X, FactorGradientList as Y, FileUploadLine as Z, GetPropertyDescriptor as _, useToast as a, ToastProvider as a$, HexPropertyLine as a0, InfoLabel as a1, InputHexField as a2, InputHsvField as a3, InspectableCommandRegistryIdentity as a4, Inspector as a5, InterceptFunction as a6, InterceptProperty as a7, IsPropertyReadonly as a8, LineContainer as a9, SelectionServiceDefinition as aA, SettingsServiceIdentity as aB, SettingsStore as aC, SettingsStoreIdentity as aD, ShowInspector as aE, SidePaneContainer as aF, SkeletonSelector as aG, Slider as aH, SpinButton as aI, StartInspectable as aJ, StatsServiceIdentity as aK, StringDropdown as aL, StringDropdownPropertyLine as aM, StringifiedPropertyLine as aN, Switch as aO, SwitchPropertyLine as aP, SyncedSliderInput as aQ, SyncedSliderPropertyLine as aR, TeachingMoment as aS, TextAreaPropertyLine as aT, TextInput as aU, TextPropertyLine as aV, Textarea as aW, TextureSelector as aX, TextureUpload as aY, Theme as aZ, ThemeServiceIdentity as a_, LinkPropertyLine as aa, LinkToEntityPropertyLine as ab, List as ac, MakeDialogTeachingMoment as ad, MakeLazyComponent as ae, MakeModularTool as af, MakePopoverTeachingMoment as ag, MakePropertyHook as ah, MakeTeachingMoment as ai, MaterialSelector as aj, NodeSelector as ak, NumberDropdown as al, NumberDropdownPropertyLine as am, ObservableCollection as an, Pane as ao, PlaceholderPropertyLine as ap, PositionedPopover as aq, PropertiesServiceIdentity as ar, Property as as, PropertyContext as at, PropertyLine as au, QuaternionPropertyLine as av, RotationVectorPropertyLine as aw, SceneExplorerServiceIdentity as ax, SearchBar as ay, SearchBox as az, useInterceptObservable as b, ToggleButton as b0, Tooltip as b1, UploadButton as b2, Vector2PropertyLine as b3, Vector4PropertyLine as b4, WatcherServiceIdentity as b5, useAngleConverters as b6, useAsyncResource as b7, useColor3Property as b8, useColor4Property as b9, useEventListener as ba, useEventfulState as bb, useKeyListener as bc, useKeyState as bd, useObservableCollection as be, useOrderedObservableCollection as bf, usePollingObservable as bg, usePropertyChangedNotifier as bh, useQuaternionProperty as bi, useResource as bj, useTheme as bk, useThemeMode as bl, useVector3Property as bm, LinkToEntity as c, SpinButtonPropertyLine as d, useProperty as e, SceneContextIdentity as f, SelectionServiceIdentity as g, useObservableState as h, AccordionSection as i, ButtonLine as j, ToolsServiceIdentity as k, AccordionSectionItem as l, AttachDebugLayer as m, BooleanBadgePropertyLine as n, BoundProperty as o, BuiltInsExtensionFeed as p, Checkbox as q, ChildWindow as r, Collapse as s, Color3GradientComponent as t, useExtensionManager as u, Color3GradientList as v, Color3PropertyLine as w, Color4GradientComponent as x, Color4GradientList as y, Color4PropertyLine as z };
24076
+ //# sourceMappingURL=index-DmfAhsIm.js.map