Skip to content

Commit

Permalink
wayyyyyy more sound zoom implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendonovich committed Jan 23, 2025
1 parent 7d68ed7 commit b5836dd
Show file tree
Hide file tree
Showing 3 changed files with 476 additions and 825 deletions.
2 changes: 1 addition & 1 deletion crates/project/src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl Default for BackgroundSource {
}
}

#[derive(Type, Serialize, Deserialize, Clone, Copy, Debug, Default)]
#[derive(Type, Serialize, Deserialize, Clone, Copy, Debug, Default, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct XY<T> {
pub x: T,
Expand Down
172 changes: 68 additions & 104 deletions crates/rendering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use cap_project::{
SLOW_VELOCITY_THRESHOLD, XY,
};
use core::f64;
use decoder::{AsyncVideoDecoder, AsyncVideoDecoderHandle, Decoder, GetFrameError};
use decoder::{AsyncVideoDecoderHandle, Decoder};
use futures::future::OptionFuture;
use futures_intrusive::channel::shared::oneshot_channel;
use serde::{Deserialize, Serialize};
Expand All @@ -20,7 +20,7 @@ use tokio::sync::mpsc;
use wgpu::util::DeviceExt;
use wgpu::{CommandEncoder, COPY_BYTES_PER_ROW_ALIGNMENT};

use image::{GenericImageView, ImageDecoderRect};
use image::GenericImageView;
use std::path::Path;
use std::time::Instant;

Expand Down Expand Up @@ -549,7 +549,6 @@ pub struct ProjectUniforms {
pub cursor_size: f32,
display: CompositeVideoFrameUniforms,
camera: Option<CompositeVideoFrameUniforms>,
pub zoom: Zoom,
pub project: ProjectConfiguration,
pub is_upgraded: bool,
}
Expand Down Expand Up @@ -713,59 +712,43 @@ impl ProjectUniforms {
&project.cursor.animation_style,
);

let zoom_keyframes = ZoomKeyframes::new(project);
let current_zoom = zoom_keyframes.interpolate(time as f64);
let prev_zoom = zoom_keyframes.interpolate((time - 1.0 / 30.0) as f64);

let velocity = if current_zoom.amount != prev_zoom.amount {
let scale_change = (current_zoom.amount - prev_zoom.amount) as f32;
// Reduce the velocity scale from 0.05 to 0.02
[
(scale_change * output_size.0 as f32) * 0.02, // Reduced from 0.05
(scale_change * output_size.1 as f32) * 0.02,
]
} else {
[0.0, 0.0]
};

let motion_blur_amount = if current_zoom.amount != prev_zoom.amount {
project.motion_blur.unwrap_or(0.2) // Reduced from 0.5 to 0.2
} else {
0.0
};
// let zoom_keyframes = ZoomKeyframes::new(project);
// let current_zoom = zoom_keyframes.interpolate(time as f64);
// let prev_zoom = zoom_keyframes.interpolate((time - 1.0 / 30.0) as f64);

let velocity = [0.0, 0.0];
// if current_zoom.amount != prev_zoom.amount {
// let scale_change = (current_zoom.amount - prev_zoom.amount) as f32;
// // Reduce the velocity scale from 0.05 to 0.02
// [
// (scale_change * output_size.0 as f32) * 0.02, // Reduced from 0.05
// (scale_change * output_size.1 as f32) * 0.02,
// ]
// } else {
// [0.0, 0.0]
// };

let motion_blur_amount = 0.0;
// if current_zoom.amount != prev_zoom.amount {
// project.motion_blur.unwrap_or(0.2) // Reduced from 0.5 to 0.2
// } else {
// 0.0
// };

let crop = Self::get_crop(options, project);

let interpolated_zoom = zoom_keyframes.interpolate(time as f64);

let (zoom_amount, zoom_origin, lowered_zoom) = {
let origin = match interpolated_zoom.position {
ZoomPosition::Manual { x, y } => Coord::<RawDisplayUVSpace>::new(XY {
x: x as f64,
y: y as f64,
})
.to_raw_display_space(options)
.to_cropped_display_space(options, project),
ZoomPosition::Cursor => {
if let Some(cursor_position) = cursor_position {
cursor_position
.to_raw_display_space(options)
.to_cropped_display_space(options, project)
} else {
let center = XY::new(
options.screen_size.x as f64 / 2.0,
options.screen_size.y as f64 / 2.0,
);
Coord::<RawDisplaySpace>::new(center)
.to_cropped_display_space(options, project)
}
}
};
let segment_cursor = SegmentsCursor::new(
time as f64,
project
.timeline
.as_ref()
.map(|t| t.zoom_segments.as_slice())
.unwrap_or(&[]),
);

(interpolated_zoom.amount, origin, interpolated_zoom.lowered)
};
let zoom = InterpolatedZoom::new(&segment_cursor);

let (display, zoom) = {
let display = {
let output_size = XY::new(output_size.0 as f64, output_size.1 as f64);
let size = [options.screen_size.x as f32, options.screen_size.y as f32];

Expand All @@ -782,27 +765,11 @@ impl ProjectUniforms {

let end = Coord::new(output_size) - display_offset;

let screen_scale_origin = zoom_origin
.to_frame_space(options, project, resolution_base)
.clamp(display_offset.coord, end.coord);

let zoom = Zoom {
amount: zoom_amount,
zoom_origin: screen_scale_origin,
// padding: screen_scale_origin,
};

let target_size = end - display_offset;

let (zoom_start, zoom_end) = (
Coord::new(XY::new(
lowered_zoom.top_left.0 as f64 * target_size.x,
lowered_zoom.top_left.1 as f64 * target_size.y,
)),
Coord::new(XY::new(
(lowered_zoom.bottom_right.0 as f64 - 1.0) * target_size.x,
(lowered_zoom.bottom_right.1 as f64 - 1.0) * target_size.y,
)),
Coord::new(zoom.bounds.top_left * target_size.coord),
Coord::new((zoom.bounds.bottom_right - 1.0) * target_size.coord),
);

let start = display_offset + zoom_start;
Expand All @@ -811,28 +778,24 @@ impl ProjectUniforms {
let target_size = end - start;
let min_target_axis = target_size.x.min(target_size.y);

(
CompositeVideoFrameUniforms {
output_size: [output_size.x as f32, output_size.y as f32],
frame_size: size,
crop_bounds: [
crop_start.x as f32,
crop_start.y as f32,
crop_end.x as f32,
crop_end.y as f32,
],
target_bounds: [start.x as f32, start.y as f32, end.x as f32, end.y as f32],
target_size: [target_size.x as f32, target_size.y as f32],
rounding_px: (project.background.rounding / 100.0 * 0.5 * min_target_axis)
as f32,
mirror_x: 0.0,
velocity_uv: velocity,
motion_blur_amount,
camera_motion_blur_amount: 0.0,
_padding: [0.0; 4],
},
zoom,
)
CompositeVideoFrameUniforms {
output_size: [output_size.x as f32, output_size.y as f32],
frame_size: size,
crop_bounds: [
crop_start.x as f32,
crop_start.y as f32,
crop_end.x as f32,
crop_end.y as f32,
],
target_bounds: [start.x as f32, start.y as f32, end.x as f32, end.y as f32],
target_size: [target_size.x as f32, target_size.y as f32],
rounding_px: (project.background.rounding / 100.0 * 0.5 * min_target_axis) as f32,
mirror_x: 0.0,
velocity_uv: velocity,
motion_blur_amount,
camera_motion_blur_amount: 0.0,
_padding: [0.0; 4],
}
};

let camera = options
Expand All @@ -847,8 +810,8 @@ impl ProjectUniforms {
let base_size = project.camera.size / 100.0;
let zoom_size = project.camera.zoom_size.unwrap_or(60.0) / 100.0;

let zoomed_size = (interpolated_zoom.t as f32) * zoom_size * base_size
+ (1.0 - interpolated_zoom.t as f32) * base_size;
let zoomed_size =
(zoom.t as f32) * zoom_size * base_size + (1.0 - zoom.t as f32) * base_size;

let size = [
min_axis * zoomed_size + CAMERA_PADDING,
Expand Down Expand Up @@ -877,17 +840,18 @@ impl ProjectUniforms {
];

// Calculate camera motion blur based on zoom transition
let camera_motion_blur = {
let base_blur = project.motion_blur.unwrap_or(0.2);
let zoom_delta = (current_zoom.amount - prev_zoom.amount).abs() as f32;
let camera_motion_blur = 0.0;
// {
// let base_blur = project.motion_blur.unwrap_or(0.2);
// let zoom_delta = (current_zoom.amount - prev_zoom.amount).abs() as f32;

// Calculate a smooth transition factor
let transition_speed = 30.0f32; // Frames per second
let transition_factor = (zoom_delta * transition_speed).min(1.0);
// // Calculate a smooth transition factor
// let transition_speed = 30.0f32; // Frames per second
// let transition_factor = (zoom_delta * transition_speed).min(1.0);

// Reduce multiplier from 3.0 to 2.0 for weaker blur
(base_blur * 2.0 * transition_factor).min(1.0)
};
// // Reduce multiplier from 3.0 to 2.0 for weaker blur
// (base_blur * 2.0 * transition_factor).min(1.0)
// };

CompositeVideoFrameUniforms {
output_size,
Expand Down Expand Up @@ -917,7 +881,6 @@ impl ProjectUniforms {
cursor_size: project.cursor.size as f32,
display,
camera,
zoom,
project: project.clone(),
is_upgraded,
}
Expand Down Expand Up @@ -1401,7 +1364,8 @@ fn draw_cursor(

let frame_position =
cursor_position.to_frame_space(&constants.options, &uniforms.project, resolution_base);
let position = uniforms.zoom.apply_scale(frame_position);
// let position = uniforms.zoom.apply_scale(frame_position);
let position = frame_position;
let relative_position = [position.x as f32, position.y as f32];

let cursor_uniforms = CursorUniforms {
Expand Down
Loading

0 comments on commit b5836dd

Please sign in to comment.