forked from StrafesNET/strafe-project
lol idk #1
@ -829,17 +829,7 @@ pub struct PhysicsState{
|
||||
//a start zone. If you change mode, a new run is created.
|
||||
run:run::Run,
|
||||
}
|
||||
//random collection of contextual data that doesn't belong in PhysicsState
|
||||
pub struct PhysicsData{
|
||||
//permanent map data
|
||||
bvh:bvh::BvhNode<ConvexMeshId>,
|
||||
//transient map/environment data (open world loads/unloads parts of this data)
|
||||
models:PhysicsModels,
|
||||
//semi-transient data
|
||||
modes:gameplay_modes::Modes,
|
||||
//cached calculations
|
||||
hitbox_mesh:HitboxMesh,
|
||||
}
|
||||
|
||||
impl Default for PhysicsState{
|
||||
fn default()->Self{
|
||||
Self{
|
||||
@ -856,19 +846,18 @@ impl Default for PhysicsState{
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Default for PhysicsData{
|
||||
fn default()->Self{
|
||||
Self{
|
||||
bvh:bvh::BvhNode::default(),
|
||||
models:Default::default(),
|
||||
modes:Default::default(),
|
||||
hitbox_mesh:StyleModifiers::default().calculate_mesh(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PhysicsState{
|
||||
fn clear(&mut self){
|
||||
pub fn camera_body(&self)->Body{
|
||||
Body{
|
||||
position:self.body.position+self.style.camera_offset,
|
||||
..self.body
|
||||
}
|
||||
}
|
||||
pub const fn camera(&self)->PhysicsCamera{
|
||||
self.camera
|
||||
}
|
||||
pub fn clear(&mut self){
|
||||
self.touching.clear();
|
||||
}
|
||||
fn reset_to_default(&mut self){
|
||||
@ -917,46 +906,67 @@ impl PhysicsState{
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PhysicsContext{
|
||||
state:PhysicsState,//this captures the entire state of the physics.
|
||||
data:PhysicsData,//data currently loaded into memory which is needded for physics to run, but is not part of the state.
|
||||
// shared geometry for simulations
|
||||
pub struct PhysicsData{
|
||||
//permanent map data
|
||||
bvh:bvh::BvhNode<ConvexMeshId>,
|
||||
//transient map/environment data (open world loads/unloads parts of this data)
|
||||
models:PhysicsModels,
|
||||
//semi-transient data
|
||||
modes:gameplay_modes::Modes,
|
||||
//cached calculations
|
||||
hitbox_mesh:HitboxMesh,
|
||||
}
|
||||
impl Default for PhysicsData{
|
||||
fn default()->Self{
|
||||
Self{
|
||||
bvh:bvh::BvhNode::default(),
|
||||
models:Default::default(),
|
||||
modes:Default::default(),
|
||||
hitbox_mesh:StyleModifiers::default().calculate_mesh(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// the collection of information required to run physics
|
||||
pub struct PhysicsContext<'a>{
|
||||
state:&'a mut PhysicsState,//this captures the entire state of the physics.
|
||||
data:&'a PhysicsData,//data currently loaded into memory which is needded for physics to run, but is not part of the state.
|
||||
}
|
||||
// the physics consumes both Instruction and PhysicsInternalInstruction,
|
||||
// but can only emit PhysicsInternalInstruction
|
||||
impl InstructionConsumer<InternalInstruction> for PhysicsContext{
|
||||
impl InstructionConsumer<InternalInstruction> for PhysicsContext<'_>{
|
||||
type TimeInner=TimeInner;
|
||||
fn process_instruction(&mut self,ins:TimedInstruction<InternalInstruction,TimeInner>){
|
||||
atomic_internal_instruction(&mut self.state,&self.data,ins)
|
||||
}
|
||||
}
|
||||
impl InstructionConsumer<Instruction> for PhysicsContext{
|
||||
impl InstructionConsumer<Instruction> for PhysicsContext<'_>{
|
||||
type TimeInner=TimeInner;
|
||||
fn process_instruction(&mut self,ins:TimedInstruction<Instruction,TimeInner>){
|
||||
atomic_input_instruction(&mut self.state,&self.data,ins)
|
||||
}
|
||||
}
|
||||
impl InstructionEmitter<InternalInstruction> for PhysicsContext{
|
||||
impl InstructionEmitter<InternalInstruction> for PhysicsContext<'_>{
|
||||
type TimeInner=TimeInner;
|
||||
//this little next instruction function could cache its return value and invalidate the cached value by watching the State.
|
||||
fn next_instruction(&self,time_limit:Time)->Option<TimedInstruction<InternalInstruction,TimeInner>>{
|
||||
next_instruction_internal(&self.state,&self.data,time_limit)
|
||||
}
|
||||
}
|
||||
impl PhysicsContext{
|
||||
pub fn camera_body(&self)->Body{
|
||||
Body{
|
||||
position:self.state.body.position+self.state.style.camera_offset,
|
||||
..self.state.body
|
||||
}
|
||||
}
|
||||
pub const fn camera(&self)->PhysicsCamera{
|
||||
self.state.camera
|
||||
impl PhysicsContext<'_>{
|
||||
pub fn run_input_instruction(
|
||||
state:&mut PhysicsState,
|
||||
data:&PhysicsData,
|
||||
instruction:TimedInstruction<Instruction,TimeInner>
|
||||
){
|
||||
let mut context=PhysicsContext{state,data};
|
||||
context.process_exhaustive(instruction.time);
|
||||
context.process_instruction(instruction);
|
||||
}
|
||||
}
|
||||
impl PhysicsData{
|
||||
/// use with caution, this is the only non-instruction way to mess with physics
|
||||
pub fn generate_models(&mut self,map:&map::CompleteMap){
|
||||
self.state.clear();
|
||||
let mut modes=map.modes.clone();
|
||||
for mode in &mut modes.modes{
|
||||
mode.denormalize_data();
|
||||
@ -1087,17 +1097,12 @@ impl PhysicsContext{
|
||||
(IntersectAttributesId::new(attr_id as u32),attr)
|
||||
).collect(),
|
||||
};
|
||||
self.data.bvh=bvh;
|
||||
self.data.models=models;
|
||||
self.data.modes=modes;
|
||||
self.bvh=bvh;
|
||||
self.models=models;
|
||||
self.modes=modes;
|
||||
//hitbox_mesh is unchanged
|
||||
println!("Physics Objects: {}",model_count);
|
||||
}
|
||||
|
||||
pub fn run_input_instruction(&mut self,instruction:TimedInstruction<Instruction,TimeInner>){
|
||||
self.process_exhaustive(instruction.time);
|
||||
self.process_instruction(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
//this is the one who asks
|
||||
|
@ -21,7 +21,7 @@ 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,SessionTimeInner>>{
|
||||
let physics=crate::physics::PhysicsContext::default();
|
||||
let physics=crate::physics::PhysicsState::default();
|
||||
let timer=Timer::unpaused(SessionTime::ZERO,PhysicsTime::ZERO);
|
||||
let simulation=Simulation::new(timer,physics);
|
||||
let mut session=Session::new(
|
||||
|
@ -14,6 +14,7 @@ use strafesnet_common::timer::{Scaled,Timer};
|
||||
use strafesnet_common::session::{TimeInner as SessionTimeInner,Time as SessionTime};
|
||||
|
||||
use crate::mouse_interpolator::{MouseInterpolator,StepInstruction,Instruction as MouseInterpolatorInstruction};
|
||||
use crate::physics::{PhysicsContext,PhysicsData};
|
||||
use crate::settings::UserSettings;
|
||||
|
||||
pub enum Instruction<'a>{
|
||||
@ -60,12 +61,12 @@ pub struct FrameState{
|
||||
|
||||
pub struct Simulation{
|
||||
timer:Timer<Scaled<SessionTimeInner,PhysicsTimeInner>>,
|
||||
physics:crate::physics::PhysicsContext,
|
||||
physics:crate::physics::PhysicsState,
|
||||
}
|
||||
impl Simulation{
|
||||
pub const fn new(
|
||||
timer:Timer<Scaled<SessionTimeInner,PhysicsTimeInner>>,
|
||||
physics:crate::physics::PhysicsContext,
|
||||
physics:crate::physics::PhysicsState,
|
||||
)->Self{
|
||||
Self{
|
||||
timer,
|
||||
@ -106,12 +107,12 @@ impl Replay{
|
||||
simulation,
|
||||
}
|
||||
}
|
||||
pub fn advance(&mut self,time_limit:SessionTime){
|
||||
pub fn advance(&mut self,physics_data:&PhysicsData,time_limit:SessionTime){
|
||||
let mut time=self.simulation.timer.time(time_limit);
|
||||
loop{
|
||||
if let Some(ins)=self.recording.instructions.get(self.last_instruction_id){
|
||||
if ins.time<time{
|
||||
self.simulation.physics.run_input_instruction(ins.clone());
|
||||
PhysicsContext::run_input_instruction(&mut self.simulation.physics,physics_data,ins.clone());
|
||||
self.last_instruction_id+=1;
|
||||
}else{
|
||||
break;
|
||||
@ -144,6 +145,7 @@ pub struct Session{
|
||||
mouse_interpolator:crate::mouse_interpolator::MouseInterpolator,
|
||||
view_state:ViewState,
|
||||
//gui:GuiState
|
||||
geometry_shared:crate::physics::PhysicsData,
|
||||
simulation:Simulation,
|
||||
// below fields not included in lite session
|
||||
recording:Recording,
|
||||
@ -158,6 +160,7 @@ impl Session{
|
||||
Self{
|
||||
user_settings,
|
||||
mouse_interpolator:MouseInterpolator::new(),
|
||||
geometry_shared:Default::default(),
|
||||
simulation,
|
||||
view_state:ViewState::Play,
|
||||
recording:Default::default(),
|
||||
@ -168,7 +171,8 @@ impl Session{
|
||||
self.recording.clear();
|
||||
}
|
||||
fn change_map(&mut self,map:&strafesnet_common::map::CompleteMap){
|
||||
self.simulation.physics.generate_models(map);
|
||||
self.simulation.physics.clear();
|
||||
self.geometry_shared.generate_models(map);
|
||||
}
|
||||
pub fn get_frame_state(&self,time:SessionTime)->Option<FrameState>{
|
||||
match &self.view_state{
|
||||
@ -339,7 +343,7 @@ impl InstructionConsumer<Instruction<'_>> for Session{
|
||||
// this just refreshes the replays
|
||||
for replay in self.replays.values_mut(){
|
||||
// TODO: filter idles from recording, inject new idles in real time
|
||||
replay.advance(ins.time);
|
||||
replay.advance(&self.geometry_shared,ins.time);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -355,7 +359,7 @@ impl InstructionConsumer<StepInstruction> for Session{
|
||||
if let Some(instruction)=self.mouse_interpolator.pop_buffered_instruction(ins.set_time(time)){
|
||||
//record
|
||||
self.recording.instructions.push(instruction.clone());
|
||||
self.simulation.physics.run_input_instruction(instruction);
|
||||
PhysicsContext::run_input_instruction(&mut self.simulation.physics,&self.geometry_shared,instruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user