diff --git a/lib.rs b/lib.rs index e52e83c..2c5b10b 100644 --- a/lib.rs +++ b/lib.rs @@ -4,14 +4,21 @@ extern mod cgmath; +use std::libc::{c_float, time_t}; +use std::c_str::ToCStr; + +use cgmath::quaternion::Quat; +use cgmath::vector::Vec3; +use cgmath::matrix::Mat4; + #[link(name="ovr_wrapper")] extern {} #[link(name="ovr")] extern {} -mod ll { - use std::libc::{c_uint, c_int, c_float, c_long, c_char}; +pub mod ll { + use std::libc::{c_uint, c_int, c_float, c_long, c_char, time_t}; pub enum DeviceManager {} pub enum HMDInfo {} @@ -19,14 +26,54 @@ mod ll { pub enum SensorDevice {} pub enum SensorFusion {} + pub struct Vector3f {x: c_float, y: c_float, z: c_float} + pub struct Quatf {x: c_float, y: c_float, z: c_float, w: c_float} + pub struct Matrix4f {m11: c_float, m12: c_float, m13: c_float, m14: c_float, + m21: c_float, m22: c_float, m23: c_float, m24: c_float, + m31: c_float, m32: c_float, m33: c_float, m34: c_float, + m41: c_float, m42: c_float, m43: c_float, m44: c_float} + extern "C" { pub fn OVR_system_init(); pub fn OVR_DeviceManager_Create() -> *DeviceManager; pub fn OVR_DeviceManager_EnumerateDevices(dm :*DeviceManager) -> *HMDDevice; pub fn OVR_HDMDevice_GetDeviceInfo(hmd: *HMDDevice) -> *HMDInfo; pub fn OVR_HDMDevice_GetSensor(hmd: *HMDDevice) -> *SensorDevice; + pub fn OVR_SensorFusion() -> *SensorFusion; pub fn OVR_SensorFusion_AttachToSensor(sf: *SensorFusion, sd: *SensorDevice) -> bool; + pub fn OVR_SensorFusion_IsAttachedToSensor(sf: *SensorFusion) -> bool; + pub fn OVR_SensorFusion_GetOrientation(sf: *SensorFusion) -> Quatf; + pub fn OVR_SensorFusion_GetPredictedOrientation(sf: *SensorFusion) -> Quatf; + pub fn OVR_SensorFusion_GetPredictedOrientation_opt(sf: *SensorFusion, dt: c_float) -> Quatf; + pub fn OVR_SensorFusion_GetAcceleration(sf: *SensorFusion) -> Vector3f; + pub fn OVR_SensorFusion_GetAngularVelocity(sf: *SensorFusion) -> Vector3f; + pub fn OVR_SensorFusion_GetMagnetometer(sf: *SensorFusion) -> Vector3f; + pub fn OVR_SensorFusion_GetCalibratedMagnetometer(sf: *SensorFusion) -> Vector3f; + pub fn OVR_SensorFusion_Reset(sf: *SensorFusion); + pub fn OVR_SensorFusion_EnableMotionTracking(sf: *SensorFusion, enable: bool); + pub fn OVR_SensorFusion_IsMotionTrackingEnabled(sf: *SensorFusion) -> bool; + pub fn OVR_SensorFusion_GetPredictionDelta(sf: *SensorFusion) -> c_float; + pub fn OVR_SensorFusion_SetPrediction(sf: *SensorFusion, dt: c_float, enable: bool); + pub fn OVR_SensorFusion_SetPredictionEnabled(sf: *SensorFusion, enable: bool); + pub fn OVR_SensorFusion_IsPredictionEnabled(sf: *SensorFusion) -> bool; + pub fn OVR_SensorFusion_SetGravityEnabled(sf: *SensorFusion, enableGravity: bool); + pub fn OVR_SensorFusion_IsGravityEnabled(sf: *SensorFusion) -> bool; + pub fn OVR_SensorFusion_GetAccelGain(sf: *SensorFusion) -> c_float; + pub fn OVR_SensorFusion_SetAccelGain(sf: *SensorFusion, ag: c_float); + pub fn OVR_SensorFusion_SaveMagCalibration(sf: *SensorFusion, calibrationName: *c_char) -> bool; + pub fn OVR_SensorFusion_LoadMagCalibration(sf: *SensorFusion, calibrationName: *c_char) -> bool; + pub fn OVR_SensorFusion_SetYawCorrectionEnabled(sf: *SensorFusion, enable: bool); + pub fn OVR_SensorFusion_IsYawCorrectionEnabled(sf: *SensorFusion) -> bool; + pub fn OVR_SensorFusion_SetMagCalibration(sf: *SensorFusion, m: *Matrix4f); + pub fn OVR_SensorFusion_GetMagCalibration(sf: *SensorFusion) -> Matrix4f; + pub fn OVR_SensorFusion_GetMagCalibrationTime(sf: *SensorFusion) -> time_t; + pub fn OVR_SensorFusion_HasMagCalibration(sf: *SensorFusion) -> bool; + pub fn OVR_SensorFusion_ClearMagCalibration(sf: *SensorFusion); + pub fn OVR_SensorFusion_ClearMagReferences(sf: *SensorFusion, rawMag: *Vector3f); + pub fn OVR_SensorFusion_GetCalibratedMagValue(sf: *SensorFusion) -> Vector3f; + //pub fn OVR_SensorFusion_OnMessage(sf: *SensorFusion, msg: *MessageBodyFrame) + //pub fn OVR_SensorFusion_SetDelegateMessageHandler(sf: *SensorFusion, handle: *MessageHandler) pub fn OVR_HMDInfo_GetScreenHResolution(info: *HMDInfo) -> c_uint; pub fn OVR_HMDInfo_GetScreenVResolution(info: *HMDInfo) -> c_uint; @@ -249,6 +296,236 @@ impl SensorFusion { ll::OVR_SensorFusion_AttachToSensor(self.ptr, sensor.ptr) } } + + pub fn is_attached_to_sensor(&self) -> bool + { + unsafe { + ll::OVR_SensorFusion_IsAttachedToSensor(self.ptr) + } + } + + pub fn get_orientation(&self) -> Quat + { + unsafe { + let out = ll::OVR_SensorFusion_GetOrientation(self.ptr); + Quat::new(out.x, out.y, out.z, out.w) + } + } + + pub fn get_predicted_orientation(&self, dt: Option) -> Quat + { + unsafe { + let out = match dt { + Some(dt) => ll::OVR_SensorFusion_GetPredictedOrientation_opt(self.ptr, dt as c_float), + None => ll::OVR_SensorFusion_GetPredictedOrientation(self.ptr) + }; + Quat::new(out.x, out.y, out.z, out.w) + } + } + + pub fn get_acceleration(&self) -> Vec3 + { + unsafe { + let out = ll::OVR_SensorFusion_GetAcceleration(self.ptr); + Vec3::new(out.x, out.y, out.z) + } + } + + pub fn get_angular_velocity(&self) -> Vec3 + { + unsafe { + let out = ll::OVR_SensorFusion_GetAngularVelocity(self.ptr); + Vec3::new(out.x, out.y, out.z) + } + } + + pub fn get_magnetometer(&self) -> Vec3 + { + unsafe { + let out = ll::OVR_SensorFusion_GetMagnetometer(self.ptr); + Vec3::new(out.x, out.y, out.z) + } + } + + pub fn get_calibrated_magnetometer(&self) -> Vec3 + { + unsafe { + let out = ll::OVR_SensorFusion_GetCalibratedMagnetometer(self.ptr); + Vec3::new(out.x, out.y, out.z) + } + } + + pub fn reset(&self) + { + unsafe { + ll::OVR_SensorFusion_Reset(self.ptr); + } + } + + pub fn enable_motion_tracking(&self, enable: bool) + { + unsafe { + ll::OVR_SensorFusion_EnableMotionTracking(self.ptr, enable) + } + } + + pub fn is_motion_tracking_enabled(&self) -> bool + { + unsafe { + ll::OVR_SensorFusion_IsMotionTrackingEnabled(self.ptr) + } + } + + pub fn get_prediction_delta(&self) -> f32 + { + unsafe { + ll::OVR_SensorFusion_GetPredictionDelta(self.ptr) as f32 + } + } + + pub fn set_prediction(&self, dt: f32, enable: bool) + { + unsafe { + ll::OVR_SensorFusion_SetPrediction(self.ptr, dt as c_float, enable) + } + } + + pub fn set_prediction_enabled(&self, enable: bool) + { + unsafe { + ll::OVR_SensorFusion_SetPredictionEnabled(self.ptr, enable) + } + } + + pub fn is_prediction_enabled(&self) -> bool + { + unsafe { + ll::OVR_SensorFusion_IsPredictionEnabled(self.ptr) + } + } + + pub fn set_gravity_enabled(&self, enable_gravity: bool) + { + unsafe { + ll::OVR_SensorFusion_SetGravityEnabled(self.ptr, enable_gravity) + } + } + + pub fn is_gravity_enabled(&self) -> bool + { + unsafe { + ll::OVR_SensorFusion_IsGravityEnabled(self.ptr) + } + } + + pub fn get_accel_gain(&self) -> f32 + { + unsafe { + ll::OVR_SensorFusion_GetAccelGain(self.ptr) as f32 + } + } + + pub fn set_accel_gain(&self, ag: f32) + { + unsafe { + ll::OVR_SensorFusion_SetAccelGain(self.ptr, ag as c_float) + } + } + + pub fn save_mag_calibration(&self, calibration_name: &str) -> bool + { + let cn = calibration_name.to_c_str(); + unsafe { + ll::OVR_SensorFusion_SaveMagCalibration(self.ptr, cn.unwrap()) + } + } + + pub fn load_mag_calibration(&self, calibration_name: &str) -> bool + { + let cn = calibration_name.to_c_str(); + unsafe { + ll::OVR_SensorFusion_LoadMagCalibration(self.ptr, cn.unwrap()) + } + } + + pub fn set_yaw_correction_enabled(&self, enable: bool) + { + unsafe { + ll::OVR_SensorFusion_SetYawCorrectionEnabled(self.ptr, enable) + } + } + + pub fn is_yaw_correction_enabled(&self) -> bool + { + unsafe { + ll::OVR_SensorFusion_IsYawCorrectionEnabled(self.ptr) + } + } + + pub fn set_mag_calibration(&self, m: &Mat4) + { + let mat = ll::Matrix4f{ + m11: m.x.x as c_float, m12: m.x.y as c_float, m13: m.x.z as c_float, m14: m.x.w as c_float, + m21: m.y.x as c_float, m22: m.y.y as c_float, m23: m.y.z as c_float, m24: m.y.w as c_float, + m31: m.z.x as c_float, m32: m.z.y as c_float, m33: m.z.z as c_float, m34: m.z.w as c_float, + m41: m.w.x as c_float, m42: m.x.y as c_float, m43: m.x.z as c_float, m44: m.x.w as c_float + }; + + unsafe { + ll::OVR_SensorFusion_SetMagCalibration(self.ptr, &mat as *ll::Matrix4f); + } + } + + pub fn get_mag_calibration(&self) -> Mat4 + { + unsafe { + let m = ll::OVR_SensorFusion_GetMagCalibration(self.ptr); + + Mat4::new(m.m11 as f32, m.m12 as f32, m.m13 as f32, m.m14 as f32, + m.m21 as f32, m.m22 as f32, m.m23 as f32, m.m24 as f32, + m.m31 as f32, m.m32 as f32, m.m33 as f32, m.m34 as f32, + m.m41 as f32, m.m42 as f32, m.m43 as f32, m.m44 as f32) + } + } + + /// TODO this should not return a time_t! + pub fn get_mag_calibration_time(&self) -> time_t + { + unsafe { + ll::OVR_SensorFusion_GetMagCalibrationTime(self.ptr) + } + } + + pub fn has_mag_calibration(&self) -> bool + { + unsafe { + ll::OVR_SensorFusion_HasMagCalibration(self.ptr) + } + } + + pub fn clear_mag_calibration(&self) + { + unsafe { + ll::OVR_SensorFusion_ClearMagCalibration(self.ptr) + } + } + + pub fn clear_mag_references(&self, vec: &Vec3) + { + let vec = ll::Vector3f{x: vec.x, y: vec.y, z: vec.z}; + + unsafe { + ll::OVR_SensorFusion_ClearMagReferences(self.ptr, &vec as *ll::Vector3f) + } + } + + pub fn get_calibrated_mag_value(&self) -> Vec3 + { + unsafe { + let vec = ll::OVR_SensorFusion_GetCalibratedMagValue(self.ptr); + Vec3::new(vec.x, vec.y, vec.z) + } + } } pub struct SensorDevice { diff --git a/wrapper.cpp b/wrapper.cpp index e57db77..8d86403 100644 --- a/wrapper.cpp +++ b/wrapper.cpp @@ -2,6 +2,21 @@ extern "C" { + struct Vector3f { + float x, y, z; + }; + + struct Quatf { + float x, y, z, w; + }; + + struct Matrix4f { + float m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44; + }; + void OVR_system_init(void) { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); @@ -35,12 +50,190 @@ extern "C" return SFusion; } + bool OVR_SensorFusion_IsAttachedToSensor(OVR::SensorFusion *sf) + { + return sf->IsAttachedToSensor(); + } + + Quatf OVR_SensorFusion_GetOrientation(OVR::SensorFusion *sf) + { + OVR::Quatf quat = sf->GetOrientation(); + Quatf out = {quat.x, quat.y, quat.z, quat.w}; + return out; + } + + Quatf OVR_SensorFusion_GetPredictedOrientation(OVR::SensorFusion *sf) + { + OVR::Quatf quat = sf->GetPredictedOrientation(); + Quatf out = {quat.x, quat.y, quat.z, quat.w}; + return out; + } + + Quatf OVR_SensorFusion_GetPredictedOrientation_opt(OVR::SensorFusion *sf, float dt) + { + OVR::Quatf quat = sf->GetPredictedOrientation(dt); + Quatf out = {quat.x, quat.y, quat.z, quat.w}; + return out; + } + + Vector3f OVR_SensorFusion_GetAcceleration(OVR::SensorFusion *sf) + { + OVR::Vector3f vec = sf->GetAcceleration(); + Vector3f out = {vec.x, vec.y, vec.z}; + return out; + } + + Vector3f OVR_SensorFusion_GetAngularVelocity(OVR::SensorFusion *sf) + { + OVR::Vector3f vec = sf->GetAngularVelocity(); + Vector3f out = {vec.x, vec.y, vec.z}; + return out; + } + + Vector3f OVR_SensorFusion_GetMagnetometer(OVR::SensorFusion *sf) + { + OVR::Vector3f vec = sf->GetMagnetometer(); + Vector3f out = {vec.x, vec.y, vec.z}; + return out; + } + + Vector3f OVR_SensorFusion_GetCalibratedMagnetometer(OVR::SensorFusion *sf) + { + OVR::Vector3f vec = sf->GetCalibratedMagnetometer(); + Vector3f out = {vec.x, vec.y, vec.z}; + return out; + } + + void OVR_SensorFusion_Reset(OVR::SensorFusion *sf) + { + sf->Reset(); + } + + void OVR_SensorFusion_EnableMotionTracking(OVR::SensorFusion *sf, bool enable) + { + sf->EnableMotionTracking(enable); + } + + bool OVR_SensorFusion_IsMotionTrackingEnabled(OVR::SensorFusion *sf) + { + return sf->IsMotionTrackingEnabled(); + } + + float OVR_SensorFusion_GetPredictionDelta(OVR::SensorFusion *sf) + { + return sf->GetPredictionDelta(); + } + + void OVR_SensorFusion_SetPrediction(OVR::SensorFusion *sf, float dt, bool enable) + { + sf->SetPrediction(dt, enable); + } + + void OVR_SensorFusion_SetPredictionEnabled(OVR::SensorFusion *sf, bool enable) + { + sf->SetPredictionEnabled(enable); + } + + bool OVR_SensorFusion_IsPredictionEnabled(OVR::SensorFusion *sf) + { + return sf->IsPredictionEnabled(); + } + + void OVR_SensorFusion_SetGravityEnabled(OVR::SensorFusion *sf, bool enableGravity) + { + sf->SetGravityEnabled(enableGravity); + } + + bool OVR_SensorFusion_IsGravityEnabled(OVR::SensorFusion *sf) + { + return sf->IsGravityEnabled(); + } + + float OVR_SensorFusion_GetAccelGain(OVR::SensorFusion *sf) + { + return sf->GetAccelGain(); + } + + void OVR_SensorFusion_SetAccelGain(OVR::SensorFusion *sf, float ag) + { + return sf->SetAccelGain(ag); + } + + bool OVR_SensorFusion_SaveMagCalibration(OVR::SensorFusion *sf, const char *calibrationName) + { + return sf->SaveMagCalibration(calibrationName); + } + + bool OVR_SensorFusion_LoadMagCalibration(OVR::SensorFusion *sf, const char *calibrationName) + { + return sf->LoadMagCalibration(calibrationName); + } + + void OVR_SensorFusion_SetYawCorrectionEnabled(OVR::SensorFusion *sf, bool enable) + { + sf->SetYawCorrectionEnabled(enable); + } + + bool OVR_SensorFusion_IsYawCorrectionEnabled(OVR::SensorFusion *sf) + { + return sf->IsYawCorrectionEnabled(); + } + + void OVR_SensorFusion_SetMagCalibration(OVR::SensorFusion *sf, Matrix4f *m) + { + OVR::Matrix4f mat = OVR::Matrix4f(m->m11, m->m12, m->m13, m->m14, + m->m21, m->m22, m->m23, m->m24, + m->m31, m->m32, m->m33, m->m34, + m->m41, m->m42, m->m43, m->m44); + sf->SetMagCalibration(mat); + } + + Matrix4f OVR_SensorFusion_GetMagCalibration(OVR::SensorFusion *sf) + { + OVR::Matrix4f m = sf->GetMagCalibration(); + Matrix4f out = { + m.M[0][0], m.M[0][1], m.M[0][2], m.M[0][3], + m.M[1][0], m.M[1][1], m.M[1][2], m.M[1][3], + m.M[2][0], m.M[2][1], m.M[2][2], m.M[2][3], + m.M[3][0], m.M[3][1], m.M[3][2], m.M[3][3], + }; + return out; + } + + time_t OVR_SensorFusion_GetMagCalibrationTime(OVR::SensorFusion *sf) + { + return sf->GetMagCalibrationTime(); + } + + bool OVR_SensorFusion_HasMagCalibration(OVR::SensorFusion *sf) + { + return sf->HasMagCalibration(); + } + + void OVR_SensorFusion_ClearMagCalibration(OVR::SensorFusion *sf) + { + sf->ClearMagCalibration(); + } + + void OVR_SensorFusion_ClearMagReferences(OVR::SensorFusion *sf) + { + sf->ClearMagReferences(); + } + + Vector3f OVR_SensorFusion_GetCalibratedMagValue(OVR::SensorFusion *sf, const Vector3f *rawMag) + { + OVR::Vector3f input = OVR::Vector3f(rawMag->x, rawMag->y, rawMag->z); + OVR::Vector3f vec = sf->GetCalibratedMagValue(input); + Vector3f out = {vec.x, vec.y, vec.z}; + return out; + } + + bool OVR_SensorFusion_AttachToSensor(OVR::SensorFusion* SFusion, OVR::SensorDevice *pSensor) { return (*SFusion).AttachToSensor(pSensor); } - unsigned OVR_HMDInfo_GetScreenHResolution(OVR::HMDInfo* info) { return info->HResolution;