From 2f22a56cec3e0656af1ce060df65f3cef32a5ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Sat, 7 Nov 2026 11:57:22 +0100 Subject: [PATCH] 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 --- docs/manual/06-geometry.md | 12 +- docs/manual/07-meshes.md | 24 +- docs/manual/19-shortcuts.md | 1 + docs/manual/img/geo_gltf_export.jpg | Bin 0 -> 104197 bytes notes/bug-review-editor.md | 12 +- notes/editor-render.md | 16 + notes/editor-tools-geometry.md | 52 +- notes/img/editor/geo_gltf_blender.jpg | Bin 0 -> 21890 bytes notes/img/editor/geo_gltf_export.jpg | Bin 0 -> 104197 bytes notes/img/editor/geo_nocollision_game.jpg | Bin 0 -> 49133 bytes .../llamamod/editor/io/WadBuilder.java | 46 ++ .../llamamod/editor/model/Tile.java | 34 +- .../llamamod/editor/model/cmd/Stroke.java | 64 +++ .../llamamod/editor/render/Batch.java | 6 + .../llamamod/editor/render/GlRenderer.java | 34 ++ .../llamamod/editor/render/Viewport.java | 19 + .../editor/tools/geometry/CollisionTool.java | 9 +- .../editor/tools/geometry/GeoWidgets.java | 3 +- .../editor/tools/geometry/TilePaintTool.java | 15 +- .../editor/tools/gltf/GltfEditorPlugin.java | 111 +++++ .../editor/tools/gltf/GltfExport.java | 465 ++++++++++++++++++ .../editor/ui/view/SceneRenderer.java | 55 +++ .../editor/tools/help/context-help.txt | 1 + .../llamamod/editor/io/NoCollisionDemo.java | 121 +++++ .../editor/io/NoCollisionTilesTest.java | 82 +++ .../llamamod/editor/model/cmd/StrokeTest.java | 83 ++++ .../editor/tools/gltf/GltfExportTest.java | 295 +++++++++++ .../editor/tools/gltf/GltfSample.java | 27 + .../llamamod/editor/ui/view/GlLeakCheck.java | 85 ++++ .../editor/ui/view/SceneRendererIdsTest.java | 92 ++++ 30 files changed, 1737 insertions(+), 27 deletions(-) create mode 100644 docs/manual/img/geo_gltf_export.jpg create mode 100644 notes/img/editor/geo_gltf_blender.jpg create mode 100644 notes/img/editor/geo_gltf_export.jpg create mode 100644 notes/img/editor/geo_nocollision_game.jpg create mode 100644 src/main/java/com/eliasmueller/llamamod/editor/model/cmd/Stroke.java create mode 100644 src/main/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfEditorPlugin.java create mode 100644 src/main/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfExport.java create mode 100644 src/test/java/com/eliasmueller/llamamod/editor/io/NoCollisionDemo.java create mode 100644 src/test/java/com/eliasmueller/llamamod/editor/io/NoCollisionTilesTest.java create mode 100644 src/test/java/com/eliasmueller/llamamod/editor/model/cmd/StrokeTest.java create mode 100644 src/test/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfExportTest.java create mode 100644 src/test/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfSample.java create mode 100644 src/test/java/com/eliasmueller/llamamod/editor/ui/view/GlLeakCheck.java create mode 100644 src/test/java/com/eliasmueller/llamamod/editor/ui/view/SceneRendererIdsTest.java diff --git a/docs/manual/06-geometry.md b/docs/manual/06-geometry.md index 716705d..be079ef 100644 --- a/docs/manual/06-geometry.md +++ b/docs/manual/06-geometry.md @@ -267,6 +267,8 @@ used in the level** hides unused ones. Click a model to make it the current one, Painting onto a tile at the same height **swaps its model** instead of stacking a second tile. New tiles copy the vertex colours of an existing tile with the same model. +One drag is one undo step: **Ctrl+Z** brings back all tiles a stroke painted over, erased or swapped. + > **Tip:** Prefer swapping, moving or hiding original tiles over erasing them. Object scripts can > address tiles by their number, and erasing a tile shifts the numbers of all later tiles. The > status bar warns you when you erase an original tile. @@ -326,7 +328,15 @@ change all tiles** (paint the model, every tile using it changes) or **Shared mo this tile** (the painted tile gets its own copy of the model first). Brushes have one material per face class (top, sides, bottom); tile models are painted per -polygon. Tile collision cannot be switched off – paint it 30 or hide the tile instead. +polygon. A painting drag is one undo step. + +### Tiles without collision + +To make a tile only visual, select it and tick **No collision** (Inspector, section **Build**; works +for several selected tiles at once). The built level then uses a copy of the tile's model without +collision polygons: the llama walks through the tile (a wall) or falls through it (a floor). Other +tiles of the same model keep their collision. In the editor the tile no longer shows collision +lines, and checks such as "no floor under the player start" ignore it. The layer **Invisible collision volumes** draws invisible walls, invisible blocks and colliders translucent red so you can see them while editing. diff --git a/docs/manual/07-meshes.md b/docs/manual/07-meshes.md index 7aab96b..7ad1ca4 100644 --- a/docs/manual/07-meshes.md +++ b/docs/manual/07-meshes.md @@ -7,7 +7,7 @@ collision and lit vertex colours, and its textures are packed onto texture pages The **library** works the other way round: it saves geometry from any level (original tiles, brushes and meshes, with their textures) so you can insert it into other levels. And **Export -selection as OBJ** takes level geometry to Blender. +selection as OBJ** takes level geometry to Blender, **Export level as glTF** the whole level. ## Supported files @@ -178,6 +178,28 @@ it in Blender, then **File → Import mesh** it back (round trip). > **Note:** The exported textures are game data – fine for your own editing, please don't share > them. +## Export the level as glTF + +**File → Export level as glTF…** writes the whole level – tiles, brushes and meshes – as one glTF +2.0 file for Blender or any 3D viewer: + +* **.glb** (binary) or **.gltf** (text, everything in one file), chosen by the file type, +* the level's texture pages as PNG pictures inside the file, the game's vertex colours + (light and shade) as vertex colours, transparent and double-sided parts as such, +* unlit materials, so viewers show the baked colours like the game. + +| Option | Meaning | +|---|---| +| **Object models** | also the models of placed objects (coins, characters …) as the viewport shows them | +| **Leave out hidden items** | items hidden in the editor (**H**) are not exported | +| **Game orientation** | mirrors the level so that Blender and viewers show it the same way round as the game. Off: the same axes as the OBJ export and **Import mesh**, so the file can be imported again unchanged | + +Tiles with **Exclude from build** are left out. 1 unit is 1 cell. + +![glTF export dialog and the exported village read back by Import mesh](img/geo_gltf_export.jpg) + +> **Note:** The exported textures are game data – fine for your own use, please don't share them. + ## Tips for good meshes * Model at the right scale: 1 cell is one grid square, the llama is about 0.6 cells tall. Use diff --git a/docs/manual/19-shortcuts.md b/docs/manual/19-shortcuts.md index d8eac34..ced0d32 100644 --- a/docs/manual/19-shortcuts.md +++ b/docs/manual/19-shortcuts.md @@ -157,6 +157,7 @@ Every menu command with its shortcut and a short description. | Import texture… | | Import PNG/JPG images as textures (colour reduction, blend class, packing) | | Export level WAD… | | Build the level and save the game file (.wad) somewhere | | Export selection as OBJ… | | Mesh, UVs, vertex colours, textures (PNG) and collision for Blender | +| Export level as glTF… | | The whole level with textures and vertex colours as .glb / .gltf (Blender, viewers) | | Close editor | **Ctrl+Q** | Close the editor | ### Edit menu diff --git a/docs/manual/img/geo_gltf_export.jpg b/docs/manual/img/geo_gltf_export.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0b81f9b0c666eae59b86de5ea88f71e18396ba18 GIT binary patch literal 104197 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

!K8bTwiLut&g^Qo%tQ^{S)x$j)#J= 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

%{Td@~5-e$$RH&7Hu6#zeYx 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 literal 0 HcmV?d00001 diff --git a/notes/bug-review-editor.md b/notes/bug-review-editor.md index 2808a93..fca6853 100644 --- a/notes/bug-review-editor.md +++ b/notes/bug-review-editor.md @@ -45,11 +45,13 @@ undo/history, project IO, build, play-test; property/fuzz tests; stress run of t ## Not fixed (reasons) -* Damaged-file dialogs show raw exception text ("ClassCastException …"); cosmetic, left to the UX review. -* After a failed open, the status bar keeps "Loading " (`StatusBar.progressDone` keeps the last message) – cosmetic (UX). -* `GlRenderer.dispose()` does not delete `dynVao`/`dynVbo` (only at window close) – negligible. -* `SceneRenderer.ids`/`nodes` keep pick ids of deleted nodes until the next level (small, bounded by edits). -* Tile-paint erase strokes are one undo step per tile (`DeferredRemove` has no merge) – UX, not a defect. +* ~~Damaged-file dialogs show raw exception text~~ – fixed 2026-11-07 (edui): `ErrorDialog` (all `ctx.error` calls) shows one + plain sentence ("The project file is damaged.", "The file x does not exist.") and the exception + stack trace behind **Details**. +* ~~After a failed open, the status bar keeps "Loading "~~ – fixed 2026-11-07 (edui): a failed background task sets + " failed"; EditorStress `corrupt` now fails if the status still says "Loading…". +* ~~`GlRenderer.dispose()` does not delete `dynVao`/`dynVbo`~~ – fixed 2026-11-07 (edgeo), see editor-render.md. +* ~~`SceneRenderer.ids`/`nodes` keep pick ids of deleted nodes~~ – fixed 2026-11-07 (edgeo): dropped every 256 removals. +* ~~Tile-paint erase strokes are one undo step per tile~~ – fixed 2026-11-07 (edgeo): `cmd.Stroke`, one step per drag. * `installTarget` treats a file with the same kind/base/level name as the previous play-test copy; two different projects with the same level name and base still share one file (rare; renaming one avoids it). * `LevelProjectSource`: when all TestLevel chapters 2..49 are taken, the 49th is used twice – practically unreachable. diff --git a/notes/editor-render.md b/notes/editor-render.md index 0a329ea..1db9526 100644 --- a/notes/editor-render.md +++ b/notes/editor-render.md @@ -277,6 +277,22 @@ behind: game look / editor). (Ranges: several agents shared the CPU.) Scene conversion from WAD 160–290 ms. On any real GPU this is far below 1 ms of GPU time; the CPU side is ~150 draw calls per frame. +## GPU resources (2026-11-07) + +* `GlRenderer.dispose()` frees everything it created: batches, texture array, pick FBO, programs and + the dynamic `dynVao`/`dynVbo` (gizmo, overlays). +* Chunks that lose their last member are deleted with their batch (before: an empty chunk kept a + `Chunk` entry until the next full rebuild). Shared per-mesh batches (`meshBatches`, objects and + tiles without vertex colours) whose mesh no instance uses any more are freed once there are more + than 256 (limit doubles with the live count) – replaced meshes used to stay until a level switch. +* `Viewport.liveGlBuffers()` counts live VAO/VBO pairs of all batches (diagnostics). + `ui.view.GlLeakCheck` (test sources, X display): 3 rounds over Village 1 / world 4 / Village 2, each + load followed by 60 rounds of tile moves, object moves, delete + undo while rendering → the count + is identical per level in every round (84 / 87 / 76), 0 with no level loaded. +* `SceneRenderer` drops the pick ids of nodes that are no longer in the scene every 256 removals + (nodes that come back by undo get a new id; selected nodes keep theirs) – `SceneRendererIdsTest`. + Tiles marked "no collision" use a copy of their model mesh without the collision overlay. + ## Known limits / next steps * Only the first vertex colour frame and the primary tile model (no alt/swap models). diff --git a/notes/editor-tools-geometry.md b/notes/editor-tools-geometry.md index 12beb4f..dbf1060 100644 --- a/notes/editor-tools-geometry.md +++ b/notes/editor-tools-geometry.md @@ -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:`, 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). diff --git a/notes/img/editor/geo_gltf_blender.jpg b/notes/img/editor/geo_gltf_blender.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f21eda1f0d7ff795916de96912fd256cfbed5e41 GIT binary patch literal 21890 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Ū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 dtfA_I=s`rv2hsCE^ne%k{{_gom#H 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

!K8bTwiLut&g^Qo%tQ^{S)x$j)#J= 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

%{Td@~5-e$$RH&7Hu6#zeYx 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 literal 0 HcmV?d00001 diff --git a/notes/img/editor/geo_nocollision_game.jpg b/notes/img/editor/geo_nocollision_game.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1195e9750a9e94f48b300d8ed81b8079aa485101 GIT binary patch literal 49133 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 literal 0 HcmV?d00001 diff --git a/src/main/java/com/eliasmueller/llamamod/editor/io/WadBuilder.java b/src/main/java/com/eliasmueller/llamamod/editor/io/WadBuilder.java index c5bb1ba..36e5e83 100644 --- a/src/main/java/com/eliasmueller/llamamod/editor/io/WadBuilder.java +++ b/src/main/java/com/eliasmueller/llamamod/editor/io/WadBuilder.java @@ -1,5 +1,7 @@ package com.eliasmueller.llamamod.editor.io; +import com.eliasmueller.llamamod.editor.model.Node; +import com.eliasmueller.llamamod.editor.model.Prop; import com.eliasmueller.llamamod.editor.model.RawChunk; import com.eliasmueller.llamamod.editor.model.Scene; import com.eliasmueller.llamamod.editor.model.TextureEntry; @@ -9,7 +11,10 @@ import com.eliasmueller.llamamod.editor.model.TileModel; import com.eliasmueller.llamamod.format.Level; import com.eliasmueller.llamamod.format.Wad; import java.util.ArrayList; +import java.util.IdentityHashMap; import java.util.List; +import java.util.Map; +import java.util.function.Function; /** * Scene → level WAD. Brushes and mesh placements are converted to tiles ({@link BrushCompiler}) @@ -48,6 +53,7 @@ public final class WadBuilder { models.addAll(gen.models()); List tiles = new ArrayList<>(s.tiles().stream().filter(t -> !t.excluded()).toList()); + visualOnly(tiles, models); tiles.addAll(gen.tiles()); List pages = new ArrayList<>(s.pages()); pages.addAll(gen.pages()); @@ -92,6 +98,46 @@ public final class WadBuilder { return new Result(wad, st, warn); } + /** + * Tiles marked "no collision" get a copy of their model (and swap models) without collision + * polygons, appended to models; one copy per model. + */ + static void visualOnly(List tiles, List models) { + Map copies = new IdentityHashMap<>(); + Function strip = m -> m == null + ? null + : copies.computeIfAbsent(m, k -> { + TileModel c = copy(new TileModel("gen:visual:" + k.id()), k); + for (int g = 0; g < 3; g++) { + c.setRaw(TileModel.collisionProp(g), new byte[0]); + } + models.add(c); + return c; + }); + for (int i = 0; i < tiles.size(); i++) { + Tile t = tiles.get(i); + if (t.noCollision() && t.model() != null) { + Tile c = copy(new Tile(t.id()), t); + c.setRaw("model", strip.apply(t.model())); + if (t.hasSwap()) { + c.setRaw("swapModel", strip.apply(t.swapModel())); + c.setRaw("swapAltModel", strip.apply(t.swapAltModel())); + } + tiles.set(i, c); + } + } + } + + /** Copies every property in declaration order (later raw values such as headers survive setters). */ + private static N copy(N to, N from) { + for (Prop p : from.props()) { + if (p.settable()) { + to.setRaw(p.name(), from.get(p.name())); + } + } + return to; + } + private static byte[] name(Scene s, RawChunk c) { String n = s.settings().levelName(); if (c.managed()) { diff --git a/src/main/java/com/eliasmueller/llamamod/editor/model/Tile.java b/src/main/java/com/eliasmueller/llamamod/editor/model/Tile.java index 16c0e9e..f4903b1 100644 --- a/src/main/java/com/eliasmueller/llamamod/editor/model/Tile.java +++ b/src/main/java/com/eliasmueller/llamamod/editor/model/Tile.java @@ -6,8 +6,8 @@ import java.util.List; /** * Placed tile (MAP): a {@link TileModel} at (x, y, z) in export space (cells; z ≤ 0, game z = −z) - * turned by {@code rot}/4096 turns about y. The tile belongs to grid cell (floor(x), floor(−z)); the - * engine tests collision only against the tiles of the player's cell. + * turned by {@code rot}/4096 turns about y. The tile belongs to the grid cell of its origin, see + * {@link #cellX()}; the engine tests collision only against the tiles of the player's cell. * *

Vertex colours: {@code colors} holds frames × vertexCount(model) RGBA words (0x80 = 1.0, the * engine doubles them); byte 3 of the first word is the frame count (0/1 = one frame). A tile with @@ -30,6 +30,7 @@ public final class Tile extends Node { TileModel swapAltModel; int[] altColors; boolean excluded; + boolean noCollision; private static final List PROPS = new Props() .group("Transform") @@ -86,6 +87,14 @@ public final class Tile extends Node { b -> b.desc( "the tile stays in the project but is left out of the built level (Hide only affects the" + " editor view)")) + .p( + "noCollision", + "No collision", + PropType.BOOL, + n -> n.noCollision, + (n, v) -> n.noCollision = v, + b -> b.desc("the built level gets this tile without collision polygons: the llama walks" + + " through it")) .group("Colours") .ints("colors", "Vertex colours (frames × vertices)", n -> n.colors, (n, v) -> n.colors = v) .p( @@ -131,6 +140,11 @@ public final class Tile extends Node { return excluded; } + /** True when the tile is only visual: the build writes it with a model copy without collision. */ + public boolean noCollision() { + return noCollision; + } + public double x() { return x; } @@ -194,14 +208,18 @@ public final class Tile extends Node { || swapAltModel != null && swapAltModel.hasCollisionMaterial(material)); } - /** Grid column, like MAP's cell lists (floor(x)). */ + /** + * Grid column of the MAP cell list the engine puts the tile in: the loader (FUN_0042ac50) takes + * ftol(x − 0.5), truncating; = floor(x) for the usual cell-centred tiles (x = n + 0.5), one cell + * less for a tile whose origin is in the left half of a cell. + */ public int cellX() { - return (int) Math.floor(x); + return (int) (x - 0.5); } - /** Grid row (floor(−z)). */ + /** Grid row: −ftol(z + 0.5) (export z ≤ 0); = floor(−z) for cell-centred tiles. */ public int cellZ() { - return (int) Math.floor(-z); + return -(int) (z + 0.5); } /** Fixed-point placement the engine uses: stored value or derived from x, y, z, rot. */ @@ -220,9 +238,9 @@ public final class Tile extends Node { }; } - /** Collision polygons of the model in world export space (none without a model). */ + /** Collision polygons of the model in world export space (none without a model or with {@link #noCollision}). */ public List worldCollisionPolygons() { - return model == null ? List.of() : model.collisionPolygons(transform()); + return model == null || noCollision ? List.of() : model.collisionPolygons(transform()); } /** Local (export space) vertex → world (export space). */ diff --git a/src/main/java/com/eliasmueller/llamamod/editor/model/cmd/Stroke.java b/src/main/java/com/eliasmueller/llamamod/editor/model/cmd/Stroke.java new file mode 100644 index 0000000..9f76258 --- /dev/null +++ b/src/main/java/com/eliasmueller/llamamod/editor/model/cmd/Stroke.java @@ -0,0 +1,64 @@ +package com.eliasmueller.llamamod.editor.model.cmd; + +import com.eliasmueller.llamamod.editor.model.Scene; +import java.util.ArrayList; +import java.util.List; + +/** + * One step of a paint/erase stroke: consecutive strokes with the same key are concatenated into + * one undo step (unlike {@link Batch}, whose merge needs commands of the same shape). + */ +public final class Stroke implements Command { + private final String label; + private final List commands; + private final Object key; + + public Stroke(String label, Command c, Object key) { + this(label, List.of(c), key); + } + + private Stroke(String label, List commands, Object key) { + this.label = label; + this.commands = commands; + this.key = key; + } + + public List commands() { + return commands; + } + + @Override + public String label() { + return label; + } + + @Override + public void apply(Scene s) { + for (Command c : commands) { + c.apply(s); + } + } + + @Override + public void revert(Scene s) { + for (int i = commands.size() - 1; i >= 0; i--) { + commands.get(i).revert(s); + } + } + + @Override + public Object mergeKey() { + return key; + } + + @Override + public Command mergeWith(Command next) { + if (!(next instanceof Stroke o) || key == null || !key.equals(o.key)) { + return null; + } + List l = new ArrayList<>(commands.size() + o.commands.size()); + l.addAll(commands); + l.addAll(o.commands); + return new Stroke(label, l, key); + } +} diff --git a/src/main/java/com/eliasmueller/llamamod/editor/render/Batch.java b/src/main/java/com/eliasmueller/llamamod/editor/render/Batch.java index 479472b..ade2fc1 100644 --- a/src/main/java/com/eliasmueller/llamamod/editor/render/Batch.java +++ b/src/main/java/com/eliasmueller/llamamod/editor/render/Batch.java @@ -15,6 +15,8 @@ final class Batch { static final int STRIDE = 36; static final int LINE_STRIDE = 16; static final int RANGES = 6; + /** Live VAO/VBO pairs of all batches (leak diagnostics, {@link Viewport#liveGlBuffers()}). */ + static final java.util.concurrent.atomic.AtomicInteger LIVE = new java.util.concurrent.atomic.AtomicInteger(); int vao; int vbo; @@ -36,10 +38,12 @@ final class Batch { if (vao != 0) { glDeleteVertexArrays(vao); glDeleteBuffers(vbo); + LIVE.decrementAndGet(); } if (lineVao != 0) { glDeleteVertexArrays(lineVao); glDeleteBuffers(lineVbo); + LIVE.decrementAndGet(); } vao = vbo = lineVao = lineVbo = 0; } @@ -194,6 +198,7 @@ final class Batch { all.flip(); g.vao = glGenVertexArrays(); g.vbo = glGenBuffers(); + LIVE.incrementAndGet(); glBindVertexArray(g.vao); glBindBuffer(GL_ARRAY_BUFFER, g.vbo); glBufferData(GL_ARRAY_BUFFER, all, GL_STATIC_DRAW); @@ -207,6 +212,7 @@ final class Batch { all.put(lines.b.flip()).put(fill.b.flip()).flip(); g.lineVao = glGenVertexArrays(); g.lineVbo = glGenBuffers(); + LIVE.incrementAndGet(); glBindVertexArray(g.lineVao); glBindBuffer(GL_ARRAY_BUFFER, g.lineVbo); glBufferData(GL_ARRAY_BUFFER, all, GL_STATIC_DRAW); diff --git a/src/main/java/com/eliasmueller/llamamod/editor/render/GlRenderer.java b/src/main/java/com/eliasmueller/llamamod/editor/render/GlRenderer.java index ccdb4b0..664135b 100644 --- a/src/main/java/com/eliasmueller/llamamod/editor/render/GlRenderer.java +++ b/src/main/java/com/eliasmueller/llamamod/editor/render/GlRenderer.java @@ -42,6 +42,8 @@ final class GlRenderer { private final Map singles = new IdentityHashMap<>(); private final Map meshBatches = new IdentityHashMap<>(); + private static final int MESH_BATCH_LIMIT = 256; + private int meshBatchLimit = MESH_BATCH_LIMIT; private final Set detached = new HashSet<>(); private Batch markerBatch; private Set markerLayers = Set.of(); @@ -161,6 +163,12 @@ final class GlRenderer { Chunk c = chunks.get(old); c.members.remove(i); c.dirty = true; + if (c.members.isEmpty()) { + if (c.batch != null) { + c.batch.delete(); + } + chunks.remove(old); + } } if (batched(i) && scene.instances.contains(i)) { long k = key(i); @@ -183,6 +191,9 @@ final class GlRenderer { } sceneVersion = scene.version(); Set dirty = scene.takeDirty(); + if (dirty != null && meshBatches.size() > meshBatchLimit) { + pruneMeshBatches(); + } if (dirty == null || chunks.isEmpty() && chunkOf.isEmpty()) { Set keep = new HashSet<>(detached); clearAll(); @@ -213,6 +224,23 @@ final class GlRenderer { overlayBatches.clear(); } + /** Frees shared mesh batches whose mesh no instance of the scene uses any more (replaced meshes). */ + private void pruneMeshBatches() { + Set used = java.util.Collections.newSetFromMap(new IdentityHashMap<>()); + for (RenderInstance i : scene.instances) { + used.add(i.mesh); + } + meshBatches.entrySet().removeIf(e -> { + if (used.contains(e.getKey())) { + return false; + } + singles.values().removeIf(b -> b == e.getValue()); + e.getValue().delete(); + return true; + }); + meshBatchLimit = Math.max(MESH_BATCH_LIMIT, meshBatches.size() * 2); + } + private Batch.Builder builder() { return new Batch.Builder(whiteLayer, pageW, arraySize); } @@ -1015,6 +1043,12 @@ final class GlRenderer { glDeleteRenderbuffers(pickColor); glDeleteRenderbuffers(pickDepth); } + if (dynVao != 0) { + glDeleteVertexArrays(dynVao); + glDeleteBuffers(dynVbo); + dynVao = dynVbo = 0; + dynCapacity = 0; + } glDeleteProgram(meshProg); glDeleteProgram(lineProg); } diff --git a/src/main/java/com/eliasmueller/llamamod/editor/render/Viewport.java b/src/main/java/com/eliasmueller/llamamod/editor/render/Viewport.java index ef88a3a..ce8127f 100644 --- a/src/main/java/com/eliasmueller/llamamod/editor/render/Viewport.java +++ b/src/main/java/com/eliasmueller/llamamod/editor/render/Viewport.java @@ -109,6 +109,7 @@ public final class Viewport extends JPanel { private Overlay toolOverlay; private Overlay toolTopOverlay; private Overlay screenOverlay; + private volatile Overlay hudOverlay; public Viewport() { super(new BorderLayout()); @@ -184,6 +185,15 @@ public final class Viewport extends JPanel { requestRender(); } + /** + * A second pixel overlay like {@link #setScreenOverlay}, for indicators that are independent of + * the active tool (e.g. a crosshair while a key is held). Null = none. + */ + public void setHudOverlay(Overlay pixels) { + hudOverlay = pixels; + requestRender(); + } + /** The GL canvas (keyboard focus owner while the viewport is active; drop target). */ public Component canvas() { return canvas; @@ -390,6 +400,11 @@ public final class Viewport extends JPanel { return new GlRendererStats(s.drawCalls(), s.triangles(), s.chunksDrawn(), s.chunksTotal(), s.cpuMs(), avg); } + /** Live vertex array/buffer pairs of the renderer's batches (leak diagnostics). */ + public static int liveGlBuffers() { + return Batch.LIVE.get(); + } + /** Frame statistics: last frame's draw calls/triangles/chunks, CPU time and the average frame time. */ public record GlRendererStats( int drawCalls, int triangles, int chunksDrawn, int chunksTotal, double cpuMs, double avgFrameMs) {} @@ -746,6 +761,10 @@ public final class Viewport extends JPanel { if (px != null && (px.lineCount() > 0 || px.triangleCount() > 0)) { fp.toolTop = screenToWorld(px, toolTopOverlay); } + Overlay hud = hudOverlay; + if (hud != null && (hud.lineCount() > 0 || hud.triangleCount() > 0)) { + fp.toolTop = screenToWorld(hud, fp.toolTop); + } if (gizmo.visible()) { fp.gizmoLines = new Overlay(); fp.gizmoTris = new Overlay(); diff --git a/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/CollisionTool.java b/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/CollisionTool.java index 7c8ed21..036750d 100644 --- a/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/CollisionTool.java +++ b/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/CollisionTool.java @@ -10,6 +10,7 @@ import com.eliasmueller.llamamod.editor.model.cmd.AddNode; import com.eliasmueller.llamamod.editor.model.cmd.Batch; import com.eliasmueller.llamamod.editor.model.cmd.Command; import com.eliasmueller.llamamod.editor.model.cmd.SetProp; +import com.eliasmueller.llamamod.editor.model.cmd.Stroke; import com.eliasmueller.llamamod.editor.render.Legend; import com.eliasmueller.llamamod.editor.render.Overlay; import com.eliasmueller.llamamod.editor.ui.EditorContext; @@ -233,7 +234,7 @@ final class CollisionTool implements Tool { } if (!b.brushKind().transformable()) { if (mode == Mode.PAINT && BrushMath.has(b, "mat") && b.i("mat") != material) { - ctx.execute(SetProp.of(b, b.prop("mat"), material, stroke)); + ctx.execute(new Stroke("Paint collision " + material, SetProp.of(b, "mat", material), stroke)); } return; } @@ -247,7 +248,7 @@ final class CollisionTool implements Tool { String cf = b.s("collFaces"); char c = BrushKind.FACES.charAt(k); String n = cf.indexOf(c) >= 0 ? cf.replace(String.valueOf(c), "") : BrushMath.mapFaces(cf + c, "", ""); - ctx.execute(SetProp.of(b, b.prop("collFaces"), n, stroke)); + ctx.execute(new Stroke("Toggle collision", SetProp.of(b, "collFaces", n), stroke)); ctx.status(b.label() + ": " + FACE_NAMES[k] + " face collision " + (cf.indexOf(c) >= 0 ? "off" : "on")); return; } @@ -260,7 +261,7 @@ final class CollisionTool implements Tool { return; } fm[k] = want; - ctx.execute(SetProp.of(b, b.prop("faceMats"), fm, stroke)); + ctx.execute(new Stroke("Paint collision " + material, SetProp.of(b, "faceMats", fm), stroke)); ctx.status(b.label() + ": " + FACE_NAMES[k] + " face → " + GeoWidgets.materialName(material)); return; } @@ -299,7 +300,7 @@ final class CollisionTool implements Tool { target, TileModel.collisionProp(p.group()), target.withCollisionMaterial(p.group(), p.index(), material))); - ctx.execute(new Batch("Paint collision " + material, cmds, stroke)); + ctx.execute(new Stroke("Paint collision " + material, new Batch("Paint collision " + material, cmds), stroke)); ctx.status(t.label() + " polygon " + p.index() + " → " + GeoWidgets.materialName(material) + (shared > 1 && !copyShared ? " (all " + shared + " tiles of this model)" : "")); } diff --git a/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/GeoWidgets.java b/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/GeoWidgets.java index 453c623..2f2d21b 100644 --- a/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/GeoWidgets.java +++ b/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/GeoWidgets.java @@ -5,6 +5,7 @@ import com.eliasmueller.llamamod.editor.model.TextureEntry; import com.eliasmueller.llamamod.editor.model.TexturePage; import com.eliasmueller.llamamod.editor.render.Legend; import com.eliasmueller.llamamod.editor.ui.EditorContext; +import com.eliasmueller.llamamod.editor.ui.Widgets; import com.eliasmueller.llamamod.levelbuild.LevelBuilder; import com.eliasmueller.llamamod.util.SwingListeners; import java.awt.BorderLayout; @@ -392,7 +393,7 @@ final class GeoWidgets { } static JLabel hint(String html) { - JLabel l = new JLabel("

"); + JLabel l = Widgets.wrappingLabel(html); l.setFont(l.getFont().deriveFont(11.5f)); l.setForeground(javax.swing.UIManager.getColor("Label.disabledForeground")); return l; diff --git a/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/TilePaintTool.java b/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/TilePaintTool.java index 6eefdd8..bab5df7 100644 --- a/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/TilePaintTool.java +++ b/src/main/java/com/eliasmueller/llamamod/editor/tools/geometry/TilePaintTool.java @@ -10,6 +10,7 @@ import com.eliasmueller.llamamod.editor.model.cmd.Batch; import com.eliasmueller.llamamod.editor.model.cmd.Command; import com.eliasmueller.llamamod.editor.model.cmd.Edits; import com.eliasmueller.llamamod.editor.model.cmd.SetProp; +import com.eliasmueller.llamamod.editor.model.cmd.Stroke; import com.eliasmueller.llamamod.editor.render.Legend; import com.eliasmueller.llamamod.editor.render.Overlay; import com.eliasmueller.llamamod.editor.ui.EditorContext; @@ -225,9 +226,13 @@ final class TilePaintTool implements Tool { && t.rot() == rot * 1024) { if (t.model() != model && !ctx.isLocked(t)) { // a tile at this height: swap its model (keeps the tile's index for strat scripts) - ctx.execute(new Batch( + ctx.execute(new Stroke( "Paint tiles", - List.of(SetProp.of(t, "model", model), SetProp.of(t, "colors", colours(s, model))), + new Batch( + "Paint tiles", + List.of( + SetProp.of(t, "model", model), + SetProp.of(t, "colors", colours(s, model)))), stroke)); } return; @@ -241,7 +246,7 @@ final class TilePaintTool implements Tool { t.setRaw("rot", rot * 1024); t.setRaw("model", model); t.setRaw("colors", colours(s, model)); - ctx.execute(new Batch("Paint tiles", List.of(new AddNode(t)), stroke)); + ctx.execute(new Stroke("Paint tiles", new AddNode(t), stroke)); ctx.status("Painted " + model.id() + " in cell " + key); } @@ -277,7 +282,7 @@ final class TilePaintTool implements Tool { case ERASE -> { if (t != null && !ctx.isLocked(t) && !painted.contains(t.id())) { painted.add(t.id()); - ctx.execute(new Batch("Erase tiles", List.of(Edits.delete(ctx.scene(), List.of(t))), stroke)); + ctx.execute(new Stroke("Erase tiles", Edits.delete(ctx.scene(), List.of(t)), stroke)); ctx.status( "Erased " + t.label() + (t.id().contains(":n") @@ -303,7 +308,7 @@ final class TilePaintTool implements Tool { List cmds = new ArrayList<>(); cmds.add(SetProp.of(t, "model", model)); cmds.add(SetProp.of(t, "colors", colours(ctx.scene(), model))); - ctx.execute(new Batch("Swap tile model", cmds, stroke)); + ctx.execute(new Stroke("Swap tile model", new Batch("Swap tile model", cmds), stroke)); ctx.status(t.label() + " now uses " + model.id()); } } diff --git a/src/main/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfEditorPlugin.java b/src/main/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfEditorPlugin.java new file mode 100644 index 0000000..7e5c75d --- /dev/null +++ b/src/main/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfEditorPlugin.java @@ -0,0 +1,111 @@ +package com.eliasmueller.llamamod.editor.tools.gltf; + +import com.eliasmueller.llamamod.editor.ui.ActionSpec; +import com.eliasmueller.llamamod.editor.ui.EditorContext; +import com.eliasmueller.llamamod.editor.ui.EditorExtensions; +import com.eliasmueller.llamamod.editor.ui.EditorPlugin; +import java.awt.BorderLayout; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Locale; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JCheckBox; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.filechooser.FileNameExtensionFilter; + +/** File → Export level as glTF… (whole level: tiles, brushes, meshes, optionally objects). */ +public final class GltfEditorPlugin implements EditorPlugin { + @Override + public void install(EditorExtensions x) { + x.action(ActionSpec.of( + "file.exportGltf", + "File", + 30, + 45, + "Export level as glTF…", + "export", + null, + GltfEditorPlugin::export) + .enabledWhen(c -> c.document() != null) + .tip("The whole level with textures and vertex colours as .glb / .gltf (Blender, viewers)")); + } + + static void export(EditorContext ctx) { + if (ctx.scene() == null) { + return; + } + JFileChooser fc = new JFileChooser(ctx.prefs().getString("gltf.exportDir", System.getProperty("user.home"))); + FileNameExtensionFilter glb = new FileNameExtensionFilter("glTF binary (.glb)", "glb"); + FileNameExtensionFilter gltf = new FileNameExtensionFilter("glTF JSON, one file (.gltf)", "gltf"); + fc.addChoosableFileFilter(glb); + fc.addChoosableFileFilter(gltf); + fc.setAcceptAllFileFilterUsed(false); + fc.setFileFilter(glb); + String stem = ctx.document().title().replaceAll("[^A-Za-z0-9._-]+", "_"); + fc.setSelectedFile(new File((stem.isBlank() ? "level" : stem) + ".glb")); + JCheckBox objects = new JCheckBox("Object models", ctx.prefs().getBool("gltf.objects", false)); + JCheckBox hidden = new JCheckBox("Leave out hidden items", ctx.prefs().getBool("gltf.skipHidden", true)); + JCheckBox mirror = new JCheckBox("Game orientation", ctx.prefs().getBool("gltf.gameView", false)); + mirror.setToolTipText("Mirror z so that Blender and viewers show the level as the game does.
" + + "Off: the same axes as the OBJ export and the editor's mesh import."); + JPanel boxes = new JPanel(); + boxes.setLayout(new BoxLayout(boxes, BoxLayout.Y_AXIS)); + boxes.add(objects); + boxes.add(hidden); + boxes.add(mirror); + JPanel acc = new JPanel(new BorderLayout(0, 6)); + acc.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + acc.add(boxes, BorderLayout.NORTH); + acc.add( + new JLabel("
The textures are game data:" + + " fine for your own use, please don't share them.
"), + BorderLayout.CENTER); + fc.setAccessory(acc); + if (fc.showSaveDialog(ctx.frame()) != JFileChooser.APPROVE_OPTION) { + return; + } + Path f = fc.getSelectedFile().toPath(); + String lower = f.getFileName().toString().toLowerCase(Locale.ROOT); + if (!lower.endsWith(".glb") && !lower.endsWith(".gltf")) { + f = f.resolveSibling(f.getFileName() + (fc.getFileFilter() == gltf ? ".gltf" : ".glb")); + } + boolean binary = !f.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".gltf"); + ctx.prefs().put("gltf.exportDir", f.getParent().toString()); + ctx.prefs().put("gltf.objects", objects.isSelected()); + ctx.prefs().put("gltf.skipHidden", hidden.isSelected()); + ctx.prefs().put("gltf.gameView", mirror.isSelected()); + GltfExport.Geometry g; + try { + g = GltfExport.collect( + ctx.scene(), + new GltfExport.Options(objects.isSelected(), mirror.isSelected()), + n -> hidden.isSelected() && ctx.isHidden(n)); + } catch (RuntimeException e) { + ctx.error("Export glTF", e); + return; + } + Path out = f; + ctx.runTask( + "Exporting " + f.getFileName(), + p -> { + Files.write(out, binary ? g.glb() : g.gltf()); + return Files.size(out); + }, + r -> { + if (r instanceof Long size) { + ctx.status(String.format( + Locale.ROOT, + "Exported %,d triangles (%d materials) to %s (%.1f MB) – textures are game data:" + + " personal use only", + g.triangles(), + g.primitives(), + out.getFileName(), + size / 1e6)); + } + }); + } +} diff --git a/src/main/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfExport.java b/src/main/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfExport.java new file mode 100644 index 0000000..3d2cc01 --- /dev/null +++ b/src/main/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfExport.java @@ -0,0 +1,465 @@ +package com.eliasmueller.llamamod.editor.tools.gltf; + +import com.eliasmueller.llamamod.editor.io.Images; +import com.eliasmueller.llamamod.editor.model.Node; +import com.eliasmueller.llamamod.editor.model.Scene; +import com.eliasmueller.llamamod.editor.model.Tile; +import com.eliasmueller.llamamod.editor.render.RenderInstance; +import com.eliasmueller.llamamod.editor.render.RenderMesh; +import com.eliasmueller.llamamod.editor.render.RenderScene; +import com.eliasmueller.llamamod.editor.render.TexturePage; +import com.eliasmueller.llamamod.editor.ui.view.SceneRenderer; +import com.eliasmueller.llamamod.platform.Json; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import org.joml.Matrix3f; +import org.joml.Vector3f; + +/** + * Level geometry (tiles, compiled brushes and meshes, optionally object models) as glTF 2.0: the + * triangles the editor viewport draws, baked to world space, one primitive per texture page × blend + * class × sidedness. Textures are the level's pages as PNG, the engine's vertex colours (doubled with + * clamp, times flat/translucent face colours) are COLOR_0, materials are unlit + * (KHR_materials_unlit, optional). Coordinates are export space like the OBJ export and the mesh + * importer (y up, z = −game z, 1 unit = 1 cell); {@link Options#gameView} mirrors z instead. + * + *

Two steps: {@link #collect} reads the scene (EDT), {@link Geometry#glb} / {@link Geometry#gltf} + * encode the snapshot (any thread). + */ +public final class GltfExport { + private GltfExport() {} + + /** + * objects: also the models of placed objects (strats) as the viewport shows them; gameView: + * mirror z so that right-handed viewers show the level as the game does (re-importing such a + * file into the editor gives mirrored geometry). + */ + public record Options(boolean objects, boolean gameView) {} + + /** One glTF primitive: unique vertices + triangle indices. */ + static final class Prim { + final int page; + final int blend; + final boolean doubleSided; + final String group; + final List verts = new ArrayList<>(); + final List cols = new ArrayList<>(); + final Map index = new HashMap<>(); + final List tris = new ArrayList<>(); + + Prim(String group, int page, int blend, boolean doubleSided) { + this.group = group; + this.page = page; + this.blend = blend; + this.doubleSided = doubleSided; + } + + int vertex(float[] v, int rgba) { + return index.computeIfAbsent(new VKey(v, rgba), k -> { + verts.add(v); + cols.add(rgba); + return verts.size() - 1; + }); + } + } + + /** Position, normal, uv, rgba as one hashable key. */ + private record VKey(float x, float y, float z, float nx, float ny, float nz, float u, float v, int c) { + VKey(float[] a, int c) { + this(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], c); + } + } + + /** Snapshot of the exported geometry: primitives and the used texture pages. */ + public static final class Geometry { + final List prims; + final List pages; + final String name; + + Geometry(String name, List prims, List pages) { + this.name = name; + this.prims = prims; + this.pages = pages; + } + + public int triangles() { + int n = 0; + for (Prim p : prims) { + n += p.tris.size() / 3; + } + return n; + } + + public int vertices() { + int n = 0; + for (Prim p : prims) { + n += p.verts.size(); + } + return n; + } + + public int primitives() { + return prims.size(); + } + + /** Binary glTF (.glb). */ + public byte[] glb() { + Encoded e = encode(false); + byte[] json = pad(e.json.getBytes(StandardCharsets.UTF_8), (byte) ' '); + byte[] bin = pad(e.bin, (byte) 0); + ByteBuffer b = + ByteBuffer.allocate(12 + 8 + json.length + 8 + bin.length).order(ByteOrder.LITTLE_ENDIAN); + b.putInt(0x46546C67).putInt(2).putInt(b.capacity()); + b.putInt(json.length).putInt(0x4E4F534A).put(json); + b.putInt(bin.length).putInt(0x004E4942).put(bin); + return b.array(); + } + + /** JSON glTF (.gltf) with the buffer embedded as a data URI (one self-contained file). */ + public byte[] gltf() { + return encode(true).json.getBytes(StandardCharsets.UTF_8); + } + + private Encoded encode(boolean dataUri) { + Writer w = new Writer(); + Map imageOf = new HashMap<>(); + List images = new ArrayList<>(); + List textures = new ArrayList<>(); + for (Prim p : prims) { + if (p.page >= 0 && !imageOf.containsKey(p.page)) { + int view = w.view(png(pages.get(p.page)), null); + imageOf.put(p.page, images.size()); + images.add(map("name", "page" + p.page, "bufferView", view, "mimeType", "image/png")); + textures.add(map("sampler", 0, "source", images.size() - 1)); + } + } + List materials = new ArrayList<>(); + Map matOf = new LinkedHashMap<>(); + Map> meshPrims = new LinkedHashMap<>(); + for (Prim p : prims) { + String mk = p.page + "/" + p.blend + "/" + p.doubleSided; + Integer mi = matOf.get(mk); + if (mi == null) { + mi = materials.size(); + matOf.put(mk, mi); + materials.add(material(p, imageOf, pages)); + } + Map attr = new LinkedHashMap<>(); + int n = p.verts.size(); + ByteBuffer pos = buf(n * 12); + ByteBuffer nor = buf(n * 12); + ByteBuffer uv = buf(n * 8); + ByteBuffer col = buf(n * 4); + float[] min = {Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE}; + float[] max = {-Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE}; + for (int vi = 0; vi < n; vi++) { + float[] v = p.verts.get(vi); + for (int k = 0; k < 3; k++) { + pos.putFloat(v[k]); + min[k] = Math.min(min[k], v[k]); + max[k] = Math.max(max[k], v[k]); + nor.putFloat(v[3 + k]); + } + uv.putFloat(v[6]).putFloat(v[7]); + int c = p.cols.get(vi); + col.put((byte) (c >>> 24)) + .put((byte) (c >>> 16)) + .put((byte) (c >>> 8)) + .put((byte) c); + } + attr.put("POSITION", w.accessor(pos, 34962, 5126, n, "VEC3", false, min, max)); + attr.put("NORMAL", w.accessor(nor, 34962, 5126, n, "VEC3", false, null, null)); + if (p.page >= 0) { + attr.put("TEXCOORD_0", w.accessor(uv, 34962, 5126, n, "VEC2", false, null, null)); + } + attr.put("COLOR_0", w.accessor(col, 34962, 5121, n, "VEC4", true, null, null)); + boolean small = n <= 65535; + ByteBuffer idx = buf(p.tris.size() * (small ? 2 : 4)); + for (int t : p.tris) { + if (small) { + idx.putShort((short) t); + } else { + idx.putInt(t); + } + } + int ia = w.accessor(idx, 34963, small ? 5123 : 5125, p.tris.size(), "SCALAR", false, null, null); + meshPrims + .computeIfAbsent(p.group, g -> new ArrayList<>()) + .add(map("attributes", attr, "indices", ia, "material", mi, "mode", 4)); + } + List meshes = new ArrayList<>(); + List nodes = new ArrayList<>(); + for (Map.Entry> e : meshPrims.entrySet()) { + nodes.add(map("name", e.getKey(), "mesh", meshes.size())); + meshes.add(map("name", e.getKey(), "primitives", e.getValue())); + } + List sceneNodes = new ArrayList<>(); + for (int i = 0; i < nodes.size(); i++) { + sceneNodes.add(i); + } + byte[] bin = w.out.toByteArray(); + Map buffer = new LinkedHashMap<>(); + buffer.put("byteLength", bin.length); + if (dataUri) { + buffer.put( + "uri", + "data:application/octet-stream;base64," + + Base64.getEncoder().encodeToString(bin)); + } + Map j = new LinkedHashMap<>(); + j.put("asset", map("version", "2.0", "generator", "LlamaMod level editor")); + j.put("extensionsUsed", List.of("KHR_materials_unlit")); + j.put("scene", 0); + j.put("scenes", List.of(map("name", name, "nodes", sceneNodes))); + j.put("nodes", nodes); + j.put("meshes", meshes); + j.put("materials", materials); + if (!textures.isEmpty()) { + j.put("samplers", List.of(map("magFilter", 9729, "minFilter", 9729, "wrapS", 33071, "wrapT", 33071))); + j.put("textures", textures); + j.put("images", images); + } + j.put("accessors", w.accessors); + j.put("bufferViews", w.views); + j.put("buffers", List.of(buffer)); + return new Encoded(Json.write(j), bin); + } + } + + private record Encoded(String json, byte[] bin) {} + + private static Map material(Prim p, Map imageOf, List pages) { + Map pbr = new LinkedHashMap<>(); + pbr.put("baseColorFactor", List.of(1, 1, 1, 1)); + if (p.page >= 0) { + pbr.put("baseColorTexture", map("index", imageOf.get(p.page))); + } + pbr.put("metallicFactor", 0); + pbr.put("roughnessFactor", 1); + Map m = new LinkedHashMap<>(); + String blend = p.blend == RenderMesh.BLEND_ADD ? "add" : p.blend == RenderMesh.BLEND_ALPHA ? "alpha" : "opaque"; + m.put("name", (p.page >= 0 ? "page" + p.page : "flat") + "_" + blend + (p.doubleSided ? "_2s" : "")); + m.put("pbrMetallicRoughness", pbr); + if (p.blend != RenderMesh.BLEND_OPAQUE) { + m.put("alphaMode", "BLEND"); + } else if (p.page >= 0 && hasCutout(pages.get(p.page))) { + m.put("alphaMode", "MASK"); + m.put("alphaCutoff", 0.5); + } + if (p.doubleSided) { + m.put("doubleSided", true); + } + m.put("extensions", map("KHR_materials_unlit", Map.of())); + return m; + } + + private static boolean hasCutout(TexturePage p) { + for (int c : p.rgba()) { + if ((c & 0xff) < 128) { + return true; + } + } + return false; + } + + private static byte[] png(TexturePage p) { + BufferedImage img = new BufferedImage(p.width(), p.height(), BufferedImage.TYPE_INT_ARGB); + int[] argb = new int[p.rgba().length]; + for (int i = 0; i < argb.length; i++) { + int c = p.rgba()[i]; + argb[i] = (c & 0xff) << 24 | c >>> 8; + } + img.setRGB(0, 0, p.width(), p.height(), argb, 0, p.width()); + return Images.png(img); + } + + private static ByteBuffer buf(int n) { + return ByteBuffer.allocate(n).order(ByteOrder.LITTLE_ENDIAN); + } + + private static byte[] pad(byte[] b, byte fill) { + int n = (b.length + 3) & ~3; + if (n == b.length) { + return b; + } + byte[] o = java.util.Arrays.copyOf(b, n); + java.util.Arrays.fill(o, b.length, n, fill); + return o; + } + + private static Map map(Object... kv) { + Map m = new LinkedHashMap<>(); + for (int i = 0; i < kv.length; i += 2) { + m.put((String) kv[i], kv[i + 1]); + } + return m; + } + + /** Binary buffer, buffer views (4-byte aligned) and accessors. */ + private static final class Writer { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final List views = new ArrayList<>(); + final List accessors = new ArrayList<>(); + + int view(byte[] data, Integer target) { + while (out.size() % 4 != 0) { + out.write(0); + } + Map v = map("buffer", 0, "byteOffset", out.size(), "byteLength", data.length); + if (target != null) { + v.put("target", target); + } + out.writeBytes(data); + views.add(v); + return views.size() - 1; + } + + int accessor( + ByteBuffer data, + int target, + int componentType, + int count, + String type, + boolean normalized, + float[] min, + float[] max) { + int v = view(data.array(), target); + Map a = map("bufferView", v, "componentType", componentType, "count", count, "type", type); + if (normalized) { + a.put("normalized", true); + } + if (min != null) { + a.put("min", List.of((double) min[0], (double) min[1], (double) min[2])); + a.put("max", List.of((double) max[0], (double) max[1], (double) max[2])); + } + accessors.add(a); + return accessors.size() - 1; + } + } + + // ------------------------------------------------------------------ collect + + /** Reads the scene as the viewport draws it; skip: nodes to leave out (e.g. hidden ones). */ + public static Geometry collect(Scene s, Options o, Predicate skip) { + SceneRenderer sr = new SceneRenderer(); + sr.setScene(s); + RenderScene rs = sr.renderScene(); + Map prims = new LinkedHashMap<>(); + Vector3f p = new Vector3f(); + Vector3f n = new Vector3f(); + Matrix3f nm = new Matrix3f(); + float[][] tri = new float[3][]; + int[] rgba = new int[3]; + Vector3f e1 = new Vector3f(); + Vector3f e2 = new Vector3f(); + for (RenderInstance ri : rs.instances) { + boolean object = ri.kind == RenderInstance.Kind.OBJECT; + if (ri.kind != RenderInstance.Kind.TILE && !(object && o.objects())) { + continue; + } + Node owner = sr.nodeOf(ri.id); + if (owner instanceof Tile t && t.excluded() || owner != null && skip.test(owner)) { + continue; + } + RenderMesh m = ri.mesh; + ri.transform.normal(nm); + String group = object ? "objects" : "level"; + for (int t = 0; t < m.triangleCount(); t++) { + int fl = m.triFlags[t]; + int page = m.pages[t] < rs.pages.size() ? m.pages[t] : -1; + int tc = m.triColors[t]; + for (int k = 0; k < 3; k++) { + int v = m.triangles[3 * t + k]; + ri.transform.transformPosition( + p.set(m.positions[3 * v], m.positions[3 * v + 1], m.positions[3 * v + 2])); + nm.transform(n.set(m.normals[3 * v], m.normals[3 * v + 1], m.normals[3 * v + 2])); + if (o.gameView()) { + p.z = -p.z; + n.z = -n.z; + } + int c = ri.vertexColors != null + && (fl & RenderMesh.NO_VERTEX_COLOR) == 0 + && v < ri.vertexColors.length + ? doubled(ri.vertexColors[v]) + : 0xffffffff; + c = mul(c, tc); + tri[k] = new float[] {p.x, p.y, p.z, n.x, n.y, n.z, m.uvs[6 * t + 2 * k], m.uvs[6 * t + 2 * k + 1]}; + rgba[k] = c; + } + if (o.gameView()) { + float[] x = tri[1]; + tri[1] = tri[2]; + tri[2] = x; + int y = rgba[1]; + rgba[1] = rgba[2]; + rgba[2] = y; + } + // unit normals (glTF requires them): face normal where the vertex normal is zero + e1.set(tri[1][0] - tri[0][0], tri[1][1] - tri[0][1], tri[1][2] - tri[0][2]); + e2.set(tri[2][0] - tri[0][0], tri[2][1] - tri[0][1], tri[2][2] - tri[0][2]); + e1.cross(e2); + if (!(e1.lengthSquared() > 1e-14f)) { + continue; + } + e1.normalize(); + for (float[] q : tri) { + float len = (float) Math.sqrt(q[3] * q[3] + q[4] * q[4] + q[5] * q[5]); + if (len > 1e-6f) { + q[3] /= len; + q[4] /= len; + q[5] /= len; + } else { + q[3] = e1.x; + q[4] = e1.y; + q[5] = e1.z; + } + if (page < 0) { + q[6] = 0; + q[7] = 0; + } + } + boolean dbl = (fl & RenderMesh.DOUBLE_SIDED) != 0; + int blend = m.blend[t]; + Prim pr = prims.computeIfAbsent( + group + "/" + page + "/" + blend + "/" + dbl, key -> new Prim(group, page, blend, dbl)); + for (int k = 0; k < 3; k++) { + pr.tris.add(pr.vertex(tri[k], rgba[k])); + } + } + } + List l = new ArrayList<>(); + for (Prim pr : prims.values()) { + if (!pr.tris.isEmpty()) { + l.add(pr); + } + } + String name = s.settings().levelName(); + return new Geometry(name == null || name.isBlank() ? "level" : name, l, List.copyOf(rs.pages)); + } + + /** Game vertex colour (0xRRGGBBAA, 0x80 = 1.0) doubled with clamp, as the viewport does. */ + static int doubled(int rgba) { + int r = Math.min(255, ((rgba >>> 24) & 0xff) * 2); + int g = Math.min(255, ((rgba >>> 16) & 0xff) * 2); + int b = Math.min(255, ((rgba >>> 8) & 0xff) * 2); + return r << 24 | g << 16 | b << 8 | (rgba & 0xff); + } + + static int mul(int a, int b) { + int r = ((a >>> 24) & 0xff) * ((b >>> 24) & 0xff) / 255; + int g = ((a >>> 16) & 0xff) * ((b >>> 16) & 0xff) / 255; + int bl = ((a >>> 8) & 0xff) * ((b >>> 8) & 0xff) / 255; + int al = (a & 0xff) * (b & 0xff) / 255; + return r << 24 | g << 16 | bl << 8 | al; + } +} diff --git a/src/main/java/com/eliasmueller/llamamod/editor/ui/view/SceneRenderer.java b/src/main/java/com/eliasmueller/llamamod/editor/ui/view/SceneRenderer.java index f6c61a4..12dfe3e 100644 --- a/src/main/java/com/eliasmueller/llamamod/editor/ui/view/SceneRenderer.java +++ b/src/main/java/com/eliasmueller/llamamod/editor/ui/view/SceneRenderer.java @@ -70,8 +70,15 @@ public final class SceneRenderer { private final Map ids = new IdentityHashMap<>(); private final Map nodes = new HashMap<>(); private final int[] counters = new int[32]; + /** Removals since the last pick-id cleanup; ids of absent nodes are dropped every PRUNE_AFTER. */ + private int removedSincePrune; + + private static final int PRUNE_AFTER = 256; private final Map modelMeshes = new IdentityHashMap<>(); + /** Meshes of "no collision" tiles: as modelMeshes, without the collision overlay. */ + private final Map visualMeshes = new IdentityHashMap<>(); + private final Map tileInst = new IdentityHashMap<>(); private final Map stratInst = new IdentityHashMap<>(); private final List brushInst = new ArrayList<>(); @@ -107,6 +114,7 @@ public final class SceneRenderer { scene = s; ids.clear(); nodes.clear(); + removedSincePrune = 0; Arrays.fill(counters, 0); hidden.clear(); selected.clear(); @@ -124,6 +132,9 @@ public final class SceneRenderer { return; } Node n = e.node(); + if (e.type() == SceneEvent.Type.REMOVED) { + removedSincePrune++; + } switch (n.kind()) { case TEXTURE_PAGE, TEXTURE, TEXTURE_ANIM -> dirtyTextures = true; case RAW_CHUNK -> dirtyAll = true; @@ -176,6 +187,7 @@ public final class SceneRenderer { } } for (TileModel m : models) { + visualMeshes.remove(m); if (scene.contains(m)) { modelMeshes.put(m, tileMesh(m)); } else { @@ -205,6 +217,30 @@ public final class SceneRenderer { dirtyMarkers = false; rebuildMarkers(); } + if (removedSincePrune >= PRUNE_AFTER) { + pruneIds(); + } + } + + /** + * Forgets the pick ids of nodes no longer in the scene (deleted, or undone additions). A node + * that comes back by undo/redo simply gets a new id; nothing keeps ids of absent nodes. + */ + private void pruneIds() { + removedSincePrune = 0; + ids.entrySet().removeIf(e -> { + Node n = e.getKey(); + if (scene.contains(n) || selected.contains(n)) { + return false; + } + nodes.remove(e.getValue()); + return true; + }); + } + + /** Pick ids currently assigned (for tests). */ + int assignedIds() { + return ids.size(); } // ------------------------------------------------------------ ids @@ -340,6 +376,7 @@ public final class SceneRenderer { rs.markers.clear(); rs.overlays.clear(); modelMeshes.clear(); + visualMeshes.clear(); tileInst.clear(); stratInst.clear(); brushInst.clear(); @@ -434,6 +471,19 @@ public final class SceneRenderer { return rm; } + private static RenderMesh withoutOverlay(RenderMesh m) { + RenderMesh c = new RenderMesh(m.name, m.vertexCount(), m.triangleCount()); + System.arraycopy(m.positions, 0, c.positions, 0, m.positions.length); + System.arraycopy(m.normals, 0, c.normals, 0, m.normals.length); + System.arraycopy(m.triangles, 0, c.triangles, 0, m.triangles.length); + System.arraycopy(m.uvs, 0, c.uvs, 0, m.uvs.length); + System.arraycopy(m.pages, 0, c.pages, 0, m.pages.length); + System.arraycopy(m.triColors, 0, c.triColors, 0, m.triColors.length); + System.arraycopy(m.triFlags, 0, c.triFlags, 0, m.triFlags.length); + System.arraycopy(m.blend, 0, c.blend, 0, m.blend.length); + return c; + } + /** Texture pages as uploaded (index = page number). */ public List pages() { return rs.pages; @@ -454,6 +504,11 @@ public final class SceneRenderer { mesh = tileMesh(t.model()); modelMeshes.put(t.model(), mesh); } + if (t.noCollision()) { + RenderMesh full = mesh; + // same triangles, no collision overlay (the build drops the tile's collision) + mesh = visualMeshes.computeIfAbsent(t.model(), m -> withoutOverlay(full)); + } RenderInstance ri = old; if (ri == null || ri.mesh != mesh) { if (old != null) { diff --git a/src/main/resources/com/eliasmueller/llamamod/editor/tools/help/context-help.txt b/src/main/resources/com/eliasmueller/llamamod/editor/tools/help/context-help.txt index 524c7ca..418a21f 100644 --- a/src/main/resources/com/eliasmueller/llamamod/editor/tools/help/context-help.txt +++ b/src/main/resources/com/eliasmueller/llamamod/editor/tools/help/context-help.txt @@ -123,6 +123,7 @@ action.geo.deathPlane = 06-geometry.md#death-floors-and-the-death-plane action.geo.reimport = 07-meshes.md#re-import-mesh action.geo.libSave = 07-meshes.md#saving-to-the-library action.geo.exportObj = 07-meshes.md#export-selection-as-obj +action.file.exportGltf = 07-meshes.md#export-the-level-as-gltf action.geo.* = 06-geometry.md#rotating-scaling-and-mirroring action.tex.manager = 08-textures.md#texture-manager action.tex.replace = 08-textures.md#replacing-pixels diff --git a/src/test/java/com/eliasmueller/llamamod/editor/io/NoCollisionDemo.java b/src/test/java/com/eliasmueller/llamamod/editor/io/NoCollisionDemo.java new file mode 100644 index 0000000..df1b944 --- /dev/null +++ b/src/test/java/com/eliasmueller/llamamod/editor/io/NoCollisionDemo.java @@ -0,0 +1,121 @@ +package com.eliasmueller.llamamod.editor.io; + +import com.eliasmueller.llamamod.editor.model.Brush; +import com.eliasmueller.llamamod.editor.model.BrushKind; +import com.eliasmueller.llamamod.editor.model.NodeKind; +import com.eliasmueller.llamamod.editor.model.PathNode; +import com.eliasmueller.llamamod.editor.model.Prop; +import com.eliasmueller.llamamod.editor.model.Scene; +import com.eliasmueller.llamamod.editor.model.Tile; +import com.eliasmueller.llamamod.editor.model.TileModel; +import com.eliasmueller.llamamod.editor.model.cmd.AddNode; +import com.eliasmueller.llamamod.editor.model.cmd.Batch; +import com.eliasmueller.llamamod.editor.model.cmd.Command; +import com.eliasmueller.llamamod.editor.model.cmd.Edits; +import com.eliasmueller.llamamod.format.Level; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.Map; + +/** + * Not a unit test: test level for "no collision" tiles. A plaza; two walls baked from box brushes + * into scene tiles (like library tiles); the north wall's tiles are visual only. The llama starts + * west of the north wall facing east. Args: CD folder, output .llamalevel, chapter. + */ +public final class NoCollisionDemo { + private NoCollisionDemo() {} + + static Brush box(Scene s, double x0, double z0, double x1, double z1, double y0, double y1, String top) { + Brush b = s.createBrush(BrushKind.BOX); + Map p = Map.of("x0", x0, "z0", z0, "x1", x1, "z1", z1, "y0", y0, "y1", y1); + p.forEach(b::setRaw); + if (top != null) { + b.setRaw("top", top); + } + new AddNode(b).apply(s); + return b; + } + + /** Compiles one brush in a scratch copy of the scene and adds its tiles/models as scene nodes. */ + static int bake(Scene s, Brush b, boolean noCollision) { + Scene scratch = s; + var others = new ArrayList<>(s.brushes()); + others.remove(b); + for (Brush o : others) { + o.setRaw("enabled", false); + } + BrushCompiler.Output out = BrushCompiler.compile(scratch, new ArrayList<>()); + for (Brush o : others) { + o.setRaw("enabled", true); + } + if (!out.pages().isEmpty()) { + throw new IllegalStateException("brush needs new texture pages"); + } + Map models = new IdentityHashMap<>(); + for (TileModel m : out.models()) { + TileModel c = (TileModel) s.create(NodeKind.TILE_MODEL); + copy(m, c); + new AddNode(c).apply(s); + models.put(m, c); + } + for (Tile t : out.tiles()) { + Tile c = (Tile) s.create(NodeKind.TILE); + copy(t, c); + c.setRaw("model", models.get(t.model())); + c.setRaw("noCollision", noCollision); + new AddNode(c).apply(s); + } + Edits.delete(s, java.util.List.of(b)).apply(s); + return out.tiles().size(); + } + + static void copy(com.eliasmueller.llamamod.editor.model.Node from, com.eliasmueller.llamamod.editor.model.Node to) { + for (Prop p : from.props()) { + if (p.settable() && !p.name().equals("name")) { + Object v = from.get(p.name()); + if (v != null || p.nullable()) { + to.setRaw(p.name(), v); + } + } + } + } + + public static void main(String[] a) throws Exception { + Bases cd = Bases.fromCd(Path.of(a[0])); + Project pr = Project.create(cd, "new", Templates.DEFAULT_BASE); + Scene s = pr.scene(); + s.settings().setRaw("name", "No Collision Test"); + s.settings().setRaw("targetChapter", Integer.parseInt(a[2])); + box(s, 4, 4, 30, 24, -1, 0, null); + Brush north = box(s, 14, 5, 15, 12, 0, 2, null); + Brush south = box(s, 14, 15, 15, 23, 0, 2, null); + System.out.println("north wall tiles (visual only): " + bake(s, north, true)); + System.out.println("south wall tiles (solid): " + bake(s, south, false)); + double px = 10.5, pz = 8.5, yaw = 90; + Batch b = (Batch) Edits.placeStrat(s, "Llama", 0, px, 0, pz, yaw); + int k = 0; + for (Command c : b.commands()) { + if (c instanceof AddNode an && an.node() instanceof PathNode p) { + p.setRaw("x", Edits.fixed(k == 0 ? px - 8 : px)); + p.setRaw("y", Edits.fixed(k == 0 ? 1.5 : 0)); + p.setRaw("z", Edits.fixed(pz)); + k++; + } + } + b.apply(s); + WadBuilder.Result r = WadBuilder.buildWithReport(s); + Level l = Level.parse(r.wad()); + int noColl = 0; + for (var m : l.models()) { + noColl += + m.coll.get(0).size() + m.coll.get(1).size() + m.coll.get(2).size() == 0 && !m.faces.isEmpty() + ? 1 + : 0; + } + System.out.println("built " + r.wad().length + " bytes, " + r.stats() + ", models with faces but no collision: " + + noColl + ", warnings " + r.warnings()); + ProjectIO.save(pr, Path.of(a[1]), cd); + System.out.println("saved " + a[1]); + } +} diff --git a/src/test/java/com/eliasmueller/llamamod/editor/io/NoCollisionTilesTest.java b/src/test/java/com/eliasmueller/llamamod/editor/io/NoCollisionTilesTest.java new file mode 100644 index 0000000..a799b58 --- /dev/null +++ b/src/test/java/com/eliasmueller/llamamod/editor/io/NoCollisionTilesTest.java @@ -0,0 +1,82 @@ +package com.eliasmueller.llamamod.editor.io; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.eliasmueller.llamamod.editor.model.Scene; +import com.eliasmueller.llamamod.editor.model.Tile; +import com.eliasmueller.llamamod.format.Level; +import com.eliasmueller.llamamod.format.Model; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** "No collision (visual only)" tiles: the build omits their collision polygons (needs the CD). */ +class NoCollisionTilesTest { + private static int coll(Model m) { + return m.coll.get(0).size() + m.coll.get(1).size() + m.coll.get(2).size(); + } + + @Test + void noCollisionTilesGetAModelCopyWithoutCollision() throws Exception { + Bases cd = Bases.fromCd(GoldenTest.cd()); + Project p = Project.create(cd, "edit", "t1l1m001"); + Scene s = p.scene(); + byte[] original = WadBuilder.build(s); + Level before = Level.parse(original); + int nModels = before.models().size(); + // two tiles sharing a model with collision, a third one of the same model stays solid + Tile a = null; + Tile b = null; + Tile solid = null; + for (Tile t : s.tiles()) { + if (t.model() == null || t.model().collisionCount() == 0) { + continue; + } + long same = s.tiles().stream().filter(o -> o.model() == t.model()).count(); + if (same >= 3) { + List l = + s.tiles().stream().filter(o -> o.model() == t.model()).toList(); + a = l.get(0); + b = l.get(1); + solid = l.get(2); + break; + } + } + assertTrue(a != null, "a shared model with collision"); + int ia = s.tiles().indexOf(a); + int ib = s.tiles().indexOf(b); + int is = s.tiles().indexOf(solid); + int orig = before.map().tiles.get(ia).model(); + a.prop("noCollision").setRaw(a, true); + b.prop("noCollision").setRaw(b, true); + assertTrue(a.worldCollisionPolygons().isEmpty(), "editor collision follows the flag"); + + Level after = Level.parse(WadBuilder.build(s)); + assertEquals(nModels + 1, after.models().size(), "one copy per model"); + assertEquals(before.map().tiles.size(), after.map().tiles.size(), "the tile stays in the level"); + int ma = after.map().tiles.get(ia).model(); + assertEquals(ma, after.map().tiles.get(ib).model(), "tiles of one model share the copy"); + assertNotEquals(orig, ma); + assertEquals(0, coll(after.models().get(ma)), "no collision polygons"); + Model src = after.models().get(orig); + Model cp = after.models().get(ma); + assertTrue(coll(src) > 0); + assertEquals(src.verts.size(), cp.verts.size(), "same vertices"); + assertEquals(src.faces.size(), cp.faces.size(), "same faces"); + assertEquals(orig, after.map().tiles.get(is).model(), "other tiles keep the solid model"); + assertEquals(before.map().tiles.get(ia).x(), after.map().tiles.get(ia).x()); + assertArrayEquals( + before.map().tilesFixed.get(ia), after.map().tilesFixed.get(ia), "placement unchanged"); + assertEquals(before.map().strats.size(), after.map().strats.size()); + + // saved with the project + Project q = ProjectIO.read(ProjectIO.write(p, cd), cd); + assertEquals(2, q.scene().tiles().stream().filter(Tile::noCollision).count()); + // off again: byte-identical original + a.prop("noCollision").setRaw(a, false); + b.prop("noCollision").setRaw(b, false); + assertArrayEquals(original, WadBuilder.build(s)); + } +} diff --git a/src/test/java/com/eliasmueller/llamamod/editor/model/cmd/StrokeTest.java b/src/test/java/com/eliasmueller/llamamod/editor/model/cmd/StrokeTest.java new file mode 100644 index 0000000..e9b0803 --- /dev/null +++ b/src/test/java/com/eliasmueller/llamamod/editor/model/cmd/StrokeTest.java @@ -0,0 +1,83 @@ +package com.eliasmueller.llamamod.editor.model.cmd; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import com.eliasmueller.llamamod.editor.io.Bases; +import com.eliasmueller.llamamod.editor.io.Project; +import com.eliasmueller.llamamod.editor.model.NodeKind; +import com.eliasmueller.llamamod.editor.model.Scene; +import com.eliasmueller.llamamod.editor.model.Tile; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** Paint/erase strokes (as issued by the tiles tool) are one undo step each. */ +class StrokeTest { + private static Scene village() throws Exception { + String cd = System.getProperty("llamamod.cd", ""); + assumeTrue(!cd.isEmpty() && Files.isDirectory(Path.of(cd, "wads")), "original CD not available"); + return Project.create(Bases.fromCd(Path.of(cd)), "edit", "t1l1m001").scene(); + } + + @Test + void eraseStrokeIsOneUndoStep() throws Exception { + Scene s = village(); + History h = new History(s); + List before = new ArrayList<>(s.tiles()); + Object stroke = new Object(); + List erased = before.subList(10, 16); + for (Tile t : erased) { + h.execute(new Stroke("Erase tiles", Edits.delete(s, List.of(t)), stroke)); + } + assertEquals(before.size() - erased.size(), s.tiles().size()); + assertEquals(List.of("Erase tiles"), h.undoLabels()); + h.undo(); + assertEquals(before, s.tiles(), "all tiles back, same order"); + assertFalse(h.canUndo()); + h.redo(); + assertEquals(before.size() - erased.size(), s.tiles().size()); + for (Tile t : erased) { + assertFalse(s.contains(t)); + } + // the next stroke is its own step + h.execute(new Stroke("Erase tiles", Edits.delete(s, List.of(before.get(30))), new Object())); + assertEquals(2, h.undoLabels().size()); + } + + @Test + void paintStrokeMixingAddsAndSwapsIsOneStep() throws Exception { + Scene s = village(); + History h = new History(s); + int n = s.tiles().size(); + Tile old = s.tiles().get(3); + var oldModel = old.model(); + var otherModel = + s.tileModels().stream().filter(m -> m != oldModel).findFirst().orElseThrow(); + Object stroke = new Object(); + for (int i = 0; i < 4; i++) { + Tile t = (Tile) s.create(NodeKind.TILE); + t.setRaw("x", 1.5 + i); + t.setRaw("y", 0.0); + t.setRaw("z", -1.5); + t.setRaw("model", otherModel); + h.execute(new Stroke("Paint tiles", new AddNode(t), stroke)); + if (i == 1) { + h.execute(new Stroke( + "Paint tiles", + new Batch("Paint tiles", List.of(SetProp.of(old, "model", otherModel))), + stroke)); + } + } + assertEquals(n + 4, s.tiles().size()); + assertTrue(old.model() == otherModel); + assertEquals(1, h.undoLabels().size()); + h.undo(); + assertEquals(n, s.tiles().size()); + assertTrue(old.model() == oldModel); + } +} diff --git a/src/test/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfExportTest.java b/src/test/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfExportTest.java new file mode 100644 index 0000000..d7d597f --- /dev/null +++ b/src/test/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfExportTest.java @@ -0,0 +1,295 @@ +package com.eliasmueller.llamamod.editor.tools.gltf; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import com.eliasmueller.llamamod.editor.io.Bases; +import com.eliasmueller.llamamod.editor.io.MeshImport; +import com.eliasmueller.llamamod.editor.io.Project; +import com.eliasmueller.llamamod.editor.model.BrushKind; +import com.eliasmueller.llamamod.editor.model.MeshData; +import com.eliasmueller.llamamod.editor.model.Scene; +import com.eliasmueller.llamamod.editor.model.Tile; +import com.eliasmueller.llamamod.editor.model.cmd.Edits; +import com.eliasmueller.llamamod.platform.Json; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; +import java.util.Map; +import javax.imageio.ImageIO; +import org.junit.jupiter.api.Test; + +/** glTF export: structural validation of .glb/.gltf and a round trip through the mesh importer. */ +class GltfExportTest { + static Bases cd() { + String cd = System.getProperty("llamamod.cd", ""); + assumeTrue(!cd.isEmpty() && Files.isDirectory(Path.of(cd, "wads")), "original CD not available (llamamod.cd)"); + return Bases.fromCd(Path.of(cd)); + } + + /** Parsed file: JSON + binary buffer. */ + record Parsed(Map json, byte[] bin) {} + + static Parsed parseGlb(byte[] d) { + ByteBuffer b = ByteBuffer.wrap(d).order(ByteOrder.LITTLE_ENDIAN); + assertEquals(0x46546C67, b.getInt(0), "magic glTF"); + assertEquals(2, b.getInt(4), "version 2"); + assertEquals(d.length, b.getInt(8), "total length"); + int jl = b.getInt(12); + assertEquals(0x4E4F534A, b.getInt(16), "JSON chunk"); + assertEquals(0, jl % 4, "JSON chunk padded"); + int bo = 20 + jl; + int bl = b.getInt(bo); + assertEquals(0x004E4942, b.getInt(bo + 4), "BIN chunk"); + assertEquals(0, bl % 4); + assertEquals(d.length, bo + 8 + bl, "no trailing bytes"); + Map j = (Map) Json.parse(new String(d, 20, jl, StandardCharsets.UTF_8)); + return new Parsed(j, Arrays.copyOfRange(d, bo + 8, bo + 8 + bl)); + } + + static int num(Object o) { + return ((Number) o).intValue(); + } + + static List list(Map m, String k) { + return m.get(k) instanceof List l ? l : List.of(); + } + + static int comps(String type) { + return switch (type) { + case "SCALAR" -> 1; + case "VEC2" -> 2; + case "VEC3" -> 3; + case "VEC4" -> 4; + default -> throw new AssertionError(type); + }; + } + + static int size(int ct) { + return switch (ct) { + case 5121 -> 1; + case 5123 -> 2; + case 5125, 5126 -> 4; + default -> throw new AssertionError("component type " + ct); + }; + } + + /** Checks what the glTF validator would: views, accessors, bounds, indices, normals, images. Returns triangles. */ + static int validate(Parsed p) throws Exception { + Map j = p.json(); + assertEquals("2.0", ((Map) j.get("asset")).get("version")); + Map buffer = (Map) list(j, "buffers").getFirst(); + assertTrue(num(buffer.get("byteLength")) <= p.bin().length); + ByteBuffer bin = ByteBuffer.wrap(p.bin()).order(ByteOrder.LITTLE_ENDIAN); + List views = list(j, "bufferViews"); + for (Object o : views) { + Map v = (Map) o; + int off = num(v.get("byteOffset")); + assertTrue(off >= 0 && off + num(v.get("byteLength")) <= num(buffer.get("byteLength")), "view in buffer"); + } + List accessors = list(j, "accessors"); + int triangles = 0; + for (Object mo : list(j, "meshes")) { + for (Object po : list((Map) mo, "primitives")) { + Map prim = (Map) po; + assertEquals(4, num(prim.get("mode"))); + Map attr = (Map) prim.get("attributes"); + int count = -1; + for (Map.Entry e : attr.entrySet()) { + Map a = (Map) accessors.get(num(e.getValue())); + int n = num(a.get("count")); + if (count < 0) { + count = n; + } + assertEquals(count, n, "all attributes have the same count"); + Map v = (Map) views.get(num(a.get("bufferView"))); + int c = comps((String) a.get("type")); + int ct = num(a.get("componentType")); + assertEquals(0, num(v.get("byteOffset")) % 4, "aligned"); + assertTrue(n * c * size(ct) <= num(v.get("byteLength")), "accessor fits its view"); + int base = num(v.get("byteOffset")); + switch ((String) e.getKey()) { + case "POSITION" -> { + List min = (List) a.get("min"); + List max = (List) a.get("max"); + float[] lo = {Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE}; + float[] hi = {-Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE}; + for (int i = 0; i < n; i++) { + for (int k = 0; k < 3; k++) { + float f = bin.getFloat(base + (i * 3 + k) * 4); + assertTrue(Float.isFinite(f)); + lo[k] = Math.min(lo[k], f); + hi[k] = Math.max(hi[k], f); + } + } + for (int k = 0; k < 3; k++) { + assertEquals(lo[k], ((Number) min.get(k)).floatValue(), "exact min"); + assertEquals(hi[k], ((Number) max.get(k)).floatValue(), "exact max"); + } + } + case "NORMAL" -> { + for (int i = 0; i < n; i++) { + double l = 0; + for (int k = 0; k < 3; k++) { + float f = bin.getFloat(base + (i * 3 + k) * 4); + l += f * f; + } + assertEquals(1, Math.sqrt(l), 1e-3, "unit normal"); + } + } + case "TEXCOORD_0" -> { + for (int i = 0; i < n * 2; i++) { + float f = bin.getFloat(base + i * 4); + assertTrue(f >= -1e-4 && f <= 1.0001f, "uv on the page: " + f); + } + } + case "COLOR_0" -> { + assertEquals(5121, ct); + assertEquals(Boolean.TRUE, a.get("normalized")); + } + default -> throw new AssertionError("unexpected attribute " + e.getKey()); + } + } + Map ia = (Map) accessors.get(num(prim.get("indices"))); + int in = num(ia.get("count")); + assertEquals(0, in % 3); + Map iv = (Map) views.get(num(ia.get("bufferView"))); + assertEquals(34963, num(iv.get("target"))); + int ct = num(ia.get("componentType")); + int base = num(iv.get("byteOffset")); + for (int i = 0; i < in; i++) { + long ix = ct == 5123 ? bin.getShort(base + i * 2) & 0xffff : bin.getInt(base + i * 4) & 0xffffffffL; + assertTrue(ix < count, "index in range"); + } + triangles += in / 3; + int mi = num(prim.get("material")); + assertTrue(mi < list(j, "materials").size()); + } + } + for (Object mo : list(j, "materials")) { + Map pbr = (Map) ((Map) mo).get("pbrMetallicRoughness"); + if (pbr.get("baseColorTexture") instanceof Map t) { + assertTrue(num(t.get("index")) < list(j, "textures").size()); + } + } + for (Object io : list(j, "images")) { + Map img = (Map) io; + assertEquals("image/png", img.get("mimeType")); + Map v = (Map) views.get(num(img.get("bufferView"))); + BufferedImage bi = + ImageIO.read(new ByteArrayInputStream(p.bin(), num(v.get("byteOffset")), num(v.get("byteLength")))); + assertNotNull(bi, "PNG decodes"); + assertTrue(bi.getWidth() > 0 && bi.getHeight() > 0); + } + for (Object no : list(j, "nodes")) { + assertTrue(num(((Map) no).get("mesh")) < list(j, "meshes").size()); + } + return triangles; + } + + @Test + void villageExportsAsValidGlbAndGltf() throws Exception { + Project pr = Project.create(cd(), "edit", "t1l1m001"); + Scene s = pr.scene(); + GltfExport.Geometry g = GltfExport.collect(s, new GltfExport.Options(false, false), n -> false); + assertTrue(g.triangles() > 20000, "village triangles: " + g.triangles()); + byte[] glb = g.glb(); + Parsed p = parseGlb(glb); + assertEquals(g.triangles(), validate(p)); + assertTrue(list(p.json(), "images").size() > 5, "texture pages"); + assertTrue(list(p.json(), "materials").size() > 3); + // vertex positions cover the tiles' cells (export space: z ≤ 0) + double[] lo = {1e9, 1e9, 1e9}; + double[] hi = {-1e9, -1e9, -1e9}; + for (Object a : list(p.json(), "accessors")) { + Map m = (Map) a; + if (m.get("min") instanceof List mn) { + List mx = (List) m.get("max"); + for (int k = 0; k < 3; k++) { + lo[k] = Math.min(lo[k], ((Number) mn.get(k)).doubleValue()); + hi[k] = Math.max(hi[k], ((Number) mx.get(k)).doubleValue()); + } + } + } + List drawn = s.tiles().stream() + .filter(t -> t.model() != null && t.model().faceCount() > 0) + .toList(); + double tx0 = drawn.stream().mapToDouble(Tile::x).min().orElseThrow(); + double tx1 = drawn.stream().mapToDouble(Tile::x).max().orElseThrow(); + double tz0 = drawn.stream().mapToDouble(Tile::z).min().orElseThrow(); + assertTrue(lo[0] < tx0 + 1 && hi[0] > tx1 - 1, "x range " + lo[0] + ".." + hi[0]); + assertTrue(lo[2] < tz0 + 1 && hi[2] <= 3, "export-space z " + lo[2] + ".." + hi[2]); + + // .gltf: same content, buffer as data URI + Map j = (Map) Json.parse(new String(g.gltf(), StandardCharsets.UTF_8)); + String uri = (String) ((Map) list(j, "buffers").getFirst()).get("uri"); + assertTrue(uri.startsWith("data:application/octet-stream;base64,")); + byte[] bin = Base64.getDecoder().decode(uri.substring(uri.indexOf(',') + 1)); + assertEquals(g.triangles(), validate(new Parsed(j, bin))); + + // round trip through the editor's own importer (file space = export space, game z = −z) + MeshData md = MeshImport.parse("v.glb", glb, f -> null, "y", 1); + assertEquals(g.triangles(), md.triangleCount()); + double[] b = md.bounds(); + assertEquals(lo[0], b[0], 1e-3); + assertEquals(hi[0], b[3], 1e-3); + assertEquals(-hi[2], b[2], 1e-3); + assertEquals(-lo[2], b[5], 1e-3); + assertTrue(md.materialList().stream().filter(m -> m.image() != null).count() > 5, "textures read back"); + assertNotNull(md.colors(), "vertex colours read back"); + + // game orientation: z mirrored, same triangles + GltfExport.Geometry m = GltfExport.collect(s, new GltfExport.Options(false, true), n -> false); + assertEquals(g.triangles(), m.triangles()); + double[] mb = MeshImport.parse("m.glb", m.glb(), f -> null, "y", 1).bounds(); + assertEquals(-b[5], mb[2], 1e-3); + assertEquals(-b[2], mb[5], 1e-3); + assertEquals(b[0], mb[0], 1e-3); + GltfExport.Geometry o = GltfExport.collect(s, new GltfExport.Options(true, false), n -> false); + assertTrue(o.triangles() > g.triangles(), "objects add triangles"); + assertEquals(o.triangles(), validate(parseGlb(o.glb()))); + } + + @Test + void brushesAndExcludedTiles() throws Exception { + Scene s = Project.create(cd(), "new", "t1l1m001").scene(); + Edits.addBrush(s, BrushKind.BOX, Map.of("x0", 10.0, "z0", 10.0, "x1", 12.0, "z1", 13.0, "y0", 0.0, "y1", 1.0)) + .apply(s); + GltfExport.Geometry g = GltfExport.collect(s, new GltfExport.Options(false, false), n -> false); + Parsed p = parseGlb(g.glb()); + assertEquals(g.triangles(), validate(p)); + assertTrue(g.triangles() >= 10, "box faces: " + g.triangles()); + MeshData md = MeshImport.parse("b.glb", g.glb(), f -> null, "y", 1); + double[] b = md.bounds(); + assertEquals(10, b[0], 1e-3); + assertEquals(12, b[3], 1e-3); + assertEquals(1, b[4], 1e-3); + // hidden brush left out + GltfExport.Geometry none = GltfExport.collect(s, new GltfExport.Options(false, false), n -> true); + assertEquals(0, none.triangles()); + } + + @Test + void excludedTilesAreLeftOut() throws Exception { + Scene s = Project.create(cd(), "edit", "t1l1m001").scene(); + int all = GltfExport.collect(s, new GltfExport.Options(false, false), n -> false) + .triangles(); + Tile t = s.tiles().stream() + .filter(x -> x.model() != null && x.model().faceCount() > 4) + .findFirst() + .orElseThrow(); + t.prop("excluded").setRaw(t, true); + int less = GltfExport.collect(s, new GltfExport.Options(false, false), n -> false) + .triangles(); + assertTrue(less < all && less >= all - t.model().faceCount(), all + " → " + less); + } +} diff --git a/src/test/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfSample.java b/src/test/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfSample.java new file mode 100644 index 0000000..87d4334 --- /dev/null +++ b/src/test/java/com/eliasmueller/llamamod/editor/tools/gltf/GltfSample.java @@ -0,0 +1,27 @@ +package com.eliasmueller.llamamod.editor.tools.gltf; + +import com.eliasmueller.llamamod.editor.io.Bases; +import com.eliasmueller.llamamod.editor.io.Project; +import com.eliasmueller.llamamod.editor.model.Scene; +import java.nio.file.Files; +import java.nio.file.Path; + +/** Writes sample exports for external validation: GltfSample CD OUTDIR level... (not a unit test). */ +public final class GltfSample { + private GltfSample() {} + + public static void main(String[] a) throws Exception { + Bases cd = Bases.fromCd(Path.of(a[0])); + Path out = Files.createDirectories(Path.of(a[1])); + for (int i = 2; i < a.length; i++) { + Scene s = Project.create(cd, "edit", a[i]).scene(); + GltfExport.Geometry g = GltfExport.collect(s, new GltfExport.Options(true, false), n -> false); + Files.write(out.resolve(a[i] + ".glb"), g.glb()); + Files.write(out.resolve(a[i] + ".gltf"), g.gltf()); + GltfExport.Geometry m = GltfExport.collect(s, new GltfExport.Options(false, true), n -> false); + Files.write(out.resolve(a[i] + "_game.glb"), m.glb()); + System.out.println(a[i] + ": " + g.triangles() + " triangles, " + g.vertices() + " vertices, " + + g.primitives() + " primitives"); + } + } +} diff --git a/src/test/java/com/eliasmueller/llamamod/editor/ui/view/GlLeakCheck.java b/src/test/java/com/eliasmueller/llamamod/editor/ui/view/GlLeakCheck.java new file mode 100644 index 0000000..0e139c5 --- /dev/null +++ b/src/test/java/com/eliasmueller/llamamod/editor/ui/view/GlLeakCheck.java @@ -0,0 +1,85 @@ +package com.eliasmueller.llamamod.editor.ui.view; + +import com.eliasmueller.llamamod.editor.io.Bases; +import com.eliasmueller.llamamod.editor.io.Project; +import com.eliasmueller.llamamod.editor.model.Scene; +import com.eliasmueller.llamamod.editor.model.Strat; +import com.eliasmueller.llamamod.editor.model.Tile; +import com.eliasmueller.llamamod.editor.model.cmd.Edits; +import com.eliasmueller.llamamod.editor.model.cmd.History; +import com.eliasmueller.llamamod.editor.render.Viewport; +import java.awt.Dimension; +import java.nio.file.Path; +import java.util.List; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +/** + * Not a unit test: on an X display, switches levels and edits while rendering and prints the live + * GL buffer count (should return to the same value per level). Args: CD folder, levels... + */ +public final class GlLeakCheck { + private GlLeakCheck() {} + + static void edt(Runnable r) throws Exception { + SwingUtilities.invokeAndWait(r); + } + + public static void main(String[] a) throws Exception { + Bases cd = Bases.fromCd(Path.of(a[0])); + SceneRenderer sr = new SceneRenderer(); + Viewport vp = new Viewport(); + edt(() -> { + JFrame f = new JFrame("leak check"); + vp.setPreferredSize(new Dimension(800, 500)); + f.add(vp); + f.pack(); + f.setVisible(true); + vp.setScene(sr.renderScene()); + }); + Thread.sleep(2000); + for (int round = 0; round < 3; round++) { + for (int i = 1; i < a.length; i++) { + Scene s = Project.create(cd, "edit", a[i]).scene(); + edt(() -> { + sr.setScene(s); + vp.frameAll(); + vp.renderNow(); + }); + Thread.sleep(300); + edt(vp::renderNow); + int afterLoad = Viewport.liveGlBuffers(); + // edits: move tiles and objects, delete/undo, while rendering + History h = new History(s); + s.addListener(sr::sceneChanged); + List tiles = s.tiles().subList(0, 40); + List strats = s.strats(); + for (int k = 0; k < 60; k++) { + int kk = k; + edt(() -> { + h.execute(Edits.translate(tiles, kk % 2 == 0 ? 1 : -1, 0, 0, null)); + if (!strats.isEmpty()) { + h.execute(Edits.translate(List.of(strats.get(kk % strats.size())), 0, 0.1, 0, null)); + } + h.execute(Edits.delete(s, List.of(tiles.get(kk % tiles.size())))); + h.undo(); + sr.flush(); + vp.renderNow(); + }); + } + edt(vp::renderNow); + System.out.printf( + "round %d %s: after load %d, after 60 edit rounds %d%n", + round, a[i], afterLoad, Viewport.liveGlBuffers()); + } + } + edt(() -> { + sr.setScene(null); + vp.renderNow(); + }); + Thread.sleep(300); + edt(vp::renderNow); + System.out.println("no level: " + Viewport.liveGlBuffers()); + System.exit(0); + } +} diff --git a/src/test/java/com/eliasmueller/llamamod/editor/ui/view/SceneRendererIdsTest.java b/src/test/java/com/eliasmueller/llamamod/editor/ui/view/SceneRendererIdsTest.java new file mode 100644 index 0000000..bd2d64c --- /dev/null +++ b/src/test/java/com/eliasmueller/llamamod/editor/ui/view/SceneRendererIdsTest.java @@ -0,0 +1,92 @@ +package com.eliasmueller.llamamod.editor.ui.view; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import com.eliasmueller.llamamod.editor.io.Bases; +import com.eliasmueller.llamamod.editor.io.Project; +import com.eliasmueller.llamamod.editor.model.NodeKind; +import com.eliasmueller.llamamod.editor.model.Scene; +import com.eliasmueller.llamamod.editor.model.Tile; +import com.eliasmueller.llamamod.editor.model.cmd.AddNode; +import com.eliasmueller.llamamod.editor.model.cmd.Edits; +import com.eliasmueller.llamamod.editor.model.cmd.History; +import com.eliasmueller.llamamod.editor.render.RenderInstance; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** Pick ids of deleted nodes are dropped (bounded); "no collision" tiles have no collision overlay. */ +class SceneRendererIdsTest { + private static Scene village() throws Exception { + String cd = System.getProperty("llamamod.cd", ""); + assumeTrue(!cd.isEmpty() && Files.isDirectory(Path.of(cd, "wads")), "original CD not available"); + return Project.create(Bases.fromCd(Path.of(cd)), "edit", "t1l1m001").scene(); + } + + @Test + void idsOfDeletedNodesAreDropped() throws Exception { + Scene s = village(); + SceneRenderer r = new SceneRenderer(); + r.setScene(s); + s.addListener(r::sceneChanged); + History h = new History(s); + int start = r.assignedIds(); + Tile keep = s.tiles().get(7); + int keepId = r.idOf(keep); + for (int i = 0; i < 1000; i++) { + Tile t = (Tile) s.create(NodeKind.TILE); + t.setRaw("x", 3.5); + t.setRaw("y", 0.0); + t.setRaw("z", -3.5); + t.setRaw("model", keep.model()); + h.execute(new AddNode(t)); + r.flush(); + h.execute(Edits.delete(s, List.of(t))); + r.flush(); + } + assertTrue(r.assignedIds() < start + 300, "bounded: " + r.assignedIds() + " vs " + start); + assertEquals(keepId, r.idOf(keep), "ids of live nodes are stable"); + assertEquals(keep, r.nodeOf(keepId)); + // a deleted tile that comes back by undo gets a working id again + Tile victim = s.tiles().get(9); + int old = r.idOf(victim); + for (int i = 0; i < 300; i++) { + h.execute(Edits.delete(s, List.of(victim))); + r.flush(); + h.undo(); + r.flush(); + } + int now = r.idOf(victim); + assertNotEquals(0, now); + assertEquals(victim, r.nodeOf(now)); + RenderInstance ri = r.renderScene().instance(now); + assertTrue(ri != null && ri.visible); + if (now != old) { + assertNull(r.nodeOf(old), "old id forgotten"); + } + } + + @Test + void noCollisionTilesHaveNoCollisionOverlay() throws Exception { + Scene s = village(); + SceneRenderer r = new SceneRenderer(); + r.setScene(s); + s.addListener(r::sceneChanged); + Tile t = s.tiles().stream() + .filter(x -> x.model() != null && x.model().collisionCount() > 0) + .findFirst() + .orElseThrow(); + RenderInstance ri = r.renderScene().instance(r.idOf(t)); + assertTrue(ri.mesh.overlay != null); + new History(s).execute(com.eliasmueller.llamamod.editor.model.cmd.SetProp.of(t, "noCollision", true)); + r.flush(); + RenderInstance after = r.renderScene().instance(r.idOf(t)); + assertNull(after.mesh.overlay); + assertEquals(ri.mesh.triangleCount(), after.mesh.triangleCount()); + } +}