diff --git a/src/body.rs b/src/body.rs new file mode 100644 index 0000000..210bcbc --- /dev/null +++ b/src/body.rs @@ -0,0 +1,65 @@ +pub struct Body { + pub position: glam::Vec3,//I64 where 2^32 = 1 u + pub velocity: glam::Vec3,//I64 where 2^32 = 1 u/s + pub time: TIME,//nanoseconds x xxxxD! +} + +pub struct PhysicsState { + pub body: Body, + pub time: TIME, + pub strafe_tick_period: TIME, + pub tick: u32, + pub gravity: glam::Vec3, + pub friction: f32, + pub mv: f32, + pub grounded: bool, + pub walkspeed: f32, +} + +pub type TIME = i64; + +const CONTROL_JUMP:u32 = 0b01000000;//temp +impl PhysicsState { + //delete this, we are tickless gamers + pub fn run(&mut self, time: TIME, control_dir: glam::Vec3, controls: u32){ + let target_tick = (time/self.strafe_tick_period) as u32;//100t + //the game code can run for 1 month before running out of ticks + while self.tick glam::Vec3 { + let dt=(time-self.body.time) as f64/1_000_000_000f64; + self.body.position+self.body.velocity*(dt as f32)+self.gravity*((0.5*dt*dt) as f32) + } +} diff --git a/src/lib.rs b/src/lib.rs index 0c71749..2aaeac4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,2 @@ pub mod framework; +pub mod body; diff --git a/src/main.rs b/src/main.rs index 720fa6e..f862e1e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,20 +34,12 @@ struct Model { // Note: we use the Y=up coordinate space in this example. struct Camera { - time: Instant, - pos: glam::Vec3, - vel: glam::Vec3, - gravity: glam::Vec3, - friction: f32, screen_size: (u32, u32), offset: glam::Vec3, fov: f32, yaw: f32, pitch: f32, controls: u32, - mv: f32, - grounded: bool, - walkspeed: f32, } const CONTROL_MOVEFORWARD:u32 = 0b00000001; @@ -100,7 +92,7 @@ fn get_control_dir(controls: u32) -> glam::Vec3{ } impl Camera { - fn to_uniform_data(&self) -> [f32; 16 * 3 + 4] { + fn to_uniform_data(&self, pos: glam::Vec3) -> [f32; 16 * 3 + 4] { let aspect = self.screen_size.0 as f32 / self.screen_size.1 as f32; let fov = if self.controls&CONTROL_ZOOM==0 { self.fov @@ -109,7 +101,7 @@ impl Camera { }; let proj = perspective_rh(fov, aspect, 0.5, 1000.0); let proj_inv = proj.inverse(); - let view = glam::Mat4::from_translation(self.pos+self.offset) * glam::Mat4::from_euler(glam::EulerRot::YXZ, self.yaw, self.pitch, 0f32); + let view = glam::Mat4::from_translation(pos+self.offset) * glam::Mat4::from_euler(glam::EulerRot::YXZ, self.yaw, self.pitch, 0f32); let view_inv = view.inverse(); let mut raw = [0f32; 16 * 3 + 4]; @@ -122,7 +114,9 @@ impl Camera { } pub struct Skybox { + start_time: std::time::Instant, camera: Camera, + physics: strafe_client::body::PhysicsState, sky_pipeline: wgpu::RenderPipeline, entity_pipeline: wgpu::RenderPipeline, ground_pipeline: wgpu::RenderPipeline, @@ -290,22 +284,30 @@ impl strafe_client::framework::Example for Skybox { }); let camera = Camera { - time: Instant::now(), - pos: glam::Vec3::new(5.0,0.0,5.0), - vel: glam::Vec3::new(0.0,0.0,0.0), - gravity: glam::Vec3::new(0.0,-100.0,0.0), - friction: 90.0, screen_size: (config.width, config.height), offset: glam::Vec3::new(0.0,4.5,0.0), fov: 1.0, //fov_slope = tan(fov_y/2) pitch: 0.0, yaw: 0.0, - mv: 2.7, controls:0, + }; + let physics = strafe_client::body::PhysicsState { + body: strafe_client::body::Body { + position: glam::Vec3::new(5.0,0.0,5.0), + velocity: glam::Vec3::new(0.0,0.0,0.0), + time: 0, + }, + time: 0, + tick: 0, + strafe_tick_period: 1_000_000_000/100,//100t + gravity: glam::Vec3::new(0.0,-100.0,0.0), + friction: 90.0, + mv: 2.7, grounded: true, walkspeed: 18.0, }; - let camera_uniforms = camera.to_uniform_data(); + + let camera_uniforms = camera.to_uniform_data(physics.extrapolate_position(0)); let camera_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("Camera"), contents: bytemuck::cast_slice(&camera_uniforms), @@ -539,7 +541,9 @@ impl strafe_client::framework::Example for Skybox { let depth_view = Self::create_depth_texture(config, device); Skybox { + start_time: Instant::now(), camera, + physics, sky_pipeline, entity_pipeline, ground_pipeline, @@ -625,44 +629,18 @@ impl strafe_client::framework::Example for Skybox { queue: &wgpu::Queue, _spawner: &strafe_client::framework::Spawner, ) { - let time = Instant::now(); - - //physique - let dt=(time-self.camera.time).as_secs_f32(); - self.camera.time=time; let camera_mat=glam::Mat3::from_euler(glam::EulerRot::YXZ,self.camera.yaw,0f32,0f32); let control_dir=camera_mat*get_control_dir(self.camera.controls&(CONTROL_MOVELEFT|CONTROL_MOVERIGHT|CONTROL_MOVEFORWARD|CONTROL_MOVEBACK)).normalize_or_zero(); - let d=self.camera.vel.dot(control_dir); - if d