Files
guardian/crates/dcs-grpc/src/dcs/common.rs
2023-12-19 19:16:41 +01:00

152 lines
4.5 KiB
Rust

pub mod v0 {
use std::ops::Neg;
tonic::include_proto!("dcs.common.v0");
#[derive(Default, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct RawTransform {
pub position: Option<Position>,
pub position_north: Option<Vector>,
pub forward: Option<Vector>,
pub right: Option<Vector>,
pub up: Option<Vector>,
pub velocity: Option<Vector>,
}
pub(crate) struct Transform {
pub position: Position,
pub orientation: Orientation,
pub velocity: Velocity,
}
impl From<RawTransform> for Transform {
fn from(raw: RawTransform) -> Self {
let RawTransform {
position,
position_north,
forward,
right,
up,
velocity,
} = raw;
let position = position.unwrap_or_default();
let position_north = position_north.unwrap_or_default();
let forward = forward.unwrap_or_default();
let right = right.unwrap_or_default();
let up = up.unwrap_or_default();
let velocity = velocity.unwrap_or_default();
let projection_error =
(position_north.z - position.u).atan2(position_north.x - position.v);
let heading = forward.z.atan2(forward.x);
let orientation = Orientation {
heading: {
let heading = heading.to_degrees();
if heading < 0.0 {
heading + 360.0
} else {
heading
}
},
yaw: (heading - projection_error).to_degrees(),
roll: right.y.asin().neg().to_degrees(),
pitch: forward.y.asin().to_degrees(),
forward: Some(forward),
right: Some(right),
up: Some(up),
};
let velocity = Velocity {
heading: {
let heading = velocity.z.atan2(velocity.x).to_degrees();
if heading < 0.0 {
heading + 360.0
} else {
heading
}
},
speed: (velocity.x.powi(2) + velocity.z.powi(2)).sqrt(),
velocity: Some(velocity),
};
Transform {
position,
orientation,
velocity,
}
}
}
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct UnitIntermediate {
id: u32,
name: String,
callsign: String,
coalition: i32,
r#type: String,
player_name: Option<String>,
group: Option<Group>,
number_in_group: u32,
raw_transform: Option<RawTransform>,
}
impl From<UnitIntermediate> for Unit {
fn from(i: UnitIntermediate) -> Self {
let UnitIntermediate {
id,
name,
callsign,
coalition,
r#type,
player_name,
group,
number_in_group,
raw_transform,
} = i;
let transform = Transform::from(raw_transform.unwrap_or_default());
Unit {
id,
name,
callsign,
coalition,
r#type,
position: Some(transform.position),
orientation: Some(transform.orientation),
velocity: Some(transform.velocity),
player_name,
group,
number_in_group,
}
}
}
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct WeaponIntermediate {
id: u32,
r#type: String,
raw_transform: Option<RawTransform>,
}
impl From<WeaponIntermediate> for Weapon {
fn from(i: WeaponIntermediate) -> Self {
let WeaponIntermediate {
id,
r#type,
raw_transform,
} = i;
let transform = Transform::from(raw_transform.unwrap_or_default());
Weapon {
id,
r#type,
position: Some(transform.position),
orientation: Some(transform.orientation),
velocity: Some(transform.velocity),
}
}
}
}