unreal-engine-mcp-server 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/automation/bridge.d.ts.map +1 -0
- package/dist/automation/bridge.js.map +1 -0
- package/dist/automation/connection-manager.d.ts.map +1 -0
- package/dist/automation/connection-manager.js.map +1 -0
- package/dist/automation/handshake.d.ts.map +1 -0
- package/dist/automation/handshake.js.map +1 -0
- package/dist/automation/index.d.ts.map +1 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/automation/message-handler.d.ts.map +1 -0
- package/dist/automation/message-handler.js.map +1 -0
- package/dist/automation/request-tracker.d.ts.map +1 -0
- package/dist/automation/request-tracker.js.map +1 -0
- package/dist/automation/types.d.ts.map +1 -0
- package/dist/automation/types.js.map +1 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +4 -3
- package/dist/cli.js.map +1 -0
- package/dist/config/class-aliases.d.ts.map +1 -0
- package/dist/config/class-aliases.js.map +1 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js.map +1 -0
- package/dist/graphql/loaders.d.ts.map +1 -0
- package/dist/graphql/loaders.js.map +1 -0
- package/dist/graphql/resolvers.d.ts.map +1 -0
- package/dist/graphql/resolvers.js +29 -29
- package/dist/graphql/resolvers.js.map +1 -0
- package/dist/graphql/schema.d.ts.map +1 -0
- package/dist/graphql/schema.js.map +1 -0
- package/dist/graphql/server.d.ts.map +1 -0
- package/dist/graphql/server.js.map +1 -0
- package/dist/graphql/types.d.ts.map +1 -0
- package/dist/graphql/types.js.map +1 -0
- package/dist/handlers/resource-handlers.d.ts.map +1 -0
- package/dist/handlers/resource-handlers.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -7
- package/dist/index.js.map +1 -0
- package/dist/resources/actors.d.ts.map +1 -0
- package/dist/resources/actors.js.map +1 -0
- package/dist/resources/assets.d.ts.map +1 -0
- package/dist/resources/assets.js +6 -4
- package/dist/resources/assets.js.map +1 -0
- package/dist/resources/levels.d.ts.map +1 -0
- package/dist/resources/levels.js.map +1 -0
- package/dist/server/resource-registry.d.ts.map +1 -0
- package/dist/server/resource-registry.js.map +1 -0
- package/dist/server/tool-registry.d.ts.map +1 -0
- package/dist/server/tool-registry.js.map +1 -0
- package/dist/server-setup.d.ts.map +1 -0
- package/dist/server-setup.js.map +1 -0
- package/dist/services/health-monitor.d.ts.map +1 -0
- package/dist/services/health-monitor.js.map +1 -0
- package/dist/services/metrics-server.d.ts.map +1 -0
- package/dist/services/metrics-server.js.map +1 -0
- package/dist/tools/actors.d.ts.map +1 -0
- package/dist/tools/actors.js +3 -1
- package/dist/tools/actors.js.map +1 -0
- package/dist/tools/animation.d.ts.map +1 -0
- package/dist/tools/animation.js +2 -2
- package/dist/tools/animation.js.map +1 -0
- package/dist/tools/assets.d.ts.map +1 -0
- package/dist/tools/assets.js.map +1 -0
- package/dist/tools/audio.d.ts.map +1 -0
- package/dist/tools/audio.js.map +1 -0
- package/dist/tools/base-tool.d.ts.map +1 -0
- package/dist/tools/base-tool.js.map +1 -0
- package/dist/tools/behavior-tree.d.ts.map +1 -0
- package/dist/tools/behavior-tree.js.map +1 -0
- package/dist/tools/blueprint.d.ts.map +1 -0
- package/dist/tools/blueprint.js +4 -2
- package/dist/tools/blueprint.js.map +1 -0
- package/dist/tools/consolidated-tool-definitions.d.ts.map +1 -0
- package/dist/tools/consolidated-tool-definitions.js.map +1 -0
- package/dist/tools/consolidated-tool-handlers.d.ts.map +1 -0
- package/dist/tools/consolidated-tool-handlers.js.map +1 -0
- package/dist/tools/debug.d.ts.map +1 -0
- package/dist/tools/debug.js +3 -1
- package/dist/tools/debug.js.map +1 -0
- package/dist/tools/dynamic-handler-registry.d.ts.map +1 -0
- package/dist/tools/dynamic-handler-registry.js +3 -1
- package/dist/tools/dynamic-handler-registry.js.map +1 -0
- package/dist/tools/editor.d.ts.map +1 -0
- package/dist/tools/editor.js +1 -1
- package/dist/tools/editor.js.map +1 -0
- package/dist/tools/engine.d.ts.map +1 -0
- package/dist/tools/engine.js.map +1 -0
- package/dist/tools/environment.d.ts.map +1 -0
- package/dist/tools/environment.js +2 -2
- package/dist/tools/environment.js.map +1 -0
- package/dist/tools/foliage.d.ts.map +1 -0
- package/dist/tools/foliage.js.map +1 -0
- package/dist/tools/handlers/actor-handlers.d.ts +1 -1
- package/dist/tools/handlers/actor-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/actor-handlers.js +6 -5
- package/dist/tools/handlers/actor-handlers.js.map +1 -0
- package/dist/tools/handlers/animation-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/animation-handlers.js.map +1 -0
- package/dist/tools/handlers/argument-helper.d.ts.map +1 -0
- package/dist/tools/handlers/argument-helper.js.map +1 -0
- package/dist/tools/handlers/asset-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/asset-handlers.js +5 -1
- package/dist/tools/handlers/asset-handlers.js.map +1 -0
- package/dist/tools/handlers/audio-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/audio-handlers.js.map +1 -0
- package/dist/tools/handlers/blueprint-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/blueprint-handlers.js +2 -1
- package/dist/tools/handlers/blueprint-handlers.js.map +1 -0
- package/dist/tools/handlers/common-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/common-handlers.js.map +1 -0
- package/dist/tools/handlers/editor-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/editor-handlers.js +12 -2
- package/dist/tools/handlers/editor-handlers.js.map +1 -0
- package/dist/tools/handlers/effect-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/effect-handlers.js.map +1 -0
- package/dist/tools/handlers/environment-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/environment-handlers.js.map +1 -0
- package/dist/tools/handlers/graph-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/graph-handlers.js +61 -1
- package/dist/tools/handlers/graph-handlers.js.map +1 -0
- package/dist/tools/handlers/input-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/input-handlers.js.map +1 -0
- package/dist/tools/handlers/inspect-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/inspect-handlers.js.map +1 -0
- package/dist/tools/handlers/level-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/level-handlers.js.map +1 -0
- package/dist/tools/handlers/lighting-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/lighting-handlers.js +23 -1
- package/dist/tools/handlers/lighting-handlers.js.map +1 -0
- package/dist/tools/handlers/performance-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/performance-handlers.js +15 -2
- package/dist/tools/handlers/performance-handlers.js.map +1 -0
- package/dist/tools/handlers/pipeline-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/pipeline-handlers.js.map +1 -0
- package/dist/tools/handlers/sequence-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/sequence-handlers.js.map +1 -0
- package/dist/tools/handlers/system-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/system-handlers.js +16 -1
- package/dist/tools/handlers/system-handlers.js.map +1 -0
- package/dist/tools/input.d.ts.map +1 -0
- package/dist/tools/input.js +3 -1
- package/dist/tools/input.js.map +1 -0
- package/dist/tools/introspection.d.ts.map +1 -0
- package/dist/tools/introspection.js.map +1 -0
- package/dist/tools/landscape.d.ts.map +1 -0
- package/dist/tools/landscape.js +3 -1
- package/dist/tools/landscape.js.map +1 -0
- package/dist/tools/level.d.ts.map +1 -0
- package/dist/tools/level.js.map +1 -0
- package/dist/tools/lighting.d.ts.map +1 -0
- package/dist/tools/lighting.js +3 -1
- package/dist/tools/lighting.js.map +1 -0
- package/dist/tools/logs.d.ts.map +1 -0
- package/dist/tools/logs.js.map +1 -0
- package/dist/tools/materials.d.ts.map +1 -0
- package/dist/tools/materials.js +3 -1
- package/dist/tools/materials.js.map +1 -0
- package/dist/tools/niagara.d.ts.map +1 -0
- package/dist/tools/niagara.js +7 -5
- package/dist/tools/niagara.js.map +1 -0
- package/dist/tools/performance.d.ts.map +1 -0
- package/dist/tools/performance.js.map +1 -0
- package/dist/tools/physics.d.ts.map +1 -0
- package/dist/tools/physics.js +9 -7
- package/dist/tools/physics.js.map +1 -0
- package/dist/tools/property-dictionary.d.ts.map +1 -0
- package/dist/tools/property-dictionary.js.map +1 -0
- package/dist/tools/sequence.d.ts.map +1 -0
- package/dist/tools/sequence.js +3 -1
- package/dist/tools/sequence.js.map +1 -0
- package/dist/tools/tool-definition-utils.d.ts.map +1 -0
- package/dist/tools/tool-definition-utils.js.map +1 -0
- package/dist/tools/ui.d.ts.map +1 -0
- package/dist/tools/ui.js +3 -1
- package/dist/tools/ui.js.map +1 -0
- package/dist/types/automation-responses.d.ts.map +1 -0
- package/dist/types/automation-responses.js.map +1 -0
- package/dist/types/env.d.ts.map +1 -0
- package/dist/types/env.js.map +1 -0
- package/dist/types/handler-types.d.ts.map +1 -0
- package/dist/types/handler-types.js.map +1 -0
- package/dist/types/tool-interfaces.d.ts.map +1 -0
- package/dist/types/tool-interfaces.js.map +1 -0
- package/dist/types/tool-types.d.ts.map +1 -0
- package/dist/types/tool-types.js.map +1 -0
- package/dist/unreal-bridge.d.ts +1 -0
- package/dist/unreal-bridge.d.ts.map +1 -0
- package/dist/unreal-bridge.js +8 -0
- package/dist/unreal-bridge.js.map +1 -0
- package/dist/utils/command-validator.d.ts.map +1 -0
- package/dist/utils/command-validator.js.map +1 -0
- package/dist/utils/elicitation.d.ts.map +1 -0
- package/dist/utils/elicitation.js.map +1 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/ini-reader.d.ts.map +1 -0
- package/dist/utils/ini-reader.js.map +1 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/normalize.d.ts.map +1 -0
- package/dist/utils/normalize.js.map +1 -0
- package/dist/utils/path-security.d.ts.map +1 -0
- package/dist/utils/path-security.js.map +1 -0
- package/dist/utils/response-factory.d.ts.map +1 -0
- package/dist/utils/response-factory.js +3 -1
- package/dist/utils/response-factory.js.map +1 -0
- package/dist/utils/response-validator.d.ts.map +1 -0
- package/dist/utils/response-validator.js.map +1 -0
- package/dist/utils/result-helpers.d.ts.map +1 -0
- package/dist/utils/result-helpers.js.map +1 -0
- package/dist/utils/safe-json.d.ts.map +1 -0
- package/dist/utils/safe-json.js.map +1 -0
- package/dist/utils/unreal-command-queue.d.ts.map +1 -0
- package/dist/utils/unreal-command-queue.js.map +1 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/wasm/index.d.ts.map +1 -0
- package/dist/wasm/index.js.map +1 -0
- package/package.json +12 -34
- package/server.json +2 -2
- package/.dockerignore +0 -57
- package/.env.example +0 -26
- package/.env.production +0 -61
- package/.eslintrc.json +0 -0
- package/.eslintrc.override.json +0 -8
- package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -94
- package/.github/ISSUE_TEMPLATE/config.yml +0 -8
- package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -56
- package/.github/copilot-instructions.md +0 -478
- package/.github/dependabot.yml +0 -19
- package/.github/labeler.yml +0 -24
- package/.github/labels.yml +0 -70
- package/.github/pull_request_template.md +0 -42
- package/.github/release-drafter-config.yml +0 -51
- package/.github/workflows/auto-merge.yml +0 -38
- package/.github/workflows/ci.yml +0 -38
- package/.github/workflows/dependency-review.yml +0 -17
- package/.github/workflows/gemini-issue-triage.yml +0 -172
- package/.github/workflows/greetings.yml +0 -27
- package/.github/workflows/labeler.yml +0 -17
- package/.github/workflows/links.yml +0 -80
- package/.github/workflows/pr-size-labeler.yml +0 -137
- package/.github/workflows/publish-mcp.yml +0 -79
- package/.github/workflows/release-drafter.yml +0 -24
- package/.github/workflows/release.yml +0 -112
- package/.github/workflows/semantic-pull-request.yml +0 -35
- package/.github/workflows/smoke-test.yml +0 -36
- package/.github/workflows/stale.yml +0 -28
- package/CONTRIBUTING.md +0 -140
- package/Dockerfile +0 -37
- package/GEMINI.md +0 -115
- package/Public/Plugin_setup_guide.mp4 +0 -0
- package/Public/icon.png +0 -0
- package/claude_desktop_config_example.json +0 -15
- package/dist/types/responses.d.ts +0 -249
- package/dist/types/responses.js +0 -2
- package/docs/GraphQL-API.md +0 -888
- package/docs/Migration-Guide-v0.5.0.md +0 -684
- package/docs/Roadmap.md +0 -53
- package/docs/WebAssembly-Integration.md +0 -628
- package/docs/editor-plugin-extension.md +0 -370
- package/docs/handler-mapping.md +0 -249
- package/docs/native-automation-progress.md +0 -128
- package/docs/testing-guide.md +0 -423
- package/eslint.config.mjs +0 -68
- package/mcp-config-example.json +0 -14
- package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +0 -8
- package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +0 -64
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +0 -189
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +0 -22
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +0 -30
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +0 -1983
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +0 -72
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +0 -46
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +0 -846
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +0 -2393
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +0 -300
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +0 -2807
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +0 -1087
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +0 -488
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +0 -643
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +0 -31
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +0 -1094
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +0 -5750
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +0 -152
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +0 -2614
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +0 -42
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +0 -1237
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +0 -1725
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +0 -2265
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +0 -954
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +0 -209
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +0 -41
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +0 -1164
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +0 -762
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +0 -663
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +0 -136
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +0 -494
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +0 -278
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +0 -625
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +0 -401
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +0 -67
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +0 -472
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +0 -2634
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +0 -189
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +0 -917
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +0 -39
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +0 -2706
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +0 -519
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +0 -38
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +0 -668
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +0 -346
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +0 -1345
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +0 -149
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +0 -782
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +0 -115
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +0 -796
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +0 -117
- package/scripts/check-unreal-connection.mjs +0 -19
- package/scripts/clean-tmp.js +0 -23
- package/scripts/patch-wasm.js +0 -26
- package/scripts/run-all-tests.mjs +0 -136
- package/scripts/smoke-test.ts +0 -94
- package/scripts/sync-mcp-plugin.js +0 -143
- package/scripts/test-no-plugin-alternates.mjs +0 -113
- package/scripts/validate-server.js +0 -46
- package/scripts/verify-automation-bridge.js +0 -200
- package/src/automation/bridge.ts +0 -630
- package/src/automation/connection-manager.ts +0 -148
- package/src/automation/handshake.ts +0 -99
- package/src/automation/index.ts +0 -2
- package/src/automation/message-handler.ts +0 -192
- package/src/automation/request-tracker.ts +0 -155
- package/src/automation/types.ts +0 -108
- package/src/cli.ts +0 -34
- package/src/config/class-aliases.ts +0 -65
- package/src/config.ts +0 -73
- package/src/constants.ts +0 -29
- package/src/graphql/loaders.ts +0 -244
- package/src/graphql/resolvers.ts +0 -1008
- package/src/graphql/schema.ts +0 -452
- package/src/graphql/server.ts +0 -156
- package/src/graphql/types.ts +0 -10
- package/src/handlers/resource-handlers.ts +0 -186
- package/src/index.ts +0 -243
- package/src/resources/actors.ts +0 -127
- package/src/resources/assets.ts +0 -286
- package/src/resources/levels.ts +0 -68
- package/src/server/resource-registry.ts +0 -47
- package/src/server/tool-registry.ts +0 -354
- package/src/server-setup.ts +0 -114
- package/src/services/health-monitor.ts +0 -132
- package/src/services/metrics-server.ts +0 -176
- package/src/tools/actors.ts +0 -564
- package/src/tools/animation.ts +0 -941
- package/src/tools/assets.ts +0 -394
- package/src/tools/audio.ts +0 -499
- package/src/tools/base-tool.ts +0 -52
- package/src/tools/behavior-tree.ts +0 -45
- package/src/tools/blueprint.ts +0 -940
- package/src/tools/consolidated-tool-definitions.ts +0 -1256
- package/src/tools/consolidated-tool-handlers.ts +0 -302
- package/src/tools/debug.ts +0 -622
- package/src/tools/dynamic-handler-registry.ts +0 -33
- package/src/tools/editor.ts +0 -435
- package/src/tools/engine.ts +0 -43
- package/src/tools/environment.ts +0 -281
- package/src/tools/foliage.ts +0 -596
- package/src/tools/handlers/actor-handlers.ts +0 -244
- package/src/tools/handlers/animation-handlers.ts +0 -237
- package/src/tools/handlers/argument-helper.ts +0 -142
- package/src/tools/handlers/asset-handlers.ts +0 -550
- package/src/tools/handlers/audio-handlers.ts +0 -194
- package/src/tools/handlers/blueprint-handlers.ts +0 -380
- package/src/tools/handlers/common-handlers.ts +0 -108
- package/src/tools/handlers/editor-handlers.ts +0 -124
- package/src/tools/handlers/effect-handlers.ts +0 -224
- package/src/tools/handlers/environment-handlers.ts +0 -183
- package/src/tools/handlers/graph-handlers.ts +0 -117
- package/src/tools/handlers/input-handlers.ts +0 -28
- package/src/tools/handlers/inspect-handlers.ts +0 -450
- package/src/tools/handlers/level-handlers.ts +0 -253
- package/src/tools/handlers/lighting-handlers.ts +0 -151
- package/src/tools/handlers/performance-handlers.ts +0 -132
- package/src/tools/handlers/pipeline-handlers.ts +0 -194
- package/src/tools/handlers/sequence-handlers.ts +0 -438
- package/src/tools/handlers/system-handlers.ts +0 -564
- package/src/tools/input.ts +0 -160
- package/src/tools/introspection.ts +0 -689
- package/src/tools/landscape.ts +0 -649
- package/src/tools/level.ts +0 -989
- package/src/tools/lighting.ts +0 -1052
- package/src/tools/logs.ts +0 -219
- package/src/tools/materials.ts +0 -295
- package/src/tools/niagara.ts +0 -485
- package/src/tools/performance.ts +0 -661
- package/src/tools/physics.ts +0 -679
- package/src/tools/property-dictionary.ts +0 -98
- package/src/tools/sequence.ts +0 -385
- package/src/tools/tool-definition-utils.ts +0 -35
- package/src/tools/ui.ts +0 -452
- package/src/types/automation-responses.ts +0 -119
- package/src/types/env.ts +0 -17
- package/src/types/handler-types.ts +0 -442
- package/src/types/responses.ts +0 -355
- package/src/types/tool-interfaces.ts +0 -250
- package/src/types/tool-types.ts +0 -575
- package/src/unreal-bridge.ts +0 -693
- package/src/utils/command-validator.ts +0 -139
- package/src/utils/elicitation.ts +0 -132
- package/src/utils/error-handler.ts +0 -287
- package/src/utils/ini-reader.ts +0 -86
- package/src/utils/logger.ts +0 -35
- package/src/utils/normalize.test.ts +0 -162
- package/src/utils/normalize.ts +0 -146
- package/src/utils/path-security.ts +0 -43
- package/src/utils/response-factory.ts +0 -44
- package/src/utils/response-validator.ts +0 -395
- package/src/utils/result-helpers.ts +0 -195
- package/src/utils/safe-json.test.ts +0 -90
- package/src/utils/safe-json.ts +0 -70
- package/src/utils/unreal-command-queue.ts +0 -166
- package/src/utils/validation.test.ts +0 -184
- package/src/utils/validation.ts +0 -312
- package/src/wasm/index.ts +0 -838
- package/test-server.mjs +0 -100
- package/tests/test-animation.mjs +0 -369
- package/tests/test-asset-advanced.mjs +0 -82
- package/tests/test-asset-graph.mjs +0 -311
- package/tests/test-audio.mjs +0 -417
- package/tests/test-automation-timeouts.mjs +0 -98
- package/tests/test-behavior-tree.mjs +0 -444
- package/tests/test-blueprint-graph.mjs +0 -410
- package/tests/test-blueprint.mjs +0 -577
- package/tests/test-client-mode.mjs +0 -86
- package/tests/test-console-command.mjs +0 -56
- package/tests/test-control-actor.mjs +0 -425
- package/tests/test-control-editor.mjs +0 -112
- package/tests/test-graphql.mjs +0 -372
- package/tests/test-input.mjs +0 -349
- package/tests/test-inspect.mjs +0 -302
- package/tests/test-landscape.mjs +0 -316
- package/tests/test-lighting.mjs +0 -428
- package/tests/test-manage-asset.mjs +0 -438
- package/tests/test-manage-level.mjs +0 -89
- package/tests/test-materials.mjs +0 -356
- package/tests/test-niagara.mjs +0 -185
- package/tests/test-no-inline-python.mjs +0 -122
- package/tests/test-performance.mjs +0 -539
- package/tests/test-plugin-handshake.mjs +0 -82
- package/tests/test-runner.mjs +0 -993
- package/tests/test-sequence.mjs +0 -104
- package/tests/test-system.mjs +0 -96
- package/tests/test-wasm.mjs +0 -283
- package/tests/test-world-partition.mjs +0 -215
- package/tsconfig.json +0 -56
- package/vitest.config.ts +0 -35
- package/wasm/Cargo.lock +0 -363
- package/wasm/Cargo.toml +0 -42
- package/wasm/LICENSE +0 -21
- package/wasm/README.md +0 -253
- package/wasm/src/dependency_resolver.rs +0 -377
- package/wasm/src/lib.rs +0 -153
- package/wasm/src/property_parser.rs +0 -271
- package/wasm/src/transform_math.rs +0 -396
- package/wasm/tests/integration.rs +0 -109
package/src/tools/lighting.ts
DELETED
|
@@ -1,1052 +0,0 @@
|
|
|
1
|
-
// Lighting tools for Unreal Engine using Automation Bridge
|
|
2
|
-
import { UnrealBridge } from '../unreal-bridge.js';
|
|
3
|
-
import { AutomationBridge } from '../automation/index.js';
|
|
4
|
-
import { ensureVector3 } from '../utils/validation.js';
|
|
5
|
-
import { wasmIntegration } from '../wasm/index.js';
|
|
6
|
-
|
|
7
|
-
export class LightingTools {
|
|
8
|
-
constructor(private bridge: UnrealBridge, private automationBridge?: AutomationBridge) { }
|
|
9
|
-
|
|
10
|
-
setAutomationBridge(automationBridge?: AutomationBridge) { this.automationBridge = automationBridge; }
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
private normalizeName(value: unknown, defaultName?: string): string {
|
|
14
|
-
if (typeof value === 'string') {
|
|
15
|
-
const trimmed = value.trim();
|
|
16
|
-
if (trimmed.length > 0) {
|
|
17
|
-
return trimmed;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (typeof defaultName === 'string') {
|
|
22
|
-
const trimmedDefault = defaultName.trim();
|
|
23
|
-
if (trimmedDefault.length > 0) {
|
|
24
|
-
return trimmedDefault;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Auto-generate if no name is provided
|
|
29
|
-
return `Light_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* List available light types (classes)
|
|
34
|
-
*/
|
|
35
|
-
async listLightTypes() {
|
|
36
|
-
if (!this.automationBridge) {
|
|
37
|
-
throw new Error('Automation Bridge required to list light types');
|
|
38
|
-
}
|
|
39
|
-
const response = await this.automationBridge.sendAutomationRequest('list_light_types', {});
|
|
40
|
-
return response;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Spawn a light actor using the Automation Bridge.
|
|
45
|
-
* @param lightClass The Unreal light class name (e.g. 'DirectionalLight', 'PointLight')
|
|
46
|
-
* @param params Light spawn parameters
|
|
47
|
-
*/
|
|
48
|
-
private async spawnLightViaAutomation(
|
|
49
|
-
lightClass: string,
|
|
50
|
-
params: {
|
|
51
|
-
name: string;
|
|
52
|
-
location?: [number, number, number];
|
|
53
|
-
rotation?: [number, number, number] | { pitch: number, yaw: number, roll: number };
|
|
54
|
-
properties?: Record<string, unknown>;
|
|
55
|
-
}
|
|
56
|
-
) {
|
|
57
|
-
if (!this.automationBridge) {
|
|
58
|
-
throw new Error('Automation Bridge not available. Cannot spawn lights without plugin support.');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
const payload: Record<string, unknown> = {
|
|
63
|
-
lightClass,
|
|
64
|
-
name: params.name,
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
if (params.location) {
|
|
68
|
-
// Use WASM vectorAdd for light location processing
|
|
69
|
-
const zeroVector: [number, number, number] = [0, 0, 0];
|
|
70
|
-
const processedLocation = wasmIntegration.vectorAdd(zeroVector, params.location);
|
|
71
|
-
console.error('[WASM] Using vectorAdd for light positioning');
|
|
72
|
-
payload.location = { x: processedLocation[0], y: processedLocation[1], z: processedLocation[2] };
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (params.rotation) {
|
|
76
|
-
if (Array.isArray(params.rotation)) {
|
|
77
|
-
payload.rotation = { pitch: params.rotation[0], yaw: params.rotation[1], roll: params.rotation[2] };
|
|
78
|
-
} else {
|
|
79
|
-
payload.rotation = params.rotation;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (params.properties) {
|
|
84
|
-
payload.properties = params.properties;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const response = await this.automationBridge.sendAutomationRequest('spawn_light', payload, {
|
|
88
|
-
timeoutMs: 60000
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
if (response.success === false) {
|
|
92
|
-
throw new Error(response.error || response.message || 'Failed to spawn light');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return response;
|
|
96
|
-
} catch (error) {
|
|
97
|
-
throw new Error(
|
|
98
|
-
`Failed to spawn ${lightClass}: ${error instanceof Error ? error.message : String(error)}`
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Create directional light
|
|
104
|
-
async createDirectionalLight(params: {
|
|
105
|
-
name: string;
|
|
106
|
-
intensity?: number;
|
|
107
|
-
color?: [number, number, number];
|
|
108
|
-
rotation?: [number, number, number] | { pitch: number, yaw: number, roll: number };
|
|
109
|
-
castShadows?: boolean;
|
|
110
|
-
temperature?: number;
|
|
111
|
-
useAsAtmosphereSunLight?: boolean;
|
|
112
|
-
properties?: Record<string, unknown>;
|
|
113
|
-
}) {
|
|
114
|
-
const name = this.normalizeName(params.name);
|
|
115
|
-
if (!this.automationBridge) {
|
|
116
|
-
throw new Error('Automation Bridge required for light spawning');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Validate numeric parameters
|
|
120
|
-
if (params.intensity !== undefined) {
|
|
121
|
-
if (typeof params.intensity !== 'number' || !isFinite(params.intensity)) {
|
|
122
|
-
throw new Error(`Invalid intensity value: ${params.intensity}`);
|
|
123
|
-
}
|
|
124
|
-
if (params.intensity < 0) {
|
|
125
|
-
throw new Error('Invalid intensity: must be non-negative');
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (params.temperature !== undefined) {
|
|
130
|
-
if (typeof params.temperature !== 'number' || !isFinite(params.temperature)) {
|
|
131
|
-
throw new Error(`Invalid temperature value: ${params.temperature}`);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Validate arrays
|
|
136
|
-
if (params.color !== undefined) {
|
|
137
|
-
if (!Array.isArray(params.color) || params.color.length !== 3) {
|
|
138
|
-
throw new Error('Invalid color: must be an array [r,g,b]');
|
|
139
|
-
}
|
|
140
|
-
for (const c of params.color) {
|
|
141
|
-
if (typeof c !== 'number' || !isFinite(c)) {
|
|
142
|
-
throw new Error('Invalid color component: must be finite numbers');
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (params.rotation !== undefined) {
|
|
148
|
-
if (Array.isArray(params.rotation)) {
|
|
149
|
-
if (params.rotation.length !== 3) {
|
|
150
|
-
throw new Error('Invalid rotation: must be an array [pitch,yaw,roll]');
|
|
151
|
-
}
|
|
152
|
-
for (const r of params.rotation) {
|
|
153
|
-
if (typeof r !== 'number' || !isFinite(r)) {
|
|
154
|
-
throw new Error('Invalid rotation component: must be finite numbers');
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const rot = params.rotation || [0, 0, 0];
|
|
161
|
-
|
|
162
|
-
// Build properties for the light
|
|
163
|
-
const properties: Record<string, unknown> = params.properties || {};
|
|
164
|
-
if (params.intensity !== undefined) {
|
|
165
|
-
properties.intensity = params.intensity;
|
|
166
|
-
}
|
|
167
|
-
if (params.color) {
|
|
168
|
-
properties.color = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
|
|
169
|
-
}
|
|
170
|
-
if (params.castShadows !== undefined) {
|
|
171
|
-
properties.castShadows = params.castShadows;
|
|
172
|
-
}
|
|
173
|
-
if (params.temperature !== undefined) {
|
|
174
|
-
properties.temperature = params.temperature;
|
|
175
|
-
}
|
|
176
|
-
if (params.useAsAtmosphereSunLight !== undefined) {
|
|
177
|
-
properties.useAsAtmosphereSunLight = params.useAsAtmosphereSunLight;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
try {
|
|
181
|
-
await this.spawnLightViaAutomation('DirectionalLight', {
|
|
182
|
-
name,
|
|
183
|
-
location: [0, 0, 500],
|
|
184
|
-
rotation: rot,
|
|
185
|
-
properties
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
return { success: true, message: `Directional light '${name}' spawned` };
|
|
189
|
-
} catch (e: unknown) {
|
|
190
|
-
// Don't mask errors as "not implemented" - report the actual error from the bridge
|
|
191
|
-
return { success: false, error: `Failed to create directional light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Create point light
|
|
196
|
-
async createPointLight(params: {
|
|
197
|
-
name: string;
|
|
198
|
-
location?: [number, number, number];
|
|
199
|
-
intensity?: number;
|
|
200
|
-
radius?: number;
|
|
201
|
-
color?: [number, number, number];
|
|
202
|
-
falloffExponent?: number;
|
|
203
|
-
castShadows?: boolean;
|
|
204
|
-
rotation?: [number, number, number] | { pitch: number, yaw: number, roll: number };
|
|
205
|
-
}) {
|
|
206
|
-
const name = this.normalizeName(params.name);
|
|
207
|
-
if (!this.automationBridge) {
|
|
208
|
-
throw new Error('Automation Bridge required for light spawning');
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Validate location array
|
|
212
|
-
// Validate location array
|
|
213
|
-
if (params.location !== undefined) {
|
|
214
|
-
// Ensure location is valid array [x,y,z]
|
|
215
|
-
try {
|
|
216
|
-
params.location = ensureVector3(params.location, 'location');
|
|
217
|
-
} catch (e) {
|
|
218
|
-
throw new Error(`Invalid location: ${e instanceof Error ? e.message : String(e)}`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Default location if not provided
|
|
223
|
-
const location = params.location || [0, 0, 0];
|
|
224
|
-
|
|
225
|
-
// Validate numeric parameters
|
|
226
|
-
if (params.intensity !== undefined) {
|
|
227
|
-
if (typeof params.intensity !== 'number' || !isFinite(params.intensity)) {
|
|
228
|
-
throw new Error(`Invalid intensity value: ${params.intensity}`);
|
|
229
|
-
}
|
|
230
|
-
if (params.intensity < 0) {
|
|
231
|
-
throw new Error('Invalid intensity: must be non-negative');
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
if (params.radius !== undefined) {
|
|
235
|
-
if (typeof params.radius !== 'number' || !isFinite(params.radius)) {
|
|
236
|
-
throw new Error(`Invalid radius value: ${params.radius}`);
|
|
237
|
-
}
|
|
238
|
-
if (params.radius < 0) {
|
|
239
|
-
throw new Error('Invalid radius: must be non-negative');
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
if (params.falloffExponent !== undefined) {
|
|
243
|
-
if (typeof params.falloffExponent !== 'number' || !isFinite(params.falloffExponent)) {
|
|
244
|
-
throw new Error(`Invalid falloffExponent value: ${params.falloffExponent}`);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Validate color array
|
|
249
|
-
if (params.color !== undefined) {
|
|
250
|
-
if (!Array.isArray(params.color) || params.color.length !== 3) {
|
|
251
|
-
throw new Error('Invalid color: must be an array [r,g,b]');
|
|
252
|
-
}
|
|
253
|
-
for (const c of params.color) {
|
|
254
|
-
if (typeof c !== 'number' || !isFinite(c)) {
|
|
255
|
-
throw new Error('Invalid color component: must be finite numbers');
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// Build properties for the light
|
|
261
|
-
const properties: Record<string, unknown> = {};
|
|
262
|
-
if (params.intensity !== undefined) {
|
|
263
|
-
properties.intensity = params.intensity;
|
|
264
|
-
}
|
|
265
|
-
if (params.radius !== undefined) {
|
|
266
|
-
properties.attenuationRadius = params.radius;
|
|
267
|
-
}
|
|
268
|
-
if (params.color) {
|
|
269
|
-
properties.color = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
|
|
270
|
-
}
|
|
271
|
-
if (params.castShadows !== undefined) {
|
|
272
|
-
properties.castShadows = params.castShadows;
|
|
273
|
-
}
|
|
274
|
-
if (params.falloffExponent !== undefined) {
|
|
275
|
-
properties.lightFalloffExponent = params.falloffExponent;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
try {
|
|
279
|
-
await this.spawnLightViaAutomation('PointLight', {
|
|
280
|
-
name,
|
|
281
|
-
location,
|
|
282
|
-
rotation: params.rotation,
|
|
283
|
-
properties
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
return { success: true, message: `Point light '${name}' spawned at ${location.join(', ')}` };
|
|
287
|
-
} catch (e: unknown) {
|
|
288
|
-
// Don't mask errors as "not implemented" - report the actual error from the bridge
|
|
289
|
-
return { success: false, error: `Failed to create point light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Create spot light
|
|
294
|
-
async createSpotLight(params: {
|
|
295
|
-
name: string;
|
|
296
|
-
location: [number, number, number];
|
|
297
|
-
rotation: [number, number, number] | { pitch: number, yaw: number, roll: number };
|
|
298
|
-
intensity?: number;
|
|
299
|
-
innerCone?: number;
|
|
300
|
-
outerCone?: number;
|
|
301
|
-
radius?: number;
|
|
302
|
-
color?: [number, number, number];
|
|
303
|
-
castShadows?: boolean;
|
|
304
|
-
}) {
|
|
305
|
-
const name = this.normalizeName(params.name);
|
|
306
|
-
if (!this.automationBridge) {
|
|
307
|
-
throw new Error('Automation Bridge required for light spawning');
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Validate required location and rotation arrays
|
|
311
|
-
if (!params.location || !Array.isArray(params.location) || params.location.length !== 3) {
|
|
312
|
-
throw new Error('Invalid location: must be an array [x,y,z]');
|
|
313
|
-
}
|
|
314
|
-
for (const l of params.location) {
|
|
315
|
-
if (typeof l !== 'number' || !isFinite(l)) {
|
|
316
|
-
throw new Error('Invalid location component: must be finite numbers');
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
if (!params.rotation) {
|
|
321
|
-
throw new Error('Rotation is required');
|
|
322
|
-
}
|
|
323
|
-
if (Array.isArray(params.rotation)) {
|
|
324
|
-
if (params.rotation.length !== 3) {
|
|
325
|
-
throw new Error('Invalid rotation: must be an array [pitch,yaw,roll]');
|
|
326
|
-
}
|
|
327
|
-
for (const r of params.rotation) {
|
|
328
|
-
if (typeof r !== 'number' || !isFinite(r)) {
|
|
329
|
-
throw new Error('Invalid rotation component: must be finite numbers');
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// Validate optional numeric parameters
|
|
335
|
-
if (params.intensity !== undefined) {
|
|
336
|
-
if (typeof params.intensity !== 'number' || !isFinite(params.intensity)) {
|
|
337
|
-
throw new Error(`Invalid intensity value: ${params.intensity}`);
|
|
338
|
-
}
|
|
339
|
-
if (params.intensity < 0) {
|
|
340
|
-
throw new Error('Invalid intensity: must be non-negative');
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
if (params.innerCone !== undefined) {
|
|
345
|
-
if (typeof params.innerCone !== 'number' || !isFinite(params.innerCone)) {
|
|
346
|
-
throw new Error(`Invalid innerCone value: ${params.innerCone}`);
|
|
347
|
-
}
|
|
348
|
-
if (params.innerCone < 0 || params.innerCone > 180) {
|
|
349
|
-
throw new Error('Invalid innerCone: must be between 0 and 180 degrees');
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (params.outerCone !== undefined) {
|
|
354
|
-
if (typeof params.outerCone !== 'number' || !isFinite(params.outerCone)) {
|
|
355
|
-
throw new Error(`Invalid outerCone value: ${params.outerCone}`);
|
|
356
|
-
}
|
|
357
|
-
if (params.outerCone < 0 || params.outerCone > 180) {
|
|
358
|
-
throw new Error('Invalid outerCone: must be between 0 and 180 degrees');
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
if (params.radius !== undefined) {
|
|
363
|
-
if (typeof params.radius !== 'number' || !isFinite(params.radius)) {
|
|
364
|
-
throw new Error(`Invalid radius value: ${params.radius}`);
|
|
365
|
-
}
|
|
366
|
-
if (params.radius < 0) {
|
|
367
|
-
throw new Error('Invalid radius: must be non-negative');
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// Validate color array
|
|
372
|
-
if (params.color !== undefined) {
|
|
373
|
-
if (!Array.isArray(params.color) || params.color.length !== 3) {
|
|
374
|
-
throw new Error('Invalid color: must be an array [r,g,b]');
|
|
375
|
-
}
|
|
376
|
-
for (const c of params.color) {
|
|
377
|
-
if (typeof c !== 'number' || !isFinite(c)) {
|
|
378
|
-
throw new Error('Invalid color component: must be finite numbers');
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
// Build properties for the light
|
|
383
|
-
const properties: Record<string, unknown> = {};
|
|
384
|
-
if (params.intensity !== undefined) {
|
|
385
|
-
properties.intensity = params.intensity;
|
|
386
|
-
}
|
|
387
|
-
if (params.innerCone !== undefined) {
|
|
388
|
-
properties.innerConeAngle = params.innerCone;
|
|
389
|
-
}
|
|
390
|
-
if (params.outerCone !== undefined) {
|
|
391
|
-
properties.outerConeAngle = params.outerCone;
|
|
392
|
-
}
|
|
393
|
-
if (params.radius !== undefined) {
|
|
394
|
-
properties.attenuationRadius = params.radius;
|
|
395
|
-
}
|
|
396
|
-
if (params.color) {
|
|
397
|
-
properties.color = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
|
|
398
|
-
}
|
|
399
|
-
if (params.castShadows !== undefined) {
|
|
400
|
-
properties.castShadows = params.castShadows;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
try {
|
|
404
|
-
await this.spawnLightViaAutomation('SpotLight', {
|
|
405
|
-
name,
|
|
406
|
-
location: params.location,
|
|
407
|
-
rotation: params.rotation,
|
|
408
|
-
properties
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
return { success: true, message: `Spot light '${name}' spawned at ${params.location.join(', ')}` };
|
|
412
|
-
} catch (e: unknown) {
|
|
413
|
-
// Don't mask errors as "not implemented" - report the actual error from the bridge
|
|
414
|
-
return { success: false, error: `Failed to create spot light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// Create rect light
|
|
419
|
-
async createRectLight(params: {
|
|
420
|
-
name: string;
|
|
421
|
-
location: [number, number, number];
|
|
422
|
-
rotation: [number, number, number] | { pitch: number, yaw: number, roll: number };
|
|
423
|
-
width?: number;
|
|
424
|
-
height?: number;
|
|
425
|
-
intensity?: number;
|
|
426
|
-
color?: [number, number, number];
|
|
427
|
-
castShadows?: boolean;
|
|
428
|
-
}) {
|
|
429
|
-
|
|
430
|
-
const name = this.normalizeName(params.name);
|
|
431
|
-
if (!this.automationBridge) {
|
|
432
|
-
throw new Error('Automation Bridge required for light spawning');
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// Validate required location and rotation arrays
|
|
436
|
-
if (!params.location || !Array.isArray(params.location) || params.location.length !== 3) {
|
|
437
|
-
throw new Error('Invalid location: must be an array [x,y,z]');
|
|
438
|
-
}
|
|
439
|
-
for (const l of params.location) {
|
|
440
|
-
if (typeof l !== 'number' || !isFinite(l)) {
|
|
441
|
-
throw new Error('Invalid location component: must be finite numbers');
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
if (!params.rotation) {
|
|
446
|
-
throw new Error('Rotation is required');
|
|
447
|
-
}
|
|
448
|
-
if (Array.isArray(params.rotation)) {
|
|
449
|
-
if (params.rotation.length !== 3) {
|
|
450
|
-
throw new Error('Invalid rotation: must be an array [pitch,yaw,roll]');
|
|
451
|
-
}
|
|
452
|
-
for (const r of params.rotation) {
|
|
453
|
-
if (typeof r !== 'number' || !isFinite(r)) {
|
|
454
|
-
throw new Error('Invalid rotation component: must be finite numbers');
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Validate optional numeric parameters
|
|
460
|
-
if (params.width !== undefined) {
|
|
461
|
-
if (typeof params.width !== 'number' || !isFinite(params.width)) {
|
|
462
|
-
throw new Error(`Invalid width value: ${params.width}`);
|
|
463
|
-
}
|
|
464
|
-
if (params.width <= 0) {
|
|
465
|
-
throw new Error('Invalid width: must be positive');
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
if (params.height !== undefined) {
|
|
470
|
-
if (typeof params.height !== 'number' || !isFinite(params.height)) {
|
|
471
|
-
throw new Error(`Invalid height value: ${params.height}`);
|
|
472
|
-
}
|
|
473
|
-
if (params.height <= 0) {
|
|
474
|
-
throw new Error('Invalid height: must be positive');
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
if (params.intensity !== undefined) {
|
|
479
|
-
if (typeof params.intensity !== 'number' || !isFinite(params.intensity)) {
|
|
480
|
-
throw new Error(`Invalid intensity value: ${params.intensity}`);
|
|
481
|
-
}
|
|
482
|
-
if (params.intensity < 0) {
|
|
483
|
-
throw new Error('Invalid intensity: must be non-negative');
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// Validate color array
|
|
488
|
-
if (params.color !== undefined) {
|
|
489
|
-
if (!Array.isArray(params.color) || params.color.length !== 3) {
|
|
490
|
-
throw new Error('Invalid color: must be an array [r,g,b]');
|
|
491
|
-
}
|
|
492
|
-
for (const c of params.color) {
|
|
493
|
-
if (typeof c !== 'number' || !isFinite(c)) {
|
|
494
|
-
throw new Error('Invalid color component: must be finite numbers');
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
// Build properties for the light
|
|
499
|
-
const properties: Record<string, unknown> = {};
|
|
500
|
-
if (params.intensity !== undefined) {
|
|
501
|
-
properties.intensity = params.intensity;
|
|
502
|
-
}
|
|
503
|
-
if (params.color) {
|
|
504
|
-
properties.color = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
|
|
505
|
-
}
|
|
506
|
-
if (params.width !== undefined) {
|
|
507
|
-
properties.sourceWidth = params.width;
|
|
508
|
-
}
|
|
509
|
-
if (params.height !== undefined) {
|
|
510
|
-
properties.sourceHeight = params.height;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
try {
|
|
514
|
-
await this.spawnLightViaAutomation('RectLight', {
|
|
515
|
-
name,
|
|
516
|
-
location: params.location,
|
|
517
|
-
rotation: params.rotation,
|
|
518
|
-
properties
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
return { success: true, message: `Rect light '${name}' spawned at ${params.location.join(', ')}` };
|
|
522
|
-
} catch (e: unknown) {
|
|
523
|
-
// Don't mask errors as "not implemented" - report the actual error from the bridge
|
|
524
|
-
return { success: false, error: `Failed to create rect light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* Create dynamic light
|
|
530
|
-
*/
|
|
531
|
-
async createDynamicLight(params: {
|
|
532
|
-
name?: string;
|
|
533
|
-
lightType?: 'Point' | 'Spot' | 'Directional' | 'Rect' | string;
|
|
534
|
-
location?: [number, number, number] | { x: number; y: number; z: number };
|
|
535
|
-
rotation?: [number, number, number];
|
|
536
|
-
intensity?: number;
|
|
537
|
-
color?: [number, number, number, number] | { r: number; g: number; b: number; a?: number };
|
|
538
|
-
pulse?: { enabled?: boolean; frequency?: number };
|
|
539
|
-
}) {
|
|
540
|
-
try {
|
|
541
|
-
const name = typeof params.name === 'string' && params.name.trim().length > 0 ? params.name.trim() : `DynamicLight_${Date.now() % 10000}`;
|
|
542
|
-
const lightTypeRaw = typeof params.lightType === 'string' && params.lightType.trim().length > 0 ? params.lightType.trim() : 'Point';
|
|
543
|
-
const location = Array.isArray(params.location) ? { x: params.location[0], y: params.location[1], z: params.location[2] } : (params.location || { x: 0, y: 0, z: 100 });
|
|
544
|
-
|
|
545
|
-
// C++ plugin does not strictly implement 'create_dynamic_light' action; it supports 'spawn_light'.
|
|
546
|
-
// However, we rely on the specific helper methods below which correctly map to 'spawn_light'
|
|
547
|
-
// with the appropriate class and properties.
|
|
548
|
-
|
|
549
|
-
const toArray3 = (loc: any): [number, number, number] => Array.isArray(loc)
|
|
550
|
-
? [Number(loc[0]) || 0, Number(loc[1]) || 0, Number(loc[2]) || 0]
|
|
551
|
-
: [Number(loc?.x) || 0, Number(loc?.y) || 0, Number(loc?.z) || 0];
|
|
552
|
-
const locArr = toArray3(location);
|
|
553
|
-
const typeNorm = (lightTypeRaw || 'Point').toLowerCase();
|
|
554
|
-
|
|
555
|
-
switch (typeNorm) {
|
|
556
|
-
case 'directional': case 'directionallight':
|
|
557
|
-
return await this.createDirectionalLight({ name, intensity: params.intensity, color: Array.isArray(params.color) ? [params.color[0], params.color[1], params.color[2]] as any : (params.color ? [params.color.r, params.color.g, params.color.b] : undefined), rotation: params.rotation as any });
|
|
558
|
-
case 'spot': case 'spotlight':
|
|
559
|
-
return await this.createSpotLight({ name, location: locArr, rotation: params.rotation as any, intensity: params.intensity, innerCone: undefined, outerCone: undefined, color: Array.isArray(params.color) ? params.color as any : (params.color ? [params.color.r, params.color.g, params.color.b] : undefined) });
|
|
560
|
-
case 'rect': case 'rectlight':
|
|
561
|
-
return await this.createRectLight({ name, location: locArr, rotation: params.rotation as any, width: undefined, height: undefined, intensity: params.intensity, color: Array.isArray(params.color) ? params.color as any : (params.color ? [params.color.r, params.color.g, params.color.b] : undefined) });
|
|
562
|
-
case 'point': default:
|
|
563
|
-
return await this.createPointLight({ name, location: locArr, intensity: params.intensity, radius: undefined, color: Array.isArray(params.color) ? params.color as any : (params.color ? [params.color.r, params.color.g, params.color.b] : undefined), castShadows: undefined });
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
} catch (err) {
|
|
567
|
-
return { success: false, error: `Failed to create dynamic light: ${err}` };
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// Create sky light
|
|
572
|
-
async createSkyLight(params: {
|
|
573
|
-
name: string;
|
|
574
|
-
sourceType?: 'CapturedScene' | 'SpecifiedCubemap';
|
|
575
|
-
cubemapPath?: string;
|
|
576
|
-
intensity?: number;
|
|
577
|
-
recapture?: boolean;
|
|
578
|
-
location?: [number, number, number];
|
|
579
|
-
rotation?: [number, number, number] | { pitch: number, yaw: number, roll: number };
|
|
580
|
-
realTimeCapture?: boolean;
|
|
581
|
-
castShadows?: boolean;
|
|
582
|
-
color?: [number, number, number];
|
|
583
|
-
}) {
|
|
584
|
-
const name = this.normalizeName(params.name);
|
|
585
|
-
if (params.sourceType === 'SpecifiedCubemap' && (!params.cubemapPath || params.cubemapPath.trim().length === 0)) {
|
|
586
|
-
const message = 'cubemapPath is required when sourceType is SpecifiedCubemap';
|
|
587
|
-
return { success: false, error: message, message };
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
if (!this.automationBridge) {
|
|
591
|
-
throw new Error('Automation Bridge required for sky light creation');
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
try {
|
|
595
|
-
const properties: Record<string, unknown> = {};
|
|
596
|
-
if (params.intensity !== undefined) properties.Intensity = params.intensity;
|
|
597
|
-
if (params.castShadows !== undefined) properties.CastShadows = params.castShadows;
|
|
598
|
-
if (params.realTimeCapture !== undefined) properties.RealTimeCapture = params.realTimeCapture;
|
|
599
|
-
if (params.color) properties.LightColor = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
|
|
600
|
-
|
|
601
|
-
const payload: Record<string, unknown> = {
|
|
602
|
-
name,
|
|
603
|
-
sourceType: params.sourceType || 'CapturedScene',
|
|
604
|
-
location: params.location,
|
|
605
|
-
rotation: params.rotation,
|
|
606
|
-
properties
|
|
607
|
-
};
|
|
608
|
-
|
|
609
|
-
if (params.cubemapPath) {
|
|
610
|
-
payload.cubemapPath = params.cubemapPath;
|
|
611
|
-
}
|
|
612
|
-
if (params.intensity !== undefined) {
|
|
613
|
-
payload.intensity = params.intensity;
|
|
614
|
-
}
|
|
615
|
-
if (params.recapture) {
|
|
616
|
-
payload.recapture = params.recapture;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
const response = await this.automationBridge.sendAutomationRequest('spawn_sky_light', payload, {
|
|
620
|
-
timeoutMs: 60000
|
|
621
|
-
});
|
|
622
|
-
|
|
623
|
-
if (response.success === false) {
|
|
624
|
-
return {
|
|
625
|
-
success: false,
|
|
626
|
-
error: response.error || response.message || 'Failed to create sky light'
|
|
627
|
-
};
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
return {
|
|
631
|
-
success: true,
|
|
632
|
-
message: response.message || 'Sky light created',
|
|
633
|
-
...(response.result || {})
|
|
634
|
-
};
|
|
635
|
-
} catch (error) {
|
|
636
|
-
return {
|
|
637
|
-
success: false,
|
|
638
|
-
error: `Failed to create sky light: ${error instanceof Error ? error.message : String(error)}`
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
// Remove duplicate SkyLights and keep only one (named target label)
|
|
644
|
-
async ensureSingleSkyLight(params?: { name?: string; recapture?: boolean }) {
|
|
645
|
-
const defaultName = 'MCP_Test_Sky';
|
|
646
|
-
const name = this.normalizeName(params?.name, defaultName);
|
|
647
|
-
const recapture = !!params?.recapture;
|
|
648
|
-
|
|
649
|
-
if (!this.automationBridge) {
|
|
650
|
-
throw new Error('Automation Bridge required for sky light management');
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
try {
|
|
654
|
-
const response = await this.automationBridge.sendAutomationRequest('ensure_single_sky_light', {
|
|
655
|
-
name,
|
|
656
|
-
recapture
|
|
657
|
-
}, {
|
|
658
|
-
timeoutMs: 60000
|
|
659
|
-
});
|
|
660
|
-
|
|
661
|
-
if (response.success === false) {
|
|
662
|
-
return {
|
|
663
|
-
success: false,
|
|
664
|
-
error: response.error || response.message || 'Failed to ensure single sky light'
|
|
665
|
-
};
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
return {
|
|
669
|
-
success: true,
|
|
670
|
-
message: response.message || `Ensured single SkyLight (removed ${(response.result as any)?.removed || 0})`,
|
|
671
|
-
...(response.result || {})
|
|
672
|
-
};
|
|
673
|
-
} catch (error) {
|
|
674
|
-
return {
|
|
675
|
-
success: false,
|
|
676
|
-
error: `Failed to ensure single sky light: ${error instanceof Error ? error.message : String(error)}`
|
|
677
|
-
};
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
// Setup global illumination
|
|
682
|
-
async setupGlobalIllumination(params: {
|
|
683
|
-
method: 'Lightmass' | 'LumenGI' | 'ScreenSpace' | 'None';
|
|
684
|
-
quality?: 'Low' | 'Medium' | 'High' | 'Epic';
|
|
685
|
-
indirectLightingIntensity?: number;
|
|
686
|
-
bounces?: number;
|
|
687
|
-
}) {
|
|
688
|
-
if (this.automationBridge) {
|
|
689
|
-
try {
|
|
690
|
-
const response = await this.automationBridge.sendAutomationRequest('setup_global_illumination', {
|
|
691
|
-
method: params.method,
|
|
692
|
-
quality: params.quality,
|
|
693
|
-
indirectLightingIntensity: params.indirectLightingIntensity,
|
|
694
|
-
bounces: params.bounces
|
|
695
|
-
});
|
|
696
|
-
if (response.success) return { success: true, message: 'Global illumination configured via bridge', ...(response.result || {}) };
|
|
697
|
-
} catch (_e) {
|
|
698
|
-
// Fallback to console commands
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
const commands = [];
|
|
703
|
-
|
|
704
|
-
switch (params.method) {
|
|
705
|
-
case 'Lightmass':
|
|
706
|
-
commands.push('r.DynamicGlobalIlluminationMethod 0');
|
|
707
|
-
break;
|
|
708
|
-
case 'LumenGI':
|
|
709
|
-
commands.push('r.DynamicGlobalIlluminationMethod 1');
|
|
710
|
-
break;
|
|
711
|
-
case 'ScreenSpace':
|
|
712
|
-
commands.push('r.DynamicGlobalIlluminationMethod 2');
|
|
713
|
-
break;
|
|
714
|
-
case 'None':
|
|
715
|
-
commands.push('r.DynamicGlobalIlluminationMethod 3');
|
|
716
|
-
break;
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
if (params.quality) {
|
|
720
|
-
const qualityMap = { 'Low': 0, 'Medium': 1, 'High': 2, 'Epic': 3 };
|
|
721
|
-
commands.push(`r.Lumen.Quality ${qualityMap[params.quality]}`);
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
if (params.indirectLightingIntensity !== undefined) {
|
|
725
|
-
commands.push(`r.IndirectLightingIntensity ${params.indirectLightingIntensity}`);
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
if (params.bounces !== undefined) {
|
|
729
|
-
commands.push(`r.Lumen.MaxReflectionBounces ${params.bounces}`);
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
for (const cmd of commands) {
|
|
733
|
-
await this.bridge.executeConsoleCommand(cmd);
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
return { success: true, message: 'Global illumination configured (console)' };
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
// Configure shadows
|
|
740
|
-
async configureShadows(params: {
|
|
741
|
-
shadowQuality?: 'Low' | 'Medium' | 'High' | 'Epic';
|
|
742
|
-
cascadedShadows?: boolean;
|
|
743
|
-
shadowDistance?: number;
|
|
744
|
-
contactShadows?: boolean;
|
|
745
|
-
rayTracedShadows?: boolean;
|
|
746
|
-
}) {
|
|
747
|
-
if (this.automationBridge) {
|
|
748
|
-
try {
|
|
749
|
-
const response = await this.automationBridge.sendAutomationRequest('configure_shadows', {
|
|
750
|
-
shadowQuality: params.shadowQuality,
|
|
751
|
-
cascadedShadows: params.cascadedShadows,
|
|
752
|
-
shadowDistance: params.shadowDistance,
|
|
753
|
-
contactShadows: params.contactShadows,
|
|
754
|
-
rayTracedShadows: params.rayTracedShadows,
|
|
755
|
-
virtualShadowMaps: params.rayTracedShadows // Map to VSM for C++ handler
|
|
756
|
-
});
|
|
757
|
-
if (response.success) return { success: true, message: 'Shadow settings configured via bridge', ...(response.result || {}) };
|
|
758
|
-
} catch (_e) {
|
|
759
|
-
// Fallback
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
const commands = [];
|
|
764
|
-
|
|
765
|
-
if (params.shadowQuality) {
|
|
766
|
-
const qualityMap = { 'Low': 0, 'Medium': 1, 'High': 2, 'Epic': 3 };
|
|
767
|
-
commands.push(`r.ShadowQuality ${qualityMap[params.shadowQuality]}`);
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
if (params.cascadedShadows !== undefined) {
|
|
771
|
-
commands.push(`r.Shadow.CSM.MaxCascades ${params.cascadedShadows ? 4 : 1}`);
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
if (params.shadowDistance !== undefined) {
|
|
775
|
-
commands.push(`r.Shadow.DistanceScale ${params.shadowDistance}`);
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
if (params.contactShadows !== undefined) {
|
|
779
|
-
commands.push(`r.ContactShadows ${params.contactShadows ? 1 : 0}`);
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
if (params.rayTracedShadows !== undefined) {
|
|
783
|
-
commands.push(`r.RayTracing.Shadows ${params.rayTracedShadows ? 1 : 0}`);
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
for (const cmd of commands) {
|
|
787
|
-
await this.bridge.executeConsoleCommand(cmd);
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
return { success: true, message: 'Shadow settings configured (console)' };
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
// Build lighting
|
|
794
|
-
async buildLighting(params: {
|
|
795
|
-
quality?: 'Preview' | 'Medium' | 'High' | 'Production';
|
|
796
|
-
buildOnlySelected?: boolean;
|
|
797
|
-
buildReflectionCaptures?: boolean;
|
|
798
|
-
levelPath?: string;
|
|
799
|
-
}) {
|
|
800
|
-
if (!this.automationBridge) {
|
|
801
|
-
throw new Error('Automation Bridge required for lighting build');
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
try {
|
|
805
|
-
const response = await this.automationBridge.sendAutomationRequest('bake_lightmap', {
|
|
806
|
-
quality: params.quality || 'High',
|
|
807
|
-
buildOnlySelected: params.buildOnlySelected || false,
|
|
808
|
-
buildReflectionCaptures: params.buildReflectionCaptures !== false,
|
|
809
|
-
levelPath: params.levelPath
|
|
810
|
-
}, {
|
|
811
|
-
timeoutMs: 300000 // 5 minutes for lighting builds
|
|
812
|
-
});
|
|
813
|
-
|
|
814
|
-
if (response.success === false) {
|
|
815
|
-
return {
|
|
816
|
-
success: false,
|
|
817
|
-
error: response.error || response.message || 'Failed to build lighting'
|
|
818
|
-
};
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
return {
|
|
822
|
-
success: true,
|
|
823
|
-
message: response.message || 'Lighting build started',
|
|
824
|
-
...(response.result || {})
|
|
825
|
-
};
|
|
826
|
-
} catch (error) {
|
|
827
|
-
return {
|
|
828
|
-
success: false,
|
|
829
|
-
error: `Failed to build lighting: ${error instanceof Error ? error.message : String(error)}`
|
|
830
|
-
};
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
// Create a new level with proper lighting settings
|
|
835
|
-
async createLightingEnabledLevel(params?: {
|
|
836
|
-
levelName?: string;
|
|
837
|
-
copyActors?: boolean;
|
|
838
|
-
useTemplate?: boolean;
|
|
839
|
-
}) {
|
|
840
|
-
const levelName = params?.levelName || 'LightingEnabledLevel';
|
|
841
|
-
|
|
842
|
-
if (!this.automationBridge) {
|
|
843
|
-
throw new Error('Automation Bridge not available. Level creation requires plugin support.');
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
try {
|
|
847
|
-
const response = await this.automationBridge.sendAutomationRequest('create_lighting_enabled_level', {
|
|
848
|
-
levelName,
|
|
849
|
-
copyActors: params?.copyActors === true,
|
|
850
|
-
useTemplate: params?.useTemplate === true,
|
|
851
|
-
path: params?.levelName ? `/Game/Maps/${params.levelName}` : undefined // Ensure path is sent
|
|
852
|
-
}, {
|
|
853
|
-
timeoutMs: 120000 // 2 minutes for level creation
|
|
854
|
-
});
|
|
855
|
-
|
|
856
|
-
if (response.success === false) {
|
|
857
|
-
return {
|
|
858
|
-
success: false,
|
|
859
|
-
error: response.error || response.message || 'Failed to create level'
|
|
860
|
-
};
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
return {
|
|
864
|
-
success: true,
|
|
865
|
-
message: response.message || `Created new level "${levelName}" with lighting enabled`,
|
|
866
|
-
...(response.result || {})
|
|
867
|
-
};
|
|
868
|
-
} catch (error) {
|
|
869
|
-
return {
|
|
870
|
-
success: false,
|
|
871
|
-
error: `Failed to create lighting-enabled level: ${error}`
|
|
872
|
-
};
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
// Create lightmass importance volume
|
|
877
|
-
async createLightmassVolume(params: {
|
|
878
|
-
name: string;
|
|
879
|
-
location: [number, number, number];
|
|
880
|
-
size: [number, number, number];
|
|
881
|
-
}) {
|
|
882
|
-
const name = this.normalizeName(params.name);
|
|
883
|
-
|
|
884
|
-
if (!this.automationBridge) {
|
|
885
|
-
throw new Error('Automation Bridge not available. Lightmass volume creation requires plugin support.');
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
try {
|
|
889
|
-
const response = await this.automationBridge.sendAutomationRequest('create_lightmass_volume', {
|
|
890
|
-
name,
|
|
891
|
-
location: { x: params.location[0], y: params.location[1], z: params.location[2] },
|
|
892
|
-
size: { x: params.size[0], y: params.size[1], z: params.size[2] }
|
|
893
|
-
}, {
|
|
894
|
-
timeoutMs: 60000
|
|
895
|
-
});
|
|
896
|
-
|
|
897
|
-
if (response.success === false) {
|
|
898
|
-
return {
|
|
899
|
-
success: false,
|
|
900
|
-
error: response.error || response.message || 'Failed to create lightmass volume'
|
|
901
|
-
};
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
return {
|
|
905
|
-
success: true,
|
|
906
|
-
message: `LightmassImportanceVolume '${name}' created`,
|
|
907
|
-
...(response.result || {})
|
|
908
|
-
};
|
|
909
|
-
} catch (error) {
|
|
910
|
-
return {
|
|
911
|
-
success: false,
|
|
912
|
-
error: `Failed to create lightmass volume: ${error}`
|
|
913
|
-
};
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
// Set exposure
|
|
918
|
-
async setExposure(params: {
|
|
919
|
-
method: 'Manual' | 'Auto';
|
|
920
|
-
compensationValue?: number;
|
|
921
|
-
minBrightness?: number;
|
|
922
|
-
maxBrightness?: number;
|
|
923
|
-
}) {
|
|
924
|
-
if (this.automationBridge) {
|
|
925
|
-
try {
|
|
926
|
-
const response = await this.automationBridge.sendAutomationRequest('set_exposure', {
|
|
927
|
-
method: params.method,
|
|
928
|
-
compensationValue: params.compensationValue,
|
|
929
|
-
minBrightness: params.minBrightness,
|
|
930
|
-
maxBrightness: params.maxBrightness
|
|
931
|
-
});
|
|
932
|
-
if (response.success) return { success: true, message: 'Exposure settings updated via bridge', ...(response.result || {}) };
|
|
933
|
-
} catch (_e) {
|
|
934
|
-
// Fallback
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
const commands = [];
|
|
939
|
-
|
|
940
|
-
commands.push(`r.EyeAdaptation.ExposureMethod ${params.method === 'Manual' ? 0 : 1}`);
|
|
941
|
-
|
|
942
|
-
if (params.compensationValue !== undefined) {
|
|
943
|
-
commands.push(`r.EyeAdaptation.ExposureCompensation ${params.compensationValue}`);
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
if (params.minBrightness !== undefined) {
|
|
947
|
-
commands.push(`r.EyeAdaptation.MinBrightness ${params.minBrightness}`);
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
if (params.maxBrightness !== undefined) {
|
|
951
|
-
commands.push(`r.EyeAdaptation.MaxBrightness ${params.maxBrightness}`);
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
for (const cmd of commands) {
|
|
955
|
-
await this.bridge.executeConsoleCommand(cmd);
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
return { success: true, message: 'Exposure settings updated (console)' };
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
// Set ambient occlusion
|
|
962
|
-
async setAmbientOcclusion(params: {
|
|
963
|
-
enabled: boolean;
|
|
964
|
-
intensity?: number;
|
|
965
|
-
radius?: number;
|
|
966
|
-
quality?: 'Low' | 'Medium' | 'High';
|
|
967
|
-
}) {
|
|
968
|
-
if (this.automationBridge) {
|
|
969
|
-
try {
|
|
970
|
-
const response = await this.automationBridge.sendAutomationRequest('set_ambient_occlusion', {
|
|
971
|
-
enabled: params.enabled,
|
|
972
|
-
intensity: params.intensity,
|
|
973
|
-
radius: params.radius,
|
|
974
|
-
quality: params.quality
|
|
975
|
-
});
|
|
976
|
-
if (response.success) return { success: true, message: 'Ambient occlusion configured via bridge', ...(response.result || {}) };
|
|
977
|
-
} catch (_e) {
|
|
978
|
-
// Fallback
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
const commands = [];
|
|
983
|
-
|
|
984
|
-
commands.push(`r.AmbientOcclusion.Enabled ${params.enabled ? 1 : 0}`);
|
|
985
|
-
|
|
986
|
-
if (params.intensity !== undefined) {
|
|
987
|
-
commands.push(`r.AmbientOcclusion.Intensity ${params.intensity}`);
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
if (params.radius !== undefined) {
|
|
991
|
-
commands.push(`r.AmbientOcclusion.Radius ${params.radius}`);
|
|
992
|
-
}
|
|
993
|
-
|
|
994
|
-
if (params.quality) {
|
|
995
|
-
const qualityMap = { 'Low': 0, 'Medium': 1, 'High': 2 };
|
|
996
|
-
commands.push(`r.AmbientOcclusion.Quality ${qualityMap[params.quality]}`);
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
for (const cmd of commands) {
|
|
1000
|
-
await this.bridge.executeConsoleCommand(cmd);
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
return { success: true, message: 'Ambient occlusion configured (console)' };
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
// Setup volumetric fog
|
|
1007
|
-
async setupVolumetricFog(params: {
|
|
1008
|
-
enabled: boolean;
|
|
1009
|
-
density?: number;
|
|
1010
|
-
scatteringIntensity?: number;
|
|
1011
|
-
fogHeight?: number; // interpreted as Z location shift for ExponentialHeightFog actor
|
|
1012
|
-
}) {
|
|
1013
|
-
// Enable/disable global volumetric fog via CVar
|
|
1014
|
-
await this.bridge.executeConsoleCommand(`r.VolumetricFog ${params.enabled ? 1 : 0}`);
|
|
1015
|
-
|
|
1016
|
-
if (!this.automationBridge) {
|
|
1017
|
-
return {
|
|
1018
|
-
success: true,
|
|
1019
|
-
message: 'Volumetric fog console setting applied (plugin required for fog actor adjustment)'
|
|
1020
|
-
};
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
try {
|
|
1024
|
-
const response = await this.automationBridge.sendAutomationRequest('setup_volumetric_fog', {
|
|
1025
|
-
enabled: params.enabled,
|
|
1026
|
-
density: params.density,
|
|
1027
|
-
scatteringIntensity: params.scatteringIntensity,
|
|
1028
|
-
fogHeight: params.fogHeight
|
|
1029
|
-
}, {
|
|
1030
|
-
timeoutMs: 60000
|
|
1031
|
-
});
|
|
1032
|
-
|
|
1033
|
-
if (response.success === false) {
|
|
1034
|
-
return {
|
|
1035
|
-
success: false,
|
|
1036
|
-
error: response.error || response.message || 'Failed to configure volumetric fog'
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
return {
|
|
1041
|
-
success: true,
|
|
1042
|
-
message: 'Volumetric fog configured',
|
|
1043
|
-
...(response.result || {})
|
|
1044
|
-
};
|
|
1045
|
-
} catch (error) {
|
|
1046
|
-
return {
|
|
1047
|
-
success: false,
|
|
1048
|
-
error: `Failed to setup volumetric fog: ${error}`
|
|
1049
|
-
};
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
}
|