-
Notifications
You must be signed in to change notification settings - Fork 96
/
Scene_ControllerModel.cpp
93 lines (78 loc) · 5.19 KB
/
Scene_ControllerModel.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"
#include <XrSceneLib/Scene.h>
#include <XrSceneLib/ControllerObject.h>
namespace {
struct ControllerModelScene : public engine::Scene {
ControllerModelScene(engine::Context& context)
: Scene(context)
, m_leftController(context.Instance.LeftHandPath)
, m_rightController(context.Instance.RightHandPath) {
sample::ActionSet& actionSet = ActionContext().CreateActionSet("controller_model_action_set", "Controller Model Action Set");
const std::vector<std::string> subactionPathBothHands = {"/user/hand/right", "/user/hand/left"};
m_gripPoseAction = actionSet.CreateAction("grip_pose", "Grip Pose", XR_ACTION_TYPE_POSE_INPUT, subactionPathBothHands);
ActionContext().SuggestInteractionProfileBindings("/interaction_profiles/microsoft/motion_controller",
{
{m_gripPoseAction, "/user/hand/right/input/grip"},
{m_gripPoseAction, "/user/hand/left/input/grip"},
});
ActionContext().SuggestInteractionProfileBindings("/interaction_profiles/oculus/touch_controller",
{
{m_gripPoseAction, "/user/hand/right/input/grip"},
{m_gripPoseAction, "/user/hand/left/input/grip"},
});
ActionContext().SuggestInteractionProfileBindings("/interaction_profiles/khr/simple_controller",
{
{m_gripPoseAction, "/user/hand/right/input/grip"},
{m_gripPoseAction, "/user/hand/left/input/grip"},
});
if (context.Extensions.XR_EXT_hp_mixed_reality_controller_enabled) {
ActionContext().SuggestInteractionProfileBindings("/interaction_profiles/hp/mixed_reality_controller",
{
{m_gripPoseAction, "/user/hand/right/input/grip"},
{m_gripPoseAction, "/user/hand/left/input/grip"},
});
}
XrActionSpaceCreateInfo actionSpaceCreateInfo{XR_TYPE_ACTION_SPACE_CREATE_INFO};
actionSpaceCreateInfo.poseInActionSpace = xr::math::Pose::Identity();
for (ControllerData& controller : {std::ref(m_leftController), std::ref(m_rightController)}) {
actionSpaceCreateInfo.subactionPath = controller.UserPath;
actionSpaceCreateInfo.action = m_gripPoseAction;
CHECK_XRCMD(
xrCreateActionSpace(m_context.Session.Handle, &actionSpaceCreateInfo, controller.GripSpace.Put(xrDestroySpace)));
// Controller objects are created with empty model. It will be loaded when available.
controller.Object = AddObject(CreateControllerObject(m_context, controller.UserPath));
}
}
void OnUpdate(const engine::FrameTime& frameTime) override {
for (ControllerData& controller : {std::ref(m_leftController), std::ref(m_rightController)}) {
// Update the grip pose and place the controller model to it.
XrSpaceLocation location{XR_TYPE_SPACE_LOCATION};
CHECK_XRCMD(xrLocateSpace(controller.GripSpace.Get(), m_context.AppSpace, frameTime.PredictedDisplayTime, &location));
if (xr::math::Pose::IsPoseValid(location)) {
controller.Object->SetVisible(true);
controller.Object->Pose() = location.pose;
controller.Object->SetFillMode(xr::math::Pose::IsPoseTracked(location) ? Pbr::FillMode::Solid
: Pbr::FillMode::Wireframe);
} else {
controller.Object->SetVisible(false);
}
}
}
private:
struct ControllerData {
const XrPath UserPath;
xr::SpaceHandle GripSpace{};
std::shared_ptr<engine::PbrModelObject> Object;
explicit ControllerData(XrPath userPath)
: UserPath(userPath) {
}
};
XrAction m_gripPoseAction{XR_NULL_HANDLE};
ControllerData m_leftController, m_rightController;
};
} // namespace
std::unique_ptr<engine::Scene> TryCreateControllerModelScene(engine::Context& context) {
return context.Extensions.XR_MSFT_controller_model_enabled ? std::make_unique<ControllerModelScene>(context) : nullptr;
}