Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
267aa89469 | |||
c6cba01dcc | |||
3e7d64b514 | |||
ca5d19e800 | |||
e9bb9e9a9f |
Cargo.lock
engine/physics/src
integration-testing
lib
bsp_loader/src
common/src
deferred_loader
fixed_wide/src
rbx_loader/src
snf/src
strafe-client/src
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -969,8 +969,11 @@ dependencies = [
|
|||||||
name = "integration-testing"
|
name = "integration-testing"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"rbx_dom_weak",
|
||||||
|
"rbx_mesh",
|
||||||
"strafesnet_common",
|
"strafesnet_common",
|
||||||
"strafesnet_physics",
|
"strafesnet_physics",
|
||||||
|
"strafesnet_rbx_loader",
|
||||||
"strafesnet_snf",
|
"strafesnet_snf",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1005,9 +1005,3 @@ fn test_is_empty_volume(){
|
|||||||
assert!(!is_empty_volume([vec3::X.fix_3(),vec3::Y.fix_3(),vec3::Z.fix_3()].to_vec()));
|
assert!(!is_empty_volume([vec3::X.fix_3(),vec3::Y.fix_3(),vec3::Z.fix_3()].to_vec()));
|
||||||
assert!(is_empty_volume([vec3::X.fix_3(),vec3::Y.fix_3(),vec3::Z.fix_3(),vec3::NEG_X.fix_3()].to_vec()));
|
assert!(is_empty_volume([vec3::X.fix_3(),vec3::Y.fix_3(),vec3::Z.fix_3(),vec3::NEG_X.fix_3()].to_vec()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn build_me_a_cube(){
|
|
||||||
let mesh=PhysicsMesh::unit_cube();
|
|
||||||
//println!("mesh={:?}",mesh);
|
|
||||||
}
|
|
||||||
|
@ -229,12 +229,6 @@ impl PhysicsModels{
|
|||||||
.map(|model|&model.transform),
|
.map(|model|&model.transform),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn contact_model(&self,model_id:ContactModelId)->&ContactModel{
|
|
||||||
&self.contact_models[&model_id]
|
|
||||||
}
|
|
||||||
fn intersect_model(&self,model_id:IntersectModelId)->&IntersectModel{
|
|
||||||
&self.intersect_models[&model_id]
|
|
||||||
}
|
|
||||||
fn contact_attr(&self,model_id:ContactModelId)->&gameplay_attributes::ContactAttributes{
|
fn contact_attr(&self,model_id:ContactModelId)->&gameplay_attributes::ContactAttributes{
|
||||||
&self.contact_attributes[&self.contact_models[&model_id].attr_id]
|
&self.contact_attributes[&self.contact_models[&model_id].attr_id]
|
||||||
}
|
}
|
||||||
@ -269,7 +263,7 @@ impl PhysicsCamera{
|
|||||||
);
|
);
|
||||||
self.clamped_mouse_pos=unclamped_mouse_pos;
|
self.clamped_mouse_pos=unclamped_mouse_pos;
|
||||||
}
|
}
|
||||||
pub fn simulate_move_angles(&self,mouse_delta:glam::IVec2)->glam::Vec2 {
|
pub fn simulate_move_angles(&self,mouse_delta:glam::IVec2)->glam::Vec2{
|
||||||
let a=-self.sensitivity.mul_int((self.clamped_mouse_pos+mouse_delta).as_i64vec2());
|
let a=-self.sensitivity.mul_int((self.clamped_mouse_pos+mouse_delta).as_i64vec2());
|
||||||
let ax=Angle32::wrap_from_i64(a.x);
|
let ax=Angle32::wrap_from_i64(a.x);
|
||||||
let ay=Angle32::clamp_from_i64(a.y)
|
let ay=Angle32::clamp_from_i64(a.y)
|
||||||
@ -1873,7 +1867,6 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test{
|
mod test{
|
||||||
use crate::body::VirtualBody;
|
|
||||||
use strafesnet_common::integer::{vec3::{self,int as int3},mat3};
|
use strafesnet_common::integer::{vec3::{self,int as int3},mat3};
|
||||||
use super::*;
|
use super::*;
|
||||||
fn test_collision_axis_aligned(relative_body:Body,expected_collision_time:Option<Time>){
|
fn test_collision_axis_aligned(relative_body:Body,expected_collision_time:Option<Time>){
|
||||||
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
rbx_dom_weak = { version = "2.7.0", registry = "strafesnet" }
|
||||||
|
rbx_mesh = { version = "0.1.2", path = "../../rbx_mesh" }
|
||||||
strafesnet_common = { version = "0.5.2", path = "../lib/common", registry = "strafesnet" }
|
strafesnet_common = { version = "0.5.2", path = "../lib/common", registry = "strafesnet" }
|
||||||
strafesnet_physics = { version = "0.1.0", path = "../engine/physics", registry = "strafesnet" }
|
strafesnet_physics = { version = "0.1.0", path = "../engine/physics", registry = "strafesnet" }
|
||||||
|
strafesnet_rbx_loader = { version = "0.5.2", path = "../lib/rbx_loader", registry = "strafesnet" }
|
||||||
strafesnet_snf = { path = "../lib/snf", registry = "strafesnet" }
|
strafesnet_snf = { path = "../lib/snf", registry = "strafesnet" }
|
||||||
|
@ -4,7 +4,7 @@ use std::{io::{Cursor,Read},path::Path};
|
|||||||
use strafesnet_physics::physics::{PhysicsData,PhysicsState,PhysicsContext};
|
use strafesnet_physics::physics::{PhysicsData,PhysicsState,PhysicsContext};
|
||||||
|
|
||||||
fn main(){
|
fn main(){
|
||||||
test_determinism().unwrap();
|
decode_all_unions().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@ -219,3 +219,125 @@ fn test_determinism()->Result<(),ReplayError>{
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum UnionError{
|
||||||
|
IO(std::io::Error),
|
||||||
|
Read(strafesnet_rbx_loader::ReadError),
|
||||||
|
Union(rbx_mesh::physics_data::Error),
|
||||||
|
}
|
||||||
|
impl From<std::io::Error> for UnionError{
|
||||||
|
fn from(value:std::io::Error)->Self{
|
||||||
|
Self::IO(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<strafesnet_rbx_loader::ReadError> for UnionError{
|
||||||
|
fn from(value:strafesnet_rbx_loader::ReadError)->Self{
|
||||||
|
Self::Read(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<rbx_mesh::physics_data::Error> for UnionError{
|
||||||
|
fn from(value:rbx_mesh::physics_data::Error)->Self{
|
||||||
|
Self::Union(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn test_unions_in_map(path:impl AsRef<Path>)->Result<u32,UnionError>{
|
||||||
|
let mut count=0;
|
||||||
|
let file=read_entire_file(path)?;
|
||||||
|
let model=strafesnet_rbx_loader::read(file)?;
|
||||||
|
let dom=model.as_ref();
|
||||||
|
for instance in dom.descendants(){
|
||||||
|
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get("PhysicsData"){
|
||||||
|
count+=1;
|
||||||
|
let physics_data:&[u8]=data.as_ref();
|
||||||
|
if let b""=physics_data{
|
||||||
|
continue;
|
||||||
|
}else{
|
||||||
|
let mut cursor=std::io::Cursor::new(physics_data);
|
||||||
|
let physics_data:rbx_mesh::physics_data::PhysicsData=rbx_mesh::read_physics_data(&mut cursor)?;
|
||||||
|
assert_eq!(cursor.position(),cursor.into_inner().len() as u64);
|
||||||
|
match physics_data.collision_data{
|
||||||
|
rbx_mesh::physics_data::CollisionData::Block=>(),
|
||||||
|
rbx_mesh::physics_data::CollisionData::Meshes(_)=>(),
|
||||||
|
rbx_mesh::physics_data::CollisionData::PhysicsInfoMesh(_)=>{
|
||||||
|
println!("pim!");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct UnionResult{
|
||||||
|
path:std::path::PathBuf,
|
||||||
|
result:Result<u32,UnionError>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_union_thread(path:std::path::PathBuf,send:std::sync::mpsc::Sender<UnionResult>){
|
||||||
|
std::thread::spawn(move ||{
|
||||||
|
let result=test_unions_in_map(path.as_path());
|
||||||
|
send.send(UnionResult{
|
||||||
|
path,
|
||||||
|
result,
|
||||||
|
}).unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode_all_unions()->Result<(),std::io::Error>{
|
||||||
|
let thread_limit=std::thread::available_parallelism()?.get();
|
||||||
|
|
||||||
|
let (send,recv)=std::sync::mpsc::channel();
|
||||||
|
|
||||||
|
let mut read_dir=std::fs::read_dir("/run/media/quat/Files/Documents/map-files/verify-scripts/maps/bhop_all")?;
|
||||||
|
|
||||||
|
let mut union_count=0;
|
||||||
|
let mut success_count=0;
|
||||||
|
let mut fail_count=0;
|
||||||
|
let mut f=|thing:UnionResult|{
|
||||||
|
println!("file={:?} result={:?}",thing.path.file_stem(),thing.result);
|
||||||
|
match thing.result{
|
||||||
|
Ok(count)=>{
|
||||||
|
union_count+=count;
|
||||||
|
success_count+=1;
|
||||||
|
},
|
||||||
|
Err(_)=>fail_count+=1,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// spawn threads
|
||||||
|
println!("spawning up to {thread_limit} threads...");
|
||||||
|
let mut active_thread_count=0;
|
||||||
|
while active_thread_count<thread_limit{
|
||||||
|
if let Some(dir_entry_result)=read_dir.next(){
|
||||||
|
if let Some(file_path)=get_file_path(dir_entry_result?)?{
|
||||||
|
active_thread_count+=1;
|
||||||
|
do_union_thread(file_path,send.clone());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// spawn another thread every time a message is received from the channel
|
||||||
|
println!("riding parallelism wave...");
|
||||||
|
while let Some(dir_entry_result)=read_dir.next(){
|
||||||
|
if let Some(file_path)=get_file_path(dir_entry_result?)?{
|
||||||
|
// wait for a thread to complete
|
||||||
|
f(recv.recv().unwrap());
|
||||||
|
do_union_thread(file_path,send.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for remaining threads to complete
|
||||||
|
println!("waiting for all threads to complete...");
|
||||||
|
for _ in 0..active_thread_count{
|
||||||
|
f(recv.recv().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("===RESULTS===\nunion_count={union_count}\nsuccess={success_count}\nfail={fail_count}");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -240,7 +240,7 @@ impl PartialMap2{
|
|||||||
.enumerate().map(|(new_texture_id,(old_texture_id,texture))|{
|
.enumerate().map(|(new_texture_id,(old_texture_id,texture))|{
|
||||||
(texture,(old_texture_id,model::TextureId::new(new_texture_id as u32)))
|
(texture,(old_texture_id,model::TextureId::new(new_texture_id as u32)))
|
||||||
}).unzip();
|
}).unzip();
|
||||||
let render_configs=render_configs.into_iter().map(|(render_config_id,mut render_config)|{
|
let render_configs=render_configs.into_iter().map(|(_render_config_id,mut render_config)|{
|
||||||
//this may generate duplicate no-texture render configs but idc
|
//this may generate duplicate no-texture render configs but idc
|
||||||
render_config.texture=render_config.texture.and_then(|texture_id|
|
render_config.texture=render_config.texture.and_then(|texture_id|
|
||||||
texture_id_map.get(&texture_id).copied()
|
texture_id_map.get(&texture_id).copied()
|
||||||
|
@ -23,7 +23,7 @@ impl PauseState for Unpaused{
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)]
|
#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)]
|
||||||
enum Inner{}
|
pub enum Inner{}
|
||||||
type InnerTime=Time<Inner>;
|
type InnerTime=Time<Inner>;
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug)]
|
#[derive(Clone,Copy,Debug)]
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// This whole thing should be a drive macro
|
||||||
|
|
||||||
pub trait Updatable<Updater>{
|
pub trait Updatable<Updater>{
|
||||||
fn update(&mut self,update:Updater);
|
fn update(&mut self,update:Updater);
|
||||||
}
|
}
|
||||||
@ -53,4 +55,3 @@ impl Updatable<OuterUpdate> for Outer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//*/
|
|
@ -12,8 +12,8 @@ authors = ["Rhys Lloyd <krakow20@gmail.com>"]
|
|||||||
[features]
|
[features]
|
||||||
default = ["legacy"]
|
default = ["legacy"]
|
||||||
legacy = ["dep:url","dep:vbsp"]
|
legacy = ["dep:url","dep:vbsp"]
|
||||||
#roblox = ["dep:lazy-regex"]
|
roblox = []
|
||||||
#source = ["dep:vbsp"]
|
source = ["dep:vbsp"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
strafesnet_common = { path = "../common", registry = "strafesnet" }
|
strafesnet_common = { path = "../common", registry = "strafesnet" }
|
||||||
|
@ -57,7 +57,7 @@ fn from_f32(){
|
|||||||
assert_eq!(b,Ok(a));
|
assert_eq!(b,Ok(a));
|
||||||
//I32F32::MIN hits a special case since it's not representable as a positive signed integer
|
//I32F32::MIN hits a special case since it's not representable as a positive signed integer
|
||||||
//TODO: don't return an overflow because this is technically possible
|
//TODO: don't return an overflow because this is technically possible
|
||||||
let a=I32F32::MIN;
|
let _a=I32F32::MIN;
|
||||||
let b:Result<I32F32,_>=Into::<f32>::into(I32F32::MIN).try_into();
|
let b:Result<I32F32,_>=Into::<f32>::into(I32F32::MIN).try_into();
|
||||||
assert_eq!(b,Err(crate::fixed::FixedFromFloatError::Overflow));
|
assert_eq!(b,Err(crate::fixed::FixedFromFloatError::Overflow));
|
||||||
//16 is within the 24 bits of float precision
|
//16 is within the 24 bits of float precision
|
||||||
|
@ -3,6 +3,7 @@ use rbx_dom_weak::WeakDom;
|
|||||||
|
|
||||||
mod rbx;
|
mod rbx;
|
||||||
mod mesh;
|
mod mesh;
|
||||||
|
mod union;
|
||||||
mod primitives;
|
mod primitives;
|
||||||
|
|
||||||
pub mod data{
|
pub mod data{
|
||||||
@ -42,7 +43,7 @@ pub struct Place{
|
|||||||
services:roblox_emulator::context::Services,
|
services:roblox_emulator::context::Services,
|
||||||
}
|
}
|
||||||
impl Place{
|
impl Place{
|
||||||
fn new(dom:WeakDom)->Option<Self>{
|
pub fn new(dom:WeakDom)->Option<Self>{
|
||||||
let context=roblox_emulator::context::Context::from_ref(&dom);
|
let context=roblox_emulator::context::Context::from_ref(&dom);
|
||||||
Some(Self{
|
Some(Self{
|
||||||
services:context.find_services()?,
|
services:context.find_services()?,
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use rbx_mesh::mesh::{Vertex2, Vertex2Truncated};
|
use rbx_mesh::mesh::{Vertex2,Vertex2Truncated};
|
||||||
use strafesnet_common::{integer::vec3,model::{self, ColorId, IndexedVertex, NormalId, PolygonGroup, PolygonList, PositionId, TextureCoordinateId, VertexId}};
|
use strafesnet_common::{integer::vec3,model::{self,ColorId,IndexedVertex,NormalId,PolygonGroup,PolygonList,PositionId,RenderConfigId,TextureCoordinateId,VertexId}};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error{
|
pub enum Error{
|
||||||
Planar64Vec3(strafesnet_common::integer::Planar64TryFromFloatError),
|
Planar64Vec3(strafesnet_common::integer::Planar64TryFromFloatError),
|
||||||
@ -204,7 +205,13 @@ pub fn convert(roblox_mesh_bytes:crate::data::RobloxMeshBytes)->Result<model::Me
|
|||||||
unique_vertices,
|
unique_vertices,
|
||||||
polygon_groups,
|
polygon_groups,
|
||||||
//these should probably be moved to the model...
|
//these should probably be moved to the model...
|
||||||
graphics_groups:Vec::new(),
|
//but what if models want to use the same texture
|
||||||
|
graphics_groups:vec![model::IndexedGraphicsGroup{
|
||||||
|
render:RenderConfigId::new(0),
|
||||||
|
//the lowest lod is highest quality
|
||||||
|
groups:vec![model::PolygonGroupId::new(0)]
|
||||||
|
}],
|
||||||
|
//disable physics
|
||||||
physics_groups:Vec::new(),
|
physics_groups:Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use strafesnet_common::model::{Color4,TextureCoordinate,Mesh,IndexedGraphicsGroup,IndexedPhysicsGroup,IndexedVertex,PolygonGroupId,PolygonGroup,PolygonList,IndexedVertexList,PositionId,TextureCoordinateId,NormalId,ColorId,VertexId,RenderConfigId};
|
use strafesnet_common::model::{Color4,TextureCoordinate,Mesh,IndexedGraphicsGroup,IndexedPhysicsGroup,IndexedVertex,PolygonGroupId,PolygonGroup,PolygonList,PositionId,TextureCoordinateId,NormalId,ColorId,VertexId,RenderConfigId};
|
||||||
use strafesnet_common::integer::{vec3,Planar64Vec3};
|
use strafesnet_common::integer::{vec3,Planar64Vec3};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -126,9 +126,6 @@ const CORNERWEDGE_DEFAULT_NORMALS:[Planar64Vec3;5]=[
|
|||||||
vec3::int( 0,-1, 0),//CornerWedge::Bottom
|
vec3::int( 0,-1, 0),//CornerWedge::Bottom
|
||||||
vec3::int( 0, 0,-1),//CornerWedge::Front
|
vec3::int( 0, 0,-1),//CornerWedge::Front
|
||||||
];
|
];
|
||||||
pub fn unit_sphere(render:RenderConfigId)->Mesh{
|
|
||||||
unit_cube(render)
|
|
||||||
}
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct CubeFaceDescription([Option<FaceDescription>;6]);
|
pub struct CubeFaceDescription([Option<FaceDescription>;6]);
|
||||||
impl CubeFaceDescription{
|
impl CubeFaceDescription{
|
||||||
@ -149,10 +146,6 @@ pub fn unit_cube(render:RenderConfigId)->Mesh{
|
|||||||
t.insert(CubeFace::Front,FaceDescription::new_with_render_id(render));
|
t.insert(CubeFace::Front,FaceDescription::new_with_render_id(render));
|
||||||
generate_partial_unit_cube(t)
|
generate_partial_unit_cube(t)
|
||||||
}
|
}
|
||||||
pub fn unit_cylinder(render:RenderConfigId)->Mesh{
|
|
||||||
//lmao
|
|
||||||
unit_cube(render)
|
|
||||||
}
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WedgeFaceDescription([Option<FaceDescription>;5]);
|
pub struct WedgeFaceDescription([Option<FaceDescription>;5]);
|
||||||
impl WedgeFaceDescription{
|
impl WedgeFaceDescription{
|
||||||
@ -163,15 +156,15 @@ impl WedgeFaceDescription{
|
|||||||
self.0.into_iter().enumerate().filter_map(|v|v.1.map(|u|(v.0,u)))
|
self.0.into_iter().enumerate().filter_map(|v|v.1.map(|u|(v.0,u)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn unit_wedge(render:RenderConfigId)->Mesh{
|
// pub fn unit_wedge(render:RenderConfigId)->Mesh{
|
||||||
let mut t=WedgeFaceDescription::default();
|
// let mut t=WedgeFaceDescription::default();
|
||||||
t.insert(WedgeFace::Right,FaceDescription::new_with_render_id(render));
|
// t.insert(WedgeFace::Right,FaceDescription::new_with_render_id(render));
|
||||||
t.insert(WedgeFace::TopFront,FaceDescription::new_with_render_id(render));
|
// t.insert(WedgeFace::TopFront,FaceDescription::new_with_render_id(render));
|
||||||
t.insert(WedgeFace::Back,FaceDescription::new_with_render_id(render));
|
// t.insert(WedgeFace::Back,FaceDescription::new_with_render_id(render));
|
||||||
t.insert(WedgeFace::Left,FaceDescription::new_with_render_id(render));
|
// t.insert(WedgeFace::Left,FaceDescription::new_with_render_id(render));
|
||||||
t.insert(WedgeFace::Bottom,FaceDescription::new_with_render_id(render));
|
// t.insert(WedgeFace::Bottom,FaceDescription::new_with_render_id(render));
|
||||||
generate_partial_unit_wedge(t)
|
// generate_partial_unit_wedge(t)
|
||||||
}
|
// }
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct CornerWedgeFaceDescription([Option<FaceDescription>;5]);
|
pub struct CornerWedgeFaceDescription([Option<FaceDescription>;5]);
|
||||||
impl CornerWedgeFaceDescription{
|
impl CornerWedgeFaceDescription{
|
||||||
@ -182,15 +175,15 @@ impl CornerWedgeFaceDescription{
|
|||||||
self.0.into_iter().enumerate().filter_map(|v|v.1.map(|u|(v.0,u)))
|
self.0.into_iter().enumerate().filter_map(|v|v.1.map(|u|(v.0,u)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn unit_cornerwedge(render:RenderConfigId)->Mesh{
|
// pub fn unit_cornerwedge(render:RenderConfigId)->Mesh{
|
||||||
let mut t=CornerWedgeFaceDescription::default();
|
// let mut t=CornerWedgeFaceDescription::default();
|
||||||
t.insert(CornerWedgeFace::Right,FaceDescription::new_with_render_id(render));
|
// t.insert(CornerWedgeFace::Right,FaceDescription::new_with_render_id(render));
|
||||||
t.insert(CornerWedgeFace::TopBack,FaceDescription::new_with_render_id(render));
|
// t.insert(CornerWedgeFace::TopBack,FaceDescription::new_with_render_id(render));
|
||||||
t.insert(CornerWedgeFace::TopLeft,FaceDescription::new_with_render_id(render));
|
// t.insert(CornerWedgeFace::TopLeft,FaceDescription::new_with_render_id(render));
|
||||||
t.insert(CornerWedgeFace::Bottom,FaceDescription::new_with_render_id(render));
|
// t.insert(CornerWedgeFace::Bottom,FaceDescription::new_with_render_id(render));
|
||||||
t.insert(CornerWedgeFace::Front,FaceDescription::new_with_render_id(render));
|
// t.insert(CornerWedgeFace::Front,FaceDescription::new_with_render_id(render));
|
||||||
generate_partial_unit_cornerwedge(t)
|
// generate_partial_unit_cornerwedge(t)
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FaceDescription{
|
pub struct FaceDescription{
|
||||||
|
@ -130,9 +130,9 @@ impl ModesBuilder{
|
|||||||
fn push_mode_update(&mut self,mode_id:gameplay_modes::ModeId,mode_update:gameplay_modes::ModeUpdate){
|
fn push_mode_update(&mut self,mode_id:gameplay_modes::ModeId,mode_update:gameplay_modes::ModeUpdate){
|
||||||
self.mode_updates.push((mode_id,mode_update));
|
self.mode_updates.push((mode_id,mode_update));
|
||||||
}
|
}
|
||||||
fn push_stage_update(&mut self,mode_id:gameplay_modes::ModeId,stage_id:gameplay_modes::StageId,stage_update:gameplay_modes::StageUpdate){
|
// fn push_stage_update(&mut self,mode_id:gameplay_modes::ModeId,stage_id:gameplay_modes::StageId,stage_update:gameplay_modes::StageUpdate){
|
||||||
self.stage_updates.push((mode_id,stage_id,stage_update));
|
// self.stage_updates.push((mode_id,stage_id,stage_update));
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:model::ModelId,modes_builder:&mut ModesBuilder,wormhole_in_model_to_id:&mut HashMap<model::ModelId,u32>,wormhole_id_to_out_model:&mut HashMap<u32,model::ModelId>)->attr::CollisionAttributes{
|
fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,model_id:model::ModelId,modes_builder:&mut ModesBuilder,wormhole_in_model_to_id:&mut HashMap<model::ModelId,u32>,wormhole_id_to_out_model:&mut HashMap<u32,model::ModelId>)->attr::CollisionAttributes{
|
||||||
let mut general=attr::GeneralAttributes::default();
|
let mut general=attr::GeneralAttributes::default();
|
||||||
@ -406,6 +406,7 @@ enum RobloxBasePartDescription{
|
|||||||
enum Shape{
|
enum Shape{
|
||||||
Primitive(primitives::Primitives),
|
Primitive(primitives::Primitives),
|
||||||
MeshPart,
|
MeshPart,
|
||||||
|
PhysicsData,
|
||||||
}
|
}
|
||||||
enum MeshAvailability{
|
enum MeshAvailability{
|
||||||
Immediate,
|
Immediate,
|
||||||
@ -446,6 +447,7 @@ where
|
|||||||
let mut primitive_models_deferred_attributes=Vec::new();
|
let mut primitive_models_deferred_attributes=Vec::new();
|
||||||
let mut primitive_meshes=Vec::new();
|
let mut primitive_meshes=Vec::new();
|
||||||
let mut mesh_id_from_description=HashMap::new();
|
let mut mesh_id_from_description=HashMap::new();
|
||||||
|
let mut mesh_id_from_physics_data=HashMap::<&[u8],_>::new();
|
||||||
|
|
||||||
//just going to leave it like this for now instead of reworking the data structures for this whole thing
|
//just going to leave it like this for now instead of reworking the data structures for this whole thing
|
||||||
let textureless_render_group=acquire_render_config_id(None);
|
let textureless_render_group=acquire_render_config_id(None);
|
||||||
@ -471,7 +473,7 @@ where
|
|||||||
object.properties.get("CanCollide"),
|
object.properties.get("CanCollide"),
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let model_transform=planar64_affine3_from_roblox(cf,size);
|
let mut model_transform=planar64_affine3_from_roblox(cf,size);
|
||||||
|
|
||||||
if model_transform.matrix3.det().is_zero(){
|
if model_transform.matrix3.det().is_zero(){
|
||||||
let mut parent_ref=object.parent();
|
let mut parent_ref=object.parent();
|
||||||
@ -485,9 +487,6 @@ where
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//at this point a new model is going to be generated for sure.
|
|
||||||
let model_id=model::ModelId::new(primitive_models_deferred_attributes.len() as u32);
|
|
||||||
|
|
||||||
//TODO: also detect "CylinderMesh" etc here
|
//TODO: also detect "CylinderMesh" etc here
|
||||||
let shape=match object.class.as_str(){
|
let shape=match object.class.as_str(){
|
||||||
"Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get("Shape"){
|
"Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get("Shape"){
|
||||||
@ -506,6 +505,7 @@ where
|
|||||||
"WedgePart"=>Shape::Primitive(primitives::Primitives::Wedge),
|
"WedgePart"=>Shape::Primitive(primitives::Primitives::Wedge),
|
||||||
"CornerWedgePart"=>Shape::Primitive(primitives::Primitives::CornerWedge),
|
"CornerWedgePart"=>Shape::Primitive(primitives::Primitives::CornerWedge),
|
||||||
"MeshPart"=>Shape::MeshPart,
|
"MeshPart"=>Shape::MeshPart,
|
||||||
|
"UnionOperation"=>Shape::PhysicsData,
|
||||||
_=>{
|
_=>{
|
||||||
println!("Unsupported BasePart ClassName={}; defaulting to cube",object.class);
|
println!("Unsupported BasePart ClassName={}; defaulting to cube",object.class);
|
||||||
Shape::Primitive(primitives::Primitives::Cube)
|
Shape::Primitive(primitives::Primitives::Cube)
|
||||||
@ -700,6 +700,38 @@ where
|
|||||||
}else{
|
}else{
|
||||||
panic!("Mesh has no Mesh or Texture");
|
panic!("Mesh has no Mesh or Texture");
|
||||||
},
|
},
|
||||||
|
Shape::PhysicsData=>{
|
||||||
|
//The union mesh is sized already
|
||||||
|
model_transform=planar64_affine3_from_roblox(cf,&rbx_dom_weak::types::Vector3{x:2.0,y:2.0,z:2.0});
|
||||||
|
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get("PhysicsData"){
|
||||||
|
let physics_data=data.as_ref();
|
||||||
|
let mesh_id=if let Some(&mesh_id)=mesh_id_from_physics_data.get(physics_data){
|
||||||
|
mesh_id
|
||||||
|
}else{
|
||||||
|
match crate::union::convert(physics_data){
|
||||||
|
Ok(mesh)=>{
|
||||||
|
let mesh_id=model::MeshId::new(primitive_meshes.len() as u32);
|
||||||
|
primitive_meshes.push(mesh);
|
||||||
|
mesh_id_from_physics_data.insert(physics_data,mesh_id);
|
||||||
|
mesh_id
|
||||||
|
},
|
||||||
|
Err(e)=>{
|
||||||
|
println!("Union mesh decode error {e:?}");
|
||||||
|
*mesh_id_from_description.entry(RobloxBasePartDescription::Part(RobloxPartDescription::default()))
|
||||||
|
.or_insert_with(||{
|
||||||
|
let mesh_id=model::MeshId::new(primitive_meshes.len() as u32);
|
||||||
|
let mesh=primitives::unit_cube(textureless_render_group);
|
||||||
|
primitive_meshes.push(mesh);
|
||||||
|
mesh_id
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(MeshAvailability::Immediate,mesh_id)
|
||||||
|
}else{
|
||||||
|
panic!("Mesh has no Mesh or Texture");
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
let model_deferred_attributes=ModelDeferredAttributes{
|
let model_deferred_attributes=ModelDeferredAttributes{
|
||||||
mesh:mesh_id,
|
mesh:mesh_id,
|
||||||
@ -779,12 +811,10 @@ impl PartialMap1{
|
|||||||
.entry(render).or_insert_with(||{
|
.entry(render).or_insert_with(||{
|
||||||
let mesh_id=model::MeshId::new(self.primitive_meshes.len() as u32);
|
let mesh_id=model::MeshId::new(self.primitive_meshes.len() as u32);
|
||||||
let mut mesh_clone=mesh_with_aabb.mesh.clone();
|
let mut mesh_clone=mesh_with_aabb.mesh.clone();
|
||||||
//add a render group lool
|
//set the render group lool
|
||||||
mesh_clone.graphics_groups.push(model::IndexedGraphicsGroup{
|
if let Some(graphics_group)=mesh_clone.graphics_groups.first_mut(){
|
||||||
render,
|
graphics_group.render=render;
|
||||||
//the lowest lod is highest quality
|
}
|
||||||
groups:vec![model::PolygonGroupId::new(0)]
|
|
||||||
});
|
|
||||||
self.primitive_meshes.push(mesh_clone);
|
self.primitive_meshes.push(mesh_clone);
|
||||||
mesh_id
|
mesh_id
|
||||||
}),
|
}),
|
||||||
@ -889,8 +919,14 @@ impl PartialMap2{
|
|||||||
=textures.into_iter().enumerate().map(|(new_texture_id,(old_texture_id,texture))|{
|
=textures.into_iter().enumerate().map(|(new_texture_id,(old_texture_id,texture))|{
|
||||||
(texture,(old_texture_id,model::TextureId::new(new_texture_id as u32)))
|
(texture,(old_texture_id,model::TextureId::new(new_texture_id as u32)))
|
||||||
}).unzip();
|
}).unzip();
|
||||||
let render_configs=render_configs.into_iter().map(|(render_config_id,mut render_config)|{
|
let render_configs=render_configs.into_iter().map(|(_render_config_id,mut render_config)|{
|
||||||
//this may generate duplicate no-texture render configs but idc
|
// This may generate duplicate no-texture render configs but idc
|
||||||
|
//
|
||||||
|
// This is because some textures may not exist, so the render config
|
||||||
|
// that it points to is unique but is texture.
|
||||||
|
//
|
||||||
|
// I don't think this needs to be fixed because missing textures
|
||||||
|
// should be a conversion error anyways.
|
||||||
render_config.texture=render_config.texture.and_then(|texture_id|
|
render_config.texture=render_config.texture.and_then(|texture_id|
|
||||||
texture_id_map.get(&texture_id).copied()
|
texture_id_map.get(&texture_id).copied()
|
||||||
);
|
);
|
||||||
|
118
lib/rbx_loader/src/union.rs
Normal file
118
lib/rbx_loader/src/union.rs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use strafesnet_common::model::{self, ColorId, IndexedVertex, NormalId, PolygonGroup, PolygonGroupId, PolygonList, PositionId, RenderConfigId, TextureCoordinateId, VertexId};
|
||||||
|
use strafesnet_common::integer::vec3;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error{
|
||||||
|
Block,
|
||||||
|
MissingVertexId(u32),
|
||||||
|
Planar64Vec3(strafesnet_common::integer::Planar64TryFromFloatError),
|
||||||
|
RobloxPhysicsData(rbx_mesh::physics_data::Error),
|
||||||
|
}
|
||||||
|
impl std::fmt::Display for Error{
|
||||||
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
|
write!(f,"{self:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error{}
|
||||||
|
pub fn convert(roblox_physics_data:&[u8])->Result<model::Mesh,Error>{
|
||||||
|
let mut cursor=std::io::Cursor::new(roblox_physics_data);
|
||||||
|
let physics_data:rbx_mesh::physics_data::PhysicsData=rbx_mesh::read_physics_data(&mut cursor).map_err(Error::RobloxPhysicsData)?;
|
||||||
|
assert_eq!(cursor.position(),cursor.into_inner().len() as u64);
|
||||||
|
let meshes=match physics_data.collision_data{
|
||||||
|
rbx_mesh::physics_data::CollisionData::Block=>return Err(Error::Block),
|
||||||
|
rbx_mesh::physics_data::CollisionData::Meshes(meshes)=>meshes.meshes,
|
||||||
|
rbx_mesh::physics_data::CollisionData::PhysicsInfoMesh(pim)=>vec![pim.mesh],
|
||||||
|
};
|
||||||
|
let mut unique_pos=Vec::new();
|
||||||
|
let mut pos_id_from=HashMap::new();
|
||||||
|
let mut unique_tex=Vec::new();
|
||||||
|
let mut tex_id_from=HashMap::new();
|
||||||
|
let mut unique_normal=Vec::new();
|
||||||
|
let mut normal_id_from=HashMap::new();
|
||||||
|
let mut unique_color=Vec::new();
|
||||||
|
let mut color_id_from=HashMap::new();
|
||||||
|
let mut unique_vertices=Vec::new();
|
||||||
|
let mut vertex_id_from=HashMap::new();
|
||||||
|
let mut acquire_pos_id=|pos|{
|
||||||
|
let p=vec3::try_from_f32_array(pos).map_err(Error::Planar64Vec3)?;
|
||||||
|
Ok(PositionId::new(*pos_id_from.entry(p).or_insert_with(||{
|
||||||
|
let pos_id=unique_pos.len();
|
||||||
|
unique_pos.push(p);
|
||||||
|
pos_id
|
||||||
|
}) as u32))
|
||||||
|
};
|
||||||
|
let mut acquire_tex_id=|tex|{
|
||||||
|
let h=bytemuck::cast::<[f32;2],[u32;2]>(tex);
|
||||||
|
TextureCoordinateId::new(*tex_id_from.entry(h).or_insert_with(||{
|
||||||
|
let tex_id=unique_tex.len();
|
||||||
|
unique_tex.push(glam::Vec2::from_array(tex));
|
||||||
|
tex_id
|
||||||
|
}) as u32)
|
||||||
|
};
|
||||||
|
let mut acquire_normal_id=|normal|{
|
||||||
|
let n=vec3::try_from_f32_array(normal).map_err(Error::Planar64Vec3)?;
|
||||||
|
Ok(NormalId::new(*normal_id_from.entry(n).or_insert_with(||{
|
||||||
|
let normal_id=unique_normal.len();
|
||||||
|
unique_normal.push(n);
|
||||||
|
normal_id
|
||||||
|
}) as u32))
|
||||||
|
};
|
||||||
|
let mut acquire_color_id=|color|{
|
||||||
|
let h=bytemuck::cast::<[f32;4],[u32;4]>(color);
|
||||||
|
ColorId::new(*color_id_from.entry(h).or_insert_with(||{
|
||||||
|
let color_id=unique_color.len();
|
||||||
|
unique_color.push(glam::Vec4::from_array(color));
|
||||||
|
color_id
|
||||||
|
}) as u32)
|
||||||
|
};
|
||||||
|
let mut acquire_vertex_id=|vertex:IndexedVertex|{
|
||||||
|
VertexId::new(*vertex_id_from.entry(vertex.clone()).or_insert_with(||{
|
||||||
|
let vertex_id=unique_vertices.len();
|
||||||
|
unique_vertices.push(vertex);
|
||||||
|
vertex_id
|
||||||
|
}) as u32)
|
||||||
|
};
|
||||||
|
let color=acquire_color_id([1.0f32;4]);
|
||||||
|
let tex=acquire_tex_id([0.0f32;2]);
|
||||||
|
let polygon_groups:Vec<PolygonGroup>=meshes.into_iter().map(|mesh|{
|
||||||
|
Ok(PolygonGroup::PolygonList(PolygonList::new(mesh.faces.into_iter().map(|[vertex_id0,vertex_id1,vertex_id2]|{
|
||||||
|
let v0=mesh.vertices.get(vertex_id0.0 as usize).ok_or(Error::MissingVertexId(vertex_id0.0))?;
|
||||||
|
let v1=mesh.vertices.get(vertex_id1.0 as usize).ok_or(Error::MissingVertexId(vertex_id1.0))?;
|
||||||
|
let v2=mesh.vertices.get(vertex_id2.0 as usize).ok_or(Error::MissingVertexId(vertex_id2.0))?;
|
||||||
|
let vertex_norm=(glam::Vec3::from_slice(v1)-glam::Vec3::from_slice(v0))
|
||||||
|
.cross(glam::Vec3::from_slice(v2)-glam::Vec3::from_slice(v0)).to_array();
|
||||||
|
let mut ingest_vertex_id=|&vertex_pos:&[f32;3]|Ok(acquire_vertex_id(IndexedVertex{
|
||||||
|
pos:acquire_pos_id(vertex_pos)?,
|
||||||
|
tex,
|
||||||
|
normal:acquire_normal_id(vertex_norm)?,
|
||||||
|
color,
|
||||||
|
}));
|
||||||
|
Ok(vec![
|
||||||
|
ingest_vertex_id(v0)?,
|
||||||
|
ingest_vertex_id(v1)?,
|
||||||
|
ingest_vertex_id(v2)?,
|
||||||
|
])
|
||||||
|
}).collect::<Result<_,_>>()?)))
|
||||||
|
}).collect::<Result<_,_>>()?;
|
||||||
|
let graphics_groups=vec![model::IndexedGraphicsGroup{
|
||||||
|
render:RenderConfigId::new(0),
|
||||||
|
groups:(0..polygon_groups.len()).map(|id|PolygonGroupId::new(id as u32)).collect()
|
||||||
|
}];
|
||||||
|
let physics_groups=(0..polygon_groups.len()).map(|id|model::IndexedPhysicsGroup{
|
||||||
|
groups:vec![PolygonGroupId::new(id as u32)]
|
||||||
|
}).collect();
|
||||||
|
Ok(model::Mesh{
|
||||||
|
unique_pos,
|
||||||
|
unique_normal,
|
||||||
|
unique_tex,
|
||||||
|
unique_color,
|
||||||
|
unique_vertices,
|
||||||
|
polygon_groups,
|
||||||
|
graphics_groups,
|
||||||
|
physics_groups,
|
||||||
|
})
|
||||||
|
}
|
@ -95,21 +95,6 @@ enum ResourceType{
|
|||||||
//Video,
|
//Video,
|
||||||
//Animation,
|
//Animation,
|
||||||
}
|
}
|
||||||
const RESOURCE_TYPE_VARIANT_COUNT:u8=2;
|
|
||||||
#[binrw]
|
|
||||||
#[brw(little)]
|
|
||||||
struct ResourceId(u128);
|
|
||||||
impl ResourceId{
|
|
||||||
fn resource_type(&self)->Option<ResourceType>{
|
|
||||||
let discriminant=self.0 as u8;
|
|
||||||
//TODO: use this when it is stabilized https://github.com/rust-lang/rust/issues/73662
|
|
||||||
//if (discriminant as usize)<std::mem::variant_count::<ResourceType>(){
|
|
||||||
match discriminant<RESOURCE_TYPE_VARIANT_COUNT{
|
|
||||||
true=>Some(unsafe{std::mem::transmute::<u8,ResourceType>(discriminant)}),
|
|
||||||
false=>None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ResourceMap<T>{
|
struct ResourceMap<T>{
|
||||||
meshes:HashMap<strafesnet_common::model::MeshId,T>,
|
meshes:HashMap<strafesnet_common::model::MeshId,T>,
|
||||||
@ -136,11 +121,6 @@ struct ResourceBlockHeader{
|
|||||||
resource:ResourceType,
|
resource:ResourceType,
|
||||||
id:BlockId,
|
id:BlockId,
|
||||||
}
|
}
|
||||||
#[binrw]
|
|
||||||
#[brw(little)]
|
|
||||||
struct ResourceExternalHeader{
|
|
||||||
resource_uuid:ResourceId,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[brw(little)]
|
#[brw(little)]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ReadError{
|
pub enum ReadError{
|
||||||
#[cfg(feature="roblox")]
|
#[cfg(feature="roblox")]
|
||||||
@ -59,6 +60,7 @@ pub fn read<R:Read+std::io::Seek>(input:R)->Result<ReadFormat,ReadError>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LoadError{
|
pub enum LoadError{
|
||||||
ReadError(ReadError),
|
ReadError(ReadError),
|
||||||
|
@ -20,11 +20,6 @@ struct SetupContextPartial1{
|
|||||||
fn create_window(title:&str,event_loop:&winit::event_loop::EventLoop<()>)->Result<winit::window::Window,winit::error::OsError>{
|
fn create_window(title:&str,event_loop:&winit::event_loop::EventLoop<()>)->Result<winit::window::Window,winit::error::OsError>{
|
||||||
let mut attr=winit::window::WindowAttributes::default();
|
let mut attr=winit::window::WindowAttributes::default();
|
||||||
attr=attr.with_title(title);
|
attr=attr.with_title(title);
|
||||||
#[cfg(windows_OFF)] // TODO
|
|
||||||
{
|
|
||||||
use winit::platform::windows::WindowBuilderExtWindows;
|
|
||||||
builder=builder.with_no_redirection_bitmap(true);
|
|
||||||
}
|
|
||||||
event_loop.create_window(attr)
|
event_loop.create_window(attr)
|
||||||
}
|
}
|
||||||
fn create_instance()->SetupContextPartial1{
|
fn create_instance()->SetupContextPartial1{
|
||||||
@ -105,14 +100,12 @@ impl<'a> SetupContextPartial2<'a>{
|
|||||||
required_downlevel_capabilities.flags - downlevel_capabilities.flags
|
required_downlevel_capabilities.flags - downlevel_capabilities.flags
|
||||||
);
|
);
|
||||||
SetupContextPartial3{
|
SetupContextPartial3{
|
||||||
instance:self.instance,
|
|
||||||
surface:self.surface,
|
surface:self.surface,
|
||||||
adapter,
|
adapter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct SetupContextPartial3<'a>{
|
struct SetupContextPartial3<'a>{
|
||||||
instance:wgpu::Instance,
|
|
||||||
surface:wgpu::Surface<'a>,
|
surface:wgpu::Surface<'a>,
|
||||||
adapter:wgpu::Adapter,
|
adapter:wgpu::Adapter,
|
||||||
}
|
}
|
||||||
@ -138,7 +131,6 @@ impl<'a> SetupContextPartial3<'a>{
|
|||||||
.expect("Unable to find a suitable GPU adapter!");
|
.expect("Unable to find a suitable GPU adapter!");
|
||||||
|
|
||||||
SetupContextPartial4{
|
SetupContextPartial4{
|
||||||
instance:self.instance,
|
|
||||||
surface:self.surface,
|
surface:self.surface,
|
||||||
adapter:self.adapter,
|
adapter:self.adapter,
|
||||||
device,
|
device,
|
||||||
@ -147,7 +139,6 @@ impl<'a> SetupContextPartial3<'a>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct SetupContextPartial4<'a>{
|
struct SetupContextPartial4<'a>{
|
||||||
instance:wgpu::Instance,
|
|
||||||
surface:wgpu::Surface<'a>,
|
surface:wgpu::Surface<'a>,
|
||||||
adapter:wgpu::Adapter,
|
adapter:wgpu::Adapter,
|
||||||
device:wgpu::Device,
|
device:wgpu::Device,
|
||||||
@ -164,7 +155,6 @@ impl<'a> SetupContextPartial4<'a>{
|
|||||||
self.surface.configure(&self.device, &config);
|
self.surface.configure(&self.device, &config);
|
||||||
|
|
||||||
SetupContext{
|
SetupContext{
|
||||||
instance:self.instance,
|
|
||||||
surface:self.surface,
|
surface:self.surface,
|
||||||
device:self.device,
|
device:self.device,
|
||||||
queue:self.queue,
|
queue:self.queue,
|
||||||
@ -173,7 +163,6 @@ impl<'a> SetupContextPartial4<'a>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub struct SetupContext<'a>{
|
pub struct SetupContext<'a>{
|
||||||
pub instance:wgpu::Instance,
|
|
||||||
pub surface:wgpu::Surface<'a>,
|
pub surface:wgpu::Surface<'a>,
|
||||||
pub device:wgpu::Device,
|
pub device:wgpu::Device,
|
||||||
pub queue:wgpu::Queue,
|
pub queue:wgpu::Queue,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user