@babylonjs/inspector 8.41.0-preview → 8.41.1-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/index.d.ts CHANGED
@@ -1261,7 +1261,7 @@ declare const Accordion: ForwardRefExoticComponent<AccordionProps & {
1261
1261
  type ButtonProps = BasePrimitiveProps & {
1262
1262
  onClick: () => void;
1263
1263
  icon?: FluentIcon;
1264
- appearance?: "subtle" | "transparent";
1264
+ appearance?: "subtle" | "transparent" | "primary";
1265
1265
  label?: string;
1266
1266
  };
1267
1267
  declare const Button: FunctionComponent<ButtonProps>;
@@ -49024,7 +49024,7 @@ declare abstract class FrameGraphTask {
49024
49024
  * This allows you to initialize asynchronous resources, which is not possible in the constructor.
49025
49025
  * @returns A promise that resolves when the initialization is complete.
49026
49026
  */
49027
- initAsync(): Promise<void>;
49027
+ initAsync(): Promise<unknown>;
49028
49028
  /**
49029
49029
  * An observable that is triggered after the textures have been allocated.
49030
49030
  */
@@ -49562,6 +49562,7 @@ declare class FrameGraph implements IDisposable {
49562
49562
  private readonly _initAsyncPromises;
49563
49563
  private _currentProcessedTask;
49564
49564
  private _whenReadyAsyncCancel;
49565
+ private _importPromise;
49565
49566
  /**
49566
49567
  * Name of the frame graph
49567
49568
  */
@@ -58104,6 +58105,7 @@ declare class TriPlanarBlock extends NodeMaterialBlock {
58104
58105
  protected _tempTextureRead: string;
58105
58106
  private _samplerName;
58106
58107
  private _textureInfoName;
58108
+ private _textureInfoName2;
58107
58109
  private _imageSource;
58108
58110
  /**
58109
58111
  * Project the texture(s) for a better fit to a cube
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { a5 as Accordion, a4 as AccordionSection, A as AttachDebugLayer, aA as BooleanBadgePropertyLine, l as BoundProperty, n as BuiltInsExtensionFeed, a6 as Button, B as ButtonLine, a7 as Checkbox, aB as CheckboxPropertyLine, C as Collapse, ah as Color3GradientComponent, ax as Color3GradientList, aC as Color3PropertyLine, ai as Color4GradientComponent, ay as Color4GradientList, aD as Color4PropertyLine, a8 as ColorPickerPopup, aj as ColorStepGradientComponent, ab as ComboBox, _ as ConstructorFactory, i as ConvertOptions, D as DebugServiceIdentity, j as DetachDebugLayer, ac as DraggableLine, ad as Dropdown, E as ExtensibleAccordion, ag as FactorGradientComponent, aw as FactorGradientList, F as FileUploadLine, W as GetPropertyDescriptor, aE as HexPropertyLine, ak as InfoLabel, a9 as InputHexField, aa as InputHsvField, I as Inspector, V as InterceptFunction, Y as InterceptProperty, X as IsPropertyReadonly, aJ as LineContainer, L as Link, aH as LinkPropertyLine, m as LinkToEntityPropertyLine, al as List, U as MakeDialogTeachingMoment, M as MakeLazyComponent, c as MakePopoverTeachingMoment, t as MakePropertyHook, R as MakeTeachingMoment, am as MessageBar, ae as NumberDropdown, N as NumberDropdownPropertyLine, aG as NumberInputPropertyLine, Z as ObservableCollection, az as Pane, aK as PlaceholderPropertyLine, an as PositionedPopover, P as PropertiesServiceIdentity, aI as PropertyLine, aQ as QuaternionPropertyLine, aP as RotationVectorPropertyLine, $ as SceneContextIdentity, f as SceneExplorerServiceIdentity, ao as SearchBar, ap as SearchBox, a1 as SelectionServiceDefinition, a0 as SelectionServiceIdentity, a2 as SettingsContextIdentity, g as SettingsServiceIdentity, b as ShellServiceIdentity, a3 as ShowInspector, e as SidePaneContainer, aq as SpinButton, aL as SpinButtonPropertyLine, h as StatsServiceIdentity, af as StringDropdown, k as StringDropdownPropertyLine, aM as StringifiedPropertyLine, ar as Switch, S as SwitchPropertyLine, as as SyncedSliderInput, a as SyncedSliderPropertyLine, d as TeachingMoment, aN as TextAreaPropertyLine, au as TextInput, aF as TextInputPropertyLine, aO as TextPropertyLine, at as Textarea, av as ToggleButton, T as ToolsServiceIdentity, aR as Vector2PropertyLine, aS as Vector3PropertyLine, aT as Vector4PropertyLine, Q as useAngleConverters, J as useAsyncResource, q as useColor3Property, r as useColor4Property, K as useCompactMode, w as useEventfulState, v as useInterceptObservable, y as useObservableCollection, x as useObservableState, z as useOrderedObservableCollection, G as usePollingObservable, o as useProperty, s as useQuaternionProperty, H as useResource, O as useSidePaneDockOverrides, p as useVector3Property } from './index-Cxm78n40.js';
1
+ export { A as Accordion, h as AccordionSection, q as AttachDebugLayer, aE as BooleanBadgePropertyLine, t as BoundProperty, w as BuiltInsExtensionFeed, b as Button, B as ButtonLine, ab as Checkbox, e as CheckboxPropertyLine, C as Collapse, al as Color3GradientComponent, aB as Color3GradientList, aF as Color3PropertyLine, am as Color4GradientComponent, aC as Color4GradientList, aG as Color4PropertyLine, ac as ColorPickerPopup, an as ColorStepGradientComponent, af as ComboBox, a6 as ConstructorFactory, p as ConvertOptions, D as DebugServiceIdentity, r as DetachDebugLayer, ag as DraggableLine, ah as Dropdown, E as ExtensibleAccordion, ak as FactorGradientComponent, aA as FactorGradientList, F as FileUploadLine, a2 as GetPropertyDescriptor, aH as HexPropertyLine, ao as InfoLabel, ad as InputHexField, ae as InputHsvField, I as Inspector, a1 as InterceptFunction, a4 as InterceptProperty, a3 as IsPropertyReadonly, aL as LineContainer, L as Link, aJ as LinkPropertyLine, v as LinkToEntityPropertyLine, ap as List, a0 as MakeDialogTeachingMoment, M as MakeLazyComponent, j as MakePopoverTeachingMoment, J as MakePropertyHook, $ as MakeTeachingMoment, aq as MessageBar, ai as NumberDropdown, N as NumberDropdownPropertyLine, aI as NumberInputPropertyLine, a5 as ObservableCollection, aD as Pane, aM as PlaceholderPropertyLine, ar as PositionedPopover, P as PropertiesServiceIdentity, aK as PropertyLine, aR as QuaternionPropertyLine, aQ as RotationVectorPropertyLine, g as SceneContextIdentity, m as SceneExplorerServiceIdentity, as as SearchBar, at as SearchBox, a8 as SelectionServiceDefinition, a7 as SelectionServiceIdentity, a9 as SettingsContextIdentity, n as SettingsServiceIdentity, f as ShellServiceIdentity, aa as ShowInspector, l as SidePaneContainer, au as SpinButton, d as SpinButtonPropertyLine, o as StatsServiceIdentity, aj as StringDropdown, s as StringDropdownPropertyLine, aN as StringifiedPropertyLine, av as Switch, S as SwitchPropertyLine, aw as SyncedSliderInput, a as SyncedSliderPropertyLine, k as TeachingMoment, aO as TextAreaPropertyLine, ay as TextInput, c as TextInputPropertyLine, aP as TextPropertyLine, ax as Textarea, az as ToggleButton, T as ToolsServiceIdentity, aS as Vector2PropertyLine, V as Vector3PropertyLine, aT as Vector4PropertyLine, _ as useAngleConverters, X as useAsyncResource, z as useColor3Property, G as useColor4Property, Y as useCompactMode, O as useEventfulState, K as useInterceptObservable, Q as useObservableCollection, u as useObservableState, R as useOrderedObservableCollection, U as usePollingObservable, x as useProperty, H as useQuaternionProperty, W as useResource, Z as useSidePaneDockOverrides, y as useVector3Property } from './index-BUtV9Nch.js';
2
2
  import 'react/jsx-runtime';
3
3
  import 'react';
4
4
  import '@babylonjs/core/Maths/math.color.js';
@@ -0,0 +1,545 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { b as Button, c as TextInputPropertyLine, d as SpinButtonPropertyLine, e as CheckboxPropertyLine, V as Vector3PropertyLine, f as ShellServiceIdentity, g as SceneContextIdentity, u as useObservableState, A as Accordion, h as AccordionSection } from './index-BUtV9Nch.js';
3
+ import { Settings20Regular, CollectionsAdd20Regular } from '@fluentui/react-icons';
4
+ import '@babylonjs/core/Particles/webgl2ParticleSystem.js';
5
+ import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder.js';
6
+ import { useState, useRef } from 'react';
7
+ import { Popover, PopoverTrigger, PopoverSurface, makeStyles, tokens } from '@fluentui/react-components';
8
+ import { FilesInput } from '@babylonjs/core/Misc/filesInput.js';
9
+ import { NodeMaterial } from '@babylonjs/core/Materials/Node/nodeMaterial.js';
10
+ import { PBRMaterial } from '@babylonjs/core/Materials/PBR/pbrMaterial.js';
11
+ import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial.js';
12
+ import { PointLight } from '@babylonjs/core/Lights/pointLight.js';
13
+ import { DirectionalLight } from '@babylonjs/core/Lights/directionalLight.js';
14
+ import { SpotLight } from '@babylonjs/core/Lights/spotLight.js';
15
+ import { Vector3 } from '@babylonjs/core/Maths/math.vector.js';
16
+ import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera.js';
17
+ import { UniversalCamera } from '@babylonjs/core/Cameras/universalCamera.js';
18
+ import { ParticleSystem } from '@babylonjs/core/Particles/particleSystem.js';
19
+ import { GPUParticleSystem } from '@babylonjs/core/Particles/gpuParticleSystem.js';
20
+ import { NodeParticleSystemSet } from '@babylonjs/core/Particles/Node/nodeParticleSystemSet.js';
21
+ import { Texture } from '@babylonjs/core/Materials/Textures/texture.js';
22
+ import '@babylonjs/core/Maths/math.color.js';
23
+ import '@babylonjs/core/Misc/observable.js';
24
+ import '@fluentui/react-motion-components-preview';
25
+ import '@babylonjs/core/Misc/typeStore.js';
26
+ import 'usehooks-ts';
27
+ import '@babylonjs/core/Misc/asyncLock.js';
28
+ import '@babylonjs/core/Misc/deferred.js';
29
+ import '@babylonjs/core/Maths/math.scalar.functions.js';
30
+ import '@fluentui-contrib/react-virtualizer';
31
+ import '@babylonjs/addons/msdfText/fontAsset.js';
32
+ import '@babylonjs/addons/msdfText/textRenderer.js';
33
+ import '@babylonjs/core/Debug/physicsViewer.js';
34
+ import '@babylonjs/core/Materials/materialFlags.js';
35
+ import '@babylonjs/core/Meshes/Builders/groundBuilder.js';
36
+ import '@babylonjs/core/Misc/tools.js';
37
+ import '@babylonjs/core/Rendering/utilityLayerRenderer.js';
38
+ import '@babylonjs/materials/grid/gridMaterial.js';
39
+ import '@babylonjs/core/Misc/dataStorage.js';
40
+ import '@babylonjs/core/Instrumentation/engineInstrumentation.js';
41
+ import '@babylonjs/core/Instrumentation/sceneInstrumentation.js';
42
+ import '@babylonjs/core/Engines/AbstractEngine/abstractEngine.timeQuery.js';
43
+ import '@babylonjs/core/Engines/Extensions/engine.query.js';
44
+ import '@babylonjs/core/Engines/WebGPU/Extensions/engine.query.js';
45
+ import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerCollectionStrategies.js';
46
+ import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerSceneExtension.js';
47
+ import '@babylonjs/core/Misc/pressureObserverWrapper.js';
48
+ import '@babylonjs/core/Engines/abstractEngine.js';
49
+ import '@babylonjs/core/Misc/logger.js';
50
+ import 'react-dom/client';
51
+ import '@babylonjs/core/FrameGraph/frameGraphUtils.js';
52
+ import '@babylonjs/core/Gizmos/cameraGizmo.js';
53
+ import '@babylonjs/core/Gizmos/lightGizmo.js';
54
+ import '@babylonjs/core/Bones/bone.js';
55
+ import '@babylonjs/core/Cameras/camera.js';
56
+ import '@babylonjs/core/Gizmos/gizmoManager.js';
57
+ import '@babylonjs/core/Lights/light.js';
58
+ import '@babylonjs/core/Meshes/abstractMesh.js';
59
+ import '@babylonjs/core/node.js';
60
+ import '@babylonjs/core/Animations/animationGroup.js';
61
+ import '@babylonjs/core/Animations/animationPropertiesOverride.js';
62
+ import '@babylonjs/addons/atmosphere/atmosphere.js';
63
+ import '@babylonjs/core/Cameras/followCamera.js';
64
+ import '@babylonjs/core/Cameras/freeCamera.js';
65
+ import '@babylonjs/core/Cameras/targetCamera.js';
66
+ import '@babylonjs/core/scene.js';
67
+ import '@babylonjs/core/FrameGraph/frameGraph.js';
68
+ import '@babylonjs/core/Lights/hemisphericLight.js';
69
+ import '@babylonjs/core/Lights/rectAreaLight.js';
70
+ import '@babylonjs/core/Lights/shadowLight.js';
71
+ import '@babylonjs/core/Lights/Shadows/cascadedShadowGenerator.js';
72
+ import '@babylonjs/core/Lights/Shadows/shadowGenerator.js';
73
+ import '@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent.js';
74
+ import '@babylonjs/core/Materials/material.js';
75
+ import '@babylonjs/core/Materials/multiMaterial.js';
76
+ import '@babylonjs/core/Materials/PBR/pbrBaseMaterial.js';
77
+ import '@babylonjs/core/Materials/PBR/pbrBaseSimpleMaterial.js';
78
+ import '@babylonjs/core/Materials/PBR/openpbrMaterial.js';
79
+ import '@babylonjs/materials/sky/skyMaterial.js';
80
+ import '@babylonjs/core/Engines/constants.js';
81
+ import '@babylonjs/core/Engines/engine.js';
82
+ import '@babylonjs/core/Misc/fileTools.js';
83
+ import '@babylonjs/core/Meshes/mesh.js';
84
+ import '@babylonjs/core/Debug/skeletonViewer.js';
85
+ import '@babylonjs/core/Meshes/buffer.js';
86
+ import '@babylonjs/core/Meshes/Builders/linesBuilder.js';
87
+ import '@babylonjs/core/Meshes/instancedMesh.js';
88
+ import '@babylonjs/core/Rendering/renderingManager.js';
89
+ import '@babylonjs/core/Rendering/edgesRenderer.js';
90
+ import '@babylonjs/core/Rendering/outlineRenderer.js';
91
+ import '@babylonjs/core/Meshes/GaussianSplatting/gaussianSplattingMesh.js';
92
+ import '@babylonjs/core/Misc/gradients.js';
93
+ import '@babylonjs/core/Materials/Node/Blocks/gradientBlock.js';
94
+ import '@babylonjs/core/Particles/attractor.js';
95
+ import '@babylonjs/core/Meshes/Builders/sphereBuilder.js';
96
+ import '@babylonjs/core/Meshes/transformNode.js';
97
+ import '@babylonjs/core/Physics/v2/IPhysicsEnginePlugin.js';
98
+ import '@babylonjs/core/Physics/v2/physicsEngineComponent.js';
99
+ import '@babylonjs/core/PostProcesses/postProcess.js';
100
+ import '@babylonjs/core/Materials/Textures/cubeTexture.js';
101
+ import '@babylonjs/core/Materials/imageProcessingConfiguration.js';
102
+ import '@babylonjs/core/Bones/skeleton.js';
103
+ import '@babylonjs/core/Sprites/sprite.js';
104
+ import '@babylonjs/core/Sprites/spriteManager.js';
105
+ import '@babylonjs/core/Materials/Textures/baseTexture.js';
106
+ import '@babylonjs/core/Materials/Textures/multiRenderTarget.js';
107
+ import '@babylonjs/core/Materials/Textures/renderTargetTexture.js';
108
+ import '@babylonjs/core/Materials/Textures/thinTexture.js';
109
+ import '@babylonjs/core/Misc/textureTools.js';
110
+ import '@babylonjs/core/Lights/Clustered/clusteredLightContainer.js';
111
+ import '@babylonjs/core/Rendering/boundingBoxRenderer.js';
112
+ import '@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.js';
113
+ import '@babylonjs/core/Sprites/spriteSceneComponent.js';
114
+ import '@babylonjs/core/Materials/Textures/dynamicTexture.js';
115
+ import '@babylonjs/core/Events/pointerEvents.js';
116
+ import '@babylonjs/core/Engines/engineStore.js';
117
+ import '@babylonjs/core/Misc/uniqueIdGenerator.js';
118
+ import '@babylonjs/core/Debug/debugLayer.js';
119
+ import '@babylonjs/core/Misc/lazy.js';
120
+
121
+ /**
122
+ * Settings popover component, can be updated to use shared popover once it exists
123
+ * @param props
124
+ * @returns
125
+ */
126
+ const SettingsPopover = (props) => {
127
+ const { children } = props;
128
+ const [popoverOpen, setPopoverOpen] = useState(false);
129
+ return (jsxs(Popover, { open: popoverOpen, onOpenChange: (_, data) => setPopoverOpen(data.open), positioning: "below-start", trapFocus: true, children: [jsx(PopoverTrigger, { disableButtonEnhancement: true, children: jsx("button", { type: "button", onClick: () => setPopoverOpen(true), style: {
130
+ display: "inline-flex",
131
+ alignItems: "center",
132
+ justifyContent: "center",
133
+ border: "none",
134
+ background: "transparent",
135
+ cursor: "pointer",
136
+ padding: "5px 8px",
137
+ borderRadius: "4px",
138
+ }, children: jsx(Settings20Regular, {}) }) }), jsx(PopoverSurface, { children: jsx("div", { style: { display: "flex", flexDirection: "column", gap: 12, padding: 16, minWidth: 300, maxWidth: 400 }, children: children }) })] }));
139
+ };
140
+
141
+ const useStyles$4 = makeStyles({
142
+ section: {
143
+ display: "flex",
144
+ flexDirection: "column",
145
+ rowGap: tokens.spacingVerticalM,
146
+ },
147
+ row: { display: "flex", alignItems: "center", gap: "4px" },
148
+ });
149
+ const SetCamera = function (scene) {
150
+ const camera = scene.activeCamera;
151
+ if (camera && camera.radius !== undefined) {
152
+ camera.radius = 5;
153
+ }
154
+ };
155
+ /**
156
+ * @internal
157
+ */
158
+ const MeshesContent = ({ scene }) => {
159
+ const classes = useStyles$4();
160
+ const [sphereParams, setSphereParams] = useState({
161
+ name: "Sphere",
162
+ segments: 32,
163
+ diameter: 1,
164
+ diameterX: 1,
165
+ diameterY: 1,
166
+ diameterZ: 1,
167
+ arc: 1,
168
+ slice: 1,
169
+ uniform: true,
170
+ });
171
+ const handleSphereParamChange = (key, value) => {
172
+ setSphereParams((prev) => ({
173
+ ...prev,
174
+ [key]: value,
175
+ }));
176
+ };
177
+ const [boxParams, setBoxParams] = useState({
178
+ name: "Box",
179
+ size: 1,
180
+ width: 1,
181
+ height: 1,
182
+ depth: 1,
183
+ });
184
+ const handleBoxParamChange = (key, value) => {
185
+ setBoxParams((prev) => ({
186
+ ...prev,
187
+ [key]: value,
188
+ }));
189
+ };
190
+ const [cylinderParams, setCylinderParams] = useState({
191
+ name: "Cylinder",
192
+ height: 2,
193
+ diameterTop: 1,
194
+ diameterBottom: 1,
195
+ diameter: 1,
196
+ tessellation: 32,
197
+ subdivisions: 1,
198
+ arc: 1,
199
+ });
200
+ const handleCylinderParamChange = (key, value) => {
201
+ setCylinderParams((prev) => ({
202
+ ...prev,
203
+ [key]: value,
204
+ }));
205
+ };
206
+ const [coneParams, setConeParams] = useState({
207
+ name: "Cone",
208
+ height: 2,
209
+ diameter: 1,
210
+ diameterTop: 0,
211
+ diameterBottom: 1,
212
+ tessellation: 32,
213
+ subdivisions: 1,
214
+ arc: 1,
215
+ });
216
+ const [coneUp, setConeUp] = useState(true);
217
+ const handleConeParamChange = (key, value) => {
218
+ setConeParams((prev) => ({
219
+ ...prev,
220
+ [key]: value,
221
+ }));
222
+ };
223
+ const [groundParams, setGroundParams] = useState({
224
+ name: "Ground",
225
+ width: 10,
226
+ height: 10,
227
+ subdivisions: 1,
228
+ subdivisionsX: 1,
229
+ subdivisionsY: 1,
230
+ });
231
+ const handleGroundParamChange = (key, value) => {
232
+ setGroundParams((prev) => ({
233
+ ...prev,
234
+ [key]: value,
235
+ }));
236
+ };
237
+ const fileInputRef = useRef(null);
238
+ const [importMeshName, setImportMeshName] = useState("ImportedMesh");
239
+ const handleLocalMeshImport = (event) => {
240
+ const files = event.target.files;
241
+ if (!files || files.length === 0) {
242
+ return;
243
+ }
244
+ const filesArray = Array.from(files);
245
+ if (importMeshName.trim().length > 0 && filesArray.length > 0) {
246
+ const originalFile = filesArray[0];
247
+ const extensionIndex = originalFile.name.lastIndexOf(".");
248
+ const extension = extensionIndex >= 0 ? originalFile.name.substring(extensionIndex) : "";
249
+ const sanitizedName = importMeshName.trim();
250
+ const desiredFileName = sanitizedName.toLowerCase().endsWith(extension.toLowerCase()) ? sanitizedName : `${sanitizedName}${extension}`;
251
+ filesArray[0] = new File([originalFile], desiredFileName, { type: originalFile.type, lastModified: originalFile.lastModified });
252
+ }
253
+ const filesInput = new FilesInput(scene.getEngine(), scene, null, null, null, null, null, null, (_sceneFile, _scene, message) => {
254
+ alert(message ? `Failed to import mesh: ${message}` : "Failed to import mesh.");
255
+ }, true);
256
+ filesInput.displayLoadingUI = false;
257
+ filesInput.loadFiles({ target: { files: filesArray } });
258
+ filesInput.dispose();
259
+ event.target.value = "";
260
+ };
261
+ return (jsxs("div", { className: classes.section, children: [jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
262
+ MeshBuilder.CreateSphere("Sphere", {}, scene);
263
+ SetCamera(scene);
264
+ }, label: "Sphere" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: sphereParams.name, onChange: (val) => handleSphereParamChange("name", val) }), jsx(SpinButtonPropertyLine, { label: "Segments", value: sphereParams.segments, min: 0, onChange: (val) => handleSphereParamChange("segments", val) }), jsx(SpinButtonPropertyLine, { label: "Diameter", value: sphereParams.diameter, min: 0, step: 0.1, onChange: (val) => handleSphereParamChange("diameter", val), disabled: !sphereParams.uniform }), jsx(CheckboxPropertyLine, { label: "Uniform", value: sphereParams.uniform, onChange: (checked) => handleSphereParamChange("uniform", checked) }), jsx(SpinButtonPropertyLine, { label: "Diameter X", value: sphereParams.diameterX, min: 0, step: 0.1, onChange: (val) => handleSphereParamChange("diameterX", val), disabled: sphereParams.uniform }), jsx(SpinButtonPropertyLine, { label: "Diameter Y", value: sphereParams.diameterY, min: 0, step: 0.1, onChange: (val) => handleSphereParamChange("diameterY", val), disabled: sphereParams.uniform }), jsx(SpinButtonPropertyLine, { label: "Diameter Z", value: sphereParams.diameterZ, min: 0, step: 0.1, onChange: (val) => handleSphereParamChange("diameterZ", val), disabled: sphereParams.uniform }), jsx(SpinButtonPropertyLine, { label: "Arc", value: sphereParams.arc, min: 0, max: 1, step: 0.1, onChange: (val) => handleSphereParamChange("arc", val) }), jsx(SpinButtonPropertyLine, { label: "Slice", value: sphereParams.slice, min: 0, max: 1, step: 0.1, onChange: (val) => handleSphereParamChange("slice", val) }), jsx("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: jsx(Button, { appearance: "primary", onClick: () => {
265
+ // Create params object based on uniform checkbox
266
+ const createParams = {
267
+ segments: sphereParams.segments,
268
+ arc: sphereParams.arc,
269
+ slice: sphereParams.slice,
270
+ };
271
+ if (sphereParams.uniform) {
272
+ // If uniform is checked, use diameter
273
+ createParams.diameter = sphereParams.diameter;
274
+ }
275
+ else {
276
+ // If uniform is unchecked, use individual diameters
277
+ createParams.diameterX = sphereParams.diameterX;
278
+ createParams.diameterY = sphereParams.diameterY;
279
+ createParams.diameterZ = sphereParams.diameterZ;
280
+ }
281
+ MeshBuilder.CreateSphere(sphereParams.name, createParams, scene);
282
+ SetCamera(scene);
283
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
284
+ MeshBuilder.CreateBox("Box", {}, scene);
285
+ SetCamera(scene);
286
+ }, label: "Box" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: boxParams.name, onChange: (val) => handleBoxParamChange("name", val) }), jsx(SpinButtonPropertyLine, { label: "Size", value: boxParams.size, min: 0, step: 0.1, onChange: (val) => handleBoxParamChange("size", val) }), jsx(SpinButtonPropertyLine, { label: "Width", value: boxParams.width, min: 0, step: 0.1, onChange: (val) => handleBoxParamChange("width", val) }), jsx(SpinButtonPropertyLine, { label: "Height", value: boxParams.height, min: 0, step: 0.1, onChange: (val) => handleBoxParamChange("height", val) }), jsx(SpinButtonPropertyLine, { label: "Depth", value: boxParams.depth, min: 0, step: 0.1, onChange: (val) => handleBoxParamChange("depth", val) }), jsx("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: jsx(Button, { appearance: "primary", onClick: () => {
287
+ MeshBuilder.CreateBox(boxParams.name, boxParams, scene);
288
+ SetCamera(scene);
289
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
290
+ MeshBuilder.CreateCylinder("Cylinder", {}, scene);
291
+ SetCamera(scene);
292
+ }, label: "Cylinder" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: cylinderParams.name, onChange: (val) => handleCylinderParamChange("name", val) }), jsx(SpinButtonPropertyLine, { label: "Height", value: cylinderParams.height, min: 0, step: 0.1, onChange: (val) => handleCylinderParamChange("height", val) }), jsx(SpinButtonPropertyLine, { label: "Diameter Top", value: cylinderParams.diameterTop, min: 0, step: 0.1, onChange: (val) => handleCylinderParamChange("diameterTop", val) }), jsx(SpinButtonPropertyLine, { label: "Diameter Bottom", value: cylinderParams.diameterBottom, min: 0, step: 0.1, onChange: (val) => handleCylinderParamChange("diameterBottom", val) }), jsx(SpinButtonPropertyLine, { label: "Diameter", value: cylinderParams.diameter, min: 0, step: 0.1, onChange: (val) => handleCylinderParamChange("diameter", val) }), jsx(SpinButtonPropertyLine, { label: "Tessellation", value: cylinderParams.tessellation, min: 3, onChange: (val) => handleCylinderParamChange("tessellation", val) }), jsx(SpinButtonPropertyLine, { label: "Subdivisions", value: cylinderParams.subdivisions, min: 1, onChange: (val) => handleCylinderParamChange("subdivisions", val) }), jsx(SpinButtonPropertyLine, { label: "Arc", value: cylinderParams.arc, min: 0, max: 1, step: 0.1, onChange: (val) => handleCylinderParamChange("arc", val) }), jsx("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: jsx(Button, { appearance: "primary", onClick: () => {
293
+ MeshBuilder.CreateCylinder(cylinderParams.name, cylinderParams, scene);
294
+ SetCamera(scene);
295
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
296
+ MeshBuilder.CreateCylinder("Cone", { diameterTop: 0 }, scene);
297
+ SetCamera(scene);
298
+ }, label: "Cone" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: coneParams.name, onChange: (val) => handleConeParamChange("name", val) }), jsx(SpinButtonPropertyLine, { label: "Height", value: coneParams.height, min: 0, step: 0.1, onChange: (val) => handleConeParamChange("height", val) }), jsx(SpinButtonPropertyLine, { label: "Diameter", value: coneParams.diameter, min: 0, step: 0.1, onChange: (val) => handleConeParamChange("diameter", val) }), jsx(SpinButtonPropertyLine, { label: "Tessellation", value: coneParams.tessellation, min: 3, onChange: (val) => handleConeParamChange("tessellation", val) }), jsx(SpinButtonPropertyLine, { label: "Subdivisions", value: coneParams.subdivisions, min: 1, onChange: (val) => handleConeParamChange("subdivisions", val) }), jsx(SpinButtonPropertyLine, { label: "Arc", value: coneParams.arc, min: 0, max: 1, step: 0.1, onChange: (val) => handleConeParamChange("arc", val) }), jsx(CheckboxPropertyLine, { label: "Up", value: coneUp, onChange: (val) => setConeUp(val) }), jsx("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: jsx(Button, { appearance: "primary", onClick: () => {
299
+ const coneParamsToUse = {
300
+ ...coneParams,
301
+ diameterTop: coneUp ? 0 : coneParams.diameterTop,
302
+ diameterBottom: coneUp ? coneParams.diameterBottom : 0,
303
+ };
304
+ MeshBuilder.CreateCylinder(coneParams.name, coneParamsToUse, scene);
305
+ SetCamera(scene);
306
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
307
+ MeshBuilder.CreateGround("Ground", {}, scene);
308
+ SetCamera(scene);
309
+ }, label: "Ground" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: groundParams.name, onChange: (val) => handleGroundParamChange("name", val) }), jsx(SpinButtonPropertyLine, { label: "Width", value: groundParams.width, min: 0, step: 0.1, onChange: (val) => handleGroundParamChange("width", val) }), jsx(SpinButtonPropertyLine, { label: "Height", value: groundParams.height, min: 0, step: 0.1, onChange: (val) => handleGroundParamChange("height", val) }), jsx(SpinButtonPropertyLine, { label: "Subdivisions", value: groundParams.subdivisions, min: 1, onChange: (val) => handleGroundParamChange("subdivisions", val) }), jsx(SpinButtonPropertyLine, { label: "Subdivisions X", value: groundParams.subdivisionsX, min: 1, onChange: (val) => handleGroundParamChange("subdivisionsX", val) }), jsx(SpinButtonPropertyLine, { label: "Subdivisions Y", value: groundParams.subdivisionsY, min: 1, onChange: (val) => handleGroundParamChange("subdivisionsY", val) }), jsx("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 16 }, children: jsx(Button, { appearance: "primary", onClick: () => {
310
+ MeshBuilder.CreateGround(groundParams.name, groundParams, scene);
311
+ SetCamera(scene);
312
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
313
+ fileInputRef.current?.click();
314
+ }, label: "Import Mesh" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: importMeshName, onChange: (val) => setImportMeshName(val) }), jsx("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: jsx(Button, { appearance: "primary", onClick: () => {
315
+ fileInputRef.current?.click();
316
+ }, label: "Import" }) })] }), jsx("input", { ref: fileInputRef, type: "file", accept: ".babylon,.glb,.gltf,.obj,.stl,.ply,.mesh,.babylonmeshdata", multiple: true, style: { display: "none" }, onChange: handleLocalMeshImport })] })] }));
317
+ };
318
+
319
+ const useStyles$3 = makeStyles({
320
+ section: {
321
+ display: "flex",
322
+ flexDirection: "column",
323
+ rowGap: tokens.spacingVerticalM,
324
+ },
325
+ row: { display: "flex", alignItems: "center", gap: "4px" },
326
+ });
327
+ /**
328
+ * Materials content component
329
+ * @param props - Component props
330
+ * @returns React component
331
+ */
332
+ const MaterialsContent = ({ scene }) => {
333
+ const classes = useStyles$3();
334
+ // Node Material state
335
+ const [nodeMaterialName, setNodeMaterialName] = useState("Node Material");
336
+ const [nodeMaterialSnippetId, setNodeMaterialSnippetId] = useState("");
337
+ // PBR Material state
338
+ const [pbrMaterialName, setPbrMaterialName] = useState("PBR Material");
339
+ // Standard Material state
340
+ const [standardMaterialName, setStandardMaterialName] = useState("Standard Material");
341
+ const handleCreateNodeMaterialAsync = async () => {
342
+ if (nodeMaterialSnippetId) {
343
+ try {
344
+ const nodeMaterial = await NodeMaterial.ParseFromSnippetAsync(nodeMaterialSnippetId, scene);
345
+ nodeMaterial.name = nodeMaterialName;
346
+ }
347
+ catch (e) {
348
+ alert("Failed to load Node Material from snippet: " + e);
349
+ }
350
+ }
351
+ else {
352
+ const nodeMaterial = new NodeMaterial(nodeMaterialName, scene);
353
+ nodeMaterial.build();
354
+ }
355
+ };
356
+ const handleCreatePBRMaterial = () => {
357
+ new PBRMaterial(pbrMaterialName, scene);
358
+ };
359
+ const handleCreateStandardMaterial = () => {
360
+ new StandardMaterial(standardMaterialName, scene);
361
+ };
362
+ return (jsxs("div", { className: classes.section, children: [jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreateNodeMaterialAsync, label: "Node Material" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: nodeMaterialName, onChange: (value) => setNodeMaterialName(value) }), jsx(TextInputPropertyLine, { label: "Snippet ID", value: nodeMaterialSnippetId, onChange: (value) => setNodeMaterialSnippetId(value) }), jsx(Button, { appearance: "primary", onClick: handleCreateNodeMaterialAsync, label: "Create" })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreatePBRMaterial, label: "PBR Material" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: pbrMaterialName, onChange: (value) => setPbrMaterialName(value) }), jsx(Button, { appearance: "primary", onClick: handleCreatePBRMaterial, label: "Create" })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreateStandardMaterial, label: "Standard Material" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: standardMaterialName, onChange: (value) => setStandardMaterialName(value) }), jsx(Button, { appearance: "primary", onClick: handleCreateStandardMaterial, label: "Create" })] })] })] }));
363
+ };
364
+
365
+ const useStyles$2 = makeStyles({
366
+ section: {
367
+ display: "flex",
368
+ flexDirection: "column",
369
+ rowGap: tokens.spacingVerticalM,
370
+ },
371
+ row: { display: "flex", alignItems: "center", gap: "4px" },
372
+ });
373
+ /**
374
+ * Lights content component
375
+ * @param props - Component props
376
+ * @returns React component
377
+ */
378
+ const LightsContent = ({ scene }) => {
379
+ const classes = useStyles$2();
380
+ // Point Light state
381
+ const [pointLightName, setPointLightName] = useState("Point Light");
382
+ const [pointLightPosition, setPointLightPosition] = useState(new Vector3(0, 5, 0));
383
+ // Directional Light state
384
+ const [directionalLightName, setDirectionalLightName] = useState("Directional Light");
385
+ const [directionalLightDirection, setDirectionalLightDirection] = useState(new Vector3(1, -1, 0));
386
+ // Spotlight state
387
+ const [spotlightName, setSpotlightName] = useState("Spotlight");
388
+ const [spotlightPosition, setSpotlightPosition] = useState(new Vector3(0, 5, 0));
389
+ const [spotlightDirection, setSpotlightDirection] = useState(new Vector3(0, -1, 0));
390
+ const [spotlightAngle, setSpotlightAngle] = useState(1);
391
+ const [spotlightExponent, setSpotlightExponent] = useState(1);
392
+ const handleCreatePointLight = () => {
393
+ const light = new PointLight(pointLightName, pointLightPosition, scene);
394
+ light.intensity = 1.0;
395
+ };
396
+ const handleCreateDirectionalLight = () => {
397
+ const dirLight = new DirectionalLight(directionalLightName, directionalLightDirection, scene);
398
+ dirLight.intensity = 1.0;
399
+ };
400
+ const handleCreateSpotlight = () => {
401
+ const spotlight = new SpotLight(spotlightName, spotlightPosition, spotlightDirection, spotlightAngle, spotlightExponent, scene);
402
+ spotlight.intensity = 1.0;
403
+ };
404
+ return (jsxs("div", { className: classes.section, children: [jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreatePointLight, label: "Point Light" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: pointLightName, onChange: (value) => setPointLightName(value) }), jsx(Vector3PropertyLine, { label: "Position", value: pointLightPosition, onChange: (value) => setPointLightPosition(value) }), jsx(Button, { appearance: "primary", onClick: handleCreatePointLight, label: "Create" })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreateDirectionalLight, label: "Directional Light" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: directionalLightName, onChange: (value) => setDirectionalLightName(value) }), jsx(Vector3PropertyLine, { label: "Direction", value: directionalLightDirection, onChange: (value) => setDirectionalLightDirection(value) }), jsx(Button, { appearance: "primary", onClick: handleCreateDirectionalLight, label: "Create" })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreateSpotlight, label: "Spotlight" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: spotlightName, onChange: (value) => setSpotlightName(value) }), jsx(Vector3PropertyLine, { label: "Position", value: spotlightPosition, onChange: (value) => setSpotlightPosition(value) }), jsx(Vector3PropertyLine, { label: "Direction", value: spotlightDirection, onChange: (value) => setSpotlightDirection(value) }), jsx(SpinButtonPropertyLine, { label: "Angle", value: spotlightAngle, onChange: (value) => setSpotlightAngle(value), min: 0, max: Math.PI, step: 0.1 }), jsx(SpinButtonPropertyLine, { label: "Exponent", value: spotlightExponent, onChange: (value) => setSpotlightExponent(value), min: 0, max: 10, step: 0.1 }), jsx(Button, { appearance: "primary", onClick: handleCreateSpotlight, label: "Create" })] })] })] }));
405
+ };
406
+
407
+ const useStyles$1 = makeStyles({
408
+ section: {
409
+ display: "flex",
410
+ flexDirection: "column",
411
+ rowGap: tokens.spacingVerticalM,
412
+ },
413
+ row: { display: "flex", alignItems: "center", gap: "4px" },
414
+ });
415
+ /**
416
+ * Cameras content component
417
+ * @param props - Component props
418
+ * @returns React component
419
+ */
420
+ const CamerasContent = ({ scene }) => {
421
+ const classes = useStyles$1();
422
+ // ArcRotate Camera state
423
+ const [arcRotateCameraName, setArcRotateCameraName] = useState("ArcRotate Camera");
424
+ const [arcRotateCameraTarget, setArcRotateCameraTarget] = useState(new Vector3(0, 0, 0));
425
+ const [arcRotateCameraRadius, setArcRotateCameraRadius] = useState(10);
426
+ const [arcRotateCameraAlpha, setArcRotateCameraAlpha] = useState(0);
427
+ const [arcRotateCameraBeta, setArcRotateCameraBeta] = useState(45);
428
+ const [arcRotateCameraUseRadians, setArcRotateCameraUseRadians] = useState(false);
429
+ // Universal Camera state
430
+ const [universalCameraName, setUniversalCameraName] = useState("Universal Camera");
431
+ const [universalCameraPosition, setUniversalCameraPosition] = useState(new Vector3(0, 1, -10));
432
+ const handleCreateArcRotateCamera = () => {
433
+ const alpha = arcRotateCameraUseRadians ? arcRotateCameraAlpha : (arcRotateCameraAlpha * Math.PI) / 180;
434
+ const beta = arcRotateCameraUseRadians ? arcRotateCameraBeta : (arcRotateCameraBeta * Math.PI) / 180;
435
+ const camera = new ArcRotateCamera(arcRotateCameraName, alpha, beta, arcRotateCameraRadius, arcRotateCameraTarget, scene);
436
+ camera.attachControl(scene.getEngine().getRenderingCanvas(), true);
437
+ if (!scene.activeCamera) {
438
+ scene.activeCamera = camera;
439
+ }
440
+ };
441
+ const handleCreateUniversalCamera = () => {
442
+ const camera = new UniversalCamera(universalCameraName, universalCameraPosition, scene);
443
+ camera.attachControl(scene.getEngine().getRenderingCanvas(), true);
444
+ if (!scene.activeCamera) {
445
+ scene.activeCamera = camera;
446
+ }
447
+ };
448
+ return (jsxs("div", { className: classes.section, children: [jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreateArcRotateCamera, label: "ArcRotate Camera" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: arcRotateCameraName, onChange: (value) => setArcRotateCameraName(value) }), jsx(Vector3PropertyLine, { label: "Target", value: arcRotateCameraTarget, onChange: (value) => setArcRotateCameraTarget(value) }), jsx(SpinButtonPropertyLine, { label: "Radius", value: arcRotateCameraRadius, onChange: (value) => setArcRotateCameraRadius(value), min: 0.1, max: 1000, step: 0.5 }), jsx(SpinButtonPropertyLine, { label: `Alpha ${arcRotateCameraUseRadians ? "(rad)" : "(deg)"}`, value: arcRotateCameraAlpha, onChange: (value) => setArcRotateCameraAlpha(value), min: arcRotateCameraUseRadians ? -Math.PI * 2 : -360, max: arcRotateCameraUseRadians ? Math.PI * 2 : 360, step: arcRotateCameraUseRadians ? 0.1 : 5 }), jsx(SpinButtonPropertyLine, { label: `Beta ${arcRotateCameraUseRadians ? "(rad)" : "(deg)"}`, value: arcRotateCameraBeta, onChange: (value) => setArcRotateCameraBeta(value), min: arcRotateCameraUseRadians ? 0 : 0, max: arcRotateCameraUseRadians ? Math.PI : 180, step: arcRotateCameraUseRadians ? 0.1 : 5 }), jsx(CheckboxPropertyLine, { label: "Use Radians", value: arcRotateCameraUseRadians, onChange: (value) => setArcRotateCameraUseRadians(value) }), jsx(Button, { appearance: "primary", onClick: handleCreateArcRotateCamera, label: "Create" })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreateUniversalCamera, label: "Universal Camera" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: universalCameraName, onChange: (value) => setUniversalCameraName(value) }), jsx(Vector3PropertyLine, { label: "Position", value: universalCameraPosition, onChange: (value) => setUniversalCameraPosition(value) }), jsx(Button, { appearance: "primary", onClick: handleCreateUniversalCamera, label: "Create" })] })] })] }));
449
+ };
450
+
451
+ const useStyles = makeStyles({
452
+ section: {
453
+ display: "flex",
454
+ flexDirection: "column",
455
+ rowGap: tokens.spacingVerticalM,
456
+ },
457
+ row: { display: "flex", alignItems: "center", gap: "4px" },
458
+ });
459
+ /**
460
+ * Particles content component
461
+ * @param props - Component props
462
+ * @returns React component
463
+ */
464
+ const ParticlesContent = ({ scene }) => {
465
+ const classes = useStyles();
466
+ // CPU Particle System state
467
+ const [cpuParticleSystemName, setCpuParticleSystemName] = useState("Particle System");
468
+ const [cpuParticleSystemCapacity, setCpuParticleSystemCapacity] = useState(2000);
469
+ // GPU Particle System state
470
+ const [gpuParticleSystemName, setGpuParticleSystemName] = useState("GPU Particle System");
471
+ const [gpuParticleSystemCapacity, setGpuParticleSystemCapacity] = useState(2000);
472
+ // Node Particle System state
473
+ const [nodeParticleSystemName, setNodeParticleSystemName] = useState("Node Particle System");
474
+ const [nodeParticleSystemSnippetId, setNodeParticleSystemSnippetId] = useState("");
475
+ const handleCreateCPUParticleSystem = () => {
476
+ setTimeout(() => {
477
+ const system = new ParticleSystem(cpuParticleSystemName, cpuParticleSystemCapacity, scene);
478
+ system.particleTexture = new Texture("https://assets.babylonjs.com/textures/flare.png", scene);
479
+ system.start();
480
+ }, 0);
481
+ };
482
+ const handleCreateGPUParticleSystem = () => {
483
+ if (GPUParticleSystem.IsSupported) {
484
+ setTimeout(() => {
485
+ const system = new GPUParticleSystem(gpuParticleSystemName, { capacity: gpuParticleSystemCapacity }, scene);
486
+ system.particleTexture = new Texture("https://assets.babylonjs.com/textures/flare.png", scene);
487
+ system.start();
488
+ }, 0);
489
+ }
490
+ else {
491
+ alert("GPU Particle System is not supported.");
492
+ }
493
+ };
494
+ const handleCreateNodeParticleSystemAsync = async () => {
495
+ try {
496
+ let nodeParticleSet;
497
+ const snippetId = nodeParticleSystemSnippetId.trim();
498
+ if (snippetId) {
499
+ nodeParticleSet = await NodeParticleSystemSet.ParseFromSnippetAsync(snippetId);
500
+ nodeParticleSet.name = nodeParticleSystemName;
501
+ }
502
+ else {
503
+ nodeParticleSet = NodeParticleSystemSet.CreateDefault(nodeParticleSystemName);
504
+ }
505
+ const particleSystemSet = await nodeParticleSet.buildAsync(scene);
506
+ for (const system of particleSystemSet.systems) {
507
+ system.name = nodeParticleSystemName;
508
+ }
509
+ particleSystemSet.start();
510
+ }
511
+ catch (e) {
512
+ global.console.error("Error creating Node Particle System:", e);
513
+ alert("Failed to create Node Particle System: " + e);
514
+ }
515
+ };
516
+ return (jsxs("div", { className: classes.section, children: [jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreateCPUParticleSystem, label: "CPU Particle System" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: cpuParticleSystemName, onChange: (value) => setCpuParticleSystemName(value) }), jsx(SpinButtonPropertyLine, { label: "Capacity", value: cpuParticleSystemCapacity, onChange: (value) => setCpuParticleSystemCapacity(value), min: 1, max: 100000, step: 100 }), jsx(Button, { appearance: "primary", onClick: handleCreateCPUParticleSystem, label: "Create" })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreateGPUParticleSystem, label: "GPU Particle System" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: gpuParticleSystemName, onChange: (value) => setGpuParticleSystemName(value) }), jsx(SpinButtonPropertyLine, { label: "Capacity", value: gpuParticleSystemCapacity, onChange: (value) => setGpuParticleSystemCapacity(value), min: 1, max: 1000000, step: 1000 }), jsx(Button, { appearance: "primary", onClick: handleCreateGPUParticleSystem, label: "Create" })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: handleCreateNodeParticleSystemAsync, label: "Node Particle System" }), jsxs(SettingsPopover, { children: [jsx(TextInputPropertyLine, { label: "Name", value: nodeParticleSystemName, onChange: (value) => setNodeParticleSystemName(value) }), jsx(TextInputPropertyLine, { label: "Snippet ID", value: nodeParticleSystemSnippetId, onChange: (value) => setNodeParticleSystemSnippetId(value) }), jsx(Button, { appearance: "primary", onClick: handleCreateNodeParticleSystemAsync, label: "Create" })] })] })] }));
517
+ };
518
+
519
+ // TODO: This is just a placeholder for a dynamically installed extension that brings in asset creation tools (node materials, etc.).
520
+ const CreateToolsServiceDefinition = {
521
+ friendlyName: "Creation Tools",
522
+ consumes: [ShellServiceIdentity, SceneContextIdentity],
523
+ factory: (shellService, sceneContext) => {
524
+ const registration = shellService.addSidePane({
525
+ key: "Create",
526
+ title: "Creation Tools",
527
+ icon: CollectionsAdd20Regular,
528
+ horizontalLocation: "left",
529
+ verticalLocation: "top",
530
+ content: () => {
531
+ const scene = useObservableState(() => sceneContext.currentScene, sceneContext.currentSceneObservable);
532
+ return (scene && (jsx(Fragment, { children: jsxs(Accordion, { children: [jsx(AccordionSection, { title: "Meshes", children: jsx(MeshesContent, { scene: scene }) }), jsx(AccordionSection, { title: "Materials", children: jsx(MaterialsContent, { scene: scene }) }), jsx(AccordionSection, { title: "Lights", children: jsx(LightsContent, { scene: scene }) }), jsx(AccordionSection, { title: "Particles", children: jsx(ParticlesContent, { scene: scene }) }), jsx(AccordionSection, { title: "Cameras", children: jsx(CamerasContent, { scene: scene }) })] }) })));
533
+ },
534
+ });
535
+ return {
536
+ dispose: () => registration.dispose(),
537
+ };
538
+ },
539
+ };
540
+ var quickCreateToolsService = {
541
+ serviceDefinitions: [CreateToolsServiceDefinition],
542
+ };
543
+
544
+ export { CreateToolsServiceDefinition, quickCreateToolsService as default };
545
+ //# sourceMappingURL=quickCreateToolsService-C-yzV033.js.map