implement primitive FaceDescriptions with fixed size arrays instead of hashmaps

This commit is contained in:
Quaternions 2023-11-07 13:26:17 -08:00
parent 9d4cadda30
commit dd6b5bed24
2 changed files with 39 additions and 35 deletions

View File

@ -422,7 +422,7 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
indexed_models.push(match basepart_texture_description{ indexed_models.push(match basepart_texture_description{
RobloxBasePartDescription::Sphere=>primitives::unit_sphere(), RobloxBasePartDescription::Sphere=>primitives::unit_sphere(),
RobloxBasePartDescription::Part(part_texture_description)=>{ RobloxBasePartDescription::Part(part_texture_description)=>{
let mut cube_face_description=primitives::CubeFaceDescription::new(); let mut cube_face_description=primitives::CubeFaceDescription::default();
for (face_id,roblox_face_description) in part_texture_description.iter().enumerate(){ for (face_id,roblox_face_description) in part_texture_description.iter().enumerate(){
cube_face_description.insert( cube_face_description.insert(
match face_id{ match face_id{
@ -443,7 +443,7 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
}, },
RobloxBasePartDescription::Cylinder=>primitives::unit_cylinder(), RobloxBasePartDescription::Cylinder=>primitives::unit_cylinder(),
RobloxBasePartDescription::Wedge(wedge_texture_description)=>{ RobloxBasePartDescription::Wedge(wedge_texture_description)=>{
let mut wedge_face_description=primitives::WedgeFaceDescription::new(); let mut wedge_face_description=primitives::WedgeFaceDescription::default();
for (face_id,roblox_face_description) in wedge_texture_description.iter().enumerate(){ for (face_id,roblox_face_description) in wedge_texture_description.iter().enumerate(){
wedge_face_description.insert( wedge_face_description.insert(
match face_id{ match face_id{
@ -462,7 +462,7 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
primitives::generate_partial_unit_wedge(wedge_face_description) primitives::generate_partial_unit_wedge(wedge_face_description)
}, },
RobloxBasePartDescription::CornerWedge(cornerwedge_texture_description)=>{ RobloxBasePartDescription::CornerWedge(cornerwedge_texture_description)=>{
let mut cornerwedge_face_description=primitives::CornerWedgeFaceDescription::new(); let mut cornerwedge_face_description=primitives::CornerWedgeFaceDescription::default();
for (face_id,roblox_face_description) in cornerwedge_texture_description.iter().enumerate(){ for (face_id,roblox_face_description) in cornerwedge_texture_description.iter().enumerate(){
cornerwedge_face_description.insert( cornerwedge_face_description.insert(
match face_id{ match face_id{

View File

@ -126,7 +126,6 @@ const CORNERWEDGE_DEFAULT_NORMALS:[Planar64Vec3;5]=[
Planar64Vec3::int( 0,-1, 0),//CornerWedge::Bottom Planar64Vec3::int( 0,-1, 0),//CornerWedge::Bottom
Planar64Vec3::int( 0, 0,-1),//CornerWedge::Front Planar64Vec3::int( 0, 0,-1),//CornerWedge::Front
]; ];
//HashMap fits this use case perfectly but feels like using a sledgehammer to drive a nail
pub fn unit_sphere()->crate::model::IndexedModel{ pub fn unit_sphere()->crate::model::IndexedModel{
let mut indexed_model=crate::model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/suzanne.obj")[..]).unwrap(),Color4::ONE).remove(0); let mut indexed_model=crate::model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/suzanne.obj")[..]).unwrap(),Color4::ONE).remove(0);
for pos in indexed_model.unique_pos.iter_mut(){ for pos in indexed_model.unique_pos.iter_mut(){
@ -134,9 +133,18 @@ pub fn unit_sphere()->crate::model::IndexedModel{
} }
indexed_model indexed_model
} }
pub type CubeFaceDescription=std::collections::HashMap::<CubeFace,FaceDescription>; #[derive(Default)]
pub struct CubeFaceDescription([Option<FaceDescription>;6]);
impl CubeFaceDescription{
pub fn insert(&mut self,index:CubeFace,value:FaceDescription){
self.0[index as usize]=Some(value);
}
pub fn pairs(self)->std::iter::FilterMap<std::iter::Enumerate<std::array::IntoIter<Option<FaceDescription>,6>>,impl FnMut((usize,Option<FaceDescription>))->Option<(usize,FaceDescription)>>{
self.0.into_iter().enumerate().filter_map(|v|v.1.map(|u|(v.0,u)))
}
}
pub fn unit_cube()->crate::model::IndexedModel{ pub fn unit_cube()->crate::model::IndexedModel{
let mut t=CubeFaceDescription::new(); let mut t=CubeFaceDescription::default();
t.insert(CubeFace::Right,FaceDescription::default()); t.insert(CubeFace::Right,FaceDescription::default());
t.insert(CubeFace::Top,FaceDescription::default()); t.insert(CubeFace::Top,FaceDescription::default());
t.insert(CubeFace::Back,FaceDescription::default()); t.insert(CubeFace::Back,FaceDescription::default());
@ -153,9 +161,18 @@ pub fn unit_cylinder()->crate::model::IndexedModel{
} }
indexed_model indexed_model
} }
pub type WedgeFaceDescription=std::collections::HashMap::<WedgeFace,FaceDescription>; #[derive(Default)]
pub struct WedgeFaceDescription([Option<FaceDescription>;5]);
impl WedgeFaceDescription{
pub fn insert(&mut self,index:WedgeFace,value:FaceDescription){
self.0[index as usize]=Some(value);
}
pub fn pairs(self)->std::iter::FilterMap<std::iter::Enumerate<std::array::IntoIter<Option<FaceDescription>,5>>,impl FnMut((usize,Option<FaceDescription>))->Option<(usize,FaceDescription)>>{
self.0.into_iter().enumerate().filter_map(|v|v.1.map(|u|(v.0,u)))
}
}
pub fn unit_wedge()->crate::model::IndexedModel{ pub fn unit_wedge()->crate::model::IndexedModel{
let mut t=WedgeFaceDescription::new(); let mut t=WedgeFaceDescription::default();
t.insert(WedgeFace::Right,FaceDescription::default()); t.insert(WedgeFace::Right,FaceDescription::default());
t.insert(WedgeFace::TopFront,FaceDescription::default()); t.insert(WedgeFace::TopFront,FaceDescription::default());
t.insert(WedgeFace::Back,FaceDescription::default()); t.insert(WedgeFace::Back,FaceDescription::default());
@ -163,9 +180,18 @@ pub fn unit_wedge()->crate::model::IndexedModel{
t.insert(WedgeFace::Bottom,FaceDescription::default()); t.insert(WedgeFace::Bottom,FaceDescription::default());
generate_partial_unit_wedge(t) generate_partial_unit_wedge(t)
} }
pub type CornerWedgeFaceDescription=std::collections::HashMap::<CornerWedgeFace,FaceDescription>; #[derive(Default)]
pub struct CornerWedgeFaceDescription([Option<FaceDescription>;5]);
impl CornerWedgeFaceDescription{
pub fn insert(&mut self,index:CornerWedgeFace,value:FaceDescription){
self.0[index as usize]=Some(value);
}
pub fn pairs(self)->std::iter::FilterMap<std::iter::Enumerate<std::array::IntoIter<Option<FaceDescription>,5>>,impl FnMut((usize,Option<FaceDescription>))->Option<(usize,FaceDescription)>>{
self.0.into_iter().enumerate().filter_map(|v|v.1.map(|u|(v.0,u)))
}
}
pub fn unit_cornerwedge()->crate::model::IndexedModel{ pub fn unit_cornerwedge()->crate::model::IndexedModel{
let mut t=CornerWedgeFaceDescription::new(); let mut t=CornerWedgeFaceDescription::default();
t.insert(CornerWedgeFace::Right,FaceDescription::default()); t.insert(CornerWedgeFace::Right,FaceDescription::default());
t.insert(CornerWedgeFace::TopBack,FaceDescription::default()); t.insert(CornerWedgeFace::TopBack,FaceDescription::default());
t.insert(CornerWedgeFace::TopLeft,FaceDescription::default()); t.insert(CornerWedgeFace::TopLeft,FaceDescription::default());
@ -200,7 +226,7 @@ pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->crate:
let mut groups=Vec::new(); let mut groups=Vec::new();
let mut transforms=Vec::new(); let mut transforms=Vec::new();
//note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices. //note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices.
for (face,face_description) in face_descriptions.into_iter(){ for (face_id,face_description) in face_descriptions.pairs(){
//assume that scanning short lists is faster than hashing. //assume that scanning short lists is faster than hashing.
let transform_index=if let Some(transform_index)=transforms.iter().position(|&transform|transform==face_description.transform){ let transform_index=if let Some(transform_index)=transforms.iter().position(|&transform|transform==face_description.transform){
transform_index transform_index
@ -221,14 +247,6 @@ pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->crate:
generated_color.push(face_description.color); generated_color.push(face_description.color);
color_index color_index
} as u32; } as u32;
let face_id=match face{
CubeFace::Right => 0,
CubeFace::Top => 1,
CubeFace::Back => 2,
CubeFace::Left => 3,
CubeFace::Bottom => 4,
CubeFace::Front => 5,
};
//always push normal //always push normal
let normal_index=generated_normal.len() as u32; let normal_index=generated_normal.len() as u32;
generated_normal.push(CUBE_DEFAULT_NORMALS[face_id]); generated_normal.push(CUBE_DEFAULT_NORMALS[face_id]);
@ -315,7 +333,7 @@ pub fn generate_partial_unit_wedge(face_descriptions:WedgeFaceDescription)->crat
let mut groups=Vec::new(); let mut groups=Vec::new();
let mut transforms=Vec::new(); let mut transforms=Vec::new();
//note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices. //note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices.
for (face,face_description) in face_descriptions.into_iter(){ for (face_id,face_description) in face_descriptions.pairs(){
//assume that scanning short lists is faster than hashing. //assume that scanning short lists is faster than hashing.
let transform_index=if let Some(transform_index)=transforms.iter().position(|&transform|transform==face_description.transform){ let transform_index=if let Some(transform_index)=transforms.iter().position(|&transform|transform==face_description.transform){
transform_index transform_index
@ -336,13 +354,6 @@ pub fn generate_partial_unit_wedge(face_descriptions:WedgeFaceDescription)->crat
generated_color.push(face_description.color); generated_color.push(face_description.color);
color_index color_index
} as u32; } as u32;
let face_id=match face{
WedgeFace::Right => 0,
WedgeFace::TopFront => 1,
WedgeFace::Back => 2,
WedgeFace::Left => 3,
WedgeFace::Bottom => 4,
};
//always push normal //always push normal
let normal_index=generated_normal.len() as u32; let normal_index=generated_normal.len() as u32;
generated_normal.push(WEDGE_DEFAULT_NORMALS[face_id]); generated_normal.push(WEDGE_DEFAULT_NORMALS[face_id]);
@ -427,7 +438,7 @@ pub fn generate_partial_unit_cornerwedge(face_descriptions:CornerWedgeFaceDescri
let mut groups=Vec::new(); let mut groups=Vec::new();
let mut transforms=Vec::new(); let mut transforms=Vec::new();
//note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices. //note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices.
for (face,face_description) in face_descriptions.into_iter(){ for (face_id,face_description) in face_descriptions.pairs(){
//assume that scanning short lists is faster than hashing. //assume that scanning short lists is faster than hashing.
let transform_index=if let Some(transform_index)=transforms.iter().position(|&transform|transform==face_description.transform){ let transform_index=if let Some(transform_index)=transforms.iter().position(|&transform|transform==face_description.transform){
transform_index transform_index
@ -448,13 +459,6 @@ pub fn generate_partial_unit_cornerwedge(face_descriptions:CornerWedgeFaceDescri
generated_color.push(face_description.color); generated_color.push(face_description.color);
color_index color_index
} as u32; } as u32;
let face_id=match face{
CornerWedgeFace::Right => 0,
CornerWedgeFace::TopBack => 1,
CornerWedgeFace::TopLeft => 2,
CornerWedgeFace::Bottom => 3,
CornerWedgeFace::Front => 4,
};
//always push normal //always push normal
let normal_index=generated_normal.len() as u32; let normal_index=generated_normal.len() as u32;
generated_normal.push(CORNERWEDGE_DEFAULT_NORMALS[face_id]); generated_normal.push(CORNERWEDGE_DEFAULT_NORMALS[face_id]);