forked from StrafesNET/strafe-project
Compare commits
6 Commits
sphere-gen
...
worker-sco
| Author | SHA1 | Date | |
|---|---|---|---|
| 580bbf2cc5 | |||
| 08f6d928cf | |||
| de7b7ba7be | |||
| 008c66e052 | |||
| ba250277bd | |||
| 085d4e7912 |
@@ -16,13 +16,15 @@ WorkerDescription{
|
||||
//up to three frames in flight, dropping new frame requests when all three are busy, and dropping output frames when one renders out of order
|
||||
|
||||
pub fn new<'a>(
|
||||
scope:&'a std::thread::Scope<'a,'_>,
|
||||
mut graphics:crate::graphics::GraphicsState,
|
||||
mut config:wgpu::SurfaceConfiguration,
|
||||
surface:wgpu::Surface,
|
||||
device:wgpu::Device,
|
||||
queue:wgpu::Queue,
|
||||
)->crate::compat_worker::INWorker<'a,Instruction>{
|
||||
crate::compat_worker::INWorker::new(move |ins:Instruction|{
|
||||
)->crate::worker::INWorker<'a,Instruction>{
|
||||
let mut resize=None;
|
||||
crate::worker::INWorker::new(scope,move |ins:Instruction|{
|
||||
match ins{
|
||||
Instruction::GenerateModels(indexed_model_instances)=>{
|
||||
graphics.generate_models(&device,&queue,indexed_model_instances);
|
||||
@@ -31,13 +33,20 @@ pub fn new<'a>(
|
||||
graphics.clear();
|
||||
},
|
||||
Instruction::Resize(size,user_settings)=>{
|
||||
println!("Resizing to {:?}",size);
|
||||
config.width=size.width.max(1);
|
||||
config.height=size.height.max(1);
|
||||
surface.configure(&device,&config);
|
||||
graphics.resize(&device,&config,&user_settings);
|
||||
resize=Some((size,user_settings));
|
||||
}
|
||||
Instruction::Render(physics_output,predicted_time,mouse_pos)=>{
|
||||
if let Some((size,user_settings))=&resize{
|
||||
println!("Resizing to {:?}",size);
|
||||
let t0=std::time::Instant::now();
|
||||
config.width=size.width.max(1);
|
||||
config.height=size.height.max(1);
|
||||
surface.configure(&device,&config);
|
||||
graphics.resize(&device,&config,user_settings);
|
||||
println!("Resize took {:?}",t0.elapsed());
|
||||
}
|
||||
//clear every time w/e
|
||||
resize=None;
|
||||
//this has to go deeper somehow
|
||||
let frame=match surface.get_current_texture(){
|
||||
Ok(frame)=>frame,
|
||||
@@ -59,4 +68,4 @@ pub fn new<'a>(
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,9 +217,9 @@ type RobloxWedgeDescription=[Option<RobloxFaceTextureDescription>;5];
|
||||
type RobloxCornerWedgeDescription=[Option<RobloxFaceTextureDescription>;5];
|
||||
#[derive(Clone,Eq,Hash,PartialEq)]
|
||||
enum RobloxBasePartDescription{
|
||||
Sphere,
|
||||
Sphere(RobloxPartDescription),
|
||||
Part(RobloxPartDescription),
|
||||
Cylinder,
|
||||
Cylinder(RobloxPartDescription),
|
||||
Wedge(RobloxWedgeDescription),
|
||||
CornerWedge(RobloxCornerWedgeDescription),
|
||||
}
|
||||
@@ -298,6 +298,7 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
|
||||
panic!("Part has no Shape!");
|
||||
}
|
||||
},
|
||||
"TrussPart"=>primitives::Primitives::Cube,
|
||||
"WedgePart"=>primitives::Primitives::Wedge,
|
||||
"CornerWedgePart"=>primitives::Primitives::CornerWedge,
|
||||
_=>{
|
||||
@@ -392,9 +393,9 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
|
||||
f5,//Cube::Front
|
||||
]=part_texture_description;
|
||||
let basepart_texture_description=match shape{
|
||||
primitives::Primitives::Sphere=>RobloxBasePartDescription::Sphere,
|
||||
primitives::Primitives::Sphere=>RobloxBasePartDescription::Sphere([f0,f1,f2,f3,f4,f5]),
|
||||
primitives::Primitives::Cube=>RobloxBasePartDescription::Part([f0,f1,f2,f3,f4,f5]),
|
||||
primitives::Primitives::Cylinder=>RobloxBasePartDescription::Cylinder,
|
||||
primitives::Primitives::Cylinder=>RobloxBasePartDescription::Cylinder([f0,f1,f2,f3,f4,f5]),
|
||||
//use front face texture first and use top face texture as a fallback
|
||||
primitives::Primitives::Wedge=>RobloxBasePartDescription::Wedge([
|
||||
f0,//Cube::Right->Wedge::Right
|
||||
@@ -420,8 +421,9 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
|
||||
let model_id=indexed_models.len();
|
||||
model_id_from_description.insert(basepart_texture_description.clone(),model_id);//borrow checker going crazy
|
||||
indexed_models.push(match basepart_texture_description{
|
||||
RobloxBasePartDescription::Sphere=>primitives::unit_sphere(),
|
||||
RobloxBasePartDescription::Part(part_texture_description)=>{
|
||||
RobloxBasePartDescription::Sphere(part_texture_description)
|
||||
|RobloxBasePartDescription::Cylinder(part_texture_description)
|
||||
|RobloxBasePartDescription::Part(part_texture_description)=>{
|
||||
let mut cube_face_description=primitives::CubeFaceDescription::default();
|
||||
for (face_id,roblox_face_description) in part_texture_description.iter().enumerate(){
|
||||
cube_face_description.insert(
|
||||
@@ -441,7 +443,6 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
|
||||
}
|
||||
primitives::generate_partial_unit_cube(cube_face_description)
|
||||
},
|
||||
RobloxBasePartDescription::Cylinder=>primitives::unit_cylinder(),
|
||||
RobloxBasePartDescription::Wedge(wedge_texture_description)=>{
|
||||
let mut wedge_face_description=primitives::WedgeFaceDescription::default();
|
||||
for (face_id,roblox_face_description) in wedge_texture_description.iter().enumerate(){
|
||||
|
||||
@@ -23,11 +23,11 @@ pub enum Instruction{
|
||||
//Graphics(crate::graphics_worker::Instruction),
|
||||
}
|
||||
|
||||
pub fn new(mut physics:crate::physics::PhysicsState,mut graphics_worker:crate::compat_worker::INWorker<crate::graphics_worker::Instruction>)->crate::compat_worker::QNWorker<TimedInstruction<Instruction>>{
|
||||
pub fn new<'a>(scope:&'a std::thread::Scope<'a,'_>,mut physics:crate::physics::PhysicsState,graphics_worker:crate::worker::INWorker<'a,crate::graphics_worker::Instruction>)->crate::worker::QNWorker<'a,TimedInstruction<Instruction>>{
|
||||
let mut mouse_blocking=true;
|
||||
let mut last_mouse_time=physics.next_mouse.time;
|
||||
let mut timeline=std::collections::VecDeque::new();
|
||||
crate::compat_worker::QNWorker::new(move |ins:TimedInstruction<Instruction>|{
|
||||
crate::worker::QNWorker::new(scope,move |ins:TimedInstruction<Instruction>|{
|
||||
if if let Some(phys_input)=match &ins.instruction{
|
||||
Instruction::Input(input_instruction)=>match input_instruction{
|
||||
&InputInstruction::MoveMouse(m)=>{
|
||||
@@ -113,10 +113,11 @@ pub enum Instruction{
|
||||
}
|
||||
match ins.instruction{
|
||||
Instruction::Render=>{
|
||||
graphics_worker.send(crate::graphics_worker::Instruction::Render(physics.output(),ins.time,physics.next_mouse.pos)).unwrap();
|
||||
let _=graphics_worker.send(crate::graphics_worker::Instruction::Render(physics.output(),ins.time,physics.next_mouse.pos));
|
||||
},
|
||||
Instruction::Resize(size,user_settings)=>{
|
||||
graphics_worker.send(crate::graphics_worker::Instruction::Resize(size,user_settings)).unwrap();
|
||||
//block!
|
||||
graphics_worker.blocking_send(crate::graphics_worker::Instruction::Resize(size,user_settings)).unwrap();
|
||||
},
|
||||
Instruction::GenerateModels(indexed_model_instances)=>{
|
||||
physics.generate_models(&indexed_model_instances);
|
||||
|
||||
@@ -126,152 +126,8 @@ const CORNERWEDGE_DEFAULT_NORMALS:[Planar64Vec3;5]=[
|
||||
Planar64Vec3::int( 0,-1, 0),//CornerWedge::Bottom
|
||||
Planar64Vec3::int( 0, 0,-1),//CornerWedge::Front
|
||||
];
|
||||
const GON:u32=6;
|
||||
const SPHERE_STUFF:([[[[u32;3];4];((GON-1)*(GON-1)) as usize];6])={
|
||||
const CUBE_EDGES:[[u32;2];12]=[[0,1],[0,3],[0,7],[1,2],[1,6],[2,3],[2,5],[3,4],[4,5],[4,7],[5,6],[6,7]];
|
||||
const fn get_pos_id(p:[[u32;3];4],tex_id:u32)->u32{
|
||||
if p[0][1]==tex_id{
|
||||
return p[0][0];
|
||||
}
|
||||
if p[1][1]==tex_id{
|
||||
return p[1][0];
|
||||
}
|
||||
if p[2][1]==tex_id{
|
||||
return p[2][0];
|
||||
}
|
||||
if p[3][1]==tex_id{
|
||||
return p[3][0];
|
||||
}
|
||||
panic!("tex missing")
|
||||
}
|
||||
const fn get_edge_id(v0:u32,v1:u32)->(u32,bool){
|
||||
(match if v0<v1{[v0,v1]}else{[v1,v0]}{
|
||||
[0,1]=>0,
|
||||
[0,3]=>1,
|
||||
[0,7]=>2,
|
||||
[1,2]=>3,
|
||||
[1,6]=>4,
|
||||
[2,3]=>5,
|
||||
[2,5]=>6,
|
||||
[3,4]=>7,
|
||||
[4,5]=>8,
|
||||
[4,7]=>9,
|
||||
[5,6]=>10,
|
||||
[6,7]=>11,
|
||||
_=>panic!(":)")
|
||||
},v0<v1)
|
||||
}
|
||||
const fn get_idx(face_id:u32,v00:u32,v10:u32,v11:u32,v01:u32,x:u32,y:u32)->u32{
|
||||
if x==0&&y==0{
|
||||
return v00
|
||||
}
|
||||
if x==0&&y==GON-1{
|
||||
return v01
|
||||
}
|
||||
if x==GON-1&&y==GON-1{
|
||||
return v11
|
||||
}
|
||||
if x==GON-1&&y==0{
|
||||
return v10
|
||||
}
|
||||
if x==0{
|
||||
//left edge
|
||||
let (edge_id,parity)=get_edge_id(v00,v01);
|
||||
if parity{
|
||||
return 8+edge_id*(GON-2)+(y-1)
|
||||
}else{
|
||||
return 8+edge_id*(GON-2)+(GON-(y-1))
|
||||
}
|
||||
}
|
||||
if x==GON-1{
|
||||
//right edge
|
||||
let (edge_id,parity)=get_edge_id(v10,v11);
|
||||
if parity{
|
||||
return 8+edge_id*(GON-2)+(y-1)
|
||||
}else{
|
||||
return 8+edge_id*(GON-2)+(GON-(y-1))
|
||||
}
|
||||
}
|
||||
if y==0{
|
||||
//top edge
|
||||
let (edge_id,parity)=get_edge_id(v00,v10);
|
||||
if parity{
|
||||
return 8+edge_id*(GON-2)+(x-1)
|
||||
}else{
|
||||
return 8+edge_id*(GON-2)+(GON-(x-1))
|
||||
}
|
||||
}
|
||||
if y==GON-1{
|
||||
//bottom edge
|
||||
let (edge_id,parity)=get_edge_id(v01,v11);
|
||||
if parity{
|
||||
return 8+edge_id*(GON-2)+(x-1)
|
||||
}else{
|
||||
return 8+edge_id*(GON-2)+(GON-(x-1))
|
||||
}
|
||||
}
|
||||
return 8+12*(GON-2)+face_id*(GON-2)*(GON-2)+(x-1)+(y-1)*(GON-2)
|
||||
}
|
||||
//topology (indexed polys)
|
||||
let mut polys=[[[[0u32;3];4];((GON-1)*(GON-1)) as usize];6];
|
||||
let mut face_id=0;
|
||||
while face_id<6{
|
||||
let p=CUBE_DEFAULT_POLYS[face_id];
|
||||
//vertex ids
|
||||
let v00=get_pos_id(p,0);//top left
|
||||
let v10=get_pos_id(p,1);//top right
|
||||
let v11=get_pos_id(p,2);//bottom right
|
||||
let v01=get_pos_id(p,3);//bottom left
|
||||
let mut i=0;
|
||||
while i<(GON-1)*(GON-1){
|
||||
let x=i as u32%GON;
|
||||
let y=i as u32/GON;
|
||||
let i00=get_idx(face_id as u32,v00,v10,v11,v01,x+0,y+0);
|
||||
let i10=get_idx(face_id as u32,v00,v10,v11,v01,x+1,y+0);
|
||||
let i11=get_idx(face_id as u32,v00,v10,v11,v01,x+1,y+1);
|
||||
let i01=get_idx(face_id as u32,v00,v10,v11,v01,x+0,y+1);
|
||||
//[pos,tex,norm]
|
||||
polys[face_id][i as usize][0]=[i00,(x+0)+(y+0)*GON,i00];
|
||||
polys[face_id][i as usize][1]=[i10,(x+1)+(y+0)*GON,i10];
|
||||
polys[face_id][i as usize][2]=[i11,(x+1)+(y+1)*GON,i11];
|
||||
polys[face_id][i as usize][3]=[i01,(x+0)+(y+1)*GON,i01];
|
||||
i+=1;
|
||||
}
|
||||
face_id+=1;
|
||||
}
|
||||
//verts
|
||||
const N_VERTS:usize=(8+12*(GON-2)+6*(GON-2)*(GON-2)) as usize;
|
||||
let mut verts=[Planar64Vec3::ZERO;N_VERTS];
|
||||
let mut i=0;
|
||||
while i<8{
|
||||
verts[i]=CUBE_DEFAULT_VERTICES[i].normalize();
|
||||
i+=1;
|
||||
}
|
||||
i=0;
|
||||
while i<12{
|
||||
//
|
||||
}
|
||||
i=0;
|
||||
while i<6{
|
||||
//
|
||||
}
|
||||
//tex
|
||||
let mut tex=[TextureCoordinate::new(0.0,0.0);(GON*GON) as usize];
|
||||
let mut i=0;
|
||||
while i<(GON*GON) as usize{
|
||||
let x=i as u32%GON;
|
||||
let y=i as u32/GON;
|
||||
tex[i]=TextureCoordinate::new(x as f32/(GON-1) as f32,y as f32/(GON-1) as f32);
|
||||
i+=1;
|
||||
}
|
||||
(verts,tex,polys)
|
||||
};
|
||||
pub fn unit_sphere()->crate::model::IndexedModel{
|
||||
let mut indexed_model=crate::model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/suzanne.obj")[..]).unwrap(),Color4::ONE).remove(0);
|
||||
for pos in indexed_model.unique_pos.iter_mut(){
|
||||
*pos=*pos/2;
|
||||
}
|
||||
indexed_model
|
||||
unit_cube()
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct CubeFaceDescription([Option<FaceDescription>;6]);
|
||||
@@ -293,13 +149,8 @@ pub fn unit_cube()->crate::model::IndexedModel{
|
||||
t.insert(CubeFace::Front,FaceDescription::default());
|
||||
generate_partial_unit_cube(t)
|
||||
}
|
||||
const TEAPOT_TRANSFORM:crate::integer::Planar64Mat3=crate::integer::Planar64Mat3::int_from_cols_array([0,1,0, -1,0,0, 0,0,1]);
|
||||
pub fn unit_cylinder()->crate::model::IndexedModel{
|
||||
let mut indexed_model=crate::model::generate_indexed_model_list_from_obj(obj::ObjData::load_buf(&include_bytes!("../models/teapot.obj")[..]).unwrap(),Color4::ONE).remove(0);
|
||||
for pos in indexed_model.unique_pos.iter_mut(){
|
||||
*pos=TEAPOT_TRANSFORM*(*pos)/10;
|
||||
}
|
||||
indexed_model
|
||||
unit_cube()
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct WedgeFaceDescription([Option<FaceDescription>;5]);
|
||||
|
||||
32
src/setup.rs
32
src/setup.rs
@@ -232,20 +232,32 @@ impl SetupContextSetup{
|
||||
let (window,event_loop,setup_context)=self.into_split();
|
||||
|
||||
//dedicated thread to ping request redraw back and resize the window doesn't seem logical
|
||||
|
||||
let window=crate::window::WindowContextSetup::new(&setup_context,window);
|
||||
//the thread that spawns the physics thread
|
||||
let window_thread=window.into_worker(setup_context);
|
||||
|
||||
println!("Entering event loop...");
|
||||
//but here I am doing it
|
||||
let root_time=std::time::Instant::now();
|
||||
run_event_loop(event_loop,window_thread,root_time).unwrap();
|
||||
std::thread::scope(|s|{
|
||||
let window=crate::window::WindowContextSetup::new(&setup_context,window);
|
||||
//the thread that spawns the physics thread
|
||||
let window_thread=window.into_worker(s,setup_context);
|
||||
|
||||
//schedule frames at 165fps
|
||||
let event_loop_proxy=event_loop.create_proxy();
|
||||
|
||||
s.spawn(move ||{
|
||||
loop{
|
||||
std::thread::sleep(std::time::Duration::from_nanos(1_000_000_000/165));
|
||||
event_loop_proxy.send_event(()).ok();
|
||||
}
|
||||
});
|
||||
|
||||
println!("Entering event loop...");
|
||||
run_event_loop(event_loop,window_thread,root_time).unwrap();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn run_event_loop(
|
||||
event_loop:winit::event_loop::EventLoop<()>,
|
||||
mut window_thread:crate::compat_worker::QNWorker<TimedInstruction<WindowInstruction>>,
|
||||
window_thread:crate::worker::QNWorker<TimedInstruction<WindowInstruction>>,
|
||||
root_time:std::time::Instant
|
||||
)->Result<(),winit::error::EventLoopError>{
|
||||
event_loop.run(move |event,elwt|{
|
||||
@@ -256,7 +268,7 @@ fn run_event_loop(
|
||||
// winit::event_loop::ControlFlow::Poll
|
||||
// };
|
||||
match event{
|
||||
winit::event::Event::AboutToWait=>{
|
||||
winit::event::Event::UserEvent(())=>{
|
||||
window_thread.send(TimedInstruction{time,instruction:WindowInstruction::RequestRedraw}).unwrap();
|
||||
}
|
||||
winit::event::Event::WindowEvent {
|
||||
@@ -300,4 +312,4 @@ fn run_event_loop(
|
||||
_=>{}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ struct WindowContext<'a>{
|
||||
screen_size:glam::UVec2,
|
||||
user_settings:crate::settings::UserSettings,
|
||||
window:winit::window::Window,
|
||||
physics_thread:crate::compat_worker::QNWorker<'a, TimedInstruction<crate::physics_worker::Instruction>>,
|
||||
physics_thread:crate::worker::QNWorker<'a,TimedInstruction<crate::physics_worker::Instruction>>,
|
||||
}
|
||||
|
||||
impl WindowContext<'_>{
|
||||
@@ -194,9 +194,9 @@ impl WindowContextSetup{
|
||||
}
|
||||
}
|
||||
|
||||
fn into_context<'a>(self,setup_context:crate::setup::SetupContext)->WindowContext<'a>{
|
||||
fn into_context<'a>(self,scope:&'a std::thread::Scope<'a,'_>,setup_context:crate::setup::SetupContext)->WindowContext<'a>{
|
||||
let screen_size=glam::uvec2(setup_context.config.width,setup_context.config.height);
|
||||
let graphics_thread=crate::graphics_worker::new(self.graphics,setup_context.config,setup_context.surface,setup_context.device,setup_context.queue);
|
||||
let graphics_thread=crate::graphics_worker::new(scope,self.graphics,setup_context.config,setup_context.surface,setup_context.device,setup_context.queue);
|
||||
WindowContext{
|
||||
manual_mouse_lock:false,
|
||||
mouse:crate::physics::MouseState::default(),
|
||||
@@ -204,13 +204,13 @@ impl WindowContextSetup{
|
||||
screen_size,
|
||||
user_settings:self.user_settings,
|
||||
window:self.window,
|
||||
physics_thread:crate::physics_worker::new(self.physics,graphics_thread),
|
||||
physics_thread:crate::physics_worker::new(scope,self.physics,graphics_thread),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_worker<'a>(self,setup_context:crate::setup::SetupContext)->crate::compat_worker::QNWorker<'a,TimedInstruction<WindowInstruction>>{
|
||||
let mut window_context=self.into_context(setup_context);
|
||||
crate::compat_worker::QNWorker::new(move |ins:TimedInstruction<WindowInstruction>|{
|
||||
pub fn into_worker<'a>(self,scope:&'a std::thread::Scope<'a,'_>,setup_context:crate::setup::SetupContext)->crate::worker::QNWorker<'a,TimedInstruction<WindowInstruction>>{
|
||||
let mut window_context=self.into_context(scope,setup_context);
|
||||
crate::worker::QNWorker::new(scope,move |ins:TimedInstruction<WindowInstruction>|{
|
||||
match ins.instruction{
|
||||
WindowInstruction::RequestRedraw=>{
|
||||
window_context.window.request_redraw();
|
||||
@@ -240,4 +240,4 @@ impl WindowContextSetup{
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user