rework interactions
This commit is contained in:
@@ -11,6 +11,7 @@ use crate::{
|
||||
overlays::{
|
||||
keyboard::create_keyboard,
|
||||
screen::{get_screens_wayland, get_screens_x11},
|
||||
toast::Toast,
|
||||
watch::create_watch,
|
||||
},
|
||||
state::AppState,
|
||||
@@ -106,7 +107,7 @@ where
|
||||
self.overlays.values_mut().for_each(|o| {
|
||||
if o.state.show_hide {
|
||||
o.state.want_visible = !any_shown;
|
||||
if o.state.want_visible && app.session.recenter_on_show {
|
||||
if o.state.want_visible && o.state.recenter {
|
||||
o.state.reset(app, false);
|
||||
}
|
||||
}
|
||||
@@ -114,6 +115,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum OverlaySelector {
|
||||
Id(usize),
|
||||
Name(Arc<str>),
|
||||
@@ -147,6 +149,7 @@ pub enum TaskType {
|
||||
OverlaySelector,
|
||||
Box<dyn FnOnce(&mut AppState, &mut OverlayState) + Send>,
|
||||
),
|
||||
Toast(Toast),
|
||||
}
|
||||
|
||||
pub struct TaskContainer {
|
||||
|
||||
@@ -239,6 +239,7 @@ pub enum PointerMode {
|
||||
Left,
|
||||
Right,
|
||||
Middle,
|
||||
Special,
|
||||
}
|
||||
|
||||
pub fn interact<O>(
|
||||
@@ -371,7 +372,7 @@ impl Pointer {
|
||||
let mut hits: SmallVec<[RayHit; 8]> = smallvec!();
|
||||
|
||||
for overlay in overlays.iter() {
|
||||
if !overlay.state.want_visible {
|
||||
if !overlay.state.want_visible || !overlay.state.interactable {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -435,30 +436,32 @@ impl Pointer {
|
||||
O: Default,
|
||||
{
|
||||
if self.now.grab {
|
||||
if self.now.click && !self.before.click {
|
||||
log::warn!("todo: click-while-grabbed");
|
||||
}
|
||||
|
||||
let grab_data = self.interaction.grabbed.as_mut().unwrap();
|
||||
match self.interaction.mode {
|
||||
PointerMode::Left => {
|
||||
grab_data.offset.z -= self.now.scroll * 0.05;
|
||||
}
|
||||
_ => {
|
||||
overlay.state.transform.matrix3 = overlay
|
||||
.state
|
||||
.transform
|
||||
.matrix3
|
||||
.mul_scalar(1.0 + 0.01 * self.now.scroll);
|
||||
if self.now.click {
|
||||
self.interaction.mode = PointerMode::Special;
|
||||
let cur_scale = overlay.state.transform.x_axis.length();
|
||||
if cur_scale < 0.1 && self.now.scroll > 0.0 {
|
||||
return;
|
||||
} else if cur_scale > 20. && self.now.scroll < 0.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
overlay.state.transform.matrix3 = overlay
|
||||
.state
|
||||
.transform
|
||||
.matrix3
|
||||
.mul_scalar(1.0 - 0.025 * self.now.scroll);
|
||||
} else {
|
||||
grab_data.offset.z -= self.now.scroll * 0.05;
|
||||
}
|
||||
overlay.state.transform.translation = self.pose.transform_point3a(grab_data.offset);
|
||||
overlay.state.realign(hmd);
|
||||
overlay.state.dirty = true;
|
||||
} else {
|
||||
overlay.state.spawn_point = hmd
|
||||
.inverse()
|
||||
.transform_point3a(overlay.state.transform.translation);
|
||||
overlay.state.saved_point = Some(
|
||||
hmd.inverse()
|
||||
.transform_point3a(overlay.state.transform.translation),
|
||||
);
|
||||
self.interaction.grabbed = None;
|
||||
log::info!("Hand {}: dropped {}", self.idx, overlay.state.name);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ static AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(1);
|
||||
pub(super) struct LinePool {
|
||||
lines: IdMap<usize, OverlayData<OpenVrOverlayData>>,
|
||||
view: Arc<ImageView>,
|
||||
colors: [Vec4; 4],
|
||||
colors: [Vec4; 5],
|
||||
}
|
||||
|
||||
impl LinePool {
|
||||
@@ -52,6 +52,7 @@ impl LinePool {
|
||||
Vec4::new(0., 0.375, 0.5, 1.),
|
||||
Vec4::new(0.69, 0.188, 0., 1.),
|
||||
Vec4::new(0.375, 0., 0.5, 1.),
|
||||
Vec4::new(1., 0., 0., 1.),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,10 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
||||
f(&mut state, &mut o.state);
|
||||
}
|
||||
}
|
||||
TaskType::Toast(t) => {
|
||||
// TODO toasts
|
||||
log::info!("Toast: {} {}", t.title, t.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ impl LinePool {
|
||||
[0x00, 0x60, 0x80, 0xff],
|
||||
[0xB0, 0x30, 0x00, 0xff],
|
||||
[0x60, 0x00, 0x80, 0xff],
|
||||
[0xff, 0x00, 0x00, 0xff],
|
||||
];
|
||||
|
||||
let views = colors
|
||||
|
||||
@@ -186,6 +186,10 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
||||
f(&mut app_state, &mut o.state);
|
||||
}
|
||||
}
|
||||
TaskType::Toast(t) => {
|
||||
// TODO toasts
|
||||
log::info!("Toast: {} {}", t.title, t.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,11 @@ pub struct OverlayState {
|
||||
pub want_visible: bool,
|
||||
pub show_hide: bool,
|
||||
pub grabbable: bool,
|
||||
pub interactable: bool,
|
||||
pub recenter: bool,
|
||||
pub dirty: bool,
|
||||
pub transform: Affine3A,
|
||||
pub saved_point: Option<Vec3A>,
|
||||
pub spawn_scale: f32, // aka width
|
||||
pub spawn_point: Vec3A,
|
||||
pub spawn_rotation: Quat,
|
||||
@@ -43,8 +46,11 @@ impl Default for OverlayState {
|
||||
want_visible: false,
|
||||
show_hide: false,
|
||||
grabbable: false,
|
||||
recenter: false,
|
||||
interactable: false,
|
||||
dirty: true,
|
||||
relative_to: RelativeTo::None,
|
||||
saved_point: None,
|
||||
spawn_scale: 1.0,
|
||||
spawn_point: Vec3A::NEG_Z,
|
||||
spawn_rotation: Quat::IDENTITY,
|
||||
@@ -90,26 +96,31 @@ impl OverlayState {
|
||||
|
||||
pub fn auto_movement(&mut self, app: &mut AppState) {
|
||||
if let Some(parent) = self.parent_transform(app) {
|
||||
let point = self.saved_point.unwrap_or(self.spawn_point);
|
||||
self.transform = parent
|
||||
* Affine3A::from_scale_rotation_translation(
|
||||
Vec3::ONE * self.spawn_scale,
|
||||
self.spawn_rotation
|
||||
* Quat::from_rotation_x(f32::to_radians(-180.0))
|
||||
* Quat::from_rotation_z(f32::to_radians(180.0)),
|
||||
self.spawn_point.into(),
|
||||
point.into(),
|
||||
);
|
||||
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset(&mut self, app: &mut AppState, reset_scale: bool) {
|
||||
let translation = app.input_state.hmd.transform_point3a(self.spawn_point);
|
||||
let scale = if reset_scale {
|
||||
pub fn reset(&mut self, app: &mut AppState, hard_reset: bool) {
|
||||
let scale = if hard_reset {
|
||||
self.saved_point = None;
|
||||
self.spawn_scale
|
||||
} else {
|
||||
self.transform.x_axis.length()
|
||||
};
|
||||
|
||||
let point = self.saved_point.unwrap_or(self.spawn_point);
|
||||
|
||||
let translation = app.input_state.hmd.transform_point3a(point);
|
||||
self.transform = Affine3A::from_scale_rotation_translation(
|
||||
Vec3::ONE * scale,
|
||||
Quat::IDENTITY,
|
||||
|
||||
Reference in New Issue
Block a user