From d4156f16f3b782b2ac4ed1aaa62971e9d9257f39 Mon Sep 17 00:00:00 2001 From: milek7 Date: Sat, 24 Oct 2020 18:07:47 +0200 Subject: [PATCH] vr WIP --- opengl33renderer.cpp | 48 ++- openvrconfig/bindings_knuckles.json | 34 ++ openvrconfig/openvr_actions.json | 18 + vr/openvr_imp.cpp | 540 +++++++++++++++++++++++++++- vr/openvr_imp.h | 18 +- vr/vr_interface.h | 1 + 6 files changed, 634 insertions(+), 25 deletions(-) create mode 100755 openvrconfig/bindings_knuckles.json create mode 100644 openvrconfig/openvr_actions.json diff --git a/opengl33renderer.cpp b/opengl33renderer.cpp index 12f5f672..e0303632 100644 --- a/opengl33renderer.cpp +++ b/opengl33renderer.cpp @@ -615,7 +615,7 @@ void opengl33_renderer::draw_debug_ui() if (!debug_ui_active) return; - if (ImGui::Begin("headlight config", &debug_ui_active)) + if (ImGui::Begin("Headlight config", &debug_ui_active)) { ImGui::SetWindowSize(ImVec2(0, 0)); @@ -630,6 +630,12 @@ void opengl33_renderer::draw_debug_ui() ImGui::SliderFloat("intensity", &conf.intensity, 0.0f, 10.0f); } ImGui::End(); + + ImGui::SetNextWindowSize(ImVec2(400, 400)); + if (ImGui::Begin("Pickbuffer") && m_pick_tex) { + ImGui::Image(reinterpret_cast(m_pick_tex->id), ImGui::GetContentRegionAvail(), ImVec2(0, 1.0), ImVec2(1.0, 0)); + } + ImGui::End(); } // runs jobs needed to generate graphics for specified render pass @@ -1358,9 +1364,6 @@ void opengl33_renderer::setup_pass(viewport_config &Viewport, renderpass_config if (Viewport.main) // TODO: update window sizes also for extra viewports target_size = glm::ivec2(Global.iWindowWidth, Global.iWindowHeight); - float const fovy = glm::radians(Global.FieldOfView / Global.ZoomFactor); - float const aspect = (float)target_size.x / std::max(1.f, (float)target_size.y); - Config.viewport_camera.position() = Global.pCamera.Pos; switch (Mode) @@ -1466,10 +1469,31 @@ void opengl33_renderer::setup_pass(viewport_config &Viewport, renderpass_config camera.position() = Global.pCamera.Pos; Global.pCamera.SetMatrix(viewmatrix); - // projection - float znear = 0.1f * Global.ZoomFactor; - float zfar = Config.draw_range * Global.fDistanceFactor; - camera.projection() = perspective_projection(Viewport.projection, znear, zfar, frustumtest_proj); + viewport_proj_config proj = Viewport.projection; + + // projection + float znear = 0.1f * Global.ZoomFactor; + float zfar = Config.draw_range * Global.fDistanceFactor; + + if (vr) { + glm::mat4 transform = vr->get_pick_transform(); + camera.position() += glm::vec3(transform[3]) * glm::mat3(viewmatrix); + viewmatrix = glm::dmat4(glm::inverse(glm::mat3(transform))) * viewmatrix; + + znear = 0.01f; + zfar = 10.0f; + float const fovy = glm::radians(3.0f); + + glm::vec2 screen_h = glm::vec2(1000.0f, 1000.0f) / 2.0f; + float const dist = screen_h.y / glm::tan(fovy / 2.0f); + + proj.pa = glm::vec3(-screen_h.x, -screen_h.y, -dist); + proj.pb = glm::vec3( screen_h.x, -screen_h.y, -dist); + proj.pc = glm::vec3(-screen_h.x, screen_h.y, -dist); + proj.pe = glm::vec3(0.0f, 0.0f, 0.0f); + } + + camera.projection() = perspective_projection(proj, znear, zfar, frustumtest_proj); break; } case rendermode::reflections: @@ -4134,12 +4158,14 @@ void opengl33_renderer::Update_Pick_Control() if (!m_control_pick_requests.empty()) { - // determine point to examine - glm::dvec2 mousepos = Application.get_cursor_pos(); - mousepos.y = Global.iWindowHeight - mousepos.y; // cursor coordinates are flipped compared to opengl + glm::dvec2 mousepos = Application.get_cursor_pos(); + mousepos.y = Global.iWindowHeight - mousepos.y; // cursor coordinates are flipped compared to opengl glm::ivec2 pickbufferpos; pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)}; + + if (vr) + pickbufferpos = glm::ivec2(EU07_PICKBUFFERSIZE / 2 + 1, EU07_PICKBUFFERSIZE / 2 + 1); pickbufferpos = glm::clamp(pickbufferpos, glm::ivec2(0, 0), glm::ivec2(EU07_PICKBUFFERSIZE - 1, EU07_PICKBUFFERSIZE - 1)); Render_pass(*m_viewports.front().get(), rendermode::pickcontrols); diff --git a/openvrconfig/bindings_knuckles.json b/openvrconfig/bindings_knuckles.json new file mode 100755 index 00000000..9d3bd51f --- /dev/null +++ b/openvrconfig/bindings_knuckles.json @@ -0,0 +1,34 @@ +{ + "action_manifest_version" : 0, + "alias_info" : {}, + "bindings" : { + "/actions/main" : { + "sources": [ + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/PrimaryAction" + } + }, + "mode" : "button", + "path" : "/user/hand/right/input/a" + }, + { + "inputs" : { + "click" : { + "output" : "/actions/main/in/SecondaryAction" + } + }, + "mode" : "button", + "path" : "/user/hand/right/input/b" + } + ] + } + }, + "category" : "steamvr_input", + "controller_type" : "knuckles", + "description" : "Default two handed bindings with movement on the off hand", + "name" : "Dual Controllers (Movement on Off Hand)", + "options" : {}, + "simulated_actions" : [] +} diff --git a/openvrconfig/openvr_actions.json b/openvrconfig/openvr_actions.json new file mode 100644 index 00000000..3daa851b --- /dev/null +++ b/openvrconfig/openvr_actions.json @@ -0,0 +1,18 @@ +{ + "default_bindings": [ + { + "binding_url" : "bindings_knuckles.json", + "controller_type" : "knuckles" + } + ], + "actions": [ + { "name": "/actions/main/in/PrimaryAction", "requirement": "mandatory", "type": "boolean" }, + { "name": "/actions/main/in/SecondaryAction", "requirement": "mandatory", "type": "boolean" } + ], + "action_sets": [ + { "name": "/actions/main", "usage": "leftright" } + ], + "localization": [ + { "language_tag": "en_us", "/actions/main": "Main", "/actions/main/in/PrimaryAction": "Primary action", "/actions/main/in/SecondaryAction": "Secondary action" } + ] +} diff --git a/vr/openvr_imp.cpp b/vr/openvr_imp.cpp index e772eedf..a6b95d27 100644 --- a/vr/openvr_imp.cpp +++ b/vr/openvr_imp.cpp @@ -3,6 +3,8 @@ #include "Logs.h" #include "Globals.h" #include "renderer.h" +#include "simulation.h" +#include "application.h" vr_openvr::vr_openvr() { @@ -17,11 +19,12 @@ vr_openvr::vr_openvr() vr::VRInput()->GetInputSourceHandle("/user/hand/left", &inputhandle_left); vr::VRInput()->GetInputSourceHandle("/user/hand/right", &inputhandle_right); - std::string action_path = std::filesystem::current_path().string() + "/openvr_actions.json"; + std::string action_path = std::filesystem::current_path().string() + "/openvrconfig/openvr_actions.json"; vr::VRInput()->SetActionManifestPath(action_path.c_str()); vr::VRInput()->GetActionSetHandle("/actions/main", &actionset); vr::VRInput()->GetActionHandle("/actions/main/in/PrimaryAction", &primary_action); + vr::VRInput()->GetActionHandle("/actions/main/in/SecondaryAction", &secondary_action); } glm::ivec2 vr_openvr::get_target_size() @@ -39,12 +42,19 @@ viewport_proj_config vr_openvr::get_proj_config(eye_e e) vr_system->GetProjectionRaw(eye, &left, &right, &top, &bottom); float ipd = vr_system->GetEyeToHeadTransform(eye).m[0][3]; + //glm::mat4 eye_mat = glm::inverse(glm::transpose(get_matrix(vr_system->GetEyeToHeadTransform(eye)))); viewport_proj_config proj; proj.pe = glm::vec3(ipd, 0.0f, 0.0f); + //glm::vec3 zz = glm::vec4(ipd + left, top, -1.0f, 1.0f) * (eye_mat); proj.pa = glm::vec3(ipd + left, top, -1.0f); + + //WriteLog("pa: " + glm::to_string(zz)); + //WriteLog("should be: " + glm::to_string(proj.pa)); + //WriteLog("---"); + proj.pc = glm::vec3(ipd + left, bottom, -1.0f); proj.pb = glm::vec3(ipd + right, top, -1.0f); @@ -52,7 +62,7 @@ viewport_proj_config vr_openvr::get_proj_config(eye_e e) return proj; } -glm::mat4 vr_openvr::get_matrix(vr::HmdMatrix34_t &src) +glm::mat4 vr_openvr::get_matrix(const vr::HmdMatrix34_t &src) { return glm::mat4(glm::transpose(glm::make_mat3x4((float*)(src.m)))); } @@ -104,12 +114,22 @@ void vr_openvr::begin_frame() } controllers[i]->model = std::make_unique(); + gfx::vertex_array vertices { + gfx::basic_vertex{ glm::vec3(0.005f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f) }, + gfx::basic_vertex{ glm::vec3(-0.005f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f) }, + gfx::basic_vertex{ glm::vec3(0.0f, 0.0f, -2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f) }, + + gfx::basic_vertex{ glm::vec3(0.0f, 0.0f, -2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f) }, + gfx::basic_vertex{ glm::vec3(-0.005f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f) }, + gfx::basic_vertex{ glm::vec3(0.005f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec2(0.0f, 0.0f) } }; controllers[i]->model->AppendChildFromGeometry("__root", "none", gfx::vertex_array(), gfx::index_array()); + + controllers[i]->model->AppendChildFromGeometry("__pointer", "__root", vertices, gfx::index_array()); } } for (size_t c = controllers[i]->pending_components.size(); c-- != 0;) { - uint32_t component = controllers[i]->pending_components[c]; + int32_t component = controllers[i]->pending_components[c]; const char *rendermodel = controllers[i]->rendermodel.c_str(); char rendermodel_name[256]; @@ -141,11 +161,11 @@ void vr_openvr::begin_frame() else if (ret != vr::VRRenderModelError_None) goto component_done; - indices.resize(model->unTriangleCount * 3); + indices.reserve(model->unTriangleCount * 3); for (size_t v = 0; v < model->unTriangleCount * 3; v++) indices.push_back(model->rIndexData[v]); - vertices.resize(model->unVertexCount); + vertices.reserve(model->unVertexCount); for (size_t v = 0; v < model->unVertexCount; v++) { const vr::RenderModel_Vertex_t *vertex = &model->rVertexData[v]; vertices.push_back(gfx::basic_vertex( @@ -213,6 +233,9 @@ texture_done: for (TSubModel *component : controllers[i]->active_components) update_component(controllers[i]->rendermodel, controllers[i]->inputhandle, component); } + + if (i == primary_controller) + primary_controller_transform = device_pose; } } @@ -223,18 +246,71 @@ texture_done: vr::VRInput()->UpdateActionState(&active_actionset, sizeof(active_actionset), 1); - vr::InputDigitalActionData_t actiondata; - vr::VRInput()->GetDigitalActionData(primary_action, &actiondata, sizeof(actiondata), vr::k_ulInvalidInputValueHandle); - if (actiondata.bChanged && actiondata.bState) { - WriteLog("VR click!"); - } + vr::InputDigitalActionData_t actiondata_pri; + vr::VRInput()->GetDigitalActionData(primary_action, &actiondata_pri, sizeof(actiondata_pri), vr::k_ulInvalidInputValueHandle); + vr::InputDigitalActionData_t actiondata_sec; + vr::VRInput()->GetDigitalActionData(secondary_action, &actiondata_sec, sizeof(actiondata_sec), vr::k_ulInvalidInputValueHandle); + + bool any_changed = (actiondata_pri.bChanged || actiondata_sec.bChanged); + bool any_active = (actiondata_pri.bState || actiondata_sec.bState); + + if (command_active == user_command::none && any_changed) { + bool primary = actiondata_pri.bState; + + vr::InputOriginInfo_t origin; + vr::VRInput()->GetOriginTrackedDeviceInfo(primary ? actiondata_pri.activeOrigin : actiondata_sec.activeOrigin, &origin, sizeof(origin)); + primary_controller = origin.trackedDeviceIndex; + + GfxRenderer->Pick_Control_Callback([this, primary](TSubModel const *control, const glm::vec2 pos) { + if (command_active != user_command::none) + return; + + if (control != nullptr) { + if (control->screen_touch_list) { + control->screen_touch_list->emplace_back(pos); + return; + } + + auto it = m_buttonbindings.find(simulation::Train->GetLabel(control)); + if (it == m_buttonbindings.end()) + return; + + if (primary) + command_active = it->second.primary; + else + command_active = it->second.secondary; + command_relay relay; + relay.post(command_active, 0, 0, GLFW_PRESS, 0); + } + }); + } else if (command_active != user_command::none && !any_active) { + command_relay relay; + relay.post(command_active, 0, 0, GLFW_RELEASE, 0); + + command_active = user_command::none; + } +/* bool prev_should_pause = should_pause; should_pause = vr_system->ShouldApplicationPause(); if (prev_should_pause != should_pause) - relay.post(user_command::focuspauseset, should_pause ? 1.0 : 0.0, 0.0, GLFW_PRESS, 0); + relay.post(user_command::focuspauseset, should_pause ? 1.0 : 0.0, 0.0, GLFW_PRESS, 0);*/ draw_controllers = !vr_system->IsSteamVRDrawingControllers(); + + vr::VREvent_t event; + while (vr_system->PollNextEvent(&event, sizeof(event))) + { + if (event.eventType == vr::VREvent_Quit) { + vr_system->AcknowledgeQuit_Exiting(); + Application.queue_quit(true); + } + } +} + +glm::mat4 vr_openvr::get_pick_transform() +{ + return primary_controller_transform; } bool vr_openvr::update_component(const std::string &rendermodel, vr::VRInputValueHandle_t handle, TSubModel *component) @@ -260,7 +336,7 @@ void vr_openvr::submit(vr_openvr::eye_e eye, opengl_texture* tex) vr::Texture_t hmd_tex = { (void*)(uint64_t)tex->id, vr::TextureType_OpenGL, - Global.gfx_shadergamma ? vr::ColorSpace_Linear : vr::ColorSpace_Gamma }; + vr::ColorSpace_Gamma }; vr::VRCompositor()->Submit(eye == vr_interface::eye_left ? vr::Eye_Left : vr::Eye_Right, &hmd_tex); } @@ -296,5 +372,445 @@ std::unique_ptr vr_openvr::create_func() return std::unique_ptr(new vr_openvr()); } +std::unordered_map vr_openvr::m_buttonbindings = +{ + /*{ "jointctrl:", { + user_command::jointcontrollerset, + user_command::none } },*/ + { "mainctrl:", { + user_command::mastercontrollerincrease, + user_command::mastercontrollerdecrease } }, + { "scndctrl:", { + user_command::secondcontrollerincrease, + user_command::secondcontrollerdecrease } }, + { "shuntmodepower:", { + user_command::secondcontrollerincrease, + user_command::secondcontrollerdecrease } }, + { "tempomat_sw:", { + user_command::tempomattoggle, + user_command::none } }, + { "dirkey:", { + user_command::reverserincrease, + user_command::reverserdecrease } }, + { "dirforward_bt:", { + user_command::reverserforward, + user_command::none } }, + { "dirneutral_bt:", { + user_command::reverserneutral, + user_command::none } }, + { "dirbackward_bt:", { + user_command::reverserbackward, + user_command::none } }, + { "brakectrl:", { + user_command::trainbrakeincrease, + user_command::trainbrakedecrease } }, + { "localbrake:", { + user_command::independentbrakeincrease, + user_command::independentbrakedecrease } }, + { "manualbrake:", { + user_command::manualbrakeincrease, + user_command::manualbrakedecrease } }, + { "alarmchain:", { + user_command::alarmchaintoggle, + user_command::none } }, + { "brakeprofile_sw:", { + user_command::brakeactingspeedincrease, + user_command::brakeactingspeeddecrease } }, + // TODO: dedicated methods for braking speed switches + { "brakeprofileg_sw:", { + user_command::brakeactingspeedsetcargo, + user_command::brakeactingspeedsetpassenger } }, + { "brakeprofiler_sw:", { + user_command::brakeactingspeedsetrapid, + user_command::brakeactingspeedsetpassenger } }, + { "brakeopmode_sw:", { + user_command::trainbrakeoperationmodeincrease, + user_command::trainbrakeoperationmodedecrease } }, + { "maxcurrent_sw:", { + user_command::motoroverloadrelaythresholdtoggle, + user_command::none } }, + { "waterpumpbreaker_sw:", { + user_command::waterpumpbreakertoggle, + user_command::none } }, + { "waterpump_sw:", { + user_command::waterpumptoggle, + user_command::none } }, + { "waterheaterbreaker_sw:", { + user_command::waterheaterbreakertoggle, + user_command::none } }, + { "waterheater_sw:", { + user_command::waterheatertoggle, + user_command::none } }, + { "fuelpump_sw:", { + user_command::fuelpumptoggle, + user_command::none } }, + { "oilpump_sw:", { + user_command::oilpumptoggle, + user_command::none } }, + { "motorblowersfront_sw:", { + user_command::motorblowerstogglefront, + user_command::none } }, + { "motorblowersrear_sw:", { + user_command::motorblowerstogglerear, + user_command::none } }, + { "motorblowersalloff_sw:", { + user_command::motorblowersdisableall, + user_command::none } }, + { "coolingfans_sw:", { + user_command::coolingfanstoggle, + user_command::none } }, + { "main_off_bt:", { + user_command::linebreakeropen, + user_command::none } }, + { "main_on_bt:",{ + user_command::linebreakerclose, + user_command::none } }, + { "security_reset_bt:", { + user_command::alerteracknowledge, + user_command::none } }, + { "releaser_bt:", { + user_command::independentbrakebailoff, + user_command::none } }, + { "springbraketoggle_bt:",{ + user_command::springbraketoggle, + user_command::none } }, + { "springbrakeon_bt:",{ + user_command::springbrakeenable, + user_command::none } }, + { "springbrakeoff_bt:",{ + user_command::springbrakedisable, + user_command::none } }, + { "universalbrake1_bt:",{ + user_command::universalbrakebutton1, + user_command::none } }, + { "universalbrake2_bt:",{ + user_command::universalbrakebutton2, + user_command::none } }, + { "universalbrake3_bt:",{ + user_command::universalbrakebutton3, + user_command::none } }, + { "epbrake_bt:",{ + user_command::epbrakecontroltoggle, + user_command::none } }, + { "sand_bt:", { + user_command::sandboxactivate, + user_command::none } }, + { "antislip_bt:", { + user_command::wheelspinbrakeactivate, + user_command::none } }, + { "horn_bt:", { + user_command::hornhighactivate, + user_command::hornlowactivate } }, + { "hornlow_bt:", { + user_command::hornlowactivate, + user_command::none } }, + { "hornhigh_bt:", { + user_command::hornhighactivate, + user_command::none } }, + { "whistle_bt:", { + user_command::whistleactivate, + user_command::none } }, + { "fuse_bt:", { + user_command::motoroverloadrelayreset, + user_command::none } }, + { "converterfuse_bt:", { + user_command::converteroverloadrelayreset, + user_command::none } }, + { "relayreset1_bt:", { + user_command::universalrelayreset1, + user_command::none } }, + { "relayreset2_bt:", { + user_command::universalrelayreset2, + user_command::none } }, + { "relayreset3_bt:", { + user_command::universalrelayreset3, + user_command::none } }, + { "stlinoff_bt:", { + user_command::motorconnectorsopen, + user_command::none } }, + { "doorleftpermit_sw:", { + user_command::doorpermitleft, + user_command::none } }, + { "doorrightpermit_sw:", { + user_command::doorpermitright, + user_command::none } }, + { "doorpermitpreset_sw:", { + user_command::doorpermitpresetactivatenext, + user_command::doorpermitpresetactivateprevious } }, + { "door_left_sw:", { + user_command::doortoggleleft, + user_command::none } }, + { "door_right_sw:", { + user_command::doortoggleright, + user_command::none } }, + { "doorlefton_sw:", { + user_command::dooropenleft, + user_command::none } }, + { "doorrighton_sw:", { + user_command::dooropenright, + user_command::none } }, + { "doorleftoff_sw:", { + user_command::doorcloseleft, + user_command::none } }, + { "doorrightoff_sw:", { + user_command::doorcloseright, + user_command::none } }, + { "doorallon_sw:", { + user_command::dooropenall, + user_command::none } }, + { "dooralloff_sw:", { + user_command::doorcloseall, + user_command::none } }, + { "doorstep_sw:", { + user_command::doorsteptoggle, + user_command::none } }, + { "doormode_sw:", { + user_command::doormodetoggle, + user_command::none } }, + { "departure_signal_bt:", { + user_command::departureannounce, + user_command::none } }, + { "upperlight_sw:", { + user_command::headlighttoggleupper, + user_command::none } }, + { "leftlight_sw:", { + user_command::headlighttoggleleft, + user_command::none } }, + { "rightlight_sw:", { + user_command::headlighttoggleright, + user_command::none } }, + { "dimheadlights_sw:", { + user_command::headlightsdimtoggle, + user_command::none } }, + { "leftend_sw:", { + user_command::redmarkertoggleleft, + user_command::none } }, + { "rightend_sw:", { + user_command::redmarkertoggleright, + user_command::none } }, + { "lights_sw:", { + user_command::lightspresetactivatenext, + user_command::lightspresetactivateprevious } }, + { "rearupperlight_sw:", { + user_command::headlighttogglerearupper, + user_command::none } }, + { "rearleftlight_sw:", { + user_command::headlighttogglerearleft, + user_command::none } }, + { "rearrightlight_sw:", { + user_command::headlighttogglerearright, + user_command::none } }, + { "rearleftend_sw:", { + user_command::redmarkertogglerearleft, + user_command::none } }, + { "rearrightend_sw:", { + user_command::redmarkertogglerearright, + user_command::none } }, + { "compressor_sw:", { + user_command::compressortoggle, + user_command::none } }, + { "compressorlocal_sw:", { + user_command::compressortogglelocal, + user_command::none } }, + { "compressorlist_sw:", { + user_command::compressorpresetactivatenext, + user_command::compressorpresetactivateprevious } }, + { "converter_sw:", { + user_command::convertertoggle, + user_command::none } }, + { "converterlocal_sw:", { + user_command::convertertogglelocal, + user_command::none } }, + { "converteroff_sw:", { + user_command::convertertoggle, + user_command::none } }, // TODO: dedicated converter shutdown command + { "main_sw:", { + user_command::linebreakertoggle, + user_command::none } }, + { "radio_sw:", { + user_command::radiotoggle, + user_command::none } }, + { "radiochannel_sw:", { + user_command::radiochannelincrease, + user_command::radiochanneldecrease } }, + { "radiochannelprev_sw:", { + user_command::radiochanneldecrease, + user_command::none } }, + { "radiochannelnext_sw:", { + user_command::radiochannelincrease, + user_command::none } }, + { "radiostop_sw:", { + user_command::radiostopsend, + user_command::none } }, + { "radiotest_sw:", { + user_command::radiostoptest, + user_command::none } }, + { "radiocall3_sw:", { + user_command::radiocall3send, + user_command::none } }, + { "radiovolume_sw:",{ + user_command::radiovolumeincrease, + user_command::radiovolumedecrease } }, + { "radiovolumeprev_sw:",{ + user_command::radiovolumedecrease, + user_command::none } }, + { "radiovolumenext_sw:",{ + user_command::radiovolumeincrease, + user_command::none } }, + { "pantfront_sw:", { + user_command::pantographtogglefront, + user_command::none } }, + { "pantrear_sw:", { + user_command::pantographtogglerear, + user_command::none } }, + { "pantfrontoff_sw:", { + user_command::pantographlowerfront, + user_command::none } }, + { "pantrearoff_sw:", { + user_command::pantographlowerrear, + user_command::none } }, + { "pantalloff_sw:", { + user_command::pantographlowerall, + user_command::none } }, + { "pantselected_sw:", { + user_command::pantographtoggleselected, + user_command::none } }, // TBD: bind lowerselected in case of toggle switch + { "pantselectedoff_sw:", { + user_command::pantographlowerselected, + user_command::none } }, + { "pantselect_sw:", { + user_command::pantographselectnext, + user_command::pantographselectprevious } }, + { "pantcompressor_sw:", { + user_command::pantographcompressoractivate, + user_command::none } }, + { "pantcompressorvalve_sw:", { + user_command::pantographcompressorvalvetoggle, + user_command::none } }, + { "trainheating_sw:", { + user_command::heatingtoggle, + user_command::none } }, + { "signalling_sw:", { + user_command::mubrakingindicatortoggle, + user_command::none } }, + { "door_signalling_sw:", { + user_command::doorlocktoggle, + user_command::none } }, + { "nextcurrent_sw:", { + user_command::mucurrentindicatorothersourceactivate, + user_command::none } }, + { "distancecounter_sw:", { + user_command::distancecounteractivate, + user_command::none } }, + { "instrumentlight_sw:", { + user_command::instrumentlighttoggle, + user_command::none } }, + { "dashboardlight_sw:", { + user_command::dashboardlighttoggle, + user_command::none } }, + { "timetablelight_sw:", { + user_command::timetablelighttoggle, + user_command::none } }, + { "cablight_sw:", { + user_command::interiorlighttoggle, + user_command::none } }, + { "cablightdim_sw:", { + user_command::interiorlightdimtoggle, + user_command::none } }, + { "compartmentlights_sw:", { + user_command::compartmentlightstoggle, + user_command::none } }, + { "compartmentlightson_sw:", { + user_command::compartmentlightsenable, + user_command::none } }, + { "compartmentlightsoff_sw:", { + user_command::compartmentlightsdisable, + user_command::none } }, + { "battery_sw:", { + user_command::batterytoggle, + user_command::none } }, + { "batteryon_sw:", { + user_command::batteryenable, + user_command::none } }, + { "batteryoff_sw:", { + user_command::batterydisable, + user_command::none } }, + { "couplingdisconnect_sw:",{ + user_command::occupiedcarcouplingdisconnect, + user_command::none } }, + { "universal0:", { + user_command::generictoggle0, + user_command::none } }, + { "universal1:", { + user_command::generictoggle1, + user_command::none } }, + { "universal2:", { + user_command::generictoggle2, + user_command::none } }, + { "universal3:", { + user_command::generictoggle3, + user_command::none } }, + { "universal4:", { + user_command::generictoggle4, + user_command::none } }, + { "universal5:", { + user_command::generictoggle5, + user_command::none } }, + { "universal6:", { + user_command::generictoggle6, + user_command::none } }, + { "universal7:", { + user_command::generictoggle7, + user_command::none } }, + { "universal8:", { + user_command::generictoggle8, + user_command::none } }, + { "universal9:", { + user_command::generictoggle9, + user_command::none } }, + { "speedinc_bt:",{ + user_command::speedcontrolincrease, + user_command::none } }, + { "speeddec_bt:",{ + user_command::speedcontroldecrease, + user_command::none } }, + { "speedctrlpowerinc_bt:",{ + user_command::speedcontrolpowerincrease, + user_command::none } }, + { "speedctrlpowerdec_bt:",{ + user_command::speedcontrolpowerdecrease, + user_command::none } }, + { "speedbutton0:",{ + user_command::speedcontrolbutton0, + user_command::none } }, + { "speedbutton1:",{ + user_command::speedcontrolbutton1, + user_command::none } }, + { "speedbutton2:",{ + user_command::speedcontrolbutton2, + user_command::none } }, + { "speedbutton3:",{ + user_command::speedcontrolbutton3, + user_command::none } }, + { "speedbutton4:",{ + user_command::speedcontrolbutton4, + user_command::none } }, + { "speedbutton5:",{ + user_command::speedcontrolbutton5, + user_command::none } }, + { "speedbutton6:",{ + user_command::speedcontrolbutton6, + user_command::none } }, + { "speedbutton7:",{ + user_command::speedcontrolbutton7, + user_command::none } }, + { "speedbutton8:",{ + user_command::speedcontrolbutton8, + user_command::none } }, + { "speedbutton9:",{ + user_command::speedcontrolbutton9, + user_command::none } }, +}; + bool vr_openvr::backend_register = vr_interface_factory::get_instance()->register_backend("openvr", vr_openvr::create_func); diff --git a/vr/openvr_imp.h b/vr/openvr_imp.h index d553bda6..d3fe98ef 100644 --- a/vr/openvr_imp.h +++ b/vr/openvr_imp.h @@ -8,7 +8,7 @@ private: struct controller_info { std::unique_ptr model; std::string rendermodel; - std::vector pending_components; + std::vector pending_components; std::vector active_components; std::vector> pending_textures; vr::VRInputValueHandle_t inputhandle = 0; @@ -22,14 +22,27 @@ private: vr::VRInputValueHandle_t inputhandle_left = 0; vr::VRInputValueHandle_t inputhandle_right = 0; + uint32_t primary_controller; + glm::mat4 primary_controller_transform; + + user_command command_active = user_command::none; + bool update_component(const std::string &rendermodel, vr::VRInputValueHandle_t handle, TSubModel *component); - glm::mat4 get_matrix(vr::HmdMatrix34_t &src); + glm::mat4 get_matrix(const vr::HmdMatrix34_t &src); vr::VRActionSetHandle_t actionset = 0; vr::VRActionHandle_t primary_action = 0; + vr::VRActionHandle_t secondary_action = 0; + bool should_pause = false; bool draw_controllers = true; + struct button_bindings { + user_command primary; + user_command secondary; + }; + + static std::unordered_map m_buttonbindings; command_relay relay; public: @@ -39,6 +52,7 @@ public: void begin_frame() override; void submit(eye_e, opengl_texture*) override; std::vector get_render_models() override; + glm::mat4 get_pick_transform() override; void finish_frame() override; ~vr_openvr() override; diff --git a/vr/vr_interface.h b/vr/vr_interface.h index acdbcb15..7be656c8 100644 --- a/vr/vr_interface.h +++ b/vr/vr_interface.h @@ -16,6 +16,7 @@ public: virtual void begin_frame() = 0; virtual void submit(eye_e, opengl_texture*) = 0; virtual std::vector get_render_models() = 0; + virtual glm::mat4 get_pick_transform() = 0; virtual void finish_frame() = 0; virtual ~vr_interface() = 0; };