From b42b29b99488f5c90cecf3f1184b72e1384bc1ff Mon Sep 17 00:00:00 2001 From: Quaternions <krakow20@gmail.com> Date: Thu, 30 Jan 2025 10:55:01 -0800 Subject: [PATCH] hooray --- lib/rbx_loader/src/union.rs | 123 ++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 62 deletions(-) diff --git a/lib/rbx_loader/src/union.rs b/lib/rbx_loader/src/union.rs index 30afbbf..644372e 100644 --- a/lib/rbx_loader/src/union.rs +++ b/lib/rbx_loader/src/union.rs @@ -6,7 +6,6 @@ use strafesnet_common::integer::vec3; #[derive(Debug)] pub enum Error{ Block, - NotSupposedToHappen, MissingVertexId(u32), Planar64Vec3(strafesnet_common::integer::Planar64TryFromFloatError), RobloxPhysicsData(rbx_mesh::physics_data::Error), @@ -54,78 +53,78 @@ impl MeshDataNormalChecker{ impl std::error::Error for Error{} pub fn convert(roblox_physics_data:&[u8],roblox_mesh_data:&[u8])->Result<model::Mesh,Error>{ - match (roblox_physics_data,roblox_mesh_data){ - (b"",b"")=>return Err(Error::Block), - (b"",_) - |(_,b"")=>return Err(Error::NotSupposedToHappen), - _=>(), - } - - // graphical - let mesh_data=rbx_mesh::read_mesh_data_versioned( - std::io::Cursor::new(roblox_mesh_data) - ).map_err(Error::RobloxMeshData)?; - let graphics_mesh=match mesh_data{ - rbx_mesh::mesh_data::CSGPHS::CSGK(_)=>return Err(Error::NotSupposedToHappen), - rbx_mesh::mesh_data::CSGPHS::CSGPHS2(mesh_data2)=>mesh_data2.mesh, - rbx_mesh::mesh_data::CSGPHS::CSGPHS4(mesh_data4)=>mesh_data4.mesh, - }; - - // physical - let physics_data=rbx_mesh::read_physics_data( - std::io::Cursor::new(roblox_physics_data) - ).map_err(Error::RobloxPhysicsData)?; - let physics_convex_meshes=match physics_data{ - rbx_mesh::physics_data::PhysicsData::CSGK(_) - // have not seen this format in practice - |rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::Block) - =>return Err(Error::NotSupposedToHappen), - rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::Meshes(meshes)) - =>meshes.meshes, - rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::PhysicsInfoMesh(pim)) - =>vec![pim.mesh], - }; + const NORMAL_FACES:usize=6; + let mut polygon_groups_normal_id=vec![Vec::new();NORMAL_FACES]; // build graphics and physics meshes let mut mb=strafesnet_common::model::MeshBuilder::new(); // graphics - const NORMAL_FACES:usize=6; - let mut polygon_groups_normal_id=vec![Vec::new();NORMAL_FACES]; - for [vertex_id0,vertex_id1,vertex_id2] in graphics_mesh.faces{ - let face=[ - graphics_mesh.vertices.get(vertex_id0.0 as usize).ok_or(Error::MissingVertexId(vertex_id0.0))?, - graphics_mesh.vertices.get(vertex_id1.0 as usize).ok_or(Error::MissingVertexId(vertex_id1.0))?, - graphics_mesh.vertices.get(vertex_id2.0 as usize).ok_or(Error::MissingVertexId(vertex_id2.0))?, - ]; - let mut normal_agreement_checker=MeshDataNormalChecker::new(); - let face=face.into_iter().map(|vertex|{ - normal_agreement_checker.check(vertex.normal_id); - let pos=mb.acquire_pos_id(vec3::try_from_f32_array(vertex.pos)?); - let normal=mb.acquire_normal_id(vec3::try_from_f32_array(vertex.norm)?); - let tex=mb.acquire_tex_id(glam::Vec2::from_array(vertex.tex)); - let color=mb.acquire_color_id(glam::Vec4::from_array(vertex.color.map(|f|f as f32/255.0f32))); - Ok(mb.acquire_vertex_id(IndexedVertex{pos,tex,normal,color})) - }).collect::<Result<Vec<_>,_>>().map_err(Error::Planar64Vec3)?; - if let Some(normal_id)=normal_agreement_checker.into_agreed_normal(){ - polygon_groups_normal_id[normal_id as usize-1].push(face); - }else{ - panic!("Empty face!"); + let graphics_groups=if !roblox_mesh_data.is_empty(){ + let mesh_data=rbx_mesh::read_mesh_data_versioned( + std::io::Cursor::new(roblox_mesh_data) + ).map_err(Error::RobloxMeshData)?; + let graphics_mesh=match mesh_data{ + rbx_mesh::mesh_data::CSGPHS::CSGK(_)=>return Err(Error::Block), + rbx_mesh::mesh_data::CSGPHS::CSGPHS2(mesh_data2)=>mesh_data2.mesh, + rbx_mesh::mesh_data::CSGPHS::CSGPHS4(mesh_data4)=>mesh_data4.mesh, + }; + for [vertex_id0,vertex_id1,vertex_id2] in graphics_mesh.faces{ + let face=[ + graphics_mesh.vertices.get(vertex_id0.0 as usize).ok_or(Error::MissingVertexId(vertex_id0.0))?, + graphics_mesh.vertices.get(vertex_id1.0 as usize).ok_or(Error::MissingVertexId(vertex_id1.0))?, + graphics_mesh.vertices.get(vertex_id2.0 as usize).ok_or(Error::MissingVertexId(vertex_id2.0))?, + ]; + let mut normal_agreement_checker=MeshDataNormalChecker::new(); + let face=face.into_iter().map(|vertex|{ + normal_agreement_checker.check(vertex.normal_id); + let pos=mb.acquire_pos_id(vec3::try_from_f32_array(vertex.pos)?); + let normal=mb.acquire_normal_id(vec3::try_from_f32_array(vertex.norm)?); + let tex=mb.acquire_tex_id(glam::Vec2::from_array(vertex.tex)); + let color=mb.acquire_color_id(glam::Vec4::from_array(vertex.color.map(|f|f as f32/255.0f32))); + Ok(mb.acquire_vertex_id(IndexedVertex{pos,tex,normal,color})) + }).collect::<Result<Vec<_>,_>>().map_err(Error::Planar64Vec3)?; + if let Some(normal_id)=normal_agreement_checker.into_agreed_normal(){ + polygon_groups_normal_id[normal_id as usize-1].push(face); + }else{ + panic!("Empty face!"); + } } - } - let graphics_groups=(0..polygon_groups_normal_id.len()).map(|polygon_group_id|{ - model::IndexedGraphicsGroup{ - render:RenderConfigId::new(0), - groups:vec![PolygonGroupId::new(polygon_group_id as u32)] - } - }).collect(); + (0..polygon_groups_normal_id.len()).map(|polygon_group_id|{ + model::IndexedGraphicsGroup{ + render:RenderConfigId::new(0), + groups:vec![PolygonGroupId::new(polygon_group_id as u32)] + } + }).collect() + }else{ + Vec::new() + }; //physics - let color=mb.acquire_color_id(glam::Vec4::ONE); - let tex=mb.acquire_tex_id(glam::Vec2::ZERO); + let physics_convex_meshes=if !roblox_physics_data.is_empty(){ + let physics_data=rbx_mesh::read_physics_data( + std::io::Cursor::new(roblox_physics_data) + ).map_err(Error::RobloxPhysicsData)?; + let physics_convex_meshes=match physics_data{ + rbx_mesh::physics_data::PhysicsData::CSGK(_) + // have not seen this format in practice + |rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::Block) + =>return Err(Error::Block), + rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::Meshes(meshes)) + =>meshes.meshes, + rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::PhysicsInfoMesh(pim)) + =>vec![pim.mesh], + }; + physics_convex_meshes + }else{ + Vec::new() + }; let polygon_groups:Vec<PolygonGroup>=polygon_groups_normal_id.into_iter().map(|faces| // graphics polygon groups (to be rendered) Ok(PolygonGroup::PolygonList(PolygonList::new(faces))) ).chain(physics_convex_meshes.into_iter().map(|mesh|{ + // this can be factored out of the loop but I am lazy + let color=mb.acquire_color_id(glam::Vec4::ONE); + let tex=mb.acquire_tex_id(glam::Vec2::ZERO); // physics polygon groups (to do physics) Ok(PolygonGroup::PolygonList(PolygonList::new(mesh.faces.into_iter().map(|[vertex_id0,vertex_id1,vertex_id2]|{ let face=[