Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6c3f20eb53 | |||
| 15736b60ce | |||
| 661d706a22 | |||
| 5550d5771e | |||
| c834d1d1ca | |||
| ca9d2238a7 | |||
|
f3bb8dd067
|
695
Cargo.lock
generated
695
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,10 +0,0 @@
|
||||
FROM docker.io/joseluisq/rust-linux-darwin-builder:2.0.0-beta.1-amd64 as build
|
||||
COPY .cargo/config.toml .cargo/config.toml
|
||||
COPY . .
|
||||
RUN cargo build --bin strafe-client --release --target aarch64-apple-darwin
|
||||
# RUN cargo build --release --target x86_64-apple-darwin
|
||||
|
||||
# isolate the binary
|
||||
FROM scratch
|
||||
COPY --from=build /root/src/target/aarch64-apple-darwin/release/strafe-client /
|
||||
ENTRYPOINT ["/strafe-client"]
|
||||
@@ -1 +0,0 @@
|
||||
docker build -f docker/aarch64-apple-darwin.Dockerfile . -o target/aarch64-apple-darwin/release/
|
||||
@@ -11,4 +11,4 @@ id = { version = "0.1.0", registry = "strafesnet" }
|
||||
strafesnet_common = { path = "../../lib/common", registry = "strafesnet" }
|
||||
strafesnet_session = { path = "../session", registry = "strafesnet" }
|
||||
strafesnet_settings = { path = "../settings", registry = "strafesnet" }
|
||||
wgpu = "26.0.1"
|
||||
wgpu = "27.0.0"
|
||||
|
||||
@@ -61,11 +61,11 @@ impl Aabb{
|
||||
pub fn center(&self)->Planar64Vec3{
|
||||
self.min.map_zip(self.max,|(min,max)|min.midpoint(max))
|
||||
}
|
||||
//probably use floats for area & volume because we don't care about precision
|
||||
// pub fn area_weight(&self)->f32{
|
||||
// let d=self.max-self.min;
|
||||
// d.x*d.y+d.y*d.z+d.z*d.x
|
||||
// }
|
||||
#[inline]
|
||||
pub fn area_weight(&self)->fixed_wide::fixed::Fixed<2,64>{
|
||||
let d=self.max-self.min;
|
||||
d.x*d.y+d.y*d.z+d.z*d.x
|
||||
}
|
||||
// pub fn volume(&self)->f32{
|
||||
// let d=self.max-self.min;
|
||||
// d.x*d.y*d.z
|
||||
|
||||
@@ -245,18 +245,19 @@ pub fn generate_bvh<T>(boxen:Vec<(T,Aabb)>)->BvhNode<T>{
|
||||
|
||||
fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
|
||||
let n=boxen.len();
|
||||
if force||n<20{
|
||||
let mut aabb=Aabb::default();
|
||||
let nodes=boxen.into_iter().map(|b|{
|
||||
aabb.join(&b.1);
|
||||
const MAX_TERMINAL_BRANCH_LEAF_NODES:usize=20;
|
||||
if force||n<MAX_TERMINAL_BRANCH_LEAF_NODES{
|
||||
let mut aabb_outer=Aabb::default();
|
||||
let nodes=boxen.into_iter().map(|(data,aabb)|{
|
||||
aabb_outer.join(&aabb);
|
||||
BvhNode{
|
||||
content:RecursiveContent::Leaf(b.0),
|
||||
aabb:b.1,
|
||||
content:RecursiveContent::Leaf(data),
|
||||
aabb,
|
||||
}
|
||||
}).collect();
|
||||
BvhNode{
|
||||
content:RecursiveContent::Branch(nodes),
|
||||
aabb,
|
||||
aabb:aabb_outer,
|
||||
}
|
||||
}else{
|
||||
let mut sort_x=Vec::with_capacity(n);
|
||||
@@ -271,62 +272,64 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
|
||||
sort_x.sort_by_key(|&(_,c)|c);
|
||||
sort_y.sort_by_key(|&(_,c)|c);
|
||||
sort_z.sort_by_key(|&(_,c)|c);
|
||||
let h=n/2;
|
||||
let median_x=sort_x[h].1;
|
||||
let median_y=sort_y[h].1;
|
||||
let median_z=sort_z[h].1;
|
||||
//locate a run of values equal to the median
|
||||
//partition point gives the first index for which the predicate evaluates to false
|
||||
let first_index_eq_median_x=sort_x.partition_point(|&(_,x)|x<median_x);
|
||||
let first_index_eq_median_y=sort_y.partition_point(|&(_,y)|y<median_y);
|
||||
let first_index_eq_median_z=sort_z.partition_point(|&(_,z)|z<median_z);
|
||||
let first_index_gt_median_x=sort_x.partition_point(|&(_,x)|x<=median_x);
|
||||
let first_index_gt_median_y=sort_y.partition_point(|&(_,y)|y<=median_y);
|
||||
let first_index_gt_median_z=sort_z.partition_point(|&(_,z)|z<=median_z);
|
||||
//pick which side median value copies go into such that both sides are as balanced as possible based on distance from n/2
|
||||
let partition_point_x=if n.abs_diff(2*first_index_eq_median_x)<n.abs_diff(2*first_index_gt_median_x){first_index_eq_median_x}else{first_index_gt_median_x};
|
||||
let partition_point_y=if n.abs_diff(2*first_index_eq_median_y)<n.abs_diff(2*first_index_gt_median_y){first_index_eq_median_y}else{first_index_gt_median_y};
|
||||
let partition_point_z=if n.abs_diff(2*first_index_eq_median_z)<n.abs_diff(2*first_index_gt_median_z){first_index_eq_median_z}else{first_index_gt_median_z};
|
||||
//this ids which octant the boxen is put in
|
||||
let mut octant=vec![0;n];
|
||||
for &(i,_) in &sort_x[partition_point_x..]{
|
||||
octant[i]+=1<<0;
|
||||
}
|
||||
for &(i,_) in &sort_y[partition_point_y..]{
|
||||
octant[i]+=1<<1;
|
||||
}
|
||||
for &(i,_) in &sort_z[partition_point_z..]{
|
||||
octant[i]+=1<<2;
|
||||
}
|
||||
//generate lists for unique octant values
|
||||
let mut list_list=Vec::with_capacity(8);
|
||||
let mut octant_list=Vec::with_capacity(8);
|
||||
for (i,(data,aabb)) in boxen.into_iter().enumerate(){
|
||||
let octant_id=octant[i];
|
||||
let list_id=if let Some(list_id)=octant_list.iter().position(|&id|id==octant_id){
|
||||
list_id
|
||||
}else{
|
||||
let list_id=list_list.len();
|
||||
octant_list.push(octant_id);
|
||||
list_list.push(Vec::new());
|
||||
list_id
|
||||
};
|
||||
list_list[list_id].push((data,aabb));
|
||||
}
|
||||
let mut aabb=Aabb::default();
|
||||
if list_list.len()==1{
|
||||
generate_bvh_node(list_list.remove(0),true)
|
||||
}else{
|
||||
BvhNode{
|
||||
content:RecursiveContent::Branch(
|
||||
list_list.into_iter().map(|b|{
|
||||
let node=generate_bvh_node(b,false);
|
||||
aabb.join(&node.aabb);
|
||||
node
|
||||
}).collect()
|
||||
),
|
||||
aabb,
|
||||
|
||||
let mut reverse_acumulated_aabbs=vec![fixed_wide::fixed::Fixed::ZERO;n];
|
||||
fn get_min_area<T>(
|
||||
boxen:&[(T,Aabb)],
|
||||
sorted_list:&[(usize,Planar64)],
|
||||
reverse_acumulated_aabbs:&mut Vec<fixed_wide::fixed::Fixed<2,64>>,
|
||||
best_area:&mut fixed_wide::fixed::Fixed<2,64>,
|
||||
)->Option<usize>{
|
||||
let mut accumulated_aabb=Aabb::default();
|
||||
// create an array of aabbs which accumulates box aabbs from the end of the list
|
||||
for (i,&(index,_)) in sorted_list.iter().enumerate().rev(){
|
||||
accumulated_aabb.join(&boxen[index].1);
|
||||
reverse_acumulated_aabbs[i]=accumulated_aabb.area_weight();
|
||||
}
|
||||
// iterate the list forwards and calculate the total area
|
||||
// if the boxes were split at this index
|
||||
accumulated_aabb=Aabb::default();
|
||||
let mut best_index=None;
|
||||
for (i,&(index,_)) in sorted_list.iter().enumerate(){
|
||||
accumulated_aabb.join(&boxen[index].1);
|
||||
let area=accumulated_aabb.area_weight()+reverse_acumulated_aabbs[i];
|
||||
if area<*best_area{
|
||||
*best_area=area;
|
||||
best_index=Some(i);
|
||||
}
|
||||
}
|
||||
best_index
|
||||
}
|
||||
let mut best_area=fixed_wide::fixed::Fixed::MAX;
|
||||
let mut best_index=0;
|
||||
let mut best_list=Vec::new();
|
||||
if let Some(index_x)=get_min_area(&boxen,&sort_x,&mut reverse_acumulated_aabbs,&mut best_area){
|
||||
best_index=index_x;
|
||||
best_list=sort_x;
|
||||
}
|
||||
if let Some(index_y)=get_min_area(&boxen,&sort_y,&mut reverse_acumulated_aabbs,&mut best_area){
|
||||
best_index=index_y;
|
||||
best_list=sort_y;
|
||||
}
|
||||
if let Some(index_z)=get_min_area(&boxen,&sort_z,&mut reverse_acumulated_aabbs,&mut best_area){
|
||||
best_index=index_z;
|
||||
best_list=sort_z;
|
||||
}
|
||||
|
||||
// need to split boxen into two according to best_list and best_index
|
||||
let mut second=Vec::with_capacity(best_index);
|
||||
boxen.retain(|i|);
|
||||
let second=best_list.split_off(best_index);
|
||||
let mut aabb=Aabb::default();
|
||||
BvhNode{
|
||||
content:RecursiveContent::Branch(
|
||||
[best_list,second].map(|b|{
|
||||
let node=generate_bvh_node(b,false);
|
||||
aabb.join(&node.aabb);
|
||||
node
|
||||
}).collect()
|
||||
),
|
||||
aabb,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ strafesnet_rbx_loader = { path = "../lib/rbx_loader", registry = "strafesnet", o
|
||||
strafesnet_session = { path = "../engine/session", registry = "strafesnet" }
|
||||
strafesnet_settings = { path = "../engine/settings", registry = "strafesnet" }
|
||||
strafesnet_snf = { path = "../lib/snf", registry = "strafesnet", optional = true }
|
||||
wgpu = "26.0.1"
|
||||
wgpu = "27.0.0"
|
||||
winit = "0.30.7"
|
||||
|
||||
[profile.dev]
|
||||
|
||||
@@ -119,12 +119,13 @@ impl<'a> SetupContextPartial3<'a>{
|
||||
|
||||
let (device, queue)=pollster::block_on(self.adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
required_features: (optional_features & self.adapter.features()) | required_features,
|
||||
required_limits: needed_limits,
|
||||
&wgpu::DeviceDescriptor{
|
||||
label:None,
|
||||
required_features:(optional_features&self.adapter.features())|required_features,
|
||||
required_limits:needed_limits,
|
||||
memory_hints:wgpu::MemoryHints::Performance,
|
||||
trace: wgpu::Trace::Off,
|
||||
trace:wgpu::Trace::Off,
|
||||
experimental_features:wgpu::ExperimentalFeatures::disabled(),
|
||||
},
|
||||
))
|
||||
.expect("Unable to find a suitable GPU adapter!");
|
||||
|
||||
Reference in New Issue
Block a user