120 lines
4.1 KiB
Rust

use cgmath::{Rotation3, Vector3};
use solar_engine::{Application, Body, Key, KeyState, Light, LightType, Simulator};
use std::sync::{Arc, RwLock};
use std::thread;
pub async fn run() {
let simulator = Arc::new(RwLock::new(Simulator::new()));
{
let mut sim = simulator.write().unwrap();
sim.add_body(Body {
name: "Sun".into(),
position: Vector3::new(0.0, 0.0, 0.0),
velocity: Vector3::new(0.0, 0.0, 0.0),
mass: 1.989e30,
radius: 6.963e8,
});
sim.add_body(Body {
name: "Earth".into(),
position: Vector3::new(1.496e11, 0.0, 0.0),
velocity: Vector3::new(0.0, 29780.0, 0.0),
mass: 5.972e24,
radius: 6.371e6,
});
}
let sim_clone = simulator.clone();
thread::spawn(move || {
use std::time::{Duration, Instant};
let mut last = Instant::now();
loop {
let now = Instant::now();
let dt = now.duration_since(last).as_secs_f64();
last = now;
{
let mut sim = sim_clone.write().unwrap();
let timewarp = sim.get_timewarp();
sim.step(dt * timewarp as f64);
}
thread::sleep(Duration::from_nanos(1));
}
});
let simulator_clone = simulator.clone();
Application::new()
.on_update(move |state| {
let sim = simulator_clone.read().unwrap();
let bodies = &sim.bodies;
let sun_pos = bodies[0].position / 1.496e11;
state.light_manager.clear();
state.light_manager.add_light(Light {
position: sun_pos.cast::<f32>().unwrap(),
direction: Vector3::new(0.0, 0.0, 0.0),
color: Vector3::from([1.0, 1.0, 0.8]),
intensity: 5.0,
range: 1.0,
inner_cutoff: 0.0,
light_type: LightType::Point,
outer_cutoff: 0.0,
});
let instances = bodies
.iter()
.enumerate()
.map(|(i, b)| {
solar_engine::RenderInstance {
position: ((b.position / 1.496e11) - sun_pos).cast::<f32>().unwrap(),
rotation: cgmath::Quaternion::from_angle_z(cgmath::Deg(0.0)),
color: match i {
0 => [1.0, 1.0, 0.0], // Sun
1 => [0.0, 0.0, 1.0], // Earth
_ => [0.5, 0.5, 0.5],
},
scale: 0.05,
shape: solar_engine::Shape::Sphere,
always_lit: i == 0, // Sun
is_transparent: false
}
})
.collect();
state.set_instances(instances);
})
.on_input(move |state, event| {
if event.state == KeyState::Pressed {
return match event.key {
Key::Period => {
let mut sim = simulator.write().unwrap();
sim.increase_timewarp();
println!("Timewarp: {}", sim.get_timewarp());
}
Key::Comma => {
let mut sim = simulator.write().unwrap();
sim.decrease_timewarp();
println!("Timewarp: {}", sim.get_timewarp());
}
Key::Minus => {
let mut sim = simulator.write().unwrap();
sim.reset_timewarp();
println!("Timewarp: {}", sim.get_timewarp());
}
Key::ArrowLeft => state.camera_mut().rotate_yaw_pitch(-5.0, 0.0),
Key::ArrowRight => state.camera_mut().rotate_yaw_pitch(5.0, 0.0),
Key::ArrowUp => state.camera_mut().zoom(-0.2),
Key::ArrowDown => state.camera_mut().zoom(0.2),
_ => {}
};
}
})
.run();
}
fn main() {
pollster::block_on(run());
}