feat(engine): clip move, clip effect_input, mandatory static FFmpeg

- oakengine_sequence_move_clip implemented for real (oaktimeline
  TrackMoveBlockCommand; fixes the graph-ownership/gap-anchor/ripple
  trim bugs the stub was hiding); same-track via the frozen C ABI,
  cross-track supported by the module command
- oaknode clip blocks now declare a tex_in texture input and set
  effect_input to it, so timeline clips can host effect chains; facade
  test covers effect insert/remove on a real clip
- oakffmpeg-link: FFMPEG_DIR is now mandatory with a clear panic (a
  Homebrew upgrade left the system ffmpeg .pc pointing at a deleted
  dav1d Cellar path, breaking links); reads a git-ignored workspace
  .env for IDEs that cannot inject env vars (RustRover); links the C++
  stdlib for C++ codec libs (svt-av1)
- oakengine re-exports oaknode so tests share one crate instance;
  it_node uses the direct instance's value type where it calls the
  module FFI (the --workspace dev-dependency feature split builds
  oaknode twice)
This commit is contained in:
2026-08-11 23:04:48 +08:00
parent a209f63d52
commit 18ff60f147
351 changed files with 32880 additions and 15939 deletions
+11 -6
View File
@@ -191,7 +191,11 @@ impl TrackBehavior {
/// Block strictly containing `time` (in < time < out; C++
/// `block_containing_time`).
pub fn block_containing_time(&self, time: oakcore_rs::Rational, blocks: &dyn BlockRange) -> Option<NodeId> {
pub fn block_containing_time(
&self,
time: oakcore_rs::Rational,
blocks: &dyn BlockRange,
) -> Option<NodeId> {
self.blocks
.iter()
.find(|b| blocks.contains_strict(**b, time))
@@ -200,7 +204,11 @@ impl TrackBehavior {
/// Block visible at `time` (in <= time < out; C++
/// `visible_block_at_time`).
pub fn visible_block_at_time(&self, time: oakcore_rs::Rational, blocks: &dyn BlockRange) -> Option<NodeId> {
pub fn visible_block_at_time(
&self,
time: oakcore_rs::Rational,
blocks: &dyn BlockRange,
) -> Option<NodeId> {
self.blocks
.iter()
.find(|b| blocks.contains(**b, time))
@@ -210,10 +218,7 @@ impl TrackBehavior {
/// Whether the [in, out) range holds no block or only a gap (C++
/// `is_range_free`).
pub fn is_range_free(&self, range: oakcore_rs::TimeRange, blocks: &dyn BlockRange) -> bool {
!self
.blocks
.iter()
.any(|b| blocks.overlaps(*b, range))
!self.blocks.iter().any(|b| blocks.overlaps(*b, range))
}
/// Total length (end of the last block; C++ `Track::get_length`).