First person controller

This commit is contained in:
2026-02-11 20:09:51 +01:00
parent fecc1f1718
commit f05ed2e613
3 changed files with 83 additions and 50 deletions

View File

@@ -50,9 +50,8 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
let x: i32 = i32(uvx * settings.scale) % 8; let x: i32 = i32(uvx * settings.scale) % 8;
let y: i32 = i32(uvy * settings.scale) % 8; let y: i32 = i32(uvy * settings.scale) % 8;
let final_gray = find_closest(x, y, grayscale); /// not even used?! let final_gray = find_closest(x, y, grayscale);
// Sample each color channel with an arbitrary shift
return vec4<f32>( return vec4<f32>(
final_gray, final_gray, final_gray, 0.0 final_gray, final_gray, final_gray, 0.0
); );

View File

@@ -1,9 +1,10 @@
use std::f32::consts::PI; use std::f32::consts::*;
use std::time::Duration; use std::time::Duration;
use bevy::app::ScheduleRunnerPlugin; use bevy::app::ScheduleRunnerPlugin;
use bevy::camera::RenderTarget; use bevy::camera::RenderTarget;
use bevy::color::Color; use bevy::color::Color;
use bevy::color::palettes::css::WHITE;
use bevy::prelude::*; use bevy::prelude::*;
use wgpu::{TextureFormat, TextureUsages}; use wgpu::{TextureFormat, TextureUsages};
@@ -12,12 +13,11 @@ mod post_process;
use crate::post_process::PostProcessSettings; use crate::post_process::PostProcessSettings;
use crate::renderer::{G13Resource, ImageExport, ImageExportPlugin, ImageExportSource}; use crate::renderer::{G13Resource, ImageExport, ImageExportPlugin, ImageExportSource};
use crate::shared::Spinner;
mod renderer; mod renderer;
mod shared; mod shared;
const USE_G13: bool = false; const USE_G13: bool = true;
fn main() { fn main() {
let mut app = App::new(); let mut app = App::new();
@@ -42,14 +42,20 @@ fn main() {
))); )));
} }
app.insert_resource(ClearColor(Color::linear_rgba(0.0, 0.0, 0.0, 0.0))) app.insert_resource(GlobalAmbientLight {
.add_systems(Startup, (setup_camera, shared::spawn_3d_scene)) color: WHITE.into(),
brightness: 400.0,
..default()
});
app.insert_resource(ClearColor(Color::linear_rgba(0.01, 0.01, 0.01, 1.0)))
.add_systems(Startup, (setup_player, shared::spawn_3d_scene))
// .add_systems(PostStartup, spawn_ui) // .add_systems(PostStartup, spawn_ui)
.add_systems(Update, rotate_cube) .add_systems(Update, camera_controller)
.run(); .run();
} }
fn setup_camera( fn setup_player(
mut commands: Commands, mut commands: Commands,
mut images: ResMut<Assets<Image>>, mut images: ResMut<Assets<Image>>,
mut export_sources: ResMut<Assets<ImageExportSource>>, mut export_sources: ResMut<Assets<ImageExportSource>>,
@@ -57,7 +63,7 @@ fn setup_camera(
let mut camera_commands = commands.spawn(( let mut camera_commands = commands.spawn((
Camera3d::default(), Camera3d::default(),
Camera::default(), Camera::default(),
Transform::from_xyz(0.0, 1.0, 2.5).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(0.0, 1.0, 2.5),
UiAntiAlias::Off, UiAntiAlias::Off,
bevy::core_pipeline::prepass::DepthPrepass, bevy::core_pipeline::prepass::DepthPrepass,
bevy::core_pipeline::prepass::NormalPrepass, bevy::core_pipeline::prepass::NormalPrepass,
@@ -68,6 +74,19 @@ fn setup_camera(
..default() ..default()
}, },
PostProcessSettings { scale: 1.0 }, PostProcessSettings { scale: 1.0 },
children![
SpotLight {
color: Color::WHITE,
intensity: light_consts::lumens::VERY_LARGE_CINEMA_LIGHT * 5.0,
range: 32.0,
inner_angle: FRAC_PI_8,
outer_angle: FRAC_PI_2,
shadows_enabled: true,
affects_lightmapped_mesh_diffuse: true,
..default()
},
Transform::from_xyz(0., 0., 0.),
],
)); ));
if USE_G13 { if USE_G13 {
@@ -115,13 +134,18 @@ fn setup_camera(
// )); // ));
// } // }
fn rotate_cube( fn camera_controller(
mut cubes: Query<(&mut Transform, &Spinner)>, camera: Single<(&mut Transform), With<Camera>>,
timer: Res<Time>, timer: Res<Time>,
g13: Res<G13Resource>, g13: Res<G13Resource>,
) { ) {
let (mut transform) = camera.into_inner();
const DEADZONE: i32 = 35; const DEADZONE: i32 = 35;
let sensitivity = Vec2::new(2.0, 1.25);
let speed = 2.0;
let g13 = g13.g13.state(); let g13 = g13.g13.state();
let mut x = g13.x as f32 / 512.0; let mut x = g13.x as f32 / 512.0;
let mut y = g13.y as f32 / 512.0; let mut y = g13.y as f32 / 512.0;
@@ -134,8 +158,35 @@ fn rotate_cube(
y = 0.0; y = 0.0;
} }
for (mut transform, _cube) in &mut cubes { let delta_yaw = -x * sensitivity.x * timer.delta_secs();
transform.rotate_y(x * PI * timer.delta_secs()); let delta_pitch = -y * sensitivity.y * timer.delta_secs();
transform.rotate_x(y * PI * timer.delta_secs());
let (yaw, pitch, roll) = transform.rotation.to_euler(EulerRot::YXZ);
let yaw = yaw + delta_yaw;
const PITCH_LIMIT: f32 = FRAC_PI_2 - 0.01;
let pitch = (pitch + delta_pitch).clamp(-PITCH_LIMIT, PITCH_LIMIT);
transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
let forward = transform.forward();
let forward = Vec3::new(forward.x, 0.0, forward.z).normalize();
let left = transform.left();
let left = Vec3::new(left.x, 0.0, left.z).normalize();
if g13.buttons.g4 {
transform.translation += forward * speed * timer.delta_secs();
}
if g13.buttons.g11 {
transform.translation -= forward * speed * timer.delta_secs();
}
if g13.buttons.g10 {
transform.translation += left * speed * timer.delta_secs();
}
if g13.buttons.g12 {
transform.translation -= left * speed * timer.delta_secs();
} }
} }

View File

@@ -1,47 +1,30 @@
use bevy::prelude::*; use bevy::prelude::*;
#[allow(dead_code)]
#[derive(Component)]
pub struct Spinner;
#[allow(dead_code)]
#[derive(Resource, Default)]
pub struct Flags {
pub debug: bool,
}
#[allow(dead_code)] #[allow(dead_code)]
pub fn spawn_3d_scene( pub fn spawn_3d_scene(
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>>,
) { ) {
commands.spawn(( let mesh = meshes.add(Plane3d::new(
Mesh3d(meshes.add(Cylinder::default())), Vec3::new(0.0, 1.0, 0.0),
MeshMaterial3d(materials.add(Color::from(bevy::color::palettes::css::WHITE))), Vec2::new(0.99, 0.99),
Transform::from_xyz(0.0, 0.0, 0.0),
Spinner,
)); ));
let material = materials.add(Color::from(bevy::color::palettes::css::WHITE));
commands.spawn(( for z in -10..10 {
PointLight { for x in -10..10 {
intensity: 6_000_000., // if ((z + x) % 2) == 0 {
shadows_enabled: true, commands.spawn((
..Default::default() Mesh3d(mesh.clone()),
}, MeshMaterial3d(material.clone()),
Transform::from_xyz(3., 4., 6.), Transform::from_xyz(x as f32 * 2.0, 0.0, z as f32 * 2.0),
)); ));
} // }
}
}
#[allow(dead_code)] // commands.spawn((
pub fn spawn_2d_scene(
mut commands: Commands, // ));
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
commands.spawn((
Spinner,
Mesh2d(meshes.add(RegularPolygon::new(66.0, 8))),
MeshMaterial2d(materials.add(Color::srgb(0.4, 0.4, 0.6))),
));
} }