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"
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
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
|
||||
|
||||
- [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
|
||||
|
||||
@ -29,10 +29,12 @@ Simulate the motion of celestial bodies under Newtonian gravity, with easy confi
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
### Run
|
||||
---
|
||||
|
||||
## Running the Simulator (CLI)
|
||||
|
||||
```bash
|
||||
cargo run --release -- \
|
||||
cargo run --release --bin simulator -- \
|
||||
--config path/to/your_config.json \
|
||||
--time 30d \
|
||||
--step-size 10.0 \
|
||||
@ -40,7 +42,6 @@ cargo run --release -- \
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `--config` (required): Path to your JSON config file with initial body states.
|
||||
- `--time` (required): Total simulation time (e.g. `10s`, `5m`, `2h`, `100d`).
|
||||
- `--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
|
||||
|
||||
The config file is a JSON file describing the initial state of each body.
|
||||
Examples provided in config/
|
||||
Examples provided in `config/`
|
||||
|
||||
```json
|
||||
{
|
||||
@ -82,12 +98,6 @@ Examples provided in config/
|
||||
|
||||
---
|
||||
|
||||
## Animation
|
||||
|
||||
Coming soon.
|
||||
|
||||
---
|
||||
|
||||
## Extending
|
||||
|
||||
- Add more bodies or change initial conditions in the config file.
|
||||
@ -105,6 +115,7 @@ MIT License
|
||||
## Acknowledgments
|
||||
|
||||
- [Rust](https://www.rust-lang.org/)
|
||||
- [Bevy](https://bevyengine.org/) for 3D visualization
|
||||
- [glam](https://crates.io/crates/glam) for fast vector math
|
||||
- [clap](https://crates.io/crates/clap) for CLI parsing
|
||||
- [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 humantime;
|
||||
|
||||
// Internal modules
|
||||
mod types;
|
||||
mod config;
|
||||
mod simulator;
|
||||
|
||||
// Specific uses from modules
|
||||
use crate::simulator::Simulation;
|
||||
use crate::types::{norm_time, real_body};
|
||||
|
||||
// Internal modules from the library crate
|
||||
use orbital_simulator::simulation::Simulation;
|
||||
use orbital_simulator::types::{norm_time, real_body};
|
||||
use orbital_simulator as _; // for mod resolution
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(
|
||||
@ -50,7 +45,7 @@ struct Args {
|
||||
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 reader = BufReader::new(file);
|
||||
|
||||
@ -119,4 +114,4 @@ fn main() {
|
||||
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