added second binary - starting opengl
This commit is contained in:
parent
82c69b7ae1
commit
2187994616
@ -17,3 +17,4 @@ log = "0.4.27"
|
|||||||
once_cell = "1.21.3"
|
once_cell = "1.21.3"
|
||||||
serde = { version = "1.0.219", features = ["derive"] }
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
||||||
|
bevy = "0.13"
|
||||||
|
33
README.md
33
README.md
@ -21,7 +21,7 @@ Simulate the motion of celestial bodies under Newtonian gravity, with easy confi
|
|||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- [Rust](https://www.rust-lang.org/tools/install) (edition 2021 or later)
|
- [Rust](https://www.rust-lang.org/tools/install) (edition 2021 or later)
|
||||||
- Python (optional, for animation/visualization)
|
- [Bevy dependencies](https://bevyengine.org/learn/book/getting-started/setup/) (for 3D visualization; see Bevy's docs for Linux requirements)
|
||||||
|
|
||||||
### Build
|
### Build
|
||||||
|
|
||||||
@ -29,10 +29,12 @@ Simulate the motion of celestial bodies under Newtonian gravity, with easy confi
|
|||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
### Run
|
---
|
||||||
|
|
||||||
|
## Running the Simulator (CLI)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo run --release -- \
|
cargo run --release --bin simulator -- \
|
||||||
--config path/to/your_config.json \
|
--config path/to/your_config.json \
|
||||||
--time 30d \
|
--time 30d \
|
||||||
--step-size 10.0 \
|
--step-size 10.0 \
|
||||||
@ -40,7 +42,6 @@ cargo run --release -- \
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
- `--config` (required): Path to your JSON config file with initial body states.
|
- `--config` (required): Path to your JSON config file with initial body states.
|
||||||
- `--time` (required): Total simulation time (e.g. `10s`, `5m`, `2h`, `100d`).
|
- `--time` (required): Total simulation time (e.g. `10s`, `5m`, `2h`, `100d`).
|
||||||
- `--step-size`: Simulation step size in seconds (default: `10.0`).
|
- `--step-size`: Simulation step size in seconds (default: `10.0`).
|
||||||
@ -49,10 +50,25 @@ cargo run --release -- \
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Running the 3D Visualizer (`orbiter`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run --release --bin orbiter
|
||||||
|
```
|
||||||
|
|
||||||
|
- Opens a 3D window with a camera and a blue sphere (placeholder for future simulation data).
|
||||||
|
- **Camera controls:**
|
||||||
|
- **Right mouse drag:** Orbit around the origin
|
||||||
|
- **Scroll wheel:** Zoom in/out
|
||||||
|
|
||||||
|
Future updates will allow loading and animating simulation output.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The config file is a JSON file describing the initial state of each body.
|
The config file is a JSON file describing the initial state of each body.
|
||||||
Examples provided in config/
|
Examples provided in `config/`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -82,12 +98,6 @@ Examples provided in config/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Animation
|
|
||||||
|
|
||||||
Coming soon.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Extending
|
## Extending
|
||||||
|
|
||||||
- Add more bodies or change initial conditions in the config file.
|
- Add more bodies or change initial conditions in the config file.
|
||||||
@ -105,6 +115,7 @@ MIT License
|
|||||||
## Acknowledgments
|
## Acknowledgments
|
||||||
|
|
||||||
- [Rust](https://www.rust-lang.org/)
|
- [Rust](https://www.rust-lang.org/)
|
||||||
|
- [Bevy](https://bevyengine.org/) for 3D visualization
|
||||||
- [glam](https://crates.io/crates/glam) for fast vector math
|
- [glam](https://crates.io/crates/glam) for fast vector math
|
||||||
- [clap](https://crates.io/crates/clap) for CLI parsing
|
- [clap](https://crates.io/crates/clap) for CLI parsing
|
||||||
- [indicatif](https://crates.io/crates/indicatif) for progress bars
|
- [indicatif](https://crates.io/crates/indicatif) for progress bars
|
||||||
|
103
src/bin/orbiter.rs
Normal file
103
src/bin/orbiter.rs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy::input::mouse::{MouseMotion, MouseWheel};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
App::new()
|
||||||
|
.add_plugins(DefaultPlugins)
|
||||||
|
.add_systems(Startup, setup)
|
||||||
|
.add_systems(Update, (camera_orbit_controls,))
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct CameraController {
|
||||||
|
pub radius: f32,
|
||||||
|
pub theta: f32, // azimuthal angle
|
||||||
|
pub phi: f32, // polar angle
|
||||||
|
pub last_mouse_pos: Option<Vec2>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
|
) {
|
||||||
|
// Camera with controller
|
||||||
|
let radius = 30.0;
|
||||||
|
let theta = 0.0;
|
||||||
|
let phi = std::f32::consts::FRAC_PI_4;
|
||||||
|
let cam_pos = spherical_to_cartesian(radius, theta, phi);
|
||||||
|
commands.spawn((
|
||||||
|
Camera3dBundle {
|
||||||
|
transform: Transform::from_translation(cam_pos).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
CameraController {
|
||||||
|
radius,
|
||||||
|
theta,
|
||||||
|
phi,
|
||||||
|
last_mouse_pos: None,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
// Light
|
||||||
|
commands.spawn(PointLightBundle {
|
||||||
|
point_light: PointLight {
|
||||||
|
intensity: 1500.0,
|
||||||
|
shadows_enabled: true,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
transform: Transform::from_xyz(4.0, 8.0, 4.0),
|
||||||
|
..default()
|
||||||
|
});
|
||||||
|
// Add a sphere at the origin using the new Sphere primitive
|
||||||
|
let mesh = meshes.add(Mesh::from(Sphere { radius: 1.0, ..default() }));
|
||||||
|
let material = materials.add(StandardMaterial {
|
||||||
|
base_color: Color::BLUE,
|
||||||
|
..default()
|
||||||
|
});
|
||||||
|
commands.spawn(PbrBundle {
|
||||||
|
mesh,
|
||||||
|
material,
|
||||||
|
..default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spherical_to_cartesian(radius: f32, theta: f32, phi: f32) -> Vec3 {
|
||||||
|
let x = radius * phi.sin() * theta.cos();
|
||||||
|
let y = radius * phi.cos();
|
||||||
|
let z = radius * phi.sin() * theta.sin();
|
||||||
|
Vec3::new(x, y, z)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn camera_orbit_controls(
|
||||||
|
mut query: Query<(&mut Transform, &mut CameraController)>,
|
||||||
|
mut mouse_motion_events: EventReader<MouseMotion>,
|
||||||
|
mut mouse_wheel_events: EventReader<MouseWheel>,
|
||||||
|
mouse_button_input: Res<ButtonInput<MouseButton>>,
|
||||||
|
windows: Query<&Window>,
|
||||||
|
) {
|
||||||
|
let window = if let Some(window) = windows.iter().next() { window } else { return; };
|
||||||
|
let mut delta = Vec2::ZERO;
|
||||||
|
for event in mouse_motion_events.read() {
|
||||||
|
delta += event.delta;
|
||||||
|
}
|
||||||
|
let mut scroll = 0.0;
|
||||||
|
for event in mouse_wheel_events.read() {
|
||||||
|
scroll += event.y;
|
||||||
|
}
|
||||||
|
for (mut transform, mut controller) in query.iter_mut() {
|
||||||
|
// Orbit (right mouse button)
|
||||||
|
if mouse_button_input.pressed(MouseButton::Right) {
|
||||||
|
let sensitivity = 0.01;
|
||||||
|
controller.theta -= delta.x * sensitivity;
|
||||||
|
controller.phi = (controller.phi - delta.y * sensitivity).clamp(0.05, std::f32::consts::PI - 0.05);
|
||||||
|
}
|
||||||
|
// Zoom
|
||||||
|
if scroll.abs() > 0.0 {
|
||||||
|
controller.radius = (controller.radius - scroll).clamp(3.0, 200.0);
|
||||||
|
}
|
||||||
|
// Update camera position
|
||||||
|
let pos = spherical_to_cartesian(controller.radius, controller.theta, controller.phi);
|
||||||
|
*transform = Transform::from_translation(pos).looking_at(Vec3::ZERO, Vec3::Y);
|
||||||
|
}
|
||||||
|
}
|
@ -11,15 +11,10 @@ use log::{info, debug};
|
|||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use humantime;
|
use humantime;
|
||||||
|
|
||||||
// Internal modules
|
// Internal modules from the library crate
|
||||||
mod types;
|
use orbital_simulator::simulation::Simulation;
|
||||||
mod config;
|
use orbital_simulator::types::{norm_time, real_body};
|
||||||
mod simulator;
|
use orbital_simulator as _; // for mod resolution
|
||||||
|
|
||||||
// Specific uses from modules
|
|
||||||
use crate::simulator::Simulation;
|
|
||||||
use crate::types::{norm_time, real_body};
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(
|
#[command(
|
||||||
@ -50,7 +45,7 @@ struct Args {
|
|||||||
output_file: String,
|
output_file: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_config<P: AsRef<Path>>(path: P) -> Result<config::ConfigFile, Box<dyn Error>> {
|
fn read_config<P: AsRef<Path>>(path: P) -> Result<orbital_simulator::config::ConfigFile, Box<dyn Error>> {
|
||||||
let file = File::open(path)?;
|
let file = File::open(path)?;
|
||||||
let reader = BufReader::new(file);
|
let reader = BufReader::new(file);
|
||||||
|
|
||||||
@ -119,4 +114,4 @@ fn main() {
|
|||||||
pb.inc(args.steps_per_save as u64);
|
pb.inc(args.steps_per_save as u64);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
3
src/lib.rs
Normal file
3
src/lib.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub mod types;
|
||||||
|
pub mod config;
|
||||||
|
pub mod simulation;
|
Loading…
x
Reference in New Issue
Block a user