#include <openvr.h>
#include <msp/vr/stereoview.h>
+#include "openvrcontroller_private.h"
#include "openvrsystem.h"
using namespace std;
unsigned OpenVRSystem::n_instances = 0;
-OpenVRSystem::OpenVRSystem()
+OpenVRSystem::OpenVRSystem():
+ n_tracked_devices(0)
{
+ vr::IVRSystem *vr_sys = 0;
if(!n_instances)
{
vr::EVRInitError init_err;
- vr::VR_Init(&init_err, vr::VRApplication_Scene);
+ vr_sys = vr::VR_Init(&init_err, vr::VRApplication_Scene);
if(init_err!=vr::VRInitError_None)
throw runtime_error("OpenVR initialization failed");
}
throw runtime_error("OpenVR compositor initialization failed");
vr::VRCompositor()->SetTrackingSpace(vr::TrackingUniverseSeated);
+
+ for(unsigned i=0; i<vr::k_unMaxTrackedDeviceCount; ++i)
+ if(vr_sys->IsTrackedDeviceConnected(i))
+ {
+ n_tracked_devices = i+1;
+ if(vr_sys->GetTrackedDeviceClass(i)==vr::TrackedDeviceClass_Controller)
+ unclaimed_controllers.push_back(i);
+ }
+
+ tracking_matrices.resize(n_tracked_devices);
}
OpenVRSystem::~OpenVRSystem()
vr::VR_Shutdown();
}
+bool OpenVRSystem::is_maybe_available()
+{
+ return vr::VR_IsHmdPresent();
+}
+
void OpenVRSystem::configure_view(StereoView &view) const
{
vr::IVRSystem *vr_sys = vr::VRSystem();
vr::VRCompositor()->SetTrackingSpace(a ? vr::TrackingUniverseStanding : vr::TrackingUniverseSeated);
}
+bool OpenVRSystem::get_absolute_tracking() const
+{
+ return vr::VRCompositor()->GetTrackingSpace()==vr::TrackingUniverseStanding;
+}
+
OpenVRCamera *OpenVRSystem::create_camera(const GL::Camera &bc)
{
return new OpenVRCamera(*this, bc);
return new OpenVRCombiner(*this, v);
}
+OpenVRController *OpenVRSystem::create_controller()
+{
+ return new OpenVRController(*this);
+}
+
+void OpenVRSystem::tick()
+{
+ vr::IVRSystem *vr_sys = vr::VRSystem();
+
+ OpenVRController::Event event;
+ while(vr_sys->PollNextEvent(&event, sizeof(event)))
+ {
+ bool controller_matched = false;
+ for(vector<OpenVRController *>::iterator i=controllers.begin(); i!=controllers.end(); ++i)
+ {
+ int cindex = (*i)->get_index();
+ if(cindex>=0 && event.trackedDeviceIndex==static_cast<unsigned>(cindex))
+ {
+ (*i)->event(event);
+ controller_matched = true;
+ }
+ }
+
+ if(!controller_matched && event.eventType==vr::VREvent_TrackedDeviceActivated)
+ {
+ if(event.trackedDeviceIndex>=n_tracked_devices)
+ {
+ n_tracked_devices = event.trackedDeviceIndex+1;
+ tracking_matrices.resize(n_tracked_devices);
+ }
+
+ vr::ETrackedDeviceClass dev_class = vr_sys->GetTrackedDeviceClass(event.trackedDeviceIndex);
+
+ if(dev_class==vr::TrackedDeviceClass_Controller)
+ {
+ bool assigned_to_controller = false;
+ for(vector<OpenVRController *>::iterator i=controllers.begin(); i!=controllers.end(); ++i)
+ if((*i)->get_index()<0)
+ {
+ (*i)->event(event);
+ assigned_to_controller = true;
+ break;
+ }
+
+ if(!assigned_to_controller)
+ unclaimed_controllers.push_back(event.trackedDeviceIndex);
+ }
+ }
+ }
+
+ for(vector<OpenVRController *>::iterator i=controllers.begin(); i!=controllers.end(); ++i)
+ (*i)->update_input_state();
+}
+
void OpenVRSystem::update_pose_matrices()
{
vector<vr::TrackedDevicePose_t> poses;
- poses.resize(vr::k_unTrackedDeviceIndex_Hmd+1);
+ poses.resize(n_tracked_devices);
vr::VRCompositor()->WaitGetPoses(&poses[0], poses.size(), 0, 0);
- vr::TrackedDevicePose_t &hmd_pose = poses[vr::k_unTrackedDeviceIndex_Hmd];
- if(hmd_pose.bPoseIsValid)
- hmd_matrix = convert_matrix(hmd_pose.mDeviceToAbsoluteTracking);
+ for(unsigned i=0; i<n_tracked_devices; ++i)
+ if(poses[i].bPoseIsValid)
+ tracking_matrices[i] = convert_matrix(poses[i].mDeviceToAbsoluteTracking);
+}
+
+const GL::Matrix &OpenVRSystem::get_tracking_matrix(unsigned index) const
+{
+ if(index>=tracking_matrices.size())
+ throw out_of_range("OpenVRSystem::get_tracking_matrix");
+
+ return tracking_matrices[index];
+}
+
+const GL::Matrix &OpenVRSystem::get_hmd_matrix() const
+{
+ return get_tracking_matrix(vr::k_unTrackedDeviceIndex_Hmd);
+}
+
+void OpenVRSystem::add_controller(OpenVRController &controller)
+{
+ vector<OpenVRController *>::iterator i = find(controllers.begin(), controllers.end(), &controller);
+ if(i!=controllers.end())
+ throw invalid_argument("already added");
+
+ controllers.push_back(&controller);
+
+ if(!unclaimed_controllers.empty())
+ {
+ OpenVRController::Event event;
+ event.eventType = vr::VREvent_TrackedDeviceActivated;
+ event.trackedDeviceIndex = unclaimed_controllers.back();
+ event.eventAgeSeconds = 0;
+ controller.event(event);
+ unclaimed_controllers.pop_back();
+ }
+}
+
+void OpenVRSystem::remove_controller(OpenVRController &controller)
+{
+ vector<OpenVRController *>::iterator i = find(controllers.begin(), controllers.end(), &controller);
+ if(i==controllers.end())
+ throw invalid_argument("not added");
+
+ int index = controller.get_index();
+ if(index>=0)
+ unclaimed_controllers.push_back(index);
+ controllers.erase(i);
}
} // namespace VR