Commit Graph

70 Commits

Author SHA1 Message Date
Brandon Thomas a4f32f8df2 Merge main into M13.5 long-tail polish
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 00:25:09 -04:00
Brandon Thomas 7537eea85c M13.5: Animate Text > Variable Font Axes
Text: text.animatorFontAxes (replaces the stub) lists the layer font's
variation axes (skrifa) or adds an animator property that offsets one axis
(weighted by the selectors, from the axis default); the renderer redraws each
character's outline at its design-space position (cached per location). The
Timeline's Animate: menu lists the font's axes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 00:24:05 -04:00
Brandon Thomas 1ebfef77c4 M13.5: vertical Roman, tate-chu-yoko, forced LTR, animated caret, Lottie style runs
Text: vertical type turns Roman characters on their side (CJK stays
upright) unless Standard Vertical Roman Alignment is on; Tate-Chu-Yoko sets
selected characters horizontally in a one-em cell of the column (layer.setText
tateChuYoko / verticalRomanUpright, Character panel toggles). A Left-to-Right
paragraph is now forced LTR instead of auto-detected. The editing caret follows
animators and text on a path (render::text::caret_maps). Lottie export writes
per-character style runs as index-unit range animators.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 00:01:24 -04:00
Brandon Thomas dbcda2eba9 Merge main into CMP-7/ANM-5/PRJ-8/PRJ-3 work
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:43:41 -04:00
Brandon Thomas 85c645f337 M13.5: camera iris bokeh depth of field and focus-link commands
3D-1: Classic 3D depth of field renders the camera's Iris Shape (Fast
Rectangle box or Triangle…Decagon polygon), Iris Rotation, Roundness, Aspect
Ratio and Diffraction Fringe as a span-kernel gather blur, with Highlight
Gain/Threshold/Saturation boosting highlights first; tilted layers blur
progressively by per-pixel camera depth. Layer > Camera > Link Focus Distance
to Point of Interest / to Layer (expressions) and Set Focus Distance to Layer
replace the stubs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:35:03 -04:00
Brandon Thomas bbaee1fa0f M13.5: stroke taper/wave/multi-dashes, radial gradient highlight, variable-width mask feather, adaptive motion-blur samples
Shapes (SHP-2): Stroke Taper (pixels/percent start/end length, width, ease) and
Wave (amount, pixels/cycles, wavelength, phase) rendered as a variable-width
outline; Dash 2/Gap 2/Dash 3/Gap 3 (shape.dashes.add/remove, timeline +/-
buttons); radial gradient Highlight Length/Angle as a focal gradient.
Masks (MSK-1): mask feather points on the Mask Path (mask.featherPoint.*,
Mask Feather tool add/drag), per-point signed radius and tension, rendered
from the signed distance to the path; carried through vertex edits.
Motion blur (LYR-10): Adaptive Sample Limit comp setting; 2D layers take one
sample per pixel of shutter travel between Samples Per Frame and the limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:22:53 -04:00
Brandon Thomas c33b80614a PRJ-8: proxies — Set Proxy / None / Use Proxy / Create Proxy / Interpret Proxy, Proxy Use; PRJ-3 interpret fields, PAR, alpha guess
Items (footage and comps) carry a proxy rendered in their place at the source's size when
its switch and Render Settings > Proxy Use allow it; Create Proxy queues a half-resolution
render whose post-render action attaches it. Interpret Footage gains Separate Fields
(upper/lower first, fields become frames at twice the rate), Guess alpha with matte colour,
explicit matte colour, Invert Alpha, Interpret As Linear Light; non-square footage, solids
and precomps are stretched by their pixel aspect in the comp. The four proxy stubs are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:11:03 -04:00
Brandon Thomas 6d0d7de922 ANM-5: sampleImage, data footage (JSON/CSV/TSV) with footage().sourceData, thisProject, error list, Expression Language menu
sampleImage renders the sampled layer through the evaluating renderer's footage source
(EvalCtx::footage), cached per thread and frame. File > Import reads .json/.csv/.tsv as data
footage kept in the project. expr.errors collects failing expressions for the error bar;
expr.languageMenu lists the categorised Expression Language menu. Marker keys expose
protectedRegion and cue points; colorDepth, timeToFeetAndFrames, comp.activeCamera.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:58:04 -04:00
Brandon Thomas abd39f5fd8 CMP-7: Essential Graphics controls, master properties, .ectemplate templates, Responsive Design — Time
Comps expose controls (properties typed as text/color/slider/checkbox/point/angle/dropdown,
Media Replacement, groups, comments); precomp layers get an Essential Properties group whose
edits override per instance (Push to Comp / Revert); templates export/import as an open ZIP
(manifest.json + project subset + media + poster). Stretched precomps keep protected regions
at their original speed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:44:06 -04:00
Brandon Thomas 36683d95ee Merge main into IO-2/SHP-5/OUT-2/PRV-2 work
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:39:47 -04:00
Brandon Thomas 94e1c86d89 IO-2/SHP-5/PRV-2: PSD import, SVG import + vector/text conversions, persistent disk cache
- effectcraft-psd (L1): PSD/PSB reader from Adobe's published file format spec (layers, groups,
  masks, blend modes, text engine data, lfx2 effects, fill/adjustment layers, vector masks;
  1/8/16/32-bit, RGB/CMYK/Gray/Lab/Indexed, raw/RLE/ZIP) and a minimal writer for fixtures.
- File > Import: importAs footage|composition|compositionLayerSizes, layer (Choose Layer);
  groups -> precomps (pass-through collapses), text -> editable text, styles -> Layer Styles,
  adjustments -> adjustment layers with effects; UI asks the Import Kind for Photoshop files.
- effectcraft-svg (L2): SVG parser (shapes, paths, transforms, use, CSS, gradients) and
  rasteriser; .svg imports as footage, continuously rasterised when the switch is on.
- layer.create: shapesFromVector, shapesFromText, masksFromText, editableText (stub removed).
- Disk cache (render::disk_cache): LZ4 content-keyed frames and layer buffers, LRU size limit
  from prefs, atomic writes, restart persistence; edit.purge clears it, cache.diskStats query;
  viewer frames read/write it and the timeline shows disk-only frames in blue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:10:48 -04:00
Brandon Thomas a51f439d34 Merge branch 'main' into worktree-agent-a758de7c5b6efcc3d
# Conflicts:
#	crates/effects/src/lib.rs
#	crates/render/src/lib.rs
#	docs/parity.md
2026-10-02 21:48:49 -04:00
Brandon Thomas 79ad7e1843 M7.6: extrusion + primitives
Extruded text keeps per-character 3D: each glyph's outline is extruded in its own space and
placed by its animated matrix; shape layers extrude their fill outlines (gradients use their
mid colour). Shadow-map bias scales with the texel footprint at the receiver and the PCF
reach (no acne on curved casters), identically on CPU and GPU. Docs: Advanced 3D in
architecture.md, parity table updated (3D, Text).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:36:59 -04:00
Brandon Thomas 9a11c577f3 M9.11: 3D Channel effects on auxiliary channels
Aux-channel model (effectcraft_raster::channels3d: depth, object/material
ID, normals, UV, coverage, Cryptomatte ranks + manifests, MurmurHash3);
EffectHost::aux; multi-layer OpenEXR channels via the exr crate
(FootageSource::aux); the compositor's depth / layer-ID / Cryptomatte pass
(Renderer::comp_aux) so the effects work on precomps of 3D comps.
3D Channel Extract, Cryptomatte, Depth Matte, Depth of Field, EXtractoR,
Fog 3D, ID Matte, IDentifier.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:28:37 -04:00
Brandon Thomas dec091e575 M7.5: advanced 3D renderer
Advanced 3D comps render their 3D runs as one scene of world-space triangles: model and
primitive layers (meshes, skinning, animation clips by layer time), extruded text/shape
layers, and textured cards for every other layer with their Material Options. Shading is
physically based in linear light: Cook-Torrance GGX + Lambert for parallel/spot/point lights
(AE falloff and cone), ambient lights, image-based light from an Environment light's layer
(equirectangular; cosine irradiance map + roughness mip chain + split-sum BRDF fit), and
PCF shadow maps (spot/parallel/point cube faces). 2x2 SSAA, depth of field as a gather blur
by circle of confusion, back to the working encoding.

The software rasteriser (depth buffer, top-left rule, perspective-correct, opaque visibility
then sorted transparent blending) is the reference and CI path; effectcraft-gpu implements
Accelerator::raster_3d with a wgpu render pipeline (advanced3d.wgsl) and matches it within
tolerance. Environment layers are hidden from both renderers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:27:59 -04:00
Brandon Thomas 83c7e14b94 M7.4: model import
New crate effectcraft-model (L2): glTF 2.0 (.gltf/.glb, data URIs, external buffers and
images, PBR metallic-roughness with base/MR/normal/occlusion/emissive textures, node
hierarchy, skins, step/linear/cubic animations) and OBJ/MTL import, parametric primitives,
extruded/bevelled outline meshes and polygon triangulation with holes.

Project: FootageKind::Model, LayerSource::Model/Primitive, Layer::environment, Geometry and
Material Options builders, Environment light Source. Media probes and loads models
(FootageSource::model). Engine: layer.newModel, layer.new3dPrimitive/newPrimitive,
comp.renderer, layer.environment, material.set/reset/duplicateAssign/revealSource (stubs
replaced); File > Import and layer.addItem pick up models. Hand-written fixtures with
attribution sidecars.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:04:47 -04:00
Brandon Thomas fe81588867 M9.11: OCIO transforms, Color Stabilizer and Color Profile Converter
Built-in minimal OCIO config (ACES2065-1, ACEScg, ACEScct, sRGB, Rec.709,
Rec.2020, Display P3, linear variants, XYZ) from published primaries,
transfer functions and Bradford adaptation; CDL v1.2 maths; .cube/.3dl/.csp
and .cc/.ccc/.cdl file transforms with nearest/trilinear/tetrahedral
interpolation and inverse; displays/views/looks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:46:53 -04:00
Brandon Thomas 97cf7e2c02 M9.11: Audio effects (Compressor, Distortion, Gate)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:39:38 -04:00
Brandon Thomas 41a796155f M12.2: test that the Auto backend keeps 3D comps on the CPU compositor
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:06:18 -04:00
Brandon Thomas 81c9a16592 Merge main (M12.2 GPU compositor) into perf-bpc
Keeps the GPU's public placement() API (motion-blur sample count now
shared via mb_samples) and the footprint-limited quantisation; the CPU
fallback helpers draw_layer_cpu / draw_collapsed_cpu pass blank = false.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 11:25:01 -04:00
Brandon Thomas a751a1cda9 Merge branch 'worktree-agent-a773c6d272696f48a' (M12.2 GPU compositor)
Auto backend keeps comps with 3D layers on the CPU compositor (3D runs are
still CPU-composited; the GPU round-trip made them slower).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 11:16:42 -04:00
Brandon Thomas a438974758 M12.2: merge main (ROI, viewer tools); gate GPU display textures
Region-of-interest frames render on the CPU path; the viewer keeps main's
frame drawing (Show Channel, exposure, ROI) and reads GPU-composited frames
back. Keeping frames as native egui-wgpu textures stays implemented behind
RenderSource::gpu_display (off).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 11:14:18 -04:00
Brandon Thomas 5c9038cbee Merge main into perf-bpc 2026-10-02 11:11:10 -04:00
Brandon Thomas 40321f963b M12.4: fast bit-depth quantization
8/16 bpc no longer re-quantises the whole comp after every layer: 2D layers
report the canvas region they can change (transformed buffer bounds plus the
resampling margin; stencil modes, motion blur, perspective, styles,
adjustment and 3D runs fall back to the full canvas), and only that region
is quantised. A quantised buffer placed pixel-exactly (integer translation,
Normal, 100%) over a blank canvas needs nothing; invisible layers need
nothing; collapsed precomps quantise per nested layer. The redundant final
comp pass is skipped unless the comp is re-encoded. Solids are filled with a
pre-quantised colour and skip the source pass unless masked. Row-parallel
vectorisable kernel. Debug builds verify every pixel outside the region is
already quantised (whole workspace test suite run with 8 bpc forced: no
violations).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 11:11:10 -04:00
Brandon Thomas 485f562e19 M12.2: gpu compositor and gpu effects
New L3 crate effectcraft-gpu: a wgpu compute backend for the per-frame
compositing walk (layer transforms with the CPU's nearest/bilinear/bicubic
sampling and minification pre-filter, motion-blur accumulation, track
mattes, Preserve Transparency, layer style passes and knockout, all 38
blend modes as a WGSL port of color::blend, 8/16 bpc clamp+quantise,
colour-space conversions). 3D runs, adjustment and wireframe layers run on
the CPU between GPU steps. GPU effects with the CPU semantics: Gaussian,
Fast Box and Directional Blur, Glow, Levels, Curves, Hue/Saturation, Tint,
Fill, Gradient Ramp, Fractal Noise, Drop Shadow, Brightness & Contrast,
Exposure, Invert, Transform (registry gpu badge from effects::GPU_EFFECTS).

render: Backend (Cpu/Gpu/Auto) in RenderOpts, the Accelerator trait and
Renderer::accel, GPU effect chains in the effect stack, hooks for the GPU
walk. Project setting gpu_acceleration (Mercury GPU Acceleration / Software
Only), render.backend command, file.projectSettings renderer. Session and
Render Queue exports carry the accelerator. CLI --gpu and bench --gpu.

Tests compare GPU vs CPU renders (blend modes x bit depths, transforms,
masks, mattes, motion blur, colour management, styles, collapse,
adjustment fallback, every GPU effect) and skip without an adapter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:59:08 -04:00
Brandon Thomas 460e650bfc Merge main into text editing (M9.10)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:46:31 -04:00
Brandon Thomas f78435927b M9.9: text style runs + paragraph settings
TextDoc gains character style runs (font, size, colours, tracking, leading,
baseline shift, h/v scale, tsume, faux styles, caps, super/subscript, kerning
metrics/optical/manual, ligatures) and per-paragraph settings (justification
with last-line modes, indents, space before/after, direction, composer,
hanging punctuation), serde-compatible with single-style documents. Layout
handles mixed runs on a line (shared baseline, largest leading), every-line
composer, editing geometry (carets, hit testing, selection quads) and basic
vertical type. Renderer colours per run. Expressions get the sourceText style
API (style, getStyleAt, createStyle, setters with character ranges).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:34:13 -04:00
Brandon Thomas 2e9938929e Merge branch 'worktree-agent-ad1b692cafaa1598a'
# Conflicts:
#	crates/render/src/lib.rs
2026-10-02 10:32:51 -04:00
Brandon Thomas 468dc13cfe M0.13: viewer snapping, rulers, channels, snapshots, ROI
Composition viewer interaction parity with After Effects:
- Snapping (View > Snapping, the Tools bar checkbox, Cmd/Ctrl inverts while
  dragging): layer edges, centres and anchor points, mask and shape-path
  vertices, comp edges/centre, guides (Snap to Guides) and grid (Snap to
  Grid), with highlighted target box / line / cross feedback. Pure maths in
  engine::viewer (nearest target within tolerance, priority ties).
- Rulers (Cmd+R) with live pointer markers and a draggable zero point;
  guides dragged out of the rulers, moved in the viewer, dragged off to
  remove (view.moveGuide / view.removeGuide), lock respected; proportional
  grid.
- Show Channel (RGB/Red/Green/Blue/Alpha/RGB Straight, Colorize), exposure
  (+/- stops in linear light, reset), Take Snapshot (Shift+F5) with a stored
  render and Show Snapshot (F5 held / button held), Fast Previews (Off,
  Adaptive Resolution, Draft, Fast Draft, Wireframe), Resolution > Custom.
- Region of interest: drawn in the viewer; RenderOpts.roi renders only that
  rectangle (crop of the full render, tested), Crop Comp to ROI uses it.
- Bottom bar in AE 2026 order ("136.1 %", "(Full)").
- Shape Pen (SHP-1): Pen on a shape layer / nothing selected draws Shape n
  groups (Path 1, Stroke 1, Fill 1) via shape.newPath; the G slot cycles
  Add / Delete / Convert Vertex and Mask Feather; mask.* vertex commands
  work on shape paths; mask.insertVertex / mask.convertVertex; marquee
  vertex selection, Alt-drag/click converts, double-click free transform
  box (path.freeTransform on masks and shape paths).
- Motion paths (ANM-3): keyframe dots and spatial tangent handles, dragging
  keys (keys.set) and tangents (keys.setSpatialTangents), parented layers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:16:05 -04:00
Brandon Thomas adf5db6397 M4.4: collapse transformations + slip
Collapsed precomps draw their layers straight into the parent with
concatenated transforms and multiplied opacity (nested blend modes and
adjustment layers act on the parent); a non-Normal mode, track matte or
Preserve Transparency composites the collapsed result as a whole; masks,
effects or styles force a flattened render. Nested 3D layers use the
parent's camera and lights and join the parent's 3D run when the precomp
layer is 3D. Continuously Rasterize re-rasterises text and shape layers at
their on-screen scale. Draft quality samples nearest-neighbour, Wireframe
draws the layer bounds. layer.slip / slipBack (Alt+PageUp) / slipForward
(Alt+PageDown) and dragging the timeline source bar slip the source under
fixed in/out points, clamped to the source duration; undoable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:14:53 -04:00
Brandon Thomas bfa21e3222 M4.3: frame blending
Frame Mix and Pixel Motion for footage and precomp layers when the layer's
Frame Blending switch and the comp's Enable Frame Blending are on and the
source time falls between source frames (rate conform, time stretch, time
remap). Exact frame positions from tick arithmetic. Pixel Motion is a
hierarchical block-matching optical flow (SAD search, sub-pixel parabola
fit, vector median) with a bidirectional warp-blend (raster::flow). Blended
footage frames are cached.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:05:52 -04:00
Brandon Thomas 029c0da5e5 M2.4: bit depth + linear blending + working space
8/16 bpc projects clamp and quantise layer pixels after source/masks and
every effect, and the comp after every layer (16 bpc = 0..32768); 32 bpc
keeps over-range values. Blend modes without HDR support clamp their inputs
in 32 bpc. Working space (sRGB, Rec. 709, Rec. 2020, Display P3; matrices
derived from the published primaries), footage colour profiles from stream
metadata or Interpret Footage, Linearize Working Space and Blend Colors Using
1.0 Gamma. Layer cache keys include the colour settings. Project panel depth
button: click cycles, Alt-click opens Project Settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:03:36 -04:00
Brandon Thomas e1f72413e0 Merge branch 'worktree-agent-a94e35b1679a89a56'
# Conflicts:
#	README.md
#	crates/engine/Cargo.toml
#	crates/engine/src/commands/mod.rs
#	crates/engine/src/lib.rs
#	crates/ui-egui/src/panels/viewer.rs
2026-10-02 09:26:35 -04:00
Brandon Thomas 22346f2949 Merge branch 'worktree-agent-a798505697e9a8db3'
# Conflicts:
#	crates/engine/src/commands/mod.rs
#	crates/engine/src/lib.rs
#	crates/ui-egui/src/lib.rs
2026-10-02 09:23:25 -04:00
Brandon Thomas 54e62c0c88 Merge branch 'worktree-agent-a70a415ce57f73911'
# Conflicts:
#	crates/engine/src/commands/mod.rs
#	crates/engine/src/lib.rs
#	crates/ui-egui/src/panels/effect_controls.rs
#	crates/ui-egui/src/panels/mod.rs
#	crates/ui-egui/src/state.rs
2026-10-02 09:22:05 -04:00
Brandon Thomas 7523898705 Merge branch 'worktree-agent-a128c7366e475da55' 2026-10-02 09:17:05 -04:00
Brandon Thomas 799b5b39ed M3.8: stub burn-down
Implement 20 formerly disabled menu stubs: Look at Selected/All Layers
(2D viewer fit, 3D view cameras, active camera), Switch View Layout (1/2/4
views in the viewer) and Share View Options, Create Camera from 3D View,
Add Output Module (every module encodes the item's frames), Pre-render
(queue + Import & Replace Usage post-render action), Save Current Preview,
RotoBezier / Convert To Bezier Path, Group / Ungroup Shapes, Set First
Vertex, Free Transform Points, mask Motion Blur (sub-frame mask samples),
Feather Falloff (smooth/linear), Hide Locked Masks, and workspace
save / save as / edit. Tests incl. undo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:16:42 -04:00
Brandon Thomas 47f7712364 M14.2: preferences
A real Settings model in the engine (`engine::prefs`): serde, versioned, dotted keys
(`general.undoLevels`, `labels.3.name`), migration of older layouts, unknown keys kept,
persisted through a `ConfigStore` trait (platform config dir on the desktop; MemoryConfig
for tests; the web app can back it with localStorage).

- After Effects 2026 pages (General … Scripting & Expressions) as a schema shared by the
  dialog, `prefs.pages` and docs/preferences.md (rows not wired yet are listed there and
  kept in step by a test).
- Commands: prefs.get, prefs.set {key, value | values}, prefs.reset {page?}, prefs.open
  {page?}, prefs.pages.
- Wired settings: undo levels, path point size, tool tips, layers at comp start / CTI,
  default spatial interpolation linear, Home screen on launch, new project template,
  rendering progress in Info, adaptive resolution limit, cache when idle, fast previews,
  theme + UI brightness, label names/colours everywhere (Label menu, timeline, project,
  render queue, viewer), label colour for handles, grid colour/spacing/subdivisions, guide
  colour, safe margins, still footage duration, sequence fps, audio output device and
  output mapping, layer / footage / preview cache budgets, default 3D renderer.
- Settings dialog: AE's left page list + right content, OK / Cancel (restores) / Previous /
  Next, every widget with an automation id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:14:45 -04:00
Brandon Thomas d6f6a10757 M13.1/M13.2: paint (Brush, Clone Stamp, Eraser) and puppet pins
Paint: non-destructive Paint effect with Brush/Clone/Eraser stroke groups
(Path, Stroke Options, Transform, Duration spans, Write On End keys),
dab rasterizer (diameter/angle/roundness/hardness/spacing/flow/opacity,
pressure dynamics, modes, channels), eraser modes, clone from layer/time,
cache keys include visible strokes. paint.stroke/options/brushPreset/
setCloneSource/removeStroke/presets. Layer panel with paint tools, Paint
and Brushes panels.

Puppet: Puppet effect with meshes and Position/Advanced/Bend/Starch/Overlap
pins; alpha contour -> expansion (exact EDT) -> simplified outline ->
Delaunay with constraint recovery; ARAP (Igarashi 2005) two-step solve with
CG; anti-aliased texture-mapped rendering with overlap depth. puppet.addPin/
movePin/setPin/removePin/mesh/info. Puppet tools in the viewer with mesh
overlay and header options.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:12:10 -04:00
Brandon Thomas 08a48cc1e3 M9.7: effect controls widgets (EFF-1/EFF-2)
Angle dial with revolutions (0x+45.0°), point crosshair + on-viewer effect
point controls via a small viewer hook, colour eyedropper sampling the
composited frame, Curves graph editor and Levels histogram/triangles bound
to their params, layer params with a Source/Masks/Effects & Masks companion,
mask (Path) popups, keyframe navigator, drag-to-reorder effect headers.

Engine: effect.copy / effect.paste / effect.reset; effect.remove takes the
selection; Edit > Copy/Paste/Duplicate/Clear act on selected effects; all
undoable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:05:17 -04:00
Brandon Thomas 243098a144 M12.3: tracker core
New L2 crate effectcraft-track: per-point feature/search region tracking with
pyramid normalized cross-correlation and Lucas-Kanade (similarity + gain/bias)
sub-pixel refinement, confidence, adapt/stop/extrapolate/continue actions,
RGB/luminance/saturation channels, blur/enhance pre-processing, and
homography/affine/similarity solves.

Project: Motion Trackers > Tracker n > Track Point n property tree
(GroupKind::Tracker with type, target and options). Engine: track.* commands
(new/motion/stabilize/property/select/setType/setTarget/options/setPoint/
analyze/stop/apply/reset/delete/status), background or blocking analysis
job with progress and cancel (one undo step), apply to Transform, Stabilize
and Corner Pin. Renderer::layer_source for the tracker's frames.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 08:28:44 -04:00
Brandon Thomas b85dc6757b Merge branch 'worktree-agent-ac3707915045f047d' 2026-10-02 00:44:39 -04:00
Brandon Thomas db21e880ef Merge main (engine menu tree) into M9.6; wire text animation menus
Animation ▸ Animate Text (Enable Per-character 3D, every animator property,
Fill/Stroke Color RGB/Hue/Saturation/Brightness/Opacity submenus, Line Anchor,
Character Value), Add Text Selector ▸ Range/Wiggly/Expression (text.addSelector
now supports all kinds) and Text Animation Presets after Browse Presets, in the
engine menu tree. Stubs replaced: text.perCharacter3d, animatorLineAnchor,
animatorCharacterValue, addWigglySelector, addExpressionSelector.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:44:20 -04:00
Brandon Thomas 362d12269f Merge branch 'worktree-agent-acb4c3cd3f5057c6a' (M15.1 web build)
Also: render uses web_time::Instant in layer styles; renderQueue.add documents
its render-settings/output-module keys so checked execution accepts them (+test).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:41:56 -04:00
Brandon Thomas 31f192e2a9 M15.1: web build (eframe wasm) + xtask web
- apps/effectcraft-web (L6): eframe web runner booting the shared EffectcraftApp with a browser
  session: in-memory file table, <input type=file> pickers and drag-and-drop for open/import,
  downloads for Save and Render Queue outputs (several files as one stored .zip), and the
  window.effectcraft promise API over the control channel. Demo project on start.
- wasm32 runtime fixes: web-time for Instant/SystemTime (render, engine, export, ui-egui);
  Frames renders queued jobs on the UI thread (Frames::pump) instead of a thread pool;
  Render Queue runs inline; relative outputs resolve under / ; control PNGs inline.
- effectcraft-export: per-job output Sink (files to memory instead of disk); host FileExporter
  carries it; test that sink exports touch no file.
- xtask web [--dev] [--serve PORT] (wasm-bindgen 0.2.129, optional wasm-opt, COOP/COEP server);
  effectcraft-web in WEB_CRATES. docs/web.md, headless Chrome smoke test, favicon (+attribution).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:19:35 -04:00
Brandon Thomas 0b3c12eed1 Merge main (layer styles, engine menu tree) into time/audio branch
Resolve conflicts; register playback.audio (Composition > Preview > Audio)
as a real frontend command replacing its stub; layer_at uses content_buf.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:19:34 -04:00
Brandon Thomas ddb33cdfd0 M11.2: audio playback + waveforms + audio effects
- Audio effects (Backwards, Bass & Treble, Delay, Flange & Chorus,
  High-Low Pass, Modulator, Parametric EQ, Reverb, Stereo Mixer, Tone)
  applied per layer in the comp mixdown, so export and preview share them.
  RBJ-cookbook biquads, Schroeder/Moorer reverb, modulated delay lines;
  stateless per block via pre-roll. Tone makes any layer audible.
- Real-time audio preview: ui-egui AudioFeed/AudioPlayback (feeder thread
  mixing ahead) behind an AudioDevice hook; the desktop app implements it
  with cpal (L6). Audio clock drives playback (consumed frames minus device
  latency, looped through the work area). Preview panel Include Audio /
  playback.muteAudio.
- Audio panel VU meters with peak hold and clip indicators; selected
  layer's Audio Levels.
- Timeline Audio > Waveform for footage with audio (L reveals Audio
  Levels, LL the Waveform), drawn from a cached per-item peak summary.
- ui.playback reports audio state and meter levels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:16:34 -04:00
Brandon Thomas f5f0b7ef52 Merge main into M9.6 text animation branch
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:14:33 -04:00
Brandon Thomas fedb5cb715 M9.6: text animation UI (Animate:/Add: pop-ups, flattened animator rows, path popup, presets, menus)
Timeline: Text group 'Animate:' and animator 'Add:' pop-ups (properties and
Range/Wiggly/Expression selectors), selectors/properties listed directly under
each animator, Path Options ▸ Path lists the layer's masks and hides the
other path options until one is chosen. Properties panel Add Animator lists
every animator property plus Enable Per-character 3D, and a Presets menu.
Animation menu: Animate Text, Add Text Selector, Text Animation Presets.
Expression Selector result replaces the selection (no Mode); selector popups
are non-keyframable like AE.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:12:41 -04:00
Brandon Thomas c5cf189e1a M9.6: text animation depth (selectors, animator properties, per-char 3D, path text, presets)
Range selector complete (units, based on, modes, shapes, smoothness, ease
high/low, randomize), Wiggly and Expression selectors combined by mode;
all AE animator properties incl. line anchor, character offset/value,
skew axis, tracking type, fill/stroke HSB+opacity, blur; More Options
(anchor grouping, fill & stroke order, inter-character blending); Path
Options (text on a mask path); per-character 3D rendered as planes in
the 3D compositor; text animation commands and original presets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:01:19 -04:00