From 0d6741a81c14b21dc322b2d899bd1a45cf6e02d3 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 27 Sep 2023 02:12:20 -0700 Subject: [PATCH] integer physics --- src/aabb.rs | 104 +++-- src/bvh.rs | 10 +- src/instruction.rs | 36 +- src/integer.rs | 914 ++++++++++++++++++++++++++++++++++++++++++ src/load_roblox.rs | 38 +- src/main.rs | 68 ++-- src/model.rs | 71 +--- src/model_graphics.rs | 35 ++ src/model_physics.rs | 1 + src/physics.rs | 399 +++++++++--------- src/primitives.rs | 110 ++--- src/settings.rs | 77 ++-- src/worker.rs | 8 +- src/zeroes.rs | 28 +- 14 files changed, 1419 insertions(+), 480 deletions(-) create mode 100644 src/integer.rs create mode 100644 src/model_graphics.rs create mode 100644 src/model_physics.rs diff --git a/src/aabb.rs b/src/aabb.rs index c027d93..14e7844 100644 --- a/src/aabb.rs +++ b/src/aabb.rs @@ -1,3 +1,5 @@ +use crate::integer::Planar64Vec3; + #[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)] pub enum AabbFace{ Right,//+X @@ -8,84 +10,80 @@ pub enum AabbFace{ Front, } #[derive(Clone)] -pub struct Aabb { - pub min: glam::Vec3, - pub max: glam::Vec3, +pub struct Aabb{ + pub min:Planar64Vec3, + pub max:Planar64Vec3, } impl Default for Aabb { - fn default() -> Self { - Aabb::new() + fn default()->Self { + Self{min:Planar64Vec3::MAX,max:Planar64Vec3::MIN} } } -impl Aabb { - const VERTEX_DATA: [glam::Vec3; 8] = [ - glam::vec3(1., -1., -1.), - glam::vec3(1., 1., -1.), - glam::vec3(1., 1., 1.), - glam::vec3(1., -1., 1.), - glam::vec3(-1., -1., 1.), - glam::vec3(-1., 1., 1.), - glam::vec3(-1., 1., -1.), - glam::vec3(-1., -1., -1.), +impl Aabb{ + const VERTEX_DATA:[Planar64Vec3;8]=[ + Planar64Vec3::int( 1,-1,-1), + Planar64Vec3::int( 1, 1,-1), + Planar64Vec3::int( 1, 1, 1), + Planar64Vec3::int( 1,-1, 1), + Planar64Vec3::int(-1,-1, 1), + Planar64Vec3::int(-1, 1, 1), + Planar64Vec3::int(-1, 1,-1), + Planar64Vec3::int(-1,-1,-1), ]; - pub fn new() -> Self { - Self {min: glam::Vec3::INFINITY,max: glam::Vec3::NEG_INFINITY} - } - - pub fn grow(&mut self, point:glam::Vec3){ + pub fn grow(&mut self,point:Planar64Vec3){ self.min=self.min.min(point); self.max=self.max.max(point); } - pub fn join(&mut self, aabb:&Aabb){ + pub fn join(&mut self,aabb:&Aabb){ self.min=self.min.min(aabb.min); self.max=self.max.max(aabb.max); } - pub fn inflate(&mut self, hs:glam::Vec3){ + pub fn inflate(&mut self,hs:Planar64Vec3){ self.min-=hs; self.max+=hs; } pub fn intersects(&self,aabb:&Aabb)->bool{ (self.min.cmplt(aabb.max)&aabb.min.cmplt(self.max)).all() } - pub fn normal(face:AabbFace) -> glam::Vec3 { + pub fn normal(face:AabbFace)->Planar64Vec3{ match face { - AabbFace::Right => glam::vec3(1.,0.,0.), - AabbFace::Top => glam::vec3(0.,1.,0.), - AabbFace::Back => glam::vec3(0.,0.,1.), - AabbFace::Left => glam::vec3(-1.,0.,0.), - AabbFace::Bottom => glam::vec3(0.,-1.,0.), - AabbFace::Front => glam::vec3(0.,0.,-1.), + AabbFace::Right=>Planar64Vec3::int(1,0,0), + AabbFace::Top=>Planar64Vec3::int(0,1,0), + AabbFace::Back=>Planar64Vec3::int(0,0,1), + AabbFace::Left=>Planar64Vec3::int(-1,0,0), + AabbFace::Bottom=>Planar64Vec3::int(0,-1,0), + AabbFace::Front=>Planar64Vec3::int(0,0,-1), } } - pub fn unit_vertices() -> [glam::Vec3;8] { + pub fn unit_vertices()->[Planar64Vec3;8] { return Self::VERTEX_DATA; } - pub fn face(&self,face:AabbFace) -> Aabb { - let mut aabb=self.clone(); - //in this implementation face = worldspace aabb face - match face { - AabbFace::Right => aabb.min.x=aabb.max.x, - AabbFace::Top => aabb.min.y=aabb.max.y, - AabbFace::Back => aabb.min.z=aabb.max.z, - AabbFace::Left => aabb.max.x=aabb.min.x, - AabbFace::Bottom => aabb.max.y=aabb.min.y, - AabbFace::Front => aabb.max.z=aabb.min.z, - } - return aabb; - } - pub fn center(&self)->glam::Vec3{ - return (self.min+self.max)/2.0 + // pub fn face(&self,face:AabbFace)->Aabb { + // let mut aabb=self.clone(); + // //in this implementation face = worldspace aabb face + // match face { + // AabbFace::Right => aabb.min.x=aabb.max.x, + // AabbFace::Top => aabb.min.y=aabb.max.y, + // AabbFace::Back => aabb.min.z=aabb.max.z, + // AabbFace::Left => aabb.max.x=aabb.min.x, + // AabbFace::Bottom => aabb.max.y=aabb.min.y, + // AabbFace::Front => aabb.max.z=aabb.min.z, + // } + // return aabb; + // } + pub fn center(&self)->Planar64Vec3{ + return self.min.midpoint(self.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 - } - pub fn volume(&self)->f32{ - let d=self.max-self.min; - d.x*d.y*d.z - } + // pub fn area_weight(&self)->f32{ + // 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 + // } } \ No newline at end of file diff --git a/src/bvh.rs b/src/bvh.rs index b79ecc0..4196bd7 100644 --- a/src/bvh.rs +++ b/src/bvh.rs @@ -36,7 +36,7 @@ pub fn generate_bvh(boxen:Vec)->BvhNode{ fn generate_bvh_node(boxen:Vec<(usize,Aabb)>)->BvhNode{ let n=boxen.len(); if n<20{ - let mut aabb=Aabb::new(); + let mut aabb=Aabb::default(); let models=boxen.into_iter().map(|b|{aabb.join(&b.1);b.0 as u32}).collect(); BvhNode{ children:Vec::new(), @@ -51,9 +51,9 @@ fn generate_bvh_node(boxen:Vec<(usize,Aabb)>)->BvhNode{ for (i,aabb) in boxen.iter(){ let center=aabb.center(); octant.insert(*i,0); - sort_x.push((*i,center.x)); - sort_y.push((*i,center.y)); - sort_z.push((*i,center.z)); + sort_x.push((*i,center.x())); + sort_y.push((*i,center.y())); + sort_z.push((*i,center.z())); } sort_x.sort_by(|tup0,tup1|tup0.1.partial_cmp(&tup1.1).unwrap()); sort_y.sort_by(|tup0,tup1|tup0.1.partial_cmp(&tup1.1).unwrap()); @@ -92,7 +92,7 @@ fn generate_bvh_node(boxen:Vec<(usize,Aabb)>)->BvhNode{ }; list_list[list_id].push((i,aabb)); } - let mut aabb=Aabb::new(); + let mut aabb=Aabb::default(); let children=list_list.into_iter().map(|b|{ let node=generate_bvh_node(b); aabb.join(&node.aabb); diff --git a/src/instruction.rs b/src/instruction.rs index 3508b93..f8880cb 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -1,23 +1,25 @@ +use crate::integer::Time; + #[derive(Debug)] -pub struct TimedInstruction { - pub time: crate::physics::TIME, - pub instruction: I, +pub struct TimedInstruction{ + pub time:Time, + pub instruction:I, } -pub trait InstructionEmitter { - fn next_instruction(&self, time_limit:crate::physics::TIME) -> Option>; +pub trait InstructionEmitter{ + fn next_instruction(&self,time_limit:Time)->Option>; } -pub trait InstructionConsumer { +pub trait InstructionConsumer{ fn process_instruction(&mut self, instruction:TimedInstruction); } //PROPER PRIVATE FIELDS!!! -pub struct InstructionCollector { - time: crate::physics::TIME, - instruction: Option, +pub struct InstructionCollector{ + time:Time, + instruction:Option, } -impl InstructionCollector { - pub fn new(time:crate::physics::TIME) -> Self { +impl InstructionCollector{ + pub fn new(time:Time)->Self{ Self{ time, instruction:None @@ -25,24 +27,24 @@ impl InstructionCollector { } pub fn collect(&mut self,instruction:Option>){ - match instruction { - Some(unwrap_instruction) => { + match instruction{ + Some(unwrap_instruction)=>{ if unwrap_instruction.time (), + None=>(), } } - pub fn instruction(self) -> Option> { + pub fn instruction(self)->Option>{ //STEAL INSTRUCTION AND DESTROY INSTRUCTIONCOLLECTOR - match self.instruction { + match self.instruction{ Some(instruction)=>Some(TimedInstruction{ time:self.time, instruction }), - None => None, + None=>None, } } } \ No newline at end of file diff --git a/src/integer.rs b/src/integer.rs new file mode 100644 index 0000000..bd43b63 --- /dev/null +++ b/src/integer.rs @@ -0,0 +1,914 @@ +//integer units +#[derive(Clone,Copy,Hash,PartialEq,PartialOrd,Debug)] +pub struct Time(i64); +impl Time{ + pub const ZERO:Self=Self(0); + pub const ONE_SECOND:Self=Self(1_000_000_000); + pub const ONE_MILLISECOND:Self=Self(1_000_000); + pub const ONE_MICROSECOND:Self=Self(1_000); + pub const ONE_NANOSECOND:Self=Self(1); + #[inline] + pub fn from_secs(num:i64)->Self{ + Self(Self::ONE_SECOND.0*num) + } + #[inline] + pub fn from_millis(num:i64)->Self{ + Self(Self::ONE_MILLISECOND.0*num) + } + #[inline] + pub fn from_micros(num:i64)->Self{ + Self(Self::ONE_MICROSECOND.0*num) + } + #[inline] + pub fn from_nanos(num:i64)->Self{ + Self(Self::ONE_NANOSECOND.0*num) + } + //should I have checked subtraction? force all time variables to be positive? + #[inline] + pub fn nanos(&self)->i64{ + self.0 + } +} +impl From for Time{ + #[inline] + fn from(value:Planar64)->Self{ + Time((((value.0 as i128)*1_000_000_000)>>32) as i64) + } +} +impl std::fmt::Display for Time{ + #[inline] + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{}s+{:09}ns",self.0/Self::ONE_SECOND.0,self.0%Self::ONE_SECOND.0) + } +} +impl std::ops::Neg for Time{ + type Output=Time; + #[inline] + fn neg(self)->Self::Output { + Time(-self.0) + } +} +impl std::ops::Add