Commit Graph

102 Commits

Author SHA1 Message Date
Brandon Thomas 210ec66ecf M9.3: render tests for effect masks and layer parameters
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:32:50 -04:00
Brandon Thomas b168d902c7 Merge branch 'worktree-agent-a45c0c688bf960993'
# Conflicts:
#	Cargo.lock
#	apps/effectcraft-cli/Cargo.toml
#	apps/effectcraft-cli/src/main.rs
#	crates/host/src/lib.rs
#	crates/ui-egui/src/panels/mod.rs
2026-10-01 22:29:58 -04:00
Brandon Thomas 702ca1757f M5.7: frame-aligned layer, comp and keyframe times
- Comp durations (comp.new / comp.settings) are whole frames.
- layer.addItem start/out, layer.timing in/out/start/delta and time-stretch in/out snap to
  the nearest comp frame; prop.addKey / prop.set with an explicit time key the nearest frame.
- The demo project builds every time on 29.97 fps frames (Lower Third in = frame 150 =
  0:00:05:00, comp = 300 frames).
- Test: demo + commands stay frame-aligned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:19:29 -04:00
Brandon Thomas 8599ac5828 M9.3: Simulation effects (CC Rainfall, CC Snowfall, CC Bubbles, CC Drizzle, CC Star Burst, CC Particle World, CC Particle Systems II, CC Mr. Mercury, CC Ball Action, CC Pixel Polly, CC Scatterize, Card Dance, Caustics, Wave World, Shatter, Foam)
Closed-form weather/bubble/star effects; stepped particle, wave and foam sims through the
checkpointed SimCache (seek-consistent); band-bucketed sprite/piece rasteriser and textured
3D pieces via per-piece inverse homography.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:13:51 -04:00
Brandon Thomas 0acc106175 M6.4: pen tool masks, mask vertex selection/dragging, tangent handles
Engine (mask.rs, tests in tests_timeline.rs incl. render + undo/redo):
mask.new, mask.addVertex, mask.setVertex, mask.setClosed (Layer > Mask and Shape Path >
Closed), mask.selectVertices, mask.moveVertices (merged drags), mask.deleteVertices
(Delete with vertices selected), mask.remove / mask.removeAll (Layer > Mask). Edits of an
animated Mask Path key the current time.

Viewer: Pen tool on the selected layer - click = corner vertex, drag = Bezier vertex,
click the first vertex to close, Esc/Enter or another tool ends the path; rubber band to
the pointer. Selection tool: click/shift-click mask vertices, drag selected vertices,
drag tangent handles (symmetric; Alt breaks). Vertices register automation ids
viewer.mask.<uid>.vertex.<i>. Mode/inverted/feather/opacity/expansion stay in the
timeline mask rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:12:52 -04:00
Brandon Thomas 8bc6d5ba4f M9.3: Text effects (Numbers, Timecode) + obsolete Basic Text, Path Text, Lightning
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:10:04 -04:00
Brandon Thomas 17af5c30c1 M9.3: Generate effects (Fractal, Scribble, Stroke, Vegas, Write-on, Paint Bucket, Eyedropper Fill, CC Glue Gun, CC Threads, Audio Spectrum, Audio Waveform)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:10:04 -04:00
Brandon Thomas fb6b3aa680 M9.1: Character panel parity (V/H scale, baseline shift, stroke order, small caps); layer.setText keys for them
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:03:37 -04:00
Brandon Thomas 43ebf68fe0 M9.3: Obsolete effects (Basic 3D, Gaussian Blur (Legacy)); move Luma Key, Spill Suppressor, Reduce Interlace Flicker to Obsolete
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:03:26 -04:00
Brandon Thomas 2c4346a15e M9.3: Color Correction effects (Change Color, Video Limiter, CC Color Neutralizer, PS Arbitrary Map, Lumetri Color)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:03:26 -04:00
Brandon Thomas b58167d0c7 M9.3: Noise & Grain effects (Match Grain, Median (Legacy), Curl Noise)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:03:26 -04:00
Brandon Thomas 5ac5560df9 M9.3: Keying effects (Difference Matte, Inner/Outer Key, Unmult, CC Simple Wire Removal)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:03:26 -04:00
Brandon Thomas d98775a931 M9.3: Channel effects (Blend, Calculations, CC Composite, Compound Arithmetic)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:03:26 -04:00
Brandon Thomas 0afa24b88f M9.3: Transition effects (CC Glass Wipe, CC Image Wipe, CC Jaws, CC Line Sweep, CC Twister, CC WarpoMatic)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:02:36 -04:00
Brandon Thomas 8503f816ae M9.3: Stylize effects (CC Block Load, CC Burn Film, CC Glass, CC HexTile, CC Mr. Smoothie, CC Plastic)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:02:36 -04:00
Brandon Thomas 7f9c3a85c0 M10: render queue + export
- crates/export (effectcraft-export): render a comp's span to H.264 MP4 (+AAC),
  ProRes 422/4444 MOV (+PCM, alpha), PNG/JPEG/TIFF/EXR sequences and animated GIF
  via FilmCraft's pure-Rust encoders and MP4/MOV muxer; parallel batched frame
  rendering, progress callback with cancellation.
- project: Render Queue model (Render Settings, Output Module, output path
  templates, status) saved with the project.
- render: FootageSource::audio hook + comp audio mixdown (levels, in/out, solo,
  precomps); media implements it.
- engine: Exporter hook, background/blocking render job, renderQueue.* commands
  (add Cmd+M, remove, setRender, setRenderSettings, setOutputModule, setOutput,
  move, duplicate, render, stop, list, formats).
- host wires the exporter; CLI `render` subcommand.
- ui-egui: After Effects-style Render Queue panel with automation ids.
- tests: encode/decode round trips for every format (FilmCraft decoders,
  ffmpeg/ffprobe oracle when installed), audio, cancel, engine commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:02:06 -04:00
Brandon Thomas 5a308a6964 M0.9: Info panel shows selected layer Duration / In / Out (AE)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:01:39 -04:00
Brandon Thomas 16a5fa7a83 M7.2: 3D viewer — 3D views, camera tools, camera/light wireframes, Camera/Light Settings dialogs
- Viewer renders through the comp's 3D view (RenderOpts.view; FrameKey hashes
  the view camera), shows the view name, and the bottom-bar 3D View dropdown
  (automation id viewer.view3d) switches Active Camera/Front/…/Custom View 3.
- Orbit / Pan / Dolly tools drag the current view (camera layer in Active
  Camera, merged into one undo step; view cameras otherwise).
- Handles, gizmo and picking go through the view camera; 3D layers move in
  the view plane at their depth.
- Camera frustum + POI and light position/direction wireframes
  (viewer.camera.<id>, viewer.light.<id>).
- Camera Settings / Light Settings dialogs open from New Camera/Light,
  Camera/Light Settings and Layer Settings; OK runs the engine commands.
- Timeline: POI only for two-node cameras/auto-oriented lights; "Z Rotation"
  label on 3D layers.
- Headless egui_kittest tests (UI wiring + opt-in wgpu snapshots); fix the
  remaining workspace clippy lints.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:01:37 -04:00
Brandon Thomas 685d6bcd04 M9.3: Perspective + Utility effects (CC Environment, 3D Glasses, HDR Compander)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:59:01 -04:00
Brandon Thomas 70c7f7c616 M9.3: Distort effects (CC Bender, CC Blobbylize, CC Power Pin, CC Ripple Pulse, CC Slant, CC Smear, CC Split, CC Split 2, Smear, Reshape, Twirl (Legacy), Warp, Detail-preserving Upscale)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:59:01 -04:00
Brandon Thomas 941e087446 M5.6: inline expression editor, expression pick-whip, parent pick-whip
- Properties with an expression get an editor row in the timeline: Expression label,
  enable (=) switch, pick whip, syntax-error warning, and a multiline code editor in the
  time-graph area (commits on blur or Cmd/Ctrl+Enter via prop.setExpression).
- Expression pick whip: drag onto another property row -> prop.pickWhip (AE reference
  expression). Parent pick whip in Parent & Link: drag onto a layer -> layer.setParent.
- Alt-click on a stopwatch starts with the property's own reference (transform.opacity).
- Timeline rows have variable heights; the empty-graph box-select area sits under the rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:58:42 -04:00
Brandon Thomas 89f10ba11f M3.1: AE Solid Settings dialog (lock aspect, % of comp, frame aspect, Make Comp Size)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:58:38 -04:00
Brandon Thomas 9d70623624 M3.1: AE Composition Settings dialog (Basic/Advanced/3D Renderer, AE presets, pixel aspect, start timecode, resize anchor)
engine comp.settings/comp.new: anchor (shifts unparented layers and their
position keys on resize), startTime/startTimecode, renderer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:57:08 -04:00
Brandon Thomas 7f43d537ed M14.1: ship .mcp.json (headless + bridge servers)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:49:20 -04:00
Brandon Thomas b307a562ed Merge branch 'worktree-agent-aaed9f382307fbe0b'
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-01 21:49:02 -04:00
Brandon Thomas 1cba07bdfe M5.1: AE timecode/ruler display parity
- Current time shown as AE does: 0:00:02:15 (hours unpadded; time::format_timecode_ae),
  frame count zero-padded to 5 digits (00075 (29.97 fps)).
- Time ruler labels in seconds:frames (00:15f, 01:00f) with frame-based adaptive spacing.
- time.set snaps seconds to the nearest frame (2.5 s at 29.97 -> frame 75).
- Mode / Track Matte columns hidden until Toggle Switches/Modes (F4), as in AE's default.
- Timeline outline pane sized to its columns and clipped so Parent & Link never draws
  over the time graph in narrow timelines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:48:47 -04:00
Brandon Thomas 951ed1fa3d M5.2–M5.5: keyframe clipboard, easy ease, velocity/interpolation dialogs, roving, time remap/stretch/reverse/freeze, graph editor, separate dimensions, pick-whip
Engine (all commands with undo/redo + tests in engine/src/tests_timeline.rs):
- keys.copy/paste (Edit Copy/Cut/Paste route to keys when keys are selected;
  relative timing kept, paste at CTI, cross-property paste of same type),
  keys.selectAll (Cmd+Alt+A), keys.nudge* (Alt+Arrow, Alt+Shift+Arrow),
  keys.set / keys.setEase (graph editor drags), keys.info (dialog data),
  keys.timeReverse; keys.interpolation gains continuous/auto Bezier, spatial
  interpolation and roving; keys.velocity takes per-dimension values and
  Continuous.
- Roving keys (keyframe::retime_roving): constant speed along the motion path.
- Layer > Time: layer.timeStretch (percent|duration, hold in/current/out),
  layer.timeReverse (Cmd+Alt+R), layer.enableTimeRemap (Cmd+Alt+T),
  layer.freezeFrame, layer.freezeOnLastFrame; render uses Time Remap as the
  source time for precomp/footage layers.
- prop.separateDimensions (X/Y/Z Position; prop.set on Position writes them).
- layer.setParent compensates so the layer stays in place (compensate:false
  to opt out).
- prop.pickWhip writes AE-style reference expressions (thisComp.layer(..),
  effect(..)(..), mask(..).maskFeather, temp=…;[temp,temp], …[0]).
- prop.setExpression: syntax errors keep the text but disable the expression.
- expr: arrays of properties returned by an expression are resolved.

UI: Keyframe Velocity, Keyframe Interpolation and Time Stretch dialogs;
Graph Editor (value + speed graphs, draggable keys and Bezier/influence
handles, auto-zoom, fit, show selected, separate dimensions, hold/linear/
auto Bezier/Easy Ease buttons); key + layer context menus. Clears the
workspace clippy -D warnings failures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:47:29 -04:00
Brandon Thomas a99be1499f M0.9: Effect Controls parity — sliders behind param twirls with range labels, About... header, no hex; headless snapshot feeds synthetic input
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:45:01 -04:00
Brandon Thomas c91af194f2 M9.3: effect env (masks, layer params, audio, comp timing), sim cache, polyline helpers; module stubs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:43:48 -04:00
Brandon Thomas c672e03160 M14.1: MCP server + agent CLI
- crates/automation (L5, no egui): hand-rolled JSON-RPC 2.0 MCP server over
  stdio (initialize, ping, tools/list, tools/call); headless backend (in-process
  Session) and bridge backend (desktop control channel). Tools: list_commands,
  execute_command, get_project/comp/layer, get/set_property, add_keyframe,
  render_frame (inline PNG), open/save_project, undo/redo; bridge-only
  screenshot, ui_* and raw control passthrough.
- effectcraft-cli: info, commands, exec, run, props, get, set, render-frame,
  mcp [--bridge PORT]; --json, --project/--demo/--empty, --save/--save-as.
- engine: prop.get, layer.tree node paths + time, Session::resolve_comp,
  render_rgba8, execute_checked (rejects unknown params, lists accepted keys).
- control channel: render.frame; engine.execute runs every engine command
  directly (no dialogs, validated params).
- docs: control-protocol.md, agents.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:40:31 -04:00
Brandon Thomas 62cfa66496 M0.9: Project panel parity — sortable columns (folders mixed by name), Frame Rate column, Size = file size, AE durations
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:38:34 -04:00
Brandon Thomas a2ff724ac2 M12.1: render cache + parallel compositing fast paths
- render: LayerCache (content-keyed processed-layer cache: source -> masks ->
  effects, keyed by a hash of the layer's non-transform props evaluated at the
  frame time, solid item, switches, scale; time folded in for clock-driven
  effects / wiggle paths). Static and transform-only layers render once;
  edits only re-render the edited layer. Session + UI frame jobs share it.
- effects: TIME_DEPENDENT list + test that every clock-reading effect is listed.
- raster: affine composite fast path (per-row span clipping, unchecked interior
  bilinear, integer-translation copies, inlined Normal blend), checked against
  composite_warp_reference; box/Gaussian blur without transposes, two
  ping-pong buffers; accumulate_warp so motion blur sums into one buffer
  instead of one full-frame image per sub-sample.
- ui: viewer frame is urgent and jumps the prefetch queue; stale-revision jobs
  are dropped; paused prefetch waits for the viewer frame; "Frame Render Time"
  reports viewer frames only; parallel f32 -> Color32 conversion.
- cli: `frame --bench N` (per-layer/per-effect timings, wall + CPU time) and
  `frame --bench-play N` (consecutive frames with/without the layer cache).
- tests: cache transparency (scrub, edits of values/keys/effects/masks/
  solids/text/timing), hit/miss accounting, time-dependent effects, demo
  cached == uncached, fast warp/blur/accumulate == reference.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:34:33 -04:00
Brandon Thomas 4f47a01fed M0.9: AE-style Properties panel, context tab titles, AE default workspace; headless UI snapshot tool
- Properties panel (panels/properties.rs): Layer Transform with keyframe navigator
  or stopwatch, AE value formatting (integers, %, Nx+N° rotation), linked Scale,
  Reset; Text (font/style/size/leading/tracking/stroke, fill/stroke toggles);
  Paragraph (7 alignments); Text Animation > Add Animator; scrolling.
- Tabs name what they show: Composition <comp>, <comp> timeline, Effect
  Controls <layer>, Properties: <layer>.
- Default workspace: full-height right column, Preview over Properties.
- engine: time.go nextKey/prevKey accept prop uid; layer.setText supports all
  seven justify modes, applyFill/applyStroke and Auto leading (fixes the
  Paragraph 'justify' button mapping to Justify All).
- examples/snapshot: render the real UI headless (egui_kittest + wgpu) with
  scripted control-channel steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:19:23 -04:00
Brandon Thomas 76ac3f74f7 M7.1: Classic 3D renderer, cameras, lights, 3D views and camera-tool commands
- render/three_d: camera eval (one/two-node, DOF), default 50mm comp camera,
  orthographic Front/Left/Top/Back/Right/Bottom + perspective Custom Views,
  orbit/pan/dolly rig math; lights (parallel/spot/point/ambient, falloff,
  cone feather) and material shading; per-pixel depth-sorted compositor for
  3D runs (exact intersections, perspective-correct sampling, blend modes,
  track mattes, motion blur), ray-cast planar shadows with transmission and
  diffusion, per-layer DOF blur. RenderOpts.view camera override.
- project: camera iris/highlight props, aperture per comp width, light
  orientation/rotations, two-node auto-orient defaults.
- engine: layer.newCamera/newLight with presets & settings,
  layer.cameraSettings/lightSettings (Layer Settings dispatches),
  view.set3DView + View > Switch 3D View items (F10/F11/F12), last/reset view,
  camera.orbit/pan/dolly, view.get3D; EditorState.views3d.
- demo: "3D Showcase" comp (camera move, key spot + ambient fill, shadows,
  DOF, intersecting planes, gridded floor).
- tests: projection, depth order, intersections, lighting, shadows, DOF,
  views, rig math; command undo/redo. Fix a few pre-existing clippy lints.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:09:21 -04:00
Brandon Thomas 214345df13 control: keep channel responsive when window is covered (disable App Nap); fail fast on occluded screenshots
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:49:29 -04:00
Brandon Thomas 9f0cfb3373 M0.1: cargo xtask (layers, assets, wasm, ci); attribute ArtCraft brand marks
Layer table matches the real dependency graph; wasm check passes for all
L0-L4 crates and the egui UI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:49:29 -04:00
Brandon Thomas dee16181fe engine: explicit layer/prop params bypass selection-based enablement
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:51:38 -04:00
Brandon Thomas 3a59a8470d M0.9–M0.10: egui frontend (AE-style panels, viewer, timeline, effect controls, dialogs), desktop app with control channel, host wiring; cargo fmt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:48:31 -04:00
Brandon Thomas e2ba01a11f Merge expressions engine (boa)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:40:22 -04:00
Brandon Thomas 58b137991b Re-export color/geom from engine; kurbo_path helper
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:40:10 -04:00
Brandon Thomas 4ce50e00a0 M8: expressions engine (boa) with AE object model
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:39:02 -04:00
Brandon Thomas 989c4ba531 Merge branch 'worktree-agent-a23886a31ccc16878' 2026-10-01 14:32:21 -04:00
Brandon Thomas 0ec4605a32 M0.6: content bounds helpers for viewer handles
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:32:21 -04:00
Brandon Thomas 4c3b92723b M9.2: effects batch 2 (keying, matte, channel, stylize, noise, perspective, transitions, utility)
Adds 105 effects in new modules (keying, matte, channel, blur2, color2, stylize2, noise, generate2, distort2, perspective, transition, utility) plus shared plane/morphology/guided-filter helpers in util.rs, with 96 new unit tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:30:57 -04:00
Brandon Thomas 426f153794 Merge media import (FilmCraft codecs)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:29:17 -04:00
Brandon Thomas 3feab9db97 Merge branch 'worktree-agent-a9f473e3a56abd824' 2026-10-01 14:28:25 -04:00
Brandon Thomas c361a9348a Cargo.lock for engine/CLI
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:28:25 -04:00
Brandon Thomas 6a5a2d9689 M0.8: engine session, undo history, ~100 commands, demo project; headless CLI
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:28:21 -04:00
Brandon Thomas d867178137 M6.8: media import via FilmCraft codecs (probe, frame cache, stills, sequences)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:28:14 -04:00
Brandon Thomas ba2fa1bddf M6.2: shape path operators (round corners, offset, twist, zig zag, wiggle, merge paths, gradient stroke)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:26:28 -04:00