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