From f0035bcee94439a5f6f12b5cc9d30da54b35a6e7 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 23 Jul 2024 11:05:01 -0700 Subject: [PATCH] newtypes (boilerplate) --- src/lib.rs | 2 + src/newtypes.rs | 6 + src/newtypes/aabb.rs | 15 ++ src/newtypes/gameplay_attributes.rs | 246 ++++++++++++++++++++++++++++ src/newtypes/gameplay_modes.rs | 126 ++++++++++++++ src/newtypes/gameplay_style.rs | 218 ++++++++++++++++++++++++ src/newtypes/integer.rs | 26 +++ src/newtypes/model.rs | 152 +++++++++++++++++ 8 files changed, 791 insertions(+) create mode 100644 src/newtypes.rs create mode 100644 src/newtypes/aabb.rs create mode 100644 src/newtypes/gameplay_attributes.rs create mode 100644 src/newtypes/gameplay_modes.rs create mode 100644 src/newtypes/gameplay_style.rs create mode 100644 src/newtypes/integer.rs create mode 100644 src/newtypes/model.rs diff --git a/src/lib.rs b/src/lib.rs index bac2c04..4f4f479 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,7 @@ use binrw::BinReaderExt; +mod newtypes; + pub mod file; pub mod map; pub mod bot; diff --git a/src/newtypes.rs b/src/newtypes.rs new file mode 100644 index 0000000..8b12c6b --- /dev/null +++ b/src/newtypes.rs @@ -0,0 +1,6 @@ +pub mod aabb; +pub mod model; +pub mod integer; +pub mod gameplay_modes; +pub mod gameplay_style; +pub mod gameplay_attributes; diff --git a/src/newtypes/aabb.rs b/src/newtypes/aabb.rs new file mode 100644 index 0000000..3908287 --- /dev/null +++ b/src/newtypes/aabb.rs @@ -0,0 +1,15 @@ +use super::integer::Planar64Vec3; +#[binrw::binrw] +#[brw(little)] +pub struct Aabb{ + pub min:Planar64Vec3, + pub max:Planar64Vec3, +} +impl Into for Aabb{ + fn into(self)->strafesnet_common::aabb::Aabb{ + strafesnet_common::aabb::Aabb::new( + strafesnet_common::integer::Planar64Vec3::raw_array(self.min), + strafesnet_common::integer::Planar64Vec3::raw_array(self.max), + ) + } +} diff --git a/src/newtypes/gameplay_attributes.rs b/src/newtypes/gameplay_attributes.rs new file mode 100644 index 0000000..10921cd --- /dev/null +++ b/src/newtypes/gameplay_attributes.rs @@ -0,0 +1,246 @@ +use super::integer::{Time,Planar64,Planar64Vec3}; + +#[binrw::binrw] +#[brw(little)] +pub struct ContactingLadder{ + pub sticky:Option<()>, +} +impl Into for ContactingLadder{ + fn into(self)->strafesnet_common::gameplay_attributes::ContactingLadder{ + strafesnet_common::gameplay_attributes::ContactingLadder{ + sticky:self.sticky.is_some(), + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub enum ContactingBehaviour{ + Surf, + Ladder(ContactingLadder), + NoJump, + Cling, + Elastic(u32), +} +impl Into for ContactingBehaviour{ + fn into(self)->strafesnet_common::gameplay_attributes::ContactingBehaviour{ + match self{ + ContactingBehaviour::Surf=> + strafesnet_common::gameplay_attributes::ContactingBehaviour::Surf, + ContactingBehaviour::Ladder(contacting_ladder)=> + strafesnet_common::gameplay_attributes::ContactingBehaviour::Ladder( + contacting_ladder.into(), + ), + ContactingBehaviour::NoJump=> + strafesnet_common::gameplay_attributes::ContactingBehaviour::NoJump, + ContactingBehaviour::Cling=> + strafesnet_common::gameplay_attributes::ContactingBehaviour::Cling, + ContactingBehaviour::Elastic(elasticity)=> + strafesnet_common::gameplay_attributes::ContactingBehaviour::Elastic(elasticity), + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct IntersectingWater{ + pub viscosity:Planar64, + pub density:Planar64, + pub velocity:Planar64Vec3, +} +impl Into for IntersectingWater{ + fn into(self)->strafesnet_common::gameplay_attributes::IntersectingWater{ + strafesnet_common::gameplay_attributes::IntersectingWater{ + viscosity:strafesnet_common::integer::Planar64::raw(self.viscosity), + density:strafesnet_common::integer::Planar64::raw(self.density), + velocity:strafesnet_common::integer::Planar64Vec3::raw_array(self.velocity), + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct Accelerator{ + pub acceleration:Planar64Vec3 +} +impl Into for Accelerator{ + fn into(self)->strafesnet_common::gameplay_attributes::Accelerator{ + strafesnet_common::gameplay_attributes::Accelerator{ + acceleration:strafesnet_common::integer::Planar64Vec3::raw_array(self.acceleration) + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub enum Booster{ + Velocity(Planar64Vec3), + Energy{direction:Planar64Vec3,energy:Planar64}, +} +impl Into for Booster{ + fn into(self)->strafesnet_common::gameplay_attributes::Booster{ + match self{ + Booster::Velocity(velocity)=> + strafesnet_common::gameplay_attributes::Booster::Velocity( + strafesnet_common::integer::Planar64Vec3::raw_array(velocity) + ), + Booster::Energy{direction,energy}=> + strafesnet_common::gameplay_attributes::Booster::Energy{ + direction:strafesnet_common::integer::Planar64Vec3::raw_array(direction), + energy:strafesnet_common::integer::Planar64::raw(energy) + }, + } + } +} + +#[binrw::binrw] +#[brw(little,repr=u8)] +pub enum TrajectoryChoice{ + HighArcLongDuration, + LowArcShortDuration, +} +impl Into for TrajectoryChoice{ + fn into(self)->strafesnet_common::gameplay_attributes::TrajectoryChoice{ + match self{ + TrajectoryChoice::HighArcLongDuration=> + strafesnet_common::gameplay_attributes::TrajectoryChoice::HighArcLongDuration, + TrajectoryChoice::LowArcShortDuration=> + strafesnet_common::gameplay_attributes::TrajectoryChoice::LowArcShortDuration, + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub enum SetTrajectory{ + AirTime(Time), + Height(Planar64), + DotVelocity{direction:Planar64Vec3,dot:Planar64}, + TargetPointTime{ + target_point:Planar64Vec3, + time:Time, + }, + TargetPointSpeed{ + target_point:Planar64Vec3, + speed:Planar64, + trajectory_choice:TrajectoryChoice, + }, + Velocity(Planar64Vec3), +} +impl Into for SetTrajectory{ + fn into(self)->strafesnet_common::gameplay_attributes::SetTrajectory{ + match self{ + SetTrajectory::AirTime(time)=> + strafesnet_common::gameplay_attributes::SetTrajectory::AirTime( + strafesnet_common::integer::Time::raw(time) + ), + SetTrajectory::Height(height)=> + strafesnet_common::gameplay_attributes::SetTrajectory::Height( + strafesnet_common::integer::Planar64::raw(height) + ), + SetTrajectory::DotVelocity{direction,dot}=> + strafesnet_common::gameplay_attributes::SetTrajectory::DotVelocity{ + direction:strafesnet_common::integer::Planar64Vec3::raw_array(direction), + dot:strafesnet_common::integer::Planar64::raw(dot), + }, + SetTrajectory::TargetPointTime{target_point,time}=> + strafesnet_common::gameplay_attributes::SetTrajectory::TargetPointTime{ + target_point:strafesnet_common::integer::Planar64Vec3::raw_array(target_point), + time:strafesnet_common::integer::Time::raw(time), + }, + SetTrajectory::TargetPointSpeed{target_point,speed,trajectory_choice}=> + strafesnet_common::gameplay_attributes::SetTrajectory::TargetPointSpeed{ + target_point:strafesnet_common::integer::Planar64Vec3::raw_array(target_point), + speed:strafesnet_common::integer::Planar64::raw(speed), + trajectory_choice:trajectory_choice.into(), + }, + SetTrajectory::Velocity(velocity)=> + strafesnet_common::gameplay_attributes::SetTrajectory::Velocity( + strafesnet_common::integer::Planar64Vec3::raw_array(velocity) + ), + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct Wormhole{ + pub destination_model:u32, +} +impl Into for Wormhole{ + fn into(self)->strafesnet_common::gameplay_attributes::Wormhole{ + strafesnet_common::gameplay_attributes::Wormhole{ + destination_model:strafesnet_common::model::ModelId::new(self.destination_model), + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct GeneralAttributes{ + pub booster:Option, + pub trajectory:Option, + pub wormhole:Option, + pub accelerator:Option, +} +impl Into for GeneralAttributes{ + fn into(self)->strafesnet_common::gameplay_attributes::GeneralAttributes{ + strafesnet_common::gameplay_attributes::GeneralAttributes{ + booster:self.booster.map(Into::into), + trajectory:self.trajectory.map(Into::into), + wormhole:self.wormhole.map(Into::into), + accelerator:self.accelerator.map(Into::into), + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct ContactingAttributes{ + pub contact_behaviour:Option, +} +impl Into for ContactingAttributes{ + fn into(self)->strafesnet_common::gameplay_attributes::ContactingAttributes{ + strafesnet_common::gameplay_attributes::ContactingAttributes{ + contact_behaviour:self.contact_behaviour.map(Into::into), + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct IntersectingAttributes{ + pub water:Option, +} +impl Into for IntersectingAttributes{ + fn into(self)->strafesnet_common::gameplay_attributes::IntersectingAttributes{ + strafesnet_common::gameplay_attributes::IntersectingAttributes{ + water:self.water.map(Into::into), + } + } +} +#[binrw::binrw] +#[brw(little)] +pub enum CollisionAttributes{ + Decoration, + Contact{ + contacting:ContactingAttributes, + general:GeneralAttributes, + }, + Intersect{ + intersecting:IntersectingAttributes, + general:GeneralAttributes, + }, +} +impl Into for CollisionAttributes{ + fn into(self)->strafesnet_common::gameplay_attributes::CollisionAttributes{ + match self{ + CollisionAttributes::Decoration=> + strafesnet_common::gameplay_attributes::CollisionAttributes::Decoration, + CollisionAttributes::Contact{contacting,general}=> + strafesnet_common::gameplay_attributes::CollisionAttributes::Contact{contacting:contacting.into(),general:general.into()}, + CollisionAttributes::Intersect{intersecting,general}=> + strafesnet_common::gameplay_attributes::CollisionAttributes::Intersect{intersecting:intersecting.into(),general:general.into()}, + } + } +} diff --git a/src/newtypes/gameplay_modes.rs b/src/newtypes/gameplay_modes.rs new file mode 100644 index 0000000..73c2eb4 --- /dev/null +++ b/src/newtypes/gameplay_modes.rs @@ -0,0 +1,126 @@ +#[binrw::binrw] +#[brw(little,repr=u8)] +pub enum StageElementBehaviour{ + SpawnAt,//must be standing on top to get effect. except cancollide false + Trigger, + Teleport, + Platform, + //Check(point) acts like a trigger if you haven't hit all the checkpoints on previous stages yet. + //Note that all stage elements act like this, this is just the isolated behaviour. + Check, + Checkpoint,//this is a combined behaviour for Ordered & Unordered in case a model is used multiple times or for both. +} +impl Into for StageElementBehaviour{ + fn into(self)->strafesnet_common::gameplay_modes::StageElementBehaviour{ + match self{ + StageElementBehaviour::SpawnAt=>strafesnet_common::gameplay_modes::StageElementBehaviour::SpawnAt, + StageElementBehaviour::Trigger=>strafesnet_common::gameplay_modes::StageElementBehaviour::Trigger, + StageElementBehaviour::Teleport=>strafesnet_common::gameplay_modes::StageElementBehaviour::Teleport, + StageElementBehaviour::Platform=>strafesnet_common::gameplay_modes::StageElementBehaviour::Platform, + StageElementBehaviour::Check=>strafesnet_common::gameplay_modes::StageElementBehaviour::Check, + StageElementBehaviour::Checkpoint=>strafesnet_common::gameplay_modes::StageElementBehaviour::Checkpoint, + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct StageElement{ + pub stage_id:u32,//which stage spawn to send to + pub behaviour:StageElementBehaviour, + pub jump_limit:Option, + pub force:Option<()>,//allow setting to lower spawn id i.e. 7->3 +} +impl Into for StageElement{ + fn into(self)->strafesnet_common::gameplay_modes::StageElement{ + strafesnet_common::gameplay_modes::StageElement::new( + strafesnet_common::gameplay_modes::StageId::new(self.stage_id), + self.force.is_some(), + self.behaviour.into(), + self.jump_limit, + ) + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct Stage{ + pub spawn:u32, + //open world support lol + pub ordered_checkpoints_count:u32, + pub unordered_checkpoints_count:u32, + //currently loaded checkpoint models + #[br(count=ordered_checkpoints_count)] + pub ordered_checkpoints:Vec<(u32,u32)>, + #[br(count=unordered_checkpoints_count)] + pub unordered_checkpoints:Vec, +} +impl Into for Stage{ + fn into(self)->strafesnet_common::gameplay_modes::Stage{ + strafesnet_common::gameplay_modes::Stage::new( + strafesnet_common::model::ModelId::new(self.spawn), + self.ordered_checkpoints_count, + self.unordered_checkpoints_count, + self.ordered_checkpoints.into_iter().map(|(checkpoint_id,model_id)|( + strafesnet_common::gameplay_modes::CheckpointId::new(checkpoint_id), + strafesnet_common::model::ModelId::new(model_id), + )).collect(), + self.unordered_checkpoints.into_iter() + .map(strafesnet_common::model::ModelId::new) + .collect(), + ) + } +} + +#[binrw::binrw] +#[brw(little,repr=u8)] +pub enum Zone{ + Start, + Finish, + Anticheat, +} +impl Into for Zone{ + fn into(self)->strafesnet_common::gameplay_modes::Zone{ + match self{ + Zone::Start=>strafesnet_common::gameplay_modes::Zone::Start, + Zone::Finish=>strafesnet_common::gameplay_modes::Zone::Finish, + Zone::Anticheat=>strafesnet_common::gameplay_modes::Zone::Anticheat, + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct ModeHeader{ + pub zones:u32, + pub stages:u32, + pub elements:u32, +} +#[binrw::binrw] +#[brw(little)] +pub struct Mode{ + pub header:ModeHeader, + pub style:super::gameplay_style::StyleModifiers, + pub start:u32, + #[br(count=header.zones)] + pub zones:Vec<(u32,Zone)>, + #[br(count=header.stages)] + pub stages:Vec, + #[br(count=header.elements)] + pub elements:Vec<(u32,StageElement)>, +} +impl Into for Mode{ + fn into(self)->strafesnet_common::gameplay_modes::Mode{ + strafesnet_common::gameplay_modes::Mode::new( + self.style.into(), + strafesnet_common::model::ModelId::new(self.start), + self.zones.into_iter().map(|(model_id,zone)| + (strafesnet_common::model::ModelId::new(model_id),zone.into()) + ).collect(), + self.stages.into_iter().map(Into::into).collect(), + self.elements.into_iter().map(|(model_id,stage_element)| + (strafesnet_common::model::ModelId::new(model_id),stage_element.into()) + ).collect(), + ) + } +} diff --git a/src/newtypes/gameplay_style.rs b/src/newtypes/gameplay_style.rs new file mode 100644 index 0000000..71c8320 --- /dev/null +++ b/src/newtypes/gameplay_style.rs @@ -0,0 +1,218 @@ +use super::integer::{Time,Ratio64,Planar64,Planar64Vec3}; + +pub type Controls=u32; + +#[binrw::binrw] +#[brw(little)] +pub struct StyleModifiers{ + pub controls_mask:Controls, + pub controls_mask_state:Controls, + pub strafe:Option, + pub rocket:Option, + pub jump:Option, + pub walk:Option, + pub ladder:Option, + pub swim:Option, + pub gravity:Planar64Vec3, + pub hitbox:Hitbox, + pub camera_offset:Planar64Vec3, + pub mass:Planar64, +} +impl Into for StyleModifiers{ + fn into(self)->strafesnet_common::gameplay_style::StyleModifiers{ + strafesnet_common::gameplay_style::StyleModifiers{ + //TODO: fail gracefully in binrw instead of panicing here + controls_mask:strafesnet_common::controls_bitflag::Controls::from_bits(self.controls_mask).unwrap(), + controls_mask_state:strafesnet_common::controls_bitflag::Controls::from_bits(self.controls_mask_state).unwrap(), + strafe:self.strafe.map(Into::into), + rocket:self.rocket.map(Into::into), + jump:self.jump.map(Into::into), + walk:self.walk.map(Into::into), + ladder:self.ladder.map(Into::into), + swim:self.swim.map(Into::into), + gravity:strafesnet_common::integer::Planar64Vec3::raw_array(self.gravity), + hitbox:self.hitbox.into(), + camera_offset:strafesnet_common::integer::Planar64Vec3::raw_array(self.camera_offset), + mass:strafesnet_common::integer::Planar64::raw(self.mass), + } + } +} + +#[binrw::binrw] +#[brw(little,repr=u8)] +pub enum JumpCalculation{ + Capped, + Energy, + Linear, +} +impl Into for JumpCalculation{ + fn into(self)->strafesnet_common::gameplay_style::JumpCalculation{ + match self{ + JumpCalculation::Capped=>strafesnet_common::gameplay_style::JumpCalculation::Capped, + JumpCalculation::Energy=>strafesnet_common::gameplay_style::JumpCalculation::Energy, + JumpCalculation::Linear=>strafesnet_common::gameplay_style::JumpCalculation::Linear, + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub enum JumpImpulse{ + FromTime(Time), + FromHeight(Planar64), + FromDeltaV(Planar64), + FromEnergy(Planar64), +} +impl Into for JumpImpulse{ + fn into(self)->strafesnet_common::gameplay_style::JumpImpulse{ + match self{ + JumpImpulse::FromTime(time)=>strafesnet_common::gameplay_style::JumpImpulse::FromTime(strafesnet_common::integer::Time::raw(time)), + JumpImpulse::FromHeight(height)=>strafesnet_common::gameplay_style::JumpImpulse::FromHeight(strafesnet_common::integer::Planar64::raw(height)), + JumpImpulse::FromDeltaV(deltav)=>strafesnet_common::gameplay_style::JumpImpulse::FromDeltaV(strafesnet_common::integer::Planar64::raw(deltav)), + JumpImpulse::FromEnergy(energy)=>strafesnet_common::gameplay_style::JumpImpulse::FromEnergy(strafesnet_common::integer::Planar64::raw(energy)), + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct ControlsActivation{ + controls_mask:Controls, + controls_intersects:Controls, + controls_contains:Controls, +} +impl Into for ControlsActivation{ + fn into(self)->strafesnet_common::gameplay_style::ControlsActivation{ + strafesnet_common::gameplay_style::ControlsActivation::new( + strafesnet_common::controls_bitflag::Controls::from_bits(self.controls_mask).unwrap(), + strafesnet_common::controls_bitflag::Controls::from_bits(self.controls_intersects).unwrap(), + strafesnet_common::controls_bitflag::Controls::from_bits(self.controls_contains).unwrap(), + ) + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct StrafeSettings{ + enable:ControlsActivation, + mv:Planar64, + air_accel_limit:Option, + tick_rate:Ratio64, +} +impl Into for StrafeSettings{ + fn into(self)->strafesnet_common::gameplay_style::StrafeSettings{ + strafesnet_common::gameplay_style::StrafeSettings::new( + self.enable.into(), + strafesnet_common::integer::Planar64::raw(self.mv), + self.air_accel_limit.map(strafesnet_common::integer::Planar64::raw), + self.tick_rate.into(), + ) + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct PropulsionSettings{ + magnitude:Planar64, +} +impl Into for PropulsionSettings{ + fn into(self)->strafesnet_common::gameplay_style::PropulsionSettings{ + strafesnet_common::gameplay_style::PropulsionSettings::new( + strafesnet_common::integer::Planar64::raw(self.magnitude) + ) + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct JumpSettings{ + impulse:JumpImpulse, + calculation:JumpCalculation, +} +impl Into for JumpSettings{ + fn into(self)->strafesnet_common::gameplay_style::JumpSettings{ + strafesnet_common::gameplay_style::JumpSettings::new( + self.impulse.into(), + self.calculation.into(), + ) + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct AccelerateSettings{ + accel:Planar64, + topspeed:Planar64, +} +impl Into for AccelerateSettings{ + fn into(self)->strafesnet_common::gameplay_style::AccelerateSettings{ + strafesnet_common::gameplay_style::AccelerateSettings::new( + strafesnet_common::integer::Planar64::raw(self.accel), + strafesnet_common::integer::Planar64::raw(self.topspeed), + ) + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct WalkSettings{ + accelerate:AccelerateSettings, + static_friction:Planar64, + kinetic_friction:Planar64, + surf_dot:Planar64, +} +impl Into for WalkSettings{ + fn into(self)->strafesnet_common::gameplay_style::WalkSettings{ + strafesnet_common::gameplay_style::WalkSettings::new( + self.accelerate.into(), + strafesnet_common::integer::Planar64::raw(self.static_friction), + strafesnet_common::integer::Planar64::raw(self.kinetic_friction), + strafesnet_common::integer::Planar64::raw(self.surf_dot), + ) + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct LadderSettings{ + accelerate:AccelerateSettings, + dot:Planar64, +} +impl Into for LadderSettings{ + fn into(self)->strafesnet_common::gameplay_style::LadderSettings{ + strafesnet_common::gameplay_style::LadderSettings::new( + self.accelerate.into(), + strafesnet_common::integer::Planar64::raw(self.dot), + ) + } +} + +#[binrw::binrw] +#[brw(little,repr=u8)] +pub enum HitboxMesh{ + Box, + Cylinder, +} +impl Into for HitboxMesh{ + fn into(self)->strafesnet_common::gameplay_style::HitboxMesh{ + match self{ + HitboxMesh::Box=>strafesnet_common::gameplay_style::HitboxMesh::Box, + HitboxMesh::Cylinder=>strafesnet_common::gameplay_style::HitboxMesh::Cylinder, + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct Hitbox{ + pub halfsize:Planar64Vec3, + pub mesh:HitboxMesh, +} +impl Into for Hitbox{ + fn into(self)->strafesnet_common::gameplay_style::Hitbox{ + strafesnet_common::gameplay_style::Hitbox{ + halfsize:strafesnet_common::integer::Planar64Vec3::raw_array(self.halfsize), + mesh:self.mesh.into(), + } + } +} diff --git a/src/newtypes/integer.rs b/src/newtypes/integer.rs new file mode 100644 index 0000000..86a8b8c --- /dev/null +++ b/src/newtypes/integer.rs @@ -0,0 +1,26 @@ +pub type Time=i64; + +#[binrw::binrw] +#[brw(little)] +pub struct Ratio64{ + num:i64, + den:u64, +} +impl Into for Ratio64{ + fn into(self)->strafesnet_common::integer::Ratio64{ + strafesnet_common::integer::Ratio64::new(self.num,self.den).unwrap() + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct Ratio64Vec2{ + pub x:Ratio64, + pub y:Ratio64, +} + +pub type Angle32=i32; +pub type Planar64=i64; +pub type Planar64Vec3=[i64;3]; +pub type Planar64Mat3=[i64;9]; +pub type Planar64Affine3=[i64;12]; diff --git a/src/newtypes/model.rs b/src/newtypes/model.rs new file mode 100644 index 0000000..1ad02f3 --- /dev/null +++ b/src/newtypes/model.rs @@ -0,0 +1,152 @@ +use super::integer::{Planar64Vec3,Planar64Affine3}; + +pub type TextureCoordinate=[f32;2]; +pub type Color4=[f32;4]; + +#[binrw::binrw] +#[brw(little)] +pub struct IndexedVertex{ + pub pos:u32, + pub tex:u32, + pub normal:u32, + pub color:u32, +} + +#[binrw::binrw] +#[brw(little)] +pub struct Polygon{ + pub count:u32, + #[br(count=count)] + pub vertices:Vec, +} +#[binrw::binrw] +#[brw(little)] +pub struct PolygonGroup{ + pub count:u32, + #[br(count=count)] + pub polys:Vec, +} +#[binrw::binrw] +#[brw(little)] +pub struct RenderConfig{ + pub texture:Option, +} +impl Into for RenderConfig{ + fn into(self)->strafesnet_common::model::RenderConfig{ + strafesnet_common::model::RenderConfig{ + texture:self.texture.map(strafesnet_common::model::TextureId::new), + } + } +} +#[binrw::binrw] +#[brw(little)] +pub struct IndexedGraphicsGroup{ + pub count:u32, + pub render:u32, + #[br(count=count)] + pub groups:Vec, +} +#[binrw::binrw] +#[brw(little)] +pub struct IndexedPhysicsGroup{ + pub count:u32, + #[br(count=count)] + pub groups:Vec, +} + +#[binrw::binrw] +#[brw(little)] +pub struct MeshHeader{ + pub unique_pos:u32, + pub unique_normal:u32, + pub unique_tex:u32, + pub unique_color:u32, + pub unique_vertices:u32, + pub polygon_groups:u32, + pub graphics_groups:u32, + pub physics_groups:u32, +} +#[binrw::binrw] +#[brw(little)] +pub struct Mesh{ + pub header:MeshHeader, + #[br(count=header.unique_pos)] + pub unique_pos:Vec, + #[br(count=header.unique_normal)] + pub unique_normal:Vec, + #[br(count=header.unique_tex)] + pub unique_tex:Vec, + #[br(count=header.unique_color)] + pub unique_color:Vec, + #[br(count=header.unique_vertices)] + pub unique_vertices:Vec, + #[br(count=header.polygon_groups)] + pub polygon_groups:Vec, + #[br(count=header.graphics_groups)] + pub graphics_groups:Vec, + #[br(count=header.physics_groups)] + pub physics_groups:Vec, +} +impl Into for Mesh{ + fn into(self)->strafesnet_common::model::Mesh{ + strafesnet_common::model::Mesh{ + unique_pos:self.unique_pos.into_iter().map(strafesnet_common::integer::Planar64Vec3::raw_array).collect(), + unique_normal:self.unique_normal.into_iter().map(strafesnet_common::integer::Planar64Vec3::raw_array).collect(), + unique_tex:self.unique_tex.into_iter().map(strafesnet_common::model::TextureCoordinate::from_array).collect(), + unique_color:self.unique_color.into_iter().map(strafesnet_common::model::Color4::from_array).collect(), + unique_vertices:self.unique_vertices.into_iter().map(|vert|strafesnet_common::model::IndexedVertex{ + pos:strafesnet_common::model::PositionId::new(vert.pos), + tex:strafesnet_common::model::TextureCoordinateId::new(vert.tex), + normal:strafesnet_common::model::NormalId::new(vert.normal), + color:strafesnet_common::model::ColorId::new(vert.color), + }).collect(), + polygon_groups:self.polygon_groups.into_iter().map(|group| + strafesnet_common::model::PolygonGroup::PolygonList( + strafesnet_common::model::PolygonList::new( + group.polys.into_iter().map(|vert| + vert.vertices.into_iter().map(strafesnet_common::model::VertexId::new).collect() + ).collect() + ) + ) + ).collect(), + graphics_groups:self.graphics_groups.into_iter().map(|group| + strafesnet_common::model::IndexedGraphicsGroup{ + render:strafesnet_common::model::RenderConfigId::new(group.render), + groups:group.groups.into_iter().map(strafesnet_common::model::PolygonGroupId::new).collect(), + } + ).collect(), + physics_groups:self.physics_groups.into_iter().map(|group| + strafesnet_common::model::IndexedPhysicsGroup{ + groups:group.groups.into_iter().map(strafesnet_common::model::PolygonGroupId::new).collect(), + } + ).collect(), + } + } +} + +#[binrw::binrw] +#[brw(little)] +pub struct Model{ + pub mesh:u32, + pub attributes:u32, + pub color:Color4, + pub transform:Planar64Affine3, +} +impl Into for Model{ + fn into(self)->strafesnet_common::model::Model{ + let [_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b]=self.transform; + strafesnet_common::model::Model{ + mesh:strafesnet_common::model::MeshId::new(self.mesh), + attributes:strafesnet_common::gameplay_attributes::CollisionAttributesId::new(self.attributes), + color:strafesnet_common::model::Color4::from_array(self.color), + transform:strafesnet_common::integer::Planar64Affine3::new( + strafesnet_common::integer::Planar64Mat3::from_cols( + strafesnet_common::integer::Planar64Vec3::raw_xyz(_0,_1,_2), + strafesnet_common::integer::Planar64Vec3::raw_xyz(_3,_4,_5), + strafesnet_common::integer::Planar64Vec3::raw_xyz(_6,_7,_8) + ), + strafesnet_common::integer::Planar64Vec3::raw_xyz(_9,_a,_b) + ), + } + } +}