This commit is contained in:
2025-12-16 11:03:32 -08:00
parent 2b1cef964c
commit d6db0ac161
4 changed files with 59 additions and 27 deletions

View File

@@ -37,6 +37,7 @@ struct GraphicsModel{
}
struct DebugGraphicsSubmesh{
verts:Vec<strafesnet_physics::model::MeshVertId>,
edges:Vec<Indices>,
faces:Vec<Indices>,
}
@@ -214,6 +215,7 @@ impl GraphicsState{
let submeshes=if let Ok(physics_mesh)=strafesnet_physics::model::PhysicsMesh::try_from(mesh){
physics_mesh.submesh_views().into_iter().map(|submesh_view|DebugGraphicsSubmesh{
verts:submesh_view.verts().to_owned(),
edges:submesh_view.edge_vert_ids_iter().map(|edge_verts|indices!(edge_verts)).collect(),
faces:submesh_view.face_vert_ids_iter().map(|face_verts|{
// triangulate
@@ -1165,15 +1167,36 @@ impl GraphicsState{
rpass.draw(0..3,0..1);
// render a single debug_model in red
if let Some(model_id)=frame_state.debug_model{
if let Some(model)=self.debug_models.get(model_id.get() as usize){
let mesh=&self.debug_meshes[model.debug_mesh_id as usize];
rpass.set_pipeline(&self.pipelines.debug_face);
rpass.set_bind_group(1,&model.bind_group,&[]);
rpass.set_vertex_buffer(0,mesh.vertex_buf.slice(..));
rpass.set_index_buffer(mesh.indices.buf.slice(..),mesh.indices.format);
//TODO: loop over triangle strips
rpass.draw_indexed(0..mesh.indices.count,0,0..1);
if let Some(hit)=frame_state.hit{
if let Some(closest_fev)=&hit.closest_fev{
let model_id:model::ModelId=hit.convex_mesh_id.model_id.into();
if let Some(model)=self.debug_models.get(model_id.get() as usize){
let mesh=&self.debug_meshes[model.debug_mesh_id as usize];
rpass.set_bind_group(1,&model.bind_group,&[]);
rpass.set_vertex_buffer(0,mesh.vertex_buf.slice(..));
match closest_fev{
strafesnet_physics::model::FEV::Face(face)=>{
rpass.set_pipeline(&self.pipelines.debug_face);
let indices=&mesh.submeshes[hit.convex_mesh_id.submesh_id.get() as usize].faces[face.get() as usize];
rpass.set_index_buffer(indices.buf.slice(..),indices.format);
//TODO: loop over triangle strips
rpass.draw_indexed(0..indices.count,0,0..1);
},
strafesnet_physics::model::FEV::Edge(edge)=>{
rpass.set_pipeline(&self.pipelines.debug_edge);
let indices=&mesh.submeshes[hit.convex_mesh_id.submesh_id.get() as usize].edges[edge.get() as usize];
rpass.set_index_buffer(indices.buf.slice(..),indices.format);
rpass.draw_indexed(0..indices.count,0,0..1);
},
strafesnet_physics::model::FEV::Vert(vert)=>{
rpass.set_pipeline(&self.pipelines.debug_vert);
let indices=&mesh.verts;
rpass.set_index_buffer(indices.buf.slice(..),indices.format);
let vert_id=mesh.submeshes[hit.convex_mesh_id.submesh_id.get() as usize].verts[vert.get() as usize].get();
rpass.draw_indexed(0..1,vert_id as i32,0..1);
},
}
}
}
}
}

View File

@@ -446,6 +446,9 @@ pub struct PhysicsMeshView<'a>{
topology:&'a PhysicsMeshTopology,
}
impl PhysicsMeshView<'_>{
pub fn verts(&self)->&[MeshVertId]{
&self.topology.verts
}
pub fn edge_vert_ids_iter(&self)->impl Iterator<Item=[u32;2]>+'_{
self.topology.edge_topology.iter().map(|edge|{
edge.verts.map(|vert_id|self.topology.verts[vert_id.get() as usize].get())

View File

@@ -709,8 +709,8 @@ impl From<PhysicsModelId> for ModelId{
//unique physics meshes indexed by this
#[derive(Debug,Clone,Copy,Eq,Hash,PartialEq)]
pub struct ConvexMeshId<Id>{
model_id:Id,
submesh_id:PhysicsSubmeshId,
pub model_id:Id,
pub submesh_id:PhysicsSubmeshId,
}
impl<Id> ConvexMeshId<Id>{
fn map<NewId>(self,model_id:NewId)->ConvexMeshId<NewId>{
@@ -1038,7 +1038,7 @@ impl PhysicsData{
})?;
Some(*convex_mesh_id)
}
pub fn closest_fev_not_inside(&self,convex_mesh_id:ConvexMeshId<PhysicsModelId>,point:Planar64Vec3)->Option<model_physics::FEV<TransformedMesh<'_>>>{
pub fn closest_fev_not_inside(&self,convex_mesh_id:ConvexMeshId<PhysicsModelId>,point:Planar64Vec3)->Option<model_physics::FEV<TransformedMesh<'static>>>{
let model_mesh=self.models.mesh(convex_mesh_id);
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,self.hitbox_mesh.transformed_mesh());
let fev=crate::minimum_difference::closest_fev_not_inside(&minkowski,point)?;

View File

@@ -2,7 +2,6 @@ use std::collections::HashMap;
use strafesnet_common::gameplay_modes::{ModeId,StageId};
use strafesnet_common::instruction::{InstructionConsumer,InstructionEmitter,InstructionFeedback,TimedInstruction};
use strafesnet_common::model::ModelId;
// session represents the non-hardware state of the client.
// Ideally it is a deterministic state which is atomically updated by instructions, same as the simulation state.
use strafesnet_common::physics::{
@@ -58,11 +57,11 @@ pub enum SessionPlaybackInstruction{
IncreaseTimescale,
}
pub struct FrameState{
pub struct FrameState<'a>{
pub body:physics::Body,
pub camera:physics::PhysicsCamera,
pub time:PhysicsTime,
pub debug_model:Option<physics::ConvexMeshId<physics::PhysicsModelId>>,
pub hit:Option<&'a Hit>,
}
pub struct Simulation{
@@ -79,12 +78,12 @@ impl Simulation{
physics,
}
}
pub fn get_frame_state(&self,time:SessionTime,debug_model:Option<physics::ConvexMeshId<physics::PhysicsModelId>>)->FrameState{
pub fn get_frame_state<'a>(&'a self,time:SessionTime,debug_model:Option<&'a Hit>)->FrameState<'a>{
FrameState{
body:self.physics.camera_body(),
camera:self.physics.camera(),
time:self.timer.time(time),
debug_model,
hit: debug_model,
}
}
}
@@ -152,6 +151,11 @@ enum ViewState{
Replay(BotId),
}
pub struct Hit{
pub convex_mesh_id:physics::ConvexMeshId<physics::PhysicsModelId>,
pub closest_fev:Option<strafesnet_physics::model::FEV<strafesnet_physics::model::TransformedMesh<'static>>>
}
pub struct Session{
directories:Directories,
user_settings:UserSettings,
@@ -164,7 +168,7 @@ pub struct Session{
recording:Recording,
//players:HashMap<PlayerId,Simulation>,
replays:HashMap<BotId,Replay>,
last_ray_hit:Option<physics::ConvexMeshId<physics::PhysicsModelId>>,
last_ray_hit:Option<Hit>,
}
impl Session{
pub fn new(
@@ -191,9 +195,9 @@ impl Session{
self.simulation.physics.clear();
self.geometry_shared=PhysicsData::new(map);
}
pub fn get_frame_state(&self,time:SessionTime)->Option<FrameState>{
pub fn get_frame_state(&self,time:SessionTime)->Option<FrameState<'_>>{
match &self.view_state{
ViewState::Play=>Some(self.simulation.get_frame_state(time,self.last_ray_hit)),
ViewState::Play=>Some(self.simulation.get_frame_state(time,self.last_ray_hit.as_ref())),
ViewState::Replay(bot_id)=>self.replays.get(bot_id).map(|replay|
replay.simulation.get_frame_state(time,None)
),
@@ -205,13 +209,15 @@ impl Session{
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;
}
if let Some(model_id)=model_id{
// self.geometry_shared./
match self.geometry_shared.trace_ray(ray){
Some(convex_mesh_id)=>{
let closest_fev=self.geometry_shared.closest_fev_not_inside(convex_mesh_id,self.simulation.physics.body().position);
self.last_ray_hit=Some(Hit{
convex_mesh_id,
closest_fev,
});
},
None=>self.last_ray_hit=None,
}
}
}