use godot::{ builtin::{Basis, Quaternion}, prelude::{Color, Transform3D, Vector3}, }; use rosc::{OscMessage, OscType}; use std::fmt; pub trait VmcMessage { fn to_osc_message(&self) -> OscMessage; fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> where Self: Sized; fn get_addr(&self) -> String; } pub struct ArgCountErr { expected_in: Vec, actual: usize, addr: String, } impl fmt::Display for ArgCountErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Invalid number of arguments for message with address {}. Expected {:?}, received {}.", self.addr, self.expected_in, self.actual) } } pub struct ArgTypeErr { expected: Vec, actual: OscType, addr: String, arg_count: usize, } impl fmt::Display for ArgTypeErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Invalid type of argument {} for message with address {}. Expected {:?}, received {:?}.", self.arg_count, self.addr, self.expected, self.actual) } } pub struct FromIntRangeErr { expected_lower: i32, expected_upper: i32, actual: i32, addr: String, arg_count: usize, } impl fmt::Display for FromIntRangeErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Invalid value of integer argument {} for message with address {}. Expected in range [{}, {}], received {}.", self.arg_count, self.addr, self.expected_lower, self.expected_upper, self.actual) } } pub struct StrValErr { expected_in: Vec, actual: String, addr: String, arg_count: usize, } impl fmt::Display for StrValErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Invalid value of string argument {} for message with address {}. Expected {:?}, received {:?}.", self.arg_count, self.addr, self.expected_in, self.actual) } } pub struct AddrErr { addr: String } impl fmt::Display for AddrErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Invalid address: {}", self.addr) } } pub enum FromMessageErr { ArgCount(ArgCountErr), ArgType(ArgTypeErr), IntRange(FromIntRangeErr), StrVal(StrValErr), Addr(AddrErr), } pub struct CreateIntRangeErr { expected_lower: i32, expected_upper: i32, actual: i32, calling_func: String, arg_name: String, } impl fmt::Display for CreateIntRangeErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Invalid value of integer argument \"{}\" for function \"{}\". Expected in range [{}, {}], received {}.", self.arg_name, self.calling_func, self.expected_lower, self.expected_upper, self.actual) } } pub struct CreateOptionalArgsErr { expected_sets: Vec, actual: String, calling_func: String, } impl fmt::Display for CreateOptionalArgsErr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Invalid set of optional arguments for function \"{}\". Expected set from {:?}, received [{}].", self.calling_func, self.expected_sets, self.actual) } } pub enum MessageCreationErr { IntRange(CreateIntRangeErr), OptionalArgs(CreateOptionalArgsErr), } #[derive(Debug)] struct VmcExtOk { loaded: i32, calibration_state: Option, calibration_mode: Option, tracking_status: Option, } impl VmcMessage for VmcExtOk { fn to_osc_message(&self) -> OscMessage { let addr = String::from("/VMC/Ext/OK"); let mut args: Vec = vec![OscType::from(self.loaded)]; if self.calibration_state.is_some() { args.append(&mut vec![ OscType::from(self.calibration_state.unwrap()), OscType::from(self.calibration_mode.unwrap()), ]); } if self.tracking_status.is_some() { args.push(OscType::from(self.tracking_status.unwrap())); } return OscMessage { addr, args }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { let mut result = VmcExtOk { loaded: -1, calibration_state: None, calibration_mode: None, tracking_status: None, }; if msg.args.len() == 1 || msg.args.len() == 3 || msg.args.len() == 4 { match msg.args[0] { OscType::Int(i) => { result.loaded = i; } _ => { return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(),addr: msg.addr.to_owned(), arg_count: 0})); } } if result.loaded < 0 || result.loaded > 1 { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: result.loaded, addr: msg.addr, arg_count: 0})); } } else { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1, 3, 4], actual: msg.args.len(), addr: msg.addr.to_owned()})); } if msg.args.len() == 3 || msg.args.len() == 4 { match msg.args[1] { OscType::Int(i) => { result.calibration_state = Some(i); } _ => { return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr.to_owned(), arg_count: 1})); } } if result.calibration_state.unwrap() < 0 || result.calibration_state.unwrap() > 3 { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 3, actual: result.loaded, addr: msg.addr, arg_count: 1})); } match msg.args[2] { OscType::Int(i) => { result.calibration_mode = Some(i); } _ => { return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[2].to_owned(), addr: msg.addr.to_owned(), arg_count: 2})); } } if result.calibration_mode.unwrap() < 0 || result.calibration_mode.unwrap() > 2 { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 2, actual: result.loaded, addr: msg.addr, arg_count: 2})); } } if msg.args.len() == 4 { match msg.args[3] { OscType::Int(i) => { result.tracking_status = Some(i); } _ => { return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[3].to_owned(), addr: msg.addr.to_owned(), arg_count: 3})); } } if result.tracking_status.unwrap() < 0 || result.tracking_status.unwrap() > 1 { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: result.loaded, addr: msg.addr, arg_count: 3})); } } let boxed_result: Box = Box::new(result); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/OK"); } } impl VmcExtOk { fn new(loaded: i32, calibration_state: Option, calibration_mode: Option, tracking_status: Option) -> Result { if loaded < 0 || loaded > 1 { return Err(MessageCreationErr::IntRange(CreateIntRangeErr { expected_lower: 0, expected_upper: 1, actual: loaded, calling_func: String::from("VmcExtOk::new"), arg_name: String::from("loaded")})); } if calibration_state.is_some() && calibration_mode.is_some() { if calibration_state.unwrap() < 0 || calibration_state.unwrap() > 3 { return Err(MessageCreationErr::IntRange(CreateIntRangeErr { expected_lower: 0, expected_upper: 3, actual: loaded, calling_func: String::from("VmcExtOk::new"), arg_name: String::from("calibration_state")})); } if calibration_mode.unwrap() < 0 || calibration_mode.unwrap() > 2 { return Err(MessageCreationErr::IntRange(CreateIntRangeErr { expected_lower: 0, expected_upper: 2, actual: loaded, calling_func: String::from("VmcExtOk::new"), arg_name: String::from("calibration_mode")})); } if tracking_status.is_some() && (tracking_status.unwrap() < 0 || tracking_status.unwrap() > 1) { return Err(MessageCreationErr::IntRange(CreateIntRangeErr { expected_lower: 0, expected_upper: 1, actual: loaded, calling_func: String::from("VmcExtOk::new"), arg_name: String::from("tracking_status")})); } return Ok(VmcExtOk { loaded, calibration_state, calibration_mode, tracking_status}) } if calibration_state.is_some() && tracking_status.is_none() { return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("calibration_state"), calling_func: String::from("VmcExtOk::new")})) } if calibration_mode.is_some() && tracking_status.is_none() { return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("calibration_mode"), calling_func: String::from("VmcExtOk::new")})) } if calibration_state.is_some() && tracking_status.is_some() { return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("calibration_state, tracking_status"), calling_func: String::from("VmcExtOk::new")})) } if calibration_mode.is_some() && tracking_status.is_some() { return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("calibration_mode, tracking_status"), calling_func: String::from("VmcExtOk::new")})) } if tracking_status.is_some() { return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("tracking_status"), calling_func: String::from("VmcExtOk::new")})) } return Ok(VmcExtOk { loaded, calibration_state: None, calibration_mode: None, tracking_status: None}) } fn new_vmc_message(loaded: i32, calibration_state: Option, calibration_mode: Option, tracking_status: Option) -> Result, MessageCreationErr> { let msg = Self::new(loaded, calibration_state, calibration_mode, tracking_status); if msg.is_ok() { let boxed_result: Box = Box::new(msg.ok().unwrap()); return Ok(boxed_result); } return Err(msg.err().unwrap()); } } #[derive(Debug)] struct VmcExtT { time: f32, } impl VmcMessage for VmcExtT { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/T"), args: vec![OscType::from(self.time)], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); } let time: f32; match msg.args[0] { OscType::Float(f) => time = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } let boxed_result: Box = Box::new(VmcExtT{time}); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/T"); } } impl VmcExtT { fn new(time: f32) -> Result { return Ok(VmcExtT { time }); } fn new_vmc_message(time: f32) -> Result, MessageCreationErr> { let msg = Self::new(time); if msg.is_ok() { let boxed_result: Box = Box::new(msg.ok().unwrap()); return Ok(boxed_result); } return Err(msg.err().unwrap()); } } #[derive(Debug)] struct VmcExtRootPos { name: String, transform: Transform3D, mr_scale: Option, mr_offset: Option, } impl VmcMessage for VmcExtRootPos { fn to_osc_message(&self) -> OscMessage { let addr = String::from("/VMC/Ext/Root/Pos"); let quat = self.transform.basis.to_quat(); let mut args: Vec = vec![ OscType::from(self.name.to_owned()), OscType::from(self.transform.origin.x), OscType::from(self.transform.origin.y), OscType::from(self.transform.origin.z), OscType::from(quat.x), OscType::from(quat.y), OscType::from(quat.z), OscType::from(quat.w), ]; if self.mr_offset.is_some() { args.append(&mut vec![ OscType::from(self.mr_scale.unwrap().x), OscType::from(self.mr_scale.unwrap().y), OscType::from(self.mr_scale.unwrap().z), OscType::from(self.mr_offset.unwrap().x), OscType::from(self.mr_offset.unwrap().y), OscType::from(self.mr_offset.unwrap().z), ]); } return OscMessage { addr, args }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { let mut result: VmcExtRootPos; if msg.args.len() == 8 || msg.args.len() == 14 { let mut origin = Vector3::new(0.0, 0.0, 0.0); let name: String; match &msg.args[0] { OscType::String(s) => name = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Float(f) => origin.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Float(f) => origin.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } match msg.args[3] { OscType::Float(f) => origin.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } let mut quat = Quaternion { x: 0.0, y: 0.0, z: 0.0, w: 0.0, }; match msg.args[4] { OscType::Float(f) => quat.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[4].to_owned(), addr: msg.addr, arg_count: 4})), } match msg.args[5] { OscType::Float(f) => quat.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[5].to_owned(), addr: msg.addr, arg_count: 5})), } match msg.args[6] { OscType::Float(f) => quat.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[6].to_owned(), addr: msg.addr, arg_count: 6})), } match msg.args[7] { OscType::Float(f) => quat.w = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[7].to_owned(), addr: msg.addr, arg_count: 7})), } result = VmcExtRootPos { name, transform: Transform3D::new(Basis::from_quat(quat), origin), mr_scale: None, mr_offset: None, }; } else { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![8, 14], actual: msg.args.len(), addr: msg.addr})); } if msg.args.len() == 14 { result.mr_scale = Some(Vector3 { x: 0.0, y: 0.0, z: 0.0, }); result.mr_offset = Some(Vector3 { x: 0.0, y: 0.0, z: 0.0, }); match msg.args[8] { OscType::Float(f) => result.mr_scale.unwrap().x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[8].to_owned(), addr: msg.addr, arg_count: 8})), } match msg.args[9] { OscType::Float(f) => result.mr_scale.unwrap().y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[9].to_owned(), addr: msg.addr, arg_count: 9})), } match msg.args[10] { OscType::Float(f) => result.mr_scale.unwrap().z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[10].to_owned(), addr: msg.addr, arg_count: 10})), } match msg.args[11] { OscType::Float(f) => result.mr_offset.unwrap().x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[11].to_owned(), addr: msg.addr, arg_count: 11})), } match msg.args[12] { OscType::Float(f) => result.mr_offset.unwrap().y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[12].to_owned(), addr: msg.addr, arg_count: 12})), } match msg.args[13] { OscType::Float(f) => result.mr_offset.unwrap().z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[13].to_owned(), addr: msg.addr, arg_count: 13})), } } let boxed_result: Box = Box::new(result); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Root/Pos"); } } impl VmcExtRootPos { fn new(name: String, transform: Transform3D, mr_scale: Option, mr_offset: Option) -> Result { if mr_scale.is_some() && mr_offset.is_none() { return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("mr_scale, mr_offset")], actual: String::from("mr_scale"), calling_func: String::from("VmcExtRootPos::new")})); } if mr_scale.is_none() && mr_offset.is_some() { return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("mr_scale, mr_offset")], actual: String::from("mr_offset"), calling_func: String::from("VmcExtRootPos::new")})) } return Ok(VmcExtRootPos { name, transform, mr_scale, mr_offset}); } fn new_vmc_message(name: String, transform: Transform3D, mr_scale: Option, mr_offset: Option) -> Result, MessageCreationErr> { let message = Self::new(name, transform, mr_scale, mr_offset); if message.is_ok() { let boxed_result: Box = Box::new(message.ok().unwrap()); return Ok(boxed_result); } return Err(message.err().unwrap()); } } #[derive(Debug)] struct VmcExtBonePos { name: String, transform: Transform3D, } impl VmcMessage for VmcExtBonePos { fn to_osc_message(&self) -> OscMessage { let quat = self.transform.basis.to_quat(); return OscMessage { addr: String::from("/VMC/Ext/Bone/Pos"), args: vec![ OscType::from(self.name.to_owned()), OscType::from(self.transform.origin.x), OscType::from(self.transform.origin.y), OscType::from(self.transform.origin.z), OscType::from(quat.x), OscType::from(quat.y), OscType::from(quat.z), OscType::from(quat.w), ], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { let name: String; let mut origin = Vector3::new(0.0, 0.0, 0.0); if msg.args.len() != 8 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![8], actual: msg.args.len(), addr: msg.addr})); } match &msg.args[0] { OscType::String(s) => name = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Float(f) => origin.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Float(f) => origin.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } match msg.args[3] { OscType::Float(f) => origin.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } let mut quat = Quaternion { x: 0.0, y: 0.0, z: 0.0, w: 0.0, }; match msg.args[4] { OscType::Float(f) => quat.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[4].to_owned(), addr: msg.addr, arg_count: 4})), } match msg.args[5] { OscType::Float(f) => quat.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[5].to_owned(), addr: msg.addr, arg_count: 5})), } match msg.args[6] { OscType::Float(f) => quat.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[6].to_owned(), addr: msg.addr, arg_count: 6})), } match msg.args[7] { OscType::Float(f) => quat.w = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[7].to_owned(), addr: msg.addr, arg_count: 7})), } let boxed_result: Box = Box::new(VmcExtBonePos { name, transform: Transform3D::new(Basis::from_quat(quat), origin), }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Bone/Pos"); } } impl VmcExtBonePos { fn new(name: String, transform: Transform3D) -> Result { return Ok(VmcExtBonePos{name, transform}); } fn new_vmc_message(name: String, transform: Transform3D) -> Result, MessageCreationErr> { let message = Self::new(name, transform); if message.is_ok() { let boxed_result: Box = Box::new(message.ok().unwrap()); return Ok(boxed_result); } return Err(message.err().unwrap()); } } #[derive(Debug)] struct VmcExtBlendVal { name: String, value: f32, } impl VmcMessage for VmcExtBlendVal { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Blend/Val"), args: vec![ OscType::from(self.name.to_owned()), OscType::from(self.value), ], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { let name: String; let value: f32; if msg.args.len() != 2 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2], actual: msg.args.len(), addr: msg.addr})); } match &msg.args[0] { OscType::String(s) => name = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Float(f) => value = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } let boxed_result: Box = Box::new(VmcExtBlendVal { name, value }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Blend/Val"); } } #[derive(Debug)] struct VmcExtCam { name: String, transform: Transform3D, fov: f32, } impl VmcMessage for VmcExtCam { fn to_osc_message(&self) -> OscMessage { let quat = self.transform.basis.to_quat(); return OscMessage { addr: String::from("/VMC/Ext/Cam"), args: vec![ OscType::from(self.name.to_owned()), OscType::from(self.transform.origin.x), OscType::from(self.transform.origin.y), OscType::from(self.transform.origin.z), OscType::from(quat.x), OscType::from(quat.y), OscType::from(quat.z), OscType::from(quat.w), OscType::from(self.fov), ], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 9 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![9], actual: msg.args.len(), addr: msg.addr})); } let name: String; let mut origin = Vector3::new(0.0, 0.0, 0.0); let mut quat = Quaternion::new(0.0, 0.0, 0.0, 0.0); let fov: f32; match &msg.args[0] { OscType::String(s) => name = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Float(f) => origin.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Float(f) => origin.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } match msg.args[3] { OscType::Float(f) => origin.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } match msg.args[4] { OscType::Float(f) => quat.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[4].to_owned(), addr: msg.addr, arg_count: 4})), } match msg.args[5] { OscType::Float(f) => quat.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[5].to_owned(), addr: msg.addr, arg_count: 5})), } match msg.args[6] { OscType::Float(f) => quat.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[6].to_owned(), addr: msg.addr, arg_count: 6})), } match msg.args[7] { OscType::Float(f) => quat.w = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[7].to_owned(), addr: msg.addr, arg_count: 7})), } match msg.args[8] { OscType::Float(f) => fov = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[8].to_owned(), addr: msg.addr, arg_count: 8})), } let boxed_result: Box = Box::new(VmcExtCam { name, transform: Transform3D::new(Basis::from_quat(quat), origin), fov, }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Cam"); } } #[derive(Debug)] struct VmcExtCon { active: i32, name: String, is_left: i32, is_touch: i32, axis: Vector3, } impl VmcMessage for VmcExtCon { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Con"), args: vec![ OscType::from(self.active), OscType::from(self.name.to_owned()), OscType::from(self.is_left), OscType::from(self.is_touch), OscType::from(self.axis.x), OscType::from(self.axis.y), OscType::from(self.axis.z), ], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 7 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![7], actual: msg.args.len(), addr: msg.addr})); } let active: i32; let name: String; let is_left: i32; let is_touch: i32; let mut axis = Vector3::new(0.0, 0.0, 0.0); match msg.args[0] { OscType::Int(i) => active = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } if active > 2 || active < 0 { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 2, actual: active, addr: msg.addr, arg_count: 0})); } match &msg.args[1] { OscType::String(s) => name = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Int(i) => is_left = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } if is_left < 0 || is_left > 1 { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: active, addr: msg.addr, arg_count: 2})); } match msg.args[3] { OscType::Int(i) => is_touch = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } if is_touch < 0 || is_touch > 1 { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: active, addr: msg.addr, arg_count: 3})); } match msg.args[4] { OscType::Float(f) => axis.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[4].to_owned(), addr: msg.addr, arg_count: 4})), } match msg.args[5] { OscType::Float(f) => axis.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[5].to_owned(), addr: msg.addr, arg_count: 5})), } match msg.args[6] { OscType::Float(f) => axis.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[6].to_owned(), addr: msg.addr, arg_count: 6})), } let boxed_result: Box = Box::new(VmcExtCon { active, name, is_left, is_touch, axis, }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Con"); } } #[derive(Debug)] struct VmcExtKey { active: bool, name: String, keycode: i32, } impl VmcMessage for VmcExtKey { fn to_osc_message(&self) -> OscMessage { let mut args: Vec; if self.active { args = vec![OscType::from(1)]; } else { args = vec![OscType::from(0)]; } args.append(&mut vec![ OscType::from(self.name.to_owned()), OscType::from(self.keycode), ]); return OscMessage { addr: String::from("/VMC/Ext/Key"), args, }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 3 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![3], actual: msg.args.len(), addr: msg.addr})); } let active: bool; let name: String; let keycode: i32; match msg.args[0] { OscType::Int(i) => { if i == 1 { active = true; } else if i == 0 { active = false; } else { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match &msg.args[1] { OscType::String(s) => name = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Int(i) => keycode = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } let boxed_result: Box = Box::new(VmcExtKey { active, name, keycode, }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Key"); } } #[derive(Debug)] struct VmcExtMidiNote { active: bool, channel: i32, note: i32, velocity: f32, } impl VmcMessage for VmcExtMidiNote { fn to_osc_message(&self) -> OscMessage { let mut args: Vec; if self.active { args = vec![OscType::from(1)]; } else { args = vec![OscType::from(0)]; } args.append(&mut vec![ OscType::from(self.channel), OscType::from(self.note), OscType::from(self.velocity), ]); return OscMessage { addr: String::from("/VMC/Ext/Midi/Note"), args, }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 4 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![4], actual: msg.args.len(), addr: msg.addr})); } let active: bool; let channel: i32; let note: i32; let velocity: f32; match msg.args[0] { OscType::Int(i) => { if i == 1 { active = true; } else if i == 0 { active = false; } else { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Int(i) => channel = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Int(i) => note = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } match msg.args[3] { OscType::Float(f) => velocity = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } let boxed_result: Box = Box::new(VmcExtMidiNote { active, channel, note, velocity, }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Midi/Note"); } } #[derive(Debug)] struct VmcExtMidiCcVal { knob: i32, value: f32, } impl VmcMessage for VmcExtMidiCcVal { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Midi/CC/Val"), args: vec![OscType::from(self.knob), OscType::from(self.value)], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 2 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2], actual: msg.args.len(), addr: msg.addr})); } let knob: i32; let value: f32; match msg.args[0] { OscType::Int(i) => knob = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Float(f) => value = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } let boxed_result: Box = Box::new(VmcExtMidiCcVal { knob, value }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Midi/CC/Val"); } } #[derive(Debug)] struct VmcExtMidiCcBit { knob: i32, active: bool, } impl VmcMessage for VmcExtMidiCcBit { fn to_osc_message(&self) -> OscMessage { let mut args = vec![OscType::from(self.knob)]; if self.active { args.push(OscType::from(1)); } else { args.push(OscType::from(0)); } return OscMessage { addr: String::from("/VMC/Ext/Midi/CC/Bit"), args, }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 2 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2], actual: msg.args.len(), addr: msg.addr})); } let knob: i32; let active: bool; match msg.args[0] { OscType::Int(i) => knob = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Int(i) => { if i == 0 { active = false; } else if i == 1 { active = true; } else { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 1})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } let boxed_result: Box = Box::new(VmcExtMidiCcBit { knob, active }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Midi/CC/Bit"); } } #[derive(Debug)] struct DeviceTranform { addr: String, serial: String, transform: Transform3D, } impl VmcMessage for DeviceTranform { fn to_osc_message(&self) -> OscMessage { let quat = self.transform.basis.to_quat(); return OscMessage { addr: self.addr.to_owned(), args: vec![ OscType::from(self.serial.to_owned()), OscType::from(self.transform.origin.x), OscType::from(self.transform.origin.y), OscType::from(self.transform.origin.z), OscType::from(quat.x), OscType::from(quat.y), OscType::from(quat.z), OscType::from(quat.w), ], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 8 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![8], actual: msg.args.len(), addr: msg.addr})); } let serial: String; let mut origin = Vector3::new(0.0, 0.0, 0.0); let mut quat = Quaternion::new(0.0, 0.0, 0.0, 0.0); match &msg.args[0] { OscType::String(s) => serial = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Float(f) => origin.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Float(f) => origin.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } match msg.args[3] { OscType::Float(f) => origin.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } match msg.args[4] { OscType::Float(f) => quat.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[4].to_owned(), addr: msg.addr, arg_count: 4})), } match msg.args[5] { OscType::Float(f) => quat.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[5].to_owned(), addr: msg.addr, arg_count: 5})), } match msg.args[6] { OscType::Float(f) => quat.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[6].to_owned(), addr: msg.addr, arg_count: 6})), } match msg.args[7] { OscType::Float(f) => quat.w = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[7].to_owned(), addr: msg.addr, arg_count: 7})), } let boxed_result: Box = Box::new(DeviceTranform { addr: msg.addr.to_owned(), serial, transform: Transform3D::new(Basis::from_quat(quat), origin), }); return Ok(boxed_result); } fn get_addr(&self) -> String { return self.addr.to_owned(); } } #[derive(Debug)] struct VmcExtRvc { enable: bool, port: u16, ip_addr: Option, } impl VmcMessage for VmcExtRvc { fn to_osc_message(&self) -> OscMessage { let mut args: Vec; if self.enable { args = vec![OscType::from(1)]; } else { args = vec![OscType::from(0)]; } args.push(OscType::from(self.port as i32)); if self.ip_addr.is_some() { args.push(OscType::from(self.ip_addr.clone().unwrap())); } return OscMessage { addr: String::from("/VMC/Ext/Rvc"), args, }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() < 2 || msg.args.len() > 3 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2, 3], actual: msg.args.len(), addr: msg.addr})); } let enable: bool; let port: u16; let mut ip_addr: Option = None; match msg.args[0] { OscType::Int(i) => { if i == 0 { enable = false; } else if i == 1 { enable = true; } else { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Int(i) => { if i >= 0 && i <= 65535 { port = i as u16; } else { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 65535, actual: i, addr: msg.addr, arg_count: 1})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } if msg.args.len() == 3 { match &msg.args[2] { OscType::String(s) => ip_addr = Some(s.to_owned()), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } } let boxed_result: Box = Box::new(VmcExtRvc { enable, port, ip_addr, }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Rvc"); } } #[derive(Debug)] struct VmcExtLight { name: String, transform: Transform3D, color: Color, } impl VmcMessage for VmcExtLight { fn to_osc_message(&self) -> OscMessage { let quat = self.transform.basis.to_quat(); return OscMessage { addr: String::from("/VMC/Ext/Light"), args: vec![ OscType::from(self.name.to_owned()), OscType::from(self.transform.origin.x), OscType::from(self.transform.origin.y), OscType::from(self.transform.origin.z), OscType::from(quat.x), OscType::from(quat.y), OscType::from(quat.z), OscType::from(quat.w), OscType::from(self.color.r), OscType::from(self.color.g), OscType::from(self.color.b), OscType::from(self.color.a), ], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 12 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![12], actual: msg.args.len(), addr: msg.addr})); } let name: String; let mut origin = Vector3::new(0.0, 0.0, 0.0); let mut quat = Quaternion::new(0.0, 0.0, 0.0, 0.0); let mut color = Color::from_rgba(0.0, 0.0, 0.0, 0.0); match &msg.args[0] { OscType::String(s) => name = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Float(f) => origin.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Float(f) => origin.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } match msg.args[3] { OscType::Float(f) => origin.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } match msg.args[4] { OscType::Float(f) => quat.x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[4].to_owned(), addr: msg.addr, arg_count: 4})), } match msg.args[5] { OscType::Float(f) => quat.y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[5].to_owned(), addr: msg.addr, arg_count: 5})), } match msg.args[6] { OscType::Float(f) => quat.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[6].to_owned(), addr: msg.addr, arg_count: 6})), } match msg.args[7] { OscType::Float(f) => quat.w = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[7].to_owned(), addr: msg.addr, arg_count: 7})), } match msg.args[8] { OscType::Float(f) => color.r = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[8].to_owned(), addr: msg.addr, arg_count: 8})), } match msg.args[9] { OscType::Float(f) => color.g = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[9].to_owned(), addr: msg.addr, arg_count: 9})), } match msg.args[10] { OscType::Float(f) => color.b = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[10].to_owned(), addr: msg.addr, arg_count: 10})), } match msg.args[11] { OscType::Float(f) => color.a = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[11].to_owned(), addr: msg.addr, arg_count: 11})), } let boxed_result: Box = Box::new(VmcExtLight { name, transform: Transform3D::new(Basis::from_quat(quat), origin), color, }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Light"); } } #[derive(Debug)] struct VmcExtVrm { path: String, title: String, hash: Option, } impl VmcMessage for VmcExtVrm { fn to_osc_message(&self) -> OscMessage { let mut args = vec![ OscType::from(self.path.to_owned()), OscType::from(self.title.to_owned()), ]; if self.hash.is_some() { args.push(OscType::from(self.hash.clone().unwrap())); } return OscMessage { addr: String::from("/Vmc/Ext/VRM"), args, }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() < 2 || msg.args.len() > 3 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2, 3], actual: msg.args.len(), addr: msg.addr})); } let path: String; let title: String; let mut hash: Option = None; match &msg.args[0] { OscType::String(s) => path = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match &msg.args[1] { OscType::String(s) => title = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } if msg.args.len() == 3 { match &msg.args[2] { OscType::String(s) => hash = Some(s.to_owned()), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } } let boxed_result: Box = Box::new(VmcExtVrm { path, title, hash }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/Vmc/Ext/VRM"); } } #[derive(Debug)] struct VmcExtRemote { service: String, json: String, } impl VmcMessage for VmcExtRemote { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Remote"), args: vec![ OscType::from(self.service.to_owned()), OscType::from(self.json.to_owned()), ], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 2 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2], actual: msg.args.len(), addr: msg.addr})); } let service: String; let json: String; match &msg.args[0] { OscType::String(s) => service = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match &msg.args[1] { OscType::String(s) => json = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } let boxed_result: Box = Box::new(VmcExtRemote{ service, json }); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Remote"); } } #[derive(Debug)] struct VmcExtOpt { option: String, } impl VmcMessage for VmcExtOpt { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Opt"), args: vec![OscType::from(self.option.to_owned())], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); } let option: String; match &msg.args[0] { OscType::String(s) => option = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } let boxed_result: Box = Box::new(VmcExtOpt{option}); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Opt"); } } #[derive(Debug)] struct VmcExtSettingColor { color: Color, } impl VmcMessage for VmcExtSettingColor { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Setting/Color"), args: vec![ OscType::from(self.color.r), OscType::from(self.color.g), OscType::from(self.color.b), OscType::from(self.color.a), ], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 4 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![4], actual: msg.args.len(), addr: msg.addr})); } let mut color = Color::from_rgba(0.0, 0.0, 0.0, 0.0); match msg.args[0] { OscType::Float(f) => color.r = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Float(f) => color.g = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Float(f) => color.b = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } match msg.args[3] { OscType::Float(f) => color.a = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } let boxed_result: Box = Box::new(VmcExtSettingColor{color}); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Setting/Color"); } } #[derive(Debug)] struct VmcExtSettingWin { is_top_most: bool, is_transparent: bool, window_click_through: i32, hide_border: i32, } impl VmcMessage for VmcExtSettingWin { fn to_osc_message(&self) -> OscMessage { let mut args: Vec; if self.is_top_most { args = vec![OscType::from(1)]; } else { args = vec![OscType::from(0)]; } if self.is_transparent { args.push(OscType::from(1)); } else { args.push(OscType::from(0)); } args.append(&mut vec![ OscType::from(self.window_click_through), OscType::from(self.hide_border), ]); return OscMessage { addr: String::from("/VMC/Ext/Setting/Win"), args, }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 4 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![4], actual: msg.args.len(), addr: msg.addr})); } let mut result = Self { is_top_most: false, is_transparent: false, window_click_through: -1, hide_border: -1, }; match msg.args[0] { OscType::Int(i) => { if i == 1 { result.is_top_most = true; } else if i != 0 { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } match msg.args[1] { OscType::Int(i) => { if i == 1 { result.is_transparent = true; } else if i != 0 { return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 1})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } match msg.args[2] { OscType::Int(i) => result.window_click_through = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } match msg.args[3] { OscType::Int(i) => result.hide_border = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } let boxed_result: Box = Box::new(result); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Setting/Win"); } } #[derive(Debug)] struct VmcExtConfig { path: String, } impl VmcMessage for VmcExtConfig { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Config"), args: vec![OscType::from(self.path.to_owned())], }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr })); } let path: String; match &msg.args[0] { OscType::String(s) => path = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } let boxed_result: Box = Box::new(VmcExtConfig{path}); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Config"); } } #[derive(Clone, Copy, Debug)] enum ThruType { Float(f32), Int(i32), } #[derive(Debug)] struct VmcThru { addr: String, arg1: String, arg2: Option } impl VmcMessage for VmcThru { fn to_osc_message(&self) -> OscMessage { let mut args = vec![OscType::from(self.arg1.to_owned() )]; if self.arg2.is_some() { match self.arg2.unwrap() { ThruType::Float(val) => args.push(OscType::from(val)), ThruType::Int(val) => args.push(OscType::from(val)), } } return OscMessage { addr: self.addr.to_owned(), args} } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() > 2 || msg.args.len() < 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1, 2], actual: msg.args.len(), addr: msg.addr})); } let arg1: String; match &msg.args[0] { OscType::String(s) => arg1 = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } let mut arg2: Option = None; if msg.args.len() == 2 { match msg.args[1] { OscType::Int(i) => arg2 = Some(ThruType::Int(i)), OscType::Float(f) => arg2 = Some(ThruType::Float(f)), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0), OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})) } } let boxed_result: Box = Box::new(VmcThru { addr: msg.addr, arg1 , arg2 }); return Ok(boxed_result); } fn get_addr(&self) -> String { return self.addr.to_owned(); } } #[derive(Debug)] struct VmcExtSetPeriod { status: i32, root: i32, bone: i32, blendshape: i32, camera: i32, devices: i32 } impl VmcMessage for VmcExtSetPeriod { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Set/Period"), args: vec![ OscType::from(self.status), OscType::from(self.root), OscType::from(self.bone), OscType::from(self.blendshape), OscType::from(self.camera), OscType::from(self.devices), ] }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 6 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![6], actual: msg.args.len(), addr: msg.addr})); } let status: i32; let root: i32; let bone: i32; let blendshape: i32; let camera: i32; let devices: i32; match msg.args[0] { OscType::Int(i) => status = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})) } match msg.args[1] { OscType::Int(i) => root = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})) } match msg.args[2] { OscType::Int(i) => bone = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})) } match msg.args[3] { OscType::Int(i) => blendshape = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})) } match msg.args[4] { OscType::Int(i) => camera = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[4].to_owned(), addr: msg.addr, arg_count: 4})) } match msg.args[5] { OscType::Int(i) => devices = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[5].to_owned(), addr: msg.addr, arg_count: 5})) } let boxed_result: Box = Box::new(VmcExtSetPeriod { status, root, bone, blendshape, camera, devices}); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Set/Period"); } } #[derive(Debug)] struct VmcExtSetEye { enable: i32, position: Vector3, } impl VmcMessage for VmcExtSetEye { fn to_osc_message(&self) -> OscMessage { return OscMessage{ addr: String::from("/VMC/Ext/Set/Eye"), args: vec![ OscType::from(self.enable), OscType::from(self.position.x), OscType::from(self.position.y), OscType::from(self.position.z), ] }; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 4 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![4], actual: msg.args.len(), addr: msg.addr})); } let enable: i32; let x: f32; let y: f32; let z: f32; match msg.args[0] { OscType::Int(i) => enable = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})) } match msg.args[1] { OscType::Float(f) => x = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})) } match msg.args[2] { OscType::Float(f) => y = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})) } match msg.args[3] { OscType::Float(f) => z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})) } let boxed_result: Box = Box::new(VmcExtSetEye { enable, position: Vector3::new(x, y, z)}); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Set/Eye"); } } #[derive(Debug)] struct VmcExtSetRes { response: String } impl VmcMessage for VmcExtSetRes { fn to_osc_message(&self) -> OscMessage { return OscMessage{addr: String::from("/VMC/Ext/Set/Res"), args: vec![OscType::from(self.response.to_owned())]}; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); } let response: String; match &msg.args[0] { OscType::String(s) => response = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})) } let boxed_result: Box = Box::new(VmcExtSetRes{response}); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Set/Res"); } } #[derive(Debug)] struct VmcExtSetCalibExec { mode: i32 } impl VmcMessage for VmcExtSetCalibExec { fn to_osc_message(&self) -> OscMessage { return OscMessage{addr: String::from("/VMC/Ext/Set/Calib/Exec"), args: vec![OscType::from(self.mode)]}; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); } let mode: i32; match msg.args[0] { OscType::Int(i) => mode = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})) } let boxed_result: Box = Box::new(VmcExtSetCalibExec{mode}); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Set/Calib/Exec"); } } #[derive(Debug)] struct VmcExtSetConfig { path: String } impl VmcMessage for VmcExtSetConfig { fn to_osc_message(&self) -> OscMessage { return OscMessage{addr: String::from("/VMC/Ext/Set/Res"), args: vec![OscType::from(self.path.to_owned())]}; } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); } let path: String; match &msg.args[0] { OscType::String(s) => path = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})) } let boxed_result: Box = Box::new(VmcExtSetConfig{path}); return Ok(boxed_result); } fn get_addr(&self) -> String { return String::from("/VMC/Ext/Set/Res"); } } #[derive(Debug)] struct VmcMessageNoArgs { addr: String } impl VmcMessage for VmcMessageNoArgs { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: self.addr.to_owned(), args: Vec::new()} } fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 0 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![0], actual: msg.args.len(), addr: msg.addr})) } let boxed_result: Box = Box::new(VmcMessageNoArgs { addr: msg.addr }); return Ok(boxed_result); } fn get_addr(&self) -> String { return self.addr.to_owned(); } } pub fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { match msg.addr.as_str() { "/VMC/Ext/OK" => VmcExtOk::from_osc_message(msg), "/VMC/Ext/T" => VmcExtT::from_osc_message(msg), "/VMC/Ext/Root/Pos" => VmcExtRootPos::from_osc_message(msg), "/VMC/Ext/Bone/Pos" => VmcExtBonePos::from_osc_message(msg), "/VMC/Ext/Blend/Val" => VmcExtBlendVal::from_osc_message(msg), "/VMC/Ext/Blend/Apply" | "/VMC/Ext/Set/Req" | "/VMC/Ext/Set/Calib/Ready" => VmcMessageNoArgs::from_osc_message(msg), "/VMC/Ext/Cam" => VmcExtCam::from_osc_message(msg), "/VMC/Ext/Con" => VmcExtCon::from_osc_message(msg), "/VMC/Ext/Key" => VmcExtKey::from_osc_message(msg), "/VMC/Ext/Midi/Note" => VmcExtMidiNote::from_osc_message(msg), "/VMC/Ext/Midi/CC/Val" => VmcExtMidiCcVal::from_osc_message(msg), "/VMC/Ext/Midi/CC/Bit" => VmcExtMidiCcBit::from_osc_message(msg), "/VMC/Ext/Hmd/Pos" | "/VMC/Ext/Con/Pos" | "/VMC/Ext/Tra/Pos" | "/VMC/Ext/Hmd/Pos/Local" | "/VMC/Ext/Con/Pos/Local" | "/VMC/Ext/Tra/Pos/Local" => DeviceTranform::from_osc_message(msg), "/VMC/Ext/Rcv" => VmcExtRvc::from_osc_message(msg), "/VMC/Ext/Light" => VmcExtLight::from_osc_message(msg), "/VMC/Ext/VRM" => VmcExtVrm::from_osc_message(msg), "/VMC/Ext/Remote" => VmcExtRemote::from_osc_message(msg), "/VMC/Ext/Opt" => VmcExtOpt::from_osc_message(msg), "/VMC/Ext/Setting/Color" => VmcExtSettingColor::from_osc_message(msg), "/VMC/Ext/Setting/Win" => VmcExtSettingWin::from_osc_message(msg), "/VMC/Ext/Config" => VmcExtConfig::from_osc_message(msg), "/VMC/Ext/Set/Period" => VmcExtSetPeriod::from_osc_message(msg), "/VMC/Ext/Set/Eye" => VmcExtSetEye::from_osc_message(msg), "/VMC/Ext/Set/Res" => VmcExtSetRes::from_osc_message(msg), "/VMC/Ext/Set/Calib/Exec" => VmcExtSetCalibExec::from_osc_message(msg), "/VMC/Ext/Set/Config" => VmcExtSetConfig::from_osc_message(msg), _ => { if &msg.addr[0..10] == "/VMC/Thru/" { return VmcThru::from_osc_message(msg) } Err(FromMessageErr::Addr(AddrErr { addr: msg.addr })) } } }