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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qquick3dxrcontroller_p.h"
#include "qquick3dxrinputmanager_p.h"
#if !defined(Q_OS_VISIONOS)
# include "openxr/qopenxrinputmanager_p.h"
#endif
#include "qquick3dxrview_p.h"
#include "qquick3dxractionmapper_p.h"
QT_BEGIN_NAMESPACE
/*!
\qmltype XrController
\inherits Node
\inqmlmodule QtQuick3D.Xr
\brief A tracked spatial node that tracks the position and orientation of an input controller.
The XrController is a tracked spatial node that tracks the position and orientation of an input controller.
Since this is a tracked node, its spatial properties should be considered read-only.
\sa XrInputAction
*/
QQuick3DXrController::QQuick3DXrController()
{
m_inputManager = QQuick3DXrInputManager::instance();
}
/*!
\qmlproperty enumeration QtQuick3D.Xr::XrController::controller
Specifies the controller to track.
It can be one of:
\value XrController.LeftController
\value XrController.RightController
\value XrController.UnknownController
\value XrController.LeftHand (alias for \c LeftController)
\value XrController.RightHand (alias for \c RightController)
*/
QQuick3DXrController::Controller QQuick3DXrController::controller() const
{
return m_controller;
}
void QQuick3DXrController::setController(QQuick3DXrController::Controller newController)
{
if (m_controller == newController)
return;
m_controller = newController;
emit controllerChanged();
disconnect(m_isActiveConnection);
QQuick3DXrInputManager::instance()->registerController(this);
auto *input = handInput();
if (input) {
setVisible(input->isActive()); // ### position not set yet, so might show up briefly in wrong location
m_isActiveConnection = connect(input, &QQuick3DXrHandInput::isActiveChanged, this, [this, input]{
setVisible(input->isActive());
});
connect(input, &QQuick3DXrHandInput::pokePositionChanged, this, &QQuick3DXrController::pokePositionChanged);
connect(input, &QQuick3DXrHandInput::jointPositionsChanged, this, &QQuick3DXrController::jointPositionsChanged);
connect(input, &QQuick3DXrHandInput::jointRotationsChanged, this, &QQuick3DXrController::jointRotationsChanged);
connect(input, &QQuick3DXrHandInput::jointDataUpdated, this, &QQuick3DXrController::jointDataUpdated);
} else {
setVisible(false);
}
}
QQuick3DXrHandInput *QQuick3DXrController::handInput() const
{
if (m_inputManager && m_inputManager->isValid()) {
if (m_controller == ControllerRight)
return m_inputManager->rightHandInput();
else if (m_controller == ControllerLeft)
return m_inputManager->leftHandInput();
}
return nullptr;
}
/*!
\qmlproperty enumeration XrController::poseSpace
Specifies the pose of the controller to track, that is, the orientation and
position relative to the physical controller.
It can be one of:
\value XrController.AimPose Used when aiming at something, such as with \l XrVirtualMouse.
\value XrController.GripPose Used when grabbing something, such as when holding an object in the hand.
\default XrController.AimPose
*/
QQuick3DXrController::HandPoseSpace QQuick3DXrController::poseSpace() const
{
return m_poseSpace;
}
void QQuick3DXrController::setPoseSpace(HandPoseSpace newPoseSpace)
{
if (m_poseSpace == newPoseSpace)
return;
m_poseSpace = newPoseSpace;
QQuick3DXrInputManager::instance()->registerController(this);
emit poseSpaceChanged();
}
/*!
\qmlproperty vector3d XrController::pokePosition
\readonly
This property holds the position to be used for touch interactions.
Typically, it will be the tip of the index finger when tracking a hand.
\sa XrView::processTouch, XrView::setTouchpoint
*/
QVector3D QQuick3DXrController::pokePosition() const
{
auto *input = handInput();
if (input)
return input->pokePosition();
return {};
}
/*!
\qmlproperty list<vector3d> XrController::jointPositions
\readonly
When using hand tracking, this property holds the positions of all the bones in the hand.
\sa jointRotations, XrHandModel
*/
QList<QVector3D> QQuick3DXrController::jointPositions() const
{
auto *input = handInput();
if (input)
return input->jointPositions();
return {};
}
/*!
\qmlproperty list<quaternion> XrController::jointRotations
\readonly
When using hand tracking, this property holds the orientation of all the bones in the hand.
\sa jointPositions, XrHandModel
*/
QList<QQuaternion> QQuick3DXrController::jointRotations() const
{
auto *input = handInput();
if (input)
return input->jointRotations();
return {};
}
/*!
\qmlproperty bool XrController::isActive
\brief Indicates whether the controller is providing input.
\readonly
This property is true if the corresponding physical controller is present
and tracking.
*/
bool QQuick3DXrController::isActive() const
{
return m_isActive;
}
QtQuick3DXr::Hand QtQuick3DXr::handForController(QQuick3DXrController::Controller controller)
{
QSSG_ASSERT(controller != QQuick3DXrController::ControllerNone, return QQuick3DXrInputManager::Hand::RightHand);
switch (controller) {
case QQuick3DXrController::ControllerLeft:
return QQuick3DXrInputManager::Hand::LeftHand;
case QQuick3DXrController::ControllerRight:
return QQuick3DXrInputManager::Hand::RightHand;
default:
Q_UNREACHABLE();
}
}
QtQuick3DXr::HandPoseSpace QtQuick3DXr::pose_cast(QQuick3DXrController::HandPoseSpace poseSpace)
{
return static_cast<QtQuick3DXr::HandPoseSpace>(poseSpace);
}
QT_END_NAMESPACE
|