diff --git a/src/load_roblox.rs b/src/load_roblox.rs index 7b578015..c0f0a801 100644 --- a/src/load_roblox.rs +++ b/src/load_roblox.rs @@ -1,4 +1,4 @@ -use crate::model::{ModelData,ModelInstance}; +use crate::model::{IndexedModelInstances,ModelInstance}; use crate::primitives; @@ -105,12 +105,12 @@ struct RobloxUnitCubeGenerationData{ } impl std::cmp::Eq for RobloxUnitCubeGenerationData{}//???? impl std::default::Default for RobloxUnitCubeGenerationData{ - fn default() -> Self { - Self{ + fn default() -> Self { + Self{ texture:None, faces:[Some(RobloxColorAndTextureTransform::default());6], } - } + } } impl std::hash::Hash for RobloxUnitCubeGenerationData { fn hash(&self, state: &mut H) { @@ -129,12 +129,13 @@ impl RobloxUnitCubeGenerationData{ } } } -pub fn generate_modeldatas_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(Vec,Vec,glam::Vec3), Box>{ +pub fn generate_indexed_model_instances_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(IndexedModelInstances,Vec,glam::Vec3), Box>{ //ModelData includes texture dds let mut spawn_point=glam::Vec3::ZERO; //TODO: generate unit Block, Wedge, etc. after based on part shape lists - let mut modeldatas=Vec::new(); + let mut indexed_models=Vec::new(); + let mut model_instances=Vec::new(); let mut texture_id_from_asset_id=std::collections::HashMap::::new(); let mut asset_id_from_texture_id=Vec::new(); diff --git a/src/main.rs b/src/main.rs index b1dc9de7..206e104e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,8 +17,12 @@ struct Entity { index_buf: wgpu::Buffer, } +struct ModelGraphicsInstance { + model_transform: glam::Affine3A, + color: glam::Vec4, +} struct ModelGraphics { - instances: Vec, + instances: Vec, vertex_buf: wgpu::Buffer, entities: Vec, bind_group: wgpu::BindGroup, @@ -90,13 +94,13 @@ impl GraphicsData { ).flatten().collect()); println!("Physics Objects: {}",self.physics.models.len()); } - fn generate_model_graphics(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,mut modeldatas:Vec,textures:Vec){ + fn generate_model_graphics(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,mut indexed_models:model::IndexedModelInstances){ //generate texture view per texture //idk how to do this gooder lol let mut double_map=std::collections::HashMap::::new(); - let mut texture_views:Vec=Vec::with_capacity(textures.len()); - for (i,t) in textures.iter().enumerate(){ + let mut texture_views:Vec=Vec::with_capacity(indexed_models.textures.len()); + for (i,t) in indexed_models.textures.iter().enumerate(){ if let Ok(mut file) = std::fs::File::open(std::path::Path::new(&format!("textures/{}.dds",t))){ let image = ddsfile::Dds::read(&mut file).unwrap(); @@ -254,12 +258,11 @@ impl framework::Example for GraphicsData { device: &wgpu::Device, queue: &wgpu::Queue, ) -> Self { - let unit_cube=primitives::the_unit_cube_lol(); let mut modeldatas = Vec::::new(); modeldatas.append(&mut model::generate_modeldatas(obj::ObjData::load_buf(&include_bytes!("../models/teslacyberv3.0.obj")[..]).unwrap(),ModelData::COLOR_FLOATS_WHITE)); modeldatas.append(&mut model::generate_modeldatas(obj::ObjData::load_buf(&include_bytes!("../models/suzanne.obj")[..]).unwrap(),ModelData::COLOR_FLOATS_WHITE)); modeldatas.append(&mut model::generate_modeldatas(obj::ObjData::load_buf(&include_bytes!("../models/teapot.obj")[..]).unwrap(),ModelData::COLOR_FLOATS_WHITE)); - modeldatas.append(&mut model::generate_modeldatas(unit_cube.clone(),ModelData::COLOR_FLOATS_WHITE)); + modeldatas.push(primitives::the_unit_cube_lol()); println!("models.len = {:?}", modeldatas.len()); modeldatas[0].instances.push(ModelInstance{ model_transform:glam::Affine3A::from_translation(glam::vec3(10.,0.,-10.)), diff --git a/src/model.rs b/src/model.rs index 5c8b26e4..21320724 100644 --- a/src/model.rs +++ b/src/model.rs @@ -7,63 +7,77 @@ pub struct Vertex { pub normal: [f32; 3], pub color: [f32; 4], } +#[derive(Hash)] +pub struct IndexedVertex{ + pub pos:u32, + pub texture:u32, + pub normal:u32, + pub color:u32, +} +pub struct IndexedPolygon{ + pub vertices:Vec, +} +pub struct IndexedGroup{ + pub texture:Option,//RenderPattern? material/texture/shader/flat color + pub polys:Vec, +} +pub struct IndexedModel{ + pub unique_pos:Vec<[f32; 3]>, + pub unique_texture:Vec<[f32; 2]>, + pub unique_normal:Vec<[f32; 3]>, + pub unique_color:Vec<[f32; 4]>, + pub unique_vertices:Vec, + pub groups: Vec, +} #[derive(Clone)] -pub struct ModelInstance { - pub model_transform: glam::Affine3A, - pub color: glam::Vec4, +pub struct ModelInstance{ + pub model:u32, + pub model_transform:glam::Affine3A, + pub color:glam::Vec4, +} +pub struct IndexedModelInstances{ + pub textures:Vec,//RenderPattern + pub models:Vec, + pub instances:Vec, + //object_index for spawns, triggers etc? } -#[derive(Clone)] -pub struct ModelData { - pub instances: Vec, - pub vertices: Vec, - pub entities: Vec>, - pub texture: Option, -} - -impl ModelData { - pub const COLOR_FLOATS_WHITE: [f32;4] = [1.0,1.0,1.0,1.0]; - pub const COLOR_VEC4_WHITE: glam::Vec4 = glam::vec4(1.0,1.0,1.0,1.0); -} - -pub fn generate_modeldatas(data:obj::ObjData,color:[f32;4]) -> Vec{ - let mut modeldatas=Vec::new(); - let mut vertices = Vec::new(); - let mut vertex_index = std::collections::HashMap::::new(); - for object in data.objects { - vertices.clear(); - vertex_index.clear(); - let mut entities = Vec::new(); - for group in object.groups { - let mut indices = Vec::new(); - for poly in group.polys { - for end_index in 2..poly.0.len() { - for &index in &[0, end_index - 1, end_index] { - let vert = poly.0[index]; - if let Some(&i)=vertex_index.get(&vert){ - indices.push(i); - }else{ - let i=vertices.len() as u16; - vertices.push(Vertex { - pos: data.position[vert.0], - texture: data.texture[vert.1.unwrap()], - normal: data.normal[vert.2.unwrap()], - color, - }); - vertex_index.insert(vert,i); - indices.push(i); - } +pub fn generate_indexed_model_from_obj(data:obj::ObjData,color:[f32;4]) -> Vec{ + let mut unique_vertex_index = std::collections::HashMap::::new(); + return data.objects.iter().map(|object|{ + unique_vertex_index.clear(); + let mut unique_vertices = Vec::new(); + let groups = object.groups.iter().map(|group|{ + IndexedGroup{ + texture:None, + polys:group.polys.iter().map(|poly|{ + IndexedPolygon{ + vertices:poly.0.iter().map(|&tup|{ + if let Some(&i)=unique_vertex_index.get(&tup){ + i + }else{ + let i=unique_vertices.len() as u32; + unique_vertices.push(IndexedVertex{ + pos: tup.0 as u32, + texture: tup.1.unwrap() as u32, + normal: tup.2.unwrap() as u32, + color: 0, + }); + unique_vertex_index.insert(tup,i); + i + } + }).collect() } - } + }).collect() } - entities.push(indices); + }).collect(); + IndexedModel{ + unique_pos: data.position.clone(), + unique_texture: data.texture.clone(), + unique_normal: data.normal.clone(), + unique_color: vec![color], + unique_vertices, + groups, } - modeldatas.push(ModelData { - instances: Vec::new(), - vertices:vertices.clone(), - entities, - texture: None, - }); - } - modeldatas -} \ No newline at end of file + }).collect() +} diff --git a/src/primitives.rs b/src/primitives.rs index 146d4040..34113909 100644 --- a/src/primitives.rs +++ b/src/primitives.rs @@ -1,53 +1,88 @@ -pub fn the_unit_cube_lol() -> obj::ObjData{ - generate_partial_unit_cube([Some(glam::Affine2::IDENTITY);6]) +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 + [ 1.,-1., 1.],//1 right bottom back + [ 1., 1., 1.],//2 right top back + [-1., 1., 1.],//3 left top back + [-1., 1.,-1.],//4 left top front + [ 1., 1.,-1.],//5 right top front + [ 1.,-1.,-1.],//6 right bottom front + [-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 +]; +const CUBE_DEFAULT_POLYS:[[[u32;3];4];6]=[ + // right (1, 0, 0) + [ + [6,2,0],//[vert,tex,norm] + [5,1,0], + [2,0,0], + [1,3,0], + ], + // top (0, 1, 0) + [ + [5,3,1], + [4,2,1], + [3,1,1], + [2,0,1], + ], + // back (0, 0, 1) + [ + [0,3,2], + [1,2,2], + [2,1,2], + [3,0,2], + ], + // left (-1, 0, 0) + [ + [0,2,3], + [3,1,3], + [4,0,3], + [7,3,3], + ], + // bottom (0,-1, 0) + [ + [1,1,4], + [0,0,4], + [7,3,4], + [6,2,4], + ], + // front (0, 0,-1) + [ + [4,1,5], + [5,0,5], + [6,3,5], + [7,2,5], + ], +]; +pub fn the_unit_cube_lol() -> crate::model::ModelData{ + generate_partial_unit_cube([Some(FaceDescription::default());6],None) } -pub fn generate_partial_unit_cube(face_transforms:[Option;6])->obj::ObjData{ - let default_polys=[ - // right (1, 0, 0) - obj::SimplePolygon(vec![ - obj::IndexTuple(6,Some(2),Some(0)), - obj::IndexTuple(5,Some(1),Some(0)), - obj::IndexTuple(2,Some(0),Some(0)), - obj::IndexTuple(1,Some(3),Some(0)), - ]), - // top (0, 1, 0) - obj::SimplePolygon(vec![ - obj::IndexTuple(5,Some(3),Some(1)), - obj::IndexTuple(4,Some(2),Some(1)), - obj::IndexTuple(3,Some(1),Some(1)), - obj::IndexTuple(2,Some(0),Some(1)), - ]), - // back (0, 0, 1) - obj::SimplePolygon(vec![ - obj::IndexTuple(0,Some(3),Some(2)), - obj::IndexTuple(1,Some(2),Some(2)), - obj::IndexTuple(2,Some(1),Some(2)), - obj::IndexTuple(3,Some(0),Some(2)), - ]), - // left (-1, 0, 0) - obj::SimplePolygon(vec![ - obj::IndexTuple(0,Some(2),Some(3)), - obj::IndexTuple(3,Some(1),Some(3)), - obj::IndexTuple(4,Some(0),Some(3)), - obj::IndexTuple(7,Some(3),Some(3)), - ]), - // bottom (0,-1, 0) - obj::SimplePolygon(vec![ - obj::IndexTuple(1,Some(1),Some(4)), - obj::IndexTuple(0,Some(0),Some(4)), - obj::IndexTuple(7,Some(3),Some(4)), - obj::IndexTuple(6,Some(2),Some(4)), - ]), - // front (0, 0,-1) - obj::SimplePolygon(vec![ - obj::IndexTuple(4,Some(1),Some(5)), - obj::IndexTuple(5,Some(0),Some(5)), - obj::IndexTuple(6,Some(3),Some(5)), - obj::IndexTuple(7,Some(2),Some(5)), - ]), - ]; - let default_verts=[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0]]; - //generate transformed vertices + +pub struct FaceDescription{ + transform:glam::Affine2, + color:glam::Vec4, +} +impl std::default::Default for FaceDescription{ + fn default() -> Self { + Self{ + transform:glam::Affine2::IDENTITY, + color:glam::Vec4::ONE, + } + } +} +impl FaceDescription{ + pub fn new(transform:glam::Affine2,color:glam::Vec4)->Self{ + Self{transform,color} + } +} +pub fn generate_partial_unit_cube(face_transforms:[Option;6],texture:Option) -> crate::model::ModelData{ //generate transformed vertices let mut generated_verts=Vec::new(); let mut transforms=Vec::new(); let mut generated_polys=Vec::new(); @@ -71,35 +106,37 @@ pub fn generate_partial_unit_cube(face_transforms:[Option;6])->ob )); } } - obj::ObjData{ - position: vec![ - [-1.,-1., 1.],//0 left bottom back - [ 1.,-1., 1.],//1 right bottom back - [ 1., 1., 1.],//2 right top back - [-1., 1., 1.],//3 left top back - [-1., 1.,-1.],//4 left top front - [ 1., 1.,-1.],//5 right top front - [ 1.,-1.,-1.],//6 right bottom front - [-1.,-1.,-1.],//7 left bottom front - ], - texture: generated_verts, - normal: vec![ - [ 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 - ], - objects: vec![obj::Object{ - name: "Unit Cube".to_owned(), - groups: vec![obj::Group{ - name: "Cube Vertices".to_owned(), - index: 0, - material: None, - polys: generated_polys, - }] - }], - material_libs: Vec::new(), + let mut vertices = Vec::new(); + let mut vertex_index = std::collections::HashMap::::new(); + let mut entities = Vec::new(); + for group in object.groups { + let mut indices = Vec::new(); + for poly in group.polys { + for end_index in 2..poly.0.len() { + for &index in &[0, end_index - 1, end_index] { + let vert = poly.0[index]; + if let Some(&i)=vertex_index.get(&vert){ + indices.push(i); + }else{ + let i=vertices.len() as u16; + vertices.push(Vertex { + pos: data.position[vert.0], + texture: data.texture[vert.1.unwrap()], + normal: data.normal[vert.2.unwrap()], + color, + }); + vertex_index.insert(vert,i); + indices.push(i); + } + } + } + } + entities.push(indices); } -} \ No newline at end of file + ModelData { + instances: Vec::new(), + vertices, + entities, + texture, + } +}