@babylonjs/inspector 9.6.2 → 9.7.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.
- package/lib/components/properties/materials/materialProperties.d.ts +3 -0
- package/lib/{extensionsListService-C33SU1_a.js → extensionsListService-DTrjNf_v.js} +3 -2
- package/lib/{extensionsListService-C33SU1_a.js.map → extensionsListService-DTrjNf_v.js.map} +1 -1
- package/lib/{index-D0JXVQQf.js → index-PYblOaAV.js} +786 -151
- package/lib/index-PYblOaAV.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/{quickCreateToolsService-pBNUavZe.js → quickCreateToolsService-8d6rBO-A.js} +3 -2
- package/lib/{quickCreateToolsService-pBNUavZe.js.map → quickCreateToolsService-8d6rBO-A.js.map} +1 -1
- package/lib/{reflectorService-CAi2NPRy.js → reflectorService-B7LcD1Sn.js} +3 -2
- package/lib/{reflectorService-CAi2NPRy.js.map → reflectorService-B7LcD1Sn.js.map} +1 -1
- package/lib/services/panes/smartAssetsService.d.ts +8 -0
- package/lib/services/panes/tools/smartAssetToolsService.d.ts +10 -0
- package/lib/services/smartAssetHandler.d.ts +22 -0
- package/lib/services/smartAssetPromptService.d.ts +7 -0
- package/package.json +1 -1
- package/lib/index-D0JXVQQf.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { createContext, forwardRef, useContext, useState, useCallback, Component, useMemo, useEffect, useRef, useReducer, Children, isValidElement, useLayoutEffect, useImperativeHandle, cloneElement, createElement, Suspense, memo, Fragment as Fragment$1, lazy } from 'react';
|
|
3
|
-
import { tokens, makeStyles, Tooltip as Tooltip$1, Button as Button$1, Spinner, Link as Link$1, Caption1, Body1, useFluent, Accordion as Accordion$1, AccordionHeader, Subtitle2Stronger, AccordionPanel, Divider, MessageBar as MessageBar$1, MessageBarBody, AccordionItem, SearchBox as SearchBox$1, Portal, ToggleButton as ToggleButton$1, InfoLabel as InfoLabel$1, Body1Strong, mergeClasses, useId, useToastController, Toast, ToastTitle, FluentProvider, Toaster, Checkbox as Checkbox$1, createLightTheme, createDarkTheme, TeachingPopover, TeachingPopoverSurface, TeachingPopoverHeader, TeachingPopoverBody, createDOMRenderer, RendererProvider, Menu, MenuTrigger, SplitButton, MenuPopover, MenuList, MenuItem, Toolbar as Toolbar$1, ToolbarRadioButton, MenuGroup, MenuGroupHeader, Switch as Switch$1, treeItemLevelToken, FlatTree, FlatTreeItem, TreeItemLayout, MenuDivider, MenuItemCheckbox, useMergedRefs, Input, Dropdown as Dropdown$1, Option, Popover as Popover$1, PopoverTrigger, PopoverSurface, ColorPicker, ColorArea, ColorSlider, AlphaSlider, ColorSwatch, PresenceBadge, Slider as Slider$1, MenuItemRadio, Dialog, DialogSurface, DialogBody, DialogTitle, DialogContent, DialogActions, List as List$1, ListItem, Badge, Label, MessageBarTitle, useComboboxFilter, Combobox, Subtitle2, Textarea as Textarea$1, ToolbarButton, ToolbarDivider, Field } from '@fluentui/react-components';
|
|
4
|
-
import { ErrorCircleRegular, EyeFilled, EyeOffRegular, CheckmarkFilled, EditRegular, FilterRegular, PinFilled, PinRegular, ArrowCircleUpRegular, ChevronCircleRight16Regular, ChevronCircleRight20Regular, ChevronCircleDown16Regular, ChevronCircleDown20Regular, Copy16Regular, CopyRegular, PanelLeftExpandRegular, PanelRightExpandRegular, PanelLeftContractRegular, PanelRightContractRegular, PictureInPictureEnterRegular, MoreHorizontalRegular, LayoutColumnTwoFocusLeftFilled, LayoutColumnTwoSplitLeftFocusTopLeftFilled, LayoutColumnTwoSplitLeftFocusBottomLeftFilled, LayoutColumnTwoFocusRightFilled, LayoutColumnTwoSplitRightFocusTopRightFilled, LayoutColumnTwoSplitRightFocusBottomRightFilled, SettingsRegular, DocumentTextRegular, createFluentIcon, TextSortAscendingRegular, GlobeRegular, WarningRegular, ArrowExpandAllRegular, ArrowCollapseAllRegular, CubeTreeRegular, BugRegular, ArrowUploadRegular, ArrowBidirectionalUpDownFilled, ArrowDownloadRegular, StopRegular, RecordRegular, DataBarHorizontalRegular, WrenchRegular, ArrowClockwiseRegular, WeatherSunnyRegular, WeatherMoonRegular, PlugDisconnectedRegular, PlugConnectedRegular, PlugConnectedCheckmarkRegular, 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';
|
|
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 as Dialog$1, DialogSurface, DialogBody, DialogTitle, DialogContent, DialogActions, List as List$1, ListItem, Badge, Label, MessageBarTitle, useComboboxFilter, Combobox, Subtitle2, Textarea as Textarea$1, ToolbarButton, ToolbarDivider, DialogTrigger, Field } from '@fluentui/react-components';
|
|
4
|
+
import { ErrorCircleRegular, EyeFilled, EyeOffRegular, CheckmarkFilled, EditRegular, FilterRegular, PinFilled, PinRegular, ArrowCircleUpRegular, ChevronCircleRight16Regular, ChevronCircleRight20Regular, ChevronCircleDown16Regular, ChevronCircleDown20Regular, Copy16Regular, CopyRegular, PanelLeftExpandRegular, PanelRightExpandRegular, PanelLeftContractRegular, PanelRightContractRegular, PictureInPictureEnterRegular, MoreHorizontalRegular, LayoutColumnTwoFocusLeftFilled, LayoutColumnTwoSplitLeftFocusTopLeftFilled, LayoutColumnTwoSplitLeftFocusBottomLeftFilled, LayoutColumnTwoFocusRightFilled, LayoutColumnTwoSplitRightFocusTopRightFilled, LayoutColumnTwoSplitRightFocusBottomRightFilled, SettingsRegular, DocumentTextRegular, createFluentIcon, TextSortAscendingRegular, GlobeRegular, WarningRegular, ArrowExpandAllRegular, ArrowCollapseAllRegular, CubeTreeRegular, BugRegular, ArrowUploadRegular, ArrowBidirectionalUpDownFilled, ArrowDownloadRegular, StopRegular, RecordRegular, DataBarHorizontalRegular, WrenchRegular, ArrowClockwiseRegular, WeatherSunnyRegular, WeatherMoonRegular, PlugDisconnectedRegular, PlugConnectedRegular, PlugConnectedCheckmarkRegular, 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, LinkRegular, ArrowSyncRegular, TargetRegular, PersonFeedbackRegular, DismissRegular, BranchRegular, DeleteFilled } from '@fluentui/react-icons';
|
|
5
5
|
import { Color3, Color4 } from '@babylonjs/core/Maths/math.color.js';
|
|
6
6
|
import { Vector3, Quaternion, Matrix, Vector2, Vector4, TmpVectors } from '@babylonjs/core/Maths/math.vector.js';
|
|
7
7
|
import { Observable } from '@babylonjs/core/Misc/observable.js';
|
|
@@ -144,6 +144,7 @@ import { SceneRecorder } from '@babylonjs/core/Misc/sceneRecorder.js';
|
|
|
144
144
|
import { VideoRecorder } from '@babylonjs/core/Misc/videoRecorder.js';
|
|
145
145
|
import { SceneSerializer } from '@babylonjs/core/Misc/sceneSerializer.js';
|
|
146
146
|
import { EnvironmentTextureTools } from '@babylonjs/core/Misc/environmentTextureTools.js';
|
|
147
|
+
import { SerializeSmartAssetManagerMap, GetAllSmartAssets, RemoveSmartAssetAsync, LoadSmartAssetMapAsync, GetSmartAssetTextureExtensions, GetSmartAssetManager, LoadSmartAssetTextureAsync, LoadSmartAssetAsync, ReloadSmartAssetAsync, FindSmartAssetKeyForObject, UnloadSmartAssetAsync } from '@babylonjs/core/SmartAssets/smartAssetManager.js';
|
|
147
148
|
import { ImportAnimationsAsync, SceneLoader } from '@babylonjs/core/Loading/sceneLoader.js';
|
|
148
149
|
import { FilesInput } from '@babylonjs/core/Misc/filesInput.js';
|
|
149
150
|
import { registeredGLTFExtensions } from '@babylonjs/loaders/glTF/2.0/glTFLoaderExtensionRegistry.js';
|
|
@@ -284,7 +285,7 @@ const Button = forwardRef((props, ref) => {
|
|
|
284
285
|
});
|
|
285
286
|
Button.displayName = "Button";
|
|
286
287
|
|
|
287
|
-
const useStyles$
|
|
288
|
+
const useStyles$11 = makeStyles({
|
|
288
289
|
root: {
|
|
289
290
|
display: "flex",
|
|
290
291
|
flexDirection: "column",
|
|
@@ -365,7 +366,7 @@ class ErrorBoundary extends Component {
|
|
|
365
366
|
}
|
|
366
367
|
}
|
|
367
368
|
function ErrorFallback({ error, onRetry }) {
|
|
368
|
-
const styles = useStyles$
|
|
369
|
+
const styles = useStyles$11();
|
|
369
370
|
return (jsxs("div", { className: styles.root, children: [jsx(ErrorCircleRegular, { className: styles.icon }), jsx("div", { className: styles.title, children: "Something went wrong" }), jsx("div", { className: styles.message, children: "An error occurred in this component. You can try again or continue using other parts of the tool." }), jsx(Button, { label: "Try Again", appearance: "primary", onClick: onRetry }), error && jsx("div", { className: styles.details, children: error.message })] }));
|
|
370
371
|
}
|
|
371
372
|
|
|
@@ -1366,7 +1367,7 @@ function useIsSectionEmpty(sectionId) {
|
|
|
1366
1367
|
return hasItems;
|
|
1367
1368
|
}
|
|
1368
1369
|
|
|
1369
|
-
const useStyles$
|
|
1370
|
+
const useStyles$10 = makeStyles({
|
|
1370
1371
|
accordion: {
|
|
1371
1372
|
display: "flex",
|
|
1372
1373
|
flexDirection: "column",
|
|
@@ -1458,7 +1459,7 @@ const useStyles$Z = makeStyles({
|
|
|
1458
1459
|
*/
|
|
1459
1460
|
const AccordionMenuBar = () => {
|
|
1460
1461
|
AccordionMenuBar.displayName = "AccordionMenuBar";
|
|
1461
|
-
const classes = useStyles$
|
|
1462
|
+
const classes = useStyles$10();
|
|
1462
1463
|
const accordionCtx = useContext(AccordionContext);
|
|
1463
1464
|
if (!accordionCtx) {
|
|
1464
1465
|
return null;
|
|
@@ -1482,7 +1483,7 @@ const AccordionMenuBar = () => {
|
|
|
1482
1483
|
const AccordionSectionBlock = (props) => {
|
|
1483
1484
|
AccordionSectionBlock.displayName = "AccordionSectionBlock";
|
|
1484
1485
|
const { children, sectionId } = props;
|
|
1485
|
-
const classes = useStyles$
|
|
1486
|
+
const classes = useStyles$10();
|
|
1486
1487
|
const accordionCtx = useContext(AccordionContext);
|
|
1487
1488
|
const { context: sectionContext, isEmpty } = useAccordionSectionBlockContext(props);
|
|
1488
1489
|
if (accordionCtx) {
|
|
@@ -1502,7 +1503,7 @@ const AccordionSectionBlock = (props) => {
|
|
|
1502
1503
|
const AccordionSectionItem = (props) => {
|
|
1503
1504
|
AccordionSectionItem.displayName = "AccordionSectionItem";
|
|
1504
1505
|
const { children, staticItem } = props;
|
|
1505
|
-
const classes = useStyles$
|
|
1506
|
+
const classes = useStyles$10();
|
|
1506
1507
|
const accordionCtx = useContext(AccordionContext);
|
|
1507
1508
|
const itemState = useAccordionSectionItemState(props);
|
|
1508
1509
|
const [ctrlMode, setCtrlMode] = useState(false);
|
|
@@ -1542,7 +1543,7 @@ const AccordionSectionItem = (props) => {
|
|
|
1542
1543
|
*/
|
|
1543
1544
|
const AccordionPinnedContainer = () => {
|
|
1544
1545
|
AccordionPinnedContainer.displayName = "AccordionPinnedContainer";
|
|
1545
|
-
const classes = useStyles$
|
|
1546
|
+
const classes = useStyles$10();
|
|
1546
1547
|
const accordionCtx = useContext(AccordionContext);
|
|
1547
1548
|
return (jsx("div", { ref: accordionCtx?.pinnedContainerRef, className: classes.pinnedContainer, children: jsx(MessageBar$1, { className: classes.pinnedContainerEmpty, children: jsx(MessageBarBody, { children: "No pinned items" }) }) }));
|
|
1548
1549
|
};
|
|
@@ -1553,7 +1554,7 @@ const AccordionPinnedContainer = () => {
|
|
|
1553
1554
|
*/
|
|
1554
1555
|
const AccordionSearchBox = () => {
|
|
1555
1556
|
AccordionSearchBox.displayName = "AccordionSearchBox";
|
|
1556
|
-
const classes = useStyles$
|
|
1557
|
+
const classes = useStyles$10();
|
|
1557
1558
|
const accordionCtx = useContext(AccordionContext);
|
|
1558
1559
|
if (!accordionCtx?.features.search) {
|
|
1559
1560
|
return null;
|
|
@@ -1569,7 +1570,7 @@ const AccordionSearchBox = () => {
|
|
|
1569
1570
|
*/
|
|
1570
1571
|
const AccordionSection = (props) => {
|
|
1571
1572
|
AccordionSection.displayName = "AccordionSection";
|
|
1572
|
-
const classes = useStyles$
|
|
1573
|
+
const classes = useStyles$10();
|
|
1573
1574
|
return jsx("div", { className: classes.panelDiv, children: props.children });
|
|
1574
1575
|
};
|
|
1575
1576
|
const StringAccordion = Accordion$1;
|
|
@@ -1577,7 +1578,7 @@ const Accordion = forwardRef((props, ref) => {
|
|
|
1577
1578
|
Accordion.displayName = "Accordion";
|
|
1578
1579
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1579
1580
|
const { children, highlightSections, uniqueId, enablePinnedItems, enableHiddenItems, enableSearchItems, ...rest } = props;
|
|
1580
|
-
const classes = useStyles$
|
|
1581
|
+
const classes = useStyles$10();
|
|
1581
1582
|
const { size } = useContext(ToolContext);
|
|
1582
1583
|
const accordionCtx = useAccordionContext(props);
|
|
1583
1584
|
const hasPinning = accordionCtx?.features.pinning ?? false;
|
|
@@ -1674,7 +1675,7 @@ const Collapse = (props) => {
|
|
|
1674
1675
|
return (jsx(Collapse$1, { visible: props.visible, orientation: props.orientation, unmountOnExit: true, children: jsx("div", { className: `${classes.collapseContent} ${props.orientation === "horizontal" ? classes.horizontal : classes.vertical}`, children: props.children }) }));
|
|
1675
1676
|
};
|
|
1676
1677
|
|
|
1677
|
-
const useStyles
|
|
1678
|
+
const useStyles$$ = makeStyles({
|
|
1678
1679
|
button: {
|
|
1679
1680
|
display: "flex",
|
|
1680
1681
|
alignItems: "center",
|
|
@@ -1692,7 +1693,7 @@ const ToggleButton = (props) => {
|
|
|
1692
1693
|
ToggleButton.displayName = "ToggleButton";
|
|
1693
1694
|
const { value, onChange, title, appearance = "subtle" } = props;
|
|
1694
1695
|
const { size } = useContext(ToolContext);
|
|
1695
|
-
const classes = useStyles
|
|
1696
|
+
const classes = useStyles$$();
|
|
1696
1697
|
const [checked, setChecked] = useState(value);
|
|
1697
1698
|
const toggle = useCallback(() => {
|
|
1698
1699
|
setChecked((prevChecked) => {
|
|
@@ -2001,7 +2002,7 @@ const UXContextProvider = (props) => {
|
|
|
2001
2002
|
function AsReadonlyArray(array) {
|
|
2002
2003
|
return array;
|
|
2003
2004
|
}
|
|
2004
|
-
const useStyles$
|
|
2005
|
+
const useStyles$_ = makeStyles({
|
|
2005
2006
|
rootDiv: {
|
|
2006
2007
|
flex: 1,
|
|
2007
2008
|
overflow: "hidden",
|
|
@@ -2016,7 +2017,7 @@ const useStyles$X = makeStyles({
|
|
|
2016
2017
|
* @returns The extensible accordion component.
|
|
2017
2018
|
*/
|
|
2018
2019
|
function ExtensibleAccordion(props) {
|
|
2019
|
-
const classes = useStyles$
|
|
2020
|
+
const classes = useStyles$_();
|
|
2020
2021
|
const { children, sections, sectionContent, context, sectionsRef, ...rest } = props;
|
|
2021
2022
|
const defaultSections = useMemo(() => {
|
|
2022
2023
|
const defaultSections = [];
|
|
@@ -2141,7 +2142,7 @@ function ExtensibleAccordion(props) {
|
|
|
2141
2142
|
})] }) })) }));
|
|
2142
2143
|
}
|
|
2143
2144
|
|
|
2144
|
-
const useStyles$
|
|
2145
|
+
const useStyles$Z = makeStyles({
|
|
2145
2146
|
paneRootDiv: {
|
|
2146
2147
|
display: "flex",
|
|
2147
2148
|
flex: 1,
|
|
@@ -2154,7 +2155,7 @@ const useStyles$W = makeStyles({
|
|
|
2154
2155
|
*/
|
|
2155
2156
|
const SidePaneContainer = forwardRef((props, ref) => {
|
|
2156
2157
|
const { className, ...rest } = props;
|
|
2157
|
-
const classes = useStyles$
|
|
2158
|
+
const classes = useStyles$Z();
|
|
2158
2159
|
return (jsx("div", { className: mergeClasses(classes.paneRootDiv, className), ref: ref, ...rest, children: props.children }));
|
|
2159
2160
|
});
|
|
2160
2161
|
|
|
@@ -2425,7 +2426,7 @@ function useTheme(invert = false) {
|
|
|
2425
2426
|
}
|
|
2426
2427
|
|
|
2427
2428
|
// Fluent doesn't apply styling to scrollbars by default, so provide our own reasonable default.
|
|
2428
|
-
const useStyles$
|
|
2429
|
+
const useStyles$Y = makeStyles({
|
|
2429
2430
|
root: {
|
|
2430
2431
|
scrollbarColor: `${tokens.colorNeutralForeground3} ${tokens.colorTransparentBackground}`,
|
|
2431
2432
|
},
|
|
@@ -2441,11 +2442,11 @@ const Theme = (props) => {
|
|
|
2441
2442
|
// break any UI within the portal. Therefore, default to false.
|
|
2442
2443
|
const { invert = false, applyStylesToPortals = false, className, ...rest } = props;
|
|
2443
2444
|
const theme = useTheme(invert);
|
|
2444
|
-
const classes = useStyles$
|
|
2445
|
+
const classes = useStyles$Y();
|
|
2445
2446
|
return (jsx(FluentProvider, { theme: theme, className: mergeClasses(classes.root, className), applyStylesToPortals: applyStylesToPortals, ...rest, children: props.children }));
|
|
2446
2447
|
};
|
|
2447
2448
|
|
|
2448
|
-
const useStyles$
|
|
2449
|
+
const useStyles$X = makeStyles({
|
|
2449
2450
|
extensionTeachingPopover: {
|
|
2450
2451
|
maxWidth: "320px",
|
|
2451
2452
|
},
|
|
@@ -2456,7 +2457,7 @@ const useStyles$U = makeStyles({
|
|
|
2456
2457
|
* @returns The teaching moment popover.
|
|
2457
2458
|
*/
|
|
2458
2459
|
const TeachingMoment = ({ shouldDisplay, positioningRef, onOpenChange, title, description }) => {
|
|
2459
|
-
const classes = useStyles$
|
|
2460
|
+
const classes = useStyles$X();
|
|
2460
2461
|
return (jsx(TeachingPopover, { appearance: "brand", open: shouldDisplay, positioning: { positioningRef }, onOpenChange: onOpenChange, children: jsxs(TeachingPopoverSurface, { className: classes.extensionTeachingPopover, children: [jsx(TeachingPopoverHeader, { children: title }), jsx(TeachingPopoverBody, { children: description })] }) }));
|
|
2461
2462
|
};
|
|
2462
2463
|
|
|
@@ -2889,7 +2890,7 @@ const RootComponentServiceIdentity = Symbol("RootComponent");
|
|
|
2889
2890
|
* The unique identity symbol for the shell service.
|
|
2890
2891
|
*/
|
|
2891
2892
|
const ShellServiceIdentity = Symbol("ShellService");
|
|
2892
|
-
const useStyles$
|
|
2893
|
+
const useStyles$W = makeStyles({
|
|
2893
2894
|
mainView: {
|
|
2894
2895
|
flex: 1,
|
|
2895
2896
|
display: "flex",
|
|
@@ -3102,14 +3103,14 @@ const DockMenu = (props) => {
|
|
|
3102
3103
|
};
|
|
3103
3104
|
const PaneHeader = (props) => {
|
|
3104
3105
|
const { id, title, dockOptions } = props;
|
|
3105
|
-
const classes = useStyles$
|
|
3106
|
+
const classes = useStyles$W();
|
|
3106
3107
|
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, {}) }) })] }));
|
|
3107
3108
|
};
|
|
3108
3109
|
// 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.
|
|
3109
3110
|
const ToolbarItem = (props) => {
|
|
3110
3111
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3111
3112
|
const { verticalLocation, horizontalLocation, id, component: Component, displayName } = props;
|
|
3112
|
-
const classes = useStyles$
|
|
3113
|
+
const classes = useStyles$W();
|
|
3113
3114
|
const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Bar/${verticalLocation}/${horizontalLocation}/${displayName ?? id}`), [displayName, id]);
|
|
3114
3115
|
const teachingMoment = useTeachingMoment(props.teachingMoment === false);
|
|
3115
3116
|
const title = typeof props.teachingMoment === "object" ? props.teachingMoment.title : (displayName ?? id);
|
|
@@ -3119,7 +3120,7 @@ const ToolbarItem = (props) => {
|
|
|
3119
3120
|
// TODO: Handle overflow, possibly via https://react.fluentui.dev/?path=/docs/components-overflow--docs with priority.
|
|
3120
3121
|
// This component just renders a toolbar with left aligned toolbar items on the left and right aligned toolbar items on the right.
|
|
3121
3122
|
const Toolbar = ({ location, components }) => {
|
|
3122
|
-
const classes = useStyles$
|
|
3123
|
+
const classes = useStyles$W();
|
|
3123
3124
|
const leftComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "left"), [components]);
|
|
3124
3125
|
const rightComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "right"), [components]);
|
|
3125
3126
|
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))) })] })) }));
|
|
@@ -3129,7 +3130,7 @@ const SidePaneTab = (props) => {
|
|
|
3129
3130
|
const { location, id, isSelected, isFirst, isLast, dockOptions,
|
|
3130
3131
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3131
3132
|
icon: Icon, title, } = props;
|
|
3132
|
-
const classes = useStyles$
|
|
3133
|
+
const classes = useStyles$W();
|
|
3133
3134
|
const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Pane/${location}/${title ?? id}`), [title, id]);
|
|
3134
3135
|
const teachingMoment = useTeachingMoment(props.teachingMoment === false);
|
|
3135
3136
|
const tabClass = mergeClasses(classes.tab, isSelected ? classes.selectedTab : classes.unselectedTab, isFirst ? classes.firstTab : undefined, isLast ? classes.lastTab : undefined);
|
|
@@ -3141,7 +3142,7 @@ const SidePaneTab = (props) => {
|
|
|
3141
3142
|
// In "compact" mode, the tab list is integrated into the pane itself.
|
|
3142
3143
|
// In "full" mode, the returned tab list is later injected into the toolbar.
|
|
3143
3144
|
function usePane(location, defaultWidth, minWidth, sidePanes, onSelectSidePane, dockOperations, toolbarMode, topBarItems, bottomBarItems, initialCollapsed) {
|
|
3144
|
-
const classes = useStyles$
|
|
3145
|
+
const classes = useStyles$W();
|
|
3145
3146
|
const [topSelectedTab, setTopSelectedTab] = useState();
|
|
3146
3147
|
const [bottomSelectedTab, setBottomSelectedTab] = useState();
|
|
3147
3148
|
const [collapsed, setCollapsed] = useState(initialCollapsed);
|
|
@@ -3370,7 +3371,7 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
|
|
|
3370
3371
|
expand: () => onCollapseChanged.notifyObservers({ location: "right", collapsed: false }),
|
|
3371
3372
|
};
|
|
3372
3373
|
const rootComponent = () => {
|
|
3373
|
-
const classes = useStyles$
|
|
3374
|
+
const classes = useStyles$W();
|
|
3374
3375
|
const [sidePaneDockOverrides, setSidePaneDockOverrides] = useSetting(SidePaneDockOverridesSettingDescriptor);
|
|
3375
3376
|
// This function returns a promise that resolves after the dock change takes effect so that
|
|
3376
3377
|
// we can then select the re-docked pane.
|
|
@@ -3757,13 +3758,13 @@ function useImpulse() {
|
|
|
3757
3758
|
return [value, pulse];
|
|
3758
3759
|
}
|
|
3759
3760
|
|
|
3760
|
-
const useStyles$
|
|
3761
|
+
const useStyles$V = makeStyles({
|
|
3761
3762
|
placeholderDiv: {
|
|
3762
3763
|
padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
|
|
3763
3764
|
},
|
|
3764
3765
|
});
|
|
3765
3766
|
const PropertiesPane = (props) => {
|
|
3766
|
-
const classes = useStyles$
|
|
3767
|
+
const classes = useStyles$V();
|
|
3767
3768
|
const entity = props.context;
|
|
3768
3769
|
return entity != null ? (jsx(ExtensibleAccordion, { ...props })) : (jsx("div", { className: classes.placeholderDiv, children: jsx(Body1Strong, { italic: true, children: "No entity selected." }) }));
|
|
3769
3770
|
};
|
|
@@ -4203,7 +4204,7 @@ function CoerceEntityArray(entities, sort) {
|
|
|
4203
4204
|
}
|
|
4204
4205
|
return entities;
|
|
4205
4206
|
}
|
|
4206
|
-
const useStyles$
|
|
4207
|
+
const useStyles$U = makeStyles({
|
|
4207
4208
|
rootDiv: {
|
|
4208
4209
|
flex: 1,
|
|
4209
4210
|
overflow: "hidden",
|
|
@@ -4312,14 +4313,14 @@ function MakeInlineCommandElement(command, isPlaceholder) {
|
|
|
4312
4313
|
}
|
|
4313
4314
|
const SceneTreeItem = (props) => {
|
|
4314
4315
|
const { isSelected, select } = props;
|
|
4315
|
-
const classes = useStyles$
|
|
4316
|
+
const classes = useStyles$U();
|
|
4316
4317
|
const [compactMode] = useSetting(CompactModeSettingDescriptor);
|
|
4317
4318
|
const treeItemLayoutClass = mergeClasses(classes.sceneTreeItemLayout, compactMode ? classes.treeItemLayoutCompact : undefined);
|
|
4318
4319
|
return (jsx(FlatTreeItem, { className: classes.treeItem, value: "scene", itemType: "leaf", parentValue: undefined, "aria-level": 1, "aria-setsize": 1, "aria-posinset": 1, onClick: select, children: jsx(TreeItemLayout, { iconBefore: jsx(GlobeRegular, {}), className: treeItemLayoutClass, style: isSelected ? { backgroundColor: tokens.colorNeutralBackground1Selected } : undefined, children: jsx(Body1Strong, { wrap: false, truncate: true, children: "Scene" }) }) }, "scene"));
|
|
4319
4320
|
};
|
|
4320
4321
|
const SectionTreeItem = (props) => {
|
|
4321
4322
|
const { section, isFiltering, commandProviders, expandAll, collapseAll, isDropTarget, ...dropProps } = props;
|
|
4322
|
-
const classes = useStyles$
|
|
4323
|
+
const classes = useStyles$U();
|
|
4323
4324
|
const [compactMode] = useSetting(CompactModeSettingDescriptor);
|
|
4324
4325
|
// Get the commands that apply to this section.
|
|
4325
4326
|
const commands = useResource(useCallback(() => {
|
|
@@ -4336,7 +4337,7 @@ const SectionTreeItem = (props) => {
|
|
|
4336
4337
|
};
|
|
4337
4338
|
const EntityTreeItem = (props) => {
|
|
4338
4339
|
const { entityItem, isSelected, select, isFiltering, commandProviders, expandAll, collapseAll, isDragging, isDropTarget, ...dragProps } = props;
|
|
4339
|
-
const classes = useStyles$
|
|
4340
|
+
const classes = useStyles$U();
|
|
4340
4341
|
const [compactMode] = useSetting(CompactModeSettingDescriptor);
|
|
4341
4342
|
const hasChildren = !!entityItem.children?.length;
|
|
4342
4343
|
const displayInfo = useResource(useCallback(() => {
|
|
@@ -4452,7 +4453,7 @@ const EntityTreeItem = (props) => {
|
|
|
4452
4453
|
}, children: jsx(Tooltip$1, { content: name, relationship: "description", children: jsx(Body1, { wrap: false, truncate: true, children: name }) }) }) }, GetEntityId$1(entityItem.entity)) }), jsx(MenuPopover, { hidden: !hasChildren && contextMenuCommands.length === 0, children: jsxs(MenuList, { children: [hasChildren && (jsxs(Fragment, { children: [jsx(MenuItem, { icon: jsx(ArrowExpandAllRegular, {}), onClick: expandAll, children: jsx(Body1, { children: "Expand All" }) }), jsx(MenuItem, { icon: jsx(ArrowCollapseAllRegular, {}), onClick: collapseAll, children: jsx(Body1, { children: "Collapse All" }) })] })), hasChildren && contextMenuCommands.length > 0 && jsx(MenuDivider, {}), contextMenuItems] }) })] }));
|
|
4453
4454
|
};
|
|
4454
4455
|
const SceneExplorer = (props) => {
|
|
4455
|
-
const classes = useStyles$
|
|
4456
|
+
const classes = useStyles$U();
|
|
4456
4457
|
const { sections, entityCommandProviders, sectionCommandProviders, scene, selectedEntity = null } = props;
|
|
4457
4458
|
const [openItems, setOpenItems] = useState(new Set());
|
|
4458
4459
|
const [sceneVersion, setSceneVersion] = useState(0);
|
|
@@ -6078,7 +6079,7 @@ class CanvasGraphService {
|
|
|
6078
6079
|
}
|
|
6079
6080
|
}
|
|
6080
6081
|
|
|
6081
|
-
const useStyles$
|
|
6082
|
+
const useStyles$T = makeStyles({
|
|
6082
6083
|
canvas: {
|
|
6083
6084
|
flexGrow: 1,
|
|
6084
6085
|
width: "100%",
|
|
@@ -6087,7 +6088,7 @@ const useStyles$Q = makeStyles({
|
|
|
6087
6088
|
});
|
|
6088
6089
|
const CanvasGraph = (props) => {
|
|
6089
6090
|
const { collector, scene, layoutObservable, returnToPlayheadObservable, onVisibleRangeChangedObservable, initialGraphSize } = props;
|
|
6090
|
-
const classes = useStyles$
|
|
6091
|
+
const classes = useStyles$T();
|
|
6091
6092
|
const canvasRef = useRef(null);
|
|
6092
6093
|
useEffect(() => {
|
|
6093
6094
|
if (!canvasRef.current) {
|
|
@@ -6164,7 +6165,7 @@ function EvaluateExpression(rawValue) {
|
|
|
6164
6165
|
return NaN;
|
|
6165
6166
|
}
|
|
6166
6167
|
}
|
|
6167
|
-
const useStyles$
|
|
6168
|
+
const useStyles$S = makeStyles({
|
|
6168
6169
|
icon: {
|
|
6169
6170
|
"&:hover": {
|
|
6170
6171
|
color: tokens.colorBrandForeground1,
|
|
@@ -6178,7 +6179,7 @@ const useStyles$P = makeStyles({
|
|
|
6178
6179
|
const SpinButton = forwardRef((props, ref) => {
|
|
6179
6180
|
SpinButton.displayName = "SpinButton2";
|
|
6180
6181
|
const inputClasses = useInputStyles$1();
|
|
6181
|
-
const classes = useStyles$
|
|
6182
|
+
const classes = useStyles$S();
|
|
6182
6183
|
const { size } = useContext(ToolContext);
|
|
6183
6184
|
const { min, max } = props;
|
|
6184
6185
|
const baseStep = props.step ?? 1;
|
|
@@ -6445,7 +6446,7 @@ const Dropdown = (props) => {
|
|
|
6445
6446
|
const NumberDropdown = Dropdown;
|
|
6446
6447
|
const StringDropdown = Dropdown;
|
|
6447
6448
|
|
|
6448
|
-
const useStyles$
|
|
6449
|
+
const useStyles$R = makeStyles({
|
|
6449
6450
|
surface: {
|
|
6450
6451
|
maxWidth: "400px",
|
|
6451
6452
|
},
|
|
@@ -6460,7 +6461,7 @@ const useStyles$O = makeStyles({
|
|
|
6460
6461
|
const Popover = forwardRef((props, ref) => {
|
|
6461
6462
|
const { children, open: controlledOpen, onOpenChange, positioning, surfaceClassName } = props;
|
|
6462
6463
|
const [internalOpen, setInternalOpen] = useState(false);
|
|
6463
|
-
const classes = useStyles$
|
|
6464
|
+
const classes = useStyles$R();
|
|
6464
6465
|
const isControlled = controlledOpen !== undefined;
|
|
6465
6466
|
const popoverOpen = isControlled ? controlledOpen : internalOpen;
|
|
6466
6467
|
const handleOpenChange = (_, data) => {
|
|
@@ -6704,7 +6705,7 @@ const InputAlphaField = (props) => {
|
|
|
6704
6705
|
} }));
|
|
6705
6706
|
};
|
|
6706
6707
|
|
|
6707
|
-
const useStyles$
|
|
6708
|
+
const useStyles$Q = makeStyles({
|
|
6708
6709
|
sidebar: {
|
|
6709
6710
|
display: "flex",
|
|
6710
6711
|
flexDirection: "column",
|
|
@@ -6768,7 +6769,7 @@ const useStyles$N = makeStyles({
|
|
|
6768
6769
|
});
|
|
6769
6770
|
const PerformanceSidebar = (props) => {
|
|
6770
6771
|
const { collector, onVisibleRangeChangedObservable } = props;
|
|
6771
|
-
const classes = useStyles$
|
|
6772
|
+
const classes = useStyles$Q();
|
|
6772
6773
|
// Map from id to IPerfMetadata information
|
|
6773
6774
|
const [metadataMap, setMetadataMap] = useState();
|
|
6774
6775
|
// Map from category to all the ids belonging to that category
|
|
@@ -6841,7 +6842,7 @@ const PerformanceSidebar = (props) => {
|
|
|
6841
6842
|
})] }, `category-${category || "version"}`))) }));
|
|
6842
6843
|
};
|
|
6843
6844
|
|
|
6844
|
-
const useStyles$
|
|
6845
|
+
const useStyles$P = makeStyles({
|
|
6845
6846
|
container: {
|
|
6846
6847
|
display: "flex",
|
|
6847
6848
|
flexDirection: "row",
|
|
@@ -6870,7 +6871,7 @@ const useStyles$M = makeStyles({
|
|
|
6870
6871
|
});
|
|
6871
6872
|
const PerformanceViewer = (props) => {
|
|
6872
6873
|
const { scene, layoutObservable, returnToLiveObservable, performanceCollector, initialGraphSize } = props;
|
|
6873
|
-
const classes = useStyles$
|
|
6874
|
+
const classes = useStyles$P();
|
|
6874
6875
|
const [onVisibleRangeChangedObservable] = useState(() => new Observable());
|
|
6875
6876
|
const onReturnToPlayheadClick = () => {
|
|
6876
6877
|
returnToLiveObservable.notifyObservers();
|
|
@@ -7037,14 +7038,14 @@ const TextPropertyLine = (props) => {
|
|
|
7037
7038
|
return (jsx(PropertyLine, { ...props, children: jsx(Body1, { title: title, children: value ?? "" }) }));
|
|
7038
7039
|
};
|
|
7039
7040
|
|
|
7040
|
-
const useStyles$
|
|
7041
|
+
const useStyles$O = makeStyles({
|
|
7041
7042
|
pinnedStatsPane: {
|
|
7042
7043
|
flex: "0 1 auto",
|
|
7043
7044
|
paddingBottom: tokens.spacingHorizontalM,
|
|
7044
7045
|
},
|
|
7045
7046
|
});
|
|
7046
7047
|
const StatsPane = (props) => {
|
|
7047
|
-
const classes = useStyles$
|
|
7048
|
+
const classes = useStyles$O();
|
|
7048
7049
|
const scene = props.context;
|
|
7049
7050
|
const engine = scene.getEngine();
|
|
7050
7051
|
const pollingObservable = usePollingObservable(250);
|
|
@@ -7207,7 +7208,7 @@ const ToolsServiceDefinition = {
|
|
|
7207
7208
|
*/
|
|
7208
7209
|
const ReactContextServiceIdentity = Symbol("ReactContextService");
|
|
7209
7210
|
|
|
7210
|
-
const useStyles$
|
|
7211
|
+
const useStyles$N = makeStyles({
|
|
7211
7212
|
dropdown: {
|
|
7212
7213
|
...UniformWidthStyling,
|
|
7213
7214
|
},
|
|
@@ -7219,7 +7220,7 @@ const useStyles$K = makeStyles({
|
|
|
7219
7220
|
*/
|
|
7220
7221
|
const DropdownPropertyLine = forwardRef((props, ref) => {
|
|
7221
7222
|
DropdownPropertyLine.displayName = "DropdownPropertyLine";
|
|
7222
|
-
const classes = useStyles$
|
|
7223
|
+
const classes = useStyles$N();
|
|
7223
7224
|
return (jsx(PropertyLine, { ...props, ref: ref, children: jsx(Dropdown, { ...props, className: classes.dropdown }) }));
|
|
7224
7225
|
});
|
|
7225
7226
|
/**
|
|
@@ -7377,7 +7378,7 @@ const SyncedSliderInput = (props) => {
|
|
|
7377
7378
|
return (jsxs("div", { className: mergeClasses(classes.container, props.className), children: [infoLabel && jsx(InfoLabel, { ...infoLabel, htmlFor: "syncedSlider" }), jsxs("div", { id: "syncedSlider", className: classes.syncedSlider, children: [hasSlider && (jsx(Slider, { className: getSliderClassName(), value: value, onChange: handleSliderChange, min: props.min, max: props.max, step: props.step, disabled: props.disabled, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), jsx(SpinButton, { ...passthroughProps, className: useCompactSizing ? classes.compactSpinButton : classes.spinButton, inputClassName: useCompactSizing ? classes.compactSpinButtonInput : classes.spinButtonInput, value: value, onChange: handleInputChange, step: props.step, disabled: props.disabled, disableDragButton: true })] })] }));
|
|
7378
7379
|
};
|
|
7379
7380
|
|
|
7380
|
-
const useStyles$
|
|
7381
|
+
const useStyles$M = makeStyles({
|
|
7381
7382
|
uniformWidth: {
|
|
7382
7383
|
...UniformWidthStyling,
|
|
7383
7384
|
},
|
|
@@ -7389,7 +7390,7 @@ const useStyles$J = makeStyles({
|
|
|
7389
7390
|
*/
|
|
7390
7391
|
const SyncedSliderPropertyLine = forwardRef((props, ref) => {
|
|
7391
7392
|
SyncedSliderPropertyLine.displayName = "SyncedSliderPropertyLine";
|
|
7392
|
-
const classes = useStyles$
|
|
7393
|
+
const classes = useStyles$M();
|
|
7393
7394
|
const { label, description, ...sliderProps } = props;
|
|
7394
7395
|
return (jsx(PropertyLine, { ref: ref, ...props, children: jsx(SyncedSliderInput, { ...sliderProps, className: mergeClasses(classes.uniformWidth, props.className) }) }));
|
|
7395
7396
|
});
|
|
@@ -7821,6 +7822,78 @@ const GizmoServiceDefinition = {
|
|
|
7821
7822
|
},
|
|
7822
7823
|
};
|
|
7823
7824
|
|
|
7825
|
+
const OnInspectorAssetNotFoundPromptRequestedObservable = new Observable(undefined, true);
|
|
7826
|
+
let InspectorAssetNotFoundPromptHandlerObserver = null;
|
|
7827
|
+
let MissingAssetPromptQueue = Promise.resolve(undefined);
|
|
7828
|
+
/**
|
|
7829
|
+
* Sets the Inspector-owned prompt handler used by Smart Assets when an asset is missing.
|
|
7830
|
+
* @param handler - The handler installed by the Inspector UI, or null to clear it.
|
|
7831
|
+
*/
|
|
7832
|
+
function SetInspectorAssetNotFoundPromptHandler(handler) {
|
|
7833
|
+
InspectorAssetNotFoundPromptHandlerObserver?.remove();
|
|
7834
|
+
InspectorAssetNotFoundPromptHandlerObserver = null;
|
|
7835
|
+
if (!handler) {
|
|
7836
|
+
OnInspectorAssetNotFoundPromptRequestedObservable.notifyIfTriggered = true;
|
|
7837
|
+
return;
|
|
7838
|
+
}
|
|
7839
|
+
InspectorAssetNotFoundPromptHandlerObserver = OnInspectorAssetNotFoundPromptRequestedObservable.add((request) => {
|
|
7840
|
+
OnInspectorAssetNotFoundPromptRequestedObservable.notifyIfTriggered = false;
|
|
7841
|
+
OnInspectorAssetNotFoundPromptRequestedObservable.cleanLastNotifiedState();
|
|
7842
|
+
void (async () => {
|
|
7843
|
+
try {
|
|
7844
|
+
request.resolve(await handler(request.key, request.expectedUrl));
|
|
7845
|
+
}
|
|
7846
|
+
catch (error) {
|
|
7847
|
+
request.reject(error);
|
|
7848
|
+
}
|
|
7849
|
+
})();
|
|
7850
|
+
});
|
|
7851
|
+
OnInspectorAssetNotFoundPromptRequestedObservable.notifyIfTriggered = false;
|
|
7852
|
+
OnInspectorAssetNotFoundPromptRequestedObservable.cleanLastNotifiedState();
|
|
7853
|
+
}
|
|
7854
|
+
async function RunQueuedMissingAssetPromptAsync(key, expectedUrl) {
|
|
7855
|
+
const previousPrompt = MissingAssetPromptQueue;
|
|
7856
|
+
let releasePrompt = () => { };
|
|
7857
|
+
MissingAssetPromptQueue = new Promise((resolve) => {
|
|
7858
|
+
releasePrompt = resolve;
|
|
7859
|
+
});
|
|
7860
|
+
await previousPrompt;
|
|
7861
|
+
try {
|
|
7862
|
+
return await new Promise((resolve, reject) => {
|
|
7863
|
+
OnInspectorAssetNotFoundPromptRequestedObservable.notifyObservers({ key, expectedUrl, resolve, reject });
|
|
7864
|
+
});
|
|
7865
|
+
}
|
|
7866
|
+
finally {
|
|
7867
|
+
releasePrompt();
|
|
7868
|
+
}
|
|
7869
|
+
}
|
|
7870
|
+
/**
|
|
7871
|
+
* Default handler for missing assets. Delegates to the Inspector UI when it is open.
|
|
7872
|
+
* Pane focus is handled by the prompt host itself once the user picks a file.
|
|
7873
|
+
* @param key - The smart asset key that was not found.
|
|
7874
|
+
* @param expectedUrl - The URL that failed to load.
|
|
7875
|
+
* @returns A promise resolving to a new URL, File, or null to skip.
|
|
7876
|
+
*/
|
|
7877
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
7878
|
+
async function inspectorAssetNotFoundHandler(key, expectedUrl) {
|
|
7879
|
+
return await RunQueuedMissingAssetPromptAsync(key, expectedUrl);
|
|
7880
|
+
}
|
|
7881
|
+
/**
|
|
7882
|
+
* Installs the Inspector `onAssetNotFound` handler while preserving any existing handler for restoration.
|
|
7883
|
+
* @param sam - The SmartAssetManager to install the handler on.
|
|
7884
|
+
* @returns A function that restores the previous handler if the Inspector handler is still installed.
|
|
7885
|
+
*/
|
|
7886
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
7887
|
+
function installInspectorAssetNotFoundHandler(sam) {
|
|
7888
|
+
const previousHandler = sam.onAssetNotFound;
|
|
7889
|
+
sam.onAssetNotFound = inspectorAssetNotFoundHandler;
|
|
7890
|
+
return () => {
|
|
7891
|
+
if (sam.onAssetNotFound === inspectorAssetNotFoundHandler) {
|
|
7892
|
+
sam.onAssetNotFound = previousHandler;
|
|
7893
|
+
}
|
|
7894
|
+
};
|
|
7895
|
+
}
|
|
7896
|
+
|
|
7824
7897
|
const InstalledExtensionsKey = "Extensions/InstalledExtensions";
|
|
7825
7898
|
const ExtensionInstalledKeyPrefix = "Extensions/IsExtensionInstalled";
|
|
7826
7899
|
function GetExtensionInstalledKey(name) {
|
|
@@ -8277,7 +8350,7 @@ function useExtensionManager() {
|
|
|
8277
8350
|
return useContext(ExtensionManagerContext)?.extensionManager;
|
|
8278
8351
|
}
|
|
8279
8352
|
|
|
8280
|
-
const useStyles$
|
|
8353
|
+
const useStyles$L = makeStyles({
|
|
8281
8354
|
themeButton: {
|
|
8282
8355
|
margin: 0,
|
|
8283
8356
|
},
|
|
@@ -8296,7 +8369,7 @@ const ThemeSelectorServiceDefinition = {
|
|
|
8296
8369
|
teachingMoment: false,
|
|
8297
8370
|
order: -300,
|
|
8298
8371
|
component: () => {
|
|
8299
|
-
const classes = useStyles$
|
|
8372
|
+
const classes = useStyles$L();
|
|
8300
8373
|
const { isDarkMode, themeMode, setThemeMode } = useThemeMode();
|
|
8301
8374
|
const onSelectedThemeChange = useCallback((e, data) => {
|
|
8302
8375
|
setThemeMode(data.checkedItems.includes("System") ? "system" : data.checkedItems[0].toLocaleLowerCase());
|
|
@@ -8313,7 +8386,7 @@ const ThemeSelectorServiceDefinition = {
|
|
|
8313
8386
|
},
|
|
8314
8387
|
};
|
|
8315
8388
|
|
|
8316
|
-
const useStyles$
|
|
8389
|
+
const useStyles$K = makeStyles({
|
|
8317
8390
|
app: {
|
|
8318
8391
|
colorScheme: "light dark",
|
|
8319
8392
|
flexGrow: 1,
|
|
@@ -8358,7 +8431,7 @@ function MakeModularTool(options) {
|
|
|
8358
8431
|
// This deferred resolves once the React effect cleanup (which disposes the ServiceContainer) is complete.
|
|
8359
8432
|
const disposeDeferred = new Deferred();
|
|
8360
8433
|
const modularToolRootComponent = () => {
|
|
8361
|
-
const classes = useStyles$
|
|
8434
|
+
const classes = useStyles$K();
|
|
8362
8435
|
const [extensionManagerContext, setExtensionManagerContext] = useState();
|
|
8363
8436
|
const [requiredExtensions, setRequiredExtensions] = useState();
|
|
8364
8437
|
const [requiredExtensionsDeferred, setRequiredExtensionsDeferred] = useState();
|
|
@@ -8445,7 +8518,7 @@ function MakeModularTool(options) {
|
|
|
8445
8518
|
}
|
|
8446
8519
|
// Register the extension list service (for browsing/installing extensions) if extension feeds are provided.
|
|
8447
8520
|
if (extensionFeeds.length > 0) {
|
|
8448
|
-
const { ExtensionListServiceDefinition } = await import('./extensionsListService-
|
|
8521
|
+
const { ExtensionListServiceDefinition } = await import('./extensionsListService-DTrjNf_v.js');
|
|
8449
8522
|
serviceContainer.addService(ExtensionListServiceDefinition);
|
|
8450
8523
|
}
|
|
8451
8524
|
// Register all external services (that make up a unique tool).
|
|
@@ -8519,7 +8592,7 @@ function MakeModularTool(options) {
|
|
|
8519
8592
|
else {
|
|
8520
8593
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
8521
8594
|
const Content = rootComponentService.rootComponent;
|
|
8522
|
-
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, { imperativeRef: setToastHandle, 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, {}) })] }) }) }) }) }));
|
|
8595
|
+
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, { imperativeRef: setToastHandle, children: [jsx(Dialog$1, { 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$1, { 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, {}) })] }) }) }) }) }));
|
|
8523
8596
|
}
|
|
8524
8597
|
};
|
|
8525
8598
|
// Set the container element to be a flex container so that the tool can be displayed properly.
|
|
@@ -8566,14 +8639,14 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
|
|
|
8566
8639
|
description: "Adds a new panel for easy creation of various Babylon assets. This is a WIP extension...expect changes!",
|
|
8567
8640
|
keywords: ["creation", "tools"],
|
|
8568
8641
|
...BabylonWebResources,
|
|
8569
|
-
getExtensionModuleAsync: async () => await import('./quickCreateToolsService-
|
|
8642
|
+
getExtensionModuleAsync: async () => await import('./quickCreateToolsService-8d6rBO-A.js'),
|
|
8570
8643
|
},
|
|
8571
8644
|
{
|
|
8572
8645
|
name: "Reflector",
|
|
8573
8646
|
description: "Connects to the Reflector Bridge for real-time scene synchronization with the Babylon.js Sandbox.",
|
|
8574
8647
|
keywords: ["reflector", "bridge", "sync", "sandbox", "tools"],
|
|
8575
8648
|
...BabylonWebResources,
|
|
8576
|
-
getExtensionModuleAsync: async () => await import('./reflectorService-
|
|
8649
|
+
getExtensionModuleAsync: async () => await import('./reflectorService-B7LcD1Sn.js'),
|
|
8577
8650
|
},
|
|
8578
8651
|
]);
|
|
8579
8652
|
|
|
@@ -9614,7 +9687,7 @@ const ColorSliders = ({ color, onSliderChange }) => (jsxs(Fragment, { children:
|
|
|
9614
9687
|
const Color3PropertyLine = ColorPropertyLine;
|
|
9615
9688
|
const Color4PropertyLine = ColorPropertyLine;
|
|
9616
9689
|
|
|
9617
|
-
const useStyles$
|
|
9690
|
+
const useStyles$J = makeStyles({
|
|
9618
9691
|
uniformWidth: {
|
|
9619
9692
|
...UniformWidthStyling,
|
|
9620
9693
|
},
|
|
@@ -9626,7 +9699,7 @@ const useStyles$G = makeStyles({
|
|
|
9626
9699
|
*/
|
|
9627
9700
|
const TextInputPropertyLine = (props) => {
|
|
9628
9701
|
TextInputPropertyLine.displayName = "TextInputPropertyLine";
|
|
9629
|
-
const classes = useStyles$
|
|
9702
|
+
const classes = useStyles$J();
|
|
9630
9703
|
return (jsx(PropertyLine, { ...props, children: jsx(TextInput, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
|
|
9631
9704
|
};
|
|
9632
9705
|
/**
|
|
@@ -9637,7 +9710,7 @@ const TextInputPropertyLine = (props) => {
|
|
|
9637
9710
|
*/
|
|
9638
9711
|
const NumberInputPropertyLine = (props) => {
|
|
9639
9712
|
NumberInputPropertyLine.displayName = "NumberInputPropertyLine";
|
|
9640
|
-
const classes = useStyles$
|
|
9713
|
+
const classes = useStyles$J();
|
|
9641
9714
|
return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
|
|
9642
9715
|
};
|
|
9643
9716
|
|
|
@@ -9769,7 +9842,7 @@ const LegacyInspectableObjectPropertiesServiceDefinition = {
|
|
|
9769
9842
|
};
|
|
9770
9843
|
|
|
9771
9844
|
const DocUrl = "https://www.npmjs.com/package/@babylonjs/inspector#inspector-cli";
|
|
9772
|
-
const useStyles$
|
|
9845
|
+
const useStyles$I = makeStyles({
|
|
9773
9846
|
tooltipContent: {
|
|
9774
9847
|
display: "flex",
|
|
9775
9848
|
flexDirection: "column",
|
|
@@ -9787,7 +9860,7 @@ const CliConnectionStatusServiceDefinition = {
|
|
|
9787
9860
|
teachingMoment: false,
|
|
9788
9861
|
order: 0 /* DefaultToolbarItemOrder.CliStatus */,
|
|
9789
9862
|
component: () => {
|
|
9790
|
-
const classes = useStyles$
|
|
9863
|
+
const classes = useStyles$I();
|
|
9791
9864
|
const isEnabled = useObservableState(() => cliConnectionStatus.isEnabled, cliConnectionStatus.onConnectionStatusChanged);
|
|
9792
9865
|
const isConnected = useObservableState(() => cliConnectionStatus.isConnected, cliConnectionStatus.onConnectionStatusChanged);
|
|
9793
9866
|
const { showToast } = useToast();
|
|
@@ -9848,7 +9921,7 @@ const BreakTangentIcon = createFluentIcon("BreakTangent", "20", '<g transform="s
|
|
|
9848
9921
|
const UnifyTangentIcon = createFluentIcon("UnifyTangent", "20", '<g transform="scale(0.5)"><path d="M27.94,18.28a1.49,1.49,0,0,0-1.41,1h-5l-1.62-1.63-1.62,1.63h-5a1.5,1.5,0,1,0,0,1h5l1.62,1.62,1.62-1.62h5a1.5,1.5,0,1,0,1.41-2Z"/></g>');
|
|
9849
9922
|
const StepTangentIcon = createFluentIcon("StepTangent", "20", '<g transform="scale(0.5)"><path d="M29,16.71a1.5,1.5,0,1,0-2,1.41v5.67H11v1H28V18.12A1.51,1.51,0,0,0,29,16.71Z"/></g>');
|
|
9850
9923
|
|
|
9851
|
-
const useStyles$
|
|
9924
|
+
const useStyles$H = makeStyles({
|
|
9852
9925
|
coordinatesModeButton: {
|
|
9853
9926
|
margin: `0 0 0 ${tokens.spacingHorizontalXS}`,
|
|
9854
9927
|
},
|
|
@@ -9864,7 +9937,7 @@ const useStyles$E = makeStyles({
|
|
|
9864
9937
|
});
|
|
9865
9938
|
const GizmoToolbar = (props) => {
|
|
9866
9939
|
const { gizmoService, sceneContext } = props;
|
|
9867
|
-
const classes = useStyles$
|
|
9940
|
+
const classes = useStyles$H();
|
|
9868
9941
|
const gizmoMode = useObservableState(() => gizmoService.gizmoMode, gizmoService.onGizmoModeChanged);
|
|
9869
9942
|
const coordinatesMode = useObservableState(() => gizmoService.coordinatesMode, gizmoService.onCoordinatesModeChanged);
|
|
9870
9943
|
const cameraGizmo = useObservableState(() => gizmoService.gizmoCamera, gizmoService.onCameraGizmoChanged);
|
|
@@ -9993,7 +10066,7 @@ const HighlightServiceDefinition = {
|
|
|
9993
10066
|
},
|
|
9994
10067
|
};
|
|
9995
10068
|
|
|
9996
|
-
const useStyles$
|
|
10069
|
+
const useStyles$G = makeStyles({
|
|
9997
10070
|
badge: {
|
|
9998
10071
|
margin: tokens.spacingHorizontalXXS,
|
|
9999
10072
|
fontFamily: "monospace",
|
|
@@ -10010,7 +10083,7 @@ const MiniStatsServiceDefinition = {
|
|
|
10010
10083
|
order: 300 /* DefaultToolbarItemOrder.FrameRate */,
|
|
10011
10084
|
teachingMoment: false,
|
|
10012
10085
|
component: () => {
|
|
10013
|
-
const classes = useStyles$
|
|
10086
|
+
const classes = useStyles$G();
|
|
10014
10087
|
const scene = useObservableState(useCallback(() => sceneContext.currentScene, [sceneContext.currentScene]), sceneContext.currentSceneObservable);
|
|
10015
10088
|
const engine = scene?.getEngine();
|
|
10016
10089
|
const pollingObservable = usePollingObservable(250);
|
|
@@ -10339,7 +10412,7 @@ function useCurveEditor() {
|
|
|
10339
10412
|
return context;
|
|
10340
10413
|
}
|
|
10341
10414
|
|
|
10342
|
-
const useStyles$
|
|
10415
|
+
const useStyles$F = makeStyles({
|
|
10343
10416
|
root: {
|
|
10344
10417
|
display: "flex",
|
|
10345
10418
|
flexDirection: "row",
|
|
@@ -10383,7 +10456,7 @@ const useStyles$C = makeStyles({
|
|
|
10383
10456
|
* @returns The top bar component
|
|
10384
10457
|
*/
|
|
10385
10458
|
const TopBar = () => {
|
|
10386
|
-
const styles = useStyles$
|
|
10459
|
+
const styles = useStyles$F();
|
|
10387
10460
|
const { state, observables } = useCurveEditor();
|
|
10388
10461
|
const [keyFrameValue, setKeyFrameValue] = useState(null);
|
|
10389
10462
|
const [keyValue, setKeyValue] = useState(null);
|
|
@@ -10476,7 +10549,7 @@ const ColorChannelColors = {
|
|
|
10476
10549
|
*/
|
|
10477
10550
|
const DefaultCurveColor = "#ffffff";
|
|
10478
10551
|
|
|
10479
|
-
const useStyles$
|
|
10552
|
+
const useStyles$E = makeStyles({
|
|
10480
10553
|
root: {
|
|
10481
10554
|
display: "flex",
|
|
10482
10555
|
flexDirection: "column",
|
|
@@ -10518,7 +10591,7 @@ const LOOP_MODES$1 = [
|
|
|
10518
10591
|
* @returns The edit animation panel component
|
|
10519
10592
|
*/
|
|
10520
10593
|
const EditAnimationPanel = ({ animation, onClose }) => {
|
|
10521
|
-
const styles = useStyles$
|
|
10594
|
+
const styles = useStyles$E();
|
|
10522
10595
|
const { observables } = useCurveEditor();
|
|
10523
10596
|
const [name, setName] = useState(animation.name);
|
|
10524
10597
|
const [property, setProperty] = useState(animation.targetProperty);
|
|
@@ -10549,7 +10622,7 @@ const EditAnimationPanel = ({ animation, onClose }) => {
|
|
|
10549
10622
|
return (jsxs("div", { className: styles.root, children: [jsxs("div", { className: styles.form, children: [jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Display Name" }), jsx(Input, { value: name, onChange: (_, data) => setName(data.value), placeholder: "Animation name" })] }), jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Property" }), jsx(Input, { value: property, onChange: (_, data) => setProperty(data.value), placeholder: "e.g., position, rotation, scaling" })] }), jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Loop Mode" }), jsx(Dropdown$1, { value: getLoopModeLabel(loopMode), selectedOptions: [loopMode.toString()], onOptionSelect: (_, data) => setLoopMode(Number(data.optionValue)), positioning: "below", inlinePopup: true, children: LOOP_MODES$1.map((mode) => (jsx(Option, { value: mode.value.toString(), children: mode.label }, mode.value))) })] })] }), jsxs("div", { className: styles.buttons, children: [jsx(Button, { appearance: "primary", onClick: saveChanges, label: "Save", disabled: !isValid }), jsx(Button, { appearance: "subtle", onClick: onClose, label: "Cancel" })] })] }));
|
|
10550
10623
|
};
|
|
10551
10624
|
|
|
10552
|
-
const useStyles$
|
|
10625
|
+
const useStyles$D = makeStyles({
|
|
10553
10626
|
root: {
|
|
10554
10627
|
display: "flex",
|
|
10555
10628
|
flexDirection: "column",
|
|
@@ -10615,7 +10688,7 @@ const useStyles$A = makeStyles({
|
|
|
10615
10688
|
* @returns Animation entry component
|
|
10616
10689
|
*/
|
|
10617
10690
|
const AnimationEntry = ({ animation }) => {
|
|
10618
|
-
const styles = useStyles$
|
|
10691
|
+
const styles = useStyles$D();
|
|
10619
10692
|
const { state, actions, observables } = useCurveEditor();
|
|
10620
10693
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
10621
10694
|
const [isHovered, setIsHovered] = useState(false);
|
|
@@ -10694,7 +10767,7 @@ const AnimationEntry = ({ animation }) => {
|
|
|
10694
10767
|
* @returns Animation sub-entry component
|
|
10695
10768
|
*/
|
|
10696
10769
|
const AnimationSubEntry = ({ animation, subName, color }) => {
|
|
10697
|
-
const styles = useStyles$
|
|
10770
|
+
const styles = useStyles$D();
|
|
10698
10771
|
const { actions, observables } = useCurveEditor();
|
|
10699
10772
|
const activeChannel = actions.getActiveChannel(animation);
|
|
10700
10773
|
const isThisChannelActive = activeChannel === color;
|
|
@@ -10717,7 +10790,7 @@ const AnimationSubEntry = ({ animation, subName, color }) => {
|
|
|
10717
10790
|
* @returns Animation list component
|
|
10718
10791
|
*/
|
|
10719
10792
|
const AnimationList = () => {
|
|
10720
|
-
const styles = useStyles$
|
|
10793
|
+
const styles = useStyles$D();
|
|
10721
10794
|
const { state, observables } = useCurveEditor();
|
|
10722
10795
|
// Re-render when animations are loaded or changed (e.g. animation deleted)
|
|
10723
10796
|
// useCallback stabilizes the accessor to prevent infinite re-render loops
|
|
@@ -10730,7 +10803,7 @@ const AnimationList = () => {
|
|
|
10730
10803
|
}) }));
|
|
10731
10804
|
};
|
|
10732
10805
|
|
|
10733
|
-
const useStyles$
|
|
10806
|
+
const useStyles$C = makeStyles({
|
|
10734
10807
|
root: {
|
|
10735
10808
|
display: "flex",
|
|
10736
10809
|
flexDirection: "column",
|
|
@@ -10779,7 +10852,7 @@ const LoopModeOptions = LOOP_MODES.map((lm) => ({ label: lm, value: lm }));
|
|
|
10779
10852
|
* @returns The add animation panel component
|
|
10780
10853
|
*/
|
|
10781
10854
|
const AddAnimationPanel = ({ onClose }) => {
|
|
10782
|
-
const styles = useStyles$
|
|
10855
|
+
const styles = useStyles$C();
|
|
10783
10856
|
const { state, actions, observables } = useCurveEditor();
|
|
10784
10857
|
const [name, setName] = useState("");
|
|
10785
10858
|
const [mode, setMode] = useState("List");
|
|
@@ -10996,7 +11069,7 @@ const AddAnimationPanel = ({ onClose }) => {
|
|
|
10996
11069
|
return (jsxs("div", { className: styles.root, children: [jsx("div", { className: styles.header, children: jsx("div", { className: styles.title, children: "Add Animation" }) }), jsxs("div", { className: styles.form, children: [jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Display Name" }), jsx(TextInput, { value: name, onChange: setName })] }), jsx("div", { className: styles.row, children: jsx(StringDropdown, { value: mode, onChange: (val) => setMode(val), options: ModeOptions, disabled: properties.length === 0, infoLabel: { label: "Mode" } }) }), jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Property" }), isCustomMode ? (jsx(TextInput, { value: customProperty, onChange: setCustomProperty })) : (jsx(StringDropdown, { value: selectedProperty, onChange: (val) => setSelectedProperty(val), options: properties.map((p) => ({ label: p, value: p })) }))] }), jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Type" }), isCustomMode ? (jsx(StringDropdown, { value: animationType, onChange: (val) => setAnimationType(val), options: AnimationTypeOptions })) : (jsx("div", { className: styles.typeDisplay, children: inferredType }))] }), jsx("div", { className: styles.row, children: jsx(StringDropdown, { value: loopMode, onChange: (val) => setLoopMode(val), options: LoopModeOptions, infoLabel: { label: "Loop Mode" } }) })] }), jsxs("div", { className: styles.buttons, children: [jsx(Button, { appearance: "primary", onClick: createAnimation, disabled: !isValid, label: "Create" }), jsx(Button, { appearance: "subtle", onClick: onClose, label: "Cancel" })] })] }));
|
|
10997
11070
|
};
|
|
10998
11071
|
|
|
10999
|
-
const useStyles$
|
|
11072
|
+
const useStyles$B = makeStyles({
|
|
11000
11073
|
root: {
|
|
11001
11074
|
display: "flex",
|
|
11002
11075
|
flexDirection: "column",
|
|
@@ -11039,7 +11112,7 @@ const useStyles$y = makeStyles({
|
|
|
11039
11112
|
* @returns The load animation panel component
|
|
11040
11113
|
*/
|
|
11041
11114
|
const LoadAnimationPanel = ({ onClose }) => {
|
|
11042
|
-
const styles = useStyles$
|
|
11115
|
+
const styles = useStyles$B();
|
|
11043
11116
|
const { state, actions, observables } = useCurveEditor();
|
|
11044
11117
|
const [snippetIdInput, setSnippetIdInput] = useState("");
|
|
11045
11118
|
const [loadedSnippetId, setLoadedSnippetId] = useState(null);
|
|
@@ -11178,7 +11251,7 @@ class StringTools {
|
|
|
11178
11251
|
}
|
|
11179
11252
|
}
|
|
11180
11253
|
|
|
11181
|
-
const useStyles$
|
|
11254
|
+
const useStyles$A = makeStyles({
|
|
11182
11255
|
root: {
|
|
11183
11256
|
display: "flex",
|
|
11184
11257
|
flexDirection: "column",
|
|
@@ -11223,7 +11296,7 @@ const useStyles$x = makeStyles({
|
|
|
11223
11296
|
* @returns The save animation panel component
|
|
11224
11297
|
*/
|
|
11225
11298
|
const SaveAnimationPanel = ({ onClose: _onClose }) => {
|
|
11226
|
-
const styles = useStyles$
|
|
11299
|
+
const styles = useStyles$A();
|
|
11227
11300
|
const { state } = useCurveEditor();
|
|
11228
11301
|
const [selectedAnimations, setSelectedAnimations] = useState(() => {
|
|
11229
11302
|
if (!state.animations) {
|
|
@@ -11296,7 +11369,7 @@ const SaveAnimationPanel = ({ onClose: _onClose }) => {
|
|
|
11296
11369
|
}) }), jsxs("div", { className: styles.buttons, children: [jsx(Button, { appearance: "primary", onClick: saveToSnippetServer, disabled: selectedAnimations.length === 0 || isSaving, label: isSaving ? "Saving..." : "Save to Snippet Server" }), jsx(Button, { appearance: "secondary", onClick: saveToFile, disabled: selectedAnimations.length === 0, label: "Save to File" })] }), saveError && jsx("div", { className: styles.errorText, children: saveError }), snippetId && jsxs("div", { className: styles.snippetId, children: ["Saved! Snippet ID: ", snippetId] })] }));
|
|
11297
11370
|
};
|
|
11298
11371
|
|
|
11299
|
-
const useStyles$
|
|
11372
|
+
const useStyles$z = makeStyles({
|
|
11300
11373
|
root: {
|
|
11301
11374
|
display: "flex",
|
|
11302
11375
|
flexDirection: "column",
|
|
@@ -11350,7 +11423,7 @@ const useStyles$w = makeStyles({
|
|
|
11350
11423
|
* @returns The sidebar component
|
|
11351
11424
|
*/
|
|
11352
11425
|
const SideBar = () => {
|
|
11353
|
-
const styles = useStyles$
|
|
11426
|
+
const styles = useStyles$z();
|
|
11354
11427
|
const { state, actions, observables } = useCurveEditor();
|
|
11355
11428
|
const [openPopover, setOpenPopover] = useState(null);
|
|
11356
11429
|
const [fps, setFps] = useState(60);
|
|
@@ -12338,7 +12411,7 @@ const KeyPointComponent = (props) => {
|
|
|
12338
12411
|
} })] }))] }))] }));
|
|
12339
12412
|
};
|
|
12340
12413
|
|
|
12341
|
-
const useStyles$
|
|
12414
|
+
const useStyles$y = makeStyles({
|
|
12342
12415
|
root: {
|
|
12343
12416
|
position: "absolute",
|
|
12344
12417
|
top: 0,
|
|
@@ -12522,7 +12595,7 @@ function ExtractValuesFromKeys(keys, curves) {
|
|
|
12522
12595
|
* @returns The graph component
|
|
12523
12596
|
*/
|
|
12524
12597
|
const Graph = ({ width, height }) => {
|
|
12525
|
-
const styles = useStyles$
|
|
12598
|
+
const styles = useStyles$y();
|
|
12526
12599
|
const { state, actions, observables } = useCurveEditor();
|
|
12527
12600
|
const svgRef = useRef(null);
|
|
12528
12601
|
const [scale, setScale] = useState(1);
|
|
@@ -12885,7 +12958,7 @@ const Graph = ({ width, height }) => {
|
|
|
12885
12958
|
}), renderValueAxis()] })] }));
|
|
12886
12959
|
};
|
|
12887
12960
|
|
|
12888
|
-
const useStyles$
|
|
12961
|
+
const useStyles$x = makeStyles({
|
|
12889
12962
|
root: {
|
|
12890
12963
|
position: "absolute",
|
|
12891
12964
|
top: 0,
|
|
@@ -12928,7 +13001,7 @@ const useStyles$u = makeStyles({
|
|
|
12928
13001
|
* @returns The playhead component
|
|
12929
13002
|
*/
|
|
12930
13003
|
const PlayHead = ({ width, height: _height }) => {
|
|
12931
|
-
const styles = useStyles$
|
|
13004
|
+
const styles = useStyles$x();
|
|
12932
13005
|
const { state, actions, observables } = useCurveEditor();
|
|
12933
13006
|
const [isDragging, setIsDragging] = useState(false);
|
|
12934
13007
|
// Use refs for all mutable values to avoid render cycles
|
|
@@ -13079,7 +13152,7 @@ const PlayHead = ({ width, height: _height }) => {
|
|
|
13079
13152
|
return (jsxs("div", { className: styles.root, children: [jsx("div", { ref: lineRef, className: styles.line, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp }), jsx("div", { ref: handleRef, className: styles.handle, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp })] }));
|
|
13080
13153
|
};
|
|
13081
13154
|
|
|
13082
|
-
const useStyles$
|
|
13155
|
+
const useStyles$w = makeStyles({
|
|
13083
13156
|
root: {
|
|
13084
13157
|
display: "flex",
|
|
13085
13158
|
flexDirection: "row",
|
|
@@ -13111,7 +13184,7 @@ const useStyles$t = makeStyles({
|
|
|
13111
13184
|
* @returns The frame bar component
|
|
13112
13185
|
*/
|
|
13113
13186
|
const FrameBar = ({ width }) => {
|
|
13114
|
-
const styles = useStyles$
|
|
13187
|
+
const styles = useStyles$w();
|
|
13115
13188
|
const { state, observables } = useCurveEditor();
|
|
13116
13189
|
const containerRef = useRef(null);
|
|
13117
13190
|
const [scale, setScale] = useState(1);
|
|
@@ -13169,7 +13242,7 @@ const FrameBar = ({ width }) => {
|
|
|
13169
13242
|
return (jsx("div", { className: styles.root, ref: containerRef, children: renderTicks() }));
|
|
13170
13243
|
};
|
|
13171
13244
|
|
|
13172
|
-
const useStyles$
|
|
13245
|
+
const useStyles$v = makeStyles({
|
|
13173
13246
|
root: {
|
|
13174
13247
|
display: "flex",
|
|
13175
13248
|
flexDirection: "column",
|
|
@@ -13210,7 +13283,7 @@ const OFFSET_X = 10;
|
|
|
13210
13283
|
* @returns The range frame bar component
|
|
13211
13284
|
*/
|
|
13212
13285
|
const RangeFrameBar = ({ width }) => {
|
|
13213
|
-
const styles = useStyles$
|
|
13286
|
+
const styles = useStyles$v();
|
|
13214
13287
|
const { state, actions, observables } = useCurveEditor();
|
|
13215
13288
|
const svgRef = useRef(null);
|
|
13216
13289
|
const [viewWidth, setViewWidth] = useState(width);
|
|
@@ -13321,7 +13394,7 @@ const RangeFrameBar = ({ width }) => {
|
|
|
13321
13394
|
}), renderKeyframes, renderActiveFrame] }) }));
|
|
13322
13395
|
};
|
|
13323
13396
|
|
|
13324
|
-
const useStyles$
|
|
13397
|
+
const useStyles$u = makeStyles({
|
|
13325
13398
|
root: {
|
|
13326
13399
|
display: "flex",
|
|
13327
13400
|
flexDirection: "column",
|
|
@@ -13353,7 +13426,7 @@ const useStyles$r = makeStyles({
|
|
|
13353
13426
|
* @returns The canvas component
|
|
13354
13427
|
*/
|
|
13355
13428
|
const Canvas = () => {
|
|
13356
|
-
const styles = useStyles$
|
|
13429
|
+
const styles = useStyles$u();
|
|
13357
13430
|
const { observables } = useCurveEditor();
|
|
13358
13431
|
const containerRef = useRef(null);
|
|
13359
13432
|
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
|
|
@@ -13383,7 +13456,7 @@ const Canvas = () => {
|
|
|
13383
13456
|
return (jsxs("div", { className: styles.root, ref: containerRef, children: [jsx("div", { className: styles.frameBar, children: jsx(FrameBar, { width: dimensions.width }) }), jsxs("div", { className: styles.canvasArea, children: [jsx(Graph, { width: dimensions.width, height: dimensions.height - 70 }), jsx(PlayHead, { width: dimensions.width, height: dimensions.height - 70 })] }), jsx("div", { className: styles.rangeFrameBar, children: jsx(RangeFrameBar, { width: dimensions.width }) })] }));
|
|
13384
13457
|
};
|
|
13385
13458
|
|
|
13386
|
-
const useStyles$
|
|
13459
|
+
const useStyles$t = makeStyles({
|
|
13387
13460
|
root: {
|
|
13388
13461
|
flex: 1,
|
|
13389
13462
|
height: "25px",
|
|
@@ -13445,7 +13518,7 @@ const useStyles$q = makeStyles({
|
|
|
13445
13518
|
* @returns The range selector component
|
|
13446
13519
|
*/
|
|
13447
13520
|
const RangeSelector = () => {
|
|
13448
|
-
const styles = useStyles$
|
|
13521
|
+
const styles = useStyles$t();
|
|
13449
13522
|
const { state, actions, observables } = useCurveEditor();
|
|
13450
13523
|
const containerRef = useRef(null);
|
|
13451
13524
|
const scrollbarRef = useRef(null);
|
|
@@ -13590,7 +13663,7 @@ function GetKeyAtAnyFrameIndex(animations, frame) {
|
|
|
13590
13663
|
}
|
|
13591
13664
|
return false;
|
|
13592
13665
|
}
|
|
13593
|
-
const useStyles$
|
|
13666
|
+
const useStyles$s = makeStyles({
|
|
13594
13667
|
root: {
|
|
13595
13668
|
display: "flex",
|
|
13596
13669
|
flexDirection: "row",
|
|
@@ -13647,7 +13720,7 @@ MediaControls.displayName = "MediaControls";
|
|
|
13647
13720
|
* @returns The BottomBar component.
|
|
13648
13721
|
*/
|
|
13649
13722
|
const BottomBar = () => {
|
|
13650
|
-
const styles = useStyles$
|
|
13723
|
+
const styles = useStyles$s();
|
|
13651
13724
|
const { state, actions, observables } = useCurveEditor();
|
|
13652
13725
|
// Track display frame separately for smooth updates during playback
|
|
13653
13726
|
const [displayFrame, setDisplayFrame] = useState(state.activeFrame);
|
|
@@ -13762,7 +13835,7 @@ const BottomBar = () => {
|
|
|
13762
13835
|
return (jsxs("div", { className: styles.root, children: [jsx("div", { className: styles.mediaControls, children: jsx(MediaControls, { hasActiveAnimations: hasActiveAnimations, isPlaying: state.isPlaying, forwardAnimation: state.forwardAnimation, onPlayForward: handlePlayForward, onPlayBackward: handlePlayBackward, onStop: handleStop, onPrevKey: handlePrevKey, onNextKey: handleNextKey, onFirstFrame: handleFirstFrame, onLastFrame: handleLastFrame }) }), jsxs("div", { className: styles.frameDisplay, children: [jsx("div", { className: styles.frameLabel, children: "Frame:" }), jsx(SpinButton, { className: styles.spinButton, value: displayFrame, onChange: handleFrameChange, min: state.fromKey, max: state.toKey, disabled: !hasActiveAnimations })] }), jsx(RangeSelector, {}), jsxs("div", { className: styles.clipLengthSection, children: [jsx("div", { className: styles.frameLabel, children: "Clip Length:" }), jsx(SpinButton, { className: styles.spinButton, value: clipLength, onChange: handleClipLengthChange, min: 1, disabled: !hasActiveAnimations })] })] }));
|
|
13763
13836
|
};
|
|
13764
13837
|
|
|
13765
|
-
const useStyles$
|
|
13838
|
+
const useStyles$r = makeStyles({
|
|
13766
13839
|
root: {
|
|
13767
13840
|
display: "flex",
|
|
13768
13841
|
flexDirection: "column",
|
|
@@ -13811,7 +13884,7 @@ const useStyles$o = makeStyles({
|
|
|
13811
13884
|
* @returns The curve editor content
|
|
13812
13885
|
*/
|
|
13813
13886
|
const CurveEditorContent = () => {
|
|
13814
|
-
const styles = useStyles$
|
|
13887
|
+
const styles = useStyles$r();
|
|
13815
13888
|
const { state, actions, observables } = useCurveEditor();
|
|
13816
13889
|
const rootRef = useRef(null);
|
|
13817
13890
|
const prepareRef = useRef(() => actions.prepare());
|
|
@@ -14653,7 +14726,7 @@ function useObservableArray(target, getItems, addFn, removeFn, changeFn) {
|
|
|
14653
14726
|
}, [getItems]), useInterceptObservable("function", target, addFn), useInterceptObservable("function", target, removeFn), changeFn ? useInterceptObservable("function", target, changeFn) : undefined);
|
|
14654
14727
|
}
|
|
14655
14728
|
|
|
14656
|
-
const useStyles$
|
|
14729
|
+
const useStyles$q = makeStyles({
|
|
14657
14730
|
lightsListDiv: {
|
|
14658
14731
|
display: "flex",
|
|
14659
14732
|
flexDirection: "column",
|
|
@@ -14663,7 +14736,7 @@ const ClusteredLightContainerSetupProperties = ({ context: container }) => {
|
|
|
14663
14736
|
return (jsxs(Fragment, { children: [jsx(BooleanBadgePropertyLine, { label: "Is Supported", value: container.isSupported }), jsx(BoundProperty, { label: "Horizontal Tiles", component: NumberInputPropertyLine, target: container, propertyKey: "horizontalTiles", step: 1, min: 1, forceInt: true }), jsx(BoundProperty, { label: "Vertical Tiles", component: NumberInputPropertyLine, target: container, propertyKey: "verticalTiles", step: 1, min: 1, forceInt: true }), jsx(BoundProperty, { label: "Depth Slices", component: NumberInputPropertyLine, target: container, propertyKey: "depthSlices", step: 1, min: 1, forceInt: true }), jsx(BoundProperty, { label: "Max Range", component: NumberInputPropertyLine, target: container, propertyKey: "maxRange", min: 1 })] }));
|
|
14664
14737
|
};
|
|
14665
14738
|
const ClusteredLightContainerLightsProperties = ({ container, selectionService, }) => {
|
|
14666
|
-
const classes = useStyles$
|
|
14739
|
+
const classes = useStyles$q();
|
|
14667
14740
|
const lights = useObservableArray(container, useCallback(() => container.lights, [container]), "addLight", "removeLight");
|
|
14668
14741
|
return (jsx(PropertyLine, { label: "Lights", expandedContent: jsx("div", { className: classes.lightsListDiv, children: lights.map((light) => (jsx(LinkToEntityPropertyLine, { label: light.getClassName(), entity: light, selectionService: selectionService }, light.uniqueId))) }), children: jsx(Badge, { appearance: "filled", children: lights.length }) }));
|
|
14669
14742
|
};
|
|
@@ -14713,7 +14786,7 @@ const HemisphericLightSetupProperties = ({ context: hemisphericLight }) => {
|
|
|
14713
14786
|
return (jsxs(Fragment, { children: [jsx(BoundProperty, { label: "Direction", component: Vector3PropertyLine, target: hemisphericLight, propertyKey: "direction" }), jsx(BoundProperty, { label: "Diffuse", component: Color3PropertyLine, target: hemisphericLight, propertyKey: "diffuse" }), jsx(BoundProperty, { label: "Ground", component: Color3PropertyLine, target: hemisphericLight, propertyKey: "groundColor" }), jsx(BoundProperty, { label: "Intensity", component: NumberInputPropertyLine, target: hemisphericLight, propertyKey: "intensity" })] }));
|
|
14714
14787
|
};
|
|
14715
14788
|
|
|
14716
|
-
const useStyles$
|
|
14789
|
+
const useStyles$p = makeStyles({
|
|
14717
14790
|
root: {
|
|
14718
14791
|
display: "grid",
|
|
14719
14792
|
gridTemplateRows: "repeat(1fr)",
|
|
@@ -14743,7 +14816,7 @@ const useStyles$m = makeStyles({
|
|
|
14743
14816
|
const ComboBox = forwardRef((props, ref) => {
|
|
14744
14817
|
ComboBox.displayName = "ComboBox";
|
|
14745
14818
|
const comboId = useId();
|
|
14746
|
-
const styles = useStyles$
|
|
14819
|
+
const styles = useStyles$p();
|
|
14747
14820
|
const { size } = useContext(ToolContext);
|
|
14748
14821
|
// Find the label for the current value
|
|
14749
14822
|
const getLabel = (value) => props.options.find((opt) => opt.value === value)?.label ?? "";
|
|
@@ -14766,7 +14839,7 @@ const ComboBox = forwardRef((props, ref) => {
|
|
|
14766
14839
|
return (jsxs("div", { className: styles.root, children: [jsx("label", { id: comboId, children: props.label }), jsx(Combobox, { ref: ref, defaultOpen: props.defaultOpen, size: size, root: { className: styles.comboBox }, input: { className: styles.input }, listbox: { className: styles.listbox }, onOptionSelect: onOptionSelect, "aria-labelledby": comboId, placeholder: "Search..", onChange: (ev) => setQuery(ev.target.value), value: query, children: children })] }));
|
|
14767
14840
|
});
|
|
14768
14841
|
|
|
14769
|
-
const useStyles$
|
|
14842
|
+
const useStyles$o = makeStyles({
|
|
14770
14843
|
linkDiv: {
|
|
14771
14844
|
display: "flex",
|
|
14772
14845
|
flexDirection: "row",
|
|
@@ -14791,7 +14864,7 @@ const useStyles$l = makeStyles({
|
|
|
14791
14864
|
function EntitySelector(props) {
|
|
14792
14865
|
const { value, onLink, getEntities, getName, filter, defaultValue } = props;
|
|
14793
14866
|
const onChange = props.onChange;
|
|
14794
|
-
const classes = useStyles$
|
|
14867
|
+
const classes = useStyles$o();
|
|
14795
14868
|
const comboBoxRef = useRef(null);
|
|
14796
14869
|
// Build options with uniqueId as key
|
|
14797
14870
|
const options = useMemo(() => {
|
|
@@ -14945,7 +15018,7 @@ const TextureUpload = (props) => {
|
|
|
14945
15018
|
return jsx(UploadButton, { onUpload: handleUpload, accept: accept, title: "Upload Texture", label: label });
|
|
14946
15019
|
};
|
|
14947
15020
|
|
|
14948
|
-
const useStyles$
|
|
15021
|
+
const useStyles$n = makeStyles({
|
|
14949
15022
|
container: {
|
|
14950
15023
|
display: "flex",
|
|
14951
15024
|
flexDirection: "row",
|
|
@@ -14962,7 +15035,7 @@ const useStyles$k = makeStyles({
|
|
|
14962
15035
|
const TextureSelector = (props) => {
|
|
14963
15036
|
TextureSelector.displayName = "TextureSelector";
|
|
14964
15037
|
const { scene, cubeOnly, value, onChange, onLink, defaultValue } = props;
|
|
14965
|
-
const classes = useStyles$
|
|
15038
|
+
const classes = useStyles$n();
|
|
14966
15039
|
const getTextures = useCallback(() => scene.textures, [scene.textures]);
|
|
14967
15040
|
const getName = useCallback((texture) => texture.displayName || texture.name || `${texture.getClassName() || "Unnamed Texture"} (${texture.uniqueId})`, []);
|
|
14968
15041
|
const filter = useCallback((texture) => !cubeOnly || texture.isCube, [cubeOnly]);
|
|
@@ -15330,6 +15403,22 @@ const MaterialTransparencyProperties = (props) => {
|
|
|
15330
15403
|
const useAlphaTest = useProperty(material, "transparencyMode") === Material.MATERIAL_ALPHATEST;
|
|
15331
15404
|
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Alpha", target: material, propertyKey: "alpha", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Transparency Mode", docLink: "https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/transparent_rendering/#the-transparencymode-property", target: material, propertyKey: "transparencyMode", options: TransparencyModeOptions, nullable: true, defaultValue: Material.MATERIAL_OPAQUE }), jsx(Collapse, { visible: hasAlphaCutOff && useAlphaTest, children: jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "alphaCutOff", target: material, propertyKey: "alphaCutOff", min: 0, max: 1, step: 0.01 }) }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Alpha Mode", docLink: "https://doc.babylonjs.com/features/featuresDeepDive/materials/using/blendModes/#available-blend-modes", target: material, propertyKey: "alphaMode", options: AlphaModeOptions }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Separate Culling Pass", target: material, propertyKey: "separateCullingPass" })] }));
|
|
15332
15405
|
};
|
|
15406
|
+
const TextureRepetitionModeOptions = [
|
|
15407
|
+
{ label: "None", value: Constants.TEXTURE_REPETITION_NONE },
|
|
15408
|
+
{ label: "Noise Blend (3 fetches)", value: Constants.TEXTURE_REPETITION_NOISE_BLEND },
|
|
15409
|
+
{ label: "Hex Tiling (3 fetches)", value: Constants.TEXTURE_REPETITION_HEX_TILING },
|
|
15410
|
+
{ label: "Tile Randomization (4 fetches)", value: Constants.TEXTURE_REPETITION_TILE_RANDOMIZATION },
|
|
15411
|
+
{ label: "Voronoi Bombing (9 fetches)", value: Constants.TEXTURE_REPETITION_VORONOI_BOMBING },
|
|
15412
|
+
];
|
|
15413
|
+
const MaterialTextureRepetitionProperties = (props) => {
|
|
15414
|
+
const { material } = props;
|
|
15415
|
+
const isHexTiling = useProperty(material, "textureRepetitionMode") === Constants.TEXTURE_REPETITION_HEX_TILING;
|
|
15416
|
+
const hexParams = material.textureRepetitionHexTilingParams;
|
|
15417
|
+
const setHexParam = useCallback((index, value) => {
|
|
15418
|
+
hexParams[index] = value;
|
|
15419
|
+
}, [hexParams]);
|
|
15420
|
+
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Mode", description: "Texture repetition breaking mode. Higher fetch counts produce better quality at higher cost.", target: material, propertyKey: "textureRepetitionMode", options: TextureRepetitionModeOptions }), jsxs(Collapse, { visible: isHexTiling, children: [jsx(SyncedSliderPropertyLine, { label: "Rotation Strength", description: "How much each hex tile is rotated (0 = no rotation, 1 = full rotation)", value: hexParams[0], onChange: (v) => setHexParam(0, v), min: 0, max: 1, step: 0.01 }), jsx(SyncedSliderPropertyLine, { label: "Fall-off Contrast", description: "How much luminance affects blending weight at tile borders", value: hexParams[1], onChange: (v) => setHexParam(1, v), min: 0, max: 1, step: 0.01 }), jsx(SyncedSliderPropertyLine, { label: "Exponent", description: "Controls the sharpness of weight falloff between tiles", value: hexParams[2], onChange: (v) => setHexParam(2, v), min: 1, max: 20, step: 0.5 }), jsx(SyncedSliderPropertyLine, { label: "Contrast", description: "Boost blending contrast (0.5 = neutral, higher = more contrast)", value: hexParams[3], onChange: (v) => setHexParam(3, v), min: 0.01, max: 0.99, step: 0.01 })] })] }));
|
|
15421
|
+
};
|
|
15333
15422
|
const MaterialStencilProperties = (props) => {
|
|
15334
15423
|
const { material } = props;
|
|
15335
15424
|
const stencilEnabled = useProperty(material.stencil, "enabled");
|
|
@@ -15551,7 +15640,7 @@ async function EditNodeMaterial(material) {
|
|
|
15551
15640
|
await material.edit({ nodeEditorConfig: { backgroundColor: material.getScene().clearColor } });
|
|
15552
15641
|
}
|
|
15553
15642
|
|
|
15554
|
-
const useStyles$
|
|
15643
|
+
const useStyles$m = makeStyles({
|
|
15555
15644
|
subsection: {
|
|
15556
15645
|
marginTop: tokens.spacingVerticalM,
|
|
15557
15646
|
},
|
|
@@ -15625,7 +15714,7 @@ const GradientBlockPropertyLine = (props) => {
|
|
|
15625
15714
|
};
|
|
15626
15715
|
const NodeMaterialInputProperties = (props) => {
|
|
15627
15716
|
const { material } = props;
|
|
15628
|
-
const classes = useStyles$
|
|
15717
|
+
const classes = useStyles$m();
|
|
15629
15718
|
const inputBlocks = useObservableState(useCallback(() => {
|
|
15630
15719
|
const inspectorVisibleInputBlocks = material
|
|
15631
15720
|
.getInputBlocks()
|
|
@@ -15877,7 +15966,7 @@ const OpenPBRMaterialBaseProperties = (props) => {
|
|
|
15877
15966
|
*/
|
|
15878
15967
|
const OpenPBRMaterialSpecularProperties = (props) => {
|
|
15879
15968
|
const { material } = props;
|
|
15880
|
-
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Specular Weight", target: material, propertyKey: "specularWeight", min: 0, max: 1, step: 0.01, description: "Controls how strong the reflections appear.", docLink: "https://academysoftwarefoundation.github.io/OpenPBR/index.html#model/basesubstrate" }), jsx(BoundProperty, { component: TextureSelectorPropertyLine, label: "Specular Weight", target: material, propertyKey: "specularWeightTexture", scene: material.getScene(), defaultValue: null, onLink: (texture) => void 0 }), jsx(BoundProperty, { component: Color3PropertyLine, label: "Specular Color", target: material, propertyKey: "specularColor", isLinearMode: true, description: "Tints the color of reflections.", docLink: "https://academysoftwarefoundation.github.io/OpenPBR/index.html#model/basesubstrate" }), jsx(BoundProperty, { component: TextureSelectorPropertyLine, label: "Specular Color", target: material, propertyKey: "specularColorTexture", scene: material.getScene(), defaultValue: null, onLink: (texture) => void 0 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Specular Roughness", target: material, propertyKey: "specularRoughness", min: 0, max: 1, step: 0.01, description: "Controls how sharp or blurry reflections are.", docLink: "https://academysoftwarefoundation.github.io/OpenPBR/index.html#model/basesubstrate" }), jsx(BoundProperty, { component: TextureSelectorPropertyLine, label: "Specular Roughness", target: material, propertyKey: "specularRoughnessTexture", scene: material.getScene(), defaultValue: null, onLink: (texture) => void 0 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Specular Roughness Anisotropy", target: material, propertyKey: "specularRoughnessAnisotropy", min: 0, max: 1, step: 0.01, description: "Stretches reflections in one direction for brushed or streaked looks. Requires specular_roughness > 0.", docLink: "https://academysoftwarefoundation.github.io/OpenPBR/index.html#model/microfacetmodel" }), jsx(BoundProperty, { component: TextureSelectorPropertyLine, label: "Specular Roughness Anisotropy", target: material, propertyKey: "specularRoughnessAnisotropyTexture", scene: material.getScene(), defaultValue: null, onLink: (texture) => void 0 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Specular IOR", target: material, propertyKey: "specularIor", min: 1, max:
|
|
15969
|
+
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Specular Weight", target: material, propertyKey: "specularWeight", min: 0, max: 1, step: 0.01, description: "Controls how strong the reflections appear.", docLink: "https://academysoftwarefoundation.github.io/OpenPBR/index.html#model/basesubstrate" }), jsx(BoundProperty, { component: TextureSelectorPropertyLine, label: "Specular Weight", target: material, propertyKey: "specularWeightTexture", scene: material.getScene(), defaultValue: null, onLink: (texture) => void 0 }), jsx(BoundProperty, { component: Color3PropertyLine, label: "Specular Color", target: material, propertyKey: "specularColor", isLinearMode: true, description: "Tints the color of reflections.", docLink: "https://academysoftwarefoundation.github.io/OpenPBR/index.html#model/basesubstrate" }), jsx(BoundProperty, { component: TextureSelectorPropertyLine, label: "Specular Color", target: material, propertyKey: "specularColorTexture", scene: material.getScene(), defaultValue: null, onLink: (texture) => void 0 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Specular Roughness", target: material, propertyKey: "specularRoughness", min: 0, max: 1, step: 0.01, description: "Controls how sharp or blurry reflections are.", docLink: "https://academysoftwarefoundation.github.io/OpenPBR/index.html#model/basesubstrate" }), jsx(BoundProperty, { component: TextureSelectorPropertyLine, label: "Specular Roughness", target: material, propertyKey: "specularRoughnessTexture", scene: material.getScene(), defaultValue: null, onLink: (texture) => void 0 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Specular Roughness Anisotropy", target: material, propertyKey: "specularRoughnessAnisotropy", min: 0, max: 1, step: 0.01, description: "Stretches reflections in one direction for brushed or streaked looks. Requires specular_roughness > 0.", docLink: "https://academysoftwarefoundation.github.io/OpenPBR/index.html#model/microfacetmodel" }), jsx(BoundProperty, { component: TextureSelectorPropertyLine, label: "Specular Roughness Anisotropy", target: material, propertyKey: "specularRoughnessAnisotropyTexture", scene: material.getScene(), defaultValue: null, onLink: (texture) => void 0 }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Specular IOR", target: material, propertyKey: "specularIor", min: 1, max: 30, step: 0.01, description: "Index of refraction is a physical value controlling the reflective intensity and refraction. The parameter has no effect on metals.", docLink: "https://academysoftwarefoundation.github.io/OpenPBR/index.html#model/basesubstrate" })] }));
|
|
15881
15970
|
};
|
|
15882
15971
|
const OpenPBRMaterialTransmissionProperties = (props) => {
|
|
15883
15972
|
const { material } = props;
|
|
@@ -16007,6 +16096,10 @@ const MaterialPropertiesServiceDefinition = {
|
|
|
16007
16096
|
section: "Stencil",
|
|
16008
16097
|
component: ({ context }) => jsx(MaterialStencilProperties, { material: context }),
|
|
16009
16098
|
},
|
|
16099
|
+
{
|
|
16100
|
+
section: "Texture Repetition",
|
|
16101
|
+
component: ({ context }) => jsx(MaterialTextureRepetitionProperties, { material: context }),
|
|
16102
|
+
},
|
|
16010
16103
|
],
|
|
16011
16104
|
});
|
|
16012
16105
|
const standardMaterialContentRegistration = propertiesService.addSectionContent({
|
|
@@ -16347,7 +16440,7 @@ function SaveMetadata(entity, metadata) {
|
|
|
16347
16440
|
entity.metadata = metadata;
|
|
16348
16441
|
}
|
|
16349
16442
|
}
|
|
16350
|
-
const useStyles$
|
|
16443
|
+
const useStyles$l = makeStyles({
|
|
16351
16444
|
mainDiv: {
|
|
16352
16445
|
display: "flex",
|
|
16353
16446
|
flexDirection: "column",
|
|
@@ -16367,7 +16460,7 @@ const useStyles$i = makeStyles({
|
|
|
16367
16460
|
*/
|
|
16368
16461
|
const MetadataProperties = (props) => {
|
|
16369
16462
|
const { entity } = props;
|
|
16370
|
-
const classes = useStyles$
|
|
16463
|
+
const classes = useStyles$l();
|
|
16371
16464
|
const { size } = useContext(ToolContext);
|
|
16372
16465
|
const metadata = useProperty(entity, "metadata");
|
|
16373
16466
|
const stringifiedMetadata = useMemo(() => StringifyMetadata(metadata, false) ?? "", [metadata]);
|
|
@@ -17302,7 +17395,7 @@ const ParticleSystemEmitterProperties = (props) => {
|
|
|
17302
17395
|
} })) : (jsx(Property, { component: TextPropertyLine, propertyPath: "source", label: "Source", value: "No meshes in scene." })), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use normals for direction", target: particleEmitterType, propertyKey: "useMeshNormalsForDirection" }), !useMeshNormalsForDirection && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction1", target: particleEmitterType, propertyKey: "direction1" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction2", target: particleEmitterType, propertyKey: "direction2" })] }))] })), particleEmitterType instanceof BoxParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction1", target: particleEmitterType, propertyKey: "direction1" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction2", target: particleEmitterType, propertyKey: "direction2" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Min emit box", target: particleEmitterType, propertyKey: "minEmitBox" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Max emit box", target: particleEmitterType, propertyKey: "maxEmitBox" })] })), particleEmitterType instanceof ConeParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Height range", target: particleEmitterType, propertyKey: "heightRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Emit from spawn point only", target: particleEmitterType, propertyKey: "emitFromSpawnPointOnly" }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof SphereParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius", target: particleEmitterType, propertyKey: "radius", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof CylinderParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius", target: particleEmitterType, propertyKey: "radius", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Height", target: particleEmitterType, propertyKey: "height", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof HemisphericParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius", target: particleEmitterType, propertyKey: "radius", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Radius range", target: particleEmitterType, propertyKey: "radiusRange", min: 0, max: 1, step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Direction randomizer", target: particleEmitterType, propertyKey: "directionRandomizer", min: 0, max: 1, step: 0.01 })] })), particleEmitterType instanceof PointParticleEmitter && (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction1", target: particleEmitterType, propertyKey: "direction1" }), jsx(BoundProperty, { component: Vector3PropertyLine, label: "Direction2", target: particleEmitterType, propertyKey: "direction2" })] }))] })), !scene && jsx(TextPropertyLine, { label: "Emitter", value: "No scene available." })] }));
|
|
17303
17396
|
};
|
|
17304
17397
|
|
|
17305
|
-
const useStyles$
|
|
17398
|
+
const useStyles$k = makeStyles({
|
|
17306
17399
|
subsection: {
|
|
17307
17400
|
marginTop: tokens.spacingVerticalM,
|
|
17308
17401
|
},
|
|
@@ -17322,7 +17415,7 @@ const ParticleSystemSizeProperties = (props) => {
|
|
|
17322
17415
|
const sizeGradientGetter = useCallback(() => system.getSizeGradients(), [system]);
|
|
17323
17416
|
const sizeGradient = useObservableArray(system, sizeGradientGetter, "addSizeGradient", "removeSizeGradient", "forceRefreshGradients");
|
|
17324
17417
|
const useSizeGradients = (sizeGradient?.length ?? 0) > 0;
|
|
17325
|
-
const classes = useStyles$
|
|
17418
|
+
const classes = useStyles$k();
|
|
17326
17419
|
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min size", target: system, propertyKey: "minSize", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max size", target: system, propertyKey: "maxSize", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min scale x", target: system, propertyKey: "minScaleX", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max scale x", target: system, propertyKey: "maxScaleX", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min scale y", target: system, propertyKey: "minScaleY", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max scale y", target: system, propertyKey: "maxScaleY", min: 0, step: 0.1 }), isCpuParticleSystem && !useStartSizeGradients && (jsx(ButtonLine, { label: "Use Start Size gradients", onClick: () => {
|
|
17327
17420
|
system.addStartSizeGradient(0, system.minSize, system.maxSize);
|
|
17328
17421
|
system.forceRefreshGradients();
|
|
@@ -17358,7 +17451,7 @@ const ParticleSystemSizeProperties = (props) => {
|
|
|
17358
17451
|
} })] }))] }));
|
|
17359
17452
|
};
|
|
17360
17453
|
|
|
17361
|
-
const useStyles$
|
|
17454
|
+
const useStyles$j = makeStyles({
|
|
17362
17455
|
subsection: {
|
|
17363
17456
|
marginTop: tokens.spacingVerticalM,
|
|
17364
17457
|
},
|
|
@@ -17384,7 +17477,7 @@ const ParticleSystemEmissionProperties = (props) => {
|
|
|
17384
17477
|
const useVelocityGradients = (velocityGradients?.length ?? 0) > 0;
|
|
17385
17478
|
const useLimitVelocityGradients = (limitVelocityGradients?.length ?? 0) > 0;
|
|
17386
17479
|
const useDragGradients = (dragGradients?.length ?? 0) > 0;
|
|
17387
|
-
const classes = useStyles$
|
|
17480
|
+
const classes = useStyles$j();
|
|
17388
17481
|
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Emit rate", target: system, propertyKey: "emitRate", min: 0, step: 1 }), isCpuParticleSystem && !useEmitRateGradients && (jsx(ButtonLine, { label: "Use Emit rate gradients", onClick: () => {
|
|
17389
17482
|
system.addEmitRateGradient(0, system.emitRate, system.emitRate);
|
|
17390
17483
|
system.forceRefreshGradients();
|
|
@@ -17452,7 +17545,7 @@ const ParticleSystemEmissionProperties = (props) => {
|
|
|
17452
17545
|
} })] }))] }));
|
|
17453
17546
|
};
|
|
17454
17547
|
|
|
17455
|
-
const useStyles$
|
|
17548
|
+
const useStyles$i = makeStyles({
|
|
17456
17549
|
subsection: {
|
|
17457
17550
|
marginTop: tokens.spacingVerticalM,
|
|
17458
17551
|
},
|
|
@@ -17469,7 +17562,7 @@ const ParticleSystemLifetimeProperties = (props) => {
|
|
|
17469
17562
|
const lifeTimeGradientsGetter = useCallback(() => system.getLifeTimeGradients(), [system]);
|
|
17470
17563
|
const lifeTimeGradients = useObservableArray(system, lifeTimeGradientsGetter, "addLifeTimeGradient", "removeLifeTimeGradient", "forceRefreshGradients");
|
|
17471
17564
|
const useLifeTimeGradients = (lifeTimeGradients?.length ?? 0) > 0;
|
|
17472
|
-
const classes = useStyles$
|
|
17565
|
+
const classes = useStyles$i();
|
|
17473
17566
|
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min lifetime", target: system, propertyKey: "minLifeTime", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max lifetime", target: system, propertyKey: "maxLifeTime", min: 0, step: 0.1 }), isCpuParticleSystem && !useLifeTimeGradients && (jsx(ButtonLine, { label: "Use Lifetime gradients", onClick: () => {
|
|
17474
17567
|
system.addLifeTimeGradient(0, system.minLifeTime, system.maxLifeTime);
|
|
17475
17568
|
system.forceRefreshGradients();
|
|
@@ -17489,7 +17582,7 @@ const ParticleSystemLifetimeProperties = (props) => {
|
|
|
17489
17582
|
} })] })), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Target stop duration", target: system, propertyKey: "targetStopDuration", min: 0, step: 0.1 })] }));
|
|
17490
17583
|
};
|
|
17491
17584
|
|
|
17492
|
-
const useStyles$
|
|
17585
|
+
const useStyles$h = makeStyles({
|
|
17493
17586
|
subsection: {
|
|
17494
17587
|
marginTop: tokens.spacingVerticalM,
|
|
17495
17588
|
},
|
|
@@ -17516,7 +17609,7 @@ const ParticleSystemColorProperties = (props) => {
|
|
|
17516
17609
|
const hasRampGradients = (rampGradients?.length ?? 0) > 0;
|
|
17517
17610
|
const hasColorRemapGradients = (colorRemapGradients?.length ?? 0) > 0;
|
|
17518
17611
|
const hasAlphaRemapGradients = (alphaRemapGradients?.length ?? 0) > 0;
|
|
17519
|
-
const classes = useStyles$
|
|
17612
|
+
const classes = useStyles$h();
|
|
17520
17613
|
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Color4PropertyLine, label: "Color 1", target: system, propertyKey: "color1" }), jsx(BoundProperty, { component: Color4PropertyLine, label: "Color 2", target: system, propertyKey: "color2" }), jsx(BoundProperty, { component: Color4PropertyLine, label: "Color dead", target: system, propertyKey: "colorDead" }), !hasColorGradients && (jsx(ButtonLine, { label: "Use Color gradients", onClick: () => {
|
|
17521
17614
|
system.addColorGradient(0, system.color1, system.color1);
|
|
17522
17615
|
system.addColorGradient(1, system.color2, system.color2);
|
|
@@ -17588,7 +17681,7 @@ const ParticleSystemColorProperties = (props) => {
|
|
|
17588
17681
|
} })] }))] }))] }));
|
|
17589
17682
|
};
|
|
17590
17683
|
|
|
17591
|
-
const useStyles$
|
|
17684
|
+
const useStyles$g = makeStyles({
|
|
17592
17685
|
subsection: {
|
|
17593
17686
|
marginTop: tokens.spacingVerticalM,
|
|
17594
17687
|
},
|
|
@@ -17603,7 +17696,7 @@ const ParticleSystemRotationProperties = (props) => {
|
|
|
17603
17696
|
const angularSpeedGradientsGetter = useCallback(() => system.getAngularSpeedGradients(), [system]);
|
|
17604
17697
|
const angularSpeedGradients = useObservableArray(system, angularSpeedGradientsGetter, "addAngularSpeedGradient", "removeAngularSpeedGradient", "forceRefreshGradients");
|
|
17605
17698
|
const useAngularSpeedGradients = (angularSpeedGradients?.length ?? 0) > 0;
|
|
17606
|
-
const classes = useStyles$
|
|
17699
|
+
const classes = useStyles$g();
|
|
17607
17700
|
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min Angular speed", target: system, propertyKey: "minAngularSpeed", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max Angular speed", target: system, propertyKey: "maxAngularSpeed", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min initial rotation", target: system, propertyKey: "minInitialRotation", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max initial rotation", target: system, propertyKey: "maxInitialRotation", step: 0.01 }), !useAngularSpeedGradients && (jsx(ButtonLine, { label: "Use Angular speed gradients", onClick: () => {
|
|
17608
17701
|
system.addAngularSpeedGradient(0, system.minAngularSpeed, system.maxAngularSpeed);
|
|
17609
17702
|
system.forceRefreshGradients();
|
|
@@ -17709,7 +17802,7 @@ const AttractorComponent = (props) => {
|
|
|
17709
17802
|
} }), !attractorData.isReadOnly && (jsx(ToggleButton, { title: "Add / remove position gizmo from particle attractor", checkedIcon: ArrowMoveFilled, value: isControlled(impostor), onChange: (control) => onControl(control ? impostor : undefined) }))] }));
|
|
17710
17803
|
};
|
|
17711
17804
|
|
|
17712
|
-
const useStyles$
|
|
17805
|
+
const useStyles$f = makeStyles({
|
|
17713
17806
|
subsection: {
|
|
17714
17807
|
marginTop: tokens.spacingVerticalM,
|
|
17715
17808
|
},
|
|
@@ -17766,7 +17859,7 @@ const AttractorList = (props) => {
|
|
|
17766
17859
|
gizmoManager.attachToMesh(attached);
|
|
17767
17860
|
setControlledImpostor(attached);
|
|
17768
17861
|
};
|
|
17769
|
-
const classes = useStyles$
|
|
17862
|
+
const classes = useStyles$f();
|
|
17770
17863
|
return (jsxs(Fragment, { children: [items.length > 0 && (jsxs(Fragment, { children: [jsx(Color3PropertyLine, { label: "Attractor Debug Color", value: impostorColor, onChange: setImpostorColor }), jsx(SyncedSliderPropertyLine, { label: "Attractor Debug Size", value: impostorScale, onChange: setImpostorScale, min: 0, max: 10, step: 0.1 }), jsx(Subtitle2, { className: classes.subsection, children: "Attractors list" })] })), jsx(List, { addButtonLabel: `Add New Attractor`, items: items, onDelete: attractorSource.removeAttractor
|
|
17771
17864
|
? (item, _index) => {
|
|
17772
17865
|
// Only CPU attractors (Attractor instances) can be removed
|
|
@@ -17876,7 +17969,7 @@ const ParticleSystemAttractorProperties = (props) => {
|
|
|
17876
17969
|
return (jsx(Fragment, { children: scene ? (jsx(AttractorList, { attractorSource: attractorSource, scene: scene })) : (jsx(MessageBar, { intent: "info", title: "No Scene Available", message: "Cannot display attractors without a scene" })) }));
|
|
17877
17970
|
};
|
|
17878
17971
|
|
|
17879
|
-
const useStyles$
|
|
17972
|
+
const useStyles$e = makeStyles({
|
|
17880
17973
|
subsection: {
|
|
17881
17974
|
marginTop: tokens.spacingVerticalM,
|
|
17882
17975
|
},
|
|
@@ -17930,7 +18023,7 @@ const InputBlockPropertyLine = (props) => {
|
|
|
17930
18023
|
*/
|
|
17931
18024
|
const ParticleSystemNodeEditorProperties = (props) => {
|
|
17932
18025
|
const { particleSystem: system } = props;
|
|
17933
|
-
const classes = useStyles$
|
|
18026
|
+
const classes = useStyles$e();
|
|
17934
18027
|
const source = system.source;
|
|
17935
18028
|
const inputBlocks = useObservableState(useCallback(() => {
|
|
17936
18029
|
if (!source) {
|
|
@@ -18791,14 +18884,14 @@ const SkeletonPropertiesServiceDefinition = {
|
|
|
18791
18884
|
},
|
|
18792
18885
|
};
|
|
18793
18886
|
|
|
18794
|
-
const useStyles$
|
|
18887
|
+
const useStyles$d = makeStyles({
|
|
18795
18888
|
uniformWidth: {
|
|
18796
18889
|
...UniformWidthStyling,
|
|
18797
18890
|
},
|
|
18798
18891
|
});
|
|
18799
18892
|
const SpinButtonPropertyLine = (props) => {
|
|
18800
18893
|
SpinButtonPropertyLine.displayName = "SpinButtonPropertyLine";
|
|
18801
|
-
const classes = useStyles$
|
|
18894
|
+
const classes = useStyles$d();
|
|
18802
18895
|
return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
|
|
18803
18896
|
};
|
|
18804
18897
|
|
|
@@ -19046,7 +19139,7 @@ function _TextureFormatHasNoAlpha(format) {
|
|
|
19046
19139
|
}
|
|
19047
19140
|
}
|
|
19048
19141
|
|
|
19049
|
-
const useStyles$
|
|
19142
|
+
const useStyles$c = makeStyles({
|
|
19050
19143
|
root: {
|
|
19051
19144
|
display: "flex",
|
|
19052
19145
|
flexDirection: "column",
|
|
@@ -19098,7 +19191,7 @@ const TextureChannelStates = {
|
|
|
19098
19191
|
*/
|
|
19099
19192
|
const TexturePreview = (props) => {
|
|
19100
19193
|
const { texture, disableToolbar = false, maxWidth = "100%", maxHeight = "384px", offsetX = 0, offsetY = 0, width, height, imperativeRef } = props;
|
|
19101
|
-
const classes = useStyles$
|
|
19194
|
+
const classes = useStyles$c();
|
|
19102
19195
|
const canvasRef = useRef(null);
|
|
19103
19196
|
const [channels, setChannels] = useState(TextureChannelStates.ALL);
|
|
19104
19197
|
const [face, setFace] = useState(0);
|
|
@@ -20008,7 +20101,7 @@ class TextureCanvasManager {
|
|
|
20008
20101
|
}
|
|
20009
20102
|
}
|
|
20010
20103
|
|
|
20011
|
-
const useStyles$
|
|
20104
|
+
const useStyles$b = makeStyles({
|
|
20012
20105
|
channelsBar: {
|
|
20013
20106
|
display: "flex",
|
|
20014
20107
|
flexDirection: "column",
|
|
@@ -20053,7 +20146,7 @@ const useStyles$8 = makeStyles({
|
|
|
20053
20146
|
*/
|
|
20054
20147
|
const ChannelsBar = (props) => {
|
|
20055
20148
|
const { channels, setChannels } = props;
|
|
20056
|
-
const classes = useStyles$
|
|
20149
|
+
const classes = useStyles$b();
|
|
20057
20150
|
const toggleVisibility = useCallback((index) => {
|
|
20058
20151
|
const newChannels = [...channels];
|
|
20059
20152
|
newChannels[index] = { ...newChannels[index], visible: !newChannels[index].visible };
|
|
@@ -20083,7 +20176,7 @@ const ChannelsBar = (props) => {
|
|
|
20083
20176
|
}) }));
|
|
20084
20177
|
};
|
|
20085
20178
|
|
|
20086
|
-
const useStyles$
|
|
20179
|
+
const useStyles$a = makeStyles({
|
|
20087
20180
|
propertiesBar: {
|
|
20088
20181
|
display: "flex",
|
|
20089
20182
|
backgroundColor: tokens.colorNeutralBackground1,
|
|
@@ -20133,7 +20226,7 @@ const useStyles$7 = makeStyles({
|
|
|
20133
20226
|
},
|
|
20134
20227
|
});
|
|
20135
20228
|
const PixelDataDisplay = ({ label, value }) => {
|
|
20136
|
-
const classes = useStyles$
|
|
20229
|
+
const classes = useStyles$a();
|
|
20137
20230
|
return (jsxs("span", { className: classes.pixelData, children: [jsxs(Label, { className: classes.pixelDataLabel, children: [label, ":"] }), jsx(Label, { className: classes.pixelDataValue, children: value !== undefined ? value : "-" })] }));
|
|
20138
20231
|
};
|
|
20139
20232
|
const CubeFaces = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
|
|
@@ -20144,7 +20237,7 @@ const CubeFaces = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
|
|
|
20144
20237
|
*/
|
|
20145
20238
|
const PropertiesBar = (props) => {
|
|
20146
20239
|
const { texture, size, saveTexture, pixelData, face, setFace, resetTexture, resizeTexture, uploadTexture, mipLevel, setMipLevel } = props;
|
|
20147
|
-
const classes = useStyles$
|
|
20240
|
+
const classes = useStyles$a();
|
|
20148
20241
|
const uploadInputRef = useRef(null);
|
|
20149
20242
|
const [width, setWidth] = useState(size.width);
|
|
20150
20243
|
const [height, setHeight] = useState(size.height);
|
|
@@ -20179,7 +20272,7 @@ const PropertiesBar = (props) => {
|
|
|
20179
20272
|
return (jsxs("div", { className: classes.propertiesBar, children: [jsxs("div", { className: classes.section, children: [jsx(Label, { children: "W:" }), jsx(Input, { className: classes.dimensionInput, size: "small", type: "text", value: width.toString(), readOnly: texture.isCube, onChange: (_, data) => setWidth(getNewDimension(width, data.value)) }), jsx(Label, { children: "H:" }), jsx(Input, { className: classes.dimensionInput, size: "small", type: "text", value: height.toString(), readOnly: texture.isCube, onChange: (_, data) => setHeight(getNewDimension(height, data.value)) }), !texture.isCube && (jsx(Tooltip$1, { content: "Resize", relationship: "label", children: jsx(ToolbarButton, { icon: jsx(ResizeRegular, {}), onClick: handleResize }) }))] }), jsx(ToolbarDivider, {}), jsxs("div", { className: classes.section, children: [jsx(PixelDataDisplay, { label: "X", value: pixelData.x }), jsx(PixelDataDisplay, { label: "Y", value: pixelData.y })] }), jsx(ToolbarDivider, {}), jsxs("div", { className: classes.section, children: [jsx(PixelDataDisplay, { label: "R", value: pixelData.r }), jsx(PixelDataDisplay, { label: "G", value: pixelData.g }), jsx(PixelDataDisplay, { label: "B", value: pixelData.b }), jsx(PixelDataDisplay, { label: "A", value: pixelData.a })] }), texture.isCube && (jsxs(Fragment, { children: [jsx(ToolbarDivider, {}), jsx(Toolbar$1, { size: "small", children: CubeFaces.map((label, index) => (jsx(ToolbarButton, { className: classes.faceButton, appearance: face === index ? "primary" : "subtle", onClick: () => setFace(index), children: label }, label))) })] })), mipsEnabled && (jsxs(Fragment, { children: [jsx(ToolbarDivider, {}), jsxs("div", { className: classes.section, children: [jsx(Label, { children: "MIP:" }), jsx(Tooltip$1, { content: "Mip Preview Up", relationship: "label", children: jsx(ToolbarButton, { icon: jsx(ChevronUpRegular, {}), disabled: mipLevel <= 0, onClick: () => setMipLevel(mipLevel - 1) }) }), jsx(Label, { children: mipLevel }), jsx(Tooltip$1, { content: "Mip Preview Down", relationship: "label", children: jsx(ToolbarButton, { icon: jsx(ChevronDownRegular, {}), disabled: mipLevel >= maxLevels, onClick: () => setMipLevel(mipLevel + 1) }) })] })] })), jsx("div", { className: classes.spacer }), jsxs(Toolbar$1, { size: "small", children: [jsx(Tooltip$1, { content: "Reset", relationship: "label", children: jsx(ToolbarButton, { icon: jsx(ArrowResetRegular, {}), onClick: resetTexture }) }), jsx(Tooltip$1, { content: "Upload", relationship: "label", children: jsx(ToolbarButton, { icon: jsx(ArrowUploadRegular, {}), onClick: handleUploadClick }) }), jsx("input", { ref: uploadInputRef, className: classes.uploadInput, type: "file", accept: ".jpg, .png, .tga, .dds, .env, .exr", onChange: handleFileChange }), jsx(Tooltip$1, { content: "Save", relationship: "label", children: jsx(ToolbarButton, { icon: jsx(SaveRegular, {}), onClick: saveTexture }) })] })] }));
|
|
20180
20273
|
};
|
|
20181
20274
|
|
|
20182
|
-
const useStyles$
|
|
20275
|
+
const useStyles$9 = makeStyles({
|
|
20183
20276
|
statusBar: {
|
|
20184
20277
|
display: "flex",
|
|
20185
20278
|
backgroundColor: tokens.colorNeutralBackground1,
|
|
@@ -20207,14 +20300,14 @@ const useStyles$6 = makeStyles({
|
|
|
20207
20300
|
*/
|
|
20208
20301
|
const StatusBar = (props) => {
|
|
20209
20302
|
const { texture, mipLevel } = props;
|
|
20210
|
-
const classes = useStyles$
|
|
20303
|
+
const classes = useStyles$9();
|
|
20211
20304
|
const factor = Math.pow(2, mipLevel);
|
|
20212
20305
|
const width = Math.ceil(texture.getSize().width / factor);
|
|
20213
20306
|
const height = Math.ceil(texture.getSize().height / factor);
|
|
20214
20307
|
return (jsxs("div", { className: classes.statusBar, children: [jsx("span", { className: classes.fileName, children: texture.name }), !texture.noMipmap && (jsxs("span", { className: classes.mipInfo, children: ["MIP Preview: ", mipLevel, " (", width, "\u00D7", height, ")"] }))] }));
|
|
20215
20308
|
};
|
|
20216
20309
|
|
|
20217
|
-
const useStyles$
|
|
20310
|
+
const useStyles$8 = makeStyles({
|
|
20218
20311
|
toolbar: {
|
|
20219
20312
|
display: "flex",
|
|
20220
20313
|
flexDirection: "column",
|
|
@@ -20251,7 +20344,7 @@ const useStyles$5 = makeStyles({
|
|
|
20251
20344
|
*/
|
|
20252
20345
|
const ToolBar = (props) => {
|
|
20253
20346
|
const { tools, changeTool, activeToolIndex, metadata, setMetadata, hasAlpha } = props;
|
|
20254
|
-
const classes = useStyles$
|
|
20347
|
+
const classes = useStyles$8();
|
|
20255
20348
|
const computeRGBAColor = useCallback(() => {
|
|
20256
20349
|
const opacityInt = Math.floor(metadata.alpha * 255);
|
|
20257
20350
|
const opacityHex = opacityInt.toString(16).padStart(2, "0");
|
|
@@ -20280,7 +20373,7 @@ const ToolBar = (props) => {
|
|
|
20280
20373
|
}) })] }));
|
|
20281
20374
|
};
|
|
20282
20375
|
|
|
20283
|
-
const useStyles$
|
|
20376
|
+
const useStyles$7 = makeStyles({
|
|
20284
20377
|
textureEditor: {
|
|
20285
20378
|
display: "flex",
|
|
20286
20379
|
flexDirection: "column",
|
|
@@ -20344,7 +20437,7 @@ const PREVIEW_UPDATE_DELAY_MS = 160;
|
|
|
20344
20437
|
*/
|
|
20345
20438
|
const TextureEditor = (props) => {
|
|
20346
20439
|
const { texture, toolProviders = [], window: editorWindow, onUpdate } = props;
|
|
20347
|
-
const classes = useStyles$
|
|
20440
|
+
const classes = useStyles$7();
|
|
20348
20441
|
// Canvas refs
|
|
20349
20442
|
const uiCanvasRef = useRef(null);
|
|
20350
20443
|
const canvas2DRef = useRef(null);
|
|
@@ -20492,7 +20585,7 @@ const TextureEditor = (props) => {
|
|
|
20492
20585
|
return (jsxs("div", { className: classes.textureEditor, children: [jsx(PropertiesBar, { texture: texture, saveTexture: saveTexture, pixelData: pixelData, face: face, setFace: setFace, resetTexture: resetTexture, resizeTexture: resizeTexture, uploadTexture: uploadTexture, mipLevel: mipLevel, setMipLevel: setMipLevel, size: canvasManagerRef.current?.size || size }), jsxs("div", { className: classes.mainContent, children: [jsxs("div", { className: classes.canvasContainer, style: { cursor }, children: [jsx("canvas", { ref: uiCanvasRef, className: classes.canvasUI, tabIndex: 1 }), jsx("canvas", { ref: canvas2DRef, className: classes.canvas2D }), jsx("canvas", { ref: canvas3DRef, className: classes.canvas3D })] }), CurrentToolSettings && (jsx("div", { className: classes.toolSettingsContainer, children: jsx(CurrentToolSettings, {}) })), !texture.isCube && (jsx("div", { className: classes.sidebarLeft, children: jsx(ToolBar, { tools: toolProviders, activeToolIndex: activeToolIndex, changeTool: changeTool, metadata: metadata, setMetadata: setMetadata, hasAlpha: hasAlpha }) })), jsx("div", { className: classes.sidebarRight, children: jsx(ChannelsBar, { channels: channels, setChannels: setChannels }) })] }), jsx(StatusBar, { texture: texture, mipLevel: mipLevel })] }));
|
|
20493
20586
|
};
|
|
20494
20587
|
|
|
20495
|
-
const useStyles$
|
|
20588
|
+
const useStyles$6 = makeStyles({
|
|
20496
20589
|
settingsContainer: {
|
|
20497
20590
|
display: "flex",
|
|
20498
20591
|
flexDirection: "column",
|
|
@@ -20512,7 +20605,7 @@ const Contrast = {
|
|
|
20512
20605
|
name: "Contrast/Exposure",
|
|
20513
20606
|
order: 500,
|
|
20514
20607
|
icon: () => {
|
|
20515
|
-
const classes = useStyles$
|
|
20608
|
+
const classes = useStyles$6();
|
|
20516
20609
|
return jsx(CircleHalfFillRegular, { className: classes.icon });
|
|
20517
20610
|
},
|
|
20518
20611
|
is3D: true,
|
|
@@ -20577,7 +20670,7 @@ const Contrast = {
|
|
|
20577
20670
|
setContrast(0);
|
|
20578
20671
|
},
|
|
20579
20672
|
settingsComponent: () => {
|
|
20580
|
-
const classes = useStyles$
|
|
20673
|
+
const classes = useStyles$6();
|
|
20581
20674
|
const [contrast, exposure] = useObservableState(useCallback(() => [_contrast, _exposure], []), stateChangedObservable);
|
|
20582
20675
|
const handleContrastChange = (_, data) => {
|
|
20583
20676
|
setContrast(data.value);
|
|
@@ -20678,7 +20771,7 @@ const Floodfill = {
|
|
|
20678
20771
|
},
|
|
20679
20772
|
};
|
|
20680
20773
|
|
|
20681
|
-
const useStyles$
|
|
20774
|
+
const useStyles$5 = makeStyles({
|
|
20682
20775
|
settingsContainer: {
|
|
20683
20776
|
display: "flex",
|
|
20684
20777
|
flexDirection: "column",
|
|
@@ -20802,7 +20895,7 @@ const Paintbrush = {
|
|
|
20802
20895
|
pointerObserver?.remove();
|
|
20803
20896
|
},
|
|
20804
20897
|
settingsComponent: () => {
|
|
20805
|
-
const classes = useStyles$
|
|
20898
|
+
const classes = useStyles$5();
|
|
20806
20899
|
const width = useObservableState(useCallback(() => _width, []), stateChangedObservable);
|
|
20807
20900
|
const handleWidthChange = (_, data) => {
|
|
20808
20901
|
setWidth(data.value);
|
|
@@ -22796,6 +22889,411 @@ const ExportServiceDefinition = {
|
|
|
22796
22889
|
},
|
|
22797
22890
|
};
|
|
22798
22891
|
|
|
22892
|
+
const useStyles$4 = makeStyles({
|
|
22893
|
+
statusMessage: {
|
|
22894
|
+
padding: `${tokens.spacingVerticalXXS} ${tokens.spacingHorizontalS}`,
|
|
22895
|
+
opacity: 0.7,
|
|
22896
|
+
},
|
|
22897
|
+
busyMessage: {
|
|
22898
|
+
display: "flex",
|
|
22899
|
+
alignItems: "center",
|
|
22900
|
+
gap: tokens.spacingHorizontalXS,
|
|
22901
|
+
padding: `${tokens.spacingVerticalXXS} ${tokens.spacingHorizontalS}`,
|
|
22902
|
+
},
|
|
22903
|
+
});
|
|
22904
|
+
/**
|
|
22905
|
+
* Save/load controls for a scene's Smart Asset map.
|
|
22906
|
+
* @param props - Component props.
|
|
22907
|
+
* @returns The Smart Asset map controls.
|
|
22908
|
+
*/
|
|
22909
|
+
const SmartAssetProjectTools = (props) => {
|
|
22910
|
+
const { scene } = props;
|
|
22911
|
+
const [statusMessage, setStatusMessage] = useState("");
|
|
22912
|
+
const [busyMessage, setBusyMessage] = useState("");
|
|
22913
|
+
const styles = useStyles$4();
|
|
22914
|
+
const isBusy = busyMessage !== "";
|
|
22915
|
+
const onSaveAssetMap = useCallback(async () => {
|
|
22916
|
+
if (isBusy) {
|
|
22917
|
+
return;
|
|
22918
|
+
}
|
|
22919
|
+
setBusyMessage("Saving assets...");
|
|
22920
|
+
setStatusMessage("");
|
|
22921
|
+
try {
|
|
22922
|
+
const assetMap = SerializeSmartAssetManagerMap(scene);
|
|
22923
|
+
const jsonBlob = new Blob([JSON.stringify(assetMap, null, 2)], { type: "application/json" });
|
|
22924
|
+
Tools.Download(jsonBlob, "smart-assets.json");
|
|
22925
|
+
setStatusMessage(`Saved: ${Object.keys(assetMap.assets).length} assets`);
|
|
22926
|
+
}
|
|
22927
|
+
catch (err) {
|
|
22928
|
+
setStatusMessage(`Save error: ${err}`);
|
|
22929
|
+
}
|
|
22930
|
+
finally {
|
|
22931
|
+
setBusyMessage("");
|
|
22932
|
+
}
|
|
22933
|
+
}, [scene, isBusy]);
|
|
22934
|
+
const onLoadAssetMap = useCallback(async (files) => {
|
|
22935
|
+
const file = files[0];
|
|
22936
|
+
if (!file) {
|
|
22937
|
+
return;
|
|
22938
|
+
}
|
|
22939
|
+
if (isBusy) {
|
|
22940
|
+
return;
|
|
22941
|
+
}
|
|
22942
|
+
setBusyMessage("Loading assets...");
|
|
22943
|
+
setStatusMessage("");
|
|
22944
|
+
try {
|
|
22945
|
+
await Promise.all(Array.from(GetAllSmartAssets(scene).keys()).map(async (key) => await RemoveSmartAssetAsync(scene, key)));
|
|
22946
|
+
await LoadSmartAssetMapAsync(scene, file);
|
|
22947
|
+
setStatusMessage(`Loaded: ${GetAllSmartAssets(scene).size} assets`);
|
|
22948
|
+
}
|
|
22949
|
+
catch (err) {
|
|
22950
|
+
setStatusMessage(`Load error: ${err}`);
|
|
22951
|
+
}
|
|
22952
|
+
finally {
|
|
22953
|
+
setBusyMessage("");
|
|
22954
|
+
}
|
|
22955
|
+
}, [scene, isBusy]);
|
|
22956
|
+
return (jsxs(Fragment, { children: [jsx(ButtonLine, { label: "Save Smart Assets", icon: ArrowDownloadRegular, onClick: onSaveAssetMap, disabled: isBusy }), jsx(FileUploadLine, { label: "Load Smart Assets", accept: ".json", onClick: onLoadAssetMap, disabled: isBusy }), jsx(Collapse, { visible: isBusy, children: jsxs("div", { className: styles.busyMessage, children: [jsx(Spinner, { size: "extra-small" }), jsx(Caption1, { children: busyMessage })] }) }), jsx(Collapse, { visible: statusMessage !== "", children: jsx(Caption1, { className: styles.statusMessage, children: statusMessage }) })] }));
|
|
22957
|
+
};
|
|
22958
|
+
|
|
22959
|
+
const SmartAssetsPaneKey$1 = "Smart Assets";
|
|
22960
|
+
const SceneFileAccept = [".glb", ".gltf", ".babylon", ".obj"];
|
|
22961
|
+
const TextureFileAccept = Array.from(GetSmartAssetTextureExtensions());
|
|
22962
|
+
const AllAcceptString = [...SceneFileAccept, ...TextureFileAccept].join(",");
|
|
22963
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
22964
|
+
function _isTextureExtension(ext) {
|
|
22965
|
+
return GetSmartAssetTextureExtensions().has(ext);
|
|
22966
|
+
}
|
|
22967
|
+
/**
|
|
22968
|
+
* Inspector pane service that hosts the Smart Assets pane.
|
|
22969
|
+
*/
|
|
22970
|
+
const SmartAssetsServiceDefinition = {
|
|
22971
|
+
friendlyName: "Smart Assets",
|
|
22972
|
+
consumes: [ShellServiceIdentity, SceneContextIdentity, SelectionServiceIdentity],
|
|
22973
|
+
factory: (shellService, sceneContext, selectionService) => {
|
|
22974
|
+
const paneRegistration = shellService.addSidePane({
|
|
22975
|
+
key: SmartAssetsPaneKey$1,
|
|
22976
|
+
title: SmartAssetsPaneKey$1,
|
|
22977
|
+
icon: CubeRegular,
|
|
22978
|
+
horizontalLocation: "right",
|
|
22979
|
+
verticalLocation: "top",
|
|
22980
|
+
order: 395,
|
|
22981
|
+
teachingMoment: false,
|
|
22982
|
+
content: () => {
|
|
22983
|
+
const scene = useObservableState(() => sceneContext.currentScene, sceneContext.currentSceneObservable);
|
|
22984
|
+
return scene ? jsx(SmartAssetsPane, { scene: scene, selectionService: selectionService }) : null;
|
|
22985
|
+
},
|
|
22986
|
+
});
|
|
22987
|
+
return {
|
|
22988
|
+
dispose: () => {
|
|
22989
|
+
paneRegistration.dispose();
|
|
22990
|
+
},
|
|
22991
|
+
};
|
|
22992
|
+
},
|
|
22993
|
+
};
|
|
22994
|
+
// ── Styles ──
|
|
22995
|
+
const useStyles$3 = makeStyles({
|
|
22996
|
+
assetRow: {
|
|
22997
|
+
display: "flex",
|
|
22998
|
+
alignItems: "center",
|
|
22999
|
+
gap: tokens.spacingHorizontalXS,
|
|
23000
|
+
padding: `${tokens.spacingVerticalXS} ${tokens.spacingHorizontalS}`,
|
|
23001
|
+
fontSize: tokens.fontSizeBase100,
|
|
23002
|
+
borderBottom: `1px solid ${tokens.colorNeutralStroke3}`,
|
|
23003
|
+
},
|
|
23004
|
+
assetKey: {
|
|
23005
|
+
fontWeight: tokens.fontWeightSemibold,
|
|
23006
|
+
minWidth: 0,
|
|
23007
|
+
flex: 1,
|
|
23008
|
+
overflow: "hidden",
|
|
23009
|
+
textOverflow: "ellipsis",
|
|
23010
|
+
whiteSpace: "nowrap",
|
|
23011
|
+
},
|
|
23012
|
+
assetUrl: {
|
|
23013
|
+
overflow: "hidden",
|
|
23014
|
+
textOverflow: "ellipsis",
|
|
23015
|
+
whiteSpace: "nowrap",
|
|
23016
|
+
minWidth: 0,
|
|
23017
|
+
flex: 1,
|
|
23018
|
+
opacity: 0.7,
|
|
23019
|
+
},
|
|
23020
|
+
assetActions: {
|
|
23021
|
+
display: "flex",
|
|
23022
|
+
gap: tokens.spacingHorizontalXXS,
|
|
23023
|
+
flexShrink: 0,
|
|
23024
|
+
},
|
|
23025
|
+
emptyMessage: {
|
|
23026
|
+
padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalS}`,
|
|
23027
|
+
fontSize: tokens.fontSizeBase100,
|
|
23028
|
+
opacity: 0.5,
|
|
23029
|
+
fontStyle: "italic",
|
|
23030
|
+
},
|
|
23031
|
+
statusMessage: {
|
|
23032
|
+
padding: `${tokens.spacingVerticalXXS} ${tokens.spacingHorizontalS}`,
|
|
23033
|
+
fontSize: tokens.fontSizeBase100,
|
|
23034
|
+
opacity: 0.7,
|
|
23035
|
+
},
|
|
23036
|
+
hiddenInput: {
|
|
23037
|
+
display: "none",
|
|
23038
|
+
},
|
|
23039
|
+
});
|
|
23040
|
+
// ── Smart Assets Pane ──
|
|
23041
|
+
const SmartAssetsPane = (props) => {
|
|
23042
|
+
const { scene, selectionService } = props;
|
|
23043
|
+
return (jsxs(Accordion, { uniqueId: "SmartAssets", enablePinnedItems: true, enableHiddenItems: true, enableSearchItems: true, children: [jsx(AccordionSection, { title: "Assets", children: jsx(SmartAssetList, { scene: scene, selectionService: selectionService }) }), jsx(AccordionSection, { title: "Asset Map", children: jsx(SmartAssetProjectTools, { scene: scene }) })] }));
|
|
23044
|
+
};
|
|
23045
|
+
// ── Smart Asset List ──
|
|
23046
|
+
const SmartAssetList = (props) => {
|
|
23047
|
+
const { scene, selectionService } = props;
|
|
23048
|
+
const styles = useStyles$3();
|
|
23049
|
+
const fileInputRef = useRef(null);
|
|
23050
|
+
const [status, setStatus] = useState("");
|
|
23051
|
+
// Force the icon-only row action buttons to render in compact ("small") size
|
|
23052
|
+
// even when the inspector's global ToolContext is "medium". They live in a
|
|
23053
|
+
// tight row and the medium-size buttons crowd the layout.
|
|
23054
|
+
const toolContext = useContext(ToolContext);
|
|
23055
|
+
const compactToolContext = useMemo(() => ({ ...toolContext, size: "small" }), [toolContext]);
|
|
23056
|
+
// Subscribe reactively to changes — re-renders the asset list whenever
|
|
23057
|
+
// RegisterSmartAsset / Load / Remove / Reload fire onChangedObservable.
|
|
23058
|
+
const sam = GetSmartAssetManager(scene);
|
|
23059
|
+
const assets = useObservableState(useCallback(() => Array.from(GetAllSmartAssets(scene), ([key, url]) => ({ key, url })), [scene]), sam.onChangedObservable);
|
|
23060
|
+
const onAddAsset = useCallback(() => {
|
|
23061
|
+
fileInputRef.current?.click();
|
|
23062
|
+
}, []);
|
|
23063
|
+
const onFileSelected = useCallback(async (e) => {
|
|
23064
|
+
const files = e.target.files;
|
|
23065
|
+
if (!files || files.length === 0) {
|
|
23066
|
+
return;
|
|
23067
|
+
}
|
|
23068
|
+
for (let i = 0; i < files.length; i++) {
|
|
23069
|
+
const file = files[i];
|
|
23070
|
+
const key = file.name.replace(/\.[^/.]+$/, "");
|
|
23071
|
+
const ext = _getExtension(file.name).toLowerCase();
|
|
23072
|
+
const isTexture = _isTextureExtension(ext);
|
|
23073
|
+
const blobUrl = URL.createObjectURL(file);
|
|
23074
|
+
const options = { ...(ext ? { extension: ext } : {}), ...(isTexture ? { type: "texture" } : {}) };
|
|
23075
|
+
try {
|
|
23076
|
+
if (isTexture) {
|
|
23077
|
+
// eslint-disable-next-line no-await-in-loop
|
|
23078
|
+
await LoadSmartAssetTextureAsync(scene, key, blobUrl, options);
|
|
23079
|
+
}
|
|
23080
|
+
else {
|
|
23081
|
+
// Temporarily set onAssetNotFound to return the File so SAM's
|
|
23082
|
+
// retry path can use the extension hint and track loaded objects.
|
|
23083
|
+
const samForOverride = GetSmartAssetManager(scene);
|
|
23084
|
+
const savedHandler = samForOverride.onAssetNotFound;
|
|
23085
|
+
samForOverride.onAssetNotFound = async () => file;
|
|
23086
|
+
try {
|
|
23087
|
+
// eslint-disable-next-line no-await-in-loop
|
|
23088
|
+
await LoadSmartAssetAsync(scene, key, blobUrl, options);
|
|
23089
|
+
}
|
|
23090
|
+
finally {
|
|
23091
|
+
samForOverride.onAssetNotFound = savedHandler;
|
|
23092
|
+
}
|
|
23093
|
+
}
|
|
23094
|
+
setStatus(`Added: ${key}`);
|
|
23095
|
+
}
|
|
23096
|
+
catch {
|
|
23097
|
+
setStatus(`Failed to load: ${key}`);
|
|
23098
|
+
}
|
|
23099
|
+
}
|
|
23100
|
+
if (fileInputRef.current) {
|
|
23101
|
+
fileInputRef.current.value = "";
|
|
23102
|
+
}
|
|
23103
|
+
}, [scene]);
|
|
23104
|
+
const onRemoveAsset = useCallback(async (key) => {
|
|
23105
|
+
await RemoveSmartAssetAsync(scene, key);
|
|
23106
|
+
setStatus(`Removed: ${key}`);
|
|
23107
|
+
}, [scene]);
|
|
23108
|
+
const onReloadAsset = useCallback(async (key) => {
|
|
23109
|
+
await ReloadSmartAssetAsync(scene, key);
|
|
23110
|
+
setStatus(`Reloaded: ${key}`);
|
|
23111
|
+
}, [scene]);
|
|
23112
|
+
const onSwapAsset = useCallback((key) => {
|
|
23113
|
+
const doSwapAsync = async (file, fileHandle) => {
|
|
23114
|
+
const sam = GetSmartAssetManager(scene);
|
|
23115
|
+
const blobUrl = URL.createObjectURL(file);
|
|
23116
|
+
const ext = _getExtension(file.name).toLowerCase();
|
|
23117
|
+
const isTexture = _isTextureExtension(ext);
|
|
23118
|
+
if (isTexture) {
|
|
23119
|
+
// Find the old texture tracked by this key
|
|
23120
|
+
let oldTex;
|
|
23121
|
+
for (const tex of scene.textures) {
|
|
23122
|
+
if (FindSmartAssetKeyForObject(scene, tex) === key) {
|
|
23123
|
+
oldTex = tex;
|
|
23124
|
+
break;
|
|
23125
|
+
}
|
|
23126
|
+
}
|
|
23127
|
+
// Load the new texture via SAM so it stays tracked by key.
|
|
23128
|
+
// Pass reloadSource so Reload can re-read the file from disk.
|
|
23129
|
+
const newTex = await LoadSmartAssetTextureAsync(scene, key, blobUrl, {
|
|
23130
|
+
...(ext ? { extension: ext } : {}),
|
|
23131
|
+
type: "texture",
|
|
23132
|
+
reloadSource: fileHandle ? async () => await fileHandle.getFile() : undefined,
|
|
23133
|
+
});
|
|
23134
|
+
// Replace references on all materials that used the old texture.
|
|
23135
|
+
// Only Standard/PBR-style slot names are rewritten here; NodeMaterial,
|
|
23136
|
+
// ShaderMaterial, BackgroundMaterial, and other custom materials with
|
|
23137
|
+
// non-standard texture slots will need to be updated manually.
|
|
23138
|
+
if (oldTex) {
|
|
23139
|
+
const texSlots = ["albedoTexture", "bumpTexture", "metallicTexture", "emissiveTexture", "ambientTexture", "reflectivityTexture", "opacityTexture"];
|
|
23140
|
+
for (const mat of scene.materials) {
|
|
23141
|
+
for (const slot of texSlots) {
|
|
23142
|
+
if (mat[slot] === oldTex) {
|
|
23143
|
+
mat[slot] = newTex;
|
|
23144
|
+
}
|
|
23145
|
+
}
|
|
23146
|
+
}
|
|
23147
|
+
oldTex.dispose();
|
|
23148
|
+
}
|
|
23149
|
+
}
|
|
23150
|
+
else {
|
|
23151
|
+
// Scene file swap (GLB, glTF, etc.)
|
|
23152
|
+
await UnloadSmartAssetAsync(scene, key);
|
|
23153
|
+
// Use onAssetNotFound to provide the File so SAM tracks loaded objects.
|
|
23154
|
+
const savedHandler = sam.onAssetNotFound;
|
|
23155
|
+
sam.onAssetNotFound = async () => file;
|
|
23156
|
+
try {
|
|
23157
|
+
// Pass reloadSource so Reload can re-read the file from disk.
|
|
23158
|
+
await LoadSmartAssetAsync(scene, key, blobUrl, {
|
|
23159
|
+
...(ext ? { extension: ext } : {}),
|
|
23160
|
+
reloadSource: fileHandle ? async () => await fileHandle.getFile() : undefined,
|
|
23161
|
+
});
|
|
23162
|
+
}
|
|
23163
|
+
finally {
|
|
23164
|
+
sam.onAssetNotFound = savedHandler;
|
|
23165
|
+
}
|
|
23166
|
+
}
|
|
23167
|
+
// Notify after everything is loaded and tracked so the UI re-renders
|
|
23168
|
+
// with the correct provEntity links
|
|
23169
|
+
sam.onChangedObservable.notifyObservers();
|
|
23170
|
+
setStatus(`Swapped: ${key}`);
|
|
23171
|
+
};
|
|
23172
|
+
// Prefer showOpenFilePicker (File System Access API) so we get a
|
|
23173
|
+
// FileSystemFileHandle that lets Reload re-read fresh contents from disk.
|
|
23174
|
+
const windowWithPicker = window;
|
|
23175
|
+
if (typeof windowWithPicker.showOpenFilePicker === "function") {
|
|
23176
|
+
const pickerAsync = async () => {
|
|
23177
|
+
let handle;
|
|
23178
|
+
try {
|
|
23179
|
+
[handle] = await windowWithPicker.showOpenFilePicker({
|
|
23180
|
+
types: [
|
|
23181
|
+
{
|
|
23182
|
+
description: "Assets",
|
|
23183
|
+
accept: {
|
|
23184
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
23185
|
+
"model/*": SceneFileAccept,
|
|
23186
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
23187
|
+
"image/*": TextureFileAccept,
|
|
23188
|
+
},
|
|
23189
|
+
},
|
|
23190
|
+
],
|
|
23191
|
+
});
|
|
23192
|
+
}
|
|
23193
|
+
catch (err) {
|
|
23194
|
+
// User cancelled the picker (AbortError) — silently ignore.
|
|
23195
|
+
if (err?.name !== "AbortError") {
|
|
23196
|
+
setStatus(`Swap cancelled: ${err}`);
|
|
23197
|
+
}
|
|
23198
|
+
return;
|
|
23199
|
+
}
|
|
23200
|
+
try {
|
|
23201
|
+
const file = await handle.getFile();
|
|
23202
|
+
await doSwapAsync(file, handle);
|
|
23203
|
+
}
|
|
23204
|
+
catch (err) {
|
|
23205
|
+
setStatus(`Failed to swap ${key}: ${err}`);
|
|
23206
|
+
}
|
|
23207
|
+
};
|
|
23208
|
+
void pickerAsync();
|
|
23209
|
+
}
|
|
23210
|
+
else {
|
|
23211
|
+
// Fallback for browsers without File System Access API
|
|
23212
|
+
const input = document.createElement("input");
|
|
23213
|
+
input.type = "file";
|
|
23214
|
+
input.accept = AllAcceptString;
|
|
23215
|
+
input.onchange = async () => {
|
|
23216
|
+
const file = input.files?.[0];
|
|
23217
|
+
if (!file) {
|
|
23218
|
+
return;
|
|
23219
|
+
}
|
|
23220
|
+
try {
|
|
23221
|
+
await doSwapAsync(file);
|
|
23222
|
+
}
|
|
23223
|
+
catch (err) {
|
|
23224
|
+
setStatus(`Failed to swap ${key}: ${err}`);
|
|
23225
|
+
}
|
|
23226
|
+
};
|
|
23227
|
+
input.click();
|
|
23228
|
+
}
|
|
23229
|
+
}, [scene]);
|
|
23230
|
+
return (jsxs(Fragment, { children: [assets.length === 0 && jsx(Caption1, { className: styles.emptyMessage, children: "No smart assets registered. Add assets to begin." }), assets.map((a) => {
|
|
23231
|
+
// Find the first mesh produced by this key for click-to-select
|
|
23232
|
+
const provEntity = _findFirstEntityForKey(a.key, scene);
|
|
23233
|
+
return (jsxs("div", { className: styles.assetRow, children: [jsx(CubeRegular, { fontSize: 14 }), provEntity ? (jsx(Caption1, { className: styles.assetKey, title: a.key, children: jsx(Link, { value: a.key, size: "small", onLink: () => (selectionService.selectedEntity = provEntity) }) })) : (jsx(Caption1, { className: styles.assetKey, title: a.key, children: a.key })), jsx(Caption1, { className: styles.assetUrl, title: a.url, children: _shortenUrl(a.url) }), jsx(ToolContext.Provider, { value: compactToolContext, children: jsxs("div", { className: styles.assetActions, children: [jsx(Button, { appearance: "subtle", icon: LinkRegular, title: `Swap URL for ${a.key}`, onClick: () => onSwapAsset(a.key) }), jsx(Button, { appearance: "subtle", icon: ArrowSyncRegular, title: `Reload ${a.key}`, onClick: async () => await onReloadAsset(a.key) }), jsx(Button, { appearance: "subtle", icon: DeleteRegular, title: `Remove ${a.key}`, onClick: async () => await onRemoveAsset(a.key) })] }) })] }, a.key));
|
|
23234
|
+
}), jsx(ButtonLine, { label: "Add Asset", icon: AddRegular, onClick: onAddAsset }), jsx("input", { ref: fileInputRef, type: "file", accept: AllAcceptString, multiple: true, className: styles.hiddenInput, onChange: onFileSelected }), status && jsx(Caption1, { className: styles.statusMessage, children: status })] }));
|
|
23235
|
+
};
|
|
23236
|
+
// ── Utilities ──
|
|
23237
|
+
/**
|
|
23238
|
+
* Finds the first scene entity produced by a smart asset key, for click-to-select.
|
|
23239
|
+
* Prefers non-root meshes, then materials, then textures.
|
|
23240
|
+
* @param key - The smart asset key.
|
|
23241
|
+
* @param scene - The scene to search.
|
|
23242
|
+
* @returns The first matching entity, or null if not found.
|
|
23243
|
+
*/
|
|
23244
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
23245
|
+
function _findFirstEntityForKey(key, scene) {
|
|
23246
|
+
for (const mesh of scene.meshes) {
|
|
23247
|
+
if (mesh.name !== "__root__" && FindSmartAssetKeyForObject(scene, mesh) === key) {
|
|
23248
|
+
return mesh;
|
|
23249
|
+
}
|
|
23250
|
+
}
|
|
23251
|
+
for (const mat of scene.materials) {
|
|
23252
|
+
if (FindSmartAssetKeyForObject(scene, mat) === key) {
|
|
23253
|
+
return mat;
|
|
23254
|
+
}
|
|
23255
|
+
}
|
|
23256
|
+
for (const tex of scene.textures) {
|
|
23257
|
+
if (FindSmartAssetKeyForObject(scene, tex) === key) {
|
|
23258
|
+
return tex;
|
|
23259
|
+
}
|
|
23260
|
+
}
|
|
23261
|
+
return null;
|
|
23262
|
+
}
|
|
23263
|
+
/**
|
|
23264
|
+
* Shortens a URL for display, collapsing blob/data URLs and long paths.
|
|
23265
|
+
* @param url - The URL to shorten.
|
|
23266
|
+
* @returns A shortened display string.
|
|
23267
|
+
*/
|
|
23268
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
23269
|
+
function _shortenUrl(url) {
|
|
23270
|
+
if (url.startsWith("blob:")) {
|
|
23271
|
+
return "(local file — blob)";
|
|
23272
|
+
}
|
|
23273
|
+
if (url.startsWith("data:")) {
|
|
23274
|
+
const mimeEnd = url.indexOf(";");
|
|
23275
|
+
const mime = mimeEnd > 5 ? url.substring(5, mimeEnd) : "binary";
|
|
23276
|
+
return `(embedded ${mime})`;
|
|
23277
|
+
}
|
|
23278
|
+
const parts = url.split("/");
|
|
23279
|
+
return parts.length > 3 ? "…/" + parts.slice(-2).join("/") : url;
|
|
23280
|
+
}
|
|
23281
|
+
/**
|
|
23282
|
+
* Returns the file extension from a filename or URL, including the leading dot.
|
|
23283
|
+
* @param url - The URL or filename to extract the extension from.
|
|
23284
|
+
* @returns The extension string (e.g. ".glb"), or empty string if none found.
|
|
23285
|
+
*/
|
|
23286
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
23287
|
+
function _getExtension(url) {
|
|
23288
|
+
const clean = url.split("?")[0].split("#")[0];
|
|
23289
|
+
const lastDot = clean.lastIndexOf(".");
|
|
23290
|
+
const lastSlash = Math.max(clean.lastIndexOf("/"), clean.lastIndexOf("\\"));
|
|
23291
|
+
if (lastDot > lastSlash && lastDot >= 0) {
|
|
23292
|
+
return clean.substring(lastDot);
|
|
23293
|
+
}
|
|
23294
|
+
return "";
|
|
23295
|
+
}
|
|
23296
|
+
|
|
22799
23297
|
const AnimationGroupLoadingModes = [
|
|
22800
23298
|
{ label: "Clean", value: 0 /* SceneLoaderAnimationGroupLoadingMode.Clean */ },
|
|
22801
23299
|
{ label: "Stop", value: 1 /* SceneLoaderAnimationGroupLoadingMode.Stop */ },
|
|
@@ -23279,6 +23777,143 @@ const UserFeedbackServiceDefinition = {
|
|
|
23279
23777
|
},
|
|
23280
23778
|
};
|
|
23281
23779
|
|
|
23780
|
+
/**
|
|
23781
|
+
* A shared dialog component wrapping Fluent UI Dialog with Babylon conventions.
|
|
23782
|
+
*
|
|
23783
|
+
* @example
|
|
23784
|
+
* ```tsx
|
|
23785
|
+
* <Dialog
|
|
23786
|
+
* open={isOpen}
|
|
23787
|
+
* title="Confirm Action"
|
|
23788
|
+
* onDismiss={() => setIsOpen(false)}
|
|
23789
|
+
* actions={[
|
|
23790
|
+
* { label: "Cancel", onClick: () => setIsOpen(false) },
|
|
23791
|
+
* { label: "Confirm", onClick: handleConfirm, appearance: "primary" },
|
|
23792
|
+
* ]}
|
|
23793
|
+
* >
|
|
23794
|
+
* <Text>Are you sure you want to proceed?</Text>
|
|
23795
|
+
* </Dialog>
|
|
23796
|
+
* ```
|
|
23797
|
+
*
|
|
23798
|
+
* @param props - The dialog props.
|
|
23799
|
+
* @returns The dialog element.
|
|
23800
|
+
*/
|
|
23801
|
+
const Dialog = (props) => {
|
|
23802
|
+
const { open, title, children, actions, onDismiss } = props;
|
|
23803
|
+
return (jsx(Dialog$1, { open: open, modalType: "modal", onOpenChange: (_, data) => {
|
|
23804
|
+
if (!data.open && onDismiss) {
|
|
23805
|
+
onDismiss();
|
|
23806
|
+
}
|
|
23807
|
+
}, children: jsx(DialogSurface, { children: jsxs(DialogBody, { children: [jsx(DialogTitle, { action: onDismiss ? (jsx(DialogTrigger, { action: "close", children: jsx(Button, { appearance: "subtle", "aria-label": "close", icon: DismissRegular }) })) : undefined, children: title }), jsx(DialogContent, { children: children }), actions && actions.length > 0 && (jsx(DialogActions, { children: actions.map((action, index) => (jsx(Button, { appearance: action.appearance ?? "secondary", onClick: action.onClick, label: action.label }, index))) }))] }) }) }));
|
|
23808
|
+
};
|
|
23809
|
+
|
|
23810
|
+
const SmartAssetsPaneKey = "Smart Assets";
|
|
23811
|
+
const SceneFileExtensions = [".glb", ".gltf", ".babylon", ".obj"];
|
|
23812
|
+
const PromptAcceptString = [...SceneFileExtensions, ...Array.from(GetSmartAssetTextureExtensions())].join(",");
|
|
23813
|
+
const useStyles$2 = makeStyles({
|
|
23814
|
+
hiddenInput: {
|
|
23815
|
+
display: "none",
|
|
23816
|
+
},
|
|
23817
|
+
body: {
|
|
23818
|
+
display: "flex",
|
|
23819
|
+
flexDirection: "column",
|
|
23820
|
+
gap: tokens.spacingVerticalS,
|
|
23821
|
+
},
|
|
23822
|
+
keyRow: {
|
|
23823
|
+
display: "flex",
|
|
23824
|
+
gap: tokens.spacingHorizontalXS,
|
|
23825
|
+
},
|
|
23826
|
+
keyLabel: {
|
|
23827
|
+
fontWeight: tokens.fontWeightSemibold,
|
|
23828
|
+
},
|
|
23829
|
+
url: {
|
|
23830
|
+
fontFamily: tokens.fontFamilyMonospace,
|
|
23831
|
+
wordBreak: "break-all",
|
|
23832
|
+
opacity: 0.8,
|
|
23833
|
+
},
|
|
23834
|
+
});
|
|
23835
|
+
const SmartAssetMissingPromptHost = (props) => {
|
|
23836
|
+
const { onAssetSelected } = props;
|
|
23837
|
+
const inputRef = useRef(null);
|
|
23838
|
+
const pendingMissingAssetRef = useRef(null);
|
|
23839
|
+
const [pendingMissingAsset, setPendingMissingAsset] = useState(null);
|
|
23840
|
+
const classes = useStyles$2();
|
|
23841
|
+
const resolvePendingMissingAsset = useCallback((value) => {
|
|
23842
|
+
pendingMissingAssetRef.current?.resolve(value);
|
|
23843
|
+
pendingMissingAssetRef.current = null;
|
|
23844
|
+
setPendingMissingAsset(null);
|
|
23845
|
+
}, []);
|
|
23846
|
+
useEffect(() => {
|
|
23847
|
+
SetInspectorAssetNotFoundPromptHandler(async (keyName, expectedUrl) => await new Promise((resolve) => {
|
|
23848
|
+
const request = { keyName, expectedUrl, resolve };
|
|
23849
|
+
pendingMissingAssetRef.current = request;
|
|
23850
|
+
setPendingMissingAsset(request);
|
|
23851
|
+
}));
|
|
23852
|
+
return () => {
|
|
23853
|
+
SetInspectorAssetNotFoundPromptHandler(null);
|
|
23854
|
+
pendingMissingAssetRef.current?.resolve(null);
|
|
23855
|
+
pendingMissingAssetRef.current = null;
|
|
23856
|
+
};
|
|
23857
|
+
}, []);
|
|
23858
|
+
const onSkip = useCallback(() => {
|
|
23859
|
+
resolvePendingMissingAsset(null);
|
|
23860
|
+
}, [resolvePendingMissingAsset]);
|
|
23861
|
+
const onLocate = useCallback(() => {
|
|
23862
|
+
inputRef.current?.click();
|
|
23863
|
+
}, []);
|
|
23864
|
+
const onFileSelected = useCallback((event) => {
|
|
23865
|
+
const file = event.target.files?.[0] ?? null;
|
|
23866
|
+
resolvePendingMissingAsset(file);
|
|
23867
|
+
event.target.value = "";
|
|
23868
|
+
if (file) {
|
|
23869
|
+
onAssetSelected();
|
|
23870
|
+
}
|
|
23871
|
+
}, [resolvePendingMissingAsset, onAssetSelected]);
|
|
23872
|
+
if (!pendingMissingAsset) {
|
|
23873
|
+
return null;
|
|
23874
|
+
}
|
|
23875
|
+
const shortUrl = pendingMissingAsset.expectedUrl.length > 60 ? "..." + pendingMissingAsset.expectedUrl.slice(-50) : pendingMissingAsset.expectedUrl;
|
|
23876
|
+
return (jsx(Dialog, { open: true, title: "Asset not found", onDismiss: onSkip, actions: [
|
|
23877
|
+
{ label: "Skip", onClick: onSkip },
|
|
23878
|
+
{ label: "Locate File...", appearance: "primary", onClick: onLocate },
|
|
23879
|
+
], children: jsxs("div", { className: classes.body, children: [jsxs("div", { className: classes.keyRow, children: [jsx(Body1, { className: classes.keyLabel, children: "Key:" }), jsx(Body1, { children: pendingMissingAsset.keyName })] }), jsx(Caption1, { className: classes.url, title: pendingMissingAsset.expectedUrl, children: shortUrl }), jsx(Body1, { children: "Locate the file or click Skip to continue without it." }), jsx("input", { ref: inputRef, type: "file", accept: PromptAcceptString, className: classes.hiddenInput, onChange: onFileSelected })] }) }));
|
|
23880
|
+
};
|
|
23881
|
+
/**
|
|
23882
|
+
* Registers the Inspector Smart Asset missing-file prompt host.
|
|
23883
|
+
*/
|
|
23884
|
+
const SmartAssetPromptServiceDefinition = {
|
|
23885
|
+
friendlyName: "Smart Asset Prompt Service",
|
|
23886
|
+
consumes: [ShellServiceIdentity, SceneContextIdentity],
|
|
23887
|
+
factory: (shellService, sceneContext) => {
|
|
23888
|
+
const focusSmartAssetsPane = () => {
|
|
23889
|
+
shellService.sidePanes.find((pane) => pane.key === SmartAssetsPaneKey)?.select();
|
|
23890
|
+
};
|
|
23891
|
+
const registration = shellService.addCentralContent({
|
|
23892
|
+
key: "Smart Asset Missing Prompt",
|
|
23893
|
+
component: () => jsx(SmartAssetMissingPromptHost, { onAssetSelected: focusSmartAssetsPane }),
|
|
23894
|
+
order: 1000,
|
|
23895
|
+
});
|
|
23896
|
+
let restoreHandler = null;
|
|
23897
|
+
const installForCurrentScene = () => {
|
|
23898
|
+
restoreHandler?.();
|
|
23899
|
+
restoreHandler = null;
|
|
23900
|
+
const currentScene = sceneContext.currentScene;
|
|
23901
|
+
if (currentScene) {
|
|
23902
|
+
restoreHandler = installInspectorAssetNotFoundHandler(GetSmartAssetManager(currentScene));
|
|
23903
|
+
}
|
|
23904
|
+
};
|
|
23905
|
+
installForCurrentScene();
|
|
23906
|
+
const sceneObserver = sceneContext.currentSceneObservable.add(installForCurrentScene);
|
|
23907
|
+
return {
|
|
23908
|
+
dispose: () => {
|
|
23909
|
+
registration.dispose();
|
|
23910
|
+
sceneObserver.remove();
|
|
23911
|
+
restoreHandler?.();
|
|
23912
|
+
},
|
|
23913
|
+
};
|
|
23914
|
+
},
|
|
23915
|
+
};
|
|
23916
|
+
|
|
23282
23917
|
// TODO: The key should probably be the Canvas, because we only want to show one inspector instance per canvas.
|
|
23283
23918
|
// If it is called for a different scene that is rendering to the same canvas, then we should probably
|
|
23284
23919
|
// switch the inspector instance to that scene (once this is supported).
|
|
@@ -23461,7 +24096,7 @@ function ShowInspector(scene, options = {}) {
|
|
|
23461
24096
|
// Stats pane tab and related services.
|
|
23462
24097
|
StatsServiceDefinition,
|
|
23463
24098
|
// Tools pane tab and related services.
|
|
23464
|
-
ToolsServiceDefinition, ExportServiceDefinition, GLTFAnimationImportServiceDefinition, GLTFLoaderOptionsServiceDefinition, GLTFValidationServiceDefinition, CaptureToolsDefinition,
|
|
24099
|
+
ToolsServiceDefinition, ExportServiceDefinition, SmartAssetPromptServiceDefinition, SmartAssetsServiceDefinition, GLTFAnimationImportServiceDefinition, GLTFLoaderOptionsServiceDefinition, GLTFValidationServiceDefinition, CaptureToolsDefinition,
|
|
23465
24100
|
// Settings pane tab and related services.
|
|
23466
24101
|
SettingsServiceDefinition, InspectorSettingsServiceDefinition, WatcherSettingsServiceDefinition, ShellSettingsServiceDefinition,
|
|
23467
24102
|
// Adds a button to refresh all properties manually (when watcher is in "manual" mode).
|
|
@@ -24322,5 +24957,5 @@ const TextAreaPropertyLine = (props) => {
|
|
|
24322
24957
|
// Attach Inspector v2 to Scene.debugLayer as a side effect for back compat.
|
|
24323
24958
|
AttachDebugLayer();
|
|
24324
24959
|
|
|
24325
|
-
export { GetPropertyDescriptor as $, Accordion as A, Button as B, CheckboxPropertyLine as C, Color4PropertyLine as D, ColorPickerPopup as E, ColorStepGradientComponent as F, ComboBox as G, ComboBoxPropertyLine as H, ConstructorFactory as I, ConvertOptions as J, DebugServiceIdentity as K, Link as L, MessageBar as M, NumberInputPropertyLine as N, DetachDebugLayer as O, Popover as P, DraggableLine as Q, Dropdown as R, ShellServiceIdentity as S, TextInputPropertyLine as T, EntitySelector as U, Vector3PropertyLine as V, ErrorBoundary as W, ExtensibleAccordion as X, FactorGradientComponent as Y, FactorGradientList as Z, FileUploadLine as _, useToast as a, ThemeServiceIdentity as a$, GizmoServiceIdentity as a0, HexPropertyLine as a1, InfoLabel as a2, InputHexField as a3, InputHsvField as a4, Inspector as a5, InterceptFunction as a6, InterceptProperty as a7, IsPropertyReadonly as a8, LineContainer as a9, SearchBox as aA, SelectionServiceDefinition as aB, SettingsServiceIdentity as aC, SettingsStore as aD, SettingsStoreIdentity as aE, ShowInspector as aF, SidePaneContainer as aG, SkeletonSelector as aH, Slider as aI, SpinButton as aJ, StartInspectable as aK, StatsServiceIdentity as aL, StringDropdown as aM, StringDropdownPropertyLine as aN, StringifiedPropertyLine as aO, Switch as aP, SwitchPropertyLine as aQ, SyncedSliderInput as aR, SyncedSliderPropertyLine as aS, TeachingMoment as aT, TextAreaPropertyLine as aU, TextInput as aV, TextPropertyLine as aW, Textarea as aX, TextureSelector as aY, TextureUpload as aZ, Theme as a_, LinkPropertyLine as aa, LinkToEntityPropertyLine as ab, List as ac, MakeDialogTeachingMoment as ad, MakeLazyComponent as ae, MakeModularBridge as af, MakeModularTool as ag, MakePopoverTeachingMoment as ah, MakePropertyHook as ai, MakeTeachingMoment as aj, MaterialSelector as ak, NodeSelector as al, NumberDropdown as am, NumberDropdownPropertyLine as an, ObservableCollection as ao, Pane as ap, PlaceholderPropertyLine as aq, PositionedPopover as ar, PropertiesServiceIdentity as as, Property as at, PropertyContext as au, PropertyLine as av, QuaternionPropertyLine as aw, RotationVectorPropertyLine as ax, SceneExplorerServiceIdentity as ay, SearchBar as az, useInterceptObservable as b, ToastProvider as b0, ToggleButton as b1, Tooltip as b2, UploadButton as b3, Vector2PropertyLine as b4, Vector4PropertyLine as b5, WatcherServiceIdentity as b6,
|
|
24326
|
-
//# sourceMappingURL=index-
|
|
24960
|
+
export { GetPropertyDescriptor as $, Accordion as A, Button as B, CheckboxPropertyLine as C, Color4PropertyLine as D, ColorPickerPopup as E, ColorStepGradientComponent as F, ComboBox as G, ComboBoxPropertyLine as H, ConstructorFactory as I, ConvertOptions as J, DebugServiceIdentity as K, Link as L, MessageBar as M, NumberInputPropertyLine as N, DetachDebugLayer as O, Popover as P, DraggableLine as Q, Dropdown as R, ShellServiceIdentity as S, TextInputPropertyLine as T, EntitySelector as U, Vector3PropertyLine as V, ErrorBoundary as W, ExtensibleAccordion as X, FactorGradientComponent as Y, FactorGradientList as Z, FileUploadLine as _, useToast as a, ThemeServiceIdentity as a$, GizmoServiceIdentity as a0, HexPropertyLine as a1, InfoLabel as a2, InputHexField as a3, InputHsvField as a4, Inspector as a5, InterceptFunction as a6, InterceptProperty as a7, IsPropertyReadonly as a8, LineContainer as a9, SearchBox as aA, SelectionServiceDefinition as aB, SettingsServiceIdentity as aC, SettingsStore as aD, SettingsStoreIdentity as aE, ShowInspector as aF, SidePaneContainer as aG, SkeletonSelector as aH, Slider as aI, SpinButton as aJ, StartInspectable as aK, StatsServiceIdentity as aL, StringDropdown as aM, StringDropdownPropertyLine as aN, StringifiedPropertyLine as aO, Switch as aP, SwitchPropertyLine as aQ, SyncedSliderInput as aR, SyncedSliderPropertyLine as aS, TeachingMoment as aT, TextAreaPropertyLine as aU, TextInput as aV, TextPropertyLine as aW, Textarea as aX, TextureSelector as aY, TextureUpload as aZ, Theme as a_, LinkPropertyLine as aa, LinkToEntityPropertyLine as ab, List as ac, MakeDialogTeachingMoment as ad, MakeLazyComponent as ae, MakeModularBridge as af, MakeModularTool as ag, MakePopoverTeachingMoment as ah, MakePropertyHook as ai, MakeTeachingMoment as aj, MaterialSelector as ak, NodeSelector as al, NumberDropdown as am, NumberDropdownPropertyLine as an, ObservableCollection as ao, Pane as ap, PlaceholderPropertyLine as aq, PositionedPopover as ar, PropertiesServiceIdentity as as, Property as at, PropertyContext as au, PropertyLine as av, QuaternionPropertyLine as aw, RotationVectorPropertyLine as ax, SceneExplorerServiceIdentity as ay, SearchBar as az, useInterceptObservable as b, ToastProvider as b0, ToggleButton as b1, Tooltip as b2, UploadButton as b3, Vector2PropertyLine as b4, Vector4PropertyLine as b5, WatcherServiceIdentity as b6, inspectorAssetNotFoundHandler as b7, useAngleConverters as b8, useAsyncResource as b9, useColor3Property as ba, useColor4Property as bb, useEventListener as bc, useEventfulState as bd, useKeyListener as be, useKeyState as bf, useObservableCollection as bg, useOrderedObservableCollection as bh, usePollingObservable as bi, usePropertyChangedNotifier as bj, useQuaternionProperty as bk, useResource as bl, useTheme as bm, useThemeMode as bn, useVector3Property as bo, 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, BridgeCommandRegistryIdentity as p, BuiltInsExtensionFeed as q, Checkbox as r, ChildWindow as s, Collapse as t, useExtensionManager as u, Color3GradientComponent as v, Color3GradientList as w, Color3PropertyLine as x, Color4GradientComponent as y, Color4GradientList as z };
|
|
24961
|
+
//# sourceMappingURL=index-PYblOaAV.js.map
|