Revision control
Copy as Markdown
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D
import QtQuick3D.Helpers
import QtQuick3D.Xr
pragma ComponentBehavior: Bound
XrView {
id: xrView
referenceSpace: XrView.ReferenceSpaceLocalFloor
depthSubmissionEnabled: true
environment: SceneEnvironment {
id: sceneEnvironment
skyMaterial: ProceduralSkyMaterial {}
antialiasingMode: SceneEnvironment.MSAA
antialiasingQuality: SceneEnvironment.High
backgroundMode: SceneEnvironment.Color
clearColor: "skyblue"
probeHorizon: 0.5
}
DirectionalLight {
eulerRotation.x: -30
eulerRotation.y: -70
}
//! [haptics]
XrHapticFeedback {
id: hapticFeedback
controller: XrHapticFeedback.RightController
hapticEffect: XrSimpleHapticEffect {
amplitude: 0.5
duration: 10
frequency: 200
}
property Model prevObj: null
function handleHover(obj: Model) {
if (obj && obj !== prevObj)
start()
prevObj = obj
}
}
//! [haptics]
xrOrigin: XrOrigin {
id: theOrigin
//! [connections]
AimController {
id: rightAim
controller: XrController.RightController
view: xrView
enableVirtualMouse: true
enableThumbstickMove: thumbCheckBox.checked
onObjectPressed: (obj, pos, dir) => {
gadgetBox.handlePress(obj, pos, dir)
}
onHoveredObjectChanged: {
gadgetBox.handleHover(hoveredObject)
hapticFeedback.handleHover(hoveredObject)
}
onMoved: (pos, dir) => {
gadgetBox.handleMove(pos, dir)
}
onReleased: {
gadgetBox.handleRelease()
}
onObjectGrabbed: (obj) => {
if (!grabCheckBox.checked)
return
const gadget = obj as XrGadget
if (!gadget)
startGrab(obj)
else if (gadget.grabbable)
startGrab(gadget.controlledObject)
}
Model {
source: "#Cylinder"
scale: "0.05, 0.1, 0.05"
z: 5
eulerRotation.x: 90
materials: PrincipledMaterial {
baseColor: "black"
}
}
xrCursor: cursor
}
//! [connections]
XrCamera {
id: camera
}
XrCursor {
id: cursor
cameraNode: camera
size: cursorSlider.value
function style() : int {
if (rightAim.pickStatus === PickResult.Item)
return XrCursor.CursorStyle.Flat
if (rightAim.pickStatus === PickResult.Null)
return XrCursor.CursorStyle.Hidden
const gadget = rightAim.hoveredObject as XrGadget
if (gadget)
return gadget.cursorStyle
return sphereButton.checked ? XrCursor.CursorStyle.Sphere : XrCursor.CursorStyle.Flat
}
cursorStyle: style()
}
}
GadgetBox {
id: gadgetBox
}
Scene {
z: -100
}
XrItem {
y: height + 75
x: -125
z: -75
width: 60
height: 80
eulerRotation.y: 30
color: "transparent"
contentItem: Rectangle {
width: 300
height: 400
opacity: 0.99
color: "#aafff7f0"
radius: 20
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
CheckBox {
id: grabCheckBox
text: "Enable grab"
checked: true
}
CheckBox {
id: thumbCheckBox
text: "Thumbstick move"
checked: true
enabled: grabCheckBox.checked
}
Slider {
id: cursorSlider
from: 0.5
value: 2.0
to: 5
}
Text {
text: "Cursor size: " + cursorSlider.value.toFixed(1)
}
Frame {
ColumnLayout {
anchors.fill: parent
Text { text: "Cursor style for 3D objects" }
RadioButton { id: sphereButton; text: "Sphere"; checked: true }
RadioButton { text: "Flat" }
}
Layout.alignment: Qt.AlignBottom
}
}
}
XrItemHandle {
visible: grabCheckBox.checked
}
}
}