code mess (SPLIT INTO MULTIPLE COMMITS)

This commit is contained in:
Quaternions 2023-10-04 01:25:03 -07:00
parent f2c71caae3
commit 51aac7b214
4 changed files with 213 additions and 98 deletions

View File

@ -45,20 +45,20 @@ trait MyHash{
fn hash(&self) -> u64; fn hash(&self) -> u64;
} }
impl MyHash for Body { impl MyHash for Body {
fn hash(&self) -> u64 { fn hash(&self) -> u64 {
let mut hasher=std::collections::hash_map::DefaultHasher::new(); let mut hasher=std::collections::hash_map::DefaultHasher::new();
for &el in self.position.as_ref().iter() { for &el in self.position.as_ref().iter() {
std::hash::Hasher::write(&mut hasher, el.to_ne_bytes().as_slice()); std::hash::Hasher::write(&mut hasher, el.to_ne_bytes().as_slice());
} }
for &el in self.velocity.as_ref().iter() { for &el in self.velocity.as_ref().iter() {
std::hash::Hasher::write(&mut hasher, el.to_ne_bytes().as_slice()); std::hash::Hasher::write(&mut hasher, el.to_ne_bytes().as_slice());
} }
for &el in self.acceleration.as_ref().iter() { for &el in self.acceleration.as_ref().iter() {
std::hash::Hasher::write(&mut hasher, el.to_ne_bytes().as_slice()); std::hash::Hasher::write(&mut hasher, el.to_ne_bytes().as_slice());
} }
std::hash::Hasher::write(&mut hasher, self.time.to_ne_bytes().as_slice()); std::hash::Hasher::write(&mut hasher, self.time.to_ne_bytes().as_slice());
return std::hash::Hasher::finish(&hasher);//hash check to see if walk target is valid return std::hash::Hasher::finish(&hasher);//hash check to see if walk target is valid
} }
} }
pub enum MoveRestriction { pub enum MoveRestriction {
@ -80,9 +80,9 @@ impl InputState {
} }
impl crate::instruction::InstructionEmitter<InputInstruction> for InputState{ impl crate::instruction::InstructionEmitter<InputInstruction> for InputState{
fn next_instruction(&self, time_limit:crate::body::TIME) -> Option<TimedInstruction<InputInstruction>> { fn next_instruction(&self, time_limit:crate::body::TIME) -> Option<TimedInstruction<InputInstruction>> {
//this is polled by PhysicsState for actions like Jump //this is polled by PhysicsState for actions like Jump
//no, it has to be the other way around. physics is run up until the jump instruction, and then the jump instruction is pushed. //no, it has to be the other way around. physics is run up until the jump instruction, and then the jump instruction is pushed.
self.queue.get(0) self.queue.get(0)
} }
} }
impl crate::instruction::InstructionConsumer<InputInstruction> for InputState{ impl crate::instruction::InstructionConsumer<InputInstruction> for InputState{
@ -171,12 +171,12 @@ pub struct Camera {
#[inline] #[inline]
fn mat3_from_rotation_y_f64(angle: f64) -> glam::Mat3 { fn mat3_from_rotation_y_f64(angle: f64) -> glam::Mat3 {
let (sina, cosa) = angle.sin_cos(); let (sina, cosa) = angle.sin_cos();
glam::Mat3::from_cols( glam::Mat3::from_cols(
glam::Vec3::new(cosa as f32, 0.0, -sina as f32), glam::Vec3::new(cosa as f32, 0.0, -sina as f32),
glam::Vec3::Y, glam::Vec3::Y,
glam::Vec3::new(sina as f32, 0.0, cosa as f32), glam::Vec3::new(sina as f32, 0.0, cosa as f32),
) )
} }
#[inline] #[inline]
fn perspective_rh(fov_x_slope: f32, fov_y_slope: f32, z_near: f32, z_far: f32) -> glam::Mat4 { fn perspective_rh(fov_x_slope: f32, fov_y_slope: f32, z_near: f32, z_far: f32) -> glam::Mat4 {
@ -192,11 +192,11 @@ fn perspective_rh(fov_x_slope: f32, fov_y_slope: f32, z_near: f32, z_far: f32) -
impl Camera { impl Camera {
pub fn from_offset(offset:glam::Vec3,aspect:f32) -> Self { pub fn from_offset(offset:glam::Vec3,aspect:f32) -> Self {
Self{ Self{
offset, offset,
angles: glam::DVec2::ZERO, angles: glam::DVec2::ZERO,
fov: glam::vec2(aspect,1.0), fov: glam::vec2(aspect,1.0),
sensitivity: glam::dvec2(1.0/6144.0,1.0/6144.0), sensitivity: glam::dvec2(1.0/16384.0,1.0/16384.0),
time: 0, time: 0,
} }
} }
fn simulate_move_angles(&self, delta: glam::IVec2) -> glam::DVec2 { fn simulate_move_angles(&self, delta: glam::IVec2) -> glam::DVec2 {
@ -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,
@ -329,6 +330,7 @@ pub struct PhysicsState{
pub models:Vec<ModelPhysics>, pub models:Vec<ModelPhysics>,
pub modes:Vec<crate::model::ModeDescription>, pub modes:Vec<crate::model::ModeDescription>,
pub mode_from_mode_id:std::collections::HashMap::<u32,usize>,
//the spawn point is where you spawn when you load into the map. //the spawn point is where you spawn when you load into the map.
//This is not the same as Reset which teleports you to Spawn0 //This is not the same as Reset which teleports you to Spawn0
pub spawn_point:glam::Vec3, pub spawn_point:glam::Vec3,
@ -458,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,
} }
@ -470,13 +473,14 @@ 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> {
match &instance.attributes{ match &instance.attributes{
crate::model::CollisionAttributes::Decoration=>None,
crate::model::CollisionAttributes::Contact{contacting,general}=>Some(ModelPhysics::from_model_transform_attributes(model,&instance.transform,PhysicsCollisionAttributes::Contact{contacting:contacting.clone(),general:general.clone()})), crate::model::CollisionAttributes::Contact{contacting,general}=>Some(ModelPhysics::from_model_transform_attributes(model,&instance.transform,PhysicsCollisionAttributes::Contact{contacting:contacting.clone(),general:general.clone()})),
crate::model::CollisionAttributes::Intersect{intersecting,general}=>None,//Some(ModelPhysics::from_model_transform_attributes(model,&instance.transform,PhysicsCollisionAttributes::Intersecting{intersecting,general})), crate::model::CollisionAttributes::Intersect{intersecting,general}=>Some(ModelPhysics::from_model_transform_attributes(model,&instance.transform,PhysicsCollisionAttributes::Intersect{intersecting:intersecting.clone(),general:general.clone()})),
crate::model::CollisionAttributes::Decoration=>None,
} }
} }
pub fn unit_vertices(&self) -> [glam::Vec3;8] { pub fn unit_vertices(&self) -> [glam::Vec3;8] {
@ -556,6 +560,15 @@ 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>{
if let Some(&mode)=self.mode_from_mode_id.get(&mode_id){
self.modes.get(mode)
}else{
None
}
} }
//tickless gaming //tickless gaming
pub fn run(&mut self, time_limit:TIME){ pub fn run(&mut self, time_limit:TIME){
@ -583,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{
@ -592,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{
@ -965,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
@ -986,56 +1006,109 @@ impl crate::instruction::InstructionEmitter<PhysicsInstruction> for PhysicsState
impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState { impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
fn process_instruction(&mut self, ins:TimedInstruction<PhysicsInstruction>) { fn process_instruction(&mut self, ins:TimedInstruction<PhysicsInstruction>) {
match &ins.instruction { match &ins.instruction {
PhysicsInstruction::StrafeTick => (), PhysicsInstruction::StrafeTick => (),
PhysicsInstruction::Input(InputInstruction::MoveMouse(_)) => (), PhysicsInstruction::Input(InputInstruction::MoveMouse(_)) => (),
_=>println!("{:?}",ins), _=>println!("{:?}",ins),
} }
//selectively update body //selectively update body
match &ins.instruction { match &ins.instruction {
PhysicsInstruction::Input(InputInstruction::MoveMouse(_)) => (),//dodge time for mouse movement PhysicsInstruction::Input(InputInstruction::MoveMouse(_)) => (),//dodge time for mouse movement
PhysicsInstruction::Input(_) PhysicsInstruction::Input(_)
|PhysicsInstruction::SetSpawnPosition(_) |PhysicsInstruction::SetSpawnPosition(_)
|PhysicsInstruction::ReachWalkTargetVelocity |PhysicsInstruction::ReachWalkTargetVelocity
|PhysicsInstruction::CollisionStart(_) |PhysicsInstruction::CollisionStart(_)
|PhysicsInstruction::CollisionEnd(_) |PhysicsInstruction::CollisionEnd(_)
|PhysicsInstruction::StrafeTick => self.advance_time(ins.time), |PhysicsInstruction::StrafeTick => self.advance_time(ins.time),
} }
match ins.instruction { match ins.instruction {
PhysicsInstruction::SetSpawnPosition(position)=>{ PhysicsInstruction::SetSpawnPosition(position)=>{
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);

View File

@ -30,7 +30,7 @@ fn get_texture_refs(dom:&rbx_dom_weak::WeakDom) -> Vec<rbx_dom_weak::types::Ref>
//next class //next class
objects objects
} }
fn get_attributes(name:&str,can_collide:bool,velocity:glam::Vec3)->crate::model::CollisionAttributes{ fn get_attributes(name:&str,can_collide:bool,velocity:glam::Vec3,force_intersecting:bool)->crate::model::CollisionAttributes{
let mut general=crate::model::GameMechanicAttributes::default(); let mut general=crate::model::GameMechanicAttributes::default();
let mut intersecting=crate::model::IntersectingAttributes::default(); let mut intersecting=crate::model::IntersectingAttributes::default();
let mut contacting=crate::model::ContactingAttributes::default(); let mut contacting=crate::model::ContactingAttributes::default();
@ -46,7 +46,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:glam::Vec3)->crate::model:
behaviour:crate::model::StageElementBehaviour::Platform, behaviour:crate::model::StageElementBehaviour::Platform,
}), }),
other=>{ other=>{
if let Some(captures)=lazy_regex::regex!(r"^(Force)?(SpawnAt|Trigger|Teleport|Platform)(\d+)$") if let Some(captures)=lazy_regex::regex!(r"^(Force)?(Spawn|SpawnAt|Trigger|Teleport|Platform)(\d+)$")
.captures(other){ .captures(other){
general.stage_element=Some(crate::model::GameMechanicStageElement{ general.stage_element=Some(crate::model::GameMechanicStageElement{
mode_id:0, mode_id:0,
@ -56,7 +56,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:glam::Vec3)->crate::model:
None=>false, None=>false,
}, },
behaviour:match &captures[2]{ behaviour:match &captures[2]{
"SpawnAt"=>crate::model::StageElementBehaviour::SpawnAt, "Spawn"|"SpawnAt"=>crate::model::StageElementBehaviour::SpawnAt,
"Trigger"=>crate::model::StageElementBehaviour::Trigger, "Trigger"=>crate::model::StageElementBehaviour::Trigger,
"Teleport"=>crate::model::StageElementBehaviour::Teleport, "Teleport"=>crate::model::StageElementBehaviour::Teleport,
"Platform"=>crate::model::StageElementBehaviour::Platform, "Platform"=>crate::model::StageElementBehaviour::Platform,
@ -89,9 +89,21 @@ fn get_attributes(name:&str,can_collide:bool,velocity:glam::Vec3)->crate::model:
//WormholeIn# //WormholeIn#
} }
} }
return crate::model::CollisionAttributes::Contact{contacting,general}; crate::model::CollisionAttributes::Contact{contacting,general}
},
false=>if force_intersecting
||general.jump_limit.is_some()
||general.booster.is_some()
||general.zone.is_some()
||general.stage_element.is_some()
||general.wormhole.is_some()
||intersecting.water.is_some()
||intersecting.accelerator.is_some()
{
crate::model::CollisionAttributes::Intersect{intersecting,general}
}else{
crate::model::CollisionAttributes::Decoration
}, },
false=>return crate::model::CollisionAttributes::Decoration,
} }
} }
@ -219,6 +231,7 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
); );
//push TempIndexedAttributes //push TempIndexedAttributes
let mut force_intersecting=false;
let mut temp_indexing_attributes=Vec::new(); let mut temp_indexing_attributes=Vec::new();
if let Some(attr)=match &object.name[..]{ if let Some(attr)=match &object.name[..]{
"MapStart"=>{ "MapStart"=>{
@ -227,11 +240,11 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
}, },
"UnorderedCheckpoint"=>Some(crate::model::TempIndexedAttributes::UnorderedCheckpoint{mode_id:0}), "UnorderedCheckpoint"=>Some(crate::model::TempIndexedAttributes::UnorderedCheckpoint{mode_id:0}),
other=>{ other=>{
let regman=lazy_regex::regex!(r"^(BonusStart|Spawn|OrderedCheckpoint)(\d+)$"); let regman=lazy_regex::regex!(r"^(BonusStart|Spawn|ForceSpawn|OrderedCheckpoint)(\d+)$");
if let Some(captures) = regman.captures(other) { if let Some(captures) = regman.captures(other) {
match &captures[1]{ match &captures[1]{
"BonusStart"=>Some(crate::model::TempIndexedAttributes::Start{mode_id:captures[2].parse::<u32>().unwrap()}), "BonusStart"=>Some(crate::model::TempIndexedAttributes::Start{mode_id:captures[2].parse::<u32>().unwrap()}),
"Spawn"=>Some(crate::model::TempIndexedAttributes::Spawn{mode_id:0,stage_id:captures[2].parse::<u32>().unwrap()}), "Spawn"|"ForceSpawn"=>Some(crate::model::TempIndexedAttributes::Spawn{mode_id:0,stage_id:captures[2].parse::<u32>().unwrap()}),
"OrderedCheckpoint"=>Some(crate::model::TempIndexedAttributes::OrderedCheckpoint{mode_id:0,checkpoint_id:captures[2].parse::<u32>().unwrap()}), "OrderedCheckpoint"=>Some(crate::model::TempIndexedAttributes::OrderedCheckpoint{mode_id:0,checkpoint_id:captures[2].parse::<u32>().unwrap()}),
_=>None, _=>None,
} }
@ -240,6 +253,7 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
} }
} }
}{ }{
force_intersecting=true;
temp_indexing_attributes.push(attr); temp_indexing_attributes.push(attr);
} }
@ -354,17 +368,17 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
primitives::Primitives::Cylinder=>RobloxBasePartDescription::Cylinder, primitives::Primitives::Cylinder=>RobloxBasePartDescription::Cylinder,
//use front face texture first and use top face texture as a fallback //use front face texture first and use top face texture as a fallback
primitives::Primitives::Wedge=>RobloxBasePartDescription::Wedge([ primitives::Primitives::Wedge=>RobloxBasePartDescription::Wedge([
f0,//Wedge::Right f0,//Cube::Right->Wedge::Right
if f5.is_some(){f5}else{f1},//Wedge::TopFront if f5.is_some(){f5}else{f1},//Cube::Front|Cube::Top->Wedge::TopFront
f2,//Wedge::Back f2,//Cube::Back->Wedge::Back
f3,//Wedge::Left f3,//Cube::Left->Wedge::Left
f4,//Wedge::Bottom f4,//Cube::Bottom->Wedge::Bottom
]), ]),
primitives::Primitives::CornerWedge=>RobloxBasePartDescription::CornerWedge([ primitives::Primitives::CornerWedge=>RobloxBasePartDescription::CornerWedge([
f0,//CornerWedge::Right f0,//Cube::Right->CornerWedge::Right
f1,//CornerWedge::Top f1,//Cube::Top->CornerWedge::Top
f4,//CornerWedge::Bottom f4,//Cube::Bottom->CornerWedge::Bottom
f5,//CornerWedge::Front f5,//Cube::Front->CornerWedge::Front
]), ]),
}; };
//make new model if unit cube has not been created before //make new model if unit cube has not been created before
@ -440,7 +454,7 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
indexed_models[model_id].instances.push(crate::model::ModelInstance { indexed_models[model_id].instances.push(crate::model::ModelInstance {
transform:model_transform, transform:model_transform,
color:glam::vec4(color3.r as f32/255f32, color3.g as f32/255f32, color3.b as f32/255f32, 1.0-*transparency), color:glam::vec4(color3.r as f32/255f32, color3.g as f32/255f32, color3.b as f32/255f32, 1.0-*transparency),
attributes:get_attributes(&object.name,*can_collide,glam::vec3(velocity.x,velocity.y,velocity.z)), attributes:get_attributes(&object.name,*can_collide,glam::vec3(velocity.x,velocity.y,velocity.z),force_intersecting),
temp_indexing:temp_indexing_attributes, temp_indexing:temp_indexing_attributes,
}); });
} }

View File

@ -104,8 +104,8 @@ impl GlobalState{
for model_instance in &model.instances{ for model_instance in &model.instances{
if let Some(model_physics)=body::ModelPhysics::from_model(model,model_instance){ if let Some(model_physics)=body::ModelPhysics::from_model(model,model_instance){
let model_id=self.physics.models.len() as u32; let model_id=self.physics.models.len() as u32;
//snoop it before it gets stolen self.physics.models.push(model_physics);
for attr in model_instance.temp_indexing.iter(){ for attr in &model_instance.temp_indexing{
match attr{ match attr{
model::TempIndexedAttributes::Start{mode_id}=>starts.push((*mode_id,model_id)), model::TempIndexedAttributes::Start{mode_id}=>starts.push((*mode_id,model_id)),
model::TempIndexedAttributes::Spawn{mode_id,stage_id}=>spawns.push((*mode_id,model_id,*stage_id)), model::TempIndexedAttributes::Spawn{mode_id,stage_id}=>spawns.push((*mode_id,model_id,*stage_id)),
@ -113,8 +113,6 @@ impl GlobalState{
model::TempIndexedAttributes::UnorderedCheckpoint{mode_id}=>unordered_checkpoints.push((*mode_id,model_id)), model::TempIndexedAttributes::UnorderedCheckpoint{mode_id}=>unordered_checkpoints.push((*mode_id,model_id)),
} }
} }
//steal it
self.physics.models.push(model_physics);
} }
} }
} }
@ -147,14 +145,22 @@ impl GlobalState{
} }
} }
} }
let num_modes=self.physics.modes.len();
for (mode_id,mode) in eshmep{
self.physics.mode_from_mode_id.insert(mode_id,num_modes+mode);
}
self.physics.modes.append(&mut modedatas.into_iter().map(|mut tup|{ self.physics.modes.append(&mut modedatas.into_iter().map(|mut tup|{
tup.1.sort_by_key(|tup|tup.0); tup.1.sort_by_key(|tup|tup.0);
tup.2.sort_by_key(|tup|tup.0); tup.2.sort_by_key(|tup|tup.0);
let mut eshmep1=std::collections::HashMap::new();
let mut eshmep2=std::collections::HashMap::new();
model::ModeDescription{ model::ModeDescription{
start:tup.0, start:tup.0,
spawns:tup.1.into_iter().map(|tup|tup.1).collect(), spawns:tup.1.into_iter().enumerate().map(|(i,tup)|{eshmep1.insert(tup.0,i);tup.1}).collect(),
ordered_checkpoints:tup.2.into_iter().map(|tup|tup.1).collect(), ordered_checkpoints:tup.2.into_iter().enumerate().map(|(i,tup)|{eshmep2.insert(tup.0,i);tup.1}).collect(),
unordered_checkpoints:tup.3, unordered_checkpoints:tup.3,
spawn_from_stage_id:eshmep1,
ordered_checkpoint_from_checkpoint_id:eshmep2,
} }
}).collect()); }).collect());
println!("Physics Objects: {}",self.physics.models.len()); println!("Physics Objects: {}",self.physics.models.len());
@ -228,7 +234,7 @@ impl GlobalState{
//the models received here are supposed to be tightly packed, i.e. no code needs to check if two models are using the same groups. //the models received here are supposed to be tightly packed, i.e. no code needs to check if two models are using the same groups.
let indexed_models_len=indexed_models.models.len(); let indexed_models_len=indexed_models.models.len();
let mut unique_texture_models=Vec::with_capacity(indexed_models_len); let mut unique_texture_models=Vec::with_capacity(indexed_models_len);
for mut model in indexed_models.models.into_iter(){ for model in indexed_models.models.into_iter(){
//convert ModelInstance into ModelGraphicsInstance //convert ModelInstance into ModelGraphicsInstance
let instances:Vec<ModelGraphicsInstance>=model.instances.into_iter().filter_map(|instance|{ let instances:Vec<ModelGraphicsInstance>=model.instances.into_iter().filter_map(|instance|{
if instance.color.w==0.0{ if instance.color.w==0.0{
@ -581,7 +587,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)),
@ -590,6 +597,7 @@ impl framework::Example for GlobalState {
world:body::WorldState{}, world:body::WorldState{},
game:body::GameMechanicsState::default(), game:body::GameMechanicsState::default(),
modes:Vec::new(), modes:Vec::new(),
mode_from_mode_id:std::collections::HashMap::new(),
}; };
//load textures //load textures
@ -904,6 +912,7 @@ impl framework::Example for GlobalState {
//if generate_indexed_models succeeds, clear the previous ones //if generate_indexed_models succeeds, clear the previous ones
self.physics.clear(); self.physics.clear();
self.graphics.clear(); self.graphics.clear();
self.physics.game.stage_id=0;
self.generate_model_physics(&indexed_model_instances); self.generate_model_physics(&indexed_model_instances);
self.generate_model_graphics(device,queue,indexed_model_instances); self.generate_model_graphics(device,queue,indexed_model_instances);
//manual reset //manual reset

View File

@ -85,7 +85,26 @@ pub struct ModeDescription{
pub spawns:Vec<u32>,//spawns[spawn_id]=model_id pub spawns:Vec<u32>,//spawns[spawn_id]=model_id
pub ordered_checkpoints:Vec<u32>,//ordered_checkpoints[checkpoint_id]=model_id pub ordered_checkpoints:Vec<u32>,//ordered_checkpoints[checkpoint_id]=model_id
pub unordered_checkpoints:Vec<u32>,//unordered_checkpoints[checkpoint_id]=model_id pub unordered_checkpoints:Vec<u32>,//unordered_checkpoints[checkpoint_id]=model_id
pub spawn_from_stage_id:std::collections::HashMap::<u32,usize>,
pub ordered_checkpoint_from_checkpoint_id:std::collections::HashMap::<u32,usize>,
} }
impl ModeDescription{
pub fn get_spawn_model_id(&self,stage_id:u32)->Option<&u32>{
if let Some(&spawn)=self.spawn_from_stage_id.get(&stage_id){
self.spawns.get(spawn)
}else{
None
}
}
pub fn get_ordered_checkpoint_model_id(&self,checkpoint_id:u32)->Option<&u32>{
if let Some(&checkpoint)=self.ordered_checkpoint_from_checkpoint_id.get(&checkpoint_id){
self.ordered_checkpoints.get(checkpoint)
}else{
None
}
}
}
#[derive(Debug)]
pub enum TempIndexedAttributes{ pub enum TempIndexedAttributes{
Start{ Start{
mode_id:u32, mode_id:u32,