Compare commits

..

24 Commits

Author SHA1 Message Date
204dce366f comments 2025-02-21 12:43:18 -08:00
99301bb990 fix bvh iter 2025-02-21 12:42:44 -08:00
28ffc82ac0 debug print ray hit 2025-02-21 12:42:44 -08:00
792c386008 last ray hit 2025-02-21 12:42:44 -08:00
151b99c3e6 PhysicsData::trace_ray 2025-02-21 12:42:44 -08:00
b0e0bda101 common: Ray 2025-02-21 12:42:44 -08:00
510aef07a8 wip wip 2025-02-21 12:42:44 -08:00
2c07673b7d TransformedMesh::faces 2025-02-21 12:42:44 -08:00
2a73f8a469 wip 2025-02-21 12:42:44 -08:00
4023ae60b1 common: Time is Ord 2025-02-21 12:42:44 -08:00
1016f95b48 common: tweak sample_ray 2025-02-21 12:42:44 -08:00
c0769abc1b common: fix intersect_aabb 2025-02-21 12:42:44 -08:00
74eefcb78f wip: fix intersect_aabb 2025-02-21 12:42:44 -08:00
f770f5ac7b implement Ray::intersect_aabb 2025-02-21 12:42:44 -08:00
5b710b531e todo 2025-02-21 12:42:44 -08:00
a77b2fd78f nondeterminism warning 2025-02-21 12:42:44 -08:00
915d6c67cd a little wild with the trait bounds 2025-02-21 12:42:44 -08:00
9b7101cbea fixups and wip 2025-02-21 12:42:44 -08:00
e67b29148e common: bvh: sample_ray 2025-02-21 12:42:44 -08:00
384b42f1ff hi 2025-02-21 12:42:44 -08:00
aceae11d42 progress 2025-02-21 12:42:44 -08:00
5123573822 wip 2025-02-21 12:42:44 -08:00
49a5acf73b wip: not smart enough for bvh iter rn 2025-02-21 12:42:44 -08:00
ba2d40970b fix Ord for Ratio 2025-02-21 12:42:29 -08:00
12 changed files with 85 additions and 59 deletions

2
Cargo.lock generated
View File

@@ -2991,7 +2991,7 @@ checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde"
[[package]]
name = "ratio_ops"
version = "0.1.1"
version = "0.1.0"
[[package]]
name = "rav1e"

View File

@@ -1,4 +1,5 @@
use std::collections::{HashMap,HashSet};
use crate::model::DirectedEdge;
use crate::model::{self as model_physics,PhysicsMesh,PhysicsMeshTransform,TransformedMesh,MeshQuery,PhysicsMeshId,PhysicsSubmeshId};
use strafesnet_common::bvh;
use strafesnet_common::map;
@@ -280,7 +281,8 @@ impl PhysicsCamera{
.clamp(Self::ANGLE_PITCH_LOWER_LIMIT,Self::ANGLE_PITCH_UPPER_LIMIT);
mat3::from_rotation_yx(ax,ay)
}
fn rotation(&self)->Planar64Mat3{
#[inline]
pub fn rotation(&self)->Planar64Mat3{
self.get_rotation(self.clamped_mouse_pos)
}
fn simulate_move_rotation(&self,mouse_delta:glam::IVec2)->Planar64Mat3{
@@ -980,6 +982,34 @@ impl PhysicsContext<'_>{
}
}
impl PhysicsData{
pub fn trace_ray(&self,ray:strafesnet_common::ray::Ray)->Option<ModelId>{
let (_time,convex_mesh_id)=self.bvh.sample_ray(&ray,Time::ZERO,Time::MAX/4,|&model,ray|{
let mesh=self.models.mesh(model);
// brute force trace every face
mesh.faces().filter_map(|face_id|{
let (n,d)=mesh.face_nd(face_id);
// trace ray onto face
// n.(o+d*t)==n.p
// n.o + n.d * t == n.p
// t == (n.p - n.o)/n.d
let nd=n.dot(ray.direction);
if nd.is_zero(){
return None;
}
let t=(d-n.dot(ray.origin))/nd;
// check if point of intersection is behind face edges
// *2 because average of 2 vertices
let p=ray.extrapolate(t)*2;
mesh.face_edges(face_id).iter().all(|&directed_edge_id|{
let edge_n=mesh.directed_edge_n(directed_edge_id);
let cross_n=edge_n.cross(n);
let &[vert0,vert1]=mesh.edge_verts(directed_edge_id.as_undirected()).as_ref();
cross_n.dot(p)<cross_n.dot(mesh.vert(vert0)+mesh.vert(vert1))
}).then(||t)
}).min().map(Into::into)
})?;
Some(convex_mesh_id.model_id.into())
}
/// use with caution, this is the only non-instruction way to mess with physics
pub fn generate_models(&mut self,map:&map::CompleteMap){
let mut modes=map.modes.clone();

View File

@@ -161,6 +161,7 @@ pub struct Session{
recording:Recording,
//players:HashMap<PlayerId,Simulation>,
replays:HashMap<BotId,Replay>,
last_ray_hit:Option<strafesnet_common::model::ModelId>,
}
impl Session{
pub fn new(
@@ -177,6 +178,7 @@ impl Session{
view_state:ViewState::Play,
recording:Default::default(),
replays:HashMap::new(),
last_ray_hit:None,
}
}
fn clear_recording(&mut self){
@@ -194,6 +196,19 @@ impl Session{
),
}
}
pub fn debug_raycast_print_model_id_if_changed(&mut self,time:SessionTime){
if let Some(frame_state)=self.get_frame_state(time){
let ray=strafesnet_common::ray::Ray{
origin:frame_state.body.extrapolated_position(self.simulation.timer.time(time)),
direction:-frame_state.camera.rotation().z_axis,
};
let model_id=self.geometry_shared.trace_ray(ray);
if model_id!=self.last_ray_hit{
println!("hit={model_id:?}");
self.last_ray_hit=model_id;
}
}
}
pub fn user_settings(&self)->&UserSettings{
&self.user_settings
}

View File

@@ -5,12 +5,6 @@ mod mesh;
pub mod loader;
const VALVE_SCALE:f32=1.0/16.0;
pub(crate) fn valve_transform_dist(d:f32)->strafesnet_common::integer::Planar64{
(d*VALVE_SCALE).try_into().unwrap()
}
pub(crate) fn valve_transform_normal([x,y,z]:[f32;3])->strafesnet_common::integer::Planar64Vec3{
strafesnet_common::integer::vec3::try_from_f32_array([x,z,-y]).unwrap()
}
pub(crate) fn valve_transform([x,y,z]:[f32;3])->strafesnet_common::integer::Planar64Vec3{
strafesnet_common::integer::vec3::try_from_f32_array([x*VALVE_SCALE,z*VALVE_SCALE,-y*VALVE_SCALE]).unwrap()
}

View File

@@ -47,7 +47,7 @@ pub enum MeshError{
Io(std::io::Error),
VMDL(vmdl::ModelError),
VBSP(vbsp::BspError),
MissingMdl(String),
MissingMdl,
MissingVtx,
MissingVvd,
}
@@ -132,7 +132,7 @@ impl<'bsp,'vpk,'a> Loader for ModelLoader<'bsp,'vpk,'a>
vvd_path.set_extension("vvd");
vtx_path.set_extension("dx90.vtx");
// TODO: search more packs, possibly using an index of multiple packs
let mdl=self.finder.find(mdl_path_lower.as_str())?.ok_or(MeshError::MissingMdl(mdl_path_lower))?;
let mdl=self.finder.find(mdl_path_lower.as_str())?.ok_or(MeshError::MissingMdl)?;
let vtx=self.finder.find(vtx_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVtx)?;
let vvd=self.finder.find(vvd_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVvd)?;
Ok(vmdl::Model::from_parts(

View File

@@ -171,7 +171,4 @@ impl CollisionAttributes{
pub fn contact_default()->Self{
Self::Contact(ContactAttributes::default())
}
pub fn intersect_default()->Self{
Self::Intersect(IntersectAttributes::default())
}
}

View File

@@ -654,19 +654,11 @@ pub struct Planar64Affine3{
pub translation:Planar64Vec3,
}
impl Planar64Affine3{
pub const IDENTITY:Self=Self::new(mat3::identity(),vec3::ZERO);
#[inline]
pub const fn new(matrix3:Planar64Mat3,translation:Planar64Vec3)->Self{
Self{matrix3,translation}
}
#[inline]
pub const fn from_translation(translation:Planar64Vec3)->Self{
Self{
matrix3:mat3::identity(),
translation,
}
}
#[inline]
pub fn transform_point3(&self,point:Planar64Vec3)->vec3::Vector3<Fixed<2,64>>{
self.translation.fix_2()+self.matrix3*point
}

View File

@@ -1,6 +1,5 @@
use crate::vector::Vector;
#[repr(transparent)]
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)]
pub struct Matrix<const X:usize,const Y:usize,T>{
pub(crate) array:[[T;Y];X],

View File

@@ -3,7 +3,6 @@
/// v.x += v.z;
/// println!("v.x={}",v.x);
#[repr(transparent)]
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)]
pub struct Vector<const N:usize,T>{
pub(crate) array:[T;N],

View File

@@ -1,6 +1,6 @@
[package]
name = "ratio_ops"
version = "0.1.1"
version = "0.1.0"
edition = "2024"
repository = "https://git.itzana.me/StrafesNET/strafe-project"
license = "MIT OR Apache-2.0"

View File

@@ -68,57 +68,54 @@ impl_ratio_method!(Add,add,add_ratio);
impl_ratio_method!(Sub,sub,sub_ratio);
impl_ratio_method!(Rem,rem,rem_ratio);
/// The denominator cannot be negative
/// otherwise cross-multiplying changes the comparison
pub trait ToUnsigned{
type Unsigned;
fn to_unsigned(self)->(bool,Self::Unsigned);
/// Comparing two ratios needs to know the parity of the denominators
/// For signed integers this can be implemented with is_negative()
pub trait Parity{
fn parity(&self)->bool;
}
macro_rules! impl_to_unsigned_unsigned{
macro_rules! impl_parity_unsigned{
($($type:ty),*)=>{
$(
impl ToUnsigned for $type{
type Unsigned=Self;
fn to_unsigned(self)->(bool,Self::Unsigned){
(false,self)
impl Parity for $type{
fn parity(&self)->bool{
false
}
}
)*
};
}
macro_rules! impl_to_unsigned_signed{
($(($type:ty,$unsigned:ty)),*)=>{
$(
impl ToUnsigned for $type{
type Unsigned=$unsigned;
fn to_unsigned(self)->(bool,Self::Unsigned){
(self.is_negative(),self.unsigned_abs())
}
}
)*
};
}
macro_rules! impl_to_unsigned_float{
macro_rules! impl_parity_signed{
($($type:ty),*)=>{
$(
impl ToUnsigned for $type{
type Unsigned=Self;
fn to_unsigned(self)->(bool,Self::Unsigned){
(self.is_sign_negative(),-self)
impl Parity for $type{
fn parity(&self)->bool{
self.is_negative()
}
}
)*
};
}
impl_to_unsigned_unsigned!(u8,u16,u32,u64,u128,usize);
impl_to_unsigned_signed!((i8,u8),(i16,u16),(i32,u32),(i64,u64),(i128,u128),(isize,usize));
impl_to_unsigned_float!(f32,f64);
macro_rules! impl_parity_float{
($($type:ty),*)=>{
$(
impl Parity for $type{
fn parity(&self)->bool{
self.is_sign_negative()
}
}
)*
};
}
impl_parity_unsigned!(u8,u16,u32,u64,u128,usize);
impl_parity_signed!(i8,i16,i32,i64,i128,isize);
impl_parity_float!(f32,f64);
macro_rules! impl_ratio_ord_method{
($method:ident, $ratio_method:ident, $output:ty)=>{
impl<LhsNum,LhsDen:ToUnsigned> Ratio<LhsNum,LhsDen>{
impl<LhsNum,LhsDen:Parity> Ratio<LhsNum,LhsDen>{
#[inline]
pub fn $ratio_method<RhsNum,RhsDen:ToUnsigned,T>(self,rhs:Ratio<RhsNum,RhsDen>)->$output
pub fn $ratio_method<RhsNum,RhsDen:Parity,T>(self,rhs:Ratio<RhsNum,RhsDen>)->$output
where
LhsNum:core::ops::Mul<RhsDen,Output=T>,
LhsDen:core::ops::Mul<RhsNum,Output=T>,
@@ -276,9 +273,9 @@ impl<Num,Den> Eq for Ratio<Num,Den> where Self:PartialEq{}
impl<LhsNum,LhsDen,RhsNum,RhsDen,T,U> PartialOrd<Ratio<RhsNum,RhsDen>> for Ratio<LhsNum,LhsDen>
where
LhsNum:Copy,
LhsDen:Copy+ToUnsigned,
LhsDen:Copy+Parity,
RhsNum:Copy,
RhsDen:Copy+ToUnsigned,
RhsDen:Copy+Parity,
LhsNum:core::ops::Mul<RhsDen,Output=T>,
LhsDen:core::ops::Mul<RhsNum,Output=T>,
RhsNum:core::ops::Mul<LhsDen,Output=U>,
@@ -293,7 +290,7 @@ impl<LhsNum,LhsDen,RhsNum,RhsDen,T,U> PartialOrd<Ratio<RhsNum,RhsDen>> for Ratio
impl<Num,Den,T> Ord for Ratio<Num,Den>
where
Num:Copy,
Den:Copy+ToUnsigned,
Den:Copy+Parity,
Num:core::ops::Mul<Den,Output=T>,
Den:core::ops::Mul<Num,Output=T>,
T:Ord,

View File

@@ -77,5 +77,8 @@ pub fn new<'a>(
run_session_instruction!(ins.time,SessionInstruction::LoadReplay(bot));
}
}
//whatever just do it
session.debug_raycast_print_model_id_if_changed(ins.time);
})
}