use serde::{Deserialize, Serialize};
use ts_rs::TS;
use super::base_types::*;
use super::devices::CoordinateSystem;
use super::navigation::NavigationConfigure;
use super::sdf::{SdfCommand, SdfHfxObject, SdfOutputConfigure};
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct ForceInput {
pub device_id: String,
pub forces: Force,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct PositionInput {
pub device_id: String,
pub positions: Linear3D,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct ExtensionDataInput {
pub device_id: String,
pub extension_data: Vec<i32>,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct AngularTorqueInput {
pub device_id: String,
pub torques: Angular3D,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct AngularPositionInput {
pub device_id: String,
pub angles: Angular3D,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct TransformPatch {
#[serde(skip_serializing_if = "Option::is_none")]
pub position: Option<Linear3D>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rotation: Option<Orientation4D>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scale: Option<Linear3D>,
}
fn default_true() -> bool {
true
}
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SetCursorForceCmd {
pub vector: Force,
#[serde(default = "default_true")]
pub execute: bool,
}
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SetCursorPositionCmd {
pub position: Linear3D,
#[serde(default = "default_true")]
pub execute: bool,
}
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SetAngularTorquesCmd {
pub torques: Angular3D,
#[serde(default = "default_true")]
pub execute: bool,
}
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SetAngularPositionCmd {
pub angles: Angular3D,
#[serde(default = "default_true")]
pub execute: bool,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SetTransformCmd {
pub transform: TransformPatch,
#[serde(default = "default_true")]
pub execute: bool,
}
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct ProbeCmd {}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SetExtensionDataCmd {
pub extension_data: Vec<i32>,
}
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
pub struct Inverse3CommandClear {
pub set_cursor_force: bool,
pub set_cursor_position: bool,
pub set_angular_torques: bool,
pub set_angular_position: bool,
pub set_transform: bool,
pub probe_position: bool,
pub set_damping: bool,
pub sdf: bool,
}
impl Inverse3CommandClear {
pub fn all() -> Self {
Self {
set_cursor_force: true,
set_cursor_position: true,
set_angular_torques: true,
set_angular_position: true,
set_transform: true,
probe_position: true,
set_damping: true,
sdf: true,
}
}
pub fn any(&self) -> bool {
self.set_cursor_force
|| self.set_cursor_position
|| self.set_angular_torques
|| self.set_angular_position
|| self.set_transform
|| self.probe_position
|| self.set_damping
|| self.sdf
}
}
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
pub struct VerseGripCommandClear {
pub set_transform: bool,
pub probe_orientation: bool,
pub set_extension_data: bool,
}
impl VerseGripCommandClear {
pub fn all() -> Self {
Self {
set_transform: true,
probe_orientation: true,
set_extension_data: true,
}
}
pub fn any(&self) -> bool {
self.set_transform || self.probe_orientation || self.set_extension_data
}
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct Inverse3Commands {
#[serde(skip_serializing_if = "Option::is_none")]
pub set_cursor_force: Option<SetCursorForceCmd>,
#[serde(skip_serializing_if = "Option::is_none")]
pub set_cursor_position: Option<SetCursorPositionCmd>,
#[serde(skip_serializing_if = "Option::is_none")]
pub set_angular_torques: Option<SetAngularTorquesCmd>,
#[serde(skip_serializing_if = "Option::is_none")]
pub set_angular_position: Option<SetAngularPositionCmd>,
#[serde(skip_serializing_if = "Option::is_none")]
pub set_transform: Option<SetTransformCmd>,
#[serde(skip_serializing_if = "Option::is_none")]
pub probe_position: Option<ProbeCmd>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sdf: Option<SdfCommand>,
}
impl Inverse3Commands {
pub fn is_empty(&self) -> bool {
self.set_cursor_force.is_none()
&& self.set_cursor_position.is_none()
&& self.set_angular_torques.is_none()
&& self.set_angular_position.is_none()
&& self.set_transform.is_none()
&& self.probe_position.is_none()
&& self.sdf.is_none()
}
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct VerseGripCommands {
#[serde(skip_serializing_if = "Option::is_none")]
pub set_transform: Option<SetTransformCmd>,
#[serde(skip_serializing_if = "Option::is_none")]
pub probe_orientation: Option<ProbeCmd>,
#[serde(skip_serializing_if = "Option::is_none")]
pub set_extension_data: Option<SetExtensionDataCmd>,
}
impl VerseGripCommands {
pub fn is_empty(&self) -> bool {
self.set_transform.is_none()
&& self.probe_orientation.is_none()
&& self.set_extension_data.is_none()
}
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct PresetConfig {
pub preset: String,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct MountConfig {
pub transform: TransformPatch,
}
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct DampingConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub scalar: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub vector: Option<Linear3D>,
}
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct ForceGateConfig {
pub gain: f32,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct ProfileConfig {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub required_version: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct Inverse3Configure {
#[serde(skip_serializing_if = "Option::is_none")]
pub preset: Option<PresetConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub basis: Option<CoordinateSystem>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mount: Option<MountConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub damping: Option<DampingConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub force_gate: Option<ForceGateConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub navigation: Option<NavigationConfigure>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sdf: Option<SdfOutputConfigure>,
}
impl Inverse3Configure {
pub fn is_empty(&self) -> bool {
self.preset.is_none() &&
self.basis.is_none() &&
self.mount.is_none() &&
self.damping.is_none() &&
self.force_gate.is_none() &&
self.navigation.is_none() &&
self.sdf.is_none()
}
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct VerseGripConfigure {
#[serde(skip_serializing_if = "Option::is_none")]
pub preset: Option<PresetConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub basis: Option<CoordinateSystem>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mount: Option<MountConfig>,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SessionConfigure {
#[serde(skip_serializing_if = "Option::is_none")]
pub profile: Option<ProfileConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub basis: Option<CoordinateSystem>,
#[serde(skip_serializing_if = "Option::is_none")]
pub serialization: Option<SessionSerializationConfigure>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sdf: Option<SdfOutputConfigure>,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SessionSerializationConfigure {
#[serde(skip_serializing_if = "Option::is_none")]
pub wireless_verse_grip: Option<SessionWvgSerializationConfigure>,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SessionWvgSerializationConfigure {
#[serde(skip_serializing_if = "Option::is_none")]
pub legacy_mode: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub explicit_custom: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub extended_data: Option<SessionWvgExtendedDataConfigure>,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SessionWvgExtendedDataConfigure {
#[serde(skip_serializing_if = "Option::is_none")]
pub raw_data: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_fields: Option<bool>,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct Inverse3OutMsg {
pub device_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub commands: Option<Inverse3Commands>,
#[serde(skip_serializing_if = "Option::is_none")]
pub configure: Option<Inverse3Configure>,
}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct VerseGripOutMsg {
pub device_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub commands: Option<VerseGripCommands>,
#[serde(skip_serializing_if = "Option::is_none")]
pub configure: Option<VerseGripConfigure>,
}
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct ForceRenderFullStateMsg {}
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SessionMsg {
#[serde(skip_serializing_if = "Option::is_none")]
pub force_render_full_state: Option<ForceRenderFullStateMsg>,
#[serde(skip_serializing_if = "Option::is_none")]
pub configure: Option<SessionConfigure>,
}
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, TS)]
pub struct ServiceMsg {
pub session: SessionMsg,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub inverse3: Vec<Inverse3OutMsg>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub verse_grip: Vec<VerseGripOutMsg>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub wireless_verse_grip: Vec<VerseGripOutMsg>,
}
impl Default for ServiceMsg {
fn default() -> Self {
ServiceMsg {
session: SessionMsg {
force_render_full_state: Some(ForceRenderFullStateMsg {}),
configure: None,
},
inverse3: Vec::new(),
verse_grip: Vec::new(),
wireless_verse_grip: Vec::new(),
}
}
}
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, TS)]
pub enum Command {
SetCursorForce { device_id: String, vector: Force, execute: bool },
SetCursorPosition { device_id: String, position: Linear3D, execute: bool },
SetAngularTorques { device_id: String, torques: Angular3D, execute: bool },
SetAngularPosition { device_id: String, angles: Angular3D, execute: bool },
SetI3Transform { device_id: String, transform: TransformPatch, execute: bool },
ProbePosition { device_id: String },
ProbeOrientation { device_id: String },
SetExtensionData { device_id: String, extension_data: Vec<i32> },
SetVgTransform { device_id: String, transform: TransformPatch, execute: bool },
SdfSet { device_id: String, objects: Vec<SdfHfxObject>, from_space: Option<String> },
SdfUpdate { device_id: String, objects: Vec<SdfHfxObject> },
SdfRemove { device_id: String, ids: Vec<String> },
SetDamping { device_id: String, damping: DampingConfig },
ConfigureInverse3 { device_id: String, config: Inverse3Configure },
ConfigureVerseGrip { device_id: String, config: VerseGripConfigure },
ConfigureSession(SessionConfigure),
ConfigureSdfOutput { device_id: String, state_output: bool },
ForceRenderFullState,
PingService,
}