diff --git a/lib/rbx_loader/src/rbx.rs b/lib/rbx_loader/src/rbx.rs index 0b69776..72d0891 100644 --- a/lib/rbx_loader/src/rbx.rs +++ b/lib/rbx_loader/src/rbx.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use crate::loader::MeshIndex; use crate::primitives; +use strafesnet_common::aabb::Aabb; use strafesnet_common::map; use strafesnet_common::model; use strafesnet_common::gameplay_modes; @@ -769,7 +770,55 @@ pub fn convert<'a>( } struct MeshWithAabb{ mesh:model::Mesh, - aabb:strafesnet_common::aabb::Aabb, + aabb:Aabb, +} +fn acquire_mesh_id_from_render_config_id<'a>( + primitive_meshes:&mut Vec<model::Mesh>, + mesh_id_from_render_config_id:&mut HashMap<model::MeshId,HashMap<RenderConfigId,model::MeshId>>, + loaded_meshes:&'a HashMap<model::MeshId,MeshWithAabb>, + old_mesh_id:model::MeshId, + render:RenderConfigId, +)->Option<(model::MeshId,&'a Aabb)>{ + //ignore meshes that fail to load completely for now + loaded_meshes.get(&old_mesh_id).map(|mesh_with_aabb|( + *mesh_id_from_render_config_id.entry(old_mesh_id).or_insert_with(||HashMap::new()) + .entry(render).or_insert_with(||{ + let mesh_id=model::MeshId::new(primitive_meshes.len() as u32); + let mut mesh_clone=mesh_with_aabb.mesh.clone(); + //set the render group lool + if let Some(graphics_group)=mesh_clone.graphics_groups.first_mut(){ + graphics_group.render=render; + } + primitive_meshes.push(mesh_clone); + mesh_id + }), + &mesh_with_aabb.aabb, + )) +} +fn acquire_union_id_from_render_config_id<'a>( + primitive_meshes:&mut Vec<model::Mesh>, + union_id_from_render_config_id:&mut HashMap<model::MeshId,HashMap<RobloxPartDescription,model::MeshId>>, + loaded_meshes:&'a HashMap<model::MeshId,MeshWithAabb>, + old_union_id:model::MeshId, + part_texture_description:RobloxPartDescription, +)->Option<(model::MeshId,&'a Aabb)>{ + //ignore uniones that fail to load completely for now + loaded_meshes.get(&old_union_id).map(|union_with_aabb|( + *union_id_from_render_config_id.entry(old_union_id).or_insert_with(||HashMap::new()) + .entry(part_texture_description.clone()).or_insert_with(||{ + let union_id=model::MeshId::new(primitive_meshes.len() as u32); + let mut union_clone=union_with_aabb.mesh.clone(); + //set the render groups + for (graphics_group,maybe_face_texture_description) in union_clone.graphics_groups.iter_mut().zip(part_texture_description){ + if let Some(face_texture_description)=maybe_face_texture_description{ + graphics_group.render=face_texture_description.render; + } + } + primitive_meshes.push(union_clone); + union_id + }), + &union_with_aabb.aabb, + )) } pub struct PartialMap1<'a>{ primitive_meshes:Vec<model::Mesh>, @@ -804,30 +853,21 @@ impl PartialMap1<'_>{ }) }).collect(); + // SAFETY: I have no idea what I'm doing and this is definitely unsound in some subtle way + // I just want to chain iterators together man + let aint_no_way=core::cell::UnsafeCell::new(&mut self.primitive_meshes); + let mut mesh_id_from_render_config_id=HashMap::new(); - //ignore meshes that fail to load completely for now - let mut acquire_mesh_id_from_render_config_id=|old_mesh_id,render|{ - loaded_meshes.get(&old_mesh_id).map(|mesh_with_aabb|( - *mesh_id_from_render_config_id.entry(old_mesh_id).or_insert_with(||HashMap::new()) - .entry(render).or_insert_with(||{ - let mesh_id=model::MeshId::new(self.primitive_meshes.len() as u32); - let mut mesh_clone=mesh_with_aabb.mesh.clone(); - //set the render group lool - if let Some(graphics_group)=mesh_clone.graphics_groups.first_mut(){ - graphics_group.render=render; - } - self.primitive_meshes.push(mesh_clone); - mesh_id - }), - &mesh_with_aabb.aabb, - )) - }; + let mut union_id_from_render_config_id=HashMap::new(); //now that the meshes are loaded, these models can be generated let models_owned_attributes:Vec<ModelOwnedAttributes>= self.deferred_models_deferred_attributes.into_iter().flat_map(|deferred_model_deferred_attributes|{ //meshes need to be cloned from loaded_meshes with a new id when they are used with a new render_id //insert into primitive_meshes let (mesh,aabb)=acquire_mesh_id_from_render_config_id( + unsafe{*aint_no_way.get()}, + &mut mesh_id_from_render_config_id, + &loaded_meshes, deferred_model_deferred_attributes.model.mesh, deferred_model_deferred_attributes.render )?; @@ -845,7 +885,32 @@ impl PartialMap1<'_>{ deferred_model_deferred_attributes.model.transform.translation ), }) - }).chain(self.primitive_models_deferred_attributes.into_iter()) + }).chain(self.deferred_unions_deferred_attributes.into_iter().flat_map(|deferred_union_deferred_attributes|{ + //meshes need to be cloned from loaded_meshes with a new id when they are used with a new render_id + //insert into primitive_meshes + let (mesh,aabb)=acquire_union_id_from_render_config_id( + unsafe{*aint_no_way.get()}, + &mut union_id_from_render_config_id, + &loaded_meshes, + deferred_union_deferred_attributes.model.mesh, + deferred_union_deferred_attributes.render + )?; + let size=aabb.size(); + Some(ModelDeferredAttributes{ + mesh, + deferred_attributes:deferred_union_deferred_attributes.model.deferred_attributes, + color:deferred_union_deferred_attributes.model.color, + transform:Planar64Affine3::new( + Planar64Mat3::from_cols([ + (deferred_union_deferred_attributes.model.transform.matrix3.x_axis*2/size.x).divide().fix_1(), + (deferred_union_deferred_attributes.model.transform.matrix3.y_axis*2/size.y).divide().fix_1(), + (deferred_union_deferred_attributes.model.transform.matrix3.z_axis*2/size.z).divide().fix_1() + ]), + deferred_union_deferred_attributes.model.transform.translation + ), + }) + })) + .chain(self.primitive_models_deferred_attributes.into_iter()) .enumerate().map(|(model_id,model_deferred_attributes)|{ let model_id=model::ModelId::new(model_id as u32); ModelOwnedAttributes{