move camera slightly to the right of the player

This commit is contained in:
aiden 2023-05-22 18:51:12 +01:00
parent 56c05ccfdf
commit 82809ff95a
Signed by: aiden
GPG Key ID: EFA9C74AEBF806E0
3 changed files with 38 additions and 33 deletions

@ -1,11 +1,10 @@
use cgmath::{Vector3, Point3, InnerSpace, Deg, Rad, Matrix4}; use cgmath::{Vector3, Point3, InnerSpace, Deg, Rad, Matrix4};
use crate::{input::Input, player::Player}; use crate::{input::Input, player::Player};
#[derive(Debug)] #[derive(Debug)]
pub struct Camera { pub struct Camera {
pub position: Point3<f32>, pub position: Option<Point3<f32>>,
pub target: Point3<f32>, pub target: Option<Point3<f32>>,
pub rot_y: Deg<f32>, pub rot_y: Deg<f32>,
@ -16,21 +15,17 @@ pub struct Camera {
} }
fn pitch_clamp(pitch: f32) -> Deg<f32> { fn pitch_clamp(pitch: f32) -> Deg<f32> {
const PITCH_LIM: f32 = 90.0 - 0.0001; const PITCH_LIM: f32 = 90.0 - (0.0001 * 10.0);
return Deg(pitch.clamp(-PITCH_LIM, PITCH_LIM)); return Deg(pitch.clamp(-PITCH_LIM, PITCH_LIM));
} }
impl Camera { impl Camera {
pub fn new< pub fn new(
V: Into<Point3<f32>>,
>(
dimensions: winit::dpi::PhysicalSize<u32>, dimensions: winit::dpi::PhysicalSize<u32>,
position: V,
rot_y: Deg<f32>, rot_y: Deg<f32>,
) -> Self { ) -> Self {
return Self { return Self {
position: position.into(), position: None,
target: (0.0, 0.0, 0.0).into(), target: None,
rot_y: pitch_clamp(rot_y.0), rot_y: pitch_clamp(rot_y.0),
aspect: dimensions.width as f32 / dimensions.height as f32, aspect: dimensions.width as f32 / dimensions.height as f32,
@ -46,7 +41,8 @@ impl Camera {
} }
pub fn update_pos(&mut self, player: &Player) { pub fn update_pos(&mut self, player: &Player) {
self.target = player.position; let mut target = player.position + (player.forward_right().1 * (0.1 /* player half width */ + 0.05 /* additional offset */));
target.y += 0.25; // player half height
let (sin_yaw, cos_yaw) = Rad::from(player.rot_x).0.sin_cos(); let (sin_yaw, cos_yaw) = Rad::from(player.rot_x).0.sin_cos();
let (sin_pitch, cos_pitch) = Rad::from(self.rot_y).0.sin_cos(); let (sin_pitch, cos_pitch) = Rad::from(self.rot_y).0.sin_cos();
@ -57,7 +53,8 @@ impl Camera {
cos_pitch * sin_yaw cos_pitch * sin_yaw
).normalize(); ).normalize();
self.position = self.target - v; self.position = Some(target - v);
self.target = Some(target);
return; return;
} }
@ -105,7 +102,7 @@ impl<'a> CameraUniform {
cos_pitch * sin_yaw cos_pitch * sin_yaw
).normalize();*/ ).normalize();*/
let view = Matrix4::look_to_rh(camera.position, camera.target - camera.position, Vector3::unit_y()); let view = Matrix4::look_to_rh(camera.position.unwrap(), camera.target.unwrap() - camera.position.unwrap(), Vector3::unit_y());
let proj = cgmath::perspective(camera.fovy, camera.aspect, camera.znear, camera.zfar); let proj = cgmath::perspective(camera.fovy, camera.aspect, camera.znear, camera.zfar);
let transformed_proj: [[f32; 4]; 4] = (Self::OPENGL_TO_WGPU_MATRIX * proj * view).into(); let transformed_proj: [[f32; 4]; 4] = (Self::OPENGL_TO_WGPU_MATRIX * proj * view).into();
queue.write_buffer(&(self.buffer), 0, bytemuck::cast_slice(&(transformed_proj))); queue.write_buffer(&(self.buffer), 0, bytemuck::cast_slice(&(transformed_proj)));

@ -9,10 +9,20 @@ pub struct Player {
} }
impl Player { impl Player {
pub fn update_pos(&mut self, input: &Input, dt: f32) { pub fn sin_cos(&self) -> (f32, f32) {
let (sin, cos) = Rad::from(self.rot_x).0.sin_cos(); return Rad::from(self.rot_x).0.sin_cos();
}
pub fn forward_right(&self) -> (Vector3<f32>, Vector3<f32>) {
let (sin, cos) = self.sin_cos();
let forward = Vector3::new(cos, 0.0, sin).normalize(); let forward = Vector3::new(cos, 0.0, sin).normalize();
let right = Vector3::new(-sin, 0.0, cos).normalize(); let right = Vector3::new(-sin, 0.0, cos).normalize();
return (forward, right);
}
pub fn update_pos(&mut self, input: &Input, dt: f32) {
let (forward, right) = self.forward_right();
self.position += forward * (input.amount_forward - input.amount_backward) * (input.speed * dt); self.position += forward * (input.amount_forward - input.amount_backward) * (input.speed * dt);
self.position += right * (input.amount_right - input.amount_left) * (input.speed * dt); self.position += right * (input.amount_right - input.amount_left) * (input.speed * dt);

@ -21,13 +21,12 @@ pub struct State {
plane_buffer: wgpu::Buffer, plane_buffer: wgpu::Buffer,
build_buffer: wgpu::Buffer, build_buffer: wgpu::Buffer,
player: Player,
camera: Camera, camera: Camera,
camera_uniform: CameraUniform, camera_uniform: CameraUniform,
camera_bind_group: wgpu::BindGroup, camera_bind_group: wgpu::BindGroup,
depth_view: wgpu::TextureView, depth_view: wgpu::TextureView,
player: Player,
} }
#[repr(C)] #[repr(C)]
@ -128,7 +127,18 @@ impl State {
mapped_at_creation: false, mapped_at_creation: false,
})); }));
let camera = Camera::new(size, (0.25, 1.0, 0.0), Deg(-90.0)); let player = Player {
position: (1.0, 0.25, -1.0).into(),
rot_x: Deg(0.0),
buffer: device.create_buffer(&(wgpu::BufferDescriptor {
label: Some("player_buffer"),
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
size: std::mem::size_of::<Vertex>() as u64 * 6,
mapped_at_creation: false,
})),
};
let mut camera = Camera::new(size, Deg(0.0));
camera.update_pos(&(player));
let camera_bind_group_layout = &(device.create_bind_group_layout(&(wgpu::BindGroupLayoutDescriptor { let camera_bind_group_layout = &(device.create_bind_group_layout(&(wgpu::BindGroupLayoutDescriptor {
entries: &[ entries: &[
@ -216,17 +226,6 @@ impl State {
label: Some("camera_bind_group"), label: Some("camera_bind_group"),
})); }));
let player = Player {
position: (1.0, 0.0, -1.0).into(),
rot_x: Deg(0.0),
buffer: device.create_buffer(&(wgpu::BufferDescriptor {
label: Some("player_buffer"),
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
size: std::mem::size_of::<Vertex>() as u64 * 6,
mapped_at_creation: false,
})),
};
return Ok(Self { return Ok(Self {
input, input,
@ -244,13 +243,12 @@ impl State {
plane_buffer, plane_buffer,
build_buffer, build_buffer,
player,
camera, camera,
camera_uniform, camera_uniform,
camera_bind_group, camera_bind_group,
depth_view, depth_view,
player,
}); });
} }
@ -407,7 +405,7 @@ impl State {
// and the player should also rotate so that // and the player should also rotate so that
// its back is facing the camera.) // its back is facing the camera.)
self.queue.write_buffer(&(self.player.buffer), 0, bytemuck::cast_slice(&(rot_rect( self.queue.write_buffer(&(self.player.buffer), 0, bytemuck::cast_slice(&(rot_rect(
0.1, 0.2, Rad::from(self.player.rot_x) 0.2, 0.5, Rad::from(self.player.rot_x)
).map(|point| Vertex { position: (self.player.position + point.to_vec()).into(), color: [1.0, 1.0, 1.0] })))); ).map(|point| Vertex { position: (self.player.position + point.to_vec()).into(), color: [1.0, 1.0, 1.0] }))));
render_pass.set_vertex_buffer(0, self.player.buffer.slice(..)); render_pass.set_vertex_buffer(0, self.player.buffer.slice(..));
render_pass.draw(0..6, 0..1); render_pass.draw(0..6, 0..1);