Skip to content

Commit

Permalink
Require fewer steps and avoid being lossy when computing up
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Dec 12, 2023
1 parent 78fc2d6 commit 8c9d0c4
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 35 deletions.
26 changes: 8 additions & 18 deletions src/geopos.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{player::Position, tilemap::TileCoord, GalacticTransformOwned};
use crate::{player::PlanetaryPosition, tilemap::TileCoord};
use bevy::prelude::*;
use big_space::FloatingOriginSettings;
use glam::DVec3;
use globe_rs::{CartesianPoint, GeographicPoint};
use std::f32::consts::PI;
Expand Down Expand Up @@ -56,25 +55,16 @@ impl GeoPos {
TileCoord::new(Vec2 { x, y }, zoom)
}

/// Prefer using `to_cartesian`, which returns a [`Position`] that has a lot more convenience
/// methods.
pub fn to_cartesian_vec(self) -> DVec3 {
/// Compute the galactic position on the planet's surface.
pub fn to_cartesian(self) -> PlanetaryPosition {
let geo = GeographicPoint::new(
(self.lon as f64).to_radians(),
(self.lat as f64).to_radians(),
EARTH_RADIUS as f64,
);
let cart = CartesianPoint::from_geographic(&geo);
DVec3::new(-cart.x(), -cart.y(), cart.z())
}

/// Compute the galactic position on the planet's surface.
pub fn to_cartesian(self, space: &FloatingOriginSettings) -> Position<'_> {
let pos = self.to_cartesian_vec();
let (cell, pos) = space.translation_to_grid(pos);
let transform = Transform::from_translation(pos);
let pos = GalacticTransformOwned { transform, cell };
Position { pos, space }
let pos = DVec3::new(-cart.x(), -cart.y(), cart.z());
PlanetaryPosition { pos }
}

pub fn from_cartesian(pos: DVec3) -> Self {
Expand All @@ -89,9 +79,9 @@ impl GeoPos {
/// Tile width and height in meters
pub fn tile_size(self, zoom: u8) -> Vec2 {
let coord = self.to_tile_coordinates(zoom);
let pos = self.to_cartesian_vec();
let x = coord.right().to_geo_pos().to_cartesian_vec().distance(pos) as f32;
let y = coord.down().to_geo_pos().to_cartesian_vec().distance(pos) as f32;
let pos = self.to_cartesian();
let x = coord.right().to_geo_pos().to_cartesian().distance(*pos) as f32;
let y = coord.down().to_geo_pos().to_cartesian().distance(*pos) as f32;
Vec2 { x, y }
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use big_space::{
FloatingOriginPlugin, FloatingOriginSettings, GridCell,
};
use geopos::{GeoPos, EARTH_RADIUS};
use glam::DVec3;
use http_assets::HttpAssetReaderPlugin;
use player::PlanetaryPosition;
use tilemap::{TileIndex, TileMap, TILE_ZOOM};

mod flycam;
Expand All @@ -45,7 +45,7 @@ type GalacticTransformItem<'a> = GridTransformItem<'a, GridPrecision>;

#[derive(Resource)]
struct Args {
starting_position: DVec3,
starting_position: PlanetaryPosition,
height: f32,
direction: f32,
view: f32,
Expand Down Expand Up @@ -103,7 +103,7 @@ pub fn main() {

let mut app = App::new();
app.insert_resource(Args {
starting_position: pos.to_cartesian_vec(),
starting_position: pos.to_cartesian(),
height,
direction,
view,
Expand Down
36 changes: 36 additions & 0 deletions src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,42 @@ pub struct Player<'w, 's> {
pub(crate) space: Res<'w, FloatingOriginSettings>,
}

/// A helper for working with positions relative to the planet center.
#[derive(Clone, Copy)]
pub struct PlanetaryPosition {
pub pos: DVec3,
}

impl Into<DVec3> for PlanetaryPosition {
fn into(self) -> DVec3 {
self.pos
}
}

impl std::ops::Deref for PlanetaryPosition {
type Target = DVec3;

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

impl PlanetaryPosition {
pub fn to_galactic_position(self, space: &FloatingOriginSettings) -> Position<'_> {
let (cell, pos) = space.translation_to_grid(self.pos);
let transform = Transform::from_translation(pos);
let pos = GalacticTransformOwned { transform, cell };
Position { pos, space }
}

pub fn directions(self) -> Directions {
let up = self.pos.normalize().as_vec3();
let west = Vec3::Z.cross(up);
let north = up.cross(west);
Directions { up, north, west }
}
}

/// A helper for working with galactic positions.
pub struct Position<'a> {
pub pos: GalacticTransformOwned,
Expand Down
19 changes: 7 additions & 12 deletions src/tilemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,10 @@ fn flat_tile(

// Four corners of the tile in cartesian coordinates relative to the
// planet's center.
let a = coord.to_geo_pos().to_cartesian_vec();
let b = pos.right().as_coord().to_geo_pos().to_cartesian_vec();
let c = pos
.down()
.right()
.as_coord()
.to_geo_pos()
.to_cartesian_vec();
let d = pos.down().as_coord().to_geo_pos().to_cartesian_vec();
let a = coord.to_geo_pos().to_cartesian();
let b = pos.right().as_coord().to_geo_pos().to_cartesian();
let c = pos.down().right().as_coord().to_geo_pos().to_cartesian();
let d = pos.down().as_coord().to_geo_pos().to_cartesian();

// Normals on a sphere are just the position on the sphere normalized.
let normals = vec![
Expand All @@ -197,9 +192,9 @@ fn flat_tile(
];

// `a` is our anchor point, all others are relative
let b = b - a;
let c = c - a;
let d = d - a;
let b = *b - *a;
let c = *c - *a;
let d = *d - *a;

let (grid, a) = space.translation_to_grid(a);
let b = a + b.as_vec3();
Expand Down
4 changes: 2 additions & 2 deletions src/tilemap/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ impl TileIndex {

pub fn to_cartesian(self, space: &FloatingOriginSettings) -> GalacticTransformOwned {
let coord = self.as_coord().center();
let pos = coord.to_geo_pos().to_cartesian(space);
let pos = coord.to_geo_pos().to_cartesian();
let Directions { up, north, west: _ } = pos.directions();
let mut pos = pos.pos;
let mut pos = pos.to_galactic_position(space).pos;
pos.transform.look_to(north, up);
pos
}
Expand Down

0 comments on commit 8c9d0c4

Please sign in to comment.