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