Skip to content

Commit bc717d9

Browse files
committed
Added base controller class
1 parent 63a5d81 commit bc717d9

File tree

7 files changed

+298
-0
lines changed

7 files changed

+298
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#include "ControllerDevice.hpp"
2+
#include <Windows.h>
3+
4+
TutorialDriver::ControllerDevice::ControllerDevice(std::string serial):m_serial(serial)
5+
{
6+
}
7+
8+
std::string TutorialDriver::ControllerDevice::serial()
9+
{
10+
return this->m_serial;
11+
}
12+
13+
void TutorialDriver::ControllerDevice::update(std::vector<vr::VREvent_t> events)
14+
{
15+
if (this->m_deviceIndex == vr::k_unTrackedDeviceIndexInvalid)
16+
return;
17+
18+
// Get deltatime
19+
auto now = std::chrono::system_clock::now();
20+
double deltaTimeSeconds = std::chrono::duration_cast<std::chrono::milliseconds>(now - m_lastFrameTime).count()/1000.0;
21+
this->m_lastFrameTime = now;
22+
23+
// Setup pose for this frame
24+
auto pose = this->GetPose();
25+
26+
// Get orientation
27+
this->m_yRot += (1.0 * (GetAsyncKeyState(0x66) == 0) - 1.0 * (GetAsyncKeyState(0x64) == 0)) * deltaTimeSeconds;
28+
this->m_xRot += (-1.0 * (GetAsyncKeyState(0x68) == 0) + 1.0 * (GetAsyncKeyState(0x62) == 0)) * deltaTimeSeconds;
29+
this->m_xRot = std::fmax(this->m_xRot, -3.14159/2);
30+
this->m_xRot = std::fmin(this->m_xRot, 3.14159/2);
31+
32+
linalg::vec<float, 4> yQuat{ 0, std::sinf((float)this->m_yRot / 2), 0, std::cosf((float)this->m_yRot / 2) };
33+
34+
linalg::vec<float, 4> xQuat{ std::sinf((float)this->m_xRot / 2), 0, 0, std::cosf((float)this->m_xRot / 2) };
35+
36+
linalg::vec<float, 4> pose_rot = linalg::qmul(yQuat, xQuat);
37+
38+
pose.qRotation.w = pose_rot.w;
39+
pose.qRotation.x = pose_rot.x;
40+
pose.qRotation.y = pose_rot.y;
41+
pose.qRotation.z = pose_rot.z;
42+
43+
// Update position based on rotation
44+
linalg::vec<float, 3> forward_vec{-1.0f * (GetAsyncKeyState(0x65) == 0) + 1.0f * (GetAsyncKeyState(0x60) == 0), 0, 0};
45+
linalg::vec<float, 3> right_vec{0, 0, 0};
46+
linalg::vec<float, 3> final_dir = forward_vec + right_vec;
47+
if (linalg::length(final_dir) > 0.01) {
48+
final_dir = linalg::normalize(final_dir) * (float)deltaTimeSeconds;
49+
final_dir = linalg::qrot(pose_rot, final_dir);
50+
this->m_x += final_dir.x;
51+
this->m_y += final_dir.y;
52+
this->m_z += final_dir.z;
53+
}
54+
55+
pose.vecPosition[0] = this->m_x;
56+
pose.vecPosition[1] = this->m_y;
57+
pose.vecPosition[2] = this->m_z;
58+
59+
// Post pose
60+
vr::VRServerDriverHost()->TrackedDevicePoseUpdated(this->device_index(), pose, sizeof(vr::DriverPose_t));
61+
}
62+
63+
vr::TrackedDeviceIndex_t TutorialDriver::ControllerDevice::device_index()
64+
{
65+
return this->m_deviceIndex;
66+
}
67+
68+
vr::EVRInitError TutorialDriver::ControllerDevice::Activate(uint32_t unObjectId)
69+
{
70+
this->m_deviceIndex = unObjectId;
71+
72+
// Get the properties handle
73+
auto props = vr::VRProperties()->TrackedDeviceToPropertyContainer(this->m_deviceIndex);
74+
75+
// Set some universe ID (Must be 2 or higher)
76+
vr::VRProperties()->SetUint64Property(props, vr::Prop_CurrentUniverseId_Uint64, 2);
77+
78+
// Set the IPD to be whatever steam has configured
79+
vr::VRProperties()->SetFloatProperty(props, vr::Prop_UserIpdMeters_Float, vr::VRSettings()->GetFloat(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_IPD_Float));
80+
81+
// Set the display FPS
82+
vr::VRProperties()->SetFloatProperty(props, vr::Prop_DisplayFrequency_Float, 90.f);
83+
84+
// Set up a model "number" (not needed but good to have)
85+
vr::VRProperties()->SetStringProperty(props, vr::Prop_ModelNumber_String, "Tutorial HMD Device");
86+
87+
// Set up icon paths
88+
vr::VRProperties()->SetStringProperty(props, vr::Prop_NamedIconPathDeviceReady_String, "{tutorial_hmd}/icons/hmd_ready.png");
89+
90+
vr::VRProperties()->SetStringProperty(props, vr::Prop_NamedIconPathDeviceOff_String, "{tutorial_hmd}/icons/hmd_not_ready.png");
91+
vr::VRProperties()->SetStringProperty(props, vr::Prop_NamedIconPathDeviceSearching_String, "{tutorial_hmd}/icons/hmd_not_ready.png");
92+
vr::VRProperties()->SetStringProperty(props, vr::Prop_NamedIconPathDeviceSearchingAlert_String, "{tutorial_hmd}/icons/hmd_not_ready.png");
93+
vr::VRProperties()->SetStringProperty(props, vr::Prop_NamedIconPathDeviceReadyAlert_String, "{tutorial_hmd}/icons/hmd_not_ready.png");
94+
vr::VRProperties()->SetStringProperty(props, vr::Prop_NamedIconPathDeviceNotReady_String, "{tutorial_hmd}/icons/hmd_not_ready.png");
95+
vr::VRProperties()->SetStringProperty(props, vr::Prop_NamedIconPathDeviceStandby_String, "{tutorial_hmd}/icons/hmd_not_ready.png");
96+
vr::VRProperties()->SetStringProperty(props, vr::Prop_NamedIconPathDeviceAlertLow_String, "{tutorial_hmd}/icons/hmd_not_ready.png");
97+
98+
this->m_lastFrameTime = std::chrono::system_clock::now();
99+
100+
return vr::EVRInitError::VRInitError_None;
101+
}
102+
103+
void TutorialDriver::ControllerDevice::Deactivate()
104+
{
105+
this->m_deviceIndex = vr::k_unTrackedDeviceIndexInvalid;
106+
}
107+
108+
void TutorialDriver::ControllerDevice::EnterStandby()
109+
{
110+
}
111+
112+
void* TutorialDriver::ControllerDevice::GetComponent(const char* pchComponentNameAndVersion)
113+
{
114+
return nullptr;
115+
}
116+
117+
void TutorialDriver::ControllerDevice::DebugRequest(const char* pchRequest, char* pchResponseBuffer, uint32_t unResponseBufferSize)
118+
{
119+
if (unResponseBufferSize >= 1)
120+
pchResponseBuffer[0] = 0;
121+
}
122+
123+
vr::DriverPose_t TutorialDriver::ControllerDevice::GetPose()
124+
{
125+
vr::DriverPose_t out_pose = { 0 };
126+
127+
out_pose.deviceIsConnected = true;
128+
out_pose.poseIsValid = true;
129+
out_pose.result = vr::ETrackingResult::TrackingResult_Running_OK;
130+
out_pose.willDriftInYaw = false;
131+
out_pose.shouldApplyHeadModel = false;
132+
out_pose.qDriverFromHeadRotation.w = out_pose.qWorldFromDriverRotation.w = out_pose.qRotation.w = 1.0;
133+
134+
return out_pose;
135+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include <chrono>
4+
#include <cmath>
5+
6+
#include <linalg.h>
7+
8+
#include <Driver/IVRDevice.hpp>
9+
10+
namespace TutorialDriver {
11+
class ControllerDevice : public IVRDevice {
12+
public:
13+
ControllerDevice(std::string serial);
14+
~ControllerDevice() = default;
15+
16+
// Inherited via IVRDevice
17+
virtual std::string serial() override;
18+
virtual void update(std::vector<vr::VREvent_t> events) override;
19+
virtual vr::TrackedDeviceIndex_t device_index() override;
20+
virtual vr::EVRInitError Activate(uint32_t unObjectId) override;
21+
virtual void Deactivate() override;
22+
virtual void EnterStandby() override;
23+
virtual void* GetComponent(const char* pchComponentNameAndVersion) override;
24+
virtual void DebugRequest(const char* pchRequest, char* pchResponseBuffer, uint32_t unResponseBufferSize) override;
25+
virtual vr::DriverPose_t GetPose() override;
26+
27+
private:
28+
vr::TrackedDeviceIndex_t m_deviceIndex = vr::k_unTrackedDeviceIndexInvalid;
29+
std::string m_serial;
30+
31+
double m_x = 0, m_y = 0, m_z = 0;
32+
double m_xRot = 0, m_yRot = 0;
33+
34+
std::chrono::system_clock::time_point m_lastFrameTime;
35+
36+
37+
};
38+
};
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include "DeviceProvider.hpp"
2+
3+
4+
vr::EVRInitError TutorialDriver::DeviceProvider::Init(vr::IVRDriverContext* pDriverContext)
5+
{
6+
// Perform driver context initialisation
7+
if (vr::EVRInitError init_error = vr::InitServerDriverContext(pDriverContext); init_error != vr::EVRInitError::VRInitError_None) {
8+
return init_error;
9+
}
10+
11+
auto leftControllerDevice = std::make_shared<ControllerDevice>("Tutorial_LeftControllerDevice");
12+
if (vr::VRServerDriverHost()->TrackedDeviceAdded(leftControllerDevice->serial().c_str(), vr::ETrackedDeviceClass::TrackedDeviceClass_Controller, leftControllerDevice.get()))
13+
this->m_devices.push_back(leftControllerDevice);
14+
15+
auto rightControllerDevice = std::make_shared<ControllerDevice>("Tutorial_RightControllerDevice");
16+
if (vr::VRServerDriverHost()->TrackedDeviceAdded(rightControllerDevice->serial().c_str(), vr::ETrackedDeviceClass::TrackedDeviceClass_Controller, rightControllerDevice.get()))
17+
this->m_devices.push_back(rightControllerDevice);
18+
19+
/*auto trackerDevice = std::make_shared<TrackerDevice>("Tutorial_TrackerDevice");
20+
if (vr::VRServerDriverHost()->TrackedDeviceAdded(trackerDevice->serial().c_str(), vr::ETrackedDeviceClass::TrackedDeviceClass_Controller, trackerDevice.get()))
21+
this->m_devices.push_back(trackerDevice);
22+
23+
auto trackingReference = std::make_shared<TrackingReferenceDevice>("Tutorial_TrackingReferenceDevice");
24+
if (vr::VRServerDriverHost()->TrackedDeviceAdded(trackingReference->serial().c_str(), vr::ETrackedDeviceClass::TrackedDeviceClass_TrackingReference, trackingReference.get()))
25+
this->m_devices.push_back(trackingReference);*/
26+
27+
28+
return vr::VRInitError_None;
29+
}
30+
31+
void TutorialDriver::DeviceProvider::Cleanup()
32+
{
33+
}
34+
35+
const char* const* TutorialDriver::DeviceProvider::GetInterfaceVersions()
36+
{
37+
return vr::k_InterfaceVersions;
38+
}
39+
40+
void TutorialDriver::DeviceProvider::RunFrame()
41+
{
42+
// Collect events
43+
vr::VREvent_t event;
44+
std::vector<vr::VREvent_t> events;
45+
while (vr::VRServerDriverHost()->PollNextEvent(&event, sizeof(event)))
46+
{
47+
events.push_back(event);
48+
}
49+
50+
// Update devices
51+
for (auto& device : m_devices)
52+
device->update(events);
53+
}
54+
55+
bool TutorialDriver::DeviceProvider::ShouldBlockStandbyMode()
56+
{
57+
return false;
58+
}
59+
60+
void TutorialDriver::DeviceProvider::EnterStandby()
61+
{
62+
}
63+
64+
void TutorialDriver::DeviceProvider::LeaveStandby()
65+
{
66+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include <vector>
4+
#include <memory>
5+
6+
#include <openvr_driver.h>
7+
8+
#include <Driver/ControllerDevice.hpp>
9+
#include <Driver/IVRDevice.hpp>
10+
11+
namespace TutorialDriver {
12+
class DeviceProvider : public vr::IServerTrackedDeviceProvider {
13+
public:
14+
// Inherited via IServerTrackedDeviceProvider
15+
virtual vr::EVRInitError Init(vr::IVRDriverContext* pDriverContext) override;
16+
virtual void Cleanup() override;
17+
virtual const char* const* GetInterfaceVersions() override;
18+
virtual void RunFrame() override;
19+
virtual bool ShouldBlockStandbyMode() override;
20+
virtual void EnterStandby() override;
21+
virtual void LeaveStandby() override;
22+
virtual ~DeviceProvider() = default;
23+
private:
24+
std::vector<std::shared_ptr<IVRDevice>> m_devices;
25+
};
26+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
#include <openvr_driver.h>
6+
7+
namespace TutorialDriver {
8+
class IVRDevice : public vr::ITrackedDeviceServerDriver {
9+
public:
10+
virtual std::string serial() = 0;
11+
virtual void update(std::vector<vr::VREvent_t> events) = 0;
12+
virtual vr::TrackedDeviceIndex_t device_index() = 0;
13+
14+
// Inherited via ITrackedDeviceServerDriver
15+
virtual vr::EVRInitError Activate(uint32_t unObjectId) = 0;
16+
virtual void Deactivate() = 0;
17+
virtual void EnterStandby() = 0;
18+
virtual void* GetComponent(const char* pchComponentNameAndVersion) = 0;
19+
virtual void DebugRequest(const char* pchRequest, char* pchResponseBuffer, uint32_t unResponseBufferSize) = 0;
20+
virtual vr::DriverPose_t GetPose() = 0;
21+
22+
~IVRDevice() = default;
23+
};
24+
};

driver_tutorial_devices/src/Native/DriverFactory.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#include "DriverFactory.hpp"
22

3+
static TutorialDriver::DeviceProvider gTrackedDeviceProvider;
4+
35
void* HmdDriverFactory(const char* interface_name, int* return_code) {
6+
if (std::strcmp(interface_name, vr::IServerTrackedDeviceProvider_Version) == 0) {
7+
return &gTrackedDeviceProvider;
8+
}
49

510
if (return_code)
611
*return_code = vr::VRInitError_Init_InterfaceNotFound;

driver_tutorial_devices/src/Native/DriverFactory.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@
44

55
#include <openvr_driver.h>
66

7+
#include <Driver/DeviceProvider.hpp>
8+
9+
extern TutorialDriver::DeviceProvider gDeviceProvider;
10+
711
extern "C" __declspec(dllexport) void* HmdDriverFactory(const char* interface_name, int* return_code);

0 commit comments

Comments
 (0)