From 361093e3612c63d4f168d1e7a06992840aed9cf2 Mon Sep 17 00:00:00 2001 From: VirxEC Date: Fri, 11 Aug 2023 23:18:20 -0400 Subject: [PATCH] Add boost to CarState --- Cargo.lock | 2 +- Cargo.toml | 2 +- pytest.py | 4 ++-- src/bytes.rs | 66 ++++++++++++++++++++++++++-------------------------- src/lib.rs | 5 ++-- 5 files changed, 40 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a925a1f..4505fa8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,7 +175,7 @@ dependencies = [ [[package]] name = "rlviser-py" -version = "0.3.0" +version = "0.3.1" dependencies = [ "glam", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index c5d62bc..ce66410 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rlviser-py" -version = "0.3.0" +version = "0.3.1" edition = "2021" description = "Python implementation that manages a UDP connection to RLViser" license = "MIT" diff --git a/pytest.py b/pytest.py index 97c0e27..93cc285 100644 --- a/pytest.py +++ b/pytest.py @@ -11,9 +11,9 @@ # Setup example arena car = arena.add_car(rs.Team.BLUE) -car.set_state(rs.CarState(pos=rs.Vec(z=17), vel=rs.Vec(x=50))) +car.set_state(rs.CarState(pos=rs.Vec(z=17), vel=rs.Vec(x=50), boost=100)) arena.ball.set_state(rs.BallState(pos=rs.Vec(y=400, z=100), ang_vel=rs.Vec(x=5))) -car.set_controls(rs.CarControls(throttle=1, steer=1)) +car.set_controls(rs.CarControls(throttle=1, steer=1, boost=True)) # Run for 3 seconds diff --git a/src/bytes.rs b/src/bytes.rs index 8a68578..8d38fc2 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -1,6 +1,6 @@ use core::panic; -use glam::{Mat3A, Quat, Vec3A}; +use glam::{Mat3, Quat, Vec3 as Vec3G}; use pyo3::FromPyObject; #[derive(Clone, Copy, Debug, Default, FromPyObject)] @@ -32,9 +32,9 @@ impl From<[f32; 3]> for Vec3 { } } -impl From for Vec3 { +impl From for Vec3 { #[inline] - fn from(value: Vec3A) -> Self { + fn from(value: Vec3G) -> Self { Self::new(value.x, value.y, value.z) } } @@ -66,9 +66,9 @@ impl RotMat { } } -impl From for RotMat { +impl From for RotMat { #[inline] - fn from(value: Mat3A) -> Self { + fn from(value: Mat3) -> Self { Self { forward: value.x_axis.into(), right: value.y_axis.into(), @@ -284,10 +284,10 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarConfig { impl ToBytesExact<{ Self::NUM_BYTES }> for BallHitInfo { fn to_bytes(&self) -> [u8; Self::NUM_BYTES] { let mut bytes = [0; Self::NUM_BYTES]; - bytes[..1].copy_from_slice(&(self.is_valid as u8).to_le_bytes()); - bytes[1..1 + Vec3::NUM_BYTES].copy_from_slice(&self.relative_pos_on_ball.to_bytes()); - bytes[1 + Vec3::NUM_BYTES..1 + Vec3::NUM_BYTES * 2].copy_from_slice(&self.ball_pos.to_bytes()); - bytes[1 + Vec3::NUM_BYTES * 2..1 + Vec3::NUM_BYTES * 3].copy_from_slice(&self.extra_hit_vel.to_bytes()); + bytes[..1].copy_from_slice(&u8::from(self.is_valid).to_le_bytes()); + bytes[1..=Vec3::NUM_BYTES].copy_from_slice(&self.relative_pos_on_ball.to_bytes()); + bytes[(1 + Vec3::NUM_BYTES)..=(Vec3::NUM_BYTES * 2)].copy_from_slice(&self.ball_pos.to_bytes()); + bytes[(1 + Vec3::NUM_BYTES * 2)..=(Vec3::NUM_BYTES * 3)].copy_from_slice(&self.extra_hit_vel.to_bytes()); bytes[1 + Vec3::NUM_BYTES * 3..1 + Vec3::NUM_BYTES * 3 + u64::NUM_BYTES] .copy_from_slice(&self.tick_count_when_hit.to_le_bytes()); bytes[1 + Vec3::NUM_BYTES * 3 + u64::NUM_BYTES..] @@ -304,9 +304,9 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarControls { bytes[f32::NUM_BYTES * 2..f32::NUM_BYTES * 3].copy_from_slice(&self.pitch.to_le_bytes()); bytes[f32::NUM_BYTES * 3..f32::NUM_BYTES * 4].copy_from_slice(&self.yaw.to_le_bytes()); bytes[f32::NUM_BYTES * 4..f32::NUM_BYTES * 5].copy_from_slice(&self.roll.to_le_bytes()); - bytes[f32::NUM_BYTES * 5..f32::NUM_BYTES * 5 + 1].copy_from_slice(&(self.boost as u8).to_le_bytes()); - bytes[f32::NUM_BYTES * 5 + 1..f32::NUM_BYTES * 5 + 2].copy_from_slice(&(self.jump as u8).to_le_bytes()); - bytes[f32::NUM_BYTES * 5 + 2..].copy_from_slice(&(self.handbrake as u8).to_le_bytes()); + bytes[(f32::NUM_BYTES * 5)..=(f32::NUM_BYTES * 5)].copy_from_slice(&u8::from(self.boost).to_le_bytes()); + bytes[f32::NUM_BYTES * 5 + 1..f32::NUM_BYTES * 5 + 2].copy_from_slice(&u8::from(self.jump).to_le_bytes()); + bytes[f32::NUM_BYTES * 5 + 2..].copy_from_slice(&u8::from(self.handbrake).to_le_bytes()); bytes } } @@ -325,17 +325,17 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarState { bytes[Vec3::NUM_BYTES * 2 + RotMat::NUM_BYTES..Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES] .copy_from_slice(&self.ang_vel.to_bytes()); // is_on_ground: bool, - bytes[Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES..Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES + 1] - .copy_from_slice(&(self.is_on_ground as u8).to_le_bytes()); + bytes[(Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES)..=(Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES)] + .copy_from_slice(&u8::from(self.is_on_ground).to_le_bytes()); // has_jumped: bool, bytes[Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES + 1..Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES + 2] - .copy_from_slice(&(self.has_jumped as u8).to_le_bytes()); + .copy_from_slice(&u8::from(self.has_jumped).to_le_bytes()); // has_double_jumped: bool, bytes[Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES + 2..Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES + 3] - .copy_from_slice(&(self.has_double_jumped as u8).to_le_bytes()); + .copy_from_slice(&u8::from(self.has_double_jumped).to_le_bytes()); // has_flipped: bool, bytes[Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES + 3..Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES + 4] - .copy_from_slice(&(self.has_flipped as u8).to_le_bytes()); + .copy_from_slice(&u8::from(self.has_flipped).to_le_bytes()); // last_rel_dodge_torque: Vec3, bytes[Vec3::NUM_BYTES * 3 + RotMat::NUM_BYTES + 4..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 4] .copy_from_slice(&self.last_rel_dodge_torque.to_bytes()); @@ -349,11 +349,11 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarState { // is_flipping: bool, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 4 + f32::NUM_BYTES * 2 ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 2] - .copy_from_slice(&(self.is_flipping as u8).to_le_bytes()); + .copy_from_slice(&u8::from(self.is_flipping).to_le_bytes()); // is_jumping: bool, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 5 + f32::NUM_BYTES * 2 ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 2] - .copy_from_slice(&(self.is_jumping as u8).to_le_bytes()); + .copy_from_slice(&u8::from(self.is_jumping).to_le_bytes()); // air_time_since_jump: f32, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 2 ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 3] @@ -369,7 +369,7 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarState { // is_supersonic: bool, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 6 + f32::NUM_BYTES * 5 ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 5] - .copy_from_slice(&(self.is_supersonic as u8).to_le_bytes()); + .copy_from_slice(&u8::from(self.is_supersonic).to_le_bytes()); // supersonic_time: f32, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 5 ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 6] @@ -381,7 +381,7 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarState { // is_auto_flipping: bool, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 7 + f32::NUM_BYTES * 7 ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 7] - .copy_from_slice(&(self.is_auto_flipping as u8).to_le_bytes()); + .copy_from_slice(&u8::from(self.is_auto_flipping).to_le_bytes()); // auto_flip_timer: f32, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 7 ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 8] @@ -393,7 +393,7 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarState { // has_contact: bool, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 8 + f32::NUM_BYTES * 9 ..Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9] - .copy_from_slice(&(self.has_world_contact as u8).to_le_bytes()); + .copy_from_slice(&u8::from(self.has_world_contact).to_le_bytes()); // contact_normal: Vec3, bytes[Vec3::NUM_BYTES * 4 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9 ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 9] @@ -409,7 +409,7 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarState { // is_demoed: bool, bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 9 + f32::NUM_BYTES * 10 + u32::NUM_BYTES ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 10 + u32::NUM_BYTES] - .copy_from_slice(&(self.is_demoed as u8).to_le_bytes()); + .copy_from_slice(&u8::from(self.is_demoed).to_le_bytes()); // demo_respawn_timer: f32, bytes[Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 10 + u32::NUM_BYTES ..Vec3::NUM_BYTES * 5 + RotMat::NUM_BYTES + 10 + f32::NUM_BYTES * 11 + u32::NUM_BYTES] @@ -430,7 +430,7 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarInfo { fn to_bytes(&self) -> [u8; Self::NUM_BYTES] { let mut bytes = [0; Self::NUM_BYTES]; bytes[..u32::NUM_BYTES].copy_from_slice(&self.id.to_le_bytes()); - bytes[u32::NUM_BYTES..u32::NUM_BYTES + 1].copy_from_slice(&(self.team as u8).to_le_bytes()); + bytes[u32::NUM_BYTES..=u32::NUM_BYTES].copy_from_slice(&(self.team as u8).to_le_bytes()); bytes[u32::NUM_BYTES + 1..u32::NUM_BYTES + 1 + CarState::NUM_BYTES].copy_from_slice(&self.state.to_bytes()); bytes[u32::NUM_BYTES + 1 + CarState::NUM_BYTES..].copy_from_slice(&self.config.to_bytes()); bytes @@ -440,7 +440,7 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for CarInfo { impl ToBytesExact<{ Self::NUM_BYTES }> for BoostPadState { fn to_bytes(&self) -> [u8; Self::NUM_BYTES] { let mut bytes = [0; Self::NUM_BYTES]; - bytes[..1].copy_from_slice(&(self.is_active as u8).to_le_bytes()); + bytes[..1].copy_from_slice(&u8::from(self.is_active).to_le_bytes()); bytes[1..5].copy_from_slice(&self.cooldown.to_le_bytes()); bytes[5..9].copy_from_slice(&self.cur_locked_car_id.to_le_bytes()); bytes[9..].copy_from_slice(&self.prev_locked_car_id.to_le_bytes()); @@ -451,8 +451,8 @@ impl ToBytesExact<{ Self::NUM_BYTES }> for BoostPadState { impl ToBytesExact<{ Self::NUM_BYTES }> for BoostPad { fn to_bytes(&self) -> [u8; Self::NUM_BYTES] { let mut bytes = [0; Self::NUM_BYTES]; - bytes[..1].copy_from_slice(&(self.is_big as u8).to_le_bytes()); - bytes[1..1 + Vec3::NUM_BYTES].copy_from_slice(&self.position.to_bytes()); + bytes[..1].copy_from_slice(&u8::from(self.is_big).to_le_bytes()); + bytes[1..=Vec3::NUM_BYTES].copy_from_slice(&self.position.to_bytes()); bytes[1 + Vec3::NUM_BYTES..].copy_from_slice(&self.state.to_bytes()); bytes } @@ -561,7 +561,7 @@ impl FromBytesExact for BoostPadState { fn from_bytes(bytes: &[u8]) -> Self { Self { is_active: bytes[0] != 0, - cooldown: f32::from_bytes(&bytes[1..1 + f32::NUM_BYTES]), + cooldown: f32::from_bytes(&bytes[1..=f32::NUM_BYTES]), cur_locked_car_id: u32::from_bytes(&bytes[1 + f32::NUM_BYTES..1 + f32::NUM_BYTES + u32::NUM_BYTES]), prev_locked_car_id: u32::from_bytes(&bytes[1 + f32::NUM_BYTES + u32::NUM_BYTES..]), } @@ -575,7 +575,7 @@ impl FromBytesExact for BoostPad { fn from_bytes(bytes: &[u8]) -> Self { Self { is_big: bytes[0] != 0, - position: Vec3::from_bytes(&bytes[1..1 + Vec3::NUM_BYTES]), + position: Vec3::from_bytes(&bytes[1..=Vec3::NUM_BYTES]), state: BoostPadState::from_bytes(&bytes[1 + Vec3::NUM_BYTES..Self::NUM_BYTES]), } } @@ -601,9 +601,9 @@ impl FromBytesExact for BallHitInfo { fn from_bytes(bytes: &[u8]) -> Self { Self { is_valid: bytes[0] != 0, - relative_pos_on_ball: Vec3::from_bytes(&bytes[1..1 + Vec3::NUM_BYTES]), - ball_pos: Vec3::from_bytes(&bytes[1 + Vec3::NUM_BYTES..1 + Vec3::NUM_BYTES * 2]), - extra_hit_vel: Vec3::from_bytes(&bytes[1 + Vec3::NUM_BYTES * 2..1 + Vec3::NUM_BYTES * 3]), + relative_pos_on_ball: Vec3::from_bytes(&bytes[1..=Vec3::NUM_BYTES]), + ball_pos: Vec3::from_bytes(&bytes[(1 + Vec3::NUM_BYTES)..=(Vec3::NUM_BYTES * 2)]), + extra_hit_vel: Vec3::from_bytes(&bytes[(1 + Vec3::NUM_BYTES * 2)..=(Vec3::NUM_BYTES * 3)]), tick_count_when_hit: u64::from_bytes(&bytes[1 + Vec3::NUM_BYTES * 3..1 + Vec3::NUM_BYTES * 3 + u64::NUM_BYTES]), tick_count_when_extra_impulse_applied: u64::from_bytes(&bytes[1 + Vec3::NUM_BYTES * 3 + u64::NUM_BYTES..]), } @@ -772,7 +772,7 @@ impl FromBytesExact for CarInfo { fn from_bytes(bytes: &[u8]) -> Self { Self { id: u32::from_bytes(&bytes[..u32::NUM_BYTES]), - team: Team::from_bytes(&bytes[u32::NUM_BYTES..u32::NUM_BYTES + Team::NUM_BYTES]), + team: Team::from_bytes(&bytes[u32::NUM_BYTES..=u32::NUM_BYTES]), state: CarState::from_bytes( &bytes[u32::NUM_BYTES + Team::NUM_BYTES..u32::NUM_BYTES + Team::NUM_BYTES + CarState::NUM_BYTES], ), diff --git a/src/lib.rs b/src/lib.rs index e538933..708df6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ use crate::{ gym::GymState, }; use bytes::{BallState, CarConfig, CarInfo, CarState, GameState, Team, Vec3, WheelPairConfig}; -use glam::{Mat3A, Quat}; +use glam::{Mat3, Quat}; use gym::BOOST_PADS_LENGTH; use pyo3::prelude::*; use std::sync::{ @@ -115,11 +115,12 @@ fn render_rlgym(gym_state: GymState) { pos: player.car_data.position.into(), vel: player.car_data.linear_velocity.into(), ang_vel: player.car_data.angular_velocity.into(), - rot_mat: Mat3A::from_quat(array_to_quat(player.car_data.quaternion)).into(), + rot_mat: Mat3::from_quat(array_to_quat(player.car_data.quaternion)).into(), is_on_ground: player.on_ground != 0, is_demoed: player.is_demoed != 0, has_flipped: player.has_flip == 0, has_jumped: player.has_jump == 0, + boost: player.boost_amount, ..Default::default() }, config: OCTANE,