Fix editor regressions and add Blender scene and animated material import

This commit is contained in:
emil28092005
2026-09-12 00:53:20 +03:00
parent 1a0bf725fa
commit 6f497d1977
34 changed files with 1241 additions and 213 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ Forma supports fixed orthographic scenes that combine 3D geometry and transparen
An entity can have `camera: { mode: "fixed", lookAt: [0, 0, 0], projection: "orthographic", orthoWidth: 24, aspect: 16 / 9 }`. The camera uses the entity's world position, faces `lookAt`, and preserves the specified aspect ratio with letterboxing. Omit `aspect` to fill the current viewport. The inspector exposes fixed mode, projection, width and look-at position. Perspective and follow/first-person cameras remain supported.
`settings.rendering` accepts `toneMapping`, `exposure` and `contrast`. Disabling tone mapping is useful for artwork that already contains lighting. Generated mesh materials accept `unlit`, `alpha` (0–1) and `doubleSided`; scripts can update them through `api.patch`. Imported GLB materials retain their authoring settings unless a material override is requested.
`settings.rendering` accepts `toneMapping`, `exposure`, `contrast` and `defaultLights`. Set `defaultLights: false` to use only authored lights, for example in an imported Blender scene. Disabling tone mapping is useful for artwork that already contains lighting. Generated mesh materials accept `unlit`, `alpha` (0–1) and `doubleSided`; scripts can update them through `api.patch`. Imported GLB materials retain their authoring settings unless a material override is requested.
## Controls
+72 -11
View File
@@ -1,15 +1,76 @@
# Blender and model import
# Blender → Forma
1. Check the model's scale, armature, deformations and animation names.
2. Export **glTF 2.0 → GLB** so geometry and textures travel in one file.
3. Include skinning and the desired animation actions/NLA tracks in the export settings.
4. Use **Импорт GLB** in Forma or drag the file into the editor. Import errors appear in the console.
5. Preview imported animation clips from the animation component. Choose clip names in your project scripts.
6. Add colliders and rigid-body or character components as needed. A model with feet at `y = 0` often needs an upward collider offset.
7. Attach a behaviour to add movement or other interactions. A model alone does not provide game logic.
Forma accepts **GLB**, **glTF with companion files**, and **ZIP containing one GLB/glTF scene and its resources**. Native `.blend` files are converted locally by Blender; the browser does not execute Blender or its node graphs.
Forma imports glTF PBR materials, model textures, skeletons and animation clips. Blender procedural materials and geometry-node workflows do not transfer directly; bake or apply them before export.
Use **Импорт модели** to add an asset to the current scene. Select a glTF and its adjacent `.bin`/images together, or use ZIP to preserve subdirectories. **Открыть сцену Blender** opens a model as a new project, selects the converter's active camera (or the first imported camera) and autoplays its first timeline on Play. If lights are present, Forma's default sun and ambient light are disabled. Undo restores the preceding project. Cameras can be selected in the model entity's Camera component. Internal glTF nodes remain inside the model entity rather than becoming individually editable Forma entities.
Self-contained `.gltf` files with data URIs are supported. External `.bin` and texture file sets are not assembled by the editor; GLB is the simplest portable path. Draco, Meshopt and KTX2-compressed assets are rejected by the current importer to avoid external decoder requirements.
## Direct export
Blender MCP is optional and is not installed by this repository. Forma's `arena` and `character` generators create editable hierarchies; `extrude`, `lathe` and `mesh_create` provide geometry tools without Blender. The compound character generator does not create a rig, and no neural text-to-3D model is bundled.
Requires a Blender glTF exporter with `Animation Pointer` and `Scene` animation support. The integration test was run with **Blender 5.2.1 LTS**. Older versions without those options fail with a diagnostic.
```bash
npm run blender:export -- /path/to/Scene.blend --output ./work/Scene.glb
```
Set `FORMA_BLENDER` or pass `--blender /path/to/blender` if Blender is not on PATH. The command launches a separate background process, disables automatic Python execution and never saves the source `.blend` or touches the open Blender session.
The converter exports the selected Blender scene and its frame range, converts curves/text/surfaces into meshes, applies render-enabled mesh modifiers when there are no shape keys, retains armatures and shape keys, embeds textures, and exports cameras, punctual lights, extras and supported property animation. `--scene NAME` chooses a scene; repeated `--objects 'Name*'` options restrict the objects. Include the rig and other dependencies when exporting a subset.
The converter defaults to Blender's **Unitless** lighting mode (`--lighting compat`), matching Forma's ordinary exposure and avoiding overexposed physical lamps. `--lighting spec` preserves physical glTF light units and requires suitable runtime exposure. When using Blender's own exporter, choose Unitless lighting for the same result.
The exporter emits one sampled scene timeline. It is not an Action/NLA clip library exporter. Alternatively, use Blender's own GLB export to retain separately named Actions, enable Animation Pointer for supported material properties, then select the desired autoplay clip in Forma's Animator component.
## Animated procedural materials
```bash
npm run blender:export -- /path/to/Scene.blend \
--output ./work/Scene.glb --bake-materials \
--resolution 128 --samples 8 \
--start-frame 1 --end-frame 240 --frame-step 4
```
The baker evaluates the material in Cycles at each sampled frame, including supported drivers, image sequences/movie frames and procedural inputs such as Noise, Voronoi, ColorRamp and Bump. It creates per-object UV atlases for base color/alpha, metallic/roughness, tangent-space normals and emission. It adds STEP animation of `KHR_texture_transform` offsets through `KHR_animation_pointer`. Forma plays these animations with the model timeline; pause also pauses materials.
Supported bake surfaces are Principled BSDF and Emission, optionally mixed with one Transparent shader. Existing UVs are used; meshes without UVs get a smart unwrap. Existing overlapping UV islands may produce artifacts and should be unwrapped before baking. Node groups feeding these inputs work through Cycles; arbitrary groups/mixes that produce a surface closure need conversion to a supported surface first. Unsupported closures fail explicitly.
`--resolution` is 16–1024 pixels per frame; `--samples` is 1–256; at most 256 sampled frames and an 8192px atlas edge are allowed. Two-pixel borders and linear filtering without mipmaps prevent adjacent frame bleeding. Smaller frame steps produce smoother animation and larger files. Static procedural materials use one atlas cell. Animated geometry can change a procedural material's appearance even without material drivers; add material animation or bake it explicitly as an animated source before relying on that case.
## Compatibility and limits
| Blender feature | Transfer |
| --- | --- |
| Mesh hierarchy, UVs, textures, transforms, extras | glTF model hierarchy; extras retained |
| Armature, skinning, shape keys | Native glTF, including animation; no retargeting |
| Curves, text, surfaces | Converted to mesh at export |
| Compatible PBR, transparency, normal/emission textures | Native glTF materials |
| Supported material, UV, camera and light keyframes | `KHR_animation_pointer`; independent targets per model instance |
| Noise/Voronoi/ColorRamp/Bump and driver-driven surface inputs | Sampled texture baking for supported surface closures |
| Movie/image sequence inputs | Sampled into atlases; no audio or live video playback |
| Point, spot, sun lights; perspective/orthographic cameras | Native glTF; rendering differs from Cycles/EEVEE |
| Area lights | Optional point-light approximation, listed in report |
| Geometry Nodes and physics simulations | Evaluated start-frame geometry; no live simulation/cache playback |
| Modifiers on meshes with shape keys | Preserved shape keys; unsupported modifier application is reported |
| Volume shaders, World node graphs, compositor, render effects | No equivalent full transfer; use Forma fog/lighting or render baking |
| View-dependent shading, true displacement, baked coat/transmission/thin-film etc. | Reported limitations; base PBR baking cannot reproduce them exactly |
| Arbitrary OSL/Python nodes, custom Python drivers, Blender scripts | No runtime execution in Forma; complex disabled drivers need authoring-side preparation |
The converter writes `Scene.report.json` and embeds warnings in the GLB. Recognized unsupported features stop export by default. Inspect the report and use `--allow-lossy` to accept its listed approximations. This flag does not turn unsupported features into equivalents, and unsupported shader closures can still fail. Always inspect Blender's own exporter log too. A successful export is not a guarantee of pixel-identical Cycles/EEVEE rendering.
Current portable model limit: **25 MiB**, ZIP expansion budget: **80 MiB**. Split large scenes or reduce texture/frame resolution. External resources must be supplied locally inside the import bundle/project directory; network URLs and escaping paths are rejected. Draco, Meshopt and KTX2 are rejected because offline decoders are not bundled.
## MCP
`asset_import_glb` keeps its name for compatibility and accepts `.glb`, `.gltf`, or `.zip`. Supply `base64` or a path inside the Forma project directory. `instantiate: true` adds a model and Animator; `asScene: true` performs an undoable project replacement using imported cameras/lights. The browser editor has the same import pipeline.
## Verification
```bash
npm run build
npm run typecheck
npm test
FORMA_BLENDER=/path/to/blender node --import tsx --test tests/blender.test.ts
```
The optional Blender integration test generates its own scene, exports driver-baked textures, a curve, shape keys, a camera and a light, and verifies that the source file is unchanged. Runtime tests exercise actual material/camera/light/morph animation and instance isolation. The shipped repository contains no personal Blender projects or baked game assets.
Reference: [Blender glTF exporter manual](https://docs.blender.org/manual/en/dev/addons/scene_gltf2.html).
+2 -2
View File
@@ -9,9 +9,9 @@ npm run build
node --import tsx scripts/export-editor.ts PROJECT.forma OUTPUT_DIRECTORY
```
Serve OUTPUT_DIRECTORY over HTTP. The entry point is index.html. It loads project.forma.json and starts Editor with `initialProject` and `browserOnly: true`. No local service probe, MCP token, server-side files or local machine access is included.
Serve OUTPUT_DIRECTORY over HTTP, including from a subdirectory such as `/demo/`. HTML, player and build-template URLs resolve relative to the publication. The entry point is index.html. It loads project.forma.json and starts Editor with `initialProject` and `browserOnly: true`. No local service probe, MCP token, server-side files or local machine access is included.
A valid IndexedDB draft takes priority over the bundled starting project. Each visitor edits their own browser copy. If storage is unavailable or corrupt, startup falls back to the validated bundled project. The project menu exports .forma backups that include the GLB assets and scripts. Imported models are stored as embedded data in the browser draft.
A valid IndexedDB draft for this publication path and bundled project ID takes priority over its starting project. Different publications do not restore each other's drafts; the local editor retains its separate `active` draft. Legacy unscoped hosted drafts are not automatically migrated. Each visitor edits their own browser copy. If storage is unavailable or corrupt, startup falls back to the validated bundled project. The project menu exports .forma backups that include the GLB assets and scripts. Imported models are stored as embedded data in the browser draft.
The build panel defaults to web export when disconnected. Native builds can be downloaded as build kits; direct native compilation and the local MCP service still require the local Forma installation. The exporter includes the player and build-kit resources needed for these downloads.
+7 -2
View File
@@ -701,7 +701,7 @@
},
{
"name": "asset_import_glb",
"description": "Import GLB or embedded glTF using base64 bytes OR a path inside the project folder. External URLs are not fetched.",
"description": "Import GLB, glTF with companion files, or a ZIP containing one model and its textures. Use base64 bytes OR a path inside the project folder. External files resolve only within that folder; network URLs are not fetched.",
"inputSchema": {
"type": "object",
"properties": {
@@ -716,7 +716,7 @@
},
"name": {
"type": "string",
"pattern": "\\.(glb|gltf)$"
"pattern": "\\.(glb|gltf|zip)$"
},
"base64": {
"type": "string",
@@ -728,6 +728,11 @@
"instantiate": {
"default": true,
"type": "boolean"
},
"asScene": {
"description": "Replace the project with the complete imported scene, using its active/first camera and lights. Undoable.",
"default": false,
"type": "boolean"
}
},
"required": [
+12
View File
@@ -16,3 +16,15 @@ The local editor was opened in a desktop browser. Visual checks covered the init
GitHub Actions repeats the clean install, build, type check and test suite on Node.js 22. The build runs before integration tests because they read the generated editor and player bundles.
Native application binaries were not rebuilt for this engine-only package; the tests cover build packaging and orchestration, not real installation on every target device.
## Blender import and regression validation — 2026-09-12
- Build and TypeScript checks pass after the Blender import changes.
- Added regression coverage for parent/child material isolation, nested hosted export URLs, draft namespaces, and shared first-person input handling.
- Generated glTF fixtures exercise skeletal animation, morph targets, material color/alpha/metallic/roughness, perspective and orthographic camera properties, light intensity, autoplay, independent instances and disposal.
- Import tests cover glTF resource ZIPs, missing files, traversal rejection, scene camera/lighting selection, and atomic MCP scene replacement with Undo.
- An optional real Blender 5.2.1 LTS integration test creates a synthetic scene, bakes a procedural material animated by a `frame` driver, converts a curve, exports shape keys/camera/light, checks scene isolation, and verifies unchanged input bytes.
- A local WebGL smoke test used a three-frame bake from an existing procedural material. All four atlas offsets changed together; pause held the frame fixed. The scene rendered in the browser. Personal project files and generated results remain outside Git.
- The exported browser-only editor loaded and ran a generated animated Blender scene under a nested URL.
Full Cycles/EEVEE equivalence, every Blender node type, full user-scene conversion and device-specific performance are not claimed. See [Blender compatibility](BLENDER.md).