@babylonjs/inspector 8.56.2 → 9.1.0

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 (278) hide show
  1. package/lib/components/curveEditor/bottomBar/rangeSelector.d.ts +6 -0
  2. package/lib/components/curveEditor/bottomBar.d.ts +6 -0
  3. package/lib/components/curveEditor/canvas/canvas.d.ts +6 -0
  4. package/lib/components/curveEditor/canvas/curve.d.ts +14 -0
  5. package/lib/components/curveEditor/canvas/curveData.d.ts +40 -0
  6. package/lib/components/curveEditor/canvas/frameBar.d.ts +12 -0
  7. package/lib/components/curveEditor/canvas/graph.d.ts +11 -0
  8. package/lib/components/curveEditor/canvas/keyPoint.d.ts +34 -0
  9. package/lib/components/curveEditor/canvas/playHead.d.ts +12 -0
  10. package/lib/components/curveEditor/canvas/rangeFrameBar.d.ts +10 -0
  11. package/lib/components/curveEditor/curveEditor.d.ts +29 -0
  12. package/lib/components/curveEditor/curveEditorButton.d.ts +31 -0
  13. package/lib/components/curveEditor/curveEditorColors.d.ts +56 -0
  14. package/lib/components/curveEditor/curveEditorContext.d.ts +267 -0
  15. package/lib/components/curveEditor/rangeSelector.d.ts +6 -0
  16. package/lib/components/curveEditor/sideBar/addAnimationPanel.d.ts +10 -0
  17. package/lib/components/curveEditor/sideBar/animationList.d.ts +6 -0
  18. package/lib/components/curveEditor/sideBar/editAnimationPanel.d.ts +12 -0
  19. package/lib/components/curveEditor/sideBar/loadAnimationPanel.d.ts +10 -0
  20. package/lib/components/curveEditor/sideBar/saveAnimationPanel.d.ts +10 -0
  21. package/lib/components/curveEditor/sideBar.d.ts +6 -0
  22. package/lib/components/curveEditor/topBar.d.ts +6 -0
  23. package/lib/components/debug/debugPane.d.ts +6 -0
  24. package/lib/components/errorBoundary.d.ts +31 -0
  25. package/lib/components/extensibleAccordion.d.ts +67 -0
  26. package/lib/components/gizmoToolbar.d.ts +7 -0
  27. package/lib/components/pane.d.ts +4 -0
  28. package/lib/components/performanceViewer/canvasGraph.d.ts +16 -0
  29. package/lib/components/performanceViewer/canvasGraphService.d.ts +238 -0
  30. package/lib/components/performanceViewer/graphSupportingTypes.d.ts +90 -0
  31. package/lib/components/performanceViewer/performanceSidebar.d.ts +10 -0
  32. package/lib/components/performanceViewer/performanceViewer.d.ts +15 -0
  33. package/lib/components/pickingToolbar.d.ts +11 -0
  34. package/lib/components/properties/animation/animationGroupProperties.d.ts +8 -0
  35. package/lib/components/properties/animation/animationsProperties.d.ts +21 -0
  36. package/lib/components/properties/animation/targetedAnimationProperties.d.ts +7 -0
  37. package/lib/components/properties/atmosphereProperties.d.ts +20 -0
  38. package/lib/components/properties/audio/soundProperties.d.ts +8 -0
  39. package/lib/components/properties/boundProperty.d.ts +80 -0
  40. package/lib/components/properties/cameras/arcRotateCameraProperties.d.ts +17 -0
  41. package/lib/components/properties/cameras/cameraProperties.d.ts +10 -0
  42. package/lib/components/properties/cameras/followCameraProperties.d.ts +8 -0
  43. package/lib/components/properties/cameras/freeCameraProperties.d.ts +11 -0
  44. package/lib/components/properties/cameras/geospatialCameraProperties.d.ts +11 -0
  45. package/lib/components/properties/cameras/targetCameraProperties.d.ts +8 -0
  46. package/lib/components/properties/commonGeneralProperties.d.ts +16 -0
  47. package/lib/components/properties/frameGraph/frameGraphProperties.d.ts +8 -0
  48. package/lib/components/properties/generateCopyString.d.ts +7 -0
  49. package/lib/components/properties/lights/areaLightProperties.d.ts +5 -0
  50. package/lib/components/properties/lights/clusteredLightContainerProperties.d.ts +10 -0
  51. package/lib/components/properties/lights/directionalLightProperties.d.ts +8 -0
  52. package/lib/components/properties/lights/hemisphericLightProperties.d.ts +5 -0
  53. package/lib/components/properties/lights/lightProperties.d.ts +7 -0
  54. package/lib/components/properties/lights/pointLightProperties.d.ts +5 -0
  55. package/lib/components/properties/lights/shadowGeneratorProperties.d.ts +6 -0
  56. package/lib/components/properties/lights/shadowLightProperties.d.ts +5 -0
  57. package/lib/components/properties/lights/spotLightProperties.d.ts +5 -0
  58. package/lib/components/properties/linkToEntityPropertyLine.d.ts +27 -0
  59. package/lib/components/properties/materials/materialProperties.d.ts +11 -0
  60. package/lib/components/properties/materials/multiMaterialProperties.d.ts +7 -0
  61. package/lib/components/properties/materials/nodeMaterialProperties.d.ts +8 -0
  62. package/lib/components/properties/materials/normalMapProperties.d.ts +19 -0
  63. package/lib/components/properties/materials/openpbrMaterialProperties.d.ts +61 -0
  64. package/lib/components/properties/materials/pbrBaseMaterialProperties.d.ts +285 -0
  65. package/lib/components/properties/materials/skyMaterialProperties.d.ts +5 -0
  66. package/lib/components/properties/materials/standardMaterialProperties.d.ts +29 -0
  67. package/lib/components/properties/metadataProperties.d.ts +12 -0
  68. package/lib/components/properties/nodes/abstractMeshProperties.d.ts +27 -0
  69. package/lib/components/properties/nodes/gaussianSplattingProperties.d.ts +5 -0
  70. package/lib/components/properties/nodes/meshProperties.d.ts +11 -0
  71. package/lib/components/properties/nodes/nodeProperties.d.ts +7 -0
  72. package/lib/components/properties/particles/attractor.d.ts +23 -0
  73. package/lib/components/properties/particles/attractorAdapter.d.ts +56 -0
  74. package/lib/components/properties/particles/attractorList.d.ts +15 -0
  75. package/lib/components/properties/particles/attractorProperties.d.ts +11 -0
  76. package/lib/components/properties/particles/colorProperties.d.ts +11 -0
  77. package/lib/components/properties/particles/commandsProperties.d.ts +13 -0
  78. package/lib/components/properties/particles/emissionProperties.d.ts +11 -0
  79. package/lib/components/properties/particles/emitterProperties.d.ts +13 -0
  80. package/lib/components/properties/particles/lifetimeProperties.d.ts +11 -0
  81. package/lib/components/properties/particles/nodeEditorProperties.d.ts +12 -0
  82. package/lib/components/properties/particles/rotationProperties.d.ts +11 -0
  83. package/lib/components/properties/particles/sizeProperties.d.ts +11 -0
  84. package/lib/components/properties/particles/spritesheetProperties.d.ts +11 -0
  85. package/lib/components/properties/particles/systemProperties.d.ts +13 -0
  86. package/lib/components/properties/physics/physicsProperties.d.ts +6 -0
  87. package/lib/components/properties/postProcesses/postProcessProperties.d.ts +10 -0
  88. package/lib/components/properties/propertiesPane.d.ts +2 -0
  89. package/lib/components/properties/renderingPipelines/defaultRenderingPipelineProperties.d.ts +23 -0
  90. package/lib/components/properties/renderingPipelines/iblShadowsRenderPipelineProperties.d.ts +11 -0
  91. package/lib/components/properties/renderingPipelines/lensRenderingPipelineProperties.d.ts +8 -0
  92. package/lib/components/properties/renderingPipelines/postProcessRenderPipelineProperties.d.ts +5 -0
  93. package/lib/components/properties/renderingPipelines/ssao2RenderingPipelineProperties.d.ts +8 -0
  94. package/lib/components/properties/renderingPipelines/ssaoRenderingPipelineProperties.d.ts +5 -0
  95. package/lib/components/properties/renderingPipelines/ssrRenderingPipelineProperties.d.ts +17 -0
  96. package/lib/components/properties/skeleton/boneProperties.d.ts +7 -0
  97. package/lib/components/properties/skeleton/skeletonProperties.d.ts +8 -0
  98. package/lib/components/properties/sprites/spriteManagerProperties.d.ts +25 -0
  99. package/lib/components/properties/sprites/spriteProperties.d.ts +19 -0
  100. package/lib/components/properties/textures/advancedDynamicTextureProperties.d.ts +11 -0
  101. package/lib/components/properties/textures/baseTextureProperties.d.ts +16 -0
  102. package/lib/components/properties/textures/cubeTextureProperties.d.ts +5 -0
  103. package/lib/components/properties/textures/multiRenderTargetProperties.d.ts +5 -0
  104. package/lib/components/properties/textures/renderTargetTextureProperties.d.ts +5 -0
  105. package/lib/components/properties/textures/textureFormatUtils.d.ts +48 -0
  106. package/lib/components/properties/textures/texturePreview.d.ts +17 -0
  107. package/lib/components/properties/textures/textureProperties.d.ts +11 -0
  108. package/lib/components/properties/textures/thinTextureProperties.d.ts +8 -0
  109. package/lib/components/properties/transformProperties.d.ts +11 -0
  110. package/lib/components/scene/sceneExplorer.d.ts +182 -0
  111. package/lib/components/scene/sceneExplorerDragDrop.d.ts +38 -0
  112. package/lib/components/scene/sceneProperties.d.ts +19 -0
  113. package/lib/components/stats/countStats.d.ts +5 -0
  114. package/lib/components/stats/frameStepStats.d.ts +8 -0
  115. package/lib/components/stats/performanceStats.d.ts +6 -0
  116. package/lib/components/stats/statsPane.d.ts +3 -0
  117. package/lib/components/stats/systemStats.d.ts +5 -0
  118. package/lib/components/teachingMoment.d.ts +20 -0
  119. package/lib/components/textureEditor/canvasManager.d.ts +113 -0
  120. package/lib/components/textureEditor/canvasShader.d.ts +10 -0
  121. package/lib/components/textureEditor/channels.d.ts +25 -0
  122. package/lib/components/textureEditor/properties.d.ts +23 -0
  123. package/lib/components/textureEditor/status.d.ts +13 -0
  124. package/lib/components/textureEditor/textureEditor.d.ts +113 -0
  125. package/lib/components/textureEditor/tools.d.ts +20 -0
  126. package/lib/components/theme.d.ts +10 -0
  127. package/lib/components/tools/capture/equirectangularCaptureTool.d.ts +5 -0
  128. package/lib/components/tools/capture/gifCaptureTool.d.ts +7 -0
  129. package/lib/components/tools/capture/sceneReplayTool.d.ts +5 -0
  130. package/lib/components/tools/capture/screenshotTool.d.ts +5 -0
  131. package/lib/components/tools/capture/videoCaptureTool.d.ts +5 -0
  132. package/lib/components/tools/exportTools.d.ts +11 -0
  133. package/lib/components/tools/import/gltfAnimationImportTool.d.ts +5 -0
  134. package/lib/components/tools/import/gltfLoaderOptionsTool.d.ts +8 -0
  135. package/lib/components/tools/import/gltfValidationTool.d.ts +5 -0
  136. package/lib/components/tools/reflectorTools.d.ts +5 -0
  137. package/lib/components/tools/toolsPane.d.ts +3 -0
  138. package/lib/components/uxContextProvider.d.ts +2 -0
  139. package/lib/contexts/extensionManagerContext.d.ts +6 -0
  140. package/lib/contexts/propertyContext.d.ts +30 -0
  141. package/lib/contexts/settingsContext.d.ts +3 -0
  142. package/lib/contexts/watcherContext.d.ts +3 -0
  143. package/lib/extensibility/builtInsExtensionFeed.d.ts +21 -0
  144. package/lib/extensibility/defaultInspectorExtensionFeed.d.ts +5 -0
  145. package/lib/extensibility/extensionFeed.d.ts +113 -0
  146. package/lib/extensibility/extensionManager.d.ts +111 -0
  147. package/lib/extensions/quickCreate/cameras.d.ts +14 -0
  148. package/lib/extensions/quickCreate/frameGraphs.d.ts +14 -0
  149. package/lib/extensions/quickCreate/lights.d.ts +14 -0
  150. package/lib/extensions/quickCreate/materials.d.ts +14 -0
  151. package/lib/extensions/quickCreate/meshes.d.ts +10 -0
  152. package/lib/extensions/quickCreate/particles.d.ts +15 -0
  153. package/lib/extensions/quickCreate/quickCreateLayout.d.ts +44 -0
  154. package/lib/extensions/quickCreate/quickCreateToolsService.d.ts +11 -0
  155. package/lib/extensions/quickCreate/renderingPipelines.d.ts +14 -0
  156. package/lib/extensions/quickCreate/settingsPopover.d.ts +14 -0
  157. package/lib/extensions/quickCreate/spriteManagers.d.ts +14 -0
  158. package/lib/{extensionsListService-zYdKn8uM.js → extensionsListService-BmiNjZiw.js} +7 -7
  159. package/lib/extensionsListService-BmiNjZiw.js.map +1 -0
  160. package/lib/hooks/compoundPropertyHooks.d.ts +24 -0
  161. package/lib/hooks/instrumentationHooks.d.ts +9 -0
  162. package/lib/hooks/observableHooks.d.ts +35 -0
  163. package/lib/hooks/pollingHooks.d.ts +7 -0
  164. package/lib/hooks/resourceHooks.d.ts +20 -0
  165. package/lib/hooks/settingsHooks.d.ts +13 -0
  166. package/lib/hooks/teachingMomentHooks.d.ts +34 -0
  167. package/lib/hooks/themeHooks.d.ts +17 -0
  168. package/lib/hooks/useObservableArray.d.ts +11 -0
  169. package/lib/hooks/useResizeHandle.d.ts +35 -0
  170. package/lib/{index-DuVF9zYN.js → index-BCbXjPTn.js} +791 -758
  171. package/lib/index-BCbXjPTn.js.map +1 -0
  172. package/lib/index.d.ts +108 -74767
  173. package/lib/index.js +5 -5
  174. package/lib/inspector.d.ts +41 -0
  175. package/lib/instrumentation/functionInstrumentation.d.ts +20 -0
  176. package/lib/instrumentation/propertyInstrumentation.d.ts +33 -0
  177. package/lib/legacy/debugLayer.d.ts +24 -0
  178. package/lib/legacy/inspectableCustomPropertiesService.d.ts +3 -0
  179. package/lib/legacy/inspector.d.ts +39 -0
  180. package/lib/legacy/legacy.d.ts +9 -0
  181. package/lib/legacy/propertiesSectionMapping.d.ts +99 -0
  182. package/lib/misc/arrayUtils.d.ts +4 -0
  183. package/lib/misc/assert.d.ts +5 -0
  184. package/lib/misc/graphUtils.d.ts +44 -0
  185. package/lib/misc/nodeGeometryEditor.d.ts +3 -0
  186. package/lib/misc/nodeMaterialEditor.d.ts +2 -0
  187. package/lib/misc/nodeParticleEditor.d.ts +2 -0
  188. package/lib/misc/nodeRenderGraphEditor.d.ts +2 -0
  189. package/lib/misc/observableCollection.d.ts +23 -0
  190. package/lib/misc/snippetUtils.d.ts +74 -0
  191. package/lib/misc/textureTools.d.ts +34 -0
  192. package/lib/modularTool.d.ts +37 -0
  193. package/lib/modularity/serviceContainer.d.ts +41 -0
  194. package/lib/modularity/serviceDefinition.d.ts +64 -0
  195. package/lib/{quickCreateToolsService-BtsSLeMY.js → quickCreateToolsService-BoqrJqoM.js} +6 -6
  196. package/lib/quickCreateToolsService-BoqrJqoM.js.map +1 -0
  197. package/lib/{reflectorService-Bzs-Ykos.js → reflectorService-CFTva2GG.js} +6 -6
  198. package/lib/reflectorService-CFTva2GG.js.map +1 -0
  199. package/lib/services/defaultToolbarMetadata.d.ts +5 -0
  200. package/lib/services/extensionsListService.d.ts +3 -0
  201. package/lib/services/gizmoService.d.ts +84 -0
  202. package/lib/services/gizmoToolbarService.d.ts +5 -0
  203. package/lib/services/globalSettings.d.ts +5 -0
  204. package/lib/services/highlightService.d.ts +8 -0
  205. package/lib/services/miniStatsService.d.ts +4 -0
  206. package/lib/services/panes/debugService.d.ts +25 -0
  207. package/lib/services/panes/properties/animationGroupPropertiesService.d.ts +4 -0
  208. package/lib/services/panes/properties/animationPropertiesService.d.ts +5 -0
  209. package/lib/services/panes/properties/atmospherePropertiesService.d.ts +5 -0
  210. package/lib/services/panes/properties/audioPropertiesService.d.ts +3 -0
  211. package/lib/services/panes/properties/cameraPropertiesService.d.ts +7 -0
  212. package/lib/services/panes/properties/commonPropertiesService.d.ts +3 -0
  213. package/lib/services/panes/properties/effectLayerPropertiesService.d.ts +3 -0
  214. package/lib/services/panes/properties/frameGraphPropertiesService.d.ts +3 -0
  215. package/lib/services/panes/properties/lightPropertiesServices.d.ts +4 -0
  216. package/lib/services/panes/properties/materialPropertiesService.d.ts +4 -0
  217. package/lib/services/panes/properties/metadataPropertiesService.d.ts +3 -0
  218. package/lib/services/panes/properties/nodePropertiesService.d.ts +4 -0
  219. package/lib/services/panes/properties/particleSystemPropertiesService.d.ts +4 -0
  220. package/lib/services/panes/properties/physicsPropertiesService.d.ts +3 -0
  221. package/lib/services/panes/properties/postProcessPropertiesService.d.ts +3 -0
  222. package/lib/services/panes/properties/propertiesService.d.ts +53 -0
  223. package/lib/services/panes/properties/renderingPipelinePropertiesService.d.ts +3 -0
  224. package/lib/services/panes/properties/scenePropertiesService.d.ts +4 -0
  225. package/lib/services/panes/properties/skeletonPropertiesService.d.ts +4 -0
  226. package/lib/services/panes/properties/spritePropertiesService.d.ts +4 -0
  227. package/lib/services/panes/properties/texturePropertiesService.d.ts +4 -0
  228. package/lib/services/panes/properties/transformPropertiesService.d.ts +3 -0
  229. package/lib/services/panes/scene/animationGroupExplorerService.d.ts +5 -0
  230. package/lib/services/panes/scene/atmosphereExplorerService.d.ts +5 -0
  231. package/lib/services/panes/scene/defaultSectionsMetadata.d.ts +33 -0
  232. package/lib/services/panes/scene/disposableCommandService.d.ts +4 -0
  233. package/lib/services/panes/scene/effectLayersExplorerService.d.ts +5 -0
  234. package/lib/services/panes/scene/frameGraphExplorerService.d.ts +5 -0
  235. package/lib/services/panes/scene/guiExplorerService.d.ts +5 -0
  236. package/lib/services/panes/scene/materialExplorerService.d.ts +5 -0
  237. package/lib/services/panes/scene/nodeExplorerService.d.ts +7 -0
  238. package/lib/services/panes/scene/particleSystemExplorerService.d.ts +5 -0
  239. package/lib/services/panes/scene/postProcessExplorerService.d.ts +5 -0
  240. package/lib/services/panes/scene/renderingPipelinesExplorerService.d.ts +5 -0
  241. package/lib/services/panes/scene/sceneExplorerService.d.ts +34 -0
  242. package/lib/services/panes/scene/skeletonExplorerService.d.ts +5 -0
  243. package/lib/services/panes/scene/soundExplorerService.d.ts +5 -0
  244. package/lib/services/panes/scene/spriteManagerExplorerService.d.ts +6 -0
  245. package/lib/services/panes/scene/texturesExplorerService.d.ts +5 -0
  246. package/lib/services/panes/settingsService.d.ts +25 -0
  247. package/lib/services/panes/statsService.d.ts +28 -0
  248. package/lib/services/panes/tools/captureService.d.ts +3 -0
  249. package/lib/services/panes/tools/exportService.d.ts +3 -0
  250. package/lib/services/panes/tools/import/gltfAnimationImportService.d.ts +3 -0
  251. package/lib/services/panes/tools/import/gltfLoaderOptionsDefaults.d.ts +46 -0
  252. package/lib/services/panes/tools/import/gltfLoaderOptionsService.d.ts +4 -0
  253. package/lib/services/panes/tools/import/gltfValidationService.d.ts +3 -0
  254. package/lib/services/panes/tools/reflectorService.d.ts +7 -0
  255. package/lib/services/panes/toolsService.d.ts +29 -0
  256. package/lib/services/pickingService.d.ts +7 -0
  257. package/lib/services/reactContextService.d.ts +18 -0
  258. package/lib/services/sceneContext.d.ts +19 -0
  259. package/lib/services/selectionService.d.ts +24 -0
  260. package/lib/services/settingsStore.d.ts +55 -0
  261. package/lib/services/shellService.d.ts +256 -0
  262. package/lib/services/shellSettingsService.d.ts +3 -0
  263. package/lib/services/textureEditor/textureEditorService.d.ts +21 -0
  264. package/lib/services/textureEditor/tools/contrast.d.ts +2 -0
  265. package/lib/services/textureEditor/tools/eyedropper.d.ts +5 -0
  266. package/lib/services/textureEditor/tools/floodfill.d.ts +5 -0
  267. package/lib/services/textureEditor/tools/paintbrush.d.ts +2 -0
  268. package/lib/services/textureEditor/tools/rectangularSelect.d.ts +5 -0
  269. package/lib/services/themeSelectorService.d.ts +3 -0
  270. package/lib/services/themeService.d.ts +60 -0
  271. package/lib/services/userFeedbackService.d.ts +3 -0
  272. package/lib/services/watcherService.d.ts +38 -0
  273. package/lib/themes/babylonTheme.d.ts +3 -0
  274. package/package.json +9 -9
  275. package/lib/extensionsListService-zYdKn8uM.js.map +0 -1
  276. package/lib/index-DuVF9zYN.js.map +0 -1
  277. package/lib/quickCreateToolsService-BtsSLeMY.js.map +0 -1
  278. package/lib/reflectorService-Bzs-Ykos.js.map +0 -1
@@ -1,6 +1,6 @@
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, cloneElement, useImperativeHandle, createElement, Suspense, memo, Fragment as Fragment$1, lazy } from 'react';
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, Switch as Switch$1, createDOMRenderer, RendererProvider, Menu, MenuTrigger, SplitButton, MenuPopover, MenuList, MenuItem, Toolbar as Toolbar$1, ToolbarRadioButton, MenuGroup, MenuGroupHeader, 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';
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
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, 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';
@@ -123,15 +123,15 @@ import { Skeleton } from '@babylonjs/core/Bones/skeleton.js';
123
123
  import { Sprite } from '@babylonjs/core/Sprites/sprite.js';
124
124
  import { SpriteManager } from '@babylonjs/core/Sprites/spriteManager.js';
125
125
  import { GetTextureDataAsync, WhenTextureReadyAsync } from '@babylonjs/core/Misc/textureTools.js';
126
- import { BaseTexture } from '@babylonjs/core/Materials/Textures/baseTexture.js';
127
- import { MultiRenderTarget } from '@babylonjs/core/Materials/Textures/multiRenderTarget.js';
128
- import { RenderTargetTexture } from '@babylonjs/core/Materials/Textures/renderTargetTexture.js';
129
- import { ThinTexture } from '@babylonjs/core/Materials/Textures/thinTexture.js';
130
126
  import { KeyboardEventTypes } from '@babylonjs/core/Events/keyboardEvents.js';
131
127
  import { PointerEventTypes } from '@babylonjs/core/Events/pointerEvents.js';
132
128
  import { HtmlElementTexture } from '@babylonjs/core/Materials/Textures/htmlElementTexture.js';
133
129
  import { ShaderMaterial } from '@babylonjs/core/Materials/shaderMaterial.js';
134
130
  import { CreatePlane } from '@babylonjs/core/Meshes/Builders/planeBuilder.js';
131
+ import { BaseTexture } from '@babylonjs/core/Materials/Textures/baseTexture.js';
132
+ import { MultiRenderTarget } from '@babylonjs/core/Materials/Textures/multiRenderTarget.js';
133
+ import { RenderTargetTexture } from '@babylonjs/core/Materials/Textures/renderTargetTexture.js';
134
+ import { ThinTexture } from '@babylonjs/core/Materials/Textures/thinTexture.js';
135
135
  import '@babylonjs/core/Rendering/boundingBoxRenderer.js';
136
136
  import '@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.js';
137
137
  import '@babylonjs/core/Sprites/spriteSceneComponent.js';
@@ -1845,9 +1845,7 @@ const PropertyLine = forwardRef((props, ref) => {
1845
1845
  defaultValue: undefined, // Don't pass defaultValue to children as there is no guarantee how this will be used and we can't mix controlled + uncontrolled state
1846
1846
  })
1847
1847
  : children;
1848
- return (jsxs(LineContainer, { ref: ref, uniqueId: uniqueId ?? label, label: label, children: [jsxs("div", { className: classes.baseLine, children: [jsx(InfoLabel, { className: classes.infoLabel, htmlFor: "property", info: description, label: label, flexLabel: true, onContextMenu: onCopy ? handleContextMenu : undefined }), jsxs("div", { className: classes.rightContent, id: "property", children: [expandedContent && (jsx(ToggleButton, { title: "Expand/Collapse property", appearance: "transparent", checkedIcon: size === "small" ? ChevronCircleDown16Regular : ChevronCircleDown20Regular, uncheckedIcon: size === "small" ? ChevronCircleRight16Regular : ChevronCircleRight20Regular, value: expanded === true, onChange: setExpanded })), nullable && !ignoreNullable && (
1849
- // If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')
1850
- jsx(Tooltip, { content: props.value == null ? "Enable property" : "Disable property (set to null)", children: jsx(Checkbox$1, { className: classes.checkbox, indicator: { className: classes.checkboxIndicator }, checked: !(props.value == null), onChange: (_, data) => {
1848
+ return (jsxs(LineContainer, { ref: ref, uniqueId: uniqueId ?? label, label: label, children: [jsxs("div", { className: classes.baseLine, children: [jsx(InfoLabel, { className: classes.infoLabel, htmlFor: "property", info: description, label: label, flexLabel: true, onContextMenu: onCopy ? handleContextMenu : undefined }), jsxs("div", { className: classes.rightContent, id: "property", children: [expandedContent && (jsx(ToggleButton, { title: "Expand/Collapse property", appearance: "transparent", checkedIcon: size === "small" ? ChevronCircleDown16Regular : ChevronCircleDown20Regular, uncheckedIcon: size === "small" ? ChevronCircleRight16Regular : ChevronCircleRight20Regular, value: expanded === true, onChange: setExpanded })), nullable && !ignoreNullable && (jsx(Tooltip, { content: props.value == null ? "Enable property" : "Disable property (set to null)", children: jsx(Checkbox$1, { className: classes.checkbox, indicator: { className: classes.checkboxIndicator }, checked: !(props.value == null), onChange: (_, data) => {
1851
1849
  if (data.checked) {
1852
1850
  // if checked this means we are returning to non-null, use cached value if exists. If no cached value, use default value
1853
1851
  cachedVal.current != null ? props.onChange(cachedVal.current) : props.onChange(props.defaultValue);
@@ -2191,6 +2189,39 @@ const SidePaneContainer = forwardRef((props, ref) => {
2191
2189
  return (jsx("div", { className: mergeClasses(classes.paneRootDiv, className), ref: ref, ...rest, children: props.children }));
2192
2190
  });
2193
2191
 
2192
+ /**
2193
+ * The unique identity symbol for the settings store service.
2194
+ */
2195
+ const SettingsStoreIdentity = Symbol("SettingsStore");
2196
+ function GetKey(namespace, settingKey) {
2197
+ return `Babylon/${namespace}/${settingKey}`;
2198
+ }
2199
+ /**
2200
+ * Default implementation of {@link ISettingsStore} that persists settings using browser local storage.
2201
+ */
2202
+ class SettingsStore {
2203
+ /**
2204
+ * Creates a new settings store.
2205
+ * @param _namespace A namespace used to scope the settings keys to avoid collisions with other stores.
2206
+ */
2207
+ constructor(_namespace) {
2208
+ this._namespace = _namespace;
2209
+ this._onChanged = new Observable();
2210
+ }
2211
+ get onChanged() {
2212
+ return this._onChanged;
2213
+ }
2214
+ readSetting(descriptor) {
2215
+ const key = GetKey(this._namespace, descriptor.key);
2216
+ return DataStorage.ReadJson(key, descriptor.defaultValue);
2217
+ }
2218
+ writeSetting(descriptor, value) {
2219
+ const key = GetKey(this._namespace, descriptor.key);
2220
+ DataStorage.WriteJson(key, value);
2221
+ this._onChanged.notifyObservers(descriptor.key);
2222
+ }
2223
+ }
2224
+
2194
2225
  // Generated from https://react.fluentui.dev/?path=/docs/theme-theme-designer--docs
2195
2226
  // Key color: #3A94FC
2196
2227
  /* eslint-disable @typescript-eslint/naming-convention */
@@ -2226,39 +2257,6 @@ const DarkTheme = {
2226
2257
  colorNeutralForeground1: BaseDarkTheme.colorNeutralForeground2,
2227
2258
  };
2228
2259
 
2229
- /**
2230
- * The unique identity symbol for the settings store service.
2231
- */
2232
- const SettingsStoreIdentity = Symbol("SettingsStore");
2233
- function GetKey(namespace, settingKey) {
2234
- return `Babylon/${namespace}/${settingKey}`;
2235
- }
2236
- /**
2237
- * Default implementation of {@link ISettingsStore} that persists settings using browser local storage.
2238
- */
2239
- class SettingsStore {
2240
- /**
2241
- * Creates a new settings store.
2242
- * @param _namespace A namespace used to scope the settings keys to avoid collisions with other stores.
2243
- */
2244
- constructor(_namespace) {
2245
- this._namespace = _namespace;
2246
- this._onChanged = new Observable();
2247
- }
2248
- get onChanged() {
2249
- return this._onChanged;
2250
- }
2251
- readSetting(descriptor) {
2252
- const key = GetKey(this._namespace, descriptor.key);
2253
- return DataStorage.ReadJson(key, descriptor.defaultValue);
2254
- }
2255
- writeSetting(descriptor, value) {
2256
- const key = GetKey(this._namespace, descriptor.key);
2257
- DataStorage.WriteJson(key, value);
2258
- this._onChanged.notifyObservers(descriptor.key);
2259
- }
2260
- }
2261
-
2262
2260
  /**
2263
2261
  * The setting descriptor for persisting the theme mode preference.
2264
2262
  */
@@ -2673,83 +2671,6 @@ function ConstructorFactory(constructor) {
2673
2671
  return (...args) => new constructor(...args);
2674
2672
  }
2675
2673
 
2676
- /**
2677
- * A hook that provides a transient state value and a "pulse" function to set it.
2678
- * The transient value is meant to be consumed immediately after being set, and will be cleared on the next render.
2679
- * @typeParam T The type of the transient value.
2680
- * @returns A tuple containing the transient value and a function to "pulse" the state.
2681
- */
2682
- function useImpulse() {
2683
- const impulseRef = useRef(undefined);
2684
- const [, setVersion] = useState(0);
2685
- const pulse = useCallback((value) => {
2686
- impulseRef.current = value;
2687
- setVersion((v) => v + 1);
2688
- }, []);
2689
- // Consume the impulse value and clear it
2690
- const value = impulseRef.current;
2691
- impulseRef.current = undefined;
2692
- return [value, pulse];
2693
- }
2694
-
2695
- const useStyles$S = makeStyles({
2696
- placeholderDiv: {
2697
- padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
2698
- },
2699
- });
2700
- const PropertiesPane = (props) => {
2701
- const classes = useStyles$S();
2702
- const entity = props.context;
2703
- return entity != null ? (jsx(ExtensibleAccordion, { ...props })) : (jsx("div", { className: classes.placeholderDiv, children: jsx(Body1Strong, { italic: true, children: "No entity selected." }) }));
2704
- };
2705
-
2706
- const useSwitchStyles = makeStyles({
2707
- switch: {
2708
- marginLeft: "auto",
2709
- },
2710
- switchSmall: {
2711
- transform: `scale(.85)`, // workaround since we cannot resize fluent switch
2712
- transformOrigin: "right",
2713
- },
2714
- indicator: {
2715
- margin: 0, // Remove the default right margin so the switch aligns well on the right side inside panels like the properties pane.
2716
- },
2717
- });
2718
- /**
2719
- * This is a primitive fluent boolean switch component whose only knowledge is the shared styling across all tools
2720
- * @param props
2721
- * @returns Switch component
2722
- */
2723
- const Switch = (props) => {
2724
- Switch.displayName = "Switch";
2725
- const { size } = useContext(ToolContext);
2726
- const classes = useSwitchStyles();
2727
- const [checked, setChecked] = useState(() => props.value ?? false);
2728
- useEffect(() => {
2729
- if (props.value != undefined) {
2730
- setChecked(props.value); // Update local state when props.checked changes
2731
- }
2732
- }, [props.value]);
2733
- const onChange = (event, _) => {
2734
- props.onChange && props.onChange(event.target.checked);
2735
- setChecked(event.target.checked);
2736
- };
2737
- return (jsx(Switch$1, { className: mergeClasses(classes.switch, size === "small" && classes.switchSmall), indicator: { className: classes.indicator }, checked: checked, disabled: props.disabled, onChange: onChange }));
2738
- };
2739
-
2740
- /**
2741
- * Wraps a switch in a property line
2742
- * @param props - The properties for the switch and property line
2743
- * @returns A React element representing the property line with a switch
2744
- */
2745
- const SwitchPropertyLine = (props) => {
2746
- SwitchPropertyLine.displayName = "SwitchPropertyLine";
2747
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2748
- const { label, ...switchProps } = props;
2749
- // Ensure the label gets passed to the PropertyLine component and not to the underlying switch
2750
- return (jsx(PropertyLine, { ...props, children: jsx(Switch, { ...switchProps }) }));
2751
- };
2752
-
2753
2674
  /**
2754
2675
  * The unique identity symbol for the scene context service.
2755
2676
  */
@@ -2898,9 +2819,7 @@ const ChildWindow = (props) => {
2898
2819
  return null;
2899
2820
  }
2900
2821
  const { mountNode, renderer } = windowState;
2901
- return (
2902
- // Portal targets the body of the child window.
2903
- jsx(Portal, { mountNode: mountNode, children: jsx(RendererProvider, { renderer: renderer, targetDocument: mountNode.ownerDocument, children: jsx(FluentProvider, { style: {
2822
+ return (jsx(Portal, { mountNode: mountNode, children: jsx(RendererProvider, { renderer: renderer, targetDocument: mountNode.ownerDocument, children: jsx(FluentProvider, { style: {
2904
2823
  display: "flex",
2905
2824
  flexGrow: 1,
2906
2825
  flexDirection: "column",
@@ -3024,7 +2943,7 @@ const RootComponentServiceIdentity = Symbol("RootComponent");
3024
2943
  * The unique identity symbol for the shell service.
3025
2944
  */
3026
2945
  const ShellServiceIdentity = Symbol("ShellService");
3027
- const useStyles$R = makeStyles({
2946
+ const useStyles$S = makeStyles({
3028
2947
  mainView: {
3029
2948
  flex: 1,
3030
2949
  display: "flex",
@@ -3237,14 +3156,14 @@ const DockMenu = (props) => {
3237
3156
  };
3238
3157
  const PaneHeader = (props) => {
3239
3158
  const { id, title, dockOptions } = props;
3240
- const classes = useStyles$R();
3159
+ const classes = useStyles$S();
3241
3160
  return (jsxs("div", { className: classes.paneHeaderDiv, children: [props.icon && (jsx("div", { className: classes.paneHeaderIcon, children: jsx(props.icon, {}) })), jsx(Subtitle2Stronger, { className: mergeClasses(classes.paneHeaderText, !props.icon && classes.paneHeaderTextNoIcon), children: title }), jsx(DockMenu, { sidePaneId: id, dockOptions: dockOptions, children: jsx(Button$1, { className: classes.paneHeaderButton, appearance: "transparent", icon: jsx(MoreHorizontalRegular, {}) }) })] }));
3242
3161
  };
3243
3162
  // This is a wrapper for an item in a toolbar that simply adds a teaching moment, which is useful for dynamically added items, possibly from extensions.
3244
3163
  const ToolbarItem = (props) => {
3245
3164
  // eslint-disable-next-line @typescript-eslint/naming-convention
3246
3165
  const { verticalLocation, horizontalLocation, id, component: Component, displayName } = props;
3247
- const classes = useStyles$R();
3166
+ const classes = useStyles$S();
3248
3167
  const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Bar/${verticalLocation}/${horizontalLocation}/${displayName ?? id}`), [displayName, id]);
3249
3168
  const teachingMoment = useTeachingMoment(props.teachingMoment === false);
3250
3169
  const title = typeof props.teachingMoment === "object" ? props.teachingMoment.title : (displayName ?? id);
@@ -3254,7 +3173,7 @@ const ToolbarItem = (props) => {
3254
3173
  // TODO: Handle overflow, possibly via https://react.fluentui.dev/?path=/docs/components-overflow--docs with priority.
3255
3174
  // This component just renders a toolbar with left aligned toolbar items on the left and right aligned toolbar items on the right.
3256
3175
  const Toolbar = ({ location, components }) => {
3257
- const classes = useStyles$R();
3176
+ const classes = useStyles$S();
3258
3177
  const leftComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "left"), [components]);
3259
3178
  const rightComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "right"), [components]);
3260
3179
  return (jsx(Fragment, { children: components.length > 0 && (jsxs("div", { className: `${classes.bar} ${location === "top" ? classes.barTop : classes.barBottom}`, children: [jsx("div", { className: classes.barLeft, children: leftComponents.map((entry) => (jsx(ToolbarItem, { verticalLocation: location, horizontalLocation: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, teachingMoment: entry.teachingMoment }, entry.key))) }), jsx("div", { className: classes.barRight, children: rightComponents.map((entry) => (jsx(ToolbarItem, { verticalLocation: location, horizontalLocation: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, teachingMoment: entry.teachingMoment }, entry.key))) })] })) }));
@@ -3264,7 +3183,7 @@ const SidePaneTab = (props) => {
3264
3183
  const { location, id, isSelected, isFirst, isLast, dockOptions,
3265
3184
  // eslint-disable-next-line @typescript-eslint/naming-convention
3266
3185
  icon: Icon, title, } = props;
3267
- const classes = useStyles$R();
3186
+ const classes = useStyles$S();
3268
3187
  const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Pane/${location}/${title ?? id}`), [title, id]);
3269
3188
  const teachingMoment = useTeachingMoment(props.teachingMoment === false);
3270
3189
  const tabClass = mergeClasses(classes.tab, isSelected ? classes.selectedTab : classes.unselectedTab, isFirst ? classes.firstTab : undefined, isLast ? classes.lastTab : undefined);
@@ -3276,7 +3195,7 @@ const SidePaneTab = (props) => {
3276
3195
  // In "compact" mode, the tab list is integrated into the pane itself.
3277
3196
  // In "full" mode, the returned tab list is later injected into the toolbar.
3278
3197
  function usePane(location, defaultWidth, minWidth, sidePanes, onSelectSidePane, dockOperations, toolbarMode, topBarItems, bottomBarItems, initialCollapsed) {
3279
- const classes = useStyles$R();
3198
+ const classes = useStyles$S();
3280
3199
  const [topSelectedTab, setTopSelectedTab] = useState();
3281
3200
  const [bottomSelectedTab, setBottomSelectedTab] = useState();
3282
3201
  const [collapsed, setCollapsed] = useState(initialCollapsed);
@@ -3473,7 +3392,7 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
3473
3392
  expand: () => onCollapseChanged.notifyObservers({ location: "right", collapsed: false }),
3474
3393
  };
3475
3394
  const rootComponent = () => {
3476
- const classes = useStyles$R();
3395
+ const classes = useStyles$S();
3477
3396
  const [sidePaneDockOverrides, setSidePaneDockOverrides] = useSetting(SidePaneDockOverridesSettingDescriptor);
3478
3397
  // This function returns a promise that resolves after the dock change takes effect so that
3479
3398
  // we can then select the re-docked pane.
@@ -3693,6 +3612,53 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
3693
3612
  };
3694
3613
  }
3695
3614
 
3615
+ const useSwitchStyles = makeStyles({
3616
+ switch: {
3617
+ marginLeft: "auto",
3618
+ },
3619
+ switchSmall: {
3620
+ transform: `scale(.85)`, // workaround since we cannot resize fluent switch
3621
+ transformOrigin: "right",
3622
+ },
3623
+ indicator: {
3624
+ margin: 0, // Remove the default right margin so the switch aligns well on the right side inside panels like the properties pane.
3625
+ },
3626
+ });
3627
+ /**
3628
+ * This is a primitive fluent boolean switch component whose only knowledge is the shared styling across all tools
3629
+ * @param props
3630
+ * @returns Switch component
3631
+ */
3632
+ const Switch = (props) => {
3633
+ Switch.displayName = "Switch";
3634
+ const { size } = useContext(ToolContext);
3635
+ const classes = useSwitchStyles();
3636
+ const [checked, setChecked] = useState(() => props.value ?? false);
3637
+ useEffect(() => {
3638
+ if (props.value != undefined) {
3639
+ setChecked(props.value); // Update local state when props.checked changes
3640
+ }
3641
+ }, [props.value]);
3642
+ const onChange = (event, _) => {
3643
+ props.onChange && props.onChange(event.target.checked);
3644
+ setChecked(event.target.checked);
3645
+ };
3646
+ return (jsx(Switch$1, { className: mergeClasses(classes.switch, size === "small" && classes.switchSmall), indicator: { className: classes.indicator }, checked: checked, disabled: props.disabled, onChange: onChange }));
3647
+ };
3648
+
3649
+ /**
3650
+ * Wraps a switch in a property line
3651
+ * @param props - The properties for the switch and property line
3652
+ * @returns A React element representing the property line with a switch
3653
+ */
3654
+ const SwitchPropertyLine = (props) => {
3655
+ SwitchPropertyLine.displayName = "SwitchPropertyLine";
3656
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3657
+ const { label, ...switchProps } = props;
3658
+ // Ensure the label gets passed to the PropertyLine component and not to the underlying switch
3659
+ return (jsx(PropertyLine, { ...props, children: jsx(Switch, { ...switchProps }) }));
3660
+ };
3661
+
3696
3662
  /**
3697
3663
  * The unique identity symbol for the settings service.
3698
3664
  */
@@ -3802,6 +3768,36 @@ const SelectionServiceDefinition = {
3802
3768
  },
3803
3769
  };
3804
3770
 
3771
+ /**
3772
+ * A hook that provides a transient state value and a "pulse" function to set it.
3773
+ * The transient value is meant to be consumed immediately after being set, and will be cleared on the next render.
3774
+ * @typeParam T The type of the transient value.
3775
+ * @returns A tuple containing the transient value and a function to "pulse" the state.
3776
+ */
3777
+ function useImpulse() {
3778
+ const impulseRef = useRef(undefined);
3779
+ const [, setVersion] = useState(0);
3780
+ const pulse = useCallback((value) => {
3781
+ impulseRef.current = value;
3782
+ setVersion((v) => v + 1);
3783
+ }, []);
3784
+ // Consume the impulse value and clear it
3785
+ const value = impulseRef.current;
3786
+ impulseRef.current = undefined;
3787
+ return [value, pulse];
3788
+ }
3789
+
3790
+ const useStyles$R = makeStyles({
3791
+ placeholderDiv: {
3792
+ padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
3793
+ },
3794
+ });
3795
+ const PropertiesPane = (props) => {
3796
+ const classes = useStyles$R();
3797
+ const entity = props.context;
3798
+ return entity != null ? (jsx(ExtensibleAccordion, { ...props })) : (jsx("div", { className: classes.placeholderDiv, children: jsx(Body1Strong, { italic: true, children: "No entity selected." }) }));
3799
+ };
3800
+
3805
3801
  /**
3806
3802
  * The unique identity symbol for the properties service.
3807
3803
  */
@@ -3881,106 +3877,16 @@ const PropertiesServiceDefinition = {
3881
3877
  },
3882
3878
  };
3883
3879
 
3884
- /**
3885
- * Performs a topological sort on a graph.
3886
- * @param graph The set of nodes that make up the graph.
3887
- * @param getAdjacentNodes A function that returns the adjacent nodes for a given node.
3888
- * @param onSortedNode A function that is called for each node in the sorted order.
3889
- * @remarks
3890
- * This function allocates. Do not use it in the hot path. Instead use an instance of GraphUtils.
3891
- */
3892
- function SortGraph(graph, getAdjacentNodes, onSortedNode) {
3893
- const sorter = new GraphUtils();
3894
- sorter.sort(graph, getAdjacentNodes, onSortedNode);
3895
- }
3896
- /**
3897
- * Traverses a graph.
3898
- * @param graph The set of nodes that make up the graph.
3899
- * @param getAdjacentNodes A function that returns the adjacent nodes for a given node.
3900
- * @param onBeforeTraverse A function that is called before traversing each node.
3901
- * @param onAfterTraverse A function that is called after traversing each node.
3902
- * @remarks
3903
- * This function allocates. Do not use it in the hot path. Instead use an instance of GraphUtils.
3904
- */
3905
- function TraverseGraph(graph, getAdjacentNodes, onBeforeTraverse, onAfterTraverse) {
3906
- const traverser = new GraphUtils();
3907
- traverser.traverse(graph, getAdjacentNodes, onBeforeTraverse, onAfterTraverse);
3908
- }
3909
- /**
3910
- * A utility class for performing graph operations.
3911
- * @remarks
3912
- * The class allocates new objects, but each operation (e.g. sort, traverse) is allocation free. This is useful when used in the hot path.
3913
- */
3914
- class GraphUtils {
3915
- constructor() {
3916
- // Tracks three states:
3917
- // 1. No entry for the node - this means the node has not been encountered yet during any traversal
3918
- // 2. Entry with value false - this means the node is currently being traversed (needed to detect cycles)
3919
- // 3. Entry with value true - this means the node has already been fully traversed (and cycles were not detected)
3920
- this._traversalState = new Map();
3921
- this._isTraversing = false;
3922
- }
3923
- /**
3924
- * Performs a topological sort on a graph.
3925
- * @param graph The set of nodes that make up the graph.
3926
- * @param getAdjacentNodes A function that returns the adjacent nodes for a given node.
3927
- * @param onSortedNode A function that is called for each node in the sorted order.
3928
- */
3929
- sort(graph, getAdjacentNodes, onSortedNode) {
3930
- this.traverse(graph, getAdjacentNodes, undefined, onSortedNode);
3931
- }
3932
- /**
3933
- * Traverses a graph.
3934
- * @param graph The set of nodes that make up the graph.
3935
- * @param getAdjacentNodes A function that returns the adjacent nodes for a given node.
3936
- * @param onBeforeTraverse A function that is called before traversing each node.
3937
- * @param onAfterTraverse A function that is called after traversing each node.
3938
- */
3939
- traverse(graph, getAdjacentNodes, onBeforeTraverse, onAfterTraverse) {
3940
- // Since the traversal state is re-used, disallow re-entrancy through the getAdjacentNodes or onBeforeTraverse or onAfterTraverse callbacks.
3941
- if (this._isTraversing) {
3942
- throw new Error("This TopologicalSorter instance is already traversing.");
3943
- }
3944
- this._isTraversing = true;
3945
- try {
3946
- for (const node of graph) {
3947
- this._traverseCore(node, getAdjacentNodes, onBeforeTraverse, onAfterTraverse);
3948
- }
3949
- }
3950
- finally {
3951
- this._isTraversing = false;
3952
- this._traversalState.clear();
3953
- }
3954
- }
3955
- _traverseCore(node, getAdjacentNodes, onBeforeTraverse, onAfterTraverse) {
3956
- if (this._traversalState.get(node) !== true) {
3957
- if (this._traversalState.get(node) === false) {
3958
- throw new Error("Graph has cycle.");
3959
- }
3960
- this._traversalState.set(node, false);
3961
- onBeforeTraverse?.(node);
3962
- const adjacentNodes = getAdjacentNodes(node);
3963
- if (adjacentNodes) {
3964
- for (const adjacentNode of adjacentNodes) {
3965
- this._traverseCore(adjacentNode, getAdjacentNodes, onBeforeTraverse, onAfterTraverse);
3966
- }
3967
- }
3968
- this._traversalState.set(node, true);
3969
- onAfterTraverse?.(node);
3970
- }
3971
- }
3972
- }
3973
-
3974
- const NoOpSectionDropProps = {
3975
- onDragOver: () => { },
3976
- onDragLeave: () => { },
3977
- onDrop: () => { },
3978
- };
3979
- const NoOpDragProps = Object.assign({
3980
- draggable: false,
3981
- onDragStart: () => { },
3982
- onDragEnd: () => { },
3983
- }, NoOpSectionDropProps);
3880
+ const NoOpSectionDropProps = {
3881
+ onDragOver: () => { },
3882
+ onDragLeave: () => { },
3883
+ onDrop: () => { },
3884
+ };
3885
+ const NoOpDragProps = Object.assign({
3886
+ draggable: false,
3887
+ onDragStart: () => { },
3888
+ onDragEnd: () => { },
3889
+ }, NoOpSectionDropProps);
3984
3890
  /**
3985
3891
  * Hook that provides drag-drop functionality for the scene explorer.
3986
3892
  * Uses vanilla HTML5 drag and drop APIs.
@@ -4151,6 +4057,96 @@ function useSceneExplorerDragDrop(options) {
4151
4057
  };
4152
4058
  }
4153
4059
 
4060
+ /**
4061
+ * Performs a topological sort on a graph.
4062
+ * @param graph The set of nodes that make up the graph.
4063
+ * @param getAdjacentNodes A function that returns the adjacent nodes for a given node.
4064
+ * @param onSortedNode A function that is called for each node in the sorted order.
4065
+ * @remarks
4066
+ * This function allocates. Do not use it in the hot path. Instead use an instance of GraphUtils.
4067
+ */
4068
+ function SortGraph(graph, getAdjacentNodes, onSortedNode) {
4069
+ const sorter = new GraphUtils();
4070
+ sorter.sort(graph, getAdjacentNodes, onSortedNode);
4071
+ }
4072
+ /**
4073
+ * Traverses a graph.
4074
+ * @param graph The set of nodes that make up the graph.
4075
+ * @param getAdjacentNodes A function that returns the adjacent nodes for a given node.
4076
+ * @param onBeforeTraverse A function that is called before traversing each node.
4077
+ * @param onAfterTraverse A function that is called after traversing each node.
4078
+ * @remarks
4079
+ * This function allocates. Do not use it in the hot path. Instead use an instance of GraphUtils.
4080
+ */
4081
+ function TraverseGraph(graph, getAdjacentNodes, onBeforeTraverse, onAfterTraverse) {
4082
+ const traverser = new GraphUtils();
4083
+ traverser.traverse(graph, getAdjacentNodes, onBeforeTraverse, onAfterTraverse);
4084
+ }
4085
+ /**
4086
+ * A utility class for performing graph operations.
4087
+ * @remarks
4088
+ * The class allocates new objects, but each operation (e.g. sort, traverse) is allocation free. This is useful when used in the hot path.
4089
+ */
4090
+ class GraphUtils {
4091
+ constructor() {
4092
+ // Tracks three states:
4093
+ // 1. No entry for the node - this means the node has not been encountered yet during any traversal
4094
+ // 2. Entry with value false - this means the node is currently being traversed (needed to detect cycles)
4095
+ // 3. Entry with value true - this means the node has already been fully traversed (and cycles were not detected)
4096
+ this._traversalState = new Map();
4097
+ this._isTraversing = false;
4098
+ }
4099
+ /**
4100
+ * Performs a topological sort on a graph.
4101
+ * @param graph The set of nodes that make up the graph.
4102
+ * @param getAdjacentNodes A function that returns the adjacent nodes for a given node.
4103
+ * @param onSortedNode A function that is called for each node in the sorted order.
4104
+ */
4105
+ sort(graph, getAdjacentNodes, onSortedNode) {
4106
+ this.traverse(graph, getAdjacentNodes, undefined, onSortedNode);
4107
+ }
4108
+ /**
4109
+ * Traverses a graph.
4110
+ * @param graph The set of nodes that make up the graph.
4111
+ * @param getAdjacentNodes A function that returns the adjacent nodes for a given node.
4112
+ * @param onBeforeTraverse A function that is called before traversing each node.
4113
+ * @param onAfterTraverse A function that is called after traversing each node.
4114
+ */
4115
+ traverse(graph, getAdjacentNodes, onBeforeTraverse, onAfterTraverse) {
4116
+ // Since the traversal state is re-used, disallow re-entrancy through the getAdjacentNodes or onBeforeTraverse or onAfterTraverse callbacks.
4117
+ if (this._isTraversing) {
4118
+ throw new Error("This TopologicalSorter instance is already traversing.");
4119
+ }
4120
+ this._isTraversing = true;
4121
+ try {
4122
+ for (const node of graph) {
4123
+ this._traverseCore(node, getAdjacentNodes, onBeforeTraverse, onAfterTraverse);
4124
+ }
4125
+ }
4126
+ finally {
4127
+ this._isTraversing = false;
4128
+ this._traversalState.clear();
4129
+ }
4130
+ }
4131
+ _traverseCore(node, getAdjacentNodes, onBeforeTraverse, onAfterTraverse) {
4132
+ if (this._traversalState.get(node) !== true) {
4133
+ if (this._traversalState.get(node) === false) {
4134
+ throw new Error("Graph has cycle.");
4135
+ }
4136
+ this._traversalState.set(node, false);
4137
+ onBeforeTraverse?.(node);
4138
+ const adjacentNodes = getAdjacentNodes(node);
4139
+ if (adjacentNodes) {
4140
+ for (const adjacentNode of adjacentNodes) {
4141
+ this._traverseCore(adjacentNode, getAdjacentNodes, onBeforeTraverse, onAfterTraverse);
4142
+ }
4143
+ }
4144
+ this._traversalState.set(node, true);
4145
+ onAfterTraverse?.(node);
4146
+ }
4147
+ }
4148
+ }
4149
+
4154
4150
  const SyntheticUniqueIds = new WeakMap();
4155
4151
  function GetEntityId(entity) {
4156
4152
  if ("uniqueId" in entity && typeof entity.uniqueId === "number") {
@@ -7234,6 +7230,11 @@ const ToolsServiceDefinition = {
7234
7230
  },
7235
7231
  };
7236
7232
 
7233
+ /**
7234
+ * The unique identity symbol for the react context service.
7235
+ */
7236
+ const ReactContextServiceIdentity = Symbol("ReactContextService");
7237
+
7237
7238
  const useStyles$J = makeStyles({
7238
7239
  dropdown: {
7239
7240
  ...UniformWidthStyling,
@@ -7434,8 +7435,8 @@ const WatcherServiceIdentity = Symbol("WatcherService");
7434
7435
  const WatcherServiceDefinition = {
7435
7436
  friendlyName: "Watcher Service",
7436
7437
  produces: [WatcherServiceIdentity],
7437
- consumes: [SettingsStoreIdentity],
7438
- factory: (settingsStore) => {
7438
+ consumes: [SettingsStoreIdentity, ReactContextServiceIdentity],
7439
+ factory: (settingsStore, reactContextService) => {
7439
7440
  let refreshObservable = null;
7440
7441
  let pollingHandle = null;
7441
7442
  const applySettings = () => {
@@ -7465,7 +7466,7 @@ const WatcherServiceDefinition = {
7465
7466
  }
7466
7467
  });
7467
7468
  applySettings();
7468
- return {
7469
+ const watcherService = {
7469
7470
  watchProperty(target, propertyKey, onChanged) {
7470
7471
  if (refreshObservable) {
7471
7472
  let previousValue = target[propertyKey];
@@ -7490,6 +7491,7 @@ const WatcherServiceDefinition = {
7490
7491
  refreshObservable?.notifyObservers();
7491
7492
  },
7492
7493
  dispose: () => {
7494
+ contextHandle.dispose();
7493
7495
  if (pollingHandle !== null) {
7494
7496
  clearInterval(pollingHandle);
7495
7497
  pollingHandle = null;
@@ -7499,6 +7501,9 @@ const WatcherServiceDefinition = {
7499
7501
  settingsStoreObserver.remove();
7500
7502
  },
7501
7503
  };
7504
+ // Register the WatcherContext provider so React components can access the watcher service.
7505
+ const contextHandle = reactContextService.addContext(WatcherContext.Provider, watcherService);
7506
+ return watcherService;
7502
7507
  },
7503
7508
  };
7504
7509
  const WatchModes = [
@@ -7844,241 +7849,16 @@ const GizmoServiceDefinition = {
7844
7849
  },
7845
7850
  };
7846
7851
 
7847
- // Created by running the following command from the packages/dev/inspector-v2 directory:
7848
- // npm run makeAvatar https://raw.githubusercontent.com/BabylonJS/Brand-Toolkit/master/babylon_logo/fullColor/babylon_logo_color.png 0.8
7849
- const BabylonLogoBase64 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAAFXElEQVR4nO2WbWwTdRzHu+EbYmLgpeILwcQXvvCFLwwGxthG1/Z6d33Ag22FDXAE98wixsCbSiS+4IUhxoQYoyiSGKcogsjaa9c9dw9sbdfrbevW611nYTDYliCRsbv7mrt2sPiGUTZf8Uua9P7/u9/383v4//MzGJ5bjgaDIQ8Ms66FYdYZ/m+D250PgyF/GUy+trb2wshEnfmPvKnG3fukJoZ+vI912vqapRsGg+481cy8I9RSbTONNkw32pXJatMvCcvmN7Q9t5ad1QSBJuzOpHvmo7JXkrX01zfq6Yd3mhxIHrHIQuUOee5EJR4MtN0D8Bnm5jbo37nd+c/UH1jmINXcvF6scxxL1VJ3Zo86kKol5UTVTlmsIXH3p68g35uXASgAoCqyCKBKy4Lup0UL4Bn6Q2piaKmWjM0etSNdTyvCoV2LwsES9daXbixMCZomoKpQFFkFsKg9aUtzv//QM7ln6zYdIlu6lUVuyLw8e7zsLbGGunqrXq8zhMMmOVFZqKQ/+QD3w8GMsB6xAmi/rN0PB+X0qQZ5psGGG/W0LNXT5/9x731tRSDubKquWJlN3H7H7N1GO1K1hDy5v1BJNe/BvPcilIUHj4TVxUWosqJnYMlmfz0H4X0jhANF8l915OJ8oxORCnv0vHHfi0+EcGcBBpwVW9hSaqGdIBSu0qrOXvgCyvzsUsgZ4WVR6zDKYxD59g3cPvspwuVmpZ2g4DPR0khNzcYVA3QwzGY/QT/wFpnBMuVqShKwsCSQDVZVVaQ9LG519z7qgyXAhwCmxnh4TJTSZiThM1NioKpqw4oBWKdzi89CLbDFZrSVudRIfzti0UFMpyXIioJ5fhSDH36Ma9uL0LrTiPDJU/hbSkFWZMxMpyGK4xjv64KPsCmBUit8ZlrqqqjYmBvAXpcaG+pFbGQA0egAOF8rfCZSF/dZaC06/Ll1B9qZciT5CIQED0mawMRg7+oBcEM9OgA/FsbQby1gjQS8JgreUiu8pSQ8Riv8tt2YHO6HKMbXEiCE0KWf4Skh0ElT4A+Q4CpJBAgrWGo3JkMDawzADyPcehlhFwnx0C5IdRRSdSSE/TsRqi5HIhqCmBxfA4DBbh0gFulHjLuO8bZLSJyqh3jIiGS1CeKZE0gNd0FMxiFOaj0Qx8RAT+4AHQyzmTUvAVSo2gngR0PgQkEdguND4LghxC9+A9F7EWI6iaQ0qYsnJ2JITUtIhAe1JtUB2Kc9hl3Oii1+M7XgNRIKW2pVe44fx0iXD6MTI/pxjA0HwUX6wcejSE4JEBM8knFOr3/qpoR4dzt6m4/BW2JW/CYSfgstjVQ8xUV0hWE2BQjb3SBh0zpe9hQUKz7Kif4zn4MbDoKfiIAL92E00p8RFsYwdVOCwIVw/fRp/WheKyjR4OVB0ok2whb17FvBVbz8hU6GeZMl6MudFhu6CJsWjezZXqwEXJUYuvA9eH4IY+MRSGlBb7zId+cQeK8MrduKFO8ui9xttaPDQi+yhO3bPlf1q8t9P5X5bU7Cb6EjQasdAQuteIpMi55Co9pZ14ARz1XwrX+g8/ARtBYUq57iUrmDsKk9hF2re0e7nXk3Z2FoA4khM5D0NjPrfVZ7k99E3Q6SDu0mVDwFJTJrpuE1EmgtKJHbzJTSp+2ZSYGlHS4Aejm1oWaptDlZiz6SZU+Hy/UyS9jOBsz0Qo/VDi3VPiMh95IO+M3UPdbqONnnanhpKYBVm5RhMOS5CwtfcGdH8Q7Hnre9FortJvQ6K6yF+tG/t/J1bU+LVofOJe1PMs3p8kHTRzvKtB7JPuatmfB/TU8vHgutarpz7Y/nZsjR/gUhEcwHmuaM9wAAAABJRU5ErkJggg==";
7850
- const BabylonWebResources = {
7851
- homepage: "https://www.babylonjs.com",
7852
- repository: "https://github.com/BabylonJS/Babylon.js",
7853
- bugs: "https://github.com/BabylonJS/Babylon.js/issues",
7854
- author: {
7855
- name: "Babylon.js",
7856
- avatar: BabylonLogoBase64,
7857
- },
7858
- };
7859
- /**
7860
- * Well-known default built in extensions for the Inspector.
7861
- */
7862
- const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
7863
- {
7864
- name: "Quick Creation Tools (Preview)",
7865
- description: "Adds a new panel for easy creation of various Babylon assets. This is a WIP extension...expect changes!",
7866
- keywords: ["creation", "tools"],
7867
- ...BabylonWebResources,
7868
- getExtensionModuleAsync: async () => await import('./quickCreateToolsService-BtsSLeMY.js'),
7869
- },
7870
- {
7871
- name: "Reflector",
7872
- description: "Connects to the Reflector Bridge for real-time scene synchronization with the Babylon.js Sandbox.",
7873
- keywords: ["reflector", "bridge", "sync", "sandbox", "tools"],
7874
- ...BabylonWebResources,
7875
- getExtensionModuleAsync: async () => await import('./reflectorService-Bzs-Ykos.js'),
7876
- },
7877
- ]);
7878
-
7852
+ const InstalledExtensionsKey = "Extensions/InstalledExtensions";
7853
+ const ExtensionInstalledKeyPrefix = "Extensions/IsExtensionInstalled";
7854
+ function GetExtensionInstalledKey(name) {
7855
+ return `${ExtensionInstalledKeyPrefix}/${name}`;
7856
+ }
7857
+ function GetExtensionIdentity(feed, name) {
7858
+ return `${feed}/${name}`;
7859
+ }
7879
7860
  /**
7880
- * Reusable component which renders a color property line containing a label, colorPicker popout, and expandable RGBA values
7881
- * The expandable RGBA values are synced sliders that allow the user to modify the color's RGBA values directly
7882
- * @param props - PropertyLine props, replacing children with a color object so that we can properly display the color
7883
- * @returns Component wrapping a colorPicker component with a property line
7884
- */
7885
- const ColorPropertyLine = forwardRef((props, ref) => {
7886
- ColorPropertyLine.displayName = "ColorPropertyLine";
7887
- const [color, setColor] = useState(props.value);
7888
- useEffect(() => {
7889
- setColor(props.value);
7890
- }, [props.value]);
7891
- const onSliderChange = (value, key) => {
7892
- let newColor;
7893
- if (key === "a") {
7894
- newColor = Color4.FromColor3(color, value);
7895
- }
7896
- else {
7897
- newColor = color.clone();
7898
- newColor[key] = value / 255;
7899
- }
7900
- setColor(newColor); // Create a new object to trigger re-render
7901
- props.onChange(newColor);
7902
- };
7903
- const onColorPickerChange = (newColor) => {
7904
- setColor(newColor);
7905
- props.onChange(newColor);
7906
- };
7907
- return (jsx(PropertyLine, { ref: ref, ...props, expandedContent: color ? jsx(ColorSliders, { color: color, onSliderChange: onSliderChange }) : undefined, children: jsx(ColorPickerPopup, { ...props, onChange: onColorPickerChange, value: color }) }));
7908
- });
7909
- const ColorSliders = ({ color, onSliderChange }) => (jsxs(Fragment, { children: [jsx(SyncedSliderPropertyLine, { label: "R", value: color.r * 255, min: 0, max: 255, onChange: (value) => onSliderChange(value, "r") }), jsx(SyncedSliderPropertyLine, { label: "G", value: color.g * 255, min: 0, max: 255, onChange: (value) => onSliderChange(value, "g") }), jsx(SyncedSliderPropertyLine, { label: "B", value: color.b * 255, min: 0, max: 255, onChange: (value) => onSliderChange(value, "b") }), color instanceof Color4 && jsx(SyncedSliderPropertyLine, { label: "A", value: color.a, min: 0, max: 1, step: 0.01, onChange: (value) => onSliderChange(value, "a") })] }));
7910
- const Color3PropertyLine = ColorPropertyLine;
7911
- const Color4PropertyLine = ColorPropertyLine;
7912
-
7913
- const useStyles$H = makeStyles({
7914
- uniformWidth: {
7915
- ...UniformWidthStyling,
7916
- },
7917
- });
7918
- /**
7919
- * Wraps a text input in a property line
7920
- * @param props - PropertyLineProps and InputProps
7921
- * @returns property-line wrapped input component
7922
- */
7923
- const TextInputPropertyLine = (props) => {
7924
- TextInputPropertyLine.displayName = "TextInputPropertyLine";
7925
- const classes = useStyles$H();
7926
- return (jsx(PropertyLine, { ...props, children: jsx(TextInput, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
7927
- };
7928
- /**
7929
- * Wraps a number input in a property line
7930
- * To force integer values, use forceInt param (this is distinct from the 'step' param, which will still allow submitting an integer value. forceInt will not)
7931
- * @param props - PropertyLineProps and InputProps
7932
- * @returns property-line wrapped input component
7933
- */
7934
- const NumberInputPropertyLine = (props) => {
7935
- NumberInputPropertyLine.displayName = "NumberInputPropertyLine";
7936
- const classes = useStyles$H();
7937
- return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
7938
- };
7939
-
7940
- const HasZ = (vector) => !(vector instanceof Vector2);
7941
- const HasW = (vector) => vector instanceof Vector4 || vector instanceof Quaternion;
7942
- /**
7943
- * Reusable component which renders a vector property line containing a label, vector value, and expandable XYZW values
7944
- * The expanded section contains a slider/input box for each component of the vector (x, y, z, w)
7945
- * @param props
7946
- * @returns
7947
- */
7948
- const TensorPropertyLine = (props) => {
7949
- TensorPropertyLine.displayName = "TensorPropertyLine";
7950
- const converted = (val) => (props.valueConverter ? props.valueConverter.from(val) : val);
7951
- const formatted = (val) => converted(val).toFixed(props.step !== undefined ? Math.max(0, CalculatePrecision(props.step)) : 2);
7952
- const [vector, setVector] = useState(props.value);
7953
- const { min, max } = props;
7954
- const onChange = (val, key) => {
7955
- const value = props.valueConverter ? props.valueConverter.to(val) : val;
7956
- const newVector = vector.clone();
7957
- newVector[key] = value; // The syncedSlider for 'w' is only rendered when vector is a Vector4, so this is safe
7958
- setVector(newVector);
7959
- props.onChange(newVector);
7960
- };
7961
- useEffect(() => {
7962
- setVector(props.value);
7963
- }, [props.value, props.expandedContent]);
7964
- return (jsx(PropertyLine, { ...props, expandedContent: jsxs(Fragment, { children: [props.expandedContent, vector ? (jsx(VectorSliders, { vector: vector, min: min, max: max, unit: props.unit, step: props.step, precision: props.precision, converted: converted, onChange: onChange })) : undefined] }), children: jsx(Body1, { children: `[${formatted(props.value.x)}, ${formatted(props.value.y)}${HasZ(props.value) ? `, ${formatted(props.value.z)}` : ""}${HasW(props.value) ? `, ${formatted(props.value.w)}` : ""}]` }) }));
7965
- };
7966
- const VectorSliders = ({ vector, min, max, unit, step, precision, converted, onChange }) => (jsxs(Fragment, { children: [jsx(NumberInputPropertyLine, { label: "X", value: converted(vector.x), min: min, max: max, onChange: (val) => onChange(val, "x"), unit: unit, step: step, precision: precision }), jsx(NumberInputPropertyLine, { label: "Y", value: converted(vector.y), min: min, max: max, onChange: (val) => onChange(val, "y"), unit: unit, step: step, precision: precision }), HasZ(vector) && (jsx(NumberInputPropertyLine, { label: "Z", value: converted(vector.z), min: min, max: max, onChange: (val) => onChange(val, "z"), unit: unit, step: step, precision: precision })), HasW(vector) && (jsx(NumberInputPropertyLine, { label: "W", value: converted(vector.w), min: min, max: max, onChange: (val) => onChange(val, "w"), unit: unit, step: step, precision: precision }))] }));
7967
- const ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };
7968
- const RotationVectorPropertyLine = (props) => {
7969
- RotationVectorPropertyLine.displayName = "RotationVectorPropertyLine";
7970
- const step = props.useDegrees ? 1 : 0.01;
7971
- const precision = props.useDegrees ? 1 : 2;
7972
- return (jsx(Vector3PropertyLine, { ...props, unit: props.useDegrees ? "°" : "rad", valueConverter: props.useDegrees ? ToDegreesConverter : undefined, step: step, precision: precision }));
7973
- };
7974
- const QuaternionPropertyLineInternal = TensorPropertyLine;
7975
- const QuaternionPropertyLine = (props) => {
7976
- QuaternionPropertyLine.displayName = "QuaternionPropertyLine";
7977
- const step = props.useDegrees ? 1 : 0.01;
7978
- const precision = props.useDegrees ? 1 : 2;
7979
- const [quat, setQuat] = useState(props.value);
7980
- useEffect(() => {
7981
- setQuat(props.value);
7982
- }, [props.value]);
7983
- // Extract only the properties that exist on QuaternionPropertyLineProps
7984
- const { useEuler, ...restProps } = props;
7985
- const onQuatChange = (val) => {
7986
- setQuat(val);
7987
- props.onChange(val);
7988
- };
7989
- const onEulerChange = (val) => {
7990
- const quat = Quaternion.FromEulerAngles(val.x, val.y, val.z);
7991
- onQuatChange(quat);
7992
- };
7993
- return useEuler ? (jsx(Vector3PropertyLine, { ...restProps, nullable: false, ignoreNullable: false, value: quat.toEulerAngles(), valueConverter: ToDegreesConverter, onChange: onEulerChange, unit: props.useDegrees ? "°" : "rad", step: step, precision: precision, expandedContent: jsx(TextPropertyLine, { label: "Quaternion", value: `[${quat.x.toFixed(4)}, ${quat.y.toFixed(4)}, ${quat.z.toFixed(4)}, ${quat.w.toFixed(4)}]` }) })) : (jsx(QuaternionPropertyLineInternal, { ...props, nullable: false, value: quat, onChange: onQuatChange, unit: props.useDegrees ? "°" : "rad", step: step, precision: precision }));
7994
- };
7995
- const Vector2PropertyLine = TensorPropertyLine;
7996
- const Vector3PropertyLine = TensorPropertyLine;
7997
- const Vector4PropertyLine = TensorPropertyLine;
7998
-
7999
- function IsInspectableObject(entity) {
8000
- return !!entity.inspectableCustomProperties;
8001
- }
8002
- const LegacyInspectableObjectPropertiesServiceDefinition = {
8003
- friendlyName: "Additional Nodes",
8004
- consumes: [PropertiesServiceIdentity],
8005
- factory: (propertiesService) => {
8006
- const propertiesSectionRegistration = propertiesService.addSection({
8007
- identity: "Custom",
8008
- order: Number.MAX_SAFE_INTEGER,
8009
- });
8010
- const propertiesContentRegistration = propertiesService.addSectionContent({
8011
- key: "Additional Nodes Properties",
8012
- predicate: (entity) => IsInspectableObject(entity),
8013
- content: [
8014
- {
8015
- section: "Custom",
8016
- component: ({ context }) => {
8017
- return (jsx(Fragment, { children: (context.inspectableCustomProperties ?? []).map((prop) => {
8018
- const commonProps = {
8019
- target: context,
8020
- propertyKey: prop.propertyName,
8021
- label: prop.label,
8022
- ignoreNullable: true,
8023
- defaultValue: undefined,
8024
- };
8025
- switch (prop.type) {
8026
- case 0 /* InspectableType.Checkbox */:
8027
- return jsx(BoundProperty, { ...commonProps, component: SwitchPropertyLine }, prop.propertyName);
8028
- case 1 /* InspectableType.Slider */:
8029
- return (jsx(BoundProperty, { ...commonProps, min: prop.min, max: prop.max, step: prop.step, component: SyncedSliderPropertyLine }, prop.propertyName));
8030
- case 2 /* InspectableType.Vector3 */:
8031
- return jsx(BoundProperty, { ...commonProps, component: Vector3PropertyLine }, prop.propertyName);
8032
- case 3 /* InspectableType.Quaternion */:
8033
- return jsx(BoundProperty, { ...commonProps, component: QuaternionPropertyLine }, prop.propertyName);
8034
- case 4 /* InspectableType.Color3 */:
8035
- return jsx(BoundProperty, { ...commonProps, component: Color3PropertyLine }, prop.propertyName);
8036
- case 5 /* InspectableType.String */:
8037
- return jsx(BoundProperty, { ...commonProps, component: TextInputPropertyLine }, prop.propertyName);
8038
- case 6 /* InspectableType.Button */:
8039
- return jsx(ButtonLine, { label: prop.label, onClick: () => prop.callback?.() }, prop.propertyName);
8040
- case 7 /* InspectableType.Options */:
8041
- return jsx(BoundProperty, { ...commonProps, component: DropdownPropertyLine, options: prop.options ?? [] }, prop.propertyName);
8042
- case 8 /* InspectableType.Tab */:
8043
- return jsx(BoundProperty, { ...commonProps, component: TextPropertyLine }, prop.propertyName);
8044
- case 9 /* InspectableType.FileButton */:
8045
- return (jsx(FileUploadLine, { label: prop.label, accept: prop.accept ?? "", onClick: (files) => {
8046
- if (files.length > 0 && prop.fileCallback) {
8047
- prop.fileCallback(files[0]);
8048
- }
8049
- } }, prop.propertyName));
8050
- case 10 /* InspectableType.Vector2 */:
8051
- return jsx(BoundProperty, { ...commonProps, component: Vector2PropertyLine }, prop.propertyName);
8052
- }
8053
- }) }));
8054
- },
8055
- },
8056
- ],
8057
- });
8058
- return {
8059
- dispose: () => {
8060
- propertiesSectionRegistration.dispose();
8061
- propertiesContentRegistration.dispose();
8062
- },
8063
- };
8064
- },
8065
- };
8066
-
8067
- const ExtensionManagerContext = createContext(undefined);
8068
- function useExtensionManager() {
8069
- return useContext(ExtensionManagerContext)?.extensionManager;
8070
- }
8071
-
8072
- const InstalledExtensionsKey = "Extensions/InstalledExtensions";
8073
- const ExtensionInstalledKeyPrefix = "Extensions/IsExtensionInstalled";
8074
- function GetExtensionInstalledKey(name) {
8075
- return `${ExtensionInstalledKeyPrefix}/${name}`;
8076
- }
8077
- function GetExtensionIdentity(feed, name) {
8078
- return `${feed}/${name}`;
8079
- }
8080
- /**
8081
- * Manages the installation, uninstallation, enabling, and disabling of extensions.
7861
+ * Manages the installation, uninstallation, enabling, and disabling of extensions.
8082
7862
  */
8083
7863
  class ExtensionManager {
8084
7864
  constructor(_namespace, _serviceContainer, _feeds, _onInstallFailed) {
@@ -8489,7 +8269,12 @@ class ServiceContainer {
8489
8269
  }
8490
8270
  }
8491
8271
 
8492
- const useStyles$G = makeStyles({
8272
+ const ExtensionManagerContext = createContext(undefined);
8273
+ function useExtensionManager() {
8274
+ return useContext(ExtensionManagerContext)?.extensionManager;
8275
+ }
8276
+
8277
+ const useStyles$H = makeStyles({
8493
8278
  themeButton: {
8494
8279
  margin: 0,
8495
8280
  },
@@ -8508,7 +8293,7 @@ const ThemeSelectorServiceDefinition = {
8508
8293
  teachingMoment: false,
8509
8294
  order: -300,
8510
8295
  component: () => {
8511
- const classes = useStyles$G();
8296
+ const classes = useStyles$H();
8512
8297
  const { isDarkMode, themeMode, setThemeMode } = useThemeMode();
8513
8298
  const onSelectedThemeChange = useCallback((e, data) => {
8514
8299
  setThemeMode(data.checkedItems.includes("System") ? "system" : data.checkedItems[0].toLocaleLowerCase());
@@ -8525,7 +8310,7 @@ const ThemeSelectorServiceDefinition = {
8525
8310
  },
8526
8311
  };
8527
8312
 
8528
- const useStyles$F = makeStyles({
8313
+ const useStyles$G = makeStyles({
8529
8314
  app: {
8530
8315
  colorScheme: "light dark",
8531
8316
  flexGrow: 1,
@@ -8551,6 +8336,9 @@ const useStyles$F = makeStyles({
8551
8336
  color: tokens.colorPaletteRedForeground1,
8552
8337
  },
8553
8338
  });
8339
+ const ReactContextsWrapper = ({ contexts, children }) => {
8340
+ return jsx(Fragment, { children: contexts.reduceRight((acc, entry) => createElement(entry.provider, { value: entry.value }, acc), children) });
8341
+ };
8554
8342
  /**
8555
8343
  * Creates a modular tool with a base set of common tool services, including the toolbar/side pane basic UI layout.
8556
8344
  * @param options The options for the tool.
@@ -8565,12 +8353,22 @@ function MakeModularTool(options) {
8565
8353
  settingsStore.writeSetting(ThemeModeSettingDescriptor, themeMode);
8566
8354
  }
8567
8355
  const modularToolRootComponent = () => {
8568
- const classes = useStyles$F();
8356
+ const classes = useStyles$G();
8569
8357
  const [extensionManagerContext, setExtensionManagerContext] = useState();
8570
8358
  const [requiredExtensions, setRequiredExtensions] = useState();
8571
8359
  const [requiredExtensionsDeferred, setRequiredExtensionsDeferred] = useState();
8572
8360
  const [extensionInstallError, setExtensionInstallError] = useState();
8573
- const [bootstrapServices, setBootstrapServices] = useState();
8361
+ const [rootComponentService, setRootComponentService] = useState();
8362
+ const [contexts, updateContexts] = useReducer((state, action) => {
8363
+ switch (action.type) {
8364
+ case "add":
8365
+ return [...state, action.entry].sort((a, b) => a.order - b.order);
8366
+ case "remove":
8367
+ return state.filter((e) => e.provider !== action.provider);
8368
+ case "update":
8369
+ return state.map((e) => (e.provider === action.provider ? { ...e, value: action.value } : e));
8370
+ }
8371
+ }, []);
8574
8372
  // This is the main async initialization.
8575
8373
  useEffect(() => {
8576
8374
  const initializeExtensionManagerAsync = async () => {
@@ -8581,22 +8379,36 @@ function MakeModularTool(options) {
8581
8379
  produces: [SettingsStoreIdentity],
8582
8380
  factory: () => settingsStore,
8583
8381
  });
8584
- // Register watcher service early since many other services will rely on it.
8585
- // TODO: Really this should be in the Inspector layer, but we would need a way
8586
- // to setup the WatcherContext.Provider before the root component is rendered
8587
- // for that to work, since components will use the WatcherContext.
8588
- await serviceContainer.addServiceAsync(WatcherServiceDefinition);
8382
+ // Expose the react context service so other services can add React context providers.
8383
+ await serviceContainer.addServiceAsync({
8384
+ friendlyName: "React Context Service",
8385
+ produces: [ReactContextServiceIdentity],
8386
+ factory: () => ({
8387
+ addContext(provider, initialValue, options) {
8388
+ const typedProvider = provider;
8389
+ updateContexts({ type: "add", entry: { provider: typedProvider, value: initialValue, order: options?.order ?? 0 } });
8390
+ return {
8391
+ updateValue: (newValue) => {
8392
+ updateContexts({ type: "update", provider: typedProvider, value: newValue });
8393
+ },
8394
+ dispose: () => {
8395
+ updateContexts({ type: "remove", provider: typedProvider });
8396
+ },
8397
+ };
8398
+ },
8399
+ }),
8400
+ });
8589
8401
  // Register the shell service (top level toolbar/side pane UI layout).
8590
8402
  await serviceContainer.addServiceAsync(MakeShellServiceDefinition(options));
8591
8403
  // Register a service that simply consumes the services we need before first render.
8592
8404
  await serviceContainer.addServiceAsync({
8593
8405
  friendlyName: "Service Bootstrapper",
8594
- consumes: [RootComponentServiceIdentity, WatcherServiceIdentity],
8595
- factory: (rootComponentService, watcherService) => {
8406
+ consumes: [RootComponentServiceIdentity],
8407
+ factory: (rootComponent) => {
8596
8408
  // Use function syntax for the state setter since the root component may be a function component.
8597
- setBootstrapServices({ rootComponentService, watcherService });
8409
+ setRootComponentService(() => rootComponent);
8598
8410
  return {
8599
- dispose: () => setBootstrapServices(undefined),
8411
+ dispose: () => setRootComponentService(undefined),
8600
8412
  };
8601
8413
  },
8602
8414
  });
@@ -8608,7 +8420,7 @@ function MakeModularTool(options) {
8608
8420
  }
8609
8421
  // Register the extension list service (for browsing/installing extensions) if extension feeds are provided.
8610
8422
  if (extensionFeeds.length > 0) {
8611
- const { ExtensionListServiceDefinition } = await import('./extensionsListService-zYdKn8uM.js');
8423
+ const { ExtensionListServiceDefinition } = await import('./extensionsListService-BmiNjZiw.js');
8612
8424
  await serviceContainer.addServiceAsync(ExtensionListServiceDefinition);
8613
8425
  }
8614
8426
  // Register all external services (that make up a unique tool).
@@ -8675,16 +8487,13 @@ function MakeModularTool(options) {
8675
8487
  setExtensionInstallError(undefined);
8676
8488
  }, [setExtensionInstallError]);
8677
8489
  // Show a spinner until a main view has been set.
8678
- if (!bootstrapServices) {
8679
- return (jsx(SettingsStoreContext.Provider, { value: settingsStore, children: jsx(Theme, { className: classes.app, children: jsx(Spinner, { className: classes.spinner }) }) }));
8490
+ if (!rootComponentService) {
8491
+ return (jsx(ReactContextsWrapper, { contexts: contexts, children: jsx(SettingsStoreContext.Provider, { value: settingsStore, children: jsx(Theme, { className: classes.app, children: jsx(Spinner, { className: classes.spinner }) }) }) }));
8680
8492
  }
8681
8493
  else {
8682
8494
  // eslint-disable-next-line @typescript-eslint/naming-convention
8683
- const Content = bootstrapServices.rootComponentService.rootComponent;
8684
- return (
8685
- // Expose the settings store as a React context so that UI components can read/write
8686
- // settings without the ISettingsService needing to be explicitly passed around.
8687
- jsx(SettingsStoreContext.Provider, { value: settingsStore, children: jsx(WatcherContext.Provider, { value: bootstrapServices.watcherService, children: jsx(ExtensionManagerContext.Provider, { value: extensionManagerContext, children: jsx(Theme, { className: classes.app, children: jsxs(ToastProvider, { children: [jsx(Dialog, { open: !!requiredExtensions, modalType: "alert", children: jsx(DialogSurface, { children: jsxs(DialogBody, { children: [jsx(DialogTitle, { children: "Required Extensions" }), jsxs(DialogContent, { children: ["Opening this URL requires the following extensions to be installed and enabled:", jsx("ul", { children: requiredExtensions?.map((name) => jsx("li", { children: name }, name)) })] }), jsxs(DialogActions, { children: [jsx(Button$1, { appearance: "primary", onClick: onAcceptRequiredExtensions, children: "Install & Enable" }), jsx(Button$1, { appearance: "secondary", onClick: onRejectRequiredExtensions, children: "No Thanks" })] })] }) }) }), jsx(Dialog, { open: !!extensionInstallError, modalType: "alert", children: jsx(DialogSurface, { children: jsxs(DialogBody, { children: [jsx(DialogTitle, { children: jsxs("div", { className: classes.extensionErrorTitleDiv, children: ["Extension Install Error", jsx(ErrorCircleRegular, { className: classes.extensionErrorIcon })] }) }), jsx(DialogContent, { children: jsxs(List$1, { children: [jsx(ListItem, { children: jsx(Body1, { children: `Extension "${extensionInstallError?.extension.name}" failed to install and was removed.` }) }), jsx(ListItem, { children: jsx(Body1, { children: `${extensionInstallError?.error}` }) })] }) }), jsx(DialogActions, { children: jsx(Button$1, { appearance: "primary", onClick: onAcknowledgedExtensionInstallError, children: "Close" }) })] }) }) }), jsx(Suspense, { fallback: jsx(Spinner, { className: classes.spinner }), children: jsx(Content, {}) })] }) }) }) }) }));
8495
+ const Content = rootComponentService.rootComponent;
8496
+ return (jsx(ReactContextsWrapper, { contexts: contexts, children: jsx(SettingsStoreContext.Provider, { value: settingsStore, children: jsx(ExtensionManagerContext.Provider, { value: extensionManagerContext, children: jsx(Theme, { className: classes.app, children: jsxs(ToastProvider, { children: [jsx(Dialog, { open: !!requiredExtensions, modalType: "alert", children: jsx(DialogSurface, { children: jsxs(DialogBody, { children: [jsx(DialogTitle, { children: "Required Extensions" }), jsxs(DialogContent, { children: ["Opening this URL requires the following extensions to be installed and enabled:", jsx("ul", { children: requiredExtensions?.map((name) => (jsx("li", { children: name }, name))) })] }), jsxs(DialogActions, { children: [jsx(Button$1, { appearance: "primary", onClick: onAcceptRequiredExtensions, children: "Install & Enable" }), jsx(Button$1, { appearance: "secondary", onClick: onRejectRequiredExtensions, children: "No Thanks" })] })] }) }) }), jsx(Dialog, { open: !!extensionInstallError, modalType: "alert", children: jsx(DialogSurface, { children: jsxs(DialogBody, { children: [jsx(DialogTitle, { children: jsxs("div", { className: classes.extensionErrorTitleDiv, children: ["Extension Install Error", jsx(ErrorCircleRegular, { className: classes.extensionErrorIcon })] }) }), jsx(DialogContent, { children: jsxs(List$1, { children: [jsx(ListItem, { children: jsx(Body1, { children: `Extension "${extensionInstallError?.extension.name}" failed to install and was removed.` }) }), jsx(ListItem, { children: jsx(Body1, { children: `${extensionInstallError?.error}` }) })] }) }), jsx(DialogActions, { children: jsx(Button$1, { appearance: "primary", onClick: onAcknowledgedExtensionInstallError, children: "Close" }) })] }) }) }), jsx(Suspense, { fallback: jsx(Spinner, { className: classes.spinner }), children: jsx(Content, {}) })] }) }) }) }) }));
8688
8497
  }
8689
8498
  };
8690
8499
  // Set the container element to be a flex container so that the tool can be displayed properly.
@@ -8706,6 +8515,226 @@ function MakeModularTool(options) {
8706
8515
  };
8707
8516
  }
8708
8517
 
8518
+ // Created by running the following command from the packages/dev/inspector-v2 directory:
8519
+ // npm run makeAvatar https://raw.githubusercontent.com/BabylonJS/Brand-Toolkit/master/babylon_logo/fullColor/babylon_logo_color.png 0.8
8520
+ const BabylonLogoBase64 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAAFXElEQVR4nO2WbWwTdRzHu+EbYmLgpeILwcQXvvCFLwwGxthG1/Z6d33Ag22FDXAE98wixsCbSiS+4IUhxoQYoyiSGKcogsjaa9c9dw9sbdfrbevW611nYTDYliCRsbv7mrt2sPiGUTZf8Uua9P7/u9/383v4//MzGJ5bjgaDIQ8Ms66FYdYZ/m+D250PgyF/GUy+trb2wshEnfmPvKnG3fukJoZ+vI912vqapRsGg+481cy8I9RSbTONNkw32pXJatMvCcvmN7Q9t5ad1QSBJuzOpHvmo7JXkrX01zfq6Yd3mhxIHrHIQuUOee5EJR4MtN0D8Bnm5jbo37nd+c/UH1jmINXcvF6scxxL1VJ3Zo86kKol5UTVTlmsIXH3p68g35uXASgAoCqyCKBKy4Lup0UL4Bn6Q2piaKmWjM0etSNdTyvCoV2LwsES9daXbixMCZomoKpQFFkFsKg9aUtzv//QM7ln6zYdIlu6lUVuyLw8e7zsLbGGunqrXq8zhMMmOVFZqKQ/+QD3w8GMsB6xAmi/rN0PB+X0qQZ5psGGG/W0LNXT5/9x731tRSDubKquWJlN3H7H7N1GO1K1hDy5v1BJNe/BvPcilIUHj4TVxUWosqJnYMlmfz0H4X0jhANF8l915OJ8oxORCnv0vHHfi0+EcGcBBpwVW9hSaqGdIBSu0qrOXvgCyvzsUsgZ4WVR6zDKYxD59g3cPvspwuVmpZ2g4DPR0khNzcYVA3QwzGY/QT/wFpnBMuVqShKwsCSQDVZVVaQ9LG519z7qgyXAhwCmxnh4TJTSZiThM1NioKpqw4oBWKdzi89CLbDFZrSVudRIfzti0UFMpyXIioJ5fhSDH36Ma9uL0LrTiPDJU/hbSkFWZMxMpyGK4xjv64KPsCmBUit8ZlrqqqjYmBvAXpcaG+pFbGQA0egAOF8rfCZSF/dZaC06/Ll1B9qZciT5CIQED0mawMRg7+oBcEM9OgA/FsbQby1gjQS8JgreUiu8pSQ8Riv8tt2YHO6HKMbXEiCE0KWf4Skh0ElT4A+Q4CpJBAgrWGo3JkMDawzADyPcehlhFwnx0C5IdRRSdSSE/TsRqi5HIhqCmBxfA4DBbh0gFulHjLuO8bZLSJyqh3jIiGS1CeKZE0gNd0FMxiFOaj0Qx8RAT+4AHQyzmTUvAVSo2gngR0PgQkEdguND4LghxC9+A9F7EWI6iaQ0qYsnJ2JITUtIhAe1JtUB2Kc9hl3Oii1+M7XgNRIKW2pVe44fx0iXD6MTI/pxjA0HwUX6wcejSE4JEBM8knFOr3/qpoR4dzt6m4/BW2JW/CYSfgstjVQ8xUV0hWE2BQjb3SBh0zpe9hQUKz7Kif4zn4MbDoKfiIAL92E00p8RFsYwdVOCwIVw/fRp/WheKyjR4OVB0ok2whb17FvBVbz8hU6GeZMl6MudFhu6CJsWjezZXqwEXJUYuvA9eH4IY+MRSGlBb7zId+cQeK8MrduKFO8ui9xttaPDQi+yhO3bPlf1q8t9P5X5bU7Cb6EjQasdAQuteIpMi55Co9pZ14ARz1XwrX+g8/ARtBYUq57iUrmDsKk9hF2re0e7nXk3Z2FoA4khM5D0NjPrfVZ7k99E3Q6SDu0mVDwFJTJrpuE1EmgtKJHbzJTSp+2ZSYGlHS4Aejm1oWaptDlZiz6SZU+Hy/UyS9jOBsz0Qo/VDi3VPiMh95IO+M3UPdbqONnnanhpKYBVm5RhMOS5CwtfcGdH8Q7Hnre9FortJvQ6K6yF+tG/t/J1bU+LVofOJe1PMs3p8kHTRzvKtB7JPuatmfB/TU8vHgutarpz7Y/nZsjR/gUhEcwHmuaM9wAAAABJRU5ErkJggg==";
8521
+ const BabylonWebResources = {
8522
+ homepage: "https://www.babylonjs.com",
8523
+ repository: "https://github.com/BabylonJS/Babylon.js",
8524
+ bugs: "https://github.com/BabylonJS/Babylon.js/issues",
8525
+ author: {
8526
+ name: "Babylon.js",
8527
+ avatar: BabylonLogoBase64,
8528
+ },
8529
+ };
8530
+ /**
8531
+ * Well-known default built in extensions for the Inspector.
8532
+ */
8533
+ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
8534
+ {
8535
+ name: "Quick Creation Tools (Preview)",
8536
+ description: "Adds a new panel for easy creation of various Babylon assets. This is a WIP extension...expect changes!",
8537
+ keywords: ["creation", "tools"],
8538
+ ...BabylonWebResources,
8539
+ getExtensionModuleAsync: async () => await import('./quickCreateToolsService-BoqrJqoM.js'),
8540
+ },
8541
+ {
8542
+ name: "Reflector",
8543
+ description: "Connects to the Reflector Bridge for real-time scene synchronization with the Babylon.js Sandbox.",
8544
+ keywords: ["reflector", "bridge", "sync", "sandbox", "tools"],
8545
+ ...BabylonWebResources,
8546
+ getExtensionModuleAsync: async () => await import('./reflectorService-CFTva2GG.js'),
8547
+ },
8548
+ ]);
8549
+
8550
+ /**
8551
+ * Reusable component which renders a color property line containing a label, colorPicker popout, and expandable RGBA values
8552
+ * The expandable RGBA values are synced sliders that allow the user to modify the color's RGBA values directly
8553
+ * @param props - PropertyLine props, replacing children with a color object so that we can properly display the color
8554
+ * @returns Component wrapping a colorPicker component with a property line
8555
+ */
8556
+ const ColorPropertyLine = forwardRef((props, ref) => {
8557
+ ColorPropertyLine.displayName = "ColorPropertyLine";
8558
+ const [color, setColor] = useState(props.value);
8559
+ useEffect(() => {
8560
+ setColor(props.value);
8561
+ }, [props.value]);
8562
+ const onSliderChange = (value, key) => {
8563
+ let newColor;
8564
+ if (key === "a") {
8565
+ newColor = Color4.FromColor3(color, value);
8566
+ }
8567
+ else {
8568
+ newColor = color.clone();
8569
+ newColor[key] = value / 255;
8570
+ }
8571
+ setColor(newColor); // Create a new object to trigger re-render
8572
+ props.onChange(newColor);
8573
+ };
8574
+ const onColorPickerChange = (newColor) => {
8575
+ setColor(newColor);
8576
+ props.onChange(newColor);
8577
+ };
8578
+ return (jsx(PropertyLine, { ref: ref, ...props, expandedContent: color ? jsx(ColorSliders, { color: color, onSliderChange: onSliderChange }) : undefined, children: jsx(ColorPickerPopup, { ...props, onChange: onColorPickerChange, value: color }) }));
8579
+ });
8580
+ const ColorSliders = ({ color, onSliderChange }) => (jsxs(Fragment, { children: [jsx(SyncedSliderPropertyLine, { label: "R", value: color.r * 255, min: 0, max: 255, onChange: (value) => onSliderChange(value, "r") }), jsx(SyncedSliderPropertyLine, { label: "G", value: color.g * 255, min: 0, max: 255, onChange: (value) => onSliderChange(value, "g") }), jsx(SyncedSliderPropertyLine, { label: "B", value: color.b * 255, min: 0, max: 255, onChange: (value) => onSliderChange(value, "b") }), color instanceof Color4 && jsx(SyncedSliderPropertyLine, { label: "A", value: color.a, min: 0, max: 1, step: 0.01, onChange: (value) => onSliderChange(value, "a") })] }));
8581
+ const Color3PropertyLine = ColorPropertyLine;
8582
+ const Color4PropertyLine = ColorPropertyLine;
8583
+
8584
+ const useStyles$F = makeStyles({
8585
+ uniformWidth: {
8586
+ ...UniformWidthStyling,
8587
+ },
8588
+ });
8589
+ /**
8590
+ * Wraps a text input in a property line
8591
+ * @param props - PropertyLineProps and InputProps
8592
+ * @returns property-line wrapped input component
8593
+ */
8594
+ const TextInputPropertyLine = (props) => {
8595
+ TextInputPropertyLine.displayName = "TextInputPropertyLine";
8596
+ const classes = useStyles$F();
8597
+ return (jsx(PropertyLine, { ...props, children: jsx(TextInput, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
8598
+ };
8599
+ /**
8600
+ * Wraps a number input in a property line
8601
+ * To force integer values, use forceInt param (this is distinct from the 'step' param, which will still allow submitting an integer value. forceInt will not)
8602
+ * @param props - PropertyLineProps and InputProps
8603
+ * @returns property-line wrapped input component
8604
+ */
8605
+ const NumberInputPropertyLine = (props) => {
8606
+ NumberInputPropertyLine.displayName = "NumberInputPropertyLine";
8607
+ const classes = useStyles$F();
8608
+ return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
8609
+ };
8610
+
8611
+ const HasZ = (vector) => !(vector instanceof Vector2);
8612
+ const HasW = (vector) => vector instanceof Vector4 || vector instanceof Quaternion;
8613
+ /**
8614
+ * Reusable component which renders a vector property line containing a label, vector value, and expandable XYZW values
8615
+ * The expanded section contains a slider/input box for each component of the vector (x, y, z, w)
8616
+ * @param props
8617
+ * @returns
8618
+ */
8619
+ const TensorPropertyLine = (props) => {
8620
+ TensorPropertyLine.displayName = "TensorPropertyLine";
8621
+ const converted = (val) => (props.valueConverter ? props.valueConverter.from(val) : val);
8622
+ const formatted = (val) => converted(val).toFixed(props.step !== undefined ? Math.max(0, CalculatePrecision(props.step)) : 2);
8623
+ const [vector, setVector] = useState(props.value);
8624
+ const { min, max } = props;
8625
+ const onChange = (val, key) => {
8626
+ const value = props.valueConverter ? props.valueConverter.to(val) : val;
8627
+ const newVector = vector.clone();
8628
+ newVector[key] = value; // The syncedSlider for 'w' is only rendered when vector is a Vector4, so this is safe
8629
+ setVector(newVector);
8630
+ props.onChange(newVector);
8631
+ };
8632
+ useEffect(() => {
8633
+ setVector(props.value);
8634
+ }, [props.value, props.expandedContent]);
8635
+ return (jsx(PropertyLine, { ...props, expandedContent: jsxs(Fragment, { children: [props.expandedContent, vector ? (jsx(VectorSliders, { vector: vector, min: min, max: max, unit: props.unit, step: props.step, precision: props.precision, converted: converted, onChange: onChange })) : undefined] }), children: jsx(Body1, { children: `[${formatted(props.value.x)}, ${formatted(props.value.y)}${HasZ(props.value) ? `, ${formatted(props.value.z)}` : ""}${HasW(props.value) ? `, ${formatted(props.value.w)}` : ""}]` }) }));
8636
+ };
8637
+ const VectorSliders = ({ vector, min, max, unit, step, precision, converted, onChange }) => (jsxs(Fragment, { children: [jsx(NumberInputPropertyLine, { label: "X", value: converted(vector.x), min: min, max: max, onChange: (val) => onChange(val, "x"), unit: unit, step: step, precision: precision }), jsx(NumberInputPropertyLine, { label: "Y", value: converted(vector.y), min: min, max: max, onChange: (val) => onChange(val, "y"), unit: unit, step: step, precision: precision }), HasZ(vector) && (jsx(NumberInputPropertyLine, { label: "Z", value: converted(vector.z), min: min, max: max, onChange: (val) => onChange(val, "z"), unit: unit, step: step, precision: precision })), HasW(vector) && (jsx(NumberInputPropertyLine, { label: "W", value: converted(vector.w), min: min, max: max, onChange: (val) => onChange(val, "w"), unit: unit, step: step, precision: precision }))] }));
8638
+ const ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };
8639
+ const RotationVectorPropertyLine = (props) => {
8640
+ RotationVectorPropertyLine.displayName = "RotationVectorPropertyLine";
8641
+ const step = props.useDegrees ? 1 : 0.01;
8642
+ const precision = props.useDegrees ? 1 : 2;
8643
+ return (jsx(Vector3PropertyLine, { ...props, unit: props.useDegrees ? "°" : "rad", valueConverter: props.useDegrees ? ToDegreesConverter : undefined, step: step, precision: precision }));
8644
+ };
8645
+ const QuaternionPropertyLineInternal = TensorPropertyLine;
8646
+ const QuaternionPropertyLine = (props) => {
8647
+ QuaternionPropertyLine.displayName = "QuaternionPropertyLine";
8648
+ const step = props.useDegrees ? 1 : 0.01;
8649
+ const precision = props.useDegrees ? 1 : 2;
8650
+ const [quat, setQuat] = useState(props.value);
8651
+ useEffect(() => {
8652
+ setQuat(props.value);
8653
+ }, [props.value]);
8654
+ // Extract only the properties that exist on QuaternionPropertyLineProps
8655
+ const { useEuler, ...restProps } = props;
8656
+ const onQuatChange = (val) => {
8657
+ setQuat(val);
8658
+ props.onChange(val);
8659
+ };
8660
+ const onEulerChange = (val) => {
8661
+ const quat = Quaternion.FromEulerAngles(val.x, val.y, val.z);
8662
+ onQuatChange(quat);
8663
+ };
8664
+ return useEuler ? (jsx(Vector3PropertyLine, { ...restProps, nullable: false, ignoreNullable: false, value: quat.toEulerAngles(), valueConverter: ToDegreesConverter, onChange: onEulerChange, unit: props.useDegrees ? "°" : "rad", step: step, precision: precision, expandedContent: jsx(TextPropertyLine, { label: "Quaternion", value: `[${quat.x.toFixed(4)}, ${quat.y.toFixed(4)}, ${quat.z.toFixed(4)}, ${quat.w.toFixed(4)}]` }) })) : (jsx(QuaternionPropertyLineInternal, { ...props, nullable: false, value: quat, onChange: onQuatChange, unit: props.useDegrees ? "°" : "rad", step: step, precision: precision }));
8665
+ };
8666
+ const Vector2PropertyLine = TensorPropertyLine;
8667
+ const Vector3PropertyLine = TensorPropertyLine;
8668
+ const Vector4PropertyLine = TensorPropertyLine;
8669
+
8670
+ function IsInspectableObject(entity) {
8671
+ return !!entity.inspectableCustomProperties;
8672
+ }
8673
+ const LegacyInspectableObjectPropertiesServiceDefinition = {
8674
+ friendlyName: "Additional Nodes",
8675
+ consumes: [PropertiesServiceIdentity],
8676
+ factory: (propertiesService) => {
8677
+ const propertiesSectionRegistration = propertiesService.addSection({
8678
+ identity: "Custom",
8679
+ order: Number.MAX_SAFE_INTEGER,
8680
+ });
8681
+ const propertiesContentRegistration = propertiesService.addSectionContent({
8682
+ key: "Additional Nodes Properties",
8683
+ predicate: (entity) => IsInspectableObject(entity),
8684
+ content: [
8685
+ {
8686
+ section: "Custom",
8687
+ component: ({ context }) => {
8688
+ return (jsx(Fragment, { children: (context.inspectableCustomProperties ?? []).map((prop) => {
8689
+ const commonProps = {
8690
+ target: context,
8691
+ propertyKey: prop.propertyName,
8692
+ label: prop.label,
8693
+ ignoreNullable: true,
8694
+ defaultValue: undefined,
8695
+ };
8696
+ switch (prop.type) {
8697
+ case 0 /* InspectableType.Checkbox */:
8698
+ return jsx(BoundProperty, { ...commonProps, component: SwitchPropertyLine }, prop.propertyName);
8699
+ case 1 /* InspectableType.Slider */:
8700
+ return (jsx(BoundProperty, { ...commonProps, min: prop.min, max: prop.max, step: prop.step, component: SyncedSliderPropertyLine }, prop.propertyName));
8701
+ case 2 /* InspectableType.Vector3 */:
8702
+ return jsx(BoundProperty, { ...commonProps, component: Vector3PropertyLine }, prop.propertyName);
8703
+ case 3 /* InspectableType.Quaternion */:
8704
+ return jsx(BoundProperty, { ...commonProps, component: QuaternionPropertyLine }, prop.propertyName);
8705
+ case 4 /* InspectableType.Color3 */:
8706
+ return jsx(BoundProperty, { ...commonProps, component: Color3PropertyLine }, prop.propertyName);
8707
+ case 5 /* InspectableType.String */:
8708
+ return jsx(BoundProperty, { ...commonProps, component: TextInputPropertyLine }, prop.propertyName);
8709
+ case 6 /* InspectableType.Button */:
8710
+ return jsx(ButtonLine, { label: prop.label, onClick: () => prop.callback?.() }, prop.propertyName);
8711
+ case 7 /* InspectableType.Options */:
8712
+ return jsx(BoundProperty, { ...commonProps, component: DropdownPropertyLine, options: prop.options ?? [] }, prop.propertyName);
8713
+ case 8 /* InspectableType.Tab */:
8714
+ return jsx(BoundProperty, { ...commonProps, component: TextPropertyLine }, prop.propertyName);
8715
+ case 9 /* InspectableType.FileButton */:
8716
+ return (jsx(FileUploadLine, { label: prop.label, accept: prop.accept ?? "", onClick: (files) => {
8717
+ if (files.length > 0 && prop.fileCallback) {
8718
+ prop.fileCallback(files[0]);
8719
+ }
8720
+ } }, prop.propertyName));
8721
+ case 10 /* InspectableType.Vector2 */:
8722
+ return jsx(BoundProperty, { ...commonProps, component: Vector2PropertyLine }, prop.propertyName);
8723
+ }
8724
+ }) }));
8725
+ },
8726
+ },
8727
+ ],
8728
+ });
8729
+ return {
8730
+ dispose: () => {
8731
+ propertiesSectionRegistration.dispose();
8732
+ propertiesContentRegistration.dispose();
8733
+ },
8734
+ };
8735
+ },
8736
+ };
8737
+
8709
8738
  const MeshIcon = createFluentIcon("Mesh", "1em", '<g transform="scale(1.25)"><path d="M14.03,3.54l-5.11-2.07c-.61-.25-1.27-.25-1.88,0L1.93,3.54c-.57.23-.94.78-.94,1.39v6.15c0,.61.37,1.16.94,1.39l5.11,2.07c.3.12.62.18.94.18s.64-.06.94-.18l5.12-2.07c.57-.23.94-.78.94-1.39v-6.15c0-.61-.37-1.16-.94-1.39ZM13.97,7.71l-2.11.86v-2.71l2.11-.86v2.71ZM1.99,5l2.11.86v2.71l-2.11-.86v-2.71ZM11.35,4.98l-2.04-.83,1.78-.72,2.04.83-1.78.72ZM10.02,5.52l-2.04.83-2.04-.83,2.04-.83,2.04.83ZM4.6,4.98l-1.78-.72,2.04-.83,1.78.72-2.04.83ZM5.1,6.26l2.38.96v2.71l-2.38-.96v-2.71ZM8.48,7.22l2.38-.96v2.71l-2.38.96v-2.71ZM7.41,2.39c.18-.07.37-.11.56-.11s.38.04.56.11l1.22.49-1.78.72-1.79-.72,1.22-.49ZM1.99,11.07v-2.29l2.11.86v2.62l-1.8-.73c-.19-.08-.31-.26-.31-.46ZM5.1,12.67v-2.62l2.38.96v2.61s-.04,0-.06-.01l-2.31-.94ZM8.54,13.61s-.04,0-.06.01v-2.61l2.38-.96v2.62l-2.31.94ZM13.66,11.54l-1.8.73v-2.62l2.11-.86v2.29c0,.2-.12.39-.31.46Z"/></g>');
8710
8739
  const TranslateIcon = createFluentIcon("Translate", "1em", '<g transform="scale(0.833)"><path d="M20.16,12.98l-2.75-2.75c-.29-.29-.77-.29-1.06,0-.29.29-.29.77,0,1.06l1.47,1.47h-6.69v-6.69l1.47,1.47c.29.29.77.29,1.06,0,.29-.29.29-.77,0-1.06l-2.75-2.75c-.14-.14-.33-.22-.53-.22s-.39.08-.53.22l-2.75,2.75c-.29.29-.29.77,0,1.06.29.29.77.29,1.06,0l1.47-1.47v7.13l-3.52,3.52v-2.08c0-.41-.34-.75-.75-.75s-.75.34-.75.75v3.89c0,.2.08.39.22.53.14.14.33.22.53.22h3.89c.41,0,.75-.34.75-.75s-.34-.75-.75-.75h-2.08s3.52-3.52,3.52-3.52h7.13l-1.47,1.47c-.29.29-.29.77,0,1.06s.77.29,1.06,0l2.75-2.75c.14-.14.22-.33.22-.53s-.08-.39-.22-.53Z" /></g>');
8711
8740
  const MaterialIcon = createFluentIcon("Material", "1em", '<g transform="scale(1.25)"><path d="M14.74,6.3c-.09-.36-.38-.64-.75-.72-.04-.09-.08-.18-.12-.27.1-.15.16-.32.16-.51,0-.18-.05-.34-.13-.48-1.23-1.97-3.41-3.28-5.9-3.28C4.16,1.04,1.04,4.16,1.04,7.99c0,.39.23.72.57.88.02.12.03.25.06.37-.18.18-.3.42-.3.7,0,.11.02.21.06.31.94,2.74,3.53,4.71,6.58,4.71,3.84,0,6.96-3.12,6.96-6.96,0-.59-.08-1.16-.22-1.7ZM2.07,8.58c-.02-.19-.03-.39-.03-.58,0-3.29,2.67-5.96,5.96-5.96,2.23,0,4.17,1.23,5.2,3.05.05.18-.07.45-.3.75-.57-.73-1.45-1.21-2.45-1.21-1.72,0-3.12,1.4-3.12,3.11,0,.33.07.65.16.95-3.05.82-5.17.52-5.42-.11ZM12.56,7.75c0,1.17-.95,2.11-2.11,2.11s-2.12-.95-2.12-2.11.95-2.11,2.12-2.11,2.11.95,2.11,2.11ZM8,13.96c-2.6,0-4.81-1.68-5.62-4.01.5.16,1.11.24,1.79.24,1.15,0,2.49-.22,3.79-.59.57.76,1.47,1.26,2.49,1.26,1.72,0,3.11-1.4,3.11-3.11,0-.34-.07-.65-.17-.96.13-.13.24-.26.34-.39.14.51.22,1.04.22,1.6,0,3.29-2.67,5.96-5.96,5.96Z"/></g>');
@@ -13453,7 +13482,7 @@ const EffectLayerPropertiesServiceDefinition = {
13453
13482
  async function EditNodeRenderGraph(nodeRenderGraph) {
13454
13483
  // TODO: Figure out how to get all the various build steps to work with this.
13455
13484
  // See the initial attempt here: https://github.com/BabylonJS/Babylon.js/pull/17646
13456
- // const { NodeRenderGraphEditor } = await import("node-render-graph-editor/nodeRenderGraphEditor");
13485
+ // const { NodeRenderGraphEditor } = await import("@babylonjs/node-render-graph-editor");
13457
13486
  // NodeRenderGraphEditor.Show({ nodeRenderGraph: renderGraph, hostScene: frameGraph.scene });
13458
13487
  await nodeRenderGraph.edit({ nodeRenderGraphEditorConfig: { backgroundColor: nodeRenderGraph.getScene().clearColor, hostScene: nodeRenderGraph.getScene() } });
13459
13488
  }
@@ -13687,14 +13716,10 @@ function EntitySelector(props) {
13687
13716
  if (value && !isEditing) {
13688
13717
  // If there is a value and we are not editing, show the link view
13689
13718
  return (jsxs("div", { className: classes.linkDiv, children: [jsx(Tooltip$1, { content: getName(value), relationship: "label", children: jsx(Link, { className: classes.link, value: getName(value), onLink: () => onLink(value) }) }), onChange &&
13690
- (defaultValue !== undefined ? (
13691
- // If the defaultValue is specified, then allow resetting to the default
13692
- jsx(Tooltip$1, { content: "Unlink", relationship: "label", children: jsx(Button, { icon: LinkDismissRegular, onClick: () => {
13719
+ (defaultValue !== undefined ? (jsx(Tooltip$1, { content: "Unlink", relationship: "label", children: jsx(Button, { icon: LinkDismissRegular, onClick: () => {
13693
13720
  pulseEnteringEditMode(true);
13694
13721
  onChange(defaultValue);
13695
- } }) })) : (
13696
- // Otherwise, just allow editing to a new value
13697
- jsx(Tooltip$1, { content: "Edit Link", relationship: "label", children: jsx(Button, { icon: LinkEditRegular, onClick: () => {
13722
+ } }) })) : (jsx(Tooltip$1, { content: "Edit Link", relationship: "label", children: jsx(Button, { icon: LinkEditRegular, onClick: () => {
13698
13723
  pulseEnteringEditMode(true);
13699
13724
  setIsEditing(true);
13700
13725
  } }) })))] }));
@@ -14417,7 +14442,7 @@ function GroupBy(items, getKey) {
14417
14442
  async function EditNodeMaterial(material) {
14418
14443
  // TODO: Figure out how to get all the various build steps to work with this.
14419
14444
  // See the initial attempt here: https://github.com/BabylonJS/Babylon.js/pull/17646
14420
- // const { NodeEditor } = await import("node-editor/nodeEditor");
14445
+ // const { NodeEditor } = await import("@babylonjs/node-editor");
14421
14446
  // NodeEditor.Show({ nodeMaterial: material });
14422
14447
  await material.edit({ nodeEditorConfig: { backgroundColor: material.getScene().clearColor } });
14423
14448
  }
@@ -15626,9 +15651,15 @@ const AbstractMeshDebugProperties = (props) => {
15626
15651
  } }), jsx(SyncedSliderPropertyLine, { label: "Target Bone", value: displayBoneIndex, min: 0, max: targetBoneOptions.length - 1, step: 1, onChange: (value) => onBoneDisplayIndexChangeHandler(value) })] }) }), skeleton && jsx(SwitchPropertyLine, { label: "Display Skeleton Map", value: displaySkeletonMap, onChange: () => displaySkeletonMapHandler() })] }));
15627
15652
  };
15628
15653
 
15654
+ const ShDegreeOptions = [
15655
+ { label: "None (0)", value: 0 },
15656
+ { label: "Degree 1 (3 params)", value: 1 },
15657
+ { label: "Degree 2 (8 params)", value: 2 },
15658
+ { label: "Degree 3 (15 params)", value: 3 },
15659
+ ];
15629
15660
  const GaussianSplattingDisplayProperties = (props) => {
15630
15661
  const { mesh } = props;
15631
- return (jsxs(Fragment, { children: [jsx(StringifiedPropertyLine, { label: "Splat Count", value: mesh.splatCount ?? 0 }), jsx(StringifiedPropertyLine, { label: "SH Parameter Count", value: (mesh.shDegree + 1) * (mesh.shDegree + 1) - 1 }), jsx(BooleanBadgePropertyLine, { label: "Has Compensation", value: mesh.compensation }), jsx(StringifiedPropertyLine, { label: "Kernel Size", value: mesh.kernelSize })] }));
15662
+ return (jsxs(Fragment, { children: [jsx(StringifiedPropertyLine, { label: "Splat Count", value: mesh.splatCount ?? 0 }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "SH Degree", options: ShDegreeOptions, target: mesh, propertyKey: "shDegree" }), jsx(StringifiedPropertyLine, { label: "Max SH Degree", value: mesh.maxShDegree }), jsx(BooleanBadgePropertyLine, { label: "Has Compensation", value: mesh.compensation }), jsx(StringifiedPropertyLine, { label: "Kernel Size", value: mesh.kernelSize })] }));
15632
15663
  };
15633
15664
 
15634
15665
  function GetNodeGeometry(mesh) {
@@ -15637,7 +15668,7 @@ function GetNodeGeometry(mesh) {
15637
15668
  async function EditNodeGeometry(nodeGeometry, hostScene) {
15638
15669
  // TODO: Figure out how to get all the various build steps to work with this.
15639
15670
  // See the initial attempt here: https://github.com/BabylonJS/Babylon.js/pull/17646
15640
- // const { NodeGeometryEditor } = await import("node-geometry-editor/nodeGeometryEditor");
15671
+ // const { NodeGeometryEditor } = await import("@babylonjs/node-geometry-editor");
15641
15672
  // NodeGeometryEditor.Show({ nodeGeometry: nodeGeometry, hostScene: mesh.getScene() });
15642
15673
  await nodeGeometry.edit({ nodeGeometryEditorConfig: { hostScene } });
15643
15674
  }
@@ -15772,7 +15803,7 @@ const NodePropertiesServiceDefinition = {
15772
15803
  async function EditParticleSystem(particleSystem) {
15773
15804
  // TODO: Figure out how to get all the various build steps to work with this.
15774
15805
  // See the initial attempt here: https://github.com/BabylonJS/Babylon.js/pull/17646
15775
- // const { NodeParticleEditor } = await import("node-particle-editor/nodeParticleEditor");
15806
+ // const { NodeParticleEditor } = await import("@babylonjs/node-particle-editor");
15776
15807
  // NodeParticleEditor.Show({ nodeParticleSet: NodeParticleSystemSet });
15777
15808
  const scene = particleSystem.getScene();
15778
15809
  if (scene) {
@@ -18132,263 +18163,47 @@ const SpritePropertiesServiceDefinition = {
18132
18163
  },
18133
18164
  {
18134
18165
  section: "Cells",
18135
- component: ({ context }) => jsx(SpriteManagerCellProperties, { spriteManager: context }),
18136
- },
18137
- {
18138
- section: "Other",
18139
- component: ({ context }) => jsx(SpriteManagerOtherProperties, { spriteManager: context }),
18140
- },
18141
- ],
18142
- });
18143
- const spriteSectionContentRegistration = propertiesService.addSectionContent({
18144
- key: "Sprite Properties",
18145
- predicate: (entity) => entity instanceof Sprite,
18146
- content: [
18147
- {
18148
- section: "General",
18149
- component: ({ context }) => jsx(SpriteGeneralProperties, { sprite: context, selectionService: selectionService }),
18150
- },
18151
- {
18152
- section: "Transform",
18153
- component: ({ context }) => jsx(SpriteTransformProperties, { sprite: context }),
18154
- },
18155
- {
18156
- section: "Cell",
18157
- component: ({ context }) => jsx(SpriteCellProperties, { sprite: context }),
18158
- },
18159
- {
18160
- section: "Animation",
18161
- component: ({ context }) => jsx(SpriteAnimationProperties, { sprite: context }),
18162
- },
18163
- {
18164
- section: "Other",
18165
- component: ({ context }) => jsx(SpriteOtherProperties, { sprite: context }),
18166
- },
18167
- ],
18168
- });
18169
- return {
18170
- dispose: () => {
18171
- spriteManagerSectionContentRegistration.dispose();
18172
- spriteSectionContentRegistration.dispose();
18173
- },
18174
- };
18175
- },
18176
- };
18177
-
18178
- /**
18179
- * Creates a lazy component wrapper that only calls the async function to get the underlying component when the lazy component is actually mounted.
18180
- * This allows deferring imports until they are needed. While the underlying component is being loaded, a spinner is displayed.
18181
- * @param getComponentAsync A function that returns a promise resolving to the component.
18182
- * @param defaultProps Options for the loading spinner.
18183
- * @returns A React component that displays a spinner while loading the async component.
18184
- */
18185
- function MakeLazyComponent(getComponentAsync, defaultProps) {
18186
- // eslint-disable-next-line @typescript-eslint/naming-convention
18187
- const LazyComponent = lazy(async () => {
18188
- const component = await getComponentAsync();
18189
- return { default: component };
18190
- });
18191
- return forwardRef((props, ref) => {
18192
- const { spinnerSize = defaultProps?.spinnerSize, spinnerLabel = defaultProps?.spinnerLabel, ...rest } = props;
18193
- const componentProps = { ...rest, ref };
18194
- return (jsx(Suspense, { fallback: jsx(Spinner, { ref: ref, size: spinnerSize, label: spinnerLabel }), children: jsx(LazyComponent, { ...componentProps }) }));
18195
- });
18196
- }
18197
-
18198
- const AdvancedDynamicTextureGeneralProperties = MakeLazyComponent(async () => {
18199
- // Defer importing anything from the gui package until this component is actually mounted.
18200
- const { AdvancedDynamicTextureInstrumentation } = await import('@babylonjs/gui/2D/adtInstrumentation.js');
18201
- return (props) => {
18202
- const { texture } = props;
18203
- const instrumentation = useResource(useCallback(() => {
18204
- const instrumentation = new AdvancedDynamicTextureInstrumentation(texture);
18205
- instrumentation.captureRenderTime = true;
18206
- instrumentation.captureLayoutTime = true;
18207
- return instrumentation;
18208
- }, [texture]));
18209
- const layoutTime = useObservableState(useCallback(() => instrumentation.layoutTimeCounter.current, [instrumentation.layoutTimeCounter]), usePollingObservable(1000));
18210
- const renderTime = useObservableState(useCallback(() => instrumentation.renderTimeCounter.current, [instrumentation.renderTimeCounter]), usePollingObservable(1000));
18211
- return (jsxs(Fragment, { children: [jsx(StringifiedPropertyLine, { label: "Last Layout Time", value: layoutTime, precision: 2, units: "ms" }), jsx(StringifiedPropertyLine, { label: "Last Render Time", value: renderTime, precision: 2, units: "ms" }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Render Scale", target: texture, propertyKey: "renderScale", min: 0.1, max: 5, step: 0.1 }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Premultiply Alpha", target: texture, propertyKey: "premulAlpha" }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Ideal Width", target: texture, propertyKey: "idealWidth" }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Ideal Height", target: texture, propertyKey: "idealHeight" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use Smallest Ideal", target: texture, propertyKey: "useSmallestIdeal" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Render at Ideal Size", target: texture, propertyKey: "renderAtIdealSize" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Invalidate Rect Optimization", target: texture, propertyKey: "useInvalidateRectOptimization" })] }));
18212
- };
18213
- }, { spinnerSize: "extra-tiny", spinnerLabel: "Loading..." });
18214
- const AdvancedDynamicTexturePreviewProperties = (props) => {
18215
- const { texture } = props;
18216
- return (jsx(Fragment, { children: jsx(ButtonLine, { label: "Edit GUI", icon: EditRegular, onClick: async () => {
18217
- const { GUIEditor } = await import('@babylonjs/gui-editor');
18218
- await GUIEditor.Show({ liveGuiTexture: texture });
18219
- } }) }));
18220
- };
18221
-
18222
- const TextureFormat = [
18223
- { label: "Alpha", normalizable: false, value: Constants.TEXTUREFORMAT_ALPHA },
18224
- { label: "Luminance", normalizable: false, value: Constants.TEXTUREFORMAT_LUMINANCE },
18225
- { label: "Luminance/Alpha", normalizable: false, value: Constants.TEXTUREFORMAT_LUMINANCE_ALPHA },
18226
- { label: "RGB", normalizable: true, value: Constants.TEXTUREFORMAT_RGB },
18227
- { label: "RGBA", normalizable: true, value: Constants.TEXTUREFORMAT_RGBA },
18228
- { label: "R (red)", normalizable: true, value: Constants.TEXTUREFORMAT_RED },
18229
- { label: "RG (red/green)", normalizable: true, value: Constants.TEXTUREFORMAT_RG },
18230
- { label: "R (red) integer", normalizable: false, value: Constants.TEXTUREFORMAT_RED_INTEGER },
18231
- { label: "RG (red/green) integer", normalizable: false, value: Constants.TEXTUREFORMAT_RG_INTEGER },
18232
- { label: "RGB integer", normalizable: false, value: Constants.TEXTUREFORMAT_RGB_INTEGER },
18233
- { label: "RGBA integer", normalizable: false, value: Constants.TEXTUREFORMAT_RGBA_INTEGER },
18234
- { label: "BGRA", normalizable: true, value: Constants.TEXTUREFORMAT_BGRA },
18235
- { label: "Depth24/Stencil8", normalizable: false, hideType: true, value: Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 },
18236
- { label: "Depth32 float", normalizable: false, hideType: true, value: Constants.TEXTUREFORMAT_DEPTH32_FLOAT },
18237
- { label: "Depth16", normalizable: false, value: Constants.TEXTUREFORMAT_DEPTH16 },
18238
- { label: "Depth24", normalizable: false, value: Constants.TEXTUREFORMAT_DEPTH24 },
18239
- { label: "Depth24Unorm/Stencil8", normalizable: false, hideType: true, value: Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 },
18240
- { label: "Depth32Float/Stencil8", normalizable: false, hideType: true, value: Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8 },
18241
- { label: "RGBA BPTC UNorm", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM },
18242
- { label: "RGB BPTC UFloat", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT },
18243
- { label: "RGB BPTC SFloat", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT },
18244
- { label: "RGBA S3TC DXT5", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5 },
18245
- { label: "RGBA S3TC DXT3", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3 },
18246
- { label: "RGBA S3TC DXT1", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1 },
18247
- { label: "RGB S3TC DXT1", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1 },
18248
- { label: "RGBA ASTC 4x4", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4 },
18249
- ];
18250
- function FindTextureFormat(format) {
18251
- for (let i = 0; i < TextureFormat.length; ++i) {
18252
- if (TextureFormat[i].value === format) {
18253
- return TextureFormat[i];
18254
- }
18255
- }
18256
- return null;
18257
- }
18258
- const TextureType = [
18259
- { label: "unsigned byte", normalizable: true, value: Constants.TEXTURETYPE_UNSIGNED_BYTE },
18260
- { label: "32-bit float", normalizable: false, value: Constants.TEXTURETYPE_FLOAT },
18261
- { label: "16-bit float", normalizable: false, value: Constants.TEXTURETYPE_HALF_FLOAT },
18262
- { label: "signed byte", normalizable: true, value: Constants.TEXTURETYPE_BYTE },
18263
- { label: "signed short", normalizable: false, value: Constants.TEXTURETYPE_SHORT },
18264
- { label: "unsigned short", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_SHORT },
18265
- { label: "signed int", normalizable: false, value: Constants.TEXTURETYPE_INT },
18266
- { label: "unsigned int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INTEGER },
18267
- { label: "unsigned 4/4/4/4 short", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4 },
18268
- { label: "unsigned 5/5/5/1 short", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1 },
18269
- { label: "unsigned 5/6/5 short", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5 },
18270
- { label: "unsigned 2/10/10/10 int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV },
18271
- { label: "unsigned 24/8 int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INT_24_8 },
18272
- { label: "unsigned 10f/11f/11f int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV },
18273
- { label: "unsigned 5/9/9/9 int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV },
18274
- { label: "32-bits with only 8-bit used (stencil)", normalizable: false, value: Constants.TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV },
18275
- ];
18276
- function FindTextureType(type) {
18277
- for (let i = 0; i < TextureType.length; ++i) {
18278
- if (TextureType[i].value === type) {
18279
- return TextureType[i];
18280
- }
18281
- }
18282
- return null;
18283
- }
18284
-
18285
- const BaseTexturePreviewProperties = (props) => {
18286
- // eslint-disable-next-line @typescript-eslint/naming-convention
18287
- const { texture, textureEditor: TextureEditor } = props;
18288
- const texturePreviewImperativeRef = useRef(null);
18289
- const childWindow = useRef(null);
18290
- return (jsxs(Fragment, { children: [jsx(TexturePreview, { imperativeRef: texturePreviewImperativeRef, texture: texture }), jsx(TextureUpload, { texture: texture }), jsx(ButtonLine, { label: "Edit Texture", onClick: () => childWindow.current?.open(), icon: EditRegular }), jsx(ChildWindow, { id: "Texture Editor", imperativeRef: childWindow, children: jsx(TextureEditor, { texture: texture, onUpdate: async () => await texturePreviewImperativeRef.current?.refresh() }) })] }));
18291
- };
18292
- const BaseTextureGeneralProperties = (props) => {
18293
- const { texture } = props;
18294
- const internalTexture = useProperty(texture, "_texture");
18295
- const internalUniqueId = useProperty(internalTexture, "uniqueId");
18296
- return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: TextInputPropertyLine, label: "Display Name", target: texture, propertyKey: "displayName" }), internalUniqueId != null ? (jsx(StringifiedPropertyLine, { label: "Internal Unique ID", description: "The unique ID of the internal texture.", value: internalUniqueId })) : (jsx(BooleanBadgePropertyLine, { label: "Internal Unique ID", description: "This texture has no internal texture.", value: false }))] }));
18297
- };
18298
- const CoordinatesMode = [
18299
- { label: "Explicit", value: Texture.EXPLICIT_MODE },
18300
- { label: "Cubic", value: Texture.CUBIC_MODE },
18301
- { label: "Inverse cubic", value: Texture.INVCUBIC_MODE },
18302
- { label: "Equirectangular", value: Texture.EQUIRECTANGULAR_MODE },
18303
- { label: "Fixed equirectangular", value: Texture.FIXED_EQUIRECTANGULAR_MODE },
18304
- { label: "Fixed equirectangular mirrored", value: Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE },
18305
- { label: "Planar", value: Texture.PLANAR_MODE },
18306
- { label: "Projection", value: Texture.PROJECTION_MODE },
18307
- { label: "Skybox", value: Texture.SKYBOX_MODE },
18308
- { label: "Spherical", value: Texture.SPHERICAL_MODE },
18309
- ];
18310
- const BaseTextureCharacteristicProperties = (props) => {
18311
- const { texture } = props;
18312
- const internalTexture = useProperty(texture, "_texture");
18313
- const format = useProperty(internalTexture, "format") ?? NaN;
18314
- const type = useProperty(internalTexture, "type") ?? NaN;
18315
- const depth = useProperty(internalTexture, "depth");
18316
- const useSRGBBuffer = useProperty(internalTexture, "_useSRGBBuffer");
18317
- const samples = useProperty(internalTexture, "samples") ?? "?";
18318
- const displayFormat = FindTextureFormat(format === -1 ? Constants.TEXTUREFORMAT_RGBA : format);
18319
- const displayType = FindTextureType(type === -1 ? Constants.TEXTURETYPE_UNSIGNED_BYTE : type);
18320
- const maxAnisotropy = texture.getScene()?.getEngine().getCaps().maxAnisotropy ?? 1;
18321
- return (jsxs(Fragment, { children: [texture.is2DArray && jsx(TextPropertyLine, { label: "Layers", value: depth?.toString() ?? "?" }), texture.is3D && jsx(TextPropertyLine, { label: "Depth", value: depth?.toString() ?? "?" }), jsx(TextPropertyLine, { label: "Format", value: displayFormat?.label ?? "unknown" }), !displayFormat?.hideType && !displayFormat?.compressed && jsx(TextPropertyLine, { label: "Type", value: displayType?.label ?? "unknown" }), !!displayFormat?.normalizable && !displayFormat?.compressed && displayType?.normalizable != undefined && (jsx(BooleanBadgePropertyLine, { label: "Normalized", value: displayType.normalizable })), jsx(BooleanBadgePropertyLine, { label: "Compressed", value: displayFormat?.compressed ?? false }), jsx(BooleanBadgePropertyLine, { label: "sRGB Buffers", value: useSRGBBuffer ?? false }), jsx(BoundProperty, { component: BooleanBadgePropertyLine, label: "Gamma Space", target: texture, propertyKey: "gammaSpace" }), jsx(BoundProperty, { component: BooleanBadgePropertyLine, label: "Has Alpha", target: texture, propertyKey: "hasAlpha" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Alpha from RGB", target: texture, propertyKey: "getAlphaFromRGB" }), jsx(BooleanBadgePropertyLine, { label: "3D", value: texture.is3D }), jsx(BooleanBadgePropertyLine, { label: "2D Array", value: texture.is2DArray }), jsx(BooleanBadgePropertyLine, { label: "Cube", value: texture.isCube }), jsx(BooleanBadgePropertyLine, { label: "Render Target", value: texture.isRenderTarget }), jsx(BooleanBadgePropertyLine, { label: "Mipmaps", value: !texture.noMipmap }), jsx(TextPropertyLine, { label: "Samples", value: samples.toString() }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "UV Set", target: texture, propertyKey: "coordinatesIndex", min: 0, max: 3, step: 1 }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Mode", target: texture, propertyKey: "coordinatesMode", options: CoordinatesMode }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Level", target: texture, propertyKey: "level", min: 0, max: 2, step: 0.01 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Anisotropy", target: texture, propertyKey: "anisotropicFilteringLevel", min: 1, max: maxAnisotropy, step: 1 })] }));
18322
- };
18323
- const BaseTextureTransformProperties = (props) => {
18324
- const { texture } = props;
18325
- return (jsxs(Fragment, { children: [texture.canRescale && (jsx(ButtonLine, { label: "Scale Up", onClick: () => {
18326
- texture.scale(2);
18327
- } })), texture.canRescale && (jsx(ButtonLine, { label: "Scale Down", onClick: () => {
18328
- texture.scale(0.5);
18329
- } }))] }));
18330
- };
18331
-
18332
- const CubeTextureTransformProperties = (props) => {
18333
- const { texture } = props;
18334
- const [toDisplayAngle, fromDisplayAngle] = useAngleConverters();
18335
- return (jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Rotation Y", target: texture, propertyKey: "rotationY", min: 0, max: toDisplayAngle(Math.PI * 2), step: 0.0001, convertTo: (value) => toDisplayAngle(value, true), convertFrom: fromDisplayAngle }));
18336
- };
18337
-
18338
- const MultiRenderTargetGeneralProperties = (props) => {
18339
- const { texture } = props;
18340
- return (jsx(Fragment, { children: jsx(BoundProperty, { component: StringifiedPropertyLine, label: "Count", description: "The number of render target textures.", target: texture, propertyKey: "count" }) }));
18341
- };
18342
-
18343
- const RenderTargetTextureGeneralProperties = (props) => {
18344
- const { texture } = props;
18345
- const depthStencilTexture = useProperty(texture.renderTarget, "_depthStencilTexture");
18346
- const depthStencilTextureDisplayFormat = depthStencilTexture ? FindTextureFormat(depthStencilTexture.format) : null;
18347
- return (jsx(Fragment, { children: depthStencilTextureDisplayFormat ? (jsx(TextPropertyLine, { label: "Depth/Stencil Format", value: depthStencilTextureDisplayFormat.label })) : (jsx(BooleanBadgePropertyLine, { label: "Depth/Stencil Texture", value: false })) }));
18348
- };
18349
-
18350
- const TexturePreviewProperties = (props) => {
18351
- const { texture } = props;
18352
- const rawUrl = useProperty(texture, "url");
18353
- const displayUrl = !rawUrl || rawUrl.substring(0, 4) === "data" || rawUrl.substring(0, 4) === "blob" ? "" : rawUrl;
18354
- return (jsx(Fragment, { children: jsx(TextInputPropertyLine, { label: "URL", value: displayUrl, onChange: (value) => {
18355
- texture.updateURL(value);
18356
- } }) }));
18357
- };
18358
- const TextureGeneralProperties = (props) => {
18359
- const { texture } = props;
18360
- return (jsx(Fragment, { children: jsx(BooleanBadgePropertyLine, { label: "Invert Y", description: "If true, the texture is stored as inverted on Y", value: texture.invertY }) }));
18361
- };
18362
- const TextureTransformProperties = (props) => {
18363
- const { texture } = props;
18364
- const [toDisplayAngle, fromDisplayAngle] = useAngleConverters();
18365
- const wrapU = useProperty(texture, "wrapU");
18366
- const wrapV = useProperty(texture, "wrapV");
18367
- return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "U offset", target: texture, propertyKey: "uOffset", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "V offset", target: texture, propertyKey: "vOffset", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "U scale", target: texture, propertyKey: "uScale", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "V scale", target: texture, propertyKey: "vScale", step: 0.01 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "U angle", target: texture, propertyKey: "uAng", min: 0, max: toDisplayAngle(Math.PI * 2), step: 0.01, convertTo: (value) => toDisplayAngle(value, true), convertFrom: fromDisplayAngle }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "V angle", target: texture, propertyKey: "vAng", min: 0, max: toDisplayAngle(Math.PI * 2), step: 0.01, convertTo: (value) => toDisplayAngle(value, true), convertFrom: fromDisplayAngle }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "W angle", target: texture, propertyKey: "wAng", min: 0, max: toDisplayAngle(Math.PI * 2), step: 0.01, convertTo: (value) => toDisplayAngle(value, true), convertFrom: fromDisplayAngle }), jsx(SwitchPropertyLine, { label: "Clamp U", value: wrapU === Constants.TEXTURE_CLAMP_ADDRESSMODE, onChange: (value) => (texture.wrapU = value ? Constants.TEXTURE_CLAMP_ADDRESSMODE : Constants.TEXTURE_WRAP_ADDRESSMODE) }), jsx(SwitchPropertyLine, { label: "Clamp V", value: wrapV === Constants.TEXTURE_CLAMP_ADDRESSMODE, onChange: (value) => (texture.wrapV = value ? Constants.TEXTURE_CLAMP_ADDRESSMODE : Constants.TEXTURE_WRAP_ADDRESSMODE) })] }));
18368
- };
18369
-
18370
- const SamplingMode = [
18371
- { label: "Nearest", value: Texture.NEAREST_NEAREST }, // 1
18372
- { label: "Linear", value: Texture.LINEAR_LINEAR }, // 2
18373
- { label: "Linear & linear mip", value: Texture.LINEAR_LINEAR_MIPLINEAR }, // 3
18374
- { label: "Linear & nearest mip", value: Texture.LINEAR_LINEAR_MIPNEAREST }, // 11
18375
- { label: "Nearest & linear mip", value: Texture.NEAREST_NEAREST_MIPLINEAR }, // 8
18376
- { label: "Nearest & nearest mip", value: Texture.NEAREST_NEAREST_MIPNEAREST }, // 4
18377
- { label: "Nearest/Linear", value: Texture.NEAREST_LINEAR }, // 7
18378
- { label: "Nearest/Linear & linear mip", value: Texture.NEAREST_LINEAR_MIPLINEAR }, // 6
18379
- { label: "Nearest/Linear & nearest mip", value: Texture.NEAREST_LINEAR_MIPNEAREST }, // 5
18380
- { label: "Linear/Nearest", value: Texture.LINEAR_NEAREST }, // 12
18381
- { label: "Linear/Nearest & linear mip", value: Texture.LINEAR_NEAREST_MIPLINEAR }, // 10
18382
- { label: "Linear/Nearest & nearest mip", value: Texture.LINEAR_NEAREST_MIPNEAREST }, // 9
18383
- ];
18384
- const ThinTextureGeneralProperties = (props) => {
18385
- const { texture } = props;
18386
- return (jsxs(Fragment, { children: [jsx(StringifiedPropertyLine, { label: "Width", value: texture.getSize().width, units: "px" }), jsx(StringifiedPropertyLine, { label: "Height", value: texture.getSize().height, units: "px" })] }));
18387
- };
18388
- const ThinTextureSamplingProperties = (props) => {
18389
- const { texture } = props;
18390
- const samplingMode = useObservableState(useCallback(() => texture.samplingMode, [texture]), useInterceptObservable("function", texture, "updateSamplingMode"));
18391
- return (jsx(Property, { component: NumberDropdownPropertyLine, label: "Sampling", propertyPath: "samplingMode", value: samplingMode, options: SamplingMode, onChange: (value) => texture.updateSamplingMode(value) }));
18166
+ component: ({ context }) => jsx(SpriteManagerCellProperties, { spriteManager: context }),
18167
+ },
18168
+ {
18169
+ section: "Other",
18170
+ component: ({ context }) => jsx(SpriteManagerOtherProperties, { spriteManager: context }),
18171
+ },
18172
+ ],
18173
+ });
18174
+ const spriteSectionContentRegistration = propertiesService.addSectionContent({
18175
+ key: "Sprite Properties",
18176
+ predicate: (entity) => entity instanceof Sprite,
18177
+ content: [
18178
+ {
18179
+ section: "General",
18180
+ component: ({ context }) => jsx(SpriteGeneralProperties, { sprite: context, selectionService: selectionService }),
18181
+ },
18182
+ {
18183
+ section: "Transform",
18184
+ component: ({ context }) => jsx(SpriteTransformProperties, { sprite: context }),
18185
+ },
18186
+ {
18187
+ section: "Cell",
18188
+ component: ({ context }) => jsx(SpriteCellProperties, { sprite: context }),
18189
+ },
18190
+ {
18191
+ section: "Animation",
18192
+ component: ({ context }) => jsx(SpriteAnimationProperties, { sprite: context }),
18193
+ },
18194
+ {
18195
+ section: "Other",
18196
+ component: ({ context }) => jsx(SpriteOtherProperties, { sprite: context }),
18197
+ },
18198
+ ],
18199
+ });
18200
+ return {
18201
+ dispose: () => {
18202
+ spriteManagerSectionContentRegistration.dispose();
18203
+ spriteSectionContentRegistration.dispose();
18204
+ },
18205
+ };
18206
+ },
18392
18207
  };
18393
18208
 
18394
18209
  // eslint-disable-next-line @typescript-eslint/naming-convention
@@ -19992,6 +19807,222 @@ const TextureEditorServiceDefinition = {
19992
19807
  },
19993
19808
  };
19994
19809
 
19810
+ /**
19811
+ * Creates a lazy component wrapper that only calls the async function to get the underlying component when the lazy component is actually mounted.
19812
+ * This allows deferring imports until they are needed. While the underlying component is being loaded, a spinner is displayed.
19813
+ * @param getComponentAsync A function that returns a promise resolving to the component.
19814
+ * @param defaultProps Options for the loading spinner.
19815
+ * @returns A React component that displays a spinner while loading the async component.
19816
+ */
19817
+ function MakeLazyComponent(getComponentAsync, defaultProps) {
19818
+ // eslint-disable-next-line @typescript-eslint/naming-convention
19819
+ const LazyComponent = lazy(async () => {
19820
+ const component = await getComponentAsync();
19821
+ return { default: component };
19822
+ });
19823
+ return forwardRef((props, ref) => {
19824
+ const { spinnerSize = defaultProps?.spinnerSize, spinnerLabel = defaultProps?.spinnerLabel, ...rest } = props;
19825
+ const componentProps = { ...rest, ref };
19826
+ return (jsx(Suspense, { fallback: jsx(Spinner, { ref: ref, size: spinnerSize, label: spinnerLabel }), children: jsx(LazyComponent, { ...componentProps }) }));
19827
+ });
19828
+ }
19829
+
19830
+ const AdvancedDynamicTextureGeneralProperties = MakeLazyComponent(async () => {
19831
+ // Defer importing anything from the gui package until this component is actually mounted.
19832
+ const { AdvancedDynamicTextureInstrumentation } = await import('@babylonjs/gui/2D/adtInstrumentation.js');
19833
+ return (props) => {
19834
+ const { texture } = props;
19835
+ const instrumentation = useResource(useCallback(() => {
19836
+ const instrumentation = new AdvancedDynamicTextureInstrumentation(texture);
19837
+ instrumentation.captureRenderTime = true;
19838
+ instrumentation.captureLayoutTime = true;
19839
+ return instrumentation;
19840
+ }, [texture]));
19841
+ const layoutTime = useObservableState(useCallback(() => instrumentation.layoutTimeCounter.current, [instrumentation.layoutTimeCounter]), usePollingObservable(1000));
19842
+ const renderTime = useObservableState(useCallback(() => instrumentation.renderTimeCounter.current, [instrumentation.renderTimeCounter]), usePollingObservable(1000));
19843
+ return (jsxs(Fragment, { children: [jsx(StringifiedPropertyLine, { label: "Last Layout Time", value: layoutTime, precision: 2, units: "ms" }), jsx(StringifiedPropertyLine, { label: "Last Render Time", value: renderTime, precision: 2, units: "ms" }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Render Scale", target: texture, propertyKey: "renderScale", min: 0.1, max: 5, step: 0.1 }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Premultiply Alpha", target: texture, propertyKey: "premulAlpha" }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Ideal Width", target: texture, propertyKey: "idealWidth" }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Ideal Height", target: texture, propertyKey: "idealHeight" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use Smallest Ideal", target: texture, propertyKey: "useSmallestIdeal" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Render at Ideal Size", target: texture, propertyKey: "renderAtIdealSize" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Invalidate Rect Optimization", target: texture, propertyKey: "useInvalidateRectOptimization" })] }));
19844
+ };
19845
+ }, { spinnerSize: "extra-tiny", spinnerLabel: "Loading..." });
19846
+ const AdvancedDynamicTexturePreviewProperties = (props) => {
19847
+ const { texture } = props;
19848
+ return (jsx(Fragment, { children: jsx(ButtonLine, { label: "Edit GUI", icon: EditRegular, onClick: async () => {
19849
+ const { GUIEditor } = await import('@babylonjs/gui-editor/guiEditor.js');
19850
+ await GUIEditor.Show({ liveGuiTexture: texture });
19851
+ } }) }));
19852
+ };
19853
+
19854
+ const TextureFormat = [
19855
+ { label: "Alpha", normalizable: false, value: Constants.TEXTUREFORMAT_ALPHA },
19856
+ { label: "Luminance", normalizable: false, value: Constants.TEXTUREFORMAT_LUMINANCE },
19857
+ { label: "Luminance/Alpha", normalizable: false, value: Constants.TEXTUREFORMAT_LUMINANCE_ALPHA },
19858
+ { label: "RGB", normalizable: true, value: Constants.TEXTUREFORMAT_RGB },
19859
+ { label: "RGBA", normalizable: true, value: Constants.TEXTUREFORMAT_RGBA },
19860
+ { label: "R (red)", normalizable: true, value: Constants.TEXTUREFORMAT_RED },
19861
+ { label: "RG (red/green)", normalizable: true, value: Constants.TEXTUREFORMAT_RG },
19862
+ { label: "R (red) integer", normalizable: false, value: Constants.TEXTUREFORMAT_RED_INTEGER },
19863
+ { label: "RG (red/green) integer", normalizable: false, value: Constants.TEXTUREFORMAT_RG_INTEGER },
19864
+ { label: "RGB integer", normalizable: false, value: Constants.TEXTUREFORMAT_RGB_INTEGER },
19865
+ { label: "RGBA integer", normalizable: false, value: Constants.TEXTUREFORMAT_RGBA_INTEGER },
19866
+ { label: "BGRA", normalizable: true, value: Constants.TEXTUREFORMAT_BGRA },
19867
+ { label: "Depth24/Stencil8", normalizable: false, hideType: true, value: Constants.TEXTUREFORMAT_DEPTH24_STENCIL8 },
19868
+ { label: "Depth32 float", normalizable: false, hideType: true, value: Constants.TEXTUREFORMAT_DEPTH32_FLOAT },
19869
+ { label: "Depth16", normalizable: false, value: Constants.TEXTUREFORMAT_DEPTH16 },
19870
+ { label: "Depth24", normalizable: false, value: Constants.TEXTUREFORMAT_DEPTH24 },
19871
+ { label: "Depth24Unorm/Stencil8", normalizable: false, hideType: true, value: Constants.TEXTUREFORMAT_DEPTH24UNORM_STENCIL8 },
19872
+ { label: "Depth32Float/Stencil8", normalizable: false, hideType: true, value: Constants.TEXTUREFORMAT_DEPTH32FLOAT_STENCIL8 },
19873
+ { label: "RGBA BPTC UNorm", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM },
19874
+ { label: "RGB BPTC UFloat", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT },
19875
+ { label: "RGB BPTC SFloat", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT },
19876
+ { label: "RGBA S3TC DXT5", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5 },
19877
+ { label: "RGBA S3TC DXT3", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3 },
19878
+ { label: "RGBA S3TC DXT1", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1 },
19879
+ { label: "RGB S3TC DXT1", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1 },
19880
+ { label: "RGBA ASTC 4x4", normalizable: false, compressed: true, value: Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4 },
19881
+ ];
19882
+ function FindTextureFormat(format) {
19883
+ for (let i = 0; i < TextureFormat.length; ++i) {
19884
+ if (TextureFormat[i].value === format) {
19885
+ return TextureFormat[i];
19886
+ }
19887
+ }
19888
+ return null;
19889
+ }
19890
+ const TextureType = [
19891
+ { label: "unsigned byte", normalizable: true, value: Constants.TEXTURETYPE_UNSIGNED_BYTE },
19892
+ { label: "32-bit float", normalizable: false, value: Constants.TEXTURETYPE_FLOAT },
19893
+ { label: "16-bit float", normalizable: false, value: Constants.TEXTURETYPE_HALF_FLOAT },
19894
+ { label: "signed byte", normalizable: true, value: Constants.TEXTURETYPE_BYTE },
19895
+ { label: "signed short", normalizable: false, value: Constants.TEXTURETYPE_SHORT },
19896
+ { label: "unsigned short", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_SHORT },
19897
+ { label: "signed int", normalizable: false, value: Constants.TEXTURETYPE_INT },
19898
+ { label: "unsigned int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INTEGER },
19899
+ { label: "unsigned 4/4/4/4 short", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4 },
19900
+ { label: "unsigned 5/5/5/1 short", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1 },
19901
+ { label: "unsigned 5/6/5 short", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5 },
19902
+ { label: "unsigned 2/10/10/10 int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV },
19903
+ { label: "unsigned 24/8 int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INT_24_8 },
19904
+ { label: "unsigned 10f/11f/11f int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV },
19905
+ { label: "unsigned 5/9/9/9 int", normalizable: false, value: Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV },
19906
+ { label: "32-bits with only 8-bit used (stencil)", normalizable: false, value: Constants.TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV },
19907
+ ];
19908
+ function FindTextureType(type) {
19909
+ for (let i = 0; i < TextureType.length; ++i) {
19910
+ if (TextureType[i].value === type) {
19911
+ return TextureType[i];
19912
+ }
19913
+ }
19914
+ return null;
19915
+ }
19916
+
19917
+ const BaseTexturePreviewProperties = (props) => {
19918
+ // eslint-disable-next-line @typescript-eslint/naming-convention
19919
+ const { texture, textureEditor: TextureEditor } = props;
19920
+ const texturePreviewImperativeRef = useRef(null);
19921
+ const childWindow = useRef(null);
19922
+ return (jsxs(Fragment, { children: [jsx(TexturePreview, { imperativeRef: texturePreviewImperativeRef, texture: texture }), jsx(TextureUpload, { texture: texture }), jsx(ButtonLine, { label: "Edit Texture", onClick: () => childWindow.current?.open(), icon: EditRegular }), jsx(ChildWindow, { id: "Texture Editor", imperativeRef: childWindow, children: jsx(TextureEditor, { texture: texture, onUpdate: async () => await texturePreviewImperativeRef.current?.refresh() }) })] }));
19923
+ };
19924
+ const BaseTextureGeneralProperties = (props) => {
19925
+ const { texture } = props;
19926
+ const internalTexture = useProperty(texture, "_texture");
19927
+ const internalUniqueId = useProperty(internalTexture, "uniqueId");
19928
+ return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: TextInputPropertyLine, label: "Display Name", target: texture, propertyKey: "displayName" }), internalUniqueId != null ? (jsx(StringifiedPropertyLine, { label: "Internal Unique ID", description: "The unique ID of the internal texture.", value: internalUniqueId })) : (jsx(BooleanBadgePropertyLine, { label: "Internal Unique ID", description: "This texture has no internal texture.", value: false }))] }));
19929
+ };
19930
+ const CoordinatesMode = [
19931
+ { label: "Explicit", value: Texture.EXPLICIT_MODE },
19932
+ { label: "Cubic", value: Texture.CUBIC_MODE },
19933
+ { label: "Inverse cubic", value: Texture.INVCUBIC_MODE },
19934
+ { label: "Equirectangular", value: Texture.EQUIRECTANGULAR_MODE },
19935
+ { label: "Fixed equirectangular", value: Texture.FIXED_EQUIRECTANGULAR_MODE },
19936
+ { label: "Fixed equirectangular mirrored", value: Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE },
19937
+ { label: "Planar", value: Texture.PLANAR_MODE },
19938
+ { label: "Projection", value: Texture.PROJECTION_MODE },
19939
+ { label: "Skybox", value: Texture.SKYBOX_MODE },
19940
+ { label: "Spherical", value: Texture.SPHERICAL_MODE },
19941
+ ];
19942
+ const BaseTextureCharacteristicProperties = (props) => {
19943
+ const { texture } = props;
19944
+ const internalTexture = useProperty(texture, "_texture");
19945
+ const format = useProperty(internalTexture, "format") ?? NaN;
19946
+ const type = useProperty(internalTexture, "type") ?? NaN;
19947
+ const depth = useProperty(internalTexture, "depth");
19948
+ const useSRGBBuffer = useProperty(internalTexture, "_useSRGBBuffer");
19949
+ const samples = useProperty(internalTexture, "samples") ?? "?";
19950
+ const displayFormat = FindTextureFormat(format === -1 ? Constants.TEXTUREFORMAT_RGBA : format);
19951
+ const displayType = FindTextureType(type === -1 ? Constants.TEXTURETYPE_UNSIGNED_BYTE : type);
19952
+ const maxAnisotropy = texture.getScene()?.getEngine().getCaps().maxAnisotropy ?? 1;
19953
+ return (jsxs(Fragment, { children: [texture.is2DArray && jsx(TextPropertyLine, { label: "Layers", value: depth?.toString() ?? "?" }), texture.is3D && jsx(TextPropertyLine, { label: "Depth", value: depth?.toString() ?? "?" }), jsx(TextPropertyLine, { label: "Format", value: displayFormat?.label ?? "unknown" }), !displayFormat?.hideType && !displayFormat?.compressed && jsx(TextPropertyLine, { label: "Type", value: displayType?.label ?? "unknown" }), !!displayFormat?.normalizable && !displayFormat?.compressed && displayType?.normalizable != undefined && (jsx(BooleanBadgePropertyLine, { label: "Normalized", value: displayType.normalizable })), jsx(BooleanBadgePropertyLine, { label: "Compressed", value: displayFormat?.compressed ?? false }), jsx(BooleanBadgePropertyLine, { label: "sRGB Buffers", value: useSRGBBuffer ?? false }), jsx(BoundProperty, { component: BooleanBadgePropertyLine, label: "Gamma Space", target: texture, propertyKey: "gammaSpace" }), jsx(BoundProperty, { component: BooleanBadgePropertyLine, label: "Has Alpha", target: texture, propertyKey: "hasAlpha" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Alpha from RGB", target: texture, propertyKey: "getAlphaFromRGB" }), jsx(BooleanBadgePropertyLine, { label: "3D", value: texture.is3D }), jsx(BooleanBadgePropertyLine, { label: "2D Array", value: texture.is2DArray }), jsx(BooleanBadgePropertyLine, { label: "Cube", value: texture.isCube }), jsx(BooleanBadgePropertyLine, { label: "Render Target", value: texture.isRenderTarget }), jsx(BooleanBadgePropertyLine, { label: "Mipmaps", value: !texture.noMipmap }), jsx(TextPropertyLine, { label: "Samples", value: samples.toString() }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "UV Set", target: texture, propertyKey: "coordinatesIndex", min: 0, max: 3, step: 1 }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Mode", target: texture, propertyKey: "coordinatesMode", options: CoordinatesMode }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Level", target: texture, propertyKey: "level", min: 0, max: 2, step: 0.01 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Anisotropy", target: texture, propertyKey: "anisotropicFilteringLevel", min: 1, max: maxAnisotropy, step: 1 })] }));
19954
+ };
19955
+ const BaseTextureTransformProperties = (props) => {
19956
+ const { texture } = props;
19957
+ return (jsxs(Fragment, { children: [texture.canRescale && (jsx(ButtonLine, { label: "Scale Up", onClick: () => {
19958
+ texture.scale(2);
19959
+ } })), texture.canRescale && (jsx(ButtonLine, { label: "Scale Down", onClick: () => {
19960
+ texture.scale(0.5);
19961
+ } }))] }));
19962
+ };
19963
+
19964
+ const CubeTextureTransformProperties = (props) => {
19965
+ const { texture } = props;
19966
+ const [toDisplayAngle, fromDisplayAngle] = useAngleConverters();
19967
+ return (jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Rotation Y", target: texture, propertyKey: "rotationY", min: 0, max: toDisplayAngle(Math.PI * 2), step: 0.0001, convertTo: (value) => toDisplayAngle(value, true), convertFrom: fromDisplayAngle }));
19968
+ };
19969
+
19970
+ const MultiRenderTargetGeneralProperties = (props) => {
19971
+ const { texture } = props;
19972
+ return (jsx(Fragment, { children: jsx(BoundProperty, { component: StringifiedPropertyLine, label: "Count", description: "The number of render target textures.", target: texture, propertyKey: "count" }) }));
19973
+ };
19974
+
19975
+ const RenderTargetTextureGeneralProperties = (props) => {
19976
+ const { texture } = props;
19977
+ const depthStencilTexture = useProperty(texture.renderTarget, "_depthStencilTexture");
19978
+ const depthStencilTextureDisplayFormat = depthStencilTexture ? FindTextureFormat(depthStencilTexture.format) : null;
19979
+ return (jsx(Fragment, { children: depthStencilTextureDisplayFormat ? (jsx(TextPropertyLine, { label: "Depth/Stencil Format", value: depthStencilTextureDisplayFormat.label })) : (jsx(BooleanBadgePropertyLine, { label: "Depth/Stencil Texture", value: false })) }));
19980
+ };
19981
+
19982
+ const TexturePreviewProperties = (props) => {
19983
+ const { texture } = props;
19984
+ const rawUrl = useProperty(texture, "url");
19985
+ const displayUrl = !rawUrl || rawUrl.substring(0, 4) === "data" || rawUrl.substring(0, 4) === "blob" ? "" : rawUrl;
19986
+ return (jsx(Fragment, { children: jsx(TextInputPropertyLine, { label: "URL", value: displayUrl, onChange: (value) => {
19987
+ texture.updateURL(value);
19988
+ } }) }));
19989
+ };
19990
+ const TextureGeneralProperties = (props) => {
19991
+ const { texture } = props;
19992
+ return (jsx(Fragment, { children: jsx(BooleanBadgePropertyLine, { label: "Invert Y", description: "If true, the texture is stored as inverted on Y", value: texture.invertY }) }));
19993
+ };
19994
+ const TextureTransformProperties = (props) => {
19995
+ const { texture } = props;
19996
+ const [toDisplayAngle, fromDisplayAngle] = useAngleConverters();
19997
+ const wrapU = useProperty(texture, "wrapU");
19998
+ const wrapV = useProperty(texture, "wrapV");
19999
+ return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "U offset", target: texture, propertyKey: "uOffset", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "V offset", target: texture, propertyKey: "vOffset", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "U scale", target: texture, propertyKey: "uScale", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "V scale", target: texture, propertyKey: "vScale", step: 0.01 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "U angle", target: texture, propertyKey: "uAng", min: 0, max: toDisplayAngle(Math.PI * 2), step: 0.01, convertTo: (value) => toDisplayAngle(value, true), convertFrom: fromDisplayAngle }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "V angle", target: texture, propertyKey: "vAng", min: 0, max: toDisplayAngle(Math.PI * 2), step: 0.01, convertTo: (value) => toDisplayAngle(value, true), convertFrom: fromDisplayAngle }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "W angle", target: texture, propertyKey: "wAng", min: 0, max: toDisplayAngle(Math.PI * 2), step: 0.01, convertTo: (value) => toDisplayAngle(value, true), convertFrom: fromDisplayAngle }), jsx(SwitchPropertyLine, { label: "Clamp U", value: wrapU === Constants.TEXTURE_CLAMP_ADDRESSMODE, onChange: (value) => (texture.wrapU = value ? Constants.TEXTURE_CLAMP_ADDRESSMODE : Constants.TEXTURE_WRAP_ADDRESSMODE) }), jsx(SwitchPropertyLine, { label: "Clamp V", value: wrapV === Constants.TEXTURE_CLAMP_ADDRESSMODE, onChange: (value) => (texture.wrapV = value ? Constants.TEXTURE_CLAMP_ADDRESSMODE : Constants.TEXTURE_WRAP_ADDRESSMODE) })] }));
20000
+ };
20001
+
20002
+ const SamplingMode = [
20003
+ { label: "Nearest", value: Texture.NEAREST_NEAREST }, // 1
20004
+ { label: "Linear", value: Texture.LINEAR_LINEAR }, // 2
20005
+ { label: "Linear & linear mip", value: Texture.LINEAR_LINEAR_MIPLINEAR }, // 3
20006
+ { label: "Linear & nearest mip", value: Texture.LINEAR_LINEAR_MIPNEAREST }, // 11
20007
+ { label: "Nearest & linear mip", value: Texture.NEAREST_NEAREST_MIPLINEAR }, // 8
20008
+ { label: "Nearest & nearest mip", value: Texture.NEAREST_NEAREST_MIPNEAREST }, // 4
20009
+ { label: "Nearest/Linear", value: Texture.NEAREST_LINEAR }, // 7
20010
+ { label: "Nearest/Linear & linear mip", value: Texture.NEAREST_LINEAR_MIPLINEAR }, // 6
20011
+ { label: "Nearest/Linear & nearest mip", value: Texture.NEAREST_LINEAR_MIPNEAREST }, // 5
20012
+ { label: "Linear/Nearest", value: Texture.LINEAR_NEAREST }, // 12
20013
+ { label: "Linear/Nearest & linear mip", value: Texture.LINEAR_NEAREST_MIPLINEAR }, // 10
20014
+ { label: "Linear/Nearest & nearest mip", value: Texture.LINEAR_NEAREST_MIPNEAREST }, // 9
20015
+ ];
20016
+ const ThinTextureGeneralProperties = (props) => {
20017
+ const { texture } = props;
20018
+ return (jsxs(Fragment, { children: [jsx(StringifiedPropertyLine, { label: "Width", value: texture.getSize().width, units: "px" }), jsx(StringifiedPropertyLine, { label: "Height", value: texture.getSize().height, units: "px" })] }));
20019
+ };
20020
+ const ThinTextureSamplingProperties = (props) => {
20021
+ const { texture } = props;
20022
+ const samplingMode = useObservableState(useCallback(() => texture.samplingMode, [texture]), useInterceptObservable("function", texture, "updateSamplingMode"));
20023
+ return (jsx(Property, { component: NumberDropdownPropertyLine, label: "Sampling", propertyPath: "samplingMode", value: samplingMode, options: SamplingMode, onChange: (value) => texture.updateSamplingMode(value) }));
20024
+ };
20025
+
19995
20026
  // Don't use instanceof in this case as we don't want to bring in the gui package just to check if the entity is an AdvancedDynamicTexture.
19996
20027
  function IsAdvancedDynamicTexture$1(entity) {
19997
20028
  return entity?.getClassName?.() === "AdvancedDynamicTexture";
@@ -20520,7 +20551,7 @@ const GuiExplorerServiceDefinition = {
20520
20551
  icon: () => jsx(EditRegular, {}),
20521
20552
  // eslint-disable-next-line @typescript-eslint/naming-convention
20522
20553
  execute: async () => {
20523
- const { GUIEditor } = await import('@babylonjs/gui-editor');
20554
+ const { GUIEditor } = await import('@babylonjs/gui-editor/guiEditor.js');
20524
20555
  await GUIEditor.Show({ liveGuiTexture: texture });
20525
20556
  },
20526
20557
  };
@@ -22152,6 +22183,8 @@ function ShowInspector(scene, options = {}) {
22152
22183
  disposeActions.push(() => observer.remove());
22153
22184
  }
22154
22185
  serviceDefinitions.push(
22186
+ // Watcher service for observing property changes.
22187
+ WatcherServiceDefinition,
22155
22188
  // Helps with managing gizmos and a shared utility layer.
22156
22189
  GizmoServiceDefinition,
22157
22190
  // Scene explorer tab and related services.
@@ -23021,5 +23054,5 @@ const TextAreaPropertyLine = (props) => {
23021
23054
  // Attach Inspector v2 to Scene.debugLayer as a side effect for back compat.
23022
23055
  AttachDebugLayer();
23023
23056
 
23024
- 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, LinkToEntity as L, MessageBar as M, NumberInputPropertyLine as N, DraggableLine as O, Popover as P, Dropdown as Q, EntitySelector as R, SpinButtonPropertyLine 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 _, useInterceptObservable as a, UploadButton as a$, HexPropertyLine as a0, InfoLabel as a1, InputHexField as a2, InputHsvField as a3, Inspector as a4, InterceptFunction as a5, InterceptProperty as a6, IsPropertyReadonly as a7, LineContainer as a8, LinkPropertyLine as a9, SettingsStore as aA, SettingsStoreIdentity as aB, ShowInspector as aC, SidePaneContainer as aD, SkeletonSelector as aE, Slider as aF, SpinButton as aG, StatsServiceIdentity as aH, StringDropdown as aI, StringDropdownPropertyLine as aJ, StringifiedPropertyLine as aK, Switch as aL, SwitchPropertyLine as aM, SyncedSliderInput as aN, SyncedSliderPropertyLine as aO, TeachingMoment as aP, TextAreaPropertyLine as aQ, TextInput as aR, TextPropertyLine as aS, Textarea as aT, TextureSelector as aU, TextureUpload as aV, Theme as aW, ThemeServiceIdentity as aX, ToastProvider as aY, ToggleButton as aZ, Tooltip as a_, LinkToEntityPropertyLine as aa, List as ab, MakeDialogTeachingMoment as ac, MakeLazyComponent as ad, MakePopoverTeachingMoment as ae, MakePropertyHook as af, MakeTeachingMoment as ag, MaterialSelector as ah, NodeSelector as ai, NumberDropdown as aj, NumberDropdownPropertyLine as ak, ObservableCollection as al, Pane as am, PlaceholderPropertyLine as an, PositionedPopover as ao, PropertiesServiceIdentity as ap, Property as aq, PropertyContext as ar, PropertyLine as as, QuaternionPropertyLine as at, RotationVectorPropertyLine as au, SceneExplorerServiceIdentity as av, SearchBar as aw, SearchBox as ax, SelectionServiceDefinition as ay, SettingsServiceIdentity as az, useProperty as b, Vector2PropertyLine as b0, Vector4PropertyLine as b1, WatcherServiceIdentity as b2, useAngleConverters as b3, useAsyncResource as b4, useColor3Property as b5, useColor4Property as b6, useEventListener as b7, useEventfulState as b8, useKeyListener as b9, useKeyState as ba, useObservableCollection as bb, useOrderedObservableCollection as bc, usePollingObservable as bd, usePropertyChangedNotifier as be, useQuaternionProperty as bf, useResource as bg, useSetting as bh, useTheme as bi, useThemeMode as bj, useVector3Property as bk, ShellServiceIdentity as c, SceneContextIdentity as d, SelectionServiceIdentity as e, useObservableState as f, AccordionSection as g, ButtonLine as h, ToolsServiceIdentity as i, useExtensionManager as j, Link 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, useToast as u, Color3GradientList as v, Color3PropertyLine as w, Color4GradientComponent as x, Color4GradientList as y, Color4PropertyLine as z };
23025
- //# sourceMappingURL=index-DuVF9zYN.js.map
23057
+ 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, Vector2PropertyLine as a$, HexPropertyLine as a0, InfoLabel as a1, InputHexField as a2, InputHsvField as a3, Inspector as a4, InterceptFunction as a5, InterceptProperty as a6, IsPropertyReadonly as a7, LineContainer as a8, LinkPropertyLine as a9, SettingsStoreIdentity as aA, ShowInspector as aB, SidePaneContainer as aC, SkeletonSelector as aD, Slider as aE, SpinButton as aF, StatsServiceIdentity as aG, StringDropdown as aH, StringDropdownPropertyLine as aI, StringifiedPropertyLine as aJ, Switch as aK, SwitchPropertyLine as aL, SyncedSliderInput as aM, SyncedSliderPropertyLine as aN, TeachingMoment as aO, TextAreaPropertyLine as aP, TextInput as aQ, TextPropertyLine as aR, Textarea as aS, TextureSelector as aT, TextureUpload as aU, Theme as aV, ThemeServiceIdentity as aW, ToastProvider as aX, ToggleButton as aY, Tooltip as aZ, UploadButton as a_, LinkToEntityPropertyLine as aa, List as ab, MakeDialogTeachingMoment as ac, MakeLazyComponent as ad, MakePopoverTeachingMoment as ae, MakePropertyHook as af, MakeTeachingMoment as ag, MaterialSelector as ah, NodeSelector as ai, NumberDropdown as aj, NumberDropdownPropertyLine as ak, ObservableCollection as al, Pane as am, PlaceholderPropertyLine as an, PositionedPopover as ao, PropertiesServiceIdentity as ap, Property as aq, PropertyContext as ar, PropertyLine as as, QuaternionPropertyLine as at, RotationVectorPropertyLine as au, SceneExplorerServiceIdentity as av, SearchBar as aw, SearchBox as ax, SelectionServiceDefinition as ay, SettingsServiceIdentity as az, useInterceptObservable as b, Vector4PropertyLine as b0, WatcherServiceIdentity as b1, useAngleConverters as b2, useAsyncResource as b3, useColor3Property as b4, useColor4Property as b5, useEventListener as b6, useEventfulState as b7, useKeyListener as b8, useKeyState as b9, useObservableCollection as ba, useOrderedObservableCollection as bb, usePollingObservable as bc, usePropertyChangedNotifier as bd, useQuaternionProperty as be, useResource as bf, useSetting as bg, useTheme as bh, useThemeMode as bi, useVector3Property as bj, 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 };
23058
+ //# sourceMappingURL=index-BCbXjPTn.js.map