rbx_loader: refactor primitive types
This commit is contained in:
parent
be85530000
commit
d0ee597416
lib/rbx_loader/src
@ -4,7 +4,7 @@ use strafesnet_common::model::Mesh;
|
||||
use strafesnet_deferred_loader::{loader::Loader,texture::Texture};
|
||||
|
||||
use crate::data::RobloxMeshBytes;
|
||||
use crate::rbx::RobloxFaceTextureDescription;
|
||||
use crate::rbx::RobloxPartDescription;
|
||||
|
||||
fn read_entire_file(path:impl AsRef<std::path::Path>)->Result<Vec<u8>,std::io::Error>{
|
||||
let mut file=std::fs::File::open(path)?;
|
||||
@ -104,7 +104,7 @@ pub enum MeshType<'a>{
|
||||
mesh_data:&'a [u8],
|
||||
physics_data:&'a [u8],
|
||||
size_float_bits:[u32;3],
|
||||
part_texture_description:[Option<RobloxFaceTextureDescription>;6],
|
||||
part_texture_description:RobloxPartDescription,
|
||||
},
|
||||
}
|
||||
#[derive(Hash,Eq,PartialEq)]
|
||||
@ -124,7 +124,7 @@ impl MeshIndex<'_>{
|
||||
mesh_data:&'a [u8],
|
||||
physics_data:&'a [u8],
|
||||
size:&rbx_dom_weak::types::Vector3,
|
||||
part_texture_description:crate::rbx::RobloxPartDescription,
|
||||
part_texture_description:RobloxPartDescription,
|
||||
)->MeshIndex<'a>{
|
||||
MeshIndex{
|
||||
mesh_type:MeshType::Union{
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::rbx::{RobloxPartDescription,RobloxWedgeDescription,RobloxCornerWedgeDescription};
|
||||
use strafesnet_common::model::{Color4,TextureCoordinate,Mesh,IndexedGraphicsGroup,IndexedPhysicsGroup,IndexedVertex,PolygonGroupId,PolygonGroup,PolygonList,PositionId,TextureCoordinateId,NormalId,ColorId,VertexId,RenderConfigId};
|
||||
use strafesnet_common::integer::{vec3,Planar64Vec3};
|
||||
|
||||
@ -9,7 +10,22 @@ pub enum Primitives{
|
||||
Wedge,
|
||||
CornerWedge,
|
||||
}
|
||||
#[derive(Hash,PartialEq,Eq)]
|
||||
#[derive(Debug)]
|
||||
pub struct PrimitivesError;
|
||||
impl TryFrom<u32> for Primitives{
|
||||
type Error=PrimitivesError;
|
||||
fn try_from(value:u32)->Result<Self,Self::Error>{
|
||||
match value{
|
||||
0=>Ok(Primitives::Sphere),
|
||||
1=>Ok(Primitives::Cube),
|
||||
2=>Ok(Primitives::Cylinder),
|
||||
3=>Ok(Primitives::Wedge),
|
||||
4=>Ok(Primitives::CornerWedge),
|
||||
_=>Err(PrimitivesError),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone,Copy,Hash,PartialEq,Eq)]
|
||||
pub enum CubeFace{
|
||||
Right,
|
||||
Top,
|
||||
@ -18,6 +34,22 @@ pub enum CubeFace{
|
||||
Bottom,
|
||||
Front,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct CubeFaceError;
|
||||
impl TryFrom<u32> for CubeFace{
|
||||
type Error=CubeFaceError;
|
||||
fn try_from(value:u32)->Result<Self,Self::Error>{
|
||||
match value{
|
||||
0=>Ok(CubeFace::Right),
|
||||
1=>Ok(CubeFace::Top),
|
||||
2=>Ok(CubeFace::Back),
|
||||
3=>Ok(CubeFace::Left),
|
||||
4=>Ok(CubeFace::Bottom),
|
||||
5=>Ok(CubeFace::Front),
|
||||
_=>Err(CubeFaceError),
|
||||
}
|
||||
}
|
||||
}
|
||||
const CUBE_DEFAULT_TEXTURE_COORDS:[TextureCoordinate;4]=[
|
||||
TextureCoordinate::new(0.0,0.0),
|
||||
TextureCoordinate::new(1.0,0.0),
|
||||
@ -43,50 +75,34 @@ const CUBE_DEFAULT_NORMALS:[Planar64Vec3;6]=[
|
||||
vec3::int( 0, 0,-1),//CubeFace::Front
|
||||
];
|
||||
|
||||
#[derive(Hash,PartialEq,Eq)]
|
||||
pub enum WedgeFace{
|
||||
Right,
|
||||
TopFront,
|
||||
Back,
|
||||
Left,
|
||||
Bottom,
|
||||
}
|
||||
#[derive(Hash,PartialEq,Eq)]
|
||||
pub enum CornerWedgeFace{
|
||||
Right,
|
||||
TopBack,
|
||||
TopLeft,
|
||||
Bottom,
|
||||
Front,
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct CubeFaceDescription([Option<FaceDescription>;6]);
|
||||
pub struct CubeFaceDescription([FaceDescription;Self::FACES]);
|
||||
impl CubeFaceDescription{
|
||||
pub fn insert(&mut self,index:CubeFace,value:FaceDescription){
|
||||
self.0[index as usize]=Some(value);
|
||||
}
|
||||
pub fn pairs(self)->impl Iterator<Item=(usize,FaceDescription)>{
|
||||
self.0.into_iter().enumerate().filter_map(|(i,v)|v.map(|u|(i,u)))
|
||||
pub const FACES:usize=6;
|
||||
pub fn new(RobloxPartDescription(part_description):RobloxPartDescription,textureless_render_id:RenderConfigId)->Self{
|
||||
Self(part_description.map(|face_description|match face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
None=>FaceDescription::new_with_render_id(textureless_render_id),
|
||||
}))
|
||||
}
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct WedgeFaceDescription([Option<FaceDescription>;5]);
|
||||
pub struct WedgeFaceDescription([FaceDescription;Self::FACES]);
|
||||
impl WedgeFaceDescription{
|
||||
pub fn insert(&mut self,index:WedgeFace,value:FaceDescription){
|
||||
self.0[index as usize]=Some(value);
|
||||
}
|
||||
pub fn pairs(self)->std::iter::FilterMap<std::iter::Enumerate<std::array::IntoIter<Option<FaceDescription>,5>>,impl FnMut((usize,Option<FaceDescription>))->Option<(usize,FaceDescription)>>{
|
||||
self.0.into_iter().enumerate().filter_map(|v|v.1.map(|u|(v.0,u)))
|
||||
pub const FACES:usize=5;
|
||||
pub fn new(RobloxWedgeDescription(part_description):RobloxWedgeDescription,textureless_render_id:RenderConfigId)->Self{
|
||||
Self(part_description.map(|face_description|match face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
None=>FaceDescription::new_with_render_id(textureless_render_id),
|
||||
}))
|
||||
}
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct CornerWedgeFaceDescription([Option<FaceDescription>;5]);
|
||||
pub struct CornerWedgeFaceDescription([FaceDescription;Self::FACES]);
|
||||
impl CornerWedgeFaceDescription{
|
||||
pub fn insert(&mut self,index:CornerWedgeFace,value:FaceDescription){
|
||||
self.0[index as usize]=Some(value);
|
||||
}
|
||||
pub fn pairs(self)->std::iter::FilterMap<std::iter::Enumerate<std::array::IntoIter<Option<FaceDescription>,5>>,impl FnMut((usize,Option<FaceDescription>))->Option<(usize,FaceDescription)>>{
|
||||
self.0.into_iter().enumerate().filter_map(|v|v.1.map(|u|(v.0,u)))
|
||||
pub const FACES:usize=5;
|
||||
pub fn new(RobloxCornerWedgeDescription(part_description):RobloxCornerWedgeDescription,textureless_render_id:RenderConfigId)->Self{
|
||||
Self(part_description.map(|face_description|match face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
None=>FaceDescription::new_with_render_id(textureless_render_id),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +113,7 @@ pub struct FaceDescription{
|
||||
pub color:Color4,
|
||||
}
|
||||
impl FaceDescription{
|
||||
pub fn new_with_render_id(render:RenderConfigId)->Self {
|
||||
pub fn new_with_render_id(render:RenderConfigId)->Self{
|
||||
Self{
|
||||
render,
|
||||
transform:glam::Affine2::IDENTITY,
|
||||
@ -105,7 +121,7 @@ impl FaceDescription{
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->Mesh{
|
||||
pub fn generate_partial_unit_cube(CubeFaceDescription(face_descriptions):CubeFaceDescription)->Mesh{
|
||||
const CUBE_DEFAULT_POLYS:[[[u32;2];4];6]=[
|
||||
// right (1, 0, 0)
|
||||
[
|
||||
@ -160,7 +176,7 @@ pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->Mesh{
|
||||
let mut physics_group=IndexedPhysicsGroup::default();
|
||||
let mut transforms=Vec::new();
|
||||
//note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices.
|
||||
for (face_id,face_description) in face_descriptions.pairs(){
|
||||
for (face_id,face_description) in face_descriptions.into_iter().enumerate(){
|
||||
//assume that scanning short lists is faster than hashing.
|
||||
let transform_index=if let Some(transform_index)=transforms.iter().position(|&transform|transform==face_description.transform){
|
||||
transform_index
|
||||
@ -227,7 +243,7 @@ pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->Mesh{
|
||||
}
|
||||
}
|
||||
//don't think too hard about the copy paste because this is all going into the map tool eventually...
|
||||
pub fn generate_partial_unit_wedge(face_descriptions:WedgeFaceDescription)->Mesh{
|
||||
pub fn generate_partial_unit_wedge(WedgeFaceDescription(face_descriptions):WedgeFaceDescription)->Mesh{
|
||||
const WEDGE_DEFAULT_POLYS:[&[[u32;2]];5]=[
|
||||
// right (1, 0, 0)
|
||||
&[
|
||||
@ -280,7 +296,7 @@ pub fn generate_partial_unit_wedge(face_descriptions:WedgeFaceDescription)->Mesh
|
||||
let mut physics_group=IndexedPhysicsGroup::default();
|
||||
let mut transforms=Vec::new();
|
||||
//note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices.
|
||||
for (face_id,face_description) in face_descriptions.pairs(){
|
||||
for (face_id,face_description) in face_descriptions.into_iter().enumerate(){
|
||||
//assume that scanning short lists is faster than hashing.
|
||||
let transform_index=if let Some(transform_index)=transforms.iter().position(|&transform|transform==face_description.transform){
|
||||
transform_index
|
||||
@ -347,7 +363,7 @@ pub fn generate_partial_unit_wedge(face_descriptions:WedgeFaceDescription)->Mesh
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_partial_unit_cornerwedge(face_descriptions:CornerWedgeFaceDescription)->Mesh{
|
||||
pub fn generate_partial_unit_cornerwedge(CornerWedgeFaceDescription(face_descriptions):CornerWedgeFaceDescription)->Mesh{
|
||||
const CORNERWEDGE_DEFAULT_POLYS:[&[[u32;2]];5]=[
|
||||
// right (1, 0, 0)
|
||||
&[
|
||||
@ -398,7 +414,7 @@ pub fn generate_partial_unit_cornerwedge(face_descriptions:CornerWedgeFaceDescri
|
||||
let mut physics_group=IndexedPhysicsGroup::default();
|
||||
let mut transforms=Vec::new();
|
||||
//note that on a cube every vertex is guaranteed to be unique, so there's no need to hash them against existing vertices.
|
||||
for (face_id,face_description) in face_descriptions.pairs(){
|
||||
for (face_id,face_description) in face_descriptions.into_iter().enumerate(){
|
||||
//assume that scanning short lists is faster than hashing.
|
||||
let transform_index=if let Some(transform_index)=transforms.iter().position(|&transform|transform==face_description.transform){
|
||||
transform_index
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::loader::MeshIndex;
|
||||
use crate::primitives;
|
||||
use crate::primitives::{self,CubeFace,CubeFaceDescription,WedgeFaceDescription,CornerWedgeFaceDescription,FaceDescription,Primitives};
|
||||
use strafesnet_common::aabb::Aabb;
|
||||
use strafesnet_common::map;
|
||||
use strafesnet_common::model;
|
||||
@ -347,17 +347,40 @@ impl RobloxFaceTextureDescription{
|
||||
transform:self.transform.to_bits(),
|
||||
}
|
||||
}
|
||||
pub fn to_face_description(&self)->primitives::FaceDescription{
|
||||
primitives::FaceDescription{
|
||||
pub fn to_face_description(&self)->FaceDescription{
|
||||
FaceDescription{
|
||||
render:self.render,
|
||||
transform:self.transform.affine(),
|
||||
color:self.color,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub type RobloxPartDescription=[Option<RobloxFaceTextureDescription>;6];
|
||||
type RobloxWedgeDescription=[Option<RobloxFaceTextureDescription>;5];
|
||||
type RobloxCornerWedgeDescription=[Option<RobloxFaceTextureDescription>;5];
|
||||
macro_rules! impl_description_index{
|
||||
($description:ident,$index:ty)=>{
|
||||
impl core::ops::Index<$index> for $description{
|
||||
type Output=Option<RobloxFaceTextureDescription>;
|
||||
fn index(&self,index:$index)->&Self::Output{
|
||||
&self.0[index as usize]
|
||||
}
|
||||
}
|
||||
impl core::ops::IndexMut<$index> for $description{
|
||||
fn index_mut(&mut self,index:$index)->&mut Self::Output{
|
||||
&mut self.0[index as usize]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone,Default,Eq,Hash,PartialEq)]
|
||||
pub struct RobloxPartDescription(pub(crate)[Option<RobloxFaceTextureDescription>;6]);
|
||||
impl_description_index!(RobloxPartDescription,CubeFace);
|
||||
|
||||
#[derive(Clone,Default,Eq,Hash,PartialEq)]
|
||||
pub struct RobloxWedgeDescription(pub(crate)[Option<RobloxFaceTextureDescription>;5]);
|
||||
|
||||
#[derive(Clone,Default,Eq,Hash,PartialEq)]
|
||||
pub struct RobloxCornerWedgeDescription(pub(crate)[Option<RobloxFaceTextureDescription>;5]);
|
||||
|
||||
#[derive(Clone,Eq,Hash,PartialEq)]
|
||||
enum RobloxBasePartDescription{
|
||||
Sphere(RobloxPartDescription),
|
||||
@ -374,7 +397,7 @@ fn get_texture_description<'a>(
|
||||
size:&rbx_dom_weak::types::Vector3,
|
||||
)->RobloxPartDescription{
|
||||
//use the biggest one and cut it down later...
|
||||
let mut part_texture_description:RobloxPartDescription=[None,None,None,None,None,None];
|
||||
let mut part_texture_description=RobloxPartDescription::default();
|
||||
temp_objects.clear();
|
||||
recursive_collect_superclass(temp_objects,&dom,object,"Decal");
|
||||
for &mut decal_ref in temp_objects{
|
||||
@ -391,8 +414,7 @@ fn get_texture_description<'a>(
|
||||
decal.properties.get("Transparency"),
|
||||
) {
|
||||
let render_id=render_config_deferred_loader.acquire_render_config_id(Some(content.as_ref()));
|
||||
let normal_id=normalid.to_u32();
|
||||
if normal_id<6{
|
||||
if let Ok(cube_face)=normalid.to_u32().try_into(){
|
||||
let (roblox_texture_color,roblox_texture_transform)=if decal.class=="Texture"{
|
||||
//generate tranform
|
||||
if let (
|
||||
@ -407,14 +429,13 @@ fn get_texture_description<'a>(
|
||||
decal.properties.get("StudsPerTileV"),
|
||||
)
|
||||
{
|
||||
let (size_u,size_v)=match normal_id{
|
||||
0=>(size.z,size.y),//right
|
||||
1=>(size.x,size.z),//top
|
||||
2=>(size.x,size.y),//back
|
||||
3=>(size.z,size.y),//left
|
||||
4=>(size.x,size.z),//bottom
|
||||
5=>(size.x,size.y),//front
|
||||
_=>unreachable!(),
|
||||
let (size_u,size_v)=match cube_face{
|
||||
CubeFace::Right=>(size.z,size.y),//right
|
||||
CubeFace::Top=>(size.x,size.z),//top
|
||||
CubeFace::Back=>(size.x,size.y),//back
|
||||
CubeFace::Left=>(size.z,size.y),//left
|
||||
CubeFace::Bottom=>(size.x,size.z),//bottom
|
||||
CubeFace::Front=>(size.x,size.y),//front
|
||||
};
|
||||
(
|
||||
glam::vec4(decal_color3.r,decal_color3.g,decal_color3.b,1.0-*decal_transparency),
|
||||
@ -433,13 +454,13 @@ fn get_texture_description<'a>(
|
||||
}else{
|
||||
(glam::Vec4::ONE,RobloxTextureTransform::identity())
|
||||
};
|
||||
part_texture_description[normal_id as usize]=Some(RobloxFaceTextureDescription{
|
||||
part_texture_description[cube_face]=Some(RobloxFaceTextureDescription{
|
||||
render:render_id,
|
||||
color:roblox_texture_color,
|
||||
transform:roblox_texture_transform,
|
||||
});
|
||||
}else{
|
||||
println!("NormalId={} is invalid",normal_id);
|
||||
println!("NormalId is invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,7 +468,7 @@ fn get_texture_description<'a>(
|
||||
part_texture_description
|
||||
}
|
||||
enum Shape{
|
||||
Primitive(primitives::Primitives),
|
||||
Primitive(Primitives),
|
||||
MeshPart,
|
||||
PhysicsData,
|
||||
}
|
||||
@ -533,25 +554,18 @@ pub fn convert<'a>(
|
||||
//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"){
|
||||
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),
|
||||
})
|
||||
Shape::Primitive(shape.to_u32().try_into().expect("Funky roblox PartType"))
|
||||
}else{
|
||||
panic!("Part has no Shape!");
|
||||
},
|
||||
"TrussPart"=>Shape::Primitive(primitives::Primitives::Cube),
|
||||
"WedgePart"=>Shape::Primitive(primitives::Primitives::Wedge),
|
||||
"CornerWedgePart"=>Shape::Primitive(primitives::Primitives::CornerWedge),
|
||||
"TrussPart"=>Shape::Primitive(Primitives::Cube),
|
||||
"WedgePart"=>Shape::Primitive(Primitives::Wedge),
|
||||
"CornerWedgePart"=>Shape::Primitive(Primitives::CornerWedge),
|
||||
"MeshPart"=>Shape::MeshPart,
|
||||
"UnionOperation"=>Shape::PhysicsData,
|
||||
_=>{
|
||||
println!("Unsupported BasePart ClassName={}; defaulting to cube",object.class);
|
||||
Shape::Primitive(primitives::Primitives::Cube)
|
||||
Shape::Primitive(Primitives::Cube)
|
||||
}
|
||||
};
|
||||
|
||||
@ -560,34 +574,34 @@ pub fn convert<'a>(
|
||||
//TODO: TAB TAB
|
||||
let part_texture_description=get_texture_description(&mut temp_objects,render_config_deferred_loader,dom,object,size);
|
||||
//obscure rust syntax "slice pattern"
|
||||
let [
|
||||
let RobloxPartDescription([
|
||||
f0,//Cube::Right
|
||||
f1,//Cube::Top
|
||||
f2,//Cube::Back
|
||||
f3,//Cube::Left
|
||||
f4,//Cube::Bottom
|
||||
f5,//Cube::Front
|
||||
]=part_texture_description;
|
||||
])=part_texture_description;
|
||||
let basepart_description=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]),
|
||||
Primitives::Sphere=>RobloxBasePartDescription::Sphere(RobloxPartDescription([f0,f1,f2,f3,f4,f5])),
|
||||
Primitives::Cube=>RobloxBasePartDescription::Part(RobloxPartDescription([f0,f1,f2,f3,f4,f5])),
|
||||
Primitives::Cylinder=>RobloxBasePartDescription::Cylinder(RobloxPartDescription([f0,f1,f2,f3,f4,f5])),
|
||||
//use front face texture first and use top face texture as a fallback
|
||||
primitives::Primitives::Wedge=>RobloxBasePartDescription::Wedge([
|
||||
Primitives::Wedge=>RobloxBasePartDescription::Wedge(RobloxWedgeDescription([
|
||||
f0,//Cube::Right->Wedge::Right
|
||||
f5.or(f1),//Cube::Front|Cube::Top->Wedge::TopFront
|
||||
f2,//Cube::Back->Wedge::Back
|
||||
f3,//Cube::Left->Wedge::Left
|
||||
f4,//Cube::Bottom->Wedge::Bottom
|
||||
]),
|
||||
])),
|
||||
//TODO: fix Left+Back texture coordinates to match roblox when not overwridden by Top
|
||||
primitives::Primitives::CornerWedge=>RobloxBasePartDescription::CornerWedge([
|
||||
Primitives::CornerWedge=>RobloxBasePartDescription::CornerWedge(RobloxCornerWedgeDescription([
|
||||
f0,//Cube::Right->CornerWedge::Right
|
||||
f2.or(f1.clone()),//Cube::Back|Cube::Top->CornerWedge::TopBack
|
||||
f3.or(f1),//Cube::Left|Cube::Top->CornerWedge::TopLeft
|
||||
f4,//Cube::Bottom->CornerWedge::Bottom
|
||||
f5,//Cube::Front->CornerWedge::Front
|
||||
]),
|
||||
])),
|
||||
};
|
||||
//make new model if unit cube has not been created before
|
||||
let mesh_id=if let Some(&mesh_id)=mesh_id_from_description.get(&basepart_description){
|
||||
@ -599,64 +613,9 @@ pub fn convert<'a>(
|
||||
let mesh=match basepart_description{
|
||||
RobloxBasePartDescription::Sphere(part_texture_description)
|
||||
|RobloxBasePartDescription::Cylinder(part_texture_description)
|
||||
|RobloxBasePartDescription::Part(part_texture_description)=>{
|
||||
let mut cube_face_description=primitives::CubeFaceDescription::default();
|
||||
for (face_id,roblox_face_description) in part_texture_description.iter().enumerate(){
|
||||
cube_face_description.insert(
|
||||
match face_id{
|
||||
0=>primitives::CubeFace::Right,
|
||||
1=>primitives::CubeFace::Top,
|
||||
2=>primitives::CubeFace::Back,
|
||||
3=>primitives::CubeFace::Left,
|
||||
4=>primitives::CubeFace::Bottom,
|
||||
5=>primitives::CubeFace::Front,
|
||||
_=>unreachable!(),
|
||||
},
|
||||
match roblox_face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
None=>primitives::FaceDescription::new_with_render_id(textureless_render_group),
|
||||
});
|
||||
}
|
||||
primitives::generate_partial_unit_cube(cube_face_description)
|
||||
},
|
||||
RobloxBasePartDescription::Wedge(wedge_texture_description)=>{
|
||||
let mut wedge_face_description=primitives::WedgeFaceDescription::default();
|
||||
for (face_id,roblox_face_description) in wedge_texture_description.iter().enumerate(){
|
||||
wedge_face_description.insert(
|
||||
match face_id{
|
||||
0=>primitives::WedgeFace::Right,
|
||||
1=>primitives::WedgeFace::TopFront,
|
||||
2=>primitives::WedgeFace::Back,
|
||||
3=>primitives::WedgeFace::Left,
|
||||
4=>primitives::WedgeFace::Bottom,
|
||||
_=>unreachable!(),
|
||||
},
|
||||
match roblox_face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
None=>primitives::FaceDescription::new_with_render_id(textureless_render_group),
|
||||
});
|
||||
}
|
||||
primitives::generate_partial_unit_wedge(wedge_face_description)
|
||||
},
|
||||
RobloxBasePartDescription::CornerWedge(cornerwedge_texture_description)=>{
|
||||
let mut cornerwedge_face_description=primitives::CornerWedgeFaceDescription::default();
|
||||
for (face_id,roblox_face_description) in cornerwedge_texture_description.iter().enumerate(){
|
||||
cornerwedge_face_description.insert(
|
||||
match face_id{
|
||||
0=>primitives::CornerWedgeFace::Right,
|
||||
1=>primitives::CornerWedgeFace::TopBack,
|
||||
2=>primitives::CornerWedgeFace::TopLeft,
|
||||
3=>primitives::CornerWedgeFace::Bottom,
|
||||
4=>primitives::CornerWedgeFace::Front,
|
||||
_=>unreachable!(),
|
||||
},
|
||||
match roblox_face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
None=>primitives::FaceDescription::new_with_render_id(textureless_render_group),
|
||||
});
|
||||
}
|
||||
primitives::generate_partial_unit_cornerwedge(cornerwedge_face_description)
|
||||
},
|
||||
|RobloxBasePartDescription::Part(part_texture_description)=>primitives::generate_partial_unit_cube(CubeFaceDescription::new(part_texture_description,textureless_render_group)),
|
||||
RobloxBasePartDescription::Wedge(wedge_texture_description)=>primitives::generate_partial_unit_wedge(WedgeFaceDescription::new(wedge_texture_description,textureless_render_group)),
|
||||
RobloxBasePartDescription::CornerWedge(cornerwedge_texture_description)=>primitives::generate_partial_unit_cornerwedge(CornerWedgeFaceDescription::new(cornerwedge_texture_description,textureless_render_group)),
|
||||
};
|
||||
primitive_meshes.push(mesh);
|
||||
mesh_id
|
||||
@ -768,7 +727,7 @@ fn acquire_union_id_from_render_config_id<'a>(
|
||||
let union_id=model::MeshId::new(primitive_meshes.len() as u32);
|
||||
let mut union_clone=union_with_aabb.mesh.clone();
|
||||
//set the render groups
|
||||
for (graphics_group,maybe_face_texture_description) in union_clone.graphics_groups.iter_mut().zip(part_texture_description){
|
||||
for (graphics_group,maybe_face_texture_description) in union_clone.graphics_groups.iter_mut().zip(part_texture_description.0){
|
||||
if let Some(face_texture_description)=maybe_face_texture_description{
|
||||
graphics_group.render=face_texture_description.render;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ pub fn convert(
|
||||
roblox_physics_data:&[u8],
|
||||
roblox_mesh_data:&[u8],
|
||||
size:glam::Vec3,
|
||||
part_texture_description:crate::rbx::RobloxPartDescription,
|
||||
crate::rbx::RobloxPartDescription(part_texture_description):crate::rbx::RobloxPartDescription,
|
||||
)->Result<model::Mesh,Error>{
|
||||
const NORMAL_FACES:usize=6;
|
||||
let mut polygon_groups_normal_id=vec![Vec::new();NORMAL_FACES];
|
||||
|
Loading…
x
Reference in New Issue
Block a user