version "0.1";
require "mspgl";
+ require "libovr";
+
+ build_info
+ {
+ warning_level 1;
+ };
library "mspvr"
{
--- /dev/null
+#include "oculusriftcamera.h"
+#include "oculusriftcamera_private.h"
+#include "oculusriftdevice.h"
+#include "oculusriftdevice_private.h"
+
+namespace Msp {
+namespace VR {
+
+OculusRiftCamera::OculusRiftCamera(const OculusRiftDevice &d, const GL::Camera &c):
+ device(d),
+ base_camera(c),
+ priv(new Private)
+{
+ const OculusRiftDevice::Private &dev_priv = device.get_private();
+ priv->ovr_sensor = dev_priv.ovr_hmd->GetSensor();
+ priv->fusion.AttachToSensor(priv->ovr_sensor);
+}
+
+OculusRiftCamera::~OculusRiftCamera()
+{
+ delete priv;
+}
+
+void OculusRiftCamera::update()
+{
+ OVR::Matrix4f sensor_matrix = priv->fusion.GetOrientation();
+ const float *m = &sensor_matrix.M[0][0];
+
+ const GL::Vector3 &base_look = base_camera.get_look_direction();
+ GL::Vector3 base_right = normalize(cross(base_look, base_camera.get_up_direction()));
+ GL::Vector3 base_up = normalize(cross(base_right, base_look));
+
+ set_position(base_camera.get_position());
+ set_up_direction(base_right*m[1]+base_up*m[5]-base_look*m[9]);
+ set_look_direction(-base_right*m[2]-base_up*m[6]+base_look*m[10]);
+ set_depth_clip(base_camera.get_near_clip(), base_camera.get_far_clip());
+}
+
+} // namespace VR
+} // namespace Msp
--- /dev/null
+#ifndef MSP_VR_OCULUSRIFTCAMERA_H_
+#define MSP_VR_OCULUSRIFTCAMERA_H_
+
+#include "headtrackingcamera.h"
+
+namespace Msp {
+namespace VR {
+
+class OculusRiftDevice;
+
+class OculusRiftCamera: public HeadTrackingCamera
+{
+private:
+ struct Private;
+
+ const OculusRiftDevice &device;
+ const GL::Camera &base_camera;
+ Private *priv;
+
+public:
+ OculusRiftCamera(const OculusRiftDevice &, const GL::Camera &);
+ virtual ~OculusRiftCamera();
+
+ virtual void update();
+};
+
+} // namespace VR
+} // namespace Msp
+
+#endif
--- /dev/null
+#ifndef MSP_VR_OCULUSRIFTCAMERA_PRIVATE_H_
+#define MSP_VR_OCULUSRIFTCAMERA_PRIVATE_H_
+
+#include <OVR.h>
+#include "oculusriftcamera.h"
+
+namespace Msp {
+namespace VR {
+
+struct OculusRiftCamera::Private
+{
+ OVR::Ptr<OVR::SensorDevice> ovr_sensor;
+ OVR::SensorFusion fusion;
+};
+
+} // namespace VR
+} // namespace Msp
+
+#endif
--- /dev/null
+#include "oculusriftdevice.h"
+#include "oculusriftdevice_private.h"
+
+using namespace std;
+
+namespace Msp {
+namespace VR {
+
+OculusRiftDevice::OculusRiftDevice():
+ priv(new Private)
+{
+ static OVR::System system(OVR::Log::ConfigureDefaultLog(OVR::LogMask_Debug));
+
+ priv->ovr_manager = OVR::DeviceManager::Create();
+ priv->ovr_hmd = priv->ovr_manager->EnumerateDevices<OVR::HMDDevice>().CreateDevice();
+ if(!priv->ovr_hmd)
+ {
+ delete priv;
+ throw runtime_error("rift hmd not found");
+ }
+}
+
+OculusRiftDevice::~OculusRiftDevice()
+{
+ delete priv;
+}
+
+OculusRiftCamera *OculusRiftDevice::create_camera(const GL::Camera &bc) const
+{
+ return new OculusRiftCamera(*this, bc);
+}
+
+OculusRiftCombiner *OculusRiftDevice::create_combiner() const
+{
+ OculusRiftCombiner *combiner = new OculusRiftCombiner;
+
+ OVR::HMDInfo info;
+ if(!priv->ovr_hmd->GetDeviceInfo(&info))
+ {
+ combiner->set_view_distance(info.EyeToScreenDistance/info.HScreenSize);
+ combiner->set_lens_separation(info.LensSeparationDistance/info.HScreenSize);
+ combiner->set_distortion(info.DistortionK[0], info.DistortionK[1], info.DistortionK[2], info.DistortionK[3]);
+ combiner->set_red_aberration(info.ChromaAbCorrection[0], info.ChromaAbCorrection[1]);
+ combiner->set_blue_aberration(info.ChromaAbCorrection[2], info.ChromaAbCorrection[3]);
+ }
+
+ return combiner;
+}
+
+} // namespace VR
+} // namespace Msp
--- /dev/null
+#ifndef MSP_VR_OCULUSRIFTDEVICE_H_
+#define MSP_VR_OCULUSRIFTDEVICE_H_
+
+#include "displaydevice.h"
+#include "oculusriftcamera.h"
+#include "oculusriftcombiner.h"
+
+namespace Msp {
+namespace VR {
+
+class OculusRiftDevice: public DisplayDevice
+{
+public:
+ struct Private;
+
+private:
+ Private *priv;
+
+public:
+ OculusRiftDevice();
+ virtual ~OculusRiftDevice();
+
+ const Private &get_private() const { return *priv; }
+
+ virtual OculusRiftCamera *create_camera(const GL::Camera &) const;
+ virtual OculusRiftCombiner *create_combiner() const;
+};
+
+} // namespace VR
+} // namespace Msp
+
+#endif
--- /dev/null
+#ifndef MSP_VR_OCULUSRIFTDEVICE_PRIVATE_H_
+#define MSP_VR_OCULUSRIFTDEVICE_PRIVATE_H_
+
+#include <OVR.h>
+#include "oculusriftdevice.h"
+
+namespace Msp {
+namespace VR {
+
+struct OculusRiftDevice::Private
+{
+ OVR::Ptr<OVR::DeviceManager> ovr_manager;
+ OVR::Ptr<OVR::HMDDevice> ovr_hmd;
+};
+
+} // namespace VR
+} // namespace Msp
+
+#endif