diff --git a/src/lib.rs b/src/lib.rs index 412cb55..bd50f4b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,14 @@ pub fn read(input:R)->Result{ //ConvertError -pub fn convert)->strafesnet_common::model::RenderConfigId>(dom:&Dom,acquire_render_config_id:F)->rbx::PartialMap1{ - rbx::convert(&dom.0,acquire_render_config_id) +pub fn convert( + dom:&Dom, + acquire_render_config_id:AcquireRenderConfigId, + acquire_mesh_id:AcquireMeshId +)->rbx::PartialMap1 +where + AcquireRenderConfigId:FnMut(Option<&str>)->strafesnet_common::model::RenderConfigId, + AcquireMeshId:FnMut(&str)->strafesnet_common::model::MeshId, +{ + rbx::convert(&dom.0,acquire_render_config_id,acquire_mesh_id) } \ No newline at end of file diff --git a/src/rbx.rs b/src/rbx.rs index f7626c7..a748bbb 100644 --- a/src/rbx.rs +++ b/src/rbx.rs @@ -397,12 +397,22 @@ type RobloxPartDescription=[Option;6]; type RobloxWedgeDescription=[Option;5]; type RobloxCornerWedgeDescription=[Option;5]; #[derive(Clone,Eq,Hash,PartialEq)] +struct RobloxMeshPartDescription{ + render:RenderConfigId, + mesh:model::MeshId, +} +#[derive(Clone,Eq,Hash,PartialEq)] enum RobloxBasePartDescription{ Sphere(RobloxPartDescription), Part(RobloxPartDescription), Cylinder(RobloxPartDescription), Wedge(RobloxWedgeDescription), CornerWedge(RobloxCornerWedgeDescription), + MeshPart(RobloxMeshPartDescription) +} +enum Shape{ + Primitive(primitives::Primitives), + MeshPart, } struct ModelOwnedAttributes{ mesh:model::MeshId, @@ -410,7 +420,15 @@ struct ModelOwnedAttributes{ color:model::Color4,//transparency is in here transform:Planar64Affine3, } -pub fn convert)->model::RenderConfigId>(dom:&rbx_dom_weak::WeakDom,mut acquire_render_config_id:F)->PartialMap1{ +pub fn convert( + dom:&rbx_dom_weak::WeakDom, + mut acquire_render_config_id:AcquireRenderConfigId, + mut acquire_mesh_id:AcquireMeshId, +)->PartialMap1 +where + AcquireRenderConfigId:FnMut(Option<&str>)->model::RenderConfigId, + AcquireMeshId:FnMut(&str)->model::MeshId, +{ let mut modes_builder=ModesBuilder::default(); let mut models1=Vec::new(); @@ -467,26 +485,29 @@ pub fn convert)->model::RenderConfigId>(dom:&rbx_dom_weak:: //TODO: also detect "CylinderMesh" etc here let shape=match object.class.as_str(){ "Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get("Shape"){ - match shape.to_u32(){ + Shape::Primitive(match shape.to_u32(){ 0=>primitives::Primitives::Sphere, 1=>primitives::Primitives::Cube, 2=>primitives::Primitives::Cylinder, 3=>primitives::Primitives::Wedge, 4=>primitives::Primitives::CornerWedge, other=>panic!("Funky roblox PartType={};",other), - } + }) }else{ panic!("Part has no Shape!"); }, - "TrussPart"=>primitives::Primitives::Cube, - "WedgePart"=>primitives::Primitives::Wedge, - "CornerWedgePart"=>primitives::Primitives::CornerWedge, + "TrussPart"=>Shape::Primitive(primitives::Primitives::Cube), + "WedgePart"=>Shape::Primitive(primitives::Primitives::Wedge), + "CornerWedgePart"=>Shape::Primitive(primitives::Primitives::CornerWedge), + "MeshPart"=>Shape::MeshPart, _=>{ println!("Unsupported BasePart ClassName={}; defaulting to cube",object.class); - primitives::Primitives::Cube + Shape::Primitive(primitives::Primitives::Cube) } }; + let basepart_description=match shape{ + Shape::Primitive(primitive_shape)=>{ //use the biggest one and cut it down later... let mut part_texture_description:RobloxPartDescription=[None,None,None,None,None,None]; temp_objects.clear(); @@ -549,7 +570,7 @@ pub fn convert)->model::RenderConfigId>(dom:&rbx_dom_weak:: transform:roblox_texture_transform, }); }else{ - println!("NormalId={} unsupported for shape={:?}",normal_id,shape); + println!("NormalId={} unsupported for shape={:?}",normal_id,primitive_shape); } } } @@ -563,7 +584,7 @@ pub fn convert)->model::RenderConfigId>(dom:&rbx_dom_weak:: f4,//Cube::Bottom f5,//Cube::Front ]=part_texture_description; - let basepart_texture_description=match shape{ + match primitive_shape{ primitives::Primitives::Sphere=>RobloxBasePartDescription::Sphere([f0,f1,f2,f3,f4,f5]), primitives::Primitives::Cube=>RobloxBasePartDescription::Part([f0,f1,f2,f3,f4,f5]), primitives::Primitives::Cylinder=>RobloxBasePartDescription::Cylinder([f0,f1,f2,f3,f4,f5]), @@ -583,15 +604,31 @@ pub fn convert)->model::RenderConfigId>(dom:&rbx_dom_weak:: f4,//Cube::Bottom->CornerWedge::Bottom f5,//Cube::Front->CornerWedge::Front ]), + } + }, + Shape::MeshPart=>if let ( + Some(rbx_dom_weak::types::Variant::Content(mesh_asset_id)), + Some(rbx_dom_weak::types::Variant::Content(texture_asset_id)), + )=( + object.properties.get("MeshId"), + object.properties.get("TextureID"), + ){ + RobloxBasePartDescription::MeshPart(RobloxMeshPartDescription{ + render:acquire_render_config_id(Some(texture_asset_id.as_ref())), + mesh:acquire_mesh_id(mesh_asset_id.as_ref()), + }) + }else{ + panic!("Mesh has no Mesh or Texture"); + }, }; //make new model if unit cube has not been created before - let indexed_model_id=if let Some(&indexed_model_id)=indexed_model_id_from_description.get(&basepart_texture_description){ + let indexed_model_id=if let Some(&indexed_model_id)=indexed_model_id_from_description.get(&basepart_description){ //push to existing texture model indexed_model_id }else{ let indexed_model_id=model::MeshId::new(meshes.len() as u32); - indexed_model_id_from_description.insert(basepart_texture_description.clone(),indexed_model_id);//borrow checker going crazy - meshes.push(match basepart_texture_description{ + indexed_model_id_from_description.insert(basepart_description.clone(),indexed_model_id);//borrow checker going crazy + let mesh_option=match basepart_description{ RobloxBasePartDescription::Sphere(part_texture_description) |RobloxBasePartDescription::Cylinder(part_texture_description) |RobloxBasePartDescription::Part(part_texture_description)=>{ @@ -612,7 +649,7 @@ pub fn convert)->model::RenderConfigId>(dom:&rbx_dom_weak:: None=>primitives::FaceDescription::new_with_render_id(textureless_render_group), }); } - primitives::generate_partial_unit_cube(cube_face_description) + Some(primitives::generate_partial_unit_cube(cube_face_description)) }, RobloxBasePartDescription::Wedge(wedge_texture_description)=>{ let mut wedge_face_description=primitives::WedgeFaceDescription::default(); @@ -631,7 +668,7 @@ pub fn convert)->model::RenderConfigId>(dom:&rbx_dom_weak:: None=>primitives::FaceDescription::new_with_render_id(textureless_render_group), }); } - primitives::generate_partial_unit_wedge(wedge_face_description) + Some(primitives::generate_partial_unit_wedge(wedge_face_description)) }, RobloxBasePartDescription::CornerWedge(cornerwedge_texture_description)=>{ let mut cornerwedge_face_description=primitives::CornerWedgeFaceDescription::default(); @@ -650,10 +687,19 @@ pub fn convert)->model::RenderConfigId>(dom:&rbx_dom_weak:: None=>primitives::FaceDescription::new_with_render_id(textureless_render_group), }); } - primitives::generate_partial_unit_cornerwedge(cornerwedge_face_description) + Some(primitives::generate_partial_unit_cornerwedge(cornerwedge_face_description)) }, - }); - indexed_model_id + RobloxBasePartDescription::MeshPart(meshpart)=>{ + //meshpart.mesh + } + }; + if let Some(mesh)=mesh_option{ + meshes.push(mesh); + indexed_model_id + }else{ + //somehow ?? + //copy bsp_loader strat + } }; let attributes=get_attributes( &object,