forked from StrafesNET/strafe-client
runtime attributes + implement model intersection (but not collision end)
This commit is contained in:
parent
fb2e2afeb9
commit
b8f13539db
135
src/body.rs
135
src/body.rs
@ -221,13 +221,13 @@ impl Camera {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct GameMechanicsState{
|
pub struct GameMechanicsState{
|
||||||
pub spawn_id:u32,
|
pub stage_id:u32,
|
||||||
//jump_counts:HashMap<u32,u32>,
|
//jump_counts:HashMap<u32,u32>,
|
||||||
}
|
}
|
||||||
impl std::default::Default for GameMechanicsState{
|
impl std::default::Default for GameMechanicsState{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self{
|
Self{
|
||||||
spawn_id:0,
|
stage_id:0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,7 +317,8 @@ pub struct PhysicsState{
|
|||||||
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::HashSet::<RelativeCollision>,
|
pub contacts:std::collections::HashMap::<u32,RelativeCollision>,
|
||||||
|
pub intersects:std::collections::HashMap::<u32,RelativeCollision>,
|
||||||
//pub intersections: Vec<ModelId>,
|
//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:Camera,
|
pub camera:Camera,
|
||||||
@ -459,6 +460,7 @@ pub struct ModelPhysics {
|
|||||||
//A model is a thing that has a hitbox. can be represented by a list of TreyMesh-es
|
//A model is a thing that has a hitbox. can be represented by a list of TreyMesh-es
|
||||||
//in this iteration, all it needs is extents.
|
//in this iteration, all it needs is extents.
|
||||||
mesh: TreyMesh,
|
mesh: TreyMesh,
|
||||||
|
transform:glam::Affine3A,
|
||||||
attributes:PhysicsCollisionAttributes,
|
attributes:PhysicsCollisionAttributes,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,6 +473,7 @@ impl ModelPhysics {
|
|||||||
Self{
|
Self{
|
||||||
mesh:aabb,
|
mesh:aabb,
|
||||||
attributes,
|
attributes,
|
||||||
|
transform:transform.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn from_model(model:&crate::model::IndexedModel,instance:&crate::model::ModelInstance) -> Option<Self> {
|
pub fn from_model(model:&crate::model::IndexedModel,instance:&crate::model::ModelInstance) -> Option<Self> {
|
||||||
@ -557,6 +560,8 @@ 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.intersects.clear();
|
||||||
}
|
}
|
||||||
pub fn get_mode(&self,mode_id:u32)->Option<&crate::model::ModeDescription>{
|
pub fn get_mode(&self,mode_id:u32)->Option<&crate::model::ModeDescription>{
|
||||||
if let Some(&mode)=self.mode_from_mode_id.get(&mode_id){
|
if let Some(&mode)=self.mode_from_mode_id.get(&mode_id){
|
||||||
@ -591,7 +596,7 @@ impl PhysicsState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn contact_constrain_velocity(&self,velocity:&mut glam::Vec3){
|
fn contact_constrain_velocity(&self,velocity:&mut glam::Vec3){
|
||||||
for contact in self.contacts.iter() {
|
for (_,contact) in &self.contacts {
|
||||||
let n=contact.normal(&self.models);
|
let n=contact.normal(&self.models);
|
||||||
let d=velocity.dot(n);
|
let d=velocity.dot(n);
|
||||||
if d<0f32{
|
if d<0f32{
|
||||||
@ -600,7 +605,7 @@ impl PhysicsState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn contact_constrain_acceleration(&self,acceleration:&mut glam::Vec3){
|
fn contact_constrain_acceleration(&self,acceleration:&mut glam::Vec3){
|
||||||
for contact in self.contacts.iter() {
|
for (_,contact) in &self.contacts {
|
||||||
let n=contact.normal(&self.models);
|
let n=contact.normal(&self.models);
|
||||||
let d=acceleration.dot(n);
|
let d=acceleration.dot(n);
|
||||||
if d<0f32{
|
if d<0f32{
|
||||||
@ -973,12 +978,19 @@ 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.iter() {
|
for (_,collision_data) in &self.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{
|
||||||
|
// collector.collect(self.predict_collision_end2(self.time,time_limit,collision_data));
|
||||||
|
// }
|
||||||
//check for collision start instructions (against every part in the game with no optimization!!)
|
//check for collision start instructions (against every part in the game with no optimization!!)
|
||||||
for i in 0..self.models.len() {
|
for i in 0..self.models.len() {
|
||||||
collector.collect(self.predict_collision_start(self.time,time_limit,i as u32));
|
let i=i as u32;
|
||||||
|
if self.contacts.contains_key(&i)||self.intersects.contains_key(&i){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
collector.collect(self.predict_collision_start(self.time,time_limit,i));
|
||||||
}
|
}
|
||||||
if self.grounded {
|
if self.grounded {
|
||||||
//walk maintenance
|
//walk maintenance
|
||||||
@ -1013,37 +1025,90 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
self.spawn_point=position;
|
self.spawn_point=position;
|
||||||
}
|
}
|
||||||
PhysicsInstruction::CollisionStart(c) => {
|
PhysicsInstruction::CollisionStart(c) => {
|
||||||
//check ground
|
let model=c.model(&self.models).unwrap();
|
||||||
match &c.face {
|
match &model.attributes{
|
||||||
AabbFace::Top => {
|
PhysicsCollisionAttributes::Contact{contacting,general}=>{
|
||||||
//ground
|
match &contacting.surf{
|
||||||
self.grounded=true;
|
Some(surf)=>println!("I'm surfing!"),
|
||||||
},
|
None=>match &c.face {
|
||||||
_ => (),
|
AabbFace::Top => {
|
||||||
}
|
//ground
|
||||||
self.contacts.insert(c);
|
self.grounded=true;
|
||||||
//flatten v
|
},
|
||||||
let mut v=self.body.velocity;
|
_ => (),
|
||||||
self.contact_constrain_velocity(&mut v);
|
},
|
||||||
self.body.velocity=v;
|
}
|
||||||
if self.grounded&&self.style.get_control(StyleModifiers::CONTROL_JUMP,self.controls){
|
match &general.booster{
|
||||||
self.jump();
|
Some(booster)=>self.body.velocity+=booster.velocity,
|
||||||
|
None=>(),
|
||||||
|
}
|
||||||
|
match &general.stage_element{
|
||||||
|
Some(stage_element)=>{
|
||||||
|
if stage_element.force||self.game.stage_id<stage_element.stage_id{
|
||||||
|
self.game.stage_id=stage_element.stage_id;
|
||||||
|
}
|
||||||
|
match stage_element.behaviour{
|
||||||
|
crate::model::StageElementBehaviour::SpawnAt=>(),
|
||||||
|
crate::model::StageElementBehaviour::Trigger
|
||||||
|
|crate::model::StageElementBehaviour::Teleport=>{
|
||||||
|
//TODO make good
|
||||||
|
if let Some(mode)=self.get_mode(stage_element.mode_id){
|
||||||
|
if let Some(&spawn)=mode.get_spawn_model_id(self.game.stage_id){
|
||||||
|
if let Some(model)=self.models.get(spawn as usize){
|
||||||
|
self.body.position=model.transform.transform_point3(glam::Vec3::Y)+glam::Vec3::Y*(self.style.hitbox_halfsize.y+0.1);
|
||||||
|
//manual clear //for c in self.contacts{process_instruction(CollisionEnd(c))}
|
||||||
|
self.contacts.clear();
|
||||||
|
self.intersects.clear();
|
||||||
|
self.body.acceleration=self.style.gravity;
|
||||||
|
self.walk.state=WalkEnum::Reached;
|
||||||
|
self.grounded=false;
|
||||||
|
}else{println!("bad1");}
|
||||||
|
}else{println!("bad2");}
|
||||||
|
}else{println!("bad3");}
|
||||||
|
},
|
||||||
|
crate::model::StageElementBehaviour::Platform=>(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None=>(),
|
||||||
|
}
|
||||||
|
//check ground
|
||||||
|
self.contacts.insert(c.model,c);
|
||||||
|
//flatten v
|
||||||
|
let mut v=self.body.velocity;
|
||||||
|
self.contact_constrain_velocity(&mut v);
|
||||||
|
self.body.velocity=v;
|
||||||
|
if self.grounded&&self.style.get_control(StyleModifiers::CONTROL_JUMP,self.controls){
|
||||||
|
self.jump();
|
||||||
|
}
|
||||||
|
self.refresh_walk_target();
|
||||||
|
},
|
||||||
|
PhysicsCollisionAttributes::Intersect{intersecting,general}=>{
|
||||||
|
//I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop
|
||||||
|
self.intersects.insert(c.model,c);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
self.refresh_walk_target();
|
|
||||||
},
|
},
|
||||||
PhysicsInstruction::CollisionEnd(c) => {
|
PhysicsInstruction::CollisionEnd(c) => {
|
||||||
self.contacts.remove(&c);//remove contact before calling contact_constrain_acceleration
|
let model=c.model(&self.models).unwrap();
|
||||||
let mut a=self.style.gravity;
|
match &model.attributes{
|
||||||
self.contact_constrain_acceleration(&mut a);
|
PhysicsCollisionAttributes::Contact{contacting,general}=>{
|
||||||
self.body.acceleration=a;
|
self.contacts.remove(&c.model);//remove contact before calling contact_constrain_acceleration
|
||||||
//check ground
|
let mut a=self.style.gravity;
|
||||||
match &c.face {
|
self.contact_constrain_acceleration(&mut a);
|
||||||
AabbFace::Top => {
|
self.body.acceleration=a;
|
||||||
self.grounded=false;
|
//check ground
|
||||||
},
|
match &c.face {
|
||||||
_ => (),
|
AabbFace::Top => {
|
||||||
}
|
self.grounded=false;
|
||||||
self.refresh_walk_target();
|
},
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
self.refresh_walk_target();
|
||||||
|
},
|
||||||
|
PhysicsCollisionAttributes::Intersect{intersecting,general}=>{
|
||||||
|
self.intersects.remove(&c.model);
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
PhysicsInstruction::StrafeTick => {
|
PhysicsInstruction::StrafeTick => {
|
||||||
let camera_mat=self.camera.simulate_move_rotation_y(self.mouse_interpolation.interpolated_position(self.time).x-self.mouse_interpolation.mouse0.x);
|
let camera_mat=self.camera.simulate_move_rotation_y(self.mouse_interpolation.interpolated_position(self.time).x-self.mouse_interpolation.mouse0.x);
|
||||||
|
@ -589,7 +589,8 @@ impl framework::Example for GlobalState {
|
|||||||
time: 0,
|
time: 0,
|
||||||
style:body::StyleModifiers::default(),
|
style:body::StyleModifiers::default(),
|
||||||
grounded: false,
|
grounded: false,
|
||||||
contacts: std::collections::HashSet::new(),
|
contacts: std::collections::HashMap::new(),
|
||||||
|
intersects: std::collections::HashMap::new(),
|
||||||
models: Vec::new(),
|
models: Vec::new(),
|
||||||
walk: body::WalkState::new(),
|
walk: body::WalkState::new(),
|
||||||
camera: body::Camera::from_offset(glam::vec3(0.0,4.5-2.5,0.0),(config.width as f32)/(config.height as f32)),
|
camera: body::Camera::from_offset(glam::vec3(0.0,4.5-2.5,0.0),(config.width as f32)/(config.height as f32)),
|
||||||
|
Loading…
Reference in New Issue
Block a user