hooray
This commit is contained in:
parent
1f95c608f0
commit
b42b29b994
@ -6,7 +6,6 @@ use strafesnet_common::integer::vec3;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error{
|
pub enum Error{
|
||||||
Block,
|
Block,
|
||||||
NotSupposedToHappen,
|
|
||||||
MissingVertexId(u32),
|
MissingVertexId(u32),
|
||||||
Planar64Vec3(strafesnet_common::integer::Planar64TryFromFloatError),
|
Planar64Vec3(strafesnet_common::integer::Planar64TryFromFloatError),
|
||||||
RobloxPhysicsData(rbx_mesh::physics_data::Error),
|
RobloxPhysicsData(rbx_mesh::physics_data::Error),
|
||||||
@ -54,78 +53,78 @@ impl MeshDataNormalChecker{
|
|||||||
|
|
||||||
impl std::error::Error for Error{}
|
impl std::error::Error for Error{}
|
||||||
pub fn convert(roblox_physics_data:&[u8],roblox_mesh_data:&[u8])->Result<model::Mesh,Error>{
|
pub fn convert(roblox_physics_data:&[u8],roblox_mesh_data:&[u8])->Result<model::Mesh,Error>{
|
||||||
match (roblox_physics_data,roblox_mesh_data){
|
const NORMAL_FACES:usize=6;
|
||||||
(b"",b"")=>return Err(Error::Block),
|
let mut polygon_groups_normal_id=vec![Vec::new();NORMAL_FACES];
|
||||||
(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],
|
|
||||||
};
|
|
||||||
|
|
||||||
// build graphics and physics meshes
|
// build graphics and physics meshes
|
||||||
let mut mb=strafesnet_common::model::MeshBuilder::new();
|
let mut mb=strafesnet_common::model::MeshBuilder::new();
|
||||||
// graphics
|
// graphics
|
||||||
const NORMAL_FACES:usize=6;
|
let graphics_groups=if !roblox_mesh_data.is_empty(){
|
||||||
let mut polygon_groups_normal_id=vec![Vec::new();NORMAL_FACES];
|
let mesh_data=rbx_mesh::read_mesh_data_versioned(
|
||||||
for [vertex_id0,vertex_id1,vertex_id2] in graphics_mesh.faces{
|
std::io::Cursor::new(roblox_mesh_data)
|
||||||
let face=[
|
).map_err(Error::RobloxMeshData)?;
|
||||||
graphics_mesh.vertices.get(vertex_id0.0 as usize).ok_or(Error::MissingVertexId(vertex_id0.0))?,
|
let graphics_mesh=match mesh_data{
|
||||||
graphics_mesh.vertices.get(vertex_id1.0 as usize).ok_or(Error::MissingVertexId(vertex_id1.0))?,
|
rbx_mesh::mesh_data::CSGPHS::CSGK(_)=>return Err(Error::Block),
|
||||||
graphics_mesh.vertices.get(vertex_id2.0 as usize).ok_or(Error::MissingVertexId(vertex_id2.0))?,
|
rbx_mesh::mesh_data::CSGPHS::CSGPHS2(mesh_data2)=>mesh_data2.mesh,
|
||||||
];
|
rbx_mesh::mesh_data::CSGPHS::CSGPHS4(mesh_data4)=>mesh_data4.mesh,
|
||||||
let mut normal_agreement_checker=MeshDataNormalChecker::new();
|
};
|
||||||
let face=face.into_iter().map(|vertex|{
|
for [vertex_id0,vertex_id1,vertex_id2] in graphics_mesh.faces{
|
||||||
normal_agreement_checker.check(vertex.normal_id);
|
let face=[
|
||||||
let pos=mb.acquire_pos_id(vec3::try_from_f32_array(vertex.pos)?);
|
graphics_mesh.vertices.get(vertex_id0.0 as usize).ok_or(Error::MissingVertexId(vertex_id0.0))?,
|
||||||
let normal=mb.acquire_normal_id(vec3::try_from_f32_array(vertex.norm)?);
|
graphics_mesh.vertices.get(vertex_id1.0 as usize).ok_or(Error::MissingVertexId(vertex_id1.0))?,
|
||||||
let tex=mb.acquire_tex_id(glam::Vec2::from_array(vertex.tex));
|
graphics_mesh.vertices.get(vertex_id2.0 as usize).ok_or(Error::MissingVertexId(vertex_id2.0))?,
|
||||||
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}))
|
let mut normal_agreement_checker=MeshDataNormalChecker::new();
|
||||||
}).collect::<Result<Vec<_>,_>>().map_err(Error::Planar64Vec3)?;
|
let face=face.into_iter().map(|vertex|{
|
||||||
if let Some(normal_id)=normal_agreement_checker.into_agreed_normal(){
|
normal_agreement_checker.check(vertex.normal_id);
|
||||||
polygon_groups_normal_id[normal_id as usize-1].push(face);
|
let pos=mb.acquire_pos_id(vec3::try_from_f32_array(vertex.pos)?);
|
||||||
}else{
|
let normal=mb.acquire_normal_id(vec3::try_from_f32_array(vertex.norm)?);
|
||||||
panic!("Empty face!");
|
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!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
(0..polygon_groups_normal_id.len()).map(|polygon_group_id|{
|
||||||
let graphics_groups=(0..polygon_groups_normal_id.len()).map(|polygon_group_id|{
|
model::IndexedGraphicsGroup{
|
||||||
model::IndexedGraphicsGroup{
|
render:RenderConfigId::new(0),
|
||||||
render:RenderConfigId::new(0),
|
groups:vec![PolygonGroupId::new(polygon_group_id as u32)]
|
||||||
groups:vec![PolygonGroupId::new(polygon_group_id as u32)]
|
}
|
||||||
}
|
}).collect()
|
||||||
}).collect();
|
}else{
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
//physics
|
//physics
|
||||||
let color=mb.acquire_color_id(glam::Vec4::ONE);
|
let physics_convex_meshes=if !roblox_physics_data.is_empty(){
|
||||||
let tex=mb.acquire_tex_id(glam::Vec2::ZERO);
|
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|
|
let polygon_groups:Vec<PolygonGroup>=polygon_groups_normal_id.into_iter().map(|faces|
|
||||||
// graphics polygon groups (to be rendered)
|
// graphics polygon groups (to be rendered)
|
||||||
Ok(PolygonGroup::PolygonList(PolygonList::new(faces)))
|
Ok(PolygonGroup::PolygonList(PolygonList::new(faces)))
|
||||||
).chain(physics_convex_meshes.into_iter().map(|mesh|{
|
).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)
|
// physics polygon groups (to do physics)
|
||||||
Ok(PolygonGroup::PolygonList(PolygonList::new(mesh.faces.into_iter().map(|[vertex_id0,vertex_id1,vertex_id2]|{
|
Ok(PolygonGroup::PolygonList(PolygonList::new(mesh.faces.into_iter().map(|[vertex_id0,vertex_id1,vertex_id2]|{
|
||||||
let face=[
|
let face=[
|
||||||
|
Loading…
x
Reference in New Issue
Block a user