From 20f68b2becca152fa934d52418d3eea3248a1410 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Thu, 13 Jan 2022 22:05:51 -0800 Subject: [PATCH 1/9] Make the planet wireframe. --- Cargo.lock | 27 +++++++++++++++++++++++++++ Cargo.toml | 11 +++++++---- src/camera.rs | 4 ++-- src/geometry.rs | 6 ++++-- src/glamor.rs | 30 ++++++++++++++++++++++++++++++ src/lib.rs | 16 ++++++++++++++-- src/main.rs | 13 +++++++++---- src/ui.rs | 13 +++---------- 8 files changed, 96 insertions(+), 24 deletions(-) create mode 100644 src/glamor.rs diff --git a/Cargo.lock b/Cargo.lock index 0dd5e22..535f0d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -390,6 +390,17 @@ dependencies = [ "glam", ] +[[package]] +name = "bevy_mod_debugdump" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5951114fabf7153eaa8050b3072f41ea2867202beadd42f1be13c94d918b3025" +dependencies = [ + "bevy", + "itertools", + "pretty-type-name", +] + [[package]] name = "bevy_pbr" version = "0.6.0" @@ -980,6 +991,7 @@ name = "cyber_rider" version = "0.1.0" dependencies = [ "bevy", + "bevy_mod_debugdump", "heron", ] @@ -1506,6 +1518,15 @@ dependencies = [ "mach", ] +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.1" @@ -2059,6 +2080,12 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "pretty-type-name" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8815d101cfb4cb491154896bdab292a395a7ac9ab185a9941a2f5be0135900d" + [[package]] name = "proc-macro-crate" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index f9b2470..065d5c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,9 @@ name = "cyber_rider" version = "0.1.0" edition = "2021" +[dependencies] +bevy_mod_debugdump = "0.3.0" + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies.bevy] @@ -28,10 +31,10 @@ heron = { path = "../heron/" } [patch."https://github.com/bevyengine/bevy"] bevy = { path = "../bevy/" } -# Enable optimizations for dependencies (incl. Bevy), but not for our code: -[profile.dev.package."*"] -opt-level = 3 - # Maybe also enable only a small amount of optimization for our code: [profile.dev] opt-level = 1 + +# Enable optimizations for dependencies (incl. Bevy), but not for our code: +[profile.dev.package."*"] +opt-level = 3 diff --git a/src/camera.rs b/src/camera.rs index 677df1c..35b7303 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -24,8 +24,8 @@ fn follow_cyberbike( let bike_xform = bike_query.single(); let up = bike_xform.translation.normalize(); - let look_at = bike_xform.translation + (bike_xform.forward() * CAM_DIST); - let cam_pos = bike_xform.translation + (bike_xform.back() * CAM_DIST * 1.5) + (up * CAM_DIST); + let look_at = bike_xform.translation + (bike_xform.forward() * 200.0); + let cam_pos = bike_xform.translation + (bike_xform.back() * 2.7) + (up * 2.4); let mut cam_xform = cam_query.single_mut(); cam_xform.translation = cam_pos; diff --git a/src/geometry.rs b/src/geometry.rs index ceb334d..3ecf1e8 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -1,6 +1,8 @@ use bevy::prelude::*; use heron::prelude::{CollisionShape, RigidBody}; +use crate::Label; + pub const PLANET_RADIUS: f32 = 350.0; pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS + 100.0; @@ -63,7 +65,7 @@ fn spawn_cyberbike(mut commands: Commands, asset_server: Res) { pub struct CyberGeomPlugin; impl Plugin for CyberGeomPlugin { fn build(&self, app: &mut App) { - app.add_startup_system(spawn_giant_sphere) - .add_startup_system(spawn_cyberbike); + app.add_startup_system(spawn_giant_sphere.label(Label::Geometry)) + .add_startup_system(spawn_cyberbike.label(Label::Geometry)); } } diff --git a/src/glamor.rs b/src/glamor.rs new file mode 100644 index 0000000..a25d301 --- /dev/null +++ b/src/glamor.rs @@ -0,0 +1,30 @@ +use bevy::{ + pbr::wireframe::{Wireframe, WireframeConfig, WireframePlugin}, + prelude::*, + render::{options::WgpuOptions, render_resource::WgpuFeatures}, +}; + +use crate::geometry::CyberSphere; + +fn wireframe( + mut commands: Commands, + mut wireframe_config: ResMut, + query: Query>, +) { + let ent = query.single(); + wireframe_config.global = false; + commands.entity(ent).insert(Wireframe); +} + +// public plugin +pub struct CyberGlamorPlugin; +impl Plugin for CyberGlamorPlugin { + fn build(&self, app: &mut App) { + app.insert_resource(WgpuOptions { + features: WgpuFeatures::POLYGON_MODE_LINE, + ..Default::default() + }) + .add_startup_system_to_stage(StartupStage::PostStartup, wireframe) + .add_plugin(WireframePlugin); + } +} diff --git a/src/lib.rs b/src/lib.rs index de2f910..152a84e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,24 @@ -use bevy::prelude::{ResMut, Windows}; +use bevy::{ + ecs::schedule::StageLabel, + prelude::{ResMut, SystemLabel, Windows}, +}; +pub mod action; pub mod camera; pub mod geometry; +pub mod glamor; pub mod input; pub mod lights; -pub mod action; pub mod ui; +#[derive(Clone, Debug, Hash, PartialEq, Eq, SystemLabel, StageLabel)] +pub enum Label { + Geometry, + Glamor, + Input, + Action, +} + pub fn disable_mouse_trap(mut windows: ResMut) { let window = windows.get_primary_mut().unwrap(); window.set_cursor_lock_mode(false); diff --git a/src/main.rs b/src/main.rs index 385147f..5f0e67a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use cyber_rider::{ camera::CyberCamPlugin, disable_mouse_trap, geometry::CyberGeomPlugin, + glamor::CyberGlamorPlugin, input::CyberInputPlugin, lights::CyberSpaceLightsPlugin, ui::CyberUIPlugin, @@ -17,10 +18,11 @@ const MOVEMENT_SETTINGS: MovementSettings = MovementSettings { }; fn main() { - App::new() - .insert_resource(Msaa { samples: 4 }) + let mut app = App::new(); + app.insert_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) .add_plugin(CyberGeomPlugin) + .add_plugin(CyberGlamorPlugin) .add_plugin(CyberInputPlugin) .add_plugin(CyberPhysicsPlugin) .insert_resource(MOVEMENT_SETTINGS) @@ -28,6 +30,9 @@ fn main() { .add_plugin(CyberSpaceLightsPlugin) .add_plugin(CyberUIPlugin) .add_startup_system(disable_mouse_trap) - .add_system(bevy::input::system::exit_on_esc_system) - .run(); + .add_system(bevy::input::system::exit_on_esc_system); + + //bevy_mod_debugdump::print_schedule(&mut app); + + app.run(); } diff --git a/src/ui.rs b/src/ui.rs index cb6fbd5..e0e301e 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,6 +1,6 @@ use bevy::prelude::*; -use crate::{action::CyberBikeState, geometry::PLANET_RADIUS}; +use crate::action::CyberBikeState; #[derive(Component)] struct UpText; @@ -32,17 +32,10 @@ fn setup_ui(mut commands: Commands, asset_server: Res) { .insert(UpText); } -fn update_ui( - state_query: Query<(&CyberBikeState, &Transform)>, - mut text_query: Query<&mut Text, With>, -) { +fn update_ui(state_query: Query<&CyberBikeState>, mut text_query: Query<&mut Text, With>) { let mut text = text_query.single_mut(); let state = state_query.single(); - text.sections[0].value = format!( - "spd: {:.2}\nalt: {:.2}", - state.0.velocity.length(), - state.1.translation.length() - PLANET_RADIUS - ); + text.sections[0].value = format!("spd: {:.2}", state.velocity.length(),); } pub struct CyberUIPlugin; From cfc32a741f89daaf915a8c7f12a701e2a384ca59 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Mon, 17 Jan 2022 13:40:31 -0800 Subject: [PATCH 2/9] Minor tidy. --- Cargo.lock | 13 +++++++------ Cargo.toml | 1 + src/lib.rs | 22 +++++++++++++++++++++- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 535f0d0..ae7e50b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -993,6 +993,7 @@ dependencies = [ "bevy", "bevy_mod_debugdump", "heron", + "rand", ] [[package]] @@ -1572,9 +1573,9 @@ checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libloading" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" dependencies = [ "cfg-if 1.0.0", "winapi", @@ -2374,9 +2375,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.74" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" +checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" dependencies = [ "itoa", "ryu", @@ -2622,9 +2623,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d81bfa81424cc98cb034b837c985b7a290f592e5b4322f353f94a0ab0f9f594" +checksum = "77be66445c4eeebb934a7340f227bfe7b338173d3f8c00a60a5a58005c9faecf" dependencies = [ "ansi_term", "lazy_static", diff --git a/Cargo.toml b/Cargo.toml index 065d5c1..c66208b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] bevy_mod_debugdump = "0.3.0" +rand = "0.8.4" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/lib.rs b/src/lib.rs index 152a84e..1ababfd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ use bevy::{ ecs::schedule::StageLabel, - prelude::{ResMut, SystemLabel, Windows}, + prelude::{ResMut, SystemLabel, Vec3, Windows}, }; pub mod action; @@ -24,3 +24,23 @@ pub fn disable_mouse_trap(mut windows: ResMut) { window.set_cursor_lock_mode(false); window.set_cursor_visibility(true); } + +pub fn random_sphere_vec(r: &mut impl rand::prelude::Rng) -> Vec3 { + // https://mathworld.wolfram.com/SpherePointPicking.html + // Marsaglia (1972) for picking x1 and x2 from (-1, 1) and generating surface + // points directly if their sum is less than 1. + + let mut x1 = 0.0; + let mut x2 = 0.0; + let mut ssum = 2.0; + while ssum >= 1.0 { + x1 = r.gen_range(-1.0..=1.0); + x2 = r.gen_range(-1.0..=1.0); + ssum = x1.powi(2) + x2.powi(2); + } + let sqrt = (1.0 - x1.powi(2) - x2.powi(2)).sqrt(); + let x = 2.0 * x1 * sqrt; + let y = 2.0 * x2 * sqrt; + let z = 1.0 - 2.0 * ssum; + Vec3::new(x, y, z) +} From 18032861d2b5af920cd2e1c2866ac8cf4a40f7d7 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Tue, 18 Jan 2022 20:08:47 -0800 Subject: [PATCH 3/9] Get a bunch of lights to rotate. --- Cargo.lock | 13 ++- src/geometry.rs | 6 +- src/lib.rs | 3 +- src/lights.rs | 207 +++++++++++++++++++----------------------------- 4 files changed, 97 insertions(+), 132 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae7e50b..694b559 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2386,9 +2386,18 @@ dependencies = [ [[package]] name = "sha1" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "sharded-slab" diff --git a/src/geometry.rs b/src/geometry.rs index 3ecf1e8..1d71a9e 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -3,7 +3,7 @@ use heron::prelude::{CollisionShape, RigidBody}; use crate::Label; -pub const PLANET_RADIUS: f32 = 350.0; +pub const PLANET_RADIUS: f32 = 340.0; pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS + 100.0; #[derive(Component, Debug)] @@ -55,8 +55,8 @@ fn spawn_cyberbike(mut commands: Commands, asset_server: Res) { }) .insert(CyberBike) .insert(RigidBody::Dynamic) - .insert(CollisionShape::Cone { - half_height: 2.0, + .insert(CollisionShape::Capsule { + half_segment: 2.0, radius: 0.8, }) .insert(CyberBikeState::default()); diff --git a/src/lib.rs b/src/lib.rs index 1ababfd..bd7ec3e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ use bevy::{ ecs::schedule::StageLabel, prelude::{ResMut, SystemLabel, Vec3, Windows}, }; +use heron::rapier_plugin::nalgebra::ComplexField; pub mod action; pub mod camera; @@ -42,5 +43,5 @@ pub fn random_sphere_vec(r: &mut impl rand::prelude::Rng) -> Vec3 { let x = 2.0 * x1 * sqrt; let y = 2.0 * x2 * sqrt; let z = 1.0 - 2.0 * ssum; - Vec3::new(x, y, z) + Vec3::new(x, y, z).normalize() } diff --git a/src/lights.rs b/src/lights.rs index 5c2724b..4f44f24 100644 --- a/src/lights.rs +++ b/src/lights.rs @@ -1,23 +1,29 @@ +use std::f32::consts::TAU; + use bevy::prelude::*; +use rand::prelude::*; use crate::geometry::PLANET_RADIUS; -pub const LIGHT_RANGE: f32 = PLANET_RADIUS * 0.6; -pub const LIGHT_DIST: f32 = PLANET_RADIUS * 1.2; +pub const LIGHT_RANGE: f32 = 50.0; #[derive(Component)] -struct Animate; +struct AnimatedCyberLight { + axis: Vec3, + rate: f32, +} fn spawn_lights( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { - let red_light = PointLight { - intensity: 1_000.0, + let pink_light = PointLight { + intensity: 1_00.0, range: LIGHT_RANGE, - color: Color::RED, + color: Color::PINK, radius: 1.0, + shadows_enabled: true, ..Default::default() }; @@ -26,14 +32,7 @@ fn spawn_lights( range: LIGHT_RANGE, color: Color::BLUE, radius: 1.0, - ..Default::default() - }; - - let purple_light = PointLight { - intensity: 1_000.0, - range: LIGHT_RANGE, - color: Color::PURPLE, - radius: 1.0, + shadows_enabled: true, ..Default::default() }; @@ -42,100 +41,72 @@ fn spawn_lights( brightness: 0.32, }); - // east light - commands - .spawn_bundle(PointLightBundle { - transform: Transform::from_xyz(LIGHT_DIST, 0.0, 0.0), - point_light: purple_light, - ..Default::default() - }) - .with_children(|builder| { - builder.spawn_bundle(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - radius: 10.0, - ..Default::default() - })), - material: materials.add(StandardMaterial { - base_color: Color::PURPLE, - emissive: Color::rgba_linear(50.0, 0.0, 50.0, 0.0), - ..Default::default() - }), - ..Default::default() - }); - }) - .insert(Animate); + let rng = &mut thread_rng(); + // spawn 200 orbiting bisexual lights + for _ in 0..255 { + let hue = rng.gen_range(260.0..320.0); + let saturation = rng.gen_range(0.8..0.95); + let lightness = rng.gen_range(0.4..0.7); + let color = Color::hsl(hue, saturation, lightness); - // west light - commands - .spawn_bundle(PointLightBundle { - transform: Transform::from_xyz(-LIGHT_DIST, 0.0, 0.0), - point_light: purple_light, + let axis = crate::random_sphere_vec(rng); + let angle = rng.gen_range(0.0..TAU); + let rate: f32 = rng.gen_range(7.0..10.0); + let rate = rate.to_radians(); + let rotation = Quat::from_axis_angle(axis, angle); + + let altitude = PLANET_RADIUS + rng.gen_range(8.0..20.0); + let perp = axis.any_orthonormal_vector(); + let translation = perp * altitude; + let transform = Transform::from_translation(translation); + + let intensity = rng.gen_range(500.0..900.0); + let radius = rng.gen::() * 2.5; // why can't this infer the gen type? + let point_light = PointLight { + intensity, + range: LIGHT_RANGE, + color, + radius, + shadows_enabled: true, ..Default::default() - }) - .with_children(|builder| { - builder.spawn_bundle(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - radius: 10.0, - ..Default::default() - })), - material: materials.add(StandardMaterial { - base_color: Color::PURPLE, - emissive: Color::rgba_linear(50.0, 0.0, 50.0, 0.0), - ..Default::default() - }), - ..Default::default() - }); - }) - .insert(Animate); - // north light - commands - .spawn_bundle(PointLightBundle { - transform: Transform::from_xyz(0.0, 0.0, LIGHT_DIST), - point_light: purple_light, - ..Default::default() - }) - .with_children(|builder| { - builder.spawn_bundle(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - radius: 10.0, - ..Default::default() - })), - material: materials.add(StandardMaterial { - base_color: Color::PURPLE, - emissive: Color::rgba_linear(50.0, 0.0, 50.0, 0.0), - ..Default::default() - }), - ..Default::default() - }); - }) - .insert(Animate); - // south light - commands - .spawn_bundle(PointLightBundle { - transform: Transform::from_xyz(0.0, 0.0, -LIGHT_DIST), - point_light: purple_light, - ..Default::default() - }) - .with_children(|builder| { - builder.spawn_bundle(PbrBundle { - mesh: meshes.add(Mesh::from(shape::UVSphere { - radius: 10.0, - ..Default::default() - })), - material: materials.add(StandardMaterial { - base_color: Color::PURPLE, - emissive: Color::rgba_linear(50.0, 0.0, 50.0, 0.0), - ..Default::default() - }), - ..Default::default() - }); - }) - .insert(Animate); + }; + + commands + .spawn_bundle(( + AnimatedCyberLight { axis, rate }, + Transform::from_rotation(rotation), + GlobalTransform::default(), + )) + .with_children(|parent| { + parent + .spawn_bundle(PointLightBundle { + transform, + point_light, + ..Default::default() + }) + .with_children(|builder| { + builder.spawn_bundle(PbrBundle { + mesh: meshes.add(Mesh::from(shape::Icosphere { + radius, + subdivisions: 2, + })), + + material: materials.add(StandardMaterial { + base_color: color, + emissive: color, + ..Default::default() + }), + ..Default::default() + }); + }); // mesh child + }); // light child + } + // up light commands .spawn_bundle(PointLightBundle { - transform: Transform::from_xyz(0.0, LIGHT_DIST, 0.0), - point_light: red_light, + transform: Transform::from_xyz(0.0, PLANET_RADIUS + 30.0, 0.0), + point_light: pink_light, ..Default::default() }) .with_children(|builder| { @@ -155,7 +126,7 @@ fn spawn_lights( // down light commands .spawn_bundle(PointLightBundle { - transform: Transform::from_xyz(0.0, -LIGHT_DIST, 0.0), + transform: Transform::from_xyz(0.0, -PLANET_RADIUS - 30.0, 0.0), point_light: blue_light, ..Default::default() }) @@ -175,28 +146,12 @@ fn spawn_lights( }); } -fn animate_lights( - time: Res