use bevy::prelude::*; use bevy_rapier2d::prelude::*; use serde::{Deserialize, Serialize}; use crate::{config::StkConfig, module::component::PartType, planet}; #[derive(Component, Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] pub enum PlanetType { Sun, Mercury, Venus, Earth, Moon, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, } #[derive(Bundle)] pub struct PlanetBundle { pub planet_type: PlanetType, pub transform: TransformBundle, } pub fn spawn_planets(mut commands: Commands) { info!("Spawning planets"); let sun_pos = Transform::from_xyz(0.0, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Sun, transform: TransformBundle::from(sun_pos), }) .insert(Collider::ball(planet!(PlanetType::Sun).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Sun).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Sun).size + 0.3)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let mercury_pos = Transform::from_xyz(2322.588, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Mercury, transform: TransformBundle::from(mercury_pos), }) .insert(Collider::ball(planet!(PlanetType::Mercury).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Mercury).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Mercury).size + 0.3)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let venus_pos = Transform::from_xyz(4339.992, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Venus, transform: TransformBundle::from(venus_pos), }) .insert(Collider::ball(planet!(PlanetType::Venus).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Venus).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Venus).size + 0.3)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let earth_pos = Transform::from_xyz(6000.0, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Earth, transform: TransformBundle::from(earth_pos), }) .insert(Collider::ball(planet!(PlanetType::Earth).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Earth).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Earth).size + 0.3)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let moon_pos = Transform::from_xyz(6030.828, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Moon, transform: TransformBundle::from(moon_pos), }) .insert(Collider::ball(planet!(PlanetType::Moon).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Moon).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Moon).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let mars_pos = Transform::from_xyz(9142.0833, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Mars, transform: TransformBundle::from(mars_pos), }) .insert(Collider::ball(planet!(PlanetType::Mars).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Mars).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Mars).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let jupiter_pos = Transform::from_xyz(31222.8, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Jupiter, transform: TransformBundle::from(jupiter_pos), }) .insert(Collider::ball(planet!(PlanetType::Jupiter).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Jupiter).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Jupiter).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let saturn_pos = Transform::from_xyz(57495.6, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Saturn, transform: TransformBundle::from(saturn_pos), }) .insert(Collider::ball(planet!(PlanetType::Saturn).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Saturn).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Saturn).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let uranus_pos = Transform::from_xyz(115147.56, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Uranus, transform: TransformBundle::from(uranus_pos), }) .insert(Collider::ball(planet!(PlanetType::Uranus).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Uranus).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Uranus).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let neptune_pos = Transform::from_xyz(180420.0, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Neptune, transform: TransformBundle::from(neptune_pos), }) .insert(Collider::ball(planet!(PlanetType::Neptune).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Neptune).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Neptune).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); let pluto_pos = Transform::from_xyz(236892.0, 0.0, 0.0); commands .spawn(PlanetBundle { planet_type: PlanetType::Pluto, transform: TransformBundle::from(pluto_pos), }) .insert(Collider::ball(planet!(PlanetType::Pluto).size)) .insert(AdditionalMassProperties::Mass( planet!(PlanetType::Pluto).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children .spawn(Collider::ball(planet!(PlanetType::Pluto).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) .insert(RigidBody::Fixed); } pub fn gravity_update( mut part_query: Query< ( &Transform, &ReadMassProperties, &mut ExternalForce, &mut ExternalImpulse, ), With, >, planet_query: Query<(&Transform, &ReadMassProperties), With>, server_config: Res, ) { for (part_transform, part_mp, mut forces, mut impulses) in &mut part_query { forces.force = Vec2::ZERO; impulses.impulse = Vec2::ZERO; forces.torque = 0.; let part_mp = part_mp.get(); let part_mass = part_mp.mass; let part_translate = part_transform.translation; for (planet_transform, planet_mp) in &planet_query { let planet_mp = planet_mp.get(); let planet_mass = planet_mp.mass; let planet_translate = planet_transform.translation; let distance = planet_translate.distance(part_translate); // gravity equation let force = server_config.world.gravity * ((part_mass * planet_mass) / (distance * distance)); // gravity vector let direction = (planet_translate - part_translate).normalize() * force; // apply gravity vector as impulse to body forces.force += direction.xy(); //impulses.impulse += direction.xy(); } } }