Skip to content

Commit

Permalink
ui: Move view transform calculation into PageLayout.
Browse files Browse the repository at this point in the history
This makes sense to have in this module next to `UiSize`,
and will eventually actually depend on the layout.
  • Loading branch information
kpreid committed Jul 24, 2024
1 parent 2fbc04f commit f0210e0
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 29 deletions.
40 changes: 13 additions & 27 deletions all-is-cubes-ui/src/ui_content/vui_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use all_is_cubes::arcstr::ArcStr;
use all_is_cubes::character::{Character, Cursor};
use all_is_cubes::inv::{EphemeralOpaque, Tool, ToolError, ToolInput};
use all_is_cubes::listen::{DirtyFlag, ListenableCell, ListenableSource, Notifier};
use all_is_cubes::math::FreeCoordinate;
use all_is_cubes::math::{FreeVector, NotNan};
use all_is_cubes::math::NotNan;
use all_is_cubes::space::Space;
use all_is_cubes::time;
use all_is_cubes::transaction::{self, Transaction};
Expand Down Expand Up @@ -237,10 +236,14 @@ impl Vui {
} => &mut self.dump_page,
};
let next_space: Handle<Space> = next_page.get_or_create_space(size, universe);
let layout = next_page.page().layout;

if Some(&next_space) != Option::as_ref(&self.current_view.get().space) {
self.current_view
.set(Self::view_state_for(Some(next_space), &self.hud_inputs));
self.current_view.set(Self::view_state_for(
layout,
Some(next_space),
&self.hud_inputs,
));
self.current_focus_on_ui = next_page.page().focus_on_ui;
log::trace!(
"UI switched to {:?} ({:?})",
Expand All @@ -250,13 +253,17 @@ impl Vui {
}
}

fn view_state_for(space: Option<Handle<Space>>, inputs: &HudInputs) -> UiViewState {
fn view_state_for(
page_layout: vui::PageLayout,
space: Option<Handle<Space>>,
inputs: &HudInputs,
) -> UiViewState {
// TODO: compute the derived graphics options only once
let graphics_options = Self::graphics_options(inputs.graphics_options.snapshot());

UiViewState {
view_transform: match space.as_ref() {
Some(space) => Self::view_transform(
Some(space) => page_layout.view_transform(
&space.read().unwrap(), // TODO: eliminate this unwrap
graphics_options.fov_y.into_inner(),
),
Expand All @@ -267,27 +274,6 @@ impl Vui {
}
}

/// Computes a [`ViewTransform`] that should be used to view the [`Vui::current_space`].
///
/// It does not need to be rechecked other than on aspect ratio changes.
///
/// TODO: used to be public before [`UiViewState`]; refactor in light of
fn view_transform(space: &Space, fov_y_degrees: FreeCoordinate) -> ViewTransform {
let bounds = space.bounds();
let mut ui_center = bounds.center();

// Arrange a view distance which will place the Z=0 plane sized to fill the viewport
// (at least vertically, as we don't have aspect ratio support yet).
ui_center.z = 0.0;

let view_distance = FreeCoordinate::from(bounds.size().height)
/ (fov_y_degrees / 2.).to_radians().tan()
/ 2.;
ViewTransform::from_translation(
ui_center.to_vector() + FreeVector::new(0., 0., view_distance),
)
}

/// Compute graphics options to render the VUI space given the user's regular options.
fn graphics_options(mut options: GraphicsOptions) -> GraphicsOptions {
// Set FOV to give a predictable, not-too-wide-angle perspective.
Expand Down
31 changes: 29 additions & 2 deletions all-is-cubes-ui/src/vui/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ use all_is_cubes::color_block;
use all_is_cubes::content::palette;
use all_is_cubes::euclid::{size2, Size2D};
use all_is_cubes::math::{
Cube, Face6, FreeCoordinate, GridAab, GridCoordinate, GridSize, GridSizeCoord, Rgba,
Cube, Face6, FreeCoordinate, FreeVector, GridAab, GridCoordinate, GridSize, GridSizeCoord, Rgba,
};
use all_is_cubes::space::{self, Space, SpaceBuilder, SpacePhysics};
use all_is_cubes::time;
use all_is_cubes::universe::{Handle, Universe};
use all_is_cubes_render::camera;
use all_is_cubes_render::camera::{self, ViewTransform};

use crate::vui::{
self, install_widgets, widgets, Align, Gravity, InstallVuiError, LayoutGrant, LayoutRequest,
Expand Down Expand Up @@ -160,6 +160,33 @@ pub(crate) enum PageLayout {
Hud,
}

impl PageLayout {
/// Calculate the camera view transform that should be used for a page with this layout.
pub(crate) fn view_transform(
self,
space: &Space,
fov_y_degrees: FreeCoordinate,
) -> ViewTransform {
let bounds = space.bounds();
let mut ui_center = bounds.center();

match self {
PageLayout::Hud => {
// Arrange a view distance which will place the Z=0 plane sized to fill the viewport
// vertically.
ui_center.z = 0.0;

let view_distance = FreeCoordinate::from(bounds.size().height)
/ (fov_y_degrees / 2.).to_radians().tan()
/ 2.;
ViewTransform::from_translation(
ui_center.to_vector() + FreeVector::new(0., 0., view_distance),
)
}
}
}
}

/// Pair of a [`Page`] and a cached space that is an instantiation of its widgets,
/// which can be recreated with a different size as needed by viewport size changes.
///
Expand Down

0 comments on commit f0210e0

Please sign in to comment.