@babylonjs/inspector 8.36.1 → 8.37.0-preview
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/captureService-DF30oxR-.js +192 -0
- package/lib/captureService-DF30oxR-.js.map +1 -0
- package/lib/exportService-BB4L49R4.js +242 -0
- package/lib/exportService-BB4L49R4.js.map +1 -0
- package/lib/extensionsListService-DcpjIM_c.js +327 -0
- package/lib/extensionsListService-DcpjIM_c.js.map +1 -0
- package/lib/importService-DEe18q7F.js +174 -0
- package/lib/importService-DEe18q7F.js.map +1 -0
- package/lib/index-B-XOu4uI.js +9862 -0
- package/lib/index-B-XOu4uI.js.map +1 -0
- package/lib/index.d.ts +71949 -0
- package/lib/index.js +110 -0
- package/lib/index.js.map +1 -0
- package/package.json +20 -36
- package/readme.md +14 -17
- package/dist/babylon.inspector.bundle.js +0 -3
- package/dist/babylon.inspector.bundle.js.LICENSE.txt +0 -72
- package/dist/babylon.inspector.bundle.js.map +0 -1
- package/dist/babylon.inspector.bundle.max.js +0 -3
- package/dist/babylon.inspector.module.d.ts +0 -9225
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { makeStyles, Dialog, DialogTrigger, Tooltip, Button, DialogSurface, DialogBody, DialogTitle, TabList, Tab, DialogContent, Accordion, tokens, AccordionItem, AccordionHeader, Body1Strong, PresenceBadge, AccordionPanel, Card, CardHeader, Caption1, Body1, CardPreview, Persona, AvatarGroup, AvatarGroupItem, CardFooter, Spinner, Popover, PopoverTrigger, PopoverSurface } from '@fluentui/react-components';
|
|
3
|
+
import { AppsAddInRegular, DismissRegular, LinkRegular, BranchForkRegular, BugRegular, ArrowDownloadRegular, DeleteRegular, MailRegular, PeopleCommunityRegular } from '@fluentui/react-icons';
|
|
4
|
+
import { Fade } from '@fluentui/react-motion-components-preview';
|
|
5
|
+
import { useState, useEffect, memo, useMemo, useCallback } from 'react';
|
|
6
|
+
import { Logger } from '@babylonjs/core/Misc/logger.js';
|
|
7
|
+
import { b as ShellServiceIdentity, u as useExtensionManager, c as MakePopoverTeachingMoment, d as TeachingMoment, L as Link } from './index-B-XOu4uI.js';
|
|
8
|
+
import '@babylonjs/core/Maths/math.color.js';
|
|
9
|
+
import '@babylonjs/core/Maths/math.vector.js';
|
|
10
|
+
import '@babylonjs/core/Misc/observable.js';
|
|
11
|
+
import '@babylonjs/core/Misc/typeStore.js';
|
|
12
|
+
import 'usehooks-ts';
|
|
13
|
+
import '@babylonjs/core/Misc/asyncLock.js';
|
|
14
|
+
import '@babylonjs/core/Misc/deferred.js';
|
|
15
|
+
import '@babylonjs/core/Maths/math.scalar.functions.js';
|
|
16
|
+
import '@fluentui-contrib/react-virtualizer';
|
|
17
|
+
import '@babylonjs/addons/msdfText/fontAsset.js';
|
|
18
|
+
import '@babylonjs/addons/msdfText/textRenderer.js';
|
|
19
|
+
import '@babylonjs/core/Debug/physicsViewer.js';
|
|
20
|
+
import '@babylonjs/core/Materials/Textures/texture.js';
|
|
21
|
+
import '@babylonjs/core/Materials/materialFlags.js';
|
|
22
|
+
import '@babylonjs/core/Materials/standardMaterial.js';
|
|
23
|
+
import '@babylonjs/core/Meshes/Builders/groundBuilder.js';
|
|
24
|
+
import '@babylonjs/core/Misc/tools.js';
|
|
25
|
+
import '@babylonjs/core/Rendering/utilityLayerRenderer.js';
|
|
26
|
+
import '@babylonjs/materials/grid/gridMaterial.js';
|
|
27
|
+
import '@babylonjs/core/Misc/dataStorage.js';
|
|
28
|
+
import '@babylonjs/core/Instrumentation/engineInstrumentation.js';
|
|
29
|
+
import '@babylonjs/core/Instrumentation/sceneInstrumentation.js';
|
|
30
|
+
import '@babylonjs/core/Engines/AbstractEngine/abstractEngine.timeQuery.js';
|
|
31
|
+
import '@babylonjs/core/Engines/Extensions/engine.query.js';
|
|
32
|
+
import '@babylonjs/core/Engines/WebGPU/Extensions/engine.query.js';
|
|
33
|
+
import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerCollectionStrategies.js';
|
|
34
|
+
import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerSceneExtension.js';
|
|
35
|
+
import '@babylonjs/core/Misc/pressureObserverWrapper.js';
|
|
36
|
+
import '@babylonjs/core/Engines/abstractEngine.js';
|
|
37
|
+
import 'react-dom/client';
|
|
38
|
+
import '@babylonjs/core/FrameGraph/frameGraphUtils.js';
|
|
39
|
+
import '@babylonjs/core/Gizmos/cameraGizmo.js';
|
|
40
|
+
import '@babylonjs/core/Gizmos/lightGizmo.js';
|
|
41
|
+
import '@babylonjs/core/Bones/bone.js';
|
|
42
|
+
import '@babylonjs/core/Cameras/camera.js';
|
|
43
|
+
import '@babylonjs/core/Gizmos/gizmoManager.js';
|
|
44
|
+
import '@babylonjs/core/Lights/light.js';
|
|
45
|
+
import '@babylonjs/core/Meshes/abstractMesh.js';
|
|
46
|
+
import '@babylonjs/core/node.js';
|
|
47
|
+
import '@babylonjs/core/Animations/animationGroup.js';
|
|
48
|
+
import '@babylonjs/core/Animations/animationPropertiesOverride.js';
|
|
49
|
+
import '@babylonjs/addons/atmosphere/atmosphere.js';
|
|
50
|
+
import '@babylonjs/core/Cameras/arcRotateCamera.js';
|
|
51
|
+
import '@babylonjs/core/Cameras/followCamera.js';
|
|
52
|
+
import '@babylonjs/core/Cameras/freeCamera.js';
|
|
53
|
+
import '@babylonjs/core/Cameras/targetCamera.js';
|
|
54
|
+
import '@babylonjs/core/scene.js';
|
|
55
|
+
import '@babylonjs/core/FrameGraph/frameGraph.js';
|
|
56
|
+
import '@babylonjs/core/Lights/directionalLight.js';
|
|
57
|
+
import '@babylonjs/core/Lights/hemisphericLight.js';
|
|
58
|
+
import '@babylonjs/core/Lights/pointLight.js';
|
|
59
|
+
import '@babylonjs/core/Lights/rectAreaLight.js';
|
|
60
|
+
import '@babylonjs/core/Lights/shadowLight.js';
|
|
61
|
+
import '@babylonjs/core/Lights/spotLight.js';
|
|
62
|
+
import '@babylonjs/core/Lights/Shadows/cascadedShadowGenerator.js';
|
|
63
|
+
import '@babylonjs/core/Lights/Shadows/shadowGenerator.js';
|
|
64
|
+
import '@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent.js';
|
|
65
|
+
import '@babylonjs/core/Materials/material.js';
|
|
66
|
+
import '@babylonjs/core/Materials/multiMaterial.js';
|
|
67
|
+
import '@babylonjs/core/Materials/PBR/pbrBaseMaterial.js';
|
|
68
|
+
import '@babylonjs/core/Materials/PBR/pbrBaseSimpleMaterial.js';
|
|
69
|
+
import '@babylonjs/core/Materials/PBR/pbrMaterial.js';
|
|
70
|
+
import '@babylonjs/core/Materials/PBR/openpbrMaterial.js';
|
|
71
|
+
import '@babylonjs/materials/sky/skyMaterial.js';
|
|
72
|
+
import '@babylonjs/core/Engines/constants.js';
|
|
73
|
+
import '@babylonjs/core/Engines/engine.js';
|
|
74
|
+
import '@babylonjs/core/Particles/particleSystem.js';
|
|
75
|
+
import '@babylonjs/core/Misc/fileTools.js';
|
|
76
|
+
import '@babylonjs/core/Meshes/mesh.js';
|
|
77
|
+
import '@babylonjs/core/Debug/skeletonViewer.js';
|
|
78
|
+
import '@babylonjs/core/Meshes/buffer.js';
|
|
79
|
+
import '@babylonjs/core/Meshes/Builders/linesBuilder.js';
|
|
80
|
+
import '@babylonjs/core/Meshes/instancedMesh.js';
|
|
81
|
+
import '@babylonjs/core/Rendering/renderingManager.js';
|
|
82
|
+
import '@babylonjs/core/Rendering/edgesRenderer.js';
|
|
83
|
+
import '@babylonjs/core/Rendering/outlineRenderer.js';
|
|
84
|
+
import '@babylonjs/core/Meshes/GaussianSplatting/gaussianSplattingMesh.js';
|
|
85
|
+
import '@babylonjs/core/Misc/gradients.js';
|
|
86
|
+
import '@babylonjs/core/Materials/Node/Blocks/gradientBlock.js';
|
|
87
|
+
import '@babylonjs/core/Particles/attractor.js';
|
|
88
|
+
import '@babylonjs/core/Meshes/Builders/sphereBuilder.js';
|
|
89
|
+
import '@babylonjs/core/Meshes/transformNode.js';
|
|
90
|
+
import '@babylonjs/core/Physics/v2/IPhysicsEnginePlugin.js';
|
|
91
|
+
import '@babylonjs/core/Physics/v2/physicsEngineComponent.js';
|
|
92
|
+
import '@babylonjs/core/PostProcesses/postProcess.js';
|
|
93
|
+
import '@babylonjs/core/Materials/Textures/cubeTexture.js';
|
|
94
|
+
import '@babylonjs/core/Materials/imageProcessingConfiguration.js';
|
|
95
|
+
import '@babylonjs/core/Bones/skeleton.js';
|
|
96
|
+
import '@babylonjs/core/Sprites/sprite.js';
|
|
97
|
+
import '@babylonjs/core/Sprites/spriteManager.js';
|
|
98
|
+
import '@babylonjs/core/Materials/Textures/baseTexture.js';
|
|
99
|
+
import '@babylonjs/core/Materials/Textures/multiRenderTarget.js';
|
|
100
|
+
import '@babylonjs/core/Materials/Textures/renderTargetTexture.js';
|
|
101
|
+
import '@babylonjs/core/Materials/Textures/thinTexture.js';
|
|
102
|
+
import '@babylonjs/core/Misc/textureTools.js';
|
|
103
|
+
import '@babylonjs/core/Rendering/boundingBoxRenderer.js';
|
|
104
|
+
import '@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.js';
|
|
105
|
+
import '@babylonjs/core/Sprites/spriteSceneComponent.js';
|
|
106
|
+
import '@babylonjs/core/Materials/Textures/dynamicTexture.js';
|
|
107
|
+
import '@babylonjs/core/Events/pointerEvents.js';
|
|
108
|
+
import '@babylonjs/core/Engines/engineStore.js';
|
|
109
|
+
import '@babylonjs/core/Misc/uniqueIdGenerator.js';
|
|
110
|
+
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
112
|
+
const useStyles = makeStyles({
|
|
113
|
+
extensionButton: {},
|
|
114
|
+
extensionsDialogSurface: {
|
|
115
|
+
height: "auto",
|
|
116
|
+
width: "70vw",
|
|
117
|
+
maxWidth: "600px",
|
|
118
|
+
maxHeight: "70vh",
|
|
119
|
+
backgroundColor: tokens.colorNeutralBackground2,
|
|
120
|
+
},
|
|
121
|
+
extensionDialogBody: {
|
|
122
|
+
maxWidth: "100%",
|
|
123
|
+
maxHeight: "100%",
|
|
124
|
+
},
|
|
125
|
+
extensionDialogContent: {
|
|
126
|
+
marginLeft: `calc(-1 * ${tokens.spacingHorizontalM})`,
|
|
127
|
+
marginRight: `calc(-1 * ${tokens.spacingHorizontalS})`,
|
|
128
|
+
},
|
|
129
|
+
extensionHeader: {},
|
|
130
|
+
extensionItem: {},
|
|
131
|
+
extensionCardPreview: {
|
|
132
|
+
padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
|
|
133
|
+
display: "flex",
|
|
134
|
+
flexDirection: "column",
|
|
135
|
+
rowGap: tokens.spacingVerticalL,
|
|
136
|
+
},
|
|
137
|
+
extensionIntro: {
|
|
138
|
+
display: "flex",
|
|
139
|
+
alignItems: "center",
|
|
140
|
+
columnGap: tokens.spacingHorizontalM,
|
|
141
|
+
},
|
|
142
|
+
extensionDescription: {
|
|
143
|
+
display: "flex",
|
|
144
|
+
flexDirection: "row",
|
|
145
|
+
columnGap: tokens.spacingHorizontalS,
|
|
146
|
+
},
|
|
147
|
+
extensionButtonContainer: {
|
|
148
|
+
marginLeft: "auto",
|
|
149
|
+
alignSelf: "flex-start",
|
|
150
|
+
},
|
|
151
|
+
spinner: {
|
|
152
|
+
animationDuration: "1s",
|
|
153
|
+
animationName: {
|
|
154
|
+
from: { opacity: 0 },
|
|
155
|
+
to: { opacity: 1 },
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
webResourceDiv: {
|
|
159
|
+
display: "flex",
|
|
160
|
+
flexDirection: "column",
|
|
161
|
+
},
|
|
162
|
+
webResourceLink: {
|
|
163
|
+
display: "flex",
|
|
164
|
+
flexDirection: "row",
|
|
165
|
+
columnGap: tokens.spacingHorizontalS,
|
|
166
|
+
alignItems: "center",
|
|
167
|
+
},
|
|
168
|
+
personPopoverSurfaceDiv: {
|
|
169
|
+
display: "flex",
|
|
170
|
+
flexDirection: "column",
|
|
171
|
+
rowGap: tokens.spacingVerticalS,
|
|
172
|
+
},
|
|
173
|
+
accordionHeaderDiv: {
|
|
174
|
+
display: "flex",
|
|
175
|
+
flexDirection: "row",
|
|
176
|
+
columnGap: tokens.spacingHorizontalS,
|
|
177
|
+
alignItems: "center",
|
|
178
|
+
},
|
|
179
|
+
resourceDetailsDiv: {
|
|
180
|
+
display: "flex",
|
|
181
|
+
flexDirection: "column",
|
|
182
|
+
rowGap: tokens.spacingVerticalS,
|
|
183
|
+
},
|
|
184
|
+
peopleDetailsDiv: {
|
|
185
|
+
display: "flex",
|
|
186
|
+
flexDirection: "row",
|
|
187
|
+
columnGap: tokens.spacingHorizontalXL,
|
|
188
|
+
},
|
|
189
|
+
avatarGroupItem: {
|
|
190
|
+
cursor: "pointer",
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
function AsPersonMetadata(person) {
|
|
194
|
+
if (typeof person === "string") {
|
|
195
|
+
return { name: person };
|
|
196
|
+
}
|
|
197
|
+
return person;
|
|
198
|
+
}
|
|
199
|
+
function usePeopleMetadata(people) {
|
|
200
|
+
const definedPeople = useMemo(() => (people ? people.filter((person) => !!person) : []), [people]);
|
|
201
|
+
//const [peopleMetadataEx, setPeopleMetadataEx] = useState<(PersonMetadata & { avatarUrl?: string })[]>(definedPeople.map(AsPersonMetadata));
|
|
202
|
+
const [peopleMetadataEx] = useState(definedPeople.map(AsPersonMetadata));
|
|
203
|
+
// TODO: Would be nice if we could pull author/contributor profile pictures from the forum, but need to see if this is ok and whether we want to adjust CORS to allow it.
|
|
204
|
+
// useEffect(() => {
|
|
205
|
+
// definedPeople.forEach(async (person, index) => {
|
|
206
|
+
// const personMetadata = AsPersonMetadata(person);
|
|
207
|
+
// if (personMetadata.forumUserName) {
|
|
208
|
+
// try {
|
|
209
|
+
// const json = await (await fetch(`https://forum.babylonjs.com/u/${personMetadata.forumUserName}.json`)).json();
|
|
210
|
+
// const avatarRelativeUrl = json.user?.avatar_template?.replace("{size}", "96");
|
|
211
|
+
// if (avatarRelativeUrl) {
|
|
212
|
+
// const avatarUrl = `https://forum.babylonjs.com${avatarRelativeUrl}`;
|
|
213
|
+
// setPeopleMetadataEx((prev) => {
|
|
214
|
+
// const newMetadata = [...prev];
|
|
215
|
+
// newMetadata[index] = { ...personMetadata, avatarUrl };
|
|
216
|
+
// return newMetadata;
|
|
217
|
+
// });
|
|
218
|
+
// }
|
|
219
|
+
// } catch {
|
|
220
|
+
// // Ignore, non-fatal
|
|
221
|
+
// }
|
|
222
|
+
// }
|
|
223
|
+
// });
|
|
224
|
+
// }, [definedPeople]);
|
|
225
|
+
return peopleMetadataEx.filter(Boolean);
|
|
226
|
+
}
|
|
227
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
228
|
+
const useTeachingMoment = MakePopoverTeachingMoment("Extensions");
|
|
229
|
+
const WebResource = (props) => {
|
|
230
|
+
const { url, urlDisplay, icon, label } = props;
|
|
231
|
+
const classes = useStyles();
|
|
232
|
+
return (jsx("div", { className: classes.webResourceDiv, children: jsx(Tooltip, { content: label, relationship: "label", positioning: "before", withArrow: true, children: jsxs("div", { className: classes.webResourceLink, children: [icon, jsx(Link, { url: url, value: urlDisplay || url })] }) }) }));
|
|
233
|
+
};
|
|
234
|
+
const PersonDetailsPopover = (props) => {
|
|
235
|
+
const { person, title, disabled, children } = props;
|
|
236
|
+
const classes = useStyles();
|
|
237
|
+
if (disabled) {
|
|
238
|
+
return jsx(Fragment, { children: children });
|
|
239
|
+
}
|
|
240
|
+
return (jsxs(Popover, { withArrow: true, children: [jsx(PopoverTrigger, { disableButtonEnhancement: true, children: children }), jsx(PopoverSurface, { children: jsxs("div", { className: classes.personPopoverSurfaceDiv, children: [jsx(Persona, { name: person.name, secondaryText: title }), person.email && jsx(WebResource, { url: `mailto:${person.email}`, urlDisplay: person.email, icon: jsx(MailRegular, {}), label: "Email" }), person.url && jsx(WebResource, { url: person.url, urlDisplay: person.url, icon: jsx(LinkRegular, {}), label: "Website" }), person.forumUserName && (jsx(WebResource, { url: `https://forum.babylonjs.com/u/${person.forumUserName}`, urlDisplay: person.forumUserName, icon: jsx(PeopleCommunityRegular, {}), label: "Forum" }))] }) })] }));
|
|
241
|
+
};
|
|
242
|
+
const ExtensionDetails = memo((props) => {
|
|
243
|
+
const { extension } = props;
|
|
244
|
+
const { metadata } = extension;
|
|
245
|
+
const classes = useStyles();
|
|
246
|
+
const [canInstall, setCanInstall] = useState(false);
|
|
247
|
+
const [canUninstall, setCanUninstall] = useState(false);
|
|
248
|
+
const [isStateChanging, setIsStateChanging] = useState(false);
|
|
249
|
+
useEffect(() => {
|
|
250
|
+
const updateState = () => {
|
|
251
|
+
setCanInstall(!extension.isInstalled && !extension.isStateChanging);
|
|
252
|
+
setCanUninstall(extension.isInstalled && !extension.isStateChanging);
|
|
253
|
+
setIsStateChanging(extension.isStateChanging);
|
|
254
|
+
};
|
|
255
|
+
const stateChangedHandlerRegistration = extension.addStateChangedHandler(updateState);
|
|
256
|
+
updateState();
|
|
257
|
+
return stateChangedHandlerRegistration.dispose;
|
|
258
|
+
}, [extension]);
|
|
259
|
+
const [author] = usePeopleMetadata(useMemo(() => [metadata.author], [metadata.author]));
|
|
260
|
+
const contributors = usePeopleMetadata(metadata.contributors);
|
|
261
|
+
const hasResourceDetails = metadata.homepage || metadata.repository || metadata.bugs;
|
|
262
|
+
const hasPeopleDetails = author || contributors.length > 0;
|
|
263
|
+
const hasPreviewDetails = hasResourceDetails || hasPeopleDetails;
|
|
264
|
+
const hasAuthorDetails = author?.email || author?.url || author?.forumUserName;
|
|
265
|
+
const subHeader = [metadata.version ? `${metadata.version}` : null, metadata.license ? `${metadata.license}` : null].filter(Boolean).join(" | ");
|
|
266
|
+
const install = useCallback(async () => {
|
|
267
|
+
try {
|
|
268
|
+
await extension.installAsync();
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
// Ignore errors. Other parts of the infrastructure handle them and communicate them to the user.
|
|
272
|
+
}
|
|
273
|
+
}, [extension]);
|
|
274
|
+
const uninstall = useCallback(async () => {
|
|
275
|
+
try {
|
|
276
|
+
await extension.uninstallAsync();
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
// Ignore errors. Other parts of the infrastructure handle them and communicate them to the user.
|
|
280
|
+
}
|
|
281
|
+
}, [extension]);
|
|
282
|
+
return (jsxs(AccordionItem, { className: classes.extensionItem, value: extension.metadata.name, children: [jsx(AccordionHeader, { className: classes.extensionHeader, expandIconPosition: "end", children: jsxs("div", { className: classes.accordionHeaderDiv, children: [jsx(Body1Strong, { children: extension.metadata.name }), jsx(Fade, { visible: extension.isInstalled, children: jsx(PresenceBadge, { size: "small" }) })] }) }), jsx(AccordionPanel, { children: jsxs(Card, { children: [jsx(CardHeader, { header: jsx(Body1, { children: metadata.description }), description: jsx(Caption1, { italic: true, children: subHeader }) }), hasPreviewDetails && (jsxs(CardPreview, { className: classes.extensionCardPreview, children: [hasResourceDetails && (jsxs("div", { className: classes.resourceDetailsDiv, style: { display: "flex" }, children: [metadata.homepage && jsx(WebResource, { url: metadata.homepage, icon: jsx(LinkRegular, {}), label: "Website" }), metadata.repository && jsx(WebResource, { url: metadata.repository, icon: jsx(BranchForkRegular, {}), label: "Repository" }), metadata.bugs && jsx(WebResource, { url: metadata.bugs, icon: jsx(BugRegular, {}), label: "Report Issues" })] })), hasPeopleDetails && (jsxs("div", { className: classes.peopleDetailsDiv, style: { display: "flex" }, children: [author && (jsx(PersonDetailsPopover, { person: author, title: "Author", disabled: !hasAuthorDetails, children: jsx(Persona, { name: author.name, secondaryText: "Author", style: { cursor: hasAuthorDetails ? "pointer" : "default" } }) })), contributors.length > 0 && (jsx(AvatarGroup, { layout: "stack", children: contributors.map((contributor) => {
|
|
283
|
+
return (jsx(PersonDetailsPopover, { person: contributor, title: "Contributor", children: jsx(AvatarGroupItem, { name: contributor.name, className: classes.avatarGroupItem }) }, contributor.name));
|
|
284
|
+
}) }))] }))] })), jsxs(CardFooter, { children: [canInstall && (jsx(Button, { appearance: "primary", size: "small", icon: jsx(ArrowDownloadRegular, {}), onClick: install, children: "Get" })), canUninstall && (jsx(Button, { appearance: "secondary", size: "small", icon: jsx(DeleteRegular, {}), onClick: uninstall, children: "Remove" })), isStateChanging && jsx(Spinner, { className: classes.spinner, size: "extra-small" })] })] }) })] }));
|
|
285
|
+
});
|
|
286
|
+
const ExtensionListServiceDefinition = {
|
|
287
|
+
friendlyName: "ExtensionList",
|
|
288
|
+
consumes: [ShellServiceIdentity],
|
|
289
|
+
factory: (shellService) => {
|
|
290
|
+
const registration = shellService.addToolbarItem({
|
|
291
|
+
key: "ExtensionList",
|
|
292
|
+
horizontalLocation: "right",
|
|
293
|
+
verticalLocation: "top",
|
|
294
|
+
suppressTeachingMoment: true,
|
|
295
|
+
order: -200,
|
|
296
|
+
component: () => {
|
|
297
|
+
const classes = useStyles();
|
|
298
|
+
const [selectedTab, setSelectedTab] = useState("available");
|
|
299
|
+
const extensionManager = useExtensionManager();
|
|
300
|
+
const [extensions, setExtensions] = useState([]);
|
|
301
|
+
useEffect(() => {
|
|
302
|
+
if (extensionManager) {
|
|
303
|
+
const populateExtensionsAsync = async () => {
|
|
304
|
+
const query = await extensionManager.queryExtensionsAsync(undefined, undefined, selectedTab === "installed");
|
|
305
|
+
const extensions = await query.getExtensionsAsync(0, query.totalCount);
|
|
306
|
+
setExtensions(extensions);
|
|
307
|
+
};
|
|
308
|
+
// eslint-disable-next-line github/no-then
|
|
309
|
+
populateExtensionsAsync().catch((error) => {
|
|
310
|
+
Logger.Warn(`Failed to populate extensions: ${error}`);
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}, [extensionManager, selectedTab]);
|
|
314
|
+
const teachingMoment = useTeachingMoment();
|
|
315
|
+
return (jsxs(Fragment, { children: [jsx(TeachingMoment, { ...teachingMoment, title: "Extensions", description: "Extensions provide new optional features that can be useful to your specific task or workflow. Click this button to manage extensions." }), jsxs(Dialog, { children: [jsx(DialogTrigger, { disableButtonEnhancement: true, children: jsx(Tooltip, { content: "Manage Extensions", relationship: "label", children: jsx(Button, { ref: teachingMoment.targetRef, className: classes.extensionButton, appearance: "subtle", icon: jsx(AppsAddInRegular, {}) }) }) }), jsx(DialogSurface, { className: classes.extensionsDialogSurface, children: jsxs(DialogBody, { className: classes.extensionDialogBody, children: [jsx(DialogTitle, { action: jsx(DialogTrigger, { action: "close", children: jsx(Button, { appearance: "subtle", "aria-label": "close", icon: jsx(DismissRegular, {}) }) }), children: jsxs(Fragment, { children: ["Extensions", jsxs(TabList, { className: classes.extensionDialogContent, selectedValue: selectedTab, onTabSelect: (event, data) => {
|
|
316
|
+
setSelectedTab(data.value);
|
|
317
|
+
}, children: [jsx(Tab, { value: "available", children: "Available" }), jsx(Tab, { value: "installed", children: "Installed" })] })] }) }), jsx(DialogContent, { className: classes.extensionDialogContent, children: jsx(Accordion, { collapsible: true, children: extensions.map((extension) => (jsx(ExtensionDetails, { extension: extension }, extension.metadata.name))) }) })] }) })] })] }));
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
return {
|
|
321
|
+
dispose: () => registration.dispose(),
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
export { ExtensionListServiceDefinition };
|
|
327
|
+
//# sourceMappingURL=extensionsListService-DcpjIM_c.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensionsListService-DcpjIM_c.js","sources":["../../../../../../../../dev/inspector-v2/src/services/extensionsListService.tsx"],"sourcesContent":["import type { SelectTabData, SelectTabEvent } from \"@fluentui/react-components\";\r\nimport type { TriggerProps } from \"@fluentui/react-utilities\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport type { PersonMetadata } from \"../extensibility/extensionFeed\";\r\nimport type { IExtension } from \"../extensibility/extensionManager\";\r\nimport type { ServiceDefinition } from \"../modularity/serviceDefinition\";\r\nimport type { IShellService } from \"./shellService\";\r\n\r\nimport {\r\n Accordion,\r\n AccordionHeader,\r\n AccordionItem,\r\n AccordionPanel,\r\n AvatarGroup,\r\n AvatarGroupItem,\r\n Body1,\r\n Body1Strong,\r\n Button,\r\n Caption1,\r\n Card,\r\n CardFooter,\r\n CardHeader,\r\n CardPreview,\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogSurface,\r\n DialogTitle,\r\n DialogTrigger,\r\n makeStyles,\r\n Persona,\r\n Popover,\r\n PopoverSurface,\r\n PopoverTrigger,\r\n PresenceBadge,\r\n Spinner,\r\n Tab,\r\n TabList,\r\n tokens,\r\n Tooltip,\r\n} from \"@fluentui/react-components\";\r\nimport {\r\n AppsAddInRegular,\r\n ArrowDownloadRegular,\r\n BranchForkRegular,\r\n BugRegular,\r\n DeleteRegular,\r\n DismissRegular,\r\n LinkRegular,\r\n MailRegular,\r\n PeopleCommunityRegular,\r\n} from \"@fluentui/react-icons\";\r\nimport { Fade } from \"@fluentui/react-motion-components-preview\";\r\nimport { memo, useCallback, useEffect, useMemo, useState } from \"react\";\r\n\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nimport { Link } from \"shared-ui-components/fluent/primitives/link\";\r\nimport { TeachingMoment } from \"../components/teachingMoment\";\r\nimport { useExtensionManager } from \"../contexts/extensionManagerContext\";\r\nimport { MakePopoverTeachingMoment } from \"../hooks/teachingMomentHooks\";\r\nimport { ShellServiceIdentity } from \"./shellService\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst useStyles = makeStyles({\r\n extensionButton: {},\r\n extensionsDialogSurface: {\r\n height: \"auto\",\r\n width: \"70vw\",\r\n maxWidth: \"600px\",\r\n maxHeight: \"70vh\",\r\n backgroundColor: tokens.colorNeutralBackground2,\r\n },\r\n extensionDialogBody: {\r\n maxWidth: \"100%\",\r\n maxHeight: \"100%\",\r\n },\r\n extensionDialogContent: {\r\n marginLeft: `calc(-1 * ${tokens.spacingHorizontalM})`,\r\n marginRight: `calc(-1 * ${tokens.spacingHorizontalS})`,\r\n },\r\n extensionHeader: {},\r\n extensionItem: {},\r\n extensionCardPreview: {\r\n padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n rowGap: tokens.spacingVerticalL,\r\n },\r\n extensionIntro: {\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n columnGap: tokens.spacingHorizontalM,\r\n },\r\n extensionDescription: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n columnGap: tokens.spacingHorizontalS,\r\n },\r\n extensionButtonContainer: {\r\n marginLeft: \"auto\",\r\n alignSelf: \"flex-start\",\r\n },\r\n spinner: {\r\n animationDuration: \"1s\",\r\n animationName: {\r\n from: { opacity: 0 },\r\n to: { opacity: 1 },\r\n },\r\n },\r\n webResourceDiv: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n },\r\n webResourceLink: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n columnGap: tokens.spacingHorizontalS,\r\n alignItems: \"center\",\r\n },\r\n personPopoverSurfaceDiv: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n rowGap: tokens.spacingVerticalS,\r\n },\r\n accordionHeaderDiv: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n columnGap: tokens.spacingHorizontalS,\r\n alignItems: \"center\",\r\n },\r\n resourceDetailsDiv: {\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n rowGap: tokens.spacingVerticalS,\r\n },\r\n peopleDetailsDiv: {\r\n display: \"flex\",\r\n flexDirection: \"row\",\r\n columnGap: tokens.spacingHorizontalXL,\r\n },\r\n avatarGroupItem: {\r\n cursor: \"pointer\",\r\n },\r\n});\r\n\r\nfunction AsPersonMetadata(person: string | PersonMetadata): PersonMetadata {\r\n if (typeof person === \"string\") {\r\n return { name: person } satisfies PersonMetadata;\r\n }\r\n return person;\r\n}\r\n\r\nfunction usePeopleMetadata(people?: readonly (string | PersonMetadata | undefined)[]) {\r\n const definedPeople = useMemo(() => (people ? people.filter((person): person is string | PersonMetadata => !!person) : []), [people]);\r\n\r\n //const [peopleMetadataEx, setPeopleMetadataEx] = useState<(PersonMetadata & { avatarUrl?: string })[]>(definedPeople.map(AsPersonMetadata));\r\n const [peopleMetadataEx] = useState(definedPeople.map(AsPersonMetadata));\r\n\r\n // TODO: Would be nice if we could pull author/contributor profile pictures from the forum, but need to see if this is ok and whether we want to adjust CORS to allow it.\r\n // useEffect(() => {\r\n // definedPeople.forEach(async (person, index) => {\r\n // const personMetadata = AsPersonMetadata(person);\r\n // if (personMetadata.forumUserName) {\r\n // try {\r\n // const json = await (await fetch(`https://forum.babylonjs.com/u/${personMetadata.forumUserName}.json`)).json();\r\n // const avatarRelativeUrl = json.user?.avatar_template?.replace(\"{size}\", \"96\");\r\n // if (avatarRelativeUrl) {\r\n // const avatarUrl = `https://forum.babylonjs.com${avatarRelativeUrl}`;\r\n // setPeopleMetadataEx((prev) => {\r\n // const newMetadata = [...prev];\r\n // newMetadata[index] = { ...personMetadata, avatarUrl };\r\n // return newMetadata;\r\n // });\r\n // }\r\n // } catch {\r\n // // Ignore, non-fatal\r\n // }\r\n // }\r\n // });\r\n // }, [definedPeople]);\r\n\r\n return peopleMetadataEx.filter(Boolean);\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst useTeachingMoment = MakePopoverTeachingMoment(\"Extensions\");\r\n\r\nconst WebResource: FunctionComponent<{ url: string; urlDisplay?: string; icon: JSX.Element; label: string }> = (props) => {\r\n const { url, urlDisplay, icon, label } = props;\r\n const classes = useStyles();\r\n\r\n return (\r\n <div className={classes.webResourceDiv}>\r\n <Tooltip content={label} relationship=\"label\" positioning=\"before\" withArrow>\r\n <div className={classes.webResourceLink}>\r\n {icon}\r\n <Link url={url} value={urlDisplay || url} />\r\n </div>\r\n </Tooltip>\r\n </div>\r\n );\r\n};\r\n\r\nconst PersonDetailsPopover: FunctionComponent<TriggerProps & { person: PersonMetadata; title: string; disabled?: boolean }> = (props) => {\r\n const { person, title, disabled, children } = props;\r\n const classes = useStyles();\r\n\r\n if (disabled) {\r\n return <>{children}</>;\r\n }\r\n\r\n return (\r\n <Popover withArrow>\r\n <PopoverTrigger disableButtonEnhancement>{children}</PopoverTrigger>\r\n <PopoverSurface>\r\n <div className={classes.personPopoverSurfaceDiv}>\r\n <Persona name={person.name} secondaryText={title} />\r\n {person.email && <WebResource url={`mailto:${person.email}`} urlDisplay={person.email} icon={<MailRegular />} label=\"Email\" />}\r\n {person.url && <WebResource url={person.url} urlDisplay={person.url} icon={<LinkRegular />} label=\"Website\" />}\r\n {person.forumUserName && (\r\n <WebResource\r\n url={`https://forum.babylonjs.com/u/${person.forumUserName}`}\r\n urlDisplay={person.forumUserName}\r\n icon={<PeopleCommunityRegular />}\r\n label=\"Forum\"\r\n />\r\n )}\r\n </div>\r\n </PopoverSurface>\r\n </Popover>\r\n );\r\n};\r\n\r\nconst ExtensionDetails: FunctionComponent<{ extension: IExtension }> = memo((props) => {\r\n const { extension } = props;\r\n const { metadata } = extension;\r\n\r\n const classes = useStyles();\r\n\r\n const [canInstall, setCanInstall] = useState(false);\r\n const [canUninstall, setCanUninstall] = useState(false);\r\n const [isStateChanging, setIsStateChanging] = useState(false);\r\n\r\n useEffect(() => {\r\n const updateState = () => {\r\n setCanInstall(!extension.isInstalled && !extension.isStateChanging);\r\n setCanUninstall(extension.isInstalled && !extension.isStateChanging);\r\n setIsStateChanging(extension.isStateChanging);\r\n };\r\n\r\n const stateChangedHandlerRegistration = extension.addStateChangedHandler(updateState);\r\n updateState();\r\n\r\n return stateChangedHandlerRegistration.dispose;\r\n }, [extension]);\r\n\r\n const [author] = usePeopleMetadata(useMemo(() => [metadata.author], [metadata.author]));\r\n const contributors = usePeopleMetadata(metadata.contributors);\r\n\r\n const hasResourceDetails = metadata.homepage || metadata.repository || metadata.bugs;\r\n const hasPeopleDetails = author || contributors.length > 0;\r\n const hasPreviewDetails = hasResourceDetails || hasPeopleDetails;\r\n const hasAuthorDetails = author?.email || author?.url || author?.forumUserName;\r\n const subHeader = [metadata.version ? `${metadata.version}` : null, metadata.license ? `${metadata.license}` : null].filter(Boolean).join(\" | \");\r\n\r\n const install = useCallback(async () => {\r\n try {\r\n await extension.installAsync();\r\n } catch {\r\n // Ignore errors. Other parts of the infrastructure handle them and communicate them to the user.\r\n }\r\n }, [extension]);\r\n\r\n const uninstall = useCallback(async () => {\r\n try {\r\n await extension.uninstallAsync();\r\n } catch {\r\n // Ignore errors. Other parts of the infrastructure handle them and communicate them to the user.\r\n }\r\n }, [extension]);\r\n\r\n return (\r\n <AccordionItem className={classes.extensionItem} value={extension.metadata.name}>\r\n <AccordionHeader className={classes.extensionHeader} expandIconPosition=\"end\">\r\n <div className={classes.accordionHeaderDiv}>\r\n <Body1Strong>{extension.metadata.name}</Body1Strong>\r\n <Fade visible={extension.isInstalled}>\r\n <PresenceBadge size=\"small\" />\r\n </Fade>\r\n </div>\r\n </AccordionHeader>\r\n <AccordionPanel>\r\n <Card>\r\n <CardHeader header={<Body1>{metadata.description}</Body1>} description={<Caption1 italic>{subHeader}</Caption1>} />\r\n {hasPreviewDetails && (\r\n <CardPreview className={classes.extensionCardPreview}>\r\n {hasResourceDetails && (\r\n <div className={classes.resourceDetailsDiv} style={{ display: \"flex\" }}>\r\n {metadata.homepage && <WebResource url={metadata.homepage} icon={<LinkRegular />} label=\"Website\" />}\r\n {metadata.repository && <WebResource url={metadata.repository} icon={<BranchForkRegular />} label=\"Repository\" />}\r\n {metadata.bugs && <WebResource url={metadata.bugs} icon={<BugRegular />} label=\"Report Issues\" />}\r\n </div>\r\n )}\r\n {hasPeopleDetails && (\r\n <div className={classes.peopleDetailsDiv} style={{ display: \"flex\" }}>\r\n {author && (\r\n <PersonDetailsPopover person={author} title=\"Author\" disabled={!hasAuthorDetails}>\r\n <Persona name={author.name} secondaryText=\"Author\" style={{ cursor: hasAuthorDetails ? \"pointer\" : \"default\" }} />\r\n </PersonDetailsPopover>\r\n )}\r\n {contributors.length > 0 && (\r\n <AvatarGroup layout=\"stack\">\r\n {contributors.map((contributor) => {\r\n return (\r\n <PersonDetailsPopover key={contributor.name} person={contributor} title=\"Contributor\">\r\n <AvatarGroupItem name={contributor.name} className={classes.avatarGroupItem} />\r\n </PersonDetailsPopover>\r\n );\r\n })}\r\n </AvatarGroup>\r\n )}\r\n </div>\r\n )}\r\n </CardPreview>\r\n )}\r\n <CardFooter>\r\n {canInstall && (\r\n <Button appearance=\"primary\" size=\"small\" icon={<ArrowDownloadRegular />} onClick={install}>\r\n Get\r\n </Button>\r\n )}\r\n {canUninstall && (\r\n <Button appearance=\"secondary\" size=\"small\" icon={<DeleteRegular />} onClick={uninstall}>\r\n Remove\r\n </Button>\r\n )}\r\n {isStateChanging && <Spinner className={classes.spinner} size=\"extra-small\" />}\r\n </CardFooter>\r\n </Card>\r\n </AccordionPanel>\r\n </AccordionItem>\r\n );\r\n});\r\n\r\ntype TabValue = \"available\" | \"installed\";\r\n\r\nexport const ExtensionListServiceDefinition: ServiceDefinition<[], [IShellService]> = {\r\n friendlyName: \"ExtensionList\",\r\n consumes: [ShellServiceIdentity],\r\n factory: (shellService) => {\r\n const registration = shellService.addToolbarItem({\r\n key: \"ExtensionList\",\r\n horizontalLocation: \"right\",\r\n verticalLocation: \"top\",\r\n suppressTeachingMoment: true,\r\n order: -200,\r\n component: () => {\r\n const classes = useStyles();\r\n\r\n const [selectedTab, setSelectedTab] = useState<TabValue>(\"available\");\r\n const extensionManager = useExtensionManager();\r\n const [extensions, setExtensions] = useState<IExtension[]>([]);\r\n\r\n useEffect(() => {\r\n if (extensionManager) {\r\n const populateExtensionsAsync = async () => {\r\n const query = await extensionManager.queryExtensionsAsync(undefined, undefined, selectedTab === \"installed\");\r\n const extensions = await query.getExtensionsAsync(0, query.totalCount);\r\n setExtensions(extensions);\r\n };\r\n\r\n // eslint-disable-next-line github/no-then\r\n populateExtensionsAsync().catch((error) => {\r\n Logger.Warn(`Failed to populate extensions: ${error}`);\r\n });\r\n }\r\n }, [extensionManager, selectedTab]);\r\n\r\n const teachingMoment = useTeachingMoment();\r\n\r\n return (\r\n <>\r\n <TeachingMoment\r\n {...teachingMoment}\r\n title=\"Extensions\"\r\n description=\"Extensions provide new optional features that can be useful to your specific task or workflow. Click this button to manage extensions.\"\r\n />\r\n <Dialog>\r\n <DialogTrigger disableButtonEnhancement>\r\n <Tooltip content=\"Manage Extensions\" relationship=\"label\">\r\n <Button ref={teachingMoment.targetRef} className={classes.extensionButton} appearance=\"subtle\" icon={<AppsAddInRegular />} />\r\n </Tooltip>\r\n </DialogTrigger>\r\n <DialogSurface className={classes.extensionsDialogSurface}>\r\n <DialogBody className={classes.extensionDialogBody}>\r\n <DialogTitle\r\n action={\r\n <DialogTrigger action=\"close\">\r\n <Button appearance=\"subtle\" aria-label=\"close\" icon={<DismissRegular />} />\r\n </DialogTrigger>\r\n }\r\n >\r\n <>\r\n Extensions\r\n <TabList\r\n className={classes.extensionDialogContent}\r\n selectedValue={selectedTab}\r\n onTabSelect={(event: SelectTabEvent, data: SelectTabData) => {\r\n setSelectedTab(data.value as TabValue);\r\n }}\r\n >\r\n <Tab value={\"available\" satisfies TabValue}>Available</Tab>\r\n <Tab value={\"installed\" satisfies TabValue}>Installed</Tab>\r\n </TabList>\r\n </>\r\n </DialogTitle>\r\n <DialogContent className={classes.extensionDialogContent}>\r\n <Accordion collapsible>\r\n {extensions.map((extension) => (\r\n <ExtensionDetails key={extension.metadata.name} extension={extension} />\r\n ))}\r\n </Accordion>\r\n </DialogContent>\r\n </DialogBody>\r\n </DialogSurface>\r\n </Dialog>\r\n </>\r\n );\r\n },\r\n });\r\n\r\n return {\r\n dispose: () => registration.dispose(),\r\n };\r\n },\r\n};\r\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { F as FileUploadLine, S as SwitchPropertyLine, C as Collapse, N as NumberDropdownPropertyLine, T as ToolsServiceIdentity } from './index-B-XOu4uI.js';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { ImportAnimationsAsync } from '@babylonjs/core/Loading/sceneLoader.js';
|
|
5
|
+
import { FilesInput } from '@babylonjs/core/Misc/filesInput.js';
|
|
6
|
+
import { Logger } from '@babylonjs/core/Misc/logger.js';
|
|
7
|
+
import '@babylonjs/core/Maths/math.color.js';
|
|
8
|
+
import '@babylonjs/core/Maths/math.vector.js';
|
|
9
|
+
import '@babylonjs/core/Misc/observable.js';
|
|
10
|
+
import '@fluentui/react-components';
|
|
11
|
+
import '@fluentui/react-icons';
|
|
12
|
+
import '@fluentui/react-motion-components-preview';
|
|
13
|
+
import '@babylonjs/core/Misc/typeStore.js';
|
|
14
|
+
import 'usehooks-ts';
|
|
15
|
+
import '@babylonjs/core/Misc/asyncLock.js';
|
|
16
|
+
import '@babylonjs/core/Misc/deferred.js';
|
|
17
|
+
import '@babylonjs/core/Maths/math.scalar.functions.js';
|
|
18
|
+
import '@fluentui-contrib/react-virtualizer';
|
|
19
|
+
import '@babylonjs/addons/msdfText/fontAsset.js';
|
|
20
|
+
import '@babylonjs/addons/msdfText/textRenderer.js';
|
|
21
|
+
import '@babylonjs/core/Debug/physicsViewer.js';
|
|
22
|
+
import '@babylonjs/core/Materials/Textures/texture.js';
|
|
23
|
+
import '@babylonjs/core/Materials/materialFlags.js';
|
|
24
|
+
import '@babylonjs/core/Materials/standardMaterial.js';
|
|
25
|
+
import '@babylonjs/core/Meshes/Builders/groundBuilder.js';
|
|
26
|
+
import '@babylonjs/core/Misc/tools.js';
|
|
27
|
+
import '@babylonjs/core/Rendering/utilityLayerRenderer.js';
|
|
28
|
+
import '@babylonjs/materials/grid/gridMaterial.js';
|
|
29
|
+
import '@babylonjs/core/Misc/dataStorage.js';
|
|
30
|
+
import '@babylonjs/core/Instrumentation/engineInstrumentation.js';
|
|
31
|
+
import '@babylonjs/core/Instrumentation/sceneInstrumentation.js';
|
|
32
|
+
import '@babylonjs/core/Engines/AbstractEngine/abstractEngine.timeQuery.js';
|
|
33
|
+
import '@babylonjs/core/Engines/Extensions/engine.query.js';
|
|
34
|
+
import '@babylonjs/core/Engines/WebGPU/Extensions/engine.query.js';
|
|
35
|
+
import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerCollectionStrategies.js';
|
|
36
|
+
import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerSceneExtension.js';
|
|
37
|
+
import '@babylonjs/core/Misc/pressureObserverWrapper.js';
|
|
38
|
+
import '@babylonjs/core/Engines/abstractEngine.js';
|
|
39
|
+
import 'react-dom/client';
|
|
40
|
+
import '@babylonjs/core/FrameGraph/frameGraphUtils.js';
|
|
41
|
+
import '@babylonjs/core/Gizmos/cameraGizmo.js';
|
|
42
|
+
import '@babylonjs/core/Gizmos/lightGizmo.js';
|
|
43
|
+
import '@babylonjs/core/Bones/bone.js';
|
|
44
|
+
import '@babylonjs/core/Cameras/camera.js';
|
|
45
|
+
import '@babylonjs/core/Gizmos/gizmoManager.js';
|
|
46
|
+
import '@babylonjs/core/Lights/light.js';
|
|
47
|
+
import '@babylonjs/core/Meshes/abstractMesh.js';
|
|
48
|
+
import '@babylonjs/core/node.js';
|
|
49
|
+
import '@babylonjs/core/Animations/animationGroup.js';
|
|
50
|
+
import '@babylonjs/core/Animations/animationPropertiesOverride.js';
|
|
51
|
+
import '@babylonjs/addons/atmosphere/atmosphere.js';
|
|
52
|
+
import '@babylonjs/core/Cameras/arcRotateCamera.js';
|
|
53
|
+
import '@babylonjs/core/Cameras/followCamera.js';
|
|
54
|
+
import '@babylonjs/core/Cameras/freeCamera.js';
|
|
55
|
+
import '@babylonjs/core/Cameras/targetCamera.js';
|
|
56
|
+
import '@babylonjs/core/scene.js';
|
|
57
|
+
import '@babylonjs/core/FrameGraph/frameGraph.js';
|
|
58
|
+
import '@babylonjs/core/Lights/directionalLight.js';
|
|
59
|
+
import '@babylonjs/core/Lights/hemisphericLight.js';
|
|
60
|
+
import '@babylonjs/core/Lights/pointLight.js';
|
|
61
|
+
import '@babylonjs/core/Lights/rectAreaLight.js';
|
|
62
|
+
import '@babylonjs/core/Lights/shadowLight.js';
|
|
63
|
+
import '@babylonjs/core/Lights/spotLight.js';
|
|
64
|
+
import '@babylonjs/core/Lights/Shadows/cascadedShadowGenerator.js';
|
|
65
|
+
import '@babylonjs/core/Lights/Shadows/shadowGenerator.js';
|
|
66
|
+
import '@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent.js';
|
|
67
|
+
import '@babylonjs/core/Materials/material.js';
|
|
68
|
+
import '@babylonjs/core/Materials/multiMaterial.js';
|
|
69
|
+
import '@babylonjs/core/Materials/PBR/pbrBaseMaterial.js';
|
|
70
|
+
import '@babylonjs/core/Materials/PBR/pbrBaseSimpleMaterial.js';
|
|
71
|
+
import '@babylonjs/core/Materials/PBR/pbrMaterial.js';
|
|
72
|
+
import '@babylonjs/core/Materials/PBR/openpbrMaterial.js';
|
|
73
|
+
import '@babylonjs/materials/sky/skyMaterial.js';
|
|
74
|
+
import '@babylonjs/core/Engines/constants.js';
|
|
75
|
+
import '@babylonjs/core/Engines/engine.js';
|
|
76
|
+
import '@babylonjs/core/Particles/particleSystem.js';
|
|
77
|
+
import '@babylonjs/core/Misc/fileTools.js';
|
|
78
|
+
import '@babylonjs/core/Meshes/mesh.js';
|
|
79
|
+
import '@babylonjs/core/Debug/skeletonViewer.js';
|
|
80
|
+
import '@babylonjs/core/Meshes/buffer.js';
|
|
81
|
+
import '@babylonjs/core/Meshes/Builders/linesBuilder.js';
|
|
82
|
+
import '@babylonjs/core/Meshes/instancedMesh.js';
|
|
83
|
+
import '@babylonjs/core/Rendering/renderingManager.js';
|
|
84
|
+
import '@babylonjs/core/Rendering/edgesRenderer.js';
|
|
85
|
+
import '@babylonjs/core/Rendering/outlineRenderer.js';
|
|
86
|
+
import '@babylonjs/core/Meshes/GaussianSplatting/gaussianSplattingMesh.js';
|
|
87
|
+
import '@babylonjs/core/Misc/gradients.js';
|
|
88
|
+
import '@babylonjs/core/Materials/Node/Blocks/gradientBlock.js';
|
|
89
|
+
import '@babylonjs/core/Particles/attractor.js';
|
|
90
|
+
import '@babylonjs/core/Meshes/Builders/sphereBuilder.js';
|
|
91
|
+
import '@babylonjs/core/Meshes/transformNode.js';
|
|
92
|
+
import '@babylonjs/core/Physics/v2/IPhysicsEnginePlugin.js';
|
|
93
|
+
import '@babylonjs/core/Physics/v2/physicsEngineComponent.js';
|
|
94
|
+
import '@babylonjs/core/PostProcesses/postProcess.js';
|
|
95
|
+
import '@babylonjs/core/Materials/Textures/cubeTexture.js';
|
|
96
|
+
import '@babylonjs/core/Materials/imageProcessingConfiguration.js';
|
|
97
|
+
import '@babylonjs/core/Bones/skeleton.js';
|
|
98
|
+
import '@babylonjs/core/Sprites/sprite.js';
|
|
99
|
+
import '@babylonjs/core/Sprites/spriteManager.js';
|
|
100
|
+
import '@babylonjs/core/Materials/Textures/baseTexture.js';
|
|
101
|
+
import '@babylonjs/core/Materials/Textures/multiRenderTarget.js';
|
|
102
|
+
import '@babylonjs/core/Materials/Textures/renderTargetTexture.js';
|
|
103
|
+
import '@babylonjs/core/Materials/Textures/thinTexture.js';
|
|
104
|
+
import '@babylonjs/core/Misc/textureTools.js';
|
|
105
|
+
import '@babylonjs/core/Rendering/boundingBoxRenderer.js';
|
|
106
|
+
import '@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.js';
|
|
107
|
+
import '@babylonjs/core/Sprites/spriteSceneComponent.js';
|
|
108
|
+
import '@babylonjs/core/Materials/Textures/dynamicTexture.js';
|
|
109
|
+
import '@babylonjs/core/Events/pointerEvents.js';
|
|
110
|
+
import '@babylonjs/core/Engines/engineStore.js';
|
|
111
|
+
import '@babylonjs/core/Misc/uniqueIdGenerator.js';
|
|
112
|
+
|
|
113
|
+
const AnimationGroupLoadingModes = [
|
|
114
|
+
{ label: "Clean", value: 0 /* SceneLoaderAnimationGroupLoadingMode.Clean */ },
|
|
115
|
+
{ label: "Stop", value: 1 /* SceneLoaderAnimationGroupLoadingMode.Stop */ },
|
|
116
|
+
{ label: "Sync", value: 2 /* SceneLoaderAnimationGroupLoadingMode.Sync */ },
|
|
117
|
+
{ label: "NoSync", value: 3 /* SceneLoaderAnimationGroupLoadingMode.NoSync */ },
|
|
118
|
+
];
|
|
119
|
+
const ImportAnimationsTools = ({ scene }) => {
|
|
120
|
+
const [importDefaults, setImportDefaults] = useState({
|
|
121
|
+
overwriteAnimations: true,
|
|
122
|
+
animationGroupLoadingMode: 0 /* SceneLoaderAnimationGroupLoadingMode.Clean */,
|
|
123
|
+
});
|
|
124
|
+
const importAnimations = (event) => {
|
|
125
|
+
const reloadAsync = async function (sceneFile) {
|
|
126
|
+
if (sceneFile) {
|
|
127
|
+
try {
|
|
128
|
+
await ImportAnimationsAsync(sceneFile, scene, {
|
|
129
|
+
overwriteAnimations: importDefaults.overwriteAnimations,
|
|
130
|
+
animationGroupLoadingMode: importDefaults.animationGroupLoadingMode,
|
|
131
|
+
});
|
|
132
|
+
if (scene.animationGroups.length > 0) {
|
|
133
|
+
const currentGroup = scene.animationGroups[0];
|
|
134
|
+
currentGroup.play(true);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
Logger.Error(`Error importing animations: ${error}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const filesInputAnimation = new FilesInput(scene.getEngine(), scene, null, null, null, null, null, reloadAsync, null);
|
|
143
|
+
filesInputAnimation.loadFiles(event);
|
|
144
|
+
filesInputAnimation.dispose();
|
|
145
|
+
};
|
|
146
|
+
return (jsxs(Fragment, { children: [jsx(FileUploadLine, { label: "Import Animations", accept: "gltf", onClick: (evt) => importAnimations(evt) }), jsx(SwitchPropertyLine, { label: "Overwrite Animations", value: importDefaults.overwriteAnimations, onChange: (value) => {
|
|
147
|
+
setImportDefaults({ ...importDefaults, overwriteAnimations: value });
|
|
148
|
+
} }), jsx(Collapse, { visible: !importDefaults.overwriteAnimations, children: jsx(NumberDropdownPropertyLine, { label: "Animation Merge Mode", options: AnimationGroupLoadingModes, value: importDefaults.animationGroupLoadingMode, onChange: (value) => {
|
|
149
|
+
setImportDefaults({ ...importDefaults, animationGroupLoadingMode: value });
|
|
150
|
+
} }) })] }));
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const SceneImportServiceDefinition = {
|
|
154
|
+
friendlyName: "Import Tool",
|
|
155
|
+
consumes: [ToolsServiceIdentity],
|
|
156
|
+
factory: (toolsService) => {
|
|
157
|
+
const contentRegistration = toolsService.addSectionContent({
|
|
158
|
+
key: "AnimationImport",
|
|
159
|
+
section: "Animation Import",
|
|
160
|
+
component: ({ context }) => jsx(ImportAnimationsTools, { scene: context }),
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
dispose: () => {
|
|
164
|
+
contentRegistration.dispose();
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
var importService = {
|
|
170
|
+
serviceDefinitions: [SceneImportServiceDefinition],
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export { SceneImportServiceDefinition, importService as default };
|
|
174
|
+
//# sourceMappingURL=importService-DEe18q7F.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importService-DEe18q7F.js","sources":["../../../../../../../../dev/inspector-v2/src/components/tools/importTools.tsx","../../../../../../../../dev/inspector-v2/src/services/panes/tools/importService.tsx"],"sourcesContent":["import { useState } from \"react\";\r\nimport type { FunctionComponent } from \"react\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { DropdownOption } from \"shared-ui-components/fluent/primitives/dropdown\";\r\nimport { ImportAnimationsAsync, SceneLoaderAnimationGroupLoadingMode } from \"core/Loading/sceneLoader\";\r\nimport { FilesInput } from \"core/Misc/filesInput\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { SwitchPropertyLine } from \"shared-ui-components/fluent/hoc/propertyLines/switchPropertyLine\";\r\nimport { NumberDropdownPropertyLine } from \"shared-ui-components/fluent/hoc/propertyLines/dropdownPropertyLine\";\r\nimport { FileUploadLine } from \"shared-ui-components/fluent/hoc/fileUploadLine\";\r\nimport { Collapse } from \"shared-ui-components/fluent/primitives/collapse\";\r\n\r\nconst AnimationGroupLoadingModes = [\r\n { label: \"Clean\", value: SceneLoaderAnimationGroupLoadingMode.Clean },\r\n { label: \"Stop\", value: SceneLoaderAnimationGroupLoadingMode.Stop },\r\n { label: \"Sync\", value: SceneLoaderAnimationGroupLoadingMode.Sync },\r\n { label: \"NoSync\", value: SceneLoaderAnimationGroupLoadingMode.NoSync },\r\n] as const satisfies DropdownOption<number>[];\r\n\r\nexport const ImportAnimationsTools: FunctionComponent<{ scene: Scene }> = ({ scene }) => {\r\n const [importDefaults, setImportDefaults] = useState({\r\n overwriteAnimations: true,\r\n animationGroupLoadingMode: SceneLoaderAnimationGroupLoadingMode.Clean,\r\n });\r\n\r\n const importAnimations = (event: FileList) => {\r\n const reloadAsync = async function (sceneFile: File) {\r\n if (sceneFile) {\r\n try {\r\n await ImportAnimationsAsync(sceneFile, scene, {\r\n overwriteAnimations: importDefaults.overwriteAnimations,\r\n animationGroupLoadingMode: importDefaults.animationGroupLoadingMode,\r\n });\r\n\r\n if (scene.animationGroups.length > 0) {\r\n const currentGroup = scene.animationGroups[0];\r\n currentGroup.play(true);\r\n }\r\n } catch (error) {\r\n Logger.Error(`Error importing animations: ${error}`);\r\n }\r\n }\r\n };\r\n\r\n const filesInputAnimation = new FilesInput(scene.getEngine(), scene, null, null, null, null, null, reloadAsync, null);\r\n filesInputAnimation.loadFiles(event);\r\n filesInputAnimation.dispose();\r\n };\r\n\r\n return (\r\n <>\r\n <FileUploadLine label=\"Import Animations\" accept=\"gltf\" onClick={(evt: FileList) => importAnimations(evt)} />\r\n <SwitchPropertyLine\r\n label=\"Overwrite Animations\"\r\n value={importDefaults.overwriteAnimations}\r\n onChange={(value) => {\r\n setImportDefaults({ ...importDefaults, overwriteAnimations: value });\r\n }}\r\n />\r\n <Collapse visible={!importDefaults.overwriteAnimations}>\r\n <NumberDropdownPropertyLine\r\n label=\"Animation Merge Mode\"\r\n options={AnimationGroupLoadingModes}\r\n value={importDefaults.animationGroupLoadingMode}\r\n onChange={(value) => {\r\n setImportDefaults({ ...importDefaults, animationGroupLoadingMode: value });\r\n }}\r\n />\r\n </Collapse>\r\n </>\r\n );\r\n};\r\n","import type { ServiceDefinition } from \"../../../modularity/serviceDefinition\";\r\nimport { ToolsServiceIdentity } from \"../toolsService\";\r\nimport type { IToolsService } from \"../toolsService\";\r\nimport { ImportAnimationsTools } from \"../../../components/tools/importTools\";\r\n\r\nexport const SceneImportServiceDefinition: ServiceDefinition<[], [IToolsService]> = {\r\n friendlyName: \"Import Tool\",\r\n consumes: [ToolsServiceIdentity],\r\n factory: (toolsService) => {\r\n const contentRegistration = toolsService.addSectionContent({\r\n key: \"AnimationImport\",\r\n section: \"Animation Import\",\r\n component: ({ context }) => <ImportAnimationsTools scene={context} />,\r\n });\r\n\r\n return {\r\n dispose: () => {\r\n contentRegistration.dispose();\r\n },\r\n };\r\n },\r\n};\r\n\r\nexport default {\r\n serviceDefinitions: [SceneImportServiceDefinition],\r\n} as const;\r\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|