Select Git revision
-
Nick Anton Christoph Kleine-Tebbe authoredNick Anton Christoph Kleine-Tebbe authored
test_vr_controller.cpp 6.39 KiB
//------------------------------------------------------------------------------
// Project Phoenix
//
// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
// Virtual Reality & Immersive Visualization Group.
//------------------------------------------------------------------------------
// License
//
// Licensed under the 3-Clause BSD License (the "License");
// you may not use this file except in compliance with the License.
// See the file LICENSE for the full text.
// You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//------------------------------------------------------------------------------
#include <memory>
#include <string>
#include "catch/catch.hpp"
#include "phx/core/logger.hpp"
#include "phx/input/vr_controller.hpp"
#include "mocks/openvr_mock.hpp"
#include "test_utilities/glm_vec.hpp"
#include "test_utilities/log_capture.hpp"
#include "trompeloeil.hpp"
extern template struct trompeloeil::reporter<trompeloeil::specialized>;
using trompeloeil::_;
namespace {
auto first_call = std::make_shared<bool>(true);
void CheckForButtonEvent(uint32_t openVR_event_type,
phx::VRController::ButtonEvent vr_cont_event,
uint32_t button_id, const std::string& side,
bool expect_to_fire,
phx::VRController* vr_controller) {
WHEN("a " + side +
" openVR event (type: " + std::to_string(openVR_event_type) +
" button id: " + std::to_string(button_id) + " is fired") {
vr::VREvent_t event;
event.eventType = openVR_event_type;
event.data.controller.button = button_id;
event.trackedDeviceIndex =
(side == "left" ? 2 // in the mock 2 is given to the left controller
: 1); // in the mock 1 is given to the right controller
*first_call = true;
ALLOW_CALL(openvr_mock.GetSystem(), PollNextEvent(_, _))
.SIDE_EFFECT(*_1 = event)
.SIDE_EFFECT(*first_call = false)
.WITH(*first_call == true)
.RETURN(true);
ALLOW_CALL(openvr_mock.GetSystem(), PollNextEvent(_, _))
.WITH(*first_call == false)
.RETURN(false);
THEN("we expect the signal to " + (expect_to_fire ? "" : "not") + " fire") {
bool signal_fired = false;
vr_controller->RegisterButtonSignal(
[&signal_fired, vr_cont_event, button_id](
phx::VRController::ButtonId id,
phx::VRController::ButtonEvent input_event) {
if (input_event == vr_cont_event &&
id == static_cast<phx::VRController::ButtonId>(button_id))
signal_fired = true;
});
vr_controller->Update();
REQUIRE(signal_fired == expect_to_fire);
}
}
}
} // namespace
SCENARIO("Button click events of openVR get forwarded as signals",
"[phx][phx::VRController]") {
OPENVR_MOCK_ALLOW_ANY_CALL
GIVEN("a VRController") {
auto vr_controller =
std::make_unique<phx::VRController>(phx::VRController::LEFT_CONTROLLER);
THEN("all button events are mapped correctly") {
CheckForButtonEvent(vr::VREvent_ButtonPress,
phx::VRController::BUTTON_PRESSED, vr::k_EButton_Grip,
"left", true, vr_controller.get());
CheckForButtonEvent(
vr::VREvent_ButtonUnpress, phx::VRController::BUTTON_RELEASED,
vr::k_EButton_Grip, "left", true, vr_controller.get());
CheckForButtonEvent(vr::VREvent_ButtonTouch,
phx::VRController::BUTTON_TOUCH, vr::k_EButton_Grip,
"left", true, vr_controller.get());
CheckForButtonEvent(vr::VREvent_ButtonUntouch,
phx::VRController::BUTTON_UNTOUCH, vr::k_EButton_Grip,
"left", true, vr_controller.get());
}
THEN("wrong sided events are ignored") {
CheckForButtonEvent(vr::VREvent_ButtonPress,
phx::VRController::BUTTON_PRESSED, vr::k_EButton_Grip,
"right", false, vr_controller.get());
}
THEN(
"events on other buttons are ignored, respectively the correct button "
"id is forwarded") {
CheckForButtonEvent(
vr::VREvent_ButtonPress, phx::VRController::BUTTON_PRESSED,
vr::k_EButton_SteamVR_Trigger, "right", false, vr_controller.get());
}
}
}
SCENARIO("we can get the actual position on the analog axes, like the trackpad",
"[phx][phx::VRController]") {
OPENVR_MOCK_ALLOW_ANY_CALL
GIVEN("a VRController") {
auto vr_controller =
std::make_unique<phx::VRController>(phx::VRController::LEFT_CONTROLLER);
WHEN("for an axis is asked that does not exist for this mocked device") {
auto log_capture = std::make_shared<test_utilities::LogCapture>();
phx::logger = std::make_shared<spdlog::logger>("logcapture", log_capture);
phx::logger->set_pattern("%w");
ALLOW_CALL(openvr_mock.GetSystem(), GetControllerAxisTypeNameFromEnum(
vr::k_eControllerAxis_Trigger))
.RETURN("k_eControllerAxis_Trigger");
vr_controller->GetAxesValue(phx::VRController::AXES_TRIGGER);
THEN("we expect a warning") {
REQUIRE(*log_capture ==
"VRController device does not provide the requested axes: "
"k_eControllerAxis_Trigger ");
}
}
WHEN("we ask for an existing axis the values are returned") {
ALLOW_CALL(
openvr_mock.GetSystem(),
GetControllerStateWithPose(vr::TrackingUniverseStanding, 2, _, _, _))
.RETURN(true)
.SIDE_EFFECT(_3->rAxis[0].x = 0.5f)
.SIDE_EFFECT(_3->rAxis[0].y = 0.7f);
ALLOW_CALL(openvr_mock.GetSystem(),
GetInt32TrackedDeviceProperty(_, vr::Prop_Axis0Type_Int32, _))
.RETURN(vr::k_eControllerAxis_Trigger);
glm::vec2 value =
vr_controller->GetAxesValue(phx::VRController::AXES_TRIGGER);
THEN("we get the expected values") {
REQUIRE(value == glm::vec2(0.5f, 0.7f));
}
}
}
}
// TODO(JW) try also axes