rbx_loader: implement roblox cylinder
This commit is contained in:
parent
2ed01dffbd
commit
39b2397d5e
lib/rbx_loader/src
@ -1,6 +1,6 @@
|
||||
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};
|
||||
use strafesnet_common::model::{Color4,TextureCoordinate,Mesh,MeshBuilder,IndexedGraphicsGroup,IndexedPhysicsGroup,IndexedVertex,PolygonGroupId,PolygonGroup,PolygonList,PositionId,TextureCoordinateId,NormalId,ColorId,VertexId,RenderConfigId};
|
||||
use strafesnet_common::integer::{vec3,Planar64,Planar64Vec3};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Primitives{
|
||||
@ -480,3 +480,132 @@ pub fn generate_partial_unit_cornerwedge(CornerWedgeFaceDescription(face_descrip
|
||||
physics_groups:vec![physics_group],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_partial_cylinder(face_descriptions:CubeFaceDescription)->Mesh{
|
||||
// cylinder is oriented about the x axis
|
||||
// roblox cylinders use projected grid coordinates
|
||||
/// how many grid coordinates to use (positive and negative)
|
||||
const GON:i32=3;
|
||||
/// grid perimeter
|
||||
const POINTS:[[i32;2];4*2*GON as usize]=const{
|
||||
let mut points=[[0;2];{4*2*GON as usize}];
|
||||
let mut i=-GON;
|
||||
while i<GON{
|
||||
points[(i+GON) as usize]=[i,GON];
|
||||
points[(i+GON+1*2*GON) as usize]=[GON,-i];
|
||||
points[(i+GON+2*2*GON) as usize]=[-i,-GON];
|
||||
points[(i+GON+3*2*GON) as usize]=[-GON,i];
|
||||
i+=1;
|
||||
}
|
||||
points
|
||||
};
|
||||
|
||||
let mut mb=MeshBuilder::new();
|
||||
let mut polygon_groups=Vec::with_capacity(CubeFaceDescription::FACES);
|
||||
let mut graphics_groups=Vec::with_capacity(CubeFaceDescription::FACES);
|
||||
let mut physics_group=IndexedPhysicsGroup{groups:Vec::with_capacity(CubeFaceDescription::FACES)};
|
||||
let CubeFaceDescription([right,top,back,left,bottom,front])=face_descriptions;
|
||||
|
||||
macro_rules! end_face{
|
||||
($face_description:expr,$end:expr,$iter:expr)=>{
|
||||
let normal=mb.acquire_normal_id($end);
|
||||
let color=mb.acquire_color_id($face_description.color);
|
||||
|
||||
// single polygon for physics
|
||||
let polygon:Vec<_>=$iter.map(|[x,y]|{
|
||||
let tex=mb.acquire_tex_id(
|
||||
$face_description.transform.transform_point2(
|
||||
(glam::vec2(-x as f32,y as f32).normalize()+1.0)/2.0
|
||||
)
|
||||
);
|
||||
let pos=mb.acquire_pos_id($end+vec3::int(0,-x,y).with_length(Planar64::ONE).divide().wrap_1());
|
||||
mb.acquire_vertex_id(IndexedVertex{pos,tex,normal,color})
|
||||
}).collect();
|
||||
|
||||
// fanned polygons for graphics
|
||||
let pos=mb.acquire_pos_id($end);
|
||||
let tex=mb.acquire_tex_id($face_description.transform.transform_point2(glam::Vec2::ONE/2.0));
|
||||
let center=mb.acquire_vertex_id(IndexedVertex{pos,tex,normal,color});
|
||||
let polygon_list=(0..POINTS.len()).map(|i|
|
||||
vec![center,polygon[i],polygon[(i+1)%POINTS.len()]]
|
||||
).collect();
|
||||
|
||||
// end face graphics
|
||||
let group_id=PolygonGroupId::new(polygon_groups.len() as u32);
|
||||
polygon_groups.push(PolygonGroup::PolygonList(PolygonList::new(polygon_list)));
|
||||
graphics_groups.push(IndexedGraphicsGroup{
|
||||
render:$face_description.render,
|
||||
groups:vec![group_id],
|
||||
});
|
||||
|
||||
// end face physics
|
||||
let polygon_list=vec![polygon];
|
||||
|
||||
let group_id=PolygonGroupId::new(polygon_groups.len() as u32);
|
||||
polygon_groups.push(PolygonGroup::PolygonList(PolygonList::new(polygon_list)));
|
||||
physics_group.groups.push(group_id);
|
||||
}
|
||||
}
|
||||
macro_rules! tex{
|
||||
($face_description:expr,$tex:expr)=>{{
|
||||
let [x,y]=$tex;
|
||||
$face_description.transform.transform_point2(
|
||||
glam::vec2((x+GON) as f32,(y+GON) as f32)/(2*GON) as f32
|
||||
)
|
||||
}};
|
||||
}
|
||||
macro_rules! barrel_face{
|
||||
($face_description:expr,$loop:ident,$lo_dir:expr,$hi_dir:expr,$tex_0:expr,$tex_1:expr,$tex_2:expr,$tex_3:expr)=>{
|
||||
let mut polygon_list=Vec::with_capacity(CubeFaceDescription::FACES);
|
||||
for $loop in -GON..GON{
|
||||
// lo Z
|
||||
let lz_dir=$lo_dir.with_length(Planar64::ONE).divide().wrap_1();
|
||||
// hi Z
|
||||
let hz_dir=$hi_dir.with_length(Planar64::ONE).divide().wrap_1();
|
||||
|
||||
// pos
|
||||
let lx_lz_pos=mb.acquire_pos_id(vec3::NEG_X+lz_dir);
|
||||
let lx_hz_pos=mb.acquire_pos_id(vec3::NEG_X+hz_dir);
|
||||
let hx_hz_pos=mb.acquire_pos_id(vec3::X+hz_dir);
|
||||
let hx_lz_pos=mb.acquire_pos_id(vec3::X+lz_dir);
|
||||
// tex
|
||||
let lx_lz_tex=mb.acquire_tex_id(tex!($face_description,$tex_0));
|
||||
let lx_hz_tex=mb.acquire_tex_id(tex!($face_description,$tex_1));
|
||||
let hx_hz_tex=mb.acquire_tex_id(tex!($face_description,$tex_2));
|
||||
let hx_lz_tex=mb.acquire_tex_id(tex!($face_description,$tex_3));
|
||||
// norm
|
||||
let lz_norm=mb.acquire_normal_id(lz_dir);
|
||||
let hz_norm=mb.acquire_normal_id(hz_dir);
|
||||
// color
|
||||
let color=mb.acquire_color_id($face_description.color);
|
||||
|
||||
polygon_list.push(vec![
|
||||
mb.acquire_vertex_id(IndexedVertex{pos:lx_lz_pos,tex:lx_lz_tex,normal:lz_norm,color}),
|
||||
mb.acquire_vertex_id(IndexedVertex{pos:lx_hz_pos,tex:lx_hz_tex,normal:hz_norm,color}),
|
||||
mb.acquire_vertex_id(IndexedVertex{pos:hx_hz_pos,tex:hx_hz_tex,normal:hz_norm,color}),
|
||||
mb.acquire_vertex_id(IndexedVertex{pos:hx_lz_pos,tex:hx_lz_tex,normal:lz_norm,color}),
|
||||
]);
|
||||
}
|
||||
|
||||
// push face
|
||||
let group_id=PolygonGroupId::new(polygon_groups.len() as u32);
|
||||
polygon_groups.push(PolygonGroup::PolygonList(PolygonList::new(polygon_list)));
|
||||
graphics_groups.push(IndexedGraphicsGroup{
|
||||
render:$face_description.render,
|
||||
groups:vec![group_id],
|
||||
});
|
||||
physics_group.groups.push(group_id);
|
||||
};
|
||||
}
|
||||
|
||||
end_face!(right, vec3::X,POINTS.into_iter());
|
||||
barrel_face!(top, z,vec3::int(0,GON,z),vec3::int(0,GON,z+1), [GON,z],[GON,z+1],[-GON,z+1],[-GON,z]);
|
||||
barrel_face!(back, y,vec3::int(0,y+1,GON),vec3::int(0,y,GON), [GON,y+1],[GON,y],[-GON,y],[-GON,y+1]);
|
||||
end_face!(left, vec3::NEG_X,POINTS.into_iter().rev());
|
||||
barrel_face!(bottom, z,vec3::int(0,-GON,z+1),vec3::int(0,-GON,z), [-GON,z+1],[-GON,z],[GON,z],[GON,z+1]);
|
||||
barrel_face!(front, y,vec3::int(0,y,-GON),vec3::int(0,y+1,-GON), [-GON,y],[-GON,y+1],[GON,y+1],[GON,y]);
|
||||
|
||||
let physics_groups=vec![physics_group];
|
||||
|
||||
mb.build(polygon_groups,graphics_groups,physics_groups)
|
||||
}
|
||||
|
@ -611,8 +611,8 @@ pub fn convert<'a>(
|
||||
let mesh_id=model::MeshId::new(primitive_meshes.len() as u32);
|
||||
mesh_id_from_description.insert(basepart_description.clone(),mesh_id);//borrow checker going crazy
|
||||
let mesh=match basepart_description{
|
||||
RobloxBasePartDescription::Cylinder(part_texture_description)=>primitives::generate_partial_cylinder(CubeFaceDescription::new(part_texture_description,textureless_render_group)),
|
||||
RobloxBasePartDescription::Sphere(part_texture_description)
|
||||
|RobloxBasePartDescription::Cylinder(part_texture_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)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user