Move the Levels screenshot's ATTRIBUTION row, the README mention, the
architecture note and the snapshot scene to places #36 does not touch, so
the two pull requests merge in either order without conflicts. No change
in behavior; the snapshot scene now runs last.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Selecting a Levels node now shows a visual editor above its sliders: a
histogram of the node's input (256 bins; red, green and blue overlaid for a
color input; scaled to the tallest bin between pure black and white) with
the clipped ranges shaded and the levels transfer curve on top, draggable
input low/mid/high handles under it and output low/high handles under a
black-to-white bar.
Fixes in how Levels is edited: Level in mid is relative to the input range,
and its handle now sits where it acts and moves with the range; the input
low and high handles cannot cross. Parameters bound to inputs or driven by
functions keep their handles locked. Every drag is a graph.node.param
command, one undo step per handle. levels_fn no longer propagates NaN.
Tests cover the histogram, the handle constraints and the remap math; the
snapshots UI test renders the editor. Documented in docs/levels-editor.md.
Clean-room implementation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shift+click adds a wire to the selection and Ctrl+click toggles it. With two
or more wires selected, X swaps where they come from: two wires trade
sources, more reverse them in target-node and input order, so selecting a
Blend node's foreground and background wires and pressing X swaps the two
layers. The wires stay selected, so X again swaps back. Delete and
Backspace remove every selected wire in one undo step, and the wire menu
gains Swap selected links and Delete selected links.
New commands graph.wire.swap and graph.wire.delete take
{wires: [{to, toPort}, ...]}; a swap that would make a cycle is refused and
changes nothing. Engine and UI tests (real clicks on a Blend node) cover
both; docs/wires-and-alpha.md documents the gestures, the ordering rule and
the commands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3D view: the material's alpha (the Opacity output, else the Base color's
alpha channel) now makes the mesh see-through. Rays composite front to back
through up to eight transparent layers and back faces shade toward the
viewer, so the inside of a cut-out mesh and the environment show through.
view.3d takes `transparency` (default on) and `alphaView`; the Display menu
and a bottom-bar button toggle an unlit view of the alpha channel.
Graph editor: click a wire to select it (Delete or Backspace removes it),
drag a wire to pull a reroute Dot out of it, double-click a wire to drop a
Dot there, right-click a wire for Insert reroute dot and Delete link. The
new graph.wire.insertDot command splits a wire with a Dot in one undo step.
Docs: docs/wires-and-alpha.md (gestures, commands, rendering, tests) with
two snapshot screenshots, plus architecture, parity, control protocol,
README and ATTRIBUTION updates.
Clean-room implementation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review: no hardcoded limit. The two MAX_TARGET constants are gone.
- Engine: CameraPrefs { pan_limit, pan_speed } with the defaults in one
place (Default: 5 mesh radii, speed 1), sanitized against NaN and
negative values. Session::set_camera_prefs stores them and pulls the
orbit target back inside a lowered limit; view.3d clamps targets to it;
session.inspect shows it.
- App: Prefs.camera persists with the other preferences (older saved
preferences load the defaults), apply_prefs pushes it into the session,
and Edit > Preferences has "3D pan limit" and "3D pan speed" sliders.
The drag uses the pan speed.
- Renderer: no limit of its own. camera() falls back to the scene center
for a non-finite target and pan() returns the unbounded offset.
The 3D view could only orbit around the mesh center and zoom, so there was
no way to look at an off-center part of a mesh up close.
- View3d gains `target`, the orbit point's offset from the mesh center in
mesh radii (world axes, so orbiting after a pan turns around the new
point). `view.3d {target: [x, y, z]}` sets it, validated before anything
changes and clamped to 5 radii; view.3d.reset clears it.
- The renderer orbits around the offset target, and `pan` turns a drag
(in view heights) into a new target so the mesh follows the pointer.
- Alt+drag or middle-drag pans in the 3D view, like the graph. Double-click
and the Camera presets recenter. The headless render honours the target.
Private repos get 2-core/7 GB standard runners, which can't hold the 12 GB
FreeBSD VM, so the FreeBSD jobs failed and blocked the draft. Turn it back
on once the repo is public.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vectorised with craftrules vectorize_tile.py at the shared Crafting Apps
settings (512 tile, rx=112, ink/paper/#178a9c), with every PNG, .ico and
.icns regenerated by packaging/icons.sh. The README shows the icon, and
the UI accent and web loader use the new teal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- render: an offline hq path (displaced subdivided mesh, ray-traced AO,
shadowed key light, 3x3 supersampling) on a vignette backdrop; the
sphere's UVs wrap twice so texels stay square
- CLI/RPC/MCP render: --tiling, --hq and --displacement
- templates: new painted metal plates, lava rock, polished marble and
wicker weave; reworked brick wall, stone tiles, wood planks and mossy
ground
- README: new material gallery and refreshed screenshots
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README in the Crafting Apps frame with real screenshots and renders made
by MaterialCraft, the agent guide with the asset and clean-room rules, the
attribution list, the parity assessment, gaps, roadmap, architecture,
control protocol, localization and file format docs. Adds the browser build
(trunk), the .ico/.icns icons and centers the 3D camera on the mesh bounds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A clean-room, pure-Rust foundation for MaterialCraft's node-based material
authoring: the package/graph/node model, float image planes, the node
library (atomic nodes, tileable noises, patterns, filters, PBR utilities,
function graphs for the pixel processor), a content-addressed cooking cache,
.mcraft packages and texture export, and the command-driven session with
snapshot undo. Infrastructure (xtask, CI, packaging) copied from TextureCraft.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>