diff --git a/build-wasm.sh b/build-wasm.sh new file mode 100644 index 0000000..857a29e --- /dev/null +++ b/build-wasm.sh @@ -0,0 +1,3 @@ +cargo build --release --target wasm32-unknown-unknown || exit 1 +echo "==> wasm-bindgen..." +wasm-bindgen --out-name jsb-gravity --out-dir target --target web target/wasm32-unknown-unknown/release/jsb-gravity.wasm || exit 1 diff --git a/index.html b/index.html new file mode 100644 index 0000000..fe9cb7d --- /dev/null +++ b/index.html @@ -0,0 +1,32 @@ + + + + + JSB Gravity + + + + Canvas did not load. + + + diff --git a/src/gen.rs b/src/gen.rs index 4de5e64..1a76b24 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -2,24 +2,36 @@ use bevy::{prelude::*, render::render_resource::PrimitiveTopology}; use opensimplex_noise_rs::OpenSimplexNoise; use rand::Rng; +/// Générer une planète pub fn planet() -> Mesh { + // Initialiser l'aléatoire let mut rng = rand::thread_rng(); let simplex = OpenSimplexNoise::new(Some(rng.gen())); + + // Créer un mesh vide let mut mesh = Mesh::new(PrimitiveTopology::TriangleList); + let perimeter: u32 = 1000; + + // Ajouter des points dans le mesh mesh.insert_attribute( Mesh::ATTRIBUTE_POSITION, (0..perimeter) .map(|i| { + // Rayon let mut r = simplex.eval_2d(i as f64 * 0.02, 0.) as f32 * 20.0 + 100.0; r += simplex.eval_2d(i as f64 * 0.05, 10.) as f32 * 10.0; r += simplex.eval_2d(i as f64 * 0.2, 10.) as f32 * 4.0; + // Angle let a = std::f32::consts::TAU * i as f32 / perimeter as f32; + // Coordonnées du point [r * a.cos(), r * a.sin(), 0.] }) .chain([[0., 0., 0.]]) .collect::>(), ); + + // Ajouter des triangles en indiquant quels points (de ceux définis juste avant) doivent être reliés let mut triangles = Vec::new(); for i in 0..perimeter { triangles.extend_from_slice(&[i, perimeter, (i + 1) % perimeter]); diff --git a/src/main.rs b/src/main.rs index 2ee5d7e..60465a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,12 +7,15 @@ use bevy::{ sprite::{MaterialMesh2dBundle, Mesh2dHandle}, }; +/// Empêche les fuites mémoire, arrête tout à 1 Go #[global_allocator] static ALLOCATOR: cap::Cap = cap::Cap::new(std::alloc::System, 1024 * 1024 * 1024); +/// Ces deux points définissent le rectangle contenant tout l'univers static UNIVERSE_POS: (Vec2, Vec2) = (Vec2::new(-1e6, -1e6), Vec2::new(1e6, 1e6)); +/// Cette fonction est l'entrée du programme fn main() { App::new() .add_plugins(( @@ -33,11 +36,13 @@ fn main() { .run(); } +/// Cette fonction est appelée à l'initialisation du jeu, par main fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { + // Créer une caméra qui filme ce qu'on va afficher à l'écran commands .spawn(Camera2dBundle::default()) .insert(bevy_pancam::PanCam::default()); @@ -45,6 +50,7 @@ fn setup( let red = materials.add(ColorMaterial::from(Color::RED)); let circle_5: Mesh2dHandle = meshes.add(shape::Circle::new(5.).into()).into(); + // Créer des planètes commands .spawn(Planet { pos: TransformBundle::from(Transform::from_translation(Vec3::new(0., 0., 0.))), @@ -87,6 +93,7 @@ fn setup( ..default() }); }); + // Créer plein de planètes ! for i in 0..4000u32 { commands .spawn(Planet { @@ -109,36 +116,53 @@ fn setup( } } +/// Un set est un ensemble de systèmes. +/// Chaque système est dans un set, ici Force ou Apply. +/// Les sets sont exécutés dans un certain ordre (défini dans main) #[derive(Clone, Debug, Eq, Hash, PartialEq, SystemSet)] enum Set { + /// Systèmes modélisant des forces (poids, champ électrique, rebonds...), donc changeant la vitesse des objets Force, + /// Systèmes appliquant les forces, donc changeant la position des objets selon leur vitesse Apply, } +/// Une vitesse (x, y) en m/s #[derive(Component)] struct Speed(Vec2); +/// Une masse en kg #[derive(Component)] struct Mass(f32); +/// Une planète #[derive(Bundle)] struct Planet { + /// Position du centre de la planète pos: TransformBundle, + /// Masse de la planète mass: Mass, + /// Vitesse de la planète speed: Speed, visibility: InheritedVisibility, } +/// Constantes physiques #[derive(Resource)] struct Constants { + /// Constante gravitationnelle g: f32, } +/// Corps. Sert à utiliser le quadtree struct Body { mass: f32, pos: Vec2, } +/// On implémente le trait Body pour la struct Body. +/// C'est-à-dire qu'on ajoute à la struct Body l'information qu'elle se comporte comme un corps. +/// On lui ajoute les méthodes (fonctions) d'un corps. impl quadtree::Body for Body { fn mass(&self) -> f32 { self.mass @@ -151,6 +175,7 @@ impl quadtree::Body for Body { } } +// Ici l'ancien système de poids, mis en commentaire pour être ignoré. /*fn weight_system( constants: Res, query1: Query<(&Transform, &Mass)>, @@ -172,22 +197,29 @@ impl quadtree::Body for Body { } }*/ +/// Le système de poids. fn weight_system( constants: Res, mut query: Query<(&Transform, &Mass, &mut Speed)>, time: Res