@volter/cyclotron 0.0.0-stage → 0.5.191
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/BUNDLED_NOTICES +6877 -0
- package/LICENSE +670 -0
- package/LICENSE-BLENDER +1409 -0
- package/LICENSE-MCP +21 -0
- package/NOTICE +20 -0
- package/README.md +91 -2
- package/dist/.vite/manifest.json +5432 -0
- package/dist/assets/BVHLoader-Dxn1IBPh.js +1 -0
- package/dist/assets/ColladaLoader-FWjhft-R.js +3 -0
- package/dist/assets/EntityModelDocument-H5MGTLgY.js +1 -0
- package/dist/assets/EnvironmentAssetDocument-DscnToFv.js +1 -0
- package/dist/assets/FBXLoader-B6D0-2sM.js +1 -0
- package/dist/assets/InspectorObjectPreview-DmgzscPS.js +1 -0
- package/dist/assets/LineSegments2-D1_2s-N-.js +370 -0
- package/dist/assets/LiveModuleDocument-DAYkZerk.js +2 -0
- package/dist/assets/LutAssetDocument-B7CFf1iQ.js +1 -0
- package/dist/assets/MTLLoader-BwtVpZY2.js +2 -0
- package/dist/assets/ModelAssetDocument-C3AYQW5D.js +1 -0
- package/dist/assets/NonThreeAuthoringBootstrap-BnkHNgwT.js +1 -0
- package/dist/assets/OBJLoader-Cwe-BN99.js +5 -0
- package/dist/assets/Object3DDocumentToolbar-6iKyx5P7.js +1 -0
- package/dist/assets/Object3DPreview-CVsX3Ez6.js +2 -0
- package/dist/assets/OrbitControls-Cn2q_IQK.js +1 -0
- package/dist/assets/PLYLoader-DOl6qb2a.js +2 -0
- package/dist/assets/QuarksAssetDocument-BrUx0sFF.js +2 -0
- package/dist/assets/RectAreaLightUniformsLib-CobhIWNK.js +1 -0
- package/dist/assets/STLLoader-B5YpfCGT.js +1 -0
- package/dist/assets/ShaderAssetDocument-8fZCtoKv.js +1 -0
- package/dist/assets/StageHost-CM6pXufo.js +1179 -0
- package/dist/assets/TDSLoader-BdQ2M2WU.js +1 -0
- package/dist/assets/ToolObject3DPreview-BY-w2JDK.js +1 -0
- package/dist/assets/ViewportShadingMenu-BcSW0SdM.js +1 -0
- package/dist/assets/animation-mixers.service-Dh2f8bk9.js +1 -0
- package/dist/assets/animation-timeline.utility-DTZfezuF.js +1 -0
- package/dist/assets/anthropic-DwpKRVGM.svg +1 -0
- package/dist/assets/asset-preview-BCSH6zvx.js +4 -0
- package/dist/assets/blender-display-shaders-BpnqnkG8.lut +0 -0
- package/dist/assets/blender-emscripten-engine-DEk9HdR1.js +2 -0
- package/dist/assets/blender-motion-worker-CtT2cV3V.js +1 -0
- package/dist/assets/blender-node-editor.document-sTxATkra.js +1 -0
- package/dist/assets/blender-properties-model-DG3h6RbJ.js +1 -0
- package/dist/assets/blender-properties-tab-kS_hNbKV.js +3 -0
- package/dist/assets/blender-runtime-host-CJ3l04y8.js +17 -0
- package/dist/assets/blender-runtime.document-CIJypNav.js +13 -0
- package/dist/assets/blender-screenshot.menu-B0WniIkP.js +1 -0
- package/dist/assets/blender-timeline.document-CCIcBTnZ.js +1 -0
- package/dist/assets/blender-uv-editor.document-CENezQQk.js +1 -0
- package/dist/assets/blender-version.status-aS3tabn9.js +1 -0
- package/dist/assets/blender-wali-engine-D2ymLooc.js +2 -0
- package/dist/assets/blender.command-Cl2XnwrS.js +1 -0
- package/dist/assets/blender.environment-CG-pC7sk.js +1 -0
- package/dist/assets/blender.keymap-BmOBRY7p.js +1 -0
- package/dist/assets/blender.status-BgdpgL9J.js +1 -0
- package/dist/assets/blender.style-DaIh9SiA.js +1 -0
- package/dist/assets/city-EkhAOo5s.exr +0 -0
- package/dist/assets/clip-planes-CmZu3QTO.js +8 -0
- package/dist/assets/content-bounds-Dg9hT5Gp.js +85 -0
- package/dist/assets/courtyard-DqlebbpC.exr +0 -0
- package/dist/assets/forest-P_CQY3b_.exr +0 -0
- package/dist/assets/icon-BkiLD9ed.png +0 -0
- package/dist/assets/index-7vd2obXq.js +3 -0
- package/dist/assets/index-BP6wv2A0.js +5 -0
- package/dist/assets/index-BRLA7zdc.js +7 -0
- package/dist/assets/index-BxW3iIJI.js +952 -0
- package/dist/assets/index-CnvSS9lU.js +2 -0
- package/dist/assets/index-DYNMP0kE.js +1 -0
- package/dist/assets/index-Dz8qGBZc.js +13 -0
- package/dist/assets/index-Fv4R0cYr.js +1 -0
- package/dist/assets/index-f-MQ14bP.js +1 -0
- package/dist/assets/index-ux8XhRyW.js +1 -0
- package/dist/assets/interior-Bo_lba15.exr +0 -0
- package/dist/assets/live-mixers-B-bwLZ7c.js +1 -0
- package/dist/assets/model-inspection-D_Z7lPhp.js +1 -0
- package/dist/assets/model.layout-BpZE1W9V.js +1 -0
- package/dist/assets/models.finder-n0qYfNhP.js +1 -0
- package/dist/assets/night-CvV4Gybt.exr +0 -0
- package/dist/assets/object3d-document-session-registry-Dso-3DdQ.js +2 -0
- package/dist/assets/openai-DHNKzFtc.svg +1 -0
- package/dist/assets/play-mode-CB-BAREv.js +7208 -0
- package/dist/assets/png-encode.worker-E8zk28Vl.js +1 -0
- package/dist/assets/product-2FMfCeKv.js +14 -0
- package/dist/assets/product-BxXXdFxI.css +1 -0
- package/dist/assets/properties-bone-constraints.inspector-DPD94zpc.js +1 -0
- package/dist/assets/properties-bone.inspector-CDYgJFMb.js +1 -0
- package/dist/assets/properties-collection.inspector-Bc7-DzEi.js +1 -0
- package/dist/assets/properties-constraints.inspector-CnyXcr_p.js +1 -0
- package/dist/assets/properties-data.inspector-Y9trp74x.js +1 -0
- package/dist/assets/properties-material.inspector-DKW8fWHF.js +1 -0
- package/dist/assets/properties-modifiers.inspector-CCxaKRAi.js +1 -0
- package/dist/assets/properties-object.inspector-DHCzFViD.js +1 -0
- package/dist/assets/properties-output.inspector-Jcvyw8r-.js +1 -0
- package/dist/assets/properties-particles.inspector-DHrpt9YM.js +1 -0
- package/dist/assets/properties-physics.inspector-BdCSY9ed.js +1 -0
- package/dist/assets/properties-render.inspector-DPNhVHyH.js +1 -0
- package/dist/assets/properties-scene.inspector-BEyWMESu.js +1 -0
- package/dist/assets/properties-texture.inspector-BDAHphbo.js +1 -0
- package/dist/assets/properties-view-layer.inspector-Dd1R2c8y.js +1 -0
- package/dist/assets/properties-world.inspector-GA10_Q2q.js +1 -0
- package/dist/assets/react-18-DLRa6EBJ.js +1 -0
- package/dist/assets/regions-DWeEBnE2.js +1 -0
- package/dist/assets/sculpt.layout-D-K5cLw6.js +1 -0
- package/dist/assets/session-C0OdhDD8.js +5393 -0
- package/dist/assets/shading.layout-CZZHKBer.js +1 -0
- package/dist/assets/sky-precompute-worker-CPGW9t_C.js +1 -0
- package/dist/assets/spark.module-GpLuSFtI.js +12120 -0
- package/dist/assets/stage-keyboard-DQMRbQSk.js +1 -0
- package/dist/assets/stage-overlay-set-BjkX6NS2.js +1 -0
- package/dist/assets/stage-presence-markers-BLzWksKB.js +1 -0
- package/dist/assets/stage-transform-tools-CmCouHjc.js +1 -0
- package/dist/assets/standard-viewport-dressing-tRKYG-Oe.js +24 -0
- package/dist/assets/studio-CysTBGIb.exr +0 -0
- package/dist/assets/sunrise-Dj0psFrf.exr +0 -0
- package/dist/assets/sunset-Bw3x2Bot.exr +0 -0
- package/dist/assets/texture.layout-DASpHVht.js +1 -0
- package/dist/assets/three-integration.service-CZBtvpOJ.js +2 -0
- package/dist/assets/three.module-dk_BdrjN.js +3840 -0
- package/dist/assets/uv-editing.layout-A8RA-cbM.js +1 -0
- package/dist/assets/volter-sdk-CTPCkGXt.js +2358 -0
- package/dist/assets/volter-sdk-account-C7TbJeFz.js +1 -0
- package/dist/assets/volter-sdk-client-DTdXvoMD.js +1 -0
- package/dist/assets/volter-sdk-contributions-eo4CPh2p.js +1 -0
- package/dist/assets/volter-sdk-css-numeric-style-Ttf_8Kmw.js +1 -0
- package/dist/assets/volter-sdk-document-probe-uMZJqaXu.js +1 -0
- package/dist/assets/volter-sdk-editor-view-CRZQicqm.js +1 -0
- package/dist/assets/volter-sdk-host-B-zxfcPu.js +1 -0
- package/dist/assets/volter-sdk-http-transport.browser-DPW20rVu.js +1 -0
- package/dist/assets/volter-sdk-index-Cb7Yywg-.js +1 -0
- package/dist/assets/volter-sdk-kit-CapabilityCoverageSection-D0IDzMdi.js +1 -0
- package/dist/assets/volter-sdk-kit-account-client-BcyEmaPH.js +1 -0
- package/dist/assets/volter-sdk-kit-action-registry-DriAF6Sc.js +1 -0
- package/dist/assets/volter-sdk-kit-active-product-r7jCIax2.js +1 -0
- package/dist/assets/volter-sdk-kit-active-project-Cjf4pJ6J.js +1 -0
- package/dist/assets/volter-sdk-kit-adapter-editor-config-BaNyB8ig.js +1 -0
- package/dist/assets/volter-sdk-kit-adapter-observation-V71hItcC.js +1 -0
- package/dist/assets/volter-sdk-kit-animation-animation-clock-DmeLqo0W.js +1 -0
- package/dist/assets/volter-sdk-kit-animation-stage-transport-BaD_Lz7M.js +1 -0
- package/dist/assets/volter-sdk-kit-api-assets-D9KgHTyt.js +1 -0
- package/dist/assets/volter-sdk-kit-api-base-DH9EkQUe.js +1 -0
- package/dist/assets/volter-sdk-kit-api-build-DHp-caUc.js +1 -0
- package/dist/assets/volter-sdk-kit-api-logs-DLGBnX6D.js +1 -0
- package/dist/assets/volter-sdk-kit-api-project-identity-Ce2bcNI8.js +1 -0
- package/dist/assets/volter-sdk-kit-api-project-open-BUoW4R4G.js +1 -0
- package/dist/assets/volter-sdk-kit-api-project-source-D_ZKYf7K.js +1 -0
- package/dist/assets/volter-sdk-kit-api-project-state-fp96KH-b.js +1 -0
- package/dist/assets/volter-sdk-kit-api-relay-Da3eSdYq.js +1 -0
- package/dist/assets/volter-sdk-kit-api-settings-7nqXhmRG.js +1 -0
- package/dist/assets/volter-sdk-kit-api-themes-CcJT4tNc.js +1 -0
- package/dist/assets/volter-sdk-kit-api-worktrees-BPery5as.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-capabilities-B0ay5F3v.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-compare-core-BRjsa1JH.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-editor-context-QSJFkrTF.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-events-DhC-oWIc.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-inspector-actions-DOGzxnKO.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-selection-D3iKMZhc.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-selection-viewer-registry-iSjetPTF.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-thumbnails-B-rnrR4e.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-viewers-DW_B6mUz.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-import-jobs-zpDDAGhi.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-ledger-BLvGK5K9.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-ledger-backend-R_sMRJxQ.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-materialization-report-Cu8PzcuH.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-pack-manifest-CykYNw93.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-audio-preview-player-DisMJvNX.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-audio-waveform-DaE4b6q5.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-cloud-asset-client-BA2DspQh.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-hosted-asset-materialization-CAs2DnB-.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-image-view-scale-CKGz1teu.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-ledger-write-lock-CUSx23CF.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-pixi-spritesheet-20DVa19-.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-preview-resource-lifetime-9aCVJ5ZD.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-project-asset-commands-D9rsm7id.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-project-content-MiELo_O1.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-thumbnail-system-C2_qZtHy.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-active-adapter-CF9u3FRf.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-active-systems-BHJmeKT1.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-adapter-key-Crk3ASvv.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-authoring-asset-url-DG5Fxmhm.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-bootstrap-state-B0nbQdGo.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-boundary-authoring-adapter-CeQy5qiB.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-canvas-scene-guides-1JIcdD37.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-composite-authoring-adapter-B92Z3v81.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-consumer-actions-VKZPMDF4.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-design-time-layers-CjdjzFCK.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-design-time-mount-registry-Dj9yuM04.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-edit-mode-authoring-7WjAL2FS.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-empty-project-authoring-Cl7rnMX7.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-instance-source-menu-D3W4NqNC.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-layered-pick-BdohFxNz.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-mounted-root-subjects-Djn9pHUW.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-no-authoring-adapter-B7eiKgrk.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-object3d-document-persistence-DLcEQvHq.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-panel-authoring-gK-CPiH6.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-project-authoring-session-uHS0CYvK.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-provenance-D-BET8RO.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-react-canvas-navigation-B60IffcY.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-react-design-canvas-style-ks9HoOST.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-react-story-board-C_LkOQ31.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-seam-evidence-Cs2OD8Mp.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-selection-scope-BBRJ_LYX.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-shell-document-ops-BgFY_dTi.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-story-board-chrome-fit-DBmpy3fX.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-three-root-DcfxyBfe.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-viewport-tool-context-iBDEmcv0.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-viewport-tool-owner-B_6F6Tjj.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-world-session-state-D5dzuuRn.js +1 -0
- package/dist/assets/volter-sdk-kit-availability-tick-CY8If63r.js +1 -0
- package/dist/assets/volter-sdk-kit-bitmap-label-Beh0HDVB.js +1 -0
- package/dist/assets/volter-sdk-kit-boot-routing-BJca1uda.js +1 -0
- package/dist/assets/volter-sdk-kit-breakpoint-state-CNWGaLfG.js +1 -0
- package/dist/assets/volter-sdk-kit-build-identity-BBdzUzJV.js +1 -0
- package/dist/assets/volter-sdk-kit-bytes-codec-DLFzHQUN.js +1 -0
- package/dist/assets/volter-sdk-kit-cancellation-reason-BH7-0ZVf.js +1 -0
- package/dist/assets/volter-sdk-kit-canvas-frames-BieYMTcU.js +1 -0
- package/dist/assets/volter-sdk-kit-capture-camera-pose-CHUoNB6d.js +1 -0
- package/dist/assets/volter-sdk-kit-capture-size-CAnl2oe2.js +1 -0
- package/dist/assets/volter-sdk-kit-chrome-registry-MC5H7QaT.js +1 -0
- package/dist/assets/volter-sdk-kit-chrome-slot-registry-0ZLiAfjQ.js +1 -0
- package/dist/assets/volter-sdk-kit-collaboration-client-BuG6oS42.js +1 -0
- package/dist/assets/volter-sdk-kit-collaboration-presence-De8jBlkX.js +1 -0
- package/dist/assets/volter-sdk-kit-command-dispatch-k9Qre0zs.js +1 -0
- package/dist/assets/volter-sdk-kit-command-listener-BCAbvhi5.js +1 -0
- package/dist/assets/volter-sdk-kit-command-registry-DhoVVzF5.js +1 -0
- package/dist/assets/volter-sdk-kit-component-board-registry-BeICFKFG.js +1 -0
- package/dist/assets/volter-sdk-kit-component-states-registry-QdCQHRDN.js +1 -0
- package/dist/assets/volter-sdk-kit-components-AlignToolbar-UuSLtczL.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ApplicationMenus-DRnMid6h.js +1 -0
- package/dist/assets/volter-sdk-kit-components-AssetEditorShell-k_gEaNs8.js +1 -0
- package/dist/assets/volter-sdk-kit-components-AssetInspectorToolSection-CgmL27Qf.js +1 -0
- package/dist/assets/volter-sdk-kit-components-BoardRulers-DaINv5KN.js +1 -0
- package/dist/assets/volter-sdk-kit-components-CanvasAddNodeDialogs-D33j4CtY.js +1 -0
- package/dist/assets/volter-sdk-kit-components-CanvasSceneViewport-U0vUe3Gh.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ChromeSlot-Di70MjzD.js +1 -0
- package/dist/assets/volter-sdk-kit-components-CodeView-Dw9qSGfW.js +1 -0
- package/dist/assets/volter-sdk-kit-components-CompactInspectorShell-BSaITVHL.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ConsolePanel-CBX_j1sn.js +1 -0
- package/dist/assets/volter-sdk-kit-components-GameplaySessionTimeline-D_SOr8n1.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectionProjection-BjmRH40i.js +1 -0
- package/dist/assets/volter-sdk-kit-components-Inspector-Bo9BYgAQ.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorCanvasPreview-C2U561Ms.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorFieldsSection-CKikcRO-.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorStoriesSection-CamEatgb.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorToolSection-qZTCY7B0.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorTransformSection-C1QrGase.js +1 -0
- package/dist/assets/volter-sdk-kit-components-LightExplorerPanel-D0XCAqj9.js +1 -0
- package/dist/assets/volter-sdk-kit-components-MediaProperties-CdL2K3l0.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ProjectHeader-Ds2BEQBR.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ReactCanvasControls-B-lQR6dk.js +1 -0
- package/dist/assets/volter-sdk-kit-components-RootSelectionOverlay-DL06pAbx.js +1 -0
- package/dist/assets/volter-sdk-kit-components-RootTextEditor-NXARIgKP.js +1 -0
- package/dist/assets/volter-sdk-kit-components-SaveStatus-D9k5E7Hu.js +1 -0
- package/dist/assets/volter-sdk-kit-components-SurfaceStateOverlay-B1204CGs.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ToolContributionSurfaces-Dg-KoCOj.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ToolHost-CQQFzB8P.js +1 -0
- package/dist/assets/volter-sdk-kit-components-Toolbar-B84RxD-H.js +1 -0
- package/dist/assets/volter-sdk-kit-components-TransientHint-Dm4X7E6D.js +1 -0
- package/dist/assets/volter-sdk-kit-components-VersionControlSection-fex1-uEJ.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ViewportOverlaysMenu-BMtIjudq.js +1 -0
- package/dist/assets/volter-sdk-kit-components-VolterLogo-CtJX1fLJ.js +1 -0
- package/dist/assets/volter-sdk-kit-components-WorktreeSwitcher-I5L1eMS3.js +1 -0
- package/dist/assets/volter-sdk-kit-components-account-documents-Dlh8Fj4d.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-documents-BGNKcXN5.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-editor-persistence-DYf1sB59.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-selection-section-DTX5bWfY.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-thumbnails-CMcb7LxE.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-AudioViewer-hYej0it1.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-GenericJsonViewer-C29xbyEa.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-ImageViewer-DKm5c9pQ.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-JsonAssetDocument-DlKL0CIE.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-OnlineAssetDetail-C4m5ChIc.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-SourceAssetViewer-C14y3ihh.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-SpritesheetSpriteView-CKB0yNjt.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-VideoViewer-BDVR2s-T.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-shader-source-DQ40_HIV.js +1 -0
- package/dist/assets/volter-sdk-kit-components-board-guides-vzj1_mB_.js +1 -0
- package/dist/assets/volter-sdk-kit-components-canvas-scene-hotkeys-BfUtoRtR.js +1 -0
- package/dist/assets/volter-sdk-kit-components-canvas-temporary-pivot-BOXeKsL_.js +1 -0
- package/dist/assets/volter-sdk-kit-components-core-utilities-2xqqv2Xj.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-preview-section-CIf6SZcH.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-revert-label-CB8zytBo.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-selection-B7qYFl9c.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-stories-gating-BBT6jLKq.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-transform-DfBSTsjH.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-transform-subject-BNvFtyig.js +1 -0
- package/dist/assets/volter-sdk-kit-components-kind-documents-Cz1AqKrb.js +1 -0
- package/dist/assets/volter-sdk-kit-components-primitives-DraftColorInput-2RRfpNhD.js +1 -0
- package/dist/assets/volter-sdk-kit-components-project-tool-documents-Baw6UVeU.js +1 -0
- package/dist/assets/volter-sdk-kit-components-scene-documents-Dp2nxLO5.js +1 -0
- package/dist/assets/volter-sdk-kit-components-status-contributions-0AL287G7.js +1 -0
- package/dist/assets/volter-sdk-kit-components-tool-documents-SxZNqv0G.js +1 -0
- package/dist/assets/volter-sdk-kit-components-tool-schema-form-CBlMD0L5.js +1 -0
- package/dist/assets/volter-sdk-kit-components-use-after-paint-HjJYZ8Gz.js +1 -0
- package/dist/assets/volter-sdk-kit-components-use-project-image-assets-BGRscgk_.js +1 -0
- package/dist/assets/volter-sdk-kit-components-workspace-history-BdMvmkrA.js +1 -0
- package/dist/assets/volter-sdk-kit-components-world-documents-BuIe0TVS.js +1 -0
- package/dist/assets/volter-sdk-kit-components-world-overlay-gestures-BKlVnBSH.js +1 -0
- package/dist/assets/volter-sdk-kit-composite-screenshot-ClRYm_mt.js +1 -0
- package/dist/assets/volter-sdk-kit-content-entry-source-registry-BTxRwbHZ.js +1 -0
- package/dist/assets/volter-sdk-kit-contribution-surfaces-BBsj68Wz.js +1 -0
- package/dist/assets/volter-sdk-kit-coverage-canvas-reveal-CPo5_e0H.js +1 -0
- package/dist/assets/volter-sdk-kit-coverage-design-time-surfaces-CZyb5EH5.js +1 -0
- package/dist/assets/volter-sdk-kit-coverage-ontology-invariants-Blt31TSP.js +1 -0
- package/dist/assets/volter-sdk-kit-coverage-session-vitals-Da5QSNR9.js +1 -0
- package/dist/assets/volter-sdk-kit-creation-site-registry-wwmnNA8H.js +1 -0
- package/dist/assets/volter-sdk-kit-delegate-harness-registry-DZhtG99C.js +1 -0
- package/dist/assets/volter-sdk-kit-document-areas-D660d1pQ.js +1 -0
- package/dist/assets/volter-sdk-kit-document-context-registry-C7A14BNb.js +1 -0
- package/dist/assets/volter-sdk-kit-document-open-registry-o7VHt0RE.js +1 -0
- package/dist/assets/volter-sdk-kit-document-play-extension-DnympyQy.js +1 -0
- package/dist/assets/volter-sdk-kit-document-preview-source-BIfEWYvh.js +1 -0
- package/dist/assets/volter-sdk-kit-document-renderer-session-BAoAh3oc.js +1 -0
- package/dist/assets/volter-sdk-kit-document-stage-sessions-rp-lUOf7.js +1 -0
- package/dist/assets/volter-sdk-kit-document-viewports-nfnBmvxp.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-api-B4otzopy.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-chrome-capture-CWmg17HP.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-commands-cJDgiqAt.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-console-DPkmRwd6.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-current-view-DxGCw3Wd.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-document-probe-CN2yr1kY.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-git-client-B46cp3L1.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-hotkeys-Dce3EYk2.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-lease-BN3_7vDZ.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-lease-view-C8WlPz7s.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-mode-B5EZmrCR.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-notifications-sTGM7WtH.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-presence-BHriH9Fy.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-presentation-activity-CmD9eBZ_.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-presentation-notice-Decyhm66.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-runtime-DHQJcaKd.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-server-response-BkWelHzj.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-session-attribution-BR9UWdR6.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-session-mode-hqIWdf2B.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-state-facets-bvq2P7SA.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-view-presentation-DLOWDzzy.js +1 -0
- package/dist/assets/volter-sdk-kit-environment-images-oMeHjbDw.js +1 -0
- package/dist/assets/volter-sdk-kit-eyedropper-session-DWAa-Biy.js +1 -0
- package/dist/assets/volter-sdk-kit-files-file-provider-U0Hd4ukx.js +1 -0
- package/dist/assets/volter-sdk-kit-files-project-files-4-kjPKJS.js +1 -0
- package/dist/assets/volter-sdk-kit-finders-index-CII4_28l.js +1 -0
- package/dist/assets/volter-sdk-kit-finders-scenes-from-entrypoint-selection-B8hycBye.js +1 -0
- package/dist/assets/volter-sdk-kit-frame-frame-parts-D-8Ffbnn.js +1 -0
- package/dist/assets/volter-sdk-kit-framed-document-capture-xuaTlR2W.js +1 -0
- package/dist/assets/volter-sdk-kit-game-surface-defaults-DMPYj1cL.js +1 -0
- package/dist/assets/volter-sdk-kit-gameplay-export-state-DwPVbG_z.js +1 -0
- package/dist/assets/volter-sdk-kit-gameplay-replay-YQ9HaJ4D.js +1 -0
- package/dist/assets/volter-sdk-kit-gameplay-session-time-CHjy5x0w.js +1 -0
- package/dist/assets/volter-sdk-kit-gameplay-sessions-DVNFi3db.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-component-marks-BO6QFbcg.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-internals-DHl0iE2O.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-kind-icon-CsQB7hVX.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-menu-registry-BqwYB4wh.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-node-rows-SGt4wx3-.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-panel-view-j1CZFQrR.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-projection-DlD5Ge3J.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-row-media-C8NlC6Zs.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-row-model-CsxqvCkr.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-rows-B6vFr7fv.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-walk-BSorleKV.js +1 -0
- package/dist/assets/volter-sdk-kit-history-editor-session-Ch7Rju03.js +1 -0
- package/dist/assets/volter-sdk-kit-history-history-commands-DHfC2eEE.js +1 -0
- package/dist/assets/volter-sdk-kit-history-history-delegate-d1VrRfJ_.js +1 -0
- package/dist/assets/volter-sdk-kit-history-history-limit-notices-Cz_aUVbj.js +1 -0
- package/dist/assets/volter-sdk-kit-history-history-service-DQuzGZjj.js +1 -0
- package/dist/assets/volter-sdk-kit-history-persistence-coordinator-B_IHVPkm.js +1 -0
- package/dist/assets/volter-sdk-kit-history-project-file-history-Carvs4Xw.js +1 -0
- package/dist/assets/volter-sdk-kit-history-project-root-history-backends-BLD_AY74.js +1 -0
- package/dist/assets/volter-sdk-kit-history-resource-registry-CNjNiuSL.js +1 -0
- package/dist/assets/volter-sdk-kit-history-snapshot-store-CJSmgzLO.js +1 -0
- package/dist/assets/volter-sdk-kit-history-source-history-backend-Dl_iBeRi.js +1 -0
- package/dist/assets/volter-sdk-kit-hmr-registration-group-CXyUJGHt.js +1 -0
- package/dist/assets/volter-sdk-kit-hmr-stable-react-context-CcADd8vA.js +1 -0
- package/dist/assets/volter-sdk-kit-hotkeys-B5mfvdNj.js +1 -0
- package/dist/assets/volter-sdk-kit-inference-diagnostics-CKudL-Hd.js +1 -0
- package/dist/assets/volter-sdk-kit-initial-project-DxdY28Kn.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-active-subject-ayxYCqDa.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-active-surface-BU9dpZgu.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-compose-subject-qD3qBc4d.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-display-C5PF41kk.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-document-subject-C7wKxaTC.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-game-subject-DbMHqpER.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-model-7J8bEzro.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-node-media-CsqEbnmq.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-null-subject-DZbH2nfV.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-serialize-BRjHRzyv.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-use-active-inspection-BwlJ4cum.js +1 -0
- package/dist/assets/volter-sdk-kit-inspector-presentation-BAs9sxmj.js +1 -0
- package/dist/assets/volter-sdk-kit-inspector-property-grouping-BMPF_r1R.js +1 -0
- package/dist/assets/volter-sdk-kit-inspector-section-registry-sIu0cDZ3.js +1 -0
- package/dist/assets/volter-sdk-kit-instance-source-actions-CuCpNP44.js +1 -0
- package/dist/assets/volter-sdk-kit-js-heap-33ODHy-d.js +1 -0
- package/dist/assets/volter-sdk-kit-key-actions-CsRondgE.js +1 -0
- package/dist/assets/volter-sdk-kit-keymap-presets-AscUFBGG.js +1 -0
- package/dist/assets/volter-sdk-kit-layout-policy-CWNvk4YG.js +1 -0
- package/dist/assets/volter-sdk-kit-light-explorer-model-DtNXjPVL.js +1 -0
- package/dist/assets/volter-sdk-kit-live-canvas-frame-BjCbO1ip.js +1 -0
- package/dist/assets/volter-sdk-kit-live-document-DcKqP5Vm.js +1 -0
- package/dist/assets/volter-sdk-kit-live-gesture-lock-D8Xw-crH.js +1 -0
- package/dist/assets/volter-sdk-kit-live-seam-evidence-BFvKDVcA.js +1 -0
- package/dist/assets/volter-sdk-kit-live-session-registry-DH6Gw6mD.js +1 -0
- package/dist/assets/volter-sdk-kit-live-transition-BqyCVB6M.js +1 -0
- package/dist/assets/volter-sdk-kit-manifest-project-DB9obnxF.js +1 -0
- package/dist/assets/volter-sdk-kit-module-fetch-diagnosis-UWhRbWd2.js +1 -0
- package/dist/assets/volter-sdk-kit-mount-failure-report-CUeYgCgW.js +1 -0
- package/dist/assets/volter-sdk-kit-native-selection-style-Cn13Teb3.js +1 -0
- package/dist/assets/volter-sdk-kit-object3d-document-write-policy-CAuCUEuz.js +1 -0
- package/dist/assets/volter-sdk-kit-packaged-runtime-CfWW26Lw.js +1 -0
- package/dist/assets/volter-sdk-kit-performance-profiler-Drw2xyyh.js +1 -0
- package/dist/assets/volter-sdk-kit-performance-sources-C5_qaCKL.js +1 -0
- package/dist/assets/volter-sdk-kit-photograph-notice-BorTV754.js +1 -0
- package/dist/assets/volter-sdk-kit-play-boot-phase-DRILY5HB.js +1 -0
- package/dist/assets/volter-sdk-kit-play-camera-flight-xWnFHyCJ.js +1 -0
- package/dist/assets/volter-sdk-kit-presentation-surface-BVjhfPW_.js +1 -0
- package/dist/assets/volter-sdk-kit-product-command-Z3FUyOZH.js +1 -0
- package/dist/assets/volter-sdk-kit-project-adapter-DYLGSL7n.js +1 -0
- package/dist/assets/volter-sdk-kit-project-asset-refresh-BQRieOTY.js +1 -0
- package/dist/assets/volter-sdk-kit-project-asset-roots-BzvdTX0f.js +1 -0
- package/dist/assets/volter-sdk-kit-project-local-state-C3v2aoZe.js +1 -0
- package/dist/assets/volter-sdk-kit-project-manager-BhNOa6yj.js +1 -0
- package/dist/assets/volter-sdk-kit-project-module-changes-D6xXn9e0.js +1 -0
- package/dist/assets/volter-sdk-kit-project-module-split-hrsUcLWw.js +1 -0
- package/dist/assets/volter-sdk-kit-project-provenance-Ch-TcC33.js +1 -0
- package/dist/assets/volter-sdk-kit-project-ready-DIs3PAtE.js +1 -0
- package/dist/assets/volter-sdk-kit-project-shape-cp-U044u.js +1 -0
- package/dist/assets/volter-sdk-kit-project-tools-Dsz8XxT2.js +1 -0
- package/dist/assets/volter-sdk-kit-readiness-DGy_iPng.js +1 -0
- package/dist/assets/volter-sdk-kit-renderer-resource-counts-CSFdq6cn.js +1 -0
- package/dist/assets/volter-sdk-kit-reported-play-state-Bbfug76r.js +1 -0
- package/dist/assets/volter-sdk-kit-resolve-contributed-command-BbMh2utc.js +1 -0
- package/dist/assets/volter-sdk-kit-resolve-relative-specifier-BuivsBeF.js +1 -0
- package/dist/assets/volter-sdk-kit-retained-document-states-CxqjPi-M.js +1 -0
- package/dist/assets/volter-sdk-kit-scene-document-plan-Pq2qwZBi.js +1 -0
- package/dist/assets/volter-sdk-kit-scene-live-open-u4QDXpQ0.js +1 -0
- package/dist/assets/volter-sdk-kit-scoped-game-css-tb7gOlcn.js +1 -0
- package/dist/assets/volter-sdk-kit-served-url-DtZEq2OD.js +1 -0
- package/dist/assets/volter-sdk-kit-session-close-BE3nJmiM.js +1 -0
- package/dist/assets/volter-sdk-kit-session-tombstone-B9q2Gxk2.js +1 -0
- package/dist/assets/volter-sdk-kit-settings-settings-provider-Bo5k3qZx.js +1 -0
- package/dist/assets/volter-sdk-kit-settings-store-BJ_3jPnk.js +1 -0
- package/dist/assets/volter-sdk-kit-shell-store-CA_p9YRS.js +1 -0
- package/dist/assets/volter-sdk-kit-shell-store-door-DrDJAdEA.js +1 -0
- package/dist/assets/volter-sdk-kit-source-conflict-BskWTHl1.js +1 -0
- package/dist/assets/volter-sdk-kit-stage-context-d2MOE3m1.js +1 -0
- package/dist/assets/volter-sdk-kit-stage-invalidation-CaUfxL_V.js +1 -0
- package/dist/assets/volter-sdk-kit-stage-store-registry-CsPquPQN.js +1 -0
- package/dist/assets/volter-sdk-kit-startup-failure-Bf4E0YMD.js +1 -0
- package/dist/assets/volter-sdk-kit-state-report-deferral-CKxDlryl.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-host-files-storage-DpV1XxZk.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-http-storage-Bu87cOj_.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-index-j54mTIme.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-mem-storage-CtFx_JD9.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-path-lock-CzDbr7Zo.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-paths-C-fXy9NI.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-StoryPreviewMount-X17hefjP.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-compose-project-stories-Dm6PyZ2j.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-prefabs-finder-Ch6FzvvU.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-prefabs-from-stories-vm7c5Dez.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-project-story-regions-0zBaevxR.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-scope-CQF_Wn9H.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-capture-CuSMTSru.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-declared-medium-D5fxOuPe.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-discovery-CARKaW03.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-dom-runtime-SNxzbxPZ.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-grouping-DyuyTFov.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-presentation-DB5Pqlf7.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-registry-C4PxIVxf.js +1 -0
- package/dist/assets/volter-sdk-kit-story-document-openers-BLRErv4h.js +1 -0
- package/dist/assets/volter-sdk-kit-story-thumbnails-nRyLNJxw.js +1 -0
- package/dist/assets/volter-sdk-kit-surface-keyboard-C5VehlZB.js +1 -0
- package/dist/assets/volter-sdk-kit-surface-state-D2RWtgU_.js +1 -0
- package/dist/assets/volter-sdk-kit-system-seam-evidence-DBmKEA5N.js +1 -0
- package/dist/assets/volter-sdk-kit-tab-census-DCYP_c6M.js +1 -0
- package/dist/assets/volter-sdk-kit-tab-lifecycle-client-B2dkacMA.js +1 -0
- package/dist/assets/volter-sdk-kit-theme-library-D2z9TIt_.js +1 -0
- package/dist/assets/volter-sdk-kit-theme-preference-CQYPOsMY.js +1 -0
- package/dist/assets/volter-sdk-kit-three-viewport-presentation-DjqLHzpC.js +1 -0
- package/dist/assets/volter-sdk-kit-tool-contribution-play-BJf9frMP.js +1 -0
- package/dist/assets/volter-sdk-kit-tool-loader-BJSPdpDJ.js +1 -0
- package/dist/assets/volter-sdk-kit-transform-mode-request-BysdaJxj.js +1 -0
- package/dist/assets/volter-sdk-kit-transient-hint-BCAURwwB.js +1 -0
- package/dist/assets/volter-sdk-kit-transport-strip-Dh_gh_Ar.js +1 -0
- package/dist/assets/volter-sdk-kit-ui-source-file-region-resolver-3PTxxNEF.js +1 -0
- package/dist/assets/volter-sdk-kit-ui-source-inspect-htLRFbbl.js +1 -0
- package/dist/assets/volter-sdk-kit-ui-source-source-write-backend--mXzGN0l.js +1 -0
- package/dist/assets/volter-sdk-kit-ui-source-tier-source-write-backend-BLldmdDB.js +1 -0
- package/dist/assets/volter-sdk-kit-user-local-state-BG9yY7wu.js +1 -0
- package/dist/assets/volter-sdk-kit-viewport-activation-timings-DI9VeZ8I.js +1 -0
- package/dist/assets/volter-sdk-kit-viewport-editor-controls-yx73yxqB.js +1 -0
- package/dist/assets/volter-sdk-kit-viewport-presentation-BiXyPx_l.js +1 -0
- package/dist/assets/volter-sdk-kit-viewport-surface-status-DhOHcCGA.js +1 -0
- package/dist/assets/volter-sdk-kit-wait-until-BxjkicFp.js +1 -0
- package/dist/assets/volter-sdk-kit-worker-call-metrics-CxIIhpb2.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-areas-CnNrdXA2.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-aux-commands-3Si9v39s.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-available-documents-DiQ-lLLQ.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-core-utilities-Htvt6dsG.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-document-ids-CaVQDIFY.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-document-registry-C-JtMmAl.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-document-restore-BMR96t8y.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-host-commands-lzroQNX_.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-persistence-gate-DuvwxRnn.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-play-utilities-C98Lvagt.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-presets-D-_A7JDE.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-regions-CjlUpZr0.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-static-panels-CMqSE6J4.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-status-registry-7kSA_sJg.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-storage-Dg-zwxJa.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-style-DOuNQjxD.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-utility-commands-Cb2B-wJ4.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-utility-registry-Bm-lvH6A.js +1 -0
- package/dist/assets/volter-sdk-kit-world-adoption-ndmh4Nmf.js +1 -0
- package/dist/assets/volter-sdk-kit-world-canvas-viewport-state-EnXhxxxs.js +1 -0
- package/dist/assets/volter-sdk-kit-world-document-routing-DBACuFYQ.js +1 -0
- package/dist/assets/volter-sdk-kit-world-pan-state-BGY2sBjP.js +1 -0
- package/dist/assets/volter-sdk-kit-write-pipe-D-TR3xVs.js +1 -0
- package/dist/assets/volter-sdk-layout-arrangements-DUPpMeSr.js +1 -0
- package/dist/assets/volter-sdk-layouts-CGyUD29k.js +1 -0
- package/dist/assets/volter-sdk-selection-tCvpnXRn.js +1 -0
- package/dist/assets/volter-sdk-session-command-table-BxONBy05.js +1 -0
- package/dist/assets/volter-sdk-session-editor-brand-BG0ODZ-8.js +1 -0
- package/dist/assets/volter-sdk-session-editor-compatibility-BHTMjwNA.js +1 -0
- package/dist/assets/volter-sdk-session-editor-control-protocol-CN7sZXZb.js +1 -0
- package/dist/assets/volter-sdk-session-entrypoint-selection-readers-9vLAGmig.js +1 -0
- package/dist/assets/volter-sdk-session-game-css-scope-BM1eAf3p.js +1 -0
- package/dist/assets/volter-sdk-session-project-module-url-CYuYhJk6.js +1 -0
- package/dist/assets/volter-sdk-session-relative-path-guard-BIEldh0Z.js +1 -0
- package/dist/assets/volter-sdk-session-tool-contribution-convention-DvN_LWlB.js +1 -0
- package/dist/assets/volter-sdk-types-BvyVPR_Q.js +1 -0
- package/dist/assets/volter-sdk-views-BDaWlMYB.js +1 -0
- package/dist/assets/volter-sdk-widgets-design-system-QBgXzl9_.js +1 -0
- package/dist/assets/volter-sdk-widgets-editor-appearance-BrIPELML.js +1 -0
- package/dist/assets/volter-sdk-widgets-editor-material-B_fvft70.js +1 -0
- package/dist/assets/volter-sdk-widgets-icon-set-registry-T4Dmzqt7.js +1 -0
- package/dist/assets/volter-sdk-widgets-index-B3HpUbVG.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-AlignmentGrid-CDr_zdnY.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-AssetSlotPicker-BWxes3gA.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-BorderEditor-etYg4PmT.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-ColorPicker-DetQDh_f.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-CurveEditor-BfTn_BsC.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-FilterEditor-saO-J7Oq.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-FontPicker-CZ7FmWxG.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-GradientEditor-ChiCM1d4.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-ScrubbableInput-Dz-bVsZ8.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-ShadowEditor-BAugA19h.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-color-utils-DxraCOXQ.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-curve-utils-kkJukQ0s.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-index-B3vyn0Ai.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-shared-CPkFF1JF.js +1 -0
- package/dist/assets/volter-sdk-widgets-interactive-edit-scope-D4_tVXsa.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Dialog-CkPDHAWE.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Fields-BJShETId.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-List-BgG2_2xL.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-StateSurface-G2He1eZg.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Surfaces-N-ry8Gth.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Tabs-gSMJ3Pp_.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Toolbar-BVbWQJC-.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Tree-BsJEhxbv.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-AnchoredMenu-CaiLdn6d.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Button-C0ugJ_I6.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-ColorInput-CJcVDa_m.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-DraftTextInput-B-I_hC_P.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-EditorIcon-BUbAPjrv.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-FormControls-9Ke8qtZ8.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-HoverPreview-IgTEdXXe.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-JsonInput-Dj0j9sft.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Layout-BfWHHWVT.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Menu-hgt5A7Kd.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-NumberInput-B_EwFkyN.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Panel-Bv-Dt2pg.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-SectionHeader-CtGyBmQ7.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Text-CROeI4AB.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-ThemeRootPortal-Bp6LhOHs.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Tooltip-CKGQWC6W.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Vec3Input-DKN5rnzb.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-banner-tones-2b5QAcYe.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-clamp-to-viewport-D94XgQyr.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-editor-icons-D9930eKI.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-panel-header-styles-DmH6-h4B.js +1 -0
- package/dist/assets/volter-sdk-widgets-theme-ah2w0Fkn.js +1 -0
- package/dist/assets/volter-sdk-widgets-z-index-BTO2KQ8P.js +1 -0
- package/dist/assets/volter-shared-fontawesome-BjL6w6Cn.js +1 -0
- package/dist/assets/volter-shared-jsx-dev-runtime-Bz1gHaPC.js +1 -0
- package/dist/assets/volter-shared-jsx-runtime-DZaM4mR0.js +1 -0
- package/dist/assets/volter-shared-react-71UsCCPo.js +1 -0
- package/dist/assets/volter-shared-react-dom-BJsW7Z0N.js +1 -0
- package/dist/assets/volter-shared-react-dom-client-Yf5gYUSE.js +1 -0
- package/dist/assets/volter-shared-three-wYzUWvH9.js +1 -0
- package/dist/assets/worker-D1j8wqVo.js +4 -0
- package/dist/volter-shared-react.json +10 -0
- package/dist/volter-shared-sdk.json +462 -0
- package/dist/volter-shared-three.json +3 -0
- package/dist-node/cli.js +21181 -0
- package/dist-node/create.js +14272 -0
- package/package.json +84 -4
- package/presets.mjs +2 -0
- package/src/contributions.d.ts +4 -0
- package/src/index.ts +10 -0
- package/starter/AGENTS.md +400 -0
- package/starter/CLAUDE.md +1 -0
- package/starter/cube.blend +0 -0
- package/starter/cube.py +82 -0
- package/starter/package.json +9 -0
- package/starter/race-state.ts +22 -0
- package/starter/track.blend +0 -0
- package/starter/track.play.ts +343 -0
- package/starter/track.py +324 -0
- package/starter/ui/game.stories.tsx +12 -0
- package/starter/ui/game.tsx +10 -0
- package/starter/ui/race-hud.tsx +29 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright 2026 Volter AI, Inc.
|
|
3
|
+
|
|
4
|
+
/** Drive the detached Cube. All positions under root are Blender's metres, Z up. */
|
|
5
|
+
import * as THREE from 'three';
|
|
6
|
+
import { publishRaceState } from './race-state';
|
|
7
|
+
|
|
8
|
+
export default function play(context: {
|
|
9
|
+
readonly root: THREE.Object3D;
|
|
10
|
+
find(name: string): THREE.Object3D | null;
|
|
11
|
+
readonly camera: THREE.Camera;
|
|
12
|
+
readonly keys: ReadonlySet<string>;
|
|
13
|
+
/** Offers the bot the Game panel's Autoplay switches on; absent outside the editor. */
|
|
14
|
+
autoplay?(controller: (input: { readonly tick: number }) => Iterable<string>): void;
|
|
15
|
+
}) {
|
|
16
|
+
const { root, find, keys } = context;
|
|
17
|
+
const car = find('Cube');
|
|
18
|
+
if (!car || !find('Track')) throw new Error('Open track.blend and run track.py first.');
|
|
19
|
+
const startPosition = car.position.clone();
|
|
20
|
+
const startHeading = car.rotation.z;
|
|
21
|
+
const wheels = ['Wheel.FL', 'Wheel.FR', 'Wheel.RL', 'Wheel.RR'].map((name) => {
|
|
22
|
+
const wheel = find(name);
|
|
23
|
+
if (!wheel) throw new Error(`The track model has no ${name}.`);
|
|
24
|
+
wheel.rotation.reorder('ZXY');
|
|
25
|
+
return wheel;
|
|
26
|
+
});
|
|
27
|
+
const startWheelRotations = wheels.map(wheel => wheel.quaternion.clone());
|
|
28
|
+
const surfaces: THREE.Object3D[] = [];
|
|
29
|
+
const kerbs: THREE.Vector3[] = [];
|
|
30
|
+
const obstacles: {
|
|
31
|
+
object: THREE.Object3D; position: THREE.Vector3; rotation: THREE.Quaternion;
|
|
32
|
+
velocity: THREE.Vector3; spin: THREE.Vector3; floor: number; hit: boolean;
|
|
33
|
+
}[] = [];
|
|
34
|
+
root.traverse((object) => {
|
|
35
|
+
if (!(object as THREE.Mesh).isMesh) return;
|
|
36
|
+
if (object.name.startsWith('Kerb.')) kerbs.push(object.position.clone());
|
|
37
|
+
if (object.name === 'Track' || object.name.startsWith('Ramp')) surfaces.push(object);
|
|
38
|
+
if (/^(Cone|Crate)\./.test(object.name)) {
|
|
39
|
+
find(object.name);
|
|
40
|
+
obstacles.push({ object, position: object.position.clone(), rotation: object.quaternion.clone(),
|
|
41
|
+
velocity: new THREE.Vector3(), spin: new THREE.Vector3(), floor: object.position.z, hit: false });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
let speed = 0;
|
|
45
|
+
let heading = car.rotation.z;
|
|
46
|
+
let steering = 0;
|
|
47
|
+
let verticalSpeed = 0;
|
|
48
|
+
let grounded = true;
|
|
49
|
+
let pitch = 0;
|
|
50
|
+
let cameraStarted = false;
|
|
51
|
+
let elapsed = 0;
|
|
52
|
+
let lap = 0;
|
|
53
|
+
let lapStarted = 0;
|
|
54
|
+
let lastLap = 0;
|
|
55
|
+
let checkpoint = 0;
|
|
56
|
+
let previousY = car.position.y;
|
|
57
|
+
let effectClock = 0;
|
|
58
|
+
let hudClock = 0;
|
|
59
|
+
let restartHeld = false;
|
|
60
|
+
const checkpoints = [1, 2, 3].map(i => find(`Checkpoint.${i}`)).filter((o): o is THREE.Object3D => o !== null);
|
|
61
|
+
const velocity = new THREE.Vector2();
|
|
62
|
+
const effects = new THREE.Group();
|
|
63
|
+
effects.name = 'Race effects';
|
|
64
|
+
root.add(effects);
|
|
65
|
+
const markGeometry = new THREE.PlaneGeometry(0.32, 0.7);
|
|
66
|
+
const markMaterial = new THREE.MeshBasicMaterial({ color: '#0f1a1f', transparent: true, opacity: 0.6, depthWrite: false });
|
|
67
|
+
const marks = Array.from({ length: 128 }, () => {
|
|
68
|
+
const mark = new THREE.Mesh(markGeometry, markMaterial);
|
|
69
|
+
mark.visible = false;
|
|
70
|
+
effects.add(mark);
|
|
71
|
+
return mark;
|
|
72
|
+
});
|
|
73
|
+
let nextMark = 0;
|
|
74
|
+
const puffGeometry = new THREE.IcosahedronGeometry(0.22, 0);
|
|
75
|
+
const puffs = Array.from({ length: 24 }, () => {
|
|
76
|
+
const material = new THREE.MeshBasicMaterial({ color: '#e9edef', transparent: true, opacity: 0, depthWrite: false });
|
|
77
|
+
const mesh = new THREE.Mesh(puffGeometry, material);
|
|
78
|
+
mesh.visible = false;
|
|
79
|
+
effects.add(mesh);
|
|
80
|
+
return { mesh, life: 0 };
|
|
81
|
+
});
|
|
82
|
+
let nextPuff = 0;
|
|
83
|
+
let fps = 0;
|
|
84
|
+
let measuredFrames = 0;
|
|
85
|
+
let measuredSince = performance.now();
|
|
86
|
+
const ray = new THREE.Raycaster();
|
|
87
|
+
const origin = new THREE.Vector3();
|
|
88
|
+
const down = new THREE.Vector3();
|
|
89
|
+
const up = new THREE.Vector3();
|
|
90
|
+
const hitPoint = new THREE.Vector3();
|
|
91
|
+
const eye = new THREE.Vector3();
|
|
92
|
+
const target = new THREE.Vector3();
|
|
93
|
+
const cameraPosition = new THREE.Vector3();
|
|
94
|
+
const cameraTarget = new THREE.Vector3();
|
|
95
|
+
const held = (arrow: string, letter: string): boolean => keys.has(arrow) || keys.has(letter);
|
|
96
|
+
const approach = (value: number, goal: number, step: number): number =>
|
|
97
|
+
value < goal ? Math.min(value + step, goal) : Math.max(value - step, goal);
|
|
98
|
+
const surfaceAt = (x: number, y: number): number | null => {
|
|
99
|
+
root.localToWorld(origin.set(x, y, 40));
|
|
100
|
+
ray.set(origin, down);
|
|
101
|
+
ray.far = 100;
|
|
102
|
+
const hit = ray.intersectObjects(surfaces, false)[0];
|
|
103
|
+
return hit ? root.worldToLocal(hitPoint.copy(hit.point)).z : null;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const restart = () => {
|
|
107
|
+
car.position.copy(startPosition);
|
|
108
|
+
heading = startHeading;
|
|
109
|
+
car.rotation.set(0, 0, heading, 'ZXY');
|
|
110
|
+
speed = steering = verticalSpeed = pitch = 0;
|
|
111
|
+
velocity.set(0, 0);
|
|
112
|
+
grounded = true;
|
|
113
|
+
cameraStarted = false;
|
|
114
|
+
elapsed = lap = lapStarted = lastLap = checkpoint = effectClock = hudClock = 0;
|
|
115
|
+
previousY = startPosition.y;
|
|
116
|
+
for (const [index, wheel] of wheels.entries()) wheel.quaternion.copy(startWheelRotations[index]!);
|
|
117
|
+
for (const obstacle of obstacles) {
|
|
118
|
+
obstacle.object.position.copy(obstacle.position);
|
|
119
|
+
obstacle.object.quaternion.copy(obstacle.rotation);
|
|
120
|
+
obstacle.velocity.set(0, 0, 0);
|
|
121
|
+
obstacle.spin.set(0, 0, 0);
|
|
122
|
+
obstacle.hit = false;
|
|
123
|
+
}
|
|
124
|
+
for (const mark of marks) mark.visible = false;
|
|
125
|
+
for (const puff of puffs) {
|
|
126
|
+
puff.life = 0;
|
|
127
|
+
puff.mesh.visible = false;
|
|
128
|
+
puff.mesh.material.opacity = 0;
|
|
129
|
+
}
|
|
130
|
+
publishRaceState({ lap: 1, lapTime: 0, lastLap: 0, speed: 0, fps, airborne: false });
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// THE BOT, offered to the editor: Autoplay in the Game panel lets it drive, and any key or
|
|
134
|
+
// click in the game hands the car back. It holds the same keys a person would, aiming at the
|
|
135
|
+
// next of track.py's control points and braking into turns it is taking too fast.
|
|
136
|
+
const route = [[32, -30], [32, -10], [32, 10], [32, 26], [22, 36], [8, 32], [4, 18], [-8, 16], [-16, 28],
|
|
137
|
+
[-30, 24], [-34, 10], [-22, 0], [-10, -4], [-16, -18], [-34, -28], [-30, -42], [-12, -44], [10, -44], [26, -40]]
|
|
138
|
+
.map(([x, y]) => new THREE.Vector2(x, y));
|
|
139
|
+
let waypoint = 0;
|
|
140
|
+
let botTick = -1;
|
|
141
|
+
context.autoplay?.(({ tick }) => {
|
|
142
|
+
const at = new THREE.Vector2(car.position.x, car.position.y);
|
|
143
|
+
// Switched on (again): aim past the nearest point, wherever the person left the car.
|
|
144
|
+
if (tick !== botTick + 1) {
|
|
145
|
+
const nearest = route.reduce((best, point, index) => point.distanceTo(at) < route[best]!.distanceTo(at) ? index : best, 0);
|
|
146
|
+
waypoint = (nearest + 1) % route.length;
|
|
147
|
+
}
|
|
148
|
+
botTick = tick;
|
|
149
|
+
if (route[waypoint]!.distanceTo(at) < 9) waypoint = (waypoint + 1) % route.length;
|
|
150
|
+
const target = route[waypoint]!;
|
|
151
|
+
const error = Math.atan2(target.y - at.y, target.x - at.x) - (heading + Math.PI / 2);
|
|
152
|
+
const turn = Math.atan2(Math.sin(error), Math.cos(error));
|
|
153
|
+
const hold = [Math.abs(turn) > 0.6 && speed > 14 ? 'ArrowDown' : 'ArrowUp'];
|
|
154
|
+
if (turn > 0.08) hold.push('ArrowLeft');
|
|
155
|
+
else if (turn < -0.08) hold.push('ArrowRight');
|
|
156
|
+
return hold;
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
update(dt: number) {
|
|
161
|
+
if (dt <= 0) return;
|
|
162
|
+
const restarting = keys.has('KeyR');
|
|
163
|
+
const firstRestartFrame = restarting && !restartHeld;
|
|
164
|
+
restartHeld = restarting;
|
|
165
|
+
if (firstRestartFrame) {
|
|
166
|
+
restart();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
elapsed += dt;
|
|
170
|
+
measuredFrames++;
|
|
171
|
+
const now = performance.now();
|
|
172
|
+
if (now - measuredSince >= 1000) {
|
|
173
|
+
fps = measuredFrames * 1000 / (now - measuredSince);
|
|
174
|
+
measuredFrames = 0;
|
|
175
|
+
measuredSince = now;
|
|
176
|
+
}
|
|
177
|
+
root.updateMatrixWorld(true);
|
|
178
|
+
up.set(0, 0, 1).transformDirection(root.matrixWorld);
|
|
179
|
+
down.copy(up).negate();
|
|
180
|
+
const throttle = held('ArrowUp', 'KeyW');
|
|
181
|
+
const brake = held('ArrowDown', 'KeyS');
|
|
182
|
+
const turn = Number(held('ArrowLeft', 'KeyA')) - Number(held('ArrowRight', 'KeyD'));
|
|
183
|
+
const steps = Math.ceil(dt / (1 / 60));
|
|
184
|
+
const h = dt / steps;
|
|
185
|
+
let travelled = 0;
|
|
186
|
+
for (let step = 0; step < steps; step++) {
|
|
187
|
+
if (throttle && !brake) speed = approach(speed, 30, (speed < 0 ? 20 : 10) * h);
|
|
188
|
+
else if (brake && !throttle) speed = approach(speed, -8, (speed > 0 ? 20 : 7) * h);
|
|
189
|
+
else speed = approach(speed, 0, (throttle && brake ? 20 : 3) * h);
|
|
190
|
+
steering = approach(steering, turn * 0.5, 3 * h);
|
|
191
|
+
if (grounded) heading += speed / 1.8 * Math.tan(steering) / (1 + Math.abs(speed) / 8) * h;
|
|
192
|
+
const drifting = grounded && Math.abs(steering) > 0.3 && Math.abs(speed) > 13;
|
|
193
|
+
const grip = grounded ? (drifting ? 1.6 : 8) : 0.2;
|
|
194
|
+
velocity.lerp(new THREE.Vector2(-Math.sin(heading) * speed, Math.cos(heading) * speed), 1 - Math.exp(-grip * h));
|
|
195
|
+
travelled += velocity.length() * h * Math.sign(speed);
|
|
196
|
+
car.position.x += velocity.x * h;
|
|
197
|
+
car.position.y += velocity.y * h;
|
|
198
|
+
const road = surfaceAt(car.position.x, car.position.y);
|
|
199
|
+
const floor = road ?? 0;
|
|
200
|
+
if (road === null && grounded) {
|
|
201
|
+
speed *= Math.exp(-2 * h);
|
|
202
|
+
speed = THREE.MathUtils.clamp(speed, -4, 4);
|
|
203
|
+
velocity.multiplyScalar(Math.exp(-2 * h));
|
|
204
|
+
}
|
|
205
|
+
// Follow a rising surface; retain its launch velocity when the surface drops away.
|
|
206
|
+
if (grounded && floor >= car.position.z - 0.15) {
|
|
207
|
+
verticalSpeed = (floor - car.position.z) / h;
|
|
208
|
+
car.position.z = floor;
|
|
209
|
+
const ahead = surfaceAt(car.position.x - Math.sin(heading), car.position.y + Math.cos(heading));
|
|
210
|
+
const behind = surfaceAt(car.position.x + Math.sin(heading), car.position.y - Math.cos(heading));
|
|
211
|
+
const slope = ahead === null || behind === null ? 0 : Math.atan2(ahead - behind, 2);
|
|
212
|
+
pitch = THREE.MathUtils.lerp(pitch, slope, 1 - Math.exp(-10 * h));
|
|
213
|
+
} else {
|
|
214
|
+
grounded = false;
|
|
215
|
+
verticalSpeed -= 30 * h;
|
|
216
|
+
car.position.z += verticalSpeed * h;
|
|
217
|
+
if (car.position.z <= floor && verticalSpeed <= 0) {
|
|
218
|
+
car.position.z = floor;
|
|
219
|
+
verticalSpeed = 0;
|
|
220
|
+
grounded = true;
|
|
221
|
+
}
|
|
222
|
+
pitch = THREE.MathUtils.lerp(pitch, Math.atan2(verticalSpeed, Math.max(10, Math.abs(speed))), 1 - Math.exp(-3 * h));
|
|
223
|
+
}
|
|
224
|
+
for (const obstacle of obstacles) {
|
|
225
|
+
const { object, velocity, spin } = obstacle;
|
|
226
|
+
const dx = object.position.x - car.position.x;
|
|
227
|
+
const dy = object.position.y - car.position.y;
|
|
228
|
+
if (!obstacle.hit && Math.hypot(dx, dy) < 1.7 && Math.abs(object.position.z - car.position.z) < 2 && Math.abs(speed) > 1) {
|
|
229
|
+
obstacle.hit = true;
|
|
230
|
+
velocity.set(-Math.sin(heading) * speed * 0.8 + dx * 2, Math.cos(heading) * speed * 0.8 + dy * 2, 5);
|
|
231
|
+
spin.set(3, -4, 2);
|
|
232
|
+
speed *= 0.93;
|
|
233
|
+
}
|
|
234
|
+
if (!obstacle.hit) continue;
|
|
235
|
+
velocity.z -= 18 * h;
|
|
236
|
+
object.position.addScaledVector(velocity, h);
|
|
237
|
+
object.rotation.x += spin.x * h;
|
|
238
|
+
object.rotation.y += spin.y * h;
|
|
239
|
+
object.rotation.z += spin.z * h;
|
|
240
|
+
if (object.position.z < obstacle.floor) {
|
|
241
|
+
object.position.z = obstacle.floor;
|
|
242
|
+
velocity.z = Math.abs(velocity.z) * 0.25;
|
|
243
|
+
velocity.x *= Math.exp(-5 * h);
|
|
244
|
+
velocity.y *= Math.exp(-5 * h);
|
|
245
|
+
spin.multiplyScalar(Math.exp(-5 * h));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const roll = grounded ? -steering * Math.min(Math.abs(speed), 24) * 0.018 : 0;
|
|
250
|
+
car.rotation.set(pitch, roll, heading, 'ZXY');
|
|
251
|
+
effectClock += dt;
|
|
252
|
+
const slipping = grounded && Math.abs(steering) > 0.3 && Math.abs(speed) > 13;
|
|
253
|
+
const offroad = grounded && surfaceAt(car.position.x, car.position.y) === null;
|
|
254
|
+
if ((slipping || offroad) && effectClock > 0.06) {
|
|
255
|
+
effectClock = 0;
|
|
256
|
+
for (const side of [-1, 1]) {
|
|
257
|
+
const mark = marks[nextMark++ % marks.length]!;
|
|
258
|
+
mark.position.copy(car.position).add(new THREE.Vector3(side * 1.2 * Math.cos(heading) + Math.sin(heading) * 0.78,
|
|
259
|
+
side * 1.2 * Math.sin(heading) - Math.cos(heading) * 0.78, 0.018));
|
|
260
|
+
mark.rotation.z = heading;
|
|
261
|
+
mark.visible = true;
|
|
262
|
+
const puff = puffs[nextPuff++ % puffs.length]!;
|
|
263
|
+
puff.mesh.position.copy(mark.position).add(new THREE.Vector3(0, 0, 0.3));
|
|
264
|
+
puff.mesh.scale.setScalar(1);
|
|
265
|
+
puff.mesh.material.color.set(offroad ? '#c7641a' : '#e9edef');
|
|
266
|
+
puff.life = 0.7;
|
|
267
|
+
puff.mesh.visible = true;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
for (const puff of puffs) {
|
|
271
|
+
if (puff.life <= 0) continue;
|
|
272
|
+
puff.life -= dt;
|
|
273
|
+
puff.mesh.visible = puff.life > 0;
|
|
274
|
+
puff.mesh.material.opacity = Math.max(0, puff.life * 0.5);
|
|
275
|
+
puff.mesh.position.z += dt * 0.9;
|
|
276
|
+
puff.mesh.scale.addScalar(dt * 1.8);
|
|
277
|
+
}
|
|
278
|
+
const nextCheckpoint = checkpoints[checkpoint];
|
|
279
|
+
if (lap > 0 && nextCheckpoint && Math.hypot(car.position.x - nextCheckpoint.position.x, car.position.y - nextCheckpoint.position.y) < 10)
|
|
280
|
+
checkpoint++;
|
|
281
|
+
if (previousY < -24 && car.position.y >= -24 && Math.abs(car.position.x - 32) < 5 && speed > 0) {
|
|
282
|
+
if (lap === 0 || checkpoint === checkpoints.length) {
|
|
283
|
+
lastLap = lap === 0 ? 0 : elapsed - lapStarted;
|
|
284
|
+
lap++;
|
|
285
|
+
checkpoint = 0;
|
|
286
|
+
lapStarted = elapsed;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
previousY = car.position.y;
|
|
290
|
+
hudClock += dt;
|
|
291
|
+
if (hudClock >= 0.1) {
|
|
292
|
+
hudClock = 0;
|
|
293
|
+
publishRaceState({ lap: Math.max(1, lap), lapTime: lap ? elapsed - lapStarted : 0,
|
|
294
|
+
lastLap, speed: Math.abs(speed) * 3.6, fps, airborne: !grounded });
|
|
295
|
+
}
|
|
296
|
+
for (const [index, wheel] of wheels.entries()) {
|
|
297
|
+
wheel.rotation.z = index < 2 ? steering : 0;
|
|
298
|
+
wheel.rotation.x = (wheel.rotation.x - travelled / 0.57) % (2 * Math.PI);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Smooth our own stage-space pose; navigation re-poses the stage camera each frame.
|
|
302
|
+
root.updateMatrixWorld(true);
|
|
303
|
+
const pace = Math.min(30, Math.abs(speed));
|
|
304
|
+
const distance = grounded ? 11 + pace * 0.07 : 12;
|
|
305
|
+
const lookAhead = grounded ? 2.5 + pace * 0.04 : 0.5;
|
|
306
|
+
const fov = 36 + pace * 0.28;
|
|
307
|
+
const height = 1.2 + (distance + lookAhead) * Math.tan(THREE.MathUtils.degToRad(fov * 0.22));
|
|
308
|
+
const kerb = grounded && kerbs.some(point => Math.hypot(point.x - car.position.x, point.y - car.position.y) < 1.4);
|
|
309
|
+
const rumble = kerb ? Math.sin(elapsed * 90) * Math.min(0.05, pace * 0.003) : 0;
|
|
310
|
+
const side = grounded ? 3 : 10;
|
|
311
|
+
root.localToWorld(eye.set(car.position.x + Math.sin(heading) * distance + side * Math.cos(heading),
|
|
312
|
+
car.position.y - Math.cos(heading) * distance + side * Math.sin(heading), car.position.z + height + rumble));
|
|
313
|
+
root.localToWorld(target.set(car.position.x - Math.sin(heading) * lookAhead,
|
|
314
|
+
car.position.y + Math.cos(heading) * lookAhead, car.position.z + (grounded ? 1.4 : 0.4)));
|
|
315
|
+
if (!cameraStarted) {
|
|
316
|
+
cameraPosition.copy(eye);
|
|
317
|
+
cameraTarget.copy(target);
|
|
318
|
+
cameraStarted = true;
|
|
319
|
+
}
|
|
320
|
+
const blend = 1 - Math.exp(-12 * dt);
|
|
321
|
+
cameraPosition.lerp(eye, blend);
|
|
322
|
+
cameraTarget.lerp(target, blend);
|
|
323
|
+
const camera = context.camera;
|
|
324
|
+
camera.position.copy(cameraPosition);
|
|
325
|
+
if (camera.parent) camera.parent.worldToLocal(camera.position);
|
|
326
|
+
camera.up.copy(up).applyAxisAngle(new THREE.Vector3().subVectors(cameraTarget, cameraPosition).normalize(), -roll * 0.3);
|
|
327
|
+
if ((camera as THREE.PerspectiveCamera).isPerspectiveCamera) {
|
|
328
|
+
const perspective = camera as THREE.PerspectiveCamera;
|
|
329
|
+
perspective.fov = fov;
|
|
330
|
+
perspective.updateProjectionMatrix();
|
|
331
|
+
}
|
|
332
|
+
camera.lookAt(cameraTarget);
|
|
333
|
+
camera.updateMatrixWorld(true);
|
|
334
|
+
},
|
|
335
|
+
dispose() {
|
|
336
|
+
root.remove(effects);
|
|
337
|
+
markGeometry.dispose();
|
|
338
|
+
markMaterial.dispose();
|
|
339
|
+
puffGeometry.dispose();
|
|
340
|
+
for (const puff of puffs) puff.mesh.material.dispose();
|
|
341
|
+
},
|
|
342
|
+
};
|
|
343
|
+
}
|
package/starter/track.py
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
# Copyright 2026 Volter AI, Inc.
|
|
3
|
+
#
|
|
4
|
+
# Like cube.py, this bpy script is GPL-3.0-or-later; the .blend it authors
|
|
5
|
+
# is your artwork, and the project's other starter source is MIT.
|
|
6
|
+
|
|
7
|
+
"""The race source for Volter Cyclotron, built on Blender.
|
|
8
|
+
|
|
9
|
+
Open Track, then run through the session's Blender:
|
|
10
|
+
editor.blender('blender-execute', { code: open('src/models/track.py').read() })
|
|
11
|
+
The agent's blender MCP server is declared in .mcp.json and runs the project's
|
|
12
|
+
installed Cyclotron CLI directly in Node, without an npm/bin shim.
|
|
13
|
+
|
|
14
|
+
Only track.blend may be replaced; the session saves it. View > Play drives
|
|
15
|
+
its grey Cube with arrows/WASD. Move any Ramp* mesh onto the circuit to jump.
|
|
16
|
+
Coordinates are metres, Z is up, and local +Y is forward.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import math
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
import bpy
|
|
23
|
+
from mathutils import Matrix, Vector
|
|
24
|
+
|
|
25
|
+
if Path(bpy.data.filepath).name != "track.blend":
|
|
26
|
+
raise RuntimeError("Open the Track model (track.blend) first: this replaces the open model.")
|
|
27
|
+
|
|
28
|
+
for obj in list(bpy.data.objects):
|
|
29
|
+
bpy.data.objects.remove(obj, do_unlink=True)
|
|
30
|
+
# This file owns its entire scene, including its display collections.
|
|
31
|
+
for group in list(bpy.data.collections):
|
|
32
|
+
if group.name != "Collection":
|
|
33
|
+
bpy.data.collections.remove(group)
|
|
34
|
+
for collection in (bpy.data.meshes, bpy.data.materials, bpy.data.lights, bpy.data.cameras, bpy.data.curves):
|
|
35
|
+
for data in list(collection):
|
|
36
|
+
collection.remove(data)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def colour(value):
|
|
40
|
+
rgb = tuple(int(value[i:i + 2], 16) / 255 for i in (1, 3, 5))
|
|
41
|
+
return tuple(c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4 for c in rgb)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def material(name, value):
|
|
45
|
+
result = bpy.data.materials.new(name=name)
|
|
46
|
+
result.use_nodes = True
|
|
47
|
+
rgba = (*colour(value), 1.0)
|
|
48
|
+
result.diffuse_color = rgba
|
|
49
|
+
result.node_tree.nodes.get("Principled BSDF").inputs["Base Color"].default_value = rgba
|
|
50
|
+
return result
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Volter's light semantic roles from brand.volter.ai/tokens.json, in linear RGB.
|
|
54
|
+
asphalt = material("Asphalt", "#16252c") # surface.inverse
|
|
55
|
+
# Dry asphalt scatters the low sun; it must not read as a polished mirror.
|
|
56
|
+
asphalt.node_tree.nodes.get("Principled BSDF").inputs["Roughness"].default_value = 1.0
|
|
57
|
+
asphalt.node_tree.nodes.get("Principled BSDF").inputs["Specular IOR Level"].default_value = 0.05
|
|
58
|
+
grass = material("Grass", "#5f9a2e") # scene.instance
|
|
59
|
+
grass.node_tree.nodes.get("Principled BSDF").inputs["Roughness"].default_value = 1.0
|
|
60
|
+
grass.node_tree.nodes.get("Principled BSDF").inputs["Specular IOR Level"].default_value = 0.05
|
|
61
|
+
orange = material("Orange", "#ff6a1f") # accent.orange
|
|
62
|
+
white = material("White", "#f3f2ec") # text.inverse
|
|
63
|
+
rubber = material("Rubber", "#0f1a1f") # surface.media
|
|
64
|
+
violet = material("Violet", "#6a5a92") # scene.dynamicSoft
|
|
65
|
+
wood = material("Wood", "#c7641a") # data.amber
|
|
66
|
+
leaves = material("Leaves", "#5f9a2e") # scene.instance
|
|
67
|
+
cube_material = bpy.data.materials.new(name="Material")
|
|
68
|
+
cube_material.use_nodes = True
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def box(name, location, dimensions, surface, parent=None):
|
|
72
|
+
bpy.ops.mesh.primitive_cube_add(size=1.0, location=location)
|
|
73
|
+
obj = bpy.context.active_object
|
|
74
|
+
obj.name = name
|
|
75
|
+
obj.data.name = name
|
|
76
|
+
obj.dimensions = dimensions
|
|
77
|
+
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
|
|
78
|
+
obj.data.materials.append(surface)
|
|
79
|
+
obj.parent = parent
|
|
80
|
+
return obj
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def mesh(name, vertices, faces, surface, location=(0.0, 0.0, 0.0)):
|
|
84
|
+
data = bpy.data.meshes.new(name)
|
|
85
|
+
data.from_pydata(vertices, [], faces)
|
|
86
|
+
data.update()
|
|
87
|
+
obj = bpy.data.objects.new(name, data)
|
|
88
|
+
bpy.context.collection.objects.link(obj)
|
|
89
|
+
obj.location = location
|
|
90
|
+
obj.data.materials.append(surface)
|
|
91
|
+
return obj
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# A long start straight, a tight northern turn and alternating infield bends.
|
|
95
|
+
points = [
|
|
96
|
+
(32, -30), (32, -10), (32, 10), (32, 26), (22, 36), (8, 32),
|
|
97
|
+
(4, 18), (-8, 16), (-16, 28), (-30, 24), (-34, 10), (-22, 0),
|
|
98
|
+
(-10, -4), (-16, -18), (-34, -28), (-30, -42), (-12, -44),
|
|
99
|
+
(10, -44), (26, -40),
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def path(index, t):
|
|
104
|
+
a, b, c, d = [Vector((*points[(index + offset) % len(points)], 0)) for offset in (-1, 0, 1, 2)]
|
|
105
|
+
return 0.5 * ((2 * b) + (-a + c) * t + (2 * a - 5 * b + 4 * c - d) * t * t + (-a + 3 * b - 3 * c + d) * t * t * t)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
samples = []
|
|
109
|
+
for i in range(len(points)):
|
|
110
|
+
for step in range(12):
|
|
111
|
+
t = step / 12
|
|
112
|
+
centre = path(i, t)
|
|
113
|
+
tangent = (path(i, t + 0.001) - centre).normalized()
|
|
114
|
+
normal = Vector((-tangent.y, tangent.x, 0))
|
|
115
|
+
samples.append((centre, tangent, normal))
|
|
116
|
+
|
|
117
|
+
vertices = []
|
|
118
|
+
for centre, tangent, normal in samples:
|
|
119
|
+
vertices.extend([tuple(centre - normal * 5), tuple(centre + normal * 5)])
|
|
120
|
+
faces = []
|
|
121
|
+
for i in range(len(samples)):
|
|
122
|
+
j = (i + 1) % len(samples)
|
|
123
|
+
faces.append((2 * i, 2 * j, 2 * j + 1, 2 * i + 1))
|
|
124
|
+
mesh("Track", vertices, faces, asphalt)
|
|
125
|
+
# Raised just above the asphalt, with face normals up: crisp road markings.
|
|
126
|
+
for side in (-1, 1):
|
|
127
|
+
edge = []
|
|
128
|
+
for centre, tangent, normal in samples:
|
|
129
|
+
edge.extend([tuple(centre + normal * (side * 4.62 - 0.09) + Vector((0, 0, 0.012))),
|
|
130
|
+
tuple(centre + normal * (side * 4.62 + 0.09) + Vector((0, 0, 0.012)))])
|
|
131
|
+
mesh(f"Edge.{side}", edge, faces, white)
|
|
132
|
+
for i, (centre, tangent, normal) in enumerate(samples):
|
|
133
|
+
if i % 4 == 0:
|
|
134
|
+
line = box(f"Centre.{i}", (centre.x, centre.y, 0.015), (0.16, 1.5, 0.02), white)
|
|
135
|
+
line.rotation_euler.z = math.atan2(tangent.y, tangent.x) - math.pi / 2
|
|
136
|
+
|
|
137
|
+
bpy.ops.mesh.primitive_plane_add(size=300, location=(0, -4, -0.04))
|
|
138
|
+
ground = bpy.context.active_object
|
|
139
|
+
ground.name = "Ground"
|
|
140
|
+
ground.data.materials.append(grass)
|
|
141
|
+
|
|
142
|
+
for i, (centre, tangent, normal) in enumerate(samples):
|
|
143
|
+
if i % 3 != 0:
|
|
144
|
+
continue
|
|
145
|
+
for side in (-1, 1):
|
|
146
|
+
at = centre + normal * (5.3 * side)
|
|
147
|
+
kerb = box(f"Kerb.{i}.{side}", (at.x, at.y, 0.09), (0.6, 1.7, 0.18), white if i % 2 else orange)
|
|
148
|
+
kerb.rotation_euler.z = math.atan2(tangent.y, tangent.x) - math.pi / 2
|
|
149
|
+
if i % 12 == 0:
|
|
150
|
+
at = centre - normal * 7.3
|
|
151
|
+
for tyre in range(3):
|
|
152
|
+
bpy.ops.mesh.primitive_torus_add(major_segments=12, minor_segments=6, major_radius=0.52, minor_radius=0.22, location=(at.x + tangent.x * (tyre - 1) * 1.4, at.y + tangent.y * (tyre - 1) * 1.4, 0.35))
|
|
153
|
+
obj = bpy.context.active_object
|
|
154
|
+
obj.name = f"Barrier.{i}.{tyre}"
|
|
155
|
+
obj.data.materials.append(rubber)
|
|
156
|
+
|
|
157
|
+
# The checker line and gantry make the start readable from the chase camera.
|
|
158
|
+
for row in range(2):
|
|
159
|
+
for column in range(10):
|
|
160
|
+
box(f"Start.{row}.{column}", (27.5 + column, -24 + row * 0.5, 0.015), (1, 0.5, 0.03), white if (row + column) % 2 else asphalt)
|
|
161
|
+
for x in (25.8, 38.2):
|
|
162
|
+
box(f"Gantry.Post.{x}", (x, -24, 3.1), (0.35, 0.5, 6.2), white)
|
|
163
|
+
box("Gantry.Beam", (32, -24, 6.0), (13, 0.6, 0.8), orange)
|
|
164
|
+
for i in range(7):
|
|
165
|
+
box(f"Gantry.Check.{i}", (27.5 + i * 1.5, -24.32, 6.0), (0.75, 0.04, 0.55), white)
|
|
166
|
+
|
|
167
|
+
# A wedge's top is read by the play script, including after an editor move.
|
|
168
|
+
mesh("Ramp.Jump", [(-3, -4, 0), (3, -4, 0), (3, 4, 2.4), (-3, 4, 2.4), (-3, 4, 0), (3, 4, 0)],
|
|
169
|
+
[(0, 1, 2, 3), (3, 2, 5, 4), (0, 3, 4), (1, 5, 2), (0, 4, 5, 1)], violet, (32, -2, 0))
|
|
170
|
+
|
|
171
|
+
for i in range(6):
|
|
172
|
+
bpy.ops.mesh.primitive_cone_add(vertices=8, radius1=0.4, radius2=0.06, depth=0.85, location=(29 + i * 1.2, 12, 0.425))
|
|
173
|
+
cone = bpy.context.active_object
|
|
174
|
+
cone.name = f"Cone.{i}"
|
|
175
|
+
cone.data.materials.append(orange)
|
|
176
|
+
box(f"ConeBase.{i}", (0, 0, -0.4), (0.8, 0.8, 0.08), rubber, cone)
|
|
177
|
+
for i in range(4):
|
|
178
|
+
crate = box(f"Crate.{i}", (-27 + i * 1.5, -28, 0.65), (1.2, 1.2, 1.3), wood)
|
|
179
|
+
box(f"CrateBand.{i}", (0, 0, 0), (1.25, 0.15, 1.35), white, crate)
|
|
180
|
+
|
|
181
|
+
for i in range(56):
|
|
182
|
+
angle = math.tau * i / 56
|
|
183
|
+
x, y = (53 + i % 3 * 7) * math.cos(angle), -4 + (56 + i % 4 * 4) * math.sin(angle)
|
|
184
|
+
box(f"Tree.Trunk.{i}", (x, y, 1.4), (0.4, 0.4, 2.8), wood)
|
|
185
|
+
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=1, radius=2.6, location=(x, y, 4.0))
|
|
186
|
+
tree = bpy.context.active_object
|
|
187
|
+
tree.name = f"Tree.Crown.{i}"
|
|
188
|
+
tree.scale.z = 1.35
|
|
189
|
+
tree.data.materials.append(leaves if i % 2 else grass)
|
|
190
|
+
|
|
191
|
+
# Low-poly hills close the horizon without textures or a skybox.
|
|
192
|
+
for i in range(18):
|
|
193
|
+
angle = math.tau * i / 18
|
|
194
|
+
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=1, radius=1, location=(150 * math.cos(angle), -4 + 150 * math.sin(angle), 0))
|
|
195
|
+
hill = bpy.context.active_object
|
|
196
|
+
hill.name = f"Hill.{i}"
|
|
197
|
+
hill.scale = (55, 55, 6 + i % 4 * 3)
|
|
198
|
+
hill.data.materials.append(grass if i % 2 else leaves)
|
|
199
|
+
for i in range(5):
|
|
200
|
+
for tier in range(3):
|
|
201
|
+
box(f"Stand.{i}.{tier}", (44 + tier * 1.3, -28 + i * 5, 0.5 + tier * 0.6), (1.3, 4.5, 1 + tier * 1.2), orange if i % 2 else violet)
|
|
202
|
+
box(f"Stand.Roof.{i}", (45.3, -28 + i * 5, 4.2), (5, 4.8, 0.2), white)
|
|
203
|
+
|
|
204
|
+
for i, (x, y) in enumerate(((22, 2), (42, 14), (-40, 18), (-24, -50))):
|
|
205
|
+
box(f"Billboard.Post.{i}", (x, y, 1.5), (0.3, 0.4, 3), white)
|
|
206
|
+
box(f"Billboard.{i}", (x, y, 3), (0.35, 6, 2), orange if i % 2 else violet)
|
|
207
|
+
for stripe in range(3):
|
|
208
|
+
box(f"Billboard.Stripe.{i}.{stripe}", (x + 0.2, y - 1.6 + stripe * 1.5, 3), (0.05, 0.65, 1.4), white)
|
|
209
|
+
|
|
210
|
+
# Ordered checkpoints prevent lap counts from shuttling over the start line.
|
|
211
|
+
for i, (x, y) in enumerate(((8, 32), (-34, 10), (-12, -44)), 1):
|
|
212
|
+
checkpoint = bpy.data.objects.new(f"Checkpoint.{i}", None)
|
|
213
|
+
bpy.context.collection.objects.link(checkpoint)
|
|
214
|
+
checkpoint.location = (x, y, 0)
|
|
215
|
+
|
|
216
|
+
# Default cube geometry and material; its ground-level origin carries the wheels.
|
|
217
|
+
car = box("Cube", (32, -28, 0), (2, 2, 2), cube_material)
|
|
218
|
+
car.data.transform(Matrix.Translation((0, 0, 1.42)))
|
|
219
|
+
for name, x, y in (("Wheel.FL", -1.2, 0.78), ("Wheel.FR", 1.2, 0.78), ("Wheel.RL", -1.2, -0.78), ("Wheel.RR", 1.2, -0.78)):
|
|
220
|
+
bpy.ops.mesh.primitive_cylinder_add(vertices=16, radius=0.57, depth=0.55, location=(x, y, 0.57), rotation=(0, math.pi / 2, 0))
|
|
221
|
+
wheel = bpy.context.active_object
|
|
222
|
+
wheel.name = name
|
|
223
|
+
bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
|
|
224
|
+
wheel.data.materials.append(rubber)
|
|
225
|
+
wheel.parent = car
|
|
226
|
+
box(name + ".Spoke", (math.copysign(0.29, x), 0, 0), (0.04, 0.14, 0.85), white, wheel)
|
|
227
|
+
|
|
228
|
+
scene = bpy.context.scene
|
|
229
|
+
scene.unit_settings.system = "METRIC"
|
|
230
|
+
scene.unit_settings.scale_length = 1
|
|
231
|
+
scene.world.use_nodes = True
|
|
232
|
+
scene.world.node_tree.nodes.clear()
|
|
233
|
+
background = scene.world.node_tree.nodes.new("ShaderNodeBackground")
|
|
234
|
+
output = scene.world.node_tree.nodes.new("ShaderNodeOutputWorld")
|
|
235
|
+
scene.world.node_tree.links.new(background.outputs[0], output.inputs[0])
|
|
236
|
+
sky = scene.world.node_tree.nodes.new("ShaderNodeTexSky")
|
|
237
|
+
# Blender 5.2 calls its Nishita successor MULTIPLE_SCATTERING; the presenter supports it.
|
|
238
|
+
sky.sky_type = "MULTIPLE_SCATTERING"
|
|
239
|
+
sky.sun_elevation = math.radians(16)
|
|
240
|
+
sky.sun_rotation = math.radians(225)
|
|
241
|
+
sky.aerosol_density = 0.0
|
|
242
|
+
sky.altitude = 0.0
|
|
243
|
+
scene.world.node_tree.links.new(sky.outputs["Color"], background.inputs["Color"])
|
|
244
|
+
# Separate visible sky brightness from ambient radiance, as an ordinary World shader.
|
|
245
|
+
light_path = scene.world.node_tree.nodes.new("ShaderNodeLightPath")
|
|
246
|
+
ambient = scene.world.node_tree.nodes.new("ShaderNodeBackground")
|
|
247
|
+
ambient.inputs["Strength"].default_value = 0.03
|
|
248
|
+
scene.world.node_tree.links.new(sky.outputs["Color"], ambient.inputs["Color"])
|
|
249
|
+
mix = scene.world.node_tree.nodes.new("ShaderNodeMixShader")
|
|
250
|
+
scene.world.node_tree.links.new(light_path.outputs["Is Camera Ray"], mix.inputs[0])
|
|
251
|
+
scene.world.node_tree.links.new(ambient.outputs["Background"], mix.inputs[1])
|
|
252
|
+
scene.world.node_tree.links.new(background.outputs["Background"], mix.inputs[2])
|
|
253
|
+
scene.world.node_tree.links.new(mix.outputs[0], output.inputs["Surface"])
|
|
254
|
+
background.inputs["Strength"].default_value = 0.06
|
|
255
|
+
scene.view_settings.view_transform = "Standard"
|
|
256
|
+
scene.view_settings.look = "None"
|
|
257
|
+
scene.view_settings.exposure = 0
|
|
258
|
+
bpy.ops.object.light_add(type="SUN", rotation=(math.radians(74), 0, math.radians(-55)))
|
|
259
|
+
sun = bpy.context.active_object
|
|
260
|
+
sun.name = "Sun"
|
|
261
|
+
sun.data.energy = 3.0
|
|
262
|
+
sun.data.color = (1.0, 0.88, 0.68)
|
|
263
|
+
sun.data.angle = math.radians(0.5)
|
|
264
|
+
|
|
265
|
+
bpy.ops.object.camera_add(location=(39, -36, 3.8))
|
|
266
|
+
camera = bpy.context.active_object
|
|
267
|
+
camera.name = "Camera"
|
|
268
|
+
camera.rotation_euler = (Vector((32, -22, 1.4)) - camera.location).to_track_quat('-Z', 'Y').to_euler()
|
|
269
|
+
camera.data.lens = 28
|
|
270
|
+
scene.camera = camera
|
|
271
|
+
scene.render.resolution_x = 1280
|
|
272
|
+
scene.render.resolution_y = 720
|
|
273
|
+
scene.render.resolution_percentage = 100
|
|
274
|
+
for screen in bpy.data.screens:
|
|
275
|
+
for area in screen.areas:
|
|
276
|
+
if area.type == "VIEW_3D":
|
|
277
|
+
space = area.spaces.active
|
|
278
|
+
# Blender demotes Rendered to Solid when loading a file. Material
|
|
279
|
+
# Preview with the scene's World/lights survives that native load.
|
|
280
|
+
space.shading.type = "MATERIAL"
|
|
281
|
+
space.shading.use_scene_world = True
|
|
282
|
+
space.shading.use_scene_lights = True
|
|
283
|
+
space.region_3d.view_location = (32, -22, 1.4)
|
|
284
|
+
space.region_3d.view_distance = 16
|
|
285
|
+
space.region_3d.view_rotation = camera.rotation_euler.to_quaternion()
|
|
286
|
+
|
|
287
|
+
# Collections organize Blender files; parent empties also survive as the Play hierarchy.
|
|
288
|
+
# Identity group transforms keep the script's Blender-space obstacle/kerb positions intact.
|
|
289
|
+
main = bpy.data.collections.get("Collection")
|
|
290
|
+
groups = {}
|
|
291
|
+
for name in ("Kerbs", "Cones", "Crates", "Trees", "Tyres", "Scenery", "Gantry", "Ramps"):
|
|
292
|
+
group = bpy.data.objects.new(name, None)
|
|
293
|
+
main.objects.link(group)
|
|
294
|
+
group.empty_display_type = "PLAIN_AXES"
|
|
295
|
+
group.empty_display_size = 0.5
|
|
296
|
+
groups[name] = group
|
|
297
|
+
|
|
298
|
+
for obj in list(bpy.data.objects):
|
|
299
|
+
if obj.parent or obj.name in groups or obj.name in {"Cube", "Track", "Ground", "Sun", "Camera"}:
|
|
300
|
+
continue
|
|
301
|
+
prefix = obj.name.split(".")[0]
|
|
302
|
+
if prefix in {"Edge", "Centre"}:
|
|
303
|
+
parent = bpy.data.objects["Track"]
|
|
304
|
+
else:
|
|
305
|
+
group = {
|
|
306
|
+
"Kerb": "Kerbs", "Cone": "Cones", "Crate": "Crates", "Tree": "Trees",
|
|
307
|
+
"Barrier": "Tyres", "Gantry": "Gantry", "Start": "Gantry", "Ramp": "Ramps",
|
|
308
|
+
}.get(prefix, "Scenery")
|
|
309
|
+
parent = groups[group]
|
|
310
|
+
world = obj.matrix_world.copy()
|
|
311
|
+
obj.parent = parent
|
|
312
|
+
obj.matrix_world = world
|
|
313
|
+
|
|
314
|
+
# Expanded object rows should name their geometry, not a primitive's .001 data.
|
|
315
|
+
for obj in bpy.data.objects:
|
|
316
|
+
if obj.data is not None:
|
|
317
|
+
obj.data.name = obj.name
|
|
318
|
+
|
|
319
|
+
# Cameras are useful for a render, but their overlay rectangle obscures the edit.
|
|
320
|
+
camera.hide_set(True)
|
|
321
|
+
|
|
322
|
+
bpy.ops.object.select_all(action="DESELECT")
|
|
323
|
+
car.select_set(True)
|
|
324
|
+
bpy.context.view_layer.objects.active = car
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright 2026 Volter AI, Inc.
|
|
3
|
+
import GameUI from './game';
|
|
4
|
+
import { RaceHud } from './race-hud';
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Race/HUD', component: GameUI, render: (args) => <RaceHud {...args} />,
|
|
7
|
+
parameters: { layout: 'fullscreen', volter: { defaultStory: 'StartLine' } },
|
|
8
|
+
args: { lap: 1, lapTime: 0, lastLap: 0, speed: 0, fps: 60, airborne: false },
|
|
9
|
+
};
|
|
10
|
+
export const StartLine = {};
|
|
11
|
+
export const Racing = { args: { lap: 2, lapTime: 18.24, lastLap: 42.15, speed: 96 } };
|
|
12
|
+
export const Jump = { args: { lapTime: 5.82, speed: 88, airborne: true } };
|