editor: tile paint and collision strokes are one undo step, no collision option for tiles (visual-only model copy in the build), freed gl buffers and stale pick ids, export level as gltf/glb with textures and vertex colours
This commit is contained in:
1 parent
59531a60b8
commit
2f22a56cec
30 files changed
+1737
-27
No files matched your search
@@ -62,6 +62,20 @@ height Page Up/Down. Painting onto a tile at the same height swaps its model ins
|
||||
copy the vertex colours of a tile with the same model. **Tile swaps** (doors/bridges, WFPC 0x10000):
|
||||
the Tile section shows the swap entry, sets the alternative model from the palette, removes or adds
|
||||
a swap; layer "Tile swap alternatives" draws the alternative model in cyan.
|
||||
One drag is **one undo step** (2026-11-07): paint, erase and swap issue `cmd.Stroke` commands with
|
||||
the gesture's key; `Stroke.mergeWith` concatenates them (a `Batch` only merges commands of the same
|
||||
shape, `DeferredRemove`/`AddNode` never merge). The collision tool's paint/toggle strokes use the
|
||||
same command.
|
||||
|
||||
**No collision (visual only)** (2026-11-07): tile property `noCollision` (Inspector → Build, "No
|
||||
collision"). `WadBuilder.visualOnly` replaces such tiles in the build by copies whose model (and
|
||||
swap models) is a copy without collision polygons (`gen:visual:<model id>`, one per model, appended
|
||||
to TRAK); other tiles of the model keep it. `Tile.worldCollisionPolygons()` is empty for them, so
|
||||
`CollisionIndex`, checks, `FloorFinder`, `Ground` and the death-plane coverage ignore them; the
|
||||
renderer draws them without the collision overlay. Default off = byte-identical builds.
|
||||
In game (apptest :23, `NoCollisionDemo`, TestLevel 6): two walls baked from box brushes into scene
|
||||
tiles, the north one visual only – the llama walks through it, the south one stops it
|
||||
(`img/editor/geo_nocollision_game.jpg`, top row through, bottom row blocked).
|
||||
|
||||
### Collision tool (K)
|
||||
Turns the collision layer on. Hovering highlights the polygon (or, on brushes, the whole face) under
|
||||
@@ -100,6 +114,33 @@ and keeps the placement.
|
||||
(round trip verified: same shape and textures, `img/editor/geo_library_insert.jpg` – right the
|
||||
library tiles, left the re-imported OBJ as a mesh brush).
|
||||
|
||||
### glTF export (File → Export level as glTF…, `editor.tools.gltf`)
|
||||
* `GltfExport.collect(scene, Options(objects, gameView), skip)` runs a private `SceneRenderer` on the
|
||||
scene and takes exactly what the viewport draws: tile instances (scene tiles + compiled brushes and
|
||||
meshes), optionally object models; `excluded` tiles and (option) hidden nodes are skipped.
|
||||
Vertices are baked to world (export) space, deduplicated per primitive; one primitive per
|
||||
page × blend class × double-sided, grouped into the meshes/nodes `level` and `objects`.
|
||||
* Attributes: POSITION (exact min/max), NORMAL (unit; zero vertex normals → face normal; degenerate
|
||||
triangles dropped), TEXCOORD_0 (page-normalised, v = 0 at the top as in glTF), COLOR_0 (u8
|
||||
normalised RGBA = engine vertex colour ×2 clamped × flat/translucent face colour, as the viewport
|
||||
shader). Materials: base colour texture = page PNG (embedded bufferView), `MASK` 0.5 for pages
|
||||
with cut-out pixels, `BLEND` for alpha/additive classes (glTF has no additive), `doubleSided`,
|
||||
`KHR_materials_unlit` (optional extension). u16 indices up to 65535 vertices, else u32.
|
||||
* `.glb` (JSON + BIN chunk) or `.gltf` (one file, buffer as base64 data URI).
|
||||
* Axes: export space (y up, z = −game z) like the OBJ export and the mesh importer, so a round trip
|
||||
through **Import mesh** is exact. **Game orientation** mirrors z (and winding) for viewers – see
|
||||
the open handedness question below.
|
||||
* Verified: `GltfExportTest` (structural validation as the Khronos validator would: GLB header and
|
||||
chunk padding, view/accessor bounds, equal attribute counts, exact POSITION min/max, unit normals,
|
||||
UV range, index range, PNGs decode; .gltf data URI; round trip through `MeshImport` with the same
|
||||
triangle count, bounds, textures and colours; mirrored bounds; objects; excluded tiles; brush box).
|
||||
The official validator (npm) could not be run here (external code not allowed). **Blender 2.9
|
||||
(local install)** imports the village .glb without complaint: meshes `level` 26 355 tris /
|
||||
`objects` 9 684, 16 + 15 materials, 14 images, vertex colours and UVs
|
||||
(`img/editor/geo_gltf_blender.jpg`, Workbench render); the editor's own Import mesh reads it back
|
||||
(26 403 triangles, 16 materials, 15 textured, `img/editor/geo_gltf_export.jpg`).
|
||||
Village: 36 087 triangles with objects, 2.9 MB .glb; without objects 2.1 MB.
|
||||
|
||||
### Checks (Level → Check, Build)
|
||||
Tiles outside the grid; tile models (also compiled brush/mesh tiles) over **8000 vertices**;
|
||||
**overlapping** identical tiles; **no floor collision under the player start** (cell-based like the
|
||||
@@ -156,9 +197,16 @@ between neighbouring floors at the same height; brush compiler warnings.
|
||||
|
||||
## Known limits
|
||||
* Collision materials of brushes are per face class, not per individual polygon; tile models per
|
||||
polygon. Collision of tile-model polygons cannot be switched off (paint 30 or hide the tile).
|
||||
polygon. Collision of a whole tile can be switched off ("No collision"), single tile-model polygons cannot.
|
||||
* Water and death planes are cell based: resize/move/90° only. Gaps check only unrotated
|
||||
box/platform/floor tops.
|
||||
* Library insert keeps tiles cell-aligned (anchor = whole cells); objects are not part of the library
|
||||
(see the objects agent's prefabs / object catalogue). glTF export not done (OBJ only).
|
||||
(see the objects agent's prefabs / object catalogue).
|
||||
* glTF export: whole level only (no "selection" variant), no collision export (the OBJ export has it),
|
||||
no texture animations, additive surfaces become plain alpha blending. **Handedness**: the editor
|
||||
view is left-handed like the game (editor-render.md), but the mesh importer and the OBJ/glTF
|
||||
exports treat file coordinates as export space – so a right-handed tool (Blender) shows exported
|
||||
levels mirrored relative to the game, and an asymmetric model imported from Blender probably
|
||||
appears mirrored in game. Not verified in game; "Game orientation" in the glTF export is the
|
||||
workaround for viewing.
|
||||
* `TextureImport` packs imported textures at one size per insert (largest texture, ≤ 256).
|
||||
Reference in new issue
Block a user