forked from StrafesNET/strafe-client
implement MoveState + TouchingState
This commit is contained in:
parent
4f596ca5d7
commit
127b205401
270
src/physics.rs
270
src/physics.rs
@ -57,12 +57,6 @@ pub struct Body {
|
|||||||
time:Time,//nanoseconds x xxxxD!
|
time:Time,//nanoseconds x xxxxD!
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum MoveRestriction {
|
|
||||||
Air,
|
|
||||||
Water,
|
|
||||||
Ground,
|
|
||||||
Ladder,//multiple ladders how
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
enum InputInstruction {
|
enum InputInstruction {
|
||||||
@ -283,21 +277,25 @@ impl StyleModifiers{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum MoveState{
|
||||||
|
Air,
|
||||||
|
Walk(WalkState),
|
||||||
|
Water,
|
||||||
|
Ladder(WalkState),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct PhysicsState{
|
pub struct PhysicsState{
|
||||||
pub time:Time,
|
pub time:Time,
|
||||||
pub body:Body,
|
pub body:Body,
|
||||||
pub world:WorldState,//currently there is only one state the world can be in
|
pub world:WorldState,//currently there is only one state the world can be in
|
||||||
pub game:GameMechanicsState,
|
pub game:GameMechanicsState,
|
||||||
pub style:StyleModifiers,
|
pub style:StyleModifiers,
|
||||||
pub contacts:std::collections::HashMap::<u32,RelativeCollision>,
|
touching:TouchingState,
|
||||||
pub intersects:std::collections::HashMap::<u32,RelativeCollision>,
|
|
||||||
//pub intersections: Vec<ModelId>,
|
|
||||||
//camera must exist in state because wormholes modify the camera, also camera punch
|
//camera must exist in state because wormholes modify the camera, also camera punch
|
||||||
pub camera:PhysicsCamera,
|
pub camera:PhysicsCamera,
|
||||||
pub next_mouse:MouseState,//Where is the mouse headed next
|
pub next_mouse:MouseState,//Where is the mouse headed next
|
||||||
pub controls:u32,
|
pub controls:u32,
|
||||||
pub walk:WalkState,
|
pub move_state:MoveState,
|
||||||
pub grounded:bool,
|
|
||||||
//all models
|
//all models
|
||||||
pub models:Vec<ModelPhysics>,
|
pub models:Vec<ModelPhysics>,
|
||||||
pub bvh:crate::bvh::BvhNode,
|
pub bvh:crate::bvh::BvhNode,
|
||||||
@ -395,6 +393,55 @@ impl RelativeCollision {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TouchingState{
|
||||||
|
contacts:std::collections::HashMap::<u32,RelativeCollision>,
|
||||||
|
intersects:std::collections::HashMap::<u32,RelativeCollision>,
|
||||||
|
}
|
||||||
|
impl TouchingState{
|
||||||
|
fn clear(&mut self){
|
||||||
|
self.contacts.clear();
|
||||||
|
self.intersects.clear();
|
||||||
|
}
|
||||||
|
fn insert_contact(&mut self,model_id:u32,collision:RelativeCollision)->Option<RelativeCollision>{
|
||||||
|
self.contacts.insert(model_id,collision)
|
||||||
|
}
|
||||||
|
fn remove_contact(&mut self,model_id:u32)->Option<RelativeCollision>{
|
||||||
|
self.contacts.remove(&model_id)
|
||||||
|
}
|
||||||
|
fn insert_intersect(&mut self,model_id:u32,collision:RelativeCollision)->Option<RelativeCollision>{
|
||||||
|
self.intersects.insert(model_id,collision)
|
||||||
|
}
|
||||||
|
fn remove_intersect(&mut self,model_id:u32)->Option<RelativeCollision>{
|
||||||
|
self.intersects.remove(&model_id)
|
||||||
|
}
|
||||||
|
fn constrain_velocity(&self,models:&Vec<ModelPhysics>,velocity:&mut Planar64Vec3){
|
||||||
|
for (_,contact) in &self.contacts {
|
||||||
|
let n=contact.normal(models);
|
||||||
|
let d=velocity.dot(n);
|
||||||
|
if d<Planar64::ZERO{
|
||||||
|
(*velocity)-=n*(d/n.dot(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn constrain_acceleration(&self,models:&Vec<ModelPhysics>,acceleration:&mut Planar64Vec3){
|
||||||
|
for (_,contact) in &self.contacts {
|
||||||
|
let n=contact.normal(models);
|
||||||
|
let d=acceleration.dot(n);
|
||||||
|
if d<Planar64::ZERO{
|
||||||
|
(*acceleration)-=n*(d/n.dot(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Default for TouchingState{
|
||||||
|
fn default() -> Self {
|
||||||
|
Self{
|
||||||
|
contacts: std::collections::HashMap::new(),
|
||||||
|
intersects: std::collections::HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Body {
|
impl Body {
|
||||||
pub fn with_pva(position:Planar64Vec3,velocity:Planar64Vec3,acceleration:Planar64Vec3) -> Self {
|
pub fn with_pva(position:Planar64Vec3,velocity:Planar64Vec3,acceleration:Planar64Vec3) -> Self {
|
||||||
Self{
|
Self{
|
||||||
@ -431,12 +478,10 @@ impl Default for PhysicsState{
|
|||||||
body: Body::with_pva(Planar64Vec3::int(0,50,0),Planar64Vec3::int(0,0,0),Planar64Vec3::int(0,-100,0)),
|
body: Body::with_pva(Planar64Vec3::int(0,50,0),Planar64Vec3::int(0,0,0),Planar64Vec3::int(0,-100,0)),
|
||||||
time: Time::ZERO,
|
time: Time::ZERO,
|
||||||
style:StyleModifiers::default(),
|
style:StyleModifiers::default(),
|
||||||
grounded: false,
|
touching:TouchingState::default(),
|
||||||
contacts: std::collections::HashMap::new(),
|
|
||||||
intersects: std::collections::HashMap::new(),
|
|
||||||
models: Vec::new(),
|
models: Vec::new(),
|
||||||
bvh:crate::bvh::BvhNode::default(),
|
bvh:crate::bvh::BvhNode::default(),
|
||||||
walk: WalkState::new(),
|
move_state: MoveState::Air,
|
||||||
camera: PhysicsCamera::from_offset(Planar64Vec3::int(0,2,0)),//4.5-2.5=2
|
camera: PhysicsCamera::from_offset(Planar64Vec3::int(0,2,0)),//4.5-2.5=2
|
||||||
next_mouse: MouseState::default(),
|
next_mouse: MouseState::default(),
|
||||||
controls: 0,
|
controls: 0,
|
||||||
@ -452,8 +497,7 @@ impl PhysicsState {
|
|||||||
pub fn clear(&mut self){
|
pub fn clear(&mut self){
|
||||||
self.models.clear();
|
self.models.clear();
|
||||||
self.modes.clear();
|
self.modes.clear();
|
||||||
self.contacts.clear();
|
self.touching.clear();
|
||||||
self.intersects.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_worker(mut self)->crate::worker::CompatWorker<TimedInstruction<InputInstruction>,PhysicsOutputState,Box<dyn FnMut(TimedInstruction<InputInstruction>)->PhysicsOutputState>>{
|
pub fn into_worker(mut self)->crate::worker::CompatWorker<TimedInstruction<InputInstruction>,PhysicsOutputState,Box<dyn FnMut(TimedInstruction<InputInstruction>)->PhysicsOutputState>>{
|
||||||
@ -653,30 +697,22 @@ impl PhysicsState {
|
|||||||
self.controls=if state{self.controls|control}else{self.controls&!control};
|
self.controls=if state{self.controls|control}else{self.controls&!control};
|
||||||
}
|
}
|
||||||
fn jump(&mut self){
|
fn jump(&mut self){
|
||||||
self.grounded=false;//do I need this?
|
match &self.move_state{
|
||||||
let mut v=self.body.velocity+self.style.get_jump_power();
|
MoveState::Air=>(),
|
||||||
self.contact_constrain_velocity(&mut v);
|
MoveState::Walk(walk_state)=>{
|
||||||
self.body.velocity=v;
|
let mut v=self.body.velocity+self.style.get_jump_power();
|
||||||
|
self.touching.constrain_velocity(&self.models,&mut v);
|
||||||
|
self.body.velocity=v;
|
||||||
|
},
|
||||||
|
MoveState::Water=>(),
|
||||||
|
MoveState::Ladder(walk_state)=>{
|
||||||
|
let mut v=self.body.velocity+self.style.get_jump_power();
|
||||||
|
self.touching.constrain_velocity(&self.models,&mut v);
|
||||||
|
self.body.velocity=v;
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contact_constrain_velocity(&self,velocity:&mut Planar64Vec3){
|
|
||||||
for (_,contact) in &self.contacts {
|
|
||||||
let n=contact.normal(&self.models);
|
|
||||||
let d=velocity.dot(n);
|
|
||||||
if d<Planar64::ZERO{
|
|
||||||
(*velocity)-=n*(d/n.dot(n));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn contact_constrain_acceleration(&self,acceleration:&mut Planar64Vec3){
|
|
||||||
for (_,contact) in &self.contacts {
|
|
||||||
let n=contact.normal(&self.models);
|
|
||||||
let d=acceleration.dot(n);
|
|
||||||
if d<Planar64::ZERO{
|
|
||||||
(*acceleration)-=n*(d/n.dot(n));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn next_strafe_instruction(&self) -> Option<TimedInstruction<PhysicsInstruction>> {
|
fn next_strafe_instruction(&self) -> Option<TimedInstruction<PhysicsInstruction>> {
|
||||||
return Some(TimedInstruction{
|
return Some(TimedInstruction{
|
||||||
time:Time::from_nanos(self.style.strafe_tick_rate.rhs_div_int(self.style.strafe_tick_rate.mul_int(self.time.nanos())+1)),
|
time:Time::from_nanos(self.style.strafe_tick_rate.rhs_div_int(self.style.strafe_tick_rate.mul_int(self.time.nanos())+1)),
|
||||||
@ -718,43 +754,48 @@ impl PhysicsState {
|
|||||||
|
|
||||||
fn refresh_walk_target(&mut self){
|
fn refresh_walk_target(&mut self){
|
||||||
//calculate acceleration yada yada
|
//calculate acceleration yada yada
|
||||||
if self.grounded{
|
match &mut self.move_state{
|
||||||
let mut v=self.walk.target_velocity;
|
MoveState::Air=>(),
|
||||||
self.contact_constrain_velocity(&mut v);
|
MoveState::Walk(walk_state)=>{
|
||||||
let mut target_diff=v-self.body.velocity;
|
let mut v=walk_state.target_velocity;
|
||||||
//remove normal component
|
self.touching.constrain_velocity(&self.models,&mut v);
|
||||||
target_diff-=Planar64Vec3::Y*target_diff.y();
|
let mut target_diff=v-self.body.velocity;
|
||||||
if target_diff==Planar64Vec3::ZERO{
|
//remove normal component
|
||||||
let mut a=Planar64Vec3::ZERO;
|
target_diff-=Planar64Vec3::Y*target_diff.y();
|
||||||
self.contact_constrain_acceleration(&mut a);
|
if target_diff==Planar64Vec3::ZERO{
|
||||||
self.body.acceleration=a;
|
let mut a=Planar64Vec3::ZERO;
|
||||||
self.walk.state=WalkEnum::Reached;
|
self.touching.constrain_acceleration(&self.models,&mut a);
|
||||||
}else{
|
self.body.acceleration=a;
|
||||||
//normal friction acceleration is clippedAcceleration.dot(normal)*friction
|
walk_state.state=WalkEnum::Reached;
|
||||||
let accel=self.style.walk_accel.min(self.style.gravity.dot(Planar64Vec3::NEG_Y)*self.style.friction);
|
}else{
|
||||||
let time_delta=target_diff.length()/accel;
|
//normal friction acceleration is clippedAcceleration.dot(normal)*friction
|
||||||
let mut a=target_diff.with_length(accel);
|
let accel=self.style.walk_accel.min(self.style.gravity.dot(Planar64Vec3::NEG_Y)*self.style.friction);
|
||||||
self.contact_constrain_acceleration(&mut a);
|
let time_delta=target_diff.length()/accel;
|
||||||
self.body.acceleration=a;
|
let mut a=target_diff.with_length(accel);
|
||||||
self.walk.target_time=self.body.time+Time::from(time_delta);
|
self.touching.constrain_acceleration(&self.models,&mut a);
|
||||||
self.walk.state=WalkEnum::Transient;
|
self.body.acceleration=a;
|
||||||
}
|
walk_state.target_time=self.body.time+Time::from(time_delta);
|
||||||
}else{
|
walk_state.state=WalkEnum::Transient;
|
||||||
self.walk.state=WalkEnum::Reached;//there is no walk target while not grounded
|
}
|
||||||
|
},
|
||||||
|
MoveState::Water=>(),
|
||||||
|
MoveState::Ladder(walk_state)=>{
|
||||||
|
//
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn next_walk_instruction(&self) -> Option<TimedInstruction<PhysicsInstruction>> {
|
fn next_move_instruction(&self)->Option<TimedInstruction<PhysicsInstruction>>{
|
||||||
//check if you have a valid walk state and create an instruction
|
//check if you have a valid walk state and create an instruction
|
||||||
if self.grounded{
|
match &self.move_state{
|
||||||
match self.walk.state{
|
MoveState::Walk(walk_state)|MoveState::Ladder(walk_state)=>match &walk_state.state{
|
||||||
WalkEnum::Transient=>Some(TimedInstruction{
|
WalkEnum::Transient=>Some(TimedInstruction{
|
||||||
time:self.walk.target_time,
|
time:walk_state.target_time,
|
||||||
instruction:PhysicsInstruction::ReachWalkTargetVelocity
|
instruction:PhysicsInstruction::ReachWalkTargetVelocity
|
||||||
}),
|
}),
|
||||||
WalkEnum::Reached=>None,
|
WalkEnum::Reached=>None,
|
||||||
}
|
}
|
||||||
}else{
|
MoveState::Air=>self.next_strafe_instruction(),
|
||||||
return None;
|
MoveState::Water=>None,//TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn mesh(&self) -> TreyMesh {
|
fn mesh(&self) -> TreyMesh {
|
||||||
@ -1044,7 +1085,7 @@ impl crate::instruction::InstructionEmitter<PhysicsInstruction> for PhysicsState
|
|||||||
//JUST POLLING!!! NO MUTATION
|
//JUST POLLING!!! NO MUTATION
|
||||||
let mut collector = crate::instruction::InstructionCollector::new(time_limit);
|
let mut collector = crate::instruction::InstructionCollector::new(time_limit);
|
||||||
//check for collision stop instructions with curent contacts
|
//check for collision stop instructions with curent contacts
|
||||||
for (_,collision_data) in &self.contacts {
|
for (_,collision_data) in &self.touching.contacts {
|
||||||
collector.collect(self.predict_collision_end(self.time,time_limit,collision_data));
|
collector.collect(self.predict_collision_end(self.time,time_limit,collision_data));
|
||||||
}
|
}
|
||||||
// for collision_data in &self.intersects{
|
// for collision_data in &self.intersects{
|
||||||
@ -1056,17 +1097,11 @@ impl crate::instruction::InstructionEmitter<PhysicsInstruction> for PhysicsState
|
|||||||
aabb.grow(self.body.extrapolated_position(time_limit));
|
aabb.grow(self.body.extrapolated_position(time_limit));
|
||||||
aabb.inflate(self.style.hitbox_halfsize);
|
aabb.inflate(self.style.hitbox_halfsize);
|
||||||
self.bvh.the_tester(&aabb,&mut |id|{
|
self.bvh.the_tester(&aabb,&mut |id|{
|
||||||
if !(self.contacts.contains_key(&id)||self.intersects.contains_key(&id)){
|
if !(self.touching.contacts.contains_key(&id)||self.touching.intersects.contains_key(&id)){
|
||||||
collector.collect(self.predict_collision_start(self.time,time_limit,id));
|
collector.collect(self.predict_collision_start(self.time,time_limit,id));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if self.grounded {
|
collector.collect(self.next_move_instruction());
|
||||||
//walk maintenance
|
|
||||||
collector.collect(self.next_walk_instruction());
|
|
||||||
}else{
|
|
||||||
//check to see when the next strafe tick is
|
|
||||||
collector.collect(self.next_strafe_instruction());
|
|
||||||
}
|
|
||||||
collector.instruction()
|
collector.instruction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1099,13 +1134,13 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
None=>match &c.face {
|
None=>match &c.face {
|
||||||
TreyMeshFace::Top => {
|
TreyMeshFace::Top => {
|
||||||
//ground
|
//ground
|
||||||
self.grounded=true;
|
self.move_state=MoveState::Walk(WalkState::new())
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
//check ground
|
//check ground
|
||||||
self.contacts.insert(c.model,c);
|
self.touching.insert_contact(c.model,c);
|
||||||
match &general.teleport_behaviour{
|
match &general.teleport_behaviour{
|
||||||
Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
|
Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
|
||||||
if stage_element.force||self.game.stage_id<stage_element.stage_id{
|
if stage_element.force||self.game.stage_id<stage_element.stage_id{
|
||||||
@ -1121,11 +1156,9 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
if let Some(model)=self.models.get(spawn as usize){
|
if let Some(model)=self.models.get(spawn as usize){
|
||||||
self.body.position=model.transform.transform_point3(Planar64Vec3::Y)+Planar64Vec3::Y*(self.style.hitbox_halfsize.y()+Planar64::ONE/16);
|
self.body.position=model.transform.transform_point3(Planar64Vec3::Y)+Planar64Vec3::Y*(self.style.hitbox_halfsize.y()+Planar64::ONE/16);
|
||||||
//manual clear //for c in self.contacts{process_instruction(CollisionEnd(c))}
|
//manual clear //for c in self.contacts{process_instruction(CollisionEnd(c))}
|
||||||
self.contacts.clear();
|
self.touching.clear();
|
||||||
self.intersects.clear();
|
|
||||||
self.body.acceleration=self.style.gravity;
|
self.body.acceleration=self.style.gravity;
|
||||||
self.walk.state=WalkEnum::Reached;
|
self.move_state=MoveState::Air;//TODO: calculate contacts and determine the actual state
|
||||||
self.grounded=false;
|
|
||||||
}else{println!("bad1");}
|
}else{println!("bad1");}
|
||||||
}else{println!("bad2");}
|
}else{println!("bad2");}
|
||||||
}else{println!("bad3");}
|
}else{println!("bad3");}
|
||||||
@ -1140,23 +1173,23 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
}
|
}
|
||||||
//flatten v
|
//flatten v
|
||||||
let mut v=self.body.velocity;
|
let mut v=self.body.velocity;
|
||||||
self.contact_constrain_velocity(&mut v);
|
self.touching.constrain_velocity(&self.models,&mut v);
|
||||||
match &general.booster{
|
match &general.booster{
|
||||||
Some(booster)=>{
|
Some(booster)=>{
|
||||||
v+=booster.velocity;
|
v+=booster.velocity;
|
||||||
self.contact_constrain_velocity(&mut v);
|
self.touching.constrain_velocity(&self.models,&mut v);
|
||||||
},
|
},
|
||||||
None=>(),
|
None=>(),
|
||||||
}
|
}
|
||||||
self.body.velocity=v;
|
self.body.velocity=v;
|
||||||
if self.grounded&&self.style.get_control(StyleModifiers::CONTROL_JUMP,self.controls){
|
if self.style.get_control(StyleModifiers::CONTROL_JUMP,self.controls){
|
||||||
self.jump();
|
self.jump();
|
||||||
}
|
}
|
||||||
self.refresh_walk_target();
|
self.refresh_walk_target();
|
||||||
},
|
},
|
||||||
PhysicsCollisionAttributes::Intersect{intersecting,general}=>{
|
PhysicsCollisionAttributes::Intersect{intersecting,general}=>{
|
||||||
//I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop
|
//I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop
|
||||||
self.intersects.insert(c.model,c);
|
self.touching.insert_intersect(c.model,c);
|
||||||
match &general.teleport_behaviour{
|
match &general.teleport_behaviour{
|
||||||
Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
|
Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
|
||||||
if stage_element.force||self.game.stage_id<stage_element.stage_id{
|
if stage_element.force||self.game.stage_id<stage_element.stage_id{
|
||||||
@ -1172,11 +1205,9 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
if let Some(model)=self.models.get(spawn as usize){
|
if let Some(model)=self.models.get(spawn as usize){
|
||||||
self.body.position=model.transform.transform_point3(Planar64Vec3::Y)+Planar64Vec3::Y*(self.style.hitbox_halfsize.y()+Planar64::ONE/16);
|
self.body.position=model.transform.transform_point3(Planar64Vec3::Y)+Planar64Vec3::Y*(self.style.hitbox_halfsize.y()+Planar64::ONE/16);
|
||||||
//manual clear //for c in self.contacts{process_instruction(CollisionEnd(c))}
|
//manual clear //for c in self.contacts{process_instruction(CollisionEnd(c))}
|
||||||
self.contacts.clear();
|
self.touching.clear();
|
||||||
self.intersects.clear();
|
|
||||||
self.body.acceleration=self.style.gravity;
|
self.body.acceleration=self.style.gravity;
|
||||||
self.walk.state=WalkEnum::Reached;
|
self.move_state=MoveState::Air;//TODO: calculate contacts and determine the actual state
|
||||||
self.grounded=false;
|
|
||||||
}else{println!("bad1");}
|
}else{println!("bad1");}
|
||||||
}else{println!("bad2");}
|
}else{println!("bad2");}
|
||||||
}else{println!("bad3");}
|
}else{println!("bad3");}
|
||||||
@ -1196,21 +1227,21 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
let model=c.model(&self.models).unwrap();
|
let model=c.model(&self.models).unwrap();
|
||||||
match &model.attributes{
|
match &model.attributes{
|
||||||
PhysicsCollisionAttributes::Contact{contacting,general}=>{
|
PhysicsCollisionAttributes::Contact{contacting,general}=>{
|
||||||
self.contacts.remove(&c.model);//remove contact before calling contact_constrain_acceleration
|
self.touching.remove_contact(c.model);//remove contact before calling contact_constrain_acceleration
|
||||||
let mut a=self.style.gravity;
|
let mut a=self.style.gravity;
|
||||||
self.contact_constrain_acceleration(&mut a);
|
self.touching.constrain_acceleration(&self.models,&mut a);
|
||||||
self.body.acceleration=a;
|
self.body.acceleration=a;
|
||||||
//check ground
|
//check ground
|
||||||
match &c.face {
|
match &c.face {
|
||||||
TreyMeshFace::Top => {
|
TreyMeshFace::Top => {
|
||||||
self.grounded=false;
|
self.move_state=MoveState::Air;
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
self.refresh_walk_target();
|
self.refresh_walk_target();
|
||||||
},
|
},
|
||||||
PhysicsCollisionAttributes::Intersect{intersecting,general}=>{
|
PhysicsCollisionAttributes::Intersect{intersecting,general}=>{
|
||||||
self.intersects.remove(&c.model);
|
self.touching.remove_intersect(c.model);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1220,19 +1251,24 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
let d=self.body.velocity.dot(control_dir);
|
let d=self.body.velocity.dot(control_dir);
|
||||||
if d<self.style.mv {
|
if d<self.style.mv {
|
||||||
let mut v=self.body.velocity+control_dir*(self.style.mv-d);
|
let mut v=self.body.velocity+control_dir*(self.style.mv-d);
|
||||||
self.contact_constrain_velocity(&mut v);
|
self.touching.constrain_velocity(&self.models,&mut v);
|
||||||
self.body.velocity=v;
|
self.body.velocity=v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PhysicsInstruction::ReachWalkTargetVelocity => {
|
PhysicsInstruction::ReachWalkTargetVelocity => {
|
||||||
//precisely set velocity
|
match &mut self.move_state{
|
||||||
let mut a=Planar64Vec3::ZERO;
|
MoveState::Air|MoveState::Water=>(),
|
||||||
self.contact_constrain_acceleration(&mut a);
|
MoveState::Walk(walk_state)|MoveState::Ladder(walk_state)=>{
|
||||||
self.body.acceleration=a;
|
//precisely set velocity
|
||||||
let mut v=self.walk.target_velocity;
|
let mut a=self.style.gravity;
|
||||||
self.contact_constrain_velocity(&mut v);
|
self.touching.constrain_acceleration(&self.models,&mut a);
|
||||||
self.body.velocity=v;
|
self.body.acceleration=a;
|
||||||
self.walk.state=WalkEnum::Reached;
|
let mut v=walk_state.target_velocity;
|
||||||
|
self.touching.constrain_velocity(&self.models,&mut v);
|
||||||
|
self.body.velocity=v;
|
||||||
|
walk_state.state=WalkEnum::Reached;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
PhysicsInstruction::Input(input_instruction) => {
|
PhysicsInstruction::Input(input_instruction) => {
|
||||||
let mut refresh_walk_target=true;
|
let mut refresh_walk_target=true;
|
||||||
@ -1254,9 +1290,7 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
PhysicsInputInstruction::SetMoveDown(s) => self.set_control(StyleModifiers::CONTROL_MOVEDOWN,s),
|
PhysicsInputInstruction::SetMoveDown(s) => self.set_control(StyleModifiers::CONTROL_MOVEDOWN,s),
|
||||||
PhysicsInputInstruction::SetJump(s) => {
|
PhysicsInputInstruction::SetJump(s) => {
|
||||||
self.set_control(StyleModifiers::CONTROL_JUMP,s);
|
self.set_control(StyleModifiers::CONTROL_JUMP,s);
|
||||||
if self.grounded{
|
self.jump();
|
||||||
self.jump();
|
|
||||||
}
|
|
||||||
refresh_walk_target_velocity=false;
|
refresh_walk_target_velocity=false;
|
||||||
},
|
},
|
||||||
PhysicsInputInstruction::SetZoom(s) => {
|
PhysicsInputInstruction::SetZoom(s) => {
|
||||||
@ -1268,10 +1302,9 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
self.body.position=self.spawn_point;
|
self.body.position=self.spawn_point;
|
||||||
self.body.velocity=Planar64Vec3::ZERO;
|
self.body.velocity=Planar64Vec3::ZERO;
|
||||||
//manual clear //for c in self.contacts{process_instruction(CollisionEnd(c))}
|
//manual clear //for c in self.contacts{process_instruction(CollisionEnd(c))}
|
||||||
self.contacts.clear();
|
self.touching.clear();
|
||||||
self.body.acceleration=self.style.gravity;
|
self.body.acceleration=self.style.gravity;
|
||||||
self.walk.state=WalkEnum::Reached;
|
self.move_state=MoveState::Air;
|
||||||
self.grounded=false;
|
|
||||||
refresh_walk_target=false;
|
refresh_walk_target=false;
|
||||||
},
|
},
|
||||||
PhysicsInputInstruction::Idle => {refresh_walk_target=false;},//literally idle!
|
PhysicsInputInstruction::Idle => {refresh_walk_target=false;},//literally idle!
|
||||||
@ -1279,9 +1312,20 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
if refresh_walk_target{
|
if refresh_walk_target{
|
||||||
//calculate walk target velocity
|
//calculate walk target velocity
|
||||||
if refresh_walk_target_velocity{
|
if refresh_walk_target_velocity{
|
||||||
let camera_mat=self.camera.simulate_move_rotation_y(self.camera.mouse.lerp(&self.next_mouse,self.time).x);
|
match &mut self.move_state{
|
||||||
let control_dir=camera_mat*self.style.get_control_dir(self.controls);
|
MoveState::Walk(walk_state)=>{
|
||||||
self.walk.target_velocity=control_dir*self.style.walkspeed;
|
let camera_mat=self.camera.simulate_move_rotation_y(self.camera.mouse.lerp(&self.next_mouse,self.time).x);
|
||||||
|
let control_dir=camera_mat*self.style.get_control_dir(self.controls);
|
||||||
|
walk_state.target_velocity=control_dir*self.style.walkspeed;
|
||||||
|
},
|
||||||
|
MoveState::Ladder(walk_state)=>{
|
||||||
|
// let camera_mat=self.camera.simulate_move_rotation(self.camera.mouse.lerp(&self.next_mouse,self.time));
|
||||||
|
// let control_dir=camera_mat*self.style.get_control_dir(self.controls);
|
||||||
|
// walk_state.target_velocity=control_dir*self.style.walkspeed;
|
||||||
|
},
|
||||||
|
MoveState::Water=>(),
|
||||||
|
MoveState::Air=>(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.refresh_walk_target();
|
self.refresh_walk_target();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user