@volter/cyclotron 0.0.0-stage → 0.5.192
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-KYkNDaSy.js +1 -0
- package/dist/assets/EnvironmentAssetDocument-Bn36-K03.js +1 -0
- package/dist/assets/FBXLoader-B6D0-2sM.js +1 -0
- package/dist/assets/InspectorObjectPreview-CQMs9zha.js +1 -0
- package/dist/assets/LineSegments2-D1_2s-N-.js +370 -0
- package/dist/assets/LiveModuleDocument-ye1IT-i6.js +2 -0
- package/dist/assets/LutAssetDocument-CouZZubV.js +1 -0
- package/dist/assets/MTLLoader-BwtVpZY2.js +2 -0
- package/dist/assets/ModelAssetDocument-SpE-ctRj.js +1 -0
- package/dist/assets/NonThreeAuthoringBootstrap-BAe_hy9t.js +1 -0
- package/dist/assets/OBJLoader-Cwe-BN99.js +5 -0
- package/dist/assets/Object3DDocumentToolbar-Bfm-RTS8.js +1 -0
- package/dist/assets/Object3DPreview-C4Ai3BNI.js +2 -0
- package/dist/assets/OrbitControls-Cn2q_IQK.js +1 -0
- package/dist/assets/PLYLoader-DOl6qb2a.js +2 -0
- package/dist/assets/QuarksAssetDocument-CqYjSnLo.js +2 -0
- package/dist/assets/RectAreaLightUniformsLib-CobhIWNK.js +1 -0
- package/dist/assets/STLLoader-B5YpfCGT.js +1 -0
- package/dist/assets/ShaderAssetDocument-BBT3ENGG.js +1 -0
- package/dist/assets/StageHost-qZAn6HZ3.js +1179 -0
- package/dist/assets/TDSLoader-BdQ2M2WU.js +1 -0
- package/dist/assets/ToolObject3DPreview-ClIcOYFk.js +1 -0
- package/dist/assets/ViewportShadingMenu-DmM-Odyl.js +1 -0
- package/dist/assets/animation-mixers.service-CsBdF1O3.js +1 -0
- package/dist/assets/animation-timeline.utility-DRfepAbV.js +1 -0
- package/dist/assets/anthropic-DwpKRVGM.svg +1 -0
- package/dist/assets/asset-preview-jtcCFntF.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-Bi2T12bG.js +1 -0
- package/dist/assets/blender-properties-model-Yj49RcLm.js +1 -0
- package/dist/assets/blender-properties-tab-Dtap7p2U.js +3 -0
- package/dist/assets/blender-runtime-host-CMI7ldx1.js +17 -0
- package/dist/assets/blender-runtime.document-D0NB4iPR.js +13 -0
- package/dist/assets/blender-screenshot.menu-D0-n31XK.js +1 -0
- package/dist/assets/blender-timeline.document-_1xorgQ6.js +1 -0
- package/dist/assets/blender-uv-editor.document-Dki4Ui-b.js +1 -0
- package/dist/assets/blender-version.status-DlBU0k-r.js +1 -0
- package/dist/assets/blender-wali-engine-D2ymLooc.js +2 -0
- package/dist/assets/blender.command-BcpIwWTF.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-B1L-FZyU.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-jRplyguX.js +1 -0
- package/dist/assets/model.layout-BpZE1W9V.js +1 -0
- package/dist/assets/models.finder-jvcjSDNd.js +1 -0
- package/dist/assets/night-CvV4Gybt.exr +0 -0
- package/dist/assets/object3d-document-session-registry-_NnPOZmk.js +2 -0
- package/dist/assets/openai-DHNKzFtc.svg +1 -0
- package/dist/assets/play-mode-DljPhCBr.js +7208 -0
- package/dist/assets/png-encode.worker-E8zk28Vl.js +1 -0
- package/dist/assets/product-BxXXdFxI.css +1 -0
- package/dist/assets/product-Dcs9ogdH.js +14 -0
- package/dist/assets/properties-bone-constraints.inspector-sNOrOqmn.js +1 -0
- package/dist/assets/properties-bone.inspector-DrRAhkXh.js +1 -0
- package/dist/assets/properties-collection.inspector-D2bNhLqd.js +1 -0
- package/dist/assets/properties-constraints.inspector-CGTEqVBY.js +1 -0
- package/dist/assets/properties-data.inspector-nwiHdy4s.js +1 -0
- package/dist/assets/properties-material.inspector-CPW_Te19.js +1 -0
- package/dist/assets/properties-modifiers.inspector-CsIgxGPe.js +1 -0
- package/dist/assets/properties-object.inspector-Cwx4QctT.js +1 -0
- package/dist/assets/properties-output.inspector-CgChOQat.js +1 -0
- package/dist/assets/properties-particles.inspector-B8j59UFB.js +1 -0
- package/dist/assets/properties-physics.inspector-ComSsHn6.js +1 -0
- package/dist/assets/properties-render.inspector-BTqY-F5-.js +1 -0
- package/dist/assets/properties-scene.inspector-C-R7eu1o.js +1 -0
- package/dist/assets/properties-texture.inspector-CFmTTdHS.js +1 -0
- package/dist/assets/properties-view-layer.inspector-BvMUCTd_.js +1 -0
- package/dist/assets/properties-world.inspector-Dpb6EWk8.js +1 -0
- package/dist/assets/react-18-BDYozTc0.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-Cjy_uKPi.js +1 -0
- package/dist/assets/stage-overlay-set-BV78wZfK.js +1 -0
- package/dist/assets/stage-presence-markers-CJVuC1Vh.js +1 -0
- package/dist/assets/stage-transform-tools-B21BRk-L.js +1 -0
- package/dist/assets/standard-viewport-dressing-zXbS_1ew.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-Bfy6rPSh.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-BwU3fa6G.js +2358 -0
- package/dist/assets/volter-sdk-account-BlUZdl9g.js +1 -0
- package/dist/assets/volter-sdk-client-C_pM7u8F.js +1 -0
- package/dist/assets/volter-sdk-contributions-CyyzzsHD.js +1 -0
- package/dist/assets/volter-sdk-css-numeric-style-B404pZI8.js +1 -0
- package/dist/assets/volter-sdk-document-probe-DAjYzNFt.js +1 -0
- package/dist/assets/volter-sdk-editor-view-suHsPgK2.js +1 -0
- package/dist/assets/volter-sdk-host-58UWGff-.js +1 -0
- package/dist/assets/volter-sdk-http-transport.browser-VJksIuNN.js +1 -0
- package/dist/assets/volter-sdk-index-DQpzb0WD.js +1 -0
- package/dist/assets/volter-sdk-kit-CapabilityCoverageSection-C41uHAFx.js +1 -0
- package/dist/assets/volter-sdk-kit-account-client-BnrRHdPV.js +1 -0
- package/dist/assets/volter-sdk-kit-action-registry-Co0Hbo6i.js +1 -0
- package/dist/assets/volter-sdk-kit-active-product-7gseHcVz.js +1 -0
- package/dist/assets/volter-sdk-kit-active-project-Bmrlj0XL.js +1 -0
- package/dist/assets/volter-sdk-kit-adapter-editor-config-DqGAdw2_.js +1 -0
- package/dist/assets/volter-sdk-kit-adapter-observation-Y-Cr3BiX.js +1 -0
- package/dist/assets/volter-sdk-kit-animation-animation-clock-BYmBGV0P.js +1 -0
- package/dist/assets/volter-sdk-kit-animation-stage-transport-CY7-VoVp.js +1 -0
- package/dist/assets/volter-sdk-kit-api-assets-CRsoN16p.js +1 -0
- package/dist/assets/volter-sdk-kit-api-base-Dw9L5xJS.js +1 -0
- package/dist/assets/volter-sdk-kit-api-build-BapF1Knc.js +1 -0
- package/dist/assets/volter-sdk-kit-api-logs-ClNHtQ6y.js +1 -0
- package/dist/assets/volter-sdk-kit-api-project-identity-CLam3F93.js +1 -0
- package/dist/assets/volter-sdk-kit-api-project-open-D9BK6gAR.js +1 -0
- package/dist/assets/volter-sdk-kit-api-project-source-B4ZDf1-O.js +1 -0
- package/dist/assets/volter-sdk-kit-api-project-state-Q0gbhHMy.js +1 -0
- package/dist/assets/volter-sdk-kit-api-relay-CEs5T2gc.js +1 -0
- package/dist/assets/volter-sdk-kit-api-settings-DQhJJaCN.js +1 -0
- package/dist/assets/volter-sdk-kit-api-themes-CK0mpUed.js +1 -0
- package/dist/assets/volter-sdk-kit-api-worktrees-CZAcA-yg.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-capabilities-BH2tqp_X.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-compare-core-CO4rbaNo.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-editor-context-Crd2QR_x.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-events-Cfuds14S.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-inspector-actions-BOh3j-zP.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-selection-UhfuT50E.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-selection-viewer-registry-EWMtCoHo.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-thumbnails-CzMUys7a.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-viewers-Cf_KVYEv.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-import-jobs-CBNjRa8N.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-ledger-_i8-7mdV.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-ledger-backend-C20xqeUO.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-materialization-report-Dech0lQC.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-asset-pack-manifest-pPS9qzPW.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-audio-preview-player-0wPh24zI.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-audio-waveform-BAY5AA4K.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-cloud-asset-client-DRc8hWEO.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-hosted-asset-materialization-BW7Al90A.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-image-view-scale-DNIgToKY.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-ledger-write-lock-DT7NxaAG.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-pixi-spritesheet-F0tDOvEn.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-preview-resource-lifetime-BvmHntAY.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-project-asset-commands-Dar362Gf.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-project-content-DAMV_NEZ.js +1 -0
- package/dist/assets/volter-sdk-kit-asset-workflow-thumbnail-system-D9b6o-CL.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-active-adapter-BZ9hzFLG.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-active-systems-Cpbjxaoi.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-adapter-key-CNJDTSi4.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-authoring-asset-url-BnteIxrT.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-bootstrap-state-DMaoNrQW.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-boundary-authoring-adapter-DBAwTDuf.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-canvas-scene-guides-DWrvby2w.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-composite-authoring-adapter-C4-Kp99J.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-consumer-actions-CBBDoLEX.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-design-time-layers-DuxPqGrN.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-design-time-mount-registry-Div61xFj.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-edit-mode-authoring-lp1HgOZY.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-empty-project-authoring-DESJUilA.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-instance-source-menu-Yw8ilOpP.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-layered-pick-CnFv-JJ4.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-mounted-root-subjects-BG3VV4R2.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-no-authoring-adapter-DdsbWdzA.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-object3d-document-persistence-Cz3dTWOm.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-panel-authoring-CVVMuMz7.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-project-authoring-session-Dr97ZYKO.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-provenance-B5PenuKN.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-react-canvas-navigation-C-FLncdT.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-react-design-canvas-style-mWGHuhfC.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-react-story-board-BJdVcnM0.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-seam-evidence-kaO6Kcw3.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-selection-scope-MaPGsoaC.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-shell-document-ops-fzF3ajnE.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-story-board-chrome-fit-BmaeUc2Q.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-three-root-_Iik8VOw.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-viewport-tool-context-BMaVuFyB.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-viewport-tool-owner-D7gzEf8Y.js +1 -0
- package/dist/assets/volter-sdk-kit-authoring-world-session-state-DHU1uP-A.js +1 -0
- package/dist/assets/volter-sdk-kit-availability-tick-mnrfOjCO.js +1 -0
- package/dist/assets/volter-sdk-kit-bitmap-label-tfpyi7Ai.js +1 -0
- package/dist/assets/volter-sdk-kit-boot-routing-BHPc5GLo.js +1 -0
- package/dist/assets/volter-sdk-kit-breakpoint-state-Db1oqXJX.js +1 -0
- package/dist/assets/volter-sdk-kit-build-identity-BTQ1Xdpa.js +1 -0
- package/dist/assets/volter-sdk-kit-bytes-codec-DvWCmxma.js +1 -0
- package/dist/assets/volter-sdk-kit-cancellation-reason-BEjzQjCf.js +1 -0
- package/dist/assets/volter-sdk-kit-canvas-frames-BJEuXRrc.js +1 -0
- package/dist/assets/volter-sdk-kit-capture-camera-pose-YJBoQ23O.js +1 -0
- package/dist/assets/volter-sdk-kit-capture-size-EmnVLs8n.js +1 -0
- package/dist/assets/volter-sdk-kit-chrome-registry-Cs0k1OX1.js +1 -0
- package/dist/assets/volter-sdk-kit-chrome-slot-registry-BwDDbLjQ.js +1 -0
- package/dist/assets/volter-sdk-kit-collaboration-client-C2jtyYW3.js +1 -0
- package/dist/assets/volter-sdk-kit-collaboration-presence-D3UftauX.js +1 -0
- package/dist/assets/volter-sdk-kit-command-dispatch-BZWUjbx5.js +1 -0
- package/dist/assets/volter-sdk-kit-command-listener-CfFEgEYh.js +1 -0
- package/dist/assets/volter-sdk-kit-command-registry-CxqLDZ_t.js +1 -0
- package/dist/assets/volter-sdk-kit-component-board-registry-wPpm4hz2.js +1 -0
- package/dist/assets/volter-sdk-kit-component-states-registry-DUnoMxYg.js +1 -0
- package/dist/assets/volter-sdk-kit-components-AlignToolbar-kgkYRPYY.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ApplicationMenus-DSUoF1z8.js +1 -0
- package/dist/assets/volter-sdk-kit-components-AssetEditorShell-BsmfaAE9.js +1 -0
- package/dist/assets/volter-sdk-kit-components-AssetInspectorToolSection-GxYRyjBh.js +1 -0
- package/dist/assets/volter-sdk-kit-components-BoardRulers-XXJ7RCz4.js +1 -0
- package/dist/assets/volter-sdk-kit-components-CanvasAddNodeDialogs-DSg-5iRY.js +1 -0
- package/dist/assets/volter-sdk-kit-components-CanvasSceneViewport-C8suTPNd.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ChromeSlot-kgnOcXb4.js +1 -0
- package/dist/assets/volter-sdk-kit-components-CodeView-8_n22zvN.js +1 -0
- package/dist/assets/volter-sdk-kit-components-CompactInspectorShell-DkR_oNfI.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ConsolePanel-DiI4aQRP.js +1 -0
- package/dist/assets/volter-sdk-kit-components-GameplaySessionTimeline-BwzyAzUn.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectionProjection-Cz94_Rt7.js +1 -0
- package/dist/assets/volter-sdk-kit-components-Inspector-BPFGLp3d.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorCanvasPreview-CA1NTcqw.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorFieldsSection-BuwRGDJ0.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorStoriesSection-BsVaquIj.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorToolSection-Di0bMd01.js +1 -0
- package/dist/assets/volter-sdk-kit-components-InspectorTransformSection-_E4Y2mdm.js +1 -0
- package/dist/assets/volter-sdk-kit-components-LightExplorerPanel-4D34umvc.js +1 -0
- package/dist/assets/volter-sdk-kit-components-MediaProperties-BtpXA40W.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ProjectHeader-COVqavbg.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ReactCanvasControls-lvb140oy.js +1 -0
- package/dist/assets/volter-sdk-kit-components-RootSelectionOverlay-BWDtha0N.js +1 -0
- package/dist/assets/volter-sdk-kit-components-RootTextEditor-E99FydcX.js +1 -0
- package/dist/assets/volter-sdk-kit-components-SaveStatus-DolfRGCT.js +1 -0
- package/dist/assets/volter-sdk-kit-components-SurfaceStateOverlay-BHtKccFF.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ToolContributionSurfaces-D02jF-QD.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ToolHost-xY2N5GR3.js +1 -0
- package/dist/assets/volter-sdk-kit-components-Toolbar-XTw72bRl.js +1 -0
- package/dist/assets/volter-sdk-kit-components-TransientHint-LyCJ6M5h.js +1 -0
- package/dist/assets/volter-sdk-kit-components-VersionControlSection-CaUBgU7Q.js +1 -0
- package/dist/assets/volter-sdk-kit-components-ViewportOverlaysMenu-DJm0Vtra.js +1 -0
- package/dist/assets/volter-sdk-kit-components-VolterLogo-7QJN2Aue.js +1 -0
- package/dist/assets/volter-sdk-kit-components-WorktreeSwitcher-Cm6EQlo9.js +1 -0
- package/dist/assets/volter-sdk-kit-components-account-documents-C1w8-N3m.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-documents-o5P9hniy.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-editor-persistence-DLsU0r1E.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-selection-section-BYEwJfLy.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-thumbnails-C-LgDd2_.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-AudioViewer-BR48_QX5.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-GenericJsonViewer-C9IP9LWM.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-ImageViewer-Dffdgv60.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-JsonAssetDocument-ChmgYQAP.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-OnlineAssetDetail-Bdpm--Jx.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-SourceAssetViewer-DdJX9xCd.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-SpritesheetSpriteView-DYXAuujE.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-VideoViewer-6xqrjETd.js +1 -0
- package/dist/assets/volter-sdk-kit-components-asset-viewers-shader-source-cHZlxpZt.js +1 -0
- package/dist/assets/volter-sdk-kit-components-board-guides-7WFdaGRg.js +1 -0
- package/dist/assets/volter-sdk-kit-components-canvas-scene-hotkeys-CnxAX0SN.js +1 -0
- package/dist/assets/volter-sdk-kit-components-canvas-temporary-pivot-CtpM87Bn.js +1 -0
- package/dist/assets/volter-sdk-kit-components-core-utilities-CHVzLxwg.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-preview-section-B8TaQyFK.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-revert-label-BNzoXVNS.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-selection-BpPShgrU.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-stories-gating-DiH66VA6.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-transform-CmjteW7M.js +1 -0
- package/dist/assets/volter-sdk-kit-components-inspector-transform-subject-DrIk_jIn.js +1 -0
- package/dist/assets/volter-sdk-kit-components-kind-documents-BK3KZxJA.js +1 -0
- package/dist/assets/volter-sdk-kit-components-primitives-DraftColorInput-1nPD0Wmj.js +1 -0
- package/dist/assets/volter-sdk-kit-components-project-tool-documents-DJ4Ucdcc.js +1 -0
- package/dist/assets/volter-sdk-kit-components-scene-documents-D0S3Ip8u.js +1 -0
- package/dist/assets/volter-sdk-kit-components-status-contributions-CnD50KDE.js +1 -0
- package/dist/assets/volter-sdk-kit-components-tool-documents-CFPlSwI0.js +1 -0
- package/dist/assets/volter-sdk-kit-components-tool-schema-form-DDm00y0g.js +1 -0
- package/dist/assets/volter-sdk-kit-components-use-after-paint-DvCjTL4J.js +1 -0
- package/dist/assets/volter-sdk-kit-components-use-project-image-assets-C2yOGb4T.js +1 -0
- package/dist/assets/volter-sdk-kit-components-workspace-history-cK1qO4Ko.js +1 -0
- package/dist/assets/volter-sdk-kit-components-world-documents-Ca0Kvd6F.js +1 -0
- package/dist/assets/volter-sdk-kit-components-world-overlay-gestures-D9tS4EXa.js +1 -0
- package/dist/assets/volter-sdk-kit-composite-screenshot-DrxN3o4m.js +1 -0
- package/dist/assets/volter-sdk-kit-content-entry-source-registry-WrKmcDj4.js +1 -0
- package/dist/assets/volter-sdk-kit-contribution-surfaces-DkZ0OqGh.js +1 -0
- package/dist/assets/volter-sdk-kit-coverage-canvas-reveal-C8pETRas.js +1 -0
- package/dist/assets/volter-sdk-kit-coverage-design-time-surfaces-BEEt0Akm.js +1 -0
- package/dist/assets/volter-sdk-kit-coverage-ontology-invariants-Bxd6b-Me.js +1 -0
- package/dist/assets/volter-sdk-kit-coverage-session-vitals-C_KOh0vV.js +1 -0
- package/dist/assets/volter-sdk-kit-creation-site-registry-xToT1mgQ.js +1 -0
- package/dist/assets/volter-sdk-kit-delegate-harness-registry-BQ2Z3x4u.js +1 -0
- package/dist/assets/volter-sdk-kit-document-areas-BoFteXyg.js +1 -0
- package/dist/assets/volter-sdk-kit-document-context-registry-DCltdAwX.js +1 -0
- package/dist/assets/volter-sdk-kit-document-open-registry-nUKbpgXi.js +1 -0
- package/dist/assets/volter-sdk-kit-document-play-extension-LhA9YSwP.js +1 -0
- package/dist/assets/volter-sdk-kit-document-preview-source-BjKu56A5.js +1 -0
- package/dist/assets/volter-sdk-kit-document-renderer-session-CmO67Fns.js +1 -0
- package/dist/assets/volter-sdk-kit-document-stage-sessions-DhjElggV.js +1 -0
- package/dist/assets/volter-sdk-kit-document-viewports-JkYxkBPk.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-api-CkTONSnh.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-chrome-capture-Ryy6MFML.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-commands-A6xFbhNt.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-console-CfXqiRHJ.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-current-view-Blu4WXH4.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-document-probe-DLQ4_TGz.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-git-client-79qLddTa.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-hotkeys-Bf8x8pPR.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-lease-DnDA6DTK.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-lease-view-DnYNNuac.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-mode-TyppF_mm.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-notifications-DbJyIY8R.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-presence-CDht_mUS.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-presentation-activity-BAw4OBGu.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-presentation-notice-vPwlLZpU.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-runtime-BM50QyRE.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-server-response-BMR_IEYq.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-session-attribution-GlzM29Xi.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-session-mode-zTS3Hh7x.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-state-facets-iq5aCQYy.js +1 -0
- package/dist/assets/volter-sdk-kit-editor-view-presentation-D-Zr2xsr.js +1 -0
- package/dist/assets/volter-sdk-kit-environment-images-BBbuCQN0.js +1 -0
- package/dist/assets/volter-sdk-kit-eyedropper-session-CVQTFAKM.js +1 -0
- package/dist/assets/volter-sdk-kit-files-file-provider-DnQAC1u2.js +1 -0
- package/dist/assets/volter-sdk-kit-files-project-files-CwASwqrX.js +1 -0
- package/dist/assets/volter-sdk-kit-finders-index-CclbaymG.js +1 -0
- package/dist/assets/volter-sdk-kit-finders-scenes-from-entrypoint-selection-B17U2yvo.js +1 -0
- package/dist/assets/volter-sdk-kit-frame-frame-parts-VVzfs78H.js +1 -0
- package/dist/assets/volter-sdk-kit-framed-document-capture-Cha1yjuL.js +1 -0
- package/dist/assets/volter-sdk-kit-game-surface-defaults-CsAR7C_G.js +1 -0
- package/dist/assets/volter-sdk-kit-gameplay-export-state-D2gCoh9n.js +1 -0
- package/dist/assets/volter-sdk-kit-gameplay-replay-DkkfYYwX.js +1 -0
- package/dist/assets/volter-sdk-kit-gameplay-session-time-Dht9eZ_4.js +1 -0
- package/dist/assets/volter-sdk-kit-gameplay-sessions-CCOOL4Eg.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-component-marks-CTw2KFgo.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-internals-D8gRo1WQ.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-kind-icon-D0OctdvL.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-menu-registry-DwA4Z2A9.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-node-rows-BGNi2kxs.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-panel-view-Bb1EP0Bk.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-projection-BtCzTzOY.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-row-media-CnHgcQM8.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-row-model-l7Qbe9Dk.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-rows-C20aO3up.js +1 -0
- package/dist/assets/volter-sdk-kit-hierarchy-walk-CE_FQf5c.js +1 -0
- package/dist/assets/volter-sdk-kit-history-editor-session-CS5IwxZx.js +1 -0
- package/dist/assets/volter-sdk-kit-history-history-commands-VU0Tf0lj.js +1 -0
- package/dist/assets/volter-sdk-kit-history-history-delegate-ZQwI-0MR.js +1 -0
- package/dist/assets/volter-sdk-kit-history-history-limit-notices-BrhHiRSY.js +1 -0
- package/dist/assets/volter-sdk-kit-history-history-service-BZ4AidfS.js +1 -0
- package/dist/assets/volter-sdk-kit-history-persistence-coordinator-Bpi3os_u.js +1 -0
- package/dist/assets/volter-sdk-kit-history-project-file-history-hDI70zmi.js +1 -0
- package/dist/assets/volter-sdk-kit-history-project-root-history-backends-BAfTGdrX.js +1 -0
- package/dist/assets/volter-sdk-kit-history-resource-registry-CGjyTLt-.js +1 -0
- package/dist/assets/volter-sdk-kit-history-snapshot-store-BgZ7Byks.js +1 -0
- package/dist/assets/volter-sdk-kit-history-source-history-backend-B25Z4lQz.js +1 -0
- package/dist/assets/volter-sdk-kit-hmr-registration-group-CiEUgAw2.js +1 -0
- package/dist/assets/volter-sdk-kit-hmr-stable-react-context-AymxVJvR.js +1 -0
- package/dist/assets/volter-sdk-kit-hotkeys-DlADec38.js +1 -0
- package/dist/assets/volter-sdk-kit-inference-diagnostics-GA9FnyOh.js +1 -0
- package/dist/assets/volter-sdk-kit-initial-project-zsKWa81T.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-active-subject-qZ5hTw90.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-active-surface-PhQ5uNsI.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-compose-subject-BgSCqJ-r.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-display-D8Nr6_ES.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-document-subject-DGznaZh-.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-game-subject-N0AxqX7G.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-model-hQetv0U9.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-node-media-fGRDtgJj.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-null-subject-ClNE9x2e.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-serialize-CpExrPTA.js +1 -0
- package/dist/assets/volter-sdk-kit-inspection-use-active-inspection-CRPvV320.js +1 -0
- package/dist/assets/volter-sdk-kit-inspector-presentation-BFfpxT4_.js +1 -0
- package/dist/assets/volter-sdk-kit-inspector-property-grouping-o7vgYhKg.js +1 -0
- package/dist/assets/volter-sdk-kit-inspector-section-registry-R5_0mSBl.js +1 -0
- package/dist/assets/volter-sdk-kit-instance-source-actions-B0lePqHO.js +1 -0
- package/dist/assets/volter-sdk-kit-js-heap-BpRVEyaI.js +1 -0
- package/dist/assets/volter-sdk-kit-key-actions-BEL1ou9N.js +1 -0
- package/dist/assets/volter-sdk-kit-keymap-presets-Qdpmq1MJ.js +1 -0
- package/dist/assets/volter-sdk-kit-layout-policy-CoLfPtzo.js +1 -0
- package/dist/assets/volter-sdk-kit-light-explorer-model-lqJF5X7X.js +1 -0
- package/dist/assets/volter-sdk-kit-live-canvas-frame-DdlhSZOw.js +1 -0
- package/dist/assets/volter-sdk-kit-live-document-MPCQkIxv.js +1 -0
- package/dist/assets/volter-sdk-kit-live-gesture-lock-BGiQikS-.js +1 -0
- package/dist/assets/volter-sdk-kit-live-seam-evidence-HsOKXOM-.js +1 -0
- package/dist/assets/volter-sdk-kit-live-session-registry-DPshp-zS.js +1 -0
- package/dist/assets/volter-sdk-kit-live-transition-SzISwcSc.js +1 -0
- package/dist/assets/volter-sdk-kit-manifest-project-BaQmD3cM.js +1 -0
- package/dist/assets/volter-sdk-kit-module-fetch-diagnosis-DVmHXvNS.js +1 -0
- package/dist/assets/volter-sdk-kit-mount-failure-report-Dk4LNPuk.js +1 -0
- package/dist/assets/volter-sdk-kit-native-selection-style-Bz3kzLsL.js +1 -0
- package/dist/assets/volter-sdk-kit-object3d-document-write-policy-yZfQc3Ch.js +1 -0
- package/dist/assets/volter-sdk-kit-packaged-runtime-Bofk4pL5.js +1 -0
- package/dist/assets/volter-sdk-kit-performance-profiler-BCQbvJC2.js +1 -0
- package/dist/assets/volter-sdk-kit-performance-sources-DmFnsOyy.js +1 -0
- package/dist/assets/volter-sdk-kit-photograph-notice-Ba8RTcKf.js +1 -0
- package/dist/assets/volter-sdk-kit-play-boot-phase-BtZNGfEm.js +1 -0
- package/dist/assets/volter-sdk-kit-play-camera-flight-DyDq7TW9.js +1 -0
- package/dist/assets/volter-sdk-kit-presentation-surface-CcUgETps.js +1 -0
- package/dist/assets/volter-sdk-kit-product-command-CTGtMf--.js +1 -0
- package/dist/assets/volter-sdk-kit-project-adapter-CncSm07i.js +1 -0
- package/dist/assets/volter-sdk-kit-project-asset-refresh-ff5GvzjI.js +1 -0
- package/dist/assets/volter-sdk-kit-project-asset-roots-2I55e0Tl.js +1 -0
- package/dist/assets/volter-sdk-kit-project-local-state-CoOxczZf.js +1 -0
- package/dist/assets/volter-sdk-kit-project-manager-CXwXszeS.js +1 -0
- package/dist/assets/volter-sdk-kit-project-module-changes-Df7bwGJA.js +1 -0
- package/dist/assets/volter-sdk-kit-project-module-split-CoOXmcMq.js +1 -0
- package/dist/assets/volter-sdk-kit-project-provenance-CsWz3dFr.js +1 -0
- package/dist/assets/volter-sdk-kit-project-ready-CEngokqw.js +1 -0
- package/dist/assets/volter-sdk-kit-project-shape-Bnk7IlEF.js +1 -0
- package/dist/assets/volter-sdk-kit-project-tools-CIrlsLd2.js +1 -0
- package/dist/assets/volter-sdk-kit-readiness-8iK1xUw-.js +1 -0
- package/dist/assets/volter-sdk-kit-renderer-resource-counts-BRlynwAB.js +1 -0
- package/dist/assets/volter-sdk-kit-reported-play-state-CdpNf7iS.js +1 -0
- package/dist/assets/volter-sdk-kit-resolve-contributed-command-CAPTMDEe.js +1 -0
- package/dist/assets/volter-sdk-kit-resolve-relative-specifier-CQavCIRh.js +1 -0
- package/dist/assets/volter-sdk-kit-retained-document-states-CkXz8CLe.js +1 -0
- package/dist/assets/volter-sdk-kit-scene-document-plan-C29w0uq_.js +1 -0
- package/dist/assets/volter-sdk-kit-scene-live-open-fodeYzCv.js +1 -0
- package/dist/assets/volter-sdk-kit-scoped-game-css-C2WRruBw.js +1 -0
- package/dist/assets/volter-sdk-kit-served-url-C17qOcC3.js +1 -0
- package/dist/assets/volter-sdk-kit-session-close-BKSX8DPi.js +1 -0
- package/dist/assets/volter-sdk-kit-session-tombstone-CQ1abA0T.js +1 -0
- package/dist/assets/volter-sdk-kit-settings-settings-provider-Drp8Ja5S.js +1 -0
- package/dist/assets/volter-sdk-kit-settings-store-DVv602rH.js +1 -0
- package/dist/assets/volter-sdk-kit-shell-store-Dwkc4LeK.js +1 -0
- package/dist/assets/volter-sdk-kit-shell-store-door-D6VAgShZ.js +1 -0
- package/dist/assets/volter-sdk-kit-source-conflict-BsgmQDuR.js +1 -0
- package/dist/assets/volter-sdk-kit-stage-context-CF3ATuJX.js +1 -0
- package/dist/assets/volter-sdk-kit-stage-invalidation-D1EKNjPS.js +1 -0
- package/dist/assets/volter-sdk-kit-stage-store-registry-DMqC8KJA.js +1 -0
- package/dist/assets/volter-sdk-kit-startup-failure-CJjXtSxT.js +1 -0
- package/dist/assets/volter-sdk-kit-state-report-deferral-BZ1Gll2x.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-host-files-storage-BeBBCrF4.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-http-storage-DMwE4aCU.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-index-85BJsCgw.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-mem-storage-Cp5EThww.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-path-lock-BEHmTQkG.js +1 -0
- package/dist/assets/volter-sdk-kit-storage-paths-GkBBUtDn.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-StoryPreviewMount-D07t88Iu.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-compose-project-stories-BAw1haKj.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-prefabs-finder-EMDMwLXg.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-prefabs-from-stories-CEQekPVJ.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-project-story-regions-m9-rTkrt.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-scope-PLybjgWr.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-capture-B3uLpufo.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-declared-medium-D92bJmIo.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-discovery-DtaxRT_i.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-dom-runtime-BjR7PW3K.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-grouping-BibwARwc.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-presentation-DaweRLV-.js +1 -0
- package/dist/assets/volter-sdk-kit-stories-story-registry-BuTw7T27.js +1 -0
- package/dist/assets/volter-sdk-kit-story-document-openers-COzuCirA.js +1 -0
- package/dist/assets/volter-sdk-kit-story-thumbnails-DsLqdnDq.js +1 -0
- package/dist/assets/volter-sdk-kit-surface-keyboard-RiClmb_a.js +1 -0
- package/dist/assets/volter-sdk-kit-surface-state-DjeLKyCd.js +1 -0
- package/dist/assets/volter-sdk-kit-system-seam-evidence-omzWuzNM.js +1 -0
- package/dist/assets/volter-sdk-kit-tab-census-C8mQ0l9z.js +1 -0
- package/dist/assets/volter-sdk-kit-tab-lifecycle-client-28DSypwI.js +1 -0
- package/dist/assets/volter-sdk-kit-theme-library-DCToyXQ0.js +1 -0
- package/dist/assets/volter-sdk-kit-theme-preference-Dc-_5b1n.js +1 -0
- package/dist/assets/volter-sdk-kit-three-viewport-presentation-1LxA9rSc.js +1 -0
- package/dist/assets/volter-sdk-kit-tool-contribution-play--JvesPkN.js +1 -0
- package/dist/assets/volter-sdk-kit-tool-loader-LTQw0aL4.js +1 -0
- package/dist/assets/volter-sdk-kit-transform-mode-request-BY9JxShG.js +1 -0
- package/dist/assets/volter-sdk-kit-transient-hint-CM0bpYj2.js +1 -0
- package/dist/assets/volter-sdk-kit-transport-strip-5bUygAkv.js +1 -0
- package/dist/assets/volter-sdk-kit-ui-source-file-region-resolver-CQMWmqhP.js +1 -0
- package/dist/assets/volter-sdk-kit-ui-source-inspect-CfayTFdC.js +1 -0
- package/dist/assets/volter-sdk-kit-ui-source-source-write-backend-DzQseyn4.js +1 -0
- package/dist/assets/volter-sdk-kit-ui-source-tier-source-write-backend-3NgYZbUE.js +1 -0
- package/dist/assets/volter-sdk-kit-user-local-state-BZf1C-cO.js +1 -0
- package/dist/assets/volter-sdk-kit-viewport-activation-timings-C-7ETz2q.js +1 -0
- package/dist/assets/volter-sdk-kit-viewport-editor-controls-f4cwlOWa.js +1 -0
- package/dist/assets/volter-sdk-kit-viewport-presentation-Il1TLCMT.js +1 -0
- package/dist/assets/volter-sdk-kit-viewport-surface-status-CXyJJGil.js +1 -0
- package/dist/assets/volter-sdk-kit-wait-until-D3i87ehY.js +1 -0
- package/dist/assets/volter-sdk-kit-worker-call-metrics-DAK8SW-7.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-areas-DxhakPE3.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-aux-commands-j3FyV7Rh.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-available-documents-DS5ZkDU4.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-core-utilities-BbuDHrHq.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-document-ids-Bm3qMqdx.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-document-registry-CfkdJLBO.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-document-restore-BqBMoUhE.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-host-commands-BC-mYI2s.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-persistence-gate-CN-Z9G7V.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-play-utilities-C5iNgpyt.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-presets-B6MKS0jx.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-regions-DZevxGmg.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-static-panels-CUVjETSY.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-status-registry-Cim_nGuV.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-storage-B9Vf07gg.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-style-yCExFcBd.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-utility-commands-C3a_TCq8.js +1 -0
- package/dist/assets/volter-sdk-kit-workspace-utility-registry-CmYswBtf.js +1 -0
- package/dist/assets/volter-sdk-kit-world-adoption-1Q7uBdLI.js +1 -0
- package/dist/assets/volter-sdk-kit-world-canvas-viewport-state-DaZzYmQU.js +1 -0
- package/dist/assets/volter-sdk-kit-world-document-routing-d9K0XNhN.js +1 -0
- package/dist/assets/volter-sdk-kit-world-pan-state-Bui5iuls.js +1 -0
- package/dist/assets/volter-sdk-kit-write-pipe-BMOSwffA.js +1 -0
- package/dist/assets/volter-sdk-layout-arrangements-DMEnPpvu.js +1 -0
- package/dist/assets/volter-sdk-layouts-DKIqaCd4.js +1 -0
- package/dist/assets/volter-sdk-selection-DM8JuNxQ.js +1 -0
- package/dist/assets/volter-sdk-session-command-table-G119qBvl.js +1 -0
- package/dist/assets/volter-sdk-session-editor-brand-DCHKPDxT.js +1 -0
- package/dist/assets/volter-sdk-session-editor-compatibility-B165I_B1.js +1 -0
- package/dist/assets/volter-sdk-session-editor-control-protocol-DwV-576_.js +1 -0
- package/dist/assets/volter-sdk-session-entrypoint-selection-readers-D88QrS-p.js +1 -0
- package/dist/assets/volter-sdk-session-game-css-scope-UkCRVi6L.js +1 -0
- package/dist/assets/volter-sdk-session-project-module-url-B49W1ltn.js +1 -0
- package/dist/assets/volter-sdk-session-relative-path-guard-Bk6lCH4Z.js +1 -0
- package/dist/assets/volter-sdk-session-tool-contribution-convention-QXzdw52f.js +1 -0
- package/dist/assets/volter-sdk-types-yKC1STwH.js +1 -0
- package/dist/assets/volter-sdk-views-CLPSu14j.js +1 -0
- package/dist/assets/volter-sdk-widgets-design-system-842xdooz.js +1 -0
- package/dist/assets/volter-sdk-widgets-editor-appearance-CoihkoDV.js +1 -0
- package/dist/assets/volter-sdk-widgets-editor-material-B4PbVOyD.js +1 -0
- package/dist/assets/volter-sdk-widgets-icon-set-registry-DzBkVTxs.js +1 -0
- package/dist/assets/volter-sdk-widgets-index-DRlEnpTD.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-AlignmentGrid-DKC7RjtF.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-AssetSlotPicker-CGyznIv-.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-BorderEditor-C74QsfSH.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-ColorPicker-Czwcm_Fi.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-CurveEditor-Tij7lXpB.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-FilterEditor-CY45gPqT.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-FontPicker-BnGlrZAL.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-GradientEditor-uN_3-0Hz.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-ScrubbableInput-kk1HfmXA.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-ShadowEditor-OuqeQbiU.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-color-utils-BArl9zsg.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-curve-utils-C9xyDCr6.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-index-DCEai530.js +1 -0
- package/dist/assets/volter-sdk-widgets-inspector-widgets-shared-CJSGOgSm.js +1 -0
- package/dist/assets/volter-sdk-widgets-interactive-edit-scope-6PmN1jnt.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Dialog-CnuLoAXX.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Fields-wFJZE-ci.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-List-DNL6_6To.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-StateSurface-Ih0mzWk7.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Surfaces-07TRSs2c.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Tabs-BKYsTo--.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Toolbar-BxOrCYIs.js +1 -0
- package/dist/assets/volter-sdk-widgets-patterns-Tree-BfYgX2pa.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-AnchoredMenu-BgHf-cYK.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Button-BUrjXrb8.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-ColorInput-BiRkft3M.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-DraftTextInput-B1KK1N_R.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-EditorIcon-CP8wT6d7.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-FormControls-ScHBA1o4.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-HoverPreview-CSS-glOy.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-JsonInput-C0TAVCVh.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Layout-CfLBd5Or.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Menu-C-Wd4QZF.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-NumberInput-sPbmhEcp.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Panel-CssQZiuw.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-SectionHeader-CCbuJZbe.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Text-CnnND9sI.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-ThemeRootPortal-DmN1LfqW.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Tooltip-D9uLAtac.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-Vec3Input-CbkOGVMc.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-banner-tones-D4w8jWDq.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-clamp-to-viewport-DUn6HqOF.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-editor-icons-Dw62jIE_.js +1 -0
- package/dist/assets/volter-sdk-widgets-primitives-panel-header-styles-BsPj50mE.js +1 -0
- package/dist/assets/volter-sdk-widgets-theme-CWND6gaS.js +1 -0
- package/dist/assets/volter-sdk-widgets-z-index-CAROhwsS.js +1 -0
- package/dist/assets/volter-shared-fontawesome-CU2fjApc.js +1 -0
- package/dist/assets/volter-shared-jsx-dev-runtime-CSjBZz-G.js +1 -0
- package/dist/assets/volter-shared-jsx-runtime-BfW1mwnX.js +1 -0
- package/dist/assets/volter-shared-react-B7X6VYnC.js +1 -0
- package/dist/assets/volter-shared-react-dom-DjKMQVYW.js +1 -0
- package/dist/assets/volter-shared-react-dom-client-76WJXUTi.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 } };
|