diff --git a/lib/rbx_loader/src/union.rs b/lib/rbx_loader/src/union.rs index c6c75c3..2d4fb7e 100644 --- a/lib/rbx_loader/src/union.rs +++ b/lib/rbx_loader/src/union.rs @@ -1,4 +1,6 @@ -use rbx_mesh::mesh_data::{NormalId2 as MeshDataNormalId2,VertexId as MeshDataVertexId}; +use crate::rbx::RobloxPartDescription; + +use rbx_mesh::mesh_data::{VertexId as MeshDataVertexId,NormalId2 as MeshDataNormalId2}; use rbx_mesh::physics_data::VertexId as PhysicsDataVertexId; use strafesnet_common::model::{self,IndexedVertex,PolygonGroup,PolygonGroupId,PolygonList,RenderConfigId}; use strafesnet_common::integer::vec3; @@ -57,10 +59,10 @@ pub fn convert( roblox_physics_data:&[u8], roblox_mesh_data:&[u8], size:glam::Vec3, - crate::rbx::RobloxPartDescription(part_texture_description):crate::rbx::RobloxPartDescription, + RobloxPartDescription(part_texture_description):RobloxPartDescription, )->Result<model::Mesh,Error>{ const NORMAL_FACES:usize=6; - let mut polygon_groups_normal_id=vec![Vec::new();NORMAL_FACES]; + let mut polygon_groups_normal_id:[_;NORMAL_FACES]=[vec![],vec![],vec![],vec![],vec![],vec![]]; // build graphics and physics meshes let mut mb=strafesnet_common::model::MeshBuilder::new(); @@ -126,7 +128,11 @@ pub fn convert( }; //physics - let physics_convex_meshes=if !roblox_physics_data.is_empty(){ + let polygon_groups_normal_it=polygon_groups_normal_id.into_iter().map(|faces| + // graphics polygon groups (to be rendered) + Ok(PolygonGroup::PolygonList(PolygonList::new(faces))) + ); + let polygon_groups:Vec<PolygonGroup>=if !roblox_physics_data.is_empty(){ let physics_data=rbx_mesh::read_physics_data_versioned( std::io::Cursor::new(roblox_physics_data) ).map_err(Error::RobloxPhysicsData)?; @@ -140,33 +146,31 @@ pub fn convert( rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::PhysicsInfoMesh(pim)) =>vec![pim.mesh], }; - physics_convex_meshes + let physics_convex_meshes_it=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(|[PhysicsDataVertexId(vertex_id0),PhysicsDataVertexId(vertex_id1),PhysicsDataVertexId(vertex_id2)]|{ + let face=[ + mesh.vertices.get(vertex_id0 as usize).ok_or(Error::MissingVertexId(vertex_id0))?, + mesh.vertices.get(vertex_id1 as usize).ok_or(Error::MissingVertexId(vertex_id1))?, + mesh.vertices.get(vertex_id2 as usize).ok_or(Error::MissingVertexId(vertex_id2))?, + ].map(|v|glam::Vec3::from_slice(v)/size); + let vertex_norm=(face[1]-face[0]) + .cross(face[2]-face[0]); + let normal=mb.acquire_normal_id(vec3::try_from_f32_array(vertex_norm.to_array()).map_err(Error::Planar64Vec3)?); + face.into_iter().map(|vertex_pos|{ + let pos=mb.acquire_pos_id(vec3::try_from_f32_array(vertex_pos.to_array()).map_err(Error::Planar64Vec3)?); + Ok(mb.acquire_vertex_id(IndexedVertex{pos,tex,normal,color})) + }).collect() + }).collect::<Result<_,_>>()?))) + }); + polygon_groups_normal_it.chain(physics_convex_meshes_it).collect::<Result<_,_>>()? }else{ - Vec::new() + // TODO: generate a unit cube as default physics + polygon_groups_normal_it.collect::<Result<_,_>>()? }; - 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(|[PhysicsDataVertexId(vertex_id0),PhysicsDataVertexId(vertex_id1),PhysicsDataVertexId(vertex_id2)]|{ - let face=[ - mesh.vertices.get(vertex_id0 as usize).ok_or(Error::MissingVertexId(vertex_id0))?, - mesh.vertices.get(vertex_id1 as usize).ok_or(Error::MissingVertexId(vertex_id1))?, - mesh.vertices.get(vertex_id2 as usize).ok_or(Error::MissingVertexId(vertex_id2))?, - ].map(|v|glam::Vec3::from_slice(v)/size); - let vertex_norm=(face[1]-face[0]) - .cross(face[2]-face[0]); - let normal=mb.acquire_normal_id(vec3::try_from_f32_array(vertex_norm.to_array()).map_err(Error::Planar64Vec3)?); - face.into_iter().map(|vertex_pos|{ - let pos=mb.acquire_pos_id(vec3::try_from_f32_array(vertex_pos.to_array()).map_err(Error::Planar64Vec3)?); - Ok(mb.acquire_vertex_id(IndexedVertex{pos,tex,normal,color})) - }).collect() - }).collect::<Result<_,_>>()?))) - })).collect::<Result<_,_>>()?; let physics_groups=(NORMAL_FACES..polygon_groups.len()).map(|id|model::IndexedPhysicsGroup{ groups:vec![PolygonGroupId::new(id as u32)] }).collect();