Skip to content

Commit

Permalink
back to basics
Browse files Browse the repository at this point in the history
  • Loading branch information
philiplinden committed Aug 6, 2024
1 parent 363e082 commit 8638309
Show file tree
Hide file tree
Showing 13 changed files with 845 additions and 1,887 deletions.
2,522 changes: 651 additions & 1,871 deletions Cargo.lock

Large diffs are not rendered by default.

47 changes: 32 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,43 @@ version = "0.2.0"
edition = "2021"

[dependencies]
avian = "0.0.0"
bevy = "0.14.0"
bevy_asset_loader = { version = "0.21.0", features = ["progress_tracking"] }
bevy_kira_audio = "0.20.0"
bevy_mod_picking = { version = "0.20.1", features = ["backend_avian", "bevy_picking_avian", "bevy_picking_highlight"] }
iyes_progress = { version = "0.12.0", features = ["assets", "bevy_asset", "bevy_log"] }
leafwing-input-manager = "0.14.0"
# Disable low-severity logs at compile time for performance.
log = { version = "0.4.22", features = [
"max_level_debug",
"release_max_level_warn",
bevy_mod_picking = { version = "0.20.1", features = [
"backend_avian",
"backend_egui",
"bevy_picking_avian",
"bevy_picking_egui",
"bevy_picking_highlight",
] }
iyes_progress = { version = "0.12.0", features = [
"assets",
"bevy_asset",
"bevy_log",
] }
iyes_perf_ui = "0.3.0"
rand = "0.8"
sickle_ui = { rev = "a548517", git = "https://github.com/UmbraLuminosa/sickle_ui" }
big_space = "0.7.0"
hifitime = "3.9.0"
particular = { version = "0.7.0", features = ["gpu", "parallel"] }
log = { version = "0.4.22", features = [
# Disable low-severity logs at compile time for performance.
"max_level_debug",
"release_max_level_warn",
] }
bevy_egui = { version = "0.28.0", features = ["serde"] }
avian2d = { version = "0.1.1", default-features = false, features = [
"2d",
"bevy_scene",
"f64",
"parallel",
"parry-f64",
"default-collider",
"enhanced-determinism",
"serialize",
] }
bevy_lit = "0.2.2"
bevy-inspector-egui = { version = "0.25.1", features = ["highlight_changes"] }
bevy_pancam = { version = "0.13.0", features = ["bevy_egui"] }

[dev-dependencies]
bevy-inspector-egui = { version = "0.25.1", features = ["highlight_changes"] }
Expand All @@ -38,6 +58,7 @@ dev = [
"bevy/dynamic_linking",
"bevy/bevy_dev_tools",
"iyes_progress/debug",
"avian2d/debug-plugin",
]
dev_native = [
"dev",
Expand Down Expand Up @@ -67,10 +88,6 @@ opt-level = 1
[profile.dev.package."*"]
opt-level = 3

# Remove expensive debug assertions due to <https://github.com/bevyengine/bevy/issues/14291>
[profile.dev.package.wgpu-types]
debug-assertions = false

# The default profile is optimized for Wasm builds because
# that's what [Trunk reads](https://github.com/trunk-rs/trunk/issues/605).
# Optimize for size in the wasm-release profile to reduce load times and bandwidth usage on web.
Expand Down
8 changes: 8 additions & 0 deletions docs/design/simulation_limits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 2D, not 3D

In 2D physics-space, rendering-space, and screen-space are basically the same thing. We can hand-wave away translations
therein and all the complexities of visualizing information about a 3D volume in 2D screen-space.

2D simulation space was selected mainly because it simplifies visualizations of information like gravitational potential
over large areas and it makes the use of compute shaders simpler as well. For example, offloading those gravity field
calculations to the GPU with a shader and then recovering that information back on the CPU later.
49 changes: 49 additions & 0 deletions docs/devlog/v0.2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,52 @@ I've set up the devlogs (formerly `captains_log`) roughly organized by major mil
with git tags. Seems like a reasonable way to break it up to me.

I can't help it, I have to mess with the site theme too. 2 hours gone.

# 2024-08-05
Starting from scratch. First question: 2D or 3D?

Honestly I'm not certain it matters. The physics engine, `avian` fully supports 2D and 3D as does the Bevy renderer.
The renderer supports physically based rendering (PBR) for 2D and 3D too. As far as I can tell, though,
[radiance cascades](https://github.com/kornelski/bevy_flatland_radiance_cascades) are only doable in 2D.

In 2D physics-space, rendering-space, and screen-space are basically the same thing. We can hand-wave away translations
therein and all the complexities of visualizing information about a 3D volume in 2D screen-space. Astrodynamics gets a
little simpler in 2D but mainly for mission design rather than computations (where it basically doesn't matter much).
It might be necessary to remove collisions between orbiting bodies in order to make things usable, though.

**I'm going to go with 2D** mainly because it makes it way simpler to visualize information like gravitational potential
over large areas and it makes the use of compute shaders simpler as well. For example, offloading those gravity field
calculations to the GPU with a shader and then recovering that information back on the CPU later.

Now I need to choose my first task. Let's start with a simple not-to-scale 2-body system.

1. Spawn a central body and an orbiting body.
2. Speed up or slow down the simulation clock.
3. Add panning and zooming to the camera.
4. Allow the camera to follow an entity, and to change which entity is followed.

Second question: which UI crate?

[egui](https://www.egui.rs/) is naturally option here. Egui is fully featured, looks pretty good, and there are examples
for basically every kind of UI element I could need. The downside is that Egui can't really be styled. This is probably
the best option for now, accepting that I might re-do the UI later on with something more artsy.

[Lunex](https://github.com/bytestring-net/bevy_lunex) is the UI crate that I've been most interested in using. It looks
great, leans hard into ECS (which I want to get more experience with), and has diagetic UI at the forefront. I don't
really need diagetic UI, but it would be cool to have interactive UI elements attached to entities instead of in a menu.
The [documentation](https://bytestring-net.github.io/bevy_lunex/) for Lunex looks really great and the
[examples](https://github.com/IDEDARY/Bevypunk) are stunning. I'd like to come back to this one later.

Other options are the default [bevy_ui](https://bevyengine.org/examples/ui-user-interface/ui/) which is lacking some
features and ergonomics, or [sickle_ui](https://github.com/UmbraLuminosa/sickle_ui), the prospective replacement for
Bevy's native UI someday. Sickle and Bevy UI crates lean into "widgets" for UI elements. To be honest, this approach
doesn't really "click" with me. I probably won't use it.

Verdict: **[egui](https://www.egui.rs/) now, [lunex](https://bytestring-net.github.io/bevy_lunex/) later**.

## Summary
- Decided to stick with 2D.
- Decided to use `bevy_egui` for now, and come back to stylized UI later with `bevy_lunex`.
- Added `bevy_pancam`, `bevy-inspector-egui`, and `bevy_lit` as dependencies.
- Selected f64 features for `avian2d`.
- Made a basic UI
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ nav:
- design:
- goals: index.md
- tools_and_frameworks: design/tools_and_frameworks.md
- simulation_limits: design/simulation_limits.md
- technical: technical/
- devlog:
- latest: devlog/v0.2.0.md
Expand Down
Empty file added src/constants.rs
Empty file.
20 changes: 19 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
mod ui;
pub mod palette;

use bevy::prelude::*;
pub struct AppPlugin;

Expand All @@ -17,10 +20,25 @@ impl Plugin for AppPlugin {
}
.into(),
..default()
}),
})
.set(ImagePlugin::default_nearest()),
);

// Add custom plugins.
app.add_plugins(ui::UserInterfacePlugins);

// Initialize the app state enum
app.init_state::<AppState>();

// Change the background color.
app.insert_resource(ClearColor(palette::BEVY_GRAY));
}
}


#[derive(Resource, Debug, Clone, Eq, PartialEq, Hash, States, Default)]
pub enum AppState {
Paused,
#[default]
Running,
}
5 changes: 5 additions & 0 deletions src/palette.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! Color palette
use bevy::color::Color;

pub const BEVY_GRAY: Color = Color::srgb(0.157, 0.157, 0.157);
pub const TERMINAL_GREEN: Color = Color::hsl(118.882, 0.535, 0.109);
Empty file added src/spawners/mod.rs
Empty file.
11 changes: 11 additions & 0 deletions src/ui/camera.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use bevy::prelude::*;
use bevy_pancam::{PanCam, PanCamPlugin};

pub(super) fn plugin(app: &mut App) {
app.add_plugins(PanCamPlugin::default());
app.add_systems(Startup, init_camera);
}

fn init_camera(mut commands: Commands) {
commands.spawn((Camera2dBundle::default(), PanCam::default()));
}
19 changes: 19 additions & 0 deletions src/ui/cursor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use bevy::prelude::*;
use bevy_mod_picking::prelude::*;

pub struct CursorPlugin;

impl Plugin for CursorPlugin {
fn build(&self, app: &mut App) {
let debug_level: DebugPickingMode;
#[cfg(not(feature = "dev"))]
{
debug_level = DebugPickingMode::Disabled;
}
#[cfg(feature = "dev")]
{
debug_level = DebugPickingMode::Normal;
}
app.add_plugins(DefaultPickingPlugins).insert_resource(debug_level);
}
}
28 changes: 28 additions & 0 deletions src/ui/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
mod camera;
mod cursor;
mod shell;

use bevy::{app::PluginGroupBuilder, prelude::*};

pub struct UserInterfacePlugins;

impl PluginGroup for UserInterfacePlugins {
fn build(self) -> PluginGroupBuilder {
PluginGroupBuilder::start::<Self>()
.add(bevy_egui::EguiPlugin)
.add(camera::plugin)
.add(shell::plugin)
.add(DebugExtrasPlugin)
}
}

/// Optionally adds more debug utility interfaces to the UI
struct DebugExtrasPlugin;

impl Plugin for DebugExtrasPlugin {
fn build(&self, app: &mut App) {

#[cfg(feature = "dev")]
app.add_plugins(bevy_inspector_egui::quick::WorldInspectorPlugin::default());
}
}
22 changes: 22 additions & 0 deletions src/ui/shell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use bevy::prelude::*;
use bevy_egui::{egui, EguiContexts};

/// The main Ui that contains everything else. This should be just Egui sugar that triggers events handled elsewhere.
pub(super) fn plugin(app: &mut App) {
app.add_systems(Update, update_shell);
}

fn update_shell(mut egui_ctx: EguiContexts, time: Res<Time>) {
let ctx = egui_ctx.ctx_mut();
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
egui::menu::bar(ui, |ui| {
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
egui::warn_if_debug_build(ui);
ui.label(format!(
"Elapsed Time: {:.2} seconds",
time.elapsed_seconds()
));
});
});
});
}

0 comments on commit 8638309

Please sign in to comment.