load textures + spawn point

This commit is contained in:
Quaternions 2023-09-22 19:41:27 -07:00
parent ff7b12e90e
commit 31156aadfb
6 changed files with 383 additions and 233 deletions

View File

@ -16,6 +16,8 @@ pub enum PhysicsInstruction {
// bool,//true = Trigger; false = teleport
// bool,//true = Force
// )
//temp
SetPosition(glam::Vec3),
}
pub struct Body {
@ -756,6 +758,7 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
//selectively update body
match &ins.instruction {
PhysicsInstruction::SetWalkTargetVelocity(_)
|PhysicsInstruction::SetPosition(_)
|PhysicsInstruction::SetControlDir(_) => self.time=ins.time,//TODO: queue instructions
PhysicsInstruction::RefreshWalkTarget
|PhysicsInstruction::ReachWalkTargetVelocity
@ -765,6 +768,15 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|PhysicsInstruction::Jump => self.advance_time(ins.time),
}
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) => {
//check ground
match &c.face {

View File

@ -53,7 +53,7 @@ pub trait Example: 'static + Sized {
device: &wgpu::Device,
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 render(
&mut self,
@ -369,7 +369,7 @@ fn start<E: Example>(
println!("{:#?}", instance.generate_report());
}
_ => {
example.update(&device,event);
example.update(&device,&queue,event);
}
},
event::Event::DeviceEvent {

View File

@ -1,3 +1,7 @@
use crate::model::{ModelData,ModelInstance};
use crate::primitives;
fn class_is_a(class: &str, superclass: &str) -> bool {
if class==superclass {
return true
@ -10,16 +14,125 @@ fn class_is_a(class: &str, superclass: &str) -> bool {
}
return false
}
pub fn get_objects(dom:rbx_dom_weak::WeakDom, superclass: &str) -> Result<std::vec::Vec<rbx_dom_weak::Instance>, Box<dyn std::error::Error>> {
let mut objects = std::vec::Vec::<rbx_dom_weak::Instance>::new();
//move matching instances into objects
let (_,mut instances) = dom.into_raw();
for (_,instance) in instances.drain() {
if class_is_a(instance.class.as_str(), superclass) {
objects.push(instance);
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){
for &referent in instance.children() {
if let Some(c) = dom.get_by_ref(referent) {
if class_is_a(c.class.as_str(), superclass) {
objects.push(c.referent());//copy ref
}
recursive_collect_superclass(objects,dom,c,superclass);
}
}
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))
}

View File

@ -6,6 +6,7 @@ mod body;
mod model;
mod zeroes;
mod framework;
mod primitives;
mod instruction;
mod load_roblox;
@ -133,7 +134,6 @@ pub struct GraphicsData {
models: Vec<ModelGraphics>,
depth_view: wgpu::TextureView,
staging_belt: wgpu::util::StagingBelt,
handy_unit_cube: obj::ObjData,
}
impl GraphicsData {
@ -161,51 +161,6 @@ impl GraphicsData {
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>){
self.physics.models.append(&mut modeldatas.iter().map(|m|
//make aabb and run vertices to get realistic bounds
@ -213,59 +168,117 @@ impl GraphicsData {
).flatten().collect());
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
let mut instance_count=0;
self.models.reserve(modeldatas.len());
for (i,modeldata) in modeldatas.drain(..).enumerate() {
let model_uniforms = get_instances_buffer_data(&modeldata.instances);
let model_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some(format!("ModelGraphics{}",i).as_str()),
contents: bytemuck::cast_slice(&model_uniforms),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
});
let model_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &self.bind_group_layouts.model,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: model_buf.as_entire_binding(),
let n_instances=modeldata.instances.len();
if 0<n_instances{
let model_uniforms = get_instances_buffer_data(&modeldata.instances);
let model_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some(format!("Model{} Buf",i).as_str()),
contents: bytemuck::cast_slice(&model_uniforms),
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,
}
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::TextureView(&self.temp_squid_texture_view),
},
wgpu::BindGroupEntry {
binding: 2,
resource: wgpu::BindingResource::Sampler(&self.samplers.repeat),
},
],
label: Some(format!("ModelGraphics{}",i).as_str()),
});
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Vertex"),
contents: bytemuck::cast_slice(&modeldata.vertices),
usage: wgpu::BufferUsages::VERTEX,
});
//all of these are being moved here
instance_count+=modeldata.instances.len();
self.models.push(ModelGraphics{
instances:modeldata.instances,
vertex_buf,
entities: modeldata.entities.iter().map(|indices|{
let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Index"),
contents: bytemuck::cast_slice(&indices),
usage: wgpu::BufferUsages::INDEX,
});
Entity {
index_buf,
index_count: indices.len() as u32,
}
}).collect(),
bind_group: model_bind_group,
model_buf,
})
None=>&self.temp_squid_texture_view,
};
let model_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &self.bind_group_layouts.model,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: model_buf.as_entire_binding(),
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::TextureView(texture_view),
},
wgpu::BindGroupEntry {
binding: 2,
resource: wgpu::BindingResource::Sampler(&self.samplers.repeat),
},
],
label: Some(format!("Model{} Bind Group",i).as_str()),
});
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Vertex"),
contents: bytemuck::cast_slice(&modeldata.vertices),
usage: wgpu::BufferUsages::VERTEX,
});
//all of these are being moved here
instance_count+=n_instances;
self.models.push(ModelGraphics{
instances:modeldata.instances,
vertex_buf,
entities: modeldata.entities.iter().map(|indices|{
let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Index"),
contents: bytemuck::cast_slice(&indices),
usage: wgpu::BufferUsages::INDEX,
});
Entity {
index_buf,
index_count: indices.len() as u32,
}
}).collect(),
bind_group: model_bind_group,
model_buf,
});
}else{
println!("WARNING: Model{} has 0 instances",i);
}
}
println!("Graphics Objects: {}",self.models.len());
println!("Graphics Instances: {}",instance_count);
@ -284,47 +297,6 @@ fn get_instances_buffer_data(instances:&Vec<ModelInstance>) -> Vec<f32> {
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 {
fn optional_features() -> wgpu::Features {
wgpu::Features::TEXTURE_COMPRESSION_ASTC
@ -340,85 +312,12 @@ impl framework::Example for GraphicsData {
device: &wgpu::Device,
queue: &wgpu::Queue,
) -> Self {
let unit_cube=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(),
};
let unit_cube=primitives::the_unit_cube_lol();
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 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 generate_modeldatas(unit_cube.clone(),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 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));
println!("models.len = {:?}", modeldatas.len());
modeldatas[0].instances.push(ModelInstance{
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 mut graphics=GraphicsData {
handy_unit_cube:unit_cube,
start_time: Instant::now(),
camera,
physics,
@ -817,13 +715,13 @@ impl framework::Example for GraphicsData {
};
graphics.generate_model_physics(&modeldatas);
graphics.generate_model_graphics(&device,modeldatas);
graphics.generate_model_graphics(&device,&queue,modeldatas,Vec::new());
return graphics;
}
#[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
match event {
winit::event::WindowEvent::DroppedFile(path) => {
@ -840,16 +738,16 @@ impl framework::Example for GraphicsData {
//.snf = "SNBF"
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 let Ok(dom) = rbx_binary::from_reader(input){
Some(self.generate_modeldatas_roblox(dom))
Some(load_roblox::generate_modeldatas_roblox(dom))
}else{
None
}
}else if &first_8==b"<roblox "{
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{
None
}
@ -863,7 +761,13 @@ impl framework::Example for GraphicsData {
self.models.clear();
self.physics.models.clear();
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{
println!("No modeldatas were generated");
}

View File

@ -8,18 +8,63 @@ pub struct Vertex {
pub color: [f32; 4],
}
#[derive(Clone)]
pub struct ModelInstance {
pub transform: glam::Mat4,
pub color: glam::Vec4,
}
#[derive(Clone)]
pub struct ModelData {
pub instances: Vec<ModelInstance>,
pub vertices: Vec<Vertex>,
pub entities: Vec<Vec<u16>>,
pub texture: Option<u32>,
}
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<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
View 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(),
}
}