Compare commits
4 Commits
master
...
load-roblo
Author | SHA1 | Date | |
---|---|---|---|
382ecfa713 | |||
28cad39b10 | |||
2af43480f1 | |||
bb7ccd97bb |
12
src/body.rs
12
src/body.rs
@ -16,6 +16,8 @@ pub enum PhysicsInstruction {
|
|||||||
// bool,//true = Trigger; false = teleport
|
// bool,//true = Trigger; false = teleport
|
||||||
// bool,//true = Force
|
// bool,//true = Force
|
||||||
// )
|
// )
|
||||||
|
//temp
|
||||||
|
SetPosition(glam::Vec3),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Body {
|
pub struct Body {
|
||||||
@ -756,6 +758,7 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
//selectively update body
|
//selectively update body
|
||||||
match &ins.instruction {
|
match &ins.instruction {
|
||||||
PhysicsInstruction::SetWalkTargetVelocity(_)
|
PhysicsInstruction::SetWalkTargetVelocity(_)
|
||||||
|
|PhysicsInstruction::SetPosition(_)
|
||||||
|PhysicsInstruction::SetControlDir(_) => self.time=ins.time,//TODO: queue instructions
|
|PhysicsInstruction::SetControlDir(_) => self.time=ins.time,//TODO: queue instructions
|
||||||
PhysicsInstruction::RefreshWalkTarget
|
PhysicsInstruction::RefreshWalkTarget
|
||||||
|PhysicsInstruction::ReachWalkTargetVelocity
|
|PhysicsInstruction::ReachWalkTargetVelocity
|
||||||
@ -765,6 +768,15 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
|||||||
|PhysicsInstruction::Jump => self.advance_time(ins.time),
|
|PhysicsInstruction::Jump => self.advance_time(ins.time),
|
||||||
}
|
}
|
||||||
match ins.instruction {
|
match ins.instruction {
|
||||||
|
PhysicsInstruction::SetPosition(position)=>{
|
||||||
|
//temp
|
||||||
|
self.body.position=position;
|
||||||
|
//manual clear //for c in self.contacts{process_instruction(CollisionEnd(c))}
|
||||||
|
self.contacts.clear();
|
||||||
|
self.body.acceleration=self.gravity;
|
||||||
|
self.walk.state=WalkEnum::Reached;
|
||||||
|
self.grounded=false;
|
||||||
|
}
|
||||||
PhysicsInstruction::CollisionStart(c) => {
|
PhysicsInstruction::CollisionStart(c) => {
|
||||||
//check ground
|
//check ground
|
||||||
match &c.face {
|
match &c.face {
|
||||||
|
@ -53,7 +53,7 @@ pub trait Example: 'static + Sized {
|
|||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
queue: &wgpu::Queue,
|
queue: &wgpu::Queue,
|
||||||
);
|
);
|
||||||
fn update(&mut self, device: &wgpu::Device, event: WindowEvent);
|
fn update(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, event: WindowEvent);
|
||||||
fn move_mouse(&mut self, delta: (f64,f64));
|
fn move_mouse(&mut self, delta: (f64,f64));
|
||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -369,7 +369,7 @@ fn start<E: Example>(
|
|||||||
println!("{:#?}", instance.generate_report());
|
println!("{:#?}", instance.generate_report());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
example.update(&device,event);
|
example.update(&device,&queue,event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
event::Event::DeviceEvent {
|
event::Event::DeviceEvent {
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
use std::todo;
|
||||||
|
|
||||||
|
use crate::model::{ModelData,ModelInstance};
|
||||||
|
|
||||||
|
use crate::primitives;
|
||||||
|
|
||||||
fn class_is_a(class: &str, superclass: &str) -> bool {
|
fn class_is_a(class: &str, superclass: &str) -> bool {
|
||||||
if class==superclass {
|
if class==superclass {
|
||||||
return true
|
return true
|
||||||
@ -10,16 +16,125 @@ fn class_is_a(class: &str, superclass: &str) -> bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
fn recursive_collect_superclass(objects: &mut std::vec::Vec<rbx_dom_weak::types::Ref>,dom: &rbx_dom_weak::WeakDom, instance: &rbx_dom_weak::Instance, superclass: &str){
|
||||||
pub fn get_objects(dom:rbx_dom_weak::WeakDom, superclass: &str) -> Result<std::vec::Vec<rbx_dom_weak::Instance>, Box<dyn std::error::Error>> {
|
for &referent in instance.children() {
|
||||||
let mut objects = std::vec::Vec::<rbx_dom_weak::Instance>::new();
|
if let Some(c) = dom.get_by_ref(referent) {
|
||||||
//move matching instances into objects
|
if class_is_a(c.class.as_str(), superclass) {
|
||||||
let (_,mut instances) = dom.into_raw();
|
objects.push(c.referent());//copy ref
|
||||||
for (_,instance) in instances.drain() {
|
}
|
||||||
if class_is_a(instance.class.as_str(), superclass) {
|
recursive_collect_superclass(objects,dom,c,superclass);
|
||||||
objects.push(instance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Ok(objects)
|
fn get_texture_refs(dom:&rbx_dom_weak::WeakDom) -> Vec<rbx_dom_weak::types::Ref>{
|
||||||
|
let mut objects = std::vec::Vec::new();
|
||||||
|
recursive_collect_superclass(&mut objects, dom, dom.root(),"Decal");
|
||||||
|
//get ids
|
||||||
|
//clear vec
|
||||||
|
//next class
|
||||||
|
objects
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RobloxAssetId(u64);
|
||||||
|
struct RobloxAssetIdParseErr;
|
||||||
|
impl std::str::FromStr for RobloxAssetId {
|
||||||
|
type Err=RobloxAssetIdParseErr;
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err>{
|
||||||
|
let regman=regex::Regex::new(r"(\d+)$").unwrap();
|
||||||
|
if let Some(captures) = regman.captures(s) {
|
||||||
|
if captures.len()==2{//captures[0] is all captures concatenated, and then each individual capture
|
||||||
|
if let Ok(id) = captures[0].parse::<u64>() {
|
||||||
|
return Ok(Self(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(RobloxAssetIdParseErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn generate_modeldatas_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(Vec<ModelData>,Vec<String>,glam::Vec3), Box<dyn std::error::Error>>{
|
||||||
|
//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=crate::model::generate_modeldatas(primitives::the_unit_cube_lol(),ModelData::COLOR_FLOATS_WHITE);
|
||||||
|
let unit_cube_modeldata=modeldatas[0].clone();
|
||||||
|
|
||||||
|
let mut texture_id_from_asset_id=std::collections::HashMap::<u64,u32>::new();
|
||||||
|
let mut asset_id_from_texture_id=Vec::new();
|
||||||
|
|
||||||
|
let mut object_refs = std::vec::Vec::new();
|
||||||
|
let mut temp_objects = std::vec::Vec::new();
|
||||||
|
recursive_collect_superclass(&mut object_refs, &dom, dom.root(),"BasePart");
|
||||||
|
for object_ref in object_refs {
|
||||||
|
if let Some(object)=dom.get_by_ref(object_ref){
|
||||||
|
if let (
|
||||||
|
Some(rbx_dom_weak::types::Variant::CFrame(cf)),
|
||||||
|
Some(rbx_dom_weak::types::Variant::Vector3(size)),
|
||||||
|
Some(rbx_dom_weak::types::Variant::Float32(transparency)),
|
||||||
|
Some(rbx_dom_weak::types::Variant::Color3uint8(color3)),
|
||||||
|
Some(rbx_dom_weak::types::Variant::Enum(shape)),
|
||||||
|
) = (
|
||||||
|
object.properties.get("CFrame"),
|
||||||
|
object.properties.get("Size"),
|
||||||
|
object.properties.get("Transparency"),
|
||||||
|
object.properties.get("Color"),
|
||||||
|
object.properties.get("Shape"),//this will also skip unions
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let model_instance=ModelInstance {
|
||||||
|
transform:glam::Mat4::from_translation(
|
||||||
|
glam::Vec3::new(cf.position.x,cf.position.y,cf.position.z)
|
||||||
|
)
|
||||||
|
* glam::Mat4::from_mat3(
|
||||||
|
glam::Mat3::from_cols(
|
||||||
|
glam::Vec3::new(cf.orientation.x.x,cf.orientation.y.x,cf.orientation.z.x),
|
||||||
|
glam::Vec3::new(cf.orientation.x.y,cf.orientation.y.y,cf.orientation.z.y),
|
||||||
|
glam::Vec3::new(cf.orientation.x.z,cf.orientation.y.z,cf.orientation.z.z),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
* glam::Mat4::from_scale(
|
||||||
|
glam::Vec3::new(size.x,size.y,size.z)/2.0
|
||||||
|
),
|
||||||
|
color: glam::vec4(color3.r as f32/255f32, color3.g as f32/255f32, color3.b as f32/255f32, 1.0-*transparency),
|
||||||
|
};
|
||||||
|
if object.name=="MapStart"{
|
||||||
|
spawn_point=glam::Vec4Swizzles::xyz(model_instance.transform*glam::Vec3::Y.extend(1.0))+glam::vec3(0.0,2.5,0.0);
|
||||||
|
println!("Found MapStart{:?}",spawn_point);
|
||||||
|
}
|
||||||
|
if *transparency==1.0||shape.to_u32()!=1 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
temp_objects.clear();
|
||||||
|
recursive_collect_superclass(&mut temp_objects, &dom, object,"Decal");
|
||||||
|
|
||||||
|
let mut i_can_only_load_one_texture_per_model=None;
|
||||||
|
for &decal_ref in &temp_objects{
|
||||||
|
if let Some(decal)=dom.get_by_ref(decal_ref){
|
||||||
|
if let Some(rbx_dom_weak::types::Variant::Content(content)) = decal.properties.get("Texture") {
|
||||||
|
if let Ok(asset_id)=content.clone().into_string().parse::<RobloxAssetId>(){
|
||||||
|
if let Some(&texture_id)=texture_id_from_asset_id.get(&asset_id.0){
|
||||||
|
i_can_only_load_one_texture_per_model=Some(texture_id);
|
||||||
|
}else{
|
||||||
|
let texture_id=asset_id_from_texture_id.len();
|
||||||
|
texture_id_from_asset_id.insert(asset_id.0,texture_id as u32);
|
||||||
|
asset_id_from_texture_id.push(asset_id.0);
|
||||||
|
//make new model
|
||||||
|
let mut unit_cube_texture=unit_cube_modeldata.clone();
|
||||||
|
unit_cube_texture.texture=Some(texture_id as u32);
|
||||||
|
modeldatas.push(unit_cube_texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match i_can_only_load_one_texture_per_model{
|
||||||
|
//push to existing texture model
|
||||||
|
Some(texture_id)=>modeldatas[(texture_id+1) as usize].instances.push(model_instance),
|
||||||
|
//push instance to big unit cube in the sky
|
||||||
|
None=>modeldatas[0].instances.push(model_instance),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok((modeldatas,asset_id_from_texture_id.iter().map(|t|t.to_string()).collect(),spawn_point))
|
||||||
}
|
}
|
||||||
|
260
src/main.rs
260
src/main.rs
@ -6,6 +6,7 @@ mod body;
|
|||||||
mod model;
|
mod model;
|
||||||
mod zeroes;
|
mod zeroes;
|
||||||
mod framework;
|
mod framework;
|
||||||
|
mod primitives;
|
||||||
mod instruction;
|
mod instruction;
|
||||||
mod load_roblox;
|
mod load_roblox;
|
||||||
|
|
||||||
@ -133,7 +134,6 @@ pub struct GraphicsData {
|
|||||||
models: Vec<ModelGraphics>,
|
models: Vec<ModelGraphics>,
|
||||||
depth_view: wgpu::TextureView,
|
depth_view: wgpu::TextureView,
|
||||||
staging_belt: wgpu::util::StagingBelt,
|
staging_belt: wgpu::util::StagingBelt,
|
||||||
handy_unit_cube: obj::ObjData,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GraphicsData {
|
impl GraphicsData {
|
||||||
@ -161,51 +161,6 @@ impl GraphicsData {
|
|||||||
depth_texture.create_view(&wgpu::TextureViewDescriptor::default())
|
depth_texture.create_view(&wgpu::TextureViewDescriptor::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_modeldatas_roblox(&self,dom:rbx_dom_weak::WeakDom) -> Vec<ModelData>{
|
|
||||||
let mut modeldatas=generate_modeldatas(self.handy_unit_cube.clone(),ModelData::COLOR_FLOATS_WHITE);
|
|
||||||
match load_roblox::get_objects(dom, "BasePart") {
|
|
||||||
Ok(objects)=>{
|
|
||||||
for object in objects.iter() {
|
|
||||||
if let (
|
|
||||||
Some(rbx_dom_weak::types::Variant::CFrame(cf)),
|
|
||||||
Some(rbx_dom_weak::types::Variant::Vector3(size)),
|
|
||||||
Some(rbx_dom_weak::types::Variant::Float32(transparency)),
|
|
||||||
Some(rbx_dom_weak::types::Variant::Color3uint8(color3)),
|
|
||||||
Some(rbx_dom_weak::types::Variant::Enum(shape)),
|
|
||||||
) = (
|
|
||||||
object.properties.get("CFrame"),
|
|
||||||
object.properties.get("Size"),
|
|
||||||
object.properties.get("Transparency"),
|
|
||||||
object.properties.get("Color"),
|
|
||||||
object.properties.get("Shape"),//this will also skip unions
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if *transparency==1.0||shape.to_u32()!=1 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
modeldatas[0].instances.push(ModelInstance {
|
|
||||||
transform:glam::Mat4::from_translation(
|
|
||||||
glam::Vec3::new(cf.position.x,cf.position.y,cf.position.z)
|
|
||||||
)
|
|
||||||
* glam::Mat4::from_mat3(
|
|
||||||
glam::Mat3::from_cols(
|
|
||||||
glam::Vec3::new(cf.orientation.x.x,cf.orientation.y.x,cf.orientation.z.x),
|
|
||||||
glam::Vec3::new(cf.orientation.x.y,cf.orientation.y.y,cf.orientation.z.y),
|
|
||||||
glam::Vec3::new(cf.orientation.x.z,cf.orientation.y.z,cf.orientation.z.z),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
* glam::Mat4::from_scale(
|
|
||||||
glam::Vec3::new(size.x,size.y,size.z)/2.0
|
|
||||||
),
|
|
||||||
color: glam::vec4(color3.r as f32/255f32, color3.g as f32/255f32, color3.b as f32/255f32, 1.0-*transparency),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => println!("lmao err {:?}", e),
|
|
||||||
}
|
|
||||||
modeldatas
|
|
||||||
}
|
|
||||||
fn generate_model_physics(&mut self,modeldatas:&Vec<ModelData>){
|
fn generate_model_physics(&mut self,modeldatas:&Vec<ModelData>){
|
||||||
self.physics.models.append(&mut modeldatas.iter().map(|m|
|
self.physics.models.append(&mut modeldatas.iter().map(|m|
|
||||||
//make aabb and run vertices to get realistic bounds
|
//make aabb and run vertices to get realistic bounds
|
||||||
@ -213,17 +168,72 @@ impl GraphicsData {
|
|||||||
).flatten().collect());
|
).flatten().collect());
|
||||||
println!("Physics Objects: {}",self.physics.models.len());
|
println!("Physics Objects: {}",self.physics.models.len());
|
||||||
}
|
}
|
||||||
fn generate_model_graphics(&mut self,device:&wgpu::Device,mut modeldatas:Vec<ModelData>){
|
fn generate_model_graphics(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,mut modeldatas:Vec<ModelData>,textures:Vec<String>){
|
||||||
|
//generate texture view per texture
|
||||||
|
|
||||||
|
//idk how to do this gooder lol
|
||||||
|
let mut double_map=std::collections::HashMap::<u32,u32>::new();
|
||||||
|
let mut texture_views:Vec<wgpu::TextureView>=Vec::with_capacity(textures.len());
|
||||||
|
for (i,t) in 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();
|
||||||
|
|
||||||
|
let size = wgpu::Extent3d {
|
||||||
|
width: image.get_width()/4*4,//floor(w,4), should be ceil(w,4)
|
||||||
|
height: image.get_height()/4*4,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let layer_size = wgpu::Extent3d {
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
..size
|
||||||
|
};
|
||||||
|
let max_mips = layer_size.max_mips(wgpu::TextureDimension::D2);
|
||||||
|
|
||||||
|
let texture = device.create_texture_with_data(
|
||||||
|
queue,
|
||||||
|
&wgpu::TextureDescriptor {
|
||||||
|
size,
|
||||||
|
mip_level_count: max_mips,
|
||||||
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Bc7RgbaUnorm,
|
||||||
|
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
||||||
|
label: Some(format!("Texture{}",i).as_str()),
|
||||||
|
view_formats: &[],
|
||||||
|
},
|
||||||
|
&image.data,
|
||||||
|
);
|
||||||
|
|
||||||
|
double_map.insert(i as u32, texture_views.len() as u32);
|
||||||
|
texture_views.push(texture.create_view(&wgpu::TextureViewDescriptor {
|
||||||
|
label: Some(format!("Texture{} View",i).as_str()),
|
||||||
|
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||||
|
..wgpu::TextureViewDescriptor::default()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
//drain the modeldata vec so entities can be /moved/ to models.entities
|
//drain the modeldata vec so entities can be /moved/ to models.entities
|
||||||
let mut instance_count=0;
|
let mut instance_count=0;
|
||||||
self.models.reserve(modeldatas.len());
|
self.models.reserve(modeldatas.len());
|
||||||
for (i,modeldata) in modeldatas.drain(..).enumerate() {
|
for (i,modeldata) in modeldatas.drain(..).enumerate() {
|
||||||
|
let n_instances=modeldata.instances.len();
|
||||||
|
if 0<n_instances{
|
||||||
let model_uniforms = get_instances_buffer_data(&modeldata.instances);
|
let model_uniforms = get_instances_buffer_data(&modeldata.instances);
|
||||||
let model_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let model_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some(format!("ModelGraphics{}",i).as_str()),
|
label: Some(format!("Model{} Buf",i).as_str()),
|
||||||
contents: bytemuck::cast_slice(&model_uniforms),
|
contents: bytemuck::cast_slice(&model_uniforms),
|
||||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
|
let texture_view=match modeldata.texture{
|
||||||
|
Some(texture_id)=>{
|
||||||
|
match double_map.get(&texture_id){
|
||||||
|
Some(&mapped_texture_id)=>&texture_views[mapped_texture_id as usize],
|
||||||
|
None=>&self.temp_squid_texture_view,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None=>&self.temp_squid_texture_view,
|
||||||
|
};
|
||||||
let model_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let model_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
layout: &self.bind_group_layouts.model,
|
layout: &self.bind_group_layouts.model,
|
||||||
entries: &[
|
entries: &[
|
||||||
@ -233,14 +243,14 @@ impl GraphicsData {
|
|||||||
},
|
},
|
||||||
wgpu::BindGroupEntry {
|
wgpu::BindGroupEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
resource: wgpu::BindingResource::TextureView(&self.temp_squid_texture_view),
|
resource: wgpu::BindingResource::TextureView(texture_view),
|
||||||
},
|
},
|
||||||
wgpu::BindGroupEntry {
|
wgpu::BindGroupEntry {
|
||||||
binding: 2,
|
binding: 2,
|
||||||
resource: wgpu::BindingResource::Sampler(&self.samplers.repeat),
|
resource: wgpu::BindingResource::Sampler(&self.samplers.repeat),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
label: Some(format!("ModelGraphics{}",i).as_str()),
|
label: Some(format!("Model{} Bind Group",i).as_str()),
|
||||||
});
|
});
|
||||||
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Vertex"),
|
label: Some("Vertex"),
|
||||||
@ -248,7 +258,7 @@ impl GraphicsData {
|
|||||||
usage: wgpu::BufferUsages::VERTEX,
|
usage: wgpu::BufferUsages::VERTEX,
|
||||||
});
|
});
|
||||||
//all of these are being moved here
|
//all of these are being moved here
|
||||||
instance_count+=modeldata.instances.len();
|
instance_count+=n_instances;
|
||||||
self.models.push(ModelGraphics{
|
self.models.push(ModelGraphics{
|
||||||
instances:modeldata.instances,
|
instances:modeldata.instances,
|
||||||
vertex_buf,
|
vertex_buf,
|
||||||
@ -265,7 +275,10 @@ impl GraphicsData {
|
|||||||
}).collect(),
|
}).collect(),
|
||||||
bind_group: model_bind_group,
|
bind_group: model_bind_group,
|
||||||
model_buf,
|
model_buf,
|
||||||
})
|
});
|
||||||
|
}else{
|
||||||
|
println!("WARNING: Model{} has 0 instances",i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
println!("Graphics Objects: {}",self.models.len());
|
println!("Graphics Objects: {}",self.models.len());
|
||||||
println!("Graphics Instances: {}",instance_count);
|
println!("Graphics Instances: {}",instance_count);
|
||||||
@ -284,47 +297,6 @@ fn get_instances_buffer_data(instances:&Vec<ModelInstance>) -> Vec<f32> {
|
|||||||
raw
|
raw
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_modeldatas(data:obj::ObjData,color:[f32;4]) -> Vec<ModelData>{
|
|
||||||
let mut modeldatas=Vec::new();
|
|
||||||
let mut vertices = Vec::new();
|
|
||||||
let mut vertex_index = std::collections::HashMap::<obj::IndexTuple,u16>::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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entities.push(indices);
|
|
||||||
}
|
|
||||||
modeldatas.push(ModelData {
|
|
||||||
instances: Vec::new(),
|
|
||||||
vertices:vertices.clone(),
|
|
||||||
entities,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
modeldatas
|
|
||||||
}
|
|
||||||
|
|
||||||
impl framework::Example for GraphicsData {
|
impl framework::Example for GraphicsData {
|
||||||
fn optional_features() -> wgpu::Features {
|
fn optional_features() -> wgpu::Features {
|
||||||
wgpu::Features::TEXTURE_COMPRESSION_ASTC
|
wgpu::Features::TEXTURE_COMPRESSION_ASTC
|
||||||
@ -340,85 +312,12 @@ impl framework::Example for GraphicsData {
|
|||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
queue: &wgpu::Queue,
|
queue: &wgpu::Queue,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let unit_cube=obj::ObjData{
|
let unit_cube=primitives::the_unit_cube_lol();
|
||||||
position: vec![
|
|
||||||
[-1.,-1., 1.],//left bottom back
|
|
||||||
[ 1.,-1., 1.],//right bottom back
|
|
||||||
[ 1., 1., 1.],//right top back
|
|
||||||
[-1., 1., 1.],//left top back
|
|
||||||
[-1., 1.,-1.],//left top front
|
|
||||||
[ 1., 1.,-1.],//right top front
|
|
||||||
[ 1.,-1.,-1.],//right bottom front
|
|
||||||
[-1.,-1.,-1.],//left bottom front
|
|
||||||
],
|
|
||||||
texture: vec![[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0]],
|
|
||||||
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: vec![
|
|
||||||
// back (0, 0, 1)
|
|
||||||
obj::SimplePolygon(vec![
|
|
||||||
obj::IndexTuple(0,Some(0),Some(2)),
|
|
||||||
obj::IndexTuple(1,Some(1),Some(2)),
|
|
||||||
obj::IndexTuple(2,Some(2),Some(2)),
|
|
||||||
obj::IndexTuple(3,Some(3),Some(2)),
|
|
||||||
]),
|
|
||||||
// front (0, 0,-1)
|
|
||||||
obj::SimplePolygon(vec![
|
|
||||||
obj::IndexTuple(4,Some(0),Some(5)),
|
|
||||||
obj::IndexTuple(5,Some(1),Some(5)),
|
|
||||||
obj::IndexTuple(6,Some(2),Some(5)),
|
|
||||||
obj::IndexTuple(7,Some(3),Some(5)),
|
|
||||||
]),
|
|
||||||
// right (1, 0, 0)
|
|
||||||
obj::SimplePolygon(vec![
|
|
||||||
obj::IndexTuple(6,Some(0),Some(0)),
|
|
||||||
obj::IndexTuple(5,Some(1),Some(0)),
|
|
||||||
obj::IndexTuple(2,Some(2),Some(0)),
|
|
||||||
obj::IndexTuple(1,Some(3),Some(0)),
|
|
||||||
]),
|
|
||||||
// left (-1, 0, 0)
|
|
||||||
obj::SimplePolygon(vec![
|
|
||||||
obj::IndexTuple(0,Some(0),Some(3)),
|
|
||||||
obj::IndexTuple(3,Some(1),Some(3)),
|
|
||||||
obj::IndexTuple(4,Some(2),Some(3)),
|
|
||||||
obj::IndexTuple(7,Some(3),Some(3)),
|
|
||||||
]),
|
|
||||||
// top (0, 1, 0)
|
|
||||||
obj::SimplePolygon(vec![
|
|
||||||
obj::IndexTuple(5,Some(1),Some(1)),
|
|
||||||
obj::IndexTuple(4,Some(0),Some(1)),
|
|
||||||
obj::IndexTuple(3,Some(3),Some(1)),
|
|
||||||
obj::IndexTuple(2,Some(2),Some(1)),
|
|
||||||
]),
|
|
||||||
// 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)),
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
}]
|
|
||||||
}],
|
|
||||||
material_libs: Vec::new(),
|
|
||||||
};
|
|
||||||
let mut modeldatas = Vec::<ModelData>::new();
|
let mut modeldatas = Vec::<ModelData>::new();
|
||||||
modeldatas.append(&mut 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/teslacyberv3.0.obj")[..]).unwrap(),ModelData::COLOR_FLOATS_WHITE));
|
||||||
modeldatas.append(&mut 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/suzanne.obj")[..]).unwrap(),ModelData::COLOR_FLOATS_WHITE));
|
||||||
modeldatas.append(&mut generate_modeldatas(obj::ObjData::load_buf(&include_bytes!("../models/teapot.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 generate_modeldatas(unit_cube.clone(),ModelData::COLOR_FLOATS_WHITE));
|
modeldatas.append(&mut model::generate_modeldatas(unit_cube.clone(),ModelData::COLOR_FLOATS_WHITE));
|
||||||
println!("models.len = {:?}", modeldatas.len());
|
println!("models.len = {:?}", modeldatas.len());
|
||||||
modeldatas[0].instances.push(ModelInstance{
|
modeldatas[0].instances.push(ModelInstance{
|
||||||
transform:glam::Mat4::from_translation(glam::vec3(10.,0.,-10.)),
|
transform:glam::Mat4::from_translation(glam::vec3(10.,0.,-10.)),
|
||||||
@ -795,7 +694,6 @@ impl framework::Example for GraphicsData {
|
|||||||
let depth_view = Self::create_depth_texture(config, device);
|
let depth_view = Self::create_depth_texture(config, device);
|
||||||
|
|
||||||
let mut graphics=GraphicsData {
|
let mut graphics=GraphicsData {
|
||||||
handy_unit_cube:unit_cube,
|
|
||||||
start_time: Instant::now(),
|
start_time: Instant::now(),
|
||||||
camera,
|
camera,
|
||||||
physics,
|
physics,
|
||||||
@ -817,13 +715,13 @@ impl framework::Example for GraphicsData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
graphics.generate_model_physics(&modeldatas);
|
graphics.generate_model_physics(&modeldatas);
|
||||||
graphics.generate_model_graphics(&device,modeldatas);
|
graphics.generate_model_graphics(&device,&queue,modeldatas,Vec::new());
|
||||||
|
|
||||||
return graphics;
|
return graphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
fn update(&mut self, device: &wgpu::Device, event: winit::event::WindowEvent) {
|
fn update(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, event: winit::event::WindowEvent) {
|
||||||
//nothing atm
|
//nothing atm
|
||||||
match event {
|
match event {
|
||||||
winit::event::WindowEvent::DroppedFile(path) => {
|
winit::event::WindowEvent::DroppedFile(path) => {
|
||||||
@ -840,16 +738,16 @@ impl framework::Example for GraphicsData {
|
|||||||
//.snf = "SNBF"
|
//.snf = "SNBF"
|
||||||
if let (Ok(()),Ok(()))=(std::io::Read::read_exact(&mut input, &mut first_8),std::io::Seek::rewind(&mut input)){
|
if let (Ok(()),Ok(()))=(std::io::Read::read_exact(&mut input, &mut first_8),std::io::Seek::rewind(&mut input)){
|
||||||
//
|
//
|
||||||
if let Some(modeldatas)={
|
if let Some(Ok((modeldatas,textures,spawn_point)))={
|
||||||
if &first_8==b"<roblox!"{
|
if &first_8==b"<roblox!"{
|
||||||
if let Ok(dom) = rbx_binary::from_reader(input){
|
if let Ok(dom) = rbx_binary::from_reader(input){
|
||||||
Some(self.generate_modeldatas_roblox(dom))
|
Some(load_roblox::generate_modeldatas_roblox(dom))
|
||||||
}else{
|
}else{
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}else if &first_8==b"<roblox "{
|
}else if &first_8==b"<roblox "{
|
||||||
if let Ok(dom) = rbx_xml::from_reader(input,rbx_xml::DecodeOptions::default()){
|
if let Ok(dom) = rbx_xml::from_reader(input,rbx_xml::DecodeOptions::default()){
|
||||||
Some(self.generate_modeldatas_roblox(dom))
|
Some(load_roblox::generate_modeldatas_roblox(dom))
|
||||||
}else{
|
}else{
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -863,7 +761,13 @@ impl framework::Example for GraphicsData {
|
|||||||
self.models.clear();
|
self.models.clear();
|
||||||
self.physics.models.clear();
|
self.physics.models.clear();
|
||||||
self.generate_model_physics(&modeldatas);
|
self.generate_model_physics(&modeldatas);
|
||||||
self.generate_model_graphics(device,modeldatas);
|
self.generate_model_graphics(device,queue,modeldatas,textures);
|
||||||
|
//manual reset
|
||||||
|
let time=self.physics.time;
|
||||||
|
instruction::InstructionConsumer::process_instruction(&mut self.physics, instruction::TimedInstruction{
|
||||||
|
time,
|
||||||
|
instruction: body::PhysicsInstruction::SetPosition(spawn_point),
|
||||||
|
})
|
||||||
}else{
|
}else{
|
||||||
println!("No modeldatas were generated");
|
println!("No modeldatas were generated");
|
||||||
}
|
}
|
||||||
|
45
src/model.rs
45
src/model.rs
@ -8,18 +8,63 @@ pub struct Vertex {
|
|||||||
pub color: [f32; 4],
|
pub color: [f32; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct ModelInstance {
|
pub struct ModelInstance {
|
||||||
pub transform: glam::Mat4,
|
pub transform: glam::Mat4,
|
||||||
pub color: glam::Vec4,
|
pub color: glam::Vec4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct ModelData {
|
pub struct ModelData {
|
||||||
pub instances: Vec<ModelInstance>,
|
pub instances: Vec<ModelInstance>,
|
||||||
pub vertices: Vec<Vertex>,
|
pub vertices: Vec<Vertex>,
|
||||||
pub entities: Vec<Vec<u16>>,
|
pub entities: Vec<Vec<u16>>,
|
||||||
|
pub texture: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModelData {
|
impl ModelData {
|
||||||
pub const COLOR_FLOATS_WHITE: [f32;4] = [1.0,1.0,1.0,1.0];
|
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 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<ModelData>{
|
||||||
|
let mut modeldatas=Vec::new();
|
||||||
|
let mut vertices = Vec::new();
|
||||||
|
let mut vertex_index = std::collections::HashMap::<obj::IndexTuple,u16>::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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entities.push(indices);
|
||||||
|
}
|
||||||
|
modeldatas.push(ModelData {
|
||||||
|
instances: Vec::new(),
|
||||||
|
vertices:vertices.clone(),
|
||||||
|
entities,
|
||||||
|
texture: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
modeldatas
|
||||||
|
}
|
76
src/primitives.rs
Normal file
76
src/primitives.rs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
pub fn the_unit_cube_lol() -> obj::ObjData{
|
||||||
|
obj::ObjData{
|
||||||
|
position: vec![
|
||||||
|
[-1.,-1., 1.],//left bottom back
|
||||||
|
[ 1.,-1., 1.],//right bottom back
|
||||||
|
[ 1., 1., 1.],//right top back
|
||||||
|
[-1., 1., 1.],//left top back
|
||||||
|
[-1., 1.,-1.],//left top front
|
||||||
|
[ 1., 1.,-1.],//right top front
|
||||||
|
[ 1.,-1.,-1.],//right bottom front
|
||||||
|
[-1.,-1.,-1.],//left bottom front
|
||||||
|
],
|
||||||
|
texture: vec![[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0]],
|
||||||
|
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: vec![
|
||||||
|
// back (0, 0, 1)
|
||||||
|
obj::SimplePolygon(vec![
|
||||||
|
obj::IndexTuple(0,Some(0),Some(2)),
|
||||||
|
obj::IndexTuple(1,Some(1),Some(2)),
|
||||||
|
obj::IndexTuple(2,Some(2),Some(2)),
|
||||||
|
obj::IndexTuple(3,Some(3),Some(2)),
|
||||||
|
]),
|
||||||
|
// front (0, 0,-1)
|
||||||
|
obj::SimplePolygon(vec![
|
||||||
|
obj::IndexTuple(4,Some(0),Some(5)),
|
||||||
|
obj::IndexTuple(5,Some(1),Some(5)),
|
||||||
|
obj::IndexTuple(6,Some(2),Some(5)),
|
||||||
|
obj::IndexTuple(7,Some(3),Some(5)),
|
||||||
|
]),
|
||||||
|
// right (1, 0, 0)
|
||||||
|
obj::SimplePolygon(vec![
|
||||||
|
obj::IndexTuple(6,Some(0),Some(0)),
|
||||||
|
obj::IndexTuple(5,Some(1),Some(0)),
|
||||||
|
obj::IndexTuple(2,Some(2),Some(0)),
|
||||||
|
obj::IndexTuple(1,Some(3),Some(0)),
|
||||||
|
]),
|
||||||
|
// left (-1, 0, 0)
|
||||||
|
obj::SimplePolygon(vec![
|
||||||
|
obj::IndexTuple(0,Some(0),Some(3)),
|
||||||
|
obj::IndexTuple(3,Some(1),Some(3)),
|
||||||
|
obj::IndexTuple(4,Some(2),Some(3)),
|
||||||
|
obj::IndexTuple(7,Some(3),Some(3)),
|
||||||
|
]),
|
||||||
|
// top (0, 1, 0)
|
||||||
|
obj::SimplePolygon(vec![
|
||||||
|
obj::IndexTuple(5,Some(1),Some(1)),
|
||||||
|
obj::IndexTuple(4,Some(0),Some(1)),
|
||||||
|
obj::IndexTuple(3,Some(3),Some(1)),
|
||||||
|
obj::IndexTuple(2,Some(2),Some(1)),
|
||||||
|
]),
|
||||||
|
// 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)),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
material_libs: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user