Get a bunch of lights to rotate.
This commit is contained in:
parent
cfc32a741f
commit
18032861d2
4 changed files with 97 additions and 132 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -2386,9 +2386,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
|
|
|
@ -3,7 +3,7 @@ use heron::prelude::{CollisionShape, RigidBody};
|
||||||
|
|
||||||
use crate::Label;
|
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;
|
pub(crate) const SPAWN_ALTITUDE: f32 = PLANET_RADIUS + 100.0;
|
||||||
|
|
||||||
#[derive(Component, Debug)]
|
#[derive(Component, Debug)]
|
||||||
|
@ -55,8 +55,8 @@ fn spawn_cyberbike(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
})
|
})
|
||||||
.insert(CyberBike)
|
.insert(CyberBike)
|
||||||
.insert(RigidBody::Dynamic)
|
.insert(RigidBody::Dynamic)
|
||||||
.insert(CollisionShape::Cone {
|
.insert(CollisionShape::Capsule {
|
||||||
half_height: 2.0,
|
half_segment: 2.0,
|
||||||
radius: 0.8,
|
radius: 0.8,
|
||||||
})
|
})
|
||||||
.insert(CyberBikeState::default());
|
.insert(CyberBikeState::default());
|
||||||
|
|
|
@ -2,6 +2,7 @@ use bevy::{
|
||||||
ecs::schedule::StageLabel,
|
ecs::schedule::StageLabel,
|
||||||
prelude::{ResMut, SystemLabel, Vec3, Windows},
|
prelude::{ResMut, SystemLabel, Vec3, Windows},
|
||||||
};
|
};
|
||||||
|
use heron::rapier_plugin::nalgebra::ComplexField;
|
||||||
|
|
||||||
pub mod action;
|
pub mod action;
|
||||||
pub mod camera;
|
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 x = 2.0 * x1 * sqrt;
|
||||||
let y = 2.0 * x2 * sqrt;
|
let y = 2.0 * x2 * sqrt;
|
||||||
let z = 1.0 - 2.0 * ssum;
|
let z = 1.0 - 2.0 * ssum;
|
||||||
Vec3::new(x, y, z)
|
Vec3::new(x, y, z).normalize()
|
||||||
}
|
}
|
||||||
|
|
207
src/lights.rs
207
src/lights.rs
|
@ -1,23 +1,29 @@
|
||||||
|
use std::f32::consts::TAU;
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
use rand::prelude::*;
|
||||||
|
|
||||||
use crate::geometry::PLANET_RADIUS;
|
use crate::geometry::PLANET_RADIUS;
|
||||||
|
|
||||||
pub const LIGHT_RANGE: f32 = PLANET_RADIUS * 0.6;
|
pub const LIGHT_RANGE: f32 = 50.0;
|
||||||
pub const LIGHT_DIST: f32 = PLANET_RADIUS * 1.2;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
struct Animate;
|
struct AnimatedCyberLight {
|
||||||
|
axis: Vec3,
|
||||||
|
rate: f32,
|
||||||
|
}
|
||||||
|
|
||||||
fn spawn_lights(
|
fn spawn_lights(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
) {
|
) {
|
||||||
let red_light = PointLight {
|
let pink_light = PointLight {
|
||||||
intensity: 1_000.0,
|
intensity: 1_00.0,
|
||||||
range: LIGHT_RANGE,
|
range: LIGHT_RANGE,
|
||||||
color: Color::RED,
|
color: Color::PINK,
|
||||||
radius: 1.0,
|
radius: 1.0,
|
||||||
|
shadows_enabled: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,14 +32,7 @@ fn spawn_lights(
|
||||||
range: LIGHT_RANGE,
|
range: LIGHT_RANGE,
|
||||||
color: Color::BLUE,
|
color: Color::BLUE,
|
||||||
radius: 1.0,
|
radius: 1.0,
|
||||||
..Default::default()
|
shadows_enabled: true,
|
||||||
};
|
|
||||||
|
|
||||||
let purple_light = PointLight {
|
|
||||||
intensity: 1_000.0,
|
|
||||||
range: LIGHT_RANGE,
|
|
||||||
color: Color::PURPLE,
|
|
||||||
radius: 1.0,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,100 +41,72 @@ fn spawn_lights(
|
||||||
brightness: 0.32,
|
brightness: 0.32,
|
||||||
});
|
});
|
||||||
|
|
||||||
// east light
|
let rng = &mut thread_rng();
|
||||||
commands
|
// spawn 200 orbiting bisexual lights
|
||||||
.spawn_bundle(PointLightBundle {
|
for _ in 0..255 {
|
||||||
transform: Transform::from_xyz(LIGHT_DIST, 0.0, 0.0),
|
let hue = rng.gen_range(260.0..320.0);
|
||||||
point_light: purple_light,
|
let saturation = rng.gen_range(0.8..0.95);
|
||||||
..Default::default()
|
let lightness = rng.gen_range(0.4..0.7);
|
||||||
})
|
let color = Color::hsl(hue, saturation, lightness);
|
||||||
.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);
|
|
||||||
|
|
||||||
// west light
|
let axis = crate::random_sphere_vec(rng);
|
||||||
commands
|
let angle = rng.gen_range(0.0..TAU);
|
||||||
.spawn_bundle(PointLightBundle {
|
let rate: f32 = rng.gen_range(7.0..10.0);
|
||||||
transform: Transform::from_xyz(-LIGHT_DIST, 0.0, 0.0),
|
let rate = rate.to_radians();
|
||||||
point_light: purple_light,
|
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::<f32>() * 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()
|
..Default::default()
|
||||||
})
|
};
|
||||||
.with_children(|builder| {
|
|
||||||
builder.spawn_bundle(PbrBundle {
|
commands
|
||||||
mesh: meshes.add(Mesh::from(shape::UVSphere {
|
.spawn_bundle((
|
||||||
radius: 10.0,
|
AnimatedCyberLight { axis, rate },
|
||||||
..Default::default()
|
Transform::from_rotation(rotation),
|
||||||
})),
|
GlobalTransform::default(),
|
||||||
material: materials.add(StandardMaterial {
|
))
|
||||||
base_color: Color::PURPLE,
|
.with_children(|parent| {
|
||||||
emissive: Color::rgba_linear(50.0, 0.0, 50.0, 0.0),
|
parent
|
||||||
..Default::default()
|
.spawn_bundle(PointLightBundle {
|
||||||
}),
|
transform,
|
||||||
..Default::default()
|
point_light,
|
||||||
});
|
..Default::default()
|
||||||
})
|
})
|
||||||
.insert(Animate);
|
.with_children(|builder| {
|
||||||
// north light
|
builder.spawn_bundle(PbrBundle {
|
||||||
commands
|
mesh: meshes.add(Mesh::from(shape::Icosphere {
|
||||||
.spawn_bundle(PointLightBundle {
|
radius,
|
||||||
transform: Transform::from_xyz(0.0, 0.0, LIGHT_DIST),
|
subdivisions: 2,
|
||||||
point_light: purple_light,
|
})),
|
||||||
..Default::default()
|
|
||||||
})
|
material: materials.add(StandardMaterial {
|
||||||
.with_children(|builder| {
|
base_color: color,
|
||||||
builder.spawn_bundle(PbrBundle {
|
emissive: color,
|
||||||
mesh: meshes.add(Mesh::from(shape::UVSphere {
|
..Default::default()
|
||||||
radius: 10.0,
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})),
|
});
|
||||||
material: materials.add(StandardMaterial {
|
}); // mesh child
|
||||||
base_color: Color::PURPLE,
|
}); // light child
|
||||||
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);
|
|
||||||
// up light
|
// up light
|
||||||
commands
|
commands
|
||||||
.spawn_bundle(PointLightBundle {
|
.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: red_light,
|
point_light: pink_light,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.with_children(|builder| {
|
.with_children(|builder| {
|
||||||
|
@ -155,7 +126,7 @@ fn spawn_lights(
|
||||||
// down light
|
// down light
|
||||||
commands
|
commands
|
||||||
.spawn_bundle(PointLightBundle {
|
.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,
|
point_light: blue_light,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
@ -175,28 +146,12 @@ fn spawn_lights(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn animate_lights(
|
fn orbit_lights(time: Res<Time>, mut query: Query<(&mut Transform, &AnimatedCyberLight)>) {
|
||||||
time: Res<Time>,
|
|
||||||
mut query: Query<&mut Transform, (With<PointLight>, With<Animate>)>,
|
|
||||||
) {
|
|
||||||
let dt = time.delta_seconds();
|
let dt = time.delta_seconds();
|
||||||
for mut transform in query.iter_mut() {
|
for (mut transform, light) in query.iter_mut() {
|
||||||
let translation = &transform.translation;
|
let AnimatedCyberLight { axis, rate } = *light;
|
||||||
let x = translation.x;
|
let theta = rate * dt;
|
||||||
let y = translation.y;
|
transform.rotation *= Quat::from_axis_angle(axis, theta);
|
||||||
let z = if translation.z.abs() < 0.1 {
|
|
||||||
translation.z + 0.15
|
|
||||||
} else {
|
|
||||||
translation.z
|
|
||||||
};
|
|
||||||
|
|
||||||
let rads = 10.0f32.to_radians();
|
|
||||||
let anim_rate = rads * dt;
|
|
||||||
let theta = z.atan2(x) + anim_rate;
|
|
||||||
let x_new = LIGHT_DIST * theta.cos();
|
|
||||||
let z_new = LIGHT_DIST * theta.sin();
|
|
||||||
|
|
||||||
*transform = Transform::from_xyz(x_new, y, z_new);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +159,6 @@ pub struct CyberSpaceLightsPlugin;
|
||||||
impl Plugin for CyberSpaceLightsPlugin {
|
impl Plugin for CyberSpaceLightsPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_startup_system(spawn_lights)
|
app.add_startup_system(spawn_lights)
|
||||||
.add_system(animate_lights);
|
.add_system(orbit_lights);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue