diff --git a/lib/rbx_loader/src/union.rs b/lib/rbx_loader/src/union.rs
index 1dd9d07..8124275 100644
--- a/lib/rbx_loader/src/union.rs
+++ b/lib/rbx_loader/src/union.rs
@@ -7,9 +7,11 @@ 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),
+	RobloxMeshData(rbx_mesh::mesh_data::Error),
 }
 impl std::fmt::Display for Error{
 	fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -18,17 +20,33 @@ impl std::fmt::Display for Error{
 }
 
 impl std::error::Error for Error{}
-pub fn convert(roblox_physics_data:&[u8])->Result<model::Mesh,Error>{
-	if let b""=roblox_physics_data{
-		return Err(Error::Block);
+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),
+		_=>(),
 	}
-	let mut cursor=std::io::Cursor::new(roblox_physics_data);
-	let physics_data:rbx_mesh::physics_data::PhysicsData=rbx_mesh::read_physics_data(&mut cursor).map_err(Error::RobloxPhysicsData)?;
-	assert_eq!(cursor.position(),cursor.into_inner().len() as u64);
-	let meshes=match physics_data{
+
+	// 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(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::Block),
+		=>return Err(Error::NotSupposedToHappen),
 		rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::Meshes3(meshes))
 		|rbx_mesh::physics_data::PhysicsData::CSGPHS(rbx_mesh::physics_data::CSGPHS::Meshes5(meshes))
 		=>meshes.meshes,
@@ -86,7 +104,7 @@ pub fn convert(roblox_physics_data:&[u8])->Result<model::Mesh,Error>{
 	};
 	let color=acquire_color_id([1.0f32;4]);
 	let tex=acquire_tex_id([0.0f32;2]);
-	let polygon_groups:Vec<PolygonGroup>=meshes.into_iter().map(|mesh|{
+	let polygon_groups:Vec<PolygonGroup>=physics_convex_meshes.into_iter().map(|mesh|{
 		Ok(PolygonGroup::PolygonList(PolygonList::new(mesh.faces.into_iter().map(|[vertex_id0,vertex_id1,vertex_id2]|{
 			let v0=mesh.vertices.get(vertex_id0.0 as usize).ok_or(Error::MissingVertexId(vertex_id0.0))?;
 			let v1=mesh.vertices.get(vertex_id1.0 as usize).ok_or(Error::MissingVertexId(vertex_id1.0))?;