3 Commits

Author SHA1 Message Date
165a59be6d Revert "delete updatable"
This reverts commit c519ed4ec2.
2024-03-29 01:10:18 -07:00
2c926efa0d delete updatable 2024-03-29 01:10:15 -07:00
74acfbf206 use strafesnet registry 2024-03-29 01:10:15 -07:00
11 changed files with 56 additions and 491 deletions

@ -1,2 +0,0 @@
[registries.strafesnet]
index = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"

10
Cargo.lock generated

@ -4,15 +4,15 @@ version = 3
[[package]]
name = "bitflags"
version = "2.6.0"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]]
name = "glam"
version = "0.28.0"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "779ae4bf7e8421cf91c0b3b64e7e8b40b862fba4d393f59150042de7c4965a94"
checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3"
[[package]]
name = "id"
@ -45,7 +45,7 @@ dependencies = [
[[package]]
name = "strafesnet_common"
version = "0.2.0"
version = "0.1.0"
dependencies = [
"bitflags",
"glam",

@ -1,15 +1,11 @@
[package]
name = "strafesnet_common"
version = "0.2.0"
version = "0.1.0"
edition = "2021"
repository = "https://git.itzana.me/StrafesNET/common"
license = "MIT OR Apache-2.0"
description = "Common types and helpers for Strafe Client associated projects."
authors = ["Rhys Lloyd <krakow20@gmail.com>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bitflags = "2.6.0"
glam = "0.28.0"
bitflags = "2.4.2"
glam = "0.25.0"
id = { version = "0.1.0", registry = "strafesnet" }

@ -6,22 +6,13 @@ pub struct Aabb{
max:Planar64Vec3,
}
impl Default for Aabb{
fn default()->Self{
impl Default for Aabb {
fn default()->Self {
Self{min:Planar64Vec3::MAX,max:Planar64Vec3::MIN}
}
}
impl Aabb{
pub const fn new(min:Planar64Vec3,max:Planar64Vec3)->Self{
Self{min,max}
}
pub const fn max(&self)->Planar64Vec3{
self.max
}
pub const fn min(&self)->Planar64Vec3{
self.min
}
pub fn grow(&mut self,point:Planar64Vec3){
self.min=self.min.min(point);
self.max=self.max.max(point);
@ -52,4 +43,4 @@ impl Aabb{
// let d=self.max-self.min;
// d.x*d.y*d.z
// }
}
}

@ -10,31 +10,26 @@ use crate::aabb::Aabb;
//sort the centerpoints on each axis (3 lists)
//bv is put into octant based on whether it is upper or lower in each list
pub enum RecursiveContent<R,T>{
Branch(Vec<R>),
enum BvhNodeContent<T>{
Branch(Vec<BvhNode<T>>),
Leaf(T),
}
impl<R,T> Default for RecursiveContent<R,T>{
impl<T> Default for BvhNodeContent<T>{
fn default()->Self{
Self::Branch(Vec::new())
}
}
#[derive(Default)]
pub struct BvhNode<T>{
content:RecursiveContent<BvhNode<T>,T>,
aabb:Aabb,
}
pub struct BvhWeightNode<W,T>{
content:RecursiveContent<BvhWeightNode<W,T>,T>,
weight:W,
content:BvhNodeContent<T>,
aabb:Aabb,
}
impl<T> BvhNode<T>{
pub fn the_tester<F:FnMut(&T)>(&self,aabb:&Aabb,f:&mut F){
impl<T:Copy+Eq+std::hash::Hash> BvhNode<T>{
pub fn the_tester<F:FnMut(T)>(&self,aabb:&Aabb,f:&mut F){
match &self.content{
RecursiveContent::Leaf(model)=>f(model),
RecursiveContent::Branch(children)=>for child in children{
&BvhNodeContent::Leaf(model)=>f(model),
BvhNodeContent::Branch(children)=>for child in children{
//this test could be moved outside the match statement
//but that would test the root node aabb
//you're probably not going to spend a lot of time outside the map,
@ -45,72 +40,25 @@ impl<T> BvhNode<T>{
},
}
}
pub fn into_visitor<F:FnMut(T)>(self,f:&mut F){
match self.content{
RecursiveContent::Leaf(model)=>f(model),
RecursiveContent::Branch(children)=>for child in children{
child.into_visitor(f)
},
}
}
pub fn weigh_contents<W:Copy+std::iter::Sum<W>,F:Fn(&T)->W>(self,f:&F)->BvhWeightNode<W,T>{
match self.content{
RecursiveContent::Leaf(model)=>BvhWeightNode{
weight:f(&model),
content:RecursiveContent::Leaf(model),
aabb:self.aabb,
},
RecursiveContent::Branch(children)=>{
let branch:Vec<BvhWeightNode<W,T>>=children.into_iter().map(|child|
child.weigh_contents(f)
).collect();
BvhWeightNode{
weight:branch.iter().map(|node|node.weight).sum(),
content:RecursiveContent::Branch(branch),
aabb:self.aabb,
}
},
}
}
}
impl <W,T> BvhWeightNode<W,T>{
pub const fn weight(&self)->&W{
&self.weight
}
pub const fn aabb(&self)->&Aabb{
&self.aabb
}
pub fn into_content(self)->RecursiveContent<BvhWeightNode<W,T>,T>{
self.content
}
pub fn into_visitor<F:FnMut(T)>(self,f:&mut F){
match self.content{
RecursiveContent::Leaf(model)=>f(model),
RecursiveContent::Branch(children)=>for child in children{
child.into_visitor(f)
},
}
}
}
pub fn generate_bvh<T>(boxen:Vec<(T,Aabb)>)->BvhNode<T>{
pub fn generate_bvh<T:Copy+Eq+std::hash::Hash>(boxen:Vec<(T,Aabb)>)->BvhNode<T>{
generate_bvh_node(boxen,false)
}
fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
fn generate_bvh_node<T:Copy+Eq+std::hash::Hash>(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);
BvhNode{
content:RecursiveContent::Leaf(b.0),
content:BvhNodeContent::Leaf(b.0),
aabb:b.1,
}
}).collect();
BvhNode{
content:RecursiveContent::Branch(nodes),
content:BvhNodeContent::Branch(nodes),
aabb,
}
}else{
@ -118,12 +66,12 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
let mut sort_x=Vec::with_capacity(n);
let mut sort_y=Vec::with_capacity(n);
let mut sort_z=Vec::with_capacity(n);
for (i,(_,aabb)) in boxen.iter().enumerate(){
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()));
octant.insert(*i,0);
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.cmp(&tup1.1));
sort_y.sort_by(|tup0,tup1|tup0.1.cmp(&tup1.1));
@ -150,7 +98,7 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
//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(){
for (i,aabb) in boxen.into_iter(){
let octant_id=octant[&i];
let list_id=if let Some(list_id)=octant_list.iter().position(|&id|id==octant_id){
list_id
@ -160,14 +108,14 @@ fn generate_bvh_node<T>(boxen:Vec<(T,Aabb)>,force:bool)->BvhNode<T>{
list_list.push(Vec::new());
list_id
};
list_list[list_id].push((data,aabb));
list_list[list_id].push((i,aabb));
}
let mut aabb=Aabb::default();
if list_list.len()==1{
generate_bvh_node(list_list.remove(0),true)
}else{
BvhNode{
content:RecursiveContent::Branch(
content:BvhNodeContent::Branch(
list_list.into_iter().map(|b|{
let node=generate_bvh_node(b,false);
aabb.join(&node.aabb);

@ -71,22 +71,7 @@ pub struct Stage{
unordered_checkpoints:HashSet<ModelId>,
}
impl Stage{
pub fn new(
spawn:ModelId,
ordered_checkpoints_count:u32,
unordered_checkpoints_count:u32,
ordered_checkpoints:HashMap<CheckpointId,ModelId>,
unordered_checkpoints:HashSet<ModelId>,
)->Self{
Self{
spawn,
ordered_checkpoints_count,
unordered_checkpoints_count,
ordered_checkpoints,
unordered_checkpoints,
}
}
pub fn empty(spawn:ModelId)->Self{
pub fn new(spawn:ModelId)->Self{
Self{
spawn,
ordered_checkpoints_count:0,
@ -100,17 +85,6 @@ impl Stage{
self.spawn
}
#[inline]
pub const fn ordered_checkpoints_count(&self)->u32{
self.ordered_checkpoints_count
}
#[inline]
pub const fn unordered_checkpoints_count(&self)->u32{
self.unordered_checkpoints_count
}
pub fn into_inner(self)->(HashMap<CheckpointId,ModelId>,HashSet<ModelId>){
(self.ordered_checkpoints,self.unordered_checkpoints)
}
#[inline]
pub const fn is_empty(&self)->bool{
self.is_complete(0,0)
}
@ -162,22 +136,7 @@ pub struct Mode{
elements:HashMap<ModelId,StageElement>,
}
impl Mode{
pub fn new(
style:gameplay_style::StyleModifiers,
start:ModelId,
zones:HashMap<ModelId,Zone>,
stages:Vec<Stage>,
elements:HashMap<ModelId,StageElement>,
)->Self{
Self{
style,
start,
zones,
stages,
elements,
}
}
pub fn empty(style:gameplay_style::StyleModifiers,start:ModelId)->Self{
pub fn new(style:gameplay_style::StyleModifiers,start:ModelId)->Self{
Self{
style,
start,
@ -186,21 +145,6 @@ impl Mode{
elements:HashMap::new(),
}
}
pub fn into_inner(self)->(
gameplay_style::StyleModifiers,
ModelId,
HashMap<ModelId,Zone>,
Vec<Stage>,
HashMap<ModelId,StageElement>,
){
(
self.style,
self.start,
self.zones,
self.stages,
self.elements,
)
}
pub const fn get_start(&self)->ModelId{
self.start
}
@ -299,17 +243,14 @@ impl ModeUpdate{
#[derive(Default,Clone)]
pub struct Modes{
pub modes:Vec<Mode>,
modes:Vec<Mode>,
}
impl Modes{
pub const fn new(modes:Vec<Mode>)->Self{
pub fn new(modes:Vec<Mode>)->Self{
Self{
modes,
}
}
pub fn into_inner(self)->Vec<Mode>{
self.modes
}
pub fn push_mode(&mut self,mode:Mode){
self.modes.push(mode)
}
@ -328,4 +269,4 @@ impl Updatable<ModesUpdate> for Modes{
}
}
}
}
}

@ -14,8 +14,6 @@ pub struct StyleModifiers{
//player gets a controllable rocket force
pub rocket:Option<PropulsionSettings>,
//flying
//pub move_type:MoveType::Fly(FlySettings)
//MoveType::Physics(PhysicsSettings) -> PhysicsSettings (strafe,rocket,jump,walk,ladder,swim,gravity)
//jumping is allowed
pub jump:Option<JumpSettings>,
//standing & walking is allowed
@ -94,15 +92,6 @@ impl ControlsActivation{
controls_contains,
}
}
pub const fn controls_mask(&self)->Controls{
self.controls_mask
}
pub const fn controls_intersects(&self)->Controls{
self.controls_intersects
}
pub const fn controls_contains(&self)->Controls{
self.controls_contains
}
pub const fn mask(&self,controls:Controls)->Controls{
controls.intersection(self.controls_mask)
}
@ -177,17 +166,6 @@ pub struct StrafeSettings{
tick_rate:Ratio64,
}
impl StrafeSettings{
pub const fn new(
enable:ControlsActivation,
mv:Planar64,
air_accel_limit:Option<Planar64>,
tick_rate:Ratio64,
)->Self{
Self{enable,mv,air_accel_limit,tick_rate}
}
pub fn into_inner(self)->(ControlsActivation,Planar64,Option<Planar64>,Ratio64){
(self.enable,self.mv,self.air_accel_limit,self.tick_rate)
}
pub fn tick_velocity(&self,velocity:Planar64Vec3,control_dir:Planar64Vec3)->Option<Planar64Vec3>{
let d=velocity.dot(control_dir);
match d<self.mv{
@ -211,12 +189,6 @@ pub struct PropulsionSettings{
magnitude:Planar64,
}
impl PropulsionSettings{
pub const fn new(magnitude:Planar64)->Self{
Self{magnitude}
}
pub fn magnitude(&self)->Planar64{
self.magnitude
}
pub fn acceleration(&self,control_dir:Planar64Vec3)->Planar64Vec3{
control_dir*self.magnitude
}
@ -230,15 +202,6 @@ pub struct JumpSettings{
calculation:JumpCalculation,
}
impl JumpSettings{
pub const fn new(
impulse:JumpImpulse,
calculation:JumpCalculation,
)->Self{
Self{impulse,calculation}
}
pub fn into_inner(self)->(JumpImpulse,JumpCalculation){
(self.impulse,self.calculation)
}
pub fn jumped_velocity(&self,style:&StyleModifiers,jump_dir:Planar64Vec3,velocity:Planar64Vec3)->Planar64Vec3{
match self.calculation{
//roblox style
@ -256,20 +219,6 @@ pub struct AccelerateSettings{
accel:Planar64,
topspeed:Planar64,
}
impl AccelerateSettings{
pub const fn new(
accel:Planar64,
topspeed:Planar64,
)->Self{
Self{accel,topspeed}
}
pub const fn accel(&self)->Planar64{
self.accel
}
pub const fn topspeed(&self)->Planar64{
self.topspeed
}
}
#[derive(Clone,Debug)]
pub struct WalkSettings{
accelerate:AccelerateSettings,
@ -279,17 +228,6 @@ pub struct WalkSettings{
surf_dot:Planar64,//surf_dot<n.dot(up)/n.length()
}
impl WalkSettings{
pub const fn new(
accelerate:AccelerateSettings,
static_friction:Planar64,
kinetic_friction:Planar64,
surf_dot:Planar64,
)->Self{
Self{accelerate,static_friction,kinetic_friction,surf_dot}
}
pub fn into_inner(self)->(AccelerateSettings,Planar64,Planar64,Planar64){
(self.accelerate,self.static_friction,self.kinetic_friction,self.surf_dot)
}
pub fn accel(&self,target_diff:Planar64Vec3,gravity:Planar64Vec3)->Planar64{
//TODO: fallible walk accel
let diff_len=target_diff.length();
@ -335,16 +273,7 @@ pub struct LadderSettings{
dot:Planar64,
}
impl LadderSettings{
pub const fn new(
accelerate:AccelerateSettings,
dot:Planar64,
)->Self{
Self{accelerate,dot}
}
pub fn into_inner(self)->(AccelerateSettings,Planar64){
(self.accelerate,self.dot)
}
pub const fn accel(&self,target_diff:Planar64Vec3,gravity:Planar64Vec3)->Planar64{
pub fn accel(&self,target_diff:Planar64Vec3,gravity:Planar64Vec3)->Planar64{
//TODO: fallible ladder accel
self.accelerate.accel
}
@ -403,7 +332,7 @@ impl Hitbox{
}
pub fn source()->Self{
Self{
halfsize:Planar64Vec3::int(33,73,33)/2*VALVE_SCALE,
halfsize:Planar64Vec3::raw(33,73,33)/2*VALVE_SCALE,
mesh:HitboxMesh::Box,
}
}
@ -591,4 +520,4 @@ impl StyleModifiers{
camera_offset:(Planar64Vec3::int(0,64,0)-Planar64Vec3::int(0,73,0)/2)*VALVE_SCALE,
}
}
}
}

@ -10,14 +10,6 @@ impl Time{
pub const ONE_MICROSECOND:Self=Self(1_000);
pub const ONE_NANOSECOND:Self=Self(1);
#[inline]
pub const fn raw(num:i64)->Self{
Self(num)
}
#[inline]
pub const fn get(self)->i64{
self.0
}
#[inline]
pub const fn from_secs(num:i64)->Self{
Self(Self::ONE_SECOND.0*num)
}
@ -117,14 +109,6 @@ impl Ratio64{
}
}
#[inline]
pub const fn num(self)->i64{
self.num
}
#[inline]
pub const fn den(self)->u64{
self.den
}
#[inline]
pub const fn mul_int(&self,rhs:i64)->i64{
rhs*self.num/(self.den as i64)
}
@ -614,26 +598,14 @@ impl Planar64Vec3{
Self(glam::i64vec3(x.0,y.0,z.0))
}
#[inline]
pub const fn get(self)->glam::I64Vec3{
self.0
}
#[inline]
pub const fn int(x:i32,y:i32,z:i32)->Self{
Self(glam::i64vec3((x as i64)<<32,(y as i64)<<32,(z as i64)<<32))
}
#[inline]
pub const fn raw_xyz(x:i64,y:i64,z:i64)->Self{
pub const fn raw(x:i64,y:i64,z:i64)->Self{
Self(glam::i64vec3(x,y,z))
}
#[inline]
pub const fn raw_array(xyz:[i64;3])->Self{
Self(glam::I64Vec3::from_array(xyz))
}
#[inline]
pub const fn raw(xyz:glam::I64Vec3)->Self{
Self(xyz)
}
#[inline]
pub const fn x(&self)->Planar64{
Planar64(self.0.x)
}
@ -885,9 +857,9 @@ impl Planar64Mat3{
#[inline]
pub const fn from_diagonal(diagonal:Planar64Vec3)->Self{
Self{
x_axis:Planar64Vec3::raw_xyz(diagonal.0.x,0,0),
y_axis:Planar64Vec3::raw_xyz(0,diagonal.0.y,0),
z_axis:Planar64Vec3::raw_xyz(0,0,diagonal.0.z),
x_axis:Planar64Vec3::raw(diagonal.0.x,0,0),
y_axis:Planar64Vec3::raw(0,diagonal.0.y,0),
z_axis:Planar64Vec3::raw(0,0,diagonal.0.z),
}
}
#[inline]
@ -931,25 +903,25 @@ impl Planar64Mat3{
+self.x_axis.0.x as i128*self.y_axis.0.y as i128*self.z_axis.0.z as i128
)>>32;
Self{
x_axis:Planar64Vec3::raw_xyz((((-(self.y_axis.0.z as i128*self.z_axis.0.y as i128)+self.y_axis.0.y as i128*self.z_axis.0.z as i128)<<32)/det) as i64,(((self.x_axis.0.z as i128*self.z_axis.0.y as i128-self.x_axis.0.y as i128*self.z_axis.0.z as i128)<<32)/det) as i64,(((-(self.x_axis.0.z as i128*self.y_axis.0.y as i128)+self.x_axis.0.y as i128*self.y_axis.0.z as i128)<<32)/det) as i64),
y_axis:Planar64Vec3::raw_xyz((((self.y_axis.0.z as i128*self.z_axis.0.x as i128-self.y_axis.0.x as i128*self.z_axis.0.z as i128)<<32)/det) as i64,(((-(self.x_axis.0.z as i128*self.z_axis.0.x as i128)+self.x_axis.0.x as i128*self.z_axis.0.z as i128)<<32)/det) as i64,(((self.x_axis.0.z as i128*self.y_axis.0.x as i128-self.x_axis.0.x as i128*self.y_axis.0.z as i128)<<32)/det) as i64),
z_axis:Planar64Vec3::raw_xyz((((-(self.y_axis.0.y as i128*self.z_axis.0.x as i128)+self.y_axis.0.x as i128*self.z_axis.0.y as i128)<<32)/det) as i64,(((self.x_axis.0.y as i128*self.z_axis.0.x as i128-self.x_axis.0.x as i128*self.z_axis.0.y as i128)<<32)/det) as i64,(((-(self.x_axis.0.y as i128*self.y_axis.0.x as i128)+self.x_axis.0.x as i128*self.y_axis.0.y as i128)<<32)/det) as i64),
x_axis:Planar64Vec3::raw((((-(self.y_axis.0.z as i128*self.z_axis.0.y as i128)+self.y_axis.0.y as i128*self.z_axis.0.z as i128)<<32)/det) as i64,(((self.x_axis.0.z as i128*self.z_axis.0.y as i128-self.x_axis.0.y as i128*self.z_axis.0.z as i128)<<32)/det) as i64,(((-(self.x_axis.0.z as i128*self.y_axis.0.y as i128)+self.x_axis.0.y as i128*self.y_axis.0.z as i128)<<32)/det) as i64),
y_axis:Planar64Vec3::raw((((self.y_axis.0.z as i128*self.z_axis.0.x as i128-self.y_axis.0.x as i128*self.z_axis.0.z as i128)<<32)/det) as i64,(((-(self.x_axis.0.z as i128*self.z_axis.0.x as i128)+self.x_axis.0.x as i128*self.z_axis.0.z as i128)<<32)/det) as i64,(((self.x_axis.0.z as i128*self.y_axis.0.x as i128-self.x_axis.0.x as i128*self.y_axis.0.z as i128)<<32)/det) as i64),
z_axis:Planar64Vec3::raw((((-(self.y_axis.0.y as i128*self.z_axis.0.x as i128)+self.y_axis.0.x as i128*self.z_axis.0.y as i128)<<32)/det) as i64,(((self.x_axis.0.y as i128*self.z_axis.0.x as i128-self.x_axis.0.x as i128*self.z_axis.0.y as i128)<<32)/det) as i64,(((-(self.x_axis.0.y as i128*self.y_axis.0.x as i128)+self.x_axis.0.x as i128*self.y_axis.0.y as i128)<<32)/det) as i64),
}
}
#[inline]
pub const fn inverse_times_det(&self)->Self{
Self{
x_axis:Planar64Vec3::raw_xyz(((-(self.y_axis.0.z as i128*self.z_axis.0.y as i128)+self.y_axis.0.y as i128*self.z_axis.0.z as i128)>>32) as i64,((self.x_axis.0.z as i128*self.z_axis.0.y as i128-self.x_axis.0.y as i128*self.z_axis.0.z as i128)>>32) as i64,((-(self.x_axis.0.z as i128*self.y_axis.0.y as i128)+self.x_axis.0.y as i128*self.y_axis.0.z as i128)>>32) as i64),
y_axis:Planar64Vec3::raw_xyz(((self.y_axis.0.z as i128*self.z_axis.0.x as i128-self.y_axis.0.x as i128*self.z_axis.0.z as i128)>>32) as i64,((-(self.x_axis.0.z as i128*self.z_axis.0.x as i128)+self.x_axis.0.x as i128*self.z_axis.0.z as i128)>>32) as i64,((self.x_axis.0.z as i128*self.y_axis.0.x as i128-self.x_axis.0.x as i128*self.y_axis.0.z as i128)>>32) as i64),
z_axis:Planar64Vec3::raw_xyz(((-(self.y_axis.0.y as i128*self.z_axis.0.x as i128)+self.y_axis.0.x as i128*self.z_axis.0.y as i128)>>32) as i64,((self.x_axis.0.y as i128*self.z_axis.0.x as i128-self.x_axis.0.x as i128*self.z_axis.0.y as i128)>>32) as i64,((-(self.x_axis.0.y as i128*self.y_axis.0.x as i128)+self.x_axis.0.x as i128*self.y_axis.0.y as i128)>>32) as i64),
x_axis:Planar64Vec3::raw(((-(self.y_axis.0.z as i128*self.z_axis.0.y as i128)+self.y_axis.0.y as i128*self.z_axis.0.z as i128)>>32) as i64,((self.x_axis.0.z as i128*self.z_axis.0.y as i128-self.x_axis.0.y as i128*self.z_axis.0.z as i128)>>32) as i64,((-(self.x_axis.0.z as i128*self.y_axis.0.y as i128)+self.x_axis.0.y as i128*self.y_axis.0.z as i128)>>32) as i64),
y_axis:Planar64Vec3::raw(((self.y_axis.0.z as i128*self.z_axis.0.x as i128-self.y_axis.0.x as i128*self.z_axis.0.z as i128)>>32) as i64,((-(self.x_axis.0.z as i128*self.z_axis.0.x as i128)+self.x_axis.0.x as i128*self.z_axis.0.z as i128)>>32) as i64,((self.x_axis.0.z as i128*self.y_axis.0.x as i128-self.x_axis.0.x as i128*self.y_axis.0.z as i128)>>32) as i64),
z_axis:Planar64Vec3::raw(((-(self.y_axis.0.y as i128*self.z_axis.0.x as i128)+self.y_axis.0.x as i128*self.z_axis.0.y as i128)>>32) as i64,((self.x_axis.0.y as i128*self.z_axis.0.x as i128-self.x_axis.0.x as i128*self.z_axis.0.y as i128)>>32) as i64,((-(self.x_axis.0.y as i128*self.y_axis.0.x as i128)+self.x_axis.0.x as i128*self.y_axis.0.y as i128)>>32) as i64),
}
}
#[inline]
pub const fn transpose(&self)->Self{
Self{
x_axis:Planar64Vec3::raw_xyz(self.x_axis.0.x,self.y_axis.0.x,self.z_axis.0.x),
y_axis:Planar64Vec3::raw_xyz(self.x_axis.0.y,self.y_axis.0.y,self.z_axis.0.y),
z_axis:Planar64Vec3::raw_xyz(self.x_axis.0.z,self.y_axis.0.z,self.z_axis.0.z),
x_axis:Planar64Vec3::raw(self.x_axis.0.x,self.y_axis.0.x,self.z_axis.0.x),
y_axis:Planar64Vec3::raw(self.x_axis.0.y,self.y_axis.0.y,self.z_axis.0.y),
z_axis:Planar64Vec3::raw(self.x_axis.0.z,self.y_axis.0.z,self.z_axis.0.z),
}
}
#[inline]
@ -1074,4 +1046,4 @@ fn test_sqrt(){
assert_eq!(1717986918400,r.get());
let s=r.sqrt();
assert_eq!(85899345920,s.get());
}
}

@ -2,7 +2,6 @@ pub mod bvh;
pub mod map;
pub mod aabb;
pub mod model;
pub mod timer;
pub mod zeroes;
pub mod integer;
pub mod updatable;
@ -10,4 +9,4 @@ pub mod instruction;
pub mod gameplay_attributes;
pub mod gameplay_modes;
pub mod gameplay_style;
pub mod controls_bitflag;
pub mod controls_bitflag;

@ -76,7 +76,7 @@ impl MapVertexId for PolygonGroup{
}
}
/// Ah yes, a group of things to render at the same time
#[derive(Clone,Copy,Debug,Hash,id::Id,Eq,PartialEq)]
#[derive(Clone,Copy,Hash,id::Id,Eq,PartialEq)]
pub struct TextureId(u32);
#[derive(Clone,Copy,Hash,id::Id,Eq,PartialEq)]
pub struct RenderConfigId(u32);
@ -103,7 +103,7 @@ pub struct IndexedPhysicsGroup{
pub groups:Vec<PolygonGroupId>,
}
//This is a superset of PhysicsModel and GraphicsModel
#[derive(Clone,Copy,Debug,Hash,id::Id,Eq,PartialEq)]
#[derive(Clone,Copy,Hash,id::Id,Eq,PartialEq)]
pub struct MeshId(u32);
#[derive(Clone)]
pub struct Mesh{

@ -1,209 +0,0 @@
use crate::integer::{Time,Ratio64};
//this could be about half as long if I only had
//scaled timers and just used a scale of 1
//but I thought the concept of a timer that could
//only be paused and not scaled was cool
trait TimerState:Copy{
fn get_time(&self,time:Time)->Time;
fn set_time(&mut self,time:Time,new_time:Time);
fn get_offset(&self)->Time;
fn set_offset(&mut self,offset:Time);
}
#[derive(Clone,Copy,Debug)]
pub struct Scaled{
scale:Ratio64,
offset:Time,
}
impl Scaled{
const fn identity()->Self{
Self{scale:Ratio64::ONE,offset:Time::ZERO}
}
const fn with_scale(scale:Ratio64)->Self{
Self{scale,offset:Time::ZERO}
}
const fn scale(&self,time:Time)->Time{
Time::raw(self.scale.mul_int(time.get()))
}
const fn get_scale(&self)->Ratio64{
self.scale
}
fn set_scale(&mut self,time:Time,new_scale:Ratio64){
let new_time=self.get_time(time);
self.scale=new_scale;
self.set_time(time,new_time);
}
}
impl TimerState for Scaled{
fn get_time(&self,time:Time)->Time{
self.scale(time)+self.offset
}
fn set_time(&mut self,time:Time,new_time:Time){
self.offset=new_time-self.scale(time);
}
fn get_offset(&self)->Time{
self.offset
}
fn set_offset(&mut self,offset:Time){
self.offset=offset;
}
}
#[derive(Clone,Copy,Debug)]
pub struct Realtime{
offset:Time,
}
impl Realtime{
const fn identity()->Self{
Self{offset:Time::ZERO}
}
}
impl TimerState for Realtime{
fn get_time(&self,time:Time)->Time{
time+self.offset
}
fn set_time(&mut self,time:Time,new_time:Time){
self.offset=new_time-time;
}
fn get_offset(&self)->Time{
self.offset
}
fn set_offset(&mut self,offset:Time){
self.offset=offset;
}
}
#[derive(Clone,Debug)]
pub struct Timer<T>{
state:T,
paused:bool,
}
impl Timer<Realtime>{
pub fn realtime(time:Time,new_time:Time)->Self{
let mut timer=Self{
state:Realtime::identity(),
paused:false,
};
timer.set_time(time,new_time);
timer
}
pub fn realtime_paused(offset:Time)->Self{
Self{
state:Realtime{offset},
paused:true,
}
}
}
#[derive(Debug)]
pub enum Error{
AlreadyPaused,
AlreadyUnpaused,
}
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{}
impl Timer<Scaled>{
pub fn new(time:Time,new_time:Time,scale:Ratio64,paused:bool)->Self{
let mut timer=Self{
state:Scaled::with_scale(scale),
paused,
};
timer.set_time(time,new_time);
timer
}
pub fn scaled(time:Time,new_time:Time,scale:Ratio64)->Self{
let mut timer=Self{
state:Scaled::with_scale(scale),
paused:false,
};
timer.set_time(time,new_time);
timer
}
pub fn scaled_paused(time:Time,new_time:Time,scale:Ratio64)->Self{
let mut timer=Self{
state:Scaled::with_scale(scale),
paused:true,
};
timer.set_time(time,new_time);
timer
}
pub const fn get_scale(&self)->Ratio64{
self.state.get_scale()
}
pub fn set_scale(&mut self,time:Time,new_scale:Ratio64){
self.state.set_scale(time,new_scale)
}
}
impl<T:TimerState> Timer<T>{
pub fn time(&self,time:Time)->Time{
match self.paused{
true=>self.state.get_offset(),
false=>self.state.get_time(time),
}
}
pub fn set_time(&mut self,time:Time,new_time:Time){
match self.paused{
true=>self.state.set_offset(new_time),
false=>self.state.set_time(time,new_time),
}
}
pub fn pause(&mut self,time:Time)->Result<(),Error>{
match self.paused{
true=>Err(Error::AlreadyPaused),
false=>{
let new_time=self.time(time);
self.state.set_offset(new_time);
self.paused=true;
Ok(())
},
}
}
pub fn unpause(&mut self,time:Time)->Result<(),Error>{
match self.paused{
true=>{
let new_time=self.time(time);
self.state.set_time(time,new_time);
self.paused=false;
Ok(())
},
false=>Err(Error::AlreadyUnpaused),
}
}
}
#[cfg(test)]
mod test{
use super::{Time,Timer,Error};
macro_rules! sec {
($s: expr) => {
Time::from_secs($s)
};
}
#[test]
fn test_timer()->Result<(),Error>{
//create a paused timer that reads 0s
let mut timer=Timer::realtime_paused(sec!(0));
//the paused timer at 1 second should read 0s
assert_eq!(timer.time(sec!(1)),sec!(0));
//unpause it after one second
timer.unpause(sec!(1))?;
//the timer at 6 seconds should read 5s
assert_eq!(timer.time(sec!(6)),sec!(5));
//pause the timer after 11 seconds
timer.pause(sec!(11))?;
//the paused timer at 20 seconds should read 10s
assert_eq!(timer.time(sec!(20)),sec!(10));
Ok(())
}
}