|
|
|
@ -212,14 +212,135 @@ impl MouseInterpolator{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn vector3_to_glam(v:&strafesnet_roblox_bot_file::v0::Vector3)->glam::Vec3{
|
|
|
|
|
glam::vec3(v.x,v.y,v.z)
|
|
|
|
|
}
|
|
|
|
|
fn f32_to_p64(f:f32)->strafesnet_common::integer::Planar64{
|
|
|
|
|
f.try_into().unwrap_or(strafesnet_common::integer::Planar64::ZERO)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct PlayBacker{
|
|
|
|
|
//Instructions
|
|
|
|
|
timelines:strafesnet_roblox_bot_file::v0::Block,
|
|
|
|
|
//"Simulation"
|
|
|
|
|
event_id:usize,
|
|
|
|
|
offset:f64,
|
|
|
|
|
duration:f64,
|
|
|
|
|
timer:Timer<Scaled>,
|
|
|
|
|
physics:crate::physics::PhysicsContext,
|
|
|
|
|
}
|
|
|
|
|
impl PlayBacker{
|
|
|
|
|
pub fn new(
|
|
|
|
|
physics:crate::physics::PhysicsContext,
|
|
|
|
|
timelines:strafesnet_roblox_bot_file::v0::Block,
|
|
|
|
|
)->Self{
|
|
|
|
|
let first=timelines.output_events.first().unwrap();
|
|
|
|
|
let last=timelines.output_events.last().unwrap();
|
|
|
|
|
Self{
|
|
|
|
|
offset:first.time,
|
|
|
|
|
duration:last.time-first.time,
|
|
|
|
|
timelines,
|
|
|
|
|
event_id:0,
|
|
|
|
|
timer:Timer::from_state(Scaled::identity(),false),
|
|
|
|
|
physics,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pub fn handle_instruction(&mut self,TimedInstruction{time,instruction}:&TimedInstruction<Instruction>){
|
|
|
|
|
//match the instruction so the playback is pausable :D
|
|
|
|
|
match instruction{
|
|
|
|
|
&Instruction::SetPaused(paused)=>{
|
|
|
|
|
let _=self.timer.set_paused(*time,paused);
|
|
|
|
|
},
|
|
|
|
|
_=>(),
|
|
|
|
|
}
|
|
|
|
|
let simulation_time=self.timer.time(*time);
|
|
|
|
|
let mut time_float=simulation_time.get() as f64/Time::ONE_SECOND.get() as f64+self.offset;
|
|
|
|
|
loop{
|
|
|
|
|
match self.timelines.output_events.get(self.event_id+1){
|
|
|
|
|
Some(next_event)=>{
|
|
|
|
|
if next_event.time<time_float{
|
|
|
|
|
self.event_id+=1;
|
|
|
|
|
}else{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
None=>{
|
|
|
|
|
//reset playback
|
|
|
|
|
self.event_id=0;
|
|
|
|
|
self.offset-=self.duration;
|
|
|
|
|
time_float-=self.duration;
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pub fn get_frame_state(&self,time:Time)->crate::graphics::FrameState{
|
|
|
|
|
let time=self.timer.time(time);
|
|
|
|
|
let event0=&self.timelines.output_events[self.event_id];
|
|
|
|
|
let event1=&self.timelines.output_events[self.event_id+1];
|
|
|
|
|
let p0=vector3_to_glam(&event0.event.position);
|
|
|
|
|
let p1=vector3_to_glam(&event1.event.position);
|
|
|
|
|
let v0=vector3_to_glam(&event0.event.velocity);
|
|
|
|
|
let v1=vector3_to_glam(&event1.event.velocity);
|
|
|
|
|
let a0=vector3_to_glam(&event0.event.acceleration);
|
|
|
|
|
let a1=vector3_to_glam(&event1.event.acceleration);
|
|
|
|
|
let t0=event0.time;
|
|
|
|
|
let t1=event1.time;
|
|
|
|
|
let time_float=time.get() as f64/Time::ONE_SECOND.get() as f64;
|
|
|
|
|
let t=((time_float+self.offset-t0)/(t1-t0)) as f32;
|
|
|
|
|
let p=p0.lerp(p1,t).to_array().map(f32_to_p64);
|
|
|
|
|
let v=v0.lerp(v1,t).to_array().map(f32_to_p64);
|
|
|
|
|
let a=a0.lerp(a1,t).to_array().map(f32_to_p64);
|
|
|
|
|
|
|
|
|
|
//println!("position={:?}",p);
|
|
|
|
|
|
|
|
|
|
let angles0=vector3_to_glam(&event0.event.angles);
|
|
|
|
|
let angles1=vector3_to_glam(&event1.event.angles);
|
|
|
|
|
let angles=angles0.lerp(angles1,t);
|
|
|
|
|
// mask mantissa out and set it to minimum value
|
|
|
|
|
// let ax_epsilon=f32::from_bits(angles.x.to_bits()&!((1<<23)-1)|1);
|
|
|
|
|
// let ay_epsilon=f32::from_bits(angles.y.to_bits()&!((1<<23)-1)|1);
|
|
|
|
|
let body=crate::physics::Body{
|
|
|
|
|
time,
|
|
|
|
|
position:strafesnet_common::integer::Planar64Vec3::new(p),
|
|
|
|
|
velocity:strafesnet_common::integer::Planar64Vec3::new(v),
|
|
|
|
|
acceleration:strafesnet_common::integer::Planar64Vec3::new(a),
|
|
|
|
|
};
|
|
|
|
|
const FLOAT64_TO_ANGLE32_RADIANS:f64=((1i64<<31) as f64)/std::f64::consts::PI;
|
|
|
|
|
// xy is reversed in strafe client for some reason
|
|
|
|
|
let (ax,ay)=(
|
|
|
|
|
-angles.y as f64*FLOAT64_TO_ANGLE32_RADIANS,
|
|
|
|
|
-angles.x as f64*FLOAT64_TO_ANGLE32_RADIANS,
|
|
|
|
|
);
|
|
|
|
|
let camera=crate::physics::PhysicsCamera::new(
|
|
|
|
|
strafesnet_common::integer::Ratio64Vec2::new(1.0f32.try_into().unwrap(),1.0f32.try_into().unwrap()),
|
|
|
|
|
glam::ivec2(ax as i64 as i32,ay as i64 as i32)
|
|
|
|
|
);
|
|
|
|
|
crate::graphics::FrameState{
|
|
|
|
|
body,
|
|
|
|
|
camera,
|
|
|
|
|
time,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pub fn user_settings(&self)->crate::settings::UserSettings{
|
|
|
|
|
//oof, settings ignored
|
|
|
|
|
crate::settings::UserSettings::default()
|
|
|
|
|
}
|
|
|
|
|
pub fn change_map(&mut self,time:Time,map:&strafesnet_common::map::CompleteMap){
|
|
|
|
|
self.physics.generate_models(&map);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new<'a>(
|
|
|
|
|
mut graphics_worker:crate::compat_worker::INWorker<'a,crate::graphics_worker::Instruction>,
|
|
|
|
|
user_settings:crate::settings::UserSettings,
|
|
|
|
|
)->crate::compat_worker::QNWorker<'a,TimedInstruction<Instruction>>{
|
|
|
|
|
let physics=crate::physics::PhysicsContext::default();
|
|
|
|
|
let mut interpolator=MouseInterpolator::new(
|
|
|
|
|
//load bot
|
|
|
|
|
let file=std::fs::File::open("/home/quat/strafesnet/roblox_bot_file/files/bhop_marble_7cf33a64-7120-4514-b9fa-4fe29d9523d").unwrap();
|
|
|
|
|
let mut bot_file=strafesnet_roblox_bot_file::v0::File::new(std::io::BufReader::new(file)).unwrap();
|
|
|
|
|
let mut interpolator=PlayBacker::new(
|
|
|
|
|
physics,
|
|
|
|
|
user_settings
|
|
|
|
|
bot_file.read_all().unwrap(),
|
|
|
|
|
);
|
|
|
|
|
crate::compat_worker::QNWorker::new(move |ins:TimedInstruction<Instruction>|{
|
|
|
|
|
interpolator.handle_instruction(&ins);
|
|
|
|
@ -229,7 +350,7 @@ pub fn new<'a>(
|
|
|
|
|
graphics_worker.send(crate::graphics_worker::Instruction::Render(frame_state)).unwrap();
|
|
|
|
|
},
|
|
|
|
|
Instruction::Resize(size)=>{
|
|
|
|
|
graphics_worker.send(crate::graphics_worker::Instruction::Resize(size,interpolator.user_settings().clone())).unwrap();
|
|
|
|
|
graphics_worker.send(crate::graphics_worker::Instruction::Resize(size,interpolator.user_settings())).unwrap();
|
|
|
|
|
},
|
|
|
|
|
Instruction::ChangeMap(map)=>{
|
|
|
|
|
interpolator.change_map(ins.time,&map);
|
|
|
|
|