forked from StrafesNET/strafe-client
wip
This commit is contained in:
parent
480cd0e3be
commit
43181c4c3f
@ -1,6 +1,5 @@
|
|||||||
use strafesnet_common::integer;
|
use strafesnet_common::{model,integer};
|
||||||
|
|
||||||
mod model;
|
|
||||||
mod setup;
|
mod setup;
|
||||||
mod window;
|
mod window;
|
||||||
mod worker;
|
mod worker;
|
||||||
|
321
src/model.rs
321
src/model.rs
@ -1,321 +0,0 @@
|
|||||||
use strafesnet_common::integer::{Time,Planar64,Planar64Vec3,Planar64Affine3};
|
|
||||||
pub type TextureCoordinate=glam::Vec2;
|
|
||||||
pub type Color4=glam::Vec4;
|
|
||||||
#[derive(Clone,Hash,PartialEq,Eq)]
|
|
||||||
pub struct IndexedVertex{
|
|
||||||
pub pos:u32,
|
|
||||||
pub tex:u32,
|
|
||||||
pub normal:u32,
|
|
||||||
pub color:u32,
|
|
||||||
}
|
|
||||||
pub struct IndexedPolygon{
|
|
||||||
pub vertices:Vec<u32>,
|
|
||||||
}
|
|
||||||
pub struct IndexedGroup{
|
|
||||||
pub texture:Option<u32>,//RenderPattern? material/texture/shader/flat color
|
|
||||||
pub polys:Vec<IndexedPolygon>,
|
|
||||||
}
|
|
||||||
pub struct IndexedModel{
|
|
||||||
pub unique_pos:Vec<Planar64Vec3>,
|
|
||||||
pub unique_normal:Vec<Planar64Vec3>,
|
|
||||||
pub unique_tex:Vec<TextureCoordinate>,
|
|
||||||
pub unique_color:Vec<Color4>,
|
|
||||||
pub unique_vertices:Vec<IndexedVertex>,
|
|
||||||
pub groups: Vec<IndexedGroup>,
|
|
||||||
pub instances:Vec<ModelInstance>,
|
|
||||||
}
|
|
||||||
pub struct ModelInstance{
|
|
||||||
//pub id:u64,//this does not actually help with map fixes resimulating bots, they must always be resimulated
|
|
||||||
pub transform:Planar64Affine3,
|
|
||||||
pub color:Color4,//transparency is in here
|
|
||||||
pub attributes:CollisionAttributes,
|
|
||||||
pub temp_indexing:Vec<TempIndexedAttributes>,
|
|
||||||
}
|
|
||||||
impl std::default::Default for ModelInstance{
|
|
||||||
fn default() -> Self {
|
|
||||||
Self{
|
|
||||||
color:Color4::ONE,
|
|
||||||
transform:Default::default(),
|
|
||||||
attributes:Default::default(),
|
|
||||||
temp_indexing:Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub struct IndexedModelInstances{
|
|
||||||
pub textures:Vec<String>,//RenderPattern
|
|
||||||
pub models:Vec<IndexedModel>,
|
|
||||||
//may make this into an object later.
|
|
||||||
pub modes:Vec<ModeDescription>,
|
|
||||||
pub spawn_point:Planar64Vec3,
|
|
||||||
}
|
|
||||||
//stage description referencing flattened ids is spooky, but the map loading is meant to be deterministic.
|
|
||||||
pub struct ModeDescription{
|
|
||||||
//TODO: put "default" style modifiers in mode
|
|
||||||
//pub style:StyleModifiers,
|
|
||||||
pub start:usize,//start=model_id
|
|
||||||
pub spawns:Vec<usize>,//spawns[spawn_id]=model_id
|
|
||||||
pub spawn_from_stage_id:std::collections::HashMap::<u32,usize>,
|
|
||||||
pub ordered_checkpoint_from_checkpoint_id:std::collections::HashMap::<u32,usize>,
|
|
||||||
}
|
|
||||||
impl ModeDescription{
|
|
||||||
pub fn get_spawn_model_id(&self,stage_id:u32)->Option<&usize>{
|
|
||||||
self.spawns.get(*self.spawn_from_stage_id.get(&stage_id)?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//I don't want this code to exist!
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct TempAttrStart{
|
|
||||||
pub mode_id:u32,
|
|
||||||
}
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct TempAttrSpawn{
|
|
||||||
pub mode_id:u32,
|
|
||||||
pub stage_id:u32,
|
|
||||||
}
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct TempAttrWormhole{
|
|
||||||
pub wormhole_id:u32,
|
|
||||||
}
|
|
||||||
pub enum TempIndexedAttributes{
|
|
||||||
Start(TempAttrStart),
|
|
||||||
Spawn(TempAttrSpawn),
|
|
||||||
Wormhole(TempAttrWormhole),
|
|
||||||
}
|
|
||||||
|
|
||||||
//you have this effect while in contact
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub struct ContactingLadder{
|
|
||||||
pub sticky:bool
|
|
||||||
}
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub enum ContactingBehaviour{
|
|
||||||
Surf,
|
|
||||||
Cling,//usable as a zipline, or other weird and wonderful things
|
|
||||||
Ladder(ContactingLadder),
|
|
||||||
Elastic(u32),//[1/2^32,1] 0=None (elasticity+1)/2^32
|
|
||||||
}
|
|
||||||
//you have this effect while intersecting
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub struct IntersectingWater{
|
|
||||||
pub viscosity:Planar64,
|
|
||||||
pub density:Planar64,
|
|
||||||
pub velocity:Planar64Vec3,
|
|
||||||
}
|
|
||||||
//All models can be given these attributes
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub struct GameMechanicAccelerator{
|
|
||||||
pub acceleration:Planar64Vec3
|
|
||||||
}
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub enum GameMechanicBooster{
|
|
||||||
Affine(Planar64Affine3),//capable of SetVelocity,DotVelocity,normal booster,bouncy part,redirect velocity, and much more
|
|
||||||
Velocity(Planar64Vec3),//straight up boost velocity adds to your current velocity
|
|
||||||
Energy{direction:Planar64Vec3,energy:Planar64},//increase energy in direction
|
|
||||||
}
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub enum TrajectoryChoice{
|
|
||||||
HighArcLongDuration,//underhand lob at target: less horizontal speed and more air time
|
|
||||||
LowArcShortDuration,//overhand throw at target: more horizontal speed and less air time
|
|
||||||
}
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub enum GameMechanicSetTrajectory{
|
|
||||||
//Speed-type SetTrajectory
|
|
||||||
AirTime(Time),//air time (relative to gravity direction) is invariant across mass and gravity changes
|
|
||||||
Height(Planar64),//boost height (relative to gravity direction) is invariant across mass and gravity changes
|
|
||||||
DotVelocity{direction:Planar64Vec3,dot:Planar64},//set your velocity in a specific direction without touching other directions
|
|
||||||
//Velocity-type SetTrajectory
|
|
||||||
TargetPointTime{//launch on a trajectory that will land at a target point in a set amount of time
|
|
||||||
target_point:Planar64Vec3,
|
|
||||||
time:Time,//short time = fast and direct, long time = launch high in the air, negative time = wrong way
|
|
||||||
},
|
|
||||||
TargetPointSpeed{//launch at a fixed speed and land at a target point
|
|
||||||
target_point:Planar64Vec3,
|
|
||||||
speed:Planar64,//if speed is too low this will fail to reach the target. The closest-passing trajectory will be chosen instead
|
|
||||||
trajectory_choice:TrajectoryChoice,
|
|
||||||
},
|
|
||||||
Velocity(Planar64Vec3),//SetVelocity
|
|
||||||
}
|
|
||||||
impl GameMechanicSetTrajectory{
|
|
||||||
fn is_velocity(&self)->bool{
|
|
||||||
match self{
|
|
||||||
GameMechanicSetTrajectory::AirTime(_)
|
|
||||||
|GameMechanicSetTrajectory::Height(_)
|
|
||||||
|GameMechanicSetTrajectory::DotVelocity{direction:_,dot:_}=>false,
|
|
||||||
GameMechanicSetTrajectory::TargetPointTime{target_point:_,time:_}
|
|
||||||
|GameMechanicSetTrajectory::TargetPointSpeed{target_point:_,speed:_,trajectory_choice:_}
|
|
||||||
|GameMechanicSetTrajectory::Velocity(_)=>true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub enum ZoneBehaviour{
|
|
||||||
//Start is indexed
|
|
||||||
//Checkpoints are indexed
|
|
||||||
Finish,
|
|
||||||
Anitcheat,
|
|
||||||
}
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub struct GameMechanicZone{
|
|
||||||
pub mode_id:u32,
|
|
||||||
pub behaviour:ZoneBehaviour,
|
|
||||||
}
|
|
||||||
// enum TrapCondition{
|
|
||||||
// FasterThan(Planar64),
|
|
||||||
// SlowerThan(Planar64),
|
|
||||||
// InRange(Planar64,Planar64),
|
|
||||||
// OutsideRange(Planar64,Planar64),
|
|
||||||
// }
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub enum StageElementBehaviour{
|
|
||||||
//Spawn,//The behaviour of stepping on a spawn setting the spawnid
|
|
||||||
SpawnAt,//must be standing on top to get effect. except cancollide false
|
|
||||||
Trigger,
|
|
||||||
Teleport,
|
|
||||||
Platform,
|
|
||||||
//Checkpoint acts like a trigger if you haven't hit all the checkpoints yet.
|
|
||||||
//Note that all stage elements act like this for the next stage.
|
|
||||||
Checkpoint,
|
|
||||||
//OrderedCheckpoint. You must pass through all of these in ascending order.
|
|
||||||
//If you hit them out of order it acts like a trigger.
|
|
||||||
//Do not support backtracking at all for now.
|
|
||||||
Ordered{
|
|
||||||
checkpoint_id:u32,
|
|
||||||
},
|
|
||||||
//UnorderedCheckpoint. You must pass through all of these in any order.
|
|
||||||
Unordered,
|
|
||||||
//If you get reset by a jump limit
|
|
||||||
JumpLimit(u32),
|
|
||||||
//Speedtrap(TrapCondition),//Acts as a trigger with a speed condition
|
|
||||||
}
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub struct GameMechanicStageElement{
|
|
||||||
pub mode_id:u32,
|
|
||||||
pub stage_id:u32,//which spawn to send to
|
|
||||||
pub force:bool,//allow setting to lower spawn id i.e. 7->3
|
|
||||||
pub behaviour:StageElementBehaviour
|
|
||||||
}
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub struct GameMechanicWormhole{
|
|
||||||
//destination does not need to be another wormhole
|
|
||||||
//this defines a one way portal to a destination model transform
|
|
||||||
//two of these can create a two way wormhole
|
|
||||||
pub destination_model_id:u32,
|
|
||||||
//(position,angles)*=origin.transform.inverse()*destination.transform
|
|
||||||
}
|
|
||||||
#[derive(Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub enum TeleportBehaviour{
|
|
||||||
StageElement(GameMechanicStageElement),
|
|
||||||
Wormhole(GameMechanicWormhole),
|
|
||||||
}
|
|
||||||
//attributes listed in order of handling
|
|
||||||
#[derive(Default,Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub struct GameMechanicAttributes{
|
|
||||||
pub zone:Option<GameMechanicZone>,
|
|
||||||
pub booster:Option<GameMechanicBooster>,
|
|
||||||
pub trajectory:Option<GameMechanicSetTrajectory>,
|
|
||||||
pub teleport_behaviour:Option<TeleportBehaviour>,
|
|
||||||
pub accelerator:Option<GameMechanicAccelerator>,
|
|
||||||
}
|
|
||||||
impl GameMechanicAttributes{
|
|
||||||
pub fn any(&self)->bool{
|
|
||||||
self.zone.is_some()
|
|
||||||
||self.booster.is_some()
|
|
||||||
||self.trajectory.is_some()
|
|
||||||
||self.teleport_behaviour.is_some()
|
|
||||||
||self.accelerator.is_some()
|
|
||||||
}
|
|
||||||
pub fn is_wrcp(&self,current_mode_id:u32)->bool{
|
|
||||||
self.trajectory.as_ref().map_or(false,|t|t.is_velocity())
|
|
||||||
&&match &self.teleport_behaviour{
|
|
||||||
Some(TeleportBehaviour::StageElement(
|
|
||||||
GameMechanicStageElement{
|
|
||||||
mode_id,
|
|
||||||
stage_id:_,
|
|
||||||
force:true,
|
|
||||||
behaviour:StageElementBehaviour::Trigger|StageElementBehaviour::Teleport
|
|
||||||
}
|
|
||||||
))=>current_mode_id==*mode_id,
|
|
||||||
_=>false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Default,Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub struct ContactingAttributes{
|
|
||||||
//friction?
|
|
||||||
pub contact_behaviour:Option<ContactingBehaviour>,
|
|
||||||
}
|
|
||||||
impl ContactingAttributes{
|
|
||||||
pub fn any(&self)->bool{
|
|
||||||
self.contact_behaviour.is_some()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Default,Clone,Hash,Eq,PartialEq)]
|
|
||||||
pub struct IntersectingAttributes{
|
|
||||||
pub water:Option<IntersectingWater>,
|
|
||||||
}
|
|
||||||
impl IntersectingAttributes{
|
|
||||||
pub fn any(&self)->bool{
|
|
||||||
self.water.is_some()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Spawn(u32) NO! spawns are indexed in the map header instead of marked with attibutes
|
|
||||||
pub enum CollisionAttributes{
|
|
||||||
Decoration,//visual only
|
|
||||||
Contact{//track whether you are contacting the object
|
|
||||||
contacting:ContactingAttributes,
|
|
||||||
general:GameMechanicAttributes,
|
|
||||||
},
|
|
||||||
Intersect{//track whether you are intersecting the object
|
|
||||||
intersecting:IntersectingAttributes,
|
|
||||||
general:GameMechanicAttributes,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
impl std::default::Default for CollisionAttributes{
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Contact{
|
|
||||||
contacting:ContactingAttributes::default(),
|
|
||||||
general:GameMechanicAttributes::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_indexed_model_list_from_obj(data:obj::ObjData,color:Color4)->Vec<IndexedModel>{
|
|
||||||
let mut unique_vertex_index = std::collections::HashMap::<obj::IndexTuple,u32>::new();
|
|
||||||
return data.objects.iter().map(|object|{
|
|
||||||
unique_vertex_index.clear();
|
|
||||||
let mut unique_vertices = Vec::new();
|
|
||||||
let groups = object.groups.iter().map(|group|{
|
|
||||||
IndexedGroup{
|
|
||||||
texture:None,
|
|
||||||
polys:group.polys.iter().map(|poly|{
|
|
||||||
IndexedPolygon{
|
|
||||||
vertices:poly.0.iter().map(|&tup|{
|
|
||||||
if let Some(&i)=unique_vertex_index.get(&tup){
|
|
||||||
i
|
|
||||||
}else{
|
|
||||||
let i=unique_vertices.len() as u32;
|
|
||||||
unique_vertices.push(IndexedVertex{
|
|
||||||
pos: tup.0 as u32,
|
|
||||||
tex: tup.1.unwrap() as u32,
|
|
||||||
normal: tup.2.unwrap() as u32,
|
|
||||||
color: 0,
|
|
||||||
});
|
|
||||||
unique_vertex_index.insert(tup,i);
|
|
||||||
i
|
|
||||||
}
|
|
||||||
}).collect()
|
|
||||||
}
|
|
||||||
}).collect()
|
|
||||||
}
|
|
||||||
}).collect();
|
|
||||||
IndexedModel{
|
|
||||||
unique_pos: data.position.iter().map(|&v|Planar64Vec3::try_from(v).unwrap()).collect(),
|
|
||||||
unique_tex: data.texture.iter().map(|&v|TextureCoordinate::from_array(v)).collect(),
|
|
||||||
unique_normal: data.normal.iter().map(|&v|Planar64Vec3::try_from(v).unwrap()).collect(),
|
|
||||||
unique_color: vec![color],
|
|
||||||
unique_vertices,
|
|
||||||
groups,
|
|
||||||
instances:Vec::new(),
|
|
||||||
}
|
|
||||||
}).collect()
|
|
||||||
}
|
|
338
src/physics.rs
338
src/physics.rs
@ -1,8 +1,9 @@
|
|||||||
use crate::model_physics::{PhysicsMesh,TransformedMesh,MeshQuery};
|
use crate::model_physics::{PhysicsMesh,TransformedMesh,MeshQuery};
|
||||||
use strafesnet_common::bvh;
|
use strafesnet_common::bvh;
|
||||||
use strafesnet_common::aabb;
|
use strafesnet_common::aabb;
|
||||||
|
use strafesnet_common::game_mechanics::{self,StyleModifiers};
|
||||||
use strafesnet_common::instruction::{self,InstructionEmitter,InstructionConsumer,TimedInstruction};
|
use strafesnet_common::instruction::{self,InstructionEmitter,InstructionConsumer,TimedInstruction};
|
||||||
use strafesnet_common::integer::{self,Time,Planar64,Planar64Vec3,Planar64Mat3,Angle32,Ratio64,Ratio64Vec2};
|
use strafesnet_common::integer::{self,Time,Planar64,Planar64Vec3,Planar64Mat3,Angle32,Ratio64Vec2};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum PhysicsInstruction {
|
pub enum PhysicsInstruction {
|
||||||
@ -143,33 +144,6 @@ impl WalkState{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Modes{
|
|
||||||
modes:Vec<crate::model::ModeDescription>,
|
|
||||||
mode_from_mode_id:std::collections::HashMap::<u32,usize>,
|
|
||||||
}
|
|
||||||
impl Modes{
|
|
||||||
fn clear(&mut self){
|
|
||||||
self.modes.clear();
|
|
||||||
self.mode_from_mode_id.clear();
|
|
||||||
}
|
|
||||||
fn get_mode(&self,mode_id:u32)->Option<&crate::model::ModeDescription>{
|
|
||||||
self.modes.get(*self.mode_from_mode_id.get(&mode_id)?)
|
|
||||||
}
|
|
||||||
fn insert(&mut self,temp_map_mode_id:u32,mode:crate::model::ModeDescription){
|
|
||||||
let mode_id=self.modes.len();
|
|
||||||
self.mode_from_mode_id.insert(temp_map_mode_id,mode_id);
|
|
||||||
self.modes.push(mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Default for Modes{
|
|
||||||
fn default() -> Self {
|
|
||||||
Self{
|
|
||||||
modes:Vec::new(),
|
|
||||||
mode_from_mode_id:std::collections::HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct PhysicsModels{
|
struct PhysicsModels{
|
||||||
meshes:Vec<PhysicsMesh>,
|
meshes:Vec<PhysicsMesh>,
|
||||||
@ -188,15 +162,6 @@ impl PhysicsModels{
|
|||||||
self.attributes.clear();
|
self.attributes.clear();
|
||||||
self.model_id_from_wormhole_id.clear();
|
self.model_id_from_wormhole_id.clear();
|
||||||
}
|
}
|
||||||
fn aabb_list(&self)->Vec<aabb::Aabb>{
|
|
||||||
self.models.iter().map(|model|{
|
|
||||||
let mut aabb=aabb::Aabb::default();
|
|
||||||
for pos in self.meshes[model.mesh_id].verts(){
|
|
||||||
aabb.grow(model.transform.transform_point3(pos));
|
|
||||||
}
|
|
||||||
aabb
|
|
||||||
}).collect()
|
|
||||||
}
|
|
||||||
//TODO: "statically" verify the maps don't refer to any nonexistant data, if they do delete the references.
|
//TODO: "statically" verify the maps don't refer to any nonexistant data, if they do delete the references.
|
||||||
//then I can make these getter functions unchecked.
|
//then I can make these getter functions unchecked.
|
||||||
fn mesh(&self,model_id:usize)->TransformedMesh{
|
fn mesh(&self,model_id:usize)->TransformedMesh{
|
||||||
@ -311,298 +276,33 @@ impl std::default::Default for GameMechanicsState{
|
|||||||
|
|
||||||
struct WorldState{}
|
struct WorldState{}
|
||||||
|
|
||||||
enum JumpCalculation{
|
trait HitboxMeshPresets{
|
||||||
Capped,//roblox
|
fn roblox()->Self;
|
||||||
Energy,//new
|
fn source()->Self;
|
||||||
Linear,//source
|
|
||||||
}
|
}
|
||||||
|
impl HitboxMeshPresets for game_mechanics::Hitbox{
|
||||||
enum JumpImpulse{
|
|
||||||
FromTime(Time),//jump time is invariant across mass and gravity changes
|
|
||||||
FromHeight(Planar64),//jump height is invariant across mass and gravity changes
|
|
||||||
FromDeltaV(Planar64),//jump velocity is invariant across mass and gravity changes
|
|
||||||
FromEnergy(Planar64),// :)
|
|
||||||
}
|
|
||||||
//Jumping acts on dot(walks_state.normal,body.velocity)
|
|
||||||
//Capped means it increases the dot to the cap
|
|
||||||
//Energy means it adds energy
|
|
||||||
//Linear means it linearly adds on
|
|
||||||
|
|
||||||
enum EnableStrafe{
|
|
||||||
Always,
|
|
||||||
MaskAny(u32),//hsw, shsw
|
|
||||||
MaskAll(u32),
|
|
||||||
//Function(Box<dyn Fn(u32)->bool>),
|
|
||||||
}
|
|
||||||
|
|
||||||
struct StrafeSettings{
|
|
||||||
enable:EnableStrafe,
|
|
||||||
air_accel_limit:Option<Planar64>,
|
|
||||||
tick_rate:Ratio64,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Hitbox{
|
|
||||||
halfsize:Planar64Vec3,
|
|
||||||
mesh:PhysicsMesh,
|
|
||||||
transform:integer::Planar64Affine3,
|
|
||||||
normal_transform:Planar64Mat3,
|
|
||||||
transform_det:Planar64,
|
|
||||||
}
|
|
||||||
impl Hitbox{
|
|
||||||
fn new(mesh:PhysicsMesh,transform:integer::Planar64Affine3)->Self{
|
|
||||||
//calculate extents
|
|
||||||
let mut aabb=aabb::Aabb::default();
|
|
||||||
for vert in mesh.verts(){
|
|
||||||
aabb.grow(transform.transform_point3(vert));
|
|
||||||
}
|
|
||||||
Self{
|
|
||||||
halfsize:aabb.size()/2,
|
|
||||||
mesh,
|
|
||||||
transform,
|
|
||||||
normal_transform:transform.matrix3.inverse_times_det().transpose(),
|
|
||||||
transform_det:transform.matrix3.determinant(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn from_mesh_scale(mesh:PhysicsMesh,scale:Planar64Vec3)->Self{
|
|
||||||
let matrix3=Planar64Mat3::from_diagonal(scale);
|
|
||||||
Self{
|
|
||||||
halfsize:scale,
|
|
||||||
mesh,
|
|
||||||
normal_transform:matrix3.inverse_times_det().transpose(),
|
|
||||||
transform:integer::Planar64Affine3::new(matrix3,Planar64Vec3::ZERO),
|
|
||||||
transform_det:matrix3.determinant(),//scale.x*scale.y*scale.z but whatever
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn from_mesh_scale_offset(mesh:PhysicsMesh,scale:Planar64Vec3,offset:Planar64Vec3)->Self{
|
|
||||||
let matrix3=Planar64Mat3::from_diagonal(scale);
|
|
||||||
Self{
|
|
||||||
halfsize:scale,
|
|
||||||
mesh,
|
|
||||||
normal_transform:matrix3.inverse_times_det().transpose(),
|
|
||||||
transform:integer::Planar64Affine3::new(matrix3,offset),
|
|
||||||
transform_det:matrix3.determinant(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn roblox()->Self{
|
fn roblox()->Self{
|
||||||
Self::from_mesh_scale(PhysicsMesh::from(&crate::primitives::unit_cylinder()),Planar64Vec3::int(2,5,2)/2)
|
Self::from_mesh_scale(PhysicsMesh::from(&crate::primitives::unit_cylinder()),Planar64Vec3::int(2,5,2)/2)
|
||||||
}
|
}
|
||||||
fn source()->Self{
|
fn source()->Self{
|
||||||
Self::from_mesh_scale(PhysicsMesh::from(&crate::primitives::unit_cube()),Planar64Vec3::raw(33<<28,73<<28,33<<28)/2)
|
Self::from_mesh_scale(PhysicsMesh::from(&crate::primitives::unit_cube()),Planar64Vec3::raw(33<<28,73<<28,33<<28)/2)
|
||||||
}
|
}
|
||||||
#[inline]
|
|
||||||
fn transformed_mesh(&self)->TransformedMesh{
|
|
||||||
TransformedMesh::new(&self.mesh,&self.transform,&self.normal_transform,self.transform_det)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StyleModifiers{
|
trait StyleHelper{
|
||||||
controls_used:u32,//controls which are allowed to pass into gameplay
|
fn get_control(&self,control:u32,controls:u32)->bool;
|
||||||
controls_mask:u32,//controls which are masked from control state (e.g. jump in scroll style)
|
fn allow_strafe(&self,controls:u32)->bool;
|
||||||
strafe:Option<StrafeSettings>,
|
fn get_control_dir(&self,controls:u32)->Planar64Vec3;
|
||||||
jump_impulse:JumpImpulse,
|
//fn get_jump_time(&self)->Planar64;
|
||||||
jump_calculation:JumpCalculation,
|
//fn get_jump_height(&self)->Planar64;
|
||||||
static_friction:Planar64,
|
//fn get_jump_energy(&self)->Planar64;
|
||||||
kinetic_friction:Planar64,
|
fn get_jump_deltav(&self)->Planar64;
|
||||||
walk_speed:Planar64,
|
fn get_walk_target_velocity(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time,normal:&Planar64Vec3)->Planar64Vec3;
|
||||||
walk_accel:Planar64,
|
fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time,normal:&Planar64Vec3)->Planar64Vec3;
|
||||||
ladder_speed:Planar64,
|
fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time)->Planar64Vec3;
|
||||||
ladder_accel:Planar64,
|
fn mesh(&self)->TransformedMesh;
|
||||||
ladder_dot:Planar64,
|
|
||||||
swim_speed:Planar64,
|
|
||||||
mass:Planar64,
|
|
||||||
mv:Planar64,
|
|
||||||
surf_slope:Option<Planar64>,
|
|
||||||
rocket_force:Option<Planar64>,
|
|
||||||
gravity:Planar64Vec3,
|
|
||||||
hitbox:Hitbox,
|
|
||||||
camera_offset:Planar64Vec3,
|
|
||||||
}
|
}
|
||||||
impl std::default::Default for StyleModifiers{
|
impl StyleHelper for StyleModifiers{
|
||||||
fn default()->Self{
|
|
||||||
Self::roblox_bhop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl StyleModifiers{
|
|
||||||
const CONTROL_MOVEFORWARD:u32=0b00000001;
|
|
||||||
const CONTROL_MOVEBACK:u32=0b00000010;
|
|
||||||
const CONTROL_MOVERIGHT:u32=0b00000100;
|
|
||||||
const CONTROL_MOVELEFT:u32=0b00001000;
|
|
||||||
const CONTROL_MOVEUP:u32=0b00010000;
|
|
||||||
const CONTROL_MOVEDOWN:u32=0b00100000;
|
|
||||||
const CONTROL_JUMP:u32=0b01000000;
|
|
||||||
const CONTROL_ZOOM:u32=0b10000000;
|
|
||||||
|
|
||||||
const RIGHT_DIR:Planar64Vec3=Planar64Vec3::X;
|
|
||||||
const UP_DIR:Planar64Vec3=Planar64Vec3::Y;
|
|
||||||
const FORWARD_DIR:Planar64Vec3=Planar64Vec3::NEG_Z;
|
|
||||||
|
|
||||||
fn neo()->Self{
|
|
||||||
Self{
|
|
||||||
controls_used:!0,
|
|
||||||
controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN),
|
|
||||||
strafe:Some(StrafeSettings{
|
|
||||||
enable:EnableStrafe::Always,
|
|
||||||
air_accel_limit:None,
|
|
||||||
tick_rate:Ratio64::new(64,Time::ONE_SECOND.nanos() as u64).unwrap(),
|
|
||||||
}),
|
|
||||||
jump_impulse:JumpImpulse::FromEnergy(Planar64::int(512)),
|
|
||||||
jump_calculation:JumpCalculation::Energy,
|
|
||||||
gravity:Planar64Vec3::int(0,-80,0),
|
|
||||||
static_friction:Planar64::int(2),
|
|
||||||
kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static
|
|
||||||
mass:Planar64::int(1),
|
|
||||||
mv:Planar64::int(3),
|
|
||||||
rocket_force:None,
|
|
||||||
walk_speed:Planar64::int(16),
|
|
||||||
walk_accel:Planar64::int(80),
|
|
||||||
ladder_speed:Planar64::int(16),
|
|
||||||
ladder_accel:Planar64::int(160),
|
|
||||||
ladder_dot:(Planar64::int(1)/2).sqrt(),
|
|
||||||
swim_speed:Planar64::int(12),
|
|
||||||
surf_slope:Some(Planar64::raw(7)/8),
|
|
||||||
hitbox:Hitbox::roblox(),
|
|
||||||
camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn roblox_bhop()->Self{
|
|
||||||
Self{
|
|
||||||
controls_used:!0,
|
|
||||||
controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN),
|
|
||||||
strafe:Some(StrafeSettings{
|
|
||||||
enable:EnableStrafe::Always,
|
|
||||||
air_accel_limit:None,
|
|
||||||
tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(),
|
|
||||||
}),
|
|
||||||
jump_impulse:JumpImpulse::FromTime(Time::from_micros(715_588)),
|
|
||||||
jump_calculation:JumpCalculation::Capped,
|
|
||||||
gravity:Planar64Vec3::int(0,-100,0),
|
|
||||||
static_friction:Planar64::int(2),
|
|
||||||
kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static
|
|
||||||
mass:Planar64::int(1),
|
|
||||||
mv:Planar64::int(27)/10,
|
|
||||||
rocket_force:None,
|
|
||||||
walk_speed:Planar64::int(18),
|
|
||||||
walk_accel:Planar64::int(90),
|
|
||||||
ladder_speed:Planar64::int(18),
|
|
||||||
ladder_accel:Planar64::int(180),
|
|
||||||
ladder_dot:(Planar64::int(1)/2).sqrt(),
|
|
||||||
swim_speed:Planar64::int(12),
|
|
||||||
surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75
|
|
||||||
hitbox:Hitbox::roblox(),
|
|
||||||
camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn roblox_surf()->Self{
|
|
||||||
Self{
|
|
||||||
controls_used:!0,
|
|
||||||
controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN),
|
|
||||||
strafe:Some(StrafeSettings{
|
|
||||||
enable:EnableStrafe::Always,
|
|
||||||
air_accel_limit:None,
|
|
||||||
tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(),
|
|
||||||
}),
|
|
||||||
jump_impulse:JumpImpulse::FromTime(Time::from_micros(715_588)),
|
|
||||||
jump_calculation:JumpCalculation::Capped,
|
|
||||||
gravity:Planar64Vec3::int(0,-50,0),
|
|
||||||
static_friction:Planar64::int(2),
|
|
||||||
kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static
|
|
||||||
mass:Planar64::int(1),
|
|
||||||
mv:Planar64::int(27)/10,
|
|
||||||
rocket_force:None,
|
|
||||||
walk_speed:Planar64::int(18),
|
|
||||||
walk_accel:Planar64::int(90),
|
|
||||||
ladder_speed:Planar64::int(18),
|
|
||||||
ladder_accel:Planar64::int(180),
|
|
||||||
ladder_dot:(Planar64::int(1)/2).sqrt(),
|
|
||||||
swim_speed:Planar64::int(12),
|
|
||||||
surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75
|
|
||||||
hitbox:Hitbox::roblox(),
|
|
||||||
camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn source_bhop()->Self{
|
|
||||||
Self{
|
|
||||||
controls_used:!0,
|
|
||||||
controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN),
|
|
||||||
strafe:Some(StrafeSettings{
|
|
||||||
enable:EnableStrafe::Always,
|
|
||||||
air_accel_limit:Some(Planar64::raw(150<<28)*100),
|
|
||||||
tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(),
|
|
||||||
}),
|
|
||||||
jump_impulse:JumpImpulse::FromHeight(Planar64::raw(52<<28)),
|
|
||||||
jump_calculation:JumpCalculation::Linear,
|
|
||||||
gravity:Planar64Vec3::raw(0,-800<<28,0),
|
|
||||||
static_friction:Planar64::int(2),//?
|
|
||||||
kinetic_friction:Planar64::int(3),//?
|
|
||||||
mass:Planar64::int(1),
|
|
||||||
mv:Planar64::raw(30<<28),
|
|
||||||
rocket_force:None,
|
|
||||||
walk_speed:Planar64::int(18),//?
|
|
||||||
walk_accel:Planar64::int(90),//?
|
|
||||||
ladder_speed:Planar64::int(18),//?
|
|
||||||
ladder_accel:Planar64::int(180),//?
|
|
||||||
ladder_dot:(Planar64::int(1)/2).sqrt(),//?
|
|
||||||
swim_speed:Planar64::int(12),//?
|
|
||||||
surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75
|
|
||||||
hitbox:Hitbox::source(),
|
|
||||||
camera_offset:Planar64Vec3::raw(0,(64<<28)-(73<<27),0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn source_surf()->Self{
|
|
||||||
Self{
|
|
||||||
controls_used:!0,
|
|
||||||
controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN),
|
|
||||||
strafe:Some(StrafeSettings{
|
|
||||||
enable:EnableStrafe::Always,
|
|
||||||
air_accel_limit:Some(Planar64::raw(150<<28)*66),
|
|
||||||
tick_rate:Ratio64::new(66,Time::ONE_SECOND.nanos() as u64).unwrap(),
|
|
||||||
}),
|
|
||||||
jump_impulse:JumpImpulse::FromHeight(Planar64::raw(52<<28)),
|
|
||||||
jump_calculation:JumpCalculation::Linear,
|
|
||||||
gravity:Planar64Vec3::raw(0,-800<<28,0),
|
|
||||||
static_friction:Planar64::int(2),//?
|
|
||||||
kinetic_friction:Planar64::int(3),//?
|
|
||||||
mass:Planar64::int(1),
|
|
||||||
mv:Planar64::raw(30<<28),
|
|
||||||
rocket_force:None,
|
|
||||||
walk_speed:Planar64::int(18),//?
|
|
||||||
walk_accel:Planar64::int(90),//?
|
|
||||||
ladder_speed:Planar64::int(18),//?
|
|
||||||
ladder_accel:Planar64::int(180),//?
|
|
||||||
ladder_dot:(Planar64::int(1)/2).sqrt(),//?
|
|
||||||
swim_speed:Planar64::int(12),//?
|
|
||||||
surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75
|
|
||||||
hitbox:Hitbox::source(),
|
|
||||||
camera_offset:Planar64Vec3::raw(0,(64<<28)-(73<<27),0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn roblox_rocket()->Self{
|
|
||||||
Self{
|
|
||||||
controls_used:!0,
|
|
||||||
controls_mask:!0,
|
|
||||||
strafe:None,
|
|
||||||
jump_impulse:JumpImpulse::FromTime(Time::from_micros(715_588)),
|
|
||||||
jump_calculation:JumpCalculation::Capped,
|
|
||||||
gravity:Planar64Vec3::int(0,-100,0),
|
|
||||||
static_friction:Planar64::int(2),
|
|
||||||
kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static
|
|
||||||
mass:Planar64::int(1),
|
|
||||||
mv:Planar64::int(27)/10,
|
|
||||||
rocket_force:Some(Planar64::int(200)),
|
|
||||||
walk_speed:Planar64::int(18),
|
|
||||||
walk_accel:Planar64::int(90),
|
|
||||||
ladder_speed:Planar64::int(18),
|
|
||||||
ladder_accel:Planar64::int(180),
|
|
||||||
ladder_dot:(Planar64::int(1)/2).sqrt(),
|
|
||||||
swim_speed:Planar64::int(12),
|
|
||||||
surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75
|
|
||||||
hitbox:Hitbox::roblox(),
|
|
||||||
camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_control(&self,control:u32,controls:u32)->bool{
|
fn get_control(&self,control:u32,controls:u32)->bool{
|
||||||
controls&self.controls_mask&control==control
|
controls&self.controls_mask&control==control
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user