Compare commits
14 Commits
master
...
entity-deb
Author | SHA1 | Date | |
---|---|---|---|
b9ed031919 | |||
364939167c | |||
8b6f3620f8 | |||
71426c257f | |||
041cc15f20 | |||
6ef6174693 | |||
70fb970582 | |||
31184d21da | |||
6b4b17f49d | |||
d0c17873f6 | |||
d39705d5e7 | |||
a3a50580f8 | |||
d5bf4549a9 | |||
b5da85fae1 |
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -1838,7 +1838,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3732,6 +3732,7 @@ dependencies = [
|
||||
"id",
|
||||
"linear_ops",
|
||||
"ratio_ops",
|
||||
"vbsp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5,7 +5,7 @@ use strafesnet_settings::settings;
|
||||
use strafesnet_session::session;
|
||||
use strafesnet_common::model::{self, ColorId, NormalId, PolygonIter, PositionId, RenderConfigId, TextureCoordinateId, VertexId};
|
||||
use wgpu::{util::DeviceExt,AstcBlock,AstcChannel};
|
||||
use crate::model::{self as model_graphics,IndexedGraphicsMeshOwnedRenderConfig,IndexedGraphicsMeshOwnedRenderConfigId,GraphicsMeshOwnedRenderConfig,GraphicsModelColor4,GraphicsModelOwned,GraphicsVertex};
|
||||
use crate::model::{self as model_graphics,IndexedGraphicsMeshOwnedRenderConfig,IndexedGraphicsMeshOwnedRenderConfigId,GraphicsMeshOwnedRenderConfig,GraphicsModelColor4,GraphicsModelOwned,GraphicsVertex,DebugGraphicsVertex};
|
||||
|
||||
pub fn required_limits()->wgpu::Limits{
|
||||
wgpu::Limits::default()
|
||||
@ -36,12 +36,22 @@ struct GraphicsModel{
|
||||
instance_count:u32,
|
||||
}
|
||||
|
||||
struct DebugGraphicsMesh{
|
||||
indices:Indices,
|
||||
vertex_buf:wgpu::Buffer,
|
||||
}
|
||||
struct DebugGraphicsModel{
|
||||
debug_mesh_id:u32,
|
||||
bind_group:wgpu::BindGroup,
|
||||
}
|
||||
|
||||
struct GraphicsSamplers{
|
||||
repeat:wgpu::Sampler,
|
||||
}
|
||||
|
||||
struct GraphicsBindGroupLayouts{
|
||||
model:wgpu::BindGroupLayout,
|
||||
debug_model:wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
struct GraphicsBindGroups{
|
||||
@ -52,6 +62,7 @@ struct GraphicsBindGroups{
|
||||
struct GraphicsPipelines{
|
||||
skybox:wgpu::RenderPipeline,
|
||||
model:wgpu::RenderPipeline,
|
||||
debug:wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
struct GraphicsCamera{
|
||||
@ -112,6 +123,8 @@ pub struct GraphicsState{
|
||||
camera_buf:wgpu::Buffer,
|
||||
temp_squid_texture_view:wgpu::TextureView,
|
||||
models:Vec<GraphicsModel>,
|
||||
debug_meshes:Vec<DebugGraphicsMesh>,
|
||||
debug_models:Vec<DebugGraphicsModel>,
|
||||
depth_view:wgpu::TextureView,
|
||||
staging_belt:wgpu::util::StagingBelt,
|
||||
}
|
||||
@ -146,6 +159,76 @@ impl GraphicsState{
|
||||
self.camera.fov=user_settings.calculate_fov(1.0,&self.camera.screen_size).as_vec2();
|
||||
}
|
||||
pub fn generate_models(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,map:&map::CompleteMap){
|
||||
//generate debug meshes, each debug model refers to one
|
||||
self.debug_meshes=map.meshes.iter().map(|mesh|{
|
||||
let vertices:Vec<DebugGraphicsVertex>=mesh.unique_vertices.iter().map(|vertex|{
|
||||
DebugGraphicsVertex{
|
||||
pos:mesh.unique_pos[vertex.pos.get() as usize].to_array().map(Into::into),
|
||||
normal:mesh.unique_normal[vertex.normal.get() as usize].to_array().map(Into::into),
|
||||
}
|
||||
}).collect();
|
||||
let vertex_buf=device.create_buffer_init(&wgpu::util::BufferInitDescriptor{
|
||||
label:Some("Vertex"),
|
||||
contents:bytemuck::cast_slice(&vertices),
|
||||
usage:wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
|
||||
let mut indices=Vec::new();
|
||||
for physics_group in &mesh.physics_groups{
|
||||
for polygon_group_id in &physics_group.groups{
|
||||
for poly in mesh.polygon_groups[polygon_group_id.get() as usize].polys(){
|
||||
// triangulate
|
||||
let mut poly_vertices=poly.into_iter().copied();
|
||||
if let (Some(a),Some(mut b))=(poly_vertices.next(),poly_vertices.next()){
|
||||
for c in poly_vertices{
|
||||
indices.extend([a,b,c]);
|
||||
b=c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DebugGraphicsMesh{
|
||||
indices:if (u32::MAX as usize)<vertices.len(){
|
||||
panic!("Model has too many vertices!")
|
||||
}else if (u16::MAX as usize)<vertices.len(){
|
||||
Indices::new(device,&indices.into_iter().map(|vertex_idx|vertex_idx.get() as u32).collect(),wgpu::IndexFormat::Uint32)
|
||||
}else{
|
||||
Indices::new(device,&indices.into_iter().map(|vertex_idx|vertex_idx.get() as u16).collect(),wgpu::IndexFormat::Uint16)
|
||||
},
|
||||
vertex_buf,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
//generate debug models, only one will be rendered at a time
|
||||
self.debug_models=map.models.iter().enumerate().map(|(model_id,model)|{
|
||||
let model_uniforms=get_instance_buffer_data(&GraphicsModelOwned{
|
||||
transform:model.transform.into(),
|
||||
normal_transform:glam::Mat3::from_cols_array_2d(&model.transform.matrix3.to_array().map(|row|row.map(Into::into))).inverse().transpose(),
|
||||
color:GraphicsModelColor4::new(glam::vec4(1.0,0.0,0.0,0.2)),
|
||||
});
|
||||
let model_buf=device.create_buffer_init(&wgpu::util::BufferInitDescriptor{
|
||||
label:Some(format!("Debug Model{} Buf",model_id).as_str()),
|
||||
contents:bytemuck::cast_slice(&model_uniforms),
|
||||
usage:wgpu::BufferUsages::UNIFORM|wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
let bind_group=device.create_bind_group(&wgpu::BindGroupDescriptor{
|
||||
layout:&self.bind_group_layouts.debug_model,
|
||||
entries:&[
|
||||
wgpu::BindGroupEntry{
|
||||
binding:0,
|
||||
resource:model_buf.as_entire_binding(),
|
||||
},
|
||||
],
|
||||
label:Some(format!("Debug Model{} Bind Group",model_id).as_str()),
|
||||
});
|
||||
DebugGraphicsModel{
|
||||
debug_mesh_id:model.mesh.get(),
|
||||
bind_group,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
//generate texture view per texture
|
||||
let texture_views:HashMap<strafesnet_common::model::TextureId,wgpu::TextureView>=map.textures.iter().enumerate().filter_map(|(texture_id,texture_data)|{
|
||||
let texture_id=model::TextureId::new(texture_id as u32);
|
||||
@ -588,6 +671,21 @@ impl GraphicsState{
|
||||
},
|
||||
],
|
||||
});
|
||||
let debug_model_bind_group_layout=device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor{
|
||||
label:Some("Debug Model Bind Group Layout"),
|
||||
entries:&[
|
||||
wgpu::BindGroupLayoutEntry{
|
||||
binding:0,
|
||||
visibility:wgpu::ShaderStages::VERTEX_FRAGMENT,
|
||||
ty:wgpu::BindingType::Buffer{
|
||||
ty:wgpu::BufferBindingType::Uniform,
|
||||
has_dynamic_offset:false,
|
||||
min_binding_size:None,
|
||||
},
|
||||
count:None,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let clamp_sampler=device.create_sampler(&wgpu::SamplerDescriptor{
|
||||
label:Some("Clamp Sampler"),
|
||||
@ -736,6 +834,14 @@ impl GraphicsState{
|
||||
],
|
||||
push_constant_ranges:&[],
|
||||
});
|
||||
let debug_model_pipeline_layout=device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor{
|
||||
label:None,
|
||||
bind_group_layouts:&[
|
||||
&camera_bind_group_layout,
|
||||
&debug_model_bind_group_layout,
|
||||
],
|
||||
push_constant_ranges:&[],
|
||||
});
|
||||
let sky_pipeline_layout=device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor{
|
||||
label:None,
|
||||
bind_group_layouts:&[
|
||||
@ -811,6 +917,45 @@ impl GraphicsState{
|
||||
multiview:None,
|
||||
cache:None,
|
||||
});
|
||||
let debug_model_pipeline=device.create_render_pipeline(&wgpu::RenderPipelineDescriptor{
|
||||
label:Some("Debug Model Pipeline"),
|
||||
layout:Some(&debug_model_pipeline_layout),
|
||||
vertex:wgpu::VertexState{
|
||||
module:&shader,
|
||||
entry_point:Some("vs_debug"),
|
||||
buffers:&[wgpu::VertexBufferLayout{
|
||||
array_stride:std::mem::size_of::<DebugGraphicsVertex>() as wgpu::BufferAddress,
|
||||
step_mode:wgpu::VertexStepMode::Vertex,
|
||||
attributes:&wgpu::vertex_attr_array![0=>Float32x3,1=>Float32x3],
|
||||
}],
|
||||
compilation_options:wgpu::PipelineCompilationOptions::default(),
|
||||
},
|
||||
fragment:Some(wgpu::FragmentState{
|
||||
module:&shader,
|
||||
entry_point:Some("fs_debug"),
|
||||
targets:&[Some(wgpu::ColorTargetState{
|
||||
format:config.view_formats[0],
|
||||
blend:Some(wgpu::BlendState::ALPHA_BLENDING),
|
||||
write_mask:wgpu::ColorWrites::default(),
|
||||
})],
|
||||
compilation_options:wgpu::PipelineCompilationOptions::default(),
|
||||
}),
|
||||
primitive:wgpu::PrimitiveState{
|
||||
front_face:wgpu::FrontFace::Cw,
|
||||
cull_mode:Some(wgpu::Face::Front),
|
||||
..Default::default()
|
||||
},
|
||||
depth_stencil:Some(wgpu::DepthStencilState{
|
||||
format:Self::DEPTH_FORMAT,
|
||||
depth_write_enabled:true,
|
||||
depth_compare:wgpu::CompareFunction::Always,
|
||||
stencil:wgpu::StencilState::default(),
|
||||
bias:wgpu::DepthBiasState::default(),
|
||||
}),
|
||||
multisample:wgpu::MultisampleState::default(),
|
||||
multiview:None,
|
||||
cache:None,
|
||||
});
|
||||
|
||||
let camera=GraphicsCamera::default();
|
||||
let camera_uniforms=camera.to_uniform_data(glam::Vec3::ZERO,glam::Vec2::ZERO);
|
||||
@ -850,7 +995,8 @@ impl GraphicsState{
|
||||
Self{
|
||||
pipelines:GraphicsPipelines{
|
||||
skybox:sky_pipeline,
|
||||
model:model_pipeline
|
||||
model:model_pipeline,
|
||||
debug:debug_model_pipeline,
|
||||
},
|
||||
bind_groups:GraphicsBindGroups{
|
||||
camera:camera_bind_group,
|
||||
@ -859,9 +1005,14 @@ impl GraphicsState{
|
||||
camera,
|
||||
camera_buf,
|
||||
models:Vec::new(),
|
||||
debug_meshes:Vec::new(),
|
||||
debug_models:Vec::new(),
|
||||
depth_view,
|
||||
staging_belt:wgpu::util::StagingBelt::new(0x100),
|
||||
bind_group_layouts:GraphicsBindGroupLayouts{model:model_bind_group_layout},
|
||||
bind_group_layouts:GraphicsBindGroupLayouts{
|
||||
model:model_bind_group_layout,
|
||||
debug_model:debug_model_bind_group_layout,
|
||||
},
|
||||
samplers:GraphicsSamplers{repeat:repeat_sampler},
|
||||
temp_squid_texture_view:squid_texture_view,
|
||||
}
|
||||
@ -949,6 +1100,7 @@ impl GraphicsState{
|
||||
rpass.set_bind_group(0,&self.bind_groups.camera,&[]);
|
||||
rpass.set_bind_group(1,&self.bind_groups.skybox_texture,&[]);
|
||||
|
||||
// Draw all models.
|
||||
rpass.set_pipeline(&self.pipelines.model);
|
||||
for model in &self.models{
|
||||
rpass.set_bind_group(2,&model.bind_group,&[]);
|
||||
@ -960,6 +1112,19 @@ impl GraphicsState{
|
||||
|
||||
rpass.set_pipeline(&self.pipelines.skybox);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
queue.submit(std::iter::once(encoder.finish()));
|
||||
@ -968,21 +1133,23 @@ impl GraphicsState{
|
||||
}
|
||||
}
|
||||
const MODEL_BUFFER_SIZE:usize=4*4 + 12 + 4;//let size=std::mem::size_of::<ModelInstance>();
|
||||
const MODEL_BUFFER_SIZE_BYTES:usize=MODEL_BUFFER_SIZE*4;
|
||||
const MODEL_BUFFER_SIZE_BYTES:usize=MODEL_BUFFER_SIZE*core::mem::size_of::<f32>();
|
||||
fn get_instance_buffer_data(instance:&GraphicsModelOwned)->[f32;MODEL_BUFFER_SIZE]{
|
||||
let mut out=[0.0;MODEL_BUFFER_SIZE];
|
||||
out[0..16].copy_from_slice(instance.transform.as_ref());
|
||||
out[16..19].copy_from_slice(instance.normal_transform.x_axis.as_ref());
|
||||
// out[20]=0.0;
|
||||
out[20..23].copy_from_slice(instance.normal_transform.y_axis.as_ref());
|
||||
// out[24]=0.0;
|
||||
out[24..27].copy_from_slice(instance.normal_transform.z_axis.as_ref());
|
||||
// out[28]=0.0;
|
||||
out[28..32].copy_from_slice(instance.color.get().as_ref());
|
||||
out
|
||||
}
|
||||
fn get_instances_buffer_data(instances:&[GraphicsModelOwned])->Vec<f32>{
|
||||
let mut raw=Vec::with_capacity(MODEL_BUFFER_SIZE*instances.len());
|
||||
for mi in instances{
|
||||
//model transform
|
||||
raw.extend_from_slice(&AsRef::<[f32; 4*4]>::as_ref(&mi.transform)[..]);
|
||||
//normal transform
|
||||
raw.extend_from_slice(AsRef::<[f32; 3]>::as_ref(&mi.normal_transform.x_axis));
|
||||
raw.extend_from_slice(&[0.0]);
|
||||
raw.extend_from_slice(AsRef::<[f32; 3]>::as_ref(&mi.normal_transform.y_axis));
|
||||
raw.extend_from_slice(&[0.0]);
|
||||
raw.extend_from_slice(AsRef::<[f32; 3]>::as_ref(&mi.normal_transform.z_axis));
|
||||
raw.extend_from_slice(&[0.0]);
|
||||
//color
|
||||
raw.extend_from_slice(AsRef::<[f32; 4]>::as_ref(&mi.color.get()));
|
||||
raw.extend_from_slice(&get_instance_buffer_data(mi));
|
||||
}
|
||||
raw
|
||||
}
|
||||
|
@ -8,6 +8,12 @@ pub struct GraphicsVertex{
|
||||
pub normal:[f32;3],
|
||||
pub color:[f32;4],
|
||||
}
|
||||
#[derive(Clone,Copy,Pod,Zeroable)]
|
||||
#[repr(C)]
|
||||
pub struct DebugGraphicsVertex{
|
||||
pub pos:[f32;3],
|
||||
pub normal:[f32;3],
|
||||
}
|
||||
#[derive(Clone,Copy,id::Id)]
|
||||
pub struct IndexedGraphicsMeshOwnedRenderConfigId(u32);
|
||||
pub struct IndexedGraphicsMeshOwnedRenderConfig{
|
||||
|
@ -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{
|
||||
@ -931,6 +933,7 @@ pub struct PhysicsData{
|
||||
modes:gameplay_modes::Modes,
|
||||
//cached calculations
|
||||
hitbox_mesh:HitboxMesh,
|
||||
pub le_models:Vec<strafesnet_common::model::Model>,
|
||||
}
|
||||
impl Default for PhysicsData{
|
||||
fn default()->Self{
|
||||
@ -939,6 +942,7 @@ impl Default for PhysicsData{
|
||||
models:Default::default(),
|
||||
modes:Default::default(),
|
||||
hitbox_mesh:StyleModifiers::default().calculate_mesh(),
|
||||
le_models:Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -980,6 +984,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().denormalize();
|
||||
@ -1112,6 +1144,7 @@ impl PhysicsData{
|
||||
self.bvh=bvh;
|
||||
self.models=models;
|
||||
self.modes=modes;
|
||||
self.le_models=map.models.clone();
|
||||
//hitbox_mesh is unchanged
|
||||
println!("Physics Objects: {}",model_count);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ 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::{
|
||||
@ -61,6 +62,7 @@ pub struct FrameState{
|
||||
pub body:physics::Body,
|
||||
pub camera:physics::PhysicsCamera,
|
||||
pub time:PhysicsTime,
|
||||
pub debug_model:Option<strafesnet_common::model::ModelId>,
|
||||
}
|
||||
|
||||
pub struct Simulation{
|
||||
@ -77,11 +79,12 @@ impl Simulation{
|
||||
physics,
|
||||
}
|
||||
}
|
||||
pub fn get_frame_state(&self,time:SessionTime)->FrameState{
|
||||
pub fn get_frame_state(&self,time:SessionTime,debug_model:Option<ModelId>)->FrameState{
|
||||
FrameState{
|
||||
body:self.physics.camera_body(),
|
||||
camera:self.physics.camera(),
|
||||
time:self.timer.time(time),
|
||||
debug_model,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -161,6 +164,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 +181,7 @@ impl Session{
|
||||
view_state:ViewState::Play,
|
||||
recording:Default::default(),
|
||||
replays:HashMap::new(),
|
||||
last_ray_hit:None,
|
||||
}
|
||||
}
|
||||
fn clear_recording(&mut self){
|
||||
@ -188,12 +193,30 @@ impl Session{
|
||||
}
|
||||
pub fn get_frame_state(&self,time:SessionTime)->Option<FrameState>{
|
||||
match &self.view_state{
|
||||
ViewState::Play=>Some(self.simulation.get_frame_state(time)),
|
||||
ViewState::Play=>Some(self.simulation.get_frame_state(time,self.last_ray_hit)),
|
||||
ViewState::Replay(bot_id)=>self.replays.get(bot_id).map(|replay|
|
||||
replay.simulation.get_frame_state(time)
|
||||
replay.simulation.get_frame_state(time,None)
|
||||
),
|
||||
}
|
||||
}
|
||||
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;
|
||||
if let Some(model_id)=model_id{
|
||||
if let Some(model)=self.geometry_shared.le_models.get(model_id.get() as usize){
|
||||
println!("{}",model.debug_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn user_settings(&self)->&UserSettings{
|
||||
&self.user_settings
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ fn add_brush<'a>(
|
||||
origin:vbsp::Vector,
|
||||
rendercolor:vbsp::Color,
|
||||
attributes:attr::CollisionAttributesId,
|
||||
debug_info:model::DebugInfo,
|
||||
){
|
||||
let transform=integer::Planar64Affine3::from_translation(
|
||||
valve_transform(origin.into())
|
||||
@ -59,7 +60,7 @@ fn add_brush<'a>(
|
||||
Ok(mesh_id)=>{
|
||||
let mesh=model::MeshId::new(mesh_id);
|
||||
world_models.push(
|
||||
model::Model{mesh,attributes,transform,color}
|
||||
model::Model{mesh,attributes,transform,color,debug_info}
|
||||
);
|
||||
},
|
||||
Err(e)=>{
|
||||
@ -70,7 +71,7 @@ fn add_brush<'a>(
|
||||
_=>{
|
||||
let mesh=mesh_deferred_loader.acquire_mesh_id(model);
|
||||
prop_models.push(
|
||||
model::Model{mesh,attributes,transform,color}
|
||||
model::Model{mesh,attributes,transform,color,debug_info}
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -139,6 +140,7 @@ pub fn convert<'a>(
|
||||
valve_transform(prop.origin.into()),
|
||||
),
|
||||
color:glam::Vec4::ONE,
|
||||
debug_info:model::DebugInfo::Prop,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
@ -207,54 +209,214 @@ pub fn convert<'a>(
|
||||
attributes:ATTRIBUTE_DECORATION,
|
||||
transform:integer::Planar64Affine3::IDENTITY,
|
||||
color:glam::Vec4::W,
|
||||
debug_info:model::DebugInfo::World,
|
||||
});
|
||||
|
||||
// THE CUBE OF DESTINY
|
||||
let destination_mesh_id=model::MeshId::new(world_meshes.len() as u32);
|
||||
world_meshes.push(crate::brush::unit_cube());
|
||||
|
||||
const WHITE:vbsp::Color=vbsp::Color{r:255,g:255,b:255};
|
||||
const ENTITY_ATTRIBUTE:gameplay_attributes::CollisionAttributesId=ATTRIBUTE_DECORATION;
|
||||
const ENTITY_TRIGGER_ATTRIBUTE:gameplay_attributes::CollisionAttributesId=ATTRIBUTE_INTERSECT_DEFAULT;
|
||||
for raw_ent in &bsp.entities{
|
||||
let debug_info=match model::EntityInfo::new(raw_ent.properties()){
|
||||
Ok(entity_info)=>model::DebugInfo::Entity(entity_info),
|
||||
Err(_)=>{
|
||||
println!("EntityInfoError");
|
||||
model::DebugInfo::World
|
||||
},
|
||||
};
|
||||
macro_rules! ent_brush_default{
|
||||
($entity:ident)=>{
|
||||
add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,$entity.model,$entity.origin,$entity.rendercolor,ENTITY_ATTRIBUTE,debug_info)
|
||||
};
|
||||
} macro_rules! ent_brush_prop{
|
||||
($entity:ident)=>{
|
||||
add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,$entity.model,$entity.origin,WHITE,ENTITY_ATTRIBUTE,debug_info)
|
||||
};
|
||||
}
|
||||
macro_rules! ent_brush_trigger{
|
||||
($entity:ident)=>{
|
||||
add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,$entity.model,$entity.origin,WHITE,ENTITY_TRIGGER_ATTRIBUTE,debug_info)
|
||||
};
|
||||
}
|
||||
match raw_ent.parse(){
|
||||
Ok(Entity::Cycler(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::EnvSprite(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncBreakable(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncBrush(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncButton(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncDoor(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncDoorRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncIllusionary(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncMonitor(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncMovelinear(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncPhysbox(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncPhysboxMultiplayer(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncRotButton(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncTracktrain(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncTrain(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncWall(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncWallToggle(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::FuncWaterAnalog(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor.unwrap_or(WHITE),ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::PropDoorRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::PropDynamic(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::PropDynamicOverride(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::PropPhysics(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::PropPhysicsMultiplayer(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::PropPhysicsOverride(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::PropRagdoll(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerGravity(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerHurt(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerLook(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerMultiple(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerOnce(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerProximity(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerPush(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerSoundscape(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerTeleport(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerVphysicsMotion(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::TriggerWind(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
|
||||
Ok(Entity::InfoPlayerCounterterrorist(spawn))=>{
|
||||
found_spawn=Some(valve_transform(spawn.origin.into()));
|
||||
},
|
||||
Ok(Entity::InfoPlayerTerrorist(spawn))=>{
|
||||
found_spawn=Some(valve_transform(spawn.origin.into()));
|
||||
},
|
||||
Ok(Entity::AmbientGeneric(_ambient_generic))=>(),
|
||||
Ok(Entity::Cycler(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::EnvBeam(_env_beam))=>(),
|
||||
Ok(Entity::EnvBubbles(_env_bubbles))=>(),
|
||||
Ok(Entity::EnvDetailController(_env_detail_controller))=>(),
|
||||
Ok(Entity::EnvEmbers(_env_embers))=>(),
|
||||
Ok(Entity::EnvEntityMaker(_env_entity_maker))=>(),
|
||||
Ok(Entity::EnvExplosion(_env_explosion))=>(),
|
||||
Ok(Entity::EnvFade(_env_fade))=>(),
|
||||
Ok(Entity::EnvFire(_env_fire))=>(),
|
||||
Ok(Entity::EnvFireTrail(_env_fire_trail))=>(),
|
||||
Ok(Entity::EnvFiresource(_env_firesource))=>(),
|
||||
Ok(Entity::EnvFogController(_env_fog_controller))=>(),
|
||||
Ok(Entity::EnvHudhint(_env_hudhint))=>(),
|
||||
Ok(Entity::EnvLaser(_env_laser))=>(),
|
||||
Ok(Entity::EnvLightglow(_env_lightglow))=>(),
|
||||
Ok(Entity::EnvPhysexplosion(_env_physexplosion))=>(),
|
||||
Ok(Entity::EnvProjectedtexture(_env_projectedtexture))=>(),
|
||||
Ok(Entity::EnvScreenoverlay(_env_screenoverlay))=>(),
|
||||
Ok(Entity::EnvShake(_env_shake))=>(),
|
||||
Ok(Entity::EnvShooter(_env_shooter))=>(),
|
||||
Ok(Entity::EnvSmokestack(_env_smokestack))=>(),
|
||||
Ok(Entity::EnvSoundscape(_env_soundscape))=>(),
|
||||
Ok(Entity::EnvSoundscapeProxy(_env_soundscape_proxy))=>(),
|
||||
Ok(Entity::EnvSoundscapeTriggerable(_env_soundscape_triggerable))=>(),
|
||||
Ok(Entity::EnvSpark(_env_spark))=>(),
|
||||
Ok(Entity::EnvSprite(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::EnvSpritetrail(_env_spritetrail))=>(),
|
||||
Ok(Entity::EnvSteam(_env_steam))=>(),
|
||||
Ok(Entity::EnvSun(_env_sun))=>(),
|
||||
Ok(Entity::EnvTonemapController(_env_tonemap_controller))=>(),
|
||||
Ok(Entity::EnvWind(_env_wind))=>(),
|
||||
// trigger_teleport.filtername probably has to do with one of these
|
||||
Ok(Entity::FilterActivatorClass(_filter_activator_class))=>(),
|
||||
Ok(Entity::FilterActivatorName(_filter_activator_name))=>(),
|
||||
Ok(Entity::FilterDamageType(_filter_damage_type))=>(),
|
||||
Ok(Entity::FilterMulti(_filter_multi))=>(),
|
||||
Ok(Entity::FuncAreaportal(_func_areaportal))=>(),
|
||||
Ok(Entity::FuncAreaportalwindow(_func_areaportalwindow))=>(),
|
||||
Ok(Entity::FuncBombTarget(_func_bomb_target))=>(),
|
||||
Ok(Entity::FuncBreakable(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncBreakableSurf(_func_breakable_surf))=>(),
|
||||
Ok(Entity::FuncBrush(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncButton(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncBuyzone(_func_buyzone))=>(),
|
||||
Ok(Entity::FuncClipVphysics(_func_clip_vphysics))=>(),
|
||||
Ok(Entity::FuncConveyor(_func_conveyor))=>(),
|
||||
// FuncDoor is Platform
|
||||
Ok(Entity::FuncDoor(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncDoorRotating(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncDustcloud(_func_dustcloud))=>(),
|
||||
Ok(Entity::FuncDustmotes(_func_dustmotes))=>(),
|
||||
Ok(Entity::FuncFishPool(_func_fish_pool))=>(),
|
||||
Ok(Entity::FuncFootstepControl(_func_footstep_control))=>(),
|
||||
Ok(Entity::FuncHostageRescue(_func_hostage_rescue))=>(),
|
||||
Ok(Entity::FuncIllusionary(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION,debug_info),
|
||||
Ok(Entity::FuncLod(_func_lod))=>(),
|
||||
Ok(Entity::FuncMonitor(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncMovelinear(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncOccluder(_func_occluder))=>(),
|
||||
Ok(Entity::FuncPhysbox(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncPhysboxMultiplayer(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncPrecipitation(_func_precipitation))=>(),
|
||||
Ok(Entity::FuncRotButton(brush))=>ent_brush_prop!(brush),
|
||||
Ok(Entity::FuncRotating(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncSmokevolume(_func_smokevolume))=>(),
|
||||
Ok(Entity::FuncTracktrain(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncTrain(brush))=>ent_brush_default!(brush),
|
||||
Ok(Entity::FuncWall(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ENTITY_ATTRIBUTE,debug_info),
|
||||
Ok(Entity::FuncWallToggle(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ENTITY_ATTRIBUTE,debug_info),
|
||||
Ok(Entity::FuncWaterAnalog(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor.unwrap_or(WHITE),ENTITY_ATTRIBUTE,debug_info),
|
||||
Ok(Entity::GamePlayerEquip(_game_player_equip))=>(),
|
||||
Ok(Entity::GameText(_game_text))=>(),
|
||||
Ok(Entity::GameUi(_game_ui))=>(),
|
||||
Ok(Entity::GameWeaponManager(_game_weapon_manager))=>(),
|
||||
Ok(Entity::HostageEntity(_hostage_entity))=>(),
|
||||
Ok(Entity::InfoCameraLink(_info_camera_link))=>(),
|
||||
Ok(Entity::InfoLadder(_info_ladder))=>(),
|
||||
Ok(Entity::InfoLightingRelative(_info_lighting_relative))=>(),
|
||||
Ok(Entity::InfoMapParameters(_info_map_parameters))=>(),
|
||||
Ok(Entity::InfoNode(_info_node))=>(),
|
||||
Ok(Entity::InfoNodeHint(_info_node_hint))=>(),
|
||||
Ok(Entity::InfoParticleSystem(_info_particle_system))=>(),
|
||||
Ok(Entity::InfoPlayerCounterterrorist(spawn))=>found_spawn=Some(spawn.origin),
|
||||
Ok(Entity::InfoPlayerLogo(_info_player_logo))=>(),
|
||||
Ok(Entity::InfoPlayerStart(_info_player_start))=>(),
|
||||
Ok(Entity::InfoPlayerTerrorist(spawn))=>found_spawn=Some(spawn.origin),
|
||||
Ok(Entity::InfoTarget(_info_target))=>(),
|
||||
// InfoTeleportDestination is Spawn#
|
||||
Ok(Entity::InfoTeleportDestination(_info_teleport_destination))=>(),
|
||||
Ok(Entity::Infodecal(_infodecal))=>(),
|
||||
Ok(Entity::KeyframeRope(_keyframe_rope))=>(),
|
||||
Ok(Entity::Light(_light))=>(),
|
||||
Ok(Entity::LightEnvironment(_light_environment))=>(),
|
||||
Ok(Entity::LightSpot(_light_spot))=>(),
|
||||
Ok(Entity::LogicAuto(_logic_auto))=>(),
|
||||
Ok(Entity::LogicBranch(_logic_branch))=>(),
|
||||
Ok(Entity::LogicCase(_logic_case))=>(),
|
||||
Ok(Entity::LogicCompare(_logic_compare))=>(),
|
||||
Ok(Entity::LogicMeasureMovement(_logic_measure_movement))=>(),
|
||||
Ok(Entity::LogicRelay(_logic_relay))=>(),
|
||||
Ok(Entity::LogicTimer(_logic_timer))=>(),
|
||||
Ok(Entity::MathCounter(_math_counter))=>(),
|
||||
Ok(Entity::MoveRope(_move_rope))=>(),
|
||||
Ok(Entity::PathTrack(_path_track))=>(),
|
||||
Ok(Entity::PhysBallsocket(_phys_ballsocket))=>(),
|
||||
Ok(Entity::PhysConstraint(_phys_constraint))=>(),
|
||||
Ok(Entity::PhysConstraintsystem(_phys_constraintsystem))=>(),
|
||||
Ok(Entity::PhysHinge(_phys_hinge))=>(),
|
||||
Ok(Entity::PhysKeepupright(_phys_keepupright))=>(),
|
||||
Ok(Entity::PhysLengthconstraint(_phys_lengthconstraint))=>(),
|
||||
Ok(Entity::PhysPulleyconstraint(_phys_pulleyconstraint))=>(),
|
||||
Ok(Entity::PhysRagdollconstraint(_phys_ragdollconstraint))=>(),
|
||||
Ok(Entity::PhysRagdollmagnet(_phys_ragdollmagnet))=>(),
|
||||
Ok(Entity::PhysThruster(_phys_thruster))=>(),
|
||||
Ok(Entity::PhysTorque(_phys_torque))=>(),
|
||||
Ok(Entity::PlayerSpeedmod(_player_speedmod))=>(),
|
||||
Ok(Entity::PlayerWeaponstrip(_player_weaponstrip))=>(),
|
||||
Ok(Entity::PointCamera(_point_camera))=>(),
|
||||
Ok(Entity::PointClientcommand(_point_clientcommand))=>(),
|
||||
Ok(Entity::PointDevshotCamera(_point_devshot_camera))=>(),
|
||||
Ok(Entity::PointServercommand(_point_servercommand))=>(),
|
||||
Ok(Entity::PointSpotlight(_point_spotlight))=>(),
|
||||
Ok(Entity::PointSurroundtest(_point_surroundtest))=>(),
|
||||
Ok(Entity::PointTemplate(_point_template))=>(),
|
||||
Ok(Entity::PointTesla(_point_tesla))=>(),
|
||||
Ok(Entity::PointViewcontrol(_point_viewcontrol))=>(),
|
||||
Ok(Entity::PropDoorRotating(brush))=>ent_brush_prop!(brush),
|
||||
Ok(Entity::PropDynamic(brush))=>ent_brush_prop!(brush),
|
||||
Ok(Entity::PropDynamicOverride(brush))=>ent_brush_prop!(brush),
|
||||
Ok(Entity::PropPhysics(brush))=>ent_brush_prop!(brush),
|
||||
Ok(Entity::PropPhysicsMultiplayer(brush))=>ent_brush_prop!(brush),
|
||||
Ok(Entity::PropPhysicsOverride(brush))=>ent_brush_prop!(brush),
|
||||
Ok(Entity::PropRagdoll(brush))=>ent_brush_prop!(brush),
|
||||
Ok(Entity::ShadowControl(_shadow_control))=>(),
|
||||
Ok(Entity::SkyCamera(_sky_camera))=>(),
|
||||
Ok(Entity::TriggerGravity(brush))=>ent_brush_trigger!(brush),
|
||||
Ok(Entity::TriggerHurt(brush))=>ent_brush_trigger!(brush),
|
||||
Ok(Entity::TriggerLook(brush))=>ent_brush_trigger!(brush),
|
||||
Ok(Entity::TriggerMultiple(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ENTITY_TRIGGER_ATTRIBUTE,debug_info),
|
||||
Ok(Entity::TriggerOnce(brush))=>ent_brush_trigger!(brush),
|
||||
Ok(Entity::TriggerProximity(brush))=>ent_brush_trigger!(brush),
|
||||
// TriggerPush is booster
|
||||
Ok(Entity::TriggerPush(brush))=>ent_brush_trigger!(brush),
|
||||
Ok(Entity::TriggerSoundscape(brush))=>ent_brush_trigger!(brush),
|
||||
// TriggerTeleport is Trigger#
|
||||
Ok(Entity::TriggerTeleport(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ENTITY_TRIGGER_ATTRIBUTE,debug_info),
|
||||
Ok(Entity::TriggerVphysicsMotion(brush))=>ent_brush_trigger!(brush),
|
||||
Ok(Entity::TriggerWind(brush))=>ent_brush_trigger!(brush),
|
||||
Ok(Entity::WaterLodControl(_water_lod_control))=>(),
|
||||
Ok(Entity::WeaponAk47(_weapon_ak47))=>(),
|
||||
Ok(Entity::WeaponAwp(_weapon_awp))=>(),
|
||||
Ok(Entity::WeaponDeagle(_weapon_deagle))=>(),
|
||||
Ok(Entity::WeaponElite(_weapon_elite))=>(),
|
||||
Ok(Entity::WeaponFamas(_weapon_famas))=>(),
|
||||
Ok(Entity::WeaponFiveseven(_weapon_fiveseven))=>(),
|
||||
Ok(Entity::WeaponFlashbang(_weapon_flashbang))=>(),
|
||||
Ok(Entity::WeaponG3sg1(_weapon_g3sg1))=>(),
|
||||
Ok(Entity::WeaponGlock(_weapon_glock))=>(),
|
||||
Ok(Entity::WeaponHegrenade(_weapon_hegrenade))=>(),
|
||||
Ok(Entity::WeaponKnife(_weapon_knife))=>(),
|
||||
Ok(Entity::WeaponM249(_weapon_m249))=>(),
|
||||
Ok(Entity::WeaponM3(_weapon_m3))=>(),
|
||||
Ok(Entity::WeaponM4a1(_weapon_m4a1))=>(),
|
||||
Ok(Entity::WeaponMac10(_weapon_mac10))=>(),
|
||||
Ok(Entity::WeaponP228(_weapon_p228))=>(),
|
||||
Ok(Entity::WeaponP90(_weapon_p90))=>(),
|
||||
Ok(Entity::WeaponScout(_weapon_scout))=>(),
|
||||
Ok(Entity::WeaponSg550(_weapon_sg550))=>(),
|
||||
Ok(Entity::WeaponSmokegrenade(_weapon_smokegrenade))=>(),
|
||||
Ok(Entity::WeaponTmp(_weapon_tmp))=>(),
|
||||
Ok(Entity::WeaponUmp45(_weapon_ump45))=>(),
|
||||
Ok(Entity::WeaponUsp(_weapon_usp))=>(),
|
||||
Ok(Entity::WeaponXm1014(_weapon_xm1014))=>(),
|
||||
Ok(Entity::Worldspawn(_worldspawn))=>(),
|
||||
Err(e)=>{
|
||||
println!("Bsp Entity parse error: {e}");
|
||||
},
|
||||
@ -290,6 +452,13 @@ pub fn convert<'a>(
|
||||
Ok(mesh)=>{
|
||||
let mesh_id=model::MeshId::new(world_meshes.len() as u32);
|
||||
world_meshes.push(mesh);
|
||||
let sides={
|
||||
let brush_start_idx=brush.brush_side as usize;
|
||||
let sides_range=brush_start_idx..brush_start_idx+brush.num_brush_sides as usize;
|
||||
bsp.brush_sides[sides_range].iter().filter_map(|side|bsp.texture_info(side.texture_info as usize)).map(|texture_info|{
|
||||
texture_info.flags
|
||||
}).collect()
|
||||
};
|
||||
world_models.push(model::Model{
|
||||
mesh:mesh_id,
|
||||
attributes,
|
||||
@ -298,6 +467,7 @@ pub fn convert<'a>(
|
||||
integer::vec3::ZERO,
|
||||
),
|
||||
color:glam::Vec4::ONE,
|
||||
debug_info:model::DebugInfo::Brush(model::BrushInfo{flags:brush.flags,sides}),
|
||||
});
|
||||
},
|
||||
Err(e)=>println!("Brush mesh error: {e}"),
|
||||
@ -306,16 +476,14 @@ pub fn convert<'a>(
|
||||
|
||||
let mut modes_list=Vec::new();
|
||||
if let Some(spawn_point)=found_spawn{
|
||||
// create a new mesh
|
||||
let mesh_id=model::MeshId::new(world_meshes.len() as u32);
|
||||
world_meshes.push(crate::brush::unit_cube());
|
||||
// create a new model
|
||||
let model_id=model::ModelId::new(world_models.len() as u32);
|
||||
world_models.push(model::Model{
|
||||
mesh:mesh_id,
|
||||
mesh:destination_mesh_id,
|
||||
attributes:ATTRIBUTE_INTERSECT_DEFAULT,
|
||||
transform:integer::Planar64Affine3::from_translation(spawn_point),
|
||||
transform:integer::Planar64Affine3::from_translation(valve_transform(spawn_point.into())),
|
||||
color:glam::Vec4::W,
|
||||
debug_info:model::DebugInfo::World,
|
||||
});
|
||||
|
||||
let first_stage=Stage::empty(model_id);
|
||||
|
@ -17,3 +17,4 @@ linear_ops = { version = "0.1.0", path = "../linear_ops", registry = "strafesnet
|
||||
ratio_ops = { version = "0.1.0", path = "../ratio_ops", registry = "strafesnet" }
|
||||
glam = "0.30.0"
|
||||
id = { version = "0.1.0", registry = "strafesnet" }
|
||||
vbsp = "0.8.0"
|
||||
|
@ -208,9 +208,87 @@ impl MeshBuilder{
|
||||
|
||||
#[derive(Debug,Clone,Copy,Hash,id::Id,Eq,PartialEq)]
|
||||
pub struct ModelId(u32);
|
||||
#[derive(Clone)]
|
||||
pub struct Model{
|
||||
pub mesh:MeshId,
|
||||
pub attributes:gameplay_attributes::CollisionAttributesId,
|
||||
pub color:Color4,//transparency is in here
|
||||
pub transform:Planar64Affine3,
|
||||
pub debug_info:DebugInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone)]
|
||||
pub enum DebugInfo{
|
||||
World,
|
||||
Prop,
|
||||
Brush(BrushInfo),
|
||||
Entity(EntityInfo),
|
||||
}
|
||||
impl std::fmt::Display for DebugInfo{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
match self{
|
||||
DebugInfo::World=>write!(f,"World"),
|
||||
DebugInfo::Prop=>write!(f,"Prop"),
|
||||
DebugInfo::Brush(brush_info)=>brush_info.fmt(f),
|
||||
DebugInfo::Entity(entity_info)=>entity_info.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone)]
|
||||
pub struct BrushInfo{
|
||||
pub flags:vbsp::BrushFlags,
|
||||
pub sides:Vec<vbsp::TextureFlags>,
|
||||
}
|
||||
impl std::fmt::Display for BrushInfo{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
let noice=self.flags.iter_names().filter_map(|(name,flags)|{
|
||||
(flags.bits()!=0).then(||name)
|
||||
}).collect::<Vec<&str>>().join("|");
|
||||
writeln!(f,"brush_info.flags={noice}")?;
|
||||
for (i,side) in self.sides.iter().enumerate(){
|
||||
let noice_string=side.iter_names().filter_map(|(name,flags)|{
|
||||
(flags.bits()!=0).then(||name)
|
||||
}).collect::<Vec<&str>>().join("|");
|
||||
writeln!(f,"brush_info.sides[{i}]={noice_string}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone)]
|
||||
pub struct EntityInfo{
|
||||
pub classname:Box<str>,
|
||||
pub properties:Vec<(Box<str>,Box<str>)>,
|
||||
}
|
||||
pub enum EntityInfoError{
|
||||
MissingClassname,
|
||||
}
|
||||
impl EntityInfo{
|
||||
pub fn new<'a>(iter:impl IntoIterator<Item=(&'a str,&'a str)>)->Result<Self,EntityInfoError>{
|
||||
let mut classname:Option<Box<str>>=None;
|
||||
let mut properties:Vec<(Box<str>,Box<str>)>=Vec::new();
|
||||
for (name,value) in iter{
|
||||
match name{
|
||||
"classname"=>classname=Some(value.into()),
|
||||
"hammerid"=>(),
|
||||
_=>properties.push((name.into(),value.into())),
|
||||
}
|
||||
}
|
||||
properties.sort_by(|(n0,_),(n1,_)|n0.cmp(n1));
|
||||
let Some(classname)=classname else{
|
||||
return Err(EntityInfoError::MissingClassname);
|
||||
};
|
||||
Ok(EntityInfo{classname,properties})
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for EntityInfo{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
writeln!(f,"struct {}{{",self.classname)?;
|
||||
for (name,value) in &self.properties{
|
||||
writeln!(f,"\t{name}:{value},")?;
|
||||
}
|
||||
write!(f,"}}")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -250,6 +250,7 @@ impl Into<strafesnet_common::model::Model> for Model{
|
||||
]),
|
||||
strafesnet_common::integer::vec3::raw_xyz(_9,_a,_b)
|
||||
),
|
||||
debug_info:strafesnet_common::model::DebugInfo::World,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
})
|
||||
}
|
||||
|
@ -86,6 +86,29 @@ fn vs_entity_texture(
|
||||
return result;
|
||||
}
|
||||
|
||||
@group(1)
|
||||
@binding(0)
|
||||
var<uniform> model_instance: ModelInstance;
|
||||
|
||||
struct DebugEntityOutput {
|
||||
@builtin(position) position: vec4<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
@location(2) view: vec3<f32>,
|
||||
};
|
||||
|
||||
@vertex
|
||||
fn vs_debug(
|
||||
@location(0) pos: vec3<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
) -> DebugEntityOutput {
|
||||
var position: vec4<f32> = model_instance.transform * vec4<f32>(pos, 1.0);
|
||||
var result: DebugEntityOutput;
|
||||
result.normal = model_instance.normal_transform * normal;
|
||||
result.view = position.xyz - camera.view_inv[3].xyz;//col(3)
|
||||
result.position = camera.proj * camera.view * position;
|
||||
return result;
|
||||
}
|
||||
|
||||
//group 2 is the skybox texture
|
||||
@group(1)
|
||||
@binding(0)
|
||||
@ -110,3 +133,8 @@ fn fs_entity_texture(vertex: EntityOutputTexture) -> @location(0) vec4<f32> {
|
||||
let reflected_color = textureSample(cube_texture, cube_sampler, reflected).rgb;
|
||||
return mix(vec4<f32>(vec3<f32>(0.05) + 0.2 * reflected_color,1.0),mix(vertex.model_color,vec4<f32>(fragment_color.rgb,1.0),fragment_color.a),0.5+0.5*abs(d));
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_debug(vertex: DebugEntityOutput) -> @location(0) vec4<f32> {
|
||||
return model_instance.color;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user