Skip to content

Commit

Permalink
Add a helper that combines Grid and Transform
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Dec 12, 2023
1 parent 79d39c8 commit 42aa0e7
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 28 deletions.
7 changes: 3 additions & 4 deletions src/flycam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use bevy_flycam::{FlyCam, KeyBindings, MovementSettings, NoCameraPlayerPlugin};
use big_space::{FloatingOrigin, FloatingOriginSettings};

use crate::geopos::EARTH_RADIUS;
use crate::GalacticGrid;
use crate::{GalacticGrid, GalacticTransform};

pub struct Plugin;

Expand Down Expand Up @@ -126,11 +126,10 @@ fn setup(

fn update_camera_speed(
mut movement_settings: ResMut<MovementSettings>,
fly_cam: Query<(&Transform, &GalacticGrid), With<FlyCam>>,
fly_cam: Query<GalacticTransform, With<FlyCam>>,
space: Res<FloatingOriginSettings>,
) {
let (transform, grid) = fly_cam.single();
let elevation = space.grid_position_double(grid, transform).length() as f32;
let elevation = fly_cam.single().grid_position_double(&space).length() as f32;
let speed = (1. * (elevation - crate::geopos::EARTH_RADIUS - 300.0)).max(100.0);
movement_settings.speed = speed;
}
Expand Down
51 changes: 36 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::f32::consts::FRAC_PI_2;

use bevy::{
diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin},
ecs::query::WorldQuery,
pbr::NotShadowCaster,
prelude::*,
};
Expand Down Expand Up @@ -255,7 +256,7 @@ mod player;

fn reposition_compass(
mut compass: Query<
(&mut Transform, &mut GalacticGrid),
GalacticTransform,
(With<Compass>, Without<FlyCam>, Without<OpenXRTrackingRoot>),
>,
mut commands: Commands,
Expand All @@ -264,12 +265,12 @@ fn reposition_compass(
server: Res<AssetServer>,
player: player::Player,
) {
if let Ok((mut pos, mut grid)) = compass.get_single_mut() {
if let Ok(mut compass) = compass.get_single_mut() {
let player = player.pos();
let directions = player.directions();
pos.translation = player.transform.translation - directions.up * 5.;
*grid = player.grid;
pos.look_to(directions.north, directions.up)
compass.transform.translation = player.transform.translation - directions.up * 5.;
*compass.grid = *player.grid;
compass.transform.look_to(directions.north, directions.up)
} else {
let mesh = shape::Plane::default();
let mesh = meshes.add(mesh.into());
Expand Down Expand Up @@ -298,34 +299,54 @@ fn reposition_compass(

fn update_camera_orientations(
mut movement_settings: ResMut<MovementSettings>,
fly_cam: Query<(&Transform, &GalacticGrid), With<FlyCam>>,
fly_cam: Query<GalacticTransform, With<FlyCam>>,
space: Res<FloatingOriginSettings>,
) {
let (transform, grid) = fly_cam.single();
movement_settings.up = space
.grid_position_double(grid, transform)
movement_settings.up = fly_cam
.single()
.grid_position_double(&space)
.normalize()
.as_vec3();
}

fn pull_to_ground(
time: Res<Time>,
mut tracking_root_query: Query<(&mut Transform, &GalacticGrid), With<OpenXRTrackingRoot>>,
mut tracking_root_query: Query<GalacticTransform, With<OpenXRTrackingRoot>>,
space: Res<FloatingOriginSettings>,
) {
let Ok((mut root, grid)) = tracking_root_query.get_single_mut() else {
let Ok(mut root) = tracking_root_query.get_single_mut() else {
return;
};

let adjustment_rate = (time.delta_seconds() * 10.0).min(1.0);

// Lower player onto sphere
let real_pos = space.grid_position_double(grid, &root);
let real_pos = root.grid_position_double(&space);
let up = real_pos.normalize();
let diff = up * EARTH_RADIUS as f64 - real_pos;
root.translation += diff.as_vec3() * adjustment_rate;
root.transform.translation += diff.as_vec3() * adjustment_rate;

// Rotate player to be upright on sphere
let angle_diff = Quat::from_rotation_arc(root.up(), up.as_vec3());
root.rotate(Quat::IDENTITY.slerp(angle_diff, adjustment_rate));
let angle_diff = Quat::from_rotation_arc(root.transform.up(), up.as_vec3());
root.transform
.rotate(Quat::IDENTITY.slerp(angle_diff, adjustment_rate));
}

#[derive(WorldQuery)]
#[world_query(mutable)]
pub struct GalacticTransform {
pub transform: &'static mut Transform,
pub grid: &'static mut GalacticGrid,
}

impl<'w> GalacticTransformItem<'w> {
pub fn grid_position_double(&self, space: &FloatingOriginSettings) -> DVec3 {
space.grid_position_double(&self.grid, &self.transform)
}
}

impl<'w> GalacticTransformReadOnlyItem<'w> {
pub fn grid_position_double(&self, space: &FloatingOriginSettings) -> DVec3 {
space.grid_position_double(self.grid, self.transform)
}
}
26 changes: 17 additions & 9 deletions src/player.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::GalacticTransform;
use crate::GalacticTransformReadOnlyItem;

use super::Compass;
use super::GalacticGrid;
use super::OpenXRTrackingRoot;
use bevy::ecs::system::SystemParam;
use bevy::prelude::*;
Expand All @@ -12,27 +14,34 @@ pub struct Player<'w, 's> {
pub(crate) xr_pos: Query<
'w,
's,
(&'static Transform, &'static GalacticGrid),
GalacticTransform,
(With<OpenXRTrackingRoot>, Without<FlyCam>, Without<Compass>),
>,
pub(crate) flycam_pos: Query<
'w,
's,
(&'static Transform, &'static GalacticGrid),
GalacticTransform,
(With<FlyCam>, Without<OpenXRTrackingRoot>, Without<Compass>),
>,
pub(crate) space: Res<'w, FloatingOriginSettings>,
}

pub struct PlayerPosition<'a> {
pub transform: Transform,
pub grid: GalacticGrid,
pub pos: GalacticTransformReadOnlyItem<'a>,
pub space: &'a FloatingOriginSettings,
}

impl<'a> std::ops::Deref for PlayerPosition<'a> {
type Target = GalacticTransformReadOnlyItem<'a>;

fn deref(&self) -> &Self::Target {
&self.pos
}
}

impl PlayerPosition<'_> {
pub fn pos(&self) -> DVec3 {
self.space.grid_position_double(&self.grid, &self.transform)
self.pos.grid_position_double(&self.space)
}
pub fn directions(&self) -> Directions {
let up = self.pos().normalize().as_vec3();
Expand All @@ -50,14 +59,13 @@ pub struct Directions {

impl<'w, 's> Player<'w, 's> {
pub fn pos(&self) -> PlayerPosition<'_> {
let (&transform, &grid) = if let Ok(xr_pos) = self.xr_pos.get_single() {
let pos = if let Ok(xr_pos) = self.xr_pos.get_single() {
xr_pos
} else {
self.flycam_pos.single()
};
PlayerPosition {
transform,
grid,
pos,
space: &self.space,
}
}
Expand Down

0 comments on commit 42aa0e7

Please sign in to comment.