Merge branch 'desert-planet'
This commit is contained in:
commit
27ba017609
16 changed files with 799 additions and 785 deletions
1055
Cargo.lock
generated
1055
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
16
Cargo.toml
16
Cargo.toml
|
@ -5,31 +5,33 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
bevy_polyline = "0.4"
|
# bevy_polyline = "0.4"
|
||||||
noise = { git = "https://github.com/Razaekel/noise-rs" }
|
noise = { git = "https://github.com/Razaekel/noise-rs" }
|
||||||
hexasphere = "7"
|
hexasphere = "7"
|
||||||
wgpu = "0.14"
|
wgpu = "0.15"
|
||||||
bevy-inspector-egui = "0.17.0"
|
bevy-inspector-egui = "0.18"
|
||||||
# wgpu = "0.12"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
inspector = []
|
inspector = []
|
||||||
|
|
||||||
[dependencies.bevy]
|
[dependencies.bevy]
|
||||||
version = "0.9"
|
version = "0.10"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = [
|
features = [
|
||||||
"bevy_gilrs",
|
"bevy_gilrs",
|
||||||
"bevy_winit",
|
"bevy_winit",
|
||||||
"render",
|
|
||||||
"png",
|
"png",
|
||||||
"hdr",
|
"hdr",
|
||||||
"x11",
|
"x11",
|
||||||
|
"bevy_ui",
|
||||||
|
"bevy_text",
|
||||||
|
"bevy_gltf",
|
||||||
|
"bevy_sprite",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies.bevy_rapier3d]
|
[dependencies.bevy_rapier3d]
|
||||||
features = ["debug-render-3d"]
|
features = ["debug-render-3d"]
|
||||||
version = "0.20"
|
version = "0.21"
|
||||||
|
|
||||||
# Maybe also enable only a small amount of optimization for our code:
|
# Maybe also enable only a small amount of optimization for our code:
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
|
|
|
@ -46,14 +46,12 @@ impl Default for Tunneling {
|
||||||
pub struct MovementSettings {
|
pub struct MovementSettings {
|
||||||
pub accel: f32,
|
pub accel: f32,
|
||||||
pub gravity: f32,
|
pub gravity: f32,
|
||||||
pub sensitivity: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MovementSettings {
|
impl Default for MovementSettings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
sensitivity: 6.0,
|
accel: 20.0,
|
||||||
accel: 40.0,
|
|
||||||
gravity: 9.8,
|
gravity: 9.8,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use bevy::{
|
use bevy::{
|
||||||
diagnostic::FrameTimeDiagnosticsPlugin,
|
diagnostic::FrameTimeDiagnosticsPlugin,
|
||||||
prelude::{App, IntoSystemDescriptor, Plugin, ReflectResource, Resource},
|
ecs::reflect::ReflectResource,
|
||||||
|
prelude::{App, IntoSystemConfigs, Plugin, Resource},
|
||||||
reflect::Reflect,
|
reflect::Reflect,
|
||||||
};
|
};
|
||||||
use bevy_rapier3d::prelude::{NoUserData, RapierPhysicsPlugin};
|
use bevy_rapier3d::prelude::{NoUserData, RapierPhysicsPlugin};
|
||||||
|
@ -28,19 +29,19 @@ impl Plugin for CyberActionPlugin {
|
||||||
.register_type::<CyberLean>()
|
.register_type::<CyberLean>()
|
||||||
.register_type::<CatControllerSettings>()
|
.register_type::<CatControllerSettings>()
|
||||||
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
|
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
|
||||||
|
.add_startup_system(timestep_setup)
|
||||||
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
||||||
.add_system(surface_fix.label("surface_fix"))
|
.add_systems(
|
||||||
.add_system(gravity.label("gravity").before("cat"))
|
(
|
||||||
.add_system(cyber_lean.before("cat").after("gravity"))
|
gravity,
|
||||||
.add_system(falling_cat.label("cat"))
|
cyber_lean,
|
||||||
.add_system(input_forces.label("iforces").after("cat"))
|
falling_cat,
|
||||||
.add_system(
|
input_forces,
|
||||||
tunnel_out
|
drag,
|
||||||
.label("tunnel")
|
tunnel_out,
|
||||||
.before("surface_fix")
|
surface_fix,
|
||||||
.after("drag"),
|
|
||||||
)
|
)
|
||||||
.add_system(surface_fix.label("surface_fix").after("cat"))
|
.chain(),
|
||||||
.add_system(drag.label("drag").after("iforces"));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,14 @@ use bevy::prelude::{
|
||||||
};
|
};
|
||||||
use bevy_rapier3d::prelude::{
|
use bevy_rapier3d::prelude::{
|
||||||
CollisionGroups, ExternalForce, Group, MultibodyJoint, QueryFilter, RapierConfiguration,
|
CollisionGroups, ExternalForce, Group, MultibodyJoint, QueryFilter, RapierConfiguration,
|
||||||
RapierContext, ReadMassProperties, Velocity,
|
RapierContext, ReadMassProperties, TimestepMode, Velocity,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "inspector")]
|
#[cfg(feature = "inspector")]
|
||||||
use super::ActionDebugInstant;
|
use super::ActionDebugInstant;
|
||||||
use super::{CatControllerSettings, CatControllerState, CyberLean, MovementSettings, Tunneling};
|
use super::{CatControllerSettings, CatControllerState, CyberLean, MovementSettings, Tunneling};
|
||||||
use crate::{
|
use crate::{
|
||||||
bike::{CyberBikeBody, CyberSteering, CyberWheel, BIKE_WHEEL_COLLISION_GROUP},
|
bike::{CyberBikeBody, CyberSteering, CyberWheel, WheelConfig, BIKE_WHEEL_COLLISION_GROUP},
|
||||||
input::InputState,
|
input::InputState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ fn yaw_to_angle(yaw: f32) -> f32 {
|
||||||
|
|
||||||
fn rotate_point(pt: &Vec3, rot: &Quat) -> Vec3 {
|
fn rotate_point(pt: &Vec3, rot: &Quat) -> Vec3 {
|
||||||
// thanks to https://danceswithcode.net/engineeringnotes/quaternions/quaternions.html
|
// thanks to https://danceswithcode.net/engineeringnotes/quaternions/quaternions.html
|
||||||
let [x, y, z] = pt.to_array();
|
let [x, y, z] = pt.normalize().to_array();
|
||||||
let qpt = Quat::from_xyzw(x, y, z, 0.0);
|
let qpt = Quat::from_xyzw(x, y, z, 0.0);
|
||||||
// p' = rot^-1 * qpt * rot
|
// p' = rot^-1 * qpt * rot
|
||||||
let rot_qpt = rot.inverse() * qpt * *rot;
|
let rot_qpt = rot.inverse() * qpt * *rot;
|
||||||
|
@ -36,13 +36,31 @@ fn rotate_point(pt: &Vec3, rot: &Quat) -> Vec3 {
|
||||||
-Vec3::from_array([rot_qpt.x, rot_qpt.y, rot_qpt.z])
|
-Vec3::from_array([rot_qpt.x, rot_qpt.y, rot_qpt.z])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn timestep_setup(mut config: ResMut<RapierConfiguration>) {
|
||||||
|
let ts = TimestepMode::Fixed {
|
||||||
|
dt: 1.0 / 60.0,
|
||||||
|
substeps: 2,
|
||||||
|
};
|
||||||
|
config.timestep_mode = ts;
|
||||||
|
}
|
||||||
|
|
||||||
/// The gravity vector points from the cyberbike to the center of the planet.
|
/// The gravity vector points from the cyberbike to the center of the planet.
|
||||||
pub(super) fn gravity(
|
pub(super) fn gravity(
|
||||||
mut query: Query<(&Transform, &mut ExternalForce), With<CyberBikeBody>>,
|
mut query: Query<(&Transform, &mut ExternalForce), With<CyberBikeBody>>,
|
||||||
settings: Res<MovementSettings>,
|
settings: Res<MovementSettings>,
|
||||||
mut rapier_config: ResMut<RapierConfiguration>,
|
mut rapier_config: ResMut<RapierConfiguration>,
|
||||||
|
#[cfg(feature = "inspector")] mut debug_instant: ResMut<ActionDebugInstant>,
|
||||||
) {
|
) {
|
||||||
let (xform, mut forces) = query.single_mut();
|
let (xform, mut forces) = query.single_mut();
|
||||||
|
|
||||||
|
#[cfg(feature = "inspectorb")]
|
||||||
|
{
|
||||||
|
if debug_instant.elapsed().as_millis() > 6000 {
|
||||||
|
dbg!(&forces);
|
||||||
|
debug_instant.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rapier_config.gravity = xform.translation.normalize() * -settings.gravity;
|
rapier_config.gravity = xform.translation.normalize() * -settings.gravity;
|
||||||
forces.force = Vec3::ZERO;
|
forces.force = Vec3::ZERO;
|
||||||
forces.torque = Vec3::ZERO;
|
forces.torque = Vec3::ZERO;
|
||||||
|
@ -80,7 +98,6 @@ pub(super) fn falling_cat(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
settings: Res<CatControllerSettings>,
|
settings: Res<CatControllerSettings>,
|
||||||
lean: Res<CyberLean>,
|
lean: Res<CyberLean>,
|
||||||
#[cfg(feature = "inspector")] mut debug_instant: ResMut<ActionDebugInstant>,
|
|
||||||
) {
|
) {
|
||||||
let (xform, mut forces, mut control_vars) = bike_query.single_mut();
|
let (xform, mut forces, mut control_vars) = bike_query.single_mut();
|
||||||
let world_up = xform.translation.normalize();
|
let world_up = xform.translation.normalize();
|
||||||
|
@ -100,13 +117,6 @@ pub(super) fn falling_cat(
|
||||||
if mag.is_finite() {
|
if mag.is_finite() {
|
||||||
forces.torque += xform.back() * mag;
|
forces.torque += xform.back() * mag;
|
||||||
}
|
}
|
||||||
#[cfg(feature = "inspector")]
|
|
||||||
{
|
|
||||||
if debug_instant.elapsed().as_millis() > 1000 {
|
|
||||||
dbg!(&control_vars, mag, &target_up);
|
|
||||||
debug_instant.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,15 +139,20 @@ pub(super) fn input_forces(
|
||||||
let force = ExternalForce::at_point(thrust, point, xform.translation);
|
let force = ExternalForce::at_point(thrust, point, xform.translation);
|
||||||
*forces += force;
|
*forces += force;
|
||||||
|
|
||||||
// brake
|
// brake + thrust
|
||||||
for mut motor in braking_query.iter_mut() {
|
for mut motor in braking_query.iter_mut() {
|
||||||
let factor = if input.brake { 500.00 } else { 0.0 };
|
let factor = if input.brake {
|
||||||
|
500.00
|
||||||
|
} else {
|
||||||
|
input.throttle * settings.accel
|
||||||
|
};
|
||||||
|
let speed = if input.brake { 0.0 } else { -70.0 };
|
||||||
motor.data = (*motor
|
motor.data = (*motor
|
||||||
.data
|
.data
|
||||||
.as_revolute_mut()
|
.as_revolute_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_motor_max_force(factor)
|
.set_motor_max_force(factor)
|
||||||
.set_motor_velocity(0.0, factor))
|
.set_motor_velocity(speed, factor))
|
||||||
.into();
|
.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,23 +174,31 @@ pub(super) fn surface_fix(
|
||||||
(Entity, &Transform, &mut CollisionGroups),
|
(Entity, &Transform, &mut CollisionGroups),
|
||||||
(With<CyberWheel>, Without<Tunneling>),
|
(With<CyberWheel>, Without<Tunneling>),
|
||||||
>,
|
>,
|
||||||
|
span_query: Query<&Transform, With<CyberWheel>>,
|
||||||
|
config: Res<WheelConfig>,
|
||||||
context: Res<RapierContext>,
|
context: Res<RapierContext>,
|
||||||
) {
|
) {
|
||||||
// assume the body is not below the planet surface
|
let mut wheels = Vec::new();
|
||||||
|
for xform in span_query.iter() {
|
||||||
|
wheels.push(xform);
|
||||||
|
}
|
||||||
|
let span = (wheels[1].translation - wheels[0].translation).normalize();
|
||||||
|
|
||||||
for (entity, xform, mut cgroups) in wheel_query.iter_mut() {
|
for (entity, xform, mut cgroups) in wheel_query.iter_mut() {
|
||||||
let ray_dir = xform.translation.normalize();
|
//let ray_dir = xform.translation.normalize();
|
||||||
|
let ray_dir = xform.right().cross(span).normalize();
|
||||||
if let Some(hit) = context.cast_ray_and_get_normal(
|
if let Some(hit) = context.cast_ray_and_get_normal(
|
||||||
xform.translation,
|
xform.translation,
|
||||||
ray_dir,
|
ray_dir,
|
||||||
10.0,
|
config.radius * 1.1,
|
||||||
false,
|
false,
|
||||||
QueryFilter::only_fixed(),
|
QueryFilter::only_fixed(),
|
||||||
) {
|
) {
|
||||||
cgroups.memberships = Group::NONE;
|
cgroups.memberships = Group::NONE;
|
||||||
cgroups.filters = Group::NONE;
|
cgroups.filters = Group::NONE;
|
||||||
commands.entity(entity).insert(Tunneling {
|
commands.entity(entity).insert(Tunneling {
|
||||||
frames: 10,
|
frames: 3,
|
||||||
dir: -hit.1.normal,
|
dir: hit.1.normal,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub(super) fn spawn_cyberbike(
|
||||||
wheel_conf: Res<WheelConfig>,
|
wheel_conf: Res<WheelConfig>,
|
||||||
mut meshterials: Meshterial,
|
mut meshterials: Meshterial,
|
||||||
) {
|
) {
|
||||||
let altitude = PLANET_RADIUS - 180.0;
|
let altitude = PLANET_RADIUS - 10.0;
|
||||||
|
|
||||||
let mut xform = Transform::from_translation(Vec3::X * altitude)
|
let mut xform = Transform::from_translation(Vec3::X * altitude)
|
||||||
.with_rotation(Quat::from_axis_angle(Vec3::Z, -89.0f32.to_radians()));
|
.with_rotation(Quat::from_axis_angle(Vec3::Z, -89.0f32.to_radians()));
|
||||||
|
@ -55,7 +55,7 @@ pub(super) fn spawn_cyberbike(
|
||||||
.spawn(RigidBody::Dynamic)
|
.spawn(RigidBody::Dynamic)
|
||||||
.insert(spatialbundle)
|
.insert(spatialbundle)
|
||||||
.insert((
|
.insert((
|
||||||
Collider::capsule(Vec3::new(0.0, 0.0, -0.65), Vec3::new(0.0, 0.0, 0.8), 0.50),
|
Collider::capsule(Vec3::new(0.0, 0.0, -0.65), Vec3::new(0.0, 0.0, 0.8), 0.5),
|
||||||
bike_collision_group,
|
bike_collision_group,
|
||||||
mass_properties,
|
mass_properties,
|
||||||
damping,
|
damping,
|
||||||
|
|
|
@ -22,6 +22,7 @@ pub struct WheelConfig {
|
||||||
pub stiffness: f32,
|
pub stiffness: f32,
|
||||||
pub damping: f32,
|
pub damping: f32,
|
||||||
pub radius: f32,
|
pub radius: f32,
|
||||||
|
pub thickness: f32,
|
||||||
pub friction: f32,
|
pub friction: f32,
|
||||||
pub restitution: f32,
|
pub restitution: f32,
|
||||||
pub density: f32,
|
pub density: f32,
|
||||||
|
@ -36,10 +37,11 @@ impl Default for WheelConfig {
|
||||||
limits: [-0.5, 0.1],
|
limits: [-0.5, 0.1],
|
||||||
stiffness: 50.0,
|
stiffness: 50.0,
|
||||||
damping: 8.0,
|
damping: 8.0,
|
||||||
radius: 0.3,
|
radius: 0.38,
|
||||||
|
thickness: 0.2,
|
||||||
friction: 1.2,
|
friction: 1.2,
|
||||||
restitution: 0.8,
|
restitution: 0.95,
|
||||||
density: 0.6,
|
density: 0.9,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@ mod body;
|
||||||
mod components;
|
mod components;
|
||||||
mod wheels;
|
mod wheels;
|
||||||
|
|
||||||
use bevy::prelude::{App, Assets, Mesh, Plugin, ResMut, StandardMaterial, StartupStage};
|
use bevy::prelude::{
|
||||||
|
App, Assets, IntoSystemConfig, Mesh, Plugin, ResMut, StandardMaterial, StartupSet,
|
||||||
|
};
|
||||||
use bevy_rapier3d::prelude::Group;
|
use bevy_rapier3d::prelude::Group;
|
||||||
|
|
||||||
pub(crate) use self::components::*;
|
pub(crate) use self::components::*;
|
||||||
|
@ -21,6 +23,6 @@ impl Plugin for CyberBikePlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.insert_resource(WheelConfig::default())
|
app.insert_resource(WheelConfig::default())
|
||||||
.register_type::<WheelConfig>()
|
.register_type::<WheelConfig>()
|
||||||
.add_startup_system_to_stage(StartupStage::PostStartup, spawn_cyberbike);
|
.add_startup_system(spawn_cyberbike.in_base_set(StartupSet::PostStartup));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ pub fn spawn_tires(
|
||||||
let wheels_collision_group = CollisionGroups::new(membership, filter);
|
let wheels_collision_group = CollisionGroups::new(membership, filter);
|
||||||
let wheel_y = conf.y;
|
let wheel_y = conf.y;
|
||||||
let wheel_rad = conf.radius;
|
let wheel_rad = conf.radius;
|
||||||
|
let _tire_thickness = conf.thickness;
|
||||||
let stiffness = conf.stiffness;
|
let stiffness = conf.stiffness;
|
||||||
let not_sleeping = Sleeping::disabled();
|
let not_sleeping = Sleeping::disabled();
|
||||||
let ccd = Ccd { enabled: true };
|
let ccd = Ccd { enabled: true };
|
||||||
|
@ -28,6 +29,7 @@ pub fn spawn_tires(
|
||||||
radius: wheel_rad,
|
radius: wheel_rad,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let material = StandardMaterial {
|
let material = StandardMaterial {
|
||||||
base_color: Color::Rgba {
|
base_color: Color::Rgba {
|
||||||
red: 0.01,
|
red: 0.01,
|
||||||
|
@ -74,6 +76,7 @@ pub fn spawn_tires(
|
||||||
linear_damping: 0.8,
|
linear_damping: 0.8,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let wheel_collider = Collider::ball(wheel_rad);
|
let wheel_collider = Collider::ball(wheel_rad);
|
||||||
let mass_props = ColliderMassProperties::Density(conf.density);
|
let mass_props = ColliderMassProperties::Density(conf.density);
|
||||||
let damping = conf.damping;
|
let damping = conf.damping;
|
||||||
|
@ -97,7 +100,7 @@ pub fn spawn_tires(
|
||||||
|
|
||||||
let axel_parent_entity = if let Some(steering) = steering {
|
let axel_parent_entity = if let Some(steering) = steering {
|
||||||
let neck_builder =
|
let neck_builder =
|
||||||
RevoluteJointBuilder::new(rake_vec).local_anchor1(Vec3::new(0.0, 0.0, 0.1)); // this adds another 0.1m of trail
|
RevoluteJointBuilder::new(rake_vec).local_anchor1(Vec3::new(0.0, -0.08, 0.1)); // this adds another 0.1m of trail
|
||||||
let neck_joint = MultibodyJoint::new(fork_rb_entity, neck_builder);
|
let neck_joint = MultibodyJoint::new(fork_rb_entity, neck_builder);
|
||||||
let neck = commands
|
let neck = commands
|
||||||
.spawn(RigidBody::Dynamic)
|
.spawn(RigidBody::Dynamic)
|
||||||
|
@ -110,10 +113,15 @@ pub fn spawn_tires(
|
||||||
fork_rb_entity
|
fork_rb_entity
|
||||||
};
|
};
|
||||||
|
|
||||||
let revolute_builder = RevoluteJointBuilder::new(Vec3::X);
|
let axel_builder = RevoluteJointBuilder::new(Vec3::X);
|
||||||
let axel_joint = MultibodyJoint::new(axel_parent_entity, revolute_builder);
|
let axel_joint = MultibodyJoint::new(axel_parent_entity, axel_builder);
|
||||||
|
// re-orient the joint so that the wheel is correctly oriented
|
||||||
|
//let real_axel = *axel_joint.data.set_local_axis1(Vec3::X);
|
||||||
|
//axel_joint.data = real_axel;
|
||||||
|
|
||||||
commands.spawn(pbr_bundle.clone()).insert((
|
commands
|
||||||
|
.spawn(pbr_bundle.clone())
|
||||||
|
.insert((
|
||||||
wheel_collider,
|
wheel_collider,
|
||||||
mass_props,
|
mass_props,
|
||||||
wheel_damping,
|
wheel_damping,
|
||||||
|
@ -125,9 +133,9 @@ pub fn spawn_tires(
|
||||||
CyberWheel,
|
CyberWheel,
|
||||||
ExternalForce::default(),
|
ExternalForce::default(),
|
||||||
Restitution::new(conf.restitution),
|
Restitution::new(conf.restitution),
|
||||||
SpatialBundle::default(),
|
|
||||||
TransformInterpolation::default(),
|
TransformInterpolation::default(),
|
||||||
RigidBody::Dynamic,
|
RigidBody::Dynamic,
|
||||||
));
|
))
|
||||||
|
.insert(SpatialBundle::default());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,9 @@ use crate::{bike::CyberBikeBody, input::InputState};
|
||||||
// 85 degrees in radians
|
// 85 degrees in radians
|
||||||
const MAX_PITCH: f32 = 1.48353;
|
const MAX_PITCH: f32 = 1.48353;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash, Component)]
|
#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash, Component, States, Default)]
|
||||||
enum CyberCameras {
|
enum CyberCameras {
|
||||||
|
#[default]
|
||||||
Hero,
|
Hero,
|
||||||
Debug,
|
Debug,
|
||||||
}
|
}
|
||||||
|
@ -42,15 +43,32 @@ fn setup_cybercams(mut commands: Commands) {
|
||||||
fov: std::f32::consts::FRAC_PI_3,
|
fov: std::f32::consts::FRAC_PI_3,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let fog_settings = FogSettings {
|
||||||
|
color: Color::rgba(0.1, 0.2, 0.4, 1.0),
|
||||||
|
directional_light_color: Color::rgba(1.0, 0.95, 0.75, 0.5),
|
||||||
|
directional_light_exponent: 30.0,
|
||||||
|
falloff: FogFalloff::from_visibility_colors(
|
||||||
|
350.0, /* distance in world units up to which objects retain visibility (>= 5%
|
||||||
|
* contrast) */
|
||||||
|
Color::rgb(0.35, 0.5, 0.66), /* atmospheric extinction color (after light is lost
|
||||||
|
* due to absorption by atmospheric particles) */
|
||||||
|
Color::rgb(0.8, 0.844, 1.0), /* atmospheric inscattering color (light gained due to
|
||||||
|
* scattering from the sun) */
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn(Camera3dBundle {
|
.spawn(Camera3dBundle {
|
||||||
projection: bevy::render::camera::Projection::Perspective(hero_projection),
|
projection: bevy::render::camera::Projection::Perspective(hero_projection),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
.insert(fog_settings.clone())
|
||||||
.insert(CyberCameras::Hero);
|
.insert(CyberCameras::Hero);
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn(Camera3dBundle::default())
|
.spawn(Camera3dBundle::default())
|
||||||
|
.insert(fog_settings)
|
||||||
.insert(CyberCameras::Debug);
|
.insert(CyberCameras::Debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +117,7 @@ fn update_active_camera(
|
||||||
) {
|
) {
|
||||||
// find the camera with the current state, set it as the ActiveCamera
|
// find the camera with the current state, set it as the ActiveCamera
|
||||||
query.iter_mut().for_each(|(mut cam, cyber)| {
|
query.iter_mut().for_each(|(mut cam, cyber)| {
|
||||||
if cyber.eq(state.current()) {
|
if cyber.eq(&state.0) {
|
||||||
cam.is_active = true;
|
cam.is_active = true;
|
||||||
} else {
|
} else {
|
||||||
cam.is_active = false;
|
cam.is_active = false;
|
||||||
|
@ -107,11 +125,15 @@ fn update_active_camera(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cycle_cam_state(mut state: ResMut<State<CyberCameras>>, mut keys: ResMut<Input<KeyCode>>) {
|
fn cycle_cam_state(
|
||||||
|
state: Res<State<CyberCameras>>,
|
||||||
|
mut next: ResMut<NextState<CyberCameras>>,
|
||||||
|
mut keys: ResMut<Input<KeyCode>>,
|
||||||
|
) {
|
||||||
if keys.just_pressed(KeyCode::D) {
|
if keys.just_pressed(KeyCode::D) {
|
||||||
let new_state = state.current().next();
|
let new_state = state.0.next();
|
||||||
info!("{:?}", new_state);
|
info!("{:?}", new_state);
|
||||||
state.set(new_state).unwrap();
|
next.set(new_state);
|
||||||
keys.reset(KeyCode::D);
|
keys.reset(KeyCode::D);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +149,7 @@ impl Plugin for CyberCamPlugin {
|
||||||
fn common(app: &mut bevy::prelude::App) {
|
fn common(app: &mut bevy::prelude::App) {
|
||||||
app.insert_resource(DebugCamOffset::default())
|
app.insert_resource(DebugCamOffset::default())
|
||||||
.add_startup_system(setup_cybercams)
|
.add_startup_system(setup_cybercams)
|
||||||
.add_state(CyberCameras::Hero)
|
.add_state::<CyberCameras>()
|
||||||
.add_system(cycle_cam_state)
|
.add_system(cycle_cam_state)
|
||||||
.add_system(update_active_camera)
|
.add_system(update_active_camera)
|
||||||
.add_system(follow_cyberbike);
|
.add_system(follow_cyberbike);
|
||||||
|
|
|
@ -1,80 +1,13 @@
|
||||||
use bevy::{
|
use bevy::prelude::{App, Color, Plugin};
|
||||||
prelude::*,
|
|
||||||
render::mesh::{Indices, VertexAttributeValues},
|
|
||||||
};
|
|
||||||
use bevy_polyline::prelude::{Polyline, PolylineBundle, PolylineMaterial, PolylinePlugin};
|
|
||||||
use rand::{thread_rng, Rng};
|
|
||||||
|
|
||||||
use crate::{lights::AnimateCyberLightWireframe, planet::CyberPlanet};
|
// use crate::planet::CyberPlanet;
|
||||||
|
|
||||||
pub const BISEXY_COLOR: Color = Color::hsla(292.0, 0.9, 0.60, 1.1);
|
pub const BISEXY_COLOR: Color = Color::hsla(292.0, 0.9, 0.60, 1.1);
|
||||||
|
|
||||||
fn wireframe_planet(
|
|
||||||
mut commands: Commands,
|
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
|
||||||
mut polylines: ResMut<Assets<Polyline>>,
|
|
||||||
mut polymats: ResMut<Assets<PolylineMaterial>>,
|
|
||||||
query: Query<&Handle<Mesh>, With<CyberPlanet>>,
|
|
||||||
) {
|
|
||||||
let handle = query.single();
|
|
||||||
let mesh = meshes.get_mut(handle).unwrap();
|
|
||||||
let vertices = mesh.attribute(Mesh::ATTRIBUTE_POSITION).unwrap();
|
|
||||||
|
|
||||||
let mut pts = Vec::with_capacity(vertices.len());
|
|
||||||
|
|
||||||
if let VertexAttributeValues::Float32x3(verts) = vertices {
|
|
||||||
let indices = mesh.indices().unwrap();
|
|
||||||
if let Indices::U32(indices) = indices {
|
|
||||||
for i in indices.iter() {
|
|
||||||
let v = verts[*i as usize];
|
|
||||||
let v = Vec3::from_slice(&v);
|
|
||||||
pts.push(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut verts = Vec::with_capacity((pts.len() as f32 * 1.4) as usize);
|
|
||||||
for pts in pts.chunks(3) {
|
|
||||||
if pts.len() > 1 {
|
|
||||||
verts.extend_from_slice(pts);
|
|
||||||
verts.push(Vec3::NAN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't need the indices anymore
|
|
||||||
mesh.duplicate_vertices();
|
|
||||||
mesh.compute_flat_normals();
|
|
||||||
|
|
||||||
commands.spawn(PolylineBundle {
|
|
||||||
polyline: polylines.add(Polyline { vertices: verts }),
|
|
||||||
material: polymats.add(PolylineMaterial {
|
|
||||||
width: 101.0,
|
|
||||||
color: BISEXY_COLOR,
|
|
||||||
perspective: true,
|
|
||||||
depth_bias: -0.001,
|
|
||||||
}),
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn wireframify_lights(mut lights: Query<&mut AnimateCyberLightWireframe>) {
|
|
||||||
let chance = 0.005;
|
|
||||||
|
|
||||||
let rng = &mut thread_rng();
|
|
||||||
|
|
||||||
for mut light in lights.iter_mut() {
|
|
||||||
if rng.gen::<f32>() < chance {
|
|
||||||
let new = !light.wired;
|
|
||||||
light.wired = new;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// public plugin
|
// public plugin
|
||||||
pub struct CyberGlamorPlugin;
|
pub struct CyberGlamorPlugin;
|
||||||
impl Plugin for CyberGlamorPlugin {
|
impl Plugin for CyberGlamorPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
#[cfg(feature = "inspector")]
|
|
||||||
{
|
{
|
||||||
use bevy_rapier3d::render::{
|
use bevy_rapier3d::render::{
|
||||||
DebugRenderMode, DebugRenderStyle, RapierDebugRenderPlugin,
|
DebugRenderMode, DebugRenderStyle, RapierDebugRenderPlugin,
|
||||||
|
@ -97,9 +30,5 @@ impl Plugin for CyberGlamorPlugin {
|
||||||
|
|
||||||
app.add_plugin(rplugin);
|
app.add_plugin(rplugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.add_startup_system_to_stage(StartupStage::PostStartup, wireframe_planet)
|
|
||||||
.add_system(wireframify_lights)
|
|
||||||
.add_plugin(PolylinePlugin);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
src/input.rs
59
src/input.rs
|
@ -1,4 +1,8 @@
|
||||||
use bevy::{prelude::*, utils::HashSet};
|
use bevy::{
|
||||||
|
input::gamepad::{GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadEvent},
|
||||||
|
prelude::*,
|
||||||
|
utils::HashSet,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::camera::DebugCamOffset;
|
use crate::camera::DebugCamOffset;
|
||||||
|
|
||||||
|
@ -46,39 +50,42 @@ fn update_debug_cam(mut offset: ResMut<DebugCamOffset>, mut keys: ResMut<Input<K
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_input(mut events: EventReader<GamepadEvent>, mut istate: ResMut<InputState>) {
|
fn update_input(mut events: EventReader<GamepadEvent>, mut istate: ResMut<InputState>) {
|
||||||
for GamepadEvent {
|
for pad_event in events.iter() {
|
||||||
gamepad: _,
|
match pad_event {
|
||||||
event_type: ev,
|
GamepadEvent::Button(button_event) => {
|
||||||
} in events.iter()
|
let GamepadButtonChangedEvent {
|
||||||
{
|
button_type, value, ..
|
||||||
match *ev {
|
} = button_event;
|
||||||
GamepadEventType::ButtonChanged(GamepadButtonType::RightTrigger2, val) => {
|
match button_type {
|
||||||
istate.throttle = val;
|
GamepadButtonType::RightTrigger2 => istate.throttle = *value,
|
||||||
}
|
GamepadButtonType::LeftTrigger2 => istate.throttle = -value,
|
||||||
GamepadEventType::ButtonChanged(GamepadButtonType::LeftTrigger2, val) => {
|
GamepadButtonType::East => {
|
||||||
istate.throttle = -val;
|
if value > &0.5 {
|
||||||
}
|
|
||||||
GamepadEventType::ButtonChanged(GamepadButtonType::East, val) => {
|
|
||||||
if val > 0.5 {
|
|
||||||
istate.brake = true;
|
istate.brake = true;
|
||||||
} else {
|
} else {
|
||||||
istate.brake = false;
|
istate.brake = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GamepadEventType::AxisChanged(GamepadAxisType::LeftStickX, val) => {
|
_ => info!("unhandled button press: {button_event:?}"),
|
||||||
istate.yaw = val;
|
|
||||||
}
|
|
||||||
// ignore spurious vertical movement for now
|
|
||||||
GamepadEventType::AxisChanged(GamepadAxisType::LeftStickY, val) => {
|
|
||||||
istate.pitch = val;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
info!("unhandled gamepad event: {:?}", ev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GamepadEvent::Axis(axis_event) => {
|
||||||
|
let GamepadAxisChangedEvent {
|
||||||
|
axis_type, value, ..
|
||||||
|
} = axis_event;
|
||||||
|
match axis_type {
|
||||||
|
GamepadAxisType::LeftStickX => {
|
||||||
|
istate.yaw = *value;
|
||||||
|
}
|
||||||
|
GamepadAxisType::RightStickY => {
|
||||||
|
istate.pitch = *value;
|
||||||
|
}
|
||||||
|
_ => info!("unhandled axis event: {axis_event:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GamepadEvent::Connection(_) => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//dbg!(&istate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CyberInputPlugin;
|
pub struct CyberInputPlugin;
|
||||||
|
|
15
src/lib.rs
15
src/lib.rs
|
@ -1,6 +1,7 @@
|
||||||
use bevy::{
|
use bevy::{
|
||||||
ecs::schedule::StageLabel,
|
ecs::schedule::SystemSet,
|
||||||
prelude::{ResMut, SystemLabel, Vec3, Windows},
|
prelude::{Query, Vec3, Window, With},
|
||||||
|
window::PrimaryWindow,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod action;
|
pub mod action;
|
||||||
|
@ -12,7 +13,7 @@ pub mod lights;
|
||||||
pub mod planet;
|
pub mod planet;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq, SystemLabel, StageLabel)]
|
#[derive(Clone, Debug, Hash, PartialEq, Eq, SystemSet)]
|
||||||
pub enum Label {
|
pub enum Label {
|
||||||
Geometry,
|
Geometry,
|
||||||
Glamor,
|
Glamor,
|
||||||
|
@ -20,10 +21,10 @@ pub enum Label {
|
||||||
Action,
|
Action,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_mouse_trap(mut windows: ResMut<Windows>) {
|
pub fn disable_mouse_trap(mut window: Query<&mut Window, With<PrimaryWindow>>) {
|
||||||
let window = windows.get_primary_mut().unwrap();
|
let mut window = window.get_single_mut().unwrap();
|
||||||
window.set_cursor_grab_mode(bevy::window::CursorGrabMode::None);
|
window.cursor.grab_mode = bevy::window::CursorGrabMode::None;
|
||||||
window.set_cursor_visibility(true);
|
window.cursor.visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn random_unit_vec(r: &mut impl rand::prelude::Rng) -> Vec3 {
|
pub fn random_unit_vec(r: &mut impl rand::prelude::Rng) -> Vec3 {
|
||||||
|
|
123
src/lights.rs
123
src/lights.rs
|
@ -1,96 +1,9 @@
|
||||||
use std::f32::consts::TAU;
|
use bevy::{pbr::CascadeShadowConfigBuilder, prelude::*};
|
||||||
|
|
||||||
use bevy::prelude::*;
|
|
||||||
use rand::prelude::*;
|
|
||||||
|
|
||||||
use crate::planet::PLANET_RADIUS;
|
use crate::planet::PLANET_RADIUS;
|
||||||
|
|
||||||
pub const LIGHT_RANGE: f32 = 90.0;
|
pub const LIGHT_RANGE: f32 = 90.0;
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
struct AnimatedCyberLight {
|
|
||||||
axis: Vec3,
|
|
||||||
rate: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component, Default)]
|
|
||||||
pub(crate) struct AnimateCyberLightWireframe {
|
|
||||||
pub wired: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spawn_moving_lights(
|
|
||||||
mut commands: Commands,
|
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
|
||||||
) {
|
|
||||||
let rng = &mut thread_rng();
|
|
||||||
// spawn orbiting bisexual lights
|
|
||||||
for _ in 0..655 {
|
|
||||||
// mechanics
|
|
||||||
let axis = crate::random_unit_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);
|
|
||||||
|
|
||||||
// optics
|
|
||||||
let hue = rng.gen_range(240.0..300.0);
|
|
||||||
let saturation = rng.gen_range(0.85..0.99);
|
|
||||||
let lightness = rng.gen_range(0.3..0.7);
|
|
||||||
let color = Color::hsl(hue, saturation, lightness);
|
|
||||||
let intensity = rng.gen_range(900.0..1300.0);
|
|
||||||
let radius = rng.gen::<f32>() * 2.2; // why can't this infer the gen type?
|
|
||||||
let point_light = PointLight {
|
|
||||||
intensity,
|
|
||||||
range: LIGHT_RANGE,
|
|
||||||
color,
|
|
||||||
radius: radius - 0.1,
|
|
||||||
shadows_enabled: true,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let sbundle = SpatialBundle {
|
|
||||||
transform: Transform::from_rotation(rotation),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
commands
|
|
||||||
// first, spawn an entity with a transform we can rotate
|
|
||||||
.spawn((AnimatedCyberLight { axis, rate },))
|
|
||||||
.insert(sbundle)
|
|
||||||
.with_children(|parent| {
|
|
||||||
parent
|
|
||||||
// now spawn a child entity with a pointlight, and a relative transform that's
|
|
||||||
// just translation from the parent
|
|
||||||
.spawn(PointLightBundle {
|
|
||||||
transform,
|
|
||||||
point_light,
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.with_children(|builder| {
|
|
||||||
builder
|
|
||||||
// now a simple mesh to show a wireframe.
|
|
||||||
.spawn(PbrBundle {
|
|
||||||
mesh: meshes.add(Mesh::from(shape::Icosphere {
|
|
||||||
radius,
|
|
||||||
subdivisions: 1,
|
|
||||||
})),
|
|
||||||
material: materials.add(StandardMaterial {
|
|
||||||
base_color: Color::hsla(272.0, 0.7, 0.56, 0.7),
|
|
||||||
emissive: color,
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.insert(AnimateCyberLightWireframe::default());
|
|
||||||
}); // mesh child
|
|
||||||
}); // light child
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spawn_static_lights(
|
fn spawn_static_lights(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
@ -119,6 +32,13 @@ fn spawn_static_lights(
|
||||||
brightness: 0.2,
|
brightness: 0.2,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let _cascade_shadow_config = CascadeShadowConfigBuilder {
|
||||||
|
first_cascade_far_bound: 0.3,
|
||||||
|
maximum_distance: 3.0,
|
||||||
|
..default()
|
||||||
|
}
|
||||||
|
.build();
|
||||||
|
|
||||||
// up light
|
// up light
|
||||||
commands
|
commands
|
||||||
.spawn(PointLightBundle {
|
.spawn(PointLightBundle {
|
||||||
|
@ -128,10 +48,13 @@ fn spawn_static_lights(
|
||||||
})
|
})
|
||||||
.with_children(|builder| {
|
.with_children(|builder| {
|
||||||
builder.spawn(PbrBundle {
|
builder.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Icosphere {
|
mesh: meshes.add(
|
||||||
|
Mesh::try_from(shape::Icosphere {
|
||||||
radius: 10.0,
|
radius: 10.0,
|
||||||
subdivisions: 2,
|
subdivisions: 2,
|
||||||
})),
|
})
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
base_color: Color::BLUE,
|
base_color: Color::BLUE,
|
||||||
emissive: Color::PINK,
|
emissive: Color::PINK,
|
||||||
|
@ -149,10 +72,13 @@ fn spawn_static_lights(
|
||||||
})
|
})
|
||||||
.with_children(|builder| {
|
.with_children(|builder| {
|
||||||
builder.spawn(PbrBundle {
|
builder.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Icosphere {
|
mesh: meshes.add(
|
||||||
|
Mesh::try_from(shape::Icosphere {
|
||||||
radius: 10.0,
|
radius: 10.0,
|
||||||
subdivisions: 2,
|
subdivisions: 2,
|
||||||
})),
|
})
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
base_color: Color::PINK,
|
base_color: Color::PINK,
|
||||||
emissive: Color::BLUE,
|
emissive: Color::BLUE,
|
||||||
|
@ -163,20 +89,9 @@ fn spawn_static_lights(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn orbit_lights(time: Res<Time>, mut query: Query<(&mut Transform, &AnimatedCyberLight)>) {
|
|
||||||
let dt = time.delta_seconds();
|
|
||||||
for (mut transform, light) in query.iter_mut() {
|
|
||||||
let AnimatedCyberLight { axis, rate } = *light;
|
|
||||||
let theta = rate * dt;
|
|
||||||
transform.rotation *= Quat::from_axis_angle(axis, theta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CyberSpaceLightsPlugin;
|
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_static_lights)
|
app.add_startup_system(spawn_static_lights);
|
||||||
.add_startup_system(spawn_moving_lights)
|
|
||||||
.add_system(orbit_lights);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -1,27 +1,27 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
#[cfg(feature = "inspector")]
|
||||||
|
use cyber_rider::glamor::CyberGlamorPlugin;
|
||||||
use cyber_rider::{
|
use cyber_rider::{
|
||||||
action::CyberActionPlugin, bike::CyberBikePlugin, camera::CyberCamPlugin, disable_mouse_trap,
|
action::CyberActionPlugin, bike::CyberBikePlugin, camera::CyberCamPlugin, disable_mouse_trap,
|
||||||
glamor::CyberGlamorPlugin, input::CyberInputPlugin, lights::CyberSpaceLightsPlugin,
|
input::CyberInputPlugin, lights::CyberSpaceLightsPlugin, planet::CyberPlanetPlugin,
|
||||||
planet::CyberPlanetPlugin, ui::CyberUIPlugin,
|
ui::CyberUIPlugin,
|
||||||
};
|
};
|
||||||
|
|
||||||
const CYBER_SKY: Color = Color::rgb(0.07, 0.001, 0.02);
|
//const CYBER_SKY: Color = Color::rgb(0.07, 0.001, 0.02);
|
||||||
// const CYBER_SKY: Color = Color::rgb(0.64, 0.745, 0.937); // a light blue sky
|
const CYBER_SKY: Color = Color::rgb(0.64, 0.745, 0.937); // a light blue sky
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut app = App::new();
|
let mut app = App::new();
|
||||||
app.insert_resource(Msaa { samples: 4 })
|
app.insert_resource(Msaa::Sample4)
|
||||||
.insert_resource(ClearColor(CYBER_SKY))
|
.insert_resource(ClearColor(CYBER_SKY))
|
||||||
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||||
window: WindowDescriptor {
|
primary_window: Some(Window {
|
||||||
width: 2560.0,
|
resolution: (2560.0, 1440.0).into(),
|
||||||
height: 1440.0,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
.add_plugin(CyberPlanetPlugin)
|
.add_plugin(CyberPlanetPlugin)
|
||||||
.add_plugin(CyberGlamorPlugin)
|
|
||||||
.add_plugin(CyberInputPlugin)
|
.add_plugin(CyberInputPlugin)
|
||||||
.add_plugin(CyberActionPlugin)
|
.add_plugin(CyberActionPlugin)
|
||||||
.add_plugin(CyberCamPlugin)
|
.add_plugin(CyberCamPlugin)
|
||||||
|
@ -31,5 +31,8 @@ fn main() {
|
||||||
.add_startup_system(disable_mouse_trap)
|
.add_startup_system(disable_mouse_trap)
|
||||||
.add_system(bevy::window::close_on_esc);
|
.add_system(bevy::window::close_on_esc);
|
||||||
|
|
||||||
|
#[cfg(feature = "inspector")]
|
||||||
|
app.add_plugin(CyberGlamorPlugin);
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use wgpu::PrimitiveTopology;
|
||||||
|
|
||||||
use crate::Label;
|
use crate::Label;
|
||||||
|
|
||||||
pub const PLANET_RADIUS: f32 = 6000.0;
|
pub const PLANET_RADIUS: f32 = 3_000.0;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct CyberPlanet;
|
pub struct CyberPlanet;
|
||||||
|
@ -19,7 +19,7 @@ fn spawn_planet(
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
) {
|
) {
|
||||||
let color = Color::rgb(0.2, 0.1, 0.2);
|
let color = Color::rgb(0.74, 0.5334, 0.176);
|
||||||
let isphere = Icosphere {
|
let isphere = Icosphere {
|
||||||
radius: PLANET_RADIUS,
|
radius: PLANET_RADIUS,
|
||||||
subdivisions: 88,
|
subdivisions: 88,
|
||||||
|
@ -43,9 +43,9 @@ fn spawn_planet(
|
||||||
mesh: meshes.add(mesh),
|
mesh: meshes.add(mesh),
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
base_color: color,
|
base_color: color,
|
||||||
metallic: 0.1,
|
metallic: 0.3,
|
||||||
perceptual_roughness: 0.3,
|
perceptual_roughness: 0.3,
|
||||||
alpha_mode: AlphaMode::Opaque,
|
//alpha_mode: AlphaMode::Opaque,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ fn spawn_planet(
|
||||||
pub struct CyberPlanetPlugin;
|
pub struct CyberPlanetPlugin;
|
||||||
impl Plugin for CyberPlanetPlugin {
|
impl Plugin for CyberPlanetPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_startup_system(spawn_planet.label(Label::Geometry));
|
app.add_startup_system(spawn_planet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ fn gen_planet(sphere: Icosphere) -> (Mesh, Collider) {
|
||||||
.raw_points()
|
.raw_points()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&p| {
|
.map(|&p| {
|
||||||
let disp = noise.get(p.as_dvec3().into()) as f32 * 0.04;
|
let disp = noise.get(p.as_dvec3().into()) as f32 * 0.01;
|
||||||
let pt = p + (p.normalize() * disp);
|
let pt = p + (p.normalize() * disp);
|
||||||
pt.into()
|
pt.into()
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue