Compare commits
58 Commits
deduplicat
...
integer-un
| Author | SHA1 | Date | |
|---|---|---|---|
| 22fa3ee81b | |||
| 3a8655c343 | |||
| 691c3e0482 | |||
| 1dfc566453 | |||
| 762f10fb01 | |||
| 8fba543684 | |||
| 8c90eb1d94 | |||
| b9e200e070 | |||
| e0e55c6883 | |||
| 0195511e49 | |||
| 7b09b3333b | |||
| cf202f52f0 | |||
| 35e8856e0f | |||
| 1271797a66 | |||
| 6bb9db739c | |||
| 9152237f2c | |||
| 282329fb33 | |||
| c88451c0f0 | |||
| 5f1d732b59 | |||
| d33b830338 | |||
| 80b1d25a13 | |||
| bf6f37fa00 | |||
| fa8ea26ddc | |||
| f5d6280e0a | |||
| 4e98e9a577 | |||
| 8fea9e0025 | |||
| ac2f1d3eac | |||
| bcab0d92fd | |||
| 36a5298b6d | |||
| cea85a099d | |||
| 9cc1674624 | |||
| 7d33f69a47 | |||
| 9cb42009cb | |||
| bcd421c4dd | |||
| 4d62042549 | |||
| fcf4d05baa | |||
| 2f33a28c95 | |||
| d939fbff94 | |||
| 9ca2f0a194 | |||
| 4bbd11dbb6 | |||
| 10a293e789 | |||
| 01b5769dc0 | |||
| 7f7b0d92e6 | |||
| 3b7a1d5dff | |||
| 7309949dd0 | |||
| 43a0eef5d1 | |||
| 76cd82967a | |||
| 69712847e3 | |||
| a8f82a14a9 | |||
| 101c92cba4 | |||
| 54ec21c490 | |||
| f16bc043c4 | |||
| 4616fd7b3b | |||
| b6b63b4c85 | |||
| c21c587edc | |||
| 9a12265881 | |||
| 3ff73ed0bc | |||
| 57386334af |
@@ -421,17 +421,14 @@ impl Planar64{
|
|||||||
pub const fn get(&self)->i64{
|
pub const fn get(&self)->i64{
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
pub fn sqrt(&self)->Self{
|
|
||||||
Planar64(unsafe{(((self.0 as i128)<<32) as f64).sqrt().to_int_unchecked()})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const PLANAR64_ONE_FLOAT32:f32=(1u64<<32) as f32;
|
const PLANAR64_FLOAT32_ONE:f32=(1u64<<32) as f32;
|
||||||
const PLANAR64_CONVERT_TO_FLOAT32:f32=1.0/PLANAR64_ONE_FLOAT32;
|
const PLANAR64_FLOAT32_MUL:f32=1.0/PLANAR64_FLOAT32_ONE;
|
||||||
const PLANAR64_ONE_FLOAT64:f64=(1u64<<32) as f64;
|
const PLANAR64_FLOAT64_ONE:f64=(1u64<<32) as f64;
|
||||||
impl Into<f32> for Planar64{
|
impl Into<f32> for Planar64{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into(self)->f32{
|
fn into(self)->f32{
|
||||||
self.0 as f32*PLANAR64_CONVERT_TO_FLOAT32
|
self.0 as f32*PLANAR64_FLOAT32_MUL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<Ratio64> for Planar64{
|
impl From<Ratio64> for Planar64{
|
||||||
@@ -643,7 +640,7 @@ impl Into<glam::Vec3> for Planar64Vec3{
|
|||||||
self.0.x as f32,
|
self.0.x as f32,
|
||||||
self.0.y as f32,
|
self.0.y as f32,
|
||||||
self.0.z as f32,
|
self.0.z as f32,
|
||||||
)*PLANAR64_CONVERT_TO_FLOAT32
|
)*PLANAR64_FLOAT32_MUL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl TryFrom<[f32;3]> for Planar64Vec3{
|
impl TryFrom<[f32;3]> for Planar64Vec3{
|
||||||
@@ -811,7 +808,7 @@ impl Planar64Mat3{
|
|||||||
pub fn from_rotation_y(angle:Angle32)->Self{
|
pub fn from_rotation_y(angle:Angle32)->Self{
|
||||||
let theta=angle.0 as f64*ANGLE32_TO_FLOAT64_RADIANS;
|
let theta=angle.0 as f64*ANGLE32_TO_FLOAT64_RADIANS;
|
||||||
let (s,c)=theta.sin_cos();
|
let (s,c)=theta.sin_cos();
|
||||||
let (c,s)=(c*PLANAR64_ONE_FLOAT64,s*PLANAR64_ONE_FLOAT64);
|
let (c,s)=(c*PLANAR64_FLOAT64_ONE,s*PLANAR64_FLOAT64_ONE);
|
||||||
//TODO: fix this rounding towards 0
|
//TODO: fix this rounding towards 0
|
||||||
let (c,s):(i64,i64)=(unsafe{c.to_int_unchecked()},unsafe{s.to_int_unchecked()});
|
let (c,s):(i64,i64)=(unsafe{c.to_int_unchecked()},unsafe{s.to_int_unchecked()});
|
||||||
Self::from_cols(
|
Self::from_cols(
|
||||||
@@ -892,8 +889,8 @@ impl Into<glam::Mat4> for Planar64Affine3{
|
|||||||
self.matrix3.x_axis.0.x as f32,self.matrix3.x_axis.0.y as f32,self.matrix3.x_axis.0.z as f32,0.0,
|
self.matrix3.x_axis.0.x as f32,self.matrix3.x_axis.0.y as f32,self.matrix3.x_axis.0.z as f32,0.0,
|
||||||
self.matrix3.y_axis.0.x as f32,self.matrix3.y_axis.0.y as f32,self.matrix3.y_axis.0.z as f32,0.0,
|
self.matrix3.y_axis.0.x as f32,self.matrix3.y_axis.0.y as f32,self.matrix3.y_axis.0.z as f32,0.0,
|
||||||
self.matrix3.z_axis.0.x as f32,self.matrix3.z_axis.0.y as f32,self.matrix3.z_axis.0.z as f32,0.0,
|
self.matrix3.z_axis.0.x as f32,self.matrix3.z_axis.0.y as f32,self.matrix3.z_axis.0.z as f32,0.0,
|
||||||
self.translation.0.x as f32,self.translation.0.y as f32,self.translation.0.z as f32,PLANAR64_ONE_FLOAT32
|
self.translation.0.x as f32,self.translation.0.y as f32,self.translation.0.z as f32,PLANAR64_FLOAT32_ONE
|
||||||
])*PLANAR64_CONVERT_TO_FLOAT32
|
])*PLANAR64_FLOAT32_MUL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl TryFrom<glam::Affine3A> for Planar64Affine3{
|
impl TryFrom<glam::Affine3A> for Planar64Affine3{
|
||||||
@@ -914,12 +911,4 @@ impl std::fmt::Display for Planar64Affine3{
|
|||||||
Into::<f32>::into(self.matrix3.z_axis.x()),Into::<f32>::into(self.matrix3.z_axis.y()),Into::<f32>::into(self.matrix3.z_axis.z()),
|
Into::<f32>::into(self.matrix3.z_axis.x()),Into::<f32>::into(self.matrix3.z_axis.y()),Into::<f32>::into(self.matrix3.z_axis.z()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_sqrt(){
|
|
||||||
let r=Planar64::int(400);
|
|
||||||
println!("r{}",r.get());
|
|
||||||
let s=r.sqrt();
|
|
||||||
println!("s{}",s.get());
|
|
||||||
}
|
}
|
||||||
@@ -50,20 +50,20 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse
|
|||||||
let mut contacting=crate::model::ContactingAttributes::default();
|
let mut contacting=crate::model::ContactingAttributes::default();
|
||||||
let mut force_can_collide=can_collide;
|
let mut force_can_collide=can_collide;
|
||||||
match name{
|
match name{
|
||||||
"Water"=>intersecting.water=Some(crate::model::IntersectingWater{density:Planar64::ONE,viscosity:Planar64::ONE/10,current:velocity}),
|
//"Water"=>intersecting.water=Some(crate::model::IntersectingWater{density:1.0,drag:1.0}),
|
||||||
"Accelerator"=>{force_can_collide=false;intersecting.accelerator=Some(crate::model::IntersectingAccelerator{acceleration:velocity})},
|
"Accelerator"=>{force_can_collide=false;intersecting.accelerator=Some(crate::model::IntersectingAccelerator{acceleration:velocity})},
|
||||||
"MapFinish"=>{force_can_collide=false;general.zone=Some(crate::model::GameMechanicZone{mode_id:0,behaviour:crate::model::ZoneBehaviour::Finish})},
|
"MapFinish"=>{force_can_collide=false;general.zone=Some(crate::model::GameMechanicZone{mode_id:0,behaviour:crate::model::ZoneBehaviour::Finish})},
|
||||||
"MapAnticheat"=>{force_can_collide=false;general.zone=Some(crate::model::GameMechanicZone{mode_id:0,behaviour:crate::model::ZoneBehaviour::Anitcheat})},
|
"MapAnticheat"=>{force_can_collide=false;general.zone=Some(crate::model::GameMechanicZone{mode_id:0,behaviour:crate::model::ZoneBehaviour::Anitcheat})},
|
||||||
"Platform"=>general.teleport_behaviour=Some(crate::model::TeleportBehaviour::StageElement(crate::model::GameMechanicStageElement{
|
"Platform"=>general.stage_element=Some(crate::model::GameMechanicStageElement{
|
||||||
mode_id:0,
|
mode_id:0,
|
||||||
stage_id:0,
|
stage_id:0,
|
||||||
force:false,
|
force:false,
|
||||||
behaviour:crate::model::StageElementBehaviour::Platform,
|
behaviour:crate::model::StageElementBehaviour::Platform,
|
||||||
})),
|
}),
|
||||||
other=>{
|
other=>{
|
||||||
if let Some(captures)=lazy_regex::regex!(r"^(Force)?(Spawn|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.teleport_behaviour=Some(crate::model::TeleportBehaviour::StageElement(crate::model::GameMechanicStageElement{
|
general.stage_element=Some(crate::model::GameMechanicStageElement{
|
||||||
mode_id:0,
|
mode_id:0,
|
||||||
stage_id:captures[3].parse::<u32>().unwrap(),
|
stage_id:captures[3].parse::<u32>().unwrap(),
|
||||||
force:match captures.get(1){
|
force:match captures.get(1){
|
||||||
@@ -77,7 +77,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse
|
|||||||
"Platform"=>crate::model::StageElementBehaviour::Platform,
|
"Platform"=>crate::model::StageElementBehaviour::Platform,
|
||||||
_=>panic!("regex1[2] messed up bad"),
|
_=>panic!("regex1[2] messed up bad"),
|
||||||
}
|
}
|
||||||
}));
|
})
|
||||||
}else if let Some(captures)=lazy_regex::regex!(r"^Bonus(Finish|Anticheat)(\d+)$")
|
}else if let Some(captures)=lazy_regex::regex!(r"^Bonus(Finish|Anticheat)(\d+)$")
|
||||||
.captures(other){
|
.captures(other){
|
||||||
force_can_collide=false;
|
force_can_collide=false;
|
||||||
@@ -96,18 +96,13 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse
|
|||||||
match force_can_collide{
|
match force_can_collide{
|
||||||
true=>{
|
true=>{
|
||||||
match name{
|
match name{
|
||||||
"Bounce"=>contacting.elasticity=Some(u32::MAX),
|
//"Bounce"=>(),
|
||||||
"Surf"=>contacting.surf=Some(crate::model::ContactingSurf{}),
|
"Surf"=>contacting.surf=Some(crate::model::ContactingSurf{}),
|
||||||
"Ladder"=>contacting.ladder=Some(crate::model::ContactingLadder{sticky:true}),
|
"Ladder"=>contacting.ladder=Some(crate::model::ContactingLadder{sticky:true}),
|
||||||
other=>{
|
other=>{
|
||||||
if let Some(captures)=lazy_regex::regex!(r"^(Jump|WormholeIn)(\d+)$")
|
//REGEX!!!!
|
||||||
.captures(other){
|
//Jump#
|
||||||
match &captures[1]{
|
//WormholeIn#
|
||||||
"Jump"=>general.jump_limit=Some(crate::model::GameMechanicJumpLimit{count:captures[2].parse::<u32>().unwrap()}),
|
|
||||||
"WormholeIn"=>general.teleport_behaviour=Some(crate::model::TeleportBehaviour::Wormhole(crate::model::GameMechanicWormhole{destination_model_id:captures[2].parse::<u32>().unwrap()})),
|
|
||||||
_=>panic!("regex3[1] messed up bad"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::model::CollisionAttributes::Contact{contacting,general}
|
crate::model::CollisionAttributes::Contact{contacting,general}
|
||||||
@@ -116,7 +111,8 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse
|
|||||||
||general.jump_limit.is_some()
|
||general.jump_limit.is_some()
|
||||||
||general.booster.is_some()
|
||general.booster.is_some()
|
||||||
||general.zone.is_some()
|
||general.zone.is_some()
|
||||||
||general.teleport_behaviour.is_some()
|
||general.stage_element.is_some()
|
||||||
|
||general.wormhole.is_some()
|
||||||
||intersecting.water.is_some()
|
||intersecting.water.is_some()
|
||||||
||intersecting.accelerator.is_some()
|
||intersecting.accelerator.is_some()
|
||||||
{
|
{
|
||||||
|
|||||||
181
src/main.rs
181
src/main.rs
@@ -230,7 +230,7 @@ impl GlobalState{
|
|||||||
Some(ModelGraphicsInstance{
|
Some(ModelGraphicsInstance{
|
||||||
transform: instance.transform.into(),
|
transform: instance.transform.into(),
|
||||||
normal_transform: Into::<glam::Mat3>::into(instance.transform.matrix3).inverse().transpose(),
|
normal_transform: Into::<glam::Mat3>::into(instance.transform.matrix3).inverse().transpose(),
|
||||||
color:model_graphics::ModelGraphicsColor4::from(instance.color),
|
color: instance.color,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
@@ -262,182 +262,9 @@ impl GlobalState{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//check every model to see if it's using the same (texture,color) but has few instances, if it is combine it into one model
|
|
||||||
//1. collect unique instances of texture and color, note model id
|
|
||||||
//2. for each model id, check if removing it from the pool decreases both the model count and instance count by more than one
|
|
||||||
//3. transpose all models that stay in the set
|
|
||||||
|
|
||||||
//best plan: benchmark set_bind_group, set_vertex_buffer, set_index_buffer and draw_indexed
|
|
||||||
//check if the estimated render performance is better by transposing multiple model instances into one model instance
|
|
||||||
|
|
||||||
//for now: just deduplicate single models...
|
|
||||||
let mut deduplicated_models=Vec::with_capacity(indexed_models_len);//use indexed_models_len because the list will likely get smaller instead of bigger
|
|
||||||
let mut unique_texture_color=std::collections::HashMap::new();//texture->color->vec![(model_id,instance_id)]
|
|
||||||
for (model_id,model) in unique_texture_models.iter().enumerate(){
|
|
||||||
//for now: filter out models with more than one instance
|
|
||||||
if 1<model.instances.len(){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//populate hashmap
|
|
||||||
let unique_color=if let Some(unique_color)=unique_texture_color.get_mut(&model.texture){
|
|
||||||
unique_color
|
|
||||||
}else{
|
|
||||||
//make new hashmap
|
|
||||||
let unique_color=std::collections::HashMap::new();
|
|
||||||
unique_texture_color.insert(model.texture,unique_color);
|
|
||||||
unique_texture_color.get_mut(&model.texture).unwrap()
|
|
||||||
};
|
|
||||||
//separate instances by color
|
|
||||||
for (instance_id,instance) in model.instances.iter().enumerate(){
|
|
||||||
let model_instance_list=if let Some(model_instance_list)=unique_color.get_mut(&instance.color){
|
|
||||||
model_instance_list
|
|
||||||
}else{
|
|
||||||
//make new hashmap
|
|
||||||
let model_instance_list=Vec::new();
|
|
||||||
unique_color.insert(instance.color.clone(),model_instance_list);
|
|
||||||
unique_color.get_mut(&instance.color).unwrap()
|
|
||||||
};
|
|
||||||
//add model instance to list
|
|
||||||
model_instance_list.push((model_id,instance_id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//populate a hashmap of models selected for transposition
|
|
||||||
let mut selected_model_instances=std::collections::HashSet::new();
|
|
||||||
for (texture,unique_color) in unique_texture_color.into_iter(){
|
|
||||||
for (color,model_instance_list) in unique_color.into_iter(){
|
|
||||||
if 1<model_instance_list.len(){
|
|
||||||
//create model
|
|
||||||
let mut unique_pos=Vec::new();
|
|
||||||
let mut pos_id_from=std::collections::HashMap::new();
|
|
||||||
let mut map_pos_id=std::collections::HashMap::new();
|
|
||||||
let mut unique_tex=Vec::new();
|
|
||||||
let mut tex_id_from=std::collections::HashMap::new();
|
|
||||||
let mut map_tex_id=std::collections::HashMap::new();
|
|
||||||
let mut unique_normal=Vec::new();
|
|
||||||
let mut normal_id_from=std::collections::HashMap::new();
|
|
||||||
let mut map_normal_id=std::collections::HashMap::new();
|
|
||||||
let mut unique_color=Vec::new();
|
|
||||||
let mut color_id_from=std::collections::HashMap::new();
|
|
||||||
let mut map_color_id=std::collections::HashMap::new();
|
|
||||||
let mut unique_vertices=Vec::new();
|
|
||||||
let mut vertex_id_from=std::collections::HashMap::new();
|
|
||||||
let mut map_vertex_id=std::collections::HashMap::new();
|
|
||||||
|
|
||||||
let mut polys=Vec::new();
|
|
||||||
//transform instance vertices
|
|
||||||
for (model_id,instance_id) in model_instance_list.into_iter(){
|
|
||||||
//populate hashset to prevent these models from being copied
|
|
||||||
selected_model_instances.insert(model_id);
|
|
||||||
//there is only one instance per model
|
|
||||||
let model=&unique_texture_models[model_id];
|
|
||||||
let instance=&model.instances[instance_id];
|
|
||||||
//just hash word slices LOL
|
|
||||||
for (old_pos_id,untransformed_pos) in model.unique_pos.iter().enumerate(){
|
|
||||||
let pos=instance.transform.transform_point3(glam::Vec3::from_array(untransformed_pos.clone())).to_array();
|
|
||||||
let h=pos.map(|v|u32::from_ne_bytes(v.to_ne_bytes()));
|
|
||||||
let pos_id=if let Some(&pos_id)=pos_id_from.get(&h){
|
|
||||||
pos_id
|
|
||||||
}else{
|
|
||||||
let pos_id=unique_pos.len();
|
|
||||||
unique_pos.push(pos.clone());
|
|
||||||
pos_id_from.insert(h,pos_id);
|
|
||||||
pos_id
|
|
||||||
};
|
|
||||||
map_pos_id.insert(old_pos_id,pos_id);
|
|
||||||
}
|
|
||||||
for (old_tex_id,tex) in model.unique_tex.iter().enumerate(){
|
|
||||||
let h=tex.map(|v|u32::from_ne_bytes(v.to_ne_bytes()));
|
|
||||||
let tex_id=if let Some(&tex_id)=tex_id_from.get(&h){
|
|
||||||
tex_id
|
|
||||||
}else{
|
|
||||||
let tex_id=unique_tex.len();
|
|
||||||
unique_tex.push(tex.clone());
|
|
||||||
tex_id_from.insert(h,tex_id);
|
|
||||||
tex_id
|
|
||||||
};
|
|
||||||
map_tex_id.insert(old_tex_id,tex_id);
|
|
||||||
}
|
|
||||||
for (old_normal_id,untransformed_normal) in model.unique_normal.iter().enumerate(){
|
|
||||||
let normal=(instance.normal_transform*glam::Vec3::from_array(untransformed_normal.clone())).to_array();
|
|
||||||
let h=normal.map(|v|u32::from_ne_bytes(v.to_ne_bytes()));
|
|
||||||
let normal_id=if let Some(&normal_id)=normal_id_from.get(&h){
|
|
||||||
normal_id
|
|
||||||
}else{
|
|
||||||
let normal_id=unique_normal.len();
|
|
||||||
unique_normal.push(normal.clone());
|
|
||||||
normal_id_from.insert(h,normal_id);
|
|
||||||
normal_id
|
|
||||||
};
|
|
||||||
map_normal_id.insert(old_normal_id,normal_id);
|
|
||||||
}
|
|
||||||
for (old_color_id,color) in model.unique_color.iter().enumerate(){
|
|
||||||
let h=color.map(|v|u32::from_ne_bytes(v.to_ne_bytes()));
|
|
||||||
let color_id=if let Some(&color_id)=color_id_from.get(&h){
|
|
||||||
color_id
|
|
||||||
}else{
|
|
||||||
let color_id=unique_color.len();
|
|
||||||
unique_color.push(color.clone());
|
|
||||||
color_id_from.insert(h,color_id);
|
|
||||||
color_id
|
|
||||||
};
|
|
||||||
map_color_id.insert(old_color_id,color_id);
|
|
||||||
}
|
|
||||||
//map the indexed vertices onto new indices
|
|
||||||
//creating the vertex map is slightly different because the vertices are directly hashable
|
|
||||||
for (old_vertex_id,unmapped_vertex) in model.unique_vertices.iter().enumerate(){
|
|
||||||
let vertex=model::IndexedVertex{
|
|
||||||
pos:map_pos_id[&(unmapped_vertex.pos as usize)] as u32,
|
|
||||||
tex:map_tex_id[&(unmapped_vertex.tex as usize)] as u32,
|
|
||||||
normal:map_normal_id[&(unmapped_vertex.normal as usize)] as u32,
|
|
||||||
color:map_color_id[&(unmapped_vertex.color as usize)] as u32,
|
|
||||||
};
|
|
||||||
let vertex_id=if let Some(&vertex_id)=vertex_id_from.get(&vertex){
|
|
||||||
vertex_id
|
|
||||||
}else{
|
|
||||||
let vertex_id=unique_vertices.len();
|
|
||||||
unique_vertices.push(vertex.clone());
|
|
||||||
vertex_id_from.insert(vertex,vertex_id);
|
|
||||||
vertex_id
|
|
||||||
};
|
|
||||||
map_vertex_id.insert(old_vertex_id as u32,vertex_id as u32);
|
|
||||||
}
|
|
||||||
for group in &model.groups{
|
|
||||||
for poly in &group.polys{
|
|
||||||
polys.push(model::IndexedPolygon{vertices:poly.vertices.iter().map(|vertex_id|map_vertex_id[vertex_id]).collect()});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//push model into dedup
|
|
||||||
deduplicated_models.push(model_graphics::IndexedModelGraphicsSingleTexture{
|
|
||||||
unique_pos,
|
|
||||||
unique_tex,
|
|
||||||
unique_normal,
|
|
||||||
unique_color,
|
|
||||||
unique_vertices,
|
|
||||||
texture,
|
|
||||||
groups:vec![model_graphics::IndexedGroupFixedTexture{
|
|
||||||
polys
|
|
||||||
}],
|
|
||||||
instances:vec![model_graphics::ModelGraphicsInstance{
|
|
||||||
transform:glam::Mat4::IDENTITY,
|
|
||||||
normal_transform:glam::Mat3::IDENTITY,
|
|
||||||
color
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//construct transposed models
|
|
||||||
//fill untouched models
|
|
||||||
for (model_id,model) in unique_texture_models.into_iter().enumerate(){
|
|
||||||
if !selected_model_instances.contains(&model_id){
|
|
||||||
deduplicated_models.push(model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//de-index models
|
//de-index models
|
||||||
let mut models=Vec::with_capacity(indexed_models_len);
|
let mut models=Vec::with_capacity(unique_texture_models.len());
|
||||||
for model in deduplicated_models.into_iter(){
|
for model in unique_texture_models.into_iter(){
|
||||||
let mut vertices = Vec::new();
|
let mut vertices = Vec::new();
|
||||||
let mut index_from_vertex = std::collections::HashMap::new();//::<IndexedVertex,usize>
|
let mut index_from_vertex = std::collections::HashMap::new();//::<IndexedVertex,usize>
|
||||||
let mut entities = Vec::new();
|
let mut entities = Vec::new();
|
||||||
@@ -566,7 +393,7 @@ fn get_instances_buffer_data(instances:&[ModelGraphicsInstance]) -> Vec<f32> {
|
|||||||
raw.extend_from_slice(AsRef::<[f32; 3]>::as_ref(&mi.normal_transform.z_axis));
|
raw.extend_from_slice(AsRef::<[f32; 3]>::as_ref(&mi.normal_transform.z_axis));
|
||||||
raw.extend_from_slice(&[0.0]);
|
raw.extend_from_slice(&[0.0]);
|
||||||
//color
|
//color
|
||||||
raw.extend_from_slice(AsRef::<[f32; 4]>::as_ref(&mi.color.get()));
|
raw.extend_from_slice(AsRef::<[f32; 4]>::as_ref(&mi.color));
|
||||||
raw.append(&mut v);
|
raw.append(&mut v);
|
||||||
}
|
}
|
||||||
raw
|
raw
|
||||||
|
|||||||
16
src/model.rs
16
src/model.rs
@@ -152,24 +152,16 @@ pub struct GameMechanicStageElement{
|
|||||||
pub behaviour:StageElementBehaviour
|
pub behaviour:StageElementBehaviour
|
||||||
}
|
}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GameMechanicWormhole{
|
pub struct GameMechanicWormhole{//(position,angles)*=origin.transform.inverse()*destination.transform
|
||||||
//destination does not need to be another wormhole
|
pub model_id:u32,
|
||||||
//this defines a one way portal to a destination model transform
|
|
||||||
//two of these can create a two way wormhole
|
|
||||||
pub destination_model_id:u32,
|
|
||||||
//(position,angles)*=origin.transform.inverse()*destination.transform
|
|
||||||
}
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum TeleportBehaviour{
|
|
||||||
StageElement(GameMechanicStageElement),
|
|
||||||
Wormhole(GameMechanicWormhole),
|
|
||||||
}
|
}
|
||||||
#[derive(Default,Clone)]
|
#[derive(Default,Clone)]
|
||||||
pub struct GameMechanicAttributes{
|
pub struct GameMechanicAttributes{
|
||||||
pub jump_limit:Option<GameMechanicJumpLimit>,
|
pub jump_limit:Option<GameMechanicJumpLimit>,
|
||||||
pub booster:Option<GameMechanicBooster>,
|
pub booster:Option<GameMechanicBooster>,
|
||||||
pub zone:Option<GameMechanicZone>,
|
pub zone:Option<GameMechanicZone>,
|
||||||
pub teleport_behaviour:Option<TeleportBehaviour>,
|
pub stage_element:Option<GameMechanicStageElement>,
|
||||||
|
pub wormhole:Option<GameMechanicWormhole>,//stage_element and wormhole are in conflict
|
||||||
}
|
}
|
||||||
#[derive(Default,Clone)]
|
#[derive(Default,Clone)]
|
||||||
pub struct ContactingAttributes{
|
pub struct ContactingAttributes{
|
||||||
|
|||||||
@@ -27,29 +27,9 @@ pub struct ModelGraphicsSingleTexture{
|
|||||||
pub entities: Vec<Vec<u16>>,
|
pub entities: Vec<Vec<u16>>,
|
||||||
pub texture: Option<u32>,
|
pub texture: Option<u32>,
|
||||||
}
|
}
|
||||||
#[derive(Clone,PartialEq)]
|
|
||||||
pub struct ModelGraphicsColor4(glam::Vec4);
|
|
||||||
impl ModelGraphicsColor4{
|
|
||||||
pub const fn get(&self)->glam::Vec4{
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<glam::Vec4> for ModelGraphicsColor4{
|
|
||||||
fn from(value:glam::Vec4)->Self{
|
|
||||||
Self(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl std::hash::Hash for ModelGraphicsColor4{
|
|
||||||
fn hash<H: std::hash::Hasher>(&self,state:&mut H) {
|
|
||||||
for &f in self.0.as_ref(){
|
|
||||||
u32::from_ne_bytes(f.to_ne_bytes()).hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Eq for ModelGraphicsColor4{}
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ModelGraphicsInstance{
|
pub struct ModelGraphicsInstance{
|
||||||
pub transform:glam::Mat4,
|
pub transform:glam::Mat4,
|
||||||
pub normal_transform:glam::Mat3,
|
pub normal_transform:glam::Mat3,
|
||||||
pub color:ModelGraphicsColor4,
|
pub color:glam::Vec4,
|
||||||
}
|
}
|
||||||
@@ -205,13 +205,12 @@ pub struct WorldState{}
|
|||||||
pub struct StyleModifiers{
|
pub struct StyleModifiers{
|
||||||
pub controls_mask:u32,//controls which are unable to be activated
|
pub controls_mask:u32,//controls which are unable to be activated
|
||||||
pub controls_held:u32,//controls which must be active to be able to strafe
|
pub controls_held:u32,//controls which must be active to be able to strafe
|
||||||
pub strafe_tick_rate:Ratio64,
|
|
||||||
pub jump_time:Time,
|
|
||||||
pub mv:Planar64,
|
pub mv:Planar64,
|
||||||
pub walkspeed:Planar64,
|
pub walkspeed:Planar64,
|
||||||
pub friction:Planar64,
|
pub friction:Planar64,
|
||||||
pub walk_accel:Planar64,
|
pub walk_accel:Planar64,
|
||||||
pub gravity:Planar64Vec3,
|
pub gravity:Planar64Vec3,
|
||||||
|
pub strafe_tick_rate:Ratio64,
|
||||||
pub hitbox_halfsize:Planar64Vec3,
|
pub hitbox_halfsize:Planar64Vec3,
|
||||||
}
|
}
|
||||||
impl std::default::Default for StyleModifiers{
|
impl std::default::Default for StyleModifiers{
|
||||||
@@ -220,7 +219,6 @@ impl std::default::Default for StyleModifiers{
|
|||||||
controls_mask: !0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN),
|
controls_mask: !0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN),
|
||||||
controls_held: 0,
|
controls_held: 0,
|
||||||
strafe_tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(),
|
strafe_tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(),
|
||||||
jump_time: Time::from_nanos(715_588_000/2*100),//0.715588/2.0*100.0
|
|
||||||
gravity: Planar64Vec3::int(0,-100,0),
|
gravity: Planar64Vec3::int(0,-100,0),
|
||||||
friction: Planar64::int(12)/10,
|
friction: Planar64::int(12)/10,
|
||||||
walk_accel: Planar64::int(90),
|
walk_accel: Planar64::int(90),
|
||||||
@@ -277,10 +275,6 @@ impl StyleModifiers{
|
|||||||
}
|
}
|
||||||
return control_dir
|
return control_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_jump_power(&self)->Planar64Vec3{
|
|
||||||
Planar64Vec3::int(0,715588,0)/(2*1000000/100)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PhysicsState{
|
pub struct PhysicsState{
|
||||||
@@ -418,11 +412,6 @@ impl Body {
|
|||||||
self.time=time;
|
self.time=time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl std::fmt::Display for Body{
|
|
||||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
|
||||||
write!(f,"p({}) v({}) a({}) t({})",self.position,self.velocity,self.acceleration,self.time)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for PhysicsState{
|
impl Default for PhysicsState{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@@ -654,7 +643,7 @@ impl PhysicsState {
|
|||||||
}
|
}
|
||||||
fn jump(&mut self){
|
fn jump(&mut self){
|
||||||
self.grounded=false;//do I need this?
|
self.grounded=false;//do I need this?
|
||||||
let mut v=self.body.velocity+self.style.get_jump_power();
|
let mut v=self.body.velocity+Planar64Vec3::int(0,715588,0)/(2*1000000/100);//0.715588/2.0*100.0
|
||||||
self.contact_constrain_velocity(&mut v);
|
self.contact_constrain_velocity(&mut v);
|
||||||
self.body.velocity=v;
|
self.body.velocity=v;
|
||||||
}
|
}
|
||||||
@@ -1106,8 +1095,8 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
}
|
}
|
||||||
//check ground
|
//check ground
|
||||||
self.contacts.insert(c.model,c);
|
self.contacts.insert(c.model,c);
|
||||||
match &general.teleport_behaviour{
|
match &general.stage_element{
|
||||||
Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
|
Some(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{
|
||||||
self.game.stage_id=stage_element.stage_id;
|
self.game.stage_id=stage_element.stage_id;
|
||||||
}
|
}
|
||||||
@@ -1133,9 +1122,6 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
crate::model::StageElementBehaviour::Platform=>(),
|
crate::model::StageElementBehaviour::Platform=>(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{
|
|
||||||
//telefart
|
|
||||||
}
|
|
||||||
None=>(),
|
None=>(),
|
||||||
}
|
}
|
||||||
//flatten v
|
//flatten v
|
||||||
@@ -1157,8 +1143,8 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
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.intersects.insert(c.model,c);
|
||||||
match &general.teleport_behaviour{
|
match &general.stage_element{
|
||||||
Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
|
Some(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{
|
||||||
self.game.stage_id=stage_element.stage_id;
|
self.game.stage_id=stage_element.stage_id;
|
||||||
}
|
}
|
||||||
@@ -1184,9 +1170,6 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
crate::model::StageElementBehaviour::Platform=>(),
|
crate::model::StageElementBehaviour::Platform=>(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{
|
|
||||||
//telefart
|
|
||||||
}
|
|
||||||
None=>(),
|
None=>(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ fn test_worker() {
|
|||||||
};
|
};
|
||||||
worker.send(task).unwrap();
|
worker.send(task).unwrap();
|
||||||
|
|
||||||
println!("value={}",worker.grab_clone());
|
println!("value={:?}",worker.grab_clone());
|
||||||
|
|
||||||
// wait long enough to see print from final task
|
// wait long enough to see print from final task
|
||||||
thread::sleep(std::time::Duration::from_secs(1));
|
thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
|||||||
Reference in New Issue
Block a user