Compare commits

..

23 Commits

Author SHA1 Message Date
a6dd7f3111 cast bool to int 2023-10-20 13:21:16 -07:00
a6c51654e5 rustge 2023-10-20 00:30:35 -07:00
abbab00eea rewrite 2023-10-18 20:55:05 -07:00
99db653c14 why not it work??? 2023-10-18 20:55:05 -07:00
e9ba0c694c use InputInstruction to drastically reduce the size of mouse instructions 2023-10-18 20:55:05 -07:00
261854cfa5 write_input_instruction 2023-10-18 20:55:05 -07:00
e3eb040675 ideas 2023-10-18 19:10:30 -07:00
fdb8f93b0b how could I forger shaders 2023-10-18 19:10:30 -07:00
a2ce319cb2 modify bot header to not depend on ownership of all blocks 2023-10-18 19:10:30 -07:00
a79157da88 sniffa 2023-10-18 19:10:30 -07:00
7be7d2c0df literally into_worker 2023-10-18 18:21:11 -07:00
cb6b0acd44 TODO: need real functions 2023-10-18 18:21:11 -07:00
cbcf047c3f basic wormholes (no velocity or camera transformation) 2023-10-18 18:21:11 -07:00
6e5de4aa46 overhaul TempIndexedAttributes + add Wormhole indexing 2023-10-18 18:21:11 -07:00
cc776e7cb4 model_id is usize + PhysicsModels struct 2023-10-18 18:21:11 -07:00
5a66ac46b9 functionate that damn code block 2023-10-18 18:21:11 -07:00
38f6e1df3f overhaul attributes 2023-10-18 18:21:11 -07:00
849dcf98f7 overhaul StyleModifiers 2023-10-18 18:21:11 -07:00
d04d1be27e overhaul WalkState + implement ladders 2023-10-18 18:21:11 -07:00
35bfd1d366 implement simulate_move_rotation 2023-10-18 18:21:11 -07:00
586bf8ce89 unpub a bunch of physics stuff 2023-10-18 18:21:11 -07:00
127b205401 implement MoveState + TouchingState 2023-10-18 18:21:11 -07:00
4f596ca5d7 unneeded mut 2023-10-18 16:30:02 -07:00
4 changed files with 174 additions and 48 deletions

View File

@@ -11,6 +11,7 @@ mod model_graphics;
mod zeroes;
mod worker;
mod physics;
mod sniffer;
mod settings;
mod framework;
mod primitives;

View File

@@ -18,9 +18,7 @@ pub enum PhysicsInstruction {
Input(PhysicsInputInstruction),
}
#[derive(Debug)]
pub enum PhysicsInputInstruction {
ReplaceMouse(MouseState,MouseState),
SetNextMouse(MouseState),
pub enum PhysicsInputInstruction{
SetMoveRight(bool),
SetMoveUp(bool),
SetMoveBack(bool),
@@ -29,26 +27,51 @@ pub enum PhysicsInputInstruction {
SetMoveForward(bool),
SetJump(bool),
SetZoom(bool),
ReplaceMouse(MouseState,MouseState),
SetNextMouse(MouseState),
Reset,
Idle,
}
#[derive(Debug)]
#[repr(u32)]
pub enum InputInstruction {
MoveMouse(glam::IVec2),
MoveRight(bool),
MoveUp(bool),
MoveBack(bool),
MoveLeft(bool),
MoveDown(bool),
MoveForward(bool),
Jump(bool),
Zoom(bool),
Reset,
Idle,
MoveRight(bool)=0,
MoveUp(bool)=1,
MoveBack(bool)=2,
MoveLeft(bool)=3,
MoveDown(bool)=4,
MoveForward(bool)=5,
Jump(bool)=6,
Zoom(bool)=7,
MoveMouse(glam::IVec2)=64,
Reset=100,
Idle=127,
//Idle: there were no input events, but the simulation is safe to advance to this timestep
//for interpolation / networking / playback reasons, most playback heads will always want
//to be 1 instruction ahead to generate the next state for interpolation.
}
impl InputInstruction{
pub fn id(&self)->u32{
let parity=match self{
crate::physics::InputInstruction::MoveRight(s)
|crate::physics::InputInstruction::MoveUp(s)
|crate::physics::InputInstruction::MoveBack(s)
|crate::physics::InputInstruction::MoveLeft(s)
|crate::physics::InputInstruction::MoveDown(s)
|crate::physics::InputInstruction::MoveForward(s)
|crate::physics::InputInstruction::Jump(s)
|crate::physics::InputInstruction::Zoom(s)=>(*s as u32)<<31,
crate::physics::InputInstruction::MoveMouse(_)
|crate::physics::InputInstruction::Reset
|crate::physics::InputInstruction::Idle=>0u32,
};
self.discriminant()|parity
}
pub fn discriminant(&self)->u32{
//from documentation for std::mem::discriminant(&self)
unsafe{*<*const _>::from(self).cast::<u32>()}
}
}
#[derive(Clone,Hash)]
pub struct Body {
position: Planar64Vec3,//I64 where 2^32 = 1 u
@@ -57,38 +80,6 @@ pub struct Body {
time:Time,//nanoseconds x xxxxD!
}
pub enum MoveRestriction {
Air,
Water,
Ground,
Ladder,//multiple ladders how
}
/*
enum InputInstruction {
}
struct InputState {
}
impl InputState {
pub fn get_control(&self,control:u32) -> bool {
self.controls&control!=0
}
}
impl crate::instruction::InstructionEmitter<InputInstruction> for InputState{
fn next_instruction(&self, time_limit:crate::body::Time) -> Option<TimedInstruction<InputInstruction>> {
//this is polled by PhysicsState for actions like Jump
//no, it has to be the other way around. physics is run up until the jump instruction, and then the jump instruction is pushed.
self.queue.get(0)
}
}
impl crate::instruction::InstructionConsumer<InputInstruction> for InputState{
fn process_instruction(&mut self,ins:TimedInstruction<InputInstruction>){
//add to queue
self.queue.push(ins);
}
}
*/
//hey dumbass just use a delta
#[derive(Clone,Debug)]
pub struct MouseState {
@@ -1317,6 +1308,7 @@ impl crate::instruction::InstructionEmitter<PhysicsInstruction> for PhysicsState
//JUST POLLING!!! NO MUTATION
let mut collector = crate::instruction::InstructionCollector::new(time_limit);
//check for collision stop instructions with curent contacts
//TODO: make this into a touching.next_instruction(&mut collector) member function
for (_,collision_data) in &self.touching.contacts {
collector.collect(self.predict_collision_end(self.time,time_limit,collision_data));
}
@@ -1368,7 +1360,6 @@ fn run_teleport_behaviour(teleport_behaviour:&Option<crate::model::TeleportBehav
}
},
Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{
//telefart
let origin_model=model;
let destination_model=models.get_wormhole_model(wormhole.destination_model_id)?;
//ignore the transform for now

134
src/sniffer.rs Normal file
View File

@@ -0,0 +1,134 @@
//file format "sniff"
/* spec
//begin global header
//global metadata (32 bytes)
b"SNFB"
u32 format_version
u64 priming_bytes
//how many bytes of the file must be read to guarantee all of the expected
//format-specific metadata is available to facilitate streaming the remaining contents
//used by the database to guarantee that it serves at least the bare minimum
u128 resource_uuid
//identifies the file from anywhere for any other file
//global block layout (variable size)
u64 num_blocks
for block_id in 0..num_blocks{
u64 first_byte
}
//end global header
//begin blocks
//each block is compressed with zstd or gz or something
*/
/* block types
BLOCK_MAP_HEADER:
StyleInfoOverrides style_info_overrides
//bvh goes here
u64 num_nodes
//node 0 parent node is implied to be None
for node_id in 1..num_nodes{
u64 parent_node
}
//block 0 is the current block, not part of the map data
u64 num_spacial_blocks
for block_id in 1..num_spacial_blocks{
u64 node_id
u64 block_id
Aabb block_extents
}
//ideally spacial blocks are sorted from distance to start zone
//texture blocks are inserted before the first spacial block they are used in
BLOCK_MAP_RESOURCE:
//an individual one of the following:
- model (IndexedModel)
- shader (compiled SPIR-V)
- image (JpegXL)
- sound (Opus)
- video (AV1)
- animation (Trey thing)
BLOCK_MAP_OBJECT:
//an individual one of the following:
- model instance
- located resource
//for a list of resources, parse the object.
BLOCK_BOT_HEADER:
u128 map_resource_uuid //which map is this bot running
u128 time_resource_uuid //resource database time
//don't include style info in bot header because it's in the physics state
//blocks are laid out in chronological order, but indices may jump around.
u64 num_segments
for _ in 0..num_segments{
i64 time //physics_state timestamp
u64 block_id
}
BLOCK_BOT_SEGMENT:
//format version indicates what version of these structures to use
PhysicsState physics_state
//to read, greedily decode instructions until eof
loop{
//delta encode as much as possible (time,mousepos)
//strafe ticks are implied
//physics can be implied in an input-only bot file
TimedInstruction<PhysicsInstruction> instruction
}
BLOCK_DEMO_HEADER:
//timeline of loading maps, player equipment, bots
*/
struct InputInstructionCodecState{
mouse_pos:glam::IVec2,
time:crate::integer::Time,
}
//8B - 12B
impl InputInstructionCodecState{
pub fn encode(&mut self,ins:&crate::instruction::TimedInstruction<crate::physics::InputInstruction>)->([u8;12],usize){
let dt=ins.time-self.time;
self.time=ins.time;
let mut data=[0u8;12];
[data[0],data[1],data[2],data[3]]=(dt.nanos() as u32).to_le_bytes();//4B
//instruction id packed with game control parity bit. This could be 1 byte but it ruins the alignment
[data[4],data[5],data[6],data[7]]=ins.instruction.id().to_le_bytes();//4B
match &ins.instruction{
&crate::physics::InputInstruction::MoveMouse(m)=>{//4B
let dm=m-self.mouse_pos;
[data[8],data[9]]=(dm.x as i16).to_le_bytes();
[data[10],data[11]]=(dm.y as i16).to_le_bytes();
self.mouse_pos=m;
(data,12)
},
//0B
crate::physics::InputInstruction::MoveRight(_)
|crate::physics::InputInstruction::MoveUp(_)
|crate::physics::InputInstruction::MoveBack(_)
|crate::physics::InputInstruction::MoveLeft(_)
|crate::physics::InputInstruction::MoveDown(_)
|crate::physics::InputInstruction::MoveForward(_)
|crate::physics::InputInstruction::Jump(_)
|crate::physics::InputInstruction::Zoom(_)
|crate::physics::InputInstruction::Reset
|crate::physics::InputInstruction::Idle=>(data,8),
}
}
}
//everything must be 4 byte aligned, it's all going to be compressed so don't think too had about saving less than 4 bytes
//TODO: Omit (mouse only?) instructions that don't surround an actual physics instruction
fn write_input_instruction<W:std::io::Write>(state:&mut InputInstructionCodecState,w:&mut W,ins:&crate::instruction::TimedInstruction<crate::physics::InputInstruction>)->Result<usize,std::io::Error>{
//TODO: insert idle instruction if gap is over u32 nanoseconds
//TODO: don't write idle instructions
//OR: end the data block! the full state at the start of the next block will contain an absolute timestamp
let (data,size)=state.encode(ins);
w.write(&data[0..size])//8B-12B
}

View File

@@ -6,7 +6,7 @@ pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64) -> Vec<Planar64>{
if a2==Planar64::ZERO{
return zeroes1(a0, a1);
}
let mut radicand=a1.get() as i128*a1.get() as i128-a2.get() as i128*a0.get() as i128*4;
let radicand=a1.get() as i128*a1.get() as i128-a2.get() as i128*a0.get() as i128*4;
if 0<radicand {
//start with f64 sqrt
let planar_radicand=Planar64::raw(unsafe{(radicand as f64).sqrt().to_int_unchecked()});