+ 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);