add Quest single controller support

This commit is contained in:
2019-05-31 15:21:43 +02:00
parent f7cfdb3795
commit d2a62df5c7
2 changed files with 93 additions and 5 deletions

View File

@@ -3,6 +3,7 @@
#include "log.h" #include "log.h"
#include "rtt.h" #include "rtt.h"
#include "app.h" #include "app.h"
#include "canvas.h"
#include <unistd.h> #include <unistd.h>
ovrJava java; ovrJava java;
@@ -12,6 +13,7 @@ int swap_chain_count = 0;
int swap_chain_index = 0; int swap_chain_index = 0;
ovrMobile* ovr_context = nullptr; ovrMobile* ovr_context = nullptr;
uint64_t ovr_frame = 0; uint64_t ovr_frame = 0;
ovrDeviceID controller = -1;
void oculus_init(JavaVM* vm, JNIEnv* jni, jobject activity_class) void oculus_init(JavaVM* vm, JNIEnv* jni, jobject activity_class)
{ {
@@ -80,9 +82,98 @@ void oculus_init_vr(EGLDisplay display, EGLContext context, ANativeWindow* surfa
void oculus_draw() void oculus_draw()
{ {
// BEGIN OVR
const double predictedDisplayTime = vrapi_GetPredictedDisplayTime(ovr_context, ovr_frame); const double predictedDisplayTime = vrapi_GetPredictedDisplayTime(ovr_context, ovr_frame);
const ovrTracking2 tracking = vrapi_GetPredictedTracking2(ovr_context, predictedDisplayTime); const ovrTracking2 tracking = vrapi_GetPredictedTracking2(ovr_context, predictedDisplayTime);
auto pose_ovr = ovrMatrix4f_CreateFromQuaternion(&tracking.HeadPose.Pose.Orientation);
auto pose_ovr_tp = ovrMatrix4f_Transpose(&pose_ovr);
glm::mat4 pose = glm::make_mat4(reinterpret_cast<float*>(&pose_ovr_tp));
glm::vec3 head_pos = glm::make_vec3((float*)&tracking.HeadPose.Pose.Position);
if (controller == -1)
{
// init controller
ovrInputCapabilityHeader capsHeader;
for (int i = 0; ; i++)
{
LOG("")
if ( vrapi_EnumerateInputDevices( ovr_context, i, &capsHeader ) >= 0 )
{
if ( capsHeader.Type == ovrControllerType_TrackedRemote )
{
ovrInputTrackedRemoteCapabilities remoteCaps;
remoteCaps.Header = capsHeader;
if ( vrapi_GetInputDeviceCapabilities( ovr_context, &remoteCaps.Header ) >= 0 )
{
// remote is connected
if (remoteCaps.ControllerCapabilities & ovrControllerCaps_RightHand)
{
// right controller found
controller = capsHeader.DeviceID;
LOG("found controller id %d", (int)controller);
break;
}
}
}
}
else
{
break;
}
}
}
if (controller != -1)
{
ovrTracking trackingState;
vrapi_GetInputTrackingState(ovr_context, controller, predictedDisplayTime, &trackingState);
glm::vec3 c_pos = glm::make_vec3((float*)&trackingState.HeadPose.Pose.Position) - head_pos;
auto c_rot_ovr = ovrMatrix4f_CreateFromQuaternion(&trackingState.HeadPose.Pose.Orientation);
glm::mat4 c_rot = glm::make_mat4((float*)&c_rot_ovr);
glm::mat4 c_mat = glm::translate(c_pos);
App::I.vr_controller = c_mat;
App::I.vr_controller_pos = c_pos;
// update controllers
ovrInputStateTrackedRemote remote_state;
remote_state.Header.ControllerType = ovrControllerType_TrackedRemote;
vrapi_GetCurrentInputState(ovr_context, controller, &remote_state.Header);
static cbuffer<glm::vec3> controller_points(10);
static bool down = false;
static glm::vec3 last_point;
auto cur = glm::normalize(c_pos) * 800.f;
if (remote_state.IndexTrigger > 0.f)
{
if (!down)
{
controller_points.clear();
last_point = cur;
Canvas::I->stroke_start(cur, remote_state.IndexTrigger);
down = true;
}
else
{
controller_points.add(cur);
auto p = controller_points.average();
if (glm::distance(last_point, p) > 0.1f)
{
Canvas::I->stroke_update(p, remote_state.IndexTrigger);
App::I.update(0);
last_point = p;
}
}
}
else if (down)
{
down = false;
Canvas::I->stroke_end();
}
}
// update hmd
auto layer = vrapi_DefaultLayerProjection2(); auto layer = vrapi_DefaultLayerProjection2();
//ovrVector4f red = {1, 1, 0, 1}; //ovrVector4f red = {1, 1, 0, 1};
//auto layer = vrapi_DefaultLayerSolidColorProjection2(&red); //auto layer = vrapi_DefaultLayerSolidColorProjection2(&red);
@@ -97,9 +188,6 @@ void oculus_draw()
glm::mat4 proj = glm::make_mat4(reinterpret_cast<const float*>(&proj_ovr)); glm::mat4 proj = glm::make_mat4(reinterpret_cast<const float*>(&proj_ovr));
auto view_ovr = ovrMatrix4f_Transpose(&tracking.Eye[eye].ViewMatrix); auto view_ovr = ovrMatrix4f_Transpose(&tracking.Eye[eye].ViewMatrix);
glm::mat4 view = glm::make_mat4(reinterpret_cast<const float*>(&view_ovr)); glm::mat4 view = glm::make_mat4(reinterpret_cast<const float*>(&view_ovr));
auto pose_ovr = ovrMatrix4f_CreateFromQuaternion(&tracking.HeadPose.Pose.Orientation);
auto pose_ovr_tp = ovrMatrix4f_Transpose(&pose_ovr);
glm::mat4 pose = glm::make_mat4(reinterpret_cast<float*>(&pose_ovr_tp));
App::I.vr_draw(proj, view, pose); App::I.vr_draw(proj, view, pose);
rtt.unbindFramebuffer(); rtt.unbindFramebuffer();
layer.Textures[eye].ColorSwapChain = swap_chain[eye]; layer.Textures[eye].ColorSwapChain = swap_chain[eye];

View File

@@ -659,7 +659,7 @@ static void engine_draw_frame(struct engine* engine) {
if (elapsed_1s > 1.f) if (elapsed_1s > 1.f)
{ {
LOG("vr %d fps", rendered_frames); //LOG("vr %d fps", rendered_frames);
elapsed_1s = 0; elapsed_1s = 0;
rendered_frames = 0; rendered_frames = 0;
} }