import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { P as Popover, a as useToast, b as useInterceptObservable, B as Button, c as LinkToEntity, T as TextInputPropertyLine, d as SpinButtonPropertyLine, C as CheckboxPropertyLine, V as Vector3PropertyLine, e as useProperty, M as MessageBar, S as ShellServiceIdentity, f as SceneContextIdentity, g as SelectionServiceIdentity, h as useObservableState, A as Accordion, i as AccordionSection } from './index--oJsOVVX.js';
import { SettingsRegular, CollectionsAdd20Regular } from '@fluentui/react-icons';
import '@babylonjs/core/Particles/webgl2ParticleSystem.js';
import '@babylonjs/core/Rendering/prePassRendererSceneComponent.js';
import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder.js';
import { useState, useEffect, useCallback, useRef } from 'react';
import { FilesInput } from '@babylonjs/core/Misc/filesInput.js';
import { makeStyles, tokens } from '@fluentui/react-components';
import { registerBuiltInLoaders } from '@babylonjs/loaders/dynamic.js';
import { GetRegisteredSceneLoaderPluginMetadata } from '@babylonjs/core/Loading/sceneLoader.js';
import { NodeMaterial } from '@babylonjs/core/Materials/Node/nodeMaterial.js';
import { PBRMaterial } from '@babylonjs/core/Materials/PBR/pbrMaterial.js';
import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial.js';
import { ClusteredLightContainer } from '@babylonjs/core/Lights/Clustered/clusteredLightContainer.js';
import { PointLight } from '@babylonjs/core/Lights/pointLight.js';
import { DirectionalLight } from '@babylonjs/core/Lights/directionalLight.js';
import { SpotLight } from '@babylonjs/core/Lights/spotLight.js';
import { Vector3 } from '@babylonjs/core/Maths/math.vector.js';
import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera.js';
import { UniversalCamera } from '@babylonjs/core/Cameras/universalCamera.js';
import { FreeCamera } from '@babylonjs/core/Cameras/freeCamera.js';
import { FollowCamera } from '@babylonjs/core/Cameras/followCamera.js';
import { FlyCamera } from '@babylonjs/core/Cameras/flyCamera.js';
import { GeospatialCamera } from '@babylonjs/core/Cameras/geospatialCamera.js';
import { ParticleSystem } from '@babylonjs/core/Particles/particleSystem.js';
import { GPUParticleSystem } from '@babylonjs/core/Particles/gpuParticleSystem.js';
import { NodeParticleSystemSet } from '@babylonjs/core/Particles/Node/nodeParticleSystemSet.js';
import { Texture } from '@babylonjs/core/Materials/Textures/texture.js';
import { DefaultRenderingPipeline } from '@babylonjs/core/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.js';
import { SSAORenderingPipeline } from '@babylonjs/core/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.js';
import { SSAO2RenderingPipeline } from '@babylonjs/core/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.js';
import { SSRRenderingPipeline } from '@babylonjs/core/PostProcesses/RenderPipeline/Pipelines/ssrRenderingPipeline.js';
import { IblShadowsRenderPipeline } from '@babylonjs/core/Rendering/IBLShadows/iblShadowsRenderPipeline.js';
import { NodeRenderGraph } from '@babylonjs/core/FrameGraph/Node/nodeRenderGraph.js';
import { SpriteManager } from '@babylonjs/core/Sprites/spriteManager.js';
import '@babylonjs/core/Maths/math.color.js';
import '@babylonjs/core/Misc/observable.js';
import '@babylonjs/core/Misc/typeStore.js';
import '@babylonjs/core/Misc/dataStorage.js';
import '@babylonjs/core/Misc/logger.js';
import '@fluentui/react-motion-components-preview';
import '@babylonjs/core/Misc/asyncLock.js';
import '@babylonjs/core/Misc/deferred.js';
import '@fluentui-contrib/react-resize-handle';
import '@fluentui-contrib/react-virtualizer';
import '@babylonjs/core/Misc/uniqueIdGenerator.js';
import '@babylonjs/addons/msdfText/fontAsset.js';
import '@babylonjs/addons/msdfText/textRenderer.js';
import '@babylonjs/core/Debug/physicsViewer.js';
import '@babylonjs/core/Materials/materialFlags.js';
import '@babylonjs/core/Meshes/Builders/groundBuilder.js';
import '@babylonjs/core/Misc/tools.js';
import '@babylonjs/core/Rendering/utilityLayerRenderer.js';
import '@babylonjs/materials/grid/gridMaterial.js';
import '@babylonjs/core/Instrumentation/engineInstrumentation.js';
import '@babylonjs/core/Instrumentation/sceneInstrumentation.js';
import '@babylonjs/core/Engines/AbstractEngine/abstractEngine.timeQuery.js';
import '@babylonjs/core/Engines/Extensions/engine.query.js';
import '@babylonjs/core/Engines/WebGPU/Extensions/engine.query.js';
import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerCollectionStrategies.js';
import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerSceneExtension.js';
import '@babylonjs/core/Misc/pressureObserverWrapper.js';
import '@babylonjs/core/Maths/math.scalar.js';
import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerCollector.js';
import '@babylonjs/core/Maths/math.scalar.functions.js';
import '@babylonjs/core/Engines/abstractEngine.js';
import '@babylonjs/core/Bones/bone.js';
import '@babylonjs/core/Cameras/camera.js';
import '@babylonjs/core/FrameGraph/frameGraphUtils.js';
import '@babylonjs/core/Gizmos/cameraGizmo.js';
import '@babylonjs/core/Gizmos/gizmoManager.js';
import '@babylonjs/core/Gizmos/lightGizmo.js';
import '@babylonjs/core/Gizmos/spatialAudioGizmo.js';
import '@babylonjs/core/Lights/light.js';
import '@babylonjs/core/Meshes/abstractMesh.js';
import '@babylonjs/core/node.js';
import 'react-dom/client';
import '@babylonjs/core/Misc/screenshotTools.js';
import '@babylonjs/core/Layers/selectionOutlineLayer.js';
import '@babylonjs/core/Meshes/GaussianSplatting/gaussianSplattingMesh.js';
import '@babylonjs/core/Animations/animationGroup.js';
import '@babylonjs/core/Animations/animation.js';
import '@babylonjs/core/Animations/animationPropertiesOverride.js';
import '@babylonjs/core/Audio/sound.js';
import '@babylonjs/core/AudioV2/abstractAudio/abstractAudioBus.js';
import '@babylonjs/core/AudioV2/abstractAudio/abstractSound.js';
import '@babylonjs/core/AudioV2/abstractAudio/abstractSoundSource.js';
import '@babylonjs/core/AudioV2/abstractAudio/audioBus.js';
import '@babylonjs/core/AudioV2/abstractAudio/audioEngineV2.js';
import '@babylonjs/core/AudioV2/abstractAudio/staticSound.js';
import '@babylonjs/core/AudioV2/abstractAudio/streamingSound.js';
import '@babylonjs/core/Cameras/targetCamera.js';
import '@babylonjs/core/scene.js';
import '@babylonjs/core/FrameGraph/frameGraph.js';
import '@babylonjs/core/Lights/hemisphericLight.js';
import '@babylonjs/core/Lights/rectAreaLight.js';
import '@babylonjs/core/Lights/shadowLight.js';
import '@babylonjs/core/Lights/Shadows/cascadedShadowGenerator.js';
import '@babylonjs/core/Debug/directionalLightFrustumViewer.js';
import '@babylonjs/core/Materials/Textures/cubeTexture.js';
import '@babylonjs/core/Misc/fileTools.js';
import '@babylonjs/core/Lights/Shadows/shadowGenerator.js';
import '@babylonjs/core/Lights/Shadows/shadowGeneratorSceneComponent.js';
import '@babylonjs/core/Materials/material.js';
import '@babylonjs/core/Materials/multiMaterial.js';
import '@babylonjs/core/Materials/PBR/openpbrMaterial.js';
import '@babylonjs/core/Materials/PBR/pbrBaseMaterial.js';
import '@babylonjs/materials/sky/skyMaterial.js';
import '@babylonjs/core/Engines/constants.js';
import '@babylonjs/core/Engines/engine.js';
import '@babylonjs/core/Materials/Node/Blocks/gradientBlock.js';
import '@babylonjs/core/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes.js';
import '@babylonjs/core/Misc/gradients.js';
import '@babylonjs/core/Meshes/mesh.js';
import '@babylonjs/core/Debug/skeletonViewer.js';
import '@babylonjs/core/Meshes/buffer.js';
import '@babylonjs/core/Meshes/Builders/linesBuilder.js';
import '@babylonjs/core/Meshes/instancedMesh.js';
import '@babylonjs/core/Rendering/renderingManager.js';
import '@babylonjs/core/Rendering/edgesRenderer.js';
import '@babylonjs/core/Rendering/outlineRenderer.js';
import '@babylonjs/core/Particles/Node/nodeParticleSystemSet.helper.js';
import '@babylonjs/core/Particles/particleHelper.js';
import '@babylonjs/core/Particles/EmitterTypes/boxParticleEmitter.js';
import '@babylonjs/core/Particles/EmitterTypes/coneParticleEmitter.js';
import '@babylonjs/core/Particles/EmitterTypes/cylinderParticleEmitter.js';
import '@babylonjs/core/Particles/EmitterTypes/hemisphericParticleEmitter.js';
import '@babylonjs/core/Particles/EmitterTypes/meshParticleEmitter.js';
import '@babylonjs/core/Particles/EmitterTypes/pointParticleEmitter.js';
import '@babylonjs/core/Particles/EmitterTypes/sphereParticleEmitter.js';
import '@babylonjs/core/Particles/attractor.js';
import '@babylonjs/core/Meshes/Builders/sphereBuilder.js';
import '@babylonjs/core/Particles/Node/Blocks/particleInputBlock.js';
import '@babylonjs/core/Particles/Node/Blocks/Update/updateAttractorBlock.js';
import '@babylonjs/core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes.js';
import '@babylonjs/core/Meshes/transformNode.js';
import '@babylonjs/core/Physics/v2/IPhysicsEnginePlugin.js';
import '@babylonjs/core/Physics/v2/physicsEngineComponent.js';
import '@babylonjs/core/PostProcesses/postProcess.js';
import '@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipeline.js';
import '@babylonjs/core/PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.js';
import '@babylonjs/core/Materials/imageProcessingConfiguration.js';
import '@babylonjs/core/Bones/skeleton.js';
import '@babylonjs/core/Sprites/sprite.js';
import '@babylonjs/core/Misc/textureTools.js';
import '@babylonjs/core/Events/keyboardEvents.js';
import '@babylonjs/core/Events/pointerEvents.js';
import '@babylonjs/core/Materials/Textures/htmlElementTexture.js';
import '@babylonjs/core/Materials/shaderMaterial.js';
import '@babylonjs/core/Meshes/Builders/planeBuilder.js';
import '@babylonjs/core/Materials/Textures/baseTexture.js';
import '@babylonjs/core/Materials/Textures/envCubeTexture.js';
import '@babylonjs/core/Materials/Textures/multiRenderTarget.js';
import '@babylonjs/core/Materials/Textures/renderTargetTexture.js';
import '@babylonjs/core/Materials/Textures/thinTexture.js';
import '@babylonjs/core/AudioV2/abstractAudio/mainAudioBus.js';
import '@babylonjs/core/Rendering/boundingBoxRenderer.js';
import '@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.js';
import '@babylonjs/core/Sprites/spriteSceneComponent.js';
import '@babylonjs/core/Materials/Textures/dynamicTexture.js';
import '@babylonjs/core/Misc/equirectangularCapture.js';
import '@babylonjs/core/Misc/sceneRecorder.js';
import '@babylonjs/core/Misc/videoRecorder.js';
import '@babylonjs/core/Misc/sceneSerializer.js';
import '@babylonjs/core/Misc/environmentTextureTools.js';
import '@babylonjs/core/SmartAssets/smartAssetManager.js';
import '@babylonjs/core/Loading/Plugins/babylonFileLoader.js';
import '@babylonjs/core/SmartAssets/smartAssetSerializer.js';
import '@babylonjs/loaders/glTF/2.0/glTFLoaderExtensionRegistry.js';
import '@babylonjs/loaders/glTF/glTFFileLoader.js';
import '@babylonjs/loaders/glTF/glTFValidation.js';
import '@babylonjs/core/Collisions/gpuPicker.js';
import '@babylonjs/core/Engines/engineStore.js';
import '@babylonjs/core/Debug/debugLayer.js';
import '@babylonjs/core/Misc/lazy.js';

/**
 * Settings popover component
 * @param props
 * @returns
 */
const SettingsPopover = (props) => {
    return (jsx(Popover, { icon: SettingsRegular, open: props.open, onOpenChange: props.onOpenChange, children: props.children }));
};

const useStyles = makeStyles({
    section: {
        display: "flex",
        flexDirection: "column",
        rowGap: tokens.spacingVerticalM,
    },
    row: { display: "flex", alignItems: "center", gap: "4px" },
    rightAligned: { marginLeft: "auto" },
});
/**
 * Container component for quick create sections that provides consistent column layout with spacing
 * @param props - Component props
 * @returns React component
 */
const QuickCreateSection = ({ children }) => {
    const classes = useStyles();
    return jsx("div", { className: classes.section, children: children });
};
/**
 * Container component for quick create rows that provides consistent row layout for button + settings popover
 * @param props - Component props
 * @returns React component
 */
const QuickCreateRow = ({ children }) => {
    const classes = useStyles();
    return jsx("div", { className: classes.row, children: children });
};
function IsDisposable(entity) {
    return "dispose" in entity && typeof entity.dispose === "function";
}
/**
 * Reusable row component for entity creation. Renders a quick-create button, an optional settings popover
 * (with a baked-in Create button), and a "go to entity" button. Manages its own state for the last created entity
 * and shows a toast on creation.
 * @param props - The label, creation handler, selection service, and optional settings content
 * @returns A row with a button, optional settings popover, and go-to-entity button
 */
const QuickCreateItem = ({ selectionService, label, onCreate, onSettingsCreate, children }) => {
    const [lastCreatedEntity, setLastCreatedEntity] = useState(null);
    const [popoverOpen, setPopoverOpen] = useState(false);
    const { showToast } = useToast();
    const classes = useStyles();
    // If the last created entity is disposable, intercept its dispose to clear the reference.
    const disposableTarget = lastCreatedEntity && IsDisposable(lastCreatedEntity) ? lastCreatedEntity : null;
    const afterDispose = useInterceptObservable("function", disposableTarget, "dispose");
    useEffect(() => {
        const observer = afterDispose.add(() => setLastCreatedEntity(null));
        return () => observer.remove();
    }, [afterDispose]);
    const handleCreate = useCallback(async (factory) => {
        try {
            const entity = await factory();
            setLastCreatedEntity(entity);
            showToast(`Created ${entity.name}`);
        }
        catch (e) {
            showToast(`Creation failed: ${e instanceof Error ? e.message : String(e)}`);
        }
    }, [showToast]);
    return (jsxs("div", { className: classes.row, children: [jsx(Button, { onClick: () => void handleCreate(onCreate), label: label }), children && (jsxs(SettingsPopover, { open: popoverOpen, onOpenChange: setPopoverOpen, children: [children, jsx(Button, { appearance: "primary", onClick: () => {
                            setPopoverOpen(false);
                            void handleCreate(onSettingsCreate ?? onCreate);
                        }, label: "Create" })] })), jsx("div", { className: classes.rightAligned, children: jsx(LinkToEntity, { entity: lastCreatedEntity, selectionService: selectionService }) })] }));
};

registerBuiltInLoaders();
const SetCamera = function (scene) {
    const camera = scene.activeCamera;
    if (camera && camera.radius !== undefined) {
        camera.radius = 5;
    }
};
/**
 * @internal
 */
const MeshesContent = ({ scene, selectionService }) => {
    const [sphereParams, setSphereParams] = useState({
        name: "Sphere",
        segments: 32,
        diameter: 1,
        diameterX: 1,
        diameterY: 1,
        diameterZ: 1,
        arc: 1,
        slice: 1,
        uniform: true,
    });
    const handleSphereParamChange = (key, value) => {
        setSphereParams((prev) => ({
            ...prev,
            [key]: value,
        }));
    };
    const [boxParams, setBoxParams] = useState({
        name: "Box",
        size: 1,
        width: 1,
        height: 1,
        depth: 1,
    });
    const handleBoxParamChange = (key, value) => {
        setBoxParams((prev) => ({
            ...prev,
            [key]: value,
        }));
    };
    const [cylinderParams, setCylinderParams] = useState({
        name: "Cylinder",
        height: 2,
        diameterTop: 1,
        diameterBottom: 1,
        diameter: 1,
        tessellation: 32,
        subdivisions: 1,
        arc: 1,
    });
    const handleCylinderParamChange = (key, value) => {
        setCylinderParams((prev) => ({
            ...prev,
            [key]: value,
        }));
    };
    const [coneParams, setConeParams] = useState({
        name: "Cone",
        height: 2,
        diameter: 1,
        diameterTop: 0,
        diameterBottom: 1,
        tessellation: 32,
        subdivisions: 1,
        arc: 1,
    });
    const [coneUp, setConeUp] = useState(true);
    const handleConeParamChange = (key, value) => {
        setConeParams((prev) => ({
            ...prev,
            [key]: value,
        }));
    };
    const [groundParams, setGroundParams] = useState({
        name: "Ground",
        width: 10,
        height: 10,
        subdivisions: 1,
        subdivisionsX: 1,
        subdivisionsY: 1,
    });
    const handleGroundParamChange = (key, value) => {
        setGroundParams((prev) => ({
            ...prev,
            [key]: value,
        }));
    };
    const fileInputRef = useRef(null);
    const [importMeshName, setImportMeshName] = useState("ImportedMesh");
    const handleLocalMeshImport = (event) => {
        const files = event.target.files;
        if (!files || files.length === 0) {
            return;
        }
        const filesArray = Array.from(files);
        if (importMeshName.trim().length > 0 && filesArray.length > 0) {
            const originalFile = filesArray[0];
            const extensionIndex = originalFile.name.lastIndexOf(".");
            const extension = extensionIndex >= 0 ? originalFile.name.substring(extensionIndex) : "";
            const sanitizedName = importMeshName.trim();
            const desiredFileName = sanitizedName.toLowerCase().endsWith(extension.toLowerCase()) ? sanitizedName : `${sanitizedName}${extension}`;
            filesArray[0] = new File([originalFile], desiredFileName, { type: originalFile.type, lastModified: originalFile.lastModified });
        }
        const filesInput = new FilesInput(scene.getEngine(), scene, null, null, null, null, null, null, (_sceneFile, _scene, message) => {
            alert(message ? `Failed to import mesh: ${message}` : "Failed to import mesh.");
        }, true);
        filesInput.displayLoadingUI = false;
        filesInput.loadFiles({ target: { files: filesArray } });
        filesInput.dispose();
        event.target.value = "";
    };
    // Note: GetRegisteredSceneLoaderPluginMetadata includes extensions from all loaders,
    // including `.json` from the SPLAT loader, which is used for SOG (Sparse Octree Gaussian)
    // metadata files. To avoid suggesting that arbitrary JSON files can be imported as meshes,
    // we explicitly filter out the generic `.json` extension here.
    const supportedModelExtensions = GetRegisteredSceneLoaderPluginMetadata()
        .flatMap((plugin) => plugin.extensions.map((extension) => extension.extension))
        .filter((extension) => extension.toLowerCase() !== ".json");
    return (jsxs(QuickCreateSection, { children: [jsxs(QuickCreateItem, { selectionService: selectionService, label: "Sphere", onCreate: () => {
                    const mesh = MeshBuilder.CreateSphere("Sphere", {}, scene);
                    SetCamera(scene);
                    return mesh;
                }, onSettingsCreate: () => {
                    const createParams = {
                        segments: sphereParams.segments,
                        arc: sphereParams.arc,
                        slice: sphereParams.slice,
                    };
                    if (sphereParams.uniform) {
                        createParams.diameter = sphereParams.diameter;
                    }
                    else {
                        createParams.diameterX = sphereParams.diameterX;
                        createParams.diameterY = sphereParams.diameterY;
                        createParams.diameterZ = sphereParams.diameterZ;
                    }
                    const mesh = MeshBuilder.CreateSphere(sphereParams.name, createParams, scene);
                    SetCamera(scene);
                    return mesh;
                }, 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) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Box", onCreate: () => {
                    const mesh = MeshBuilder.CreateBox("Box", {}, scene);
                    SetCamera(scene);
                    return mesh;
                }, onSettingsCreate: () => {
                    const mesh = MeshBuilder.CreateBox(boxParams.name, boxParams, scene);
                    SetCamera(scene);
                    return mesh;
                }, 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) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Cylinder", onCreate: () => {
                    const mesh = MeshBuilder.CreateCylinder("Cylinder", {}, scene);
                    SetCamera(scene);
                    return mesh;
                }, onSettingsCreate: () => {
                    const mesh = MeshBuilder.CreateCylinder(cylinderParams.name, cylinderParams, scene);
                    SetCamera(scene);
                    return mesh;
                }, 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) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Cone", onCreate: () => {
                    const mesh = MeshBuilder.CreateCylinder("Cone", { diameterTop: 0 }, scene);
                    SetCamera(scene);
                    return mesh;
                }, onSettingsCreate: () => {
                    const coneParamsToUse = {
                        ...coneParams,
                        diameterTop: coneUp ? 0 : coneParams.diameterTop,
                        diameterBottom: coneUp ? coneParams.diameterBottom : 0,
                    };
                    const mesh = MeshBuilder.CreateCylinder(coneParams.name, coneParamsToUse, scene);
                    SetCamera(scene);
                    return mesh;
                }, 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) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Ground", onCreate: () => {
                    const mesh = MeshBuilder.CreateGround("Ground", {}, scene);
                    SetCamera(scene);
                    return mesh;
                }, onSettingsCreate: () => {
                    const mesh = MeshBuilder.CreateGround(groundParams.name, groundParams, scene);
                    SetCamera(scene);
                    return mesh;
                }, 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) })] }), jsxs(QuickCreateRow, { children: [jsx(Button, { onClick: () => {
                            fileInputRef.current?.click();
                        }, 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: () => {
                                        fileInputRef.current?.click();
                                    }, label: "Import" }) })] }), jsx("input", { ref: fileInputRef, type: "file", accept: supportedModelExtensions.join(","), multiple: true, style: { display: "none" }, onChange: handleLocalMeshImport })] })] }));
};

/**
 * Materials content component
 * @param props - Component props
 * @returns React component
 */
const MaterialsContent = ({ scene, selectionService }) => {
    // Node Material state
    const [nodeMaterialName, setNodeMaterialName] = useState("Node Material");
    const [nodeMaterialSnippetId, setNodeMaterialSnippetId] = useState("");
    // PBR Material state
    const [pbrMaterialName, setPbrMaterialName] = useState("PBR Material");
    // Standard Material state
    const [standardMaterialName, setStandardMaterialName] = useState("Standard Material");
    const createPBRMaterial = () => {
        return new PBRMaterial(pbrMaterialName, scene);
    };
    const createStandardMaterial = () => {
        return new StandardMaterial(standardMaterialName, scene);
    };
    const handleCreateNodeMaterialAsync = async () => {
        if (nodeMaterialSnippetId) {
            const nodeMaterial = await NodeMaterial.ParseFromSnippetAsync(nodeMaterialSnippetId, scene);
            nodeMaterial.name = nodeMaterialName;
            return nodeMaterial;
        }
        else {
            const nodeMaterial = new NodeMaterial(nodeMaterialName, scene);
            nodeMaterial.setToDefault();
            nodeMaterial.build();
            return nodeMaterial;
        }
    };
    return (jsxs(QuickCreateSection, { children: [jsxs(QuickCreateItem, { selectionService: selectionService, label: "Node Material", onCreate: handleCreateNodeMaterialAsync, children: [jsx(TextInputPropertyLine, { label: "Name", value: nodeMaterialName, onChange: (value) => setNodeMaterialName(value) }), jsx(TextInputPropertyLine, { label: "Snippet ID", value: nodeMaterialSnippetId, onChange: (value) => setNodeMaterialSnippetId(value) })] }), jsx(QuickCreateItem, { selectionService: selectionService, label: "PBR Material", onCreate: () => createPBRMaterial(), children: jsx(TextInputPropertyLine, { label: "Name", value: pbrMaterialName, onChange: (value) => setPbrMaterialName(value) }) }), jsx(QuickCreateItem, { selectionService: selectionService, label: "Standard Material", onCreate: () => createStandardMaterial(), children: jsx(TextInputPropertyLine, { label: "Name", value: standardMaterialName, onChange: (value) => setStandardMaterialName(value) }) })] }));
};

/**
 * Lights content component
 * @param props - Component props
 * @returns React component
 */
const LightsContent = ({ scene, selectionService }) => {
    // Point Light state
    const [pointLightName, setPointLightName] = useState("Point Light");
    const [pointLightPosition, setPointLightPosition] = useState(new Vector3(0, 5, 0));
    // Directional Light state
    const [directionalLightName, setDirectionalLightName] = useState("Directional Light");
    const [directionalLightDirection, setDirectionalLightDirection] = useState(new Vector3(1, -1, 0));
    // Spotlight state
    const [spotlightName, setSpotlightName] = useState("Spotlight");
    const [spotlightPosition, setSpotlightPosition] = useState(new Vector3(0, 5, 0));
    const [spotlightDirection, setSpotlightDirection] = useState(new Vector3(0, -1, 0));
    const [spotlightAngle, setSpotlightAngle] = useState(1);
    const [spotlightExponent, setSpotlightExponent] = useState(1);
    // Clustered Light Container state
    const [clusteredLightContainerName, setClusteredLightContainerName] = useState("Clustered Light");
    const createPointLight = () => {
        const light = new PointLight(pointLightName, pointLightPosition, scene);
        light.intensity = 1.0;
        return light;
    };
    const createDirectionalLight = () => {
        const dirLight = new DirectionalLight(directionalLightName, directionalLightDirection, scene);
        dirLight.intensity = 1.0;
        return dirLight;
    };
    const createSpotlight = () => {
        const spotlight = new SpotLight(spotlightName, spotlightPosition, spotlightDirection, spotlightAngle, spotlightExponent, scene);
        spotlight.intensity = 1.0;
        return spotlight;
    };
    const createClusteredLightContainerAsync = async () => {
        await import('@babylonjs/core/Lights/Clustered/clusteredLightingSceneComponent.js');
        return new ClusteredLightContainer(clusteredLightContainerName, [], scene);
    };
    return (jsxs(QuickCreateSection, { children: [jsxs(QuickCreateItem, { selectionService: selectionService, label: "Point Light", onCreate: () => createPointLight(), children: [jsx(TextInputPropertyLine, { label: "Name", value: pointLightName, onChange: (value) => setPointLightName(value) }), jsx(Vector3PropertyLine, { label: "Position", value: pointLightPosition, onChange: (value) => setPointLightPosition(value) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Directional Light", onCreate: () => createDirectionalLight(), children: [jsx(TextInputPropertyLine, { label: "Name", value: directionalLightName, onChange: (value) => setDirectionalLightName(value) }), jsx(Vector3PropertyLine, { label: "Direction", value: directionalLightDirection, onChange: (value) => setDirectionalLightDirection(value) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Spotlight", onCreate: () => createSpotlight(), 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(QuickCreateItem, { selectionService: selectionService, label: "Clustered Light", onCreate: async () => await createClusteredLightContainerAsync(), children: jsx(TextInputPropertyLine, { label: "Name", value: clusteredLightContainerName, onChange: (value) => setClusteredLightContainerName(value) }) })] }));
};

/**
 * Cameras content component
 * @param props - Component props
 * @returns React component
 */
const CamerasContent = ({ scene, selectionService }) => {
    // ArcRotate Camera state
    const [arcRotateCameraName, setArcRotateCameraName] = useState("ArcRotate Camera");
    const [arcRotateCameraTarget, setArcRotateCameraTarget] = useState(new Vector3(0, 0, 0));
    const [arcRotateCameraRadius, setArcRotateCameraRadius] = useState(10);
    const [arcRotateCameraAlpha, setArcRotateCameraAlpha] = useState(0);
    const [arcRotateCameraBeta, setArcRotateCameraBeta] = useState(45);
    const [arcRotateCameraUseRadians, setArcRotateCameraUseRadians] = useState(false);
    // Universal Camera state
    const [universalCameraName, setUniversalCameraName] = useState("Universal Camera");
    const [universalCameraPosition, setUniversalCameraPosition] = useState(new Vector3(0, 1, -10));
    // Free Camera state
    const [freeCameraName, setFreeCameraName] = useState("Free Camera");
    const [freeCameraPosition, setFreeCameraPosition] = useState(new Vector3(0, 1, -10));
    // Follow Camera state
    const [followCameraName, setFollowCameraName] = useState("Follow Camera");
    const [followCameraPosition, setFollowCameraPosition] = useState(new Vector3(0, 5, -10));
    const [followCameraRadius, setFollowCameraRadius] = useState(10);
    const [followCameraHeightOffset, setFollowCameraHeightOffset] = useState(4);
    const [followCameraRotationOffset, setFollowCameraRotationOffset] = useState(0);
    // Fly Camera state
    const [flyCameraName, setFlyCameraName] = useState("Fly Camera");
    const [flyCameraPosition, setFlyCameraPosition] = useState(new Vector3(0, 1, -10));
    // Geospatial Camera state
    const [geospatialCameraName, setGeospatialCameraName] = useState("Geospatial Camera");
    const [geospatialCameraPlanetRadius, setGeospatialCameraPlanetRadius] = useState(6371000);
    const setAsActiveIfNeeded = (camera) => {
        if (!scene.activeCamera) {
            scene.activeCamera = camera;
        }
    };
    const createArcRotateCamera = () => {
        const alpha = arcRotateCameraUseRadians ? arcRotateCameraAlpha : (arcRotateCameraAlpha * Math.PI) / 180;
        const beta = arcRotateCameraUseRadians ? arcRotateCameraBeta : (arcRotateCameraBeta * Math.PI) / 180;
        const camera = new ArcRotateCamera(arcRotateCameraName, alpha, beta, arcRotateCameraRadius, arcRotateCameraTarget, scene);
        camera.attachControl(scene.getEngine().getRenderingCanvas(), true);
        setAsActiveIfNeeded(camera);
        return camera;
    };
    const createUniversalCamera = () => {
        const camera = new UniversalCamera(universalCameraName, universalCameraPosition, scene);
        camera.attachControl(scene.getEngine().getRenderingCanvas(), true);
        setAsActiveIfNeeded(camera);
        return camera;
    };
    const createFreeCamera = () => {
        const camera = new FreeCamera(freeCameraName, freeCameraPosition, scene);
        camera.attachControl(scene.getEngine().getRenderingCanvas(), true);
        setAsActiveIfNeeded(camera);
        return camera;
    };
    const createFollowCamera = () => {
        const camera = new FollowCamera(followCameraName, followCameraPosition, scene);
        camera.radius = followCameraRadius;
        camera.heightOffset = followCameraHeightOffset;
        camera.rotationOffset = followCameraRotationOffset;
        camera.attachControl(true);
        setAsActiveIfNeeded(camera);
        return camera;
    };
    const createFlyCamera = () => {
        const camera = new FlyCamera(flyCameraName, flyCameraPosition, scene);
        camera.attachControl(true);
        setAsActiveIfNeeded(camera);
        return camera;
    };
    const createGeospatialCamera = () => {
        const camera = new GeospatialCamera(geospatialCameraName, scene, { planetRadius: geospatialCameraPlanetRadius });
        camera.attachControl(true);
        setAsActiveIfNeeded(camera);
        return camera;
    };
    return (jsxs(QuickCreateSection, { children: [jsxs(QuickCreateItem, { selectionService: selectionService, label: "ArcRotate Camera", onCreate: () => createArcRotateCamera(), 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) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Universal Camera", onCreate: () => createUniversalCamera(), children: [jsx(TextInputPropertyLine, { label: "Name", value: universalCameraName, onChange: (value) => setUniversalCameraName(value) }), jsx(Vector3PropertyLine, { label: "Position", value: universalCameraPosition, onChange: (value) => setUniversalCameraPosition(value) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Free Camera", onCreate: () => createFreeCamera(), children: [jsx(TextInputPropertyLine, { label: "Name", value: freeCameraName, onChange: (value) => setFreeCameraName(value) }), jsx(Vector3PropertyLine, { label: "Position", value: freeCameraPosition, onChange: (value) => setFreeCameraPosition(value) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Follow Camera", onCreate: () => createFollowCamera(), children: [jsx(TextInputPropertyLine, { label: "Name", value: followCameraName, onChange: (value) => setFollowCameraName(value) }), jsx(Vector3PropertyLine, { label: "Position", value: followCameraPosition, onChange: (value) => setFollowCameraPosition(value) }), jsx(SpinButtonPropertyLine, { label: "Radius", value: followCameraRadius, onChange: (value) => setFollowCameraRadius(value), min: 0.1, max: 1000, step: 0.5 }), jsx(SpinButtonPropertyLine, { label: "Height Offset", value: followCameraHeightOffset, onChange: (value) => setFollowCameraHeightOffset(value), min: -100, max: 100, step: 0.5 }), jsx(SpinButtonPropertyLine, { label: "Rotation Offset (deg)", value: followCameraRotationOffset, onChange: (value) => setFollowCameraRotationOffset(value), min: -180, max: 180, step: 5 })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Fly Camera", onCreate: () => createFlyCamera(), children: [jsx(TextInputPropertyLine, { label: "Name", value: flyCameraName, onChange: (value) => setFlyCameraName(value) }), jsx(Vector3PropertyLine, { label: "Position", value: flyCameraPosition, onChange: (value) => setFlyCameraPosition(value) })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Geospatial Camera", onCreate: () => createGeospatialCamera(), children: [jsx(TextInputPropertyLine, { label: "Name", value: geospatialCameraName, onChange: (value) => setGeospatialCameraName(value) }), jsx(SpinButtonPropertyLine, { label: "Planet Radius (m)", value: geospatialCameraPlanetRadius, onChange: (value) => setGeospatialCameraPlanetRadius(value), min: 1000, max: 100000000, step: 1000 })] })] }));
};

/**
 * Particles content component
 * @param props - Component props
 * @returns React component
 */
const ParticlesContent = ({ scene, selectionService }) => {
    // CPU Particle System state
    const [cpuParticleSystemName, setCpuParticleSystemName] = useState("Particle System");
    const [cpuParticleSystemCapacity, setCpuParticleSystemCapacity] = useState(2000);
    // GPU Particle System state
    const [gpuParticleSystemName, setGpuParticleSystemName] = useState("GPU Particle System");
    const [gpuParticleSystemCapacity, setGpuParticleSystemCapacity] = useState(2000);
    // Node Particle System state
    const [nodeParticleSystemName, setNodeParticleSystemName] = useState("Node Particle System");
    const [nodeParticleSystemSnippetId, setNodeParticleSystemSnippetId] = useState("");
    const handleCreateCPUAsync = async () => {
        return await new Promise((resolve) => {
            setTimeout(() => {
                const system = new ParticleSystem(cpuParticleSystemName, cpuParticleSystemCapacity, scene);
                system.particleTexture = new Texture("https://assets.babylonjs.com/textures/flare.png", scene);
                system.start();
                resolve(system);
            }, 0);
        });
    };
    const handleCreateGPUAsync = async () => {
        if (!GPUParticleSystem.IsSupported) {
            alert("GPU Particle System is not supported.");
            throw new Error("GPU Particle System is not supported.");
        }
        return await new Promise((resolve) => {
            setTimeout(() => {
                const system = new GPUParticleSystem(gpuParticleSystemName, { capacity: gpuParticleSystemCapacity }, scene);
                system.particleTexture = new Texture("https://assets.babylonjs.com/textures/flare.png", scene);
                system.start();
                resolve(system);
            }, 0);
        });
    };
    const handleCreateNodeAsync = async () => {
        let nodeParticleSet;
        const snippetId = nodeParticleSystemSnippetId.trim();
        if (snippetId) {
            nodeParticleSet = await NodeParticleSystemSet.ParseFromSnippetAsync(snippetId);
            nodeParticleSet.name = nodeParticleSystemName;
        }
        else {
            nodeParticleSet = NodeParticleSystemSet.CreateDefault(nodeParticleSystemName);
        }
        const particleSystemSet = await nodeParticleSet.buildAsync(scene);
        const systems = particleSystemSet.systems;
        if (systems.length === 0) {
            throw new Error("No particle systems were produced by the node particle system.");
        }
        for (const system of systems) {
            system.name = nodeParticleSystemName;
        }
        particleSystemSet.start();
        return systems[0];
    };
    return (jsxs(QuickCreateSection, { children: [jsxs(QuickCreateItem, { selectionService: selectionService, label: "CPU Particle System", onCreate: handleCreateCPUAsync, 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 })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "GPU Particle System", onCreate: handleCreateGPUAsync, 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 })] }), jsxs(QuickCreateItem, { selectionService: selectionService, label: "Node Particle System", onCreate: handleCreateNodeAsync, children: [jsx(TextInputPropertyLine, { label: "Name", value: nodeParticleSystemName, onChange: (value) => setNodeParticleSystemName(value) }), jsx(TextInputPropertyLine, { label: "Snippet ID", value: nodeParticleSystemSnippetId, onChange: (value) => setNodeParticleSystemSnippetId(value) })] })] }));
};

const GetUniquePipelineName = (baseName, scene) => {
    const pipelines = scene.postProcessRenderPipelineManager.supportedPipelines;
    const existingNames = new Set(pipelines.map((p) => p._name));
    if (!existingNames.has(baseName)) {
        return baseName;
    }
    let counter = 1;
    let uniqueName = `${baseName} ${counter}`;
    while (existingNames.has(uniqueName)) {
        counter++;
        uniqueName = `${baseName} ${counter}`;
    }
    return uniqueName;
};
/**
 * Rendering Pipelines content component
 * @param props - Component props
 * @returns React component
 */
const RenderingPipelinesContent = ({ scene, selectionService }) => {
    // Default Rendering Pipeline state
    const [defaultPipelineName, setDefaultPipelineName] = useState("Default rendering pipeline");
    // SSAO Pipeline state
    const [ssaoPipelineName, setSsaoPipelineName] = useState("SSAO rendering pipeline");
    // SSAO2 Pipeline state
    const [ssao2PipelineName, setSsao2PipelineName] = useState("SSAO2 rendering pipeline");
    // SSR Pipeline state
    const [ssrPipelineName, setSsrPipelineName] = useState("SSR rendering pipeline");
    // IBL Shadows Pipeline state
    const [iblShadowsPipelineName, setIblShadowsPipelineName] = useState("IBL Shadows rendering pipeline");
    const createDefaultPipeline = () => {
        const name = GetUniquePipelineName(defaultPipelineName, scene);
        return new DefaultRenderingPipeline(name, true, scene, scene.cameras);
    };
    const createSSAOPipeline = () => {
        const name = GetUniquePipelineName(ssaoPipelineName, scene);
        return new SSAORenderingPipeline(name, scene, 1, scene.cameras);
    };
    const createSSAO2Pipeline = () => {
        const name = GetUniquePipelineName(ssao2PipelineName, scene);
        return new SSAO2RenderingPipeline(name, scene, 1, scene.cameras);
    };
    const createSSRPipeline = () => {
        const name = GetUniquePipelineName(ssrPipelineName, scene);
        return new SSRRenderingPipeline(name, scene, scene.cameras);
    };
    const createIBLShadowsPipeline = () => {
        const name = GetUniquePipelineName(iblShadowsPipelineName, scene);
        return new IblShadowsRenderPipeline(name, scene, {}, scene.cameras);
    };
    const caps = scene.getEngine().getCaps();
    const hasDrawBuffers = caps.drawBuffersExtension;
    const hasTexelFetch = caps.texelFetch;
    const camera = useProperty(scene, "activeCamera");
    return (jsx(QuickCreateSection, { children: !camera ? (jsx(MessageBar, { message: "Cannot create rendering pipeline without an active camera.", title: "No active camera", intent: "info" })) : (jsxs(Fragment, { children: [jsx(QuickCreateItem, { selectionService: selectionService, label: "Default Pipeline", onCreate: () => createDefaultPipeline(), children: jsx(TextInputPropertyLine, { label: "Name", value: defaultPipelineName, onChange: (value) => setDefaultPipelineName(value) }) }), jsx(QuickCreateItem, { selectionService: selectionService, label: "SSAO Pipeline", onCreate: () => createSSAOPipeline(), children: jsx(TextInputPropertyLine, { label: "Name", value: ssaoPipelineName, onChange: (value) => setSsaoPipelineName(value) }) }), hasDrawBuffers && (jsx(QuickCreateItem, { selectionService: selectionService, label: "SSAO2 Pipeline", onCreate: () => createSSAO2Pipeline(), children: jsx(TextInputPropertyLine, { label: "Name", value: ssao2PipelineName, onChange: (value) => setSsao2PipelineName(value) }) })), hasDrawBuffers && hasTexelFetch && (jsx(QuickCreateItem, { selectionService: selectionService, label: "SSR Pipeline", onCreate: () => createSSRPipeline(), children: jsx(TextInputPropertyLine, { label: "Name", value: ssrPipelineName, onChange: (value) => setSsrPipelineName(value) }) })), hasDrawBuffers && hasTexelFetch && (jsx(QuickCreateItem, { selectionService: selectionService, label: "IBL Shadows Pipeline", onCreate: () => createIBLShadowsPipeline(), children: jsx(TextInputPropertyLine, { label: "Name", value: iblShadowsPipelineName, onChange: (value) => setIblShadowsPipelineName(value) }) }))] })) }));
};

/**
 * Helper to generate a unique frame graph name
 * @param baseName - The base name to use
 * @param scene - The scene to check for existing frame graphs
 * @returns A unique name
 */
function GetUniqueName(baseName, scene) {
    let name = baseName;
    let idSubscript = 1;
    while (scene.getFrameGraphByName(name)) {
        name = baseName + " " + idSubscript++;
    }
    return name;
}
/**
 * Frame Graphs content component
 * @param props - Component props
 * @returns React component
 */
const FrameGraphsContent = ({ scene, selectionService }) => {
    // Node Render Graph state
    const [frameGraphName, setFrameGraphName] = useState("Frame Graph");
    const createFrameGraph = () => {
        const uniqueName = GetUniqueName(frameGraphName, scene);
        const newNodeRenderGraph = new NodeRenderGraph(uniqueName, scene);
        newNodeRenderGraph.setToDefault();
        void newNodeRenderGraph.buildAsync();
        // Return the underlying FrameGraph, which is what gets registered with the scene
        // and matched by the properties/explorer services via `instanceof FrameGraph`.
        return newNodeRenderGraph.frameGraph;
    };
    return (jsx(QuickCreateSection, { children: jsx(QuickCreateItem, { selectionService: selectionService, label: "Frame Graph", onCreate: () => createFrameGraph(), children: jsx(TextInputPropertyLine, { label: "Name", value: frameGraphName, onChange: (value) => setFrameGraphName(value) }) }) }));
};

/**
 * Sprite Managers content component
 * @param props - Component props
 * @returns React component
 */
const SpriteManagersContent = ({ scene, selectionService }) => {
    // Sprite Manager state
    const [spriteManagerName, setSpriteManagerName] = useState("Sprite Manager");
    const [spriteManagerCapacity, setSpriteManagerCapacity] = useState(500);
    const [spriteManagerCellSize, setSpriteManagerCellSize] = useState(64);
    const [spriteManagerTextureUrl, setSpriteManagerTextureUrl] = useState("https://assets.babylonjs.com/textures/player.png");
    const createSpriteManager = () => {
        return new SpriteManager(spriteManagerName, spriteManagerTextureUrl, spriteManagerCapacity, spriteManagerCellSize, scene);
    };
    return (jsx(QuickCreateSection, { children: jsxs(QuickCreateItem, { selectionService: selectionService, label: "Sprite Manager", onCreate: () => createSpriteManager(), children: [jsx(TextInputPropertyLine, { label: "Name", value: spriteManagerName, onChange: (value) => setSpriteManagerName(value) }), jsx(TextInputPropertyLine, { label: "Texture URL", value: spriteManagerTextureUrl, onChange: (value) => setSpriteManagerTextureUrl(value) }), jsx(SpinButtonPropertyLine, { label: "Capacity", value: spriteManagerCapacity, onChange: (value) => setSpriteManagerCapacity(value), min: 1, max: 10000, step: 100 }), jsx(SpinButtonPropertyLine, { label: "Cell Size", value: spriteManagerCellSize, onChange: (value) => setSpriteManagerCellSize(value), min: 1, max: 1024, step: 1 })] }) }));
};

// TODO: This is just a placeholder for a dynamically installed extension that brings in asset creation tools (node materials, etc.).
const CreateToolsServiceDefinition = {
    friendlyName: "Creation Tools",
    consumes: [ShellServiceIdentity, SceneContextIdentity, SelectionServiceIdentity],
    factory: (shellService, sceneContext, selectionService) => {
        const registration = shellService.addSidePane({
            key: "Create",
            title: "Creation Tools",
            icon: CollectionsAdd20Regular,
            horizontalLocation: "left",
            verticalLocation: "top",
            content: () => {
                const scene = useObservableState(() => sceneContext.currentScene, sceneContext.currentSceneObservable);
                return (scene && (jsx(Fragment, { children: jsxs(Accordion, { children: [jsx(AccordionSection, { title: "Meshes", children: jsx(MeshesContent, { scene: scene, selectionService: selectionService }) }), jsx(AccordionSection, { title: "Materials", children: jsx(MaterialsContent, { scene: scene, selectionService: selectionService }) }), jsx(AccordionSection, { title: "Lights", children: jsx(LightsContent, { scene: scene, selectionService: selectionService }) }), jsx(AccordionSection, { title: "Particles", children: jsx(ParticlesContent, { scene: scene, selectionService: selectionService }) }), jsx(AccordionSection, { title: "Cameras", children: jsx(CamerasContent, { scene: scene, selectionService: selectionService }) }), jsx(AccordionSection, { title: "Rendering Pipelines", children: jsx(RenderingPipelinesContent, { scene: scene, selectionService: selectionService }) }), jsx(AccordionSection, { title: "Frame Graphs", children: jsx(FrameGraphsContent, { scene: scene, selectionService: selectionService }) }), jsx(AccordionSection, { title: "Sprite Managers", children: jsx(SpriteManagersContent, { scene: scene, selectionService: selectionService }) })] }) })));
            },
        });
        return {
            dispose: () => registration.dispose(),
        };
    },
};
var quickCreateToolsService = {
    serviceDefinitions: [CreateToolsServiceDefinition],
};

export { CreateToolsServiceDefinition, quickCreateToolsService as default };
//# sourceMappingURL=quickCreateToolsService-eZ4MCuJ2.js.map
