feat: add full frame 3d support

Related to #346
This commit is contained in:
amoshydra
2026-01-11 06:32:41 +08:00
committed by galister
parent 37e3ab1bda
commit ce5191ddd1
11 changed files with 90 additions and 8 deletions

View File

@@ -82,6 +82,9 @@
<PosButton id="stereo_topbottom" src="edit/3d_topbottom.svg" tooltip="EDIT_MODE.STEREO_3D_MODE.SPLIT_TOP_BOTTOM" press="::EditModeSetStereo topbottom" />
<PosButton id="stereo_bottomtop" src="edit/3d_bottomtop.svg" tooltip="EDIT_MODE.STEREO_3D_MODE.SPLIT_BOTTOM_TOP" press="::EditModeSetStereo bottomtop" />
</div>
<div justify_content="center" align_items="center">
<CheckBox id="stereo_full_frame_box" translation="EDIT_MODE.STEREO_3D_MODE.FULL_FRAME" tooltip_side="top" />
</div>
</div>
<div id="tab_mouse" display="none" height="100" flex_direction="column">
<div padding_left="8" padding_right="8" gap="8" justify_content="center" align_items="center">

View File

@@ -54,7 +54,8 @@
"SPLIT_LEFT_RIGHT": "LINKS→RECHTS",
"SPLIT_RIGHT_LEFT": "RECHTS→LINKS",
"SPLIT_TOP_BOTTOM": "OBEN→UNTEN",
"SPLIT_BOTTOM_TOP": "UNTEN→OBEN"
"SPLIT_BOTTOM_TOP": "UNTEN→OBEN",
"FULL_FRAME": "Voll 3D"
},
"STEREO_3D_MODE_": {},
"ALIGN_TO_HMD": "An HMD ausrichten",

View File

@@ -44,7 +44,8 @@
"SPLIT_LEFT_RIGHT": "LEFT→RIGHT",
"SPLIT_RIGHT_LEFT": "RIGHT→LEFT",
"SPLIT_TOP_BOTTOM": "TOP→BOTTOM",
"TITLE": "3D Stereo Mode"
"TITLE": "3D Stereo Mode",
"FULL_FRAME": "Full 3D"
},
"MOUSE": {
"TITLE": "Mouse fixes",

View File

@@ -54,7 +54,8 @@
"SPLIT_LEFT_RIGHT": "IZQ→DER",
"SPLIT_RIGHT_LEFT": "DERECHA→IZQUIERDA",
"SPLIT_TOP_BOTTOM": "ARRIBA→ABAJO",
"SPLIT_BOTTOM_TOP": "ABAJO→ARRIBA"
"SPLIT_BOTTOM_TOP": "ABAJO→ARRIBA",
"FULL_FRAME": "3D completo"
},
"STEREO_3D_MODE_": {},
"ALIGN_TO_HMD": "Alinear al HMD",

View File

@@ -44,7 +44,8 @@
"SPLIT_LEFT_RIGHT": "SINISTRA→DESTRA",
"SPLIT_RIGHT_LEFT": "DESTRA→SINISTRA",
"SPLIT_TOP_BOTTOM": "TOP→BOTTOM",
"TITLE": "Modalità Stereo 3D"
"TITLE": "Modalità Stereo 3D",
"FULL_FRAME": "3D Completo"
},
"MOUSE": {
"TITLE": "Correzioni del mouse",

View File

@@ -53,7 +53,8 @@
"SPLIT_LEFT_RIGHT": "左→右",
"SPLIT_RIGHT_LEFT": "右→左",
"SPLIT_TOP_BOTTOM": "上→下",
"SPLIT_BOTTOM_TOP": "下→上"
"SPLIT_BOTTOM_TOP": "下→上",
"FULL_FRAME": "フル3D"
},
"ALIGN_TO_HMD": "常にHMDの方を向く",
"MOUSE": {

View File

@@ -53,7 +53,8 @@
"SPLIT_LEFT_RIGHT": "LEWO→PRAWO",
"SPLIT_RIGHT_LEFT": "PRAWO→LEWO",
"SPLIT_TOP_BOTTOM": "GÓRA→DÓŁ",
"TITLE": "Tryb stereoskopowy 3D"
"TITLE": "Tryb stereoskopowy 3D",
"FULL_FRAME": "Pełny 3D"
},
"ALIGN_TO_HMD": "Dopasuj do HMD",
"MOUSE": {

View File

@@ -355,6 +355,24 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
Ok(EventResult::Consumed)
})
}
"::EditModeSetStereoFullFrame" => {
let full_frame = args.next().unwrap().parse::<bool>().unwrap();
Box::new(move |common, data, app, state| {
if !test_button(data) || !test_duration(&button, app) {
return Ok(EventResult::Pass);
}
let sel = OverlaySelector::Id(*state.id.borrow());
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
sel,
Box::new(move |_app, owc| {
let attrib = BackendAttribValue::StereoFullFrame(full_frame);
owc.backend.set_attrib(_app, attrib);
}),
)));
Ok(EventResult::Consumed)
})
}
"::EditModeSetMouse" => {
let key = args.next().unwrap().to_owned();
Box::new(move |common, data, app, state| {
@@ -412,6 +430,11 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
set_up_checkbox(&mut panel, "additive_box", cb_assign_additive)?;
set_up_checkbox(&mut panel, "align_box", cb_assign_align)?;
set_up_checkbox(
&mut panel,
"stereo_full_frame_box",
cb_assign_stereo_full_frame,
)?;
set_up_slider(&mut panel, "lerp_slider", cb_assign_lerp)?;
set_up_slider(&mut panel, "alpha_slider", cb_assign_alpha)?;
set_up_slider(&mut panel, "curve_slider", cb_assign_curve)?;
@@ -499,6 +522,16 @@ fn reset_panel(
.set_tab_visible(&mut common, "mouse", false);
}
if let Some(full_frame) = attrib_value!(
owc.backend.get_attrib(BackendAttrib::StereoFullFrame),
BackendAttribValue::StereoFullFrame
) {
let c = panel
.parser_state
.fetch_component_as::<ComponentCheckbox>("stereo_full_frame_box")?;
c.set_checked(&mut common, full_frame);
}
panel.layout.process_alterables(alterables)?;
Ok(())
@@ -535,6 +568,16 @@ const fn cb_assign_align(_app: &mut AppState, owc: &mut OverlayWindowConfig, ali
active_state.positioning = active_state.positioning.with_align(align);
}
fn cb_assign_stereo_full_frame(
_app: &mut AppState,
owc: &mut OverlayWindowConfig,
full_frame: bool,
) {
owc.dirty = true;
let attrib = BackendAttribValue::StereoFullFrame(full_frame);
owc.backend.set_attrib(_app, attrib);
}
fn set_up_slider(
panel: &mut EditModeWrapPanel,
id: &str,

View File

@@ -57,6 +57,7 @@ pub struct ScreenBackend {
mouse_transform: Affine2,
interaction_transform: Option<Affine2>,
stereo: Option<StereoMode>,
stereo_full_frame: bool,
pub(super) logical_pos: Vec2,
pub(super) logical_size: Vec2,
pub(super) mouse_transform_original: Transform,
@@ -85,6 +86,7 @@ impl ScreenBackend {
} else {
None
},
stereo_full_frame: false,
logical_pos: Vec2::ZERO,
logical_size: Vec2::ZERO,
mouse_transform_original: Transform::Undefined,
@@ -208,7 +210,22 @@ impl OverlayBackend for ScreenBackend {
if let Some(frame) = self.capture.receive() {
let stereo = self.stereo.unwrap_or(StereoMode::None);
let meta = frame.get_frame_meta(&app.session.config, stereo);
let mut meta = frame.get_frame_meta(&app.session.config, stereo);
if let Some(stereo) = self.stereo {
// Apply stereo full frame logic
if self.stereo_full_frame {
match stereo {
StereoMode::LeftRight | StereoMode::RightLeft => {
meta.extent[0] /= 2;
}
StereoMode::TopBottom | StereoMode::BottomTop => {
meta.extent[1] /= 2;
}
_ => {}
}
}
}
if let Some(pipeline) = self.pipeline.as_mut() {
if self.meta.is_some_and(|old| old.extent != meta.extent) {
@@ -331,6 +348,9 @@ impl OverlayBackend for ScreenBackend {
BackendAttrib::MouseTransform => Some(BackendAttribValue::MouseTransform(
self.mouse_transform_override,
)),
BackendAttrib::StereoFullFrame => {
Some(BackendAttribValue::StereoFullFrame(self.stereo_full_frame))
}
_ => None,
}
}
@@ -364,6 +384,10 @@ impl OverlayBackend for ScreenBackend {
self.apply_mouse_transform_with_override(frame_transform);
true
}
BackendAttribValue::StereoFullFrame(new) => {
self.stereo_full_frame = new;
true
}
_ => false,
}
}

View File

@@ -382,7 +382,11 @@ where
}
}
const SAVED_ATTRIBS: [BackendAttrib; 2] = [BackendAttrib::Stereo, BackendAttrib::MouseTransform];
const SAVED_ATTRIBS: [BackendAttrib; 3] = [
BackendAttrib::Stereo,
BackendAttrib::StereoFullFrame,
BackendAttrib::MouseTransform,
];
impl<T> OverlayWindowManager<T> {
pub fn pop_dropped(&mut self) -> Option<OverlayWindowData<T>> {

View File

@@ -22,6 +22,7 @@ pub enum ToastDisplayMethod {
#[derive(Debug, Clone, Copy, IntegerId, PartialEq)]
pub enum BackendAttrib {
Stereo,
StereoFullFrame,
MouseTransform,
Icon,
}
@@ -29,6 +30,7 @@ pub enum BackendAttrib {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BackendAttribValue {
Stereo(StereoMode),
StereoFullFrame(bool),
MouseTransform(MouseTransform),
#[serde(skip_serializing, skip_deserializing)]
Icon(Arc<str>),