editor: readable names in tool status and problem texts, waypoint reference buttons shorten to fit, x/y/z fields stack in a narrow inspector, whole-number outliner filter for tiles, z-buffered mesh import preview, gltf export of the selection only and of collision as a separate mesh

This commit is contained in:
MineTec committed 2026-11-07 13:39:54 +01:00
1 parent d12c642b37
commit 01208aa36f
30 files changed
+840 -100

No files matched your search

+19 -5
View File
@@ -88,7 +88,9 @@ Invisible collision volumes (Invisible wall/block, colliders) are drawn transluc
"Invisible collision volumes").
### Mesh import (File → Import mesh)
File chooser, then a dialog: rotatable preview (shown as in game) with a 1-cell grid and a llama-sized marker, source
File chooser, then a dialog: rotatable preview (shown as in game; flat shading with a small z-buffer at
twice the panel size, `PreviewRaster` – before 2026-11-07 the triangles were sorted by centroid and hidden
faces showed as slivers) with a 1-cell grid and a llama-sized marker, source
info, up axis, unit scale and "fit largest side to n cells", turn, mirror, stand on the ground,
texture size and UV precision, double-sided, lit, collision **from the mesh / simplified invisible
box / none** + material, warnings (densest cell vs. the 8000-vertex limit, larger than the grid).
@@ -117,9 +119,19 @@ and keeps the placement.
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), skip)` runs a private `SceneRenderer` on the
* `GltfExport.collect(scene, Options(objects, collision, only), 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.
* **Selection only** (2026-11-07): `only` = the selected nodes; an instance is exported when its owner
(tile, brush that the compiled tile belongs to, object) is in it. Nothing exportable → status message,
no file.
* **Collision as separate mesh** (2026-11-07): mesh/node `collision` with one primitive per collision
material (`collision_<mat>`, unlit base colour: 0 grey, 16 green, 30 red, others by hue, double-sided,
no UVs). Polygons of scene tiles (`Tile.worldCollisionPolygons`, so "No collision" tiles have none) and of
the compiled brush tiles (`SceneRenderer.brushOutput()`, owner = the brush instance in the same order),
fan-triangulated in game space and wound like the polygon's own plane normal (floors face +y).
`GltfExportTest.selectionOnlyAndCollisionMesh` / `collisionFloorsFaceUp`: validation, box bounds of both
nodes, a single tile's collision ≤ its polygons, round trip through Import mesh, outward box.
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
@@ -140,7 +152,9 @@ and keeps the placement.
(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`).
(26 403 triangles, 16 materials, 15 textured). `img/editor/geo_gltf_export.jpg` (retaken 2026-11-07): export
dialog with the new options and the village exported with **Collision as separate mesh** read back
(45 558 triangles, 25 materials; red = material 30 under the islands), z-buffered preview.
Village: 36 087 triangles with objects, 2.9 MB .glb; without objects 2.1 MB.
### Handedness of files (fix 2026-11-07)
@@ -245,7 +259,7 @@ between neighbouring floors at the same height; brush compiler warnings.
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: whole level only (no "selection" variant), no collision export (the OBJ export has it),
no texture animations, additive surfaces become plain alpha blending. (Handedness: fixed, see
* glTF export: no texture animations, additive surfaces become plain alpha blending; the collision node
has no tile-swap alternatives. (Handedness: fixed, see
"Handedness of files" above.)
* `TextureImport` packs imported textures at one size per insert (largest texture, ≤ 256).
+8
View File
@@ -42,6 +42,13 @@ actions (AWT canvases do not get Swing key bindings).
"Coin 3", status bar hover "Coin 3"/"Tile 41, 66 · Model 87", asset tab "Model 0"); inspector button
rows wrap without clipping in a narrow dock (`ui_waypoint_buttons_narrow.jpg`); long property labels
wrap (`ui_inspector_label_wrap.jpg`).
* Narrow inspector (2026-11-07, `ui_inspector_narrow.jpg`): Position/Rotation X/Y/Z use `AxisLayout`
(one row while each cell gets ≥ 66 px, else stacked one per row; also the brush rotation spinners);
reference buttons (`InspectorPanel.RefButton`) show the longest name that fits ("Waypoint 5 (chain 3)" →
"Waypoint 5" → "#5", other names drop a "(…)" suffix, then "…"), full name + id in the tooltip.
* Tool status and check texts use `NodeNames` too (geometry, tile paint, collision, texture paint,
lights, brush-outside-grid check, "Placed Model 12 in cell …"); the outliner filter applies the
whole-number rule to the old label and the id as well ("tile 3" no longer finds x = 39).
## Architecture
@@ -126,6 +133,7 @@ same id again replaces (panels, tools, actions, asset tabs, layers).
| `LevelCheck` | adds `Problem.error/warning/info(msg, node)`; errors block Build/Play |
| `Icons` | vector icons by name; `Icons.register(name, painter)` for your own (16×16 Java2D); `Icons.swatch(colour, w, h)` |
| `NodeNames` | `NodeNames.name(node)` (one node) or `NodeNames.of(scene)` (index for many: `nameOf`, `objectName`, `waypointName`, `chainStarts`) – use it instead of `Node.label()` in UI texts; tooltips may show `node.id()` |
| `AxisLayout` | public layout for X/Y/Z cells: one row, or stacked when a cell would be narrower than its minimum (`new AxisLayout(AxisLayout.CELL_MIN)`) |
| `WrapLayout` | public `FlowLayout` that grows to more rows in a narrow container (inspector button rows: `ParamsSection.compact` switches a FlowLayout bar to it) |
| `Widgets`, `util.SwingListeners` | `Widgets.button(text, icon, tip, run)`, `Widgets.listCell(c, list, selected)`, `Widgets.wrappingLabel(html)` (help text that wraps at the dock width – use it instead of `<body style='width:…'>`); `onTextChange`, `onMenuOpen` |
| `ErrorDialog` | `ctx.error(title, t)` uses it: plain sentence (`ErrorDialog.plain(t)`, no exception class names) + collapsible **Details** (stack trace) |
Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB