@babylonjs/inspector 8.41.2 → 8.42.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.
@@ -0,0 +1,534 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { P as Popover, 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-BgzFAhky.js';
3
+ import { SettingsRegular, 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 { 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/Materials/Textures/cubeTexture.js';
84
+ import '@babylonjs/core/Meshes/mesh.js';
85
+ import '@babylonjs/core/Debug/skeletonViewer.js';
86
+ import '@babylonjs/core/Meshes/buffer.js';
87
+ import '@babylonjs/core/Meshes/Builders/linesBuilder.js';
88
+ import '@babylonjs/core/Meshes/instancedMesh.js';
89
+ import '@babylonjs/core/Rendering/renderingManager.js';
90
+ import '@babylonjs/core/Rendering/edgesRenderer.js';
91
+ import '@babylonjs/core/Rendering/outlineRenderer.js';
92
+ import '@babylonjs/core/Meshes/GaussianSplatting/gaussianSplattingMesh.js';
93
+ import '@babylonjs/core/Misc/gradients.js';
94
+ import '@babylonjs/core/Materials/Node/Blocks/gradientBlock.js';
95
+ import '@babylonjs/core/Particles/attractor.js';
96
+ import '@babylonjs/core/Meshes/Builders/sphereBuilder.js';
97
+ import '@babylonjs/core/Meshes/transformNode.js';
98
+ import '@babylonjs/core/Physics/v2/IPhysicsEnginePlugin.js';
99
+ import '@babylonjs/core/Physics/v2/physicsEngineComponent.js';
100
+ import '@babylonjs/core/PostProcesses/postProcess.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/Misc/textureTools.js';
106
+ import '@babylonjs/core/Materials/Textures/baseTexture.js';
107
+ import '@babylonjs/core/Materials/Textures/multiRenderTarget.js';
108
+ import '@babylonjs/core/Materials/Textures/renderTargetTexture.js';
109
+ import '@babylonjs/core/Materials/Textures/thinTexture.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
123
+ * @param props
124
+ * @returns
125
+ */
126
+ const SettingsPopover = (props) => {
127
+ return jsxs(Popover, { icon: SettingsRegular, children: [" ", props.children, " "] });
128
+ };
129
+
130
+ const useStyles$4 = makeStyles({
131
+ section: {
132
+ display: "flex",
133
+ flexDirection: "column",
134
+ rowGap: tokens.spacingVerticalM,
135
+ },
136
+ row: { display: "flex", alignItems: "center", gap: "4px" },
137
+ });
138
+ const SetCamera = function (scene) {
139
+ const camera = scene.activeCamera;
140
+ if (camera && camera.radius !== undefined) {
141
+ camera.radius = 5;
142
+ }
143
+ };
144
+ /**
145
+ * @internal
146
+ */
147
+ const MeshesContent = ({ scene }) => {
148
+ const classes = useStyles$4();
149
+ const [sphereParams, setSphereParams] = useState({
150
+ name: "Sphere",
151
+ segments: 32,
152
+ diameter: 1,
153
+ diameterX: 1,
154
+ diameterY: 1,
155
+ diameterZ: 1,
156
+ arc: 1,
157
+ slice: 1,
158
+ uniform: true,
159
+ });
160
+ const handleSphereParamChange = (key, value) => {
161
+ setSphereParams((prev) => ({
162
+ ...prev,
163
+ [key]: value,
164
+ }));
165
+ };
166
+ const [boxParams, setBoxParams] = useState({
167
+ name: "Box",
168
+ size: 1,
169
+ width: 1,
170
+ height: 1,
171
+ depth: 1,
172
+ });
173
+ const handleBoxParamChange = (key, value) => {
174
+ setBoxParams((prev) => ({
175
+ ...prev,
176
+ [key]: value,
177
+ }));
178
+ };
179
+ const [cylinderParams, setCylinderParams] = useState({
180
+ name: "Cylinder",
181
+ height: 2,
182
+ diameterTop: 1,
183
+ diameterBottom: 1,
184
+ diameter: 1,
185
+ tessellation: 32,
186
+ subdivisions: 1,
187
+ arc: 1,
188
+ });
189
+ const handleCylinderParamChange = (key, value) => {
190
+ setCylinderParams((prev) => ({
191
+ ...prev,
192
+ [key]: value,
193
+ }));
194
+ };
195
+ const [coneParams, setConeParams] = useState({
196
+ name: "Cone",
197
+ height: 2,
198
+ diameter: 1,
199
+ diameterTop: 0,
200
+ diameterBottom: 1,
201
+ tessellation: 32,
202
+ subdivisions: 1,
203
+ arc: 1,
204
+ });
205
+ const [coneUp, setConeUp] = useState(true);
206
+ const handleConeParamChange = (key, value) => {
207
+ setConeParams((prev) => ({
208
+ ...prev,
209
+ [key]: value,
210
+ }));
211
+ };
212
+ const [groundParams, setGroundParams] = useState({
213
+ name: "Ground",
214
+ width: 10,
215
+ height: 10,
216
+ subdivisions: 1,
217
+ subdivisionsX: 1,
218
+ subdivisionsY: 1,
219
+ });
220
+ const handleGroundParamChange = (key, value) => {
221
+ setGroundParams((prev) => ({
222
+ ...prev,
223
+ [key]: value,
224
+ }));
225
+ };
226
+ const fileInputRef = useRef(null);
227
+ const [importMeshName, setImportMeshName] = useState("ImportedMesh");
228
+ const handleLocalMeshImport = (event) => {
229
+ const files = event.target.files;
230
+ if (!files || files.length === 0) {
231
+ return;
232
+ }
233
+ const filesArray = Array.from(files);
234
+ if (importMeshName.trim().length > 0 && filesArray.length > 0) {
235
+ const originalFile = filesArray[0];
236
+ const extensionIndex = originalFile.name.lastIndexOf(".");
237
+ const extension = extensionIndex >= 0 ? originalFile.name.substring(extensionIndex) : "";
238
+ const sanitizedName = importMeshName.trim();
239
+ const desiredFileName = sanitizedName.toLowerCase().endsWith(extension.toLowerCase()) ? sanitizedName : `${sanitizedName}${extension}`;
240
+ filesArray[0] = new File([originalFile], desiredFileName, { type: originalFile.type, lastModified: originalFile.lastModified });
241
+ }
242
+ const filesInput = new FilesInput(scene.getEngine(), scene, null, null, null, null, null, null, (_sceneFile, _scene, message) => {
243
+ alert(message ? `Failed to import mesh: ${message}` : "Failed to import mesh.");
244
+ }, true);
245
+ filesInput.displayLoadingUI = false;
246
+ filesInput.loadFiles({ target: { files: filesArray } });
247
+ filesInput.dispose();
248
+ event.target.value = "";
249
+ };
250
+ return (jsxs("div", { className: classes.section, children: [jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
251
+ MeshBuilder.CreateSphere("Sphere", {}, scene);
252
+ SetCamera(scene);
253
+ }, 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: () => {
254
+ // Create params object based on uniform checkbox
255
+ const createParams = {
256
+ segments: sphereParams.segments,
257
+ arc: sphereParams.arc,
258
+ slice: sphereParams.slice,
259
+ };
260
+ if (sphereParams.uniform) {
261
+ // If uniform is checked, use diameter
262
+ createParams.diameter = sphereParams.diameter;
263
+ }
264
+ else {
265
+ // If uniform is unchecked, use individual diameters
266
+ createParams.diameterX = sphereParams.diameterX;
267
+ createParams.diameterY = sphereParams.diameterY;
268
+ createParams.diameterZ = sphereParams.diameterZ;
269
+ }
270
+ MeshBuilder.CreateSphere(sphereParams.name, createParams, scene);
271
+ SetCamera(scene);
272
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
273
+ MeshBuilder.CreateBox("Box", {}, scene);
274
+ SetCamera(scene);
275
+ }, 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: () => {
276
+ MeshBuilder.CreateBox(boxParams.name, boxParams, scene);
277
+ SetCamera(scene);
278
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
279
+ MeshBuilder.CreateCylinder("Cylinder", {}, scene);
280
+ SetCamera(scene);
281
+ }, 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: () => {
282
+ MeshBuilder.CreateCylinder(cylinderParams.name, cylinderParams, scene);
283
+ SetCamera(scene);
284
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
285
+ MeshBuilder.CreateCylinder("Cone", { diameterTop: 0 }, scene);
286
+ SetCamera(scene);
287
+ }, 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: () => {
288
+ const coneParamsToUse = {
289
+ ...coneParams,
290
+ diameterTop: coneUp ? 0 : coneParams.diameterTop,
291
+ diameterBottom: coneUp ? coneParams.diameterBottom : 0,
292
+ };
293
+ MeshBuilder.CreateCylinder(coneParams.name, coneParamsToUse, scene);
294
+ SetCamera(scene);
295
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
296
+ MeshBuilder.CreateGround("Ground", {}, scene);
297
+ SetCamera(scene);
298
+ }, 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: () => {
299
+ MeshBuilder.CreateGround(groundParams.name, groundParams, scene);
300
+ SetCamera(scene);
301
+ }, label: "Create" }) })] })] }), jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => {
302
+ fileInputRef.current?.click();
303
+ }, 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: () => {
304
+ fileInputRef.current?.click();
305
+ }, label: "Import" }) })] }), jsx("input", { ref: fileInputRef, type: "file", accept: ".babylon,.glb,.gltf,.obj,.stl,.ply,.mesh,.babylonmeshdata", multiple: true, style: { display: "none" }, onChange: handleLocalMeshImport })] })] }));
306
+ };
307
+
308
+ const useStyles$3 = makeStyles({
309
+ section: {
310
+ display: "flex",
311
+ flexDirection: "column",
312
+ rowGap: tokens.spacingVerticalM,
313
+ },
314
+ row: { display: "flex", alignItems: "center", gap: "4px" },
315
+ });
316
+ /**
317
+ * Materials content component
318
+ * @param props - Component props
319
+ * @returns React component
320
+ */
321
+ const MaterialsContent = ({ scene }) => {
322
+ const classes = useStyles$3();
323
+ // Node Material state
324
+ const [nodeMaterialName, setNodeMaterialName] = useState("Node Material");
325
+ const [nodeMaterialSnippetId, setNodeMaterialSnippetId] = useState("");
326
+ // PBR Material state
327
+ const [pbrMaterialName, setPbrMaterialName] = useState("PBR Material");
328
+ // Standard Material state
329
+ const [standardMaterialName, setStandardMaterialName] = useState("Standard Material");
330
+ const handleCreateNodeMaterialAsync = async () => {
331
+ if (nodeMaterialSnippetId) {
332
+ try {
333
+ const nodeMaterial = await NodeMaterial.ParseFromSnippetAsync(nodeMaterialSnippetId, scene);
334
+ nodeMaterial.name = nodeMaterialName;
335
+ }
336
+ catch (e) {
337
+ alert("Failed to load Node Material from snippet: " + e);
338
+ }
339
+ }
340
+ else {
341
+ const nodeMaterial = new NodeMaterial(nodeMaterialName, scene);
342
+ nodeMaterial.build();
343
+ }
344
+ };
345
+ const handleCreatePBRMaterial = () => {
346
+ new PBRMaterial(pbrMaterialName, scene);
347
+ };
348
+ const handleCreateStandardMaterial = () => {
349
+ new StandardMaterial(standardMaterialName, scene);
350
+ };
351
+ 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" })] })] })] }));
352
+ };
353
+
354
+ const useStyles$2 = makeStyles({
355
+ section: {
356
+ display: "flex",
357
+ flexDirection: "column",
358
+ rowGap: tokens.spacingVerticalM,
359
+ },
360
+ row: { display: "flex", alignItems: "center", gap: "4px" },
361
+ });
362
+ /**
363
+ * Lights content component
364
+ * @param props - Component props
365
+ * @returns React component
366
+ */
367
+ const LightsContent = ({ scene }) => {
368
+ const classes = useStyles$2();
369
+ // Point Light state
370
+ const [pointLightName, setPointLightName] = useState("Point Light");
371
+ const [pointLightPosition, setPointLightPosition] = useState(new Vector3(0, 5, 0));
372
+ // Directional Light state
373
+ const [directionalLightName, setDirectionalLightName] = useState("Directional Light");
374
+ const [directionalLightDirection, setDirectionalLightDirection] = useState(new Vector3(1, -1, 0));
375
+ // Spotlight state
376
+ const [spotlightName, setSpotlightName] = useState("Spotlight");
377
+ const [spotlightPosition, setSpotlightPosition] = useState(new Vector3(0, 5, 0));
378
+ const [spotlightDirection, setSpotlightDirection] = useState(new Vector3(0, -1, 0));
379
+ const [spotlightAngle, setSpotlightAngle] = useState(1);
380
+ const [spotlightExponent, setSpotlightExponent] = useState(1);
381
+ const handleCreatePointLight = () => {
382
+ const light = new PointLight(pointLightName, pointLightPosition, scene);
383
+ light.intensity = 1.0;
384
+ };
385
+ const handleCreateDirectionalLight = () => {
386
+ const dirLight = new DirectionalLight(directionalLightName, directionalLightDirection, scene);
387
+ dirLight.intensity = 1.0;
388
+ };
389
+ const handleCreateSpotlight = () => {
390
+ const spotlight = new SpotLight(spotlightName, spotlightPosition, spotlightDirection, spotlightAngle, spotlightExponent, scene);
391
+ spotlight.intensity = 1.0;
392
+ };
393
+ 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" })] })] })] }));
394
+ };
395
+
396
+ const useStyles$1 = makeStyles({
397
+ section: {
398
+ display: "flex",
399
+ flexDirection: "column",
400
+ rowGap: tokens.spacingVerticalM,
401
+ },
402
+ row: { display: "flex", alignItems: "center", gap: "4px" },
403
+ });
404
+ /**
405
+ * Cameras content component
406
+ * @param props - Component props
407
+ * @returns React component
408
+ */
409
+ const CamerasContent = ({ scene }) => {
410
+ const classes = useStyles$1();
411
+ // ArcRotate Camera state
412
+ const [arcRotateCameraName, setArcRotateCameraName] = useState("ArcRotate Camera");
413
+ const [arcRotateCameraTarget, setArcRotateCameraTarget] = useState(new Vector3(0, 0, 0));
414
+ const [arcRotateCameraRadius, setArcRotateCameraRadius] = useState(10);
415
+ const [arcRotateCameraAlpha, setArcRotateCameraAlpha] = useState(0);
416
+ const [arcRotateCameraBeta, setArcRotateCameraBeta] = useState(45);
417
+ const [arcRotateCameraUseRadians, setArcRotateCameraUseRadians] = useState(false);
418
+ // Universal Camera state
419
+ const [universalCameraName, setUniversalCameraName] = useState("Universal Camera");
420
+ const [universalCameraPosition, setUniversalCameraPosition] = useState(new Vector3(0, 1, -10));
421
+ const handleCreateArcRotateCamera = () => {
422
+ const alpha = arcRotateCameraUseRadians ? arcRotateCameraAlpha : (arcRotateCameraAlpha * Math.PI) / 180;
423
+ const beta = arcRotateCameraUseRadians ? arcRotateCameraBeta : (arcRotateCameraBeta * Math.PI) / 180;
424
+ const camera = new ArcRotateCamera(arcRotateCameraName, alpha, beta, arcRotateCameraRadius, arcRotateCameraTarget, scene);
425
+ camera.attachControl(scene.getEngine().getRenderingCanvas(), true);
426
+ if (!scene.activeCamera) {
427
+ scene.activeCamera = camera;
428
+ }
429
+ };
430
+ const handleCreateUniversalCamera = () => {
431
+ const camera = new UniversalCamera(universalCameraName, universalCameraPosition, scene);
432
+ camera.attachControl(scene.getEngine().getRenderingCanvas(), true);
433
+ if (!scene.activeCamera) {
434
+ scene.activeCamera = camera;
435
+ }
436
+ };
437
+ 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" })] })] })] }));
438
+ };
439
+
440
+ const useStyles = makeStyles({
441
+ section: {
442
+ display: "flex",
443
+ flexDirection: "column",
444
+ rowGap: tokens.spacingVerticalM,
445
+ },
446
+ row: { display: "flex", alignItems: "center", gap: "4px" },
447
+ });
448
+ /**
449
+ * Particles content component
450
+ * @param props - Component props
451
+ * @returns React component
452
+ */
453
+ const ParticlesContent = ({ scene }) => {
454
+ const classes = useStyles();
455
+ // CPU Particle System state
456
+ const [cpuParticleSystemName, setCpuParticleSystemName] = useState("Particle System");
457
+ const [cpuParticleSystemCapacity, setCpuParticleSystemCapacity] = useState(2000);
458
+ // GPU Particle System state
459
+ const [gpuParticleSystemName, setGpuParticleSystemName] = useState("GPU Particle System");
460
+ const [gpuParticleSystemCapacity, setGpuParticleSystemCapacity] = useState(2000);
461
+ // Node Particle System state
462
+ const [nodeParticleSystemName, setNodeParticleSystemName] = useState("Node Particle System");
463
+ const [nodeParticleSystemSnippetId, setNodeParticleSystemSnippetId] = useState("");
464
+ const handleCreateCPUParticleSystem = () => {
465
+ setTimeout(() => {
466
+ const system = new ParticleSystem(cpuParticleSystemName, cpuParticleSystemCapacity, scene);
467
+ system.particleTexture = new Texture("https://assets.babylonjs.com/textures/flare.png", scene);
468
+ system.start();
469
+ }, 0);
470
+ };
471
+ const handleCreateGPUParticleSystem = () => {
472
+ if (GPUParticleSystem.IsSupported) {
473
+ setTimeout(() => {
474
+ const system = new GPUParticleSystem(gpuParticleSystemName, { capacity: gpuParticleSystemCapacity }, scene);
475
+ system.particleTexture = new Texture("https://assets.babylonjs.com/textures/flare.png", scene);
476
+ system.start();
477
+ }, 0);
478
+ }
479
+ else {
480
+ alert("GPU Particle System is not supported.");
481
+ }
482
+ };
483
+ const handleCreateNodeParticleSystemAsync = async () => {
484
+ try {
485
+ let nodeParticleSet;
486
+ const snippetId = nodeParticleSystemSnippetId.trim();
487
+ if (snippetId) {
488
+ nodeParticleSet = await NodeParticleSystemSet.ParseFromSnippetAsync(snippetId);
489
+ nodeParticleSet.name = nodeParticleSystemName;
490
+ }
491
+ else {
492
+ nodeParticleSet = NodeParticleSystemSet.CreateDefault(nodeParticleSystemName);
493
+ }
494
+ const particleSystemSet = await nodeParticleSet.buildAsync(scene);
495
+ for (const system of particleSystemSet.systems) {
496
+ system.name = nodeParticleSystemName;
497
+ }
498
+ particleSystemSet.start();
499
+ }
500
+ catch (e) {
501
+ global.console.error("Error creating Node Particle System:", e);
502
+ alert("Failed to create Node Particle System: " + e);
503
+ }
504
+ };
505
+ 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" })] })] })] }));
506
+ };
507
+
508
+ // TODO: This is just a placeholder for a dynamically installed extension that brings in asset creation tools (node materials, etc.).
509
+ const CreateToolsServiceDefinition = {
510
+ friendlyName: "Creation Tools",
511
+ consumes: [ShellServiceIdentity, SceneContextIdentity],
512
+ factory: (shellService, sceneContext) => {
513
+ const registration = shellService.addSidePane({
514
+ key: "Create",
515
+ title: "Creation Tools",
516
+ icon: CollectionsAdd20Regular,
517
+ horizontalLocation: "left",
518
+ verticalLocation: "top",
519
+ content: () => {
520
+ const scene = useObservableState(() => sceneContext.currentScene, sceneContext.currentSceneObservable);
521
+ 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 }) })] }) })));
522
+ },
523
+ });
524
+ return {
525
+ dispose: () => registration.dispose(),
526
+ };
527
+ },
528
+ };
529
+ var quickCreateToolsService = {
530
+ serviceDefinitions: [CreateToolsServiceDefinition],
531
+ };
532
+
533
+ export { CreateToolsServiceDefinition, quickCreateToolsService as default };
534
+ //# sourceMappingURL=quickCreateToolsService-Bg2plbI-.js.map