Commit Graph
3793 Commits
Author SHA1 Message Date
aiongg dd12ed8f9c Merge pull request #2518 from Silvertree2010/perf/export-speed
Export: encode while the next batch renders, skip transparent pixels when compositing
2026-10-27 13:42:31 -04:00
dotCooCoo 572ed5d17f Preserve script keyboard shortcuts across menu module changes 2026-10-27 10:25:26 -07:00
dotCooCoo 2c2c51ca0c Preserve recent script files across menu and settings module changes 2026-10-27 10:11:33 -07:00
vangel76andClaude Sonnet 5.5 36ec54f007 Merge upstream/main into warp-skip-discarded-plan
Upstream split lib.rs files into modules and moved engine commands/ to cmd/; this branch's change merges without textual conflicts.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 17:51:52 +01:00
vangel76andClaude Sonnet 5.5 6418c8c0a4 Merge upstream/main into camtrack-validate-input
Upstream split lib.rs files into modules and moved engine commands/ to cmd/; this branch's change merges without textual conflicts.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 17:51:50 +01:00
Christopher Linnett c8b07b4b06 Text: duplicate during a text edit leaves no keyframe or mask vertex selected on the original (#2226)
Opening the editor keeps the keyframe and mask-vertex selection as well as the property one,
and Duplicate cleared only the properties. With the copy selected, Clear then deleted a key or
vertex of the original instead of the copy. During an edit the copies now take the selection the
way a click on them does: layer.select's rule, moved into one helper both use. With no edit
open, Duplicate's selection is unchanged.
2026-10-28 00:50:43 +08:00
NetterSilverandClaude Opus 5.5 94399e62ff Pin movie export bytes
H.264 and ProRes exports of a 60-frame comp (several render batches, a
rotating stroked ring, a fading solid at a fractional position, a
Screen-mode shape, 8 bpc) must keep the exact bytes main wrote before the
two previous commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:40:41 +01:00
NetterSilverandClaude Opus 5.5 db41fa7980 Skip transparent pixels and quantise while compositing
Much of a layer buffer is often transparent (a stroked ring, a glow-padded
text layer, a precomp canvas), yet every destination pixel sampled it
bilinearly, and 8/16 bpc comps then re-quantised the layer's whole rotated
bounding box.

- Bilinear warps skip 16x16 source tiles whose pixels (and a one-pixel
  apron) all have zero alpha: their samples are transparent and were never
  drawn.
- The fast affine warp reports the rectangle it changed and, given the
  comp's levels, quantises each pixel as it blends it, so draw_comp has
  nothing left to re-quantise for that layer. quantize_px moves to
  effectcraft-raster for this.
- quantize_rect skips runs of four all-zero (+0.0) pixels, which quantise
  to themselves.
- to_rgba8 / to_rgba8_over convert row by row instead of per 4-byte item.

Every pixel stays bit-identical: tests compare the warp against the
reference path, fused quantising against quantising after blending, and
the zero-run skip against per-pixel quantising.

With the previous commit, demo comp to H.264 (`cargo xtask bench --scenario
demo --format h264 --frames 300`, 11 interleaved runs on a 16-thread Ryzen):
wall 9.26 s -> 6.97 s median (-24.8%), 8.55 s -> 6.55 s min (-23.3%); CPU
time -23%. Output byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:40:41 +01:00
NetterSilverandClaude Opus 5.5 d8bca3cdd9 Overlap movie encoding with rendering
Movie exports (H.264, HEVC, AV1, ProRes, uncompressed) rendered a batch of
frames on every core, then encoded it frame by frame while the render
threads waited. Each batch now encodes on a pool shared by all exports while the
next batch renders (Cx::frames_beside). With deferred GPU readbacks, or
where no thread can be started (wasm without threads), the two still take
turns. A panicking encoder becomes an export error.

H.264 frames are converted to 4:2:0 on the render threads, per frame, instead
of on the encoder's critical path. The conversion reads 8-bit levels from a
table and rounds without a libm call; both give the same values as before
(tested against the previous formula).

Demo comp (1920x1080, 300 frames) to H.264 on a 16-thread Ryzen, export
wall time -6% (median of 7 interleaved runs); output byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:40:41 +01:00
Christopher Linnett 0e3b894cd9 Text: the text-edit tests count layers with the shared helper; forwarding docs name Duplicate (#2226)
The engine's text-edit tests repeated one layer-count closure in five places; they now use
the layer_count helper the 3D tests already had. The doc of forwardable_during_text_edit and
of the Type-tool test helper still spoke of Deselect All alone, though the editor now forwards
Duplicate too.
2026-10-28 00:30:00 +08:00
Christopher Linnett eeedd6b540 Text: duplicate during a text edit leaves no effect selected on the original (#2226)
Duplicate passes over the property selection an open edit kept and copies the edited layer,
but left that selection in place on the original. With the copy selected, the next Duplicate
copied the original's effect, shape item or text animator, and Clear would have removed it.
Ending the edit through Duplicate now clears that property selection along with it.
2026-10-28 00:26:52 +08:00
Christopher Linnett 9928f6181b Text: duplicate during a text edit copies the layer, not a selected effect (#2226)
Opening the editor keeps the property selection, so Cmd+D while typing duplicated an
effect, shape item or text animator selected before and left the edit open. An open edit
now comes first, as it does for Clear: Duplicate ends it and copies the edited layer. With
no edit open, selected effects and items keep their precedence, and the command's
description says so.
2026-10-28 00:22:35 +08:00
dotCooCoo 87eb51a089 Include alpha interpretation in frame-blend cache keys 2026-10-27 09:22:14 -07:00
Christopher Linnett f7094b619b Merge origin/main into fix/issue-2226-duplicate-during-text-edit
Main moved the engine's topic tests to src/tests/ and commands/ to cmd/. The
engine tests go to tests/text_edit.rs, opening their edit with its editing()
helper; ui_text_edit.rs keeps both sides' tests, this branch's first.
2026-10-28 00:16:44 +08:00
Christopher Linnett 60da124f11 Merge remote-tracking branch 'origin/main' into fix/issue-2092-camera-focus-crash 2026-10-28 00:13:40 +08:00
vangel76andClaude Sonnet 5.5 9fc04e8fe3 Merge upstream/main into fix-1083-beat-marker-audio-pause
Conflicts came from upstream splitting crates/project/src/lib.rs and moving the
frames tests. Re-applied the branch's change in the new places:
- Layer::same_pixels_with now in crates/project/src/layer.rs
- Comp::same_pixels_with, same_settings(o, with_markers), pixel_form_with and the
  timing-marker helpers in crates/project/src/comp.rs (same_pixels_ignoring_markers
  stays removed)
- Project::reads_markers in crates/project/src/item.rs
- crates/ui-egui/src/frames.rs uses reads_markers/same_pixels_with; the branch's
  two marker tests replace the old ones in crates/ui-egui/src/frames/tests.rs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 17:09:17 +01:00
vangel76andClaude Sonnet 5.5 2078b492d9 Merge upstream/main into rfx-text
text/layout: upstream split paragraph() into Para/place_line helpers and moved the tests to
layout/tests.rs. The branch's changes are re-applied there: the resolved paragraph direction
is passed to margins_for/avail_for/align_for (RTL point text with Justify sits flush right),
first_ascent/plausible_first and ParaLine.first/style_first (box first baseline is the d
height, vertical text keeps the ascent), and the Justify All last-line cost in
optimal_breaks. The branch's seven new layout tests moved to layout/tests.rs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 17:06:38 +01:00
vangel76andClaude Sonnet 5.5 107d595c1c Merge upstream/main into feat-gap25-a11y-audit
Conflicts: crates/ui-egui/src/menus.rs (upstream split it into menus/{bar,commands,entries,frontend,invoke,shortcuts,tests}.rs) and panels/settings.rs (ComboBox is now craft_ui::ComboBox).

- menus.rs: took upstream's slim module; re-applied the branch's two hunks in the new locations: nudge() now also skips Effects & Presets and Render Queue (menus/invoke.rs), and Enter is left to those panels in handle_shortcuts (menus/shortcuts.rs).
- panels/settings.rs: kept the branch's accessibility lines (shown_name, value_text) on top of craft_ui::ComboBox.

The accessibility audit BASELINE still matches the measured findings.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 17:01:33 +01:00
vangel76andClaude Sonnet 5.5 ca00da2f55 Merge upstream/main into rfx-masks-shapes
render: upstream moved the tests_*.rs modules into crates/render/src/tests/; the branch's
tests_mask_feather.rs now lives at tests/mask_feather.rs and is registered in tests.rs.
path: rect() keeps the branch's explicit-outline version with an added NaN guard on the
roundness clamp bound (main's fix for the same panic).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 16:57:13 +01:00
vangel76 92e33beef0 Merge remote-tracking branch 'upstream/main' into gap-behaviors-presets 2026-10-27 16:51:00 +01:00
dotCooCoo c0f6151185 Preserve font name fallback in the shared dropdown menu 2026-10-27 08:31:12 -07:00
midasdf 242457f84d Merge remote-tracking branch 'origin/main' into jp/ja-dialogs
# Conflicts:
#	crates/ui-egui/src/credits.rs
#	crates/ui-egui/src/panels/tracker.rs
2026-10-27 23:45:42 +09:00
dotCooCoo 97ef73d592 Preserve bug fixes after main module moves and bound workspace migration 2026-10-27 07:45:09 -07:00
aiongg bc4b48f67d fix(ui): dropdown menus grow back after a search with no matches (#2511)
* fix(ui-egui): craft_ui::ComboBox for every combo box, so open menus grow back (egui#5225)

Repins craft-libs to aiongg/craft-libs 60d60d48 (storytold main with the shared
dropdown) and bans egui::ComboBox in clippy.toml.

* fix(ui-egui): font menu under the font field is a craft_ui combo menu that grows back

The filter row is the menu's header and only the font list scrolls, so a search
that matched nothing grows the menu back when it is cleared.

* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)

* chore(deps): craft-libs 92d392cf (#387 merged)

* chore(xtask): pdf-deps expects craft-libs 92d392cf
2026-10-27 10:27:52 -04:00
Kushagra Kumar 97b80f3eab Merge branch 'upstream/main' into fix/png-frame-alpha-preservation 2026-10-27 19:51:42 +05:30
Z User a8cba23edc Review fixes: the environment shadow follows the tinted radiance (#2436)
dominant_direction weighted texels by their raw channel sum before the
light's colour tinted the radiance, so equally bright red and blue regions
on opposite sides cancelled to no sun and no key — while a red Environment
light's tint removed the blue contribution and left the scene lit
directionally red, with no shadow for its Cast Shadows to show. The tint
now weights the direction sum (a white light weights [1; 3], a coloured
one its normalised colour), so the sun and key are derived from the
radiance the light actually emits; add_environment computes the tint once,
before the direction pass, and reuses it for the texel tinting. An
achromatic image is unaffected (its weights scale uniformly), so the
default studio and white-lit scenes keep their shadows exactly.

Tests: opposed red and blue texels cancel to a white light but a red tint
points the sun straight at the red one (a blue tint, at the blue one); end
to end, a red Environment light over an image with equally bright red and
blue regions on exactly antipodal positions casts the shadow a white light
over the same image does not — and the shadow falls opposite the red
region, the side the tinted radiance comes from.
2026-10-27 14:11:55 +00:00
midasdf 5aadb0df80 Merge remote-tracking branch 'origin/main' into pr
# Conflicts:
#	crates/text/src/fonts.rs
#	crates/text/src/layout.rs
2026-10-27 22:33:32 +09:00
midasdf 145c345036 Merge remote-tracking branch 'origin/main' into pr
# Conflicts:
#	crates/ui-egui/src/i18n/ui.rs
2026-10-27 22:31:03 +09:00
Z User eb34d10d21 Review fixes: a failed environment source lights nothing (#2436)
Two review points on the merge:

- env_pixels returned None both for an unconfigured light (no Source, no
  Environment Layer) and for a failed source (a deleted layer, missing
  footage, a failed decode), so a selected source that failed silently
  swapped in the default studio environment — relighting and reshadowing
  the scene behind the user's back. It now tells the three apart
  (EnvPixels::Absent/Image/Failed): only the unconfigured light uses the
  default; a failed source contributes nothing, exactly like a layer whose
  source fails renders nothing. The repair the user can act on stays where
  it already lives — missing footage is flagged on the item, with the
  relink commands to fix it.

- The docs claimed only a uniform image casts no shadow. A non-uniform one
  can be directionless too: opposing bright regions cancel, and anything
  under 1% directional is rejected. agents.md, architecture.md and the
  sun/dominant_direction doc comments now say an image without a
  sufficiently strong dominant direction.

Tests: an unreadable Environment Layer (auto-picked), an unreadable
selected Source and a deleted one all light nothing — pixel-equal to the
unlit render, no studio default, no default-environment shadow — while an
unconfigured light still lights; two equal bright spots at opposite
azimuths cancel to no sun and no key, and tilting the balance re-emerges
pointing at the brighter spot.
2026-10-27 12:33:46 +00:00
Kirill M 98afe1c51e i18n: Russian, German and French follow Match System and translate the menus
supported() mapped only ja, uk, es, cs, ka, pt and zh, so Match System
on a ru, de or fr system (ru-SK, de-DE, fr-CA) fell back to English
although all three have menu catalogs. And entry() returned the shown
label before the catalog lookup for every language without its own
undo/redo wording, so choosing Deutsch, Русский or Français by hand
still left the menus in English (#1449).

supported() now maps ru, de and fr. entry() keeps the undo/redo wording
as an Option: a language without it keeps the English undo/redo label,
and its other entries go through the catalog. Russian gets its undo and
redo wording.
2026-10-27 11:15:52 +01:00
Minher0 36a50a6366 layer.create: the instance copy takes the source's Solo switch
A soloed model keeps its Solo switch with its video off, and any_solo
hides non-soloed layers: the copy was excluded and the comp rendered
blank. The copy now takes the Solo over; the source's video stays off.
Covered by instance3d_keeps_the_copy_visible_when_the_source_is_soloed.
2026-10-27 09:46:32 +00:00
Minher0 db1f798455 Merge main into #2410
PR #2491 moved the modules; the instance3d changes follow the new layout:
- tests_instance3d.rs lives in src/tests/instance3d.rs now (declared in src/tests.rs)
- solo_3d moved from render/src/lib.rs to render/src/pipeline.rs, pub(crate),
  and its FxHost::layer caller moved to render/src/fx_host.rs
- cmd/create.rs, effects/channel2.rs, gpu/fx_pixel2.rs and render/cache/dependencies.rs
  followed their moves automatically (rename detection)
2026-10-27 09:15:43 +00:00
Z User 978ca419b9 Merge remote-tracking branch 'origin/main' into fix/environment-light-no-effect-cast-shadows 2026-10-27 08:54:33 +00:00
onlykshitijandClaude Opus 5.5 c9d823483f Merge upstream main into feat/script-panel-submenus
Upstream moved crates/ui-egui/src/menus.rs into menus/*.rs; the dynamic-menu change that
draws script folders as submenus now lives in menus/bar.rs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 10:56:49 +05:30
ashokram-si de27e1ea0a Merge main into feat/targa-sequence-output 2026-10-27 10:46:47 +05:30
heojunfo 7a665a67b3 Merge remote-tracking branch 'upstream/main' into fix/classic3d-shadow-diffusion 2026-10-27 14:06:18 +09:00
midasmatterhorn 027c537447 model: try the complete texture name before its final token 2026-10-27 03:52:33 +03:00
midasmatterhorn e60f654cc6 media: a model reference into another machine finds its file beside the model, so the pool test asserts the local lookup 2026-10-27 02:53:11 +03:00
Minher0 743119d6e5 Give the Environment light After Effects' look (#2436)
The default studio environment's level-preserving mean of 1 acted like a
100% white Ambient light: with only the Environment light on, a white floor
rendered at full white (95% of the frame saturated) while its shadow core
went to pitch black — a fog over the scene, nothing like After Effects'
default. Three changes bring the look in line, CPU and GPU alike:

- The default environment is a dim studio now: a solid-angle-weighted mean
  of 0.3 (and a stronger key gradient), so a white floor reads a mid gray
  and the light's colour x intensity still scales the level.
- The shadow occludes only the image's directional (key) fraction of the
  light — |sum of dir x radiance| / sum of radiance, computed beside the
  dominant direction and carried in the scene — so the fill keeps shining
  inside the shadow: an area-light shadow, partial like After Effects'
  (a lone bright spot on black still shadows almost fully; a uniform image
  not at all).
- The environment shadow map's penumbra has a floor — eight output pixels,
  or four map texels where those are coarser — because the map covers the
  whole scene bounding sphere rather than the view, and its texels would
  otherwise stair-step the edge (all the more in a draft render's flat 512
  budget). Shadow Diffusion widens it further, as before.

Tests: the key fraction tracks directionality; the default keeps its dim
level, its direction and its key; the default and a bright key both shadow
the floor (the default partial, the key deep) with Cast Shadows off lit
everywhere; and the full look — a mid-gray lit floor (no fog), a partial
core, and a soft edge ramp in quality and draft renders alike.
2026-10-26 23:36:19 +00:00
midasmatterhorn 408e36a5f2 Merge remote-tracking branch 'upstream/main' into fix/issue-1274-obj-sibling-textures
# Conflicts:
#	Cargo.lock
2026-10-27 01:48:06 +03:00
aiongg b7b75ed37a style: cargo fmt on the moved files 2026-10-26 21:54:30 +00:00
aiongg 3e38bd7349 refactor(pdf): split the PostScript interpreter ps.rs into ps/*.rs 2026-10-26 21:49:12 +00:00
aiongg 5cb742591c refactor(effects): split ocio.rs into ocio/*.rs 2026-10-26 21:49:12 +00:00
aiongg 13fe6e5c03 refactor(effects): split sim.rs into sim/*.rs 2026-10-26 21:49:12 +00:00
aiongg 67ef9ad93c refactor(effects): split sim2.rs into sim2/*.rs 2026-10-26 21:49:12 +00:00
aiongg b05467e47f refactor(effects): split generate3.rs into generate3/*.rs 2026-10-26 21:49:12 +00:00
aiongg f5f51f8db8 refactor(ui-egui): move viewer frame, geometry, gestures, shapes, tools and view parts to panels/viewer/*.rs 2026-10-26 21:49:12 +00:00
aiongg 9b52c71a71 refactor(ui-egui): move viewer tests to panels/viewer/tests.rs 2026-10-26 21:49:12 +00:00
aiongg 319d2cba3b refactor(ui-egui): move menu commands, dispatch, entries, shortcuts and the menu bar to menus/*.rs 2026-10-26 21:49:11 +00:00
aiongg 03f5ba581d refactor(ui-egui): move EffectcraftApp methods to app/*.rs 2026-10-26 21:49:11 +00:00