]> git.tdb.fi Git - libs/vr.git/blobdiff - source/openvr/openvrsystem.cpp
Add support for motion controllers
[libs/vr.git] / source / openvr / openvrsystem.cpp
index d631f48f8dece03c7a27c074924eafc0ded64b86..e847b201385f4a8c685367dcee8f3799c337ed11 100644 (file)
@@ -1,5 +1,6 @@
 #include <openvr.h>
 #include <msp/vr/stereoview.h>
+#include "openvrcontroller_private.h"
 #include "openvrsystem.h"
 
 using namespace std;
@@ -26,10 +27,11 @@ unsigned OpenVRSystem::n_instances = 0;
 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");
        }
@@ -43,7 +45,11 @@ OpenVRSystem::OpenVRSystem():
 
        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);
 }
@@ -101,20 +107,58 @@ OpenVRCombiner *OpenVRSystem::create_combiner(GL::View &v)
        return new OpenVRCombiner(*this, v);
 }
 
+OpenVRController *OpenVRSystem::create_controller()
+{
+       return new OpenVRController(*this);
+}
+
 void OpenVRSystem::tick()
 {
        vr::IVRSystem *vr_sys = vr::VRSystem();
 
-       vr::VREvent_t event;
+       OpenVRController::Event event;
        while(vr_sys->PollNextEvent(&event, sizeof(event)))
        {
-               if(event.eventType==vr::VREvent_TrackedDeviceActivated)
+               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()
@@ -141,5 +185,36 @@ 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
 } // namespace Msp