forked from StrafesNET/strafe-client
umm wend
This commit is contained in:
parent
5cd40afa56
commit
92bbbce1c3
@ -86,12 +86,30 @@ impl std::hash::Hash for RobloxFaceTextureDescription {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl RobloxFaceTextureDescription{
|
||||
fn to_face_description(&self)->primitives::FaceDescription{
|
||||
primitives::FaceDescription{
|
||||
texture:Some(self.texture),
|
||||
transform:glam::Affine2::from_translation(
|
||||
glam::vec2(self.transform.offset_u,self.transform.offset_v)
|
||||
)
|
||||
*glam::Affine2::from_scale(
|
||||
glam::vec2(self.transform.scale_u,self.transform.scale_v)
|
||||
),
|
||||
color:self.color,
|
||||
}
|
||||
}
|
||||
}
|
||||
type RobloxPartDescription=[Option<RobloxFaceTextureDescription>;6];
|
||||
//type RobloxWedgeDescription=[Option<RobloxFaceTextureDescription>;5];
|
||||
type RobloxWedgeDescription=[Option<RobloxFaceTextureDescription>;5];
|
||||
type RobloxCornerWedgeDescription=[Option<RobloxFaceTextureDescription>;4];
|
||||
#[derive(Clone,Eq,Hash,PartialEq)]
|
||||
enum RobloxBasePartDescription{
|
||||
Sphere,
|
||||
Part(RobloxPartDescription),
|
||||
//Wedge(RobloxWedgeDescription),
|
||||
Cylinder,
|
||||
Wedge(RobloxWedgeDescription),
|
||||
CornerWedge(RobloxCornerWedgeDescription),
|
||||
}
|
||||
pub fn generate_indexed_models_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(IndexedModelInstances,glam::Vec3), Box<dyn std::error::Error>>{
|
||||
//IndexedModelInstances includes textures
|
||||
@ -139,13 +157,55 @@ pub fn generate_indexed_models_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(Inde
|
||||
spawn_point=model_transform.transform_point3(glam::Vec3::Y)+glam::vec3(0.0,2.5,0.0);
|
||||
println!("Found MapStart{:?}",spawn_point);
|
||||
}
|
||||
if *transparency==1.0||shape.to_u32()!=1 {
|
||||
if *transparency==1.0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let shape=match shape.to_u32(){
|
||||
0=>primitives::Primitives::Sphere,
|
||||
1=>primitives::Primitives::Cube,
|
||||
2=>primitives::Primitives::Cylinder,
|
||||
3=>primitives::Primitives::Wedge,
|
||||
4=>primitives::Primitives::CornerWedge,
|
||||
_=>panic!("funky roblox PartType={}",shape.to_u32()),
|
||||
};
|
||||
|
||||
//TODO: also detect "CylinderMesh" etc here
|
||||
let mut face_map=std::collections::HashMap::new();
|
||||
match shape{
|
||||
primitives::Primitives::Cube => {
|
||||
face_map.insert(0,0);//Right
|
||||
face_map.insert(1,1);//Top
|
||||
face_map.insert(2,2);//Back
|
||||
face_map.insert(3,3);//Left
|
||||
face_map.insert(4,4);//Bottom
|
||||
face_map.insert(5,5);//Front
|
||||
},
|
||||
primitives::Primitives::Wedge => {
|
||||
face_map.insert(0,0);//Right
|
||||
face_map.insert(1,1);//Top -> TopFront (some surf maps put surf textures on the Top face)
|
||||
face_map.insert(2,1);//Front -> TopFront
|
||||
face_map.insert(3,2);//Back
|
||||
face_map.insert(4,3);//Left
|
||||
face_map.insert(5,4);//Bottom
|
||||
},
|
||||
primitives::Primitives::CornerWedge => {
|
||||
//Right -> None
|
||||
face_map.insert(1,0);//Top
|
||||
//Back -> None
|
||||
face_map.insert(3,1);//Right
|
||||
face_map.insert(4,2);//Bottom
|
||||
face_map.insert(5,3);//Front
|
||||
},
|
||||
//do not support textured spheres/cylinders imported from roblox
|
||||
//this can be added later, there are some maps that use it
|
||||
primitives::Primitives::Sphere
|
||||
|primitives::Primitives::Cylinder => (),
|
||||
}
|
||||
//use the biggest one and cut it down later...
|
||||
let mut part_texture_description:RobloxPartDescription=[None,None,None,None,None,None];
|
||||
temp_objects.clear();
|
||||
recursive_collect_superclass(&mut temp_objects, &dom, object,"Decal");
|
||||
|
||||
let mut part_texture_description:RobloxPartDescription=[None,None,None,None,None,None];
|
||||
for &decal_ref in &temp_objects{
|
||||
if let Some(decal)=dom.get_by_ref(decal_ref){
|
||||
if let (
|
||||
@ -168,8 +228,8 @@ pub fn generate_indexed_models_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(Inde
|
||||
asset_id_from_texture_id.push(asset_id.0);
|
||||
texture_id
|
||||
};
|
||||
let face=normalid.to_u32();
|
||||
if face<6{
|
||||
let normal_id=normalid.to_u32();
|
||||
if let Some(&face)=face_map.get(&normal_id){
|
||||
let mut roblox_texture_transform=RobloxTextureTransform::default();
|
||||
let mut roblox_texture_color=glam::Vec4::ONE;
|
||||
if decal.class=="Texture"{
|
||||
@ -186,7 +246,7 @@ pub fn generate_indexed_models_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(Inde
|
||||
decal.properties.get("StudsPerTileV"),
|
||||
)
|
||||
{
|
||||
let (size_u,size_v)=match face{
|
||||
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
|
||||
@ -202,20 +262,28 @@ pub fn generate_indexed_models_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(Inde
|
||||
roblox_texture_color=glam::vec4(decal_color3.r,decal_color3.g,decal_color3.b,1.0-*decal_transparency);
|
||||
}
|
||||
}
|
||||
part_texture_description[face as usize]=Some(RobloxFaceTextureDescription{
|
||||
part_texture_description[face]=Some(RobloxFaceTextureDescription{
|
||||
texture:texture_id,
|
||||
color:roblox_texture_color,
|
||||
transform:roblox_texture_transform,
|
||||
});
|
||||
}else{
|
||||
println!("goofy ahh roblox gave NormalId {}", face);
|
||||
println!("NormalId={} unsupported for shape={:?}",normal_id,shape);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO: generate unit Block, Wedge, etc. based on part shape lists
|
||||
let basepart_texture_description=RobloxBasePartDescription::Part(part_texture_description);
|
||||
//obscure rust syntax "slice pattern"
|
||||
let [f0,f1,f2,f3,f4,f5]=part_texture_description;
|
||||
let basepart_texture_description=match shape{
|
||||
primitives::Primitives::Sphere=>RobloxBasePartDescription::Sphere,
|
||||
primitives::Primitives::Cube=>RobloxBasePartDescription::Part([f0,f1,f2,f3,f4,f5]),
|
||||
primitives::Primitives::Cylinder=>RobloxBasePartDescription::Cylinder,
|
||||
//HAHAHA
|
||||
primitives::Primitives::Wedge=>RobloxBasePartDescription::Wedge([f0,f1,f2,f3,f4]),
|
||||
primitives::Primitives::CornerWedge=>RobloxBasePartDescription::CornerWedge([f0,f1,f2,f3]),
|
||||
};
|
||||
//make new model if unit cube has not been crated before
|
||||
let model_id=if let Some(&model_id)=model_id_from_description.get(&basepart_texture_description){
|
||||
//push to existing texture model
|
||||
@ -223,30 +291,68 @@ pub fn generate_indexed_models_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(Inde
|
||||
}else{
|
||||
let model_id=indexed_models.len();
|
||||
model_id_from_description.insert(basepart_texture_description.clone(),model_id);//borrow checker going crazy
|
||||
match basepart_texture_description{
|
||||
indexed_models.push(match basepart_texture_description{
|
||||
RobloxBasePartDescription::Sphere=>primitives::unit_sphere(),
|
||||
RobloxBasePartDescription::Part(part_texture_description)=>{
|
||||
let unit_cube_faces=part_texture_description.map(|face|{
|
||||
match face{
|
||||
Some(roblox_texture_transform)=>Some(
|
||||
primitives::FaceDescription{
|
||||
texture:Some(roblox_texture_transform.texture),
|
||||
transform:glam::Affine2::from_translation(
|
||||
glam::vec2(roblox_texture_transform.transform.offset_u,roblox_texture_transform.transform.offset_v)
|
||||
)
|
||||
*glam::Affine2::from_scale(
|
||||
glam::vec2(roblox_texture_transform.transform.scale_u,roblox_texture_transform.transform.scale_v)
|
||||
),
|
||||
color:roblox_texture_transform.color,
|
||||
}
|
||||
),
|
||||
None=>Some(primitives::FaceDescription::default()),
|
||||
}
|
||||
});
|
||||
let indexed_model=primitives::generate_partial_unit_cube(unit_cube_faces);
|
||||
indexed_models.push(indexed_model);
|
||||
model_id
|
||||
let mut cube_face_description=primitives::CubeFaceDescription::new();
|
||||
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,
|
||||
_=>panic!("unreachable"),
|
||||
},
|
||||
match roblox_face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
None=>primitives::FaceDescription::default(),
|
||||
});
|
||||
}
|
||||
primitives::generate_partial_unit_cube(cube_face_description)
|
||||
},
|
||||
}
|
||||
RobloxBasePartDescription::Cylinder=>primitives::unit_cylinder(),
|
||||
RobloxBasePartDescription::Wedge(wedge_texture_description)=>{
|
||||
let mut wedge_face_description=primitives::WedgeFaceDescription::new();
|
||||
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,
|
||||
_=>panic!("unreachable"),
|
||||
},
|
||||
match roblox_face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
None=>primitives::FaceDescription::default(),
|
||||
});
|
||||
}
|
||||
primitives::generate_partial_unit_wedge(wedge_face_description)
|
||||
},
|
||||
RobloxBasePartDescription::CornerWedge(cornerwedge_texture_description)=>{
|
||||
let mut cornerwedge_face_description=primitives::CornerWedgeFaceDescription::new();
|
||||
for (face_id,roblox_face_description) in cornerwedge_texture_description.iter().enumerate(){
|
||||
cornerwedge_face_description.insert(
|
||||
match face_id{
|
||||
0=>primitives::CornerWedgeFace::Top,
|
||||
1=>primitives::CornerWedgeFace::Right,
|
||||
2=>primitives::CornerWedgeFace::Bottom,
|
||||
3=>primitives::CornerWedgeFace::Front,
|
||||
_=>panic!("unreachable"),
|
||||
},
|
||||
match roblox_face_description{
|
||||
Some(roblox_texture_transform)=>roblox_texture_transform.to_face_description(),
|
||||
None=>primitives::FaceDescription::default(),
|
||||
});
|
||||
}
|
||||
primitives::generate_partial_unit_cornerwedge(cornerwedge_face_description)
|
||||
},
|
||||
});
|
||||
model_id
|
||||
};
|
||||
indexed_models[model_id].instances.push(ModelInstance {
|
||||
transform:model_transform,
|
||||
|
@ -197,6 +197,7 @@ impl GraphicsData {
|
||||
let mut vertices = Vec::new();
|
||||
let mut index_from_vertex = std::collections::HashMap::new();//::<IndexedVertex,usize>
|
||||
let mut entities = Vec::new();
|
||||
//TODO: combine groups using the same render pattern
|
||||
for group in model.groups {
|
||||
let mut indices = Vec::new();
|
||||
for poly in group.polys {
|
||||
@ -355,9 +356,9 @@ impl framework::Example for GraphicsData {
|
||||
) -> Self {
|
||||
let mut indexed_models = Vec::new();
|
||||
indexed_models.append(&mut model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/teslacyberv3.0.obj")[..]).unwrap(),*glam::Vec4::ONE.as_ref()));
|
||||
indexed_models.append(&mut model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/suzanne.obj")[..]).unwrap(),*glam::Vec4::ONE.as_ref()));
|
||||
indexed_models.append(&mut model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/teapot.obj")[..]).unwrap(),*glam::Vec4::ONE.as_ref()));
|
||||
indexed_models.push(primitives::the_unit_cube_lol());
|
||||
indexed_models.push(primitives::unit_sphere());
|
||||
indexed_models.push(primitives::unit_cylinder());
|
||||
indexed_models.push(primitives::unit_cube());
|
||||
println!("models.len = {:?}", indexed_models.len());
|
||||
indexed_models[0].instances.push(ModelInstance{
|
||||
transform:glam::Affine3A::from_translation(glam::vec3(10.,0.,-10.)),
|
||||
@ -382,7 +383,7 @@ impl framework::Example for GraphicsData {
|
||||
});
|
||||
//teapot
|
||||
indexed_models[2].instances.push(ModelInstance{
|
||||
transform:glam::Affine3A::from_translation(glam::vec3(-10.,5.,10.)),
|
||||
transform:glam::Affine3A::from_scale_rotation_translation(glam::vec3(0.5, 1.0, 0.2),glam::quat(-0.22248298016985793,-0.839457167990537,-0.05603504040830783,-0.49261857546227916),glam::vec3(-10.,7.,10.)),
|
||||
color:glam::Vec4::ONE,
|
||||
});
|
||||
//ground
|
||||
|
@ -1,5 +1,22 @@
|
||||
use crate::model::{IndexedModel, IndexedPolygon, IndexedGroup, IndexedVertex};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Primitives{
|
||||
Sphere,
|
||||
Cube,
|
||||
Cylinder,
|
||||
Wedge,
|
||||
CornerWedge,
|
||||
}
|
||||
#[derive(Hash,PartialEq,Eq)]
|
||||
pub enum CubeFace{
|
||||
Right,
|
||||
Top,
|
||||
Back,
|
||||
Left,
|
||||
Bottom,
|
||||
Front,
|
||||
}
|
||||
const CUBE_DEFAULT_TEXTURE_COORDS:[[f32;2];4]=[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0]];
|
||||
const CUBE_DEFAULT_VERTICES:[[f32;3];8]=[
|
||||
[-1.,-1., 1.],//0 left bottom back
|
||||
@ -12,12 +29,12 @@ const CUBE_DEFAULT_VERTICES:[[f32;3];8]=[
|
||||
[-1.,-1.,-1.],//7 left bottom front
|
||||
];
|
||||
const CUBE_DEFAULT_NORMALS:[[f32;3];6]=[
|
||||
[ 1., 0., 0.],//AabbFace::Right
|
||||
[ 0., 1., 0.],//AabbFace::Top
|
||||
[ 0., 0., 1.],//AabbFace::Back
|
||||
[-1., 0., 0.],//AabbFace::Left
|
||||
[ 0.,-1., 0.],//AabbFace::Bottom
|
||||
[ 0., 0.,-1.],//AabbFace::Front
|
||||
[ 1., 0., 0.],//CubeFace::Right
|
||||
[ 0., 1., 0.],//CubeFace::Top
|
||||
[ 0., 0., 1.],//CubeFace::Back
|
||||
[-1., 0., 0.],//CubeFace::Left
|
||||
[ 0.,-1., 0.],//CubeFace::Bottom
|
||||
[ 0., 0.,-1.],//CubeFace::Front
|
||||
];
|
||||
const CUBE_DEFAULT_POLYS:[[[u32;3];4];6]=[
|
||||
// right (1, 0, 0)
|
||||
@ -63,8 +80,93 @@ const CUBE_DEFAULT_POLYS:[[[u32;3];4];6]=[
|
||||
[7,2,5],
|
||||
],
|
||||
];
|
||||
pub fn the_unit_cube_lol() -> crate::model::IndexedModel{
|
||||
generate_partial_unit_cube([Some(FaceDescription::default());6])
|
||||
|
||||
#[derive(Hash,PartialEq,Eq)]
|
||||
pub enum WedgeFace{
|
||||
Right,
|
||||
TopFront,
|
||||
Back,
|
||||
Left,
|
||||
Bottom,
|
||||
}
|
||||
const WEDGE_DEFAULT_NORMALS:[[f32;3];5]=[
|
||||
[ 1., 0., 0.],//Wedge::Right
|
||||
[ 0., 1.,-1.],//Wedge::TopFront
|
||||
[ 0., 0., 1.],//Wedge::Back
|
||||
[-1., 0., 0.],//Wedge::Left
|
||||
[ 0.,-1., 0.],//Wedge::Bottom
|
||||
];
|
||||
/*
|
||||
local cornerWedgeVerticies = {
|
||||
Vector3.new(-1/2,-1/2,-1/2),7
|
||||
Vector3.new(-1/2,-1/2, 1/2),0
|
||||
Vector3.new( 1/2,-1/2,-1/2),6
|
||||
Vector3.new( 1/2,-1/2, 1/2),1
|
||||
Vector3.new( 1/2, 1/2,-1/2),5
|
||||
}
|
||||
*/
|
||||
#[derive(Hash,PartialEq,Eq)]
|
||||
pub enum CornerWedgeFace{
|
||||
Top,
|
||||
Right,
|
||||
Bottom,
|
||||
Front,
|
||||
}
|
||||
const CORNERWEDGE_DEFAULT_NORMALS:[[f32;3];5]=[
|
||||
[ 1., 0., 0.],//Wedge::Right
|
||||
[ 0., 1., 1.],//Wedge::BackTop
|
||||
[-1., 1., 0.],//Wedge::LeftTop
|
||||
[ 0.,-1., 0.],//Wedge::Bottom
|
||||
[ 0., 0.,-1.],//Wedge::Front
|
||||
];
|
||||
//HashMap fits this use case perfectly but feels like using a sledgehammer to drive a nail
|
||||
pub fn unit_sphere()->crate::model::IndexedModel{
|
||||
let mut indexed_model=crate::model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/suzanne.obj")[..]).unwrap(),*glam::Vec4::ONE.as_ref()).remove(0);
|
||||
for pos in indexed_model.unique_pos.iter_mut(){
|
||||
pos[0]=pos[0]*0.5;
|
||||
pos[1]=pos[1]*0.5;
|
||||
pos[2]=pos[2]*0.5;
|
||||
}
|
||||
indexed_model
|
||||
}
|
||||
pub type CubeFaceDescription=std::collections::HashMap::<CubeFace,FaceDescription>;
|
||||
pub fn unit_cube()->crate::model::IndexedModel{
|
||||
let mut t=CubeFaceDescription::new();
|
||||
t.insert(CubeFace::Right,FaceDescription::default());
|
||||
t.insert(CubeFace::Top,FaceDescription::default());
|
||||
t.insert(CubeFace::Back,FaceDescription::default());
|
||||
t.insert(CubeFace::Left,FaceDescription::default());
|
||||
t.insert(CubeFace::Bottom,FaceDescription::default());
|
||||
t.insert(CubeFace::Front,FaceDescription::default());
|
||||
generate_partial_unit_cube(t)
|
||||
}
|
||||
pub fn unit_cylinder()->crate::model::IndexedModel{
|
||||
let mut indexed_model=crate::model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/teapot.obj")[..]).unwrap(),*glam::Vec4::ONE.as_ref()).remove(0);
|
||||
for pos in indexed_model.unique_pos.iter_mut(){
|
||||
pos[0]=pos[0]*0.1;
|
||||
pos[1]=pos[1]*0.1;
|
||||
pos[2]=pos[2]*0.1;
|
||||
}
|
||||
indexed_model
|
||||
}
|
||||
pub type WedgeFaceDescription=std::collections::HashMap::<WedgeFace,FaceDescription>;
|
||||
pub fn unit_wedge()->crate::model::IndexedModel{
|
||||
let mut t=WedgeFaceDescription::new();
|
||||
t.insert(WedgeFace::Right,FaceDescription::default());
|
||||
t.insert(WedgeFace::TopFront,FaceDescription::default());
|
||||
t.insert(WedgeFace::Back,FaceDescription::default());
|
||||
t.insert(WedgeFace::Left,FaceDescription::default());
|
||||
t.insert(WedgeFace::Bottom,FaceDescription::default());
|
||||
generate_partial_unit_wedge(t)
|
||||
}
|
||||
pub type CornerWedgeFaceDescription=std::collections::HashMap::<CornerWedgeFace,FaceDescription>;
|
||||
pub fn unit_cornerwedge()->crate::model::IndexedModel{
|
||||
let mut t=CornerWedgeFaceDescription::new();
|
||||
t.insert(CornerWedgeFace::Right,FaceDescription::default());
|
||||
t.insert(CornerWedgeFace::Top,FaceDescription::default());
|
||||
t.insert(CornerWedgeFace::Bottom,FaceDescription::default());
|
||||
t.insert(CornerWedgeFace::Front,FaceDescription::default());
|
||||
generate_partial_unit_cornerwedge(t)
|
||||
}
|
||||
|
||||
#[derive(Copy,Clone)]
|
||||
@ -74,7 +176,7 @@ pub struct FaceDescription{
|
||||
pub color:glam::Vec4,
|
||||
}
|
||||
impl std::default::Default for FaceDescription{
|
||||
fn default() -> Self {
|
||||
fn default()->Self {
|
||||
Self{
|
||||
texture:None,
|
||||
transform:glam::Affine2::IDENTITY,
|
||||
@ -95,8 +197,8 @@ impl FaceDescription{
|
||||
}
|
||||
}
|
||||
//TODO: it's probably better to use a shared vertex buffer between all primitives and use indexed rendering instead of generating a unique vertex buffer for each primitive.
|
||||
//implementation: put all roblox primitives into one model.groups
|
||||
pub fn generate_partial_unit_cube(face_descriptions:[Option<FaceDescription>;6]) -> crate::model::IndexedModel{
|
||||
//implementation: put all roblox primitives into one model.groups <- this won't work but I forget why
|
||||
pub fn generate_partial_unit_cube(face_descriptions:CubeFaceDescription)->crate::model::IndexedModel{
|
||||
let mut generated_pos=Vec::<[f32;3]>::new();
|
||||
let mut generated_tex=Vec::new();
|
||||
let mut generated_normal=Vec::new();
|
||||
@ -105,59 +207,290 @@ pub fn generate_partial_unit_cube(face_descriptions:[Option<FaceDescription>;6])
|
||||
let mut groups=Vec::new();
|
||||
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 (i,maybe_face_description) in face_descriptions.iter().enumerate(){
|
||||
if let Some(face_description)=maybe_face_description{
|
||||
//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
|
||||
}else{
|
||||
//create new transform_index
|
||||
let transform_index=transforms.len();
|
||||
transforms.push(face_description.transform);
|
||||
for tex in CUBE_DEFAULT_TEXTURE_COORDS{
|
||||
generated_tex.push(*face_description.transform.transform_point2(glam::Vec2::from_array(tex)).as_ref());
|
||||
}
|
||||
transform_index
|
||||
} as u32;
|
||||
let color_index=if let Some(color_index)=generated_color.iter().position(|color|color==face_description.color.as_ref()){
|
||||
color_index
|
||||
}else{
|
||||
//create new color_index
|
||||
let color_index=generated_color.len();
|
||||
generated_color.push(*face_description.color.as_ref());
|
||||
color_index
|
||||
} as u32;
|
||||
//always push normal
|
||||
let normal_index=generated_normal.len() as u32;
|
||||
generated_normal.push(CUBE_DEFAULT_NORMALS[i]);
|
||||
//push vertices as they are needed
|
||||
groups.push(IndexedGroup{
|
||||
texture:face_description.texture,
|
||||
polys:vec![IndexedPolygon{
|
||||
vertices:CUBE_DEFAULT_POLYS[i].map(|tup|{
|
||||
let pos=CUBE_DEFAULT_VERTICES[tup[0] as usize];
|
||||
let pos_index=if let Some(pos_index)=generated_pos.iter().position(|&p|p==pos){
|
||||
pos_index
|
||||
}else{
|
||||
//create new pos_index
|
||||
let pos_index=generated_pos.len();
|
||||
generated_pos.push(pos);
|
||||
pos_index
|
||||
} as u32;
|
||||
//always push vertex
|
||||
let vertex=IndexedVertex{
|
||||
pos:pos_index,
|
||||
tex:tup[1]+4*transform_index,
|
||||
normal:normal_index,
|
||||
color:color_index,
|
||||
};
|
||||
let vert_index=generated_vertices.len();
|
||||
generated_vertices.push(vertex);
|
||||
vert_index as u32
|
||||
}).to_vec(),
|
||||
}],
|
||||
});
|
||||
}
|
||||
for (face,face_description) in face_descriptions.iter(){
|
||||
//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
|
||||
}else{
|
||||
//create new transform_index
|
||||
let transform_index=transforms.len();
|
||||
transforms.push(face_description.transform);
|
||||
for tex in CUBE_DEFAULT_TEXTURE_COORDS{
|
||||
generated_tex.push(*face_description.transform.transform_point2(glam::Vec2::from_array(tex)).as_ref());
|
||||
}
|
||||
transform_index
|
||||
} as u32;
|
||||
let color_index=if let Some(color_index)=generated_color.iter().position(|color|color==face_description.color.as_ref()){
|
||||
color_index
|
||||
}else{
|
||||
//create new color_index
|
||||
let color_index=generated_color.len();
|
||||
generated_color.push(*face_description.color.as_ref());
|
||||
color_index
|
||||
} as u32;
|
||||
let face_id=match face{
|
||||
CubeFace::Right => 0,
|
||||
CubeFace::Top => 1,
|
||||
CubeFace::Back => 2,
|
||||
CubeFace::Left => 3,
|
||||
CubeFace::Bottom => 4,
|
||||
CubeFace::Front => 5,
|
||||
};
|
||||
//always push normal
|
||||
let normal_index=generated_normal.len() as u32;
|
||||
generated_normal.push(CUBE_DEFAULT_NORMALS[face_id]);
|
||||
//push vertices as they are needed
|
||||
groups.push(IndexedGroup{
|
||||
texture:face_description.texture,
|
||||
polys:vec![IndexedPolygon{
|
||||
vertices:CUBE_DEFAULT_POLYS[face_id].map(|tup|{
|
||||
let pos=CUBE_DEFAULT_VERTICES[tup[0] as usize];
|
||||
let pos_index=if let Some(pos_index)=generated_pos.iter().position(|&p|p==pos){
|
||||
pos_index
|
||||
}else{
|
||||
//create new pos_index
|
||||
let pos_index=generated_pos.len();
|
||||
generated_pos.push(pos);
|
||||
pos_index
|
||||
} as u32;
|
||||
//always push vertex
|
||||
let vertex=IndexedVertex{
|
||||
pos:pos_index,
|
||||
tex:tup[1]+4*transform_index,
|
||||
normal:normal_index,
|
||||
color:color_index,
|
||||
};
|
||||
let vert_index=generated_vertices.len();
|
||||
generated_vertices.push(vertex);
|
||||
vert_index as u32
|
||||
}).to_vec(),
|
||||
}],
|
||||
});
|
||||
}
|
||||
IndexedModel{
|
||||
unique_pos:generated_pos,
|
||||
unique_tex:generated_tex,
|
||||
unique_normal:generated_normal,
|
||||
unique_color:generated_color,
|
||||
unique_vertices:generated_vertices,
|
||||
groups,
|
||||
instances:Vec::new(),
|
||||
}
|
||||
}
|
||||
//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)->crate::model::IndexedModel{
|
||||
let wedge_default_polys=vec![
|
||||
// right (1, 0, 0)
|
||||
vec![
|
||||
[6,2,0],//[vertex,tex,norm]
|
||||
[2,0,0],
|
||||
[1,3,0],
|
||||
],
|
||||
// FrontTop (0, 1, -1)
|
||||
vec![
|
||||
[3,1,1],
|
||||
[2,0,1],
|
||||
[6,3,1],
|
||||
[7,2,1],
|
||||
],
|
||||
// back (0, 0, 1)
|
||||
vec![
|
||||
[0,3,2],
|
||||
[1,2,2],
|
||||
[2,1,2],
|
||||
[3,0,2],
|
||||
],
|
||||
// left (-1, 0, 0)
|
||||
vec![
|
||||
[0,2,3],
|
||||
[3,1,3],
|
||||
[7,3,3],
|
||||
],
|
||||
// bottom (0,-1, 0)
|
||||
vec![
|
||||
[1,1,4],
|
||||
[0,0,4],
|
||||
[7,3,4],
|
||||
[6,2,4],
|
||||
],
|
||||
];
|
||||
let mut generated_pos=Vec::<[f32;3]>::new();
|
||||
let mut generated_tex=Vec::new();
|
||||
let mut generated_normal=Vec::new();
|
||||
let mut generated_color=Vec::new();
|
||||
let mut generated_vertices=Vec::new();
|
||||
let mut groups=Vec::new();
|
||||
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,face_description) in face_descriptions.iter(){
|
||||
//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
|
||||
}else{
|
||||
//create new transform_index
|
||||
let transform_index=transforms.len();
|
||||
transforms.push(face_description.transform);
|
||||
for tex in CUBE_DEFAULT_TEXTURE_COORDS{
|
||||
generated_tex.push(*face_description.transform.transform_point2(glam::Vec2::from_array(tex)).as_ref());
|
||||
}
|
||||
transform_index
|
||||
} as u32;
|
||||
let color_index=if let Some(color_index)=generated_color.iter().position(|color|color==face_description.color.as_ref()){
|
||||
color_index
|
||||
}else{
|
||||
//create new color_index
|
||||
let color_index=generated_color.len();
|
||||
generated_color.push(*face_description.color.as_ref());
|
||||
color_index
|
||||
} as u32;
|
||||
let face_id=match face{
|
||||
WedgeFace::Right => 0,
|
||||
WedgeFace::TopFront => 1,
|
||||
WedgeFace::Back => 2,
|
||||
WedgeFace::Left => 3,
|
||||
WedgeFace::Bottom => 4,
|
||||
};
|
||||
//always push normal
|
||||
let normal_index=generated_normal.len() as u32;
|
||||
generated_normal.push(WEDGE_DEFAULT_NORMALS[face_id]);
|
||||
//push vertices as they are needed
|
||||
groups.push(IndexedGroup{
|
||||
texture:face_description.texture,
|
||||
polys:vec![IndexedPolygon{
|
||||
vertices:wedge_default_polys[face_id].iter().map(|tup|{
|
||||
let pos=CUBE_DEFAULT_VERTICES[tup[0] as usize];
|
||||
let pos_index=if let Some(pos_index)=generated_pos.iter().position(|&p|p==pos){
|
||||
pos_index
|
||||
}else{
|
||||
//create new pos_index
|
||||
let pos_index=generated_pos.len();
|
||||
generated_pos.push(pos);
|
||||
pos_index
|
||||
} as u32;
|
||||
//always push vertex
|
||||
let vertex=IndexedVertex{
|
||||
pos:pos_index,
|
||||
tex:tup[1]+4*transform_index,
|
||||
normal:normal_index,
|
||||
color:color_index,
|
||||
};
|
||||
let vert_index=generated_vertices.len();
|
||||
generated_vertices.push(vertex);
|
||||
vert_index as u32
|
||||
}).collect(),
|
||||
}],
|
||||
});
|
||||
}
|
||||
IndexedModel{
|
||||
unique_pos:generated_pos,
|
||||
unique_tex:generated_tex,
|
||||
unique_normal:generated_normal,
|
||||
unique_color:generated_color,
|
||||
unique_vertices:generated_vertices,
|
||||
groups,
|
||||
instances:Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_partial_unit_cornerwedge(face_descriptions:CornerWedgeFaceDescription)->crate::model::IndexedModel{
|
||||
let cornerwedge_default_polys=vec![
|
||||
// right (1, 0, 0)
|
||||
vec![
|
||||
[6,2,0],//[vertex,tex,norm]
|
||||
[5,1,0],
|
||||
[1,3,0],
|
||||
],
|
||||
// BackTop (0, 1, 1)
|
||||
vec![
|
||||
[5,3,1],
|
||||
[0,1,1],
|
||||
[1,0,1],
|
||||
],
|
||||
// LeftTop (-1, 1, 0)
|
||||
vec![
|
||||
[5,3,2],
|
||||
[7,2,2],
|
||||
[0,1,2],
|
||||
],
|
||||
// bottom (0,-1, 0)
|
||||
vec![
|
||||
[1,1,3],
|
||||
[0,0,3],
|
||||
[7,3,3],
|
||||
[6,2,3],
|
||||
],
|
||||
// front (0, 0,-1)
|
||||
vec![
|
||||
[5,0,4],
|
||||
[6,3,4],
|
||||
[7,2,4],
|
||||
],
|
||||
];
|
||||
let mut generated_pos=Vec::<[f32;3]>::new();
|
||||
let mut generated_tex=Vec::new();
|
||||
let mut generated_normal=Vec::new();
|
||||
let mut generated_color=Vec::new();
|
||||
let mut generated_vertices=Vec::new();
|
||||
let mut groups=Vec::new();
|
||||
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,face_description) in face_descriptions.iter(){
|
||||
//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
|
||||
}else{
|
||||
//create new transform_index
|
||||
let transform_index=transforms.len();
|
||||
transforms.push(face_description.transform);
|
||||
for tex in CUBE_DEFAULT_TEXTURE_COORDS{
|
||||
generated_tex.push(*face_description.transform.transform_point2(glam::Vec2::from_array(tex)).as_ref());
|
||||
}
|
||||
transform_index
|
||||
} as u32;
|
||||
let color_index=if let Some(color_index)=generated_color.iter().position(|color|color==face_description.color.as_ref()){
|
||||
color_index
|
||||
}else{
|
||||
//create new color_index
|
||||
let color_index=generated_color.len();
|
||||
generated_color.push(*face_description.color.as_ref());
|
||||
color_index
|
||||
} as u32;
|
||||
let face_id=match face{
|
||||
CornerWedgeFace::Right => 0,
|
||||
CornerWedgeFace::Top => 1,
|
||||
CornerWedgeFace::Bottom => 2,
|
||||
CornerWedgeFace::Front => 3,
|
||||
};
|
||||
//always push normal
|
||||
let normal_index=generated_normal.len() as u32;
|
||||
generated_normal.push(CORNERWEDGE_DEFAULT_NORMALS[face_id]);
|
||||
//push vertices as they are needed
|
||||
groups.push(IndexedGroup{
|
||||
texture:face_description.texture,
|
||||
polys:vec![IndexedPolygon{
|
||||
vertices:cornerwedge_default_polys[face_id].iter().map(|tup|{
|
||||
let pos=CUBE_DEFAULT_VERTICES[tup[0] as usize];
|
||||
let pos_index=if let Some(pos_index)=generated_pos.iter().position(|&p|p==pos){
|
||||
pos_index
|
||||
}else{
|
||||
//create new pos_index
|
||||
let pos_index=generated_pos.len();
|
||||
generated_pos.push(pos);
|
||||
pos_index
|
||||
} as u32;
|
||||
//always push vertex
|
||||
let vertex=IndexedVertex{
|
||||
pos:pos_index,
|
||||
tex:tup[1]+4*transform_index,
|
||||
normal:normal_index,
|
||||
color:color_index,
|
||||
};
|
||||
let vert_index=generated_vertices.len();
|
||||
generated_vertices.push(vertex);
|
||||
vert_index as u32
|
||||
}).collect(),
|
||||
}],
|
||||
});
|
||||
}
|
||||
IndexedModel{
|
||||
unique_pos:generated_pos,
|
||||
|
Loading…
Reference in New Issue
Block a user