Compare commits

..

2 Commits
bb2 ... apple

Author SHA1 Message Date
a9a9b410b7 script invocation 2025-11-08 12:39:16 -08:00
3f7ae1fa8b add apple build
The build fails due to using an outdated compiler.  Odd considering it was updated recently.
2025-11-08 12:39:16 -08:00
8 changed files with 364 additions and 486 deletions

695
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
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
docker/build-apple.sh Executable file
View File

@@ -0,0 +1 @@
docker build -f docker/aarch64-apple-darwin.Dockerfile . -o target/aarch64-apple-darwin/release/

View File

@@ -11,4 +11,4 @@ id = { version = "0.1.0", registry = "strafesnet" }
strafesnet_common = { path = "../../lib/common", registry = "strafesnet" } strafesnet_common = { path = "../../lib/common", registry = "strafesnet" }
strafesnet_session = { path = "../session", registry = "strafesnet" } strafesnet_session = { path = "../session", registry = "strafesnet" }
strafesnet_settings = { path = "../settings", registry = "strafesnet" } strafesnet_settings = { path = "../settings", registry = "strafesnet" }
wgpu = "27.0.0" wgpu = "26.0.1"

View File

@@ -61,11 +61,11 @@ impl Aabb{
pub fn center(&self)->Planar64Vec3{ pub fn center(&self)->Planar64Vec3{
self.min.map_zip(self.max,|(min,max)|min.midpoint(max)) self.min.map_zip(self.max,|(min,max)|min.midpoint(max))
} }
#[inline] //probably use floats for area & volume because we don't care about precision
pub fn area_weight(&self)->fixed_wide::fixed::Fixed<2,64>{ // pub fn area_weight(&self)->f32{
let d=self.max-self.min; // let d=self.max-self.min;
d.x*d.y+d.y*d.z+d.z*d.x // d.x*d.y+d.y*d.z+d.z*d.x
} // }
// pub fn volume(&self)->f32{ // pub fn volume(&self)->f32{
// let d=self.max-self.min; // let d=self.max-self.min;
// d.x*d.y*d.z // d.x*d.y*d.z

View File

@@ -245,19 +245,18 @@ pub fn generate_bvh<T>(boxen:Vec<(T,Aabb)>)->BvhNode<T>{
fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
let n=boxen.len(); let n=boxen.len();
const MAX_TERMINAL_BRANCH_LEAF_NODES:usize=20; if force||n<20{
if force||n<MAX_TERMINAL_BRANCH_LEAF_NODES{ let mut aabb=Aabb::default();
let mut aabb_outer=Aabb::default(); let nodes=boxen.into_iter().map(|b|{
let nodes=boxen.into_iter().map(|(data,aabb)|{ aabb.join(&b.1);
aabb_outer.join(&aabb);
BvhNode{ BvhNode{
content:RecursiveContent::Leaf(data), content:RecursiveContent::Leaf(b.0),
aabb, aabb:b.1,
} }
}).collect(); }).collect();
BvhNode{ BvhNode{
content:RecursiveContent::Branch(nodes), content:RecursiveContent::Branch(nodes),
aabb:aabb_outer, aabb,
} }
}else{ }else{
let mut sort_x=Vec::with_capacity(n); let mut sort_x=Vec::with_capacity(n);
@@ -272,64 +271,62 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
sort_x.sort_by_key(|&(_,c)|c); sort_x.sort_by_key(|&(_,c)|c);
sort_y.sort_by_key(|&(_,c)|c); sort_y.sort_by_key(|&(_,c)|c);
sort_z.sort_by_key(|&(_,c)|c); sort_z.sort_by_key(|&(_,c)|c);
let h=n/2;
let mut reverse_acumulated_aabbs=vec![fixed_wide::fixed::Fixed::ZERO;n]; let median_x=sort_x[h].1;
fn get_min_area<T>( let median_y=sort_y[h].1;
boxen:&[(T,Aabb)], let median_z=sort_z[h].1;
sorted_list:&[(usize,Planar64)], //locate a run of values equal to the median
reverse_acumulated_aabbs:&mut Vec<fixed_wide::fixed::Fixed<2,64>>, //partition point gives the first index for which the predicate evaluates to false
best_area:&mut fixed_wide::fixed::Fixed<2,64>, let first_index_eq_median_x=sort_x.partition_point(|&(_,x)|x<median_x);
)->Option<usize>{ let first_index_eq_median_y=sort_y.partition_point(|&(_,y)|y<median_y);
let mut accumulated_aabb=Aabb::default(); let first_index_eq_median_z=sort_z.partition_point(|&(_,z)|z<median_z);
// create an array of aabbs which accumulates box aabbs from the end of the list let first_index_gt_median_x=sort_x.partition_point(|&(_,x)|x<=median_x);
for (i,&(index,_)) in sorted_list.iter().enumerate().rev(){ let first_index_gt_median_y=sort_y.partition_point(|&(_,y)|y<=median_y);
accumulated_aabb.join(&boxen[index].1); let first_index_gt_median_z=sort_z.partition_point(|&(_,z)|z<=median_z);
reverse_acumulated_aabbs[i]=accumulated_aabb.area_weight(); //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};
// iterate the list forwards and calculate the total area 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};
// if the boxes were split at this index 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};
accumulated_aabb=Aabb::default(); //this ids which octant the boxen is put in
let mut best_index=None; let mut octant=vec![0;n];
for (i,&(index,_)) in sorted_list.iter().enumerate(){ for &(i,_) in &sort_x[partition_point_x..]{
accumulated_aabb.join(&boxen[index].1); octant[i]+=1<<0;
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; for &(i,_) in &sort_y[partition_point_y..]{
let mut best_index=0; octant[i]+=1<<1;
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){ for &(i,_) in &sort_z[partition_point_z..]{
best_index=index_y; octant[i]+=1<<2;
best_list=sort_y;
} }
if let Some(index_z)=get_min_area(&boxen,&sort_z,&mut reverse_acumulated_aabbs,&mut best_area){ //generate lists for unique octant values
best_index=index_z; let mut list_list=Vec::with_capacity(8);
best_list=sort_z; 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));
} }
// 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(); let mut aabb=Aabb::default();
BvhNode{ if list_list.len()==1{
content:RecursiveContent::Branch( generate_bvh_node(list_list.remove(0),true)
[best_list,second].map(|b|{ }else{
let node=generate_bvh_node(b,false); BvhNode{
aabb.join(&node.aabb); content:RecursiveContent::Branch(
node list_list.into_iter().map(|b|{
}).collect() let node=generate_bvh_node(b,false);
), aabb.join(&node.aabb);
aabb, node
}).collect()
),
aabb,
}
} }
} }
} }

View File

@@ -28,7 +28,7 @@ strafesnet_rbx_loader = { path = "../lib/rbx_loader", registry = "strafesnet", o
strafesnet_session = { path = "../engine/session", registry = "strafesnet" } strafesnet_session = { path = "../engine/session", registry = "strafesnet" }
strafesnet_settings = { path = "../engine/settings", registry = "strafesnet" } strafesnet_settings = { path = "../engine/settings", registry = "strafesnet" }
strafesnet_snf = { path = "../lib/snf", registry = "strafesnet", optional = true } strafesnet_snf = { path = "../lib/snf", registry = "strafesnet", optional = true }
wgpu = "27.0.0" wgpu = "26.0.1"
winit = "0.30.7" winit = "0.30.7"
[profile.dev] [profile.dev]

View File

@@ -119,13 +119,12 @@ impl<'a> SetupContextPartial3<'a>{
let (device, queue)=pollster::block_on(self.adapter let (device, queue)=pollster::block_on(self.adapter
.request_device( .request_device(
&wgpu::DeviceDescriptor{ &wgpu::DeviceDescriptor {
label:None, label: None,
required_features:(optional_features&self.adapter.features())|required_features, required_features: (optional_features & self.adapter.features()) | required_features,
required_limits:needed_limits, required_limits: needed_limits,
memory_hints:wgpu::MemoryHints::Performance, 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!"); .expect("Unable to find a suitable GPU adapter!");